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