1 //===-- VEInstrInfo.td - Target Description for VE Target -----------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file describes the VE instructions in TableGen format.
11 //===----------------------------------------------------------------------===//
13 //===----------------------------------------------------------------------===//
14 // Instruction format superclass
15 //===----------------------------------------------------------------------===//
17 include "VEInstrFormats.td"
19 //===----------------------------------------------------------------------===//
20 // Helper functions to retrieve target constants.
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.
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.
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 //===----------------------------------------------------------------------===//
42 def ULO7 : SDNodeXForm<imm, [{
43 return CurDAG->getTargetConstant(N->getZExtValue() & 0x7f,
46 def LO7 : SDNodeXForm<imm, [{
47 return CurDAG->getSignedTargetConstant(SignExtend64(N->getSExtValue(), 7),
50 def MIMM : SDNodeXForm<imm, [{
51 return CurDAG->getTargetConstant(val2MImm(getImmVal(N)),
54 def LO32 : SDNodeXForm<imm, [{
55 return CurDAG->getTargetConstant(Lo_32(N->getZExtValue()),
58 def HI32 : SDNodeXForm<imm, [{
59 // Transformation function: shift the immediate value down into the low bits.
60 return CurDAG->getTargetConstant(Hi_32(N->getZExtValue()),
64 def LO7FP : SDNodeXForm<fpimm, [{
65 uint64_t Val = getFpImmVal(N);
66 return CurDAG->getTargetConstant(SignExtend32(Val, 7), SDLoc(N), MVT::i32);
68 def MIMMFP : SDNodeXForm<fpimm, [{
69 return CurDAG->getTargetConstant(val2MImm(getFpImmVal(N)),
72 def LOFP32 : SDNodeXForm<fpimm, [{
73 return CurDAG->getTargetConstant(Lo_32(getFpImmVal(N) & 0xffffffff),
76 def HIFP32 : SDNodeXForm<fpimm, [{
77 return CurDAG->getTargetConstant(Hi_32(getFpImmVal(N)), SDLoc(N), MVT::i32);
80 def icond2cc : SDNodeXForm<cond, [{
81 VECC::CondCode VECC = intCondCode2Icc(N->get());
82 return CurDAG->getTargetConstant(VECC, SDLoc(N), MVT::i32);
85 def 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);
91 def fcond2cc : SDNodeXForm<cond, [{
92 VECC::CondCode VECC = fpCondCode2Fcc(N->get());
93 return CurDAG->getTargetConstant(VECC, SDLoc(N), MVT::i32);
96 def 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);
102 def CCOP : SDNodeXForm<imm, [{
103 return CurDAG->getTargetConstant(N->getZExtValue(),
107 //===----------------------------------------------------------------------===//
108 // Feature predicates.
109 //===----------------------------------------------------------------------===//
111 //===----------------------------------------------------------------------===//
112 // Instruction Pattern Stuff
113 //===----------------------------------------------------------------------===//
116 def ZeroAsmOperand : AsmOperandClass {
119 def zero : Operand<i32>, PatLeaf<(imm), [{
120 return N->getSExtValue() == 0; }]> {
121 let ParserMatchClass = ZeroAsmOperand;
124 // uimm0to2 - Special immediate value represents 0, 1, and 2.
125 def UImm0to2AsmOperand : AsmOperandClass {
126 let Name = "UImm0to2";
128 def uimm0to2 : Operand<i32>, PatLeaf<(imm), [{
129 return N->getZExtValue() < 3; }], ULO7> {
130 let ParserMatchClass = UImm0to2AsmOperand;
133 // uimm1 - Generic immediate value.
134 def UImm1AsmOperand : AsmOperandClass {
137 def uimm1 : Operand<i32>, PatLeaf<(imm), [{
138 return isUInt<1>(N->getZExtValue()); }], ULO7> {
139 let ParserMatchClass = UImm1AsmOperand;
142 // uimm2 - Generic immediate value.
143 def UImm2AsmOperand : AsmOperandClass {
146 def uimm2 : Operand<i32>, PatLeaf<(imm), [{
147 return isUInt<2>(N->getZExtValue()); }], ULO7> {
148 let ParserMatchClass = UImm2AsmOperand;
151 // uimm3 - Generic immediate value.
152 def UImm3AsmOperand : AsmOperandClass {
155 def uimm3 : Operand<i32>, PatLeaf<(imm), [{
156 return isUInt<3>(N->getZExtValue()); }], ULO7> {
157 let ParserMatchClass = UImm3AsmOperand;
160 // uimm4 - Generic immediate value.
161 def UImm4AsmOperand : AsmOperandClass {
164 def uimm4 : Operand<i32>, PatLeaf<(imm), [{
165 return isUInt<4>(N->getZExtValue()); }], ULO7> {
166 let ParserMatchClass = UImm4AsmOperand;
169 // uimm6 - Generic immediate value.
170 def UImm6AsmOperand : AsmOperandClass {
173 def uimm6 : Operand<i32>, PatLeaf<(imm), [{
174 return isUInt<6>(N->getZExtValue()); }], ULO7> {
175 let ParserMatchClass = UImm6AsmOperand;
178 // uimm7 - Generic immediate value.
179 def UImm7AsmOperand : AsmOperandClass {
182 def uimm7 : Operand<i32>, PatLeaf<(imm), [{
183 return isUInt<7>(N->getZExtValue()); }], ULO7> {
184 let ParserMatchClass = UImm7AsmOperand;
187 // simm7 - Generic immediate value.
188 def SImm7AsmOperand : AsmOperandClass {
191 def simm7 : Operand<i32>, PatLeaf<(imm), [{
192 return isInt<7>(N->getSExtValue()); }], LO7> {
193 let ParserMatchClass = SImm7AsmOperand;
194 let DecoderMethod = "DecodeSIMM7";
197 // mimm - Special immediate value of sequential bit stream of 0 or 1.
198 def MImmAsmOperand : AsmOperandClass {
200 let ParserMethod = "parseMImmOperand";
202 def mimm : Operand<i32>, PatLeaf<(imm), [{
203 return isMImmVal(getImmVal(N)); }], MIMM> {
204 let ParserMatchClass = MImmAsmOperand;
205 let PrintMethod = "printMImmOperand";
208 // zerofp - Generic fp immediate zero value.
209 def zerofp : Operand<i32>, PatLeaf<(fpimm), [{
210 return getFpImmVal(N) == 0; }]> {
211 let ParserMatchClass = ZeroAsmOperand;
214 // simm7fp - Generic fp immediate value.
215 def simm7fp : Operand<i32>, PatLeaf<(fpimm), [{
216 return isInt<7>(getFpImmVal(N));
218 let ParserMatchClass = SImm7AsmOperand;
219 let DecoderMethod = "DecodeSIMM7";
222 // mimmfp - Special fp immediate value of sequential bit stream of 0 or 1.
223 def mimmfp : Operand<i32>, PatLeaf<(fpimm), [{
224 return isMImmVal(getFpImmVal(N)); }], MIMMFP> {
225 let ParserMatchClass = MImmAsmOperand;
226 let PrintMethod = "printMImmOperand";
229 // mimmfp32 - 32 bit width mimmfp
230 // Float value places at higher bits, so ignore lower 32 bits.
231 def mimmfp32 : Operand<i32>, PatLeaf<(fpimm), [{
232 return isMImm32Val(getFpImmVal(N) >> 32); }], MIMMFP> {
233 let ParserMatchClass = MImmAsmOperand;
234 let PrintMethod = "printMImmOperand";
237 // other generic patterns to use in pattern matchings
238 def simm32 : PatLeaf<(imm), [{ return isInt<32>(N->getSExtValue()); }]>;
239 def uimm32 : PatLeaf<(imm), [{ return isUInt<32>(N->getZExtValue()); }]>;
240 def lomsbzero : PatLeaf<(imm), [{ return (N->getZExtValue() & 0x80000000)
242 def lozero : PatLeaf<(imm), [{ return (N->getZExtValue() & 0xffffffff)
244 def fplomsbzero : PatLeaf<(fpimm), [{ return (getFpImmVal(N) & 0x80000000)
246 def fplozero : PatLeaf<(fpimm), [{ return (getFpImmVal(N) & 0xffffffff)
248 def nonzero : PatLeaf<(imm), [{ return N->getSExtValue() !=0 ; }]>;
250 def CCSIOp : PatLeaf<(cond), [{
252 default: return true;
256 case ISD::SETUGE: return false;
260 def CCUIOp : PatLeaf<(cond), [{
262 default: return true;
266 case ISD::SETGE: return false;
270 //===----------------------------------------------------------------------===//
272 // SX-Aurora has following fields.
274 // sy: register or immediate (-64 to 63)
275 // disp: immediate (-2147483648 to 2147483647)
277 // There are two kinds of instruction.
278 // ASX format uses sz + sy + disp.
279 // AS format uses sz + disp.
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)",
289 // We defined them below.
292 // MEMrri, MEMrii, MEMzri, MEMzii
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 //===----------------------------------------------------------------------===//
299 // DAG selections for both ASX and AS formats.
300 def ADDRrri : ComplexPattern<iPTR, 3, "selectADDRrri", [frameindex], []>;
301 def ADDRrii : ComplexPattern<iPTR, 3, "selectADDRrii", [frameindex], []>;
302 def ADDRzri : ComplexPattern<iPTR, 3, "selectADDRzri", [], []>;
303 def ADDRzii : ComplexPattern<iPTR, 3, "selectADDRzii", [], []>;
304 def ADDRri : ComplexPattern<iPTR, 2, "selectADDRri", [frameindex], []>;
305 def ADDRzi : ComplexPattern<iPTR, 2, "selectADDRzi", [], []>;
308 def VEMEMrriAsmOperand : AsmOperandClass {
310 let ParserMethod = "parseMEMOperand";
312 def VEMEMriiAsmOperand : AsmOperandClass {
314 let ParserMethod = "parseMEMOperand";
316 def VEMEMzriAsmOperand : AsmOperandClass {
318 let ParserMethod = "parseMEMOperand";
320 def VEMEMziiAsmOperand : AsmOperandClass {
322 let ParserMethod = "parseMEMOperand";
325 // ASX format uses single assembly instruction format.
326 def MEMrri : Operand<iPTR> {
327 let PrintMethod = "printMemASXOperand";
328 let MIOperandInfo = (ops ptr_rc, ptr_rc, i64imm);
329 let ParserMatchClass = VEMEMrriAsmOperand;
331 def MEMrii : Operand<iPTR> {
332 let PrintMethod = "printMemASXOperand";
333 let MIOperandInfo = (ops ptr_rc, i32imm, i64imm);
334 let ParserMatchClass = VEMEMriiAsmOperand;
336 def MEMzri : Operand<iPTR> {
337 let PrintMethod = "printMemASXOperand";
338 let MIOperandInfo = (ops i32imm /* = 0 */, ptr_rc, i64imm);
339 let ParserMatchClass = VEMEMzriAsmOperand;
341 def MEMzii : Operand<iPTR> {
342 let PrintMethod = "printMemASXOperand";
343 let MIOperandInfo = (ops i32imm /* = 0 */, i32imm, i64imm);
344 let ParserMatchClass = VEMEMziiAsmOperand;
348 def VEMEMriAsmOperand : AsmOperandClass {
350 let ParserMethod = "parseMEMAsOperand";
352 def VEMEMziAsmOperand : AsmOperandClass {
354 let ParserMethod = "parseMEMAsOperand";
357 // AS format uses multiple assembly instruction formats
358 // 1. AS generic assembly instruction format:
359 def MEMriASX : Operand<iPTR> {
360 let PrintMethod = "printMemASOperandASX";
361 let MIOperandInfo = (ops ptr_rc, i32imm);
362 let ParserMatchClass = VEMEMriAsmOperand;
364 def MEMziASX : Operand<iPTR> {
365 let PrintMethod = "printMemASOperandASX";
366 let MIOperandInfo = (ops i32imm /* = 0 */, i32imm);
367 let ParserMatchClass = VEMEMziAsmOperand;
370 // 2. AS RRM style assembly instruction format:
371 def MEMriRRM : Operand<iPTR> {
372 let PrintMethod = "printMemASOperandRRM";
373 let MIOperandInfo = (ops ptr_rc, i32imm);
374 let ParserMatchClass = VEMEMriAsmOperand;
376 def MEMziRRM : Operand<iPTR> {
377 let PrintMethod = "printMemASOperandRRM";
378 let MIOperandInfo = (ops i32imm /* = 0 */, i32imm);
379 let ParserMatchClass = VEMEMziAsmOperand;
382 // 3. AS HM style assembly instruction format:
383 def MEMriHM : Operand<iPTR> {
384 let PrintMethod = "printMemASOperandHM";
385 let MIOperandInfo = (ops ptr_rc, i32imm);
386 let ParserMatchClass = VEMEMriAsmOperand;
388 def MEMziHM : Operand<iPTR> {
389 let PrintMethod = "printMemASOperandHM";
390 let MIOperandInfo = (ops i32imm /* = 0 */, i32imm);
391 let ParserMatchClass = VEMEMziAsmOperand;
394 //===----------------------------------------------------------------------===//
396 //===----------------------------------------------------------------------===//
398 // Branch targets have OtherVT type.
399 def brtarget32 : Operand<OtherVT> {
400 let EncoderMethod = "getBranchTargetOpValue";
401 let DecoderMethod = "DecodeSIMM32";
404 // Operand for printing out a condition code.
405 def CCOpAsmOperand : AsmOperandClass { let Name = "CCOp"; }
406 def 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;
414 // Operand for a rounding mode code.
415 def RDOpAsmOperand : AsmOperandClass {
418 def RDOp : Operand<i32> {
419 let PrintMethod = "printRDOperand";
420 let DecoderMethod = "DecodeRDOperand";
421 let EncoderMethod = "getRDOpValue";
422 let ParserMatchClass = RDOpAsmOperand;
425 def VEhi : SDNode<"VEISD::Hi", SDTIntUnaryOp>;
426 def VElo : SDNode<"VEISD::Lo", SDTIntUnaryOp>;
428 // These are target-independent nodes, but have target-specific formats.
429 def SDT_SPCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i64>,
431 def SDT_SPCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i64>,
434 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPCallSeqStart,
435 [SDNPHasChain, SDNPOutGlue]>;
436 def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SPCallSeqEnd,
437 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
439 def SDT_SPCall : SDTypeProfile<0, -1, [SDTCisVT<0, i64>]>;
440 def call : SDNode<"VEISD::CALL", SDT_SPCall,
441 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
444 def retglue : SDNode<"VEISD::RET_GLUE", SDTNone,
445 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
447 def getGOT : Operand<iPTR>;
450 def cmpi : SDNode<"VEISD::CMPI", SDTIntBinOp>;
451 def cmpu : SDNode<"VEISD::CMPU", SDTIntBinOp>;
452 def cmpf : SDNode<"VEISD::CMPF", SDTFPBinOp>;
453 def SDT_Cmpq : SDTypeProfile<1, 2, [SDTCisSameAs<1, 2>, SDTCisFP<0>,
455 def cmpq : SDNode<"VEISD::CMPQ", SDT_Cmpq>;
457 // res = cmov cmp, t, f, cond
458 def SDT_Cmov : SDTypeProfile<1, 4, [SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>,
460 def cmov : SDNode<"VEISD::CMOV", SDT_Cmov>;
462 def VEeh_sjlj_setjmp: SDNode<"VEISD::EH_SJLJ_SETJMP",
463 SDTypeProfile<1, 1, [SDTCisInt<0>,
465 [SDNPHasChain, SDNPSideEffect]>;
466 def VEeh_sjlj_longjmp: SDNode<"VEISD::EH_SJLJ_LONGJMP",
467 SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>,
468 [SDNPHasChain, SDNPSideEffect]>;
469 def VEeh_sjlj_setup_dispatch: SDNode<"VEISD::EH_SJLJ_SETUP_DISPATCH",
470 SDTypeProfile<0, 0, []>,
471 [SDNPHasChain, SDNPSideEffect]>;
474 def GetFunPLT : SDNode<"VEISD::GETFUNPLT", SDTIntUnaryOp>;
476 // GETTLSADDR for TLS
477 def GetTLSAddr : SDNode<"VEISD::GETTLSADDR", SDT_SPCall,
478 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
482 def GetStackTop : SDNode<"VEISD::GETSTACKTOP", SDTNone,
483 [SDNPHasChain, SDNPSideEffect]>;
486 def SDT_TS1AM : SDTypeProfile<1, 3, [SDTCisSameAs<0, 3>, SDTCisPtrTy<1>,
487 SDTCisVT<2, i32>, SDTCisInt<3>]>;
488 def ts1am : SDNode<"VEISD::TS1AM", SDT_TS1AM,
489 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
492 //===----------------------------------------------------------------------===//
493 // VE Flag Conditions
494 //===----------------------------------------------------------------------===//
496 // Note that these values must be kept in sync with the CCOp::CondCode enum
498 class CC_VAL<int N> : PatLeaf<(i32 N)>;
499 def CC_IG : CC_VAL< 0>; // Greater
500 def CC_IL : CC_VAL< 1>; // Less
501 def CC_INE : CC_VAL< 2>; // Not Equal
502 def CC_IEQ : CC_VAL< 3>; // Equal
503 def CC_IGE : CC_VAL< 4>; // Greater or Equal
504 def CC_ILE : CC_VAL< 5>; // Less or Equal
505 def CC_AF : CC_VAL< 6>; // Always false
506 def CC_G : CC_VAL< 7>; // Greater
507 def CC_L : CC_VAL< 8>; // Less
508 def CC_NE : CC_VAL< 9>; // Not Equal
509 def CC_EQ : CC_VAL<10>; // Equal
510 def CC_GE : CC_VAL<11>; // Greater or Equal
511 def CC_LE : CC_VAL<12>; // Less or Equal
512 def CC_NUM : CC_VAL<13>; // Number
513 def CC_NAN : CC_VAL<14>; // NaN
514 def CC_GNAN : CC_VAL<15>; // Greater or NaN
515 def CC_LNAN : CC_VAL<16>; // Less or NaN
516 def CC_NENAN : CC_VAL<17>; // Not Equal or NaN
517 def CC_EQNAN : CC_VAL<18>; // Equal or NaN
518 def CC_GENAN : CC_VAL<19>; // Greater or Equal or NaN
519 def CC_LENAN : CC_VAL<20>; // Less or Equal or NaN
520 def CC_AT : CC_VAL<21>; // Always true
522 //===----------------------------------------------------------------------===//
524 //===----------------------------------------------------------------------===//
526 // Note that these values must be kept in sync with the VERD::RoundingMode enum
528 class RD_VAL<int N> : PatLeaf<(i32 N)>;
529 def RD_NONE : RD_VAL< 0>; // According to PSW
530 def RD_RZ : RD_VAL< 8>; // Round toward Zero
531 def RD_RP : RD_VAL< 9>; // Round toward Plus infinity
532 def RD_RM : RD_VAL<10>; // Round toward Minus infinity
533 def RD_RN : RD_VAL<11>; // Round to Nearest (ties to Even)
534 def RD_RA : RD_VAL<12>; // Round to Nearest (ties to Away)
536 //===----------------------------------------------------------------------===//
537 // VE Multiclasses for common instruction formats
538 //===----------------------------------------------------------------------===//
540 // Multiclass for generic RR type instructions
541 let hasSideEffects = 0 in
542 multiclass 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,
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.
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)))]>;
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
568 let isMoveImm = MoveImm;
572 // Multiclass for non-commutative RR type instructions
573 let hasSideEffects = 0 in
574 multiclass 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))]>;
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))]>;
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)))]>;
596 // Generic RR multiclass with 2 arguments.
597 // e.g. ADDUL, ADDSWSX, ADDSWZX, and etc.
598 multiclass 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>;
604 // Generic RR multiclass for non-commutative instructions with 2 arguments.
605 // e.g. SUBUL, SUBUW, SUBSWSX, and etc.
606 multiclass 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>;
612 // Generic RR multiclass for floating point instructions with 2 arguments.
613 // e.g. FADDD, FADDS, FSUBD, and etc.
614 multiclass 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>;
620 // Generic RR multiclass for shift instructions with 2 arguments.
621 // e.g. SLL, SRL, SLAWSX, and etc.
622 let hasSideEffects = 0 in
623 multiclass 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))]>;
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))]>;
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)))]>;
643 // Special RR multiclass for 128 bits shift left instruction.
645 let Constraints = "$hi = $sx", DisableEncoding = "$hi", hasSideEffects = 0 in
646 multiclass 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")>;
650 def rmr : RR<opc, (outs RC:$sx), (ins RC:$hi, mimm:$sz, I32:$sy),
651 !strconcat(opcStr, " $sx, $sz, $sy")>;
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")>;
660 // Special RR multiclass for 128 bits shift right instruction.
662 let Constraints = "$low = $sx", DisableEncoding = "$low", hasSideEffects = 0 in
663 multiclass 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")>;
667 def mrr : RR<opc, (outs RC:$sx), (ins mimm:$sz, RC:$low, I32:$sy),
668 !strconcat(opcStr, " $sx, $sz, $sy")>;
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")>;
677 // Generic RR multiclass with an argument.
678 // e.g. LDZ, PCNT, and BRV
679 let cy = 0, sy = 0, hasSideEffects = 0 in
680 multiclass 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))]>;
685 def m : RR<opc, (outs RC:$sx), (ins mimm:$sz),
686 !strconcat(opcStr, " $sx, $sz"),
687 [(set Ty:$sx, (OpNode (Ty mimm:$sz)))]>;
690 // Special RR multiclass for MRG instruction.
692 let Constraints = "$sx = $sd", DisableEncoding = "$sd", hasSideEffects = 0 in
693 multiclass 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")>;
697 def ir : RR<opc, (outs RC:$sx), (ins simm7:$sy, RC:$sz, RC:$sd),
698 !strconcat(opcStr, " $sx, $sy, $sz")>;
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")>;
707 // Special RR multiclass for BSWP instruction.
709 let hasSideEffects = 0 in
710 multiclass RRSWPm<string opcStr, bits<8>opc,
711 RegisterClass RC, ValueType Ty,
712 SDPatternOperator OpNode = null_frag> {
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)))]>;
723 // Multiclass for CMOV instructions.
724 // e.g. CMOVL, CMOVW, CMOVD, and etc.
725 let Constraints = "$sx = $sd", DisableEncoding = "$sd", hasSideEffects = 0,
727 multiclass 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,
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,
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,
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,
754 // Multiclass for floating point conversion instructions.
755 // e.g. CVTWDSX, CVTWDZX, CVTWSSX, and etc.
756 // sz{3-0} = rounding mode
757 let cz = 0, hasSideEffects = 0 in
758 multiclass CVTRDm<string opcStr, bits<8> opc, RegisterClass RCo,
760 def r : RR<opc, (outs RCo:$sx), (ins RDOp:$rd, RCi:$sy),
761 !strconcat(opcStr, "${rd} $sx, $sy")> {
767 def i : RR<opc, (outs RCo:$sx), (ins RDOp:$rd, simm7:$sy),
768 !strconcat(opcStr, "${rd} $sx, $sy")> {
775 // Multiclass for floating point conversion instructions.
776 // e.g. CVTDW, CVTSW, CVTDL, and etc.
777 let cz = 0, sz = 0, hasSideEffects = 0 in
778 multiclass 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))]>;
785 def i : RR<opc, (outs RCo:$sx), (ins simm7:$sy),
786 !strconcat(opcStr, " $sx, $sy")>;
789 // Multiclass for PFCH instructions.
791 let sx = 0, hasSideEffects = 0 in
792 multiclass 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))]>;
796 def rii : RM<opc, (outs), (ins (MEMrii $sz, $sy, $imm32):$addr), !strconcat(opcStr, " $addr"),
797 [(prefetch ADDRrii:$addr, imm, imm, (i32 1))]>;
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))]>;
806 // Multiclass for CAS instructions.
807 // e.g. TS1AML, TS1AMW, TS2AM, and etc.
808 let Constraints = "$sx = $sd", DisableEncoding = "$sd",
809 mayStore=1, mayLoad = 1, hasSideEffects = 0 in
810 multiclass 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))]>;
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))]>;
821 multiclass 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>;
825 defm zi : RRCAStgm<opcStr, opc, RC, Ty, immOp, MEMziRRM, ADDRzi, OpNode>;
828 // Multiclass for branch instructions
829 // e.g. BCFL, BCFW, BCFD, and etc.
830 let isBranch = 1, isTerminator = 1, isIndirectBranch = 1, hasSideEffects = 0 in
831 multiclass BCbpfm<string opcStr, string cmpStr, bits<8> opc, dag cond,
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")>;
843 multiclass 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>;
847 multiclass 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,
858 defm na : BCtgm<opcStrAf, "", opc, (ins)>;
861 // Multiclass for relative branch instructions
862 // e.g. BRCFL, BRCFW, BRCFD, and etc.
863 let isBranch = 1, isTerminator = 1, hasSideEffects = 0 in
864 multiclass 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")>;
875 multiclass 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)>;
879 defm ir : BCRbpfm<opcStr, "$sy, $sz, ", opc, (ins CCOp:$cond, immOp:$sy,
882 defm rz : BCRbpfm<opcStr, "$sy, $sz, ", opc, (ins CCOp:$cond, RC:$sy,
884 let cy = 0, cz = 0 in
885 defm iz : BCRbpfm<opcStr, "$sy, $sz, ", opc, (ins CCOp:$cond, immOp:$sy,
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)>;
893 // Multiclass for communication register instructions.
895 let hasSideEffects = 1 in
896 multiclass 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")>;
908 // Multiclass for communication register instructions.
910 let hasSideEffects = 1 in
911 multiclass 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")>;
923 let hasSideEffects = 1, Constraints = "$sx = $sx_in", DisableEncoding = "$sx_in" in
924 multiclass 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")>;
937 // Multiclass for communication register instructions.
939 let cz = 0, hasSideEffects = 1 in
940 multiclass 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")>;
947 // Multiclass for LHM instruction.
948 let mayLoad = 1, hasSideEffects = 0 in
949 multiclass 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")>;
953 def zi : RRMHM<opc, (outs RC:$sx), (ins (MEMziHM $sz, $imm32):$addr),
954 !strconcat(opcStr, " $sx, $addr")>;
957 // Multiclass for SHM instruction.
958 let mayStore = 1, hasSideEffects = 0 in
959 multiclass 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")>;
963 def zi : RRMHM<opc, (outs), (ins (MEMziHM $sz, $imm32):$addr, RC:$sx),
964 !strconcat(opcStr, " $sx, $addr")>;
967 //===----------------------------------------------------------------------===//
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 //===----------------------------------------------------------------------===//
975 //-----------------------------------------------------------------------------
976 // Section 8.2 - Load/Store instructions
977 //-----------------------------------------------------------------------------
979 // Multiclass for generic RM instructions
980 multiclass 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"), []>;
984 def rii : RM<opc, (outs RC:$sx), (ins (MEMrii $sz, $sy, $imm32):$addr),
985 !strconcat(opcStr, " $sx, $addr"), []>;
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;
999 // Section 8.2.1 - LEA
1000 let 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>;
1006 // LEA basic patterns.
1007 // Need to be defined here to prioritize LEA over ADX.
1008 def : Pat<(iPTR ADDRrri:$addr), (LEArri MEMrri:$addr)>;
1009 def : Pat<(iPTR ADDRrii:$addr), (LEArii MEMrii:$addr)>;
1010 def : Pat<(add I64:$base, simm32:$disp), (LEArii $base, 0, (LO32 $disp))>;
1011 def : Pat<(add I64:$base, lozero:$disp), (LEASLrii $base, 0, (HI32 $disp))>;
1013 // Multiclass for load instructions.
1014 let mayLoad = 1, hasSideEffects = 0 in
1015 multiclass 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))]>;
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))]>;
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))]>;
1034 // Section 8.2.2 - LDS
1035 let DecoderMethod = "DecodeLoadI64" in
1036 defm LD : LOADm<"ld", 0x01, I64, i64, load>;
1037 def : Pat<(f64 (load ADDRrri:$addr)), (LDrri MEMrri:$addr)>;
1038 def : Pat<(f64 (load ADDRrii:$addr)), (LDrii MEMrii:$addr)>;
1039 def : Pat<(f64 (load ADDRzri:$addr)), (LDzri MEMzri:$addr)>;
1040 def : Pat<(f64 (load ADDRzii:$addr)), (LDzii MEMzii:$addr)>;
1042 // Section 8.2.3 - LDU
1043 let DecoderMethod = "DecodeLoadF32" in
1044 defm LDU : LOADm<"ldu", 0x02, F32, f32, load>;
1046 // Section 8.2.4 - LDL
1047 let DecoderMethod = "DecodeLoadI32" in
1048 defm LDLSX : LOADm<"ldl.sx", 0x03, I32, i32, load>;
1049 let cx = 1, DecoderMethod = "DecodeLoadI32" in
1050 defm LDLZX : LOADm<"ldl.zx", 0x03, I32, i32, load>;
1052 // Section 8.2.5 - LD2B
1053 let DecoderMethod = "DecodeLoadI32" in
1054 defm LD2BSX : LOADm<"ld2b.sx", 0x04, I32, i32, sextloadi16>;
1055 let cx = 1, DecoderMethod = "DecodeLoadI32" in
1056 defm LD2BZX : LOADm<"ld2b.zx", 0x04, I32, i32, zextloadi16>;
1058 // Section 8.2.6 - LD1B
1059 let DecoderMethod = "DecodeLoadI32" in
1060 defm LD1BSX : LOADm<"ld1b.sx", 0x05, I32, i32, sextloadi8>;
1061 let cx = 1, DecoderMethod = "DecodeLoadI32" in
1062 defm LD1BZX : LOADm<"ld1b.zx", 0x05, I32, i32, zextloadi8>;
1064 // LDQ pseudo instructions
1065 let 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))]>;
1071 // Multiclass for store instructions.
1073 multiclass 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)]>;
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)]>;
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)]>;
1092 // Section 8.2.7 - STS
1093 let DecoderMethod = "DecodeStoreI64" in
1094 defm ST : STOREm<"st", 0x11, I64, i64, store>;
1095 def : Pat<(store f64:$src, ADDRrri:$addr), (STrri MEMrri:$addr, $src)>;
1096 def : Pat<(store f64:$src, ADDRrii:$addr), (STrii MEMrii:$addr, $src)>;
1097 def : Pat<(store f64:$src, ADDRzri:$addr), (STzri MEMzri:$addr, $src)>;
1098 def : Pat<(store f64:$src, ADDRzii:$addr), (STzii MEMzii:$addr, $src)>;
1100 // Section 8.2.8 - STU
1101 let DecoderMethod = "DecodeStoreF32" in
1102 defm STU : STOREm<"stu", 0x12, F32, f32, store>;
1104 // Section 8.2.9 - STL
1105 let DecoderMethod = "DecodeStoreI32" in
1106 defm STL : STOREm<"stl", 0x13, I32, i32, store>;
1108 // Section 8.2.10 - ST2B
1109 let DecoderMethod = "DecodeStoreI32" in
1110 defm ST2B : STOREm<"st2b", 0x14, I32, i32, truncstorei16>;
1112 // Section 8.2.11 - ST1B
1113 let DecoderMethod = "DecodeStoreI32" in
1114 defm ST1B : STOREm<"st1b", 0x15, I32, i32, truncstorei8>;
1116 // STQ pseudo instructions
1117 let 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)]>;
1123 // Section 8.2.12 - DLDS
1124 let DecoderMethod = "DecodeLoadI64" in
1125 defm DLD : LOADm<"dld", 0x09, I64, i64, load>;
1127 // Section 8.2.13 - DLDU
1128 let DecoderMethod = "DecodeLoadF32" in
1129 defm DLDU : LOADm<"dldu", 0x0a, F32, f32, load>;
1131 // Section 8.2.14 - DLDL
1132 let DecoderMethod = "DecodeLoadI32" in
1133 defm DLDLSX : LOADm<"dldl.sx", 0x0b, I32, i32, load>;
1134 let cx = 1, DecoderMethod = "DecodeLoadI32" in
1135 defm DLDLZX : LOADm<"dldl.zx", 0x0b, I32, i32, load>;
1137 // Section 8.2.15 - PFCH
1138 let DecoderMethod = "DecodeASX" in
1139 defm PFCH : PFCHm<"pfch", 0x0c>;
1141 // Section 8.2.16 - TS1AM (Test and Set 1 AM)
1142 let DecoderMethod = "DecodeTS1AMI64" in
1143 defm TS1AML : RRCASm<"ts1am.l", 0x42, I64, i64, uimm7>;
1144 let DecoderMethod = "DecodeTS1AMI32", cx = 1 in
1145 defm TS1AMW : RRCASm<"ts1am.w", 0x42, I32, i32, uimm7>;
1147 // Section 8.2.17 - TS2AM (Test and Set 2 AM)
1148 let DecoderMethod = "DecodeTS1AMI64" in
1149 defm TS2AM : RRCASm<"ts2am", 0x43, I64, i64, uimm7>;
1151 // Section 8.2.18 - TS3AM (Test and Set 3 AM)
1152 let DecoderMethod = "DecodeTS1AMI64" in
1153 defm TS3AM : RRCASm<"ts3am", 0x52, I64, i64, uimm1>;
1155 // Section 8.2.19 - ATMAM (Atomic AM)
1156 let DecoderMethod = "DecodeTS1AMI64" in
1157 defm ATMAM : RRCASm<"atmam", 0x53, I64, i64, uimm0to2>;
1159 // Section 8.2.20 - CAS (Compare and Swap)
1160 let DecoderMethod = "DecodeCASI64" in
1161 defm CASL : RRCASm<"cas.l", 0x62, I64, i64, simm7, atomic_cmp_swap_i64>;
1162 let DecoderMethod = "DecodeCASI32", cx = 1 in
1163 defm CASW : RRCASm<"cas.w", 0x62, I32, i32, simm7, atomic_cmp_swap_i32>;
1165 //-----------------------------------------------------------------------------
1166 // Section 8.3 - Transfer Control Instructions
1167 //-----------------------------------------------------------------------------
1169 // Section 8.3.1 - FENCE (Fence)
1170 let 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"> {
1177 def FENCEC : RRFENCE<0x20, (outs), (ins uimm3:$kind), "fencec $kind"> {
1185 // Section 8.3.2 - SVOB (Set Vector Out-of-order memory access Boundary)
1186 let sx = 0, cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 1 in
1187 def SVOB : RR<0x30, (outs), (ins), "svob">;
1189 //-----------------------------------------------------------------------------
1190 // Section 8.4 - Fixed-point Operation Instructions
1191 //-----------------------------------------------------------------------------
1193 // Section 8.4.1 - ADD (Add)
1194 defm ADDUL : RRm<"addu.l", 0x48, I64, i64>;
1195 let cx = 1 in defm ADDUW : RRm<"addu.w", 0x48, I32, i32>;
1197 // Section 8.4.2 - ADS (Add Single)
1198 defm ADDSWSX : RRm<"adds.w.sx", 0x4A, I32, i32, add>;
1199 let cx = 1 in defm ADDSWZX : RRm<"adds.w.zx", 0x4A, I32, i32>;
1201 // Section 8.4.3 - ADX (Add)
1202 defm ADDSL : RRm<"adds.l", 0x59, I64, i64, add>;
1204 // Section 8.4.4 - SUB (Subtract)
1205 defm SUBUL : RRNCm<"subu.l", 0x58, I64, i64>;
1206 let cx = 1 in defm SUBUW : RRNCm<"subu.w", 0x58, I32, i32>;
1208 // Section 8.4.5 - SBS (Subtract Single)
1209 defm SUBSWSX : RRNCm<"subs.w.sx", 0x5A, I32, i32, sub>;
1210 let cx = 1 in defm SUBSWZX : RRNCm<"subs.w.zx", 0x5A, I32, i32>;
1212 // Section 8.4.6 - SBX (Subtract)
1213 defm SUBSL : RRNCm<"subs.l", 0x5B, I64, i64, sub>;
1215 // Section 8.4.7 - MPY (Multiply)
1216 defm MULUL : RRm<"mulu.l", 0x49, I64, i64>;
1217 let cx = 1 in defm MULUW : RRm<"mulu.w", 0x49, I32, i32>;
1219 // Section 8.4.8 - MPS (Multiply Single)
1220 defm MULSWSX : RRm<"muls.w.sx", 0x4B, I32, i32, mul>;
1221 let cx = 1 in defm MULSWZX : RRm<"muls.w.zx", 0x4B, I32, i32>;
1223 // Section 8.4.9 - MPX (Multiply)
1224 defm MULSL : RRm<"muls.l", 0x6E, I64, i64, mul>;
1226 // Section 8.4.10 - MPD (Multiply)
1227 defm MULSLW : RRbm<"muls.l.w", 0x6B, I64, i64, I32, i32>;
1229 // Section 8.4.11 - DIV (Divide)
1230 defm DIVUL : RRNCm<"divu.l", 0x6F, I64, i64, udiv>;
1231 let cx = 1 in defm DIVUW : RRNCm<"divu.w", 0x6F, I32, i32, udiv>;
1233 // Section 8.4.12 - DVS (Divide Single)
1234 defm DIVSWSX : RRNCm<"divs.w.sx", 0x7B, I32, i32, sdiv>;
1235 let cx = 1 in defm DIVSWZX : RRNCm<"divs.w.zx", 0x7B, I32, i32>;
1237 // Section 8.4.13 - DVX (Divide)
1238 defm DIVSL : RRNCm<"divs.l", 0x7F, I64, i64, sdiv>;
1240 // Section 8.4.14 - CMP (Compare)
1241 defm CMPUL : RRNCm<"cmpu.l", 0x55, I64, i64, cmpu>;
1242 let cx = 1 in defm CMPUW : RRNCm<"cmpu.w", 0x55, I32, i32, cmpu>;
1244 // Section 8.4.15 - CPS (Compare Single)
1245 defm CMPSWSX : RRNCm<"cmps.w.sx", 0x7A, I32, i32>;
1246 let cx = 1 in defm CMPSWZX : RRNCm<"cmps.w.zx", 0x7A, I32, i32, cmpi>;
1248 // Section 8.4.16 - CPX (Compare)
1249 defm CMPSL : RRNCm<"cmps.l", 0x6A, I64, i64, cmpi>;
1251 // Section 8.4.17 - CMS (Compare and Select Maximum/Minimum Single)
1252 // cx: sx/zx, cw: max/min
1253 defm MAXSWSX : RRm<"maxs.w.sx", 0x78, I32, i32, smax>;
1254 let cx = 1 in defm MAXSWZX : RRm<"maxs.w.zx", 0x78, I32, i32>;
1255 let cw = 1 in defm MINSWSX : RRm<"mins.w.sx", 0x78, I32, i32, smin>;
1256 let cx = 1, cw = 1 in defm MINSWZX : RRm<"mins.w.zx", 0x78, I32, i32>;
1258 // Section 8.4.18 - CMX (Compare and Select Maximum/Minimum)
1259 defm MAXSL : RRm<"maxs.l", 0x68, I64, i64, smax>;
1260 let cw = 1 in defm MINSL : RRm<"mins.l", 0x68, I64, i64, smin>;
1262 //-----------------------------------------------------------------------------
1263 // Section 8.5 - Logical Operation Instructions
1264 //-----------------------------------------------------------------------------
1266 // Section 8.5.1 - AND (AND)
1267 defm AND : RRm<"and", 0x44, I64, i64, and>;
1269 // Section 8.5.2 - OR (OR)
1270 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1271 defm OR : RRm<"or", 0x45, I64, i64, or, simm7, mimm, /* MoveImm */ 1>;
1273 // Section 8.5.3 - XOR (Exclusive OR)
1274 defm XOR : RRm<"xor", 0x46, I64, i64, xor>;
1276 // Section 8.5.4 - EQV (Equivalence)
1277 defm EQV : RRm<"eqv", 0x47, I64, i64>;
1279 // Section 8.5.5 - NND (Negate AND)
1280 def and_not : PatFrags<(ops node:$x, node:$y),
1281 [(and (not node:$x), node:$y)]>;
1282 defm NND : RRNCm<"nnd", 0x54, I64, i64, and_not>;
1284 // Section 8.5.6 - MRG (Merge)
1285 defm MRG : RRMRGm<"mrg", 0x56, I64>;
1287 // Section 8.5.7 - LDZ (Leading Zero Count)
1288 def ctlz_pat : PatFrags<(ops node:$src),
1290 (ctlz_zero_undef node:$src)]>;
1291 defm LDZ : RRI1m<"ldz", 0x67, I64, i64, ctlz_pat>;
1293 // Section 8.5.8 - PCNT (Population Count)
1294 defm PCNT : RRI1m<"pcnt", 0x38, I64, i64, ctpop>;
1296 // Section 8.5.9 - BRV (Bit Reverse)
1297 defm BRV : RRI1m<"brv", 0x39, I64, i64, bitreverse>;
1299 // Section 8.5.10 - BSWP (Byte Swap)
1300 defm BSWP : RRSWPm<"bswp", 0x2B, I64, i64>;
1302 def : Pat<(i64 (bswap i64:$src)),
1304 def : Pat<(i64 (bswap (i64 mimm:$src))),
1305 (BSWPmi (MIMM $src), 0)>;
1306 def : Pat<(i32 (bswap i32:$src)),
1308 (BSWPri (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $src, sub_i32), 1),
1310 def : Pat<(i32 (bswap (i32 mimm:$src))),
1311 (EXTRACT_SUBREG (BSWPmi (MIMM $src), 1), sub_i32)>;
1313 // Section 8.5.11 - CMOV (Conditional Move)
1314 let cw = 0, cw2 = 0 in
1315 defm CMOVL : RRCMOVm<"cmov.l.${cfw}", 0x3B, I64, i64, cmov>;
1316 let cw = 1, cw2 = 0 in
1317 defm CMOVW : RRCMOVm<"cmov.w.${cfw}", 0x3B, I32, i32, cmov>;
1318 let cw = 0, cw2 = 1 in
1319 defm CMOVD : RRCMOVm<"cmov.d.${cfw}", 0x3B, I64, f64, cmov, simm7fp>;
1320 let cw = 1, cw2 = 1 in
1321 defm CMOVS : RRCMOVm<"cmov.s.${cfw}", 0x3B, F32, f32, cmov, simm7fp>;
1322 def : MnemonicAlias<"cmov.l", "cmov.l.at">;
1323 def : MnemonicAlias<"cmov.w", "cmov.w.at">;
1324 def : MnemonicAlias<"cmov.d", "cmov.d.at">;
1325 def : MnemonicAlias<"cmov.s", "cmov.s.at">;
1327 //-----------------------------------------------------------------------------
1328 // Section 8.6 - Shift Operation Instructions
1329 //-----------------------------------------------------------------------------
1331 // Section 8.6.1 - SLL (Shift Left Logical)
1332 defm SLL : RRIm<"sll", 0x65, I64, i64, shl>;
1334 // Section 8.6.2 - SLD (Shift Left Double)
1335 defm SLD : RRILDm<"sld", 0x64, I64>;
1337 // Section 8.6.3 - SRL (Shift Right Logical)
1338 defm SRL : RRIm<"srl", 0x75, I64, i64, srl>;
1340 // Section 8.6.4 - SRD (Shift Right Double)
1341 defm SRD : RRIRDm<"srd", 0x74, I64>;
1343 // Section 8.6.5 - SLA (Shift Left Arithmetic)
1344 defm SLAWSX : RRIm<"sla.w.sx", 0x66, I32, i32, shl>;
1345 let cx = 1 in defm SLAWZX : RRIm<"sla.w.zx", 0x66, I32, i32>;
1347 // Section 8.6.6 - SLAX (Shift Left Arithmetic)
1348 defm SLAL : RRIm<"sla.l", 0x57, I64, i64>;
1350 // Section 8.6.7 - SRA (Shift Right Arithmetic)
1351 defm SRAWSX : RRIm<"sra.w.sx", 0x76, I32, i32, sra>;
1352 let cx = 1 in defm SRAWZX : RRIm<"sra.w.zx", 0x76, I32, i32>;
1354 // Section 8.6.8 - SRAX (Shift Right Arithmetic)
1355 defm SRAL : RRIm<"sra.l", 0x77, I64, i64, sra>;
1357 def : 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)>;
1360 def : 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)>;
1364 //-----------------------------------------------------------------------------
1365 // Section 8.7 - Floating-point Arithmetic Instructions
1366 //-----------------------------------------------------------------------------
1368 // Section 8.7.1 - FAD (Floating Add)
1369 defm FADDD : RRFm<"fadd.d", 0x4C, I64, f64, fadd>;
1371 defm FADDS : RRFm<"fadd.s", 0x4C, F32, f32, fadd, simm7fp, mimmfp32>;
1373 // Section 8.7.2 - FSB (Floating Subtract)
1374 defm FSUBD : RRFm<"fsub.d", 0x5C, I64, f64, fsub>;
1376 defm FSUBS : RRFm<"fsub.s", 0x5C, F32, f32, fsub, simm7fp, mimmfp32>;
1378 // Section 8.7.3 - FMP (Floating Multiply)
1379 defm FMULD : RRFm<"fmul.d", 0x4D, I64, f64, fmul>;
1381 defm FMULS : RRFm<"fmul.s", 0x4D, F32, f32, fmul, simm7fp, mimmfp32>;
1383 // Section 8.7.4 - FDV (Floating Divide)
1384 defm FDIVD : RRFm<"fdiv.d", 0x5D, I64, f64, fdiv>;
1386 defm FDIVS : RRFm<"fdiv.s", 0x5D, F32, f32, fdiv, simm7fp, mimmfp32>;
1388 // Section 8.7.5 - FCP (Floating Compare)
1389 defm FCMPD : RRFm<"fcmp.d", 0x7E, I64, f64, cmpf>;
1391 defm FCMPS : RRFm<"fcmp.s", 0x7E, F32, f32, cmpf, simm7fp, mimmfp32>;
1393 // Section 8.7.6 - CMS (Compare and Select Maximum/Minimum Single)
1394 // cx: double/float, cw: max/min
1395 let cw = 0, cx = 0 in
1396 defm FMAXD : RRFm<"fmax.d", 0x3E, I64, f64, fmaxnum>;
1397 let cw = 0, cx = 1 in
1398 defm FMAXS : RRFm<"fmax.s", 0x3E, F32, f32, fmaxnum, simm7fp, mimmfp32>;
1399 let cw = 1, cx = 0 in
1400 defm FMIND : RRFm<"fmin.d", 0x3E, I64, f64, fminnum>;
1401 let cw = 1, cx = 1 in
1402 defm FMINS : RRFm<"fmin.s", 0x3E, F32, f32, fminnum, simm7fp, mimmfp32>;
1404 // Section 8.7.7 - FAQ (Floating Add Quadruple)
1405 defm FADDQ : RRFm<"fadd.q", 0x6C, F128, f128, fadd>;
1407 // Section 8.7.8 - FSQ (Floating Subtract Quadruple)
1408 defm FSUBQ : RRFm<"fsub.q", 0x7C, F128, f128, fsub>;
1410 // Section 8.7.9 - FMQ (Floating Subtract Quadruple)
1411 defm FMULQ : RRFm<"fmul.q", 0x6D, F128, f128, fmul>;
1413 // Section 8.7.10 - FCQ (Floating Compare Quadruple)
1414 defm FCMPQ : RRNCbm<"fcmp.q", 0x7D, I64, f64, F128, f128, cmpq, simm7fp,
1417 // Section 8.7.11 - FIX (Convert to Fixed Point)
1418 // cx: double/float, cw: sx/zx, sz{0-3} = round
1419 let cx = 0, cw = 0 /* sign extend */ in
1420 defm CVTWDSX : CVTRDm<"cvt.w.d.sx", 0x4E, I32, I64>;
1421 let cx = 0, cw = 1 /* zero extend */ in
1422 defm CVTWDZX : CVTRDm<"cvt.w.d.zx", 0x4E, I32, I64>;
1423 let cx = 1, cw = 0 /* sign extend */ in
1424 defm CVTWSSX : CVTRDm<"cvt.w.s.sx", 0x4E, I32, F32>;
1425 let cx = 1, cw = 1 /* zero extend */ in
1426 defm CVTWSZX : CVTRDm<"cvt.w.s.zx", 0x4E, I32, F32>;
1428 // Section 8.7.12 - FIXX (Convert to Fixed Point)
1429 defm CVTLD : CVTRDm<"cvt.l.d", 0x4F, I64, I64>;
1431 // Section 8.7.13 - FLT (Convert to Floating Point)
1432 defm CVTDW : CVTm<"cvt.d.w", 0x5E, I64, f64, I32, i32, sint_to_fp>;
1434 defm CVTSW : CVTm<"cvt.s.w", 0x5E, F32, f32, I32, i32, sint_to_fp>;
1436 // Section 8.7.14 - FLTX (Convert to Floating Point)
1437 defm CVTDL : CVTm<"cvt.d.l", 0x5F, I64, f64, I64, i64, sint_to_fp>;
1439 // Section 8.7.15 - CVS (Convert to Single-format)
1440 defm CVTSD : CVTm<"cvt.s.d", 0x1F, F32, f32, I64, f64, fpround>;
1442 defm CVTSQ : CVTm<"cvt.s.q", 0x1F, F32, f32, F128, f128, fpround>;
1444 // Section 8.7.16 - CVD (Convert to Double-format)
1445 defm CVTDS : CVTm<"cvt.d.s", 0x0F, I64, f64, F32, f32, fpextend>;
1447 defm CVTDQ : CVTm<"cvt.d.q", 0x0F, I64, f64, F128, f128, fpround>;
1449 // Section 8.7.17 - CVQ (Convert to Single-format)
1450 defm CVTQD : CVTm<"cvt.q.d", 0x2D, F128, f128, I64, f64, fpextend>;
1452 defm CVTQS : CVTm<"cvt.q.s", 0x2D, F128, f128, F32, f32, fpextend>;
1454 //-----------------------------------------------------------------------------
1455 // Section 8.8 - Branch instructions
1456 //-----------------------------------------------------------------------------
1458 // Section 8.8.1 - BC (Branch on Codition)
1459 defm BCFL : BCm<"b${cond}.l", "b.l", "baf.l", 0x19, I64, simm7>;
1461 // Indirect branch aliases
1462 def : Pat<(brind I64:$reg), (BCFLari_t $reg, 0)>;
1463 def : Pat<(brind tblockaddress:$imm), (BCFLazi_t 0, $imm)>;
1465 // Return instruction is a special case of jump.
1466 let 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
1469 def RET : CF<0x19, (outs), (ins), "b.l.t (, %s10)", [(retglue)]>;
1471 // Section 8.8.2 - BCS (Branch on Condition Single)
1472 defm BCFW : BCm<"b${cond}.w", "b.w", "baf.w", 0x1B, I32, simm7>;
1474 // Section 8.8.3 - BCF (Branch on Condition Floating Point)
1475 defm BCFD : BCm<"b${cond}.d", "b.d", "baf.d", 0x1C, I64, simm7fp>;
1477 defm BCFS : BCm<"b${cond}.s", "b.s", "baf.s", 0x1C, F32, simm7fp>;
1479 // Section 8.8.4 - BCR (Branch on Condition Relative)
1480 let cx = 0, cx2 = 0 in
1481 defm BRCFL : BCRm<"br${cond}.l", "br.l", "braf.l", 0x18, I64, simm7, zero>;
1482 let cx = 1, cx2 = 0 in
1483 defm BRCFW : BCRm<"br${cond}.w", "br.w", "braf.w", 0x18, I32, simm7, zero>;
1484 let cx = 0, cx2 = 1 in
1485 defm BRCFD : BCRm<"br${cond}.d", "br.d", "braf.d", 0x18, I64, simm7fp, zerofp>;
1486 let cx = 1, cx2 = 1 in
1487 defm BRCFS : BCRm<"br${cond}.s", "br.s", "braf.s", 0x18, F32, simm7fp, zerofp>;
1489 // Section 8.8.5 - BSIC (Branch and Save IC)
1490 let isCall = 1, hasSideEffects = 0, DecoderMethod = "DecodeCall" in
1491 defm BSIC : RMm<"bsic", 0x08, I64>;
1493 // Call instruction is a special case of BSIC.
1494 let Defs = [SX10], sx = 10 /* SX10 */, cy = 0, sy = 0, imm32 = 0,
1495 isCall = 1, isCodeGenOnly = 1, hasSideEffects = 0 in
1496 def CALLr : RM<0x08, (outs), (ins I64:$sz, variable_ops),
1497 "bsic %s10, (, $sz)", [(call i64:$sz)]>;
1499 //-----------------------------------------------------------------------------
1500 // Section 8.19 - Control Instructions
1501 //-----------------------------------------------------------------------------
1503 // Section 8.19.1 - SIC (Save Instruction Counter)
1504 let cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 1, Uses = [IC] in
1505 def SIC : RR<0x28, (outs I32:$sx), (ins), "sic $sx">;
1507 // Section 8.19.2 - LPM (Load Program Mode Flags)
1508 let sx = 0, cz = 0, sz = 0, hasSideEffects = 1, Defs = [PSW] in
1509 def LPM : RR<0x3a, (outs), (ins I64:$sy), "lpm $sy">;
1511 // Section 8.19.3 - SPM (Save Program Mode Flags)
1512 let cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 1, Uses = [PSW] in
1513 def SPM : RR<0x2a, (outs I64:$sx), (ins), "spm $sx">;
1515 // Section 8.19.4 - LFR (Load Flag Register)
1516 let 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">;
1521 // Section 8.19.5 - SFR (Save Flag Register)
1522 let cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 1, Uses = [PSW] in
1523 def SFR : RR<0x29, (outs I64:$sx), (ins), "sfr $sx">;
1525 // Section 8.19.6 - SMIR (Save Miscellaneous Register)
1526 let cy = 0, cz = 0, sz = 0, hasSideEffects = 1 in {
1527 def SMIR : RR<0x22, (outs I64:$sx), (ins MISC:$sy), "smir $sx, $sy">;
1530 // Section 8.19.7 - NOP (No Operation)
1531 let sx = 0, cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 0 in
1532 def NOP : RR<0x79, (outs), (ins), "nop">;
1534 // Section 8.19.8 - MONC (Monitor Call)
1535 let 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">;
1540 // Section 8.19.9 - LCR (Load Communication Register)
1541 defm LCR : LOADCRm<"lcr", 0x40, I64>;
1543 // Section 8.19.10 - SCR (Save Communication Register)
1544 defm SCR : STORECRm<"scr", 0x50, I64>;
1546 // Section 8.19.11 - TSCR (Test & Set Communication Register)
1547 defm TSCR : TSCRm<"tscr", 0x41, I64>;
1549 // Section 8.19.12 - FIDCR (Fetch & Increment/Decrement CR)
1550 defm FIDCR : FIDCRm<"fidcr", 0x51, I64>;
1552 //-----------------------------------------------------------------------------
1553 // Section 8.20 - Host Memory Access Instructions
1554 //-----------------------------------------------------------------------------
1556 // Section 8.20.1 - LHM (Load Host Memory)
1557 let ry = 3, DecoderMethod = "DecodeLoadASI64" in
1558 defm LHML : LHMm<"lhm.l", 0x21, I64>;
1559 let ry = 2, DecoderMethod = "DecodeLoadASI64" in
1560 defm LHMW : LHMm<"lhm.w", 0x21, I64>;
1561 let ry = 1, DecoderMethod = "DecodeLoadASI64" in
1562 defm LHMH : LHMm<"lhm.h", 0x21, I64>;
1563 let ry = 0, DecoderMethod = "DecodeLoadASI64" in
1564 defm LHMB : LHMm<"lhm.b", 0x21, I64>;
1566 // Section 8.20.2 - SHM (Store Host Memory)
1567 let ry = 3, DecoderMethod = "DecodeStoreASI64" in
1568 defm SHML : SHMm<"shm.l", 0x31, I64>;
1569 let ry = 2, DecoderMethod = "DecodeStoreASI64" in
1570 defm SHMW : SHMm<"shm.w", 0x31, I64>;
1571 let ry = 1, DecoderMethod = "DecodeStoreASI64" in
1572 defm SHMH : SHMm<"shm.h", 0x31, I64>;
1573 let ry = 0, DecoderMethod = "DecodeStoreASI64" in
1574 defm SHMB : SHMm<"shm.b", 0x31, I64>;
1576 //===----------------------------------------------------------------------===//
1577 // Instructions for CodeGenOnly
1578 //===----------------------------------------------------------------------===//
1580 //===----------------------------------------------------------------------===//
1581 // Pattern Matchings
1582 //===----------------------------------------------------------------------===//
1584 // Basic cast between registers. This is often used in ISel patterns, so make
1585 // them as OutPatFrag.
1586 def i2l : OutPatFrag<(ops node:$exp),
1587 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $exp, sub_i32)>;
1588 def l2i : OutPatFrag<(ops node:$exp),
1589 (EXTRACT_SUBREG $exp, sub_i32)>;
1590 def f2l : OutPatFrag<(ops node:$exp),
1591 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $exp, sub_f32)>;
1592 def l2f : OutPatFrag<(ops node:$exp),
1593 (EXTRACT_SUBREG $exp, sub_f32)>;
1595 // Zero out subregisters.
1596 def zero_i32 : OutPatFrag<(ops node:$expr),
1598 def zero_f32 : OutPatFrag<(ops node:$expr),
1599 (ANDrm $expr, !add(32, 64))>;
1601 // Small immediates.
1602 def : Pat<(i32 simm7:$val), (l2i (ORim (LO7 $val), 0))>;
1603 def : Pat<(i64 simm7:$val), (ORim (LO7 $val), 0)>;
1604 // Medium immediates.
1605 def : Pat<(i32 simm32:$val), (l2i (LEAzii 0, 0, (LO32 $val)))>;
1606 def : Pat<(i64 simm32:$val), (LEAzii 0, 0, (LO32 $val))>;
1607 def : Pat<(i64 uimm32:$val), (zero_f32 (LEAzii 0, 0, (LO32 $val)))>;
1608 // Arbitrary immediates.
1609 def : Pat<(i64 lozero:$val),
1610 (LEASLzii 0, 0, (HI32 imm:$val))>;
1611 def : Pat<(i64 lomsbzero:$val),
1612 (LEASLrii (LEAzii 0, 0, (LO32 imm:$val)), 0, (HI32 imm:$val))>;
1613 def : Pat<(i64 imm:$val),
1614 (LEASLrii (ANDrm (LEAzii 0, 0, (LO32 imm:$val)), !add(32, 64)), 0,
1618 def 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))]>;
1622 def : Pat<(lea_add I64:$base, simm7:$idx, simm32:$disp),
1623 (LEArii $base, (LO7 $idx), (LO32 $disp))>;
1624 def : Pat<(lea_add I64:$base, I64:$idx, simm32:$disp),
1625 (LEArri $base, $idx, (LO32 $disp))>;
1626 def : Pat<(lea_add I64:$base, simm7:$idx, lozero:$disp),
1627 (LEASLrii $base, (LO7 $idx), (HI32 $disp))>;
1628 def : Pat<(lea_add I64:$base, I64:$idx, lozero:$disp),
1629 (LEASLrri $base, $idx, (HI32 $disp))>;
1631 // Address calculation patterns and optimizations
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)
1644 def velo_only : OutPatFrag<(ops node:$lo),
1645 (ANDrm (LEAzii 0, 0, $lo), !add(32, 64))>;
1646 def vehi_only : OutPatFrag<(ops node:$hi),
1647 (LEASLzii 0, 0, $hi)>;
1648 def vehi_lo : OutPatFrag<(ops node:$hi, node:$lo),
1649 (LEASLrii $lo, 0, $hi)>;
1650 def vehi_lo_imm : OutPatFrag<(ops node:$hi, node:$lo, node:$idx),
1651 (LEASLrii $lo, $idx, $hi)>;
1652 def vehi_baselo : OutPatFrag<(ops node:$base, node:$hi, node:$lo),
1653 (LEASLrri $base, $lo, $hi)>;
1654 foreach 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)>;
1666 def : Pat<(f32 fpimm:$val),
1667 (EXTRACT_SUBREG (LEASLzii 0, 0, (HIFP32 $val)), sub_f32)>;
1668 def : Pat<(f64 fplozero:$val),
1669 (LEASLzii 0, 0, (HIFP32 $val))>;
1670 def : Pat<(f64 fplomsbzero:$val),
1671 (LEASLrii (LEAzii 0, 0, (LOFP32 $val)), 0, (HIFP32 $val))>;
1672 def : Pat<(f64 fpimm:$val),
1673 (LEASLrii (ANDrm (LEAzii 0, 0, (LOFP32 $val)), !add(32, 64)), 0,
1676 // The same integer registers are used for i32 and i64 values.
1677 // When registers hold i32 values, the high bits are unused.
1679 // TODO Use standard expansion for shift-based lowering of sext_inreg
1682 def : Pat<(sext_inreg I32:$src, i1),
1683 (SRAWSXri (SLAWSXri $src, 31), 31)>;
1684 def : Pat<(sext_inreg I64:$src, i1),
1685 (SRALri (SLLri $src, 63), 63)>;
1688 def : Pat<(sext_inreg I32:$src, i8),
1689 (SRAWSXri (SLAWSXri $src, 24), 24)>;
1690 def : Pat<(sext_inreg I64:$src, i8),
1691 (SRALri (SLLri $src, 56), 56)>;
1692 def : Pat<(sext_inreg (i32 (trunc i64:$src)), i8),
1693 (EXTRACT_SUBREG (SRALri (SLLri $src, 56), 56), sub_i32)>;
1694 def : Pat<(i32 (and (trunc i64:$src), 0xff)),
1695 (EXTRACT_SUBREG (ANDrm $src, !add(56, 64)), sub_i32)>;
1698 def : Pat<(sext_inreg I32:$src, i16),
1699 (SRAWSXri (SLAWSXri $src, 16), 16)>;
1700 def : Pat<(sext_inreg I64:$src, i16),
1701 (SRALri (SLLri $src, 48), 48)>;
1702 def : Pat<(sext_inreg (i32 (trunc i64:$src)), i16),
1703 (EXTRACT_SUBREG (SRALri (SLLri $src, 48), 48), sub_i32)>;
1704 def : Pat<(i32 (and (trunc i64:$src), 0xffff)),
1705 (EXTRACT_SUBREG (ANDrm $src, !add(48, 64)), sub_i32)>;
1708 def : Pat<(i32 (trunc i64:$src)), (l2i (zero_f32 $src))>;
1709 def : Pat<(i32 (fp_to_sint f32:$src)), (CVTWSSXr RD_RZ, $src)>;
1710 def : Pat<(i32 (fp_to_sint f64:$src)), (CVTWDSXr RD_RZ, $src)>;
1711 def : Pat<(i32 (fp_to_sint f128:$src)), (CVTWDSXr RD_RZ, (CVTDQr $src))>;
1714 def : Pat<(sext_inreg i64:$src, i32), (i2l (ADDSWSXrm (l2i $src), 0))>;
1715 def : Pat<(i64 (sext i32:$src)), (i2l (ADDSWSXrm $src, 0))>;
1716 def : Pat<(i64 (zext i32:$src)), (i2l (ADDSWZXrm $src, 0))>;
1717 def : Pat<(i64 (anyext i32:$sy)), (i2l $sy)>;
1718 def : Pat<(i64 (fp_to_sint f32:$src)), (CVTLDr RD_RZ, (CVTDSr $src))>;
1719 def : Pat<(i64 (fp_to_sint f64:$src)), (CVTLDr RD_RZ, $src)>;
1720 def : Pat<(i64 (fp_to_sint f128:$src)), (CVTLDr RD_RZ, (CVTDQr $src))>;
1723 def : Pat<(f32 (sint_to_fp i64:$src)), (CVTSDr (CVTDLr i64:$src))>;
1726 def : Pat<(f128 (sint_to_fp i32:$src)), (CVTQDr (CVTDWr $src))>;
1727 def : Pat<(f128 (sint_to_fp i64:$src)), (CVTQDr (CVTDLr $src))>;
1730 // extload, sextload and zextload stuff
1731 multiclass EXT64m<SDPatternOperator from,
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))>;
1745 defm : EXT64m<sextloadi8, LD1BSXrri, LD1BSXrii, LD1BSXzri, LD1BSXzii>;
1746 defm : EXT64m<zextloadi8, LD1BZXrri, LD1BZXrii, LD1BZXzri, LD1BZXzii>;
1747 defm : EXT64m<extloadi8, LD1BZXrri, LD1BZXrii, LD1BZXzri, LD1BZXzii>;
1748 defm : EXT64m<sextloadi16, LD2BSXrri, LD2BSXrii, LD2BSXzri, LD2BSXzii>;
1749 defm : EXT64m<zextloadi16, LD2BZXrri, LD2BZXrii, LD2BZXzri, LD2BZXzii>;
1750 defm : EXT64m<extloadi16, LD2BZXrri, LD2BZXrii, LD2BZXzri, LD2BZXzii>;
1751 defm : EXT64m<sextloadi32, LDLSXrri, LDLSXrii, LDLSXzri, LDLSXzii>;
1752 defm : EXT64m<zextloadi32, LDLZXrri, LDLZXrii, LDLZXzri, LDLZXzii>;
1753 defm : EXT64m<extloadi32, LDLSXrri, LDLSXrii, LDLSXzri, LDLSXzii>;
1756 multiclass EXT32m<SDPatternOperator from,
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)>;
1766 defm : EXT32m<extloadi8, LD1BZXrri, LD1BZXrii, LD1BZXzri, LD1BZXzii>;
1767 defm : EXT32m<extloadi16, LD2BZXrri, LD2BZXrii, LD2BZXzri, LD2BZXzii>;
1770 multiclass TRUNC64m<SDPatternOperator from,
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))>;
1784 defm : TRUNC64m<truncstorei8, ST1Brri, ST1Brii, ST1Bzri, ST1Bzii>;
1785 defm : TRUNC64m<truncstorei16, ST2Brri, ST2Brii, ST2Bzri, ST2Bzii>;
1786 defm : TRUNC64m<truncstorei32, STLrri, STLrii, STLzri, ST1Bzii>;
1788 // Atomic loads (FIXME: replace iAny with the correct integer VT:)
1789 multiclass ATMLDm<SDPatternOperator from,
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)>;
1797 defm : ATMLDm<atomic_load_8, LD1BZXrri, LD1BZXrii, LD1BZXzri, LD1BZXzii>;
1798 defm : ATMLDm<atomic_load_16, LD2BZXrri, LD2BZXrii, LD2BZXzri, LD2BZXzii>;
1799 defm : ATMLDm<atomic_load_32, LDLZXrri, LDLZXrii, LDLZXzri, LDLZXzii>;
1800 defm : ATMLDm<atomic_load_64, LDrri, LDrii, LDzri, LDzii>;
1802 // Optimized atomic loads with sext
1803 multiclass SXATMLDm<SDPatternOperator from, ValueType TY,
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))>;
1815 multiclass SXATMLD32m<SDPatternOperator from,
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))>;
1827 defm : SXATMLDm<atomic_load_8, i8, LD1BSXrri, LD1BSXrii, LD1BSXzri, LD1BSXzii>;
1828 defm : SXATMLDm<atomic_load_16, i16, LD2BSXrri, LD2BSXrii, LD2BSXzri,
1830 defm : SXATMLD32m<atomic_load_32, LDLSXrri, LDLSXrii, LDLSXzri, LDLSXzii>;
1832 // Optimized atomic loads with zext
1833 multiclass ZXATMLDm<SDPatternOperator from, int VAL,
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))>;
1845 multiclass ZXATMLD32m<SDPatternOperator from,
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))>;
1857 defm : ZXATMLDm<atomic_load_8, 0xFF, LD1BZXrri, LD1BZXrii, LD1BZXzri,
1859 defm : ZXATMLDm<atomic_load_16, 0xFFFF, LD2BZXrri, LD2BZXrii, LD2BZXzri,
1861 defm : ZXATMLD32m<atomic_load_32, LDLZXrri, LDLZXrii, LDLZXzri, LDLZXzii>;
1864 multiclass ATMSTm<SDPatternOperator from, ValueType ty,
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)>;
1872 defm : ATMSTm<atomic_store_8, i32, ST1Brri, ST1Brii, ST1Bzri, ST1Bzii>;
1873 defm : ATMSTm<atomic_store_16, i32, ST2Brri, ST2Brii, ST2Bzri, ST2Bzii>;
1874 defm : ATMSTm<atomic_store_32, i32, STLrri, STLrii, STLzri, STLzii>;
1875 defm : ATMSTm<atomic_store_64, i64, STrri, STrii, STzri, STzii>;
1877 // Optimized atomic stores with truncate
1878 multiclass TRATMSTm<SDPatternOperator from,
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))>;
1892 defm : TRATMSTm<atomic_store_8, ST1Brri, ST1Brii, ST1Bzri, ST1Bzii>;
1893 defm : TRATMSTm<atomic_store_16, ST2Brri, ST2Brii, ST2Bzri, ST2Bzii>;
1894 defm : TRATMSTm<atomic_store_32, STLrri, STLrii, STLzri, STLzii>;
1897 def : Pat<(i32 (ts1am i64:$src, i32:$flag, i32:$new)),
1898 (TS1AMWrir $src, 0, $flag, $new)>;
1899 def : Pat<(i32 (atomic_swap_i32 ADDRri:$src, i32:$new)),
1900 (TS1AMWrii MEMriRRM:$src, 15, $new)>;
1901 def : Pat<(i64 (atomic_swap_i64 ADDRri:$src, i64:$new)),
1902 (TS1AMLrir MEMriRRM:$src, (LEAzii 0, 0, 255), i64:$new)>;
1904 //===----------------------------------------------------------------------===//
1905 // SJLJ Exception handling patterns
1906 //===----------------------------------------------------------------------===//
1908 let 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)]>;
1915 def EH_SjLj_SetJmp : Pseudo<(outs I32:$dst), (ins I64:$buf),
1917 [(set I32:$dst, (VEeh_sjlj_setjmp I64:$buf))]>;
1919 def EH_SjLj_Setup_Dispatch : Pseudo<(outs), (ins), "# EH_SJLJ_SETUP_DISPATCH",
1920 [(VEeh_sjlj_setup_dispatch)]>;
1923 let isTerminator = 1, isBranch = 1, isCodeGenOnly = 1 in
1924 def EH_SjLj_Setup : Pseudo<(outs), (ins brtarget32:$dst),
1925 "# EH_SJlJ_SETUP $dst">;
1927 //===----------------------------------------------------------------------===//
1928 // Branch related patterns
1929 //===----------------------------------------------------------------------===//
1932 def : Pat<(br bb:$addr), (BRCFLa bb:$addr)>;
1936 multiclass BRCCIm<ValueType ty, CF BrOpNode1,
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),
1947 def : Pat<(brcc CCUIOp:$cond, ty:$l, ty:$r, bb:$addr),
1948 (BrOpNode2 (icond2cc $cond), 0, (CmpOpNode1 $r, $l), bb:$addr)>;
1950 defm : BRCCIm<i32, BRCFWrr, BRCFWir, CMPUWrr, CMPUWir>;
1951 defm : BRCCIm<i64, BRCFLrr, BRCFLir, CMPULrr, CMPULir>;
1953 // floating point brcc
1954 multiclass 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)>;
1960 defm : BRCCFm<f32, BRCFSrr, BRCFSir>;
1961 defm : BRCCFm<f64, BRCFDrr, BRCFDir>;
1962 def : Pat<(brcc cond:$cond, f128:$l, f128:$r, bb:$addr),
1963 (BRCFDir (fcond2cc $cond), 0, (FCMPQrr $r, $l), bb:$addr)>;
1965 //===----------------------------------------------------------------------===//
1966 // Pseudo Instructions
1967 //===----------------------------------------------------------------------===//
1970 let Defs = [SX15 /* %got */, SX16 /* %plt */], hasSideEffects = 0 in {
1971 def GETGOT : Pseudo<(outs getGOT:$getpcseq), (ins), "$getpcseq">;
1974 // GETFUNPLT for PIC
1975 let hasSideEffects = 0 in
1976 def GETFUNPLT : Pseudo<(outs I64:$dst), (ins i64imm:$addr),
1978 [(set iPTR:$dst, (GetFunPLT tglobaladdr:$addr))] >;
1980 def : Pat<(GetFunPLT tglobaladdr:$dst),
1981 (GETFUNPLT tglobaladdr:$dst)>;
1982 def : Pat<(GetFunPLT texternalsym:$dst),
1983 (GETFUNPLT texternalsym:$dst)>;
1985 // GETTLSADDR for TLS
1986 let Defs = [SX0, SX10, SX12], hasSideEffects = 0 in
1987 def GETTLSADDR : Pseudo<(outs), (ins i64imm:$addr),
1988 "# GETTLSADDR $addr",
1989 [(GetTLSAddr tglobaltlsaddr:$addr)] >;
1991 def : Pat<(GetTLSAddr tglobaltlsaddr:$dst),
1992 (GETTLSADDR tglobaltlsaddr:$dst)>;
1994 let Defs = [SX11], Uses = [SX11], hasSideEffects = 0 in {
1995 def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i64imm:$amt, i64imm:$amt2),
1996 "# ADJCALLSTACKDOWN $amt, $amt2",
1997 [(callseq_start timm:$amt, timm:$amt2)]>;
1998 def ADJCALLSTACKUP : Pseudo<(outs), (ins i64imm:$amt1, i64imm:$amt2),
1999 "# ADJCALLSTACKUP $amt1",
2000 [(callseq_end timm:$amt1, timm:$amt2)]>;
2003 let Defs = [SX8], Uses = [SX8, SX11], hasSideEffects = 0 in
2004 def EXTEND_STACK : Pseudo<(outs), (ins),
2007 let hasSideEffects = 0 in
2008 def EXTEND_STACK_GUARD : Pseudo<(outs), (ins),
2009 "# EXTEND STACK GUARD",
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).
2016 let Uses = [SX11], hasSideEffects = 1 in
2017 def GETSTACKTOP : Pseudo<(outs I64:$dst), (ins),
2019 [(set iPTR:$dst, (GetStackTop))]>;
2021 //===----------------------------------------------------------------------===//
2023 //===----------------------------------------------------------------------===//
2025 // SETCC pattern matches
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
2031 class setccrr<Instruction INSN> :
2032 OutPatFrag<(ops node:$cond, node:$comp),
2035 !add(63, 64), // means (63)0 == 1
2036 (ORim 0, 0)), sub_i32)>;
2038 def : Pat<(i32 (setcc i32:$l, i32:$r, CCSIOp:$cond)),
2039 (setccrr<CMOVWrm> (icond2cc $cond), (CMPSWSXrr $l, $r))>;
2040 def : Pat<(i32 (setcc i32:$l, i32:$r, CCUIOp:$cond)),
2041 (setccrr<CMOVWrm> (icond2cc $cond), (CMPUWrr $l, $r))>;
2042 def : Pat<(i32 (setcc i64:$l, i64:$r, CCSIOp:$cond)),
2043 (setccrr<CMOVLrm> (icond2cc $cond), (CMPSLrr $l, $r))>;
2044 def : Pat<(i32 (setcc i64:$l, i64:$r, CCUIOp:$cond)),
2045 (setccrr<CMOVLrm> (icond2cc $cond), (CMPULrr $l, $r))>;
2046 def : Pat<(i32 (setcc f32:$l, f32:$r, cond:$cond)),
2047 (setccrr<CMOVSrm> (fcond2cc $cond), (FCMPSrr $l, $r))>;
2048 def : Pat<(i32 (setcc f64:$l, f64:$r, cond:$cond)),
2049 (setccrr<CMOVDrm> (fcond2cc $cond), (FCMPDrr $l, $r))>;
2050 def : Pat<(i32 (setcc f128:$l, f128:$r, cond:$cond)),
2051 (setccrr<CMOVDrm> (fcond2cc $cond), (FCMPQrr $l, $r))>;
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.
2058 multiclass CMOVI32m<ValueType TY, string Insn> {
2059 def : Pat<(i32 (cmov TY:$cmp, i32:$t, i32:$f, (i32 CCOp:$cond))),
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)),
2065 def : Pat<(i32 (cmov TY:$cmp, (i32 mimm:$t), i32:$f, (i32 CCOp:$cond))),
2067 (!cast<Instruction>(Insn#"rm") (CCOP $cond), $cmp,
2069 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $f, sub_i32)),
2072 defm : CMOVI32m<i64, "CMOVL">;
2073 defm : CMOVI32m<i32, "CMOVW">;
2074 defm : CMOVI32m<f64, "CMOVD">;
2075 defm : CMOVI32m<f32, "CMOVS">;
2078 multiclass CMOVF32m<ValueType TY, string Insn> {
2079 def : Pat<(f32 (cmov TY:$cmp, f32:$t, f32:$f, (i32 CCOp:$cond))),
2081 (!cast<Instruction>(Insn#"rr")
2083 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $t, sub_f32),
2084 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $f, sub_f32)),
2086 def : Pat<(f32 (cmov TY:$cmp, (f32 mimmfp:$t), f32:$f, (i32 CCOp:$cond))),
2088 (!cast<Instruction>(Insn#"rm")
2089 (CCOP $cond), $cmp, (MIMMFP $t),
2090 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $f, sub_f32)),
2093 defm : CMOVF32m<i64, "CMOVL">;
2094 defm : CMOVF32m<i32, "CMOVW">;
2095 defm : CMOVF32m<f64, "CMOVD">;
2096 defm : CMOVF32m<f32, "CMOVS">;
2099 multiclass 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),
2106 defm : CMOVF64m<i64, "CMOVL">;
2107 defm : CMOVF64m<i32, "CMOVW">;
2108 defm : CMOVF64m<f64, "CMOVD">;
2109 defm : CMOVF64m<f32, "CMOVS">;
2112 multiclass CMOVF128m<ValueType TY, string Insn> {
2113 def : Pat<(f128 (cmov TY:$cmp, f128:$t, f128:$f, (i32 CCOp:$cond))),
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)>;
2123 defm : CMOVF128m<i64, "CMOVL">;
2124 defm : CMOVF128m<i32, "CMOVW">;
2125 defm : CMOVF128m<f64, "CMOVD">;
2126 defm : CMOVF128m<f32, "CMOVS">;
2129 def : Pat<(f64 (bitconvert i64:$src)), (COPY_TO_REGCLASS $src, I64)>;
2130 def : Pat<(i64 (bitconvert f64:$src)), (COPY_TO_REGCLASS $src, I64)>;
2132 def : Pat<(i32 (bitconvert f32:$op)), (l2i (SRALri (f2l $op), 32))>;
2133 def : Pat<(f32 (bitconvert i32:$op)), (l2f (SLLri (i2l $op), 32))>;
2135 //===----------------------------------------------------------------------===//
2136 // Vector Instruction Pattern Stuff
2137 //===----------------------------------------------------------------------===//
2139 // Custom intermediate ISDs.
2140 class IsVLVT<int OpIdx> : SDTCisVT<OpIdx,i32>;
2141 def vec_broadcast : SDNode<"VEISD::VEC_BROADCAST", SDTypeProfile<1, 2,
2142 [SDTCisVec<0>, IsVLVT<2>]>>;
2144 ///// Packed mode Support /////
2145 // unpack the lo part of this vector
2146 def 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
2149 def 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
2152 def vec_pack : SDNode<"VEISD::VEC_PACK", SDTypeProfile<1, 3,
2153 [SDTCisVec<0>, SDTCisVec<1>, SDTCisVec<2>,
2154 SDTCisSameNumEltsAs<1,2>, IsVLVT<3>]>>;
2156 // replicate lower 32bit to upper 32bit (f32 scalar replication).
2157 def repl_f32 : SDNode<"VEISD::REPL_F32",
2159 [SDTCisInt<0>, SDTCisFP<1>]>>;
2160 // replicate upper 32bit to lower 32 bit (i32 scalar replication).
2161 def repl_i32 : SDNode<"VEISD::REPL_I32",
2163 [SDTCisInt<0>, SDTCisInt<1>]>>;
2166 // Whether this is an all-true mask (assuming undef-bits above VL are all-true).
2167 def true_mask : PatLeaf<
2168 (vec_broadcast (i32 nonzero), (i32 srcvalue))>;
2169 // Match any broadcast (ignoring VL).
2170 def any_broadcast : PatFrag<(ops node:$sx),
2171 (vec_broadcast node:$sx, (i32 srcvalue))>;
2173 // Vector instructions.
2174 include "VEInstrVec.td"
2177 include "VEInstrIntrinsicVL.td"
2179 // Patterns and intermediate SD nodes (VEC_*).
2180 include "VEInstrPatternsVec.td"
2182 // Patterns and intermediate SD nodes (VVP_*).
2183 include "VVPInstrPatternsVec.td"