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//===----------------------------------------------------------------------===// 159// Misc. PatFrags 160//===----------------------------------------------------------------------===// 161 162class HasOneUseBinOp<SDPatternOperator op> : PatFrag< 163 (ops node:$src0, node:$src1), 164 (op $src0, $src1), 165 [{ return N->hasOneUse(); }] 166>; 167 168//===----------------------------------------------------------------------===// 169// Load/Store Pattern Fragments 170//===----------------------------------------------------------------------===// 171 172class PrivateMemOp <dag ops, dag frag> : PatFrag <ops, frag, [{ 173 return cast<MemSDNode>(N)->getAddressSpace() == AMDGPUAS::PRIVATE_ADDRESS; 174}]>; 175 176class PrivateLoad <SDPatternOperator op> : PrivateMemOp < 177 (ops node:$ptr), (op node:$ptr) 178>; 179 180class PrivateStore <SDPatternOperator op> : PrivateMemOp < 181 (ops node:$value, node:$ptr), (op node:$value, node:$ptr) 182>; 183 184def load_private : PrivateLoad <load>; 185 186def truncstorei8_private : PrivateStore <truncstorei8>; 187def truncstorei16_private : PrivateStore <truncstorei16>; 188def store_private : PrivateStore <store>; 189 190class GlobalMemOp <dag ops, dag frag> : PatFrag <ops, frag, [{ 191 return cast<MemSDNode>(N)->getAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS; 192}]>; 193 194// Global address space loads 195class GlobalLoad <SDPatternOperator op> : GlobalMemOp < 196 (ops node:$ptr), (op node:$ptr) 197>; 198 199def global_load : GlobalLoad <load>; 200 201// Global address space stores 202class GlobalStore <SDPatternOperator op> : GlobalMemOp < 203 (ops node:$value, node:$ptr), (op node:$value, node:$ptr) 204>; 205 206def global_store : GlobalStore <store>; 207def global_store_atomic : GlobalStore<atomic_store>; 208 209 210class ConstantMemOp <dag ops, dag frag> : PatFrag <ops, frag, [{ 211 return cast<MemSDNode>(N)->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS; 212}]>; 213 214// Constant address space loads 215class ConstantLoad <SDPatternOperator op> : ConstantMemOp < 216 (ops node:$ptr), (op node:$ptr) 217>; 218 219def constant_load : ConstantLoad<load>; 220 221class LocalMemOp <dag ops, dag frag> : PatFrag <ops, frag, [{ 222 return cast<MemSDNode>(N)->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS; 223}]>; 224 225// Local address space loads 226class LocalLoad <SDPatternOperator op> : LocalMemOp < 227 (ops node:$ptr), (op node:$ptr) 228>; 229 230class LocalStore <SDPatternOperator op> : LocalMemOp < 231 (ops node:$value, node:$ptr), (op node:$value, node:$ptr) 232>; 233 234class FlatMemOp <dag ops, dag frag> : PatFrag <ops, frag, [{ 235 return cast<MemSDNode>(N)->getAddressSPace() == AMDGPUAS::FLAT_ADDRESS; 236}]>; 237 238class FlatLoad <SDPatternOperator op> : FlatMemOp < 239 (ops node:$ptr), (op node:$ptr) 240>; 241 242class AZExtLoadBase <SDPatternOperator ld_node>: PatFrag<(ops node:$ptr), 243 (ld_node node:$ptr), [{ 244 LoadSDNode *L = cast<LoadSDNode>(N); 245 return L->getExtensionType() == ISD::ZEXTLOAD || 246 L->getExtensionType() == ISD::EXTLOAD; 247}]>; 248 249def az_extload : AZExtLoadBase <unindexedload>; 250 251def az_extloadi8 : PatFrag<(ops node:$ptr), (az_extload node:$ptr), [{ 252 return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8; 253}]>; 254 255def az_extloadi8_global : GlobalLoad <az_extloadi8>; 256def sextloadi8_global : GlobalLoad <sextloadi8>; 257 258def az_extloadi8_constant : ConstantLoad <az_extloadi8>; 259def sextloadi8_constant : ConstantLoad <sextloadi8>; 260 261def az_extloadi8_local : LocalLoad <az_extloadi8>; 262def sextloadi8_local : LocalLoad <sextloadi8>; 263 264def extloadi8_private : PrivateLoad <az_extloadi8>; 265def sextloadi8_private : PrivateLoad <sextloadi8>; 266 267def az_extloadi16 : PatFrag<(ops node:$ptr), (az_extload node:$ptr), [{ 268 return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16; 269}]>; 270 271def az_extloadi16_global : GlobalLoad <az_extloadi16>; 272def sextloadi16_global : GlobalLoad <sextloadi16>; 273 274def az_extloadi16_constant : ConstantLoad <az_extloadi16>; 275def sextloadi16_constant : ConstantLoad <sextloadi16>; 276 277def az_extloadi16_local : LocalLoad <az_extloadi16>; 278def sextloadi16_local : LocalLoad <sextloadi16>; 279 280def extloadi16_private : PrivateLoad <az_extloadi16>; 281def sextloadi16_private : PrivateLoad <sextloadi16>; 282 283def az_extloadi32 : PatFrag<(ops node:$ptr), (az_extload node:$ptr), [{ 284 return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32; 285}]>; 286 287def az_extloadi32_global : GlobalLoad <az_extloadi32>; 288 289def az_extloadi32_flat : FlatLoad <az_extloadi32>; 290 291def az_extloadi32_constant : ConstantLoad <az_extloadi32>; 292 293def truncstorei8_global : GlobalStore <truncstorei8>; 294def truncstorei16_global : GlobalStore <truncstorei16>; 295 296def local_store : LocalStore <store>; 297def truncstorei8_local : LocalStore <truncstorei8>; 298def truncstorei16_local : LocalStore <truncstorei16>; 299 300def local_load : LocalLoad <load>; 301 302class Aligned8Bytes <dag ops, dag frag> : PatFrag <ops, frag, [{ 303 return cast<MemSDNode>(N)->getAlignment() % 8 == 0; 304}]>; 305 306def local_load_aligned8bytes : Aligned8Bytes < 307 (ops node:$ptr), (local_load node:$ptr) 308>; 309 310def local_store_aligned8bytes : Aligned8Bytes < 311 (ops node:$val, node:$ptr), (local_store node:$val, node:$ptr) 312>; 313 314class local_binary_atomic_op<SDNode atomic_op> : 315 PatFrag<(ops node:$ptr, node:$value), 316 (atomic_op node:$ptr, node:$value), [{ 317 return cast<MemSDNode>(N)->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS; 318}]>; 319 320 321def atomic_swap_local : local_binary_atomic_op<atomic_swap>; 322def atomic_load_add_local : local_binary_atomic_op<atomic_load_add>; 323def atomic_load_sub_local : local_binary_atomic_op<atomic_load_sub>; 324def atomic_load_and_local : local_binary_atomic_op<atomic_load_and>; 325def atomic_load_or_local : local_binary_atomic_op<atomic_load_or>; 326def atomic_load_xor_local : local_binary_atomic_op<atomic_load_xor>; 327def atomic_load_nand_local : local_binary_atomic_op<atomic_load_nand>; 328def atomic_load_min_local : local_binary_atomic_op<atomic_load_min>; 329def atomic_load_max_local : local_binary_atomic_op<atomic_load_max>; 330def atomic_load_umin_local : local_binary_atomic_op<atomic_load_umin>; 331def atomic_load_umax_local : local_binary_atomic_op<atomic_load_umax>; 332 333def mskor_global : PatFrag<(ops node:$val, node:$ptr), 334 (AMDGPUstore_mskor node:$val, node:$ptr), [{ 335 return cast<MemSDNode>(N)->getAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS; 336}]>; 337 338multiclass AtomicCmpSwapLocal <SDNode cmp_swap_node> { 339 340 def _32_local : PatFrag < 341 (ops node:$ptr, node:$cmp, node:$swap), 342 (cmp_swap_node node:$ptr, node:$cmp, node:$swap), [{ 343 AtomicSDNode *AN = cast<AtomicSDNode>(N); 344 return AN->getMemoryVT() == MVT::i32 && 345 AN->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS; 346 }]>; 347 348 def _64_local : PatFrag< 349 (ops node:$ptr, node:$cmp, node:$swap), 350 (cmp_swap_node node:$ptr, node:$cmp, node:$swap), [{ 351 AtomicSDNode *AN = cast<AtomicSDNode>(N); 352 return AN->getMemoryVT() == MVT::i64 && 353 AN->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS; 354 }]>; 355} 356 357defm atomic_cmp_swap : AtomicCmpSwapLocal <atomic_cmp_swap>; 358 359def mskor_flat : PatFrag<(ops node:$val, node:$ptr), 360 (AMDGPUstore_mskor node:$val, node:$ptr), [{ 361 return cast<MemSDNode>(N)->getAddressSpace() == AMDGPUAS::FLAT_ADDRESS; 362}]>; 363 364class global_binary_atomic_op<SDNode atomic_op> : PatFrag< 365 (ops node:$ptr, node:$value), 366 (atomic_op node:$ptr, node:$value), 367 [{return cast<MemSDNode>(N)->getAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS;}] 368>; 369 370class flat_binary_atomic_op<SDNode atomic_op> : PatFrag< 371 (ops node:$ptr, node:$value), 372 (atomic_op node:$ptr, node:$value), 373 [{return cast<MemSDNode>(N)->getAddressSpace() == AMDGPUAS::FLAT_ADDRESS;}] 374>; 375 376def atomic_swap_global : global_binary_atomic_op<atomic_swap>; 377def atomic_add_global : global_binary_atomic_op<atomic_load_add>; 378def atomic_and_global : global_binary_atomic_op<atomic_load_and>; 379def atomic_max_global : global_binary_atomic_op<atomic_load_max>; 380def atomic_min_global : global_binary_atomic_op<atomic_load_min>; 381def atomic_or_global : global_binary_atomic_op<atomic_load_or>; 382def atomic_sub_global : global_binary_atomic_op<atomic_load_sub>; 383def atomic_umax_global : global_binary_atomic_op<atomic_load_umax>; 384def atomic_umin_global : global_binary_atomic_op<atomic_load_umin>; 385def atomic_xor_global : global_binary_atomic_op<atomic_load_xor>; 386 387def atomic_cmp_swap_global : global_binary_atomic_op<AMDGPUatomic_cmp_swap>; 388def atomic_cmp_swap_global_nortn : PatFrag< 389 (ops node:$ptr, node:$value), 390 (atomic_cmp_swap_global node:$ptr, node:$value), 391 [{ return SDValue(N, 0).use_empty(); }] 392>; 393 394def atomic_swap_flat : flat_binary_atomic_op<atomic_swap>; 395def atomic_add_flat : flat_binary_atomic_op<atomic_load_add>; 396def atomic_and_flat : flat_binary_atomic_op<atomic_load_and>; 397def atomic_max_flat : flat_binary_atomic_op<atomic_load_max>; 398def atomic_min_flat : flat_binary_atomic_op<atomic_load_min>; 399def atomic_or_flat : flat_binary_atomic_op<atomic_load_or>; 400def atomic_sub_flat : flat_binary_atomic_op<atomic_load_sub>; 401def atomic_umax_flat : flat_binary_atomic_op<atomic_load_umax>; 402def atomic_umin_flat : flat_binary_atomic_op<atomic_load_umin>; 403def atomic_xor_flat : flat_binary_atomic_op<atomic_load_xor>; 404 405def atomic_cmp_swap_flat : flat_binary_atomic_op<AMDGPUatomic_cmp_swap>; 406 407//===----------------------------------------------------------------------===// 408// Misc Pattern Fragments 409//===----------------------------------------------------------------------===// 410 411class Constants { 412int TWO_PI = 0x40c90fdb; 413int PI = 0x40490fdb; 414int TWO_PI_INV = 0x3e22f983; 415int FP_UINT_MAX_PLUS_1 = 0x4f800000; // 1 << 32 in floating point encoding 416int FP32_NEG_ONE = 0xbf800000; 417int FP32_ONE = 0x3f800000; 418int FP64_ONE = 0x3ff0000000000000; 419} 420def CONST : Constants; 421 422def FP_ZERO : PatLeaf < 423 (fpimm), 424 [{return N->getValueAPF().isZero();}] 425>; 426 427def FP_ONE : PatLeaf < 428 (fpimm), 429 [{return N->isExactlyValue(1.0);}] 430>; 431 432def FP_HALF : PatLeaf < 433 (fpimm), 434 [{return N->isExactlyValue(0.5);}] 435>; 436 437let isCodeGenOnly = 1, isPseudo = 1 in { 438 439let usesCustomInserter = 1 in { 440 441class CLAMP <RegisterClass rc> : AMDGPUShaderInst < 442 (outs rc:$dst), 443 (ins rc:$src0), 444 "CLAMP $dst, $src0", 445 [(set f32:$dst, (AMDGPUclamp f32:$src0, (f32 FP_ZERO), (f32 FP_ONE)))] 446>; 447 448class FABS <RegisterClass rc> : AMDGPUShaderInst < 449 (outs rc:$dst), 450 (ins rc:$src0), 451 "FABS $dst, $src0", 452 [(set f32:$dst, (fabs f32:$src0))] 453>; 454 455class FNEG <RegisterClass rc> : AMDGPUShaderInst < 456 (outs rc:$dst), 457 (ins rc:$src0), 458 "FNEG $dst, $src0", 459 [(set f32:$dst, (fneg f32:$src0))] 460>; 461 462} // usesCustomInserter = 1 463 464multiclass RegisterLoadStore <RegisterClass dstClass, Operand addrClass, 465 ComplexPattern addrPat> { 466let UseNamedOperandTable = 1 in { 467 468 def RegisterLoad : AMDGPUShaderInst < 469 (outs dstClass:$dst), 470 (ins addrClass:$addr, i32imm:$chan), 471 "RegisterLoad $dst, $addr", 472 [(set i32:$dst, (AMDGPUregister_load addrPat:$addr, (i32 timm:$chan)))] 473 > { 474 let isRegisterLoad = 1; 475 } 476 477 def RegisterStore : AMDGPUShaderInst < 478 (outs), 479 (ins dstClass:$val, addrClass:$addr, i32imm:$chan), 480 "RegisterStore $val, $addr", 481 [(AMDGPUregister_store i32:$val, addrPat:$addr, (i32 timm:$chan))] 482 > { 483 let isRegisterStore = 1; 484 } 485} 486} 487 488} // End isCodeGenOnly = 1, isPseudo = 1 489 490/* Generic helper patterns for intrinsics */ 491/* -------------------------------------- */ 492 493class POW_Common <AMDGPUInst log_ieee, AMDGPUInst exp_ieee, AMDGPUInst mul> 494 : Pat < 495 (fpow f32:$src0, f32:$src1), 496 (exp_ieee (mul f32:$src1, (log_ieee f32:$src0))) 497>; 498 499/* Other helper patterns */ 500/* --------------------- */ 501 502/* Extract element pattern */ 503class Extract_Element <ValueType sub_type, ValueType vec_type, int sub_idx, 504 SubRegIndex sub_reg> 505 : Pat< 506 (sub_type (extractelt vec_type:$src, sub_idx)), 507 (EXTRACT_SUBREG $src, sub_reg) 508>; 509 510/* Insert element pattern */ 511class Insert_Element <ValueType elem_type, ValueType vec_type, 512 int sub_idx, SubRegIndex sub_reg> 513 : Pat < 514 (insertelt vec_type:$vec, elem_type:$elem, sub_idx), 515 (INSERT_SUBREG $vec, $elem, sub_reg) 516>; 517 518// XXX: Convert to new syntax and use COPY_TO_REG, once the DFAPacketizer 519// can handle COPY instructions. 520// bitconvert pattern 521class BitConvert <ValueType dt, ValueType st, RegisterClass rc> : Pat < 522 (dt (bitconvert (st rc:$src0))), 523 (dt rc:$src0) 524>; 525 526// XXX: Convert to new syntax and use COPY_TO_REG, once the DFAPacketizer 527// can handle COPY instructions. 528class DwordAddrPat<ValueType vt, RegisterClass rc> : Pat < 529 (vt (AMDGPUdwordaddr (vt rc:$addr))), 530 (vt rc:$addr) 531>; 532 533// BFI_INT patterns 534 535multiclass BFIPatterns <Instruction BFI_INT, 536 Instruction LoadImm32, 537 RegisterClass RC64> { 538 // Definition from ISA doc: 539 // (y & x) | (z & ~x) 540 def : Pat < 541 (or (and i32:$y, i32:$x), (and i32:$z, (not i32:$x))), 542 (BFI_INT $x, $y, $z) 543 >; 544 545 // SHA-256 Ch function 546 // z ^ (x & (y ^ z)) 547 def : Pat < 548 (xor i32:$z, (and i32:$x, (xor i32:$y, i32:$z))), 549 (BFI_INT $x, $y, $z) 550 >; 551 552 def : Pat < 553 (fcopysign f32:$src0, f32:$src1), 554 (BFI_INT (LoadImm32 0x7fffffff), $src0, $src1) 555 >; 556 557 def : Pat < 558 (f64 (fcopysign f64:$src0, f64:$src1)), 559 (REG_SEQUENCE RC64, 560 (i32 (EXTRACT_SUBREG $src0, sub0)), sub0, 561 (BFI_INT (LoadImm32 0x7fffffff), 562 (i32 (EXTRACT_SUBREG $src0, sub1)), 563 (i32 (EXTRACT_SUBREG $src1, sub1))), sub1) 564 >; 565} 566 567// SHA-256 Ma patterns 568 569// ((x & z) | (y & (x | z))) -> BFI_INT (XOR x, y), z, y 570class SHA256MaPattern <Instruction BFI_INT, Instruction XOR> : Pat < 571 (or (and i32:$x, i32:$z), (and i32:$y, (or i32:$x, i32:$z))), 572 (BFI_INT (XOR i32:$x, i32:$y), i32:$z, i32:$y) 573>; 574 575// Bitfield extract patterns 576 577def IMMZeroBasedBitfieldMask : PatLeaf <(imm), [{ 578 return isMask_32(N->getZExtValue()); 579}]>; 580 581def IMMPopCount : SDNodeXForm<imm, [{ 582 return CurDAG->getTargetConstant(countPopulation(N->getZExtValue()), SDLoc(N), 583 MVT::i32); 584}]>; 585 586class BFEPattern <Instruction BFE, Instruction MOV> : Pat < 587 (i32 (and (i32 (srl i32:$src, i32:$rshift)), IMMZeroBasedBitfieldMask:$mask)), 588 (BFE $src, $rshift, (MOV (i32 (IMMPopCount $mask)))) 589>; 590 591// rotr pattern 592class ROTRPattern <Instruction BIT_ALIGN> : Pat < 593 (rotr i32:$src0, i32:$src1), 594 (BIT_ALIGN $src0, $src0, $src1) 595>; 596 597// This matches 16 permutations of 598// max(min(x, y), min(max(x, y), z)) 599class IntMed3Pat<Instruction med3Inst, 600 SDPatternOperator max, 601 SDPatternOperator max_oneuse, 602 SDPatternOperator min_oneuse> : Pat< 603 (max (min_oneuse i32:$src0, i32:$src1), 604 (min_oneuse (max_oneuse i32:$src0, i32:$src1), i32:$src2)), 605 (med3Inst $src0, $src1, $src2) 606>; 607 608let Properties = [SDNPCommutative, SDNPAssociative] in { 609def smax_oneuse : HasOneUseBinOp<smax>; 610def smin_oneuse : HasOneUseBinOp<smin>; 611def umax_oneuse : HasOneUseBinOp<umax>; 612def umin_oneuse : HasOneUseBinOp<umin>; 613} // Properties = [SDNPCommutative, SDNPAssociative] 614 615 616// 24-bit arithmetic patterns 617def umul24 : PatFrag <(ops node:$x, node:$y), (mul node:$x, node:$y)>; 618 619// Special conversion patterns 620 621def cvt_rpi_i32_f32 : PatFrag < 622 (ops node:$src), 623 (fp_to_sint (ffloor (fadd $src, FP_HALF))), 624 [{ (void) N; return TM.Options.NoNaNsFPMath; }] 625>; 626 627def cvt_flr_i32_f32 : PatFrag < 628 (ops node:$src), 629 (fp_to_sint (ffloor $src)), 630 [{ (void)N; return TM.Options.NoNaNsFPMath; }] 631>; 632 633class IMad24Pat<Instruction Inst> : Pat < 634 (add (AMDGPUmul_i24 i32:$src0, i32:$src1), i32:$src2), 635 (Inst $src0, $src1, $src2) 636>; 637 638class UMad24Pat<Instruction Inst> : Pat < 639 (add (AMDGPUmul_u24 i32:$src0, i32:$src1), i32:$src2), 640 (Inst $src0, $src1, $src2) 641>; 642 643class RcpPat<Instruction RcpInst, ValueType vt> : Pat < 644 (fdiv FP_ONE, vt:$src), 645 (RcpInst $src) 646>; 647 648class RsqPat<Instruction RsqInst, ValueType vt> : Pat < 649 (AMDGPUrcp (fsqrt vt:$src)), 650 (RsqInst $src) 651>; 652 653include "R600Instructions.td" 654include "R700Instructions.td" 655include "EvergreenInstructions.td" 656include "CaymanInstructions.td" 657 658include "SIInstrInfo.td" 659 660