summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/patches/patch-r262261-llvm-r198145-sparc.diff
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/patches/patch-r262261-llvm-r198145-sparc.diff')
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198145-sparc.diff166
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()) {
OpenPOWER on IntegriCloud