Add memory barrier intrinsic support for ARM. Moving towards adding the atomic operations intrinsics.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@91003 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jim Grosbach 2009-12-10 00:11:09 +00:00
parent b6760b4a1e
commit 3728e96a6c
3 changed files with 49 additions and 1 deletions

View File

@ -377,7 +377,7 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Custom); setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Custom);
else else
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand); setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand);
setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand); setOperationAction(ISD::MEMBARRIER, MVT::Other, Custom);
if (!Subtarget->hasV6Ops() && !Subtarget->isThumb2()) { if (!Subtarget->hasV6Ops() && !Subtarget->isThumb2()) {
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand); setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand);
@ -500,6 +500,9 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
case ARMISD::DYN_ALLOC: return "ARMISD::DYN_ALLOC"; case ARMISD::DYN_ALLOC: return "ARMISD::DYN_ALLOC";
case ARMISD::MEMBARRIER: return "ARMISD::MEMBARRIER";
case ARMISD::SYNCBARRIER: return "ARMISD::SYNCBARRIER";
case ARMISD::VCEQ: return "ARMISD::VCEQ"; case ARMISD::VCEQ: return "ARMISD::VCEQ";
case ARMISD::VCGE: return "ARMISD::VCGE"; case ARMISD::VCGE: return "ARMISD::VCGE";
case ARMISD::VCGEU: return "ARMISD::VCGEU"; case ARMISD::VCGEU: return "ARMISD::VCGEU";
@ -1470,6 +1473,21 @@ ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) {
} }
} }
static SDValue LowerMEMBARRIER(SDValue Op, SelectionDAG &DAG) {
DebugLoc dl = Op.getDebugLoc();
SDValue Op5 = Op.getOperand(5);
SDValue Res;
unsigned isDeviceBarrier = cast<ConstantSDNode>(Op5)->getZExtValue();
if (isDeviceBarrier) {
Res = DAG.getNode(ARMISD::SYNCBARRIER, dl, MVT::Other,
Op.getOperand(0));
} else {
Res = DAG.getNode(ARMISD::MEMBARRIER, dl, MVT::Other,
Op.getOperand(0));
}
return Res;
}
static SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG, static SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG,
unsigned VarArgsFrameIndex) { unsigned VarArgsFrameIndex) {
// vastart just stores the address of the VarArgsFrameIndex slot into the // vastart just stores the address of the VarArgsFrameIndex slot into the
@ -2972,6 +2990,7 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
case ISD::BR_JT: return LowerBR_JT(Op, DAG); case ISD::BR_JT: return LowerBR_JT(Op, DAG);
case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG); case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG);
case ISD::VASTART: return LowerVASTART(Op, DAG, VarArgsFrameIndex); case ISD::VASTART: return LowerVASTART(Op, DAG, VarArgsFrameIndex);
case ISD::MEMBARRIER: return LowerMEMBARRIER(Op, DAG);
case ISD::SINT_TO_FP: case ISD::SINT_TO_FP:
case ISD::UINT_TO_FP: return LowerINT_TO_FP(Op, DAG); case ISD::UINT_TO_FP: return LowerINT_TO_FP(Op, DAG);
case ISD::FP_TO_SINT: case ISD::FP_TO_SINT:

View File

@ -72,6 +72,9 @@ namespace llvm {
DYN_ALLOC, // Dynamic allocation on the stack. DYN_ALLOC, // Dynamic allocation on the stack.
MEMBARRIER, // Memory barrier
SYNCBARRIER, // Memory sync barrier
VCEQ, // Vector compare equal. VCEQ, // Vector compare equal.
VCGE, // Vector compare greater than or equal. VCGE, // Vector compare greater than or equal.
VCGEU, // Vector compare unsigned greater than or equal. VCGEU, // Vector compare unsigned greater than or equal.

View File

@ -46,6 +46,9 @@ def SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>; def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisPtrTy<1>]>; def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
def SDT_ARMMEMBARRIER : SDTypeProfile<0, 0, []>;
def SDT_ARMSYNCBARRIER : SDTypeProfile<0, 0, []>;
// Node definitions. // Node definitions.
def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>; def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>;
def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>; def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>;
@ -93,6 +96,11 @@ def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInFlag ]>;
def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>; 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_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", SDT_ARMEH_SJLJ_Setjmp>;
def ARMMemBarrier : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIER,
[SDNPHasChain]>;
def ARMSyncBarrier : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIER,
[SDNPHasChain]>;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// ARM Instruction Predicate Definitions. // ARM Instruction Predicate Definitions.
// //
@ -1561,6 +1569,24 @@ def MOVCCi : AI1<0b1101, (outs GPR:$dst),
let Inst{25} = 1; let Inst{25} = 1;
} }
//===----------------------------------------------------------------------===//
// Atomic operations intrinsics
//
// memory barriers protect the atomic sequences
let isBarrier = 1 in {
def Int_MemBarrierV7 : AI<(outs), (ins),
Pseudo, NoItinerary,
"dmb", "",
[(ARMMemBarrier)]>,
Requires<[HasV7]>;
def Int_SyncBarrierV7 : AI<(outs), (ins),
Pseudo, NoItinerary,
"dsb", "",
[(ARMSyncBarrier)]>,
Requires<[HasV7]>;
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// TLS Instructions // TLS Instructions