mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-22 12:08:26 +00:00
Thumb1 exception handling setjmp
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@90246 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b731e87649
commit
d122874996
@ -467,6 +467,8 @@ unsigned ARMBaseInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
|
||||
return MI->getOperand(2).getImm();
|
||||
case ARM::Int_eh_sjlj_setjmp:
|
||||
return 24;
|
||||
case ARM::tInt_eh_sjlj_setjmp:
|
||||
return 22;
|
||||
case ARM::t2Int_eh_sjlj_setjmp:
|
||||
return 22;
|
||||
case ARM::BR_JTr:
|
||||
|
@ -967,6 +967,17 @@ class Thumb2XI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
|
||||
list<Predicate> Predicates = [IsThumb2];
|
||||
}
|
||||
|
||||
class ThumbXI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
|
||||
InstrItinClass itin,
|
||||
string asm, string cstr, list<dag> pattern>
|
||||
: InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
|
||||
let OutOperandList = oops;
|
||||
let InOperandList = iops;
|
||||
let AsmString = asm;
|
||||
let Pattern = pattern;
|
||||
list<Predicate> Predicates = [IsThumb1Only];
|
||||
}
|
||||
|
||||
class T2I<dag oops, dag iops, InstrItinClass itin,
|
||||
string opc, string asm, list<dag> pattern>
|
||||
: Thumb2I<oops, iops, AddrModeNone, Size4Bytes, itin, opc, asm, "", pattern>;
|
||||
|
@ -669,6 +669,35 @@ let isCall = 1,
|
||||
[(set R0, ARMthread_pointer)]>;
|
||||
}
|
||||
|
||||
// SJLJ Exception handling intrinsics
|
||||
// eh_sjlj_setjmp() is an instruction sequence to store the return
|
||||
// address and save #0 in R0 for the non-longjmp case.
|
||||
// Since by its nature we may be coming from some other function to get
|
||||
// here, and we're using the stack frame for the containing function to
|
||||
// save/restore registers, we can't keep anything live in regs across
|
||||
// the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
|
||||
// when we get here from a longjmp(). We force everthing out of registers
|
||||
// except for our own input by listing the relevant registers in Defs. By
|
||||
// doing so, we also cause the prologue/epilogue code to actively preserve
|
||||
// all of the callee-saved resgisters, which is exactly what we want.
|
||||
let Defs =
|
||||
[ R0, R1, R2, R3, R4, R5, R6, R7, R12 ] in {
|
||||
def tInt_eh_sjlj_setjmp : ThumbXI<(outs), (ins GPR:$src),
|
||||
AddrModeNone, SizeSpecial, NoItinerary,
|
||||
"mov\tr12, r1\t@ begin eh.setjmp\n"
|
||||
"\tmov\tr1, sp\n"
|
||||
"\tstr\tr1, [$src, #8]\n"
|
||||
"\tadr\tr1, 0f\n"
|
||||
"\tadds\tr1, #1\n"
|
||||
"\tstr\tr1, [$src, #4]\n"
|
||||
"\tmov\tr1, r12\n"
|
||||
"\tmovs\tr0, #0\n"
|
||||
"\tb\t1f\n"
|
||||
".align 2\n"
|
||||
"0:\tmovs\tr0, #1\t@ end eh.setjmp\n"
|
||||
"1:", "",
|
||||
[(set R0, (ARMeh_sjlj_setjmp GPR:$src))]>;
|
||||
}
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Non-Instruction Patterns
|
||||
//
|
||||
|
Loading…
Reference in New Issue
Block a user