#ifndef X86SUBTARGET_H
#define X86SUBTARGET_H
#include "llvm/Target/TargetSubtarget.h"
#include <string>
namespace llvm {
class Module;
class GlobalValue;
class TargetMachine;
namespace PICStyles {
enum Style {
Stub, GOT, RIPRel, WinPIC, None
};
}
class X86Subtarget : public TargetSubtarget {
public:
enum AsmWriterFlavorTy {
ATT = 0, Intel = 1, Unset
};
protected:
enum X86SSEEnum {
NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
};
enum X863DNowEnum {
NoThreeDNow, ThreeDNow, ThreeDNowA
};
AsmWriterFlavorTy AsmFlavor;
PICStyles::Style PICStyle;
X86SSEEnum X86SSELevel;
X863DNowEnum X863DNowLevel;
bool HasX86_64;
bool IsBTMemSlow;
unsigned char DarwinVers;
bool IsLinux;
unsigned stackAlignment;
unsigned MaxInlineSizeThreshold;
private:
bool Is64Bit;
public:
enum {
isELF, isCygwin, isDarwin, isWindows, isMingw
} TargetType;
X86Subtarget(const Module &M, const std::string &FS, bool is64Bit);
unsigned getStackAlignment() const { return stackAlignment; }
unsigned getMaxInlineSizeThreshold() const { return MaxInlineSizeThreshold; }
void ParseSubtargetFeatures(const std::string &FS, const std::string &CPU);
void AutoDetectSubtargetFeatures();
bool is64Bit() const { return Is64Bit; }
PICStyles::Style getPICStyle() const { return PICStyle; }
void setPICStyle(PICStyles::Style Style) { PICStyle = Style; }
bool hasMMX() const { return X86SSELevel >= MMX; }
bool hasSSE1() const { return X86SSELevel >= SSE1; }
bool hasSSE2() const { return X86SSELevel >= SSE2; }
bool hasSSE3() const { return X86SSELevel >= SSE3; }
bool hasSSSE3() const { return X86SSELevel >= SSSE3; }
bool hasSSE41() const { return X86SSELevel >= SSE41; }
bool hasSSE42() const { return X86SSELevel >= SSE42; }
bool has3DNow() const { return X863DNowLevel >= ThreeDNow; }
bool has3DNowA() const { return X863DNowLevel >= ThreeDNowA; }
bool isBTMemSlow() const { return IsBTMemSlow; }
unsigned getAsmFlavor() const {
return AsmFlavor != Unset ? unsigned(AsmFlavor) : 0;
}
bool isFlavorAtt() const { return AsmFlavor == ATT; }
bool isFlavorIntel() const { return AsmFlavor == Intel; }
bool isTargetDarwin() const { return TargetType == isDarwin; }
bool isTargetELF() const {
return TargetType == isELF;
}
bool isTargetWindows() const { return TargetType == isWindows; }
bool isTargetMingw() const { return TargetType == isMingw; }
bool isTargetCygMing() const { return (TargetType == isMingw ||
TargetType == isCygwin); }
bool isTargetCygwin() const { return TargetType == isCygwin; }
bool isTargetWin64() const {
return (Is64Bit && (TargetType == isMingw || TargetType == isWindows));
}
std::string getDataLayout() const {
const char *p;
if (is64Bit())
p = "e-p:64:64-s:64-f64:64:64-i64:64:64-f80:128:128";
else {
if (isTargetDarwin())
p = "e-p:32:32-f64:32:64-i64:32:64-f80:128:128";
else
p = "e-p:32:32-f64:32:64-i64:32:64-f80:32:32";
}
return std::string(p);
}
bool isPICStyleSet() const { return PICStyle != PICStyles::None; }
bool isPICStyleGOT() const { return PICStyle == PICStyles::GOT; }
bool isPICStyleStub() const { return PICStyle == PICStyles::Stub; }
bool isPICStyleRIPRel() const { return PICStyle == PICStyles::RIPRel; }
bool isPICStyleWinPIC() const { return PICStyle == PICStyles:: WinPIC; }
unsigned getDarwinVers() const { return DarwinVers; }
bool isLinux() const { return IsLinux; }
bool GVRequiresExtraLoad(const GlobalValue* GV, const TargetMachine& TM,
bool isDirectCall) const;
bool GVRequiresRegister(const GlobalValue* GV, const TargetMachine& TM,
bool isDirectCall) const;
bool IsLegalToCallImmediateAddr(const TargetMachine &TM) const;
const char *getBZeroEntry() const;
unsigned getSpecialAddressLatency() const;
};
namespace X86 {
bool GetCpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
unsigned *rECX, unsigned *rEDX);
}
}
#endif