aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Bendersky <eliben@google.com>2013-04-08 21:31:01 +0000
committerEli Bendersky <eliben@google.com>2013-04-08 21:31:01 +0000
commitc0783dc18a78b55e9486b72fa0b193dbf1b65fbb (patch)
tree5b41622f2ad208bed5b648958f5dd8320079917e
parent3769f38264ba46a18059ad82a3a506f27bbf2537 (diff)
The PNaCl target no longer permits __attribute__((regparm)).
Remove the custom lowering code dealing with it, disallow it in PNaclTargetInfo and adjust tests accordingly. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179059 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Basic/Targets.cpp4
-rw-r--r--lib/CodeGen/TargetInfo.cpp46
-rw-r--r--test/CodeGen/le32-regparm.c41
3 files changed, 18 insertions, 73 deletions
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index 4419bf5ee1..82ea6563d9 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -621,7 +621,7 @@ class NaClTargetInfo : public OSTargetInfo<Target> {
this->SizeType = TargetInfo::UnsignedInt;
this->PtrDiffType = TargetInfo::SignedInt;
this->IntPtrType = TargetInfo::SignedInt;
- this->RegParmMax = 2;
+ // RegParmMax is inherited from the underlying architecture
this->LongDoubleFormat = &llvm::APFloat::IEEEdouble;
this->DescriptionString = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"
"f32:32:32-f64:64:64-p:32:32:32-v128:32:32";
@@ -4862,7 +4862,7 @@ public:
this->SizeType = TargetInfo::UnsignedInt;
this->PtrDiffType = TargetInfo::SignedInt;
this->IntPtrType = TargetInfo::SignedInt;
- this->RegParmMax = 2;
+ this->RegParmMax = 0; // Disallow regparm
DescriptionString = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"
"f32:32:32-f64:64:64-p:32:32:32-v128:32:32";
}
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index d230a17df1..d0b4918c67 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -398,6 +398,9 @@ ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy) const {
//===----------------------------------------------------------------------===//
// le32/PNaCl bitcode ABI Implementation
+//
+// This is a simplified version of the x86_32 ABI. Arguments and return values
+// are always passed on the stack.
//===----------------------------------------------------------------------===//
class PNaClABIInfo : public ABIInfo {
@@ -405,7 +408,7 @@ class PNaClABIInfo : public ABIInfo {
PNaClABIInfo(CodeGen::CodeGenTypes &CGT) : ABIInfo(CGT) {}
ABIArgInfo classifyReturnType(QualType RetTy) const;
- ABIArgInfo classifyArgumentType(QualType RetTy, unsigned &FreeRegs) const;
+ ABIArgInfo classifyArgumentType(QualType RetTy) const;
virtual void computeInfo(CGFunctionInfo &FI) const;
virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
@@ -421,13 +424,9 @@ class PNaClTargetCodeGenInfo : public TargetCodeGenInfo {
void PNaClABIInfo::computeInfo(CGFunctionInfo &FI) const {
FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
- // Obtain the initial number of registers available for passing integers
- // from the function's regparm attribute.
- unsigned FreeRegs = FI.getHasRegParm() ? FI.getRegParm() : 0;
-
for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
it != ie; ++it)
- it->info = classifyArgumentType(it->type, FreeRegs);
+ it->info = classifyArgumentType(it->type);
}
llvm::Value *PNaClABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
@@ -435,42 +434,25 @@ llvm::Value *PNaClABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
return 0;
}
-/// \brief Classify argument of given type \p Ty. \p FreeRegs is the number of
-/// registers available for passing arguments - it can be updated by this
-/// method.
-ABIArgInfo PNaClABIInfo::classifyArgumentType(QualType Ty,
- unsigned &FreeRegs) const {
+/// \brief Classify argument of given type \p Ty.
+ABIArgInfo PNaClABIInfo::classifyArgumentType(QualType Ty) const {
if (isAggregateTypeForABI(Ty)) {
// In the PNaCl ABI we always pass records/structures on the stack. The
// byval attribute can be used if the record doesn't have non-trivial
// constructors/destructors.
- FreeRegs = 0;
if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty))
return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
return ABIArgInfo::getIndirect(0);
- }
-
- // Treat an enum type as its underlying type.
- if (const EnumType *EnumTy = Ty->getAs<EnumType>())
+ } else if (const EnumType *EnumTy = Ty->getAs<EnumType>()) {
+ // Treat an enum type as its underlying type.
Ty = EnumTy->getDecl()->getIntegerType();
+ } else if (Ty->isFloatingType()) {
+ // Floating-point types don't go inreg.
+ return ABIArgInfo::getDirect();
+ }
- ABIArgInfo BaseInfo = (Ty->isPromotableIntegerType() ?
+ return (Ty->isPromotableIntegerType() ?
ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
-
- // Figure out how many of the free registers can be occupied by this type.
- // regparm registers are 32-bit.
- unsigned NumRegsRequired = (getContext().getTypeSize(Ty) + 31) / 32;
- if (NumRegsRequired == 0) return BaseInfo;
- if (NumRegsRequired > FreeRegs) {
- // If this type needs more registers than we have available, no more
- // passing in-registers can happen.
- FreeRegs = 0;
- return BaseInfo;
- }
- FreeRegs -= NumRegsRequired;
- return BaseInfo.isDirect() ?
- ABIArgInfo::getDirectInReg(BaseInfo.getCoerceToType()) :
- ABIArgInfo::getExtendInReg(BaseInfo.getCoerceToType());
}
ABIArgInfo PNaClABIInfo::classifyReturnType(QualType RetTy) const {
diff --git a/test/CodeGen/le32-regparm.c b/test/CodeGen/le32-regparm.c
index 8c1ae5eb45..c8f70694c4 100644
--- a/test/CodeGen/le32-regparm.c
+++ b/test/CodeGen/le32-regparm.c
@@ -1,41 +1,4 @@
-// RUN: %clang_cc1 -triple le32-unknown-nacl %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple le32-unknown-nacl %s -fsyntax-only -verify
-#define FASTCALL __attribute__((regparm(2)))
+void __attribute__((regparm(2))) fc_f1(int i, int j, int k) {} // expected-error{{'regparm' is not valid on this platform}}
-typedef struct {
- int aaa;
- double bbbb;
- int ccc[200];
-} foo;
-
-// 2 inreg arguments are supported.
-void FASTCALL f1(int i, int j, int k);
-// CHECK: define void @f1(i32 inreg %i, i32 inreg %j, i32 %k)
-void f1(int i, int j, int k) { }
-
-// inreg structs are not supported.
-// CHECK: define void @f2(%struct.foo* inreg %a)
-void __attribute__((regparm(1))) f2(foo* a) {}
-
-// Only the first 2 arguments can be passed inreg, and the first
-// non-integral type consumes remaining available registers.
-// CHECK: define void @f3(%struct.foo* byval %a, i32 %b)
-void __attribute__((regparm(2))) f3(foo a, int b) {}
-
-// Only 64 total bits are supported
-// CHECK: define void @f4(i64 inreg %g, i32 %h)
-void __attribute__((regparm(2))) f4(long long g, int h) {}
-
-typedef void (*FType)(int, int) __attribute ((regparm (2)));
-FType bar;
-extern void FASTCALL reduced(char b, double c, foo* d, double e, int f);
-
-int
-main(void) {
- // The presence of double c means that foo* d is not passed inreg. This
- // behavior is different from current x86-32 behavior
- // CHECK: call void @reduced(i8 inreg signext 0, {{.*}} %struct.foo* null
- reduced(0, 0.0, 0, 0.0, 0);
- // CHECK: call void {{.*}}(i32 inreg 1, i32 inreg 2)
- bar(1,2);
-}