1//===-- VEInstrInfo.td - Target Description for VE Target -----------------===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// This file describes the VE instructions in TableGen format. 10// 11//===----------------------------------------------------------------------===// 12 13//===----------------------------------------------------------------------===// 14// Instruction format superclass 15//===----------------------------------------------------------------------===// 16 17include "VEInstrFormats.td" 18 19//===----------------------------------------------------------------------===// 20// Helper functions to retrieve target constants. 21// 22// VE instructions have a space to hold following immediates 23// $sy has 7 bits to represent simm7, uimm7, simm7fp, or uimm7fp. 24// $sz also has 7 bits to represent mimm or mimmfp. 25// $disp has 32 bits to represent simm32. 26// 27// The mimm is a special immediate value of sequential bit stream of 0 or 1. 28// `(m)0`: Represents 0 sequence then 1 sequence like 0b00...0011...11, 29// where `m` is equal to the number of leading zeros. 30// `(m)1`: Represents 1 sequence then 0 sequence like 0b11...1100...00, 31// where `m` is equal to the number of leading ones. 32// Each bit of mimm's 7 bits is used like below: 33// bit 6 : If `(m)0`, this bit is 1. Otherwise, this bit is 0. 34// bit 5-0: Represents the m (0-63). 35// Use `!add(m, 64)` to generates an immediate value in pattern matchings. 36// 37// The floating point immediate value is not something like compacted value. 38// It is simple integer representation, so it works rarely. 39// e.g. 0.0 (0x00000000) or -2.0 (0xC0000000=(2)1). 40//===----------------------------------------------------------------------===// 41 42def ULO7 : SDNodeXForm<imm, [{ 43 return CurDAG->getTargetConstant(N->getZExtValue() & 0x7f, 44 SDLoc(N), MVT::i32); 45}]>; 46def LO7 : SDNodeXForm<imm, [{ 47 return CurDAG->getTargetConstant(SignExtend32(N->getSExtValue(), 7), 48 SDLoc(N), MVT::i32); 49}]>; 50def MIMM : SDNodeXForm<imm, [{ 51 return CurDAG->getTargetConstant(val2MImm(getImmVal(N)), 52 SDLoc(N), MVT::i32); 53}]>; 54def LO32 : SDNodeXForm<imm, [{ 55 return CurDAG->getTargetConstant(Lo_32(N->getZExtValue()), 56 SDLoc(N), MVT::i32); 57}]>; 58def HI32 : SDNodeXForm<imm, [{ 59 // Transformation function: shift the immediate value down into the low bits. 60 return CurDAG->getTargetConstant(Hi_32(N->getZExtValue()), 61 SDLoc(N), MVT::i32); 62}]>; 63 64def LO7FP : SDNodeXForm<fpimm, [{ 65 uint64_t Val = getFpImmVal(N); 66 return CurDAG->getTargetConstant(SignExtend32(Val, 7), SDLoc(N), MVT::i32); 67}]>; 68def MIMMFP : SDNodeXForm<fpimm, [{ 69 return CurDAG->getTargetConstant(val2MImm(getFpImmVal(N)), 70 SDLoc(N), MVT::i32); 71}]>; 72def LOFP32 : SDNodeXForm<fpimm, [{ 73 return CurDAG->getTargetConstant(Lo_32(getFpImmVal(N) & 0xffffffff), 74 SDLoc(N), MVT::i32); 75}]>; 76def HIFP32 : SDNodeXForm<fpimm, [{ 77 return CurDAG->getTargetConstant(Hi_32(getFpImmVal(N)), SDLoc(N), MVT::i32); 78}]>; 79 80def icond2cc : SDNodeXForm<cond, [{ 81 VECC::CondCode VECC = intCondCode2Icc(N->get()); 82 return CurDAG->getTargetConstant(VECC, SDLoc(N), MVT::i32); 83}]>; 84 85def icond2ccSwap : SDNodeXForm<cond, [{ 86 ISD::CondCode CC = getSetCCSwappedOperands(N->get()); 87 VECC::CondCode VECC = intCondCode2Icc(CC); 88 return CurDAG->getTargetConstant(VECC, SDLoc(N), MVT::i32); 89}]>; 90 91def fcond2cc : SDNodeXForm<cond, [{ 92 VECC::CondCode VECC = fpCondCode2Fcc(N->get()); 93 return CurDAG->getTargetConstant(VECC, SDLoc(N), MVT::i32); 94}]>; 95 96def fcond2ccSwap : SDNodeXForm<cond, [{ 97 ISD::CondCode CC = getSetCCSwappedOperands(N->get()); 98 VECC::CondCode VECC = fpCondCode2Fcc(CC); 99 return CurDAG->getTargetConstant(VECC, SDLoc(N), MVT::i32); 100}]>; 101 102def CCOP : SDNodeXForm<imm, [{ 103 return CurDAG->getTargetConstant(N->getZExtValue(), 104 SDLoc(N), MVT::i32); 105}]>; 106 107//===----------------------------------------------------------------------===// 108// Feature predicates. 109//===----------------------------------------------------------------------===// 110 111//===----------------------------------------------------------------------===// 112// Instruction Pattern Stuff 113//===----------------------------------------------------------------------===// 114 115// zero 116def ZeroAsmOperand : AsmOperandClass { 117 let Name = "Zero"; 118} 119def zero : Operand<i32>, PatLeaf<(imm), [{ 120 return N->getSExtValue() == 0; }]> { 121 let ParserMatchClass = ZeroAsmOperand; 122} 123 124// uimm0to2 - Special immediate value represents 0, 1, and 2. 125def UImm0to2AsmOperand : AsmOperandClass { 126 let Name = "UImm0to2"; 127} 128def uimm0to2 : Operand<i32>, PatLeaf<(imm), [{ 129 return N->getZExtValue() < 3; }], ULO7> { 130 let ParserMatchClass = UImm0to2AsmOperand; 131} 132 133// uimm1 - Generic immediate value. 134def UImm1AsmOperand : AsmOperandClass { 135 let Name = "UImm1"; 136} 137def uimm1 : Operand<i32>, PatLeaf<(imm), [{ 138 return isUInt<1>(N->getZExtValue()); }], ULO7> { 139 let ParserMatchClass = UImm1AsmOperand; 140} 141 142// uimm2 - Generic immediate value. 143def UImm2AsmOperand : AsmOperandClass { 144 let Name = "UImm2"; 145} 146def uimm2 : Operand<i32>, PatLeaf<(imm), [{ 147 return isUInt<2>(N->getZExtValue()); }], ULO7> { 148 let ParserMatchClass = UImm2AsmOperand; 149} 150 151// uimm3 - Generic immediate value. 152def UImm3AsmOperand : AsmOperandClass { 153 let Name = "UImm3"; 154} 155def uimm3 : Operand<i32>, PatLeaf<(imm), [{ 156 return isUInt<3>(N->getZExtValue()); }], ULO7> { 157 let ParserMatchClass = UImm3AsmOperand; 158} 159 160// uimm4 - Generic immediate value. 161def UImm4AsmOperand : AsmOperandClass { 162 let Name = "UImm4"; 163} 164def uimm4 : Operand<i32>, PatLeaf<(imm), [{ 165 return isUInt<4>(N->getZExtValue()); }], ULO7> { 166 let ParserMatchClass = UImm4AsmOperand; 167} 168 169// uimm6 - Generic immediate value. 170def UImm6AsmOperand : AsmOperandClass { 171 let Name = "UImm6"; 172} 173def uimm6 : Operand<i32>, PatLeaf<(imm), [{ 174 return isUInt<6>(N->getZExtValue()); }], ULO7> { 175 let ParserMatchClass = UImm6AsmOperand; 176} 177 178// uimm7 - Generic immediate value. 179def UImm7AsmOperand : AsmOperandClass { 180 let Name = "UImm7"; 181} 182def uimm7 : Operand<i32>, PatLeaf<(imm), [{ 183 return isUInt<7>(N->getZExtValue()); }], ULO7> { 184 let ParserMatchClass = UImm7AsmOperand; 185} 186 187// simm7 - Generic immediate value. 188def SImm7AsmOperand : AsmOperandClass { 189 let Name = "SImm7"; 190} 191def simm7 : Operand<i32>, PatLeaf<(imm), [{ 192 return isInt<7>(N->getSExtValue()); }], LO7> { 193 let ParserMatchClass = SImm7AsmOperand; 194 let DecoderMethod = "DecodeSIMM7"; 195} 196 197// mimm - Special immediate value of sequential bit stream of 0 or 1. 198def MImmAsmOperand : AsmOperandClass { 199 let Name = "MImm"; 200 let ParserMethod = "parseMImmOperand"; 201} 202def mimm : Operand<i32>, PatLeaf<(imm), [{ 203 return isMImmVal(getImmVal(N)); }], MIMM> { 204 let ParserMatchClass = MImmAsmOperand; 205 let PrintMethod = "printMImmOperand"; 206} 207 208// zerofp - Generic fp immediate zero value. 209def zerofp : Operand<i32>, PatLeaf<(fpimm), [{ 210 return getFpImmVal(N) == 0; }]> { 211 let ParserMatchClass = ZeroAsmOperand; 212} 213 214// simm7fp - Generic fp immediate value. 215def simm7fp : Operand<i32>, PatLeaf<(fpimm), [{ 216 return isInt<7>(getFpImmVal(N)); 217 }], LO7FP> { 218 let ParserMatchClass = SImm7AsmOperand; 219 let DecoderMethod = "DecodeSIMM7"; 220} 221 222// mimmfp - Special fp immediate value of sequential bit stream of 0 or 1. 223def mimmfp : Operand<i32>, PatLeaf<(fpimm), [{ 224 return isMImmVal(getFpImmVal(N)); }], MIMMFP> { 225 let ParserMatchClass = MImmAsmOperand; 226 let PrintMethod = "printMImmOperand"; 227} 228 229// mimmfp32 - 32 bit width mimmfp 230// Float value places at higher bits, so ignore lower 32 bits. 231def mimmfp32 : Operand<i32>, PatLeaf<(fpimm), [{ 232 return isMImm32Val(getFpImmVal(N) >> 32); }], MIMMFP> { 233 let ParserMatchClass = MImmAsmOperand; 234 let PrintMethod = "printMImmOperand"; 235} 236 237// other generic patterns to use in pattern matchings 238def simm32 : PatLeaf<(imm), [{ return isInt<32>(N->getSExtValue()); }]>; 239def uimm32 : PatLeaf<(imm), [{ return isUInt<32>(N->getZExtValue()); }]>; 240def lomsbzero : PatLeaf<(imm), [{ return (N->getZExtValue() & 0x80000000) 241 == 0; }]>; 242def lozero : PatLeaf<(imm), [{ return (N->getZExtValue() & 0xffffffff) 243 == 0; }]>; 244def fplomsbzero : PatLeaf<(fpimm), [{ return (getFpImmVal(N) & 0x80000000) 245 == 0; }]>; 246def fplozero : PatLeaf<(fpimm), [{ return (getFpImmVal(N) & 0xffffffff) 247 == 0; }]>; 248 249def CCSIOp : PatLeaf<(cond), [{ 250 switch (N->get()) { 251 default: return true; 252 case ISD::SETULT: 253 case ISD::SETULE: 254 case ISD::SETUGT: 255 case ISD::SETUGE: return false; 256 } 257}]>; 258 259def CCUIOp : PatLeaf<(cond), [{ 260 switch (N->get()) { 261 default: return true; 262 case ISD::SETLT: 263 case ISD::SETLE: 264 case ISD::SETGT: 265 case ISD::SETGE: return false; 266 } 267}]>; 268 269//===----------------------------------------------------------------------===// 270// Addressing modes. 271// SX-Aurora has following fields. 272// sz: register or 0 273// sy: register or immediate (-64 to 63) 274// disp: immediate (-2147483648 to 2147483647) 275// 276// There are two kinds of instruction. 277// ASX format uses sz + sy + disp. 278// AS format uses sz + disp. 279// 280// Moreover, there are four kinds of assembly instruction format. 281// ASX format uses "disp", "disp(, sz)", "disp(sy)", "disp(sy, sz)", 282// "(, sz)", "(sy)", or "(sy, sz)". 283// AS format uses "disp", "disp(, sz)", or "(, sz)" in general. 284// AS format in RRM format uses "disp", "disp(sz)", or "(sz)". 285// AS format in RRM format for host memory access uses "sz", "(sz)", 286// or "disp(sz)". 287// 288// We defined them below. 289// 290// ASX format: 291// MEMrri, MEMrii, MEMzri, MEMzii 292// AS format: 293// MEMriASX, MEMziASX : simple AS format 294// MEMriRRM, MEMziRRM : AS format in RRM format 295// MEMriHM, MEMziHM : AS format in RRM format for host memory access 296//===----------------------------------------------------------------------===// 297 298// DAG selections for both ASX and AS formats. 299def ADDRrri : ComplexPattern<iPTR, 3, "selectADDRrri", [frameindex], []>; 300def ADDRrii : ComplexPattern<iPTR, 3, "selectADDRrii", [frameindex], []>; 301def ADDRzri : ComplexPattern<iPTR, 3, "selectADDRzri", [], []>; 302def ADDRzii : ComplexPattern<iPTR, 3, "selectADDRzii", [], []>; 303def ADDRri : ComplexPattern<iPTR, 2, "selectADDRri", [frameindex], []>; 304def ADDRzi : ComplexPattern<iPTR, 2, "selectADDRzi", [], []>; 305 306// ASX format. 307def VEMEMrriAsmOperand : AsmOperandClass { 308 let Name = "MEMrri"; 309 let ParserMethod = "parseMEMOperand"; 310} 311def VEMEMriiAsmOperand : AsmOperandClass { 312 let Name = "MEMrii"; 313 let ParserMethod = "parseMEMOperand"; 314} 315def VEMEMzriAsmOperand : AsmOperandClass { 316 let Name = "MEMzri"; 317 let ParserMethod = "parseMEMOperand"; 318} 319def VEMEMziiAsmOperand : AsmOperandClass { 320 let Name = "MEMzii"; 321 let ParserMethod = "parseMEMOperand"; 322} 323 324// ASX format uses single assembly instruction format. 325def MEMrri : Operand<iPTR> { 326 let PrintMethod = "printMemASXOperand"; 327 let MIOperandInfo = (ops ptr_rc, ptr_rc, i32imm); 328 let ParserMatchClass = VEMEMrriAsmOperand; 329} 330def MEMrii : Operand<iPTR> { 331 let PrintMethod = "printMemASXOperand"; 332 let MIOperandInfo = (ops ptr_rc, i32imm, i32imm); 333 let ParserMatchClass = VEMEMriiAsmOperand; 334} 335def MEMzri : Operand<iPTR> { 336 let PrintMethod = "printMemASXOperand"; 337 let MIOperandInfo = (ops i32imm /* = 0 */, ptr_rc, i32imm); 338 let ParserMatchClass = VEMEMzriAsmOperand; 339} 340def MEMzii : Operand<iPTR> { 341 let PrintMethod = "printMemASXOperand"; 342 let MIOperandInfo = (ops i32imm /* = 0 */, i32imm, i32imm); 343 let ParserMatchClass = VEMEMziiAsmOperand; 344} 345 346// AS format. 347def VEMEMriAsmOperand : AsmOperandClass { 348 let Name = "MEMri"; 349 let ParserMethod = "parseMEMAsOperand"; 350} 351def VEMEMziAsmOperand : AsmOperandClass { 352 let Name = "MEMzi"; 353 let ParserMethod = "parseMEMAsOperand"; 354} 355 356// AS format uses multiple assembly instruction formats 357// 1. AS generic assembly instruction format: 358def MEMriASX : Operand<iPTR> { 359 let PrintMethod = "printMemASOperandASX"; 360 let MIOperandInfo = (ops ptr_rc, i32imm); 361 let ParserMatchClass = VEMEMriAsmOperand; 362} 363def MEMziASX : Operand<iPTR> { 364 let PrintMethod = "printMemASOperandASX"; 365 let MIOperandInfo = (ops i32imm /* = 0 */, i32imm); 366 let ParserMatchClass = VEMEMziAsmOperand; 367} 368 369// 2. AS RRM style assembly instruction format: 370def MEMriRRM : Operand<iPTR> { 371 let PrintMethod = "printMemASOperandRRM"; 372 let MIOperandInfo = (ops ptr_rc, i32imm); 373 let ParserMatchClass = VEMEMriAsmOperand; 374} 375def MEMziRRM : Operand<iPTR> { 376 let PrintMethod = "printMemASOperandRRM"; 377 let MIOperandInfo = (ops i32imm /* = 0 */, i32imm); 378 let ParserMatchClass = VEMEMziAsmOperand; 379} 380 381// 3. AS HM style assembly instruction format: 382def MEMriHM : Operand<iPTR> { 383 let PrintMethod = "printMemASOperandHM"; 384 let MIOperandInfo = (ops ptr_rc, i32imm); 385 let ParserMatchClass = VEMEMriAsmOperand; 386} 387def MEMziHM : Operand<iPTR> { 388 let PrintMethod = "printMemASOperandHM"; 389 let MIOperandInfo = (ops i32imm /* = 0 */, i32imm); 390 let ParserMatchClass = VEMEMziAsmOperand; 391} 392 393//===----------------------------------------------------------------------===// 394// Other operands. 395//===----------------------------------------------------------------------===// 396 397// Branch targets have OtherVT type. 398def brtarget32 : Operand<OtherVT> { 399 let EncoderMethod = "getBranchTargetOpValue"; 400 let DecoderMethod = "DecodeSIMM32"; 401} 402 403// Operand for printing out a condition code. 404def CCOpAsmOperand : AsmOperandClass { let Name = "CCOp"; } 405def CCOp : Operand<i32>, ImmLeaf<i32, [{ 406 return Imm >= 0 && Imm < 22; }], CCOP> { 407 let PrintMethod = "printCCOperand"; 408 let DecoderMethod = "DecodeCCOperand"; 409 let EncoderMethod = "getCCOpValue"; 410 let ParserMatchClass = CCOpAsmOperand; 411} 412 413// Operand for a rounding mode code. 414def RDOpAsmOperand : AsmOperandClass { 415 let Name = "RDOp"; 416} 417def RDOp : Operand<i32> { 418 let PrintMethod = "printRDOperand"; 419 let DecoderMethod = "DecodeRDOperand"; 420 let EncoderMethod = "getRDOpValue"; 421 let ParserMatchClass = RDOpAsmOperand; 422} 423 424def VEhi : SDNode<"VEISD::Hi", SDTIntUnaryOp>; 425def VElo : SDNode<"VEISD::Lo", SDTIntUnaryOp>; 426 427// These are target-independent nodes, but have target-specific formats. 428def SDT_SPCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i64>, 429 SDTCisVT<1, i64> ]>; 430def SDT_SPCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i64>, 431 SDTCisVT<1, i64> ]>; 432 433def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPCallSeqStart, 434 [SDNPHasChain, SDNPOutGlue]>; 435def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SPCallSeqEnd, 436 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 437 438def SDT_SPCall : SDTypeProfile<0, -1, [SDTCisVT<0, i64>]>; 439def call : SDNode<"VEISD::CALL", SDT_SPCall, 440 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 441 SDNPVariadic]>; 442 443def retflag : SDNode<"VEISD::RET_FLAG", SDTNone, 444 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 445 446def getGOT : Operand<iPTR>; 447 448// GETFUNPLT for PIC 449def GetFunPLT : SDNode<"VEISD::GETFUNPLT", SDTIntUnaryOp>; 450 451// GETTLSADDR for TLS 452def GetTLSAddr : SDNode<"VEISD::GETTLSADDR", SDT_SPCall, 453 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 454 SDNPVariadic]>; 455 456// GETSTACKTOP 457def GetStackTop : SDNode<"VEISD::GETSTACKTOP", SDTNone, 458 [SDNPHasChain, SDNPSideEffect]>; 459 460// MEMBARRIER 461def MemBarrier : SDNode<"VEISD::MEMBARRIER", SDTNone, 462 [SDNPHasChain, SDNPSideEffect]>; 463 464//===----------------------------------------------------------------------===// 465// VE Flag Conditions 466//===----------------------------------------------------------------------===// 467 468// Note that these values must be kept in sync with the CCOp::CondCode enum 469// values. 470class CC_VAL<int N> : PatLeaf<(i32 N)>; 471def CC_IG : CC_VAL< 0>; // Greater 472def CC_IL : CC_VAL< 1>; // Less 473def CC_INE : CC_VAL< 2>; // Not Equal 474def CC_IEQ : CC_VAL< 3>; // Equal 475def CC_IGE : CC_VAL< 4>; // Greater or Equal 476def CC_ILE : CC_VAL< 5>; // Less or Equal 477def CC_AF : CC_VAL< 6>; // Always false 478def CC_G : CC_VAL< 7>; // Greater 479def CC_L : CC_VAL< 8>; // Less 480def CC_NE : CC_VAL< 9>; // Not Equal 481def CC_EQ : CC_VAL<10>; // Equal 482def CC_GE : CC_VAL<11>; // Greater or Equal 483def CC_LE : CC_VAL<12>; // Less or Equal 484def CC_NUM : CC_VAL<13>; // Number 485def CC_NAN : CC_VAL<14>; // NaN 486def CC_GNAN : CC_VAL<15>; // Greater or NaN 487def CC_LNAN : CC_VAL<16>; // Less or NaN 488def CC_NENAN : CC_VAL<17>; // Not Equal or NaN 489def CC_EQNAN : CC_VAL<18>; // Equal or NaN 490def CC_GENAN : CC_VAL<19>; // Greater or Equal or NaN 491def CC_LENAN : CC_VAL<20>; // Less or Equal or NaN 492def CC_AT : CC_VAL<21>; // Always true 493 494//===----------------------------------------------------------------------===// 495// VE Rounding Mode 496//===----------------------------------------------------------------------===// 497 498// Note that these values must be kept in sync with the VERD::RoundingMode enum 499// values. 500class RD_VAL<int N> : PatLeaf<(i32 N)>; 501def RD_NONE : RD_VAL< 0>; // According to PSW 502def RD_RZ : RD_VAL< 8>; // Round toward Zero 503def RD_RP : RD_VAL< 9>; // Round toward Plus infinity 504def RD_RM : RD_VAL<10>; // Round toward Minus infinity 505def RD_RN : RD_VAL<11>; // Round to Nearest (ties to Even) 506def RD_RA : RD_VAL<12>; // Round to Nearest (ties to Away) 507 508//===----------------------------------------------------------------------===// 509// VE Multiclasses for common instruction formats 510//===----------------------------------------------------------------------===// 511 512// Multiclass for generic RR type instructions 513let hasSideEffects = 0 in 514multiclass RRbm<string opcStr, bits<8>opc, 515 RegisterClass RCo, ValueType Tyo, 516 RegisterClass RCi, ValueType Tyi, 517 SDPatternOperator OpNode = null_frag, 518 Operand immOp = simm7, Operand mOp = mimm, 519 bit MoveImm = 0> { 520 def rr : RR<opc, (outs RCo:$sx), (ins RCi:$sy, RCi:$sz), 521 !strconcat(opcStr, " $sx, $sy, $sz"), 522 [(set Tyo:$sx, (OpNode Tyi:$sy, Tyi:$sz))]>; 523 // VE calculates (OpNode $sy, $sz), but llvm requires to have immediate 524 // in RHS, so we use following definition. 525 let cy = 0 in 526 def ri : RR<opc, (outs RCo:$sx), (ins RCi:$sz, immOp:$sy), 527 !strconcat(opcStr, " $sx, $sy, $sz"), 528 [(set Tyo:$sx, (OpNode Tyi:$sz, (Tyi immOp:$sy)))]>; 529 let cz = 0 in 530 def rm : RR<opc, (outs RCo:$sx), (ins RCi:$sy, mOp:$sz), 531 !strconcat(opcStr, " $sx, $sy, $sz"), 532 [(set Tyo:$sx, (OpNode Tyi:$sy, (Tyi mOp:$sz)))]>; 533 let cy = 0, cz = 0 in 534 def im : RR<opc, (outs RCo:$sx), (ins immOp:$sy, mOp:$sz), 535 !strconcat(opcStr, " $sx, $sy, $sz"), 536 [(set Tyo:$sx, (OpNode (Tyi immOp:$sy), (Tyi mOp:$sz)))]> { 537 // VE uses ORim as a move immediate instruction, so declare it here. 538 // An instruction declared as MoveImm will be optimized in FoldImmediate 539 // later. 540 let isMoveImm = MoveImm; 541 } 542} 543 544// Multiclass for non-commutative RR type instructions 545let hasSideEffects = 0 in 546multiclass RRNCbm<string opcStr, bits<8>opc, 547 RegisterClass RCo, ValueType Tyo, 548 RegisterClass RCi, ValueType Tyi, 549 SDPatternOperator OpNode = null_frag, 550 Operand immOp = simm7, Operand mOp = mimm> { 551 def rr : RR<opc, (outs RCo:$sx), (ins RCi:$sy, RCi:$sz), 552 !strconcat(opcStr, " $sx, $sy, $sz"), 553 [(set Tyo:$sx, (OpNode Tyi:$sy, Tyi:$sz))]>; 554 let cy = 0 in 555 def ir : RR<opc, (outs RCo:$sx), (ins immOp:$sy, RCi:$sz), 556 !strconcat(opcStr, " $sx, $sy, $sz"), 557 [(set Tyo:$sx, (OpNode (Tyi immOp:$sy), Tyi:$sz))]>; 558 let cz = 0 in 559 def rm : RR<opc, (outs RCo:$sx), (ins RCi:$sy, mOp:$sz), 560 !strconcat(opcStr, " $sx, $sy, $sz"), 561 [(set Tyo:$sx, (OpNode Tyi:$sy, (Tyi mOp:$sz)))]>; 562 let cy = 0, cz = 0 in 563 def im : RR<opc, (outs RCo:$sx), (ins immOp:$sy, mOp:$sz), 564 !strconcat(opcStr, " $sx, $sy, $sz"), 565 [(set Tyo:$sx, (OpNode (Tyi immOp:$sy), (Tyi mOp:$sz)))]>; 566} 567 568// Generic RR multiclass with 2 arguments. 569// e.g. ADDUL, ADDSWSX, ADDSWZX, and etc. 570multiclass RRm<string opcStr, bits<8>opc, 571 RegisterClass RC, ValueType Ty, 572 SDPatternOperator OpNode = null_frag, 573 Operand immOp = simm7, Operand mOp = mimm, bit MoveImm = 0> : 574 RRbm<opcStr, opc, RC, Ty, RC, Ty, OpNode, immOp, mOp, MoveImm>; 575 576// Generic RR multiclass for non-commutative instructions with 2 arguments. 577// e.g. SUBUL, SUBUW, SUBSWSX, and etc. 578multiclass RRNCm<string opcStr, bits<8>opc, 579 RegisterClass RC, ValueType Ty, 580 SDPatternOperator OpNode = null_frag, 581 Operand immOp = simm7, Operand mOp = mimm> : 582 RRNCbm<opcStr, opc, RC, Ty, RC, Ty, OpNode, immOp, mOp>; 583 584// Generic RR multiclass for floating point instructions with 2 arguments. 585// e.g. FADDD, FADDS, FSUBD, and etc. 586multiclass RRFm<string opcStr, bits<8>opc, 587 RegisterClass RC, ValueType Ty, 588 SDPatternOperator OpNode = null_frag, 589 Operand immOp = simm7fp, Operand mOp = mimmfp> : 590 RRNCbm<opcStr, opc, RC, Ty, RC, Ty, OpNode, immOp, mOp>; 591 592// Generic RR multiclass for shift instructions with 2 arguments. 593// e.g. SLL, SRL, SLAWSX, and etc. 594let hasSideEffects = 0 in 595multiclass RRIm<string opcStr, bits<8>opc, 596 RegisterClass RC, ValueType Ty, 597 SDPatternOperator OpNode = null_frag> { 598 def rr : RR<opc, (outs RC:$sx), (ins RC:$sz, I32:$sy), 599 !strconcat(opcStr, " $sx, $sz, $sy"), 600 [(set Ty:$sx, (OpNode Ty:$sz, i32:$sy))]>; 601 let cz = 0 in 602 def mr : RR<opc, (outs RC:$sx), (ins mimm:$sz, I32:$sy), 603 !strconcat(opcStr, " $sx, $sz, $sy"), 604 [(set Ty:$sx, (OpNode (Ty mimm:$sz), i32:$sy))]>; 605 let cy = 0 in 606 def ri : RR<opc, (outs RC:$sx), (ins RC:$sz, uimm7:$sy), 607 !strconcat(opcStr, " $sx, $sz, $sy"), 608 [(set Ty:$sx, (OpNode Ty:$sz, (i32 uimm7:$sy)))]>; 609 let cy = 0, cz = 0 in 610 def mi : RR<opc, (outs RC:$sx), (ins mimm:$sz, uimm7:$sy), 611 !strconcat(opcStr, " $sx, $sz, $sy"), 612 [(set Ty:$sx, (OpNode (Ty mimm:$sz), (i32 uimm7:$sy)))]>; 613} 614 615// Special RR multiclass for 128 bits shift left instruction. 616// e.g. SLD 617let Constraints = "$hi = $sx", DisableEncoding = "$hi", hasSideEffects = 0 in 618multiclass RRILDm<string opcStr, bits<8>opc, 619 RegisterClass RC, ValueType Ty, 620 SDPatternOperator OpNode = null_frag> { 621 def rrr : RR<opc, (outs RC:$sx), (ins RC:$hi, RC:$sz, I32:$sy), 622 !strconcat(opcStr, " $sx, $sz, $sy")>; 623 let cz = 0 in 624 def rmr : RR<opc, (outs RC:$sx), (ins RC:$hi, mimm:$sz, I32:$sy), 625 !strconcat(opcStr, " $sx, $sz, $sy")>; 626 let cy = 0 in 627 def rri : RR<opc, (outs RC:$sx), (ins RC:$hi, RC:$sz, uimm7:$sy), 628 !strconcat(opcStr, " $sx, $sz, $sy")>; 629 let cy = 0, cz = 0 in 630 def rmi : RR<opc, (outs RC:$sx), (ins RC:$hi, mimm:$sz, uimm7:$sy), 631 !strconcat(opcStr, " $sx, $sz, $sy")>; 632} 633 634// Special RR multiclass for 128 bits shift right instruction. 635// e.g. SRD 636let Constraints = "$low = $sx", DisableEncoding = "$low", hasSideEffects = 0 in 637multiclass RRIRDm<string opcStr, bits<8>opc, 638 RegisterClass RC, ValueType Ty, 639 SDPatternOperator OpNode = null_frag> { 640 def rrr : RR<opc, (outs RC:$sx), (ins RC:$sz, RC:$low, I32:$sy), 641 !strconcat(opcStr, " $sx, $sz, $sy")>; 642 let cz = 0 in 643 def mrr : RR<opc, (outs RC:$sx), (ins mimm:$sz, RC:$low, I32:$sy), 644 !strconcat(opcStr, " $sx, $sz, $sy")>; 645 let cy = 0 in 646 def rri : RR<opc, (outs RC:$sx), (ins RC:$sz, RC:$low, uimm7:$sy), 647 !strconcat(opcStr, " $sx, $sz, $sy")>; 648 let cy = 0, cz = 0 in 649 def mri : RR<opc, (outs RC:$sx), (ins mimm:$sz, RC:$low, uimm7:$sy), 650 !strconcat(opcStr, " $sx, $sz, $sy")>; 651} 652 653// Generic RR multiclass with an argument. 654// e.g. LDZ, PCNT, and BRV 655let cy = 0, sy = 0, hasSideEffects = 0 in 656multiclass RRI1m<string opcStr, bits<8>opc, RegisterClass RC, ValueType Ty, 657 SDPatternOperator OpNode = null_frag> { 658 def r : RR<opc, (outs RC:$sx), (ins RC:$sz), !strconcat(opcStr, " $sx, $sz"), 659 [(set Ty:$sx, (OpNode Ty:$sz))]>; 660 let cz = 0 in 661 def m : RR<opc, (outs RC:$sx), (ins mimm:$sz), 662 !strconcat(opcStr, " $sx, $sz"), 663 [(set Ty:$sx, (OpNode (Ty mimm:$sz)))]>; 664} 665 666// Special RR multiclass for MRG instruction. 667// e.g. MRG 668let Constraints = "$sx = $sd", DisableEncoding = "$sd", hasSideEffects = 0 in 669multiclass RRMRGm<string opcStr, bits<8>opc, RegisterClass RC, ValueType Ty> { 670 def rr : RR<opc, (outs RC:$sx), (ins RC:$sy, RC:$sz, RC:$sd), 671 !strconcat(opcStr, " $sx, $sy, $sz")>; 672 let cy = 0 in 673 def ir : RR<opc, (outs RC:$sx), (ins simm7:$sy, RC:$sz, RC:$sd), 674 !strconcat(opcStr, " $sx, $sy, $sz")>; 675 let cz = 0 in 676 def rm : RR<opc, (outs RC:$sx), (ins RC:$sy, mimm:$sz, RC:$sd), 677 !strconcat(opcStr, " $sx, $sy, $sz")>; 678 let cy = 0, cz = 0 in 679 def im : RR<opc, (outs RC:$sx), (ins simm7:$sy, mimm:$sz, RC:$sd), 680 !strconcat(opcStr, " $sx, $sy, $sz")>; 681} 682 683// Special RR multiclass for BSWP instruction. 684// e.g. BSWP 685let hasSideEffects = 0 in 686multiclass RRSWPm<string opcStr, bits<8>opc, 687 RegisterClass RC, ValueType Ty, 688 SDPatternOperator OpNode = null_frag> { 689 let cy = 0 in 690 def ri : RR<opc, (outs RC:$sx), (ins RC:$sz, uimm1:$sy), 691 !strconcat(opcStr, " $sx, $sz, $sy"), 692 [(set Ty:$sx, (OpNode Ty:$sz, (i32 uimm1:$sy)))]>; 693 let cy = 0, cz = 0 in 694 def mi : RR<opc, (outs RC:$sx), (ins mimm:$sz, uimm1:$sy), 695 !strconcat(opcStr, " $sx, $sz, $sy"), 696 [(set Ty:$sx, (OpNode (Ty mimm:$sz), (i32 uimm1:$sy)))]>; 697} 698 699// Multiclass for CMOV instructions. 700// e.g. CMOVL, CMOVW, CMOVD, and etc. 701let Constraints = "$sx = $sd", DisableEncoding = "$sd", hasSideEffects = 0, 702 cfw = ? in 703multiclass RRCMOVm<string opcStr, bits<8>opc, RegisterClass RC, ValueType Ty> { 704 def rr : RR<opc, (outs I64:$sx), (ins CCOp:$cfw, RC:$sy, I64:$sz, I64:$sd), 705 !strconcat(opcStr, " $sx, $sz, $sy")>; 706 let cy = 0 in 707 def ir : RR<opc, (outs I64:$sx), 708 (ins CCOp:$cfw, simm7:$sy, I64:$sz, I64:$sd), 709 !strconcat(opcStr, " $sx, $sz, $sy")>; 710 let cz = 0 in 711 def rm : RR<opc, (outs I64:$sx), 712 (ins CCOp:$cfw, RC:$sy, mimm:$sz, I64:$sd), 713 !strconcat(opcStr, " $sx, $sz, $sy")>; 714 let cy = 0, cz = 0 in 715 def im : RR<opc, (outs I64:$sx), 716 (ins CCOp:$cfw, simm7:$sy, mimm:$sz, I64:$sd), 717 !strconcat(opcStr, " $sx, $sz, $sy")>; 718} 719 720// Multiclass for floating point conversion instructions. 721// e.g. CVTWDSX, CVTWDZX, CVTWSSX, and etc. 722// sz{3-0} = rounding mode 723let cz = 0, hasSideEffects = 0 in 724multiclass CVTRDm<string opcStr, bits<8> opc, RegisterClass RCo, ValueType Tyo, 725 RegisterClass RCi, ValueType Tyi> { 726 def r : RR<opc, (outs RCo:$sx), (ins RDOp:$rd, RCi:$sy), 727 !strconcat(opcStr, "${rd} $sx, $sy")> { 728 bits<4> rd; 729 let sz{5-4} = 0; 730 let sz{3-0} = rd; 731 } 732 let cy = 0 in 733 def i : RR<opc, (outs RCo:$sx), (ins RDOp:$rd, simm7:$sy), 734 !strconcat(opcStr, "${rd} $sx, $sy")> { 735 bits<4> rd; 736 let sz{5-4} = 0; 737 let sz{3-0} = rd; 738 } 739} 740 741// Multiclass for floating point conversion instructions. 742// e.g. CVTDW, CVTSW, CVTDL, and etc. 743let cz = 0, sz = 0, hasSideEffects = 0 in 744multiclass CVTm<string opcStr, bits<8> opc, RegisterClass RCo, ValueType Tyo, 745 RegisterClass RCi, ValueType Tyi, 746 SDPatternOperator OpNode = null_frag> { 747 def r : RR<opc, (outs RCo:$sx), (ins RCi:$sy), 748 !strconcat(opcStr, " $sx, $sy"), 749 [(set Tyo:$sx, (OpNode Tyi:$sy))]>; 750 let cy = 0 in 751 def i : RR<opc, (outs RCo:$sx), (ins simm7:$sy), 752 !strconcat(opcStr, " $sx, $sy")>; 753} 754 755// Multiclass for PFCH instructions. 756// e.g. PFCH 757let sx = 0, hasSideEffects = 0 in 758multiclass PFCHm<string opcStr, bits<8>opc> { 759 def rri : RM<opc, (outs), (ins MEMrri:$addr), !strconcat(opcStr, " $addr"), 760 [(prefetch ADDRrri:$addr, imm, imm, (i32 1))]>; 761 let cy = 0 in 762 def rii : RM<opc, (outs), (ins MEMrii:$addr), !strconcat(opcStr, " $addr"), 763 [(prefetch ADDRrii:$addr, imm, imm, (i32 1))]>; 764 let cz = 0 in 765 def zri : RM<opc, (outs), (ins MEMzri:$addr), !strconcat(opcStr, " $addr"), 766 [(prefetch ADDRzri:$addr, imm, imm, (i32 1))]>; 767 let cy = 0, cz = 0 in 768 def zii : RM<opc, (outs), (ins MEMzii:$addr), !strconcat(opcStr, " $addr"), 769 [(prefetch ADDRzii:$addr, imm, imm, (i32 1))]>; 770} 771 772// Multiclass for CAS instructions. 773// e.g. TS1AML, TS1AMW, TS2AM, and etc. 774let Constraints = "$dest = $sd", DisableEncoding = "$sd", 775 mayStore=1, mayLoad = 1, hasSideEffects = 0 in 776multiclass RRCAStgm<string opcStr, bits<8>opc, RegisterClass RC, ValueType Ty, 777 Operand immOp, Operand MEM, Operand ADDR, 778 SDPatternOperator OpNode = null_frag> { 779 def r : RRM<opc, (outs RC:$dest), (ins MEM:$addr, RC:$sy, RC:$sd), 780 !strconcat(opcStr, " $dest, $addr, $sy"), 781 [(set Ty:$dest, (OpNode ADDR:$addr, Ty:$sy, Ty:$sd))]>; 782 let cy = 0 in 783 def i : RRM<opc, (outs RC:$dest), (ins MEM:$addr, immOp:$sy, RC:$sd), 784 !strconcat(opcStr, " $dest, $addr, $sy"), 785 [(set Ty:$dest, (OpNode ADDR:$addr, (Ty immOp:$sy), Ty:$sd))]>; 786} 787multiclass RRCASm<string opcStr, bits<8>opc, RegisterClass RC, ValueType Ty, 788 Operand immOp, SDPatternOperator OpNode = null_frag> { 789 defm ri : RRCAStgm<opcStr, opc, RC, Ty, immOp, MEMriRRM, ADDRri, OpNode>; 790 let cz = 0 in 791 defm zi : RRCAStgm<opcStr, opc, RC, Ty, immOp, MEMziRRM, ADDRzi, OpNode>; 792} 793 794// Multiclass for branch instructions 795// e.g. BCFL, BCFW, BCFD, and etc. 796let isBranch = 1, isTerminator = 1, isIndirectBranch = 1, hasSideEffects = 0 in 797multiclass BCbpfm<string opcStr, string cmpStr, bits<8> opc, dag cond, 798 Operand ADDR> { 799 let bpf = 0 /* NONE */ in 800 def "" : CF<opc, (outs), !con(cond, (ins ADDR:$addr)), 801 !strconcat(opcStr, " ", cmpStr, "$addr")>; 802 let bpf = 2 /* NOT TAKEN */ in 803 def _nt : CF<opc, (outs), !con(cond, (ins ADDR:$addr)), 804 !strconcat(opcStr, ".nt ", cmpStr, "$addr")>; 805 let bpf = 3 /* TAKEN */ in 806 def _t : CF<opc, (outs), !con(cond, (ins ADDR:$addr)), 807 !strconcat(opcStr, ".t ", cmpStr, "$addr")>; 808} 809multiclass BCtgm<string opcStr, string cmpStr, bits<8> opc, dag cond> { 810 defm ri : BCbpfm<opcStr, cmpStr, opc, cond, MEMriASX>; 811 let cz = 0 in defm zi : BCbpfm<opcStr, cmpStr, opc, cond, MEMziASX>; 812} 813multiclass BCm<string opcStr, string opcStrAt, string opcStrAf, bits<8> opc, 814 RegisterClass RC, Operand immOp> { 815 let DecoderMethod = "DecodeBranchCondition" in 816 defm r : BCtgm<opcStr, "$comp, ", opc, (ins CCOp:$cond, RC:$comp)>; 817 let DecoderMethod = "DecodeBranchCondition", cy = 0 in 818 defm i : BCtgm<opcStr, "$comp, ", opc, (ins CCOp:$cond, immOp:$comp)>; 819 let DecoderMethod = "DecodeBranchConditionAlways", cy = 0, sy = 0, 820 cf = 15 /* AT */, isBarrier = 1 in 821 defm a : BCtgm<opcStrAt, "", opc, (ins)>; 822 let DecoderMethod = "DecodeBranchConditionAlways", cy = 0, sy = 0, 823 cf = 0 /* AF */ in 824 defm na : BCtgm<opcStrAf, "", opc, (ins)>; 825} 826 827// Multiclass for relative branch instructions 828// e.g. BRCFL, BRCFW, BRCFD, and etc. 829let isBranch = 1, isTerminator = 1, hasSideEffects = 0 in 830multiclass BCRbpfm<string opcStr, string cmpStr, bits<8> opc, dag cond> { 831 let bpf = 0 /* NONE */ in 832 def "" : CF<opc, (outs), !con(cond, (ins brtarget32:$imm32)), 833 !strconcat(opcStr, " ", cmpStr, "$imm32")>; 834 let bpf = 2 /* NOT TAKEN */ in 835 def _nt : CF<opc, (outs), !con(cond, (ins brtarget32:$imm32)), 836 !strconcat(opcStr, ".nt ", cmpStr, "$imm32")>; 837 let bpf = 3 /* TAKEN */ in 838 def _t : CF<opc, (outs), !con(cond, (ins brtarget32:$imm32)), 839 !strconcat(opcStr, ".t ", cmpStr, "$imm32")>; 840} 841multiclass BCRm<string opcStr, string opcStrAt, string opcStrAf, bits<8> opc, 842 RegisterClass RC, Operand immOp, Operand zeroOp> { 843 defm rr : BCRbpfm<opcStr, "$sy, $sz, ", opc, (ins CCOp:$cf, RC:$sy, RC:$sz)>; 844 let cy = 0 in 845 defm ir : BCRbpfm<opcStr, "$sy, $sz, ", opc, (ins CCOp:$cf, immOp:$sy, 846 RC:$sz)>; 847 let cz = 0 in 848 defm rz : BCRbpfm<opcStr, "$sy, $sz, ", opc, (ins CCOp:$cf, RC:$sy, 849 zeroOp:$sz)>; 850 let cy = 0, cz = 0 in 851 defm iz : BCRbpfm<opcStr, "$sy, $sz, ", opc, (ins CCOp:$cf, immOp:$sy, 852 zeroOp:$sz)>; 853 let cy = 0, sy = 0, cz = 0, sz = 0, cf = 15 /* AT */, isBarrier = 1 in 854 defm a : BCRbpfm<opcStrAt, "", opc, (ins)>; 855 let cy = 0, sy = 0, cz = 0, sz = 0, cf = 0 /* AF */ in 856 defm na : BCRbpfm<opcStrAf, "", opc, (ins)>; 857} 858 859// Multiclass for communication register instructions. 860// e.g. LCR 861let hasSideEffects = 1 in 862multiclass LOADCRm<string opcStr, bits<8>opc, RegisterClass RC> { 863 def rr : RR<opc, (outs RC:$sx), (ins RC:$sz, RC:$sy), 864 !strconcat(opcStr, " $sx, $sy, $sz")>; 865 let cy = 0 in def ri : RR<opc, (outs RC:$sx), (ins RC:$sz, simm7:$sy), 866 !strconcat(opcStr, " $sx, $sy, $sz")>; 867 let cz = 0 in def zr : RR<opc, (outs RC:$sx), (ins zero:$sz, RC:$sy), 868 !strconcat(opcStr, " $sx, $sy, $sz")>; 869 let cy = 0, cz = 0 in 870 def zi : RR<opc, (outs RC:$sx), (ins zero:$sz, simm7:$sy), 871 !strconcat(opcStr, " $sx, $sy, $sz")>; 872} 873 874// Multiclass for communication register instructions. 875// e.g. SCR 876let hasSideEffects = 1 in 877multiclass STORECRm<string opcStr, bits<8>opc, RegisterClass RC> { 878 def rr : RR<opc, (outs), (ins RC:$sz, RC:$sy, RC:$sx), 879 !strconcat(opcStr, " $sx, $sy, $sz")>; 880 let cy = 0 in def ri : RR<opc, (outs), (ins RC:$sz, simm7:$sy, RC:$sx), 881 !strconcat(opcStr, " $sx, $sy, $sz")>; 882 let cz = 0 in def zr : RR<opc, (outs), (ins zero:$sz, RC:$sy, RC:$sx), 883 !strconcat(opcStr, " $sx, $sy, $sz")>; 884 let cy = 0, cz = 0 in 885 def zi : RR<opc, (outs), (ins zero:$sz, simm7:$sy, RC:$sx), 886 !strconcat(opcStr, " $sx, $sy, $sz")>; 887} 888 889// Multiclass for communication register instructions. 890// e.g. FIDCR 891let cz = 0, hasSideEffects = 1 in 892multiclass FIDCRm<string opcStr, bits<8>opc, RegisterClass RC> { 893 def ri : RR<opc, (outs RC:$sx), (ins RC:$sy, uimm3:$sz), 894 !strconcat(opcStr, " $sx, $sy, $sz")>; 895 let cy = 0 in def ii : RR<opc, (outs RC:$sx), (ins simm7:$sy, uimm3:$sz), 896 !strconcat(opcStr, " $sx, $sy, $sz")>; 897} 898 899// Multiclass for LHM instruction. 900let mayLoad = 1, hasSideEffects = 0 in 901multiclass LHMm<string opcStr, bits<8> opc, RegisterClass RC> { 902 def ri : RRMHM<opc, (outs RC:$dest), (ins MEMriHM:$addr), 903 !strconcat(opcStr, " $dest, $addr")>; 904 let cz = 0 in 905 def zi : RRMHM<opc, (outs RC:$dest), (ins MEMziHM:$addr), 906 !strconcat(opcStr, " $dest, $addr")>; 907} 908 909// Multiclass for SHM instruction. 910let mayStore = 1, hasSideEffects = 0 in 911multiclass SHMm<string opcStr, bits<8> opc, RegisterClass RC> { 912 def ri : RRMHM<opc, (outs), (ins MEMriHM:$addr, RC:$sx), 913 !strconcat(opcStr, " $sx, $addr")>; 914 let cz = 0 in 915 def zi : RRMHM<opc, (outs), (ins MEMziHM:$addr, RC:$sx), 916 !strconcat(opcStr, " $sx, $addr")>; 917} 918 919//===----------------------------------------------------------------------===// 920// Instructions 921// 922// Define all scalar instructions defined in SX-Aurora TSUBASA Architecture 923// Guide here. As those mnemonics, we use mnemonics defined in Vector Engine 924// Assembly Language Reference Manual. 925//===----------------------------------------------------------------------===// 926 927//----------------------------------------------------------------------------- 928// Section 8.2 - Load/Store instructions 929//----------------------------------------------------------------------------- 930 931// Multiclass for generic RM instructions 932multiclass RMm<string opcStr, bits<8>opc, RegisterClass RC, bit MoveImm = 0> { 933 def rri : RM<opc, (outs RC:$dest), (ins MEMrri:$addr), 934 !strconcat(opcStr, " $dest, $addr"), []>; 935 let cy = 0 in 936 def rii : RM<opc, (outs RC:$dest), (ins MEMrii:$addr), 937 !strconcat(opcStr, " $dest, $addr"), []>; 938 let cz = 0 in 939 def zri : RM<opc, (outs RC:$dest), (ins MEMzri:$addr), 940 !strconcat(opcStr, " $dest, $addr"), []>; 941 let cy = 0, cz = 0 in 942 def zii : RM<opc, (outs RC:$dest), (ins MEMzii:$addr), 943 !strconcat(opcStr, " $dest, $addr"), []> { 944 // VE uses LEAzii and LEASLzii as a move immediate instruction, so declare 945 // it here. An instruction declared as MoveImm will be optimized in 946 // FoldImmediate later. 947 let isMoveImm = MoveImm; 948 } 949} 950 951// Section 8.2.1 - LEA 952let isReMaterializable = 1, isAsCheapAsAMove = 1, 953 DecoderMethod = "DecodeLoadI64" in { 954 let cx = 0 in defm LEA : RMm<"lea", 0x06, I64, /* MoveImm */ 1>; 955 let cx = 1 in defm LEASL : RMm<"lea.sl", 0x06, I64, /* MoveImm */ 1>; 956} 957 958// LEA basic patterns. 959// Need to be defined here to prioritize LEA over ADX. 960def : Pat<(iPTR ADDRrri:$addr), (LEArri MEMrri:$addr)>; 961def : Pat<(iPTR ADDRrii:$addr), (LEArii MEMrii:$addr)>; 962def : Pat<(add I64:$base, simm32:$disp), (LEArii $base, 0, (LO32 $disp))>; 963def : Pat<(add I64:$base, lozero:$disp), (LEASLrii $base, 0, (HI32 $disp))>; 964 965// Multiclass for load instructions. 966let mayLoad = 1, hasSideEffects = 0 in 967multiclass LOADm<string opcStr, bits<8> opc, RegisterClass RC, ValueType Ty, 968 SDPatternOperator OpNode = null_frag> { 969 def rri : RM<opc, (outs RC:$dest), (ins MEMrri:$addr), 970 !strconcat(opcStr, " $dest, $addr"), 971 [(set Ty:$dest, (OpNode ADDRrri:$addr))]>; 972 let cy = 0 in 973 def rii : RM<opc, (outs RC:$dest), (ins MEMrii:$addr), 974 !strconcat(opcStr, " $dest, $addr"), 975 [(set Ty:$dest, (OpNode ADDRrii:$addr))]>; 976 let cz = 0 in 977 def zri : RM<opc, (outs RC:$dest), (ins MEMzri:$addr), 978 !strconcat(opcStr, " $dest, $addr"), 979 [(set Ty:$dest, (OpNode ADDRzri:$addr))]>; 980 let cy = 0, cz = 0 in 981 def zii : RM<opc, (outs RC:$dest), (ins MEMzii:$addr), 982 !strconcat(opcStr, " $dest, $addr"), 983 [(set Ty:$dest, (OpNode ADDRzii:$addr))]>; 984} 985 986// Section 8.2.2 - LDS 987let DecoderMethod = "DecodeLoadI64" in 988defm LD : LOADm<"ld", 0x01, I64, i64, load>; 989def : Pat<(f64 (load ADDRrri:$addr)), (LDrri MEMrri:$addr)>; 990def : Pat<(f64 (load ADDRrii:$addr)), (LDrii MEMrii:$addr)>; 991def : Pat<(f64 (load ADDRzri:$addr)), (LDzri MEMzri:$addr)>; 992def : Pat<(f64 (load ADDRzii:$addr)), (LDzii MEMzii:$addr)>; 993 994// Section 8.2.3 - LDU 995let DecoderMethod = "DecodeLoadF32" in 996defm LDU : LOADm<"ldu", 0x02, F32, f32, load>; 997 998// Section 8.2.4 - LDL 999let DecoderMethod = "DecodeLoadI32" in 1000defm LDLSX : LOADm<"ldl.sx", 0x03, I32, i32, load>; 1001let cx = 1, DecoderMethod = "DecodeLoadI32" in 1002defm LDLZX : LOADm<"ldl.zx", 0x03, I32, i32, load>; 1003 1004// Section 8.2.5 - LD2B 1005let DecoderMethod = "DecodeLoadI32" in 1006defm LD2BSX : LOADm<"ld2b.sx", 0x04, I32, i32, sextloadi16>; 1007let cx = 1, DecoderMethod = "DecodeLoadI32" in 1008defm LD2BZX : LOADm<"ld2b.zx", 0x04, I32, i32, zextloadi16>; 1009 1010// Section 8.2.6 - LD1B 1011let DecoderMethod = "DecodeLoadI32" in 1012defm LD1BSX : LOADm<"ld1b.sx", 0x05, I32, i32, sextloadi8>; 1013let cx = 1, DecoderMethod = "DecodeLoadI32" in 1014defm LD1BZX : LOADm<"ld1b.zx", 0x05, I32, i32, zextloadi8>; 1015 1016// LDQ pseudo instructions 1017let mayLoad = 1, hasSideEffects = 0 in { 1018 def LDQrii : Pseudo<(outs F128:$dest), (ins MEMrii:$addr), 1019 "# pseudo ldq $dest, $addr", 1020 [(set f128:$dest, (load ADDRrii:$addr))]>; 1021} 1022 1023// Multiclass for store instructions. 1024let mayStore = 1 in 1025multiclass STOREm<string opcStr, bits<8> opc, RegisterClass RC, ValueType Ty, 1026 SDPatternOperator OpNode = null_frag> { 1027 def rri : RM<opc, (outs), (ins MEMrri:$addr, RC:$sx), 1028 !strconcat(opcStr, " $sx, $addr"), 1029 [(OpNode Ty:$sx, ADDRrri:$addr)]>; 1030 let cy = 0 in 1031 def rii : RM<opc, (outs), (ins MEMrii:$addr, RC:$sx), 1032 !strconcat(opcStr, " $sx, $addr"), 1033 [(OpNode Ty:$sx, ADDRrii:$addr)]>; 1034 let cz = 0 in 1035 def zri : RM<opc, (outs), (ins MEMzri:$addr, RC:$sx), 1036 !strconcat(opcStr, " $sx, $addr"), 1037 [(OpNode Ty:$sx, ADDRzri:$addr)]>; 1038 let cy = 0, cz = 0 in 1039 def zii : RM<opc, (outs), (ins MEMzii:$addr, RC:$sx), 1040 !strconcat(opcStr, " $sx, $addr"), 1041 [(OpNode Ty:$sx, ADDRzii:$addr)]>; 1042} 1043 1044// Section 8.2.7 - STS 1045let DecoderMethod = "DecodeStoreI64" in 1046defm ST : STOREm<"st", 0x11, I64, i64, store>; 1047def : Pat<(store f64:$src, ADDRrri:$addr), (STrri MEMrri:$addr, $src)>; 1048def : Pat<(store f64:$src, ADDRrii:$addr), (STrii MEMrii:$addr, $src)>; 1049def : Pat<(store f64:$src, ADDRzri:$addr), (STzri MEMzri:$addr, $src)>; 1050def : Pat<(store f64:$src, ADDRzii:$addr), (STzii MEMzii:$addr, $src)>; 1051 1052// Section 8.2.8 - STU 1053let DecoderMethod = "DecodeStoreF32" in 1054defm STU : STOREm<"stu", 0x12, F32, f32, store>; 1055 1056// Section 8.2.9 - STL 1057let DecoderMethod = "DecodeStoreI32" in 1058defm STL : STOREm<"stl", 0x13, I32, i32, store>; 1059 1060// Section 8.2.10 - ST2B 1061let DecoderMethod = "DecodeStoreI32" in 1062defm ST2B : STOREm<"st2b", 0x14, I32, i32, truncstorei16>; 1063 1064// Section 8.2.11 - ST1B 1065let DecoderMethod = "DecodeStoreI32" in 1066defm ST1B : STOREm<"st1b", 0x15, I32, i32, truncstorei8>; 1067 1068// STQ pseudo instructions 1069let mayStore = 1, hasSideEffects = 0 in { 1070 def STQrii : Pseudo<(outs), (ins MEMrii:$addr, F128:$sx), 1071 "# pseudo stq $sx, $addr", 1072 [(store f128:$sx, ADDRrii:$addr)]>; 1073} 1074 1075// Section 8.2.12 - DLDS 1076let DecoderMethod = "DecodeLoadI64" in 1077defm DLD : LOADm<"dld", 0x09, I64, i64, load>; 1078 1079// Section 8.2.13 - DLDU 1080let DecoderMethod = "DecodeLoadF32" in 1081defm DLDU : LOADm<"dldu", 0x0a, F32, f32, load>; 1082 1083// Section 8.2.14 - DLDL 1084let DecoderMethod = "DecodeLoadI32" in 1085defm DLDLSX : LOADm<"dldl.sx", 0x0b, I32, i32, load>; 1086let cx = 1, DecoderMethod = "DecodeLoadI32" in 1087defm DLDLZX : LOADm<"dldl.zx", 0x0b, I32, i32, load>; 1088 1089// Section 8.2.15 - PFCH 1090let DecoderMethod = "DecodeASX" in 1091defm PFCH : PFCHm<"pfch", 0x0c>; 1092 1093// Section 8.2.16 - TS1AM (Test and Set 1 AM) 1094let DecoderMethod = "DecodeTS1AMI64" in 1095defm TS1AML : RRCASm<"ts1am.l", 0x42, I64, i64, uimm7>; 1096let DecoderMethod = "DecodeTS1AMI32", cx = 1 in 1097defm TS1AMW : RRCASm<"ts1am.w", 0x42, I32, i32, uimm7>; 1098 1099// Section 8.2.17 - TS2AM (Test and Set 2 AM) 1100let DecoderMethod = "DecodeTS1AMI64" in 1101defm TS2AM : RRCASm<"ts2am", 0x43, I64, i64, uimm7>; 1102 1103// Section 8.2.18 - TS3AM (Test and Set 3 AM) 1104let DecoderMethod = "DecodeTS1AMI64" in 1105defm TS3AM : RRCASm<"ts3am", 0x52, I64, i64, uimm1>; 1106 1107// Section 8.2.19 - ATMAM (Atomic AM) 1108let DecoderMethod = "DecodeTS1AMI64" in 1109defm ATMAM : RRCASm<"atmam", 0x53, I64, i64, uimm0to2>; 1110 1111// Section 8.2.20 - CAS (Compare and Swap) 1112let DecoderMethod = "DecodeCASI64" in 1113defm CASL : RRCASm<"cas.l", 0x62, I64, i64, simm7>; 1114let DecoderMethod = "DecodeCASI32", cx = 1 in 1115defm CASW : RRCASm<"cas.w", 0x62, I32, i32, simm7>; 1116 1117//----------------------------------------------------------------------------- 1118// Section 8.3 - Transfer Control Instructions 1119//----------------------------------------------------------------------------- 1120 1121// Section 8.3.1 - FENCE (Fence) 1122let hasSideEffects = 1 in { 1123 let avo = 1 in def FENCEI : RRFENCE<0x20, (outs), (ins), "fencei">; 1124 def FENCEM : RRFENCE<0x20, (outs), (ins uimm2:$kind), "fencem $kind"> { 1125 bits<2> kind; 1126 let lf = kind{1}; 1127 let sf = kind{0}; 1128 } 1129 def FENCEC : RRFENCE<0x20, (outs), (ins uimm3:$kind), "fencec $kind"> { 1130 bits<3> kind; 1131 let c2 = kind{2}; 1132 let c1 = kind{1}; 1133 let c0 = kind{0}; 1134 } 1135} 1136 1137// Section 8.3.2 - SVOB (Set Vector Out-of-order memory access Boundary) 1138let sx = 0, cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 1 in 1139def SVOB : RR<0x30, (outs), (ins), "svob">; 1140 1141//----------------------------------------------------------------------------- 1142// Section 8.4 - Fixed-point Operation Instructions 1143//----------------------------------------------------------------------------- 1144 1145let isReMaterializable = 1, isAsCheapAsAMove = 1 in { 1146 1147// Section 8.4.1 - ADD (Add) 1148defm ADDUL : RRm<"addu.l", 0x48, I64, i64>; 1149let cx = 1 in defm ADDUW : RRm<"addu.w", 0x48, I32, i32>; 1150 1151// Section 8.4.2 - ADS (Add Single) 1152defm ADDSWSX : RRm<"adds.w.sx", 0x4A, I32, i32, add>; 1153let cx = 1 in defm ADDSWZX : RRm<"adds.w.zx", 0x4A, I32, i32>; 1154 1155// Section 8.4.3 - ADX (Add) 1156defm ADDSL : RRm<"adds.l", 0x59, I64, i64, add>; 1157 1158// Section 8.4.4 - SUB (Subtract) 1159defm SUBUL : RRNCm<"subu.l", 0x58, I64, i64>; 1160let cx = 1 in defm SUBUW : RRNCm<"subu.w", 0x58, I32, i32>; 1161 1162// Section 8.4.5 - SBS (Subtract Single) 1163defm SUBSWSX : RRNCm<"subs.w.sx", 0x5A, I32, i32, sub>; 1164let cx = 1 in defm SUBSWZX : RRNCm<"subs.w.zx", 0x5A, I32, i32>; 1165 1166// Section 8.4.6 - SBX (Subtract) 1167defm SUBSL : RRNCm<"subs.l", 0x5B, I64, i64, sub>; 1168 1169} // isReMaterializable, isAsCheapAsAMove 1170 1171// Section 8.4.7 - MPY (Multiply) 1172defm MULUL : RRm<"mulu.l", 0x49, I64, i64>; 1173let cx = 1 in defm MULUW : RRm<"mulu.w", 0x49, I32, i32>; 1174 1175// Section 8.4.8 - MPS (Multiply Single) 1176defm MULSWSX : RRm<"muls.w.sx", 0x4B, I32, i32, mul>; 1177let cx = 1 in defm MULSWZX : RRm<"muls.w.zx", 0x4B, I32, i32>; 1178 1179// Section 8.4.9 - MPX (Multiply) 1180defm MULSL : RRm<"muls.l", 0x6E, I64, i64, mul>; 1181 1182// Section 8.4.10 - MPD (Multiply) 1183defm MULSLW : RRbm<"muls.l.w", 0x6B, I64, i64, I32, i32>; 1184 1185// Section 8.4.11 - DIV (Divide) 1186defm DIVUL : RRNCm<"divu.l", 0x6F, I64, i64, udiv>; 1187let cx = 1 in defm DIVUW : RRNCm<"divu.w", 0x6F, I32, i32, udiv>; 1188 1189// Section 8.4.12 - DVS (Divide Single) 1190defm DIVSWSX : RRNCm<"divs.w.sx", 0x7B, I32, i32, sdiv>; 1191let cx = 1 in defm DIVSWZX : RRNCm<"divs.w.zx", 0x7B, I32, i32>; 1192 1193// Section 8.4.13 - DVX (Divide) 1194defm DIVSL : RRNCm<"divs.l", 0x7F, I64, i64, sdiv>; 1195 1196let isReMaterializable = 1, isAsCheapAsAMove = 1 in { 1197 1198// Section 8.4.14 - CMP (Compare) 1199defm CMPUL : RRNCm<"cmpu.l", 0x55, I64, i64>; 1200let cx = 1 in defm CMPUW : RRNCm<"cmpu.w", 0x55, I32, i32>; 1201 1202// Section 8.4.15 - CPS (Compare Single) 1203defm CMPSWSX : RRNCm<"cmps.w.sx", 0x7A, I32, i32>; 1204let cx = 1 in defm CMPSWZX : RRNCm<"cmps.w.zx", 0x7A, I32, i32>; 1205 1206// Section 8.4.16 - CPX (Compare) 1207defm CMPSL : RRNCm<"cmps.l", 0x6A, I64, i64>; 1208 1209// Section 8.4.17 - CMS (Compare and Select Maximum/Minimum Single) 1210// cx: sx/zx, cw: max/min 1211defm MAXSWSX : RRm<"maxs.w.sx", 0x78, I32, i32>; 1212let cx = 1 in defm MAXSWZX : RRm<"maxs.w.zx", 0x78, I32, i32>; 1213let cw = 1 in defm MINSWSX : RRm<"mins.w.sx", 0x78, I32, i32>; 1214let cx = 1, cw = 1 in defm MINSWZX : RRm<"mins.w.zx", 0x78, I32, i32>; 1215 1216// Section 8.4.18 - CMX (Compare and Select Maximum/Minimum) 1217defm MAXSL : RRm<"maxs.l", 0x68, I64, i64>; 1218let cw = 1 in defm MINSL : RRm<"mins.l", 0x68, I64, i64>; 1219 1220} // isReMaterializable, isAsCheapAsAMove 1221 1222//----------------------------------------------------------------------------- 1223// Section 8.5 - Logical Operation Instructions 1224//----------------------------------------------------------------------------- 1225 1226let isReMaterializable = 1, isAsCheapAsAMove = 1 in { 1227 1228// Section 8.5.1 - AND (AND) 1229defm AND : RRm<"and", 0x44, I64, i64, and>; 1230 1231// Section 8.5.2 - OR (OR) 1232defm OR : RRm<"or", 0x45, I64, i64, or, simm7, mimm, /* MoveImm */ 1>; 1233 1234// Section 8.5.3 - XOR (Exclusive OR) 1235defm XOR : RRm<"xor", 0x46, I64, i64, xor>; 1236 1237// Section 8.5.4 - EQV (Equivalence) 1238defm EQV : RRm<"eqv", 0x47, I64, i64>; 1239 1240} // isReMaterializable, isAsCheapAsAMove 1241 1242// Section 8.5.5 - NND (Negate AND) 1243def and_not : PatFrags<(ops node:$x, node:$y), 1244 [(and (not node:$x), node:$y)]>; 1245let isReMaterializable = 1, isAsCheapAsAMove = 1 in 1246defm NND : RRNCm<"nnd", 0x54, I64, i64, and_not>; 1247 1248// Section 8.5.6 - MRG (Merge) 1249defm MRG : RRMRGm<"mrg", 0x56, I64, i64>; 1250 1251// Section 8.5.7 - LDZ (Leading Zero Count) 1252def ctlz_pat : PatFrags<(ops node:$src), 1253 [(ctlz node:$src), 1254 (ctlz_zero_undef node:$src)]>; 1255let isReMaterializable = 1, isAsCheapAsAMove = 1 in 1256defm LDZ : RRI1m<"ldz", 0x67, I64, i64, ctlz_pat>; 1257 1258// Section 8.5.8 - PCNT (Population Count) 1259defm PCNT : RRI1m<"pcnt", 0x38, I64, i64, ctpop>; 1260 1261// Section 8.5.9 - BRV (Bit Reverse) 1262let isReMaterializable = 1, isAsCheapAsAMove = 1 in 1263defm BRV : RRI1m<"brv", 0x39, I64, i64, bitreverse>; 1264 1265// Section 8.5.10 - BSWP (Byte Swap) 1266let isReMaterializable = 1, isAsCheapAsAMove = 1 in 1267defm BSWP : RRSWPm<"bswp", 0x2B, I64, i64>; 1268 1269def : Pat<(i64 (bswap i64:$src)), 1270 (BSWPri $src, 0)>; 1271def : Pat<(i64 (bswap (i64 mimm:$src))), 1272 (BSWPmi (MIMM $src), 0)>; 1273def : Pat<(i32 (bswap i32:$src)), 1274 (EXTRACT_SUBREG 1275 (BSWPri (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $src, sub_i32), 1), 1276 sub_i32)>; 1277def : Pat<(i32 (bswap (i32 mimm:$src))), 1278 (EXTRACT_SUBREG (BSWPmi (MIMM $src), 1), sub_i32)>; 1279 1280// Section 8.5.11 - CMOV (Conditional Move) 1281let cw = 0, cw2 = 0 in defm CMOVL : RRCMOVm<"cmov.l.${cfw}", 0x3B, I64, i64>; 1282let cw = 1, cw2 = 0 in defm CMOVW : RRCMOVm<"cmov.w.${cfw}", 0x3B, I32, i32>; 1283let cw = 0, cw2 = 1 in defm CMOVD : RRCMOVm<"cmov.d.${cfw}", 0x3B, I64, f64>; 1284let cw = 1, cw2 = 1 in defm CMOVS : RRCMOVm<"cmov.s.${cfw}", 0x3B, F32, f32>; 1285def : MnemonicAlias<"cmov.l", "cmov.l.at">; 1286def : MnemonicAlias<"cmov.w", "cmov.w.at">; 1287def : MnemonicAlias<"cmov.d", "cmov.d.at">; 1288def : MnemonicAlias<"cmov.s", "cmov.s.at">; 1289 1290//----------------------------------------------------------------------------- 1291// Section 8.6 - Shift Operation Instructions 1292//----------------------------------------------------------------------------- 1293 1294// Section 8.6.1 - SLL (Shift Left Logical) 1295let isReMaterializable = 1, isAsCheapAsAMove = 1 in 1296defm SLL : RRIm<"sll", 0x65, I64, i64, shl>; 1297 1298// Section 8.6.2 - SLD (Shift Left Double) 1299defm SLD : RRILDm<"sld", 0x64, I64, i64>; 1300 1301// Section 8.6.3 - SRL (Shift Right Logical) 1302let isReMaterializable = 1, isAsCheapAsAMove = 1 in 1303defm SRL : RRIm<"srl", 0x75, I64, i64, srl>; 1304 1305// Section 8.6.4 - SRD (Shift Right Double) 1306defm SRD : RRIRDm<"srd", 0x74, I64, i64>; 1307 1308let isReMaterializable = 1, isAsCheapAsAMove = 1 in { 1309 1310// Section 8.6.5 - SLA (Shift Left Arithmetic) 1311defm SLAWSX : RRIm<"sla.w.sx", 0x66, I32, i32, shl>; 1312let cx = 1 in defm SLAWZX : RRIm<"sla.w.zx", 0x66, I32, i32>; 1313 1314// Section 8.6.6 - SLAX (Shift Left Arithmetic) 1315defm SLAL : RRIm<"sla.l", 0x57, I64, i64>; 1316 1317// Section 8.6.7 - SRA (Shift Right Arithmetic) 1318defm SRAWSX : RRIm<"sra.w.sx", 0x76, I32, i32, sra>; 1319let cx = 1 in defm SRAWZX : RRIm<"sra.w.zx", 0x76, I32, i32>; 1320 1321// Section 8.6.8 - SRAX (Shift Right Arithmetic) 1322defm SRAL : RRIm<"sra.l", 0x77, I64, i64, sra>; 1323 1324} // isReMaterializable, isAsCheapAsAMove 1325 1326def : Pat<(i32 (srl i32:$src, (i32 simm7:$val))), 1327 (EXTRACT_SUBREG (SRLri (ANDrm (INSERT_SUBREG (i64 (IMPLICIT_DEF)), 1328 $src, sub_i32), !add(32, 64)), imm:$val), sub_i32)>; 1329def : Pat<(i32 (srl i32:$src, i32:$val)), 1330 (EXTRACT_SUBREG (SRLrr (ANDrm (INSERT_SUBREG (i64 (IMPLICIT_DEF)), 1331 $src, sub_i32), !add(32, 64)), $val), sub_i32)>; 1332 1333//----------------------------------------------------------------------------- 1334// Section 8.7 - Floating-point Arithmetic Instructions 1335//----------------------------------------------------------------------------- 1336 1337// Section 8.7.1 - FAD (Floating Add) 1338defm FADDD : RRFm<"fadd.d", 0x4C, I64, f64, fadd>; 1339let cx = 1 in 1340defm FADDS : RRFm<"fadd.s", 0x4C, F32, f32, fadd, simm7fp, mimmfp32>; 1341 1342// Section 8.7.2 - FSB (Floating Subtract) 1343defm FSUBD : RRFm<"fsub.d", 0x5C, I64, f64, fsub>; 1344let cx = 1 in 1345defm FSUBS : RRFm<"fsub.s", 0x5C, F32, f32, fsub, simm7fp, mimmfp32>; 1346 1347// Section 8.7.3 - FMP (Floating Multiply) 1348defm FMULD : RRFm<"fmul.d", 0x4D, I64, f64, fmul>; 1349let cx = 1 in 1350defm FMULS : RRFm<"fmul.s", 0x4D, F32, f32, fmul, simm7fp, mimmfp32>; 1351 1352// Section 8.7.4 - FDV (Floating Divide) 1353defm FDIVD : RRFm<"fdiv.d", 0x5D, I64, f64, fdiv>; 1354let cx = 1 in 1355defm FDIVS : RRFm<"fdiv.s", 0x5D, F32, f32, fdiv, simm7fp, mimmfp32>; 1356 1357// Section 8.7.5 - FCP (Floating Compare) 1358defm FCMPD : RRFm<"fcmp.d", 0x7E, I64, f64>; 1359let cx = 1 in 1360defm FCMPS : RRFm<"fcmp.s", 0x7E, F32, f32, null_frag, simm7fp, mimmfp32>; 1361 1362// Section 8.7.6 - CMS (Compare and Select Maximum/Minimum Single) 1363// cx: double/float, cw: max/min 1364let cw = 0, cx = 0 in 1365defm FMAXD : RRFm<"fmax.d", 0x3E, I64, f64, fmaxnum>; 1366let cw = 0, cx = 1 in 1367defm FMAXS : RRFm<"fmax.s", 0x3E, F32, f32, fmaxnum, simm7fp, mimmfp32>; 1368let cw = 1, cx = 0 in 1369defm FMIND : RRFm<"fmin.d", 0x3E, I64, f64, fminnum>; 1370let cw = 1, cx = 1 in 1371defm FMINS : RRFm<"fmin.s", 0x3E, F32, f32, fminnum, simm7fp, mimmfp32>; 1372 1373// Section 8.7.7 - FAQ (Floating Add Quadruple) 1374defm FADDQ : RRFm<"fadd.q", 0x6C, F128, f128, fadd>; 1375 1376// Section 8.7.8 - FSQ (Floating Subtract Quadruple) 1377defm FSUBQ : RRFm<"fsub.q", 0x7C, F128, f128, fsub>; 1378 1379// Section 8.7.9 - FMQ (Floating Subtract Quadruple) 1380defm FMULQ : RRFm<"fmul.q", 0x6D, F128, f128, fmul>; 1381 1382// Section 8.7.10 - FCQ (Floating Compare Quadruple) 1383defm FCMPQ : RRNCbm<"fcmp.q", 0x7D, I64, f64, F128, f128, null_frag, simm7fp, 1384 mimmfp>; 1385 1386// Section 8.7.11 - FIX (Convert to Fixed Point) 1387// cx: double/float, cw: sx/zx, sz{0-3} = round 1388let cx = 0, cw = 0 /* sign extend */ in 1389defm CVTWDSX : CVTRDm<"cvt.w.d.sx", 0x4E, I32, i32, I64, f64>; 1390let cx = 0, cw = 1 /* zero extend */ in 1391defm CVTWDZX : CVTRDm<"cvt.w.d.zx", 0x4E, I32, i32, I64, f64>; 1392let cx = 1, cw = 0 /* sign extend */ in 1393defm CVTWSSX : CVTRDm<"cvt.w.s.sx", 0x4E, I32, i32, F32, f32>; 1394let cx = 1, cw = 1 /* zero extend */ in 1395defm CVTWSZX : CVTRDm<"cvt.w.s.zx", 0x4E, I32, i32, F32, f32>; 1396 1397// Section 8.7.12 - FIXX (Convert to Fixed Point) 1398defm CVTLD : CVTRDm<"cvt.l.d", 0x4F, I64, i64, I64, f64>; 1399 1400// Section 8.7.13 - FLT (Convert to Floating Point) 1401defm CVTDW : CVTm<"cvt.d.w", 0x5E, I64, f64, I32, i32, sint_to_fp>; 1402let cx = 1 in 1403defm CVTSW : CVTm<"cvt.s.w", 0x5E, F32, f32, I32, i32, sint_to_fp>; 1404 1405// Section 8.7.14 - FLTX (Convert to Floating Point) 1406defm CVTDL : CVTm<"cvt.d.l", 0x5F, I64, f64, I64, i64, sint_to_fp>; 1407 1408// Section 8.7.15 - CVS (Convert to Single-format) 1409defm CVTSD : CVTm<"cvt.s.d", 0x1F, F32, f32, I64, f64, fpround>; 1410let cx = 1 in 1411defm CVTSQ : CVTm<"cvt.s.q", 0x1F, F32, f32, F128, f128, fpround>; 1412 1413// Section 8.7.16 - CVD (Convert to Double-format) 1414defm CVTDS : CVTm<"cvt.d.s", 0x0F, I64, f64, F32, f32, fpextend>; 1415let cx = 1 in 1416defm CVTDQ : CVTm<"cvt.d.q", 0x0F, I64, f64, F128, f128, fpround>; 1417 1418// Section 8.7.17 - CVQ (Convert to Single-format) 1419defm CVTQD : CVTm<"cvt.q.d", 0x2D, F128, f128, I64, f64, fpextend>; 1420let cx = 1 in 1421defm CVTQS : CVTm<"cvt.q.s", 0x2D, F128, f128, F32, f32, fpextend>; 1422 1423//----------------------------------------------------------------------------- 1424// Section 8.8 - Branch instructions 1425//----------------------------------------------------------------------------- 1426 1427// Section 8.8.1 - BC (Branch on Codition) 1428defm BCFL : BCm<"b${cond}.l", "b.l", "baf.l", 0x19, I64, simm7>; 1429 1430// Indirect branch aliases 1431def : Pat<(brind I64:$reg), (BCFLari_t $reg, 0)>; 1432def : Pat<(brind tblockaddress:$imm), (BCFLazi_t 0, $imm)>; 1433 1434// Return instruction is a special case of jump. 1435let Uses = [SX10], bpf = 3 /* TAKEN */, cf = 15 /* AT */, cy = 0, sy = 0, 1436 sz = 10 /* SX10 */, imm32 = 0, isReturn = 1, isTerminator = 1, 1437 isBarrier = 1, isCodeGenOnly = 1, hasSideEffects = 0 in 1438def RET : CF<0x19, (outs), (ins), "b.l.t (, %s10)", [(retflag)]>; 1439 1440// Section 8.8.2 - BCS (Branch on Condition Single) 1441defm BCFW : BCm<"b${cond}.w", "b.w", "baf.w", 0x1B, I32, simm7>; 1442 1443// Section 8.8.3 - BCF (Branch on Condition Floating Point) 1444defm BCFD : BCm<"b${cond}.d", "b.d", "baf.d", 0x1C, I64, simm7fp>; 1445let cx = 1 in 1446defm BCFS : BCm<"b${cond}.s", "b.s", "baf.s", 0x1C, F32, simm7fp>; 1447 1448// Section 8.8.4 - BCR (Branch on Condition Relative) 1449let cx = 0, cx2 = 0 in 1450defm BRCFL : BCRm<"br${cf}.l", "br.l", "braf.l", 0x18, I64, simm7, zero>; 1451let cx = 1, cx2 = 0 in 1452defm BRCFW : BCRm<"br${cf}.w", "br.w", "braf.w", 0x18, I32, simm7, zero>; 1453let cx = 0, cx2 = 1 in 1454defm BRCFD : BCRm<"br${cf}.d", "br.d", "braf.d", 0x18, I64, simm7fp, zerofp>; 1455let cx = 1, cx2 = 1 in 1456defm BRCFS : BCRm<"br${cf}.s", "br.s", "braf.s", 0x18, F32, simm7fp, zerofp>; 1457 1458// Section 8.8.5 - BSIC (Branch and Save IC) 1459let isCall = 1, hasSideEffects = 0, DecoderMethod = "DecodeCall" in 1460defm BSIC : RMm<"bsic", 0x08, I64>; 1461 1462// Call instruction is a special case of BSIC. 1463let Defs = [SX10], sx = 10 /* SX10 */, cy = 0, sy = 0, imm32 = 0, 1464 isCall = 1, isCodeGenOnly = 1, hasSideEffects = 0 in 1465def CALLr : RM<0x08, (outs), (ins I64:$sz, variable_ops), 1466 "bsic %s10, (, $sz)", [(call i64:$sz)]>; 1467 1468//----------------------------------------------------------------------------- 1469// Section 8.19 - Control Instructions 1470//----------------------------------------------------------------------------- 1471 1472// Section 8.19.1 - SIC (Save Instruction Counter) 1473let cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 1, Uses = [IC] in 1474def SIC : RR<0x28, (outs I32:$sx), (ins), "sic $sx">; 1475 1476// Section 8.19.2 - LPM (Load Program Mode Flags) 1477let sx = 0, cz = 0, sz = 0, hasSideEffects = 1, Defs = [PSW] in 1478def LPM : RR<0x3a, (outs), (ins I64:$sy), "lpm $sy">; 1479 1480// Section 8.19.3 - SPM (Save Program Mode Flags) 1481let cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 1, Uses = [PSW] in 1482def SPM : RR<0x2a, (outs I64:$sx), (ins), "spm $sx">; 1483 1484// Section 8.19.4 - LFR (Load Flag Register) 1485let sx = 0, cz = 0, sz = 0, hasSideEffects = 1, Defs = [PSW] in { 1486 def LFRr : RR<0x69, (outs), (ins I64:$sy), "lfr $sy">; 1487 let cy = 0 in def LFRi : RR<0x69, (outs), (ins uimm6:$sy), "lfr $sy">; 1488} 1489 1490// Section 8.19.5 - SFR (Save Flag Register) 1491let cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 1, Uses = [PSW] in 1492def SFR : RR<0x29, (outs I64:$sx), (ins), "sfr $sx">; 1493 1494// Section 8.19.6 - SMIR (Save Miscellaneous Register) 1495let cy = 0, cz = 0, sz = 0, hasSideEffects = 1 in { 1496 def SMIR : RR<0x22, (outs I64:$sx), (ins MISC:$sy), "smir $sx, $sy">; 1497} 1498 1499// Section 8.19.7 - NOP (No Operation) 1500let sx = 0, cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 0 in 1501def NOP : RR<0x79, (outs), (ins), "nop">; 1502 1503// Section 8.19.8 - MONC (Monitor Call) 1504let sx = 0, cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 1 in { 1505 def MONC : RR<0x3F, (outs), (ins), "monc">; 1506 let cx = 1, isTrap = 1 in def MONCHDB : RR<0x3F, (outs), (ins), "monc.hdb">; 1507} 1508 1509// Section 8.19.9 - LCR (Load Communication Register) 1510defm LCR : LOADCRm<"lcr", 0x40, I64>; 1511 1512// Section 8.19.10 - SCR (Save Communication Register) 1513defm SCR : STORECRm<"scr", 0x50, I64>; 1514 1515// Section 8.19.11 - TSCR (Test & Set Communication Register) 1516defm TSCR : LOADCRm<"tscr", 0x41, I64>; 1517 1518// Section 8.19.12 - FIDCR (Fetch & Increment/Decrement CR) 1519defm FIDCR : FIDCRm<"fidcr", 0x51, I64>; 1520 1521//----------------------------------------------------------------------------- 1522// Section 8.20 - Host Memory Access Instructions 1523//----------------------------------------------------------------------------- 1524 1525// Section 8.20.1 - LHM (Load Host Memory) 1526let ry = 3, DecoderMethod = "DecodeLoadASI64" in 1527defm LHML : LHMm<"lhm.l", 0x21, I64>; 1528let ry = 2, DecoderMethod = "DecodeLoadASI64" in 1529defm LHMW : LHMm<"lhm.w", 0x21, I64>; 1530let ry = 1, DecoderMethod = "DecodeLoadASI64" in 1531defm LHMH : LHMm<"lhm.h", 0x21, I64>; 1532let ry = 0, DecoderMethod = "DecodeLoadASI64" in 1533defm LHMB : LHMm<"lhm.b", 0x21, I64>; 1534 1535// Section 8.20.2 - SHM (Store Host Memory) 1536let ry = 3, DecoderMethod = "DecodeStoreASI64" in 1537defm SHML : SHMm<"shm.l", 0x31, I64>; 1538let ry = 2, DecoderMethod = "DecodeStoreASI64" in 1539defm SHMW : SHMm<"shm.w", 0x31, I64>; 1540let ry = 1, DecoderMethod = "DecodeStoreASI64" in 1541defm SHMH : SHMm<"shm.h", 0x31, I64>; 1542let ry = 0, DecoderMethod = "DecodeStoreASI64" in 1543defm SHMB : SHMm<"shm.b", 0x31, I64>; 1544 1545//===----------------------------------------------------------------------===// 1546// Instructions for CodeGenOnly 1547//===----------------------------------------------------------------------===// 1548 1549//===----------------------------------------------------------------------===// 1550// Pattern Matchings 1551//===----------------------------------------------------------------------===// 1552 1553// Small immediates. 1554def : Pat<(i32 simm7:$val), (EXTRACT_SUBREG (ORim (LO7 $val), 0), sub_i32)>; 1555def : Pat<(i64 simm7:$val), (ORim (LO7 $val), 0)>; 1556// Medium immediates. 1557def : Pat<(i32 simm32:$val), 1558 (EXTRACT_SUBREG (LEAzii 0, 0, (LO32 $val)), sub_i32)>; 1559def : Pat<(i64 simm32:$val), (LEAzii 0, 0, (LO32 $val))>; 1560def : Pat<(i64 uimm32:$val), (ANDrm (LEAzii 0, 0, (LO32 $val)), !add(32, 64))>; 1561// Arbitrary immediates. 1562def : Pat<(i64 lozero:$val), 1563 (LEASLzii 0, 0, (HI32 imm:$val))>; 1564def : Pat<(i64 lomsbzero:$val), 1565 (LEASLrii (LEAzii 0, 0, (LO32 imm:$val)), 0, (HI32 imm:$val))>; 1566def : Pat<(i64 imm:$val), 1567 (LEASLrii (ANDrm (LEAzii 0, 0, (LO32 imm:$val)), !add(32, 64)), 0, 1568 (HI32 imm:$val))>; 1569 1570// LEA patterns 1571def lea_add : PatFrags<(ops node:$base, node:$idx, node:$disp), 1572 [(add (add node:$base, node:$idx), node:$disp), 1573 (add (add node:$base, node:$disp), node:$idx), 1574 (add node:$base, (add $idx, $disp))]>; 1575def : Pat<(lea_add I64:$base, simm7:$idx, simm32:$disp), 1576 (LEArii $base, (LO7 $idx), (LO32 $disp))>; 1577def : Pat<(lea_add I64:$base, I64:$idx, simm32:$disp), 1578 (LEArri $base, $idx, (LO32 $disp))>; 1579def : Pat<(lea_add I64:$base, simm7:$idx, lozero:$disp), 1580 (LEASLrii $base, (LO7 $idx), (HI32 $disp))>; 1581def : Pat<(lea_add I64:$base, I64:$idx, lozero:$disp), 1582 (LEASLrri $base, $idx, (HI32 $disp))>; 1583 1584// Address calculation patterns and optimizations 1585// 1586// Generate following instructions: 1587// 1. LEA %reg, label@LO32 1588// AND %reg, %reg, (32)0 1589// 2. LEASL %reg, label@HI32 1590// 3. (LEA %reg, label@LO32) 1591// (AND %reg, %reg, (32)0) 1592// LEASL %reg, label@HI32(, %reg) 1593// 4. (LEA %reg, label@LO32) 1594// (AND %reg, %reg, (32)0) 1595// LEASL %reg, label@HI32(%reg, %got) 1596// 1597def velo_only : OutPatFrag<(ops node:$lo), 1598 (ANDrm (LEAzii 0, 0, $lo), !add(32, 64))>; 1599def vehi_only : OutPatFrag<(ops node:$hi), 1600 (LEASLzii 0, 0, $hi)>; 1601def vehi_lo : OutPatFrag<(ops node:$hi, node:$lo), 1602 (LEASLrii $lo, 0, $hi)>; 1603def vehi_baselo : OutPatFrag<(ops node:$base, node:$hi, node:$lo), 1604 (LEASLrri $base, $lo, $hi)>; 1605foreach type = [ "tblockaddress", "tconstpool", "texternalsym", "tglobaladdr", 1606 "tglobaltlsaddr" ] in { 1607 def : Pat<(VElo !cast<SDNode>(type):$lo), (velo_only $lo)>; 1608 def : Pat<(VEhi !cast<SDNode>(type):$hi), (vehi_only $hi)>; 1609 def : Pat<(add (VEhi !cast<SDNode>(type):$hi), I64:$lo), (vehi_lo $hi, $lo)>; 1610 def : Pat<(add I64:$base, (add (VEhi !cast<SDNode>(type):$hi), I64:$lo)), 1611 (vehi_baselo $base, $hi, $lo)>; 1612} 1613 1614// floating point 1615def : Pat<(f32 fpimm:$val), 1616 (EXTRACT_SUBREG (LEASLzii 0, 0, (HIFP32 $val)), sub_f32)>; 1617def : Pat<(f64 fplozero:$val), 1618 (LEASLzii 0, 0, (HIFP32 $val))>; 1619def : Pat<(f64 fplomsbzero:$val), 1620 (LEASLrii (LEAzii 0, 0, (LOFP32 $val)), 0, (HIFP32 $val))>; 1621def : Pat<(f64 fpimm:$val), 1622 (LEASLrii (ANDrm (LEAzii 0, 0, (LOFP32 $val)), !add(32, 64)), 0, 1623 (HIFP32 $val))>; 1624 1625// The same integer registers are used for i32 and i64 values. 1626// When registers hold i32 values, the high bits are unused. 1627 1628// TODO Use standard expansion for shift-based lowering of sext_inreg 1629 1630// Cast to i1 1631def : Pat<(sext_inreg I32:$src, i1), 1632 (SRAWSXri (SLAWSXri $src, 31), 31)>; 1633def : Pat<(sext_inreg I64:$src, i1), 1634 (SRALri (SLLri $src, 63), 63)>; 1635 1636// Cast to i8 1637def : Pat<(sext_inreg I32:$src, i8), 1638 (SRAWSXri (SLAWSXri $src, 24), 24)>; 1639def : Pat<(sext_inreg I64:$src, i8), 1640 (SRALri (SLLri $src, 56), 56)>; 1641def : Pat<(sext_inreg (i32 (trunc i64:$src)), i8), 1642 (EXTRACT_SUBREG (SRALri (SLLri $src, 56), 56), sub_i32)>; 1643def : Pat<(i32 (and (trunc i64:$src), 0xff)), 1644 (EXTRACT_SUBREG (ANDrm $src, !add(56, 64)), sub_i32)>; 1645 1646// Cast to i16 1647def : Pat<(sext_inreg I32:$src, i16), 1648 (SRAWSXri (SLAWSXri $src, 16), 16)>; 1649def : Pat<(sext_inreg I64:$src, i16), 1650 (SRALri (SLLri $src, 48), 48)>; 1651def : Pat<(sext_inreg (i32 (trunc i64:$src)), i16), 1652 (EXTRACT_SUBREG (SRALri (SLLri $src, 48), 48), sub_i32)>; 1653def : Pat<(i32 (and (trunc i64:$src), 0xffff)), 1654 (EXTRACT_SUBREG (ANDrm $src, !add(48, 64)), sub_i32)>; 1655 1656// Cast to i32 1657def : Pat<(i32 (trunc i64:$src)), 1658 (ADDSWSXrm (EXTRACT_SUBREG $src, sub_i32), 0)>; 1659def : Pat<(i32 (fp_to_sint f32:$src)), (CVTWSSXr RD_RZ, $src)>; 1660def : Pat<(i32 (fp_to_sint f64:$src)), (CVTWDSXr RD_RZ, $src)>; 1661def : Pat<(i32 (fp_to_sint f128:$src)), (CVTWDSXr RD_RZ, (CVTDQr $src))>; 1662 1663// Cast to i64 1664def : Pat<(sext_inreg i64:$src, i32), 1665 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), 1666 (ADDSWSXrm (EXTRACT_SUBREG $src, sub_i32), 0), sub_i32)>; 1667def : Pat<(i64 (sext i32:$src)), 1668 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (ADDSWSXrm $src, 0), sub_i32)>; 1669def : Pat<(i64 (zext i32:$src)), 1670 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (ADDSWZXrm $src, 0), sub_i32)>; 1671def : Pat<(i64 (fp_to_sint f32:$src)), (CVTLDr RD_RZ, (CVTDSr $src))>; 1672def : Pat<(i64 (fp_to_sint f64:$src)), (CVTLDr RD_RZ, $src)>; 1673def : Pat<(i64 (fp_to_sint f128:$src)), (CVTLDr RD_RZ, (CVTDQr $src))>; 1674 1675// Cast to f32 1676def : Pat<(f32 (sint_to_fp i64:$src)), (CVTSDr (CVTDLr i64:$src))>; 1677 1678// Cast to f128 1679def : Pat<(f128 (sint_to_fp i32:$src)), (CVTQDr (CVTDWr $src))>; 1680def : Pat<(f128 (sint_to_fp i64:$src)), (CVTQDr (CVTDLr $src))>; 1681 1682def : Pat<(i64 (anyext i32:$sy)), 1683 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $sy, sub_i32)>; 1684 1685 1686// extload, sextload and zextload stuff 1687multiclass EXT64m<SDPatternOperator from, 1688 SDPatternOperator torri, 1689 SDPatternOperator torii, 1690 SDPatternOperator tozri, 1691 SDPatternOperator tozii> { 1692 def : Pat<(i64 (from ADDRrri:$addr)), 1693 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (torri MEMrri:$addr), 1694 sub_i32)>; 1695 def : Pat<(i64 (from ADDRrii:$addr)), 1696 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (torii MEMrii:$addr), 1697 sub_i32)>; 1698 def : Pat<(i64 (from ADDRzri:$addr)), 1699 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (tozri MEMzri:$addr), 1700 sub_i32)>; 1701 def : Pat<(i64 (from ADDRzii:$addr)), 1702 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (tozii MEMzii:$addr), 1703 sub_i32)>; 1704} 1705defm : EXT64m<sextloadi8, LD1BSXrri, LD1BSXrii, LD1BSXzri, LD1BSXzii>; 1706defm : EXT64m<zextloadi8, LD1BZXrri, LD1BZXrii, LD1BZXzri, LD1BZXzii>; 1707defm : EXT64m<extloadi8, LD1BZXrri, LD1BZXrii, LD1BZXzri, LD1BZXzii>; 1708defm : EXT64m<sextloadi16, LD2BSXrri, LD2BSXrii, LD2BSXzri, LD2BSXzii>; 1709defm : EXT64m<zextloadi16, LD2BZXrri, LD2BZXrii, LD2BZXzri, LD2BZXzii>; 1710defm : EXT64m<extloadi16, LD2BZXrri, LD2BZXrii, LD2BZXzri, LD2BZXzii>; 1711defm : EXT64m<sextloadi32, LDLSXrri, LDLSXrii, LDLSXzri, LDLSXzii>; 1712defm : EXT64m<zextloadi32, LDLZXrri, LDLZXrii, LDLZXzri, LDLZXzii>; 1713defm : EXT64m<extloadi32, LDLSXrri, LDLSXrii, LDLSXzri, LDLSXzii>; 1714 1715// anyextload 1716multiclass EXT32m<SDPatternOperator from, 1717 SDPatternOperator torri, 1718 SDPatternOperator torii, 1719 SDPatternOperator tozri, 1720 SDPatternOperator tozii> { 1721 def : Pat<(from ADDRrri:$addr), (torri MEMrri:$addr)>; 1722 def : Pat<(from ADDRrii:$addr), (torii MEMrii:$addr)>; 1723 def : Pat<(from ADDRzri:$addr), (tozri MEMzri:$addr)>; 1724 def : Pat<(from ADDRzii:$addr), (tozii MEMzii:$addr)>; 1725} 1726defm : EXT32m<extloadi8, LD1BZXrri, LD1BZXrii, LD1BZXzri, LD1BZXzii>; 1727defm : EXT32m<extloadi16, LD2BZXrri, LD2BZXrii, LD2BZXzri, LD2BZXzii>; 1728 1729// truncstore 1730multiclass TRUNC64m<SDPatternOperator from, 1731 SDPatternOperator torri, 1732 SDPatternOperator torii, 1733 SDPatternOperator tozri, 1734 SDPatternOperator tozii> { 1735 def : Pat<(from i64:$src, ADDRrri:$addr), 1736 (torri MEMrri:$addr, (EXTRACT_SUBREG $src, sub_i32))>; 1737 def : Pat<(from i64:$src, ADDRrii:$addr), 1738 (torii MEMrii:$addr, (EXTRACT_SUBREG $src, sub_i32))>; 1739 def : Pat<(from i64:$src, ADDRzri:$addr), 1740 (tozri MEMzri:$addr, (EXTRACT_SUBREG $src, sub_i32))>; 1741 def : Pat<(from i64:$src, ADDRzii:$addr), 1742 (tozii MEMzii:$addr, (EXTRACT_SUBREG $src, sub_i32))>; 1743} 1744defm : TRUNC64m<truncstorei8, ST1Brri, ST1Brii, ST1Bzri, ST1Bzii>; 1745defm : TRUNC64m<truncstorei16, ST2Brri, ST2Brii, ST2Bzri, ST2Bzii>; 1746defm : TRUNC64m<truncstorei32, STLrri, STLrii, STLzri, ST1Bzii>; 1747 1748// Atomic loads 1749multiclass ATMLDm<SDPatternOperator from, 1750 SDPatternOperator torri, SDPatternOperator torii, 1751 SDPatternOperator tozri, SDPatternOperator tozii> { 1752 def : Pat<(from ADDRrri:$addr), (torri MEMrri:$addr)>; 1753 def : Pat<(from ADDRrii:$addr), (torii MEMrii:$addr)>; 1754 def : Pat<(from ADDRzri:$addr), (tozri MEMzri:$addr)>; 1755 def : Pat<(from ADDRzii:$addr), (tozii MEMzii:$addr)>; 1756} 1757defm : ATMLDm<atomic_load_8, LD1BZXrri, LD1BZXrii, LD1BZXzri, LD1BZXzii>; 1758defm : ATMLDm<atomic_load_16, LD2BZXrri, LD2BZXrii, LD2BZXzri, LD2BZXzii>; 1759defm : ATMLDm<atomic_load_32, LDLZXrri, LDLZXrii, LDLZXzri, LDLZXzii>; 1760defm : ATMLDm<atomic_load_64, LDrri, LDrii, LDzri, LDzii>; 1761 1762def i2l : OutPatFrag<(ops node:$exp), 1763 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $exp, sub_i32)>; 1764 1765// Optimized atomic loads with sext 1766multiclass SXATMLDm<SDPatternOperator from, Operand TY, 1767 SDPatternOperator torri, SDPatternOperator torii, 1768 SDPatternOperator tozri, SDPatternOperator tozii> { 1769 def : Pat<(i64 (sext_inreg (i64 (anyext (from ADDRrri:$addr))), TY)), 1770 (i2l (torri MEMrri:$addr))>; 1771 def : Pat<(i64 (sext_inreg (i64 (anyext (from ADDRrii:$addr))), TY)), 1772 (i2l (torii MEMrii:$addr))>; 1773 def : Pat<(i64 (sext_inreg (i64 (anyext (from ADDRzri:$addr))), TY)), 1774 (i2l (tozri MEMzri:$addr))>; 1775 def : Pat<(i64 (sext_inreg (i64 (anyext (from ADDRzii:$addr))), TY)), 1776 (i2l (tozii MEMzii:$addr))>; 1777} 1778multiclass SXATMLD32m<SDPatternOperator from, 1779 SDPatternOperator torri, SDPatternOperator torii, 1780 SDPatternOperator tozri, SDPatternOperator tozii> { 1781 def : Pat<(i64 (sext (from ADDRrri:$addr))), 1782 (i2l (torri MEMrri:$addr))>; 1783 def : Pat<(i64 (sext (from ADDRrii:$addr))), 1784 (i2l (torii MEMrii:$addr))>; 1785 def : Pat<(i64 (sext (from ADDRzri:$addr))), 1786 (i2l (tozri MEMzri:$addr))>; 1787 def : Pat<(i64 (sext (from ADDRzii:$addr))), 1788 (i2l (tozii MEMzii:$addr))>; 1789} 1790defm : SXATMLDm<atomic_load_8, i8, LD1BSXrri, LD1BSXrii, LD1BSXzri, LD1BSXzii>; 1791defm : SXATMLDm<atomic_load_16, i16, LD2BSXrri, LD2BSXrii, LD2BSXzri, 1792 LD2BSXzii>; 1793defm : SXATMLD32m<atomic_load_32, LDLSXrri, LDLSXrii, LDLSXzri, LDLSXzii>; 1794 1795// Optimized atomic loads with zext 1796multiclass ZXATMLDm<SDPatternOperator from, Operand VAL, 1797 SDPatternOperator torri, SDPatternOperator torii, 1798 SDPatternOperator tozri, SDPatternOperator tozii> { 1799 def : Pat<(i64 (and (anyext (from ADDRrri:$addr)), VAL)), 1800 (i2l (torri MEMrri:$addr))>; 1801 def : Pat<(i64 (and (anyext (from ADDRrii:$addr)), VAL)), 1802 (i2l (torii MEMrii:$addr))>; 1803 def : Pat<(i64 (and (anyext (from ADDRzri:$addr)), VAL)), 1804 (i2l (tozri MEMzri:$addr))>; 1805 def : Pat<(i64 (and (anyext (from ADDRzii:$addr)), VAL)), 1806 (i2l (tozii MEMzii:$addr))>; 1807} 1808multiclass ZXATMLD32m<SDPatternOperator from, Operand VAL, 1809 SDPatternOperator torri, SDPatternOperator torii, 1810 SDPatternOperator tozri, SDPatternOperator tozii> { 1811 def : Pat<(i64 (zext (from ADDRrri:$addr))), 1812 (i2l (torri MEMrri:$addr))>; 1813 def : Pat<(i64 (zext (from ADDRrii:$addr))), 1814 (i2l (torii MEMrii:$addr))>; 1815 def : Pat<(i64 (zext (from ADDRzri:$addr))), 1816 (i2l (tozri MEMzri:$addr))>; 1817 def : Pat<(i64 (zext (from ADDRzii:$addr))), 1818 (i2l (tozii MEMzii:$addr))>; 1819} 1820defm : ZXATMLDm<atomic_load_8, 0xFF, LD1BZXrri, LD1BZXrii, LD1BZXzri, 1821 LD1BZXzii>; 1822defm : ZXATMLDm<atomic_load_16, 0xFFFF, LD2BZXrri, LD2BZXrii, LD2BZXzri, 1823 LD2BZXzii>; 1824defm : ZXATMLD32m<atomic_load_32, 0xFFFFFFFF, LDLZXrri, LDLZXrii, LDLZXzri, 1825 LDLZXzii>; 1826 1827// Atomic stores 1828multiclass ATMSTm<SDPatternOperator from, ValueType ty, 1829 SDPatternOperator torri, SDPatternOperator torii, 1830 SDPatternOperator tozri, SDPatternOperator tozii> { 1831 def : Pat<(from ADDRrri:$addr, ty:$src), (torri MEMrri:$addr, $src)>; 1832 def : Pat<(from ADDRrii:$addr, ty:$src), (torii MEMrii:$addr, $src)>; 1833 def : Pat<(from ADDRzri:$addr, ty:$src), (tozri MEMzri:$addr, $src)>; 1834 def : Pat<(from ADDRzii:$addr, ty:$src), (tozii MEMzii:$addr, $src)>; 1835} 1836defm : ATMSTm<atomic_store_8, i32, ST1Brri, ST1Brii, ST1Bzri, ST1Bzii>; 1837defm : ATMSTm<atomic_store_16, i32, ST2Brri, ST2Brii, ST2Bzri, ST2Bzii>; 1838defm : ATMSTm<atomic_store_32, i32, STLrri, STLrii, STLzri, STLzii>; 1839defm : ATMSTm<atomic_store_64, i64, STrri, STrii, STzri, STzii>; 1840 1841// Optimized atomic stores with truncate 1842multiclass TRATMSTm<SDPatternOperator from, 1843 ValueType ty, 1844 SDPatternOperator torri, 1845 SDPatternOperator torii, 1846 SDPatternOperator tozri, 1847 SDPatternOperator tozii> { 1848 def : Pat<(from ADDRrri:$addr, (i32 (trunc i64:$src))), 1849 (torri MEMrri:$addr, (EXTRACT_SUBREG $src, sub_i32))>; 1850 def : Pat<(from ADDRrii:$addr, (i32 (trunc i64:$src))), 1851 (torii MEMrii:$addr, (EXTRACT_SUBREG $src, sub_i32))>; 1852 def : Pat<(from ADDRzri:$addr, (i32 (trunc i64:$src))), 1853 (tozri MEMzri:$addr, (EXTRACT_SUBREG $src, sub_i32))>; 1854 def : Pat<(from ADDRzii:$addr, (i32 (trunc i64:$src))), 1855 (tozii MEMzii:$addr, (EXTRACT_SUBREG $src, sub_i32))>; 1856} 1857defm : TRATMSTm<atomic_store_8, i32, ST1Brri, ST1Brii, ST1Bzri, ST1Bzii>; 1858defm : TRATMSTm<atomic_store_16, i32, ST2Brri, ST2Brii, ST2Bzri, ST2Bzii>; 1859defm : TRATMSTm<atomic_store_32, i32, STLrri, STLrii, STLzri, STLzii>; 1860 1861// Branches 1862def : Pat<(br bb:$addr), (BRCFLa bb:$addr)>; 1863 1864// brcc 1865// integer brcc 1866multiclass BRCCIm<ValueType ty, SDPatternOperator BrOpNode1, 1867 SDPatternOperator BrOpNode2, 1868 SDPatternOperator CmpOpNode1, 1869 SDPatternOperator CmpOpNode2> { 1870 def : Pat<(brcc CCSIOp:$cond, ty:$l, simm7:$r, bb:$addr), 1871 (BrOpNode2 (icond2ccSwap $cond), (LO7 $r), $l, bb:$addr)>; 1872 def : Pat<(brcc CCSIOp:$cond, ty:$l, ty:$r, bb:$addr), 1873 (BrOpNode1 (icond2cc $cond), $l, $r, bb:$addr)>; 1874 def : Pat<(brcc CCUIOp:$cond, ty:$l, simm7:$r, bb:$addr), 1875 (BrOpNode2 (icond2cc $cond), 0, (CmpOpNode2 (LO7 $r), $l), 1876 bb:$addr)>; 1877 def : Pat<(brcc CCUIOp:$cond, ty:$l, ty:$r, bb:$addr), 1878 (BrOpNode2 (icond2cc $cond), 0, (CmpOpNode1 $r, $l), bb:$addr)>; 1879} 1880defm : BRCCIm<i32, BRCFWrr, BRCFWir, CMPUWrr, CMPUWir>; 1881defm : BRCCIm<i64, BRCFLrr, BRCFLir, CMPULrr, CMPULir>; 1882 1883// floating point brcc 1884multiclass BRCCFm<ValueType ty, SDPatternOperator BrOpNode1, 1885 SDPatternOperator BrOpNode2> { 1886 def : Pat<(brcc cond:$cond, ty:$l, simm7fp:$r, bb:$addr), 1887 (BrOpNode2 (fcond2ccSwap $cond), (LO7FP $r), $l, bb:$addr)>; 1888 def : Pat<(brcc cond:$cond, ty:$l, ty:$r, bb:$addr), 1889 (BrOpNode1 (fcond2cc $cond), $l, $r, bb:$addr)>; 1890} 1891defm : BRCCFm<f32, BRCFSrr, BRCFSir>; 1892defm : BRCCFm<f64, BRCFDrr, BRCFDir>; 1893def : Pat<(brcc cond:$cond, f128:$l, f128:$r, bb:$addr), 1894 (BRCFDir (fcond2cc $cond), 0, (FCMPQrr $r, $l), bb:$addr)>; 1895 1896//===----------------------------------------------------------------------===// 1897// Pseudo Instructions 1898//===----------------------------------------------------------------------===// 1899 1900// GETGOT for PIC 1901let Defs = [SX15 /* %got */, SX16 /* %plt */], hasSideEffects = 0 in { 1902 def GETGOT : Pseudo<(outs getGOT:$getpcseq), (ins), "$getpcseq">; 1903} 1904 1905// GETFUNPLT for PIC 1906let hasSideEffects = 0 in 1907def GETFUNPLT : Pseudo<(outs I64:$dst), (ins i64imm:$addr), 1908 "$dst, $addr", 1909 [(set iPTR:$dst, (GetFunPLT tglobaladdr:$addr))] >; 1910 1911def : Pat<(GetFunPLT tglobaladdr:$dst), 1912 (GETFUNPLT tglobaladdr:$dst)>; 1913def : Pat<(GetFunPLT texternalsym:$dst), 1914 (GETFUNPLT texternalsym:$dst)>; 1915 1916// GETTLSADDR for TLS 1917let Defs = [SX0, SX10, SX12], hasSideEffects = 0 in 1918def GETTLSADDR : Pseudo<(outs), (ins i64imm:$addr), 1919 "# GETTLSADDR $addr", 1920 [(GetTLSAddr tglobaltlsaddr:$addr)] >; 1921 1922def : Pat<(GetTLSAddr tglobaltlsaddr:$dst), 1923 (GETTLSADDR tglobaltlsaddr:$dst)>; 1924 1925let Defs = [SX11], Uses = [SX11], hasSideEffects = 0 in { 1926def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i64imm:$amt, i64imm:$amt2), 1927 "# ADJCALLSTACKDOWN $amt, $amt2", 1928 [(callseq_start timm:$amt, timm:$amt2)]>; 1929def ADJCALLSTACKUP : Pseudo<(outs), (ins i64imm:$amt1, i64imm:$amt2), 1930 "# ADJCALLSTACKUP $amt1", 1931 [(callseq_end timm:$amt1, timm:$amt2)]>; 1932} 1933 1934let Defs = [SX8], Uses = [SX8, SX11], hasSideEffects = 0 in 1935def EXTEND_STACK : Pseudo<(outs), (ins), 1936 "# EXTEND STACK", 1937 []>; 1938let hasSideEffects = 0 in 1939def EXTEND_STACK_GUARD : Pseudo<(outs), (ins), 1940 "# EXTEND STACK GUARD", 1941 []>; 1942 1943// Dynamic stack allocation yields a __llvm_grow_stack for VE targets. 1944// These calls are needed to probe the stack when allocating more over 1945// %s8 (%sl - stack limit). 1946 1947let Uses = [SX11], hasSideEffects = 1 in 1948def GETSTACKTOP : Pseudo<(outs I64:$dst), (ins), 1949 "# GET STACK TOP", 1950 [(set iPTR:$dst, (GetStackTop))]>; 1951 1952// MEMBARRIER 1953let hasSideEffects = 1 in 1954def MEMBARRIER : Pseudo<(outs), (ins), "# MEMBARRIER", [(MemBarrier)] >; 1955 1956//===----------------------------------------------------------------------===// 1957// Other patterns 1958//===----------------------------------------------------------------------===// 1959 1960// SETCC pattern matches 1961// 1962// CMP %tmp, lhs, rhs ; compare lhs and rhs 1963// or %res, 0, (0)1 ; initialize by 0 1964// CMOV %res, (63)0, %tmp ; set 1 if %tmp is true 1965 1966class setccrr<Instruction INSN> : 1967 OutPatFrag<(ops node:$cond, node:$comp), 1968 (EXTRACT_SUBREG 1969 (INSN $cond, $comp, 1970 !add(63, 64), // means (63)0 == 1 1971 (ORim 0, 0)), sub_i32)>; 1972 1973def : Pat<(i32 (setcc i32:$l, i32:$r, CCSIOp:$cond)), 1974 (setccrr<CMOVWrm> (icond2cc $cond), (CMPSWSXrr $l, $r))>; 1975def : Pat<(i32 (setcc i32:$l, i32:$r, CCUIOp:$cond)), 1976 (setccrr<CMOVWrm> (icond2cc $cond), (CMPUWrr $l, $r))>; 1977def : Pat<(i32 (setcc i64:$l, i64:$r, CCSIOp:$cond)), 1978 (setccrr<CMOVLrm> (icond2cc $cond), (CMPSLrr $l, $r))>; 1979def : Pat<(i32 (setcc i64:$l, i64:$r, CCUIOp:$cond)), 1980 (setccrr<CMOVLrm> (icond2cc $cond), (CMPULrr $l, $r))>; 1981def : Pat<(i32 (setcc f32:$l, f32:$r, cond:$cond)), 1982 (setccrr<CMOVSrm> (fcond2cc $cond), (FCMPSrr $l, $r))>; 1983def : Pat<(i32 (setcc f64:$l, f64:$r, cond:$cond)), 1984 (setccrr<CMOVDrm> (fcond2cc $cond), (FCMPDrr $l, $r))>; 1985def : Pat<(i32 (setcc f128:$l, f128:$r, cond:$cond)), 1986 (setccrr<CMOVDrm> (fcond2cc $cond), (FCMPQrr $l, $r))>; 1987 1988// Special SELECTCC pattern matches 1989// Use min/max for better performance. 1990// 1991// MAX/MIN %res, %lhs, %rhs 1992 1993def : Pat<(f64 (selectcc f64:$LHS, f64:$RHS, f64:$LHS, f64:$RHS, SETOGT)), 1994 (FMAXDrr $LHS, $RHS)>; 1995def : Pat<(f32 (selectcc f32:$LHS, f32:$RHS, f32:$LHS, f32:$RHS, SETOGT)), 1996 (FMAXSrr $LHS, $RHS)>; 1997def : Pat<(i64 (selectcc i64:$LHS, i64:$RHS, i64:$LHS, i64:$RHS, SETGT)), 1998 (MAXSLrr $LHS, $RHS)>; 1999def : Pat<(i32 (selectcc i32:$LHS, i32:$RHS, i32:$LHS, i32:$RHS, SETGT)), 2000 (MAXSWSXrr $LHS, $RHS)>; 2001def : Pat<(f64 (selectcc f64:$LHS, f64:$RHS, f64:$LHS, f64:$RHS, SETOGE)), 2002 (FMAXDrr $LHS, $RHS)>; 2003def : Pat<(f32 (selectcc f32:$LHS, f32:$RHS, f32:$LHS, f32:$RHS, SETOGE)), 2004 (FMAXSrr $LHS, $RHS)>; 2005def : Pat<(i64 (selectcc i64:$LHS, i64:$RHS, i64:$LHS, i64:$RHS, SETGE)), 2006 (MAXSLrr $LHS, $RHS)>; 2007def : Pat<(i32 (selectcc i32:$LHS, i32:$RHS, i32:$LHS, i32:$RHS, SETGE)), 2008 (MAXSWSXrr $LHS, $RHS)>; 2009 2010def : Pat<(f64 (selectcc f64:$LHS, f64:$RHS, f64:$LHS, f64:$RHS, SETOLT)), 2011 (FMINDrr $LHS, $RHS)>; 2012def : Pat<(f32 (selectcc f32:$LHS, f32:$RHS, f32:$LHS, f32:$RHS, SETOLT)), 2013 (FMINSrr $LHS, $RHS)>; 2014def : Pat<(i64 (selectcc i64:$LHS, i64:$RHS, i64:$LHS, i64:$RHS, SETLT)), 2015 (MINSLrr $LHS, $RHS)>; 2016def : Pat<(i32 (selectcc i32:$LHS, i32:$RHS, i32:$LHS, i32:$RHS, SETLT)), 2017 (MINSWSXrr $LHS, $RHS)>; 2018def : Pat<(f64 (selectcc f64:$LHS, f64:$RHS, f64:$LHS, f64:$RHS, SETOLE)), 2019 (FMINDrr $LHS, $RHS)>; 2020def : Pat<(f32 (selectcc f32:$LHS, f32:$RHS, f32:$LHS, f32:$RHS, SETOLE)), 2021 (FMINSrr $LHS, $RHS)>; 2022def : Pat<(i64 (selectcc i64:$LHS, i64:$RHS, i64:$LHS, i64:$RHS, SETLE)), 2023 (MINSLrr $LHS, $RHS)>; 2024def : Pat<(i32 (selectcc i32:$LHS, i32:$RHS, i32:$LHS, i32:$RHS, SETLE)), 2025 (MINSWSXrr $LHS, $RHS)>; 2026 2027// Helper classes to construct cmov patterns for the ease. 2028// 2029// Hiding INSERT_SUBREG/EXTRACT_SUBREG patterns. 2030 2031class cmovrr<Instruction INSN> : 2032 OutPatFrag<(ops node:$cond, node:$comp, node:$t, node:$f), 2033 (INSN $cond, $comp, $t, $f)>; 2034class cmovrm<Instruction INSN, SDNodeXForm MOP = MIMM> : 2035 OutPatFrag<(ops node:$cond, node:$comp, node:$t, node:$f), 2036 (INSN $cond, $comp, (MOP $t), $f)>; 2037class cmov32rr<Instruction INSN, SubRegIndex sub_oty> : 2038 OutPatFrag<(ops node:$cond, node:$comp, node:$t, node:$f), 2039 (EXTRACT_SUBREG 2040 (INSN $cond, $comp, 2041 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $t, sub_oty), 2042 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $f, sub_oty)), 2043 sub_oty)>; 2044class cmov32rm<Instruction INSN, SubRegIndex sub_oty, SDNodeXForm MOP = MIMM> : 2045 OutPatFrag<(ops node:$cond, node:$comp, node:$t, node:$f), 2046 (EXTRACT_SUBREG 2047 (INSN $cond, $comp, 2048 (MOP $t), 2049 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $f, sub_oty)), 2050 sub_oty)>; 2051class cmov128rr<Instruction INSN> : 2052 OutPatFrag<(ops node:$cond, node:$comp, node:$t, node:$f), 2053 (INSERT_SUBREG 2054 (INSERT_SUBREG (f128 (IMPLICIT_DEF)), 2055 (INSN $cond, $comp, 2056 (EXTRACT_SUBREG $t, sub_odd), 2057 (EXTRACT_SUBREG $f, sub_odd)), sub_odd), 2058 (INSN $cond, $comp, 2059 (EXTRACT_SUBREG $t, sub_even), 2060 (EXTRACT_SUBREG $f, sub_even)), sub_even)>; 2061 2062// Generic SELECTCC pattern matches 2063// 2064// CMP %tmp, %l, %r ; compare %l and %r 2065// or %res, %f, (0)1 ; initialize by %f 2066// CMOV %res, %t, %tmp ; set %t if %tmp is true 2067 2068def : Pat<(i32 (selectcc i32:$l, i32:$r, i32:$t, i32:$f, CCSIOp:$cond)), 2069 (cmov32rr<CMOVWrr, sub_i32> (icond2cc $cond), (CMPSWSXrr $l, $r), 2070 $t, $f)>; 2071def : Pat<(i32 (selectcc i32:$l, i32:$r, i32:$t, i32:$f, CCUIOp:$cond)), 2072 (cmov32rr<CMOVWrr, sub_i32> (icond2cc $cond), (CMPUWrr $l, $r), 2073 $t, $f)>; 2074def : Pat<(i32 (selectcc i64:$l, i64:$r, i32:$t, i32:$f, CCSIOp:$cond)), 2075 (cmov32rr<CMOVLrr, sub_i32> (icond2cc $cond), (CMPSLrr $l, $r), 2076 $t, $f)>; 2077def : Pat<(i32 (selectcc i64:$l, i64:$r, i32:$t, i32:$f, CCUIOp:$cond)), 2078 (cmov32rr<CMOVLrr, sub_i32> (icond2cc $cond), (CMPULrr $l, $r), 2079 $t, $f)>; 2080def : Pat<(i32 (selectcc f32:$l, f32:$r, i32:$t, i32:$f, cond:$cond)), 2081 (cmov32rr<CMOVSrr, sub_i32> (fcond2cc $cond), (FCMPSrr $l, $r), 2082 $t, $f)>; 2083def : Pat<(i32 (selectcc f64:$l, f64:$r, i32:$t, i32:$f, cond:$cond)), 2084 (cmov32rr<CMOVDrr, sub_i32> (fcond2cc $cond), (FCMPDrr $l, $r), 2085 $t, $f)>; 2086def : Pat<(i32 (selectcc f128:$l, f128:$r, i32:$t, i32:$f, cond:$cond)), 2087 (cmov32rr<CMOVDrr, sub_i32> (fcond2cc $cond), (FCMPQrr $l, $r), 2088 $t, $f)>; 2089 2090def : Pat<(i64 (selectcc i32:$l, i32:$r, i64:$t, i64:$f, CCSIOp:$cond)), 2091 (cmovrr<CMOVWrr> (icond2cc $cond), (CMPSWSXrr $l, $r), $t, $f)>; 2092def : Pat<(i64 (selectcc i32:$l, i32:$r, i64:$t, i64:$f, CCUIOp:$cond)), 2093 (cmovrr<CMOVWrr> (icond2cc $cond), (CMPUWrr $l, $r), $t, $f)>; 2094def : Pat<(i64 (selectcc i64:$l, i64:$r, i64:$t, i64:$f, CCSIOp:$cond)), 2095 (cmovrr<CMOVLrr> (icond2cc $cond), (CMPSLrr $l, $r), $t, $f)>; 2096def : Pat<(i64 (selectcc i64:$l, i64:$r, i64:$t, i64:$f, CCUIOp:$cond)), 2097 (cmovrr<CMOVLrr> (icond2cc $cond), (CMPULrr $l, $r), $t, $f)>; 2098def : Pat<(i64 (selectcc f32:$l, f32:$r, i64:$t, i64:$f, cond:$cond)), 2099 (cmovrr<CMOVSrr> (fcond2cc $cond), (FCMPSrr $l, $r), $t, $f)>; 2100def : Pat<(i64 (selectcc f64:$l, f64:$r, i64:$t, i64:$f, cond:$cond)), 2101 (cmovrr<CMOVDrr> (fcond2cc $cond), (FCMPDrr $l, $r), $t, $f)>; 2102def : Pat<(i64 (selectcc f128:$l, f128:$r, i64:$t, i64:$f, cond:$cond)), 2103 (cmovrr<CMOVDrr> (fcond2cc $cond), (FCMPQrr $l, $r), $t, $f)>; 2104 2105def : Pat<(f32 (selectcc i32:$l, i32:$r, f32:$t, f32:$f, CCSIOp:$cond)), 2106 (cmov32rr<CMOVWrr, sub_f32> (icond2cc $cond), (CMPSWSXrr $l, $r), 2107 $t, $f)>; 2108def : Pat<(f32 (selectcc i32:$l, i32:$r, f32:$t, f32:$f, CCUIOp:$cond)), 2109 (cmov32rr<CMOVWrr, sub_f32> (icond2cc $cond), (CMPUWrr $l, $r), 2110 $t, $f)>; 2111def : Pat<(f32 (selectcc i64:$l, i64:$r, f32:$t, f32:$f, CCSIOp:$cond)), 2112 (cmov32rr<CMOVLrr, sub_f32> (icond2cc $cond), (CMPSLrr $l, $r), 2113 $t, $f)>; 2114def : Pat<(f32 (selectcc i64:$l, i64:$r, f32:$t, f32:$f, CCUIOp:$cond)), 2115 (cmov32rr<CMOVLrr, sub_f32> (icond2cc $cond), (CMPULrr $l, $r), 2116 $t, $f)>; 2117def : Pat<(f32 (selectcc f32:$l, f32:$r, f32:$t, f32:$f, cond:$cond)), 2118 (cmov32rr<CMOVSrr, sub_f32> (fcond2cc $cond), (FCMPSrr $l, $r), 2119 $t, $f)>; 2120def : Pat<(f32 (selectcc f64:$l, f64:$r, f32:$t, f32:$f, cond:$cond)), 2121 (cmov32rr<CMOVDrr, sub_f32> (fcond2cc $cond), (FCMPDrr $l, $r), 2122 $t, $f)>; 2123def : Pat<(f32 (selectcc f128:$l, f128:$r, f32:$t, f32:$f, cond:$cond)), 2124 (cmov32rr<CMOVDrr, sub_f32> (fcond2cc $cond), (FCMPQrr $l, $r), 2125 $t, $f)>; 2126 2127def : Pat<(f64 (selectcc i32:$l, i32:$r, f64:$t, f64:$f, CCSIOp:$cond)), 2128 (cmovrr<CMOVWrr> (icond2cc $cond), (CMPSWSXrr $l, $r), $t, $f)>; 2129def : Pat<(f64 (selectcc i32:$l, i32:$r, f64:$t, f64:$f, CCUIOp:$cond)), 2130 (cmovrr<CMOVWrr> (icond2cc $cond), (CMPUWrr $l, $r), $t, $f)>; 2131def : Pat<(f64 (selectcc i64:$l, i64:$r, f64:$t, f64:$f, CCSIOp:$cond)), 2132 (cmovrr<CMOVLrr> (icond2cc $cond), (CMPSLrr $l, $r), $t, $f)>; 2133def : Pat<(f64 (selectcc i64:$l, i64:$r, f64:$t, f64:$f, CCUIOp:$cond)), 2134 (cmovrr<CMOVLrr> (icond2cc $cond), (CMPULrr $l, $r), $t, $f)>; 2135def : Pat<(f64 (selectcc f32:$l, f32:$r, f64:$t, f64:$f, cond:$cond)), 2136 (cmovrr<CMOVSrr> (fcond2cc $cond), (FCMPSrr $l, $r), $t, $f)>; 2137def : Pat<(f64 (selectcc f64:$l, f64:$r, f64:$t, f64:$f, cond:$cond)), 2138 (cmovrr<CMOVDrr> (fcond2cc $cond), (FCMPDrr $l, $r), $t, $f)>; 2139def : Pat<(f64 (selectcc f128:$l, f128:$r, f64:$t, f64:$f, cond:$cond)), 2140 (cmovrr<CMOVDrr> (fcond2cc $cond), (FCMPQrr $l, $r), $t, $f)>; 2141 2142def : Pat<(f128 (selectcc i32:$l, i32:$r, f128:$t, f128:$f, CCSIOp:$cond)), 2143 (cmov128rr<CMOVWrr> (icond2cc $cond), (CMPSWSXrr $l, $r), $t, $f)>; 2144def : Pat<(f128 (selectcc i32:$l, i32:$r, f128:$t, f128:$f, CCUIOp:$cond)), 2145 (cmov128rr<CMOVWrr> (icond2cc $cond), (CMPUWrr $l, $r), $t, $f)>; 2146def : Pat<(f128 (selectcc i64:$l, i64:$r, f128:$t, f128:$f, CCSIOp:$cond)), 2147 (cmov128rr<CMOVLrr> (icond2cc $cond), (CMPSLrr $l, $r), $t, $f)>; 2148def : Pat<(f128 (selectcc i64:$l, i64:$r, f128:$t, f128:$f, CCUIOp:$cond)), 2149 (cmov128rr<CMOVLrr> (icond2cc $cond), (CMPULrr $l, $r), $t, $f)>; 2150def : Pat<(f128 (selectcc f32:$l, f32:$r, f128:$t, f128:$f, cond:$cond)), 2151 (cmov128rr<CMOVSrr> (fcond2cc $cond), (FCMPSrr $l, $r), $t, $f)>; 2152def : Pat<(f128 (selectcc f64:$l, f64:$r, f128:$t, f128:$f, cond:$cond)), 2153 (cmov128rr<CMOVDrr> (fcond2cc $cond), (FCMPDrr $l, $r), $t, $f)>; 2154def : Pat<(f128 (selectcc f128:$l, f128:$r, f128:$t, f128:$f, cond:$cond)), 2155 (cmov128rr<CMOVDrr> (fcond2cc $cond), (FCMPQrr $l, $r), $t, $f)>; 2156 2157// Generic SELECT pattern matches 2158// Use cmov.w for all cases since %pred holds i32. 2159// 2160// CMOV.w.ne %res, %tval, %tmp ; set tval if %tmp is true 2161 2162def : Pat<(i32 (select i32:$pred, i32:$t, i32:$f)), 2163 (cmov32rr<CMOVWrr, sub_i32> CC_INE, $pred, $t, $f)>; 2164def : Pat<(i32 (select i32:$pred, (i32 mimm:$t), i32:$f)), 2165 (cmov32rm<CMOVWrm, sub_i32> CC_INE, $pred, $t, $f)>; 2166def : Pat<(i32 (select i32:$pred, i32:$t, (i32 mimm:$f))), 2167 (cmov32rm<CMOVWrm, sub_i32> CC_IEQ, $pred, $f, $t)>; 2168 2169def : Pat<(i64 (select i32:$pred, i64:$t, i64:$f)), 2170 (cmovrr<CMOVWrr> CC_INE, $pred, $t, $f)>; 2171def : Pat<(i64 (select i32:$pred, (i64 mimm:$t), i64:$f)), 2172 (cmovrm<CMOVWrm, MIMM> CC_INE, $pred, $t, $f)>; 2173def : Pat<(i64 (select i32:$pred, i64:$t, (i64 mimm:$f))), 2174 (cmovrm<CMOVWrm, MIMM> CC_IEQ, $pred, $f, $t)>; 2175 2176def : Pat<(f32 (select i32:$pred, f32:$t, f32:$f)), 2177 (cmov32rr<CMOVWrr, sub_f32> CC_INE, $pred, $t, $f)>; 2178def : Pat<(f32 (select i32:$pred, (f32 mimmfp:$t), f32:$f)), 2179 (cmov32rm<CMOVWrm, sub_f32, MIMMFP> CC_INE, $pred, $t, $f)>; 2180def : Pat<(f32 (select i32:$pred, f32:$t, (f32 mimmfp:$f))), 2181 (cmov32rm<CMOVWrm, sub_f32, MIMMFP> CC_IEQ, $pred, $f, $t)>; 2182 2183def : Pat<(f64 (select i32:$pred, f64:$t, f64:$f)), 2184 (cmovrr<CMOVWrr> CC_INE, $pred, $t, $f)>; 2185def : Pat<(f64 (select i32:$pred, (f64 mimmfp:$t), f64:$f)), 2186 (cmovrm<CMOVWrm, MIMMFP> CC_INE, $pred, $t, $f)>; 2187def : Pat<(f64 (select i32:$pred, f64:$t, (f64 mimmfp:$f))), 2188 (cmovrm<CMOVWrm, MIMMFP> CC_IEQ, $pred, $f, $t)>; 2189 2190def : Pat<(f128 (select i32:$pred, f128:$t, f128:$f)), 2191 (cmov128rr<CMOVWrr> CC_INE, $pred, $t, $f)>; 2192 2193// bitconvert 2194def : Pat<(f64 (bitconvert i64:$src)), (COPY_TO_REGCLASS $src, I64)>; 2195def : Pat<(i64 (bitconvert f64:$src)), (COPY_TO_REGCLASS $src, I64)>; 2196 2197def : Pat<(i32 (bitconvert f32:$op)), 2198 (EXTRACT_SUBREG (SRALri (INSERT_SUBREG (i64 (IMPLICIT_DEF)), 2199 $op, sub_f32), 32), sub_i32)>; 2200def : Pat<(f32 (bitconvert i32:$op)), 2201 (EXTRACT_SUBREG (SLLri (INSERT_SUBREG (i64 (IMPLICIT_DEF)), 2202 $op, sub_i32), 32), sub_f32)>; 2203 2204// Optimize code A generated by `(unsigned char)c << 5` to B. 2205// A) sla.w.sx %s0, %s0, 5 2206// lea %s1, 224 ; 0xE0 2207// and %s0, %s0, %s1 2208// B) sla.w.sx %s0, %s0, 5 2209// and %s0, %s0, (56)0 2210 2211def : Pat<(i32 (and i32:$val, 0xff)), 2212 (EXTRACT_SUBREG 2213 (ANDrm (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $val, sub_i32), 2214 !add(56, 64)), sub_i32)>; 2215def : Pat<(i32 (and i32:$val, 0xffff)), 2216 (EXTRACT_SUBREG 2217 (ANDrm (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $val, sub_i32), 2218 !add(48, 64)), sub_i32)>; 2219def : Pat<(i64 (and i64:$val, 0xffffffff)), 2220 (ANDrm $val, !add(32, 64))>; 2221 2222// Vector instructions. 2223include "VEInstrVec.td" 2224