Skip to content

Commit a210ae9

Browse files
committed
[Xtensa] Lowering FRAMEADDR/RETURNADDR operations.
1 parent f1ac334 commit a210ae9

File tree

3 files changed

+68
-0
lines changed

3 files changed

+68
-0
lines changed

llvm/lib/Target/Xtensa/XtensaISelLowering.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,26 @@ SDValue XtensaTargetLowering::LowerSELECT_CC(SDValue Op,
594594
FalseValue, TargetCC);
595595
}
596596

597+
SDValue XtensaTargetLowering::LowerRETURNADDR(SDValue Op,
598+
SelectionDAG &DAG) const {
599+
// check the depth
600+
// TODO: xtensa-gcc can handle this, by navigating through the stack, we
601+
// should be able to do this too
602+
assert((cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() == 0) &&
603+
"Return address can be determined only for current frame.");
604+
605+
MachineFunction &MF = DAG.getMachineFunction();
606+
MachineFrameInfo &MFI = MF.getFrameInfo();
607+
EVT VT = Op.getValueType();
608+
unsigned RA = Xtensa::A0;
609+
MFI.setReturnAddressIsTaken(true);
610+
611+
// Return RA, which contains the return address. Mark it an implicit
612+
// live-in.
613+
unsigned Register = MF.addLiveIn(RA, getRegClassFor(MVT::i32));
614+
return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), Register, VT);
615+
}
616+
597617
SDValue XtensaTargetLowering::LowerImmediate(SDValue Op,
598618
SelectionDAG &DAG) const {
599619
const ConstantSDNode *CN = cast<ConstantSDNode>(Op);
@@ -722,6 +742,24 @@ SDValue XtensaTargetLowering::LowerSTACKRESTORE(SDValue Op,
722742
Op.getOperand(1));
723743
}
724744

745+
SDValue XtensaTargetLowering::LowerFRAMEADDR(SDValue Op,
746+
SelectionDAG &DAG) const {
747+
// check the depth
748+
assert((cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() == 0) &&
749+
"Frame address can only be determined for current frame.");
750+
751+
MachineFunction &MF = DAG.getMachineFunction();
752+
MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
753+
MFI.setFrameAddressIsTaken(true);
754+
EVT VT = Op.getValueType();
755+
SDLoc DL(Op);
756+
757+
unsigned FrameRegister = Subtarget.getRegisterInfo()->getFrameRegister(MF);
758+
SDValue FrameAddr =
759+
DAG.getCopyFromReg(DAG.getEntryNode(), DL, FrameRegister, VT);
760+
return FrameAddr;
761+
}
762+
725763
SDValue XtensaTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
726764
SelectionDAG &DAG) const {
727765
SDValue Chain = Op.getOperand(0); // Legalize the chain.
@@ -867,6 +905,8 @@ SDValue XtensaTargetLowering::LowerOperation(SDValue Op,
867905
return LowerBR_JT(Op, DAG);
868906
case ISD::Constant:
869907
return LowerImmediate(Op, DAG);
908+
case ISD::RETURNADDR:
909+
return LowerRETURNADDR(Op, DAG);
870910
case ISD::GlobalAddress:
871911
return LowerGlobalAddress(Op, DAG);
872912
case ISD::BlockAddress:
@@ -883,6 +923,8 @@ SDValue XtensaTargetLowering::LowerOperation(SDValue Op,
883923
return LowerSTACKSAVE(Op, DAG);
884924
case ISD::STACKRESTORE:
885925
return LowerSTACKRESTORE(Op, DAG);
926+
case ISD::FRAMEADDR:
927+
return LowerFRAMEADDR(Op, DAG);
886928
case ISD::DYNAMIC_STACKALLOC:
887929
return LowerDYNAMIC_STACKALLOC(Op, DAG);
888930
case ISD::SHL_PARTS:

llvm/lib/Target/Xtensa/XtensaISelLowering.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,16 @@ class XtensaTargetLowering : public TargetLowering {
125125

126126
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
127127

128+
SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
129+
128130
SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
129131

130132
SDValue LowerSTACKSAVE(SDValue Op, SelectionDAG &DAG) const;
131133

132134
SDValue LowerSTACKRESTORE(SDValue Op, SelectionDAG &DAG) const;
133135

136+
SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
137+
134138
SDValue LowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const;
135139

136140
SDValue LowerShiftRightParts(SDValue Op, SelectionDAG &DAG, bool IsSRA) const;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2+
; RUN: llc -mtriple=xtensa -verify-machineinstrs < %s \
3+
; RUN: | FileCheck %s
4+
5+
declare ptr @llvm.frameaddress(i32)
6+
declare ptr @llvm.returnaddress(i32)
7+
8+
define ptr @test_frameaddress_0() nounwind {
9+
; CHECK-LABEL: test_frameaddress_0:
10+
; CHECK: or a2, a1, a1
11+
; CHECK-NEXT: ret
12+
%1 = call ptr @llvm.frameaddress(i32 0)
13+
ret ptr %1
14+
}
15+
16+
define ptr @test_returnaddress_0() nounwind {
17+
; CHECK-LABEL: test_returnaddress_0:
18+
; CHECK: or a2, a0, a0
19+
; CHECK-NEXT: ret
20+
%1 = call ptr @llvm.returnaddress(i32 0)
21+
ret ptr %1
22+
}

0 commit comments

Comments
 (0)