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