#ifndef X86SUBTARGET_H
#define X86SUBTARGET_H
#include "llvm/Target/TargetSubtarget.h"
#include "llvm/CallingConv.h"
#include <string>
namespace llvm {
class GlobalValue;
class TargetMachine;
namespace PICStyles {
enum Style {
StubPIC, StubDynamicNoPIC, GOT, RIPRel, None };
}
class X86Subtarget : public TargetSubtarget {
protected:
enum X86SSEEnum {
NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
};
enum X863DNowEnum {
NoThreeDNow, ThreeDNow, ThreeDNowA
};
PICStyles::Style PICStyle;
X86SSEEnum X86SSELevel;
X863DNowEnum X863DNowLevel;
bool HasCMov;
bool HasX86_64;
bool HasSSE4A;
bool HasAVX;
bool HasAES;
bool HasFMA3;
bool HasFMA4;
bool IsBTMemSlow;
bool IsUAMemFast;
bool HasVectorUAMem;
unsigned char DarwinVers;
unsigned stackAlignment;
unsigned MaxInlineSizeThreshold;
private:
bool Is64Bit;
public:
enum {
isELF, isCygwin, isDarwin, isWindows, isMingw
} TargetType;
X86Subtarget(const std::string &TT, const std::string &FS, bool is64Bit);
unsigned getStackAlignment() const { return stackAlignment; }
unsigned getMaxInlineSizeThreshold() const { return MaxInlineSizeThreshold; }
std::string 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 hasCMov() const { return HasCMov; }
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 hasSSE4A() const { return HasSSE4A; }
bool has3DNow() const { return X863DNowLevel >= ThreeDNow; }
bool has3DNowA() const { return X863DNowLevel >= ThreeDNowA; }
bool hasAVX() const { return HasAVX; }
bool hasAES() const { return HasAES; }
bool hasFMA3() const { return HasFMA3; }
bool hasFMA4() const { return HasFMA4; }
bool isBTMemSlow() const { return IsBTMemSlow; }
bool isUnalignedMemAccessFast() const { return IsUAMemFast; }
bool hasVectorUAMem() const { return HasVectorUAMem; }
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 isTargetCygwin() const { return TargetType == isCygwin; }
bool isTargetCygMing() const {
return TargetType == isMingw || TargetType == isCygwin;
}
bool isTargetCOFF() const {
return TargetType == isMingw || TargetType == isCygwin ||
TargetType == isWindows;
}
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-n8:16:32:64";
else if (isTargetDarwin())
p = "e-p:32:32-f64:32:64-i64:32:64-f80:128:128-n8:16:32";
else if (isTargetMingw() || isTargetWindows())
p = "e-p:32:32-f64:64:64-i64:64:64-f80:32:32-n8:16:32";
else
p = "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32";
return std::string(p);
}
bool isPICStyleSet() const { return PICStyle != PICStyles::None; }
bool isPICStyleGOT() const { return PICStyle == PICStyles::GOT; }
bool isPICStyleRIPRel() const { return PICStyle == PICStyles::RIPRel; }
bool isPICStyleStubPIC() const {
return PICStyle == PICStyles::StubPIC;
}
bool isPICStyleStubNoDynamic() const {
return PICStyle == PICStyles::StubDynamicNoPIC;
}
bool isPICStyleStubAny() const {
return PICStyle == PICStyles::StubDynamicNoPIC ||
PICStyle == PICStyles::StubPIC; }
unsigned getDarwinVers() const { return DarwinVers; }
unsigned char ClassifyGlobalReference(const GlobalValue *GV,
const TargetMachine &TM)const;
unsigned char ClassifyBlockAddressReference() const;
bool IsLegalToCallImmediateAddr(const TargetMachine &TM) const;
const char *getBZeroEntry() const;
unsigned getSpecialAddressLatency() const;
bool IsCalleePop(bool isVarArg, CallingConv::ID CallConv) const;
};
}
#endif