diff options
author | Jim Grosbach <grosbach@apple.com> | 2009-08-11 19:42:21 +0000 |
---|---|---|
committer | Jim Grosbach <grosbach@apple.com> | 2009-08-11 19:42:21 +0000 |
commit | 5aa1684e5da9a85286bf7d29da419d261a70c2f2 (patch) | |
tree | 49c7099cb5eb3699f11b08f835fbb595c1562b7f | |
parent | 3524bd755154f6b8283582a0636cab2080a39a01 (diff) | |
download | external_llvm-5aa1684e5da9a85286bf7d29da419d261a70c2f2.zip external_llvm-5aa1684e5da9a85286bf7d29da419d261a70c2f2.tar.gz external_llvm-5aa1684e5da9a85286bf7d29da419d261a70c2f2.tar.bz2 |
Add Thumb2 eh_sjlj_setjmp implementation
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78701 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/ARM/ARMBaseInstrInfo.cpp | 2 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrThumb2.td | 32 |
2 files changed, 34 insertions, 0 deletions
diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index f4aded9..b5bfe9d 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -441,6 +441,8 @@ unsigned ARMBaseInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const { return MI->getOperand(2).getImm(); case ARM::Int_eh_sjlj_setjmp: return 24; + case ARM::t2Int_eh_sjlj_setjmp: + return 20; case ARM::BR_JTr: case ARM::BR_JTm: case ARM::BR_JTadd: diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 7dd77df..31b8488 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -1064,6 +1064,38 @@ let isCall = 1, } //===----------------------------------------------------------------------===// +// SJLJ Exception handling intrinsics +// eh_sjlj_setjmp() is a three 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, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, + D0, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, + D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30, + D31 ] in { + def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins GPR:$src), + AddrModeNone, SizeSpecial, NoItinerary, + "str.w sp, [$src, #+8] @ eh_setjmp begin\n" + "\tadr ip, 0f\n" + "\torr ip, #1\n" + "\tstr.w ip, [$src, #+4]\n" + "\tmovs r0, #0\n" + "\tb 1f\n" + "0:\tmovs r0, #1 @ eh_setjmp end\n" + "1:\n", "", + [(set R0, (ARMeh_sjlj_setjmp GPR:$src))]>; +} + + + +//===----------------------------------------------------------------------===// // Control-Flow Instructions // |