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