diff options
Diffstat (limited to 'contrib/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td')
| -rw-r--r-- | contrib/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td | 174 |
1 files changed, 151 insertions, 23 deletions
diff --git a/contrib/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td b/contrib/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td index 31f728b0c22f..9426df399597 100644 --- a/contrib/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td +++ b/contrib/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td @@ -42,6 +42,47 @@ class AMDGPUShaderInst <dag outs, dag ins, string asm = "", field bits<32> Inst = 0xffffffff; } +//===---------------------------------------------------------------------===// +// Return instruction +//===---------------------------------------------------------------------===// + +class ILFormat<dag outs, dag ins, string asmstr, list<dag> pattern> +: Instruction { + + let Namespace = "AMDGPU"; + dag OutOperandList = outs; + dag InOperandList = ins; + let Pattern = pattern; + let AsmString = !strconcat(asmstr, "\n"); + let isPseudo = 1; + let Itinerary = NullALU; + bit hasIEEEFlag = 0; + bit hasZeroOpFlag = 0; + let mayLoad = 0; + let mayStore = 0; + let hasSideEffects = 0; + let isCodeGenOnly = 1; +} + +def TruePredicate : Predicate<"true">; + +// Exists to help track down where SubtargetPredicate isn't set rather +// than letting tablegen crash with an unhelpful error. +def InvalidPred : Predicate<"predicate not set on instruction or pattern">; + +class PredicateControl { + Predicate SubtargetPredicate = InvalidPred; + list<Predicate> AssemblerPredicates = []; + Predicate AssemblerPredicate = TruePredicate; + list<Predicate> OtherPredicates = []; + list<Predicate> Predicates = !listconcat([SubtargetPredicate, + AssemblerPredicate], + AssemblerPredicates, + OtherPredicates); +} +class AMDGPUPat<dag pattern, dag result> : Pat<pattern, result>, + PredicateControl; + def FP16Denormals : Predicate<"Subtarget->hasFP16Denormals()">; def FP32Denormals : Predicate<"Subtarget->hasFP32Denormals()">; def FP64Denormals : Predicate<"Subtarget->hasFP64Denormals()">; @@ -52,7 +93,6 @@ def UnsafeFPMath : Predicate<"TM.Options.UnsafeFPMath">; def FMA : Predicate<"Subtarget->hasFMA()">; def InstFlag : OperandWithDefaultOps <i32, (ops (i32 0))>; -def ADDRIndirect : ComplexPattern<iPTR, 2, "SelectADDRIndirect", [], []>; def u16ImmTarget : AsmOperandClass { let Name = "U16Imm"; @@ -95,12 +135,6 @@ def brtarget : Operand<OtherVT>; // Misc. PatFrags //===----------------------------------------------------------------------===// -class HasOneUseUnaryOp<SDPatternOperator op> : PatFrag< - (ops node:$src0), - (op $src0), - [{ return N->hasOneUse(); }] ->; - class HasOneUseBinOp<SDPatternOperator op> : PatFrag< (ops node:$src0, node:$src1), (op $src0, $src1), @@ -113,8 +147,6 @@ class HasOneUseTernaryOp<SDPatternOperator op> : PatFrag< [{ return N->hasOneUse(); }] >; -def trunc_oneuse : HasOneUseUnaryOp<trunc>; - let Properties = [SDNPCommutative, SDNPAssociative] in { def smax_oneuse : HasOneUseBinOp<smax>; def smin_oneuse : HasOneUseBinOp<smin>; @@ -127,6 +159,7 @@ def or_oneuse : HasOneUseBinOp<or>; def xor_oneuse : HasOneUseBinOp<xor>; } // Properties = [SDNPCommutative, SDNPAssociative] +def add_oneuse : HasOneUseBinOp<add>; def sub_oneuse : HasOneUseBinOp<sub>; def srl_oneuse : HasOneUseBinOp<srl>; @@ -240,6 +273,37 @@ def COND_NULL : PatLeaf < [{(void)N; return false;}] >; +//===----------------------------------------------------------------------===// +// PatLeafs for Texture Constants +//===----------------------------------------------------------------------===// + +def TEX_ARRAY : PatLeaf< + (imm), + [{uint32_t TType = (uint32_t)N->getZExtValue(); + return TType == 9 || TType == 10 || TType == 16; + }] +>; + +def TEX_RECT : PatLeaf< + (imm), + [{uint32_t TType = (uint32_t)N->getZExtValue(); + return TType == 5; + }] +>; + +def TEX_SHADOW : PatLeaf< + (imm), + [{uint32_t TType = (uint32_t)N->getZExtValue(); + return (TType >= 6 && TType <= 8) || TType == 13; + }] +>; + +def TEX_SHADOW_ARRAY : PatLeaf< + (imm), + [{uint32_t TType = (uint32_t)N->getZExtValue(); + return TType == 11 || TType == 12 || TType == 17; + }] +>; //===----------------------------------------------------------------------===// // Load/Store Pattern Fragments @@ -249,6 +313,10 @@ class Aligned8Bytes <dag ops, dag frag> : PatFrag <ops, frag, [{ return cast<MemSDNode>(N)->getAlignment() % 8 == 0; }]>; +class Aligned16Bytes <dag ops, dag frag> : PatFrag <ops, frag, [{ + return cast<MemSDNode>(N)->getAlignment() >= 16; +}]>; + class LoadFrag <SDPatternOperator op> : PatFrag<(ops node:$ptr), (op node:$ptr)>; class StoreFrag<SDPatternOperator op> : PatFrag < @@ -361,21 +429,31 @@ def az_extloadi8_local : LocalLoad <az_extloadi8>; def sextloadi8_local : LocalLoad <sextloadi8>; def az_extloadi16_local : LocalLoad <az_extloadi16>; def sextloadi16_local : LocalLoad <sextloadi16>; +def atomic_load_32_local : LocalLoad<atomic_load_32>; +def atomic_load_64_local : LocalLoad<atomic_load_64>; def store_local : LocalStore <store>; def truncstorei8_local : LocalStore <truncstorei8>; def truncstorei16_local : LocalStore <truncstorei16>; def store_local_hi16 : StoreHi16 <truncstorei16>, LocalAddress; def truncstorei8_local_hi16 : StoreHi16<truncstorei8>, LocalAddress; +def atomic_store_local : LocalStore <atomic_store>; def load_align8_local : Aligned8Bytes < (ops node:$ptr), (load_local node:$ptr) >; +def load_align16_local : Aligned16Bytes < + (ops node:$ptr), (load_local node:$ptr) +>; + def store_align8_local : Aligned8Bytes < (ops node:$val, node:$ptr), (store_local node:$val, node:$ptr) >; +def store_align16_local : Aligned16Bytes < + (ops node:$val, node:$ptr), (store_local node:$val, node:$ptr) +>; def load_flat : FlatLoad <load>; def az_extloadi8_flat : FlatLoad <az_extloadi8>; @@ -571,6 +649,18 @@ multiclass BFIPatterns <Instruction BFI_INT, (BFI_INT $x, $y, $z) >; + // 64-bit version + def : AMDGPUPat < + (or (and i64:$y, i64:$x), (and i64:$z, (not i64:$x))), + (REG_SEQUENCE RC64, + (BFI_INT (i32 (EXTRACT_SUBREG $x, sub0)), + (i32 (EXTRACT_SUBREG $y, sub0)), + (i32 (EXTRACT_SUBREG $z, sub0))), sub0, + (BFI_INT (i32 (EXTRACT_SUBREG $x, sub1)), + (i32 (EXTRACT_SUBREG $y, sub1)), + (i32 (EXTRACT_SUBREG $z, sub1))), sub1) + >; + // SHA-256 Ch function // z ^ (x & (y ^ z)) def : AMDGPUPat < @@ -578,6 +668,18 @@ multiclass BFIPatterns <Instruction BFI_INT, (BFI_INT $x, $y, $z) >; + // 64-bit version + def : AMDGPUPat < + (xor i64:$z, (and i64:$x, (xor i64:$y, i64:$z))), + (REG_SEQUENCE RC64, + (BFI_INT (i32 (EXTRACT_SUBREG $x, sub0)), + (i32 (EXTRACT_SUBREG $y, sub0)), + (i32 (EXTRACT_SUBREG $z, sub0))), sub0, + (BFI_INT (i32 (EXTRACT_SUBREG $x, sub1)), + (i32 (EXTRACT_SUBREG $y, sub1)), + (i32 (EXTRACT_SUBREG $z, sub1))), sub1) + >; + def : AMDGPUPat < (fcopysign f32:$src0, f32:$src1), (BFI_INT (LoadImm32 (i32 0x7fffffff)), $src0, $src1) @@ -611,10 +713,25 @@ multiclass BFIPatterns <Instruction BFI_INT, // SHA-256 Ma patterns // ((x & z) | (y & (x | z))) -> BFI_INT (XOR x, y), z, y -class SHA256MaPattern <Instruction BFI_INT, Instruction XOR> : AMDGPUPat < - (or (and i32:$x, i32:$z), (and i32:$y, (or i32:$x, i32:$z))), - (BFI_INT (XOR i32:$x, i32:$y), i32:$z, i32:$y) ->; +multiclass SHA256MaPattern <Instruction BFI_INT, Instruction XOR, RegisterClass RC64> { + def : AMDGPUPat < + (or (and i32:$x, i32:$z), (and i32:$y, (or i32:$x, i32:$z))), + (BFI_INT (XOR i32:$x, i32:$y), i32:$z, i32:$y) + >; + + def : AMDGPUPat < + (or (and i64:$x, i64:$z), (and i64:$y, (or i64:$x, i64:$z))), + (REG_SEQUENCE RC64, + (BFI_INT (XOR (i32 (EXTRACT_SUBREG $x, sub0)), + (i32 (EXTRACT_SUBREG $y, sub0))), + (i32 (EXTRACT_SUBREG $z, sub0)), + (i32 (EXTRACT_SUBREG $y, sub0))), sub0, + (BFI_INT (XOR (i32 (EXTRACT_SUBREG $x, sub1)), + (i32 (EXTRACT_SUBREG $y, sub1))), + (i32 (EXTRACT_SUBREG $z, sub1)), + (i32 (EXTRACT_SUBREG $y, sub1))), sub1) + >; +} // Bitfield extract patterns @@ -633,14 +750,33 @@ multiclass BFEPattern <Instruction UBFE, Instruction SBFE, Instruction MOV> { (UBFE $src, $rshift, (MOV (i32 (IMMPopCount $mask)))) >; + // x & ((1 << y) - 1) + def : AMDGPUPat < + (and i32:$src, (add_oneuse (shl_oneuse 1, i32:$width), -1)), + (UBFE $src, (MOV (i32 0)), $width) + >; + + // x & ~(-1 << y) + def : AMDGPUPat < + (and i32:$src, (xor_oneuse (shl_oneuse -1, i32:$width), -1)), + (UBFE $src, (MOV (i32 0)), $width) + >; + + // x & (-1 >> (bitwidth - y)) + def : AMDGPUPat < + (and i32:$src, (srl_oneuse -1, (sub 32, i32:$width))), + (UBFE $src, (MOV (i32 0)), $width) + >; + + // x << (bitwidth - y) >> (bitwidth - y) def : AMDGPUPat < (srl (shl_oneuse i32:$src, (sub 32, i32:$width)), (sub 32, i32:$width)), - (UBFE $src, (i32 0), $width) + (UBFE $src, (MOV (i32 0)), $width) >; def : AMDGPUPat < (sra (shl_oneuse i32:$src, (sub 32, i32:$width)), (sub 32, i32:$width)), - (SBFE $src, (i32 0), $width) + (SBFE $src, (MOV (i32 0)), $width) >; } @@ -697,11 +833,3 @@ class RsqPat<Instruction RsqInst, ValueType vt> : AMDGPUPat < (AMDGPUrcp (fsqrt vt:$src)), (RsqInst $src) >; - -include "R600Instructions.td" -include "R700Instructions.td" -include "EvergreenInstructions.td" -include "CaymanInstructions.td" - -include "SIInstrInfo.td" - |
