a1f8ad145e
applied to our copy of llvm/clang. These can be applied in alphabetical order to a pristine llvm/clang 3.4 release source tree, to result in the same version used in FreeBSD. This is intended to clearly document all the changes until now, which mostly consist of cherry pickings from the respective upstream trunks, plus a number of hand-written FreeBSD-specific ones. Hopefully those can eventually be cleaned up and sent upstream too. MFC after: 1 week X-MFC-With: r263313
214 lines
7.7 KiB
Diff
214 lines
7.7 KiB
Diff
Pull in r198480 from upstream llvm trunk (by Venkatraman Govindaraju):
|
|
|
|
[SparcV9]: Implement RETURNADDR and FRAMEADDR lowering in SPARC64.
|
|
|
|
Introduced here: http://svn.freebsd.org/changeset/base/262261
|
|
|
|
Index: lib/Target/Sparc/SparcISelLowering.cpp
|
|
===================================================================
|
|
--- lib/Target/Sparc/SparcISelLowering.cpp
|
|
+++ lib/Target/Sparc/SparcISelLowering.cpp
|
|
@@ -2415,7 +2415,8 @@ static SDValue getFLUSHW(SDValue Op, SelectionDAG
|
|
return Chain;
|
|
}
|
|
|
|
-static SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) {
|
|
+static SDValue getFRAMEADDR(uint64_t depth, SDValue Op, SelectionDAG &DAG,
|
|
+ const SparcSubtarget *Subtarget) {
|
|
MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
|
|
MFI->setFrameAddressIsTaken(true);
|
|
|
|
@@ -2422,32 +2423,49 @@ static SDValue getFLUSHW(SDValue Op, SelectionDAG
|
|
EVT VT = Op.getValueType();
|
|
SDLoc dl(Op);
|
|
unsigned FrameReg = SP::I6;
|
|
+ unsigned stackBias = Subtarget->getStackPointerBias();
|
|
|
|
- uint64_t depth = Op.getConstantOperandVal(0);
|
|
+ SDValue FrameAddr;
|
|
|
|
- SDValue FrameAddr;
|
|
- if (depth == 0)
|
|
+ if (depth == 0) {
|
|
FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);
|
|
- else {
|
|
- // flush first to make sure the windowed registers' values are in stack
|
|
- SDValue Chain = getFLUSHW(Op, DAG);
|
|
- FrameAddr = DAG.getCopyFromReg(Chain, dl, FrameReg, VT);
|
|
+ if (Subtarget->is64Bit())
|
|
+ FrameAddr = DAG.getNode(ISD::ADD, dl, VT, FrameAddr,
|
|
+ DAG.getIntPtrConstant(stackBias));
|
|
+ return FrameAddr;
|
|
+ }
|
|
|
|
- for (uint64_t i = 0; i != depth; ++i) {
|
|
- SDValue Ptr = DAG.getNode(ISD::ADD,
|
|
- dl, MVT::i32,
|
|
- FrameAddr, DAG.getIntPtrConstant(56));
|
|
- FrameAddr = DAG.getLoad(MVT::i32, dl,
|
|
- Chain,
|
|
- Ptr,
|
|
- MachinePointerInfo(), false, false, false, 0);
|
|
- }
|
|
+ // flush first to make sure the windowed registers' values are in stack
|
|
+ SDValue Chain = getFLUSHW(Op, DAG);
|
|
+ FrameAddr = DAG.getCopyFromReg(Chain, dl, FrameReg, VT);
|
|
+
|
|
+ unsigned Offset = (Subtarget->is64Bit()) ? (stackBias + 112) : 56;
|
|
+
|
|
+ while (depth--) {
|
|
+ SDValue Ptr = DAG.getNode(ISD::ADD, dl, VT, FrameAddr,
|
|
+ DAG.getIntPtrConstant(Offset));
|
|
+ FrameAddr = DAG.getLoad(VT, dl, Chain, Ptr, MachinePointerInfo(),
|
|
+ false, false, false, 0);
|
|
}
|
|
+ if (Subtarget->is64Bit())
|
|
+ FrameAddr = DAG.getNode(ISD::ADD, dl, VT, FrameAddr,
|
|
+ DAG.getIntPtrConstant(stackBias));
|
|
return FrameAddr;
|
|
}
|
|
|
|
+
|
|
+static SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG,
|
|
+ const SparcSubtarget *Subtarget) {
|
|
+
|
|
+ uint64_t depth = Op.getConstantOperandVal(0);
|
|
+
|
|
+ return getFRAMEADDR(depth, Op, DAG, Subtarget);
|
|
+
|
|
+}
|
|
+
|
|
static SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG,
|
|
- const SparcTargetLowering &TLI) {
|
|
+ const SparcTargetLowering &TLI,
|
|
+ const SparcSubtarget *Subtarget) {
|
|
MachineFunction &MF = DAG.getMachineFunction();
|
|
MachineFrameInfo *MFI = MF.getFrameInfo();
|
|
MFI->setReturnAddressIsTaken(true);
|
|
@@ -2461,25 +2479,20 @@ static SDValue LowerRETURNADDR(SDValue Op, Selecti
|
|
unsigned RetReg = MF.addLiveIn(SP::I7,
|
|
TLI.getRegClassFor(TLI.getPointerTy()));
|
|
RetAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, RetReg, VT);
|
|
- } else {
|
|
- // Need frame address to find return address of the caller.
|
|
- MFI->setFrameAddressIsTaken(true);
|
|
+ return RetAddr;
|
|
+ }
|
|
|
|
- // flush first to make sure the windowed registers' values are in stack
|
|
- SDValue Chain = getFLUSHW(Op, DAG);
|
|
- RetAddr = DAG.getCopyFromReg(Chain, dl, SP::I6, VT);
|
|
+ // Need frame address to find return address of the caller.
|
|
+ SDValue FrameAddr = getFRAMEADDR(depth - 1, Op, DAG, Subtarget);
|
|
|
|
- for (uint64_t i = 0; i != depth; ++i) {
|
|
- SDValue Ptr = DAG.getNode(ISD::ADD,
|
|
- dl, MVT::i32,
|
|
- RetAddr,
|
|
- DAG.getIntPtrConstant((i == depth-1)?60:56));
|
|
- RetAddr = DAG.getLoad(MVT::i32, dl,
|
|
- Chain,
|
|
- Ptr,
|
|
- MachinePointerInfo(), false, false, false, 0);
|
|
- }
|
|
- }
|
|
+ unsigned Offset = (Subtarget->is64Bit()) ? 120 : 60;
|
|
+ SDValue Ptr = DAG.getNode(ISD::ADD,
|
|
+ dl, VT,
|
|
+ FrameAddr,
|
|
+ DAG.getIntPtrConstant(Offset));
|
|
+ RetAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), Ptr,
|
|
+ MachinePointerInfo(), false, false, false, 0);
|
|
+
|
|
return RetAddr;
|
|
}
|
|
|
|
@@ -2763,8 +2776,10 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) cons
|
|
switch (Op.getOpcode()) {
|
|
default: llvm_unreachable("Should not custom lower this!");
|
|
|
|
- case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG, *this);
|
|
- case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
|
|
+ case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG, *this,
|
|
+ Subtarget);
|
|
+ case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG,
|
|
+ Subtarget);
|
|
case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG);
|
|
case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
|
|
case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
|
|
Index: test/CodeGen/SPARC/2011-01-11-FrameAddr.ll
|
|
===================================================================
|
|
--- test/CodeGen/SPARC/2011-01-11-FrameAddr.ll
|
|
+++ test/CodeGen/SPARC/2011-01-11-FrameAddr.ll
|
|
@@ -2,6 +2,7 @@
|
|
;RUN: llc -march=sparc -mattr=v9 < %s | FileCheck %s -check-prefix=V9
|
|
;RUN: llc -march=sparc -regalloc=basic < %s | FileCheck %s -check-prefix=V8
|
|
;RUN: llc -march=sparc -regalloc=basic -mattr=v9 < %s | FileCheck %s -check-prefix=V9
|
|
+;RUN: llc -march=sparcv9 < %s | FileCheck %s -check-prefix=SPARC64
|
|
|
|
|
|
define i8* @frameaddr() nounwind readnone {
|
|
@@ -15,6 +16,13 @@ entry:
|
|
;V9: save %sp, -96, %sp
|
|
;V9: jmp %i7+8
|
|
;V9: restore %g0, %fp, %o0
|
|
+
|
|
+;SPARC64-LABEL: frameaddr
|
|
+;SPARC64: save %sp, -128, %sp
|
|
+;SPARC64: add %fp, 2047, %i0
|
|
+;SPARC64: jmp %i7+8
|
|
+;SPARC64: restore %g0, %g0, %g0
|
|
+
|
|
%0 = tail call i8* @llvm.frameaddress(i32 0)
|
|
ret i8* %0
|
|
}
|
|
@@ -32,6 +40,14 @@ entry:
|
|
;V9: ld [%fp+56], {{.+}}
|
|
;V9: ld [{{.+}}+56], {{.+}}
|
|
;V9: ld [{{.+}}+56], {{.+}}
|
|
+
|
|
+;SPARC64-LABEL: frameaddr2
|
|
+;SPARC64: flushw
|
|
+;SPARC64: ldx [%fp+2159], %[[R0:[goli][0-7]]]
|
|
+;SPARC64: ldx [%[[R0]]+2159], %[[R1:[goli][0-7]]]
|
|
+;SPARC64: ldx [%[[R1]]+2159], %[[R2:[goli][0-7]]]
|
|
+;SPARC64: add %[[R2]], 2047, {{.+}}
|
|
+
|
|
%0 = tail call i8* @llvm.frameaddress(i32 3)
|
|
ret i8* %0
|
|
}
|
|
@@ -48,6 +64,9 @@ entry:
|
|
;V9-LABEL: retaddr:
|
|
;V9: or %g0, %o7, {{.+}}
|
|
|
|
+;SPARC64-LABEL: retaddr
|
|
+;SPARC64: or %g0, %o7, {{.+}}
|
|
+
|
|
%0 = tail call i8* @llvm.returnaddress(i32 0)
|
|
ret i8* %0
|
|
}
|
|
@@ -66,18 +85,12 @@ entry:
|
|
;V9: ld [{{.+}}+56], {{.+}}
|
|
;V9: ld [{{.+}}+60], {{.+}}
|
|
|
|
-;V8LEAF-LABEL: retaddr2:
|
|
-;V8LEAF: ta 3
|
|
-;V8LEAF: ld [%fp+56], %[[R:[goli][0-7]]]
|
|
-;V8LEAF: ld [%[[R]]+56], %[[R1:[goli][0-7]]]
|
|
-;V8LEAF: ld [%[[R1]]+60], {{.+}}
|
|
+;SPARC64-LABEL: retaddr2
|
|
+;SPARC64: flushw
|
|
+;SPARC64: ldx [%fp+2159], %[[R0:[goli][0-7]]]
|
|
+;SPARC64: ldx [%[[R0]]+2159], %[[R1:[goli][0-7]]]
|
|
+;SPARC64: ldx [%[[R1]]+2167], {{.+}}
|
|
|
|
-;V9LEAF-LABEL: retaddr2:
|
|
-;V9LEAF: flushw
|
|
-;V9LEAF: ld [%fp+56], %[[R:[goli][0-7]]]
|
|
-;V9LEAF: ld [%[[R]]+56], %[[R1:[goli][0-7]]]
|
|
-;V9LEAF: ld [%[[R1]]+60], {{.+}}
|
|
-
|
|
%0 = tail call i8* @llvm.returnaddress(i32 3)
|
|
ret i8* %0
|
|
}
|