diff options
Diffstat (limited to 'contrib/llvm/patches/patch-r262261-llvm-r198145-sparc.diff')
-rw-r--r-- | contrib/llvm/patches/patch-r262261-llvm-r198145-sparc.diff | 166 |
1 files changed, 0 insertions, 166 deletions
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198145-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198145-sparc.diff deleted file mode 100644 index 1ff7ada..0000000 --- a/contrib/llvm/patches/patch-r262261-llvm-r198145-sparc.diff +++ /dev/null @@ -1,166 +0,0 @@ -Pull in r198145 from upstream llvm trunk (by Venkatraman Govindaraju): - - [SparcV9]: Implement lowering of long double (fp128) arguments in Sparc64 ABI. - Also, pass fp128 arguments to varargs through integer registers if necessary. - -Introduced here: http://svnweb.freebsd.org/changeset/base/262261 - -Index: test/CodeGen/SPARC/64abi.ll -=================================================================== ---- test/CodeGen/SPARC/64abi.ll -+++ test/CodeGen/SPARC/64abi.ll -@@ -411,3 +411,33 @@ entry: - } - - declare i32 @use_buf(i32, i8*) -+ -+; CHECK-LABEL: test_fp128_args -+; CHECK-DAG: std %f0, [%fp+{{.+}}] -+; CHECK-DAG: std %f2, [%fp+{{.+}}] -+; CHECK-DAG: std %f6, [%fp+{{.+}}] -+; CHECK-DAG: std %f4, [%fp+{{.+}}] -+; CHECK: add %fp, [[Offset:[0-9]+]], %o0 -+; CHECK: call _Qp_add -+; CHECK: ldd [%fp+[[Offset]]], %f0 -+define fp128 @test_fp128_args(fp128 %a, fp128 %b) { -+entry: -+ %0 = fadd fp128 %a, %b -+ ret fp128 %0 -+} -+ -+declare i64 @receive_fp128(i64 %a, ...) -+ -+; CHECK-LABEL: test_fp128_variable_args -+; CHECK-DAG: std %f4, [%sp+[[Offset0:[0-9]+]]] -+; CHECK-DAG: std %f6, [%sp+[[Offset1:[0-9]+]]] -+; CHECK-DAG: ldx [%sp+[[Offset0]]], %o2 -+; CHECK-DAG: ldx [%sp+[[Offset1]]], %o3 -+; CHECK: call receive_fp128 -+define i64 @test_fp128_variable_args(i64 %a, fp128 %b) { -+entry: -+ %0 = call i64 (i64, ...)* @receive_fp128(i64 %a, fp128 %b) -+ ret i64 %0 -+} -+ -+ -Index: lib/Target/Sparc/SparcISelLowering.cpp -=================================================================== ---- lib/Target/Sparc/SparcISelLowering.cpp -+++ lib/Target/Sparc/SparcISelLowering.cpp -@@ -80,11 +80,14 @@ static bool CC_Sparc_Assign_f64(unsigned &ValNo, M - static bool CC_Sparc64_Full(unsigned &ValNo, MVT &ValVT, - MVT &LocVT, CCValAssign::LocInfo &LocInfo, - ISD::ArgFlagsTy &ArgFlags, CCState &State) { -- assert((LocVT == MVT::f32 || LocVT.getSizeInBits() == 64) && -+ assert((LocVT == MVT::f32 || LocVT == MVT::f128 -+ || LocVT.getSizeInBits() == 64) && - "Can't handle non-64 bits locations"); - - // Stack space is allocated for all arguments starting from [%fp+BIAS+128]. -- unsigned Offset = State.AllocateStack(8, 8); -+ unsigned size = (LocVT == MVT::f128) ? 16 : 8; -+ unsigned alignment = (LocVT == MVT::f128) ? 16 : 8; -+ unsigned Offset = State.AllocateStack(size, alignment); - unsigned Reg = 0; - - if (LocVT == MVT::i64 && Offset < 6*8) -@@ -96,6 +99,9 @@ static bool CC_Sparc64_Full(unsigned &ValNo, MVT & - else if (LocVT == MVT::f32 && Offset < 16*8) - // Promote floats to %f1, %f3, ... - Reg = SP::F1 + Offset/4; -+ else if (LocVT == MVT::f128 && Offset < 16*8) -+ // Promote long doubles to %q0-%q28. (Which LLVM calls Q0-Q7). -+ Reg = SP::Q0 + Offset/16; - - // Promote to register when possible, otherwise use the stack slot. - if (Reg) { -@@ -998,9 +1004,10 @@ static void fixupVariableFloatArgs(SmallVectorImpl - ArrayRef<ISD::OutputArg> Outs) { - for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { - const CCValAssign &VA = ArgLocs[i]; -+ MVT ValTy = VA.getLocVT(); - // FIXME: What about f32 arguments? C promotes them to f64 when calling - // varargs functions. -- if (!VA.isRegLoc() || VA.getLocVT() != MVT::f64) -+ if (!VA.isRegLoc() || (ValTy != MVT::f64 && ValTy != MVT::f128)) - continue; - // The fixed arguments to a varargs function still go in FP registers. - if (Outs[VA.getValNo()].IsFixed) -@@ -1010,15 +1017,25 @@ static void fixupVariableFloatArgs(SmallVectorImpl - CCValAssign NewVA; - - // Determine the offset into the argument array. -- unsigned Offset = 8 * (VA.getLocReg() - SP::D0); -+ unsigned firstReg = (ValTy == MVT::f64) ? SP::D0 : SP::Q0; -+ unsigned argSize = (ValTy == MVT::f64) ? 8 : 16; -+ unsigned Offset = argSize * (VA.getLocReg() - firstReg); - assert(Offset < 16*8 && "Offset out of range, bad register enum?"); - - if (Offset < 6*8) { - // This argument should go in %i0-%i5. - unsigned IReg = SP::I0 + Offset/8; -- // Full register, just bitconvert into i64. -- NewVA = CCValAssign::getReg(VA.getValNo(), VA.getValVT(), -- IReg, MVT::i64, CCValAssign::BCvt); -+ if (ValTy == MVT::f64) -+ // Full register, just bitconvert into i64. -+ NewVA = CCValAssign::getReg(VA.getValNo(), VA.getValVT(), -+ IReg, MVT::i64, CCValAssign::BCvt); -+ else { -+ assert(ValTy == MVT::f128 && "Unexpected type!"); -+ // Full register, just bitconvert into i128 -- We will lower this into -+ // two i64s in LowerCall_64. -+ NewVA = CCValAssign::getCustomReg(VA.getValNo(), VA.getValVT(), -+ IReg, MVT::i128, CCValAssign::BCvt); -+ } - } else { - // This needs to go to memory, we're out of integer registers. - NewVA = CCValAssign::getMem(VA.getValNo(), VA.getValVT(), -@@ -1094,11 +1111,46 @@ SparcTargetLowering::LowerCall_64(TargetLowering:: - Arg = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Arg); - break; - case CCValAssign::BCvt: -- Arg = DAG.getNode(ISD::BITCAST, DL, VA.getLocVT(), Arg); -+ // fixupVariableFloatArgs() may create bitcasts from f128 to i128. But -+ // SPARC does not support i128 natively. Lower it into two i64, see below. -+ if (!VA.needsCustom() || VA.getValVT() != MVT::f128 -+ || VA.getLocVT() != MVT::i128) -+ Arg = DAG.getNode(ISD::BITCAST, DL, VA.getLocVT(), Arg); - break; - } - - if (VA.isRegLoc()) { -+ if (VA.needsCustom() && VA.getValVT() == MVT::f128 -+ && VA.getLocVT() == MVT::i128) { -+ // Store and reload into the interger register reg and reg+1. -+ unsigned Offset = 8 * (VA.getLocReg() - SP::I0); -+ unsigned StackOffset = Offset + Subtarget->getStackPointerBias() + 128; -+ SDValue StackPtr = DAG.getRegister(SP::O6, getPointerTy()); -+ SDValue HiPtrOff = DAG.getIntPtrConstant(StackOffset); -+ HiPtrOff = DAG.getNode(ISD::ADD, DL, getPointerTy(), StackPtr, -+ HiPtrOff); -+ SDValue LoPtrOff = DAG.getIntPtrConstant(StackOffset + 8); -+ LoPtrOff = DAG.getNode(ISD::ADD, DL, getPointerTy(), StackPtr, -+ LoPtrOff); -+ -+ // Store to %sp+BIAS+128+Offset -+ SDValue Store = DAG.getStore(Chain, DL, Arg, HiPtrOff, -+ MachinePointerInfo(), -+ false, false, 0); -+ // Load into Reg and Reg+1 -+ SDValue Hi64 = DAG.getLoad(MVT::i64, DL, Store, HiPtrOff, -+ MachinePointerInfo(), -+ false, false, false, 0); -+ SDValue Lo64 = DAG.getLoad(MVT::i64, DL, Store, LoPtrOff, -+ MachinePointerInfo(), -+ false, false, false, 0); -+ RegsToPass.push_back(std::make_pair(toCallerWindow(VA.getLocReg()), -+ Hi64)); -+ RegsToPass.push_back(std::make_pair(toCallerWindow(VA.getLocReg()+1), -+ Lo64)); -+ continue; -+ } -+ - // The custom bit on an i32 return value indicates that it should be - // passed in the high bits of the register. - if (VA.getValVT() == MVT::i32 && VA.needsCustom()) { |