1//===-- AMDGPUInstructions.td - Common 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// This file contains instruction defs that are common to all hw codegen 11// targets. 12// 13//===----------------------------------------------------------------------===// 14 15class AMDGPUInst <dag outs, dag ins, string asm, list<dag> pattern> : Instruction { 16 field bit isRegisterLoad = 0; 17 field bit isRegisterStore = 0; 18 19 let Namespace = "AMDGPU"; 20 let OutOperandList = outs; 21 let InOperandList = ins; 22 let AsmString = asm; 23 let Pattern = pattern; 24 let Itinerary = NullALU; 25 26 // SoftFail is a field the disassembler can use to provide a way for 27 // instructions to not match without killing the whole decode process. It is 28 // mainly used for ARM, but Tablegen expects this field to exist or it fails 29 // to build the decode table. 30 field bits<64> SoftFail = 0; 31 32 let DecoderNamespace = Namespace; 33 34 let TSFlags{63} = isRegisterLoad; 35 let TSFlags{62} = isRegisterStore; 36} 37 38class AMDGPUShaderInst <dag outs, dag ins, string asm, list<dag> pattern> 39 : AMDGPUInst<outs, ins, asm, pattern> { 40 41 field bits<32> Inst = 0xffffffff; 42 43} 44 45def FP32Denormals : Predicate<"Subtarget.hasFP32Denormals()">; 46def FP64Denormals : Predicate<"Subtarget.hasFP64Denormals()">; 47def UnsafeFPMath : Predicate<"TM.Options.UnsafeFPMath">; 48 49def InstFlag : OperandWithDefaultOps <i32, (ops (i32 0))>; 50def ADDRIndirect : ComplexPattern<iPTR, 2, "SelectADDRIndirect", [], []>; 51 52let OperandType = "OPERAND_IMMEDIATE" in { 53 54def u32imm : Operand<i32> { 55 let PrintMethod = "printU32ImmOperand"; 56} 57 58def u16imm : Operand<i16> { 59 let PrintMethod = "printU16ImmOperand"; 60} 61 62def u8imm : Operand<i8> { 63 let PrintMethod = "printU8ImmOperand"; 64} 65 66} // End OperandType = "OPERAND_IMMEDIATE" 67 68//===--------------------------------------------------------------------===// 69// Custom Operands 70//===--------------------------------------------------------------------===// 71def brtarget : Operand<OtherVT>; 72 73//===----------------------------------------------------------------------===// 74// PatLeafs for floating-point comparisons 75//===----------------------------------------------------------------------===// 76 77def COND_OEQ : PatLeaf < 78 (cond), 79 [{return N->get() == ISD::SETOEQ || N->get() == ISD::SETEQ;}] 80>; 81 82def COND_ONE : PatLeaf < 83 (cond), 84 [{return N->get() == ISD::SETONE || N->get() == ISD::SETNE;}] 85>; 86 87def COND_OGT : PatLeaf < 88 (cond), 89 [{return N->get() == ISD::SETOGT || N->get() == ISD::SETGT;}] 90>; 91 92def COND_OGE : PatLeaf < 93 (cond), 94 [{return N->get() == ISD::SETOGE || N->get() == ISD::SETGE;}] 95>; 96 97def COND_OLT : PatLeaf < 98 (cond), 99 [{return N->get() == ISD::SETOLT || N->get() == ISD::SETLT;}] 100>; 101 102def COND_OLE : PatLeaf < 103 (cond), 104 [{return N->get() == ISD::SETOLE || N->get() == ISD::SETLE;}] 105>; 106 107 108def COND_O : PatLeaf <(cond), [{return N->get() == ISD::SETO;}]>; 109def COND_UO : PatLeaf <(cond), [{return N->get() == ISD::SETUO;}]>; 110 111//===----------------------------------------------------------------------===// 112// PatLeafs for unsigned / unordered comparisons 113//===----------------------------------------------------------------------===// 114 115def COND_UEQ : PatLeaf <(cond), [{return N->get() == ISD::SETUEQ;}]>; 116def COND_UNE : PatLeaf <(cond), [{return N->get() == ISD::SETUNE;}]>; 117def COND_UGT : PatLeaf <(cond), [{return N->get() == ISD::SETUGT;}]>; 118def COND_UGE : PatLeaf <(cond), [{return N->get() == ISD::SETUGE;}]>; 119def COND_ULT : PatLeaf <(cond), [{return N->get() == ISD::SETULT;}]>; 120def COND_ULE : PatLeaf <(cond), [{return N->get() == ISD::SETULE;}]>; 121 122// XXX - For some reason R600 version is preferring to use unordered 123// for setne? 124def COND_UNE_NE : PatLeaf < 125 (cond), 126 [{return N->get() == ISD::SETUNE || N->get() == ISD::SETNE;}] 127>; 128 129//===----------------------------------------------------------------------===// 130// PatLeafs for signed comparisons 131//===----------------------------------------------------------------------===// 132 133def COND_SGT : PatLeaf <(cond), [{return N->get() == ISD::SETGT;}]>; 134def COND_SGE : PatLeaf <(cond), [{return N->get() == ISD::SETGE;}]>; 135def COND_SLT : PatLeaf <(cond), [{return N->get() == ISD::SETLT;}]>; 136def COND_SLE : PatLeaf <(cond), [{return N->get() == ISD::SETLE;}]>; 137 138//===----------------------------------------------------------------------===// 139// PatLeafs for integer equality 140//===----------------------------------------------------------------------===// 141 142def COND_EQ : PatLeaf < 143 (cond), 144 [{return N->get() == ISD::SETEQ || N->get() == ISD::SETUEQ;}] 145>; 146 147def COND_NE : PatLeaf < 148 (cond), 149 [{return N->get() == ISD::SETNE || N->get() == ISD::SETUNE;}] 150>; 151 152def COND_NULL : PatLeaf < 153 (cond), 154 [{(void)N; return false;}] 155>; 156 157//===----------------------------------------------------------------------===// 158// Load/Store Pattern Fragments 159//===----------------------------------------------------------------------===// 160 161class PrivateMemOp <dag ops, dag frag> : PatFrag <ops, frag, [{ 162 return cast<MemSDNode>(N)->getAddressSpace() == AMDGPUAS::PRIVATE_ADDRESS; 163}]>; 164 165class PrivateLoad <SDPatternOperator op> : PrivateMemOp < 166 (ops node:$ptr), (op node:$ptr) 167>; 168 169class PrivateStore <SDPatternOperator op> : PrivateMemOp < 170 (ops node:$value, node:$ptr), (op node:$value, node:$ptr) 171>; 172 173def load_private : PrivateLoad <load>; 174 175def truncstorei8_private : PrivateStore <truncstorei8>; 176def truncstorei16_private : PrivateStore <truncstorei16>; 177def store_private : PrivateStore <store>; 178 179def global_store : PatFrag<(ops node:$val, node:$ptr), 180 (store node:$val, node:$ptr), [{ 181 return isGlobalStore(dyn_cast<StoreSDNode>(N)); 182}]>; 183 184// Global address space loads 185def global_load : PatFrag<(ops node:$ptr), (load node:$ptr), [{ 186 return isGlobalLoad(dyn_cast<LoadSDNode>(N)); 187}]>; 188 189// Constant address space loads 190def constant_load : PatFrag<(ops node:$ptr), (load node:$ptr), [{ 191 return isConstantLoad(dyn_cast<LoadSDNode>(N), -1); 192}]>; 193 194class AZExtLoadBase <SDPatternOperator ld_node>: PatFrag<(ops node:$ptr), 195 (ld_node node:$ptr), [{ 196 LoadSDNode *L = cast<LoadSDNode>(N); 197 return L->getExtensionType() == ISD::ZEXTLOAD || 198 L->getExtensionType() == ISD::EXTLOAD; 199}]>; 200 201def az_extload : AZExtLoadBase <unindexedload>; 202 203def az_extloadi8 : PatFrag<(ops node:$ptr), (az_extload node:$ptr), [{ 204 return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8; 205}]>; 206 207def az_extloadi8_global : PatFrag<(ops node:$ptr), (az_extloadi8 node:$ptr), [{ 208 return isGlobalLoad(dyn_cast<LoadSDNode>(N)); 209}]>; 210 211def sextloadi8_global : PatFrag<(ops node:$ptr), (sextloadi8 node:$ptr), [{ 212 return isGlobalLoad(dyn_cast<LoadSDNode>(N)); 213}]>; 214 215def az_extloadi8_constant : PatFrag<(ops node:$ptr), (az_extloadi8 node:$ptr), [{ 216 return isConstantLoad(dyn_cast<LoadSDNode>(N), -1); 217}]>; 218 219def sextloadi8_constant : PatFrag<(ops node:$ptr), (sextloadi8 node:$ptr), [{ 220 return isConstantLoad(dyn_cast<LoadSDNode>(N), -1); 221}]>; 222 223def az_extloadi8_local : PatFrag<(ops node:$ptr), (az_extloadi8 node:$ptr), [{ 224 return isLocalLoad(dyn_cast<LoadSDNode>(N)); 225}]>; 226 227def sextloadi8_local : PatFrag<(ops node:$ptr), (sextloadi8 node:$ptr), [{ 228 return isLocalLoad(dyn_cast<LoadSDNode>(N)); 229}]>; 230 231def extloadi8_private : PrivateLoad <az_extloadi8>; 232def sextloadi8_private : PrivateLoad <sextloadi8>; 233 234def az_extloadi16 : PatFrag<(ops node:$ptr), (az_extload node:$ptr), [{ 235 return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16; 236}]>; 237 238def az_extloadi16_global : PatFrag<(ops node:$ptr), (az_extloadi16 node:$ptr), [{ 239 return isGlobalLoad(dyn_cast<LoadSDNode>(N)); 240}]>; 241 242def sextloadi16_global : PatFrag<(ops node:$ptr), (sextloadi16 node:$ptr), [{ 243 return isGlobalLoad(dyn_cast<LoadSDNode>(N)); 244}]>; 245 246def az_extloadi16_constant : PatFrag<(ops node:$ptr), (az_extloadi16 node:$ptr), [{ 247 return isConstantLoad(dyn_cast<LoadSDNode>(N), -1); 248}]>; 249 250def sextloadi16_constant : PatFrag<(ops node:$ptr), (sextloadi16 node:$ptr), [{ 251 return isConstantLoad(dyn_cast<LoadSDNode>(N), -1); 252}]>; 253 254def az_extloadi16_local : PatFrag<(ops node:$ptr), (az_extloadi16 node:$ptr), [{ 255 return isLocalLoad(dyn_cast<LoadSDNode>(N)); 256}]>; 257 258def sextloadi16_local : PatFrag<(ops node:$ptr), (sextloadi16 node:$ptr), [{ 259 return isLocalLoad(dyn_cast<LoadSDNode>(N)); 260}]>; 261 262def extloadi16_private : PrivateLoad <az_extloadi16>; 263def sextloadi16_private : PrivateLoad <sextloadi16>; 264 265def az_extloadi32 : PatFrag<(ops node:$ptr), (az_extload node:$ptr), [{ 266 return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32; 267}]>; 268 269def az_extloadi32_global : PatFrag<(ops node:$ptr), 270 (az_extloadi32 node:$ptr), [{ 271 return isGlobalLoad(dyn_cast<LoadSDNode>(N)); 272}]>; 273 274def az_extloadi32_flat : PatFrag<(ops node:$ptr), 275 (az_extloadi32 node:$ptr), [{ 276 return isFlatLoad(dyn_cast<LoadSDNode>(N)); 277}]>; 278 279def az_extloadi32_constant : PatFrag<(ops node:$ptr), 280 (az_extloadi32 node:$ptr), [{ 281 return isConstantLoad(dyn_cast<LoadSDNode>(N), -1); 282}]>; 283 284def truncstorei8_global : PatFrag<(ops node:$val, node:$ptr), 285 (truncstorei8 node:$val, node:$ptr), [{ 286 return isGlobalStore(dyn_cast<StoreSDNode>(N)); 287}]>; 288 289def truncstorei16_global : PatFrag<(ops node:$val, node:$ptr), 290 (truncstorei16 node:$val, node:$ptr), [{ 291 return isGlobalStore(dyn_cast<StoreSDNode>(N)); 292}]>; 293 294def local_store : PatFrag<(ops node:$val, node:$ptr), 295 (store node:$val, node:$ptr), [{ 296 return isLocalStore(dyn_cast<StoreSDNode>(N)); 297}]>; 298 299def truncstorei8_local : PatFrag<(ops node:$val, node:$ptr), 300 (truncstorei8 node:$val, node:$ptr), [{ 301 return isLocalStore(dyn_cast<StoreSDNode>(N)); 302}]>; 303 304def truncstorei16_local : PatFrag<(ops node:$val, node:$ptr), 305 (truncstorei16 node:$val, node:$ptr), [{ 306 return isLocalStore(dyn_cast<StoreSDNode>(N)); 307}]>; 308 309def local_load : PatFrag<(ops node:$ptr), (load node:$ptr), [{ 310 return isLocalLoad(dyn_cast<LoadSDNode>(N)); 311}]>; 312 313class Aligned8Bytes <dag ops, dag frag> : PatFrag <ops, frag, [{ 314 return cast<MemSDNode>(N)->getAlignment() % 8 == 0; 315}]>; 316 317def local_load_aligned8bytes : Aligned8Bytes < 318 (ops node:$ptr), (local_load node:$ptr) 319>; 320 321def local_store_aligned8bytes : Aligned8Bytes < 322 (ops node:$val, node:$ptr), (local_store node:$val, node:$ptr) 323>; 324 325class local_binary_atomic_op<SDNode atomic_op> : 326 PatFrag<(ops node:$ptr, node:$value), 327 (atomic_op node:$ptr, node:$value), [{ 328 return cast<MemSDNode>(N)->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS; 329}]>; 330 331 332def atomic_swap_local : local_binary_atomic_op<atomic_swap>; 333def atomic_load_add_local : local_binary_atomic_op<atomic_load_add>; 334def atomic_load_sub_local : local_binary_atomic_op<atomic_load_sub>; 335def atomic_load_and_local : local_binary_atomic_op<atomic_load_and>; 336def atomic_load_or_local : local_binary_atomic_op<atomic_load_or>; 337def atomic_load_xor_local : local_binary_atomic_op<atomic_load_xor>; 338def atomic_load_nand_local : local_binary_atomic_op<atomic_load_nand>; 339def atomic_load_min_local : local_binary_atomic_op<atomic_load_min>; 340def atomic_load_max_local : local_binary_atomic_op<atomic_load_max>; 341def atomic_load_umin_local : local_binary_atomic_op<atomic_load_umin>; 342def atomic_load_umax_local : local_binary_atomic_op<atomic_load_umax>; 343 344def mskor_global : PatFrag<(ops node:$val, node:$ptr), 345 (AMDGPUstore_mskor node:$val, node:$ptr), [{ 346 return cast<MemSDNode>(N)->getAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS; 347}]>; 348 349multiclass AtomicCmpSwapLocal <SDNode cmp_swap_node> { 350 351 def _32_local : PatFrag < 352 (ops node:$ptr, node:$cmp, node:$swap), 353 (cmp_swap_node node:$ptr, node:$cmp, node:$swap), [{ 354 AtomicSDNode *AN = cast<AtomicSDNode>(N); 355 return AN->getMemoryVT() == MVT::i32 && 356 AN->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS; 357 }]>; 358 359 def _64_local : PatFrag< 360 (ops node:$ptr, node:$cmp, node:$swap), 361 (cmp_swap_node node:$ptr, node:$cmp, node:$swap), [{ 362 AtomicSDNode *AN = cast<AtomicSDNode>(N); 363 return AN->getMemoryVT() == MVT::i64 && 364 AN->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS; 365 }]>; 366} 367 368defm atomic_cmp_swap : AtomicCmpSwapLocal <atomic_cmp_swap>; 369 370def mskor_flat : PatFrag<(ops node:$val, node:$ptr), 371 (AMDGPUstore_mskor node:$val, node:$ptr), [{ 372 return cast<MemSDNode>(N)->getAddressSpace() == AMDGPUAS::FLAT_ADDRESS; 373}]>; 374 375class global_binary_atomic_op<SDNode atomic_op> : PatFrag< 376 (ops node:$ptr, node:$value), 377 (atomic_op node:$ptr, node:$value), 378 [{return cast<MemSDNode>(N)->getAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS;}] 379>; 380 381def atomic_swap_global : global_binary_atomic_op<atomic_swap>; 382def atomic_add_global : global_binary_atomic_op<atomic_load_add>; 383def atomic_and_global : global_binary_atomic_op<atomic_load_and>; 384def atomic_max_global : global_binary_atomic_op<atomic_load_max>; 385def atomic_min_global : global_binary_atomic_op<atomic_load_min>; 386def atomic_or_global : global_binary_atomic_op<atomic_load_or>; 387def atomic_sub_global : global_binary_atomic_op<atomic_load_sub>; 388def atomic_umax_global : global_binary_atomic_op<atomic_load_umax>; 389def atomic_umin_global : global_binary_atomic_op<atomic_load_umin>; 390def atomic_xor_global : global_binary_atomic_op<atomic_load_xor>; 391 392//===----------------------------------------------------------------------===// 393// Misc Pattern Fragments 394//===----------------------------------------------------------------------===// 395 396class Constants { 397int TWO_PI = 0x40c90fdb; 398int PI = 0x40490fdb; 399int TWO_PI_INV = 0x3e22f983; 400int FP_UINT_MAX_PLUS_1 = 0x4f800000; // 1 << 32 in floating point encoding 401int FP32_NEG_ONE = 0xbf800000; 402int FP32_ONE = 0x3f800000; 403} 404def CONST : Constants; 405 406def FP_ZERO : PatLeaf < 407 (fpimm), 408 [{return N->getValueAPF().isZero();}] 409>; 410 411def FP_ONE : PatLeaf < 412 (fpimm), 413 [{return N->isExactlyValue(1.0);}] 414>; 415 416def FP_HALF : PatLeaf < 417 (fpimm), 418 [{return N->isExactlyValue(0.5);}] 419>; 420 421let isCodeGenOnly = 1, isPseudo = 1 in { 422 423let usesCustomInserter = 1 in { 424 425class CLAMP <RegisterClass rc> : AMDGPUShaderInst < 426 (outs rc:$dst), 427 (ins rc:$src0), 428 "CLAMP $dst, $src0", 429 [(set f32:$dst, (AMDGPUclamp f32:$src0, (f32 FP_ZERO), (f32 FP_ONE)))] 430>; 431 432class FABS <RegisterClass rc> : AMDGPUShaderInst < 433 (outs rc:$dst), 434 (ins rc:$src0), 435 "FABS $dst, $src0", 436 [(set f32:$dst, (fabs f32:$src0))] 437>; 438 439class FNEG <RegisterClass rc> : AMDGPUShaderInst < 440 (outs rc:$dst), 441 (ins rc:$src0), 442 "FNEG $dst, $src0", 443 [(set f32:$dst, (fneg f32:$src0))] 444>; 445 446} // usesCustomInserter = 1 447 448multiclass RegisterLoadStore <RegisterClass dstClass, Operand addrClass, 449 ComplexPattern addrPat> { 450let UseNamedOperandTable = 1 in { 451 452 def RegisterLoad : AMDGPUShaderInst < 453 (outs dstClass:$dst), 454 (ins addrClass:$addr, i32imm:$chan), 455 "RegisterLoad $dst, $addr", 456 [(set i32:$dst, (AMDGPUregister_load addrPat:$addr, (i32 timm:$chan)))] 457 > { 458 let isRegisterLoad = 1; 459 } 460 461 def RegisterStore : AMDGPUShaderInst < 462 (outs), 463 (ins dstClass:$val, addrClass:$addr, i32imm:$chan), 464 "RegisterStore $val, $addr", 465 [(AMDGPUregister_store i32:$val, addrPat:$addr, (i32 timm:$chan))] 466 > { 467 let isRegisterStore = 1; 468 } 469} 470} 471 472} // End isCodeGenOnly = 1, isPseudo = 1 473 474/* Generic helper patterns for intrinsics */ 475/* -------------------------------------- */ 476 477class POW_Common <AMDGPUInst log_ieee, AMDGPUInst exp_ieee, AMDGPUInst mul> 478 : Pat < 479 (fpow f32:$src0, f32:$src1), 480 (exp_ieee (mul f32:$src1, (log_ieee f32:$src0))) 481>; 482 483/* Other helper patterns */ 484/* --------------------- */ 485 486/* Extract element pattern */ 487class Extract_Element <ValueType sub_type, ValueType vec_type, int sub_idx, 488 SubRegIndex sub_reg> 489 : Pat< 490 (sub_type (extractelt vec_type:$src, sub_idx)), 491 (EXTRACT_SUBREG $src, sub_reg) 492>; 493 494/* Insert element pattern */ 495class Insert_Element <ValueType elem_type, ValueType vec_type, 496 int sub_idx, SubRegIndex sub_reg> 497 : Pat < 498 (insertelt vec_type:$vec, elem_type:$elem, sub_idx), 499 (INSERT_SUBREG $vec, $elem, sub_reg) 500>; 501 502// XXX: Convert to new syntax and use COPY_TO_REG, once the DFAPacketizer 503// can handle COPY instructions. 504// bitconvert pattern 505class BitConvert <ValueType dt, ValueType st, RegisterClass rc> : Pat < 506 (dt (bitconvert (st rc:$src0))), 507 (dt rc:$src0) 508>; 509 510// XXX: Convert to new syntax and use COPY_TO_REG, once the DFAPacketizer 511// can handle COPY instructions. 512class DwordAddrPat<ValueType vt, RegisterClass rc> : Pat < 513 (vt (AMDGPUdwordaddr (vt rc:$addr))), 514 (vt rc:$addr) 515>; 516 517// BFI_INT patterns 518 519multiclass BFIPatterns <Instruction BFI_INT, 520 Instruction LoadImm32, 521 RegisterClass RC64> { 522 // Definition from ISA doc: 523 // (y & x) | (z & ~x) 524 def : Pat < 525 (or (and i32:$y, i32:$x), (and i32:$z, (not i32:$x))), 526 (BFI_INT $x, $y, $z) 527 >; 528 529 // SHA-256 Ch function 530 // z ^ (x & (y ^ z)) 531 def : Pat < 532 (xor i32:$z, (and i32:$x, (xor i32:$y, i32:$z))), 533 (BFI_INT $x, $y, $z) 534 >; 535 536 def : Pat < 537 (fcopysign f32:$src0, f32:$src1), 538 (BFI_INT (LoadImm32 0x7fffffff), $src0, $src1) 539 >; 540 541 def : Pat < 542 (f64 (fcopysign f64:$src0, f64:$src1)), 543 (REG_SEQUENCE RC64, 544 (i32 (EXTRACT_SUBREG $src0, sub0)), sub0, 545 (BFI_INT (LoadImm32 0x7fffffff), 546 (i32 (EXTRACT_SUBREG $src0, sub1)), 547 (i32 (EXTRACT_SUBREG $src1, sub1))), sub1) 548 >; 549} 550 551// SHA-256 Ma patterns 552 553// ((x & z) | (y & (x | z))) -> BFI_INT (XOR x, y), z, y 554class SHA256MaPattern <Instruction BFI_INT, Instruction XOR> : Pat < 555 (or (and i32:$x, i32:$z), (and i32:$y, (or i32:$x, i32:$z))), 556 (BFI_INT (XOR i32:$x, i32:$y), i32:$z, i32:$y) 557>; 558 559// Bitfield extract patterns 560 561def IMMZeroBasedBitfieldMask : PatLeaf <(imm), [{ 562 return isMask_32(N->getZExtValue()); 563}]>; 564 565def IMMPopCount : SDNodeXForm<imm, [{ 566 return CurDAG->getTargetConstant(countPopulation(N->getZExtValue()), SDLoc(N), 567 MVT::i32); 568}]>; 569 570class BFEPattern <Instruction BFE, Instruction MOV> : Pat < 571 (i32 (and (i32 (srl i32:$src, i32:$rshift)), IMMZeroBasedBitfieldMask:$mask)), 572 (BFE $src, $rshift, (MOV (i32 (IMMPopCount $mask)))) 573>; 574 575// rotr pattern 576class ROTRPattern <Instruction BIT_ALIGN> : Pat < 577 (rotr i32:$src0, i32:$src1), 578 (BIT_ALIGN $src0, $src0, $src1) 579>; 580 581// 24-bit arithmetic patterns 582def umul24 : PatFrag <(ops node:$x, node:$y), (mul node:$x, node:$y)>; 583 584// Special conversion patterns 585 586def cvt_rpi_i32_f32 : PatFrag < 587 (ops node:$src), 588 (fp_to_sint (ffloor (fadd $src, FP_HALF))), 589 [{ (void) N; return TM.Options.NoNaNsFPMath; }] 590>; 591 592def cvt_flr_i32_f32 : PatFrag < 593 (ops node:$src), 594 (fp_to_sint (ffloor $src)), 595 [{ (void)N; return TM.Options.NoNaNsFPMath; }] 596>; 597 598class IMad24Pat<Instruction Inst> : Pat < 599 (add (AMDGPUmul_i24 i32:$src0, i32:$src1), i32:$src2), 600 (Inst $src0, $src1, $src2) 601>; 602 603class UMad24Pat<Instruction Inst> : Pat < 604 (add (AMDGPUmul_u24 i32:$src0, i32:$src1), i32:$src2), 605 (Inst $src0, $src1, $src2) 606>; 607 608class RcpPat<Instruction RcpInst, ValueType vt> : Pat < 609 (fdiv FP_ONE, vt:$src), 610 (RcpInst $src) 611>; 612 613class RsqPat<Instruction RsqInst, ValueType vt> : Pat < 614 (AMDGPUrcp (fsqrt vt:$src)), 615 (RsqInst $src) 616>; 617 618include "R600Instructions.td" 619include "R700Instructions.td" 620include "EvergreenInstructions.td" 621include "CaymanInstructions.td" 622 623include "SIInstrInfo.td" 624 625