mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
Update the names of the exception handling sjlj instrinsics to
llvm.eh.sjlj.* for better clarity as to their purpose and scope. Add a description of llvm.eh.sjlj.setjmp to ExceptionHandling.html. (llvm.eh.sjlj.longjmp documentation coming when that implementation is added). llvm-svn: 71758
This commit is contained in:
parent
3ae08059b5
commit
bed3aeff20
@ -31,6 +31,8 @@
|
||||
<li><a href="#llvm_eh_exception"><tt>llvm.eh.exception</tt></a></li>
|
||||
<li><a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a></li>
|
||||
<li><a href="#llvm_eh_typeid_for"><tt>llvm.eh.typeid.for</tt></a></li>
|
||||
<li><a href="#llvm_eh_sjlj_setjmp"><tt>llvm.eh.sjlj.setjmp</tt></a></li>
|
||||
<li><a href="#llvm_eh_sjlj_longjmp"><tt>llvm.eh.sjlj.longjmp</tt></a></li>
|
||||
</ol></li>
|
||||
<li><a href="#asm">Asm Table Formats</a>
|
||||
<ol>
|
||||
@ -400,6 +402,30 @@ a reference to a type info.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsubsection">
|
||||
<a name="llvm_eh_sjlj_setjmp">llvm.eh.sjlj.setjmp</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
<pre>
|
||||
i32 %<a href="#llvm_eh_sjlj_setjmp">llvm.eh.sjlj.setjmp</a>(i8*)
|
||||
</pre>
|
||||
|
||||
<p>The SJLJ exception handling uses this intrinsic to force register saving
|
||||
for the current function and to store the address of the following instruction
|
||||
for use as a destination address by <a href="#llvm_eh_sjlj_setjmp">
|
||||
<tt>llvm.eh.sjlj.longjmp</tt></a>. The buffer format and the overall functioning
|
||||
of this intrinsic is compatible with the GCC <tt>__builtin_setjmp</tt> implementation,
|
||||
allowing code built with the two compilers to interoperate.</p>
|
||||
|
||||
<p>The single parameter is a pointer to a five word buffer in which the
|
||||
calling context is saved. The front end places the frame pointer in the
|
||||
first word, and the target implementation of this intrinsic should place the
|
||||
destination address for a <a href="#llvm_eh_sjlj_longjmp"><tt>
|
||||
llvm.eh.sjlj.longjmp</tt></a> in the second word. The following three words are available for use in a
|
||||
target-specific manner.</p>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_section">
|
||||
<a name="asm">Asm Table Formats</a>
|
||||
|
@ -300,8 +300,8 @@ def int_eh_unwind_init: Intrinsic<[llvm_void_ty]>,
|
||||
def int_eh_dwarf_cfa : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty]>;
|
||||
|
||||
let Properties = [IntrNoMem] in {
|
||||
def int_builtinsetjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>;
|
||||
def int_builtinlongjmp : Intrinsic<[llvm_void_ty], [llvm_ptr_ty, llvm_i32_ty]>;
|
||||
def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>;
|
||||
def int_eh_sjlj_longjmp : Intrinsic<[llvm_void_ty], [llvm_ptr_ty, llvm_i32_ty]>;
|
||||
}
|
||||
|
||||
//===---------------- Generic Variable Attribute Intrinsics----------------===//
|
||||
|
@ -1045,8 +1045,8 @@ ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) {
|
||||
default: return SDValue(); // Don't custom lower most intrinsics.
|
||||
case Intrinsic::arm_thread_pointer:
|
||||
return DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT);
|
||||
case Intrinsic::builtinsetjmp:
|
||||
SDValue Res = DAG.getNode(ARMISD::BUILTIN_SETJMP, dl, MVT::i32,
|
||||
case Intrinsic::eh_sjlj_setjmp:
|
||||
SDValue Res = DAG.getNode(ARMISD::EH_SJLJ_SETJMP, dl, MVT::i32,
|
||||
Op.getOperand(1));
|
||||
return Res;
|
||||
}
|
||||
|
@ -64,8 +64,8 @@ namespace llvm {
|
||||
FMRRD, // double to two gprs.
|
||||
FMDRR, // Two gprs to double.
|
||||
|
||||
BUILTIN_SETJMP, // exception handling setjmp
|
||||
BUILTIN_LONGJMP, // exception handling longjmp
|
||||
EH_SJLJ_SETJMP, // SjLj exception handling setjmp
|
||||
EH_SJLJ_LONGJMP, // SjLj exception handling longjmp
|
||||
|
||||
THREAD_POINTER
|
||||
};
|
||||
|
@ -991,7 +991,7 @@ unsigned ARMInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
|
||||
// If this machine instr is a constant pool entry, its size is recorded as
|
||||
// operand #2.
|
||||
return MI->getOperand(2).getImm();
|
||||
case ARM::Int_builtin_setjmp: return 12;
|
||||
case ARM::Int_eh_sjlj_setjmp: return 12;
|
||||
case ARM::BR_JTr:
|
||||
case ARM::BR_JTm:
|
||||
case ARM::BR_JTadd:
|
||||
|
@ -40,7 +40,7 @@ def SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
|
||||
SDTCisPtrTy<1>, SDTCisVT<2, i32>]>;
|
||||
|
||||
def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
|
||||
def SDT_ARMBuiltinSetjmp : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
|
||||
def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
|
||||
|
||||
// Node definitions.
|
||||
def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>;
|
||||
@ -85,7 +85,7 @@ def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
|
||||
def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInFlag ]>;
|
||||
|
||||
def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
|
||||
def ARMbuiltin_setjmp: SDNode<"ARMISD::BUILTIN_SETJMP", SDT_ARMBuiltinSetjmp>;
|
||||
def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", SDT_ARMEH_SJLJ_Setjmp>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ARM Instruction Predicate Definitions.
|
||||
@ -1269,23 +1269,25 @@ let isCall = 1,
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// SJLJ Exception handling intrinsics
|
||||
// setjmp() is a three instruction sequence to store the return address
|
||||
// and save #0 in R0 for the non-longjmp case.
|
||||
// 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 setjmp(), else it will almost certainly have been tromped upon
|
||||
// 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.
|
||||
// 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 ] in {
|
||||
def Int_builtin_setjmp : XI<(outs), (ins GPR:$src),
|
||||
def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src),
|
||||
AddrModeNone, SizeSpecial, IndexModeNone, Pseudo,
|
||||
"add r0, pc, #4\n\t"
|
||||
"str r0, [$src, #+4]\n\t"
|
||||
"mov r0, #0 @ setjmp", "",
|
||||
[(set R0, (ARMbuiltin_setjmp GPR:$src))]>;
|
||||
"mov r0, #0 @ eh_setjmp", "",
|
||||
[(set R0, (ARMeh_sjlj_setjmp GPR:$src))]>;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
Loading…
Reference in New Issue
Block a user