diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/ARM/ARMBaseInfo.h | 2 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMISelLowering.cpp | 32 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMISelLowering.h | 4 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMInstrInfo.td | 71 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMInstrThumb2.td | 83 |
5 files changed, 61 insertions, 131 deletions
diff --git a/llvm/lib/Target/ARM/ARMBaseInfo.h b/llvm/lib/Target/ARM/ARMBaseInfo.h index 2da7be25a13..63e8f9655db 100644 --- a/llvm/lib/Target/ARM/ARMBaseInfo.h +++ b/llvm/lib/Target/ARM/ARMBaseInfo.h @@ -101,6 +101,7 @@ namespace ARM_MB { // The Memory Barrier Option constants map directly to the 4-bit encoding of // the option field for memory barrier operations. enum MemBOpt { + SY = 15, ST = 14, ISH = 11, ISHST = 10, @@ -113,6 +114,7 @@ namespace ARM_MB { inline static const char *MemBOptToString(unsigned val) { switch (val) { default: llvm_unreachable("Unknown memory operation"); + case SY: return "sy"; case ST: return "st"; case ISH: return "ish"; case ISHST: return "ishst"; diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 810335b4c57..d086093597a 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -766,7 +766,7 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const { case ARMISD::DYN_ALLOC: return "ARMISD::DYN_ALLOC"; case ARMISD::MEMBARRIER: return "ARMISD::MEMBARRIER"; - case ARMISD::SYNCBARRIER: return "ARMISD::SYNCBARRIER"; + case ARMISD::MEMBARRIER_MCR: return "ARMISD::MEMBARRIER_MCR"; case ARMISD::VCEQ: return "ARMISD::VCEQ"; case ARMISD::VCGE: return "ARMISD::VCGE"; @@ -2026,21 +2026,29 @@ ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG, static SDValue LowerMEMBARRIER(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *Subtarget) { DebugLoc dl = Op.getDebugLoc(); - SDValue Op5 = Op.getOperand(5); - unsigned isDeviceBarrier = cast<ConstantSDNode>(Op5)->getZExtValue(); - // Some subtargets which have dmb and dsb instructions can handle barriers - // directly. Some ARMv6 cpus can support them with the help of mcr - // instruction. Thumb1 and pre-v6 ARM mode use a libcall instead and should - // never get here. - unsigned Opc = isDeviceBarrier ? ARMISD::SYNCBARRIER : ARMISD::MEMBARRIER; - if (Subtarget->hasDataBarrier()) - return DAG.getNode(Opc, dl, MVT::Other, Op.getOperand(0)); - else { + if (!Subtarget->hasDataBarrier()) { + // Some ARMv6 cpus can support data barriers with an mcr instruction. + // Thumb1 and pre-v6 ARM mode use a libcall instead and should never get + // here. assert(Subtarget->hasV6Ops() && !Subtarget->isThumb1Only() && "Unexpected ISD::MEMBARRIER encountered. Should be libcall!"); - return DAG.getNode(Opc, dl, MVT::Other, Op.getOperand(0), + return DAG.getNode(ARMISD::MEMBARRIER_MCR, dl, MVT::Other, Op.getOperand(0), DAG.getConstant(0, MVT::i32)); } + + SDValue Op5 = Op.getOperand(5); + bool isDeviceBarrier = cast<ConstantSDNode>(Op5)->getZExtValue() != 0; + unsigned isLL = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); + unsigned isLS = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue(); + bool isOnlyStoreBarrier = (isLL == 0 && isLS == 0); + + ARM_MB::MemBOpt DMBOpt; + if (isDeviceBarrier) + DMBOpt = isOnlyStoreBarrier ? ARM_MB::ST : ARM_MB::SY; + else + DMBOpt = isOnlyStoreBarrier ? ARM_MB::ISHST : ARM_MB::ISH; + return DAG.getNode(ARMISD::MEMBARRIER, dl, MVT::Other, Op.getOperand(0), + DAG.getConstant(DMBOpt, MVT::i32)); } static SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) { diff --git a/llvm/lib/Target/ARM/ARMISelLowering.h b/llvm/lib/Target/ARM/ARMISelLowering.h index bf3553becc8..bd2fa8eb47e 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.h +++ b/llvm/lib/Target/ARM/ARMISelLowering.h @@ -81,8 +81,8 @@ namespace llvm { DYN_ALLOC, // Dynamic allocation on the stack. - MEMBARRIER, // Memory barrier - SYNCBARRIER, // Memory sync barrier + MEMBARRIER, // Memory barrier (DMB) + MEMBARRIER_MCR, // Memory barrier (MCR) VCEQ, // Vector compare equal. VCGE, // Vector compare greater than or equal. diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td index 4497a92cceb..3bf601ef74f 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/llvm/lib/Target/ARM/ARMInstrInfo.td @@ -60,10 +60,7 @@ def SDT_ARMEH_SJLJ_Longjmp: SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisInt<1>]>; def SDT_ARMEH_SJLJ_DispatchSetup: SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>; -def SDT_ARMMEMBARRIER : SDTypeProfile<0, 0, []>; -def SDT_ARMSYNCBARRIER : SDTypeProfile<0, 0, []>; -def SDT_ARMMEMBARRIERMCR : SDTypeProfile<0, 1, [SDTCisInt<0>]>; -def SDT_ARMSYNCBARRIERMCR : SDTypeProfile<0, 1, [SDTCisInt<0>]>; +def SDT_ARMMEMBARRIER : SDTypeProfile<0, 1, [SDTCisInt<0>]>; def SDT_ARMTCRET : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>; @@ -131,11 +128,7 @@ def ARMeh_sjlj_dispatchsetup: SDNode<"ARMISD::EH_SJLJ_DISPATCHSETUP", def ARMMemBarrier : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIER, [SDNPHasChain]>; -def ARMSyncBarrier : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIER, - [SDNPHasChain]>; -def ARMMemBarrierMCR : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIERMCR, - [SDNPHasChain]>; -def ARMSyncBarrierMCR : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIERMCR, +def ARMMemBarrierMCR : SDNode<"ARMISD::MEMBARRIER_MCR", SDT_ARMMEMBARRIER, [SDNPHasChain]>; def ARMrbit : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>; @@ -2888,64 +2881,40 @@ def MOVCCi : AI1<0b1101, (outs GPR:$Rd), // Atomic operations intrinsics // +def memb_opt : Operand<i32> { + let PrintMethod = "printMemBOption"; +} + // memory barriers protect the atomic sequences let hasSideEffects = 1 in { -def DMBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "dmb", "", - [(ARMMemBarrier)]>, Requires<[IsARM, HasDB]> { +def DMB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary, + "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>, + Requires<[IsARM, HasDB]> { + bits<4> opt; let Inst{31-4} = 0xf57ff05; - // FIXME: add support for options other than a full system DMB - // See DMB disassembly-only variants below. - let Inst{3-0} = 0b1111; -} - -def DSBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "dsb", "", - [(ARMSyncBarrier)]>, Requires<[IsARM, HasDB]> { - let Inst{31-4} = 0xf57ff04; - // FIXME: add support for options other than a full system DSB - // See DSB disassembly-only variants below. - let Inst{3-0} = 0b1111; + let Inst{3-0} = opt; } def DMB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary, "mcr", "\tp15, 0, $zero, c7, c10, 5", [(ARMMemBarrierMCR GPR:$zero)]>, Requires<[IsARM, HasV6]> { - // FIXME: add support for options other than a full system DMB // FIXME: add encoding } - -def DSB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary, - "mcr", "\tp15, 0, $zero, c7, c10, 4", - [(ARMSyncBarrierMCR GPR:$zero)]>, - Requires<[IsARM, HasV6]> { - // FIXME: add support for options other than a full system DSB - // FIXME: add encoding -} -} - -// Memory Barrier Operations Variants -- for disassembly only - -def memb_opt : Operand<i32> { - let PrintMethod = "printMemBOption"; } -class AMBI<bits<4> op7_4, string opc> - : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary, opc, "\t$opt", - [/* For disassembly only; pattern left blank */]>, - Requires<[IsARM, HasDB]> { - let Inst{31-8} = 0xf57ff0; - let Inst{7-4} = op7_4; +def DSB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary, + "dsb", "\t$opt", + [/* For disassembly only; pattern left blank */]>, + Requires<[IsARM, HasDB]> { + bits<4> opt; + let Inst{31-4} = 0xf57ff04; + let Inst{3-0} = opt; } -// These DMB variants are for disassembly only. -def DMBvar : AMBI<0b0101, "dmb">; - -// These DSB variants are for disassembly only. -def DSBvar : AMBI<0b0100, "dsb">; - // ISB has only full system option -- for disassembly only -def ISBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "isb", "", []>, - Requires<[IsARM, HasDB]> { +def ISB : AInoP<(outs), (ins), MiscFrm, NoItinerary, "isb", "", []>, + Requires<[IsARM, HasDB]> { let Inst{31-4} = 0xf57ff06; let Inst{3-0} = 0b1111; } diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td index a24281d16c3..f11ccb31ed6 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb2.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td @@ -2268,78 +2268,29 @@ def t2MOVCCror : T2I_movcc_sh<0b11, (outs rGPR:$dst), // memory barriers protect the atomic sequences let hasSideEffects = 1 in { -def t2DMBsy : AInoP<(outs), (ins), ThumbFrm, NoItinerary, "dmb", "", - [(ARMMemBarrier)]>, Requires<[IsThumb, HasDB]> { - let Inst{31-4} = 0xF3BF8F5; - // FIXME: add support for options other than a full system DMB - let Inst{3-0} = 0b1111; -} - -def t2DSBsy : AInoP<(outs), (ins), ThumbFrm, NoItinerary, "dsb", "", - [(ARMSyncBarrier)]>, Requires<[IsThumb, HasDB]> { - let Inst{31-4} = 0xF3BF8F4; - // FIXME: add support for options other than a full system DSB - let Inst{3-0} = 0b1111; +def t2DMB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary, + "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>, + Requires<[IsThumb, HasDB]> { + bits<4> opt; + let Inst{31-4} = 0xf3bf8f5; + let Inst{3-0} = opt; } } -// Helper class for multiclass T2MemB -- for disassembly only -class T2I_memb<string opc, string asm> - : T2I<(outs), (ins), NoItinerary, opc, asm, - [/* For disassembly only; pattern left blank */]>, - Requires<[IsThumb2, HasV7]> { - let Inst{31-20} = 0xf3b; - let Inst{15-14} = 0b10; - let Inst{12} = 0; -} - -multiclass T2MemB<bits<4> op7_4, string opc> { - - def st : T2I_memb<opc, "\tst"> { - let Inst{7-4} = op7_4; - let Inst{3-0} = 0b1110; - } - - def ish : T2I_memb<opc, "\tish"> { - let Inst{7-4} = op7_4; - let Inst{3-0} = 0b1011; - } - - def ishst : T2I_memb<opc, "\tishst"> { - let Inst{7-4} = op7_4; - let Inst{3-0} = 0b1010; - } - - def nsh : T2I_memb<opc, "\tnsh"> { - let Inst{7-4} = op7_4; - let Inst{3-0} = 0b0111; - } - - def nshst : T2I_memb<opc, "\tnshst"> { - let Inst{7-4} = op7_4; - let Inst{3-0} = 0b0110; - } - - def osh : T2I_memb<opc, "\tosh"> { - let Inst{7-4} = op7_4; - let Inst{3-0} = 0b0011; - } - - def oshst : T2I_memb<opc, "\toshst"> { - let Inst{7-4} = op7_4; - let Inst{3-0} = 0b0010; - } +def t2DSB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary, + "dsb", "\t$opt", + [/* For disassembly only; pattern left blank */]>, + Requires<[IsThumb, HasDB]> { + bits<4> opt; + let Inst{31-4} = 0xf3bf8f4; + let Inst{3-0} = opt; } -// These DMB variants are for disassembly only. -defm t2DMB : T2MemB<0b0101, "dmb">; - -// These DSB variants are for disassembly only. -defm t2DSB : T2MemB<0b0100, "dsb">; - // ISB has only full system option -- for disassembly only -def t2ISBsy : T2I_memb<"isb", ""> { - let Inst{7-4} = 0b0110; +def t2ISB : T2I<(outs), (ins), NoItinerary, "isb", "", + [/* For disassembly only; pattern left blank */]>, + Requires<[IsThumb2, HasV7]> { + let Inst{31-4} = 0xf3bf8f6; let Inst{3-0} = 0b1111; } |

