summaryrefslogtreecommitdiff
path: root/lib/Target/X86/X86ExpandPseudo.cpp
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2015-09-17 20:43:47 +0000
committerReid Kleckner <rnk@google.com>2015-09-17 20:43:47 +0000
commitf946dd04123e27edfcd15dcf0d9de68dcb79be42 (patch)
tree923635a8cfe33b7567c4fc336c8871f366d9d3b5 /lib/Target/X86/X86ExpandPseudo.cpp
parent9ac4d865671263781325ceeebb5716e4d4b60aea (diff)
downloadllvm-f946dd04123e27edfcd15dcf0d9de68dcb79be42.tar.gz
[WinEH] Make funclet return instrs pseudo instrs
This makes catchret look more like a branch, and less like a weird use of BlockAddress. It also lets us get away from llvm.x86.seh.restoreframe, which relies on the old parentfpoffset label arithmetic. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@247936 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/X86/X86ExpandPseudo.cpp')
-rw-r--r--lib/Target/X86/X86ExpandPseudo.cpp35
1 files changed, 35 insertions, 0 deletions
diff --git a/lib/Target/X86/X86ExpandPseudo.cpp b/lib/Target/X86/X86ExpandPseudo.cpp
index 6a5a28e546f2..c9441bd0c2f1 100644
--- a/lib/Target/X86/X86ExpandPseudo.cpp
+++ b/lib/Target/X86/X86ExpandPseudo.cpp
@@ -141,6 +141,41 @@ bool X86ExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
// The EH_RETURN pseudo is really removed during the MC Lowering.
return true;
}
+
+ case X86::CLEANUPRET: {
+ // Replace CATCHRET with the appropriate RET.
+ unsigned RetOp = STI->is64Bit() ? X86::RETQ : X86::RETL;
+ BuildMI(MBB, MBBI, DL, TII->get(RetOp));
+ MBBI->eraseFromParent();
+ return true;
+ }
+
+ case X86::CATCHRET: {
+ MachineBasicBlock *TargetMBB = MBBI->getOperand(0).getMBB();
+
+ // Fill EAX/RAX with the address of the target block.
+ unsigned ReturnReg = STI->is64Bit() ? X86::RAX : X86::EAX;
+ unsigned RetOp = STI->is64Bit() ? X86::RETQ : X86::RETL;
+ if (STI->is64Bit()) {
+ // LEA64r TargetMBB(%rip), %rax
+ BuildMI(MBB, MBBI, DL, TII->get(X86::LEA64r), ReturnReg)
+ .addReg(X86::RIP)
+ .addImm(0)
+ .addReg(0)
+ .addMBB(TargetMBB)
+ .addReg(0);
+ } else {
+ // MOV32ri $TargetMBB, %eax
+ BuildMI(MBB, MBBI, DL, TII->get(X86::MOV32ri))
+ .addReg(ReturnReg)
+ .addMBB(TargetMBB);
+ }
+
+ // Replace CATCHRET with the appropriate RET.
+ BuildMI(MBB, MBBI, DL, TII->get(RetOp)).addReg(ReturnReg);
+ MBBI->eraseFromParent();
+ return true;
+ }
}
llvm_unreachable("Previous switch has a fallthrough?");
}