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 // Transformation function, extract the upper 32bit of a 64bit immediate 25 def HI32 : SDNodeXForm<imm, [{ 26 return CurDAG->getTargetConstant(N->getZExtValue() >> 32, MVT::i32); 27 }]>; 28 29 def IMM8bitDWORD : ImmLeaf < 30 i32, [{ 31 return (Imm & ~0x3FC) == 0; 32 }], SDNodeXForm<imm, [{ 33 return CurDAG->getTargetConstant( 34 N->getZExtValue() >> 2, MVT::i32); 35 }]> 36 >; 37 38 def IMM12bit : ImmLeaf < 39 i16, 40 [{return isUInt<12>(Imm);}] 41 >; 42 43 class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{ 44 return ((const SITargetLowering &)TLI).analyzeImmediate(N) == 0; 45 }]>; 46 47 //===----------------------------------------------------------------------===// 48 // SI assembler operands 49 //===----------------------------------------------------------------------===// 50 51 def SIOperand { 52 int ZERO = 0x80; 53 int VCC = 0x6A; 54 } 55 56 include "SIInstrFormats.td" 57 58 //===----------------------------------------------------------------------===// 59 // 60 // SI Instruction multiclass helpers. 61 // 62 // Instructions with _32 take 32-bit operands. 63 // Instructions with _64 take 64-bit operands. 64 // 65 // VOP_* instructions can use either a 32-bit or 64-bit encoding. The 32-bit 66 // encoding is the standard encoding, but instruction that make use of 67 // any of the instruction modifiers must use the 64-bit encoding. 68 // 69 // Instructions with _e32 use the 32-bit encoding. 70 // Instructions with _e64 use the 64-bit encoding. 71 // 72 //===----------------------------------------------------------------------===// 73 74 //===----------------------------------------------------------------------===// 75 // Scalar classes 76 //===----------------------------------------------------------------------===// 77 78 class SOP1_32 <bits<8> op, string opName, list<dag> pattern> : SOP1 < 79 op, (outs SReg_32:$dst), (ins SSrc_32:$src0), 80 opName#" $dst, $src0", pattern 81 >; 82 83 class SOP1_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 < 84 op, (outs SReg_64:$dst), (ins SSrc_64:$src0), 85 opName#" $dst, $src0", pattern 86 >; 87 88 class SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 < 89 op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1), 90 opName#" $dst, $src0, $src1", pattern 91 >; 92 93 class SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 < 94 op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1), 95 opName#" $dst, $src0, $src1", pattern 96 >; 97 98 class SOPC_32 <bits<7> op, string opName, list<dag> pattern> : SOPC < 99 op, (outs SCCReg:$dst), (ins SSrc_32:$src0, SSrc_32:$src1), 100 opName#" $dst, $src0, $src1", pattern 101 >; 102 103 class SOPC_64 <bits<7> op, string opName, list<dag> pattern> : SOPC < 104 op, (outs SCCReg:$dst), (ins SSrc_64:$src0, SSrc_64:$src1), 105 opName#" $dst, $src0, $src1", pattern 106 >; 107 108 class SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK < 109 op, (outs SReg_32:$dst), (ins i16imm:$src0), 110 opName#" $dst, $src0", pattern 111 >; 112 113 class SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK < 114 op, (outs SReg_64:$dst), (ins i16imm:$src0), 115 opName#" $dst, $src0", pattern 116 >; 117 118 multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass, 119 RegisterClass dstClass> { 120 def _IMM : SMRD < 121 op, 1, (outs dstClass:$dst), 122 (ins baseClass:$sbase, i32imm:$offset), 123 asm#" $dst, $sbase, $offset", [] 124 >; 125 126 def _SGPR : SMRD < 127 op, 0, (outs dstClass:$dst), 128 (ins baseClass:$sbase, SReg_32:$soff), 129 asm#" $dst, $sbase, $soff", [] 130 >; 131 } 132 133 //===----------------------------------------------------------------------===// 134 // Vector ALU classes 135 //===----------------------------------------------------------------------===// 136 137 class VOP <string opName> { 138 string OpName = opName; 139 } 140 141 multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src, 142 string opName, list<dag> pattern> { 143 144 def _e32 : VOP1 < 145 op, (outs drc:$dst), (ins src:$src0), 146 opName#"_e32 $dst, $src0", pattern 147 >, VOP <opName>; 148 149 def _e64 : VOP3 < 150 {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}}, 151 (outs drc:$dst), 152 (ins src:$src0, 153 i32imm:$abs, i32imm:$clamp, 154 i32imm:$omod, i32imm:$neg), 155 opName#"_e64 $dst, $src0, $abs, $clamp, $omod, $neg", [] 156 >, VOP <opName> { 157 let SRC1 = SIOperand.ZERO; 158 let SRC2 = SIOperand.ZERO; 159 } 160 } 161 162 multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern> 163 : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>; 164 165 multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern> 166 : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>; 167 168 multiclass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc, 169 string opName, list<dag> pattern> { 170 def _e32 : VOP2 < 171 op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1), 172 opName#"_e32 $dst, $src0, $src1", pattern 173 >, VOP <opName>; 174 175 def _e64 : VOP3 < 176 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}}, 177 (outs vrc:$dst), 178 (ins arc:$src0, arc:$src1, 179 i32imm:$abs, i32imm:$clamp, 180 i32imm:$omod, i32imm:$neg), 181 opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", [] 182 >, VOP <opName> { 183 let SRC2 = SIOperand.ZERO; 184 } 185 } 186 187 multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern> 188 : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern>; 189 190 multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern> 191 : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern>; 192 193 multiclass VOP2b_32 <bits<6> op, string opName, list<dag> pattern> { 194 195 def _e32 : VOP2 < 196 op, (outs VReg_32:$dst), (ins VSrc_32:$src0, VReg_32:$src1), 197 opName#"_e32 $dst, $src0, $src1", pattern 198 >, VOP <opName>; 199 200 def _e64 : VOP3b < 201 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}}, 202 (outs VReg_32:$dst), 203 (ins VSrc_32:$src0, VSrc_32:$src1, 204 i32imm:$abs, i32imm:$clamp, 205 i32imm:$omod, i32imm:$neg), 206 opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", [] 207 >, VOP <opName> { 208 let SRC2 = SIOperand.ZERO; 209 /* the VOP2 variant puts the carry out into VCC, the VOP3 variant 210 can write it into any SGPR. We currently don't use the carry out, 211 so for now hardcode it to VCC as well */ 212 let SDST = SIOperand.VCC; 213 } 214 } 215 216 multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc, 217 string opName, ValueType vt, PatLeaf cond> { 218 219 def _e32 : VOPC < 220 op, (ins arc:$src0, vrc:$src1), 221 opName#"_e32 $dst, $src0, $src1", [] 222 >, VOP <opName>; 223 224 def _e64 : VOP3 < 225 {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}}, 226 (outs SReg_64:$dst), 227 (ins arc:$src0, arc:$src1, 228 InstFlag:$abs, InstFlag:$clamp, 229 InstFlag:$omod, InstFlag:$neg), 230 opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", 231 !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>, 232 [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))] 233 ) 234 >, VOP <opName> { 235 let SRC2 = SIOperand.ZERO; 236 } 237 } 238 239 multiclass VOPC_32 <bits<8> op, string opName, 240 ValueType vt = untyped, PatLeaf cond = COND_NULL> 241 : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>; 242 243 multiclass VOPC_64 <bits<8> op, string opName, 244 ValueType vt = untyped, PatLeaf cond = COND_NULL> 245 : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>; 246 247 class VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3 < 248 op, (outs VReg_32:$dst), 249 (ins VSrc_32:$src0, VSrc_32:$src1, VSrc_32:$src2, 250 i32imm:$abs, i32imm:$clamp, i32imm:$omod, i32imm:$neg), 251 opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern 252 >, VOP <opName>; 253 254 class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 < 255 op, (outs VReg_64:$dst), 256 (ins VSrc_64:$src0, VSrc_64:$src1, VSrc_64:$src2, 257 i32imm:$abs, i32imm:$clamp, i32imm:$omod, i32imm:$neg), 258 opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern 259 >, VOP <opName>; 260 261 //===----------------------------------------------------------------------===// 262 // Vector I/O classes 263 //===----------------------------------------------------------------------===// 264 265 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF < 266 op, 267 (outs), 268 (ins regClass:$vdata, i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, 269 i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, 270 SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset), 271 asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt," 272 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", 273 []> { 274 let mayStore = 1; 275 let mayLoad = 0; 276 } 277 278 class MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> : MUBUF < 279 op, 280 (outs regClass:$dst), 281 (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64, 282 i1imm:$lds, VReg_32:$vaddr, SReg_128:$srsrc, i1imm:$slc, 283 i1imm:$tfe, SSrc_32:$soffset), 284 asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, " 285 #"$lds, $vaddr, $srsrc, $slc, $tfe, $soffset", 286 []> { 287 let mayLoad = 1; 288 let mayStore = 0; 289 } 290 291 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF < 292 op, 293 (outs regClass:$dst), 294 (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64, 295 i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc, 296 i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset), 297 asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt," 298 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", 299 []> { 300 let mayLoad = 1; 301 let mayStore = 0; 302 } 303 304 class MIMG_Load_Helper <bits<7> op, string asm> : MIMG < 305 op, 306 (outs VReg_128:$vdata), 307 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128, 308 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, VReg_32:$vaddr, 309 SReg_256:$srsrc, SReg_128:$ssamp), 310 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128," 311 #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp", 312 []> { 313 let mayLoad = 1; 314 let mayStore = 0; 315 } 316 317 //===----------------------------------------------------------------------===// 318 // Vector instruction mappings 319 //===----------------------------------------------------------------------===// 320 321 // Maps an opcode in e32 form to its e64 equivalent 322 def getVOPe64 : InstrMapping { 323 let FilterClass = "VOP"; 324 let RowFields = ["OpName"]; 325 let ColFields = ["Size"]; 326 let KeyCol = ["4"]; 327 let ValueCols = [["8"]]; 328 } 329 330 include "SIInstructions.td" 331