diff options
author | Jim Grosbach <grosbach@apple.com> | 2009-12-01 18:10:36 +0000 |
---|---|---|
committer | Jim Grosbach <grosbach@apple.com> | 2009-12-01 18:10:36 +0000 |
commit | 36d4dec28ae66f8663ef39a5a474c3ed5c766dac (patch) | |
tree | d97fe6d6cf6387c84ed15c21b3bf6e6719758a0d /llvm/lib/Target | |
parent | d3a241a9c66e630814cb098c2d08e2d372c9faf3 (diff) | |
download | bcm5719-llvm-36d4dec28ae66f8663ef39a5a474c3ed5c766dac.tar.gz bcm5719-llvm-36d4dec28ae66f8663ef39a5a474c3ed5c766dac.zip |
Thumb1 exception handling setjmp
llvm-svn: 90246
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMInstrFormats.td | 11 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMInstrThumb.td | 29 |
3 files changed, 42 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp index c95d4c8f3f4..6e476a6e62b 100644 --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -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: diff --git a/llvm/lib/Target/ARM/ARMInstrFormats.td b/llvm/lib/Target/ARM/ARMInstrFormats.td index e76e93cf671..66babd6737a 100644 --- a/llvm/lib/Target/ARM/ARMInstrFormats.td +++ b/llvm/lib/Target/ARM/ARMInstrFormats.td @@ -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>; diff --git a/llvm/lib/Target/ARM/ARMInstrThumb.td b/llvm/lib/Target/ARM/ARMInstrThumb.td index b5956a32c58..9306bdb4b70 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb.td @@ -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 // |