summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/TargetInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/TargetInfo.cpp')
-rw-r--r--lib/CodeGen/TargetInfo.cpp189
1 files changed, 129 insertions, 60 deletions
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index e1fdf86..b29d3cb 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -23,6 +23,18 @@
using namespace clang;
using namespace CodeGen;
+static void AssignToArrayRange(CodeGen::CGBuilderTy &Builder,
+ llvm::Value *Array,
+ llvm::Value *Value,
+ unsigned FirstIndex,
+ unsigned LastIndex) {
+ // Alternatively, we could emit this as a loop in the source.
+ for (unsigned I = FirstIndex; I <= LastIndex; ++I) {
+ llvm::Value *Cell = Builder.CreateConstInBoundsGEP1_32(Array, I);
+ Builder.CreateStore(Value, Cell);
+ }
+}
+
ABIInfo::~ABIInfo() {}
void ABIArgInfo::dump() const {
@@ -71,6 +83,17 @@ static bool isEmptyField(ASTContext &Context, const FieldDecl *FD,
while (const ConstantArrayType *AT = Context.getAsConstantArrayType(FT))
FT = AT->getElementType();
+ const RecordType *RT = FT->getAs<RecordType>();
+ if (!RT)
+ return false;
+
+ // C++ record fields are never empty, at least in the Itanium ABI.
+ //
+ // FIXME: We should use a predicate for whether this behavior is true in the
+ // current ABI.
+ if (isa<CXXRecordDecl>(RT->getDecl()))
+ return false;
+
return isEmptyRecord(Context, FT, AllowArrays);
}
@@ -84,6 +107,14 @@ static bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays) {
const RecordDecl *RD = RT->getDecl();
if (RD->hasFlexibleArrayMember())
return false;
+
+ // If this is a C++ record, check the bases first.
+ if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
+ for (CXXRecordDecl::base_class_const_iterator i = CXXRD->bases_begin(),
+ e = CXXRD->bases_end(); i != e; ++i)
+ if (!isEmptyRecord(Context, i->getType(), true))
+ return false;
+
for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
i != e; ++i)
if (!isEmptyField(Context, *i, AllowArrays))
@@ -130,6 +161,28 @@ static const Type *isSingleElementStruct(QualType T, ASTContext &Context) {
return 0;
const Type *Found = 0;
+
+ // If this is a C++ record, check the bases first.
+ if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
+ for (CXXRecordDecl::base_class_const_iterator i = CXXRD->bases_begin(),
+ e = CXXRD->bases_end(); i != e; ++i) {
+ // Ignore empty records.
+ if (isEmptyRecord(Context, i->getType(), true))
+ continue;
+
+ // If we already found an element then this isn't a single-element struct.
+ if (Found)
+ return 0;
+
+ // If this is non-empty and not a single element struct, the composite
+ // cannot be a single element struct.
+ Found = isSingleElementStruct(i->getType(), Context);
+ if (!Found)
+ return 0;
+ }
+ }
+
+ // Check for single element.
for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
i != e; ++i) {
const FieldDecl *FD = *i;
@@ -164,7 +217,7 @@ static const Type *isSingleElementStruct(QualType T, ASTContext &Context) {
}
static bool is32Or64BitBasicType(QualType Ty, ASTContext &Context) {
- if (!Ty->getAs<BuiltinType>() && !Ty->isAnyPointerType() &&
+ if (!Ty->getAs<BuiltinType>() && !Ty->hasPointerRepresentation() &&
!Ty->isAnyComplexType() && !Ty->isEnumeralType() &&
!Ty->isBlockPointerType())
return false;
@@ -212,23 +265,6 @@ static bool canExpandIndirectArgument(QualType Ty, ASTContext &Context) {
return true;
}
-static bool typeContainsSSEVector(const RecordDecl *RD, ASTContext &Context) {
- for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
- i != e; ++i) {
- const FieldDecl *FD = *i;
-
- if (FD->getType()->isVectorType() &&
- Context.getTypeSize(FD->getType()) >= 128)
- return true;
-
- if (const RecordType* RT = FD->getType()->getAs<RecordType>())
- if (typeContainsSSEVector(RT->getDecl(), Context))
- return true;
- }
-
- return false;
-}
-
namespace {
/// DefaultABIInfo - The default implementation for ABI specific
/// details. This implementation provides information which results in
@@ -363,10 +399,11 @@ bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty,
return true;
}
- // If this is a builtin, pointer, enum, or complex type, it is ok.
- if (Ty->getAs<BuiltinType>() || Ty->isAnyPointerType() ||
+ // If this is a builtin, pointer, enum, complex type, member pointer, or
+ // member function pointer it is ok.
+ if (Ty->getAs<BuiltinType>() || Ty->hasPointerRepresentation() ||
Ty->isAnyComplexType() || Ty->isEnumeralType() ||
- Ty->isBlockPointerType())
+ Ty->isBlockPointerType() || Ty->isMemberPointerType())
return true;
// Arrays are treated like records.
@@ -596,20 +633,14 @@ bool X86_32TargetCodeGenInfo::initDwarfEHRegSizeTable(
// 0-7 are the eight integer registers; the order is different
// on Darwin (for EH), but the range is the same.
// 8 is %eip.
- for (unsigned I = 0, E = 9; I != E; ++I) {
- llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
- Builder.CreateStore(Four8, Slot);
- }
+ AssignToArrayRange(Builder, Address, Four8, 0, 8);
if (CGF.CGM.isTargetDarwin()) {
// 12-16 are st(0..4). Not sure why we stop at 4.
// These have size 16, which is sizeof(long double) on
// platforms with 8-byte alignment for that type.
llvm::Value *Sixteen8 = llvm::ConstantInt::get(i8, 16);
- for (unsigned I = 12, E = 17; I != E; ++I) {
- llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
- Builder.CreateStore(Sixteen8, Slot);
- }
+ AssignToArrayRange(Builder, Address, Sixteen8, 12, 16);
} else {
// 9 is %eflags, which doesn't get a size on Darwin for some
@@ -620,11 +651,8 @@ bool X86_32TargetCodeGenInfo::initDwarfEHRegSizeTable(
// These have size 12, which is sizeof(long double) on
// platforms with 4-byte alignment for that type.
llvm::Value *Twelve8 = llvm::ConstantInt::get(i8, 12);
- for (unsigned I = 11, E = 17; I != E; ++I) {
- llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
- Builder.CreateStore(Twelve8, Slot);
- }
- }
+ AssignToArrayRange(Builder, Address, Twelve8, 11, 16);
+ }
return false;
}
@@ -733,12 +761,9 @@ public:
const llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context);
llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8);
- // 0-16 are the 16 integer registers.
- // 17 is %rip.
- for (unsigned I = 0, E = 17; I != E; ++I) {
- llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
- Builder.CreateStore(Eight8, Slot);
- }
+ // 0-15 are the 16 integer registers.
+ // 16 is %rip.
+ AssignToArrayRange(Builder, Address, Eight8, 0, 16);
return false;
}
@@ -828,6 +853,11 @@ void X86_64ABIInfo::classify(QualType Ty,
classify(ET->getDecl()->getIntegerType(), Context, OffsetBase, Lo, Hi);
} else if (Ty->hasPointerRepresentation()) {
Current = Integer;
+ } else if (Ty->isMemberPointerType()) {
+ if (Ty->isMemberFunctionPointerType())
+ Lo = Hi = Integer;
+ else
+ Current = Integer;
} else if (const VectorType *VT = Ty->getAs<VectorType>()) {
uint64_t Size = Context.getTypeSize(VT);
if (Size == 32) {
@@ -1661,16 +1691,10 @@ PPC32TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
llvm::Value *Sixteen8 = llvm::ConstantInt::get(i8, 16);
// 0-31: r0-31, the 4-byte general-purpose registers
- for (unsigned I = 0, E = 32; I != E; ++I) {
- llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
- Builder.CreateStore(Four8, Slot);
- }
+ AssignToArrayRange(Builder, Address, Four8, 0, 31);
// 32-63: fp0-31, the 8-byte floating-point registers
- for (unsigned I = 32, E = 64; I != E; ++I) {
- llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
- Builder.CreateStore(Eight8, Slot);
- }
+ AssignToArrayRange(Builder, Address, Eight8, 32, 63);
// 64-76 are various 4-byte special-purpose registers:
// 64: mq
@@ -1679,26 +1703,17 @@ PPC32TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
// 67: ap
// 68-75 cr0-7
// 76: xer
- for (unsigned I = 64, E = 77; I != E; ++I) {
- llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
- Builder.CreateStore(Four8, Slot);
- }
+ AssignToArrayRange(Builder, Address, Four8, 64, 76);
// 77-108: v0-31, the 16-byte vector registers
- for (unsigned I = 77, E = 109; I != E; ++I) {
- llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
- Builder.CreateStore(Sixteen8, Slot);
- }
+ AssignToArrayRange(Builder, Address, Sixteen8, 77, 108);
// 109: vrsave
// 110: vscr
// 111: spe_acc
// 112: spefscr
// 113: sfp
- for (unsigned I = 109, E = 114; I != E; ++I) {
- llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
- Builder.CreateStore(Four8, Slot);
- }
+ AssignToArrayRange(Builder, Address, Four8, 109, 113);
return false;
}
@@ -2123,6 +2138,56 @@ void MSP430TargetCodeGenInfo::SetTargetAttributes(const Decl *D,
}
}
+// MIPS ABI Implementation. This works for both little-endian and
+// big-endian variants.
+namespace {
+class MIPSTargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+ MIPSTargetCodeGenInfo(): TargetCodeGenInfo(new DefaultABIInfo()) {}
+
+ int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const {
+ return 29;
+ }
+
+ bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
+ llvm::Value *Address) const;
+};
+}
+
+bool
+MIPSTargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
+ llvm::Value *Address) const {
+ // This information comes from gcc's implementation, which seems to
+ // as canonical as it gets.
+
+ CodeGen::CGBuilderTy &Builder = CGF.Builder;
+ llvm::LLVMContext &Context = CGF.getLLVMContext();
+
+ // Everything on MIPS is 4 bytes. Double-precision FP registers
+ // are aliased to pairs of single-precision FP registers.
+ const llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context);
+ llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4);
+
+ // 0-31 are the general purpose registers, $0 - $31.
+ // 32-63 are the floating-point registers, $f0 - $f31.
+ // 64 and 65 are the multiply/divide registers, $hi and $lo.
+ // 66 is the (notional, I think) register for signal-handler return.
+ AssignToArrayRange(Builder, Address, Four8, 0, 65);
+
+ // 67-74 are the floating-point status registers, $fcc0 - $fcc7.
+ // They are one bit wide and ignored here.
+
+ // 80-111 are the coprocessor 0 registers, $c0r0 - $c0r31.
+ // (coprocessor 1 is the FP unit)
+ // 112-143 are the coprocessor 2 registers, $c2r0 - $c2r31.
+ // 144-175 are the coprocessor 3 registers, $c3r0 - $c3r31.
+ // 176-181 are the DSP accumulator registers.
+ AssignToArrayRange(Builder, Address, Four8, 80, 181);
+
+ return false;
+}
+
+
const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() const {
if (TheTargetCodeGenInfo)
return *TheTargetCodeGenInfo;
@@ -2135,6 +2200,10 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() const {
default:
return *(TheTargetCodeGenInfo = new DefaultTargetCodeGenInfo);
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ return *(TheTargetCodeGenInfo = new MIPSTargetCodeGenInfo());
+
case llvm::Triple::arm:
case llvm::Triple::thumb:
// FIXME: We want to know the float calling convention as well.
OpenPOWER on IntegriCloud