#include "X86InstrInfo.h"
#include "X86MachineFunctionInfo.h"
#include "X86Subtarget.h"
-#include "llvm/CodeGen/Passes.h" // For IDs of passes that are preserved.
+#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/Passes.h" // For IDs of passes that are preserved.
#include "llvm/IR/GlobalValue.h"
using namespace llvm;
// 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();
+ case X86::IRET: {
+ // Adjust stack to erase error code
+ int64_t StackAdj = MBBI->getOperand(0).getImm();
+ X86FL->emitSPUpdate(MBB, MBBI, StackAdj, true);
+ // Replace pseudo with machine iret
+ BuildMI(MBB, MBBI, DL,
+ TII->get(STI->is64Bit() ? X86::IRET64 : X86::IRET32));
+ MBB.erase(MBBI);
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);
+ case X86::EH_RESTORE: {
+ // Restore ESP and EBP, and optionally ESI if required.
+ bool IsSEH = isAsynchronousEHPersonality(classifyEHPersonality(
+ MBB.getParent()->getFunction()->getPersonalityFn()));
+ X86FL->restoreWin32EHStackPointers(MBB, MBBI, DL, /*RestoreSP=*/IsSEH);
MBBI->eraseFromParent();
return true;
}