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 365def mskor_flat : PatFrag<(ops node:$val, node:$ptr), 366 (AMDGPUstore_mskor node:$val, node:$ptr), [{ 367 return cast<MemSDNode>(N)->getAddressSpace() == AMDGPUAS::FLAT_ADDRESS; 368}]>; 369 370class global_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::GLOBAL_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 394//===----------------------------------------------------------------------===// 395// Misc Pattern Fragments 396//===----------------------------------------------------------------------===// 397 398class Constants { 399int TWO_PI = 0x40c90fdb; 400int PI = 0x40490fdb; 401int TWO_PI_INV = 0x3e22f983; 402int FP_UINT_MAX_PLUS_1 = 0x4f800000; // 1 << 32 in floating point encoding 403int FP32_ONE = 0x3f800000; 404int FP32_NEG_ONE = 0xbf800000; 405int FP64_ONE = 0x3ff0000000000000; 406int FP64_NEG_ONE = 0xbff0000000000000; 407} 408def CONST : Constants; 409 410def FP_ZERO : PatLeaf < 411 (fpimm), 412 [{return N->getValueAPF().isZero();}] 413>; 414 415def FP_ONE : PatLeaf < 416 (fpimm), 417 [{return N->isExactlyValue(1.0);}] 418>; 419 420def FP_HALF : PatLeaf < 421 (fpimm), 422 [{return N->isExactlyValue(0.5);}] 423>; 424 425let isCodeGenOnly = 1, isPseudo = 1 in { 426 427let usesCustomInserter = 1 in { 428 429class CLAMP <RegisterClass rc> : AMDGPUShaderInst < 430 (outs rc:$dst), 431 (ins rc:$src0), 432 "CLAMP $dst, $src0", 433 [(set f32:$dst, (AMDGPUclamp f32:$src0, (f32 FP_ZERO), (f32 FP_ONE)))] 434>; 435 436class FABS <RegisterClass rc> : AMDGPUShaderInst < 437 (outs rc:$dst), 438 (ins rc:$src0), 439 "FABS $dst, $src0", 440 [(set f32:$dst, (fabs f32:$src0))] 441>; 442 443class FNEG <RegisterClass rc> : AMDGPUShaderInst < 444 (outs rc:$dst), 445 (ins rc:$src0), 446 "FNEG $dst, $src0", 447 [(set f32:$dst, (fneg f32:$src0))] 448>; 449 450} // usesCustomInserter = 1 451 452multiclass RegisterLoadStore <RegisterClass dstClass, Operand addrClass, 453 ComplexPattern addrPat> { 454let UseNamedOperandTable = 1 in { 455 456 def RegisterLoad : AMDGPUShaderInst < 457 (outs dstClass:$dst), 458 (ins addrClass:$addr, i32imm:$chan), 459 "RegisterLoad $dst, $addr", 460 [(set i32:$dst, (AMDGPUregister_load addrPat:$addr, (i32 timm:$chan)))] 461 > { 462 let isRegisterLoad = 1; 463 } 464 465 def RegisterStore : AMDGPUShaderInst < 466 (outs), 467 (ins dstClass:$val, addrClass:$addr, i32imm:$chan), 468 "RegisterStore $val, $addr", 469 [(AMDGPUregister_store i32:$val, addrPat:$addr, (i32 timm:$chan))] 470 > { 471 let isRegisterStore = 1; 472 } 473} 474} 475 476} // End isCodeGenOnly = 1, isPseudo = 1 477 478/* Generic helper patterns for intrinsics */ 479/* -------------------------------------- */ 480 481class POW_Common <AMDGPUInst log_ieee, AMDGPUInst exp_ieee, AMDGPUInst mul> 482 : Pat < 483 (fpow f32:$src0, f32:$src1), 484 (exp_ieee (mul f32:$src1, (log_ieee f32:$src0))) 485>; 486 487/* Other helper patterns */ 488/* --------------------- */ 489 490/* Extract element pattern */ 491class Extract_Element <ValueType sub_type, ValueType vec_type, int sub_idx, 492 SubRegIndex sub_reg> 493 : Pat< 494 (sub_type (extractelt vec_type:$src, sub_idx)), 495 (EXTRACT_SUBREG $src, sub_reg) 496>; 497 498/* Insert element pattern */ 499class Insert_Element <ValueType elem_type, ValueType vec_type, 500 int sub_idx, SubRegIndex sub_reg> 501 : Pat < 502 (insertelt vec_type:$vec, elem_type:$elem, sub_idx), 503 (INSERT_SUBREG $vec, $elem, sub_reg) 504>; 505 506// XXX: Convert to new syntax and use COPY_TO_REG, once the DFAPacketizer 507// can handle COPY instructions. 508// bitconvert pattern 509class BitConvert <ValueType dt, ValueType st, RegisterClass rc> : Pat < 510 (dt (bitconvert (st rc:$src0))), 511 (dt rc:$src0) 512>; 513 514// XXX: Convert to new syntax and use COPY_TO_REG, once the DFAPacketizer 515// can handle COPY instructions. 516class DwordAddrPat<ValueType vt, RegisterClass rc> : Pat < 517 (vt (AMDGPUdwordaddr (vt rc:$addr))), 518 (vt rc:$addr) 519>; 520 521// BFI_INT patterns 522 523multiclass BFIPatterns <Instruction BFI_INT, 524 Instruction LoadImm32, 525 RegisterClass RC64> { 526 // Definition from ISA doc: 527 // (y & x) | (z & ~x) 528 def : Pat < 529 (or (and i32:$y, i32:$x), (and i32:$z, (not i32:$x))), 530 (BFI_INT $x, $y, $z) 531 >; 532 533 // SHA-256 Ch function 534 // z ^ (x & (y ^ z)) 535 def : Pat < 536 (xor i32:$z, (and i32:$x, (xor i32:$y, i32:$z))), 537 (BFI_INT $x, $y, $z) 538 >; 539 540 def : Pat < 541 (fcopysign f32:$src0, f32:$src1), 542 (BFI_INT (LoadImm32 0x7fffffff), $src0, $src1) 543 >; 544 545 def : Pat < 546 (f64 (fcopysign f64:$src0, f64:$src1)), 547 (REG_SEQUENCE RC64, 548 (i32 (EXTRACT_SUBREG $src0, sub0)), sub0, 549 (BFI_INT (LoadImm32 0x7fffffff), 550 (i32 (EXTRACT_SUBREG $src0, sub1)), 551 (i32 (EXTRACT_SUBREG $src1, sub1))), sub1) 552 >; 553} 554 555// SHA-256 Ma patterns 556 557// ((x & z) | (y & (x | z))) -> BFI_INT (XOR x, y), z, y 558class SHA256MaPattern <Instruction BFI_INT, Instruction XOR> : Pat < 559 (or (and i32:$x, i32:$z), (and i32:$y, (or i32:$x, i32:$z))), 560 (BFI_INT (XOR i32:$x, i32:$y), i32:$z, i32:$y) 561>; 562 563// Bitfield extract patterns 564 565def IMMZeroBasedBitfieldMask : PatLeaf <(imm), [{ 566 return isMask_32(N->getZExtValue()); 567}]>; 568 569def IMMPopCount : SDNodeXForm<imm, [{ 570 return CurDAG->getTargetConstant(countPopulation(N->getZExtValue()), SDLoc(N), 571 MVT::i32); 572}]>; 573 574class BFEPattern <Instruction BFE, Instruction MOV> : Pat < 575 (i32 (and (i32 (srl i32:$src, i32:$rshift)), IMMZeroBasedBitfieldMask:$mask)), 576 (BFE $src, $rshift, (MOV (i32 (IMMPopCount $mask)))) 577>; 578 579// rotr pattern 580class ROTRPattern <Instruction BIT_ALIGN> : Pat < 581 (rotr i32:$src0, i32:$src1), 582 (BIT_ALIGN $src0, $src0, $src1) 583>; 584 585// This matches 16 permutations of 586// max(min(x, y), min(max(x, y), z)) 587class IntMed3Pat<Instruction med3Inst, 588 SDPatternOperator max, 589 SDPatternOperator max_oneuse, 590 SDPatternOperator min_oneuse> : Pat< 591 (max (min_oneuse i32:$src0, i32:$src1), 592 (min_oneuse (max_oneuse i32:$src0, i32:$src1), i32:$src2)), 593 (med3Inst $src0, $src1, $src2) 594>; 595 596let Properties = [SDNPCommutative, SDNPAssociative] in { 597def smax_oneuse : HasOneUseBinOp<smax>; 598def smin_oneuse : HasOneUseBinOp<smin>; 599def umax_oneuse : HasOneUseBinOp<umax>; 600def umin_oneuse : HasOneUseBinOp<umin>; 601def sub_oneuse : HasOneUseBinOp<sub>; 602} // Properties = [SDNPCommutative, SDNPAssociative] 603 604def select_oneuse : HasOneUseTernaryOp<select>; 605 606// 24-bit arithmetic patterns 607def umul24 : PatFrag <(ops node:$x, node:$y), (mul node:$x, node:$y)>; 608 609// Special conversion patterns 610 611def cvt_rpi_i32_f32 : PatFrag < 612 (ops node:$src), 613 (fp_to_sint (ffloor (fadd $src, FP_HALF))), 614 [{ (void) N; return TM.Options.NoNaNsFPMath; }] 615>; 616 617def cvt_flr_i32_f32 : PatFrag < 618 (ops node:$src), 619 (fp_to_sint (ffloor $src)), 620 [{ (void)N; return TM.Options.NoNaNsFPMath; }] 621>; 622 623class IMad24Pat<Instruction Inst> : Pat < 624 (add (AMDGPUmul_i24 i32:$src0, i32:$src1), i32:$src2), 625 (Inst $src0, $src1, $src2) 626>; 627 628class UMad24Pat<Instruction Inst> : Pat < 629 (add (AMDGPUmul_u24 i32:$src0, i32:$src1), i32:$src2), 630 (Inst $src0, $src1, $src2) 631>; 632 633class RcpPat<Instruction RcpInst, ValueType vt> : Pat < 634 (fdiv FP_ONE, vt:$src), 635 (RcpInst $src) 636>; 637 638class RsqPat<Instruction RsqInst, ValueType vt> : Pat < 639 (AMDGPUrcp (fsqrt vt:$src)), 640 (RsqInst $src) 641>; 642 643include "R600Instructions.td" 644include "R700Instructions.td" 645include "EvergreenInstructions.td" 646include "CaymanInstructions.td" 647 648include "SIInstrInfo.td" 649 650