summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorAmara Emerson <aemerson@apple.com>2020-01-14 13:39:23 -0800
committerAmara Emerson <aemerson@apple.com>2020-01-14 13:41:21 -0800
commit6078f2fedcac5797ac39ee5ef3fd7a35ef1202d5 (patch)
tree7fdb4cdf3e7caca831e39e855f468d750d2376c1 /llvm/lib/Target
parent1ca51c06729d7f7326fcc2a826e07d1c92158dfd (diff)
downloadbcm5719-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.cpp39
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;
}
OpenPOWER on IntegriCloud