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