diff options
author | Amara Emerson <aemerson@apple.com> | 2020-01-14 13:39:23 -0800 |
---|---|---|
committer | Amara Emerson <aemerson@apple.com> | 2020-01-14 13:41:21 -0800 |
commit | 6078f2fedcac5797ac39ee5ef3fd7a35ef1202d5 (patch) | |
tree | 7fdb4cdf3e7caca831e39e855f468d750d2376c1 /llvm/lib/Target | |
parent | 1ca51c06729d7f7326fcc2a826e07d1c92158dfd (diff) | |
download | bcm5719-llvm-6078f2fedcac5797ac39ee5ef3fd7a35ef1202d5.tar.gz bcm5719-llvm-6078f2fedcac5797ac39ee5ef3fd7a35ef1202d5.zip |
[AArch64][GlobalISel]: Support @llvm.{return,frame}address selection.
These intrinsics expand to a variable number of instructions so just like in
ISelLowering.cpp we use custom code to deal with them.
Committing Tim's original patch.
Differential Revision: https://reviews.llvm.org/D65656
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp index b9ac2657e1c..9f9cc7d7c9e 100644 --- a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp @@ -4091,7 +4091,7 @@ bool AArch64InstructionSelector::selectIntrinsic( switch (IntrinID) { default: break; - case Intrinsic::aarch64_crypto_sha1h: + case Intrinsic::aarch64_crypto_sha1h: { Register DstReg = I.getOperand(0).getReg(); Register SrcReg = I.getOperand(2).getReg(); @@ -4130,6 +4130,43 @@ bool AArch64InstructionSelector::selectIntrinsic( I.eraseFromParent(); return true; } + case Intrinsic::frameaddress: + case Intrinsic::returnaddress: { + MachineFunction &MF = *I.getParent()->getParent(); + MachineFrameInfo &MFI = MF.getFrameInfo(); + + unsigned Depth = I.getOperand(2).getImm(); + Register DstReg = I.getOperand(0).getReg(); + RBI.constrainGenericRegister(DstReg, AArch64::GPR64RegClass, MRI); + + if (Depth == 0 && IntrinID == Intrinsic::returnaddress) { + MFI.setReturnAddressIsTaken(true); + MF.addLiveIn(AArch64::LR, &AArch64::GPR64RegClass); + I.getParent()->addLiveIn(AArch64::LR); + MIRBuilder.buildCopy({DstReg}, {Register(AArch64::LR)}); + I.eraseFromParent(); + return true; + } + + MFI.setFrameAddressIsTaken(true); + Register FrameAddr(AArch64::FP); + while (Depth--) { + Register NextFrame = MRI.createVirtualRegister(&AArch64::GPR64RegClass); + MIRBuilder.buildInstr(AArch64::LDRXui, {NextFrame}, {FrameAddr}).addImm(0); + FrameAddr = NextFrame; + } + + if (IntrinID == Intrinsic::frameaddress) + MIRBuilder.buildCopy({DstReg}, {FrameAddr}); + else { + MFI.setReturnAddressIsTaken(true); + MIRBuilder.buildInstr(AArch64::LDRXui, {DstReg}, {FrameAddr}).addImm(1); + } + + I.eraseFromParent(); + return true; + } + } return false; } |