summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Basic/Targets.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/Targets.cpp174
1 files changed, 169 insertions, 5 deletions
diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
index 92fd417..fdf63e7 100644
--- a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
@@ -150,7 +150,7 @@ protected:
public:
DarwinTargetInfo(const std::string& triple) :
OSTargetInfo<Target>(triple) {
- this->TLSSupported = false;
+ this->TLSSupported = llvm::Triple(triple).getDarwinMajorNumber() > 10;
}
virtual std::string isValidSectionSpecifier(llvm::StringRef SR) const {
@@ -160,6 +160,12 @@ public:
return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section,
TAA, StubSize);
}
+
+ virtual const char *getStaticInitSectionSpecifier() const {
+ // FIXME: We should return 0 when building kexts.
+ return "__TEXT,__StaticInit,regular,pure_instructions";
+ }
+
};
@@ -206,6 +212,30 @@ public:
}
};
+// Minix Target
+template<typename Target>
+class MinixTargetInfo : public OSTargetInfo<Target> {
+protected:
+ virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+ MacroBuilder &Builder) const {
+ // Minix defines
+
+ Builder.defineMacro("__minix", "3");
+ Builder.defineMacro("_EM_WSIZE", "4");
+ Builder.defineMacro("_EM_PSIZE", "4");
+ Builder.defineMacro("_EM_SSIZE", "2");
+ Builder.defineMacro("_EM_LSIZE", "4");
+ Builder.defineMacro("_EM_FSIZE", "4");
+ Builder.defineMacro("_EM_DSIZE", "8");
+ DefineStd(Builder, "unix", Opts);
+ }
+public:
+ MinixTargetInfo(const std::string &triple)
+ : OSTargetInfo<Target>(triple) {
+ this->UserLabelPrefix = "";
+ }
+};
+
// Linux target
template<typename Target>
class LinuxTargetInfo : public OSTargetInfo<Target> {
@@ -299,13 +329,20 @@ protected:
Builder.defineMacro("__CELLOS_LV2__");
Builder.defineMacro("__ELF__");
Builder.defineMacro("__LP32__");
+ Builder.defineMacro("_ARCH_PPC64");
+ Builder.defineMacro("__powerpc64__");
}
public:
PS3PPUTargetInfo(const std::string& triple)
: OSTargetInfo<Target>(triple) {
this->UserLabelPrefix = "";
this->LongWidth = this->LongAlign = this->PointerWidth = this->PointerAlign = 32;
+ this->IntMaxType = TargetInfo::SignedLongLong;
+ this->UIntMaxType = TargetInfo::UnsignedLongLong;
+ this->Int64Type = TargetInfo::SignedLongLong;
this->SizeType = TargetInfo::UnsignedInt;
+ this->DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
+ "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
}
};
@@ -413,12 +450,98 @@ public:
switch (*Name) {
default: return false;
case 'O': // Zero
- return true;
+ break;
case 'b': // Base register
case 'f': // Floating point register
Info.setAllowsRegister();
- return true;
+ break;
+ // FIXME: The following are added to allow parsing.
+ // I just took a guess at what the actions should be.
+ // Also, is more specific checking needed? I.e. specific registers?
+ case 'd': // Floating point register (containing 64-bit value)
+ case 'v': // Altivec vector register
+ Info.setAllowsRegister();
+ break;
+ case 'w':
+ switch (Name[1]) {
+ case 'd':// VSX vector register to hold vector double data
+ case 'f':// VSX vector register to hold vector float data
+ case 's':// VSX vector register to hold scalar float data
+ case 'a':// Any VSX register
+ break;
+ default:
+ return false;
+ }
+ Info.setAllowsRegister();
+ Name++; // Skip over 'w'.
+ break;
+ case 'h': // `MQ', `CTR', or `LINK' register
+ case 'q': // `MQ' register
+ case 'c': // `CTR' register
+ case 'l': // `LINK' register
+ case 'x': // `CR' register (condition register) number 0
+ case 'y': // `CR' register (condition register)
+ case 'z': // `XER[CA]' carry bit (part of the XER register)
+ Info.setAllowsRegister();
+ break;
+ case 'I': // Signed 16-bit constant
+ case 'J': // Unsigned 16-bit constant shifted left 16 bits
+ // (use `L' instead for SImode constants)
+ case 'K': // Unsigned 16-bit constant
+ case 'L': // Signed 16-bit constant shifted left 16 bits
+ case 'M': // Constant larger than 31
+ case 'N': // Exact power of 2
+ case 'P': // Constant whose negation is a signed 16-bit constant
+ case 'G': // Floating point constant that can be loaded into a
+ // register with one instruction per word
+ case 'H': // Integer/Floating point constant that can be loaded
+ // into a register using three instructions
+ break;
+ case 'm': // Memory operand. Note that on PowerPC targets, m can
+ // include addresses that update the base register. It
+ // 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
+ // load or store instruction. For example:
+ // asm ("st%U0 %1,%0" : "=m" (mem) : "r" (val));
+ // is correct but:
+ // asm ("st %1,%0" : "=m" (mem) : "r" (val));
+ // is not. Use es rather than m if you don't want the base
+ // register to be updated.
+ case 'e':
+ if (Name[1] != 's')
+ return false;
+ // 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
+ // access it at all.
+ Info.setAllowsMemory();
+ Name++; // Skip over 'e'.
+ break;
+ case 'Q': // Memory operand that is an offset from a register (it is
+ // usually better to use `m' or `es' in asm statements)
+ case 'Z': // Memory operand that is an indexed or indirect from a
+ // register (it is usually better to use `m' or `es' in
+ // asm statements)
+ Info.setAllowsMemory();
+ Info.setAllowsRegister();
+ break;
+ case 'R': // AIX TOC entry
+ case 'a': // Address operand that is an indexed or indirect from a
+ // register (`p' is preferable for asm statements)
+ case 'S': // Constant suitable as a 64-bit mask operand
+ case 'T': // Constant suitable as a 32-bit mask operand
+ case 'U': // System V Release 4 small data area reference
+ case 't': // AND masks that can be performed by two rldic{l, r}
+ // instructions
+ case 'W': // Vector constant that does not require memory
+ case 'j': // Vector constant that is all zeros.
+ break;
+ // End FIXME.
}
+ return true;
}
virtual const char *getClobbers() const {
return "";
@@ -600,6 +723,27 @@ public:
};
} // end anonymous namespace.
+
+namespace {
+class DarwinPPCTargetInfo :
+ public DarwinTargetInfo<PPCTargetInfo> {
+public:
+ DarwinPPCTargetInfo(const std::string& triple)
+ : DarwinTargetInfo<PPCTargetInfo>(triple) {
+ HasAlignMac68kSupport = true;
+ }
+};
+
+class DarwinPPC64TargetInfo :
+ public DarwinTargetInfo<PPC64TargetInfo> {
+public:
+ DarwinPPC64TargetInfo(const std::string& triple)
+ : DarwinTargetInfo<PPC64TargetInfo>(triple) {
+ HasAlignMac68kSupport = true;
+ }
+};
+} // end anonymous namespace.
+
namespace {
// MBlaze abstract base class
class MBlazeTargetInfo : public TargetInfo {
@@ -1101,6 +1245,11 @@ public:
PtrDiffType = SignedInt;
IntPtrType = SignedInt;
RegParmMax = 3;
+
+ // Use fpret for all types.
+ RealTypeUsesObjCFPRet = ((1 << TargetInfo::Float) |
+ (1 << TargetInfo::Double) |
+ (1 << TargetInfo::LongDouble));
}
virtual const char *getVAListDeclaration() const {
return "typedef char* __builtin_va_list;";
@@ -1257,6 +1406,8 @@ public:
LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
LongDoubleWidth = 128;
LongDoubleAlign = 128;
+ LargeArrayMinWidth = 128;
+ LargeArrayAlign = 128;
IntMaxType = SignedLong;
UIntMaxType = UnsignedLong;
Int64Type = SignedLong;
@@ -1265,6 +1416,9 @@ public:
DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
"i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
"a0:0:64-s0:64:64-f80:128:128-n8:16:32:64";
+
+ // Use fpret only for long double.
+ RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble);
}
virtual const char *getVAListDeclaration() const {
return "typedef struct __va_list_tag {"
@@ -2294,6 +2448,8 @@ static TargetInfo *AllocateTarget(const std::string &T) {
case llvm::Triple::arm:
case llvm::Triple::thumb:
switch (os) {
+ case llvm::Triple::Linux:
+ return new LinuxTargetInfo<ARMTargetInfo>(T);
case llvm::Triple::Darwin:
return new DarwinARMTargetInfo(T);
case llvm::Triple::FreeBSD:
@@ -2327,14 +2483,14 @@ static TargetInfo *AllocateTarget(const std::string &T) {
case llvm::Triple::ppc:
if (os == llvm::Triple::Darwin)
- return new DarwinTargetInfo<PPCTargetInfo>(T);
+ return new DarwinPPCTargetInfo(T);
else if (os == llvm::Triple::FreeBSD)
return new FreeBSDTargetInfo<PPC32TargetInfo>(T);
return new PPC32TargetInfo(T);
case llvm::Triple::ppc64:
if (os == llvm::Triple::Darwin)
- return new DarwinTargetInfo<PPC64TargetInfo>(T);
+ return new DarwinPPC64TargetInfo(T);
else if (os == llvm::Triple::Lv2)
return new PS3PPUTargetInfo<PPC64TargetInfo>(T);
else if (os == llvm::Triple::FreeBSD)
@@ -2377,6 +2533,8 @@ static TargetInfo *AllocateTarget(const std::string &T) {
return new OpenBSDI386TargetInfo(T);
case llvm::Triple::FreeBSD:
return new FreeBSDTargetInfo<X86_32TargetInfo>(T);
+ case llvm::Triple::Minix:
+ return new MinixTargetInfo<X86_32TargetInfo>(T);
case llvm::Triple::Solaris:
return new SolarisTargetInfo<X86_32TargetInfo>(T);
case llvm::Triple::Cygwin:
@@ -2444,6 +2602,12 @@ TargetInfo *TargetInfo::CreateTargetInfo(Diagnostic &Diags,
return 0;
}
+ // Set the target C++ ABI.
+ if (!Target->setCXXABI(Opts.CXXABI)) {
+ Diags.Report(diag::err_target_unknown_cxxabi) << Opts.CXXABI;
+ return 0;
+ }
+
// Compute the default target features, we need the target to handle this
// because features may have dependencies on one another.
llvm::StringMap<bool> Features;
OpenPOWER on IntegriCloud