diff options
author | Tom Stellard <thomas.stellard@amd.com> | 2014-09-25 18:30:26 +0000 |
---|---|---|
committer | Tom Stellard <thomas.stellard@amd.com> | 2014-09-25 18:30:26 +0000 |
commit | 7980fc856272f392bba56f0e09cec5475b8a5090 (patch) | |
tree | 1b598d9765176dc6ef8090b50a0b12417b610102 /llvm/lib | |
parent | 810739d17420d914b1a6f239f2ca7d5d82bd5f66 (diff) | |
download | bcm5719-llvm-7980fc856272f392bba56f0e09cec5475b8a5090.tar.gz bcm5719-llvm-7980fc856272f392bba56f0e09cec5475b8a5090.zip |
R600/SI: Add support for global atomic add
llvm-svn: 218457
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/R600/AMDGPUISelDAGToDAG.cpp | 21 | ||||
-rw-r--r-- | llvm/lib/Target/R600/AMDGPUInstructions.td | 8 | ||||
-rw-r--r-- | llvm/lib/Target/R600/SIInstrInfo.td | 81 | ||||
-rw-r--r-- | llvm/lib/Target/R600/SIInstructions.td | 4 |
4 files changed, 111 insertions, 3 deletions
diff --git a/llvm/lib/Target/R600/AMDGPUISelDAGToDAG.cpp b/llvm/lib/Target/R600/AMDGPUISelDAGToDAG.cpp index d8b38a233dd..b598ac84513 100644 --- a/llvm/lib/Target/R600/AMDGPUISelDAGToDAG.cpp +++ b/llvm/lib/Target/R600/AMDGPUISelDAGToDAG.cpp @@ -96,11 +96,16 @@ private: SDValue &TFE) const; bool SelectMUBUFAddr64(SDValue Addr, SDValue &SRsrc, SDValue &VAddr, SDValue &Offset) const; + bool SelectMUBUFAddr64(SDValue Addr, SDValue &SRsrc, + SDValue &VAddr, SDValue &Offset, + SDValue &SLC) const; bool SelectMUBUFScratch(SDValue Addr, SDValue &RSrc, SDValue &VAddr, SDValue &SOffset, SDValue &ImmOffset) const; bool SelectMUBUFOffset(SDValue Addr, SDValue &SRsrc, SDValue &SOffset, SDValue &Offset, SDValue &GLC, SDValue &SLC, SDValue &TFE) const; + bool SelectMUBUFOffset(SDValue Addr, SDValue &SRsrc, SDValue &Soffset, + SDValue &Offset, SDValue &GLC) const; SDNode *SelectAddrSpaceCast(SDNode *N); bool SelectVOP3Mods(SDValue In, SDValue &Src, SDValue &SrcMods) const; bool SelectVOP3Mods0(SDValue In, SDValue &Src, SDValue &SrcMods, @@ -891,6 +896,14 @@ bool AMDGPUDAGToDAGISel::SelectMUBUFAddr64(SDValue Addr, SDValue &SRsrc, return false; } +bool AMDGPUDAGToDAGISel::SelectMUBUFAddr64(SDValue Addr, SDValue &SRsrc, + SDValue &VAddr, SDValue &Offset, + SDValue &SLC) const { + SLC = CurDAG->getTargetConstant(0, MVT::i1); + + return SelectMUBUFAddr64(Addr, SRsrc, VAddr, Offset); +} + static SDValue buildRSRC(SelectionDAG *DAG, SDLoc DL, SDValue Ptr, uint32_t RsrcDword1, uint64_t RsrcDword2And3) { @@ -1001,6 +1014,14 @@ bool AMDGPUDAGToDAGISel::SelectMUBUFOffset(SDValue Addr, SDValue &SRsrc, return false; } +bool AMDGPUDAGToDAGISel::SelectMUBUFOffset(SDValue Addr, SDValue &SRsrc, + SDValue &Soffset, SDValue &Offset, + SDValue &GLC) const { + SDValue SLC, TFE; + + return SelectMUBUFOffset(Addr, SRsrc, Soffset, Offset, GLC, SLC, TFE); +} + // FIXME: This is incorrect and only enough to be able to compile. SDNode *AMDGPUDAGToDAGISel::SelectAddrSpaceCast(SDNode *N) { AddrSpaceCastSDNode *ASC = cast<AddrSpaceCastSDNode>(N); diff --git a/llvm/lib/Target/R600/AMDGPUInstructions.td b/llvm/lib/Target/R600/AMDGPUInstructions.td index d152c884522..a6086270968 100644 --- a/llvm/lib/Target/R600/AMDGPUInstructions.td +++ b/llvm/lib/Target/R600/AMDGPUInstructions.td @@ -380,6 +380,14 @@ def mskor_flat : PatFrag<(ops node:$val, node:$ptr), return dyn_cast<MemSDNode>(N)->getAddressSpace() == AMDGPUAS::FLAT_ADDRESS; }]>; +class global_binary_atomic_op<SDNode atomic_op> : PatFrag< + (ops node:$ptr, node:$value), + (atomic_op node:$ptr, node:$value), + [{return cast<MemSDNode>(N)->getAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS;}] +>; + +def atomic_add_global : global_binary_atomic_op<atomic_load_add>; + //===----------------------------------------------------------------------===// // Misc Pattern Fragments //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/R600/SIInstrInfo.td b/llvm/lib/Target/R600/SIInstrInfo.td index bde90d8ceaa..cf45b30c0b5 100644 --- a/llvm/lib/Target/R600/SIInstrInfo.td +++ b/llvm/lib/Target/R600/SIInstrInfo.td @@ -196,8 +196,10 @@ def DS64Bit4ByteAligned : ComplexPattern<i32, 3, "SelectDS64Bit4ByteAligned">; def MUBUFAddr32 : ComplexPattern<i64, 9, "SelectMUBUFAddr32">; def MUBUFAddr64 : ComplexPattern<i64, 3, "SelectMUBUFAddr64">; +def MUBUFAddr64Atomic : ComplexPattern<i64, 4, "SelectMUBUFAddr64">; def MUBUFScratch : ComplexPattern<i64, 4, "SelectMUBUFScratch">; def MUBUFOffset : ComplexPattern<i64, 6, "SelectMUBUFOffset">; +def MUBUFOffsetAtomic : ComplexPattern<i64, 4, "SelectMUBUFOffset">; def VOP3Mods0 : ComplexPattern<untyped, 4, "SelectVOP3Mods0">; def VOP3Mods : ComplexPattern<untyped, 2, "SelectVOP3Mods">; @@ -929,9 +931,10 @@ class DS_1A1D_NORET <bits<8> op, string asm, RegisterClass rc, string noRetOp = let mayLoad = 1; } -class MUBUFAddr64Table <bit is_addr64> { +class MUBUFAddr64Table <bit is_addr64, string suffix = ""> { bit IsAddr64 = is_addr64; + string OpName = NAME # suffix; } class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF < @@ -947,6 +950,80 @@ class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBU let mayLoad = 0; } +class MUBUFAtomicAddr64 <bits<7> op, dag outs, dag ins, string asm, list<dag> pattern> + : MUBUF <op, outs, ins, asm, pattern> { + + let offen = 0; + let idxen = 0; + let addr64 = 1; + let tfe = 0; + let lds = 0; + let soffset = 128; +} + +class MUBUFAtomicOffset <bits<7> op, dag outs, dag ins, string asm, list<dag> pattern> + : MUBUF <op, outs, ins, asm, pattern> { + + let offen = 0; + let idxen = 0; + let addr64 = 0; + let tfe = 0; + let lds = 0; + let vaddr = 0; +} + +multiclass MUBUF_Atomic <bits<7> op, string name, RegisterClass rc, + ValueType vt, SDPatternOperator atomic> { + + let mayStore = 1, mayLoad = 1, hasPostISelHook = 1 in { + + // No return variants + let glc = 0 in { + + def _ADDR64 : MUBUFAtomicAddr64 < + op, (outs), + (ins rc:$vdata, SReg_128:$srsrc, VReg_64:$vaddr, + mbuf_offset:$offset, slc:$slc), + name#" $vdata, $vaddr, $srsrc, 0 addr64"#"$offset"#"$slc", [] + >, MUBUFAddr64Table<1>, AtomicNoRet<NAME#"_ADDR64", 0>; + + def _OFFSET : MUBUFAtomicOffset < + op, (outs), + (ins rc:$vdata, SReg_128:$srsrc, mbuf_offset:$offset, + SSrc_32:$soffset, slc:$slc), + name#" $vdata, $srsrc, $soffset"#"$offset"#"$slc", [] + >, MUBUFAddr64Table<0>, AtomicNoRet<NAME#"_OFFSET", 0>; + } // glc = 0 + + // Variant that return values + let glc = 1, Constraints = "$vdata = $vdata_in", + DisableEncoding = "$vdata_in" in { + + def _RTN_ADDR64 : MUBUFAtomicAddr64 < + op, (outs rc:$vdata), + (ins rc:$vdata_in, SReg_128:$srsrc, VReg_64:$vaddr, + mbuf_offset:$offset, slc:$slc), + name#" $vdata, $vaddr, $srsrc, 0 addr64"#"$offset"#" glc"#"$slc", + [(set vt:$vdata, + (atomic (MUBUFAddr64Atomic v4i32:$srsrc, i64:$vaddr, i16:$offset, + i1:$slc), vt:$vdata_in))] + >, MUBUFAddr64Table<1, "_RTN">, AtomicNoRet<NAME#"_ADDR64", 1>; + + def _RTN_OFFSET : MUBUFAtomicOffset < + op, (outs rc:$vdata), + (ins rc:$vdata_in, SReg_128:$srsrc, mbuf_offset:$offset, + SSrc_32:$soffset, slc:$slc), + name#" $vdata, $srsrc, $soffset"#"$offset"#" glc $slc", + [(set vt:$vdata, + (atomic (MUBUFOffsetAtomic v4i32:$srsrc, i32:$soffset, i16:$offset, + i1:$slc), vt:$vdata_in))] + >, MUBUFAddr64Table<0, "_RTN">, AtomicNoRet<NAME#"_OFFSET", 1>; + + } // glc = 1 + + } // mayStore = 1, mayLoad = 1, hasPostISelHook = 1 +} + multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass, ValueType load_vt = i32, SDPatternOperator ld = null_frag> { @@ -1292,7 +1369,7 @@ def getMCOpcode : InstrMapping { def getAddr64Inst : InstrMapping { let FilterClass = "MUBUFAddr64Table"; - let RowFields = ["NAME"]; + let RowFields = ["OpName"]; let ColFields = ["IsAddr64"]; let KeyCol = ["0"]; let ValueCols = [["1"]]; diff --git a/llvm/lib/Target/R600/SIInstructions.td b/llvm/lib/Target/R600/SIInstructions.td index 30923077538..9ac1389ee48 100644 --- a/llvm/lib/Target/R600/SIInstructions.td +++ b/llvm/lib/Target/R600/SIInstructions.td @@ -891,7 +891,9 @@ defm BUFFER_STORE_DWORDX4 : MUBUF_Store_Helper < >; //def BUFFER_ATOMIC_SWAP : MUBUF_ <0x00000030, "BUFFER_ATOMIC_SWAP", []>; //def BUFFER_ATOMIC_CMPSWAP : MUBUF_ <0x00000031, "BUFFER_ATOMIC_CMPSWAP", []>; -//def BUFFER_ATOMIC_ADD : MUBUF_ <0x00000032, "BUFFER_ATOMIC_ADD", []>; +defm BUFFER_ATOMIC_ADD : MUBUF_Atomic < + 0x00000032, "BUFFER_ATOMIC_ADD", VReg_32, i32, atomic_add_global +>; //def BUFFER_ATOMIC_SUB : MUBUF_ <0x00000033, "BUFFER_ATOMIC_SUB", []>; //def BUFFER_ATOMIC_RSUB : MUBUF_ <0x00000034, "BUFFER_ATOMIC_RSUB", []>; //def BUFFER_ATOMIC_SMIN : MUBUF_ <0x00000035, "BUFFER_ATOMIC_SMIN", []>; |