}
static SDValue getFRAMEADDR(uint64_t depth, SDValue Op, SelectionDAG &DAG,
- const SparcSubtarget *Subtarget) {
+ const SparcSubtarget *Subtarget,
+ bool AlwaysFlush = false) {
MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
MFI.setFrameAddressIsTaken(true);
unsigned stackBias = Subtarget->getStackPointerBias();
SDValue FrameAddr;
-
- if (depth == 0) {
- FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);
- if (Subtarget->is64Bit())
- FrameAddr = DAG.getNode(ISD::ADD, dl, VT, FrameAddr,
- DAG.getIntPtrConstant(stackBias, dl));
- return FrameAddr;
- }
+ SDValue Chain;
// flush first to make sure the windowed registers' values are in stack
- SDValue Chain = getFLUSHW(Op, DAG);
+ Chain = (depth || AlwaysFlush) ? getFLUSHW(Op, DAG) : DAG.getEntryNode();
+
FrameAddr = DAG.getCopyFromReg(Chain, dl, FrameReg, VT);
unsigned Offset = (Subtarget->is64Bit()) ? (stackBias + 112) : 56;
}
// Need frame address to find return address of the caller.
- SDValue FrameAddr = getFRAMEADDR(depth - 1, Op, DAG, Subtarget);
+ SDValue FrameAddr = getFRAMEADDR(depth - 1, Op, DAG, Subtarget, true);
unsigned Offset = (Subtarget->is64Bit()) ? 120 : 60;
SDValue Ptr = DAG.getNode(ISD::ADD,
ret i8* %0
}
+define i8* @retaddr3() nounwind readnone {
+entry:
+;V8-LABEL: retaddr3:
+;V8: ta 3
+;V8: ld [%fp+60], {{.+}}
+
+;V9-LABEL: retaddr3:
+;V9: flushw
+;V9: ld [%fp+60], {{.+}}
+
+;SPARC64-LABEL: retaddr3
+;SPARC64: flushw
+;SPARC64: ldx [%fp+2167], %[[R0:[goli][0-7]]]
+
+ %0 = tail call i8* @llvm.returnaddress(i32 1)
+ ret i8* %0
+}
+
declare i8* @llvm.returnaddress(i32) nounwind readnone