diff options
author | Andrei Safronov <andrei.safronov@espressif.com> | 2024-09-13 21:33:54 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-13 21:33:54 +0300 |
commit | 0ba8b247dd63042528850af8cc572dc73225a04c (patch) | |
tree | 8e78a3ce43e9ef831b26f0564eca120be9bc111b | |
parent | c13bf6d4a89b8d62bc6eedf68d810a4584ccc4a8 (diff) | |
download | llvm-0ba8b247dd63042528850af8cc572dc73225a04c.zip llvm-0ba8b247dd63042528850af8cc572dc73225a04c.tar.gz llvm-0ba8b247dd63042528850af8cc572dc73225a04c.tar.bz2 |
[Xtensa] Lowering FRAMEADDR/RETURNADDR operations. (#107363)
-rw-r--r-- | llvm/lib/Target/Xtensa/XtensaISelLowering.cpp | 47 | ||||
-rw-r--r-- | llvm/lib/Target/Xtensa/XtensaISelLowering.h | 4 | ||||
-rw-r--r-- | llvm/test/CodeGen/Xtensa/frameaddr-returnaddr.ll | 38 |
3 files changed, 89 insertions, 0 deletions
diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp index 0d2ce26..bc1360e 100644 --- a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp +++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp @@ -594,6 +594,27 @@ SDValue XtensaTargetLowering::LowerSELECT_CC(SDValue Op, FalseValue, TargetCC); } +SDValue XtensaTargetLowering::LowerRETURNADDR(SDValue Op, + SelectionDAG &DAG) const { + // This nodes represent llvm.returnaddress on the DAG. + // It takes one operand, the index of the return address to return. + // An index of zero corresponds to the current function's return address. + // An index of one to the parent's return address, and so on. + // Depths > 0 not supported yet! + if (Op.getConstantOperandVal(0) != 0) + return SDValue(); + + MachineFunction &MF = DAG.getMachineFunction(); + MachineFrameInfo &MFI = MF.getFrameInfo(); + EVT VT = Op.getValueType(); + MFI.setReturnAddressIsTaken(true); + + // Return RA, which contains the return address. Mark it an implicit + // live-in. + Register RA = MF.addLiveIn(Xtensa::A0, getRegClassFor(MVT::i32)); + return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), RA, VT); +} + SDValue XtensaTargetLowering::LowerImmediate(SDValue Op, SelectionDAG &DAG) const { const ConstantSDNode *CN = cast<ConstantSDNode>(Op); @@ -722,6 +743,28 @@ SDValue XtensaTargetLowering::LowerSTACKRESTORE(SDValue Op, Op.getOperand(1)); } +SDValue XtensaTargetLowering::LowerFRAMEADDR(SDValue Op, + SelectionDAG &DAG) const { + // This nodes represent llvm.frameaddress on the DAG. + // It takes one operand, the index of the frame address to return. + // An index of zero corresponds to the current function's frame address. + // An index of one to the parent's frame address, and so on. + // Depths > 0 not supported yet! + if (Op.getConstantOperandVal(0) != 0) + return SDValue(); + + MachineFunction &MF = DAG.getMachineFunction(); + MachineFrameInfo &MFI = MF.getFrameInfo(); + MFI.setFrameAddressIsTaken(true); + EVT VT = Op.getValueType(); + SDLoc DL(Op); + + Register FrameRegister = Subtarget.getRegisterInfo()->getFrameRegister(MF); + SDValue FrameAddr = + DAG.getCopyFromReg(DAG.getEntryNode(), DL, FrameRegister, VT); + return FrameAddr; +} + SDValue XtensaTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const { SDValue Chain = Op.getOperand(0); // Legalize the chain. @@ -867,6 +910,8 @@ SDValue XtensaTargetLowering::LowerOperation(SDValue Op, return LowerBR_JT(Op, DAG); case ISD::Constant: return LowerImmediate(Op, DAG); + case ISD::RETURNADDR: + return LowerRETURNADDR(Op, DAG); case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); case ISD::BlockAddress: @@ -883,6 +928,8 @@ SDValue XtensaTargetLowering::LowerOperation(SDValue Op, return LowerSTACKSAVE(Op, DAG); case ISD::STACKRESTORE: return LowerSTACKRESTORE(Op, DAG); + case ISD::FRAMEADDR: + return LowerFRAMEADDR(Op, DAG); case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG); case ISD::SHL_PARTS: diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.h b/llvm/lib/Target/Xtensa/XtensaISelLowering.h index 8e7346b..2a878e4 100644 --- a/llvm/lib/Target/Xtensa/XtensaISelLowering.h +++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.h @@ -125,12 +125,16 @@ private: SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const; SDValue LowerSTACKSAVE(SDValue Op, SelectionDAG &DAG) const; SDValue LowerSTACKRESTORE(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const; SDValue LowerShiftRightParts(SDValue Op, SelectionDAG &DAG, bool IsSRA) const; diff --git a/llvm/test/CodeGen/Xtensa/frameaddr-returnaddr.ll b/llvm/test/CodeGen/Xtensa/frameaddr-returnaddr.ll new file mode 100644 index 0000000..e7e5094 --- /dev/null +++ b/llvm/test/CodeGen/Xtensa/frameaddr-returnaddr.ll @@ -0,0 +1,38 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc -mtriple=xtensa < %s \ +; RUN: | FileCheck %s + +declare ptr @llvm.frameaddress(i32) +declare ptr @llvm.returnaddress(i32) + +define ptr @test_frameaddress_0() nounwind { +; CHECK-LABEL: test_frameaddress_0: +; CHECK: or a2, a1, a1 +; CHECK-NEXT: ret + %frameaddr = call ptr @llvm.frameaddress(i32 0) + ret ptr %frameaddr +} + +define ptr @test_returnaddress_0() nounwind { +; CHECK-LABEL: test_returnaddress_0: +; CHECK: or a2, a0, a0 +; CHECK-NEXT: ret + %retaddr = call ptr @llvm.returnaddress(i32 0) + ret ptr %retaddr +} + +define ptr @test_frameaddress_1() nounwind { +; CHECK-LABEL: test_frameaddress_1: +; CHECK: movi a2, 0 +; CHECK-NEXT: ret + %frameaddr = call ptr @llvm.frameaddress(i32 1) + ret ptr %frameaddr +} + +define ptr @test_returnaddress_1() nounwind { +; CHECK-LABEL: test_returnaddress_1: +; CHECK: movi a2, 0 +; CHECK-NEXT: ret + %retaddr = call ptr @llvm.returnaddress(i32 1) + ret ptr %retaddr +} |