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, 638 RegisterClass RC, ValueType Ty, 639 SDPatternOperator OpNode = null_frag> { 640 def rrr : RR<opc, (outs RC:$sx), (ins RC:$hi, RC:$sz, I32:$sy), 641 !strconcat(opcStr, " $sx, $sz, $sy")>; 642 let cz = 0 in 643 def rmr : RR<opc, (outs RC:$sx), (ins RC:$hi, mimm:$sz, I32:$sy), 644 !strconcat(opcStr, " $sx, $sz, $sy")>; 645 let cy = 0 in 646 def rri : RR<opc, (outs RC:$sx), (ins RC:$hi, RC:$sz, uimm7:$sy), 647 !strconcat(opcStr, " $sx, $sz, $sy")>; 648 let cy = 0, cz = 0 in 649 def rmi : RR<opc, (outs RC:$sx), (ins RC:$hi, mimm:$sz, uimm7:$sy), 650 !strconcat(opcStr, " $sx, $sz, $sy")>; 651} 652 653// Special RR multiclass for 128 bits shift right instruction. 654// e.g. SRD 655let Constraints = "$low = $sx", DisableEncoding = "$low", hasSideEffects = 0 in 656multiclass RRIRDm<string opcStr, bits<8>opc, 657 RegisterClass RC, ValueType Ty, 658 SDPatternOperator OpNode = null_frag> { 659 def rrr : RR<opc, (outs RC:$sx), (ins RC:$sz, RC:$low, I32:$sy), 660 !strconcat(opcStr, " $sx, $sz, $sy")>; 661 let cz = 0 in 662 def mrr : RR<opc, (outs RC:$sx), (ins mimm:$sz, RC:$low, I32:$sy), 663 !strconcat(opcStr, " $sx, $sz, $sy")>; 664 let cy = 0 in 665 def rri : RR<opc, (outs RC:$sx), (ins RC:$sz, RC:$low, uimm7:$sy), 666 !strconcat(opcStr, " $sx, $sz, $sy")>; 667 let cy = 0, cz = 0 in 668 def mri : RR<opc, (outs RC:$sx), (ins mimm:$sz, RC:$low, uimm7:$sy), 669 !strconcat(opcStr, " $sx, $sz, $sy")>; 670} 671 672// Generic RR multiclass with an argument. 673// e.g. LDZ, PCNT, and BRV 674let cy = 0, sy = 0, hasSideEffects = 0 in 675multiclass RRI1m<string opcStr, bits<8>opc, RegisterClass RC, ValueType Ty, 676 SDPatternOperator OpNode = null_frag> { 677 def r : RR<opc, (outs RC:$sx), (ins RC:$sz), !strconcat(opcStr, " $sx, $sz"), 678 [(set Ty:$sx, (OpNode Ty:$sz))]>; 679 let cz = 0 in 680 def m : RR<opc, (outs RC:$sx), (ins mimm:$sz), 681 !strconcat(opcStr, " $sx, $sz"), 682 [(set Ty:$sx, (OpNode (Ty mimm:$sz)))]>; 683} 684 685// Special RR multiclass for MRG instruction. 686// e.g. MRG 687let Constraints = "$sx = $sd", DisableEncoding = "$sd", hasSideEffects = 0 in 688multiclass RRMRGm<string opcStr, bits<8>opc, RegisterClass RC, ValueType Ty> { 689 def rr : RR<opc, (outs RC:$sx), (ins RC:$sy, RC:$sz, RC:$sd), 690 !strconcat(opcStr, " $sx, $sy, $sz")>; 691 let cy = 0 in 692 def ir : RR<opc, (outs RC:$sx), (ins simm7:$sy, RC:$sz, RC:$sd), 693 !strconcat(opcStr, " $sx, $sy, $sz")>; 694 let cz = 0 in 695 def rm : RR<opc, (outs RC:$sx), (ins RC:$sy, mimm:$sz, RC:$sd), 696 !strconcat(opcStr, " $sx, $sy, $sz")>; 697 let cy = 0, cz = 0 in 698 def im : RR<opc, (outs RC:$sx), (ins simm7:$sy, mimm:$sz, RC:$sd), 699 !strconcat(opcStr, " $sx, $sy, $sz")>; 700} 701 702// Special RR multiclass for BSWP instruction. 703// e.g. BSWP 704let hasSideEffects = 0 in 705multiclass RRSWPm<string opcStr, bits<8>opc, 706 RegisterClass RC, ValueType Ty, 707 SDPatternOperator OpNode = null_frag> { 708 let cy = 0 in 709 def ri : RR<opc, (outs RC:$sx), (ins RC:$sz, uimm1:$sy), 710 !strconcat(opcStr, " $sx, $sz, $sy"), 711 [(set Ty:$sx, (OpNode Ty:$sz, (i32 uimm1:$sy)))]>; 712 let cy = 0, cz = 0 in 713 def mi : RR<opc, (outs RC:$sx), (ins mimm:$sz, uimm1:$sy), 714 !strconcat(opcStr, " $sx, $sz, $sy"), 715 [(set Ty:$sx, (OpNode (Ty mimm:$sz), (i32 uimm1:$sy)))]>; 716} 717 718// Multiclass for CMOV instructions. 719// e.g. CMOVL, CMOVW, CMOVD, and etc. 720let Constraints = "$sx = $sd", DisableEncoding = "$sd", hasSideEffects = 0, 721 cfw = ? in 722multiclass RRCMOVm<string opcStr, bits<8>opc, RegisterClass RC, ValueType Ty> { 723 def rr : RR<opc, (outs I64:$sx), (ins CCOp:$cfw, RC:$sy, I64:$sz, I64:$sd), 724 !strconcat(opcStr, " $sx, $sz, $sy")>; 725 let cy = 0 in 726 def ir : RR<opc, (outs I64:$sx), 727 (ins CCOp:$cfw, simm7:$sy, I64:$sz, I64:$sd), 728 !strconcat(opcStr, " $sx, $sz, $sy")>; 729 let cz = 0 in 730 def rm : RR<opc, (outs I64:$sx), 731 (ins CCOp:$cfw, RC:$sy, mimm:$sz, I64:$sd), 732 !strconcat(opcStr, " $sx, $sz, $sy")>; 733 let cy = 0, cz = 0 in 734 def im : RR<opc, (outs I64:$sx), 735 (ins CCOp:$cfw, simm7:$sy, mimm:$sz, I64:$sd), 736 !strconcat(opcStr, " $sx, $sz, $sy")>; 737} 738 739// Multiclass for floating point conversion instructions. 740// e.g. CVTWDSX, CVTWDZX, CVTWSSX, and etc. 741// sz{3-0} = rounding mode 742let cz = 0, hasSideEffects = 0 in 743multiclass CVTRDm<string opcStr, bits<8> opc, RegisterClass RCo, ValueType Tyo, 744 RegisterClass RCi, ValueType Tyi> { 745 def r : RR<opc, (outs RCo:$sx), (ins RDOp:$rd, RCi:$sy), 746 !strconcat(opcStr, "${rd} $sx, $sy")> { 747 bits<4> rd; 748 let sz{5-4} = 0; 749 let sz{3-0} = rd; 750 } 751 let cy = 0 in 752 def i : RR<opc, (outs RCo:$sx), (ins RDOp:$rd, simm7:$sy), 753 !strconcat(opcStr, "${rd} $sx, $sy")> { 754 bits<4> rd; 755 let sz{5-4} = 0; 756 let sz{3-0} = rd; 757 } 758} 759 760// Multiclass for floating point conversion instructions. 761// e.g. CVTDW, CVTSW, CVTDL, and etc. 762let cz = 0, sz = 0, hasSideEffects = 0 in 763multiclass CVTm<string opcStr, bits<8> opc, RegisterClass RCo, ValueType Tyo, 764 RegisterClass RCi, ValueType Tyi, 765 SDPatternOperator OpNode = null_frag> { 766 def r : RR<opc, (outs RCo:$sx), (ins RCi:$sy), 767 !strconcat(opcStr, " $sx, $sy"), 768 [(set Tyo:$sx, (OpNode Tyi:$sy))]>; 769 let cy = 0 in 770 def i : RR<opc, (outs RCo:$sx), (ins simm7:$sy), 771 !strconcat(opcStr, " $sx, $sy")>; 772} 773 774// Multiclass for PFCH instructions. 775// e.g. PFCH 776let sx = 0, hasSideEffects = 0 in 777multiclass PFCHm<string opcStr, bits<8>opc> { 778 def rri : RM<opc, (outs), (ins MEMrri:$addr), !strconcat(opcStr, " $addr"), 779 [(prefetch ADDRrri:$addr, imm, imm, (i32 1))]>; 780 let cy = 0 in 781 def rii : RM<opc, (outs), (ins MEMrii:$addr), !strconcat(opcStr, " $addr"), 782 [(prefetch ADDRrii:$addr, imm, imm, (i32 1))]>; 783 let cz = 0 in 784 def zri : RM<opc, (outs), (ins MEMzri:$addr), !strconcat(opcStr, " $addr"), 785 [(prefetch ADDRzri:$addr, imm, imm, (i32 1))]>; 786 let cy = 0, cz = 0 in 787 def zii : RM<opc, (outs), (ins MEMzii:$addr), !strconcat(opcStr, " $addr"), 788 [(prefetch ADDRzii:$addr, imm, imm, (i32 1))]>; 789} 790 791// Multiclass for CAS instructions. 792// e.g. TS1AML, TS1AMW, TS2AM, and etc. 793let Constraints = "$dest = $sd", DisableEncoding = "$sd", 794 mayStore=1, mayLoad = 1, hasSideEffects = 0 in 795multiclass RRCAStgm<string opcStr, bits<8>opc, RegisterClass RC, ValueType Ty, 796 Operand immOp, Operand MEM, ComplexPattern ADDR, 797 SDPatternOperator OpNode = null_frag> { 798 def r : RRM<opc, (outs RC:$dest), (ins MEM:$addr, RC:$sy, RC:$sd), 799 !strconcat(opcStr, " $dest, $addr, $sy"), 800 [(set Ty:$dest, (OpNode ADDR:$addr, Ty:$sy, Ty:$sd))]>; 801 let cy = 0 in 802 def i : RRM<opc, (outs RC:$dest), (ins MEM:$addr, immOp:$sy, RC:$sd), 803 !strconcat(opcStr, " $dest, $addr, $sy"), 804 [(set Ty:$dest, (OpNode ADDR:$addr, (Ty immOp:$sy), Ty:$sd))]>; 805} 806multiclass RRCASm<string opcStr, bits<8>opc, RegisterClass RC, ValueType Ty, 807 Operand immOp, SDPatternOperator OpNode = null_frag> { 808 defm ri : RRCAStgm<opcStr, opc, RC, Ty, immOp, MEMriRRM, ADDRri, OpNode>; 809 let cz = 0 in 810 defm zi : RRCAStgm<opcStr, opc, RC, Ty, immOp, MEMziRRM, ADDRzi, OpNode>; 811} 812 813// Multiclass for branch instructions 814// e.g. BCFL, BCFW, BCFD, and etc. 815let isBranch = 1, isTerminator = 1, isIndirectBranch = 1, hasSideEffects = 0 in 816multiclass BCbpfm<string opcStr, string cmpStr, bits<8> opc, dag cond, 817 Operand ADDR> { 818 let bpf = 0 /* NONE */ in 819 def "" : CF<opc, (outs), !con(cond, (ins ADDR:$addr)), 820 !strconcat(opcStr, " ", cmpStr, "$addr")>; 821 let bpf = 2 /* NOT TAKEN */ in 822 def _nt : CF<opc, (outs), !con(cond, (ins ADDR:$addr)), 823 !strconcat(opcStr, ".nt ", cmpStr, "$addr")>; 824 let bpf = 3 /* TAKEN */ in 825 def _t : CF<opc, (outs), !con(cond, (ins ADDR:$addr)), 826 !strconcat(opcStr, ".t ", cmpStr, "$addr")>; 827} 828multiclass BCtgm<string opcStr, string cmpStr, bits<8> opc, dag cond> { 829 defm ri : BCbpfm<opcStr, cmpStr, opc, cond, MEMriASX>; 830 let cz = 0 in defm zi : BCbpfm<opcStr, cmpStr, opc, cond, MEMziASX>; 831} 832multiclass BCm<string opcStr, string opcStrAt, string opcStrAf, bits<8> opc, 833 RegisterClass RC, Operand immOp> { 834 let DecoderMethod = "DecodeBranchCondition" in 835 defm r : BCtgm<opcStr, "$comp, ", opc, (ins CCOp:$cond, RC:$comp)>; 836 let DecoderMethod = "DecodeBranchCondition", cy = 0 in 837 defm i : BCtgm<opcStr, "$comp, ", opc, (ins CCOp:$cond, immOp:$comp)>; 838 let DecoderMethod = "DecodeBranchConditionAlways", cy = 0, sy = 0, 839 cf = 15 /* AT */, isBarrier = 1 in 840 defm a : BCtgm<opcStrAt, "", opc, (ins)>; 841 let DecoderMethod = "DecodeBranchConditionAlways", cy = 0, sy = 0, 842 cf = 0 /* AF */ in 843 defm na : BCtgm<opcStrAf, "", opc, (ins)>; 844} 845 846// Multiclass for relative branch instructions 847// e.g. BRCFL, BRCFW, BRCFD, and etc. 848let isBranch = 1, isTerminator = 1, hasSideEffects = 0 in 849multiclass BCRbpfm<string opcStr, string cmpStr, bits<8> opc, dag cond> { 850 let bpf = 0 /* NONE */ in 851 def "" : CF<opc, (outs), !con(cond, (ins brtarget32:$imm32)), 852 !strconcat(opcStr, " ", cmpStr, "$imm32")>; 853 let bpf = 2 /* NOT TAKEN */ in 854 def _nt : CF<opc, (outs), !con(cond, (ins brtarget32:$imm32)), 855 !strconcat(opcStr, ".nt ", cmpStr, "$imm32")>; 856 let bpf = 3 /* TAKEN */ in 857 def _t : CF<opc, (outs), !con(cond, (ins brtarget32:$imm32)), 858 !strconcat(opcStr, ".t ", cmpStr, "$imm32")>; 859} 860multiclass BCRm<string opcStr, string opcStrAt, string opcStrAf, bits<8> opc, 861 RegisterClass RC, Operand immOp, Operand zeroOp> { 862 defm rr : BCRbpfm<opcStr, "$sy, $sz, ", opc, (ins CCOp:$cf, RC:$sy, RC:$sz)>; 863 let cy = 0 in 864 defm ir : BCRbpfm<opcStr, "$sy, $sz, ", opc, (ins CCOp:$cf, immOp:$sy, 865 RC:$sz)>; 866 let cz = 0 in 867 defm rz : BCRbpfm<opcStr, "$sy, $sz, ", opc, (ins CCOp:$cf, RC:$sy, 868 zeroOp:$sz)>; 869 let cy = 0, cz = 0 in 870 defm iz : BCRbpfm<opcStr, "$sy, $sz, ", opc, (ins CCOp:$cf, immOp:$sy, 871 zeroOp:$sz)>; 872 let cy = 0, sy = 0, cz = 0, sz = 0, cf = 15 /* AT */, isBarrier = 1 in 873 defm a : BCRbpfm<opcStrAt, "", opc, (ins)>; 874 let cy = 0, sy = 0, cz = 0, sz = 0, cf = 0 /* AF */ in 875 defm na : BCRbpfm<opcStrAf, "", opc, (ins)>; 876} 877 878// Multiclass for communication register instructions. 879// e.g. LCR 880let hasSideEffects = 1 in 881multiclass LOADCRm<string opcStr, bits<8>opc, RegisterClass RC> { 882 def rr : RR<opc, (outs RC:$sx), (ins RC:$sz, RC:$sy), 883 !strconcat(opcStr, " $sx, $sy, $sz")>; 884 let cy = 0 in def ri : RR<opc, (outs RC:$sx), (ins RC:$sz, simm7:$sy), 885 !strconcat(opcStr, " $sx, $sy, $sz")>; 886 let cz = 0 in def zr : RR<opc, (outs RC:$sx), (ins zero:$sz, RC:$sy), 887 !strconcat(opcStr, " $sx, $sy, $sz")>; 888 let cy = 0, cz = 0 in 889 def zi : RR<opc, (outs RC:$sx), (ins zero:$sz, simm7:$sy), 890 !strconcat(opcStr, " $sx, $sy, $sz")>; 891} 892 893// Multiclass for communication register instructions. 894// e.g. SCR 895let hasSideEffects = 1 in 896multiclass STORECRm<string opcStr, bits<8>opc, RegisterClass RC> { 897 def rr : RR<opc, (outs), (ins RC:$sz, RC:$sy, RC:$sx), 898 !strconcat(opcStr, " $sx, $sy, $sz")>; 899 let cy = 0 in def ri : RR<opc, (outs), (ins RC:$sz, simm7:$sy, RC:$sx), 900 !strconcat(opcStr, " $sx, $sy, $sz")>; 901 let cz = 0 in def zr : RR<opc, (outs), (ins zero:$sz, RC:$sy, RC:$sx), 902 !strconcat(opcStr, " $sx, $sy, $sz")>; 903 let cy = 0, cz = 0 in 904 def zi : RR<opc, (outs), (ins zero:$sz, simm7:$sy, RC:$sx), 905 !strconcat(opcStr, " $sx, $sy, $sz")>; 906} 907 908// Multiclass for communication register instructions. 909// e.g. FIDCR 910let cz = 0, hasSideEffects = 1 in 911multiclass FIDCRm<string opcStr, bits<8>opc, RegisterClass RC> { 912 def ri : RR<opc, (outs RC:$sx), (ins RC:$sy, uimm3:$sz), 913 !strconcat(opcStr, " $sx, $sy, $sz")>; 914 let cy = 0 in def ii : RR<opc, (outs RC:$sx), (ins simm7:$sy, uimm3:$sz), 915 !strconcat(opcStr, " $sx, $sy, $sz")>; 916} 917 918// Multiclass for LHM instruction. 919let mayLoad = 1, hasSideEffects = 0 in 920multiclass LHMm<string opcStr, bits<8> opc, RegisterClass RC> { 921 def ri : RRMHM<opc, (outs RC:$dest), (ins MEMriHM:$addr), 922 !strconcat(opcStr, " $dest, $addr")>; 923 let cz = 0 in 924 def zi : RRMHM<opc, (outs RC:$dest), (ins MEMziHM:$addr), 925 !strconcat(opcStr, " $dest, $addr")>; 926} 927 928// Multiclass for SHM instruction. 929let mayStore = 1, hasSideEffects = 0 in 930multiclass SHMm<string opcStr, bits<8> opc, RegisterClass RC> { 931 def ri : RRMHM<opc, (outs), (ins MEMriHM:$addr, RC:$sx), 932 !strconcat(opcStr, " $sx, $addr")>; 933 let cz = 0 in 934 def zi : RRMHM<opc, (outs), (ins MEMziHM:$addr, RC:$sx), 935 !strconcat(opcStr, " $sx, $addr")>; 936} 937 938//===----------------------------------------------------------------------===// 939// Instructions 940// 941// Define all scalar instructions defined in SX-Aurora TSUBASA Architecture 942// Guide here. As those mnemonics, we use mnemonics defined in Vector Engine 943// Assembly Language Reference Manual. 944//===----------------------------------------------------------------------===// 945 946//----------------------------------------------------------------------------- 947// Section 8.2 - Load/Store instructions 948//----------------------------------------------------------------------------- 949 950// Multiclass for generic RM instructions 951multiclass RMm<string opcStr, bits<8>opc, RegisterClass RC, bit MoveImm = 0> { 952 def rri : RM<opc, (outs RC:$dest), (ins MEMrri:$addr), 953 !strconcat(opcStr, " $dest, $addr"), []>; 954 let cy = 0 in 955 def rii : RM<opc, (outs RC:$dest), (ins MEMrii:$addr), 956 !strconcat(opcStr, " $dest, $addr"), []>; 957 let cz = 0 in 958 def zri : RM<opc, (outs RC:$dest), (ins MEMzri:$addr), 959 !strconcat(opcStr, " $dest, $addr"), []>; 960 let cy = 0, cz = 0 in 961 def zii : RM<opc, (outs RC:$dest), (ins MEMzii:$addr), 962 !strconcat(opcStr, " $dest, $addr"), []> { 963 // VE uses LEAzii and LEASLzii as a move immediate instruction, so declare 964 // it here. An instruction declared as MoveImm will be optimized in 965 // FoldImmediate later. 966 let isMoveImm = MoveImm; 967 } 968} 969 970// Section 8.2.1 - LEA 971let isReMaterializable = 1, isAsCheapAsAMove = 1, 972 DecoderMethod = "DecodeLoadI64" in { 973 let cx = 0 in defm LEA : RMm<"lea", 0x06, I64, /* MoveImm */ 1>; 974 let cx = 1 in defm LEASL : RMm<"lea.sl", 0x06, I64, /* MoveImm */ 1>; 975} 976 977// LEA basic patterns. 978// Need to be defined here to prioritize LEA over ADX. 979def : Pat<(iPTR ADDRrri:$addr), (LEArri MEMrri:$addr)>; 980def : Pat<(iPTR ADDRrii:$addr), (LEArii MEMrii:$addr)>; 981def : Pat<(add I64:$base, simm32:$disp), (LEArii $base, 0, (LO32 $disp))>; 982def : Pat<(add I64:$base, lozero:$disp), (LEASLrii $base, 0, (HI32 $disp))>; 983 984// Multiclass for load instructions. 985let mayLoad = 1, hasSideEffects = 0 in 986multiclass LOADm<string opcStr, bits<8> opc, RegisterClass RC, ValueType Ty, 987 SDPatternOperator OpNode = null_frag> { 988 def rri : RM<opc, (outs RC:$dest), (ins MEMrri:$addr), 989 !strconcat(opcStr, " $dest, $addr"), 990 [(set Ty:$dest, (OpNode ADDRrri:$addr))]>; 991 let cy = 0 in 992 def rii : RM<opc, (outs RC:$dest), (ins MEMrii:$addr), 993 !strconcat(opcStr, " $dest, $addr"), 994 [(set Ty:$dest, (OpNode ADDRrii:$addr))]>; 995 let cz = 0 in 996 def zri : RM<opc, (outs RC:$dest), (ins MEMzri:$addr), 997 !strconcat(opcStr, " $dest, $addr"), 998 [(set Ty:$dest, (OpNode ADDRzri:$addr))]>; 999 let cy = 0, cz = 0 in 1000 def zii : RM<opc, (outs RC:$dest), (ins MEMzii:$addr), 1001 !strconcat(opcStr, " $dest, $addr"), 1002 [(set Ty:$dest, (OpNode ADDRzii:$addr))]>; 1003} 1004 1005// Section 8.2.2 - LDS 1006let DecoderMethod = "DecodeLoadI64" in 1007defm LD : LOADm<"ld", 0x01, I64, i64, load>; 1008def : Pat<(f64 (load ADDRrri:$addr)), (LDrri MEMrri:$addr)>; 1009def : Pat<(f64 (load ADDRrii:$addr)), (LDrii MEMrii:$addr)>; 1010def : Pat<(f64 (load ADDRzri:$addr)), (LDzri MEMzri:$addr)>; 1011def : Pat<(f64 (load ADDRzii:$addr)), (LDzii MEMzii:$addr)>; 1012 1013// Section 8.2.3 - LDU 1014let DecoderMethod = "DecodeLoadF32" in 1015defm LDU : LOADm<"ldu", 0x02, F32, f32, load>; 1016 1017// Section 8.2.4 - LDL 1018let DecoderMethod = "DecodeLoadI32" in 1019defm LDLSX : LOADm<"ldl.sx", 0x03, I32, i32, load>; 1020let cx = 1, DecoderMethod = "DecodeLoadI32" in 1021defm LDLZX : LOADm<"ldl.zx", 0x03, I32, i32, load>; 1022 1023// Section 8.2.5 - LD2B 1024let DecoderMethod = "DecodeLoadI32" in 1025defm LD2BSX : LOADm<"ld2b.sx", 0x04, I32, i32, sextloadi16>; 1026let cx = 1, DecoderMethod = "DecodeLoadI32" in 1027defm LD2BZX : LOADm<"ld2b.zx", 0x04, I32, i32, zextloadi16>; 1028 1029// Section 8.2.6 - LD1B 1030let DecoderMethod = "DecodeLoadI32" in 1031defm LD1BSX : LOADm<"ld1b.sx", 0x05, I32, i32, sextloadi8>; 1032let cx = 1, DecoderMethod = "DecodeLoadI32" in 1033defm LD1BZX : LOADm<"ld1b.zx", 0x05, I32, i32, zextloadi8>; 1034 1035// LDQ pseudo instructions 1036let mayLoad = 1, hasSideEffects = 0 in { 1037 def LDQrii : Pseudo<(outs F128:$dest), (ins MEMrii:$addr), 1038 "# pseudo ldq $dest, $addr", 1039 [(set f128:$dest, (load ADDRrii:$addr))]>; 1040} 1041 1042// Multiclass for store instructions. 1043let mayStore = 1 in 1044multiclass STOREm<string opcStr, bits<8> opc, RegisterClass RC, ValueType Ty, 1045 SDPatternOperator OpNode = null_frag> { 1046 def rri : RM<opc, (outs), (ins MEMrri:$addr, RC:$sx), 1047 !strconcat(opcStr, " $sx, $addr"), 1048 [(OpNode Ty:$sx, ADDRrri:$addr)]>; 1049 let cy = 0 in 1050 def rii : RM<opc, (outs), (ins MEMrii:$addr, RC:$sx), 1051 !strconcat(opcStr, " $sx, $addr"), 1052 [(OpNode Ty:$sx, ADDRrii:$addr)]>; 1053 let cz = 0 in 1054 def zri : RM<opc, (outs), (ins MEMzri:$addr, RC:$sx), 1055 !strconcat(opcStr, " $sx, $addr"), 1056 [(OpNode Ty:$sx, ADDRzri:$addr)]>; 1057 let cy = 0, cz = 0 in 1058 def zii : RM<opc, (outs), (ins MEMzii:$addr, RC:$sx), 1059 !strconcat(opcStr, " $sx, $addr"), 1060 [(OpNode Ty:$sx, ADDRzii:$addr)]>; 1061} 1062 1063// Section 8.2.7 - STS 1064let DecoderMethod = "DecodeStoreI64" in 1065defm ST : STOREm<"st", 0x11, I64, i64, store>; 1066def : Pat<(store f64:$src, ADDRrri:$addr), (STrri MEMrri:$addr, $src)>; 1067def : Pat<(store f64:$src, ADDRrii:$addr), (STrii MEMrii:$addr, $src)>; 1068def : Pat<(store f64:$src, ADDRzri:$addr), (STzri MEMzri:$addr, $src)>; 1069def : Pat<(store f64:$src, ADDRzii:$addr), (STzii MEMzii:$addr, $src)>; 1070 1071// Section 8.2.8 - STU 1072let DecoderMethod = "DecodeStoreF32" in 1073defm STU : STOREm<"stu", 0x12, F32, f32, store>; 1074 1075// Section 8.2.9 - STL 1076let DecoderMethod = "DecodeStoreI32" in 1077defm STL : STOREm<"stl", 0x13, I32, i32, store>; 1078 1079// Section 8.2.10 - ST2B 1080let DecoderMethod = "DecodeStoreI32" in 1081defm ST2B : STOREm<"st2b", 0x14, I32, i32, truncstorei16>; 1082 1083// Section 8.2.11 - ST1B 1084let DecoderMethod = "DecodeStoreI32" in 1085defm ST1B : STOREm<"st1b", 0x15, I32, i32, truncstorei8>; 1086 1087// STQ pseudo instructions 1088let mayStore = 1, hasSideEffects = 0 in { 1089 def STQrii : Pseudo<(outs), (ins MEMrii:$addr, F128:$sx), 1090 "# pseudo stq $sx, $addr", 1091 [(store f128:$sx, ADDRrii:$addr)]>; 1092} 1093 1094// Section 8.2.12 - DLDS 1095let DecoderMethod = "DecodeLoadI64" in 1096defm DLD : LOADm<"dld", 0x09, I64, i64, load>; 1097 1098// Section 8.2.13 - DLDU 1099let DecoderMethod = "DecodeLoadF32" in 1100defm DLDU : LOADm<"dldu", 0x0a, F32, f32, load>; 1101 1102// Section 8.2.14 - DLDL 1103let DecoderMethod = "DecodeLoadI32" in 1104defm DLDLSX : LOADm<"dldl.sx", 0x0b, I32, i32, load>; 1105let cx = 1, DecoderMethod = "DecodeLoadI32" in 1106defm DLDLZX : LOADm<"dldl.zx", 0x0b, I32, i32, load>; 1107 1108// Section 8.2.15 - PFCH 1109let DecoderMethod = "DecodeASX" in 1110defm PFCH : PFCHm<"pfch", 0x0c>; 1111 1112// Section 8.2.16 - TS1AM (Test and Set 1 AM) 1113let DecoderMethod = "DecodeTS1AMI64" in 1114defm TS1AML : RRCASm<"ts1am.l", 0x42, I64, i64, uimm7>; 1115let DecoderMethod = "DecodeTS1AMI32", cx = 1 in 1116defm TS1AMW : RRCASm<"ts1am.w", 0x42, I32, i32, uimm7>; 1117 1118// Section 8.2.17 - TS2AM (Test and Set 2 AM) 1119let DecoderMethod = "DecodeTS1AMI64" in 1120defm TS2AM : RRCASm<"ts2am", 0x43, I64, i64, uimm7>; 1121 1122// Section 8.2.18 - TS3AM (Test and Set 3 AM) 1123let DecoderMethod = "DecodeTS1AMI64" in 1124defm TS3AM : RRCASm<"ts3am", 0x52, I64, i64, uimm1>; 1125 1126// Section 8.2.19 - ATMAM (Atomic AM) 1127let DecoderMethod = "DecodeTS1AMI64" in 1128defm ATMAM : RRCASm<"atmam", 0x53, I64, i64, uimm0to2>; 1129 1130// Section 8.2.20 - CAS (Compare and Swap) 1131let DecoderMethod = "DecodeCASI64" in 1132defm CASL : RRCASm<"cas.l", 0x62, I64, i64, simm7, atomic_cmp_swap_64>; 1133let DecoderMethod = "DecodeCASI32", cx = 1 in 1134defm CASW : RRCASm<"cas.w", 0x62, I32, i32, simm7, atomic_cmp_swap_32>; 1135 1136//----------------------------------------------------------------------------- 1137// Section 8.3 - Transfer Control Instructions 1138//----------------------------------------------------------------------------- 1139 1140// Section 8.3.1 - FENCE (Fence) 1141let hasSideEffects = 1 in { 1142 let avo = 1 in def FENCEI : RRFENCE<0x20, (outs), (ins), "fencei">; 1143 def FENCEM : RRFENCE<0x20, (outs), (ins uimm2:$kind), "fencem $kind"> { 1144 bits<2> kind; 1145 let lf = kind{1}; 1146 let sf = kind{0}; 1147 } 1148 def FENCEC : RRFENCE<0x20, (outs), (ins uimm3:$kind), "fencec $kind"> { 1149 bits<3> kind; 1150 let c2 = kind{2}; 1151 let c1 = kind{1}; 1152 let c0 = kind{0}; 1153 } 1154} 1155 1156// Section 8.3.2 - SVOB (Set Vector Out-of-order memory access Boundary) 1157let sx = 0, cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 1 in 1158def SVOB : RR<0x30, (outs), (ins), "svob">; 1159 1160//----------------------------------------------------------------------------- 1161// Section 8.4 - Fixed-point Operation Instructions 1162//----------------------------------------------------------------------------- 1163 1164let isReMaterializable = 1, isAsCheapAsAMove = 1 in { 1165 1166// Section 8.4.1 - ADD (Add) 1167defm ADDUL : RRm<"addu.l", 0x48, I64, i64>; 1168let cx = 1 in defm ADDUW : RRm<"addu.w", 0x48, I32, i32>; 1169 1170// Section 8.4.2 - ADS (Add Single) 1171defm ADDSWSX : RRm<"adds.w.sx", 0x4A, I32, i32, add>; 1172let cx = 1 in defm ADDSWZX : RRm<"adds.w.zx", 0x4A, I32, i32>; 1173 1174// Section 8.4.3 - ADX (Add) 1175defm ADDSL : RRm<"adds.l", 0x59, I64, i64, add>; 1176 1177// Section 8.4.4 - SUB (Subtract) 1178defm SUBUL : RRNCm<"subu.l", 0x58, I64, i64>; 1179let cx = 1 in defm SUBUW : RRNCm<"subu.w", 0x58, I32, i32>; 1180 1181// Section 8.4.5 - SBS (Subtract Single) 1182defm SUBSWSX : RRNCm<"subs.w.sx", 0x5A, I32, i32, sub>; 1183let cx = 1 in defm SUBSWZX : RRNCm<"subs.w.zx", 0x5A, I32, i32>; 1184 1185// Section 8.4.6 - SBX (Subtract) 1186defm SUBSL : RRNCm<"subs.l", 0x5B, I64, i64, sub>; 1187 1188} // isReMaterializable, isAsCheapAsAMove 1189 1190// Section 8.4.7 - MPY (Multiply) 1191defm MULUL : RRm<"mulu.l", 0x49, I64, i64>; 1192let cx = 1 in defm MULUW : RRm<"mulu.w", 0x49, I32, i32>; 1193 1194// Section 8.4.8 - MPS (Multiply Single) 1195defm MULSWSX : RRm<"muls.w.sx", 0x4B, I32, i32, mul>; 1196let cx = 1 in defm MULSWZX : RRm<"muls.w.zx", 0x4B, I32, i32>; 1197 1198// Section 8.4.9 - MPX (Multiply) 1199defm MULSL : RRm<"muls.l", 0x6E, I64, i64, mul>; 1200 1201// Section 8.4.10 - MPD (Multiply) 1202defm MULSLW : RRbm<"muls.l.w", 0x6B, I64, i64, I32, i32>; 1203 1204// Section 8.4.11 - DIV (Divide) 1205defm DIVUL : RRNCm<"divu.l", 0x6F, I64, i64, udiv>; 1206let cx = 1 in defm DIVUW : RRNCm<"divu.w", 0x6F, I32, i32, udiv>; 1207 1208// Section 8.4.12 - DVS (Divide Single) 1209defm DIVSWSX : RRNCm<"divs.w.sx", 0x7B, I32, i32, sdiv>; 1210let cx = 1 in defm DIVSWZX : RRNCm<"divs.w.zx", 0x7B, I32, i32>; 1211 1212// Section 8.4.13 - DVX (Divide) 1213defm DIVSL : RRNCm<"divs.l", 0x7F, I64, i64, sdiv>; 1214 1215let isReMaterializable = 1, isAsCheapAsAMove = 1 in { 1216 1217// Section 8.4.14 - CMP (Compare) 1218defm CMPUL : RRNCm<"cmpu.l", 0x55, I64, i64>; 1219let cx = 1 in defm CMPUW : RRNCm<"cmpu.w", 0x55, I32, i32>; 1220 1221// Section 8.4.15 - CPS (Compare Single) 1222defm CMPSWSX : RRNCm<"cmps.w.sx", 0x7A, I32, i32>; 1223let cx = 1 in defm CMPSWZX : RRNCm<"cmps.w.zx", 0x7A, I32, i32>; 1224 1225// Section 8.4.16 - CPX (Compare) 1226defm CMPSL : RRNCm<"cmps.l", 0x6A, I64, i64>; 1227 1228// Section 8.4.17 - CMS (Compare and Select Maximum/Minimum Single) 1229// cx: sx/zx, cw: max/min 1230defm MAXSWSX : RRm<"maxs.w.sx", 0x78, I32, i32>; 1231let cx = 1 in defm MAXSWZX : RRm<"maxs.w.zx", 0x78, I32, i32>; 1232let cw = 1 in defm MINSWSX : RRm<"mins.w.sx", 0x78, I32, i32>; 1233let cx = 1, cw = 1 in defm MINSWZX : RRm<"mins.w.zx", 0x78, I32, i32>; 1234 1235// Section 8.4.18 - CMX (Compare and Select Maximum/Minimum) 1236defm MAXSL : RRm<"maxs.l", 0x68, I64, i64>; 1237let cw = 1 in defm MINSL : RRm<"mins.l", 0x68, I64, i64>; 1238 1239} // isReMaterializable, isAsCheapAsAMove 1240 1241//----------------------------------------------------------------------------- 1242// Section 8.5 - Logical Operation Instructions 1243//----------------------------------------------------------------------------- 1244 1245let isReMaterializable = 1, isAsCheapAsAMove = 1 in { 1246 1247// Section 8.5.1 - AND (AND) 1248defm AND : RRm<"and", 0x44, I64, i64, and>; 1249 1250// Section 8.5.2 - OR (OR) 1251defm OR : RRm<"or", 0x45, I64, i64, or, simm7, mimm, /* MoveImm */ 1>; 1252 1253// Section 8.5.3 - XOR (Exclusive OR) 1254defm XOR : RRm<"xor", 0x46, I64, i64, xor>; 1255 1256// Section 8.5.4 - EQV (Equivalence) 1257defm EQV : RRm<"eqv", 0x47, I64, i64>; 1258 1259} // isReMaterializable, isAsCheapAsAMove 1260 1261// Section 8.5.5 - NND (Negate AND) 1262def and_not : PatFrags<(ops node:$x, node:$y), 1263 [(and (not node:$x), node:$y)]>; 1264let isReMaterializable = 1, isAsCheapAsAMove = 1 in 1265defm NND : RRNCm<"nnd", 0x54, I64, i64, and_not>; 1266 1267// Section 8.5.6 - MRG (Merge) 1268defm MRG : RRMRGm<"mrg", 0x56, I64, i64>; 1269 1270// Section 8.5.7 - LDZ (Leading Zero Count) 1271def ctlz_pat : PatFrags<(ops node:$src), 1272 [(ctlz node:$src), 1273 (ctlz_zero_undef node:$src)]>; 1274let isReMaterializable = 1, isAsCheapAsAMove = 1 in 1275defm LDZ : RRI1m<"ldz", 0x67, I64, i64, ctlz_pat>; 1276 1277// Section 8.5.8 - PCNT (Population Count) 1278defm PCNT : RRI1m<"pcnt", 0x38, I64, i64, ctpop>; 1279 1280// Section 8.5.9 - BRV (Bit Reverse) 1281let isReMaterializable = 1, isAsCheapAsAMove = 1 in 1282defm BRV : RRI1m<"brv", 0x39, I64, i64, bitreverse>; 1283 1284// Section 8.5.10 - BSWP (Byte Swap) 1285let isReMaterializable = 1, isAsCheapAsAMove = 1 in 1286defm BSWP : RRSWPm<"bswp", 0x2B, I64, i64>; 1287 1288def : Pat<(i64 (bswap i64:$src)), 1289 (BSWPri $src, 0)>; 1290def : Pat<(i64 (bswap (i64 mimm:$src))), 1291 (BSWPmi (MIMM $src), 0)>; 1292def : Pat<(i32 (bswap i32:$src)), 1293 (EXTRACT_SUBREG 1294 (BSWPri (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $src, sub_i32), 1), 1295 sub_i32)>; 1296def : Pat<(i32 (bswap (i32 mimm:$src))), 1297 (EXTRACT_SUBREG (BSWPmi (MIMM $src), 1), sub_i32)>; 1298 1299// Section 8.5.11 - CMOV (Conditional Move) 1300let cw = 0, cw2 = 0 in defm CMOVL : RRCMOVm<"cmov.l.${cfw}", 0x3B, I64, i64>; 1301let cw = 1, cw2 = 0 in defm CMOVW : RRCMOVm<"cmov.w.${cfw}", 0x3B, I32, i32>; 1302let cw = 0, cw2 = 1 in defm CMOVD : RRCMOVm<"cmov.d.${cfw}", 0x3B, I64, f64>; 1303let cw = 1, cw2 = 1 in defm CMOVS : RRCMOVm<"cmov.s.${cfw}", 0x3B, F32, f32>; 1304def : MnemonicAlias<"cmov.l", "cmov.l.at">; 1305def : MnemonicAlias<"cmov.w", "cmov.w.at">; 1306def : MnemonicAlias<"cmov.d", "cmov.d.at">; 1307def : MnemonicAlias<"cmov.s", "cmov.s.at">; 1308 1309//----------------------------------------------------------------------------- 1310// Section 8.6 - Shift Operation Instructions 1311//----------------------------------------------------------------------------- 1312 1313// Section 8.6.1 - SLL (Shift Left Logical) 1314let isReMaterializable = 1, isAsCheapAsAMove = 1 in 1315defm SLL : RRIm<"sll", 0x65, I64, i64, shl>; 1316 1317// Section 8.6.2 - SLD (Shift Left Double) 1318defm SLD : RRILDm<"sld", 0x64, I64, i64>; 1319 1320// Section 8.6.3 - SRL (Shift Right Logical) 1321let isReMaterializable = 1, isAsCheapAsAMove = 1 in 1322defm SRL : RRIm<"srl", 0x75, I64, i64, srl>; 1323 1324// Section 8.6.4 - SRD (Shift Right Double) 1325defm SRD : RRIRDm<"srd", 0x74, I64, i64>; 1326 1327let isReMaterializable = 1, isAsCheapAsAMove = 1 in { 1328 1329// Section 8.6.5 - SLA (Shift Left Arithmetic) 1330defm SLAWSX : RRIm<"sla.w.sx", 0x66, I32, i32, shl>; 1331let cx = 1 in defm SLAWZX : RRIm<"sla.w.zx", 0x66, I32, i32>; 1332 1333// Section 8.6.6 - SLAX (Shift Left Arithmetic) 1334defm SLAL : RRIm<"sla.l", 0x57, I64, i64>; 1335 1336// Section 8.6.7 - SRA (Shift Right Arithmetic) 1337defm SRAWSX : RRIm<"sra.w.sx", 0x76, I32, i32, sra>; 1338let cx = 1 in defm SRAWZX : RRIm<"sra.w.zx", 0x76, I32, i32>; 1339 1340// Section 8.6.8 - SRAX (Shift Right Arithmetic) 1341defm SRAL : RRIm<"sra.l", 0x77, I64, i64, sra>; 1342 1343} // isReMaterializable, isAsCheapAsAMove 1344 1345def : Pat<(i32 (srl i32:$src, (i32 simm7:$val))), 1346 (EXTRACT_SUBREG (SRLri (ANDrm (INSERT_SUBREG (i64 (IMPLICIT_DEF)), 1347 $src, sub_i32), !add(32, 64)), imm:$val), sub_i32)>; 1348def : Pat<(i32 (srl i32:$src, i32:$val)), 1349 (EXTRACT_SUBREG (SRLrr (ANDrm (INSERT_SUBREG (i64 (IMPLICIT_DEF)), 1350 $src, sub_i32), !add(32, 64)), $val), sub_i32)>; 1351 1352//----------------------------------------------------------------------------- 1353// Section 8.7 - Floating-point Arithmetic Instructions 1354//----------------------------------------------------------------------------- 1355 1356// Section 8.7.1 - FAD (Floating Add) 1357defm FADDD : RRFm<"fadd.d", 0x4C, I64, f64, fadd>; 1358let cx = 1 in 1359defm FADDS : RRFm<"fadd.s", 0x4C, F32, f32, fadd, simm7fp, mimmfp32>; 1360 1361// Section 8.7.2 - FSB (Floating Subtract) 1362defm FSUBD : RRFm<"fsub.d", 0x5C, I64, f64, fsub>; 1363let cx = 1 in 1364defm FSUBS : RRFm<"fsub.s", 0x5C, F32, f32, fsub, simm7fp, mimmfp32>; 1365 1366// Section 8.7.3 - FMP (Floating Multiply) 1367defm FMULD : RRFm<"fmul.d", 0x4D, I64, f64, fmul>; 1368let cx = 1 in 1369defm FMULS : RRFm<"fmul.s", 0x4D, F32, f32, fmul, simm7fp, mimmfp32>; 1370 1371// Section 8.7.4 - FDV (Floating Divide) 1372defm FDIVD : RRFm<"fdiv.d", 0x5D, I64, f64, fdiv>; 1373let cx = 1 in 1374defm FDIVS : RRFm<"fdiv.s", 0x5D, F32, f32, fdiv, simm7fp, mimmfp32>; 1375 1376// Section 8.7.5 - FCP (Floating Compare) 1377defm FCMPD : RRFm<"fcmp.d", 0x7E, I64, f64>; 1378let cx = 1 in 1379defm FCMPS : RRFm<"fcmp.s", 0x7E, F32, f32, null_frag, simm7fp, mimmfp32>; 1380 1381// Section 8.7.6 - CMS (Compare and Select Maximum/Minimum Single) 1382// cx: double/float, cw: max/min 1383let cw = 0, cx = 0 in 1384defm FMAXD : RRFm<"fmax.d", 0x3E, I64, f64, fmaxnum>; 1385let cw = 0, cx = 1 in 1386defm FMAXS : RRFm<"fmax.s", 0x3E, F32, f32, fmaxnum, simm7fp, mimmfp32>; 1387let cw = 1, cx = 0 in 1388defm FMIND : RRFm<"fmin.d", 0x3E, I64, f64, fminnum>; 1389let cw = 1, cx = 1 in 1390defm FMINS : RRFm<"fmin.s", 0x3E, F32, f32, fminnum, simm7fp, mimmfp32>; 1391 1392// Section 8.7.7 - FAQ (Floating Add Quadruple) 1393defm FADDQ : RRFm<"fadd.q", 0x6C, F128, f128, fadd>; 1394 1395// Section 8.7.8 - FSQ (Floating Subtract Quadruple) 1396defm FSUBQ : RRFm<"fsub.q", 0x7C, F128, f128, fsub>; 1397 1398// Section 8.7.9 - FMQ (Floating Subtract Quadruple) 1399defm FMULQ : RRFm<"fmul.q", 0x6D, F128, f128, fmul>; 1400 1401// Section 8.7.10 - FCQ (Floating Compare Quadruple) 1402defm FCMPQ : RRNCbm<"fcmp.q", 0x7D, I64, f64, F128, f128, null_frag, simm7fp, 1403 mimmfp>; 1404 1405// Section 8.7.11 - FIX (Convert to Fixed Point) 1406// cx: double/float, cw: sx/zx, sz{0-3} = round 1407let cx = 0, cw = 0 /* sign extend */ in 1408defm CVTWDSX : CVTRDm<"cvt.w.d.sx", 0x4E, I32, i32, I64, f64>; 1409let cx = 0, cw = 1 /* zero extend */ in 1410defm CVTWDZX : CVTRDm<"cvt.w.d.zx", 0x4E, I32, i32, I64, f64>; 1411let cx = 1, cw = 0 /* sign extend */ in 1412defm CVTWSSX : CVTRDm<"cvt.w.s.sx", 0x4E, I32, i32, F32, f32>; 1413let cx = 1, cw = 1 /* zero extend */ in 1414defm CVTWSZX : CVTRDm<"cvt.w.s.zx", 0x4E, I32, i32, F32, f32>; 1415 1416// Section 8.7.12 - FIXX (Convert to Fixed Point) 1417defm CVTLD : CVTRDm<"cvt.l.d", 0x4F, I64, i64, I64, f64>; 1418 1419// Section 8.7.13 - FLT (Convert to Floating Point) 1420defm CVTDW : CVTm<"cvt.d.w", 0x5E, I64, f64, I32, i32, sint_to_fp>; 1421let cx = 1 in 1422defm CVTSW : CVTm<"cvt.s.w", 0x5E, F32, f32, I32, i32, sint_to_fp>; 1423 1424// Section 8.7.14 - FLTX (Convert to Floating Point) 1425defm CVTDL : CVTm<"cvt.d.l", 0x5F, I64, f64, I64, i64, sint_to_fp>; 1426 1427// Section 8.7.15 - CVS (Convert to Single-format) 1428defm CVTSD : CVTm<"cvt.s.d", 0x1F, F32, f32, I64, f64, fpround>; 1429let cx = 1 in 1430defm CVTSQ : CVTm<"cvt.s.q", 0x1F, F32, f32, F128, f128, fpround>; 1431 1432// Section 8.7.16 - CVD (Convert to Double-format) 1433defm CVTDS : CVTm<"cvt.d.s", 0x0F, I64, f64, F32, f32, fpextend>; 1434let cx = 1 in 1435defm CVTDQ : CVTm<"cvt.d.q", 0x0F, I64, f64, F128, f128, fpround>; 1436 1437// Section 8.7.17 - CVQ (Convert to Single-format) 1438defm CVTQD : CVTm<"cvt.q.d", 0x2D, F128, f128, I64, f64, fpextend>; 1439let cx = 1 in 1440defm CVTQS : CVTm<"cvt.q.s", 0x2D, F128, f128, F32, f32, fpextend>; 1441 1442//----------------------------------------------------------------------------- 1443// Section 8.8 - Branch instructions 1444//----------------------------------------------------------------------------- 1445 1446// Section 8.8.1 - BC (Branch on Codition) 1447defm BCFL : BCm<"b${cond}.l", "b.l", "baf.l", 0x19, I64, simm7>; 1448 1449// Indirect branch aliases 1450def : Pat<(brind I64:$reg), (BCFLari_t $reg, 0)>; 1451def : Pat<(brind tblockaddress:$imm), (BCFLazi_t 0, $imm)>; 1452 1453// Return instruction is a special case of jump. 1454let Uses = [SX10], bpf = 3 /* TAKEN */, cf = 15 /* AT */, cy = 0, sy = 0, 1455 sz = 10 /* SX10 */, imm32 = 0, isReturn = 1, isTerminator = 1, 1456 isBarrier = 1, isCodeGenOnly = 1, hasSideEffects = 0 in 1457def RET : CF<0x19, (outs), (ins), "b.l.t (, %s10)", [(retflag)]>; 1458 1459// Section 8.8.2 - BCS (Branch on Condition Single) 1460defm BCFW : BCm<"b${cond}.w", "b.w", "baf.w", 0x1B, I32, simm7>; 1461 1462// Section 8.8.3 - BCF (Branch on Condition Floating Point) 1463defm BCFD : BCm<"b${cond}.d", "b.d", "baf.d", 0x1C, I64, simm7fp>; 1464let cx = 1 in 1465defm BCFS : BCm<"b${cond}.s", "b.s", "baf.s", 0x1C, F32, simm7fp>; 1466 1467// Section 8.8.4 - BCR (Branch on Condition Relative) 1468let cx = 0, cx2 = 0 in 1469defm BRCFL : BCRm<"br${cf}.l", "br.l", "braf.l", 0x18, I64, simm7, zero>; 1470let cx = 1, cx2 = 0 in 1471defm BRCFW : BCRm<"br${cf}.w", "br.w", "braf.w", 0x18, I32, simm7, zero>; 1472let cx = 0, cx2 = 1 in 1473defm BRCFD : BCRm<"br${cf}.d", "br.d", "braf.d", 0x18, I64, simm7fp, zerofp>; 1474let cx = 1, cx2 = 1 in 1475defm BRCFS : BCRm<"br${cf}.s", "br.s", "braf.s", 0x18, F32, simm7fp, zerofp>; 1476 1477// Section 8.8.5 - BSIC (Branch and Save IC) 1478let isCall = 1, hasSideEffects = 0, DecoderMethod = "DecodeCall" in 1479defm BSIC : RMm<"bsic", 0x08, I64>; 1480 1481// Call instruction is a special case of BSIC. 1482let Defs = [SX10], sx = 10 /* SX10 */, cy = 0, sy = 0, imm32 = 0, 1483 isCall = 1, isCodeGenOnly = 1, hasSideEffects = 0 in 1484def CALLr : RM<0x08, (outs), (ins I64:$sz, variable_ops), 1485 "bsic %s10, (, $sz)", [(call i64:$sz)]>; 1486 1487//----------------------------------------------------------------------------- 1488// Section 8.19 - Control Instructions 1489//----------------------------------------------------------------------------- 1490 1491// Section 8.19.1 - SIC (Save Instruction Counter) 1492let cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 1, Uses = [IC] in 1493def SIC : RR<0x28, (outs I32:$sx), (ins), "sic $sx">; 1494 1495// Section 8.19.2 - LPM (Load Program Mode Flags) 1496let sx = 0, cz = 0, sz = 0, hasSideEffects = 1, Defs = [PSW] in 1497def LPM : RR<0x3a, (outs), (ins I64:$sy), "lpm $sy">; 1498 1499// Section 8.19.3 - SPM (Save Program Mode Flags) 1500let cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 1, Uses = [PSW] in 1501def SPM : RR<0x2a, (outs I64:$sx), (ins), "spm $sx">; 1502 1503// Section 8.19.4 - LFR (Load Flag Register) 1504let sx = 0, cz = 0, sz = 0, hasSideEffects = 1, Defs = [PSW] in { 1505 def LFRr : RR<0x69, (outs), (ins I64:$sy), "lfr $sy">; 1506 let cy = 0 in def LFRi : RR<0x69, (outs), (ins uimm6:$sy), "lfr $sy">; 1507} 1508 1509// Section 8.19.5 - SFR (Save Flag Register) 1510let cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 1, Uses = [PSW] in 1511def SFR : RR<0x29, (outs I64:$sx), (ins), "sfr $sx">; 1512 1513// Section 8.19.6 - SMIR (Save Miscellaneous Register) 1514let cy = 0, cz = 0, sz = 0, hasSideEffects = 1 in { 1515 def SMIR : RR<0x22, (outs I64:$sx), (ins MISC:$sy), "smir $sx, $sy">; 1516} 1517 1518// Section 8.19.7 - NOP (No Operation) 1519let sx = 0, cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 0 in 1520def NOP : RR<0x79, (outs), (ins), "nop">; 1521 1522// Section 8.19.8 - MONC (Monitor Call) 1523let sx = 0, cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 1 in { 1524 def MONC : RR<0x3F, (outs), (ins), "monc">; 1525 let cx = 1, isTrap = 1 in def MONCHDB : RR<0x3F, (outs), (ins), "monc.hdb">; 1526} 1527 1528// Section 8.19.9 - LCR (Load Communication Register) 1529defm LCR : LOADCRm<"lcr", 0x40, I64>; 1530 1531// Section 8.19.10 - SCR (Save Communication Register) 1532defm SCR : STORECRm<"scr", 0x50, I64>; 1533 1534// Section 8.19.11 - TSCR (Test & Set Communication Register) 1535defm TSCR : LOADCRm<"tscr", 0x41, I64>; 1536 1537// Section 8.19.12 - FIDCR (Fetch & Increment/Decrement CR) 1538defm FIDCR : FIDCRm<"fidcr", 0x51, I64>; 1539 1540//----------------------------------------------------------------------------- 1541// Section 8.20 - Host Memory Access Instructions 1542//----------------------------------------------------------------------------- 1543 1544// Section 8.20.1 - LHM (Load Host Memory) 1545let ry = 3, DecoderMethod = "DecodeLoadASI64" in 1546defm LHML : LHMm<"lhm.l", 0x21, I64>; 1547let ry = 2, DecoderMethod = "DecodeLoadASI64" in 1548defm LHMW : LHMm<"lhm.w", 0x21, I64>; 1549let ry = 1, DecoderMethod = "DecodeLoadASI64" in 1550defm LHMH : LHMm<"lhm.h", 0x21, I64>; 1551let ry = 0, DecoderMethod = "DecodeLoadASI64" in 1552defm LHMB : LHMm<"lhm.b", 0x21, I64>; 1553 1554// Section 8.20.2 - SHM (Store Host Memory) 1555let ry = 3, DecoderMethod = "DecodeStoreASI64" in 1556defm SHML : SHMm<"shm.l", 0x31, I64>; 1557let ry = 2, DecoderMethod = "DecodeStoreASI64" in 1558defm SHMW : SHMm<"shm.w", 0x31, I64>; 1559let ry = 1, DecoderMethod = "DecodeStoreASI64" in 1560defm SHMH : SHMm<"shm.h", 0x31, I64>; 1561let ry = 0, DecoderMethod = "DecodeStoreASI64" in 1562defm SHMB : SHMm<"shm.b", 0x31, I64>; 1563 1564//===----------------------------------------------------------------------===// 1565// Instructions for CodeGenOnly 1566//===----------------------------------------------------------------------===// 1567 1568//===----------------------------------------------------------------------===// 1569// Pattern Matchings 1570//===----------------------------------------------------------------------===// 1571 1572// Basic cast between registers. This is often used in ISel patterns, so make 1573// them as OutPatFrag. 1574def i2l : OutPatFrag<(ops node:$exp), 1575 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $exp, sub_i32)>; 1576def l2i : OutPatFrag<(ops node:$exp), 1577 (EXTRACT_SUBREG $exp, sub_i32)>; 1578def f2l : OutPatFrag<(ops node:$exp), 1579 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $exp, sub_f32)>; 1580def l2f : OutPatFrag<(ops node:$exp), 1581 (EXTRACT_SUBREG $exp, sub_f32)>; 1582 1583// Small immediates. 1584def : Pat<(i32 simm7:$val), (EXTRACT_SUBREG (ORim (LO7 $val), 0), sub_i32)>; 1585def : Pat<(i64 simm7:$val), (ORim (LO7 $val), 0)>; 1586// Medium immediates. 1587def : Pat<(i32 simm32:$val), 1588 (EXTRACT_SUBREG (LEAzii 0, 0, (LO32 $val)), sub_i32)>; 1589def : Pat<(i64 simm32:$val), (LEAzii 0, 0, (LO32 $val))>; 1590def : Pat<(i64 uimm32:$val), (ANDrm (LEAzii 0, 0, (LO32 $val)), !add(32, 64))>; 1591// Arbitrary immediates. 1592def : Pat<(i64 lozero:$val), 1593 (LEASLzii 0, 0, (HI32 imm:$val))>; 1594def : Pat<(i64 lomsbzero:$val), 1595 (LEASLrii (LEAzii 0, 0, (LO32 imm:$val)), 0, (HI32 imm:$val))>; 1596def : Pat<(i64 imm:$val), 1597 (LEASLrii (ANDrm (LEAzii 0, 0, (LO32 imm:$val)), !add(32, 64)), 0, 1598 (HI32 imm:$val))>; 1599 1600// LEA patterns 1601def lea_add : PatFrags<(ops node:$base, node:$idx, node:$disp), 1602 [(add (add node:$base, node:$idx), node:$disp), 1603 (add (add node:$base, node:$disp), node:$idx), 1604 (add node:$base, (add $idx, $disp))]>; 1605def : Pat<(lea_add I64:$base, simm7:$idx, simm32:$disp), 1606 (LEArii $base, (LO7 $idx), (LO32 $disp))>; 1607def : Pat<(lea_add I64:$base, I64:$idx, simm32:$disp), 1608 (LEArri $base, $idx, (LO32 $disp))>; 1609def : Pat<(lea_add I64:$base, simm7:$idx, lozero:$disp), 1610 (LEASLrii $base, (LO7 $idx), (HI32 $disp))>; 1611def : Pat<(lea_add I64:$base, I64:$idx, lozero:$disp), 1612 (LEASLrri $base, $idx, (HI32 $disp))>; 1613 1614// Address calculation patterns and optimizations 1615// 1616// Generate following instructions: 1617// 1. LEA %reg, label@LO32 1618// AND %reg, %reg, (32)0 1619// 2. LEASL %reg, label@HI32 1620// 3. (LEA %reg, label@LO32) 1621// (AND %reg, %reg, (32)0) 1622// LEASL %reg, label@HI32(, %reg) 1623// 4. (LEA %reg, label@LO32) 1624// (AND %reg, %reg, (32)0) 1625// LEASL %reg, label@HI32(%reg, %got) 1626// 1627def velo_only : OutPatFrag<(ops node:$lo), 1628 (ANDrm (LEAzii 0, 0, $lo), !add(32, 64))>; 1629def vehi_only : OutPatFrag<(ops node:$hi), 1630 (LEASLzii 0, 0, $hi)>; 1631def vehi_lo : OutPatFrag<(ops node:$hi, node:$lo), 1632 (LEASLrii $lo, 0, $hi)>; 1633def vehi_lo_imm : OutPatFrag<(ops node:$hi, node:$lo, node:$idx), 1634 (LEASLrii $lo, $idx, $hi)>; 1635def vehi_baselo : OutPatFrag<(ops node:$base, node:$hi, node:$lo), 1636 (LEASLrri $base, $lo, $hi)>; 1637foreach type = [ "tblockaddress", "tconstpool", "texternalsym", "tglobaladdr", 1638 "tglobaltlsaddr", "tjumptable" ] in { 1639 def : Pat<(VElo !cast<SDNode>(type):$lo), (velo_only $lo)>; 1640 def : Pat<(VEhi !cast<SDNode>(type):$hi), (vehi_only $hi)>; 1641 def : Pat<(add (VEhi !cast<SDNode>(type):$hi), I64:$lo), (vehi_lo $hi, $lo)>; 1642 def : Pat<(add (add (VEhi !cast<SDNode>(type):$hi), I64:$lo), simm7:$val), 1643 (vehi_lo_imm $hi, $lo, (LO7 $val))>; 1644 def : Pat<(add I64:$base, (add (VEhi !cast<SDNode>(type):$hi), I64:$lo)), 1645 (vehi_baselo $base, $hi, $lo)>; 1646} 1647 1648// floating point 1649def : Pat<(f32 fpimm:$val), 1650 (EXTRACT_SUBREG (LEASLzii 0, 0, (HIFP32 $val)), sub_f32)>; 1651def : Pat<(f64 fplozero:$val), 1652 (LEASLzii 0, 0, (HIFP32 $val))>; 1653def : Pat<(f64 fplomsbzero:$val), 1654 (LEASLrii (LEAzii 0, 0, (LOFP32 $val)), 0, (HIFP32 $val))>; 1655def : Pat<(f64 fpimm:$val), 1656 (LEASLrii (ANDrm (LEAzii 0, 0, (LOFP32 $val)), !add(32, 64)), 0, 1657 (HIFP32 $val))>; 1658 1659// The same integer registers are used for i32 and i64 values. 1660// When registers hold i32 values, the high bits are unused. 1661 1662// TODO Use standard expansion for shift-based lowering of sext_inreg 1663 1664// Cast to i1 1665def : Pat<(sext_inreg I32:$src, i1), 1666 (SRAWSXri (SLAWSXri $src, 31), 31)>; 1667def : Pat<(sext_inreg I64:$src, i1), 1668 (SRALri (SLLri $src, 63), 63)>; 1669 1670// Cast to i8 1671def : Pat<(sext_inreg I32:$src, i8), 1672 (SRAWSXri (SLAWSXri $src, 24), 24)>; 1673def : Pat<(sext_inreg I64:$src, i8), 1674 (SRALri (SLLri $src, 56), 56)>; 1675def : Pat<(sext_inreg (i32 (trunc i64:$src)), i8), 1676 (EXTRACT_SUBREG (SRALri (SLLri $src, 56), 56), sub_i32)>; 1677def : Pat<(i32 (and (trunc i64:$src), 0xff)), 1678 (EXTRACT_SUBREG (ANDrm $src, !add(56, 64)), sub_i32)>; 1679 1680// Cast to i16 1681def : Pat<(sext_inreg I32:$src, i16), 1682 (SRAWSXri (SLAWSXri $src, 16), 16)>; 1683def : Pat<(sext_inreg I64:$src, i16), 1684 (SRALri (SLLri $src, 48), 48)>; 1685def : Pat<(sext_inreg (i32 (trunc i64:$src)), i16), 1686 (EXTRACT_SUBREG (SRALri (SLLri $src, 48), 48), sub_i32)>; 1687def : Pat<(i32 (and (trunc i64:$src), 0xffff)), 1688 (EXTRACT_SUBREG (ANDrm $src, !add(48, 64)), sub_i32)>; 1689 1690// Cast to i32 1691def : Pat<(i32 (trunc i64:$src)), 1692 (EXTRACT_SUBREG (ANDrm $src, !add(32, 64)), sub_i32)>; 1693def : Pat<(i32 (fp_to_sint f32:$src)), (CVTWSSXr RD_RZ, $src)>; 1694def : Pat<(i32 (fp_to_sint f64:$src)), (CVTWDSXr RD_RZ, $src)>; 1695def : Pat<(i32 (fp_to_sint f128:$src)), (CVTWDSXr RD_RZ, (CVTDQr $src))>; 1696 1697// Cast to i64 1698def : Pat<(sext_inreg i64:$src, i32), 1699 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), 1700 (ADDSWSXrm (EXTRACT_SUBREG $src, sub_i32), 0), sub_i32)>; 1701def : Pat<(i64 (sext i32:$src)), 1702 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (ADDSWSXrm $src, 0), sub_i32)>; 1703def : Pat<(i64 (zext i32:$src)), 1704 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (ADDSWZXrm $src, 0), sub_i32)>; 1705def : Pat<(i64 (fp_to_sint f32:$src)), (CVTLDr RD_RZ, (CVTDSr $src))>; 1706def : Pat<(i64 (fp_to_sint f64:$src)), (CVTLDr RD_RZ, $src)>; 1707def : Pat<(i64 (fp_to_sint f128:$src)), (CVTLDr RD_RZ, (CVTDQr $src))>; 1708 1709// Cast to f32 1710def : Pat<(f32 (sint_to_fp i64:$src)), (CVTSDr (CVTDLr i64:$src))>; 1711 1712// Cast to f128 1713def : Pat<(f128 (sint_to_fp i32:$src)), (CVTQDr (CVTDWr $src))>; 1714def : Pat<(f128 (sint_to_fp i64:$src)), (CVTQDr (CVTDLr $src))>; 1715 1716def : Pat<(i64 (anyext i32:$sy)), 1717 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $sy, sub_i32)>; 1718 1719 1720// extload, sextload and zextload stuff 1721multiclass EXT64m<SDPatternOperator from, 1722 RM torri, 1723 RM torii, 1724 RM tozri, 1725 RM tozii> { 1726 def : Pat<(i64 (from ADDRrri:$addr)), 1727 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (torri MEMrri:$addr), 1728 sub_i32)>; 1729 def : Pat<(i64 (from ADDRrii:$addr)), 1730 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (torii MEMrii:$addr), 1731 sub_i32)>; 1732 def : Pat<(i64 (from ADDRzri:$addr)), 1733 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (tozri MEMzri:$addr), 1734 sub_i32)>; 1735 def : Pat<(i64 (from ADDRzii:$addr)), 1736 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (tozii MEMzii:$addr), 1737 sub_i32)>; 1738} 1739defm : EXT64m<sextloadi8, LD1BSXrri, LD1BSXrii, LD1BSXzri, LD1BSXzii>; 1740defm : EXT64m<zextloadi8, LD1BZXrri, LD1BZXrii, LD1BZXzri, LD1BZXzii>; 1741defm : EXT64m<extloadi8, LD1BZXrri, LD1BZXrii, LD1BZXzri, LD1BZXzii>; 1742defm : EXT64m<sextloadi16, LD2BSXrri, LD2BSXrii, LD2BSXzri, LD2BSXzii>; 1743defm : EXT64m<zextloadi16, LD2BZXrri, LD2BZXrii, LD2BZXzri, LD2BZXzii>; 1744defm : EXT64m<extloadi16, LD2BZXrri, LD2BZXrii, LD2BZXzri, LD2BZXzii>; 1745defm : EXT64m<sextloadi32, LDLSXrri, LDLSXrii, LDLSXzri, LDLSXzii>; 1746defm : EXT64m<zextloadi32, LDLZXrri, LDLZXrii, LDLZXzri, LDLZXzii>; 1747defm : EXT64m<extloadi32, LDLSXrri, LDLSXrii, LDLSXzri, LDLSXzii>; 1748 1749// anyextload 1750multiclass EXT32m<SDPatternOperator from, 1751 RM torri, 1752 RM torii, 1753 RM tozri, 1754 RM tozii> { 1755 def : Pat<(from ADDRrri:$addr), (torri MEMrri:$addr)>; 1756 def : Pat<(from ADDRrii:$addr), (torii MEMrii:$addr)>; 1757 def : Pat<(from ADDRzri:$addr), (tozri MEMzri:$addr)>; 1758 def : Pat<(from ADDRzii:$addr), (tozii MEMzii:$addr)>; 1759} 1760defm : EXT32m<extloadi8, LD1BZXrri, LD1BZXrii, LD1BZXzri, LD1BZXzii>; 1761defm : EXT32m<extloadi16, LD2BZXrri, LD2BZXrii, LD2BZXzri, LD2BZXzii>; 1762 1763// truncstore 1764multiclass TRUNC64m<SDPatternOperator from, 1765 RM torri, 1766 RM torii, 1767 RM tozri, 1768 RM tozii> { 1769 def : Pat<(from i64:$src, ADDRrri:$addr), 1770 (torri MEMrri:$addr, (EXTRACT_SUBREG $src, sub_i32))>; 1771 def : Pat<(from i64:$src, ADDRrii:$addr), 1772 (torii MEMrii:$addr, (EXTRACT_SUBREG $src, sub_i32))>; 1773 def : Pat<(from i64:$src, ADDRzri:$addr), 1774 (tozri MEMzri:$addr, (EXTRACT_SUBREG $src, sub_i32))>; 1775 def : Pat<(from i64:$src, ADDRzii:$addr), 1776 (tozii MEMzii:$addr, (EXTRACT_SUBREG $src, sub_i32))>; 1777} 1778defm : TRUNC64m<truncstorei8, ST1Brri, ST1Brii, ST1Bzri, ST1Bzii>; 1779defm : TRUNC64m<truncstorei16, ST2Brri, ST2Brii, ST2Bzri, ST2Bzii>; 1780defm : TRUNC64m<truncstorei32, STLrri, STLrii, STLzri, ST1Bzii>; 1781 1782// Atomic loads 1783multiclass ATMLDm<SDPatternOperator from, 1784 RM torri, RM torii, 1785 RM tozri, RM tozii> { 1786 def : Pat<(from ADDRrri:$addr), (torri MEMrri:$addr)>; 1787 def : Pat<(from ADDRrii:$addr), (torii MEMrii:$addr)>; 1788 def : Pat<(from ADDRzri:$addr), (tozri MEMzri:$addr)>; 1789 def : Pat<(from ADDRzii:$addr), (tozii MEMzii:$addr)>; 1790} 1791defm : ATMLDm<atomic_load_8, LD1BZXrri, LD1BZXrii, LD1BZXzri, LD1BZXzii>; 1792defm : ATMLDm<atomic_load_16, LD2BZXrri, LD2BZXrii, LD2BZXzri, LD2BZXzii>; 1793defm : ATMLDm<atomic_load_32, LDLZXrri, LDLZXrii, LDLZXzri, LDLZXzii>; 1794defm : ATMLDm<atomic_load_64, LDrri, LDrii, LDzri, LDzii>; 1795 1796// Optimized atomic loads with sext 1797multiclass SXATMLDm<SDPatternOperator from, ValueType TY, 1798 RM torri, RM torii, 1799 RM tozri, RM tozii> { 1800 def : Pat<(i64 (sext_inreg (i64 (anyext (from ADDRrri:$addr))), TY)), 1801 (i2l (torri MEMrri:$addr))>; 1802 def : Pat<(i64 (sext_inreg (i64 (anyext (from ADDRrii:$addr))), TY)), 1803 (i2l (torii MEMrii:$addr))>; 1804 def : Pat<(i64 (sext_inreg (i64 (anyext (from ADDRzri:$addr))), TY)), 1805 (i2l (tozri MEMzri:$addr))>; 1806 def : Pat<(i64 (sext_inreg (i64 (anyext (from ADDRzii:$addr))), TY)), 1807 (i2l (tozii MEMzii:$addr))>; 1808} 1809multiclass SXATMLD32m<SDPatternOperator from, 1810 RM torri, RM torii, 1811 RM tozri, RM tozii> { 1812 def : Pat<(i64 (sext (from ADDRrri:$addr))), 1813 (i2l (torri MEMrri:$addr))>; 1814 def : Pat<(i64 (sext (from ADDRrii:$addr))), 1815 (i2l (torii MEMrii:$addr))>; 1816 def : Pat<(i64 (sext (from ADDRzri:$addr))), 1817 (i2l (tozri MEMzri:$addr))>; 1818 def : Pat<(i64 (sext (from ADDRzii:$addr))), 1819 (i2l (tozii MEMzii:$addr))>; 1820} 1821defm : SXATMLDm<atomic_load_8, i8, LD1BSXrri, LD1BSXrii, LD1BSXzri, LD1BSXzii>; 1822defm : SXATMLDm<atomic_load_16, i16, LD2BSXrri, LD2BSXrii, LD2BSXzri, 1823 LD2BSXzii>; 1824defm : SXATMLD32m<atomic_load_32, LDLSXrri, LDLSXrii, LDLSXzri, LDLSXzii>; 1825 1826// Optimized atomic loads with zext 1827multiclass ZXATMLDm<SDPatternOperator from, int VAL, 1828 RM torri, RM torii, 1829 RM tozri, RM tozii> { 1830 def : Pat<(i64 (and (anyext (from ADDRrri:$addr)), VAL)), 1831 (i2l (torri MEMrri:$addr))>; 1832 def : Pat<(i64 (and (anyext (from ADDRrii:$addr)), VAL)), 1833 (i2l (torii MEMrii:$addr))>; 1834 def : Pat<(i64 (and (anyext (from ADDRzri:$addr)), VAL)), 1835 (i2l (tozri MEMzri:$addr))>; 1836 def : Pat<(i64 (and (anyext (from ADDRzii:$addr)), VAL)), 1837 (i2l (tozii MEMzii:$addr))>; 1838} 1839multiclass ZXATMLD32m<SDPatternOperator from, int VAL, 1840 RM torri, RM torii, 1841 RM tozri, RM tozii> { 1842 def : Pat<(i64 (zext (from ADDRrri:$addr))), 1843 (i2l (torri MEMrri:$addr))>; 1844 def : Pat<(i64 (zext (from ADDRrii:$addr))), 1845 (i2l (torii MEMrii:$addr))>; 1846 def : Pat<(i64 (zext (from ADDRzri:$addr))), 1847 (i2l (tozri MEMzri:$addr))>; 1848 def : Pat<(i64 (zext (from ADDRzii:$addr))), 1849 (i2l (tozii MEMzii:$addr))>; 1850} 1851defm : ZXATMLDm<atomic_load_8, 0xFF, LD1BZXrri, LD1BZXrii, LD1BZXzri, 1852 LD1BZXzii>; 1853defm : ZXATMLDm<atomic_load_16, 0xFFFF, LD2BZXrri, LD2BZXrii, LD2BZXzri, 1854 LD2BZXzii>; 1855defm : ZXATMLD32m<atomic_load_32, 0xFFFFFFFF, LDLZXrri, LDLZXrii, LDLZXzri, 1856 LDLZXzii>; 1857 1858// Atomic stores 1859multiclass ATMSTm<SDPatternOperator from, ValueType ty, 1860 RM torri, RM torii, 1861 RM tozri, RM tozii> { 1862 def : Pat<(from ADDRrri:$addr, ty:$src), (torri MEMrri:$addr, $src)>; 1863 def : Pat<(from ADDRrii:$addr, ty:$src), (torii MEMrii:$addr, $src)>; 1864 def : Pat<(from ADDRzri:$addr, ty:$src), (tozri MEMzri:$addr, $src)>; 1865 def : Pat<(from ADDRzii:$addr, ty:$src), (tozii MEMzii:$addr, $src)>; 1866} 1867defm : ATMSTm<atomic_store_8, i32, ST1Brri, ST1Brii, ST1Bzri, ST1Bzii>; 1868defm : ATMSTm<atomic_store_16, i32, ST2Brri, ST2Brii, ST2Bzri, ST2Bzii>; 1869defm : ATMSTm<atomic_store_32, i32, STLrri, STLrii, STLzri, STLzii>; 1870defm : ATMSTm<atomic_store_64, i64, STrri, STrii, STzri, STzii>; 1871 1872// Optimized atomic stores with truncate 1873multiclass TRATMSTm<SDPatternOperator from, 1874 ValueType ty, 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, i32, ST1Brri, ST1Brii, ST1Bzri, ST1Bzii>; 1889defm : TRATMSTm<atomic_store_16, i32, ST2Brri, ST2Brii, ST2Bzri, ST2Bzii>; 1890defm : TRATMSTm<atomic_store_32, i32, 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// Whether this is an all-true mask (assuming undef-bits above VL are all-true). 2297def true_mask : PatLeaf< 2298 (vec_broadcast (i32 nonzero), (i32 srcvalue))>; 2299// Match any broadcast (ignoring VL). 2300def any_broadcast : PatFrag<(ops node:$sx), 2301 (vec_broadcast node:$sx, (i32 srcvalue))>; 2302 2303// Vector instructions. 2304include "VEInstrVec.td" 2305 2306// The vevlintrin 2307include "VEInstrIntrinsicVL.td" 2308 2309// Patterns and intermediate SD nodes (VEC_*). 2310include "VEInstrPatternsVec.td" 2311 2312// Patterns and intermediate SD nodes (VVP_*). 2313include "VVPInstrPatternsVec.td" 2314