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