// 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?");
}
if (STI.is32Bit()) {
RestoreMBB = MF.CreateMachineBasicBlock(MBB.getBasicBlock());
MF.insert(TargetMBB, RestoreMBB);
- MBB.transferSuccessors(RestoreMBB);
+ MBB.removeSuccessor(TargetMBB);
MBB.addSuccessor(RestoreMBB);
- MBBI->getOperand(0).setMBB(RestoreMBB);
+ RestoreMBB->addSuccessor(TargetMBB);
+ }
+
+ // Fill EAX/RAX with the address of the target block.
+ unsigned ReturnReg = STI.is64Bit() ? X86::RAX : X86::EAX;
+ if (STI.is64Bit()) {
+ // LEA64r RestoreMBB(%rip), %rax
+ BuildMI(MBB, MBBI, DL, TII.get(X86::LEA64r), ReturnReg)
+ .addReg(X86::RIP)
+ .addImm(0)
+ .addReg(0)
+ .addMBB(RestoreMBB)
+ .addReg(0);
+ } else {
+ // MOV32ri $RestoreMBB, %eax
+ BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri))
+ .addReg(ReturnReg)
+ .addMBB(RestoreMBB);
}
// Pop EBP.
BuildMI(*RestoreMBB, RestoreMBBI, DL, TII.get(X86::JMP_4))
.addMBB(TargetMBB);
}
- } else if (isFuncletReturnInstr(MBBI)) {
+ // Replace CATCHRET with the appropriate RET.
+ unsigned RetOp = STI.is64Bit() ? X86::RETQ : X86::RETL;
+ MachineBasicBlock::iterator NewExit =
+ BuildMI(MBB, MBBI, DL, TII.get(RetOp)).addReg(ReturnReg);
+ MBBI->eraseFromParent();
+ MBBI = NewExit;
+ } else if (MBBI->getOpcode() == X86::CLEANUPRET) {
NumBytes = MFI->getMaxCallFrameSize();
assert(hasFP(MF) && "EH funclets without FP not yet implemented");
BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r),
MachineFramePtr)
.setMIFlag(MachineInstr::FrameDestroy);
+ // Replace CLEANUPRET with the appropriate RET.
+ unsigned RetOp = STI.is64Bit() ? X86::RETQ : X86::RETL;
+ MachineBasicBlock::iterator NewExit =
+ BuildMI(MBB, MBBI, DL, TII.get(RetOp));
+ MBBI->eraseFromParent();
+ MBBI = NewExit;
} else if (hasFP(MF)) {
// Calculate required stack adjustment.
uint64_t FrameSize = StackSize - SlotSize;
; X86: movl $1, -{{[0-9]+}}(%ebp)
; X86: movl $2, (%esp)
; X86: calll _f
-; X86: addl $16, %esp
+; X86: movl $[[restorebb]], %eax
+; X86-NEXT: addl $16, %esp
; X86-NEXT: popl %ebp
-; X86-NEXT: movl $[[restorebb]], %eax
; X86-NEXT: retl
; X86: L__ehtable$try_catch_catch:
; X64: subq $32, %rsp
; X64: movl $2, %ecx
; X64: callq f
+; X64: leaq [[contbb]](%rip), %rax
; X64: addq $32, %rsp
; X64: popq %rbp
-; X64: leaq [[contbb]](%rip), %rax
; X64: retq
; X64: $handlerMap$0$try_catch_catch:
; X86: [[contbb:LBB0_[0-9]+]]: # %try.cont
; X86: retl
-; X86: [[restorebb:LBB0_[0-9]+]]: # %invoke.cont.3
+; FIXME: These should be de-duplicated.
+; X86: [[restorebb1:LBB0_[0-9]+]]: # %invoke.cont.2
+; X86: movl -16(%ebp), %esp
+; X86: addl $12, %ebp
+; X86: jmp [[contbb]]
+
+; X86: [[restorebb2:LBB0_[0-9]+]]: # %invoke.cont.3
; X86: movl -16(%ebp), %esp
; X86: addl $12, %ebp
; X86: jmp [[contbb]]
; X86-DAG: movl %[[addr_reg]], 4(%esp)
; X86-DAG: movl %[[e_reg]], (%esp)
; X86: calll _f
+; X86-NEXT: movl $[[restorebb1]], %eax
; X86-NEXT: addl $8, %esp
; X86-NEXT: popl %ebp
-; X86-NEXT: movl $[[restorebb]], %eax
; X86-NEXT: retl
; X86: "?catch$[[catch2bb:[0-9]+]]@?0?try_catch_catch@4HA":
; X86-DAG: movl %[[addr_reg]], 4(%esp)
; X86-DAG: movl $3, (%esp)
; X86: calll _f
+; X86-NEXT: movl $[[restorebb2]], %eax
; X86-NEXT: addl $8, %esp
; X86-NEXT: popl %ebp
-; X86-NEXT: movl $[[restorebb]], %eax
; X86-NEXT: retl
; X86: L__ehtable$try_catch_catch:
; X64-DAG: leaq -[[local_offs]](%rbp), %rdx
; X64-DAG: movl [[e_addr:[-0-9]+]](%rbp), %ecx
; X64: callq f
-; X64: addq $32, %rsp
+; X64: leaq [[contbb]](%rip), %rax
+; X64-NEXT: addq $32, %rsp
; X64-NEXT: popq %rbp
-; X64-NEXT: leaq [[contbb]](%rip), %rax
; X64-NEXT: retq
; X64: "?catch$[[catch2bb:[0-9]+]]@?0?try_catch_catch@4HA":
; X64-DAG: movl $3, %ecx
; X64: callq f
; X64: .Ltmp3
-; X64: addq $32, %rsp
+; X64: leaq [[contbb]](%rip), %rax
+; X64-NEXT: addq $32, %rsp
; X64-NEXT: popq %rbp
-; X64-NEXT: leaq [[contbb]](%rip), %rax
; X64-NEXT: retq
; X64: $cppxdata$try_catch_catch:
; Prologue is done, emit the .seh_endprologue directive.
; CHECK: .seh_endprologue
-; Make sure there is a nop after a call if the call precedes the epilogue.
+; Make sure there is at least one instruction after a call before the epilogue.
; CHECK: callq g
-; CHECK-NEXT: nop
+; CHECK-NEXT: leaq .LBB0_{{[0-9]+}}(%rip), %rax
; Emit a reference to the LSDA.
; CHECK: .seh_handlerdata