forked from OSchip/llvm-project
ARM: support high registers in __builtin_longjmp on WoA
Windows on ARM uses a pure thumb-2 environment. This means that it can select a high register when doing a __builtin_longjmp. We would use a tLDRi which would truncate the register to a low register. Use a t2LDRi12 to get the full register file access. Tweak the code to just load into PC, as that is an interworking branch on all supported cores anyways. llvm-svn: 274815
This commit is contained in:
parent
c61723f73e
commit
eb059b0e0a
|
@ -1882,8 +1882,7 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
|||
.addReg(0));
|
||||
return;
|
||||
}
|
||||
case ARM::tInt_eh_sjlj_longjmp:
|
||||
case ARM::tInt_WIN_eh_sjlj_longjmp: {
|
||||
case ARM::tInt_eh_sjlj_longjmp: {
|
||||
// ldr $scratch, [$src, #8]
|
||||
// mov sp, $scratch
|
||||
// ldr $scratch, [$src, #4]
|
||||
|
@ -1918,7 +1917,7 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
|||
.addReg(0));
|
||||
|
||||
EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tLDRi)
|
||||
.addReg(Opc == ARM::tInt_WIN_eh_sjlj_longjmp ? ARM::R11 : ARM::R7)
|
||||
.addReg(ARM::R7)
|
||||
.addReg(SrcReg)
|
||||
.addImm(0)
|
||||
// Predicate.
|
||||
|
@ -1932,6 +1931,36 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
|||
.addReg(0));
|
||||
return;
|
||||
}
|
||||
case ARM::tInt_WIN_eh_sjlj_longjmp: {
|
||||
// ldr.w r11, [$src, #0]
|
||||
// ldr.w sp, [$src, #8]
|
||||
// ldr.w pc, [$src, #4]
|
||||
|
||||
unsigned SrcReg = MI->getOperand(0).getReg();
|
||||
|
||||
EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::t2LDRi12)
|
||||
.addReg(ARM::R11)
|
||||
.addReg(SrcReg)
|
||||
.addImm(0)
|
||||
// Predicate
|
||||
.addImm(ARMCC::AL)
|
||||
.addReg(0));
|
||||
EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::t2LDRi12)
|
||||
.addReg(ARM::SP)
|
||||
.addReg(SrcReg)
|
||||
.addImm(8)
|
||||
// Predicate
|
||||
.addImm(ARMCC::AL)
|
||||
.addReg(0));
|
||||
EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::t2LDRi12)
|
||||
.addReg(ARM::PC)
|
||||
.addReg(SrcReg)
|
||||
.addImm(4)
|
||||
// Predicate
|
||||
.addImm(ARMCC::AL)
|
||||
.addReg(0));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
MCInst TmpInst;
|
||||
|
|
|
@ -648,8 +648,9 @@ unsigned ARMBaseInstrInfo::GetInstSizeInBytes(const MachineInstr &MI) const {
|
|||
case ARM::Int_eh_sjlj_longjmp:
|
||||
return 16;
|
||||
case ARM::tInt_eh_sjlj_longjmp:
|
||||
case ARM::tInt_WIN_eh_sjlj_longjmp:
|
||||
return 10;
|
||||
case ARM::tInt_WIN_eh_sjlj_longjmp:
|
||||
return 12;
|
||||
case ARM::Int_eh_sjlj_setjmp:
|
||||
case ARM::Int_eh_sjlj_setjmp_nofp:
|
||||
return 20;
|
||||
|
|
|
@ -9,9 +9,7 @@ entry:
|
|||
}
|
||||
|
||||
; CHECK: push.w {r11, lr}
|
||||
; CHECK: ldr r[[SP:[0-9]+]], [r0, #8]
|
||||
; CHECK: mov sp, r[[SP]]
|
||||
; CHECK: ldr r[[PC:[0-9]+]], [r0, #4]
|
||||
; CHECK: ldr r11, [r0]
|
||||
; CHECK: bx r[[PC]]
|
||||
; CHECK: ldr.w r11, [r0]
|
||||
; CHECK: ldr.w sp, [r0, #8]
|
||||
; CHECK: ldr.w pc, [r0, #4]
|
||||
|
||||
|
|
Loading…
Reference in New Issue