mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-26 20:57:15 +00:00
Implement eh.sjlj.longjmp for ARM. Clean up the intrinsic a bit.
Followups: docs patch for the builtin and eh.sjlj.setjmp cleanup to match longjmp. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@104419 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1e6d3ac709
commit
5eb1951539
@ -95,6 +95,13 @@ namespace ISD {
|
||||
// execution to HANDLER. Many platform-related details also :)
|
||||
EH_RETURN,
|
||||
|
||||
|
||||
// OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer)
|
||||
// This corresponds to the eh.sjlj.longjmp intrinsic.
|
||||
// It takes an input chain and a pointer to the jump buffer as inputs
|
||||
// and returns an outchain.
|
||||
EH_SJLJ_LONGJMP,
|
||||
|
||||
// TargetConstant* - Like Constant*, but the DAG does not do any folding,
|
||||
// simplification, or lowering of the constant. They are used for constants
|
||||
// which are known to fit in the immediate fields of their users, or for
|
||||
|
@ -306,11 +306,13 @@ def int_eh_unwind_init: Intrinsic<[]>,
|
||||
def int_eh_dwarf_cfa : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty]>;
|
||||
|
||||
let Properties = [IntrNoMem] in {
|
||||
def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>;
|
||||
def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty]>;
|
||||
def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>,
|
||||
GCCBuiltin<"__builtin_setjmp">;
|
||||
def int_eh_sjlj_lsda : Intrinsic<[llvm_ptr_ty]>;
|
||||
def int_eh_sjlj_callsite: Intrinsic<[], [llvm_i32_ty]>;
|
||||
}
|
||||
def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty], [IntrWriteArgMem]>,
|
||||
GCCBuiltin<"__builtin_longjmp">;
|
||||
|
||||
//===---------------- Generic Variable Attribute Intrinsics----------------===//
|
||||
//
|
||||
|
@ -4038,6 +4038,11 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
|
||||
MMI.setCurrentCallSite(CI->getZExtValue());
|
||||
return 0;
|
||||
}
|
||||
case Intrinsic::eh_sjlj_longjmp: {
|
||||
DAG.setRoot(DAG.getNode(ISD::EH_SJLJ_LONGJMP, dl, MVT::Other, getRoot(),
|
||||
getValue(I.getOperand(1))));
|
||||
return 0;
|
||||
}
|
||||
|
||||
case Intrinsic::convertff:
|
||||
case Intrinsic::convertfsi:
|
||||
|
@ -481,6 +481,10 @@ unsigned ARMBaseInstrInfo::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_eh_sjlj_longjmp:
|
||||
return 16;
|
||||
case ARM::tInt_eh_sjlj_longjmp:
|
||||
return 10;
|
||||
case ARM::Int_eh_sjlj_setjmp:
|
||||
case ARM::Int_eh_sjlj_setjmp_nofp:
|
||||
return 24;
|
||||
|
@ -412,6 +412,7 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
|
||||
|
||||
// We want to custom lower some of our intrinsics.
|
||||
setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
|
||||
setOperationAction(ISD::EH_SJLJ_LONGJMP, MVT::Other, Custom);
|
||||
|
||||
setOperationAction(ISD::SETCC, MVT::i32, Expand);
|
||||
setOperationAction(ISD::SETCC, MVT::f32, Expand);
|
||||
@ -1547,6 +1548,13 @@ SDValue ARMTargetLowering::LowerGLOBAL_OFFSET_TABLE(SDValue Op,
|
||||
return DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel);
|
||||
}
|
||||
|
||||
SDValue
|
||||
ARMTargetLowering::LowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const {
|
||||
DebugLoc dl = Op.getDebugLoc();
|
||||
return DAG.getNode(ARMISD::EH_SJLJ_LONGJMP, dl, MVT::Other, Op.getOperand(0),
|
||||
Op.getOperand(1), DAG.getConstant(0, MVT::i32));
|
||||
}
|
||||
|
||||
SDValue
|
||||
ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG,
|
||||
const ARMSubtarget *Subtarget)
|
||||
@ -3153,6 +3161,7 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
|
||||
case ISD::RETURNADDR: break;
|
||||
case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
|
||||
case ISD::GLOBAL_OFFSET_TABLE: return LowerGLOBAL_OFFSET_TABLE(Op, DAG);
|
||||
case ISD::EH_SJLJ_LONGJMP: return LowerEH_SJLJ_LONGJMP(Op, DAG);
|
||||
case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG,
|
||||
Subtarget);
|
||||
case ISD::BIT_CONVERT: return ExpandBIT_CONVERT(Op.getNode(), DAG);
|
||||
|
@ -287,7 +287,7 @@ namespace llvm {
|
||||
DebugLoc dl, SelectionDAG &DAG,
|
||||
const CCValAssign &VA,
|
||||
ISD::ArgFlagsTy Flags) const;
|
||||
SDValue LowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG,
|
||||
const ARMSubtarget *Subtarget) const;
|
||||
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
|
||||
|
@ -46,6 +46,7 @@ def SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
|
||||
def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
|
||||
def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisPtrTy<1>,
|
||||
SDTCisInt<2>]>;
|
||||
def SDT_ARMEH_SJLJ_Longjmp: SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisInt<1>]>;
|
||||
|
||||
def SDT_ARMMEMBARRIERV7 : SDTypeProfile<0, 0, []>;
|
||||
def SDT_ARMSYNCBARRIERV7 : SDTypeProfile<0, 0, []>;
|
||||
@ -101,6 +102,8 @@ def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInFlag ]>;
|
||||
|
||||
def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
|
||||
def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", SDT_ARMEH_SJLJ_Setjmp>;
|
||||
def ARMeh_sjlj_longjmp: SDNode<"ARMISD::EH_SJLJ_LONGJMP",
|
||||
SDT_ARMEH_SJLJ_Longjmp, [SDNPHasChain]>;
|
||||
|
||||
def ARMMemBarrierV7 : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIERV7,
|
||||
[SDNPHasChain]>;
|
||||
@ -2555,6 +2558,20 @@ let Defs =
|
||||
Requires<[IsARM, NoVFP]>;
|
||||
}
|
||||
|
||||
// FIXME: Non-Darwin version(s)
|
||||
let isBarrier = 1, hasSideEffects = 1, isTerminator = 1,
|
||||
Defs = [ R7, LR, SP ] in {
|
||||
def Int_eh_sjlj_longjmp : XI<(outs), (ins GPR:$src, GPR:$scratch),
|
||||
AddrModeNone, SizeSpecial, IndexModeNone,
|
||||
Pseudo, NoItinerary,
|
||||
"ldr\tsp, [$src, #8]\n\t"
|
||||
"ldr\t$scratch, [$src, #4]\n\t"
|
||||
"ldr\tr7, [$src]\n\t"
|
||||
"bx\t$scratch", "",
|
||||
[(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
|
||||
Requires<[IsARM, IsDarwin]>;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Non-Instruction Patterns
|
||||
//
|
||||
|
@ -938,6 +938,22 @@ let Defs =
|
||||
"1:", "",
|
||||
[(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>;
|
||||
}
|
||||
|
||||
// FIXME: Non-Darwin version(s)
|
||||
let isBarrier = 1, hasSideEffects = 1, isTerminator = 1,
|
||||
Defs = [ R7, LR, SP ] in {
|
||||
def tInt_eh_sjlj_longjmp : XI<(outs), (ins GPR:$src, GPR:$scratch),
|
||||
AddrModeNone, SizeSpecial, IndexModeNone,
|
||||
Pseudo, NoItinerary,
|
||||
"ldr\t$scratch, [$src, #8]\n\t"
|
||||
"mov\tsp, $scratch\n\t"
|
||||
"ldr\t$scratch, [$src, #4]\n\t"
|
||||
"ldr\tr7, [$src]\n\t"
|
||||
"bx\t$scratch", "",
|
||||
[(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
|
||||
Requires<[IsThumb, IsDarwin]>;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Non-Instruction Patterns
|
||||
//
|
||||
|
Loading…
x
Reference in New Issue
Block a user