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