Skip to content

Commit 0ba8b24

Browse files
authored
[Xtensa] Lowering FRAMEADDR/RETURNADDR operations. (#107363)
1 parent c13bf6d commit 0ba8b24

File tree

3 files changed

+89
-0
lines changed

3 files changed

+89
-0
lines changed

llvm/lib/Target/Xtensa/XtensaISelLowering.cpp

+47
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,27 @@ SDValue XtensaTargetLowering::LowerSELECT_CC(SDValue Op,
594594
FalseValue, TargetCC);
595595
}
596596

597+
SDValue XtensaTargetLowering::LowerRETURNADDR(SDValue Op,
598+
SelectionDAG &DAG) const {
599+
// This nodes represent llvm.returnaddress on the DAG.
600+
// It takes one operand, the index of the return address to return.
601+
// An index of zero corresponds to the current function's return address.
602+
// An index of one to the parent's return address, and so on.
603+
// Depths > 0 not supported yet!
604+
if (Op.getConstantOperandVal(0) != 0)
605+
return SDValue();
606+
607+
MachineFunction &MF = DAG.getMachineFunction();
608+
MachineFrameInfo &MFI = MF.getFrameInfo();
609+
EVT VT = Op.getValueType();
610+
MFI.setReturnAddressIsTaken(true);
611+
612+
// Return RA, which contains the return address. Mark it an implicit
613+
// live-in.
614+
Register RA = MF.addLiveIn(Xtensa::A0, getRegClassFor(MVT::i32));
615+
return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), RA, VT);
616+
}
617+
597618
SDValue XtensaTargetLowering::LowerImmediate(SDValue Op,
598619
SelectionDAG &DAG) const {
599620
const ConstantSDNode *CN = cast<ConstantSDNode>(Op);
@@ -722,6 +743,28 @@ SDValue XtensaTargetLowering::LowerSTACKRESTORE(SDValue Op,
722743
Op.getOperand(1));
723744
}
724745

746+
SDValue XtensaTargetLowering::LowerFRAMEADDR(SDValue Op,
747+
SelectionDAG &DAG) const {
748+
// This nodes represent llvm.frameaddress on the DAG.
749+
// It takes one operand, the index of the frame address to return.
750+
// An index of zero corresponds to the current function's frame address.
751+
// An index of one to the parent's frame address, and so on.
752+
// Depths > 0 not supported yet!
753+
if (Op.getConstantOperandVal(0) != 0)
754+
return SDValue();
755+
756+
MachineFunction &MF = DAG.getMachineFunction();
757+
MachineFrameInfo &MFI = MF.getFrameInfo();
758+
MFI.setFrameAddressIsTaken(true);
759+
EVT VT = Op.getValueType();
760+
SDLoc DL(Op);
761+
762+
Register FrameRegister = Subtarget.getRegisterInfo()->getFrameRegister(MF);
763+
SDValue FrameAddr =
764+
DAG.getCopyFromReg(DAG.getEntryNode(), DL, FrameRegister, VT);
765+
return FrameAddr;
766+
}
767+
725768
SDValue XtensaTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
726769
SelectionDAG &DAG) const {
727770
SDValue Chain = Op.getOperand(0); // Legalize the chain.
@@ -867,6 +910,8 @@ SDValue XtensaTargetLowering::LowerOperation(SDValue Op,
867910
return LowerBR_JT(Op, DAG);
868911
case ISD::Constant:
869912
return LowerImmediate(Op, DAG);
913+
case ISD::RETURNADDR:
914+
return LowerRETURNADDR(Op, DAG);
870915
case ISD::GlobalAddress:
871916
return LowerGlobalAddress(Op, DAG);
872917
case ISD::BlockAddress:
@@ -883,6 +928,8 @@ SDValue XtensaTargetLowering::LowerOperation(SDValue Op,
883928
return LowerSTACKSAVE(Op, DAG);
884929
case ISD::STACKRESTORE:
885930
return LowerSTACKRESTORE(Op, DAG);
931+
case ISD::FRAMEADDR:
932+
return LowerFRAMEADDR(Op, DAG);
886933
case ISD::DYNAMIC_STACKALLOC:
887934
return LowerDYNAMIC_STACKALLOC(Op, DAG);
888935
case ISD::SHL_PARTS:

llvm/lib/Target/Xtensa/XtensaISelLowering.h

+4
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;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2+
; RUN: llc -mtriple=xtensa < %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+
%frameaddr = call ptr @llvm.frameaddress(i32 0)
13+
ret ptr %frameaddr
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+
%retaddr = call ptr @llvm.returnaddress(i32 0)
21+
ret ptr %retaddr
22+
}
23+
24+
define ptr @test_frameaddress_1() nounwind {
25+
; CHECK-LABEL: test_frameaddress_1:
26+
; CHECK: movi a2, 0
27+
; CHECK-NEXT: ret
28+
%frameaddr = call ptr @llvm.frameaddress(i32 1)
29+
ret ptr %frameaddr
30+
}
31+
32+
define ptr @test_returnaddress_1() nounwind {
33+
; CHECK-LABEL: test_returnaddress_1:
34+
; CHECK: movi a2, 0
35+
; CHECK-NEXT: ret
36+
%retaddr = call ptr @llvm.returnaddress(i32 1)
37+
ret ptr %retaddr
38+
}

0 commit comments

Comments
 (0)