summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/ABIInfo.h
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2012-07-31 02:44:24 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2012-07-31 02:44:24 +0000
commitb48280ba1790122cd3fa6e17c88ecd6a4571a4eb (patch)
treef9542b6b14db62a150a7af7d2cfb0b0d7d3b859f /lib/CodeGen/ABIInfo.h
parentd72f56de7c79828928147389aed2c6c46f331031 (diff)
Handle functions with struct arguments or return types and the regparm
attribute. It is a variation of the x86_64 ABI: * A struct returned indirectly uses the first register argument to pass the pointer. * Floats, Doubles and structs containing only one of them are not passed in registers. * Other structs are split into registers if they fit on the remaining ones. Otherwise they are passed in memory. * When a struct doesn't fit it still consumes the registers. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161022 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/ABIInfo.h')
-rw-r--r--lib/CodeGen/ABIInfo.h30
1 files changed, 23 insertions, 7 deletions
diff --git a/lib/CodeGen/ABIInfo.h b/lib/CodeGen/ABIInfo.h
index 838cb2989a..86f53803d5 100644
--- a/lib/CodeGen/ABIInfo.h
+++ b/lib/CodeGen/ABIInfo.h
@@ -74,31 +74,42 @@ namespace clang {
unsigned UIntData;
bool BoolData0;
bool BoolData1;
+ bool InReg;
- ABIArgInfo(Kind K, llvm::Type *TD, unsigned UI, bool B0, bool B1,
+ ABIArgInfo(Kind K, llvm::Type *TD, unsigned UI, bool B0, bool B1, bool IR,
llvm::Type* P)
: TheKind(K), TypeData(TD), PaddingType(P), UIntData(UI), BoolData0(B0),
- BoolData1(B1) {}
+ BoolData1(B1), InReg(IR) {}
public:
ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {}
static ABIArgInfo getDirect(llvm::Type *T = 0, unsigned Offset = 0,
llvm::Type *Padding = 0) {
- return ABIArgInfo(Direct, T, Offset, false, false, Padding);
+ return ABIArgInfo(Direct, T, Offset, false, false, false, Padding);
+ }
+ static ABIArgInfo getDirectInReg(llvm::Type *T) {
+ return ABIArgInfo(Direct, T, 0, false, false, true, 0);
}
static ABIArgInfo getExtend(llvm::Type *T = 0) {
- return ABIArgInfo(Extend, T, 0, false, false, 0);
+ return ABIArgInfo(Extend, T, 0, false, false, false, 0);
+ }
+ static ABIArgInfo getExtendInReg(llvm::Type *T = 0) {
+ return ABIArgInfo(Extend, T, 0, false, false, true, 0);
}
static ABIArgInfo getIgnore() {
- return ABIArgInfo(Ignore, 0, 0, false, false, 0);
+ return ABIArgInfo(Ignore, 0, 0, false, false, false, 0);
}
static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true
, bool Realign = false) {
- return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign, 0);
+ return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign, false, 0);
+ }
+ static ABIArgInfo getIndirectInReg(unsigned Alignment, bool ByVal = true
+ , bool Realign = false) {
+ return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign, true, 0);
}
static ABIArgInfo getExpand() {
- return ABIArgInfo(Expand, 0, 0, false, false, 0);
+ return ABIArgInfo(Expand, 0, 0, false, false, false, 0);
}
Kind getKind() const { return TheKind; }
@@ -132,6 +143,11 @@ namespace clang {
TypeData = T;
}
+ bool getInReg() const {
+ assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!");
+ return InReg;
+ }
+
// Indirect accessors
unsigned getIndirectAlign() const {
assert(TheKind == Indirect && "Invalid kind!");