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