a426b286c8
patch for r263619, and unify all the URLs to point to svnweb.
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://svnweb.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
|
|
}
|