diff options
author | Reid Kleckner <rnk@google.com> | 2015-09-17 20:43:47 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2015-09-17 20:43:47 +0000 |
commit | f946dd04123e27edfcd15dcf0d9de68dcb79be42 (patch) | |
tree | 923635a8cfe33b7567c4fc336c8871f366d9d3b5 /lib/Target/X86/X86ExpandPseudo.cpp | |
parent | 9ac4d865671263781325ceeebb5716e4d4b60aea (diff) | |
download | llvm-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.cpp | 35 |
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?"); } |