summaryrefslogtreecommitdiffstats
path: root/lib/Basic/Targets.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Basic/Targets.cpp')
-rw-r--r--lib/Basic/Targets.cpp84
1 files changed, 66 insertions, 18 deletions
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index fdf63e7..df20def 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -502,7 +502,7 @@ public:
// is therefore only safe to use `m' in an asm statement
// if that asm statement accesses the operand exactly once.
// The asm statement must also use `%U<opno>' as a
- // placeholder for the �update� flag in the corresponding
+ // placeholder for the "update" flag in the corresponding
// load or store instruction. For example:
// asm ("st%U0 %1,%0" : "=m" (mem) : "r" (val));
// is correct but:
@@ -512,7 +512,7 @@ public:
case 'e':
if (Name[1] != 's')
return false;
- // es: A �stable� memory operand; that is, one which does not
+ // es: A "stable" memory operand; that is, one which does not
// include any automodification of the base register. Unlike
// `m', this constraint can be used in asm statements that
// might access the operand several times, or that might not
@@ -912,11 +912,12 @@ class X86TargetInfo : public TargetInfo {
} AMD3DNowLevel;
bool HasAES;
-
+ bool HasAVX;
+
public:
X86TargetInfo(const std::string& triple)
: TargetInfo(triple), SSELevel(NoMMXSSE), AMD3DNowLevel(NoAMD3DNow),
- HasAES(false) {
+ HasAES(false), HasAVX(false) {
LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
}
virtual void getTargetBuiltins(const Builtin::Info *&Records,
@@ -963,6 +964,7 @@ void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
Features["sse41"] = false;
Features["sse42"] = false;
Features["aes"] = false;
+ Features["avx"] = false;
// LLVM does not currently recognize this.
// Features["sse4a"] = false;
@@ -1046,6 +1048,8 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
Features["3dnow"] = Features["3dnowa"] = true;
else if (Name == "aes")
Features["aes"] = true;
+ else if (Name == "avx")
+ Features["avx"] = true;
} else {
if (Name == "mmx")
Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
@@ -1073,6 +1077,8 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
Features["3dnowa"] = false;
else if (Name == "aes")
Features["aes"] = false;
+ else if (Name == "avx")
+ Features["avx"] = false;
}
return true;
@@ -1092,6 +1098,13 @@ void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) {
continue;
}
+ // FIXME: Not sure yet how to treat AVX in regard to SSE levels.
+ // For now let it be enabled together with other SSE levels.
+ if (Features[i].substr(1) == "avx") {
+ HasAVX = true;
+ continue;
+ }
+
assert(Features[i][0] == '+' && "Invalid target feature!");
X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Features[i].substr(1))
.Case("sse42", SSE42)
@@ -1133,6 +1146,9 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
if (HasAES)
Builder.defineMacro("__AES__");
+ if (HasAVX)
+ Builder.defineMacro("__AVX__");
+
// Target properties.
Builder.defineMacro("__LITTLE_ENDIAN__");
@@ -1186,6 +1202,15 @@ X86TargetInfo::validateAsmConstraint(const char *&Name,
TargetInfo::ConstraintInfo &Info) const {
switch (*Name) {
default: return false;
+ case 'Y': // first letter of a pair:
+ switch (*(Name+1)) {
+ default: return false;
+ case '0': // First SSE register.
+ case 't': // Any SSE register, when SSE2 is enabled.
+ case 'i': // Any SSE register, when SSE2 and inter-unit moves enabled.
+ case 'm': // any MMX register, when inter-unit moves enabled.
+ break; // falls through to setAllowsRegister.
+ }
case 'a': // eax.
case 'b': // ebx.
case 'c': // ecx.
@@ -1193,22 +1218,27 @@ X86TargetInfo::validateAsmConstraint(const char *&Name,
case 'S': // esi.
case 'D': // edi.
case 'A': // edx:eax.
+ case 'f': // any x87 floating point stack register.
case 't': // top of floating point stack.
case 'u': // second from top of floating point stack.
case 'q': // Any register accessible as [r]l: a, b, c, and d.
case 'y': // Any MMX register.
case 'x': // Any SSE register.
case 'Q': // Any register accessible as [r]h: a, b, c, and d.
+ case 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
+ case 'l': // "Index" registers: any general register that can be used as an
+ // index in a base+index memory access.
+ Info.setAllowsRegister();
+ return true;
+ case 'C': // SSE floating point constant.
+ case 'G': // x87 floating point constant.
case 'e': // 32-bit signed integer constant for use with zero-extending
// x86_64 instructions.
case 'Z': // 32-bit unsigned integer constant for use with zero-extending
// x86_64 instructions.
- case 'N': // unsigned 8-bit integer constant for use with in and out
- // instructions.
- case 'R': // "legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
- Info.setAllowsRegister();
return true;
}
+ return false;
}
std::string
@@ -1333,6 +1363,8 @@ public:
// 300=386, 400=486, 500=Pentium, 600=Blend (default)
// We lost the original triple, so we use the default.
Builder.defineMacro("_M_IX86", "600");
+ Builder.defineMacro("_INTEGRAL_MAX_BITS", "64");
+ Builder.defineMacro("_STDCALL_SUPPORTED");
}
};
} // end anonymous namespace
@@ -1388,7 +1420,7 @@ public:
SizeType = UnsignedLong;
IntPtrType = SignedLong;
PtrDiffType = SignedLong;
- }
+ }
virtual void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
X86_32TargetInfo::getTargetDefines(Opts, Builder);
@@ -1447,7 +1479,10 @@ public:
TLSSupported = false;
WCharType = UnsignedShort;
LongWidth = LongAlign = 32;
- DoubleAlign = LongLongAlign = 64;
+ DoubleAlign = LongLongAlign = 64;
+ IntMaxType = SignedLongLong;
+ UIntMaxType = UnsignedLongLong;
+ Int64Type = SignedLongLong;
}
virtual void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
@@ -1469,9 +1504,10 @@ public:
MacroBuilder &Builder) const {
WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
Builder.defineMacro("_M_X64");
+ Builder.defineMacro("_INTEGRAL_MAX_BITS", "64");
}
virtual const char *getVAListDeclaration() const {
- return "typedef char* va_list;";
+ return "typedef char* __builtin_va_list;";
}
};
} // end anonymous namespace
@@ -1566,6 +1602,9 @@ public:
"i64:64:64-f32:32:32-f64:64:64-"
"v64:64:64-v128:128:128-a0:0:64-n32");
}
+
+ // ARM targets default to using the ARM C++ ABI.
+ CXXABI = CXXABI_ARM;
}
virtual const char *getABI() const { return ABI.c_str(); }
virtual bool setABI(const std::string &Name) {
@@ -1769,18 +1808,27 @@ public:
};
const char * const ARMTargetInfo::GCCRegNames[] = {
+ // Integer registers
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
+ "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc",
+
+ // Float registers
+ "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
+ "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15",
+ "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
+ "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31"
+
+ // FIXME: Need double and NEON registers, but we need support for aliasing
+ // multiple registers for that.
};
void ARMTargetInfo::getGCCRegNames(const char * const *&Names,
- unsigned &NumNames) const {
+ unsigned &NumNames) const {
Names = GCCRegNames;
NumNames = llvm::array_lengthof(GCCRegNames);
}
const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
-
{ { "a1" }, "r0" },
{ { "a2" }, "r1" },
{ { "a3" }, "r2" },
@@ -1794,9 +1842,9 @@ const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
{ { "sl" }, "r10" },
{ { "fp" }, "r11" },
{ { "ip" }, "r12" },
- { { "sp" }, "r13" },
- { { "lr" }, "r14" },
- { { "pc" }, "r15" },
+ { { "r13" }, "sp" },
+ { { "r14" }, "lr" },
+ { { "r15" }, "pc" },
};
void ARMTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
@@ -2603,7 +2651,7 @@ TargetInfo *TargetInfo::CreateTargetInfo(Diagnostic &Diags,
}
// Set the target C++ ABI.
- if (!Target->setCXXABI(Opts.CXXABI)) {
+ if (!Opts.CXXABI.empty() && !Target->setCXXABI(Opts.CXXABI)) {
Diags.Report(diag::err_target_unknown_cxxabi) << Opts.CXXABI;
return 0;
}
OpenPOWER on IntegriCloud