forked from OSchip/llvm-project
Add XCore support for ATOMIC_FENCE.
ATOMIC_FENCE is lowered to a compiler barrier which is codegen only. There is no need to emit an instructions since the XCore provides sequential consistency. Original patch by Richard Osborne llvm-svn: 194464
This commit is contained in:
parent
ed835b6fd4
commit
61d9149c73
|
@ -59,6 +59,7 @@ getTargetNodeName(unsigned Opcode) const
|
|||
case XCoreISD::CRC8 : return "XCoreISD::CRC8";
|
||||
case XCoreISD::BR_JT : return "XCoreISD::BR_JT";
|
||||
case XCoreISD::BR_JT32 : return "XCoreISD::BR_JT32";
|
||||
case XCoreISD::MEMBARRIER : return "XCoreISD::MEMBARRIER";
|
||||
default : return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -148,6 +149,9 @@ XCoreTargetLowering::XCoreTargetLowering(XCoreTargetMachine &XTM)
|
|||
setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
|
||||
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand);
|
||||
|
||||
// Atomic operations
|
||||
setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom);
|
||||
|
||||
// TRAMPOLINE is custom lowered.
|
||||
setOperationAction(ISD::INIT_TRAMPOLINE, MVT::Other, Custom);
|
||||
setOperationAction(ISD::ADJUST_TRAMPOLINE, MVT::Other, Custom);
|
||||
|
@ -206,6 +210,7 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const {
|
|||
case ISD::INIT_TRAMPOLINE: return LowerINIT_TRAMPOLINE(Op, DAG);
|
||||
case ISD::ADJUST_TRAMPOLINE: return LowerADJUST_TRAMPOLINE(Op, DAG);
|
||||
case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
|
||||
case ISD::ATOMIC_FENCE: return LowerATOMIC_FENCE(Op, DAG);
|
||||
default:
|
||||
llvm_unreachable("unimplemented operand");
|
||||
}
|
||||
|
@ -847,6 +852,12 @@ LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const {
|
|||
return SDValue();
|
||||
}
|
||||
|
||||
SDValue XCoreTargetLowering::
|
||||
LowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const {
|
||||
SDLoc DL(Op);
|
||||
return DAG.getNode(XCoreISD::MEMBARRIER, DL, MVT::Other, Op.getOperand(0));
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Calling Convention Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -70,7 +70,10 @@ namespace llvm {
|
|||
BR_JT,
|
||||
|
||||
// Jumptable branch using long branches for each entry.
|
||||
BR_JT32
|
||||
BR_JT32,
|
||||
|
||||
// Memory barrier.
|
||||
MEMBARRIER
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -158,6 +161,7 @@ namespace llvm {
|
|||
SDValue LowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerADJUST_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const;
|
||||
|
||||
// Inline asm support
|
||||
std::pair<unsigned, const TargetRegisterClass*>
|
||||
|
|
|
@ -70,6 +70,11 @@ def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_XCoreCallSeqStart,
|
|||
def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_XCoreCallSeqEnd,
|
||||
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
|
||||
|
||||
def SDT_XCoreMEMBARRIER : SDTypeProfile<0, 0, []>;
|
||||
|
||||
def XCoreMemBarrier : SDNode<"XCoreISD::MEMBARRIER", SDT_XCoreMEMBARRIER,
|
||||
[SDNPHasChain]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instruction Pattern Stuff
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -343,6 +348,10 @@ let usesCustomInserter = 1 in {
|
|||
(select GRRegs:$cond, GRRegs:$T, GRRegs:$F))]>;
|
||||
}
|
||||
|
||||
let hasSideEffects = 1 in
|
||||
def Int_MemBarrier : PseudoInstXCore<(outs), (ins), "#MEMBARRIER",
|
||||
[(XCoreMemBarrier)]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
; RUN: llc < %s -march=xcore | FileCheck %s
|
||||
|
||||
; CHECK-LABEL: atomic_fence
|
||||
; CHECK: #MEMBARRIER
|
||||
; CHECK: #MEMBARRIER
|
||||
; CHECK: #MEMBARRIER
|
||||
; CHECK: #MEMBARRIER
|
||||
; CHECK: retsp 0
|
||||
define void @atomic_fence() nounwind {
|
||||
entry:
|
||||
fence acquire
|
||||
fence release
|
||||
fence acq_rel
|
||||
fence seq_cst
|
||||
ret void
|
||||
}
|
Loading…
Reference in New Issue