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
diff --git a/lib/CodeGen/ABIInfo.h b/lib/CodeGen/ABIInfo.h
index 838cb29..86f5380 100644
--- a/lib/CodeGen/ABIInfo.h
+++ b/lib/CodeGen/ABIInfo.h
@@ -74,31 +74,42 @@
     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 @@
       TypeData = T;
     }
 
+    bool getInReg() const {
+      assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!");
+      return InReg;
+    }
+
     // Indirect accessors
     unsigned getIndirectAlign() const {
       assert(TheKind == Indirect && "Invalid kind!");