1Pull in r198145 from upstream llvm trunk (by Venkatraman Govindaraju):
2
3  [SparcV9]: Implement lowering of long double (fp128) arguments in Sparc64 ABI.
4  Also, pass fp128 arguments to varargs through integer registers if necessary.
5
6Introduced here: http://svnweb.freebsd.org/changeset/base/262261
7
8Index: test/CodeGen/SPARC/64abi.ll
9===================================================================
10--- test/CodeGen/SPARC/64abi.ll
11+++ test/CodeGen/SPARC/64abi.ll
12@@ -411,3 +411,33 @@ entry:
13 }
14
15 declare i32 @use_buf(i32, i8*)
16+
17+; CHECK-LABEL: test_fp128_args
18+; CHECK-DAG:   std %f0, [%fp+{{.+}}]
19+; CHECK-DAG:   std %f2, [%fp+{{.+}}]
20+; CHECK-DAG:   std %f6, [%fp+{{.+}}]
21+; CHECK-DAG:   std %f4, [%fp+{{.+}}]
22+; CHECK:       add %fp, [[Offset:[0-9]+]], %o0
23+; CHECK:       call _Qp_add
24+; CHECK:       ldd [%fp+[[Offset]]], %f0
25+define fp128 @test_fp128_args(fp128 %a, fp128 %b) {
26+entry:
27+  %0 = fadd fp128 %a, %b
28+  ret fp128 %0
29+}
30+
31+declare i64 @receive_fp128(i64 %a, ...)
32+
33+; CHECK-LABEL: test_fp128_variable_args
34+; CHECK-DAG:   std %f4, [%sp+[[Offset0:[0-9]+]]]
35+; CHECK-DAG:   std %f6, [%sp+[[Offset1:[0-9]+]]]
36+; CHECK-DAG:   ldx [%sp+[[Offset0]]], %o2
37+; CHECK-DAG:   ldx [%sp+[[Offset1]]], %o3
38+; CHECK:       call receive_fp128
39+define i64 @test_fp128_variable_args(i64 %a, fp128 %b) {
40+entry:
41+  %0 = call i64 (i64, ...)* @receive_fp128(i64 %a, fp128 %b)
42+  ret i64 %0
43+}
44+
45+
46Index: lib/Target/Sparc/SparcISelLowering.cpp
47===================================================================
48--- lib/Target/Sparc/SparcISelLowering.cpp
49+++ lib/Target/Sparc/SparcISelLowering.cpp
50@@ -80,11 +80,14 @@ static bool CC_Sparc_Assign_f64(unsigned &ValNo, M
51 static bool CC_Sparc64_Full(unsigned &ValNo, MVT &ValVT,
52                             MVT &LocVT, CCValAssign::LocInfo &LocInfo,
53                             ISD::ArgFlagsTy &ArgFlags, CCState &State) {
54-  assert((LocVT == MVT::f32 || LocVT.getSizeInBits() == 64) &&
55+  assert((LocVT == MVT::f32 || LocVT == MVT::f128
56+          || LocVT.getSizeInBits() == 64) &&
57          "Can't handle non-64 bits locations");
58
59   // Stack space is allocated for all arguments starting from [%fp+BIAS+128].
60-  unsigned Offset = State.AllocateStack(8, 8);
61+  unsigned size      = (LocVT == MVT::f128) ? 16 : 8;
62+  unsigned alignment = (LocVT == MVT::f128) ? 16 : 8;
63+  unsigned Offset = State.AllocateStack(size, alignment);
64   unsigned Reg = 0;
65
66   if (LocVT == MVT::i64 && Offset < 6*8)
67@@ -96,6 +99,9 @@ static bool CC_Sparc64_Full(unsigned &ValNo, MVT &
68   else if (LocVT == MVT::f32 && Offset < 16*8)
69     // Promote floats to %f1, %f3, ...
70     Reg = SP::F1 + Offset/4;
71+  else if (LocVT == MVT::f128 && Offset < 16*8)
72+    // Promote long doubles to %q0-%q28. (Which LLVM calls Q0-Q7).
73+    Reg = SP::Q0 + Offset/16;
74
75   // Promote to register when possible, otherwise use the stack slot.
76   if (Reg) {
77@@ -998,9 +1004,10 @@ static void fixupVariableFloatArgs(SmallVectorImpl
78                                    ArrayRef<ISD::OutputArg> Outs) {
79   for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
80     const CCValAssign &VA = ArgLocs[i];
81+    MVT ValTy = VA.getLocVT();
82     // FIXME: What about f32 arguments? C promotes them to f64 when calling
83     // varargs functions.
84-    if (!VA.isRegLoc() || VA.getLocVT() != MVT::f64)
85+    if (!VA.isRegLoc() || (ValTy != MVT::f64 && ValTy != MVT::f128))
86       continue;
87     // The fixed arguments to a varargs function still go in FP registers.
88     if (Outs[VA.getValNo()].IsFixed)
89@@ -1010,15 +1017,25 @@ static void fixupVariableFloatArgs(SmallVectorImpl
90     CCValAssign NewVA;
91
92     // Determine the offset into the argument array.
93-    unsigned Offset = 8 * (VA.getLocReg() - SP::D0);
94+    unsigned firstReg = (ValTy == MVT::f64) ? SP::D0 : SP::Q0;
95+    unsigned argSize  = (ValTy == MVT::f64) ? 8 : 16;
96+    unsigned Offset = argSize * (VA.getLocReg() - firstReg);
97     assert(Offset < 16*8 && "Offset out of range, bad register enum?");
98
99     if (Offset < 6*8) {
100       // This argument should go in %i0-%i5.
101       unsigned IReg = SP::I0 + Offset/8;
102-      // Full register, just bitconvert into i64.
103-      NewVA = CCValAssign::getReg(VA.getValNo(), VA.getValVT(),
104-                                  IReg, MVT::i64, CCValAssign::BCvt);
105+      if (ValTy == MVT::f64)
106+        // Full register, just bitconvert into i64.
107+        NewVA = CCValAssign::getReg(VA.getValNo(), VA.getValVT(),
108+                                    IReg, MVT::i64, CCValAssign::BCvt);
109+      else {
110+        assert(ValTy == MVT::f128 && "Unexpected type!");
111+        // Full register, just bitconvert into i128 -- We will lower this into
112+        // two i64s in LowerCall_64.
113+        NewVA = CCValAssign::getCustomReg(VA.getValNo(), VA.getValVT(),
114+                                          IReg, MVT::i128, CCValAssign::BCvt);
115+      }
116     } else {
117       // This needs to go to memory, we're out of integer registers.
118       NewVA = CCValAssign::getMem(VA.getValNo(), VA.getValVT(),
119@@ -1094,11 +1111,46 @@ SparcTargetLowering::LowerCall_64(TargetLowering::
120       Arg = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Arg);
121       break;
122     case CCValAssign::BCvt:
123-      Arg = DAG.getNode(ISD::BITCAST, DL, VA.getLocVT(), Arg);
124+      // fixupVariableFloatArgs() may create bitcasts from f128 to i128. But
125+      // SPARC does not support i128 natively. Lower it into two i64, see below.
126+      if (!VA.needsCustom() || VA.getValVT() != MVT::f128
127+          || VA.getLocVT() != MVT::i128)
128+        Arg = DAG.getNode(ISD::BITCAST, DL, VA.getLocVT(), Arg);
129       break;
130     }
131
132     if (VA.isRegLoc()) {
133+      if (VA.needsCustom() && VA.getValVT() == MVT::f128
134+          && VA.getLocVT() == MVT::i128) {
135+        // Store and reload into the interger register reg and reg+1.
136+        unsigned Offset = 8 * (VA.getLocReg() - SP::I0);
137+        unsigned StackOffset = Offset + Subtarget->getStackPointerBias() + 128;
138+        SDValue StackPtr = DAG.getRegister(SP::O6, getPointerTy());
139+        SDValue HiPtrOff = DAG.getIntPtrConstant(StackOffset);
140+        HiPtrOff         = DAG.getNode(ISD::ADD, DL, getPointerTy(), StackPtr,
141+                                       HiPtrOff);
142+        SDValue LoPtrOff = DAG.getIntPtrConstant(StackOffset + 8);
143+        LoPtrOff         = DAG.getNode(ISD::ADD, DL, getPointerTy(), StackPtr,
144+                                       LoPtrOff);
145+
146+        // Store to %sp+BIAS+128+Offset
147+        SDValue Store = DAG.getStore(Chain, DL, Arg, HiPtrOff,
148+                                     MachinePointerInfo(),
149+                                     false, false, 0);
150+        // Load into Reg and Reg+1
151+        SDValue Hi64 = DAG.getLoad(MVT::i64, DL, Store, HiPtrOff,
152+                                   MachinePointerInfo(),
153+                                   false, false, false, 0);
154+        SDValue Lo64 = DAG.getLoad(MVT::i64, DL, Store, LoPtrOff,
155+                                   MachinePointerInfo(),
156+                                   false, false, false, 0);
157+        RegsToPass.push_back(std::make_pair(toCallerWindow(VA.getLocReg()),
158+                                            Hi64));
159+        RegsToPass.push_back(std::make_pair(toCallerWindow(VA.getLocReg()+1),
160+                                            Lo64));
161+        continue;
162+      }
163+
164       // The custom bit on an i32 return value indicates that it should be
165       // passed in the high bits of the register.
166       if (VA.getValVT() == MVT::i32 && VA.needsCustom()) {
167