Home | History | Annotate | Download | only in R600
      1 //===-- SIInstrInfo.td - SI Instruction Infos -------------*- tablegen -*--===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 //===----------------------------------------------------------------------===//
     11 // SI DAG Nodes
     12 //===----------------------------------------------------------------------===//
     13 
     14 // SMRD takes a 64bit memory address and can only add an 32bit offset
     15 def SIadd64bit32bit : SDNode<"ISD::ADD",
     16   SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, SDTCisVT<0, i64>, SDTCisVT<2, i32>]>
     17 >;
     18 
     19 // Transformation function, extract the lower 32bit of a 64bit immediate
     20 def LO32 : SDNodeXForm<imm, [{
     21   return CurDAG->getTargetConstant(N->getZExtValue() & 0xffffffff, MVT::i32);
     22 }]>;
     23 
     24 def LO32f : SDNodeXForm<fpimm, [{
     25   APInt V = N->getValueAPF().bitcastToAPInt().trunc(32);
     26   return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
     27 }]>;
     28 
     29 // Transformation function, extract the upper 32bit of a 64bit immediate
     30 def HI32 : SDNodeXForm<imm, [{
     31   return CurDAG->getTargetConstant(N->getZExtValue() >> 32, MVT::i32);
     32 }]>;
     33 
     34 def HI32f : SDNodeXForm<fpimm, [{
     35   APInt V = N->getValueAPF().bitcastToAPInt().lshr(32).trunc(32);
     36   return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
     37 }]>;
     38 
     39 def IMM8bitDWORD : ImmLeaf <
     40   i32, [{
     41     return (Imm & ~0x3FC) == 0;
     42   }], SDNodeXForm<imm, [{
     43     return CurDAG->getTargetConstant(
     44       N->getZExtValue() >> 2, MVT::i32);
     45   }]>
     46 >;
     47 
     48 def as_i16imm : SDNodeXForm<imm, [{
     49   return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i16);
     50 }]>;
     51 
     52 def IMM12bit : PatLeaf <(imm),
     53   [{return isUInt<12>(N->getZExtValue());}]
     54 >;
     55 
     56 class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
     57   return
     58     (*(const SITargetLowering *)getTargetLowering()).analyzeImmediate(N) == 0;
     59 }]>;
     60 
     61 //===----------------------------------------------------------------------===//
     62 // SI assembler operands
     63 //===----------------------------------------------------------------------===//
     64 
     65 def SIOperand {
     66   int ZERO = 0x80;
     67   int VCC = 0x6A;
     68 }
     69 
     70 include "SIInstrFormats.td"
     71 
     72 //===----------------------------------------------------------------------===//
     73 //
     74 // SI Instruction multiclass helpers.
     75 //
     76 // Instructions with _32 take 32-bit operands.
     77 // Instructions with _64 take 64-bit operands.
     78 //
     79 // VOP_* instructions can use either a 32-bit or 64-bit encoding.  The 32-bit
     80 // encoding is the standard encoding, but instruction that make use of
     81 // any of the instruction modifiers must use the 64-bit encoding.
     82 //
     83 // Instructions with _e32 use the 32-bit encoding.
     84 // Instructions with _e64 use the 64-bit encoding.
     85 //
     86 //===----------------------------------------------------------------------===//
     87 
     88 //===----------------------------------------------------------------------===//
     89 // Scalar classes
     90 //===----------------------------------------------------------------------===//
     91 
     92 class SOP1_32 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
     93   op, (outs SReg_32:$dst), (ins SSrc_32:$src0),
     94   opName#" $dst, $src0", pattern
     95 >;
     96 
     97 class SOP1_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
     98   op, (outs SReg_64:$dst), (ins SSrc_64:$src0),
     99   opName#" $dst, $src0", pattern
    100 >;
    101 
    102 class SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
    103   op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
    104   opName#" $dst, $src0, $src1", pattern
    105 >;
    106 
    107 class SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
    108   op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
    109   opName#" $dst, $src0, $src1", pattern
    110 >;
    111 
    112 class SOPC_32 <bits<7> op, string opName, list<dag> pattern> : SOPC <
    113   op, (outs SCCReg:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
    114   opName#" $dst, $src0, $src1", pattern
    115 >;
    116 
    117 class SOPC_64 <bits<7> op, string opName, list<dag> pattern> : SOPC <
    118   op, (outs SCCReg:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
    119   opName#" $dst, $src0, $src1", pattern
    120 >;
    121 
    122 class SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK <
    123   op, (outs SReg_32:$dst), (ins i16imm:$src0),
    124   opName#" $dst, $src0", pattern
    125 >;
    126 
    127 class SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK <
    128   op, (outs SReg_64:$dst), (ins i16imm:$src0),
    129   opName#" $dst, $src0", pattern
    130 >;
    131 
    132 multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass,
    133                         RegisterClass dstClass> {
    134   def _IMM : SMRD <
    135     op, 1, (outs dstClass:$dst),
    136     (ins baseClass:$sbase, i32imm:$offset),
    137     asm#" $dst, $sbase, $offset", []
    138   >;
    139 
    140   def _SGPR : SMRD <
    141     op, 0, (outs dstClass:$dst),
    142     (ins baseClass:$sbase, SReg_32:$soff),
    143     asm#" $dst, $sbase, $soff", []
    144   >;
    145 }
    146 
    147 //===----------------------------------------------------------------------===//
    148 // Vector ALU classes
    149 //===----------------------------------------------------------------------===//
    150 
    151 class VOP <string opName> {
    152   string OpName = opName;
    153 }
    154 
    155 class VOP2_REV <string revOp, bit isOrig> {
    156   string RevOp = revOp;
    157   bit IsOrig = isOrig;
    158 }
    159 
    160 multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
    161                         string opName, list<dag> pattern> {
    162 
    163   def _e32 : VOP1 <
    164     op, (outs drc:$dst), (ins src:$src0),
    165     opName#"_e32 $dst, $src0", pattern
    166   >, VOP <opName>;
    167 
    168   def _e64 : VOP3 <
    169     {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
    170     (outs drc:$dst),
    171     (ins src:$src0,
    172          i32imm:$abs, i32imm:$clamp,
    173          i32imm:$omod, i32imm:$neg),
    174     opName#"_e64 $dst, $src0, $abs, $clamp, $omod, $neg", []
    175   >, VOP <opName> {
    176     let src1 = SIOperand.ZERO;
    177     let src2 = SIOperand.ZERO;
    178   }
    179 }
    180 
    181 multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
    182   : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
    183 
    184 multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
    185   : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
    186 
    187 multiclass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
    188                         string opName, list<dag> pattern, string revOp> {
    189   def _e32 : VOP2 <
    190     op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1),
    191     opName#"_e32 $dst, $src0, $src1", pattern
    192   >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
    193 
    194   def _e64 : VOP3 <
    195     {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
    196     (outs vrc:$dst),
    197     (ins arc:$src0, arc:$src1,
    198          i32imm:$abs, i32imm:$clamp,
    199          i32imm:$omod, i32imm:$neg),
    200     opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
    201   >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
    202     let src2 = SIOperand.ZERO;
    203   }
    204 }
    205 
    206 multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern,
    207                     string revOp = opName>
    208   : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>;
    209 
    210 multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern,
    211                     string revOp = opName>
    212   : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>;
    213 
    214 multiclass VOP2b_32 <bits<6> op, string opName, list<dag> pattern,
    215                      string revOp = opName> {
    216 
    217   def _e32 : VOP2 <
    218     op, (outs VReg_32:$dst), (ins VSrc_32:$src0, VReg_32:$src1),
    219     opName#"_e32 $dst, $src0, $src1", pattern
    220   >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
    221 
    222   def _e64 : VOP3b <
    223     {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
    224     (outs VReg_32:$dst),
    225     (ins VSrc_32:$src0, VSrc_32:$src1,
    226          i32imm:$abs, i32imm:$clamp,
    227          i32imm:$omod, i32imm:$neg),
    228     opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
    229   >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
    230     let src2 = SIOperand.ZERO;
    231     /* the VOP2 variant puts the carry out into VCC, the VOP3 variant
    232        can write it into any SGPR. We currently don't use the carry out,
    233        so for now hardcode it to VCC as well */
    234     let sdst = SIOperand.VCC;
    235   }
    236 }
    237 
    238 multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
    239                         string opName, ValueType vt, PatLeaf cond> {
    240 
    241   def _e32 : VOPC <
    242     op, (ins arc:$src0, vrc:$src1),
    243     opName#"_e32 $dst, $src0, $src1", []
    244   >, VOP <opName>;
    245 
    246   def _e64 : VOP3 <
    247     {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
    248     (outs SReg_64:$dst),
    249     (ins arc:$src0, arc:$src1,
    250          InstFlag:$abs, InstFlag:$clamp,
    251          InstFlag:$omod, InstFlag:$neg),
    252     opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg",
    253     !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>,
    254       [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))]
    255     )
    256   >, VOP <opName> {
    257     let src2 = SIOperand.ZERO;
    258   }
    259 }
    260 
    261 multiclass VOPC_32 <bits<8> op, string opName,
    262   ValueType vt = untyped, PatLeaf cond = COND_NULL>
    263   : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>;
    264 
    265 multiclass VOPC_64 <bits<8> op, string opName,
    266   ValueType vt = untyped, PatLeaf cond = COND_NULL>
    267   : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>;
    268 
    269 class VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
    270   op, (outs VReg_32:$dst),
    271   (ins VSrc_32:$src0, VSrc_32:$src1, VSrc_32:$src2,
    272    InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
    273   opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
    274 >, VOP <opName>;
    275 
    276 class VOP3_64_Shift <bits <9> op, string opName, list<dag> pattern> : VOP3 <
    277   op, (outs VReg_64:$dst),
    278   (ins VSrc_64:$src0, VSrc_32:$src1),
    279   opName#" $dst, $src0, $src1", pattern
    280 >, VOP <opName> {
    281 
    282   let src2 = SIOperand.ZERO;
    283   let abs = 0;
    284   let clamp = 0;
    285   let omod = 0;
    286   let neg = 0;
    287 }
    288 
    289 class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
    290   op, (outs VReg_64:$dst),
    291   (ins VSrc_64:$src0, VSrc_64:$src1, VSrc_64:$src2,
    292    InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
    293   opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
    294 >, VOP <opName>;
    295 
    296 //===----------------------------------------------------------------------===//
    297 // Vector I/O classes
    298 //===----------------------------------------------------------------------===//
    299 
    300 class DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
    301   op,
    302   (outs regClass:$vdst),
    303   (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, VReg_32:$data1,
    304        i8imm:$offset0, i8imm:$offset1),
    305   asm#" $vdst, $gds, $addr, $data0, $data1, $offset0, $offset1, [M0]",
    306   []> {
    307   let mayLoad = 1;
    308   let mayStore = 0;
    309 }
    310 
    311 class DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
    312   op,
    313   (outs),
    314   (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, VReg_32:$data1,
    315        i8imm:$offset0, i8imm:$offset1),
    316   asm#" $gds, $addr, $data0, $data1, $offset0, $offset1, [M0]",
    317   []> {
    318   let mayStore = 1;
    319   let mayLoad = 0;
    320   let vdst = 0;
    321 }
    322 
    323 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
    324   op,
    325   (outs),
    326   (ins regClass:$vdata, i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
    327    i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
    328    SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
    329   asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
    330      #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
    331   []> {
    332   let mayStore = 1;
    333   let mayLoad = 0;
    334 }
    335 
    336 multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> {
    337 
    338   let glc = 0, lds = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */,
    339                                           mayLoad = 1 in {
    340 
    341   let offen = 1, idxen = 0, addr64 = 0, offset = 0 in {
    342     def _OFFEN  : MUBUF <op, (outs regClass:$vdata),
    343                          (ins SReg_128:$srsrc, VReg_32:$vaddr),
    344                          asm#" $vdata, $srsrc + $vaddr", []>;
    345   }
    346 
    347   let offen = 0, idxen = 1, addr64 = 0 in {
    348     def _IDXEN  : MUBUF <op, (outs regClass:$vdata),
    349                          (ins SReg_128:$srsrc, VReg_32:$vaddr, i16imm:$offset),
    350                          asm#" $vdata, $srsrc[$vaddr] + $offset", []>;
    351   }
    352 
    353   let offen = 0, idxen = 0, addr64 = 1 in {
    354     def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
    355                          (ins SReg_128:$srsrc, VReg_64:$vaddr, i16imm:$offset),
    356                          asm#" $vdata, $srsrc + $vaddr + $offset", []>;
    357   }
    358   }
    359 }
    360 
    361 class MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass,
    362                          ValueType VT> :
    363     MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr, i16imm:$offset),
    364           name#" $vdata, $srsrc + $vaddr + $offset",
    365          []> {
    366 
    367   let mayLoad = 0;
    368   let mayStore = 1;
    369 
    370   // Encoding
    371   let offen = 0;
    372   let idxen = 0;
    373   let glc = 0;
    374   let addr64 = 1;
    375   let lds = 0;
    376   let slc = 0;
    377   let tfe = 0;
    378   let soffset = 128; // ZERO
    379 }
    380 
    381 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
    382   op,
    383   (outs regClass:$dst),
    384   (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
    385        i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
    386        i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
    387   asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
    388      #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
    389   []> {
    390   let mayLoad = 1;
    391   let mayStore = 0;
    392 }
    393 
    394 class MIMG_NoSampler_Helper <bits<7> op, string asm> : MIMG <
    395   op,
    396   (outs VReg_128:$vdata),
    397   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
    398        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, unknown:$vaddr,
    399        SReg_256:$srsrc),
    400   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
    401      #" $tfe, $lwe, $slc, $vaddr, $srsrc",
    402   []> {
    403   let SSAMP = 0;
    404   let mayLoad = 1;
    405   let mayStore = 0;
    406   let hasPostISelHook = 1;
    407 }
    408 
    409 class MIMG_Sampler_Helper <bits<7> op, string asm> : MIMG <
    410   op,
    411   (outs VReg_128:$vdata),
    412   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
    413        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, unknown:$vaddr,
    414        SReg_256:$srsrc, SReg_128:$ssamp),
    415   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
    416      #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
    417   []> {
    418   let mayLoad = 1;
    419   let mayStore = 0;
    420   let hasPostISelHook = 1;
    421 }
    422 
    423 //===----------------------------------------------------------------------===//
    424 // Vector instruction mappings
    425 //===----------------------------------------------------------------------===//
    426 
    427 // Maps an opcode in e32 form to its e64 equivalent
    428 def getVOPe64 : InstrMapping {
    429   let FilterClass = "VOP";
    430   let RowFields = ["OpName"];
    431   let ColFields = ["Size"];
    432   let KeyCol = ["4"];
    433   let ValueCols = [["8"]];
    434 }
    435 
    436 // Maps an original opcode to its commuted version
    437 def getCommuteRev : InstrMapping {
    438   let FilterClass = "VOP2_REV";
    439   let RowFields = ["RevOp"];
    440   let ColFields = ["IsOrig"];
    441   let KeyCol = ["1"];
    442   let ValueCols = [["0"]];
    443 }
    444 
    445 // Maps an commuted opcode to its original version
    446 def getCommuteOrig : InstrMapping {
    447   let FilterClass = "VOP2_REV";
    448   let RowFields = ["RevOp"];
    449   let ColFields = ["IsOrig"];
    450   let KeyCol = ["0"];
    451   let ValueCols = [["1"]];
    452 }
    453 
    454 // Test if the supplied opcode is an MIMG instruction
    455 def isMIMG : InstrMapping {
    456   let FilterClass = "MIMG";
    457   let RowFields = ["Inst"];
    458   let ColFields = ["Size"];
    459   let KeyCol = ["8"];
    460   let ValueCols = [["8"]];
    461 }
    462 
    463 include "SIInstructions.td"
    464