R600Instructions.td revision 249423
1//===-- R600Instructions.td - R600 Instruction defs -------*- 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// R600 Tablegen instruction definitions 11// 12//===----------------------------------------------------------------------===// 13 14include "R600Intrinsics.td" 15 16class InstR600 <bits<11> inst, dag outs, dag ins, string asm, list<dag> pattern, 17 InstrItinClass itin> 18 : AMDGPUInst <outs, ins, asm, pattern> { 19 20 field bits<64> Inst; 21 bit Trig = 0; 22 bit Op3 = 0; 23 bit isVector = 0; 24 bits<2> FlagOperandIdx = 0; 25 bit Op1 = 0; 26 bit Op2 = 0; 27 bit HasNativeOperands = 0; 28 29 bits<11> op_code = inst; 30 //let Inst = inst; 31 let Namespace = "AMDGPU"; 32 let OutOperandList = outs; 33 let InOperandList = ins; 34 let AsmString = asm; 35 let Pattern = pattern; 36 let Itinerary = itin; 37 38 let TSFlags{4} = Trig; 39 let TSFlags{5} = Op3; 40 41 // Vector instructions are instructions that must fill all slots in an 42 // instruction group 43 let TSFlags{6} = isVector; 44 let TSFlags{8-7} = FlagOperandIdx; 45 let TSFlags{9} = HasNativeOperands; 46 let TSFlags{10} = Op1; 47 let TSFlags{11} = Op2; 48} 49 50class InstR600ISA <dag outs, dag ins, string asm, list<dag> pattern> : 51 AMDGPUInst <outs, ins, asm, pattern> { 52 field bits<64> Inst; 53 54 let Namespace = "AMDGPU"; 55} 56 57def MEMxi : Operand<iPTR> { 58 let MIOperandInfo = (ops R600_TReg32_X:$ptr, i32imm:$index); 59 let PrintMethod = "printMemOperand"; 60} 61 62def MEMrr : Operand<iPTR> { 63 let MIOperandInfo = (ops R600_Reg32:$ptr, R600_Reg32:$index); 64} 65 66// Operands for non-registers 67 68class InstFlag<string PM = "printOperand", int Default = 0> 69 : OperandWithDefaultOps <i32, (ops (i32 Default))> { 70 let PrintMethod = PM; 71} 72 73// src_sel for ALU src operands, see also ALU_CONST, ALU_PARAM registers 74def SEL : OperandWithDefaultOps <i32, (ops (i32 -1))> { 75 let PrintMethod = "printSel"; 76} 77 78def LITERAL : InstFlag<"printLiteral">; 79 80def WRITE : InstFlag <"printWrite", 1>; 81def OMOD : InstFlag <"printOMOD">; 82def REL : InstFlag <"printRel">; 83def CLAMP : InstFlag <"printClamp">; 84def NEG : InstFlag <"printNeg">; 85def ABS : InstFlag <"printAbs">; 86def UEM : InstFlag <"printUpdateExecMask">; 87def UP : InstFlag <"printUpdatePred">; 88 89// XXX: The r600g finalizer in Mesa expects last to be one in most cases. 90// Once we start using the packetizer in this backend we should have this 91// default to 0. 92def LAST : InstFlag<"printLast", 1>; 93 94def FRAMEri : Operand<iPTR> { 95 let MIOperandInfo = (ops R600_Reg32:$ptr, i32imm:$index); 96} 97 98def ADDRParam : ComplexPattern<i32, 2, "SelectADDRParam", [], []>; 99def ADDRDWord : ComplexPattern<i32, 1, "SelectADDRDWord", [], []>; 100def ADDRVTX_READ : ComplexPattern<i32, 2, "SelectADDRVTX_READ", [], []>; 101def ADDRGA_CONST_OFFSET : ComplexPattern<i32, 1, "SelectGlobalValueConstantOffset", [], []>; 102def ADDRGA_VAR_OFFSET : ComplexPattern<i32, 2, "SelectGlobalValueVariableOffset", [], []>; 103def ADDRIndirect : ComplexPattern<iPTR, 2, "SelectADDRIndirect", [], []>; 104 105class R600ALU_Word0 { 106 field bits<32> Word0; 107 108 bits<11> src0; 109 bits<1> src0_neg; 110 bits<1> src0_rel; 111 bits<11> src1; 112 bits<1> src1_rel; 113 bits<1> src1_neg; 114 bits<3> index_mode = 0; 115 bits<2> pred_sel; 116 bits<1> last; 117 118 bits<9> src0_sel = src0{8-0}; 119 bits<2> src0_chan = src0{10-9}; 120 bits<9> src1_sel = src1{8-0}; 121 bits<2> src1_chan = src1{10-9}; 122 123 let Word0{8-0} = src0_sel; 124 let Word0{9} = src0_rel; 125 let Word0{11-10} = src0_chan; 126 let Word0{12} = src0_neg; 127 let Word0{21-13} = src1_sel; 128 let Word0{22} = src1_rel; 129 let Word0{24-23} = src1_chan; 130 let Word0{25} = src1_neg; 131 let Word0{28-26} = index_mode; 132 let Word0{30-29} = pred_sel; 133 let Word0{31} = last; 134} 135 136class R600ALU_Word1 { 137 field bits<32> Word1; 138 139 bits<11> dst; 140 bits<3> bank_swizzle = 0; 141 bits<1> dst_rel; 142 bits<1> clamp; 143 144 bits<7> dst_sel = dst{6-0}; 145 bits<2> dst_chan = dst{10-9}; 146 147 let Word1{20-18} = bank_swizzle; 148 let Word1{27-21} = dst_sel; 149 let Word1{28} = dst_rel; 150 let Word1{30-29} = dst_chan; 151 let Word1{31} = clamp; 152} 153 154class R600ALU_Word1_OP2 <bits<11> alu_inst> : R600ALU_Word1{ 155 156 bits<1> src0_abs; 157 bits<1> src1_abs; 158 bits<1> update_exec_mask; 159 bits<1> update_pred; 160 bits<1> write; 161 bits<2> omod; 162 163 let Word1{0} = src0_abs; 164 let Word1{1} = src1_abs; 165 let Word1{2} = update_exec_mask; 166 let Word1{3} = update_pred; 167 let Word1{4} = write; 168 let Word1{6-5} = omod; 169 let Word1{17-7} = alu_inst; 170} 171 172class R600ALU_Word1_OP3 <bits<5> alu_inst> : R600ALU_Word1{ 173 174 bits<11> src2; 175 bits<1> src2_rel; 176 bits<1> src2_neg; 177 178 bits<9> src2_sel = src2{8-0}; 179 bits<2> src2_chan = src2{10-9}; 180 181 let Word1{8-0} = src2_sel; 182 let Word1{9} = src2_rel; 183 let Word1{11-10} = src2_chan; 184 let Word1{12} = src2_neg; 185 let Word1{17-13} = alu_inst; 186} 187 188class VTX_WORD0 { 189 field bits<32> Word0; 190 bits<7> SRC_GPR; 191 bits<5> VC_INST; 192 bits<2> FETCH_TYPE; 193 bits<1> FETCH_WHOLE_QUAD; 194 bits<8> BUFFER_ID; 195 bits<1> SRC_REL; 196 bits<2> SRC_SEL_X; 197 bits<6> MEGA_FETCH_COUNT; 198 199 let Word0{4-0} = VC_INST; 200 let Word0{6-5} = FETCH_TYPE; 201 let Word0{7} = FETCH_WHOLE_QUAD; 202 let Word0{15-8} = BUFFER_ID; 203 let Word0{22-16} = SRC_GPR; 204 let Word0{23} = SRC_REL; 205 let Word0{25-24} = SRC_SEL_X; 206 let Word0{31-26} = MEGA_FETCH_COUNT; 207} 208 209class VTX_WORD1_GPR { 210 field bits<32> Word1; 211 bits<7> DST_GPR; 212 bits<1> DST_REL; 213 bits<3> DST_SEL_X; 214 bits<3> DST_SEL_Y; 215 bits<3> DST_SEL_Z; 216 bits<3> DST_SEL_W; 217 bits<1> USE_CONST_FIELDS; 218 bits<6> DATA_FORMAT; 219 bits<2> NUM_FORMAT_ALL; 220 bits<1> FORMAT_COMP_ALL; 221 bits<1> SRF_MODE_ALL; 222 223 let Word1{6-0} = DST_GPR; 224 let Word1{7} = DST_REL; 225 let Word1{8} = 0; // Reserved 226 let Word1{11-9} = DST_SEL_X; 227 let Word1{14-12} = DST_SEL_Y; 228 let Word1{17-15} = DST_SEL_Z; 229 let Word1{20-18} = DST_SEL_W; 230 let Word1{21} = USE_CONST_FIELDS; 231 let Word1{27-22} = DATA_FORMAT; 232 let Word1{29-28} = NUM_FORMAT_ALL; 233 let Word1{30} = FORMAT_COMP_ALL; 234 let Word1{31} = SRF_MODE_ALL; 235} 236 237class TEX_WORD0 { 238 field bits<32> Word0; 239 240 bits<5> TEX_INST; 241 bits<2> INST_MOD; 242 bits<1> FETCH_WHOLE_QUAD; 243 bits<8> RESOURCE_ID; 244 bits<7> SRC_GPR; 245 bits<1> SRC_REL; 246 bits<1> ALT_CONST; 247 bits<2> RESOURCE_INDEX_MODE; 248 bits<2> SAMPLER_INDEX_MODE; 249 250 let Word0{4-0} = TEX_INST; 251 let Word0{6-5} = INST_MOD; 252 let Word0{7} = FETCH_WHOLE_QUAD; 253 let Word0{15-8} = RESOURCE_ID; 254 let Word0{22-16} = SRC_GPR; 255 let Word0{23} = SRC_REL; 256 let Word0{24} = ALT_CONST; 257 let Word0{26-25} = RESOURCE_INDEX_MODE; 258 let Word0{28-27} = SAMPLER_INDEX_MODE; 259} 260 261class TEX_WORD1 { 262 field bits<32> Word1; 263 264 bits<7> DST_GPR; 265 bits<1> DST_REL; 266 bits<3> DST_SEL_X; 267 bits<3> DST_SEL_Y; 268 bits<3> DST_SEL_Z; 269 bits<3> DST_SEL_W; 270 bits<7> LOD_BIAS; 271 bits<1> COORD_TYPE_X; 272 bits<1> COORD_TYPE_Y; 273 bits<1> COORD_TYPE_Z; 274 bits<1> COORD_TYPE_W; 275 276 let Word1{6-0} = DST_GPR; 277 let Word1{7} = DST_REL; 278 let Word1{11-9} = DST_SEL_X; 279 let Word1{14-12} = DST_SEL_Y; 280 let Word1{17-15} = DST_SEL_Z; 281 let Word1{20-18} = DST_SEL_W; 282 let Word1{27-21} = LOD_BIAS; 283 let Word1{28} = COORD_TYPE_X; 284 let Word1{29} = COORD_TYPE_Y; 285 let Word1{30} = COORD_TYPE_Z; 286 let Word1{31} = COORD_TYPE_W; 287} 288 289class TEX_WORD2 { 290 field bits<32> Word2; 291 292 bits<5> OFFSET_X; 293 bits<5> OFFSET_Y; 294 bits<5> OFFSET_Z; 295 bits<5> SAMPLER_ID; 296 bits<3> SRC_SEL_X; 297 bits<3> SRC_SEL_Y; 298 bits<3> SRC_SEL_Z; 299 bits<3> SRC_SEL_W; 300 301 let Word2{4-0} = OFFSET_X; 302 let Word2{9-5} = OFFSET_Y; 303 let Word2{14-10} = OFFSET_Z; 304 let Word2{19-15} = SAMPLER_ID; 305 let Word2{22-20} = SRC_SEL_X; 306 let Word2{25-23} = SRC_SEL_Y; 307 let Word2{28-26} = SRC_SEL_Z; 308 let Word2{31-29} = SRC_SEL_W; 309} 310 311/* 312XXX: R600 subtarget uses a slightly different encoding than the other 313subtargets. We currently handle this in R600MCCodeEmitter, but we may 314want to use these instruction classes in the future. 315 316class R600ALU_Word1_OP2_r600 : R600ALU_Word1_OP2 { 317 318 bits<1> fog_merge; 319 bits<10> alu_inst; 320 321 let Inst{37} = fog_merge; 322 let Inst{39-38} = omod; 323 let Inst{49-40} = alu_inst; 324} 325 326class R600ALU_Word1_OP2_r700 : R600ALU_Word1_OP2 { 327 328 bits<11> alu_inst; 329 330 let Inst{38-37} = omod; 331 let Inst{49-39} = alu_inst; 332} 333*/ 334 335def R600_Pred : PredicateOperand<i32, (ops R600_Predicate), 336 (ops PRED_SEL_OFF)>; 337 338 339let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 340 341// Class for instructions with only one source register. 342// If you add new ins to this instruction, make sure they are listed before 343// $literal, because the backend currently assumes that the last operand is 344// a literal. Also be sure to update the enum R600Op1OperandIndex::ROI in 345// R600Defines.h, R600InstrInfo::buildDefaultInstruction(), 346// and R600InstrInfo::getOperandIdx(). 347class R600_1OP <bits<11> inst, string opName, list<dag> pattern, 348 InstrItinClass itin = AnyALU> : 349 InstR600 <0, 350 (outs R600_Reg32:$dst), 351 (ins WRITE:$write, OMOD:$omod, REL:$dst_rel, CLAMP:$clamp, 352 R600_Reg32:$src0, NEG:$src0_neg, REL:$src0_rel, ABS:$src0_abs, SEL:$src0_sel, 353 LAST:$last, R600_Pred:$pred_sel, LITERAL:$literal), 354 !strconcat(" ", opName, 355 "$clamp $dst$write$dst_rel$omod, " 356 "$src0_neg$src0_abs$src0$src0_abs$src0_rel, " 357 "$literal $pred_sel$last"), 358 pattern, 359 itin>, 360 R600ALU_Word0, 361 R600ALU_Word1_OP2 <inst> { 362 363 let src1 = 0; 364 let src1_rel = 0; 365 let src1_neg = 0; 366 let src1_abs = 0; 367 let update_exec_mask = 0; 368 let update_pred = 0; 369 let HasNativeOperands = 1; 370 let Op1 = 1; 371 let DisableEncoding = "$literal"; 372 373 let Inst{31-0} = Word0; 374 let Inst{63-32} = Word1; 375} 376 377class R600_1OP_Helper <bits<11> inst, string opName, SDPatternOperator node, 378 InstrItinClass itin = AnyALU> : 379 R600_1OP <inst, opName, 380 [(set R600_Reg32:$dst, (node R600_Reg32:$src0))] 381>; 382 383// If you add our change the operands for R600_2OP instructions, you must 384// also update the R600Op2OperandIndex::ROI enum in R600Defines.h, 385// R600InstrInfo::buildDefaultInstruction(), and R600InstrInfo::getOperandIdx(). 386class R600_2OP <bits<11> inst, string opName, list<dag> pattern, 387 InstrItinClass itin = AnyALU> : 388 InstR600 <inst, 389 (outs R600_Reg32:$dst), 390 (ins UEM:$update_exec_mask, UP:$update_pred, WRITE:$write, 391 OMOD:$omod, REL:$dst_rel, CLAMP:$clamp, 392 R600_Reg32:$src0, NEG:$src0_neg, REL:$src0_rel, ABS:$src0_abs, SEL:$src0_sel, 393 R600_Reg32:$src1, NEG:$src1_neg, REL:$src1_rel, ABS:$src1_abs, SEL:$src1_sel, 394 LAST:$last, R600_Pred:$pred_sel, LITERAL:$literal), 395 !strconcat(" ", opName, 396 "$clamp $update_exec_mask$update_pred$dst$write$dst_rel$omod, " 397 "$src0_neg$src0_abs$src0$src0_abs$src0_rel, " 398 "$src1_neg$src1_abs$src1$src1_abs$src1_rel, " 399 "$literal $pred_sel$last"), 400 pattern, 401 itin>, 402 R600ALU_Word0, 403 R600ALU_Word1_OP2 <inst> { 404 405 let HasNativeOperands = 1; 406 let Op2 = 1; 407 let DisableEncoding = "$literal"; 408 409 let Inst{31-0} = Word0; 410 let Inst{63-32} = Word1; 411} 412 413class R600_2OP_Helper <bits<11> inst, string opName, SDPatternOperator node, 414 InstrItinClass itim = AnyALU> : 415 R600_2OP <inst, opName, 416 [(set R600_Reg32:$dst, (node R600_Reg32:$src0, 417 R600_Reg32:$src1))] 418>; 419 420// If you add our change the operands for R600_3OP instructions, you must 421// also update the R600Op3OperandIndex::ROI enum in R600Defines.h, 422// R600InstrInfo::buildDefaultInstruction(), and 423// R600InstrInfo::getOperandIdx(). 424class R600_3OP <bits<5> inst, string opName, list<dag> pattern, 425 InstrItinClass itin = AnyALU> : 426 InstR600 <0, 427 (outs R600_Reg32:$dst), 428 (ins REL:$dst_rel, CLAMP:$clamp, 429 R600_Reg32:$src0, NEG:$src0_neg, REL:$src0_rel, SEL:$src0_sel, 430 R600_Reg32:$src1, NEG:$src1_neg, REL:$src1_rel, SEL:$src1_sel, 431 R600_Reg32:$src2, NEG:$src2_neg, REL:$src2_rel, SEL:$src2_sel, 432 LAST:$last, R600_Pred:$pred_sel, LITERAL:$literal), 433 !strconcat(" ", opName, "$clamp $dst$dst_rel, " 434 "$src0_neg$src0$src0_rel, " 435 "$src1_neg$src1$src1_rel, " 436 "$src2_neg$src2$src2_rel, " 437 "$literal $pred_sel$last"), 438 pattern, 439 itin>, 440 R600ALU_Word0, 441 R600ALU_Word1_OP3<inst>{ 442 443 let HasNativeOperands = 1; 444 let DisableEncoding = "$literal"; 445 let Op3 = 1; 446 447 let Inst{31-0} = Word0; 448 let Inst{63-32} = Word1; 449} 450 451class R600_REDUCTION <bits<11> inst, dag ins, string asm, list<dag> pattern, 452 InstrItinClass itin = VecALU> : 453 InstR600 <inst, 454 (outs R600_Reg32:$dst), 455 ins, 456 asm, 457 pattern, 458 itin>; 459 460class R600_TEX <bits<11> inst, string opName, list<dag> pattern, 461 InstrItinClass itin = AnyALU> : 462 InstR600 <inst, 463 (outs R600_Reg128:$DST_GPR), 464 (ins R600_Reg128:$SRC_GPR, i32imm:$RESOURCE_ID, i32imm:$SAMPLER_ID, i32imm:$textureTarget), 465 !strconcat(opName, "$DST_GPR, $SRC_GPR, $RESOURCE_ID, $SAMPLER_ID, $textureTarget"), 466 pattern, 467 itin>, TEX_WORD0, TEX_WORD1, TEX_WORD2 { 468 let Inst{31-0} = Word0; 469 let Inst{63-32} = Word1; 470 471 let TEX_INST = inst{4-0}; 472 let SRC_REL = 0; 473 let DST_REL = 0; 474 let DST_SEL_X = 0; 475 let DST_SEL_Y = 1; 476 let DST_SEL_Z = 2; 477 let DST_SEL_W = 3; 478 let LOD_BIAS = 0; 479 480 let INST_MOD = 0; 481 let FETCH_WHOLE_QUAD = 0; 482 let ALT_CONST = 0; 483 let SAMPLER_INDEX_MODE = 0; 484 485 let COORD_TYPE_X = 0; 486 let COORD_TYPE_Y = 0; 487 let COORD_TYPE_Z = 0; 488 let COORD_TYPE_W = 0; 489 } 490 491} // End mayLoad = 1, mayStore = 0, hasSideEffects = 0 492 493def TEX_SHADOW : PatLeaf< 494 (imm), 495 [{uint32_t TType = (uint32_t)N->getZExtValue(); 496 return (TType >= 6 && TType <= 8) || (TType >= 11 && TType <= 13); 497 }] 498>; 499 500def TEX_RECT : PatLeaf< 501 (imm), 502 [{uint32_t TType = (uint32_t)N->getZExtValue(); 503 return TType == 5; 504 }] 505>; 506 507def TEX_ARRAY : PatLeaf< 508 (imm), 509 [{uint32_t TType = (uint32_t)N->getZExtValue(); 510 return TType == 9 || TType == 10 || TType == 15 || TType == 16; 511 }] 512>; 513 514def TEX_SHADOW_ARRAY : PatLeaf< 515 (imm), 516 [{uint32_t TType = (uint32_t)N->getZExtValue(); 517 return TType == 11 || TType == 12 || TType == 17; 518 }] 519>; 520 521class EG_CF_RAT <bits <8> cf_inst, bits <6> rat_inst, bits<4> rat_id, dag outs, 522 dag ins, string asm, list<dag> pattern> : 523 InstR600ISA <outs, ins, asm, pattern> { 524 bits<7> RW_GPR; 525 bits<7> INDEX_GPR; 526 527 bits<2> RIM; 528 bits<2> TYPE; 529 bits<1> RW_REL; 530 bits<2> ELEM_SIZE; 531 532 bits<12> ARRAY_SIZE; 533 bits<4> COMP_MASK; 534 bits<4> BURST_COUNT; 535 bits<1> VPM; 536 bits<1> eop; 537 bits<1> MARK; 538 bits<1> BARRIER; 539 540 // CF_ALLOC_EXPORT_WORD0_RAT 541 let Inst{3-0} = rat_id; 542 let Inst{9-4} = rat_inst; 543 let Inst{10} = 0; // Reserved 544 let Inst{12-11} = RIM; 545 let Inst{14-13} = TYPE; 546 let Inst{21-15} = RW_GPR; 547 let Inst{22} = RW_REL; 548 let Inst{29-23} = INDEX_GPR; 549 let Inst{31-30} = ELEM_SIZE; 550 551 // CF_ALLOC_EXPORT_WORD1_BUF 552 let Inst{43-32} = ARRAY_SIZE; 553 let Inst{47-44} = COMP_MASK; 554 let Inst{51-48} = BURST_COUNT; 555 let Inst{52} = VPM; 556 let Inst{53} = eop; 557 let Inst{61-54} = cf_inst; 558 let Inst{62} = MARK; 559 let Inst{63} = BARRIER; 560} 561 562class LoadParamFrag <PatFrag load_type> : PatFrag < 563 (ops node:$ptr), (load_type node:$ptr), 564 [{ return isParamLoad(dyn_cast<LoadSDNode>(N)); }] 565>; 566 567def load_param : LoadParamFrag<load>; 568def load_param_zexti8 : LoadParamFrag<zextloadi8>; 569def load_param_zexti16 : LoadParamFrag<zextloadi16>; 570 571def isR600 : Predicate<"Subtarget.device()" 572 "->getGeneration() == AMDGPUDeviceInfo::HD4XXX">; 573def isR700 : Predicate<"Subtarget.device()" 574 "->getGeneration() == AMDGPUDeviceInfo::HD4XXX &&" 575 "Subtarget.device()->getDeviceFlag()" 576 ">= OCL_DEVICE_RV710">; 577def isEG : Predicate< 578 "Subtarget.device()->getGeneration() >= AMDGPUDeviceInfo::HD5XXX && " 579 "Subtarget.device()->getGeneration() < AMDGPUDeviceInfo::HD7XXX && " 580 "Subtarget.device()->getDeviceFlag() != OCL_DEVICE_CAYMAN">; 581 582def isCayman : Predicate<"Subtarget.device()" 583 "->getDeviceFlag() == OCL_DEVICE_CAYMAN">; 584def isEGorCayman : Predicate<"Subtarget.device()" 585 "->getGeneration() == AMDGPUDeviceInfo::HD5XXX" 586 "|| Subtarget.device()->getGeneration() ==" 587 "AMDGPUDeviceInfo::HD6XXX">; 588 589def isR600toCayman : Predicate< 590 "Subtarget.device()->getGeneration() <= AMDGPUDeviceInfo::HD6XXX">; 591 592//===----------------------------------------------------------------------===// 593// R600 SDNodes 594//===----------------------------------------------------------------------===// 595 596def INTERP_PAIR_XY : AMDGPUShaderInst < 597 (outs R600_TReg32_X:$dst0, R600_TReg32_Y:$dst1), 598 (ins i32imm:$src0, R600_Reg32:$src1, R600_Reg32:$src2), 599 "INTERP_PAIR_XY $src0 $src1 $src2 : $dst0 dst1", 600 []>; 601 602def INTERP_PAIR_ZW : AMDGPUShaderInst < 603 (outs R600_TReg32_Z:$dst0, R600_TReg32_W:$dst1), 604 (ins i32imm:$src0, R600_Reg32:$src1, R600_Reg32:$src2), 605 "INTERP_PAIR_ZW $src0 $src1 $src2 : $dst0 dst1", 606 []>; 607 608def CONST_ADDRESS: SDNode<"AMDGPUISD::CONST_ADDRESS", 609 SDTypeProfile<1, -1, [SDTCisInt<0>, SDTCisPtrTy<1>]>, 610 [SDNPVariadic] 611>; 612 613//===----------------------------------------------------------------------===// 614// Interpolation Instructions 615//===----------------------------------------------------------------------===// 616 617def INTERP_VEC_LOAD : AMDGPUShaderInst < 618 (outs R600_Reg128:$dst), 619 (ins i32imm:$src0), 620 "INTERP_LOAD $src0 : $dst", 621 []>; 622 623def INTERP_XY : R600_2OP <0xD6, "INTERP_XY", []> { 624 let bank_swizzle = 5; 625} 626 627def INTERP_ZW : R600_2OP <0xD7, "INTERP_ZW", []> { 628 let bank_swizzle = 5; 629} 630 631def INTERP_LOAD_P0 : R600_1OP <0xE0, "INTERP_LOAD_P0", []>; 632 633//===----------------------------------------------------------------------===// 634// Export Instructions 635//===----------------------------------------------------------------------===// 636 637def ExportType : SDTypeProfile<0, 7, [SDTCisFP<0>, SDTCisInt<1>]>; 638 639def EXPORT: SDNode<"AMDGPUISD::EXPORT", ExportType, 640 [SDNPHasChain, SDNPSideEffect]>; 641 642class ExportWord0 { 643 field bits<32> Word0; 644 645 bits<13> arraybase; 646 bits<2> type; 647 bits<7> gpr; 648 bits<2> elem_size; 649 650 let Word0{12-0} = arraybase; 651 let Word0{14-13} = type; 652 let Word0{21-15} = gpr; 653 let Word0{22} = 0; // RW_REL 654 let Word0{29-23} = 0; // INDEX_GPR 655 let Word0{31-30} = elem_size; 656} 657 658class ExportSwzWord1 { 659 field bits<32> Word1; 660 661 bits<3> sw_x; 662 bits<3> sw_y; 663 bits<3> sw_z; 664 bits<3> sw_w; 665 bits<1> eop; 666 bits<8> inst; 667 668 let Word1{2-0} = sw_x; 669 let Word1{5-3} = sw_y; 670 let Word1{8-6} = sw_z; 671 let Word1{11-9} = sw_w; 672} 673 674class ExportBufWord1 { 675 field bits<32> Word1; 676 677 bits<12> arraySize; 678 bits<4> compMask; 679 bits<1> eop; 680 bits<8> inst; 681 682 let Word1{11-0} = arraySize; 683 let Word1{15-12} = compMask; 684} 685 686multiclass ExportPattern<Instruction ExportInst, bits<8> cf_inst> { 687 def : Pat<(int_R600_store_pixel_depth R600_Reg32:$reg), 688 (ExportInst 689 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), R600_Reg32:$reg, sub0), 690 0, 61, 0, 7, 7, 7, cf_inst, 0) 691 >; 692 693 def : Pat<(int_R600_store_pixel_stencil R600_Reg32:$reg), 694 (ExportInst 695 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), R600_Reg32:$reg, sub0), 696 0, 61, 7, 0, 7, 7, cf_inst, 0) 697 >; 698 699 def : Pat<(int_R600_store_dummy (i32 imm:$type)), 700 (ExportInst 701 (v4f32 (IMPLICIT_DEF)), imm:$type, 0, 7, 7, 7, 7, cf_inst, 0) 702 >; 703 704 def : Pat<(int_R600_store_dummy 1), 705 (ExportInst 706 (v4f32 (IMPLICIT_DEF)), 1, 60, 7, 7, 7, 7, cf_inst, 0) 707 >; 708 709 def : Pat<(EXPORT (v4f32 R600_Reg128:$src), (i32 imm:$base), (i32 imm:$type), 710 (i32 imm:$swz_x), (i32 imm:$swz_y), (i32 imm:$swz_z), (i32 imm:$swz_w)), 711 (ExportInst R600_Reg128:$src, imm:$type, imm:$base, 712 imm:$swz_x, imm:$swz_y, imm:$swz_z, imm:$swz_w, cf_inst, 0) 713 >; 714 715} 716 717multiclass SteamOutputExportPattern<Instruction ExportInst, 718 bits<8> buf0inst, bits<8> buf1inst, bits<8> buf2inst, bits<8> buf3inst> { 719// Stream0 720 def : Pat<(int_R600_store_stream_output (v4f32 R600_Reg128:$src), 721 (i32 imm:$arraybase), (i32 0), (i32 imm:$mask)), 722 (ExportInst R600_Reg128:$src, 0, imm:$arraybase, 723 4095, imm:$mask, buf0inst, 0)>; 724// Stream1 725 def : Pat<(int_R600_store_stream_output (v4f32 R600_Reg128:$src), 726 (i32 imm:$arraybase), (i32 1), (i32 imm:$mask)), 727 (ExportInst R600_Reg128:$src, 0, imm:$arraybase, 728 4095, imm:$mask, buf1inst, 0)>; 729// Stream2 730 def : Pat<(int_R600_store_stream_output (v4f32 R600_Reg128:$src), 731 (i32 imm:$arraybase), (i32 2), (i32 imm:$mask)), 732 (ExportInst R600_Reg128:$src, 0, imm:$arraybase, 733 4095, imm:$mask, buf2inst, 0)>; 734// Stream3 735 def : Pat<(int_R600_store_stream_output (v4f32 R600_Reg128:$src), 736 (i32 imm:$arraybase), (i32 3), (i32 imm:$mask)), 737 (ExportInst R600_Reg128:$src, 0, imm:$arraybase, 738 4095, imm:$mask, buf3inst, 0)>; 739} 740 741let usesCustomInserter = 1 in { 742 743class ExportSwzInst : InstR600ISA<( 744 outs), 745 (ins R600_Reg128:$gpr, i32imm:$type, i32imm:$arraybase, 746 i32imm:$sw_x, i32imm:$sw_y, i32imm:$sw_z, i32imm:$sw_w, i32imm:$inst, 747 i32imm:$eop), 748 !strconcat("EXPORT", " $gpr"), 749 []>, ExportWord0, ExportSwzWord1 { 750 let elem_size = 3; 751 let Inst{31-0} = Word0; 752 let Inst{63-32} = Word1; 753} 754 755} // End usesCustomInserter = 1 756 757class ExportBufInst : InstR600ISA<( 758 outs), 759 (ins R600_Reg128:$gpr, i32imm:$type, i32imm:$arraybase, 760 i32imm:$arraySize, i32imm:$compMask, i32imm:$inst, i32imm:$eop), 761 !strconcat("EXPORT", " $gpr"), 762 []>, ExportWord0, ExportBufWord1 { 763 let elem_size = 0; 764 let Inst{31-0} = Word0; 765 let Inst{63-32} = Word1; 766} 767 768//===----------------------------------------------------------------------===// 769// Control Flow Instructions 770//===----------------------------------------------------------------------===// 771 772class CF_ALU_WORD0 { 773 field bits<32> Word0; 774 775 bits<22> ADDR; 776 bits<4> KCACHE_BANK0; 777 bits<4> KCACHE_BANK1; 778 bits<2> KCACHE_MODE0; 779 780 let Word0{21-0} = ADDR; 781 let Word0{25-22} = KCACHE_BANK0; 782 let Word0{29-26} = KCACHE_BANK1; 783 let Word0{31-30} = KCACHE_MODE0; 784} 785 786class CF_ALU_WORD1 { 787 field bits<32> Word1; 788 789 bits<2> KCACHE_MODE1; 790 bits<8> KCACHE_ADDR0; 791 bits<8> KCACHE_ADDR1; 792 bits<7> COUNT; 793 bits<1> ALT_CONST; 794 bits<4> CF_INST; 795 bits<1> WHOLE_QUAD_MODE; 796 bits<1> BARRIER; 797 798 let Word1{1-0} = KCACHE_MODE1; 799 let Word1{9-2} = KCACHE_ADDR0; 800 let Word1{17-10} = KCACHE_ADDR1; 801 let Word1{24-18} = COUNT; 802 let Word1{25} = ALT_CONST; 803 let Word1{29-26} = CF_INST; 804 let Word1{30} = WHOLE_QUAD_MODE; 805 let Word1{31} = BARRIER; 806} 807 808class ALU_CLAUSE<bits<4> inst, string OpName> : AMDGPUInst <(outs), 809(ins i32imm:$ADDR, i32imm:$KCACHE_BANK0, i32imm:$KCACHE_BANK1, i32imm:$KCACHE_MODE0, i32imm:$KCACHE_MODE1, 810i32imm:$KCACHE_ADDR0, i32imm:$KCACHE_ADDR1, i32imm:$COUNT), 811!strconcat(OpName, " $COUNT, @$ADDR, " 812"KC0[CB$KCACHE_BANK0:$KCACHE_ADDR0-$KCACHE_ADDR0+32]" 813", KC1[CB$KCACHE_BANK1:$KCACHE_ADDR1-$KCACHE_ADDR1+32]"), 814[] >, CF_ALU_WORD0, CF_ALU_WORD1 { 815 field bits<64> Inst; 816 817 let CF_INST = inst; 818 let ALT_CONST = 0; 819 let WHOLE_QUAD_MODE = 0; 820 let BARRIER = 1; 821 822 let Inst{31-0} = Word0; 823 let Inst{63-32} = Word1; 824} 825 826class CF_WORD0 { 827 field bits<32> Word0; 828 829 bits<24> ADDR; 830 bits<3> JUMPTABLE_SEL; 831 832 let Word0{23-0} = ADDR; 833 let Word0{26-24} = JUMPTABLE_SEL; 834} 835 836class CF_WORD1 { 837 field bits<32> Word1; 838 839 bits<3> POP_COUNT; 840 bits<5> CF_CONST; 841 bits<2> COND; 842 bits<6> COUNT; 843 bits<1> VALID_PIXEL_MODE; 844 bits<8> CF_INST; 845 bits<1> BARRIER; 846 847 let Word1{2-0} = POP_COUNT; 848 let Word1{7-3} = CF_CONST; 849 let Word1{9-8} = COND; 850 let Word1{15-10} = COUNT; 851 let Word1{20} = VALID_PIXEL_MODE; 852 let Word1{29-22} = CF_INST; 853 let Word1{31} = BARRIER; 854} 855 856class CF_CLAUSE <bits<8> inst, dag ins, string AsmPrint> : AMDGPUInst <(outs), 857ins, AsmPrint, [] >, CF_WORD0, CF_WORD1 { 858 field bits<64> Inst; 859 860 let CF_INST = inst; 861 let BARRIER = 1; 862 let JUMPTABLE_SEL = 0; 863 let CF_CONST = 0; 864 let VALID_PIXEL_MODE = 0; 865 let COND = 0; 866 867 let Inst{31-0} = Word0; 868 let Inst{63-32} = Word1; 869} 870 871def CF_TC : CF_CLAUSE<1, (ins i32imm:$ADDR, i32imm:$COUNT), 872"TEX $COUNT @$ADDR"> { 873 let POP_COUNT = 0; 874} 875 876def CF_VC : CF_CLAUSE<2, (ins i32imm:$ADDR, i32imm:$COUNT), 877"VTX $COUNT @$ADDR"> { 878 let POP_COUNT = 0; 879} 880 881def WHILE_LOOP : CF_CLAUSE<6, (ins i32imm:$ADDR), "LOOP_START_DX10 @$ADDR"> { 882 let POP_COUNT = 0; 883 let COUNT = 0; 884} 885 886def END_LOOP : CF_CLAUSE<5, (ins i32imm:$ADDR), "END_LOOP @$ADDR"> { 887 let POP_COUNT = 0; 888 let COUNT = 0; 889} 890 891def LOOP_BREAK : CF_CLAUSE<9, (ins i32imm:$ADDR), "LOOP_BREAK @$ADDR"> { 892 let POP_COUNT = 0; 893 let COUNT = 0; 894} 895 896def CF_CONTINUE : CF_CLAUSE<8, (ins i32imm:$ADDR), "CONTINUE @$ADDR"> { 897 let POP_COUNT = 0; 898 let COUNT = 0; 899} 900 901def CF_JUMP : CF_CLAUSE<10, (ins i32imm:$ADDR, i32imm:$POP_COUNT), "JUMP @$ADDR POP:$POP_COUNT"> { 902 let COUNT = 0; 903} 904 905def CF_ELSE : CF_CLAUSE<13, (ins i32imm:$ADDR, i32imm:$POP_COUNT), "ELSE @$ADDR POP:$POP_COUNT"> { 906 let COUNT = 0; 907} 908 909def CF_CALL_FS : CF_CLAUSE<19, (ins), "CALL_FS"> { 910 let ADDR = 0; 911 let COUNT = 0; 912 let POP_COUNT = 0; 913} 914 915def POP : CF_CLAUSE<14, (ins i32imm:$ADDR, i32imm:$POP_COUNT), "POP @$ADDR POP:$POP_COUNT"> { 916 let COUNT = 0; 917} 918 919def CF_ALU : ALU_CLAUSE<8, "ALU">; 920def CF_ALU_PUSH_BEFORE : ALU_CLAUSE<9, "ALU_PUSH_BEFORE">; 921 922def STACK_SIZE : AMDGPUInst <(outs), 923(ins i32imm:$num), "nstack $num", [] > { 924 field bits<8> Inst; 925 bits<8> num; 926 let Inst = num; 927} 928 929let Predicates = [isR600toCayman] in { 930 931//===----------------------------------------------------------------------===// 932// Common Instructions R600, R700, Evergreen, Cayman 933//===----------------------------------------------------------------------===// 934 935def ADD : R600_2OP_Helper <0x0, "ADD", fadd>; 936// Non-IEEE MUL: 0 * anything = 0 937def MUL : R600_2OP_Helper <0x1, "MUL NON-IEEE", int_AMDGPU_mul>; 938def MUL_IEEE : R600_2OP_Helper <0x2, "MUL_IEEE", fmul>; 939def MAX : R600_2OP_Helper <0x3, "MAX", AMDGPUfmax>; 940def MIN : R600_2OP_Helper <0x4, "MIN", AMDGPUfmin>; 941 942// For the SET* instructions there is a naming conflict in TargetSelectionDAG.td, 943// so some of the instruction names don't match the asm string. 944// XXX: Use the defs in TargetSelectionDAG.td instead of intrinsics. 945def SETE : R600_2OP < 946 0x08, "SETE", 947 [(set R600_Reg32:$dst, 948 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO, 949 COND_EQ))] 950>; 951 952def SGT : R600_2OP < 953 0x09, "SETGT", 954 [(set R600_Reg32:$dst, 955 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO, 956 COND_GT))] 957>; 958 959def SGE : R600_2OP < 960 0xA, "SETGE", 961 [(set R600_Reg32:$dst, 962 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO, 963 COND_GE))] 964>; 965 966def SNE : R600_2OP < 967 0xB, "SETNE", 968 [(set R600_Reg32:$dst, 969 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO, 970 COND_NE))] 971>; 972 973def SETE_DX10 : R600_2OP < 974 0xC, "SETE_DX10", 975 [(set R600_Reg32:$dst, 976 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, (i32 -1), (i32 0), 977 COND_EQ))] 978>; 979 980def SETGT_DX10 : R600_2OP < 981 0xD, "SETGT_DX10", 982 [(set R600_Reg32:$dst, 983 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, (i32 -1), (i32 0), 984 COND_GT))] 985>; 986 987def SETGE_DX10 : R600_2OP < 988 0xE, "SETGE_DX10", 989 [(set R600_Reg32:$dst, 990 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, (i32 -1), (i32 0), 991 COND_GE))] 992>; 993 994def SETNE_DX10 : R600_2OP < 995 0xF, "SETNE_DX10", 996 [(set R600_Reg32:$dst, 997 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, (i32 -1), (i32 0), 998 COND_NE))] 999>; 1000 1001def FRACT : R600_1OP_Helper <0x10, "FRACT", AMDGPUfract>; 1002def TRUNC : R600_1OP_Helper <0x11, "TRUNC", int_AMDGPU_trunc>; 1003def CEIL : R600_1OP_Helper <0x12, "CEIL", fceil>; 1004def RNDNE : R600_1OP_Helper <0x13, "RNDNE", frint>; 1005def FLOOR : R600_1OP_Helper <0x14, "FLOOR", ffloor>; 1006 1007def MOV : R600_1OP <0x19, "MOV", []>; 1008 1009let isPseudo = 1, isCodeGenOnly = 1, usesCustomInserter = 1 in { 1010 1011class MOV_IMM <ValueType vt, Operand immType> : AMDGPUInst < 1012 (outs R600_Reg32:$dst), 1013 (ins immType:$imm), 1014 "", 1015 [] 1016>; 1017 1018} // end let isPseudo = 1, isCodeGenOnly = 1, usesCustomInserter = 1 1019 1020def MOV_IMM_I32 : MOV_IMM<i32, i32imm>; 1021def : Pat < 1022 (imm:$val), 1023 (MOV_IMM_I32 imm:$val) 1024>; 1025 1026def MOV_IMM_F32 : MOV_IMM<f32, f32imm>; 1027def : Pat < 1028 (fpimm:$val), 1029 (MOV_IMM_F32 fpimm:$val) 1030>; 1031 1032def PRED_SETE : R600_2OP <0x20, "PRED_SETE", []>; 1033def PRED_SETGT : R600_2OP <0x21, "PRED_SETGT", []>; 1034def PRED_SETGE : R600_2OP <0x22, "PRED_SETGE", []>; 1035def PRED_SETNE : R600_2OP <0x23, "PRED_SETNE", []>; 1036 1037let hasSideEffects = 1 in { 1038 1039def KILLGT : R600_2OP <0x2D, "KILLGT", []>; 1040 1041} // end hasSideEffects 1042 1043def AND_INT : R600_2OP_Helper <0x30, "AND_INT", and>; 1044def OR_INT : R600_2OP_Helper <0x31, "OR_INT", or>; 1045def XOR_INT : R600_2OP_Helper <0x32, "XOR_INT", xor>; 1046def NOT_INT : R600_1OP_Helper <0x33, "NOT_INT", not>; 1047def ADD_INT : R600_2OP_Helper <0x34, "ADD_INT", add>; 1048def SUB_INT : R600_2OP_Helper <0x35, "SUB_INT", sub>; 1049def MAX_INT : R600_2OP_Helper <0x36, "MAX_INT", AMDGPUsmax>; 1050def MIN_INT : R600_2OP_Helper <0x37, "MIN_INT", AMDGPUsmin>; 1051def MAX_UINT : R600_2OP_Helper <0x38, "MAX_UINT", AMDGPUumax>; 1052def MIN_UINT : R600_2OP_Helper <0x39, "MIN_UINT", AMDGPUumin>; 1053 1054def SETE_INT : R600_2OP < 1055 0x3A, "SETE_INT", 1056 [(set (i32 R600_Reg32:$dst), 1057 (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETEQ))] 1058>; 1059 1060def SETGT_INT : R600_2OP < 1061 0x3B, "SETGT_INT", 1062 [(set (i32 R600_Reg32:$dst), 1063 (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETGT))] 1064>; 1065 1066def SETGE_INT : R600_2OP < 1067 0x3C, "SETGE_INT", 1068 [(set (i32 R600_Reg32:$dst), 1069 (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETGE))] 1070>; 1071 1072def SETNE_INT : R600_2OP < 1073 0x3D, "SETNE_INT", 1074 [(set (i32 R600_Reg32:$dst), 1075 (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETNE))] 1076>; 1077 1078def SETGT_UINT : R600_2OP < 1079 0x3E, "SETGT_UINT", 1080 [(set (i32 R600_Reg32:$dst), 1081 (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETUGT))] 1082>; 1083 1084def SETGE_UINT : R600_2OP < 1085 0x3F, "SETGE_UINT", 1086 [(set (i32 R600_Reg32:$dst), 1087 (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETUGE))] 1088>; 1089 1090def PRED_SETE_INT : R600_2OP <0x42, "PRED_SETE_INT", []>; 1091def PRED_SETGT_INT : R600_2OP <0x43, "PRED_SETGE_INT", []>; 1092def PRED_SETGE_INT : R600_2OP <0x44, "PRED_SETGE_INT", []>; 1093def PRED_SETNE_INT : R600_2OP <0x45, "PRED_SETNE_INT", []>; 1094 1095def CNDE_INT : R600_3OP < 1096 0x1C, "CNDE_INT", 1097 [(set (i32 R600_Reg32:$dst), 1098 (selectcc (i32 R600_Reg32:$src0), 0, 1099 (i32 R600_Reg32:$src1), (i32 R600_Reg32:$src2), 1100 COND_EQ))] 1101>; 1102 1103def CNDGE_INT : R600_3OP < 1104 0x1E, "CNDGE_INT", 1105 [(set (i32 R600_Reg32:$dst), 1106 (selectcc (i32 R600_Reg32:$src0), 0, 1107 (i32 R600_Reg32:$src1), (i32 R600_Reg32:$src2), 1108 COND_GE))] 1109>; 1110 1111def CNDGT_INT : R600_3OP < 1112 0x1D, "CNDGT_INT", 1113 [(set (i32 R600_Reg32:$dst), 1114 (selectcc (i32 R600_Reg32:$src0), 0, 1115 (i32 R600_Reg32:$src1), (i32 R600_Reg32:$src2), 1116 COND_GT))] 1117>; 1118 1119//===----------------------------------------------------------------------===// 1120// Texture instructions 1121//===----------------------------------------------------------------------===// 1122 1123def TEX_LD : R600_TEX < 1124 0x03, "TEX_LD", 1125 [(set R600_Reg128:$DST_GPR, (int_AMDGPU_txf R600_Reg128:$SRC_GPR, 1126 imm:$OFFSET_X, imm:$OFFSET_Y, imm:$OFFSET_Z, imm:$RESOURCE_ID, 1127 imm:$SAMPLER_ID, imm:$textureTarget))] 1128> { 1129let AsmString = "TEX_LD $DST_GPR, $SRC_GPR, $OFFSET_X, $OFFSET_Y, $OFFSET_Z," 1130 "$RESOURCE_ID, $SAMPLER_ID, $textureTarget"; 1131let InOperandList = (ins R600_Reg128:$SRC_GPR, i32imm:$OFFSET_X, 1132 i32imm:$OFFSET_Y, i32imm:$OFFSET_Z, i32imm:$RESOURCE_ID, i32imm:$SAMPLER_ID, 1133 i32imm:$textureTarget); 1134} 1135 1136def TEX_GET_TEXTURE_RESINFO : R600_TEX < 1137 0x04, "TEX_GET_TEXTURE_RESINFO", 1138 [(set R600_Reg128:$DST_GPR, (int_AMDGPU_txq R600_Reg128:$SRC_GPR, 1139 imm:$RESOURCE_ID, imm:$SAMPLER_ID, imm:$textureTarget))] 1140>; 1141 1142def TEX_GET_GRADIENTS_H : R600_TEX < 1143 0x07, "TEX_GET_GRADIENTS_H", 1144 [(set R600_Reg128:$DST_GPR, (int_AMDGPU_ddx R600_Reg128:$SRC_GPR, 1145 imm:$RESOURCE_ID, imm:$SAMPLER_ID, imm:$textureTarget))] 1146>; 1147 1148def TEX_GET_GRADIENTS_V : R600_TEX < 1149 0x08, "TEX_GET_GRADIENTS_V", 1150 [(set R600_Reg128:$DST_GPR, (int_AMDGPU_ddy R600_Reg128:$SRC_GPR, 1151 imm:$RESOURCE_ID, imm:$SAMPLER_ID, imm:$textureTarget))] 1152>; 1153 1154def TEX_SET_GRADIENTS_H : R600_TEX < 1155 0x0B, "TEX_SET_GRADIENTS_H", 1156 [] 1157>; 1158 1159def TEX_SET_GRADIENTS_V : R600_TEX < 1160 0x0C, "TEX_SET_GRADIENTS_V", 1161 [] 1162>; 1163 1164def TEX_SAMPLE : R600_TEX < 1165 0x10, "TEX_SAMPLE", 1166 [(set R600_Reg128:$DST_GPR, (int_AMDGPU_tex R600_Reg128:$SRC_GPR, 1167 imm:$RESOURCE_ID, imm:$SAMPLER_ID, imm:$textureTarget))] 1168>; 1169 1170def TEX_SAMPLE_C : R600_TEX < 1171 0x18, "TEX_SAMPLE_C", 1172 [(set R600_Reg128:$DST_GPR, (int_AMDGPU_tex R600_Reg128:$SRC_GPR, 1173 imm:$RESOURCE_ID, imm:$SAMPLER_ID, TEX_SHADOW:$textureTarget))] 1174>; 1175 1176def TEX_SAMPLE_L : R600_TEX < 1177 0x11, "TEX_SAMPLE_L", 1178 [(set R600_Reg128:$DST_GPR, (int_AMDGPU_txl R600_Reg128:$SRC_GPR, 1179 imm:$RESOURCE_ID, imm:$SAMPLER_ID, imm:$textureTarget))] 1180>; 1181 1182def TEX_SAMPLE_C_L : R600_TEX < 1183 0x19, "TEX_SAMPLE_C_L", 1184 [(set R600_Reg128:$DST_GPR, (int_AMDGPU_txl R600_Reg128:$SRC_GPR, 1185 imm:$RESOURCE_ID, imm:$SAMPLER_ID, TEX_SHADOW:$textureTarget))] 1186>; 1187 1188def TEX_SAMPLE_LB : R600_TEX < 1189 0x12, "TEX_SAMPLE_LB", 1190 [(set R600_Reg128:$DST_GPR, (int_AMDGPU_txb R600_Reg128:$SRC_GPR, 1191 imm:$RESOURCE_ID, imm:$SAMPLER_ID, imm:$textureTarget))] 1192>; 1193 1194def TEX_SAMPLE_C_LB : R600_TEX < 1195 0x1A, "TEX_SAMPLE_C_LB", 1196 [(set R600_Reg128:$DST_GPR, (int_AMDGPU_txb R600_Reg128:$SRC_GPR, 1197 imm:$RESOURCE_ID, imm:$SAMPLER_ID, TEX_SHADOW:$textureTarget))] 1198>; 1199 1200def TEX_SAMPLE_G : R600_TEX < 1201 0x14, "TEX_SAMPLE_G", 1202 [] 1203>; 1204 1205def TEX_SAMPLE_C_G : R600_TEX < 1206 0x1C, "TEX_SAMPLE_C_G", 1207 [] 1208>; 1209 1210//===----------------------------------------------------------------------===// 1211// Helper classes for common instructions 1212//===----------------------------------------------------------------------===// 1213 1214class MUL_LIT_Common <bits<5> inst> : R600_3OP < 1215 inst, "MUL_LIT", 1216 [] 1217>; 1218 1219class MULADD_Common <bits<5> inst> : R600_3OP < 1220 inst, "MULADD", 1221 [] 1222>; 1223 1224class MULADD_IEEE_Common <bits<5> inst> : R600_3OP < 1225 inst, "MULADD_IEEE", 1226 [(set (f32 R600_Reg32:$dst), 1227 (fadd (fmul R600_Reg32:$src0, R600_Reg32:$src1), R600_Reg32:$src2))] 1228>; 1229 1230class CNDE_Common <bits<5> inst> : R600_3OP < 1231 inst, "CNDE", 1232 [(set R600_Reg32:$dst, 1233 (selectcc (f32 R600_Reg32:$src0), FP_ZERO, 1234 (f32 R600_Reg32:$src1), (f32 R600_Reg32:$src2), 1235 COND_EQ))] 1236>; 1237 1238class CNDGT_Common <bits<5> inst> : R600_3OP < 1239 inst, "CNDGT", 1240 [(set R600_Reg32:$dst, 1241 (selectcc (f32 R600_Reg32:$src0), FP_ZERO, 1242 (f32 R600_Reg32:$src1), (f32 R600_Reg32:$src2), 1243 COND_GT))] 1244>; 1245 1246class CNDGE_Common <bits<5> inst> : R600_3OP < 1247 inst, "CNDGE", 1248 [(set R600_Reg32:$dst, 1249 (selectcc (f32 R600_Reg32:$src0), FP_ZERO, 1250 (f32 R600_Reg32:$src1), (f32 R600_Reg32:$src2), 1251 COND_GE))] 1252>; 1253 1254multiclass DOT4_Common <bits<11> inst> { 1255 1256 def _pseudo : R600_REDUCTION <inst, 1257 (ins R600_Reg128:$src0, R600_Reg128:$src1), 1258 "DOT4 $dst $src0, $src1", 1259 [(set R600_Reg32:$dst, (int_AMDGPU_dp4 R600_Reg128:$src0, R600_Reg128:$src1))] 1260 >; 1261 1262 def _real : R600_2OP <inst, "DOT4", []>; 1263} 1264 1265let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 1266multiclass CUBE_Common <bits<11> inst> { 1267 1268 def _pseudo : InstR600 < 1269 inst, 1270 (outs R600_Reg128:$dst), 1271 (ins R600_Reg128:$src), 1272 "CUBE $dst $src", 1273 [(set R600_Reg128:$dst, (int_AMDGPU_cube R600_Reg128:$src))], 1274 VecALU 1275 > { 1276 let isPseudo = 1; 1277 } 1278 1279 def _real : R600_2OP <inst, "CUBE", []>; 1280} 1281} // End mayLoad = 0, mayStore = 0, hasSideEffects = 0 1282 1283class EXP_IEEE_Common <bits<11> inst> : R600_1OP_Helper < 1284 inst, "EXP_IEEE", fexp2 1285>; 1286 1287class FLT_TO_INT_Common <bits<11> inst> : R600_1OP_Helper < 1288 inst, "FLT_TO_INT", fp_to_sint 1289>; 1290 1291class INT_TO_FLT_Common <bits<11> inst> : R600_1OP_Helper < 1292 inst, "INT_TO_FLT", sint_to_fp 1293>; 1294 1295class FLT_TO_UINT_Common <bits<11> inst> : R600_1OP_Helper < 1296 inst, "FLT_TO_UINT", fp_to_uint 1297>; 1298 1299class UINT_TO_FLT_Common <bits<11> inst> : R600_1OP_Helper < 1300 inst, "UINT_TO_FLT", uint_to_fp 1301>; 1302 1303class LOG_CLAMPED_Common <bits<11> inst> : R600_1OP < 1304 inst, "LOG_CLAMPED", [] 1305>; 1306 1307class LOG_IEEE_Common <bits<11> inst> : R600_1OP_Helper < 1308 inst, "LOG_IEEE", flog2 1309>; 1310 1311class LSHL_Common <bits<11> inst> : R600_2OP_Helper <inst, "LSHL", shl>; 1312class LSHR_Common <bits<11> inst> : R600_2OP_Helper <inst, "LSHR", srl>; 1313class ASHR_Common <bits<11> inst> : R600_2OP_Helper <inst, "ASHR", sra>; 1314class MULHI_INT_Common <bits<11> inst> : R600_2OP_Helper < 1315 inst, "MULHI_INT", mulhs 1316>; 1317class MULHI_UINT_Common <bits<11> inst> : R600_2OP_Helper < 1318 inst, "MULHI", mulhu 1319>; 1320class MULLO_INT_Common <bits<11> inst> : R600_2OP_Helper < 1321 inst, "MULLO_INT", mul 1322>; 1323class MULLO_UINT_Common <bits<11> inst> : R600_2OP <inst, "MULLO_UINT", []>; 1324 1325class RECIP_CLAMPED_Common <bits<11> inst> : R600_1OP < 1326 inst, "RECIP_CLAMPED", [] 1327>; 1328 1329class RECIP_IEEE_Common <bits<11> inst> : R600_1OP < 1330 inst, "RECIP_IEEE", [(set R600_Reg32:$dst, (fdiv FP_ONE, R600_Reg32:$src0))] 1331>; 1332 1333class RECIP_UINT_Common <bits<11> inst> : R600_1OP_Helper < 1334 inst, "RECIP_UINT", AMDGPUurecip 1335>; 1336 1337class RECIPSQRT_CLAMPED_Common <bits<11> inst> : R600_1OP_Helper < 1338 inst, "RECIPSQRT_CLAMPED", int_AMDGPU_rsq 1339>; 1340 1341class RECIPSQRT_IEEE_Common <bits<11> inst> : R600_1OP < 1342 inst, "RECIPSQRT_IEEE", [] 1343>; 1344 1345class SIN_Common <bits<11> inst> : R600_1OP < 1346 inst, "SIN", []>{ 1347 let Trig = 1; 1348} 1349 1350class COS_Common <bits<11> inst> : R600_1OP < 1351 inst, "COS", []> { 1352 let Trig = 1; 1353} 1354 1355//===----------------------------------------------------------------------===// 1356// Helper patterns for complex intrinsics 1357//===----------------------------------------------------------------------===// 1358 1359multiclass DIV_Common <InstR600 recip_ieee> { 1360def : Pat< 1361 (int_AMDGPU_div R600_Reg32:$src0, R600_Reg32:$src1), 1362 (MUL_IEEE R600_Reg32:$src0, (recip_ieee R600_Reg32:$src1)) 1363>; 1364 1365def : Pat< 1366 (fdiv R600_Reg32:$src0, R600_Reg32:$src1), 1367 (MUL_IEEE R600_Reg32:$src0, (recip_ieee R600_Reg32:$src1)) 1368>; 1369} 1370 1371class TGSI_LIT_Z_Common <InstR600 mul_lit, InstR600 log_clamped, InstR600 exp_ieee> : Pat < 1372 (int_TGSI_lit_z R600_Reg32:$src_x, R600_Reg32:$src_y, R600_Reg32:$src_w), 1373 (exp_ieee (mul_lit (log_clamped (MAX R600_Reg32:$src_y, (f32 ZERO))), R600_Reg32:$src_w, R600_Reg32:$src_x)) 1374>; 1375 1376//===----------------------------------------------------------------------===// 1377// R600 / R700 Instructions 1378//===----------------------------------------------------------------------===// 1379 1380let Predicates = [isR600] in { 1381 1382 def MUL_LIT_r600 : MUL_LIT_Common<0x0C>; 1383 def MULADD_r600 : MULADD_Common<0x10>; 1384 def MULADD_IEEE_r600 : MULADD_IEEE_Common<0x14>; 1385 def CNDE_r600 : CNDE_Common<0x18>; 1386 def CNDGT_r600 : CNDGT_Common<0x19>; 1387 def CNDGE_r600 : CNDGE_Common<0x1A>; 1388 defm DOT4_r600 : DOT4_Common<0x50>; 1389 defm CUBE_r600 : CUBE_Common<0x52>; 1390 def EXP_IEEE_r600 : EXP_IEEE_Common<0x61>; 1391 def LOG_CLAMPED_r600 : LOG_CLAMPED_Common<0x62>; 1392 def LOG_IEEE_r600 : LOG_IEEE_Common<0x63>; 1393 def RECIP_CLAMPED_r600 : RECIP_CLAMPED_Common<0x64>; 1394 def RECIP_IEEE_r600 : RECIP_IEEE_Common<0x66>; 1395 def RECIPSQRT_CLAMPED_r600 : RECIPSQRT_CLAMPED_Common<0x67>; 1396 def RECIPSQRT_IEEE_r600 : RECIPSQRT_IEEE_Common<0x69>; 1397 def FLT_TO_INT_r600 : FLT_TO_INT_Common<0x6b>; 1398 def INT_TO_FLT_r600 : INT_TO_FLT_Common<0x6c>; 1399 def FLT_TO_UINT_r600 : FLT_TO_UINT_Common<0x79>; 1400 def UINT_TO_FLT_r600 : UINT_TO_FLT_Common<0x6d>; 1401 def SIN_r600 : SIN_Common<0x6E>; 1402 def COS_r600 : COS_Common<0x6F>; 1403 def ASHR_r600 : ASHR_Common<0x70>; 1404 def LSHR_r600 : LSHR_Common<0x71>; 1405 def LSHL_r600 : LSHL_Common<0x72>; 1406 def MULLO_INT_r600 : MULLO_INT_Common<0x73>; 1407 def MULHI_INT_r600 : MULHI_INT_Common<0x74>; 1408 def MULLO_UINT_r600 : MULLO_UINT_Common<0x75>; 1409 def MULHI_UINT_r600 : MULHI_UINT_Common<0x76>; 1410 def RECIP_UINT_r600 : RECIP_UINT_Common <0x78>; 1411 1412 defm DIV_r600 : DIV_Common<RECIP_IEEE_r600>; 1413 def : POW_Common <LOG_IEEE_r600, EXP_IEEE_r600, MUL, R600_Reg32>; 1414 def TGSI_LIT_Z_r600 : TGSI_LIT_Z_Common<MUL_LIT_r600, LOG_CLAMPED_r600, EXP_IEEE_r600>; 1415 1416 def : Pat<(fsqrt R600_Reg32:$src), 1417 (MUL R600_Reg32:$src, (RECIPSQRT_CLAMPED_r600 R600_Reg32:$src))>; 1418 1419 def R600_ExportSwz : ExportSwzInst { 1420 let Word1{20-17} = 1; // BURST_COUNT 1421 let Word1{21} = eop; 1422 let Word1{22} = 1; // VALID_PIXEL_MODE 1423 let Word1{30-23} = inst; 1424 let Word1{31} = 1; // BARRIER 1425 } 1426 defm : ExportPattern<R600_ExportSwz, 39>; 1427 1428 def R600_ExportBuf : ExportBufInst { 1429 let Word1{20-17} = 1; // BURST_COUNT 1430 let Word1{21} = eop; 1431 let Word1{22} = 1; // VALID_PIXEL_MODE 1432 let Word1{30-23} = inst; 1433 let Word1{31} = 1; // BARRIER 1434 } 1435 defm : SteamOutputExportPattern<R600_ExportBuf, 0x20, 0x21, 0x22, 0x23>; 1436} 1437 1438// Helper pattern for normalizing inputs to triginomic instructions for R700+ 1439// cards. 1440class COS_PAT <InstR600 trig> : Pat< 1441 (fcos R600_Reg32:$src), 1442 (trig (MUL_IEEE (MOV_IMM_I32 CONST.TWO_PI_INV), R600_Reg32:$src)) 1443>; 1444 1445class SIN_PAT <InstR600 trig> : Pat< 1446 (fsin R600_Reg32:$src), 1447 (trig (MUL_IEEE (MOV_IMM_I32 CONST.TWO_PI_INV), R600_Reg32:$src)) 1448>; 1449 1450//===----------------------------------------------------------------------===// 1451// R700 Only instructions 1452//===----------------------------------------------------------------------===// 1453 1454let Predicates = [isR700] in { 1455 def SIN_r700 : SIN_Common<0x6E>; 1456 def COS_r700 : COS_Common<0x6F>; 1457 1458 // R700 normalizes inputs to SIN/COS the same as EG 1459 def : SIN_PAT <SIN_r700>; 1460 def : COS_PAT <COS_r700>; 1461} 1462 1463//===----------------------------------------------------------------------===// 1464// Evergreen Only instructions 1465//===----------------------------------------------------------------------===// 1466 1467let Predicates = [isEG] in { 1468 1469def RECIP_IEEE_eg : RECIP_IEEE_Common<0x86>; 1470defm DIV_eg : DIV_Common<RECIP_IEEE_eg>; 1471 1472def MULLO_INT_eg : MULLO_INT_Common<0x8F>; 1473def MULHI_INT_eg : MULHI_INT_Common<0x90>; 1474def MULLO_UINT_eg : MULLO_UINT_Common<0x91>; 1475def MULHI_UINT_eg : MULHI_UINT_Common<0x92>; 1476def RECIP_UINT_eg : RECIP_UINT_Common<0x94>; 1477def RECIPSQRT_CLAMPED_eg : RECIPSQRT_CLAMPED_Common<0x87>; 1478def EXP_IEEE_eg : EXP_IEEE_Common<0x81>; 1479def LOG_IEEE_eg : LOG_IEEE_Common<0x83>; 1480def RECIP_CLAMPED_eg : RECIP_CLAMPED_Common<0x84>; 1481def RECIPSQRT_IEEE_eg : RECIPSQRT_IEEE_Common<0x89>; 1482def SIN_eg : SIN_Common<0x8D>; 1483def COS_eg : COS_Common<0x8E>; 1484 1485def : POW_Common <LOG_IEEE_eg, EXP_IEEE_eg, MUL, R600_Reg32>; 1486def : SIN_PAT <SIN_eg>; 1487def : COS_PAT <COS_eg>; 1488def : Pat<(fsqrt R600_Reg32:$src), 1489 (MUL R600_Reg32:$src, (RECIPSQRT_CLAMPED_eg R600_Reg32:$src))>; 1490} // End Predicates = [isEG] 1491 1492//===----------------------------------------------------------------------===// 1493// Evergreen / Cayman Instructions 1494//===----------------------------------------------------------------------===// 1495 1496let Predicates = [isEGorCayman] in { 1497 1498 // BFE_UINT - bit_extract, an optimization for mask and shift 1499 // Src0 = Input 1500 // Src1 = Offset 1501 // Src2 = Width 1502 // 1503 // bit_extract = (Input << (32 - Offset - Width)) >> (32 - Width) 1504 // 1505 // Example Usage: 1506 // (Offset, Width) 1507 // 1508 // (0, 8) = (Input << 24) >> 24 = (Input & 0xff) >> 0 1509 // (8, 8) = (Input << 16) >> 24 = (Input & 0xffff) >> 8 1510 // (16,8) = (Input << 8) >> 24 = (Input & 0xffffff) >> 16 1511 // (24,8) = (Input << 0) >> 24 = (Input & 0xffffffff) >> 24 1512 def BFE_UINT_eg : R600_3OP <0x4, "BFE_UINT", 1513 [(set R600_Reg32:$dst, (int_AMDIL_bit_extract_u32 R600_Reg32:$src0, 1514 R600_Reg32:$src1, 1515 R600_Reg32:$src2))], 1516 VecALU 1517 >; 1518 1519 def BIT_ALIGN_INT_eg : R600_3OP <0xC, "BIT_ALIGN_INT", 1520 [(set R600_Reg32:$dst, (AMDGPUbitalign R600_Reg32:$src0, R600_Reg32:$src1, 1521 R600_Reg32:$src2))], 1522 VecALU 1523 >; 1524 1525 def MULADD_eg : MULADD_Common<0x14>; 1526 def MULADD_IEEE_eg : MULADD_IEEE_Common<0x18>; 1527 def ASHR_eg : ASHR_Common<0x15>; 1528 def LSHR_eg : LSHR_Common<0x16>; 1529 def LSHL_eg : LSHL_Common<0x17>; 1530 def CNDE_eg : CNDE_Common<0x19>; 1531 def CNDGT_eg : CNDGT_Common<0x1A>; 1532 def CNDGE_eg : CNDGE_Common<0x1B>; 1533 def MUL_LIT_eg : MUL_LIT_Common<0x1F>; 1534 def LOG_CLAMPED_eg : LOG_CLAMPED_Common<0x82>; 1535 defm DOT4_eg : DOT4_Common<0xBE>; 1536 defm CUBE_eg : CUBE_Common<0xC0>; 1537 1538let hasSideEffects = 1 in { 1539 def MOVA_INT_eg : R600_1OP <0xCC, "MOVA_INT", []>; 1540} 1541 1542 def TGSI_LIT_Z_eg : TGSI_LIT_Z_Common<MUL_LIT_eg, LOG_CLAMPED_eg, EXP_IEEE_eg>; 1543 1544 def FLT_TO_INT_eg : FLT_TO_INT_Common<0x50> { 1545 let Pattern = []; 1546 } 1547 1548 def INT_TO_FLT_eg : INT_TO_FLT_Common<0x9B>; 1549 1550 def FLT_TO_UINT_eg : FLT_TO_UINT_Common<0x9A> { 1551 let Pattern = []; 1552 } 1553 1554 def UINT_TO_FLT_eg : UINT_TO_FLT_Common<0x9C>; 1555 1556 // TRUNC is used for the FLT_TO_INT instructions to work around a 1557 // perceived problem where the rounding modes are applied differently 1558 // depending on the instruction and the slot they are in. 1559 // See: 1560 // https://bugs.freedesktop.org/show_bug.cgi?id=50232 1561 // Mesa commit: a1a0974401c467cb86ef818f22df67c21774a38c 1562 // 1563 // XXX: Lowering SELECT_CC will sometimes generate fp_to_[su]int nodes, 1564 // which do not need to be truncated since the fp values are 0.0f or 1.0f. 1565 // We should look into handling these cases separately. 1566 def : Pat<(fp_to_sint R600_Reg32:$src0), 1567 (FLT_TO_INT_eg (TRUNC R600_Reg32:$src0))>; 1568 1569 def : Pat<(fp_to_uint R600_Reg32:$src0), 1570 (FLT_TO_UINT_eg (TRUNC R600_Reg32:$src0))>; 1571 1572 def EG_ExportSwz : ExportSwzInst { 1573 let Word1{19-16} = 1; // BURST_COUNT 1574 let Word1{20} = 1; // VALID_PIXEL_MODE 1575 let Word1{21} = eop; 1576 let Word1{29-22} = inst; 1577 let Word1{30} = 0; // MARK 1578 let Word1{31} = 1; // BARRIER 1579 } 1580 defm : ExportPattern<EG_ExportSwz, 83>; 1581 1582 def EG_ExportBuf : ExportBufInst { 1583 let Word1{19-16} = 1; // BURST_COUNT 1584 let Word1{20} = 1; // VALID_PIXEL_MODE 1585 let Word1{21} = eop; 1586 let Word1{29-22} = inst; 1587 let Word1{30} = 0; // MARK 1588 let Word1{31} = 1; // BARRIER 1589 } 1590 defm : SteamOutputExportPattern<EG_ExportBuf, 0x40, 0x41, 0x42, 0x43>; 1591 1592//===----------------------------------------------------------------------===// 1593// Memory read/write instructions 1594//===----------------------------------------------------------------------===// 1595let usesCustomInserter = 1 in { 1596 1597class RAT_WRITE_CACHELESS_eg <dag ins, bits<4> comp_mask, string name, 1598 list<dag> pattern> 1599 : EG_CF_RAT <0x57, 0x2, 0, (outs), ins, 1600 !strconcat(name, " $rw_gpr, $index_gpr, $eop"), pattern> { 1601 let RIM = 0; 1602 // XXX: Have a separate instruction for non-indexed writes. 1603 let TYPE = 1; 1604 let RW_REL = 0; 1605 let ELEM_SIZE = 0; 1606 1607 let ARRAY_SIZE = 0; 1608 let COMP_MASK = comp_mask; 1609 let BURST_COUNT = 0; 1610 let VPM = 0; 1611 let MARK = 0; 1612 let BARRIER = 1; 1613} 1614 1615} // End usesCustomInserter = 1 1616 1617// 32-bit store 1618def RAT_WRITE_CACHELESS_32_eg : RAT_WRITE_CACHELESS_eg < 1619 (ins R600_TReg32_X:$rw_gpr, R600_TReg32_X:$index_gpr, InstFlag:$eop), 1620 0x1, "RAT_WRITE_CACHELESS_32_eg", 1621 [(global_store (i32 R600_TReg32_X:$rw_gpr), R600_TReg32_X:$index_gpr)] 1622>; 1623 1624//128-bit store 1625def RAT_WRITE_CACHELESS_128_eg : RAT_WRITE_CACHELESS_eg < 1626 (ins R600_Reg128:$rw_gpr, R600_TReg32_X:$index_gpr, InstFlag:$eop), 1627 0xf, "RAT_WRITE_CACHELESS_128", 1628 [(global_store (v4i32 R600_Reg128:$rw_gpr), R600_TReg32_X:$index_gpr)] 1629>; 1630 1631class VTX_READ_eg <string name, bits<8> buffer_id, dag outs, list<dag> pattern> 1632 : InstR600ISA <outs, (ins MEMxi:$ptr), name#" $dst, $ptr", pattern>, 1633 VTX_WORD1_GPR, VTX_WORD0 { 1634 1635 // Static fields 1636 let VC_INST = 0; 1637 let FETCH_TYPE = 2; 1638 let FETCH_WHOLE_QUAD = 0; 1639 let BUFFER_ID = buffer_id; 1640 let SRC_REL = 0; 1641 // XXX: We can infer this field based on the SRC_GPR. This would allow us 1642 // to store vertex addresses in any channel, not just X. 1643 let SRC_SEL_X = 0; 1644 let DST_REL = 0; 1645 // The docs say that if this bit is set, then DATA_FORMAT, NUM_FORMAT_ALL, 1646 // FORMAT_COMP_ALL, SRF_MODE_ALL, and ENDIAN_SWAP fields will be ignored, 1647 // however, based on my testing if USE_CONST_FIELDS is set, then all 1648 // these fields need to be set to 0. 1649 let USE_CONST_FIELDS = 0; 1650 let NUM_FORMAT_ALL = 1; 1651 let FORMAT_COMP_ALL = 0; 1652 let SRF_MODE_ALL = 0; 1653 1654 let Inst{31-0} = Word0; 1655 let Inst{63-32} = Word1; 1656 // LLVM can only encode 64-bit instructions, so these fields are manually 1657 // encoded in R600CodeEmitter 1658 // 1659 // bits<16> OFFSET; 1660 // bits<2> ENDIAN_SWAP = 0; 1661 // bits<1> CONST_BUF_NO_STRIDE = 0; 1662 // bits<1> MEGA_FETCH = 0; 1663 // bits<1> ALT_CONST = 0; 1664 // bits<2> BUFFER_INDEX_MODE = 0; 1665 1666 1667 1668 // VTX_WORD2 (LLVM can only encode 64-bit instructions, so WORD2 encoding 1669 // is done in R600CodeEmitter 1670 // 1671 // Inst{79-64} = OFFSET; 1672 // Inst{81-80} = ENDIAN_SWAP; 1673 // Inst{82} = CONST_BUF_NO_STRIDE; 1674 // Inst{83} = MEGA_FETCH; 1675 // Inst{84} = ALT_CONST; 1676 // Inst{86-85} = BUFFER_INDEX_MODE; 1677 // Inst{95-86} = 0; Reserved 1678 1679 // VTX_WORD3 (Padding) 1680 // 1681 // Inst{127-96} = 0; 1682} 1683 1684class VTX_READ_8_eg <bits<8> buffer_id, list<dag> pattern> 1685 : VTX_READ_eg <"VTX_READ_8", buffer_id, (outs R600_TReg32_X:$dst), 1686 pattern> { 1687 1688 let MEGA_FETCH_COUNT = 1; 1689 let DST_SEL_X = 0; 1690 let DST_SEL_Y = 7; // Masked 1691 let DST_SEL_Z = 7; // Masked 1692 let DST_SEL_W = 7; // Masked 1693 let DATA_FORMAT = 1; // FMT_8 1694} 1695 1696class VTX_READ_16_eg <bits<8> buffer_id, list<dag> pattern> 1697 : VTX_READ_eg <"VTX_READ_16", buffer_id, (outs R600_TReg32_X:$dst), 1698 pattern> { 1699 let MEGA_FETCH_COUNT = 2; 1700 let DST_SEL_X = 0; 1701 let DST_SEL_Y = 7; // Masked 1702 let DST_SEL_Z = 7; // Masked 1703 let DST_SEL_W = 7; // Masked 1704 let DATA_FORMAT = 5; // FMT_16 1705 1706} 1707 1708class VTX_READ_32_eg <bits<8> buffer_id, list<dag> pattern> 1709 : VTX_READ_eg <"VTX_READ_32", buffer_id, (outs R600_TReg32_X:$dst), 1710 pattern> { 1711 1712 let MEGA_FETCH_COUNT = 4; 1713 let DST_SEL_X = 0; 1714 let DST_SEL_Y = 7; // Masked 1715 let DST_SEL_Z = 7; // Masked 1716 let DST_SEL_W = 7; // Masked 1717 let DATA_FORMAT = 0xD; // COLOR_32 1718 1719 // This is not really necessary, but there were some GPU hangs that appeared 1720 // to be caused by ALU instructions in the next instruction group that wrote 1721 // to the $ptr registers of the VTX_READ. 1722 // e.g. 1723 // %T3_X<def> = VTX_READ_PARAM_32_eg %T2_X<kill>, 24 1724 // %T2_X<def> = MOV %ZERO 1725 //Adding this constraint prevents this from happening. 1726 let Constraints = "$ptr.ptr = $dst"; 1727} 1728 1729class VTX_READ_128_eg <bits<8> buffer_id, list<dag> pattern> 1730 : VTX_READ_eg <"VTX_READ_128", buffer_id, (outs R600_Reg128:$dst), 1731 pattern> { 1732 1733 let MEGA_FETCH_COUNT = 16; 1734 let DST_SEL_X = 0; 1735 let DST_SEL_Y = 1; 1736 let DST_SEL_Z = 2; 1737 let DST_SEL_W = 3; 1738 let DATA_FORMAT = 0x22; // COLOR_32_32_32_32 1739 1740 // XXX: Need to force VTX_READ_128 instructions to write to the same register 1741 // that holds its buffer address to avoid potential hangs. We can't use 1742 // the same constraint as VTX_READ_32_eg, because the $ptr.ptr and $dst 1743 // registers are different sizes. 1744} 1745 1746//===----------------------------------------------------------------------===// 1747// VTX Read from parameter memory space 1748//===----------------------------------------------------------------------===// 1749 1750def VTX_READ_PARAM_8_eg : VTX_READ_8_eg <0, 1751 [(set (i32 R600_TReg32_X:$dst), (load_param_zexti8 ADDRVTX_READ:$ptr))] 1752>; 1753 1754def VTX_READ_PARAM_16_eg : VTX_READ_16_eg <0, 1755 [(set (i32 R600_TReg32_X:$dst), (load_param_zexti16 ADDRVTX_READ:$ptr))] 1756>; 1757 1758def VTX_READ_PARAM_32_eg : VTX_READ_32_eg <0, 1759 [(set (i32 R600_TReg32_X:$dst), (load_param ADDRVTX_READ:$ptr))] 1760>; 1761 1762def VTX_READ_PARAM_128_eg : VTX_READ_128_eg <0, 1763 [(set (v4i32 R600_Reg128:$dst), (load_param ADDRVTX_READ:$ptr))] 1764>; 1765 1766//===----------------------------------------------------------------------===// 1767// VTX Read from global memory space 1768//===----------------------------------------------------------------------===// 1769 1770// 8-bit reads 1771def VTX_READ_GLOBAL_8_eg : VTX_READ_8_eg <1, 1772 [(set (i32 R600_TReg32_X:$dst), (zextloadi8_global ADDRVTX_READ:$ptr))] 1773>; 1774 1775// 32-bit reads 1776def VTX_READ_GLOBAL_32_eg : VTX_READ_32_eg <1, 1777 [(set (i32 R600_TReg32_X:$dst), (global_load ADDRVTX_READ:$ptr))] 1778>; 1779 1780// 128-bit reads 1781def VTX_READ_GLOBAL_128_eg : VTX_READ_128_eg <1, 1782 [(set (v4i32 R600_Reg128:$dst), (global_load ADDRVTX_READ:$ptr))] 1783>; 1784 1785//===----------------------------------------------------------------------===// 1786// Constant Loads 1787// XXX: We are currently storing all constants in the global address space. 1788//===----------------------------------------------------------------------===// 1789 1790def CONSTANT_LOAD_eg : VTX_READ_32_eg <1, 1791 [(set (i32 R600_TReg32_X:$dst), (constant_load ADDRVTX_READ:$ptr))] 1792>; 1793 1794} 1795 1796//===----------------------------------------------------------------------===// 1797// Regist loads and stores - for indirect addressing 1798//===----------------------------------------------------------------------===// 1799 1800defm R600_ : RegisterLoadStore <R600_Reg32, FRAMEri, ADDRIndirect>; 1801 1802let Predicates = [isCayman] in { 1803 1804let isVector = 1 in { 1805 1806def RECIP_IEEE_cm : RECIP_IEEE_Common<0x86>; 1807 1808def MULLO_INT_cm : MULLO_INT_Common<0x8F>; 1809def MULHI_INT_cm : MULHI_INT_Common<0x90>; 1810def MULLO_UINT_cm : MULLO_UINT_Common<0x91>; 1811def MULHI_UINT_cm : MULHI_UINT_Common<0x92>; 1812def RECIPSQRT_CLAMPED_cm : RECIPSQRT_CLAMPED_Common<0x87>; 1813def EXP_IEEE_cm : EXP_IEEE_Common<0x81>; 1814def LOG_IEEE_cm : LOG_IEEE_Common<0x83>; 1815def RECIP_CLAMPED_cm : RECIP_CLAMPED_Common<0x84>; 1816def RECIPSQRT_IEEE_cm : RECIPSQRT_IEEE_Common<0x89>; 1817def SIN_cm : SIN_Common<0x8D>; 1818def COS_cm : COS_Common<0x8E>; 1819} // End isVector = 1 1820 1821def : POW_Common <LOG_IEEE_cm, EXP_IEEE_cm, MUL, R600_Reg32>; 1822def : SIN_PAT <SIN_cm>; 1823def : COS_PAT <COS_cm>; 1824 1825defm DIV_cm : DIV_Common<RECIP_IEEE_cm>; 1826 1827// RECIP_UINT emulation for Cayman 1828def : Pat < 1829 (AMDGPUurecip R600_Reg32:$src0), 1830 (FLT_TO_UINT_eg (MUL_IEEE (RECIP_IEEE_cm (UINT_TO_FLT_eg R600_Reg32:$src0)), 1831 (MOV_IMM_I32 0x4f800000))) 1832>; 1833 1834 1835def : Pat<(fsqrt R600_Reg32:$src), 1836 (MUL R600_Reg32:$src, (RECIPSQRT_CLAMPED_cm R600_Reg32:$src))>; 1837 1838} // End isCayman 1839 1840//===----------------------------------------------------------------------===// 1841// Branch Instructions 1842//===----------------------------------------------------------------------===// 1843 1844 1845def IF_PREDICATE_SET : ILFormat<(outs), (ins GPRI32:$src), 1846 "IF_PREDICATE_SET $src", []>; 1847 1848def PREDICATED_BREAK : ILFormat<(outs), (ins GPRI32:$src), 1849 "PREDICATED_BREAK $src", []>; 1850 1851//===----------------------------------------------------------------------===// 1852// Pseudo instructions 1853//===----------------------------------------------------------------------===// 1854 1855let isPseudo = 1 in { 1856 1857def PRED_X : InstR600 < 1858 0, (outs R600_Predicate_Bit:$dst), 1859 (ins R600_Reg32:$src0, i32imm:$src1, i32imm:$flags), 1860 "", [], NullALU> { 1861 let FlagOperandIdx = 3; 1862} 1863 1864let isTerminator = 1, isBranch = 1 in { 1865def JUMP_COND : InstR600 <0x10, 1866 (outs), 1867 (ins brtarget:$target, R600_Predicate_Bit:$p), 1868 "JUMP $target ($p)", 1869 [], AnyALU 1870 >; 1871 1872def JUMP : InstR600 <0x10, 1873 (outs), 1874 (ins brtarget:$target), 1875 "JUMP $target", 1876 [], AnyALU 1877 > 1878{ 1879 let isPredicable = 1; 1880 let isBarrier = 1; 1881} 1882 1883} // End isTerminator = 1, isBranch = 1 1884 1885let usesCustomInserter = 1 in { 1886 1887let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in { 1888 1889def MASK_WRITE : AMDGPUShaderInst < 1890 (outs), 1891 (ins R600_Reg32:$src), 1892 "MASK_WRITE $src", 1893 [] 1894>; 1895 1896} // End mayLoad = 0, mayStore = 0, hasSideEffects = 1 1897 1898 1899def TXD: AMDGPUShaderInst < 1900 (outs R600_Reg128:$dst), 1901 (ins R600_Reg128:$src0, R600_Reg128:$src1, R600_Reg128:$src2, i32imm:$resourceId, i32imm:$samplerId, i32imm:$textureTarget), 1902 "TXD $dst, $src0, $src1, $src2, $resourceId, $samplerId, $textureTarget", 1903 [(set R600_Reg128:$dst, (int_AMDGPU_txd R600_Reg128:$src0, R600_Reg128:$src1, R600_Reg128:$src2, imm:$resourceId, imm:$samplerId, imm:$textureTarget))] 1904>; 1905 1906def TXD_SHADOW: AMDGPUShaderInst < 1907 (outs R600_Reg128:$dst), 1908 (ins R600_Reg128:$src0, R600_Reg128:$src1, R600_Reg128:$src2, i32imm:$resourceId, i32imm:$samplerId, i32imm:$textureTarget), 1909 "TXD_SHADOW $dst, $src0, $src1, $src2, $resourceId, $samplerId, $textureTarget", 1910 [(set R600_Reg128:$dst, (int_AMDGPU_txd R600_Reg128:$src0, R600_Reg128:$src1, R600_Reg128:$src2, imm:$resourceId, imm:$samplerId, TEX_SHADOW:$textureTarget))] 1911>; 1912 1913} // End isPseudo = 1 1914} // End usesCustomInserter = 1 1915 1916def CLAMP_R600 : CLAMP <R600_Reg32>; 1917def FABS_R600 : FABS<R600_Reg32>; 1918def FNEG_R600 : FNEG<R600_Reg32>; 1919 1920//===---------------------------------------------------------------------===// 1921// Return instruction 1922//===---------------------------------------------------------------------===// 1923let isTerminator = 1, isReturn = 1, hasCtrlDep = 1, 1924 usesCustomInserter = 1 in { 1925 def RETURN : ILFormat<(outs), (ins variable_ops), 1926 "RETURN", [(IL_retflag)]>; 1927} 1928 1929 1930//===----------------------------------------------------------------------===// 1931// Constant Buffer Addressing Support 1932//===----------------------------------------------------------------------===// 1933 1934let usesCustomInserter = 1, isCodeGenOnly = 1, isPseudo = 1, Namespace = "AMDGPU" in { 1935def CONST_COPY : Instruction { 1936 let OutOperandList = (outs R600_Reg32:$dst); 1937 let InOperandList = (ins i32imm:$src); 1938 let Pattern = 1939 [(set R600_Reg32:$dst, (CONST_ADDRESS ADDRGA_CONST_OFFSET:$src))]; 1940 let AsmString = "CONST_COPY"; 1941 let neverHasSideEffects = 1; 1942 let isAsCheapAsAMove = 1; 1943 let Itinerary = NullALU; 1944} 1945} // end usesCustomInserter = 1, isCodeGenOnly = 1, isPseudo = 1, Namespace = "AMDGPU" 1946 1947def TEX_VTX_CONSTBUF : 1948 InstR600ISA <(outs R600_Reg128:$dst), (ins MEMxi:$ptr, i32imm:$BUFFER_ID), "VTX_READ_eg $dst, $ptr", 1949 [(set R600_Reg128:$dst, (CONST_ADDRESS ADDRGA_VAR_OFFSET:$ptr, (i32 imm:$BUFFER_ID)))]>, 1950 VTX_WORD1_GPR, VTX_WORD0 { 1951 1952 let VC_INST = 0; 1953 let FETCH_TYPE = 2; 1954 let FETCH_WHOLE_QUAD = 0; 1955 let SRC_REL = 0; 1956 let SRC_SEL_X = 0; 1957 let DST_REL = 0; 1958 let USE_CONST_FIELDS = 0; 1959 let NUM_FORMAT_ALL = 2; 1960 let FORMAT_COMP_ALL = 1; 1961 let SRF_MODE_ALL = 1; 1962 let MEGA_FETCH_COUNT = 16; 1963 let DST_SEL_X = 0; 1964 let DST_SEL_Y = 1; 1965 let DST_SEL_Z = 2; 1966 let DST_SEL_W = 3; 1967 let DATA_FORMAT = 35; 1968 1969 let Inst{31-0} = Word0; 1970 let Inst{63-32} = Word1; 1971 1972// LLVM can only encode 64-bit instructions, so these fields are manually 1973// encoded in R600CodeEmitter 1974// 1975// bits<16> OFFSET; 1976// bits<2> ENDIAN_SWAP = 0; 1977// bits<1> CONST_BUF_NO_STRIDE = 0; 1978// bits<1> MEGA_FETCH = 0; 1979// bits<1> ALT_CONST = 0; 1980// bits<2> BUFFER_INDEX_MODE = 0; 1981 1982 1983 1984// VTX_WORD2 (LLVM can only encode 64-bit instructions, so WORD2 encoding 1985// is done in R600CodeEmitter 1986// 1987// Inst{79-64} = OFFSET; 1988// Inst{81-80} = ENDIAN_SWAP; 1989// Inst{82} = CONST_BUF_NO_STRIDE; 1990// Inst{83} = MEGA_FETCH; 1991// Inst{84} = ALT_CONST; 1992// Inst{86-85} = BUFFER_INDEX_MODE; 1993// Inst{95-86} = 0; Reserved 1994 1995// VTX_WORD3 (Padding) 1996// 1997// Inst{127-96} = 0; 1998} 1999 2000def TEX_VTX_TEXBUF: 2001 InstR600ISA <(outs R600_Reg128:$dst), (ins MEMxi:$ptr, i32imm:$BUFFER_ID), "TEX_VTX_EXPLICIT_READ $dst, $ptr", 2002 [(set R600_Reg128:$dst, (int_R600_load_texbuf ADDRGA_VAR_OFFSET:$ptr, imm:$BUFFER_ID))]>, 2003VTX_WORD1_GPR, VTX_WORD0 { 2004 2005let VC_INST = 0; 2006let FETCH_TYPE = 2; 2007let FETCH_WHOLE_QUAD = 0; 2008let SRC_REL = 0; 2009let SRC_SEL_X = 0; 2010let DST_REL = 0; 2011let USE_CONST_FIELDS = 1; 2012let NUM_FORMAT_ALL = 0; 2013let FORMAT_COMP_ALL = 0; 2014let SRF_MODE_ALL = 1; 2015let MEGA_FETCH_COUNT = 16; 2016let DST_SEL_X = 0; 2017let DST_SEL_Y = 1; 2018let DST_SEL_Z = 2; 2019let DST_SEL_W = 3; 2020let DATA_FORMAT = 0; 2021 2022let Inst{31-0} = Word0; 2023let Inst{63-32} = Word1; 2024 2025// LLVM can only encode 64-bit instructions, so these fields are manually 2026// encoded in R600CodeEmitter 2027// 2028// bits<16> OFFSET; 2029// bits<2> ENDIAN_SWAP = 0; 2030// bits<1> CONST_BUF_NO_STRIDE = 0; 2031// bits<1> MEGA_FETCH = 0; 2032// bits<1> ALT_CONST = 0; 2033// bits<2> BUFFER_INDEX_MODE = 0; 2034 2035 2036 2037// VTX_WORD2 (LLVM can only encode 64-bit instructions, so WORD2 encoding 2038// is done in R600CodeEmitter 2039// 2040// Inst{79-64} = OFFSET; 2041// Inst{81-80} = ENDIAN_SWAP; 2042// Inst{82} = CONST_BUF_NO_STRIDE; 2043// Inst{83} = MEGA_FETCH; 2044// Inst{84} = ALT_CONST; 2045// Inst{86-85} = BUFFER_INDEX_MODE; 2046// Inst{95-86} = 0; Reserved 2047 2048// VTX_WORD3 (Padding) 2049// 2050// Inst{127-96} = 0; 2051} 2052 2053 2054 2055//===--------------------------------------------------------------------===// 2056// Instructions support 2057//===--------------------------------------------------------------------===// 2058//===---------------------------------------------------------------------===// 2059// Custom Inserter for Branches and returns, this eventually will be a 2060// seperate pass 2061//===---------------------------------------------------------------------===// 2062let isTerminator = 1, usesCustomInserter = 1, isBranch = 1, isBarrier = 1 in { 2063 def BRANCH : ILFormat<(outs), (ins brtarget:$target), 2064 "; Pseudo unconditional branch instruction", 2065 [(br bb:$target)]>; 2066 defm BRANCH_COND : BranchConditional<IL_brcond>; 2067} 2068 2069//===---------------------------------------------------------------------===// 2070// Flow and Program control Instructions 2071//===---------------------------------------------------------------------===// 2072let isTerminator=1 in { 2073 def SWITCH : ILFormat< (outs), (ins GPRI32:$src), 2074 !strconcat("SWITCH", " $src"), []>; 2075 def CASE : ILFormat< (outs), (ins GPRI32:$src), 2076 !strconcat("CASE", " $src"), []>; 2077 def BREAK : ILFormat< (outs), (ins), 2078 "BREAK", []>; 2079 def CONTINUE : ILFormat< (outs), (ins), 2080 "CONTINUE", []>; 2081 def DEFAULT : ILFormat< (outs), (ins), 2082 "DEFAULT", []>; 2083 def ELSE : ILFormat< (outs), (ins), 2084 "ELSE", []>; 2085 def ENDSWITCH : ILFormat< (outs), (ins), 2086 "ENDSWITCH", []>; 2087 def ENDMAIN : ILFormat< (outs), (ins), 2088 "ENDMAIN", []>; 2089 def END : ILFormat< (outs), (ins), 2090 "END", []>; 2091 def ENDFUNC : ILFormat< (outs), (ins), 2092 "ENDFUNC", []>; 2093 def ENDIF : ILFormat< (outs), (ins), 2094 "ENDIF", []>; 2095 def WHILELOOP : ILFormat< (outs), (ins), 2096 "WHILE", []>; 2097 def ENDLOOP : ILFormat< (outs), (ins), 2098 "ENDLOOP", []>; 2099 def FUNC : ILFormat< (outs), (ins), 2100 "FUNC", []>; 2101 def RETDYN : ILFormat< (outs), (ins), 2102 "RET_DYN", []>; 2103 // This opcode has custom swizzle pattern encoded in Swizzle Encoder 2104 defm IF_LOGICALNZ : BranchInstr<"IF_LOGICALNZ">; 2105 // This opcode has custom swizzle pattern encoded in Swizzle Encoder 2106 defm IF_LOGICALZ : BranchInstr<"IF_LOGICALZ">; 2107 // This opcode has custom swizzle pattern encoded in Swizzle Encoder 2108 defm BREAK_LOGICALNZ : BranchInstr<"BREAK_LOGICALNZ">; 2109 // This opcode has custom swizzle pattern encoded in Swizzle Encoder 2110 defm BREAK_LOGICALZ : BranchInstr<"BREAK_LOGICALZ">; 2111 // This opcode has custom swizzle pattern encoded in Swizzle Encoder 2112 defm CONTINUE_LOGICALNZ : BranchInstr<"CONTINUE_LOGICALNZ">; 2113 // This opcode has custom swizzle pattern encoded in Swizzle Encoder 2114 defm CONTINUE_LOGICALZ : BranchInstr<"CONTINUE_LOGICALZ">; 2115 defm IFC : BranchInstr2<"IFC">; 2116 defm BREAKC : BranchInstr2<"BREAKC">; 2117 defm CONTINUEC : BranchInstr2<"CONTINUEC">; 2118} 2119 2120//===----------------------------------------------------------------------===// 2121// ISel Patterns 2122//===----------------------------------------------------------------------===// 2123 2124// CND*_INT Pattterns for f32 True / False values 2125 2126class CND_INT_f32 <InstR600 cnd, CondCode cc> : Pat < 2127 (selectcc (i32 R600_Reg32:$src0), 0, (f32 R600_Reg32:$src1), 2128 R600_Reg32:$src2, cc), 2129 (cnd R600_Reg32:$src0, R600_Reg32:$src1, R600_Reg32:$src2) 2130>; 2131 2132def : CND_INT_f32 <CNDE_INT, SETEQ>; 2133def : CND_INT_f32 <CNDGT_INT, SETGT>; 2134def : CND_INT_f32 <CNDGE_INT, SETGE>; 2135 2136//CNDGE_INT extra pattern 2137def : Pat < 2138 (selectcc (i32 R600_Reg32:$src0), -1, (i32 R600_Reg32:$src1), 2139 (i32 R600_Reg32:$src2), COND_GT), 2140 (CNDGE_INT R600_Reg32:$src0, R600_Reg32:$src1, R600_Reg32:$src2) 2141>; 2142 2143// KIL Patterns 2144def KILP : Pat < 2145 (int_AMDGPU_kilp), 2146 (MASK_WRITE (KILLGT (f32 ONE), (f32 ZERO))) 2147>; 2148 2149def KIL : Pat < 2150 (int_AMDGPU_kill R600_Reg32:$src0), 2151 (MASK_WRITE (KILLGT (f32 ZERO), (f32 R600_Reg32:$src0))) 2152>; 2153 2154// SGT Reverse args 2155def : Pat < 2156 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO, COND_LT), 2157 (SGT R600_Reg32:$src1, R600_Reg32:$src0) 2158>; 2159 2160// SGE Reverse args 2161def : Pat < 2162 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO, COND_LE), 2163 (SGE R600_Reg32:$src1, R600_Reg32:$src0) 2164>; 2165 2166// SETGT_DX10 reverse args 2167def : Pat < 2168 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, COND_LT), 2169 (SETGT_DX10 R600_Reg32:$src1, R600_Reg32:$src0) 2170>; 2171 2172// SETGE_DX10 reverse args 2173def : Pat < 2174 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, COND_LE), 2175 (SETGE_DX10 R600_Reg32:$src1, R600_Reg32:$src0) 2176>; 2177 2178// SETGT_INT reverse args 2179def : Pat < 2180 (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETLT), 2181 (SETGT_INT R600_Reg32:$src1, R600_Reg32:$src0) 2182>; 2183 2184// SETGE_INT reverse args 2185def : Pat < 2186 (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETLE), 2187 (SETGE_INT R600_Reg32:$src1, R600_Reg32:$src0) 2188>; 2189 2190// SETGT_UINT reverse args 2191def : Pat < 2192 (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETULT), 2193 (SETGT_UINT R600_Reg32:$src1, R600_Reg32:$src0) 2194>; 2195 2196// SETGE_UINT reverse args 2197def : Pat < 2198 (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETULE), 2199 (SETGE_UINT R600_Reg32:$src1, R600_Reg32:$src0) 2200>; 2201 2202// The next two patterns are special cases for handling 'true if ordered' and 2203// 'true if unordered' conditionals. The assumption here is that the behavior of 2204// SETE and SNE conforms to the Direct3D 10 rules for floating point values 2205// described here: 2206// http://msdn.microsoft.com/en-us/library/windows/desktop/cc308050.aspx#alpha_32_bit 2207// We assume that SETE returns false when one of the operands is NAN and 2208// SNE returns true when on of the operands is NAN 2209 2210//SETE - 'true if ordered' 2211def : Pat < 2212 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO, SETO), 2213 (SETE R600_Reg32:$src0, R600_Reg32:$src1) 2214>; 2215 2216//SETE_DX10 - 'true if ordered' 2217def : Pat < 2218 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETO), 2219 (SETE_DX10 R600_Reg32:$src0, R600_Reg32:$src1) 2220>; 2221 2222//SNE - 'true if unordered' 2223def : Pat < 2224 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO, SETUO), 2225 (SNE R600_Reg32:$src0, R600_Reg32:$src1) 2226>; 2227 2228//SETNE_DX10 - 'true if ordered' 2229def : Pat < 2230 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETUO), 2231 (SETNE_DX10 R600_Reg32:$src0, R600_Reg32:$src1) 2232>; 2233 2234def : Extract_Element <f32, v4f32, R600_Reg128, 0, sub0>; 2235def : Extract_Element <f32, v4f32, R600_Reg128, 1, sub1>; 2236def : Extract_Element <f32, v4f32, R600_Reg128, 2, sub2>; 2237def : Extract_Element <f32, v4f32, R600_Reg128, 3, sub3>; 2238 2239def : Insert_Element <f32, v4f32, R600_Reg32, R600_Reg128, 0, sub0>; 2240def : Insert_Element <f32, v4f32, R600_Reg32, R600_Reg128, 1, sub1>; 2241def : Insert_Element <f32, v4f32, R600_Reg32, R600_Reg128, 2, sub2>; 2242def : Insert_Element <f32, v4f32, R600_Reg32, R600_Reg128, 3, sub3>; 2243 2244def : Extract_Element <i32, v4i32, R600_Reg128, 0, sub0>; 2245def : Extract_Element <i32, v4i32, R600_Reg128, 1, sub1>; 2246def : Extract_Element <i32, v4i32, R600_Reg128, 2, sub2>; 2247def : Extract_Element <i32, v4i32, R600_Reg128, 3, sub3>; 2248 2249def : Insert_Element <i32, v4i32, R600_Reg32, R600_Reg128, 0, sub0>; 2250def : Insert_Element <i32, v4i32, R600_Reg32, R600_Reg128, 1, sub1>; 2251def : Insert_Element <i32, v4i32, R600_Reg32, R600_Reg128, 2, sub2>; 2252def : Insert_Element <i32, v4i32, R600_Reg32, R600_Reg128, 3, sub3>; 2253 2254def : Vector4_Build <v4f32, R600_Reg128, f32, R600_Reg32>; 2255def : Vector4_Build <v4i32, R600_Reg128, i32, R600_Reg32>; 2256 2257// bitconvert patterns 2258 2259def : BitConvert <i32, f32, R600_Reg32>; 2260def : BitConvert <f32, i32, R600_Reg32>; 2261def : BitConvert <v4f32, v4i32, R600_Reg128>; 2262def : BitConvert <v4i32, v4f32, R600_Reg128>; 2263 2264// DWORDADDR pattern 2265def : DwordAddrPat <i32, R600_Reg32>; 2266 2267} // End isR600toCayman Predicate 2268