1 //===-- CSKYInstrInfo.td - Target Description for CSKY -----*- tablegen -*-===//
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 CSKY instructions in TableGen format.
11 //===----------------------------------------------------------------------===//
14 //===----------------------------------------------------------------------===//
15 // CSKY specific DAG Nodes.
16 //===----------------------------------------------------------------------===//
18 // Target-independent type requirements, but with target-specific formats.
19 def SDT_CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>,
22 def SDT_CallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>,
25 def SDT_CSKYCall : SDTypeProfile<0, 2, [SDTCisVT<0, iPTR>, SDTCisVT<1, iPTR>]>;
27 def SDT_CSKYCallReg : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;
29 def SDT_CSKY_LOADADDR : SDTypeProfile<1, 2, [SDTCisVT<0, i32>,
30 SDTCisVT<1, iPTR>, SDTCisVT<2, iPTR>]>;
32 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_CallSeqStart,
33 [SDNPHasChain, SDNPOutGlue]>;
34 def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_CallSeqEnd,
35 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
37 def CSKY_RET : SDNode<"CSKYISD::RET", SDTNone,
38 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
40 def CSKY_CALL : SDNode<"CSKYISD::CALL", SDT_CSKYCall,
41 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, SDNPVariadic]>;
43 def CSKY_CALLReg : SDNode<"CSKYISD::CALLReg", SDT_CSKYCallReg,
44 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, SDNPVariadic]>;
46 def CSKY_TAIL : SDNode<"CSKYISD::TAIL", SDT_CSKYCall,
47 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, SDNPVariadic]>;
49 def CSKY_TAILReg : SDNode<"CSKYISD::TAILReg", SDT_CSKYCallReg,
50 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, SDNPVariadic]>;
52 def CSKY_LOAD_ADDR : SDNode<"CSKYISD::LOAD_ADDR", SDT_CSKY_LOADADDR>;
54 //===----------------------------------------------------------------------===//
55 // Operand and SDNode transformation definitions.
56 //===----------------------------------------------------------------------===//
57 class ImmAsmOperand<string prefix, int width, string suffix> : AsmOperandClass {
58 let Name = prefix # "Imm" # width # suffix;
59 let RenderMethod = "addImmOperands";
60 let DiagnosticType = !strconcat("Invalid", Name);
63 class SImmAsmOperand<int width, string suffix = "">
64 : ImmAsmOperand<"S", width, suffix> {
67 class UImmAsmOperand<int width, string suffix = "">
68 : ImmAsmOperand<"U", width, suffix> {
71 class OImmAsmOperand<int width, string suffix = "">
72 : ImmAsmOperand<"O", width, suffix> {
75 def to_tframeindex : SDNodeXForm<frameindex, [{
76 auto FI = cast<FrameIndexSDNode>(N);
77 return CurDAG->getTargetFrameIndex(FI->getIndex(), TLI->getPointerTy(CurDAG->getDataLayout()));
80 def to_tconstpool : SDNodeXForm<constpool, [{
81 auto CP = cast<ConstantPoolSDNode>(N);
82 return CurDAG->getTargetConstantPool(CP->getConstVal(), TLI->getPointerTy(CurDAG->getDataLayout()),
83 CP->getAlign(), CP->getOffset(), CSKYII::MO_None);
86 def to_tconstpool_hi16 : SDNodeXForm<constpool, [{
87 auto CP = cast<ConstantPoolSDNode>(N);
88 return CurDAG->getTargetConstantPool(CP->getConstVal(), TLI->getPointerTy(CurDAG->getDataLayout()),
89 CP->getAlign(), CP->getOffset(), CSKYII::MO_ADDR_HI16);
92 def to_tconstpool_lo16 : SDNodeXForm<constpool, [{
93 auto CP = cast<ConstantPoolSDNode>(N);
94 return CurDAG->getTargetConstantPool(CP->getConstVal(), TLI->getPointerTy(CurDAG->getDataLayout()),
95 CP->getAlign(), CP->getOffset(), CSKYII::MO_ADDR_LO16);
98 class oimm<int num> : Operand<i32>,
99 ImmLeaf<i32, "return isUInt<"#num#">(Imm - 1);"> {
100 let EncoderMethod = "getOImmOpValue";
101 let ParserMatchClass = OImmAsmOperand<num>;
102 let DecoderMethod = "decodeOImmOperand<"#num#">";
105 def imm_neg_XFORM : SDNodeXForm<imm, [{
106 return CurDAG->getTargetConstant(-N->getSExtValue(), SDLoc(N), MVT::i32);
109 class oimm_neg<int num> : Operand<i32>,
110 ImmLeaf<i32, "return isUInt<"#num#">(-Imm - 1);"> {
113 class uimm<int num, int shift = 0> : Operand<i32>,
114 ImmLeaf<i32, "return isShiftedUInt<"#num#", "#shift#">(Imm);"> {
115 let EncoderMethod = "getImmOpValue<"#shift#">";
116 let ParserMatchClass =
118 UImmAsmOperand<num, "Shift"#shift>,
119 UImmAsmOperand<num>);
120 let DecoderMethod = "decodeUImmOperand<"#num#", "#shift#">";
123 class uimm_neg<int num, int shift = 0> : Operand<i32>,
124 ImmLeaf<i32, "return isShiftedUInt<"#num#", "#shift#">(-Imm);"> {
127 class simm<int num, int shift = 0> : Operand<i32>,
128 ImmLeaf<i32, "return isShiftedInt<"#num#", "#shift#">(Imm);"> {
129 let EncoderMethod = "getImmOpValue<"#shift#">";
130 let ParserMatchClass = SImmAsmOperand<num>;
131 let DecoderMethod = "decodeSImmOperand<"#num#", "#shift#">";
134 def nimm_XFORM : SDNodeXForm<imm, [{
135 return CurDAG->getTargetConstant(~N->getSExtValue(), SDLoc(N), MVT::i32);
137 class nimm<int num> : Operand<i32>,
138 ImmLeaf<i32, "return isUInt<"#num#">(~Imm);", nimm_XFORM> {
139 let ParserMatchClass = UImmAsmOperand<num>;
142 def uimm32_hi16 : SDNodeXForm<imm, [{
143 return CurDAG->getTargetConstant((N->getZExtValue() >> 16) & 0xFFFF,
146 def uimm32_lo16 : SDNodeXForm<imm, [{
147 return CurDAG->getTargetConstant(N->getZExtValue()& 0xFFFF, SDLoc(N), MVT::i32);
149 def uimm16_16_xform : Operand<i32>,
150 ImmLeaf<i32, "return isShiftedUInt<16, 16>(Imm);", uimm32_hi16> {
151 let ParserMatchClass = UImmAsmOperand<16>;
152 let EncoderMethod = "getImmOpValue";
155 def uimm_shift : Operand<i32>, ImmLeaf<i32, "return isUInt<2>(Imm);"> {
156 let EncoderMethod = "getImmShiftOpValue";
157 let ParserMatchClass = UImmAsmOperand<2>;
158 let DecoderMethod = "decodeImmShiftOpValue";
161 def CSKYSymbol : AsmOperandClass {
162 let Name = "CSKYSymbol";
163 let RenderMethod = "addImmOperands";
164 let DiagnosticType = "InvalidCSKYSymbol";
165 let ParserMethod = "parseCSKYSymbol";
168 def br_symbol : Operand<OtherVT> {
170 "getBranchSymbolOpValue<CSKY::fixup_csky_pcrel_imm16_scale2>";
171 let ParserMatchClass = CSKYSymbol;
172 let DecoderMethod = "decodeSImmOperand<16, 1>";
173 let PrintMethod = "printCSKYSymbolOperand";
174 let OperandType = "OPERAND_PCREL";
177 def call_symbol : Operand<iPTR> {
178 let ParserMatchClass = CSKYSymbol;
179 let EncoderMethod = "getCallSymbolOpValue";
180 let DecoderMethod = "decodeSImmOperand<26, 1>";
181 let PrintMethod = "printCSKYSymbolOperand";
182 let OperandType = "OPERAND_PCREL";
185 def Constpool : AsmOperandClass {
186 let Name = "Constpool";
187 let RenderMethod = "addConstpoolOperands";
188 let DiagnosticType = "InvalidConstpool";
189 let ParserMethod = "parseConstpoolSymbol";
192 def constpool_symbol : Operand<iPTR> {
193 let ParserMatchClass = Constpool;
195 "getConstpoolSymbolOpValue<CSKY::fixup_csky_pcrel_uimm16_scale4>";
196 let DecoderMethod = "decodeUImmOperand<16, 2>";
197 let PrintMethod = "printConstpool";
198 let OperandType = "OPERAND_PCREL";
201 def DataAsmClass : AsmOperandClass {
202 let Name = "DataSymbol";
203 let RenderMethod = "addConstpoolOperands";
204 let DiagnosticType = "InvalidConstpool";
205 let ParserMethod = "parseDataSymbol";
208 class data_symbol<string reloc, int shift> : Operand<iPTR> {
209 let ParserMatchClass = Constpool;
211 "getDataSymbolOpValue<"#reloc#">";
212 let DecoderMethod = "decodeUImmOperand<18, "#shift#">";
213 let PrintMethod = "printDataSymbol";
216 def bare_symbol : Operand<iPTR> {
217 let ParserMatchClass = CSKYSymbol;
218 let EncoderMethod = "getBareSymbolOpValue";
219 let PrintMethod = "printCSKYSymbolOperand";
220 let DecoderMethod = "decodeSImmOperand<18, 1>";
221 let OperandType = "OPERAND_PCREL";
224 def oimm3 : oimm<3> {
225 let MCOperandPredicate = [{
227 if (MCOp.evaluateAsConstantImm(Imm))
228 return isUInt<3>(Imm - 1);
229 return MCOp.isBareSymbolRef();
233 def oimm5 : oimm<5> {
234 let MCOperandPredicate = [{
236 if (MCOp.evaluateAsConstantImm(Imm))
237 return isUInt<5>(Imm - 1);
238 return MCOp.isBareSymbolRef();
243 def imm5_idly : Operand<i32>, ImmLeaf<i32,
244 "return Imm <= 32 && Imm >= 0;"> {
245 let EncoderMethod = "getImmOpValueIDLY";
246 let DecoderMethod = "decodeOImmOperand<5>";
249 def oimm8 : oimm<8> {
250 let MCOperandPredicate = [{
252 if (MCOp.evaluateAsConstantImm(Imm))
253 return isUInt<8>(Imm - 1);
254 return MCOp.isBareSymbolRef();
257 def oimm12 : oimm<12> {
258 let MCOperandPredicate = [{
260 if (MCOp.evaluateAsConstantImm(Imm))
261 return isUInt<12>(Imm - 1);
262 return MCOp.isBareSymbolRef();
265 def oimm16 : oimm<16> {
266 let MCOperandPredicate = [{
268 if (MCOp.evaluateAsConstantImm(Imm))
269 return isUInt<16>(Imm - 1);
270 return MCOp.isBareSymbolRef();
274 def oimm8_neg : oimm_neg<8> {
275 let MCOperandPredicate = [{
277 if (MCOp.evaluateAsConstantImm(Imm))
278 return isUInt<8>(-Imm - 1);
279 return MCOp.isBareSymbolRef();
282 def oimm12_neg : oimm_neg<12> {
283 let MCOperandPredicate = [{
285 if (MCOp.evaluateAsConstantImm(Imm))
286 return isUInt<12>(-Imm - 1);
287 return MCOp.isBareSymbolRef();
291 def nimm12 : nimm<12>;
297 def uimm2_jmpix : Operand<i32>,
298 ImmLeaf<i32, "return Imm == 16 || Imm == 24 || Imm == 32 || Imm == 40;"> {
299 let EncoderMethod = "getImmJMPIX";
300 let DecoderMethod = "decodeJMPIXImmOperand";
305 def uimm5 : uimm<5> {
306 let MCOperandPredicate = [{
308 if (MCOp.evaluateAsConstantImm(Imm))
309 return isShiftedUInt<5, 0>(Imm);
310 return MCOp.isBareSymbolRef();
313 def uimm5_msb_size : uimm<5> {
314 let EncoderMethod = "getImmOpValueMSBSize";
317 def uimm5_1 : uimm<5, 1> {
318 let MCOperandPredicate = [{
320 if (MCOp.evaluateAsConstantImm(Imm))
321 return isShiftedUInt<5, 1>(Imm);
322 return MCOp.isBareSymbolRef();
325 def uimm5_2 : uimm<5, 2> {
326 let MCOperandPredicate = [{
328 if (MCOp.evaluateAsConstantImm(Imm))
329 return isShiftedUInt<5, 2>(Imm);
330 return MCOp.isBareSymbolRef();
335 def uimm7_1 : uimm<7, 1>;
336 def uimm7_2 : uimm<7, 2>{
337 let MCOperandPredicate = [{
339 if (MCOp.evaluateAsConstantImm(Imm))
340 return isShiftedUInt<7, 2>(Imm);
341 return MCOp.isBareSymbolRef();
344 def uimm7_3 : uimm<7, 3>;
345 def uimm8 : uimm<8> {
346 let MCOperandPredicate = [{
348 if (MCOp.evaluateAsConstantImm(Imm))
349 return isShiftedUInt<8, 0>(Imm);
350 return MCOp.isBareSymbolRef();
353 def uimm8_2 : uimm<8, 2> {
354 let MCOperandPredicate = [{
356 if (MCOp.evaluateAsConstantImm(Imm))
357 return isShiftedUInt<8, 2>(Imm);
358 return MCOp.isBareSymbolRef();
361 def uimm8_3 : uimm<8, 3>;
362 def uimm8_8 : uimm<8, 8>;
363 def uimm8_16 : uimm<8, 16>;
364 def uimm8_24 : uimm<8, 24>;
365 def uimm12 : uimm<12> {
366 let MCOperandPredicate = [{
368 if (MCOp.evaluateAsConstantImm(Imm))
369 return isShiftedUInt<12, 0>(Imm);
370 return MCOp.isBareSymbolRef();
373 def uimm12_1 : uimm<12, 1> {
374 let MCOperandPredicate = [{
376 if (MCOp.evaluateAsConstantImm(Imm))
377 return isShiftedUInt<12, 1>(Imm);
378 return MCOp.isBareSymbolRef();
381 def uimm12_2 : uimm<12, 2> {
382 let MCOperandPredicate = [{
384 if (MCOp.evaluateAsConstantImm(Imm))
385 return isShiftedUInt<12, 2>(Imm);
386 return MCOp.isBareSymbolRef();
389 def uimm16 : uimm<16> {
390 let MCOperandPredicate = [{
392 if (MCOp.evaluateAsConstantImm(Imm))
393 return isShiftedUInt<16, 0>(Imm);
394 return MCOp.isBareSymbolRef();
397 def uimm16_8 : uimm<16, 8>;
398 def uimm16_16 : uimm<16, 16>;
399 def uimm20 : uimm<20>;
400 def uimm24 : uimm<24>;
401 def uimm24_8 : uimm<24, 8>;
403 def uimm5_neg : uimm_neg<5>;
405 def simm8_2 : simm<8, 2>;
407 class RegSeqAsmOperand<string Suffix = ""> : AsmOperandClass {
408 let Name = "RegSeq"#Suffix;
409 let RenderMethod = "addRegSeqOperands";
410 let DiagnosticType = "InvalidRegSeq";
411 let ParserMethod = "parseRegSeq";
414 def regseq : Operand<iPTR> {
415 let EncoderMethod = "getRegisterSeqOpValue";
416 let ParserMatchClass = RegSeqAsmOperand<"">;
417 let PrintMethod = "printRegisterSeq";
418 let DecoderMethod = "DecodeRegSeqOperand";
419 let MIOperandInfo = (ops GPR, uimm5);
422 def RegListAsmOperand : AsmOperandClass {
423 let Name = "RegList";
424 let RenderMethod = "addRegListOperands";
425 let DiagnosticType = "InvalidRegList";
426 let ParserMethod = "parseRegList";
429 def reglist : Operand<iPTR> {
430 let ParserMatchClass = RegListAsmOperand;
431 let PrintMethod = "printRegisterList";
434 def PSRFlag : AsmOperandClass {
435 let Name = "PSRFlag";
436 let RenderMethod = "addImmOperands";
437 let DiagnosticType = "InvalidPSRFlag";
438 let ParserMethod = "parsePSRFlag";
441 def psrflag : Operand<i32>, ImmLeaf<i32, "return isShiftedUInt<5, 0>(Imm);"> {
442 let EncoderMethod = "getImmOpValue";
443 let ParserMatchClass = PSRFlag;
444 let PrintMethod = "printPSRFlag";
447 multiclass uimm8SRLXForm<SDNode opc> {
448 def _0: SDNodeXForm<opc,
449 [{return CurDAG->getTargetConstant((N->getZExtValue() >> 0) & 0xFF, SDLoc(N), MVT::i32);}]>;
450 def _8: SDNodeXForm<opc,
451 [{return CurDAG->getTargetConstant((N->getZExtValue() >> 8) & 0xFF, SDLoc(N), MVT::i32);}]>;
452 def _16: SDNodeXForm<opc,
453 [{return CurDAG->getTargetConstant((N->getZExtValue() >> 16) & 0xFF, SDLoc(N), MVT::i32);}]>;
454 def _24: SDNodeXForm<opc,
455 [{return CurDAG->getTargetConstant((N->getZExtValue() >> 24) & 0xFF, SDLoc(N), MVT::i32);}]>;
458 defm uimm8SRL : uimm8SRLXForm<imm>;
460 //===----------------------------------------------------------------------===//
461 // Instruction Formats
462 //===----------------------------------------------------------------------===//
464 include "CSKYInstrFormats.td"
466 //===----------------------------------------------------------------------===//
467 // Instruction definitions.
468 //===----------------------------------------------------------------------===//
470 class TriOpFrag<dag res> : PatFrag<(ops node: $LHS, node:$MHS, node:$RHS), res>;
471 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
472 class UnOpFrag<dag res> : PatFrag<(ops node:$Src), res>;
474 def eqToAdd : PatFrag<(ops node:$lhs, node:$rhs), (or node:$lhs, node:$rhs), [{
475 return isOrEquivalentToAdd(N);
478 def BaseAddr : ComplexPattern<iPTR, 1, "SelectBaseAddr">;
481 //===----------------------------------------------------------------------===//
483 //===----------------------------------------------------------------------===//
485 // Pessimistically assume the stack pointer will be clobbered
486 let Defs = [R14], Uses = [R14] in {
487 def ADJCALLSTACKDOWN : CSKYPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
488 "!ADJCALLSTACKDOWN $amt1, $amt2", [(callseq_start timm:$amt1, timm:$amt2)]>;
489 def ADJCALLSTACKUP : CSKYPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
490 "!ADJCALLSTACKUP $amt1, $amt2", [(callseq_end timm:$amt1, timm:$amt2)]>;
491 } // Defs = [R14], Uses = [R14]
494 //===----------------------------------------------------------------------===//
495 // Basic ALU instructions.
496 //===----------------------------------------------------------------------===//
498 let Predicates = [iHasE2] in {
499 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
501 def ADDI32 : I_12<0x0, "addi32", add, oimm12>;
502 def SUBI32 : I_12<0x1, "subi32", sub, oimm12>;
503 def ORI32 : I_16_ZX<"ori32", uimm16,
504 [(set GPR:$rz, (or GPR:$rx, uimm16:$imm16))]>;
505 def XORI32 : I_12<0x4, "xori32", xor, uimm12>;
506 def ANDI32 : I_12<0x2, "andi32", and, uimm12>;
507 def ANDNI32 : I_12<0x3, "andni32", and, nimm12>;
508 def LSLI32 : I_5_XZ<0x12, 0x1, "lsli32",
509 (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5),
510 [(set GPR:$rz, (shl GPR:$rx, uimm5:$imm5))]>;
511 def LSRI32 : I_5_XZ<0x12, 0x2, "lsri32",
512 (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5),
513 [(set GPR:$rz, (srl GPR:$rx, uimm5:$imm5))]>;
514 def ASRI32 : I_5_XZ<0x12, 0x4, "asri32",
515 (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5),
516 [(set GPR:$rz, (sra GPR:$rx, uimm5:$imm5))]>;
517 def ROTLI32 : I_5_XZ<0x12, 0x8, "rotli32",
518 (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5),
519 [(set GPR:$rz, (rotl GPR:$rx, uimm5:$imm5))]>;
521 def ROTRI32 : CSKYPseudo<(outs GPR:$rz), (ins GPR:$rx, oimm5:$imm5),
522 "rotri32 $rz, $rx, $imm5", []>;
525 def ADDU32 : R_YXZ_SP_F1<0x0, 0x1,
526 BinOpFrag<(add node:$LHS, node:$RHS)>, "addu32", 1>;
527 def SUBU32 : R_YXZ_SP_F1<0x0, 0x4,
528 BinOpFrag<(sub node:$LHS, node:$RHS)>, "subu32">;
530 def MULT32 : R_YXZ_SP_F1<0x21, 0x1,
531 BinOpFrag<(mul node:$LHS, node:$RHS)>, "mult32", 1>;
532 def AND32 : R_YXZ_SP_F1<0x8, 0x1,
533 BinOpFrag<(and node:$LHS, node:$RHS)>, "and32", 1>;
534 def ANDN32 : R_YXZ_SP_F1<0x8, 0x2,
535 BinOpFrag<(and node:$LHS, (not node:$RHS))>, "andn32">;
536 def OR32: R_YXZ_SP_F1<0x9, 0x1,
537 BinOpFrag<(or node:$LHS, node:$RHS)>, "or32", 1>;
538 def XOR32 : R_YXZ_SP_F1<0x9, 0x2,
539 BinOpFrag<(xor node:$LHS, node:$RHS)>, "xor32", 1>;
540 def NOR32 : R_YXZ_SP_F1<0x9, 0x4,
541 BinOpFrag<(not (or node:$LHS, node:$RHS))>, "nor32", 1>;
542 let isCodeGenOnly = 1 in
543 def NOT32 : R_XXZ<0b001001, 0b00100, (outs GPR:$rz), (ins GPR:$rx),
544 "not32", [(set GPR:$rz, (not GPR:$rx))]>;
547 def NEG32 : CSKYPseudo<(outs GPR:$rd), (ins GPR:$rx), "neg32 $rd, $rx", []>;
550 def RSUBI32 : CSKYPseudo<(outs GPR:$rd), (ins GPR:$rx, uimm12:$imm12), "rsubi32 $rd, $rx, $imm12", []>;
552 def : Pat<(add GPR:$rs1, (oimm12_neg:$im)),
553 (SUBI32 GPR:$rs1, (imm_neg_XFORM oimm12_neg:$im))>;
555 def LSL32 : R_YXZ_SP_F1<0x10, 0x1,
556 BinOpFrag<(shl node:$LHS, node:$RHS)>, "lsl32">;
557 def LSR32 : R_YXZ_SP_F1<0x10, 0x2,
558 BinOpFrag<(srl node:$LHS, node:$RHS)>, "lsr32">;
559 def ASR32 : R_YXZ_SP_F1<0x10, 0x4,
560 BinOpFrag<(sra node:$LHS, node:$RHS)>, "asr32">;
561 def ROTL32 : R_YXZ_SP_F1<0x10, 0x8,
562 BinOpFrag<(rotl node:$LHS, (and node:$RHS, 0x1f))>, "rotl32">;
564 def BMASKI32 : I_5_Z<0b010100, 0x1, "bmaski32", oimm5, []>;
565 def LSLC32 : I_5_XZ<0x13, 0x1, "lslc32",
566 (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, oimm5:$imm5), []>;
567 def LSRC32 : I_5_XZ<0x13, 0x2, "lsrc32",
568 (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, oimm5:$imm5), []>;
569 def ASRC32 : I_5_XZ<0x13, 0x4, "asrc32",
570 (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, oimm5:$imm5), []>;
571 def XSR32 : I_5_XZ<0x13, 0x8, "xsr32",
572 (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, oimm5:$imm5, CARRY:$cin), []>;
574 def IXH32 : R_YXZ_SP_F1<0x2, 0x1,
575 BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 1)))>, "ixh32">;
576 def IXW32 : R_YXZ_SP_F1<0x2, 0x2,
577 BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 2)))>, "ixw32">;
578 let Predicates = [iHas2E3] in
579 def IXD32 : R_YXZ_SP_F1<0x2, 0x4,
580 BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 3)))>, "ixd32">;
582 let isCommutable = 1, isAdd = 1 in
583 def ADDC32 : R_YXZ<0x31, 0x0, 0x2, (outs GPR:$rz, CARRY:$cout),
584 (ins GPR:$rx, GPR:$ry, CARRY:$cin), "addc32", []>;
585 def SUBC32 : R_YXZ<0x31, 0x0, 0x8, (outs GPR:$rz, CARRY:$cout),
586 (ins GPR:$rx, GPR:$ry, CARRY:$cin), "subc32", []>;
588 def INCF32 : I_5_ZX<0x3, 0x1, "incf32", uimm5, []>;
589 def INCT32 : I_5_ZX<0x3, 0x2, "inct32", uimm5, []>;
590 def DECF32 : I_5_ZX<0x3, 0x4, "decf32", uimm5, []>;
591 def DECT32 : I_5_ZX<0x3, 0x8, "dect32", uimm5, []>;
594 let Predicates = [iHas2E3] in {
595 def DIVS32 : R_YXZ_SP_F1<0x20, 0x2,
596 BinOpFrag<(sdiv node:$LHS, node:$RHS)>, "divs32">;
597 def DIVU32 : R_YXZ_SP_F1<0x20, 0x1,
598 BinOpFrag<(udiv node:$LHS, node:$RHS)>, "divu32">;
600 def DECGT32 : I_5_XZ<0x4, 0x1, "decgt32",
601 (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, uimm5:$imm5), []>;
602 def DECLT32 : I_5_XZ<0x4, 0x2, "declt32",
603 (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, uimm5:$imm5), []>;
604 def DECNE32 : I_5_XZ<0x4, 0x4, "decne32",
605 (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, uimm5:$imm5), []>;
607 def SEXT32 : I_5_XZ_U<0x16, (outs GPR:$rz), (ins GPR:$rx, uimm5:$msb, uimm5:$lsb), "sext32", []>;
608 let isCodeGenOnly = 1 in {
609 def SEXTB32 : I_5_XZ_US<0x16, 0, 7, "sextb32", sext_inreg, i8>;
610 def SEXTH32 : I_5_XZ_US<0x16, 0, 15, "sexth32", sext_inreg, i16>;
611 def ZEXTB32 : I_5_XZ_UZ<0x15, 0, 7, "zextb32", 255>;
612 def ZEXTH32 : I_5_XZ_UZ<0x15, 0, 15, "zexth32", 65535>;
614 def ZEXT32 : I_5_XZ_U<0x15, (outs GPR:$rz), (ins GPR:$rx, uimm5:$msb, uimm5:$lsb), "zext32",[]>;
616 let Constraints = "$rZ = $rz" in
617 def INS32 : I_5_XZ_INS<0b010111, (outs GPR:$rz), (ins GPR:$rZ, GPR:$rx, uimm5_msb_size:$msb, uimm5:$lsb), "ins32", []>;
620 let Predicates = [iHas3E3r1] in {
621 def MULTS32 : R_YXZ<0x3e, 0x20, 0x10, (outs GPRPair:$rz),
622 (ins GPR:$rx, GPR:$ry), "mul.s32", []>;
623 def MULTU32 : R_YXZ<0x3e, 0x20, 0x00, (outs GPRPair:$rz),
624 (ins GPR:$rx, GPR:$ry), "mul.u32", []>;
626 let Constraints = "$rZ = $rz" in {
627 def MULATS32 : R_YXZ<0x3e, 0x20, 0x14, (outs GPRPair:$rZ),
628 (ins GPRPair:$rz, GPR:$rx, GPR:$ry), "mula.s32", []>;
629 def MULATU32 : R_YXZ<0x3e, 0x20, 0x04, (outs GPRPair:$rZ),
630 (ins GPRPair:$rz, GPR:$rx, GPR:$ry), "mula.u32", []>;
634 def MULSH32 : R_YXZ<0x31, 0b100100, 0b00001, (outs GPR:$rz),
635 (ins GPR:$rx, GPR:$ry), "mulsh32", []>;
637 //===----------------------------------------------------------------------===//
638 // Load & Store instructions.
639 //===----------------------------------------------------------------------===//
641 def LD32B : I_LD<AddrMode32B, 0x0, "ld32.b", uimm12>;
642 def LD32H : I_LD<AddrMode32H, 0x1, "ld32.h", uimm12_1>;
643 def LD32W : I_LD<AddrMode32WD, 0x2, "ld32.w", uimm12_2>;
645 let OutOperandList = (outs GPRPair:$rz) in
646 def LD32D : I_LD<AddrMode32WD, 0x3, "ld32.d", uimm12_2>;
648 let Predicates = [iHasE2] in {
649 def LD32BS : I_LD<AddrMode32B, 0x4, "ld32.bs", uimm12>;
650 def LD32HS : I_LD<AddrMode32H, 0x5, "ld32.hs", uimm12_1>;
652 def LDM32 : I_5_YX<0b110100, 0b000111,
653 (outs), (ins GPR:$rx, regseq:$regs, variable_ops), "ldm32\t$regs, (${rx})", []>;
654 def STM32 : I_5_YX<0b110101, 0b000111,
655 (outs), (ins GPR:$rx, regseq:$regs, variable_ops), "stm32\t$regs, (${rx})", []>;
657 let Size = 4, isCodeGenOnly = 0 in {
658 def LDQ32 : CSKYPseudo<(outs), (ins GPR:$rx, regseq:$regs, variable_ops),
659 "ldq32\t$regs, (${rx})", []>;
660 def STQ32 : CSKYPseudo<(outs), (ins GPR:$rx, regseq:$regs, variable_ops),
661 "stq32\t$regs, (${rx})", []>;
666 def ST32B : I_ST<AddrMode32B, 0x0, "st32.b", uimm12>;
667 def ST32H : I_ST<AddrMode32H, 0x1, "st32.h", uimm12_1>;
668 def ST32W : I_ST<AddrMode32WD, 0x2, "st32.w", uimm12_2>;
670 let InOperandList = (ins GPRPair:$rz, GPR:$rx, uimm12_2:$imm12 ) in
671 def ST32D : I_ST<AddrMode32WD, 0x3, "st32.d", uimm12_2>;
673 let Predicates = [iHas2E3] in {
674 def LDR32B : I_LDR<0x0, "ldr32.b">;
675 def LDR32BS : I_LDR<0x4, "ldr32.bs">;
676 def LDR32H : I_LDR<0x1, "ldr32.h">;
677 def LDR32HS : I_LDR<0x5, "ldr32.hs">;
678 def LDR32W : I_LDR<0x2, "ldr32.w">;
679 def STR32B : I_STR<0x0, "str32.b">;
680 def STR32H : I_STR<0x1, "str32.h">;
681 def STR32W : I_STR<0x2, "str32.w">;
684 // Indicate that we're dumping the CR register, so we'll need to
685 // scavenge a register for it.
686 let mayStore = 1 in {
687 def SPILL_CARRY : CSKYPseudo<(outs), (ins CARRY:$cond, GPR:$rx, uimm12_2:$imm),
688 "!SPILL_CARRY $cond, $rx, $imm", []>;
691 // Indicate that we're restoring the CR register (previously
692 // spilled), so we'll need to scavenge a register for it.
694 def RESTORE_CARRY : CSKYPseudo<(outs CARRY:$cond), (ins GPR:$rx, uimm12_2:$imm),
695 "!RESTORE_CARRY $cond, $rx, $imm", []>;
699 def STORE_PAIR : CSKYPseudo<(outs), (ins GPRPair:$rz, GPR:$rx, uimm12_2:$imm),
700 "!STORE_PAIR $rz, $rx, $imm", []>;
704 def LOAD_PAIR : CSKYPseudo<(outs GPRPair:$rz), (ins GPR:$rx, uimm12_2:$imm),
705 "!LOAD_PAIR $rz, $rx, $imm", []>;
708 //===----------------------------------------------------------------------===//
709 // Compare instructions.
710 //===----------------------------------------------------------------------===//
711 let Predicates = [iHasE2] in {
712 def CMPNEI32 : I_16_X<0x1A, "cmpnei32", uimm16>;
713 def CMPHSI32 : I_16_X<0x18, "cmphsi32", oimm16>;
714 def CMPLTI32 : I_16_X<0x19, "cmplti32", oimm16>;
715 def CMPLEI32 : CSKYPseudo<(outs CARRY:$ca), (ins GPR:$rx, uimm16:$imm16),
716 "cmplei32\t$rx, $imm16", []>;
718 let Predicates = [iHas2E3] in {
719 def CMPNE32 : R_YX<0x1, 0x4, "cmpne32">;
720 def CMPHS32 : R_YX<0x1, 0x1, "cmphs32">;
721 def CMPLT32 : R_YX<0x1, 0x2, "cmplt32">;
723 def SETC32 : CSKY32Inst<AddrModeNone, 0x31,
724 (outs CARRY:$ca), (ins), "setc32", []> {
725 let Inst{25 - 21} = 0; //rx
726 let Inst{20 - 16} = 0; //ry
727 let Inst{15 - 10} = 0x1;
728 let Inst{9 - 5} = 0x1;
732 def CLRC32 : CSKY32Inst<AddrModeNone, 0x31,
733 (outs CARRY:$ca), (ins), "clrc32", []> {
734 let Inst{25 - 21} = 0; //rx
735 let Inst{20 - 16} = 0; //ry
736 let Inst{15 - 10} = 0x1;
737 let Inst{9 - 5} = 0x4;
742 def TST32 : R_YX<0x8, 0x4, "tst32">;
743 def TSTNBZ32 : R_X<0x8, 0x8,
744 (outs CARRY:$ca), (ins GPR:$rx), "tstnbz32", []>;
747 //===----------------------------------------------------------------------===//
748 // Data move instructions.
749 //===----------------------------------------------------------------------===//
751 let Predicates= [iHasE2] in {
752 let isCodeGenOnly = 1 in {
753 def MOVT32 : R_ZX<0x3, 0x2, "movt32", []>;
754 def MOVF32 : R_ZX<0x3, 0x1, "movf32", []>;
756 def MOVI32 : I_16_MOV<0x10, "movi32", uimm16>;
757 let Size = 4, isCodeGenOnly = 0 in
758 def BGENI : CSKYPseudo<(outs GPR:$dst), (ins uimm5:$imm), "bgeni\t$dst, $imm", []>;
759 def MOVIH32 : I_16_MOV<0x11, "movih32", uimm16_16_xform>;
760 def MVC32 : R_Z_1<0x1, 0x8, "mvc32">;
761 let isCodeGenOnly = 1 in
762 def MOV32 : R_XZ<0x12, 0x1, "mov32">;
764 let usesCustomInserter = 1 in
765 def ISEL32 : CSKYPseudo<(outs GPR:$dst), (ins CARRY:$cond, GPR:$src1, GPR:$src2),
766 "!isel32\t$dst, $src1, src2", [(set GPR:$dst, (select CARRY:$cond, GPR:$src1, GPR:$src2))]>;
769 let Predicates = [iHas2E3] in {
770 def MVCV32 : R_Z_1<0x1, 0x10, "mvcv32">;
771 def CLRF32 : R_Z_2<0xB, 0x1, "clrf32">;
772 def CLRT32 : R_Z_2<0xB, 0x2, "clrt32">;
775 //===----------------------------------------------------------------------===//
776 // Branch and call instructions.
777 //===----------------------------------------------------------------------===//
779 let isBranch = 1, isTerminator = 1 in {
780 let isBarrier = 1, isPredicable = 1 in
781 def BR32 : I_16_L<0x0, (outs), (ins br_symbol:$imm16), "br32\t$imm16",
784 def BT32 : I_16_L<0x3, (outs), (ins CARRY:$ca, br_symbol:$imm16),
785 "bt32\t$imm16", [(brcond CARRY:$ca, bb:$imm16)]>, Requires<[iHasE2]>;
786 def BF32 : I_16_L<0x2, (outs), (ins CARRY:$ca, br_symbol:$imm16),
787 "bf32\t$imm16", []>, Requires<[iHasE2]>;
790 let Predicates = [iHas2E3] in {
791 def BEZ32 : I_16_X_L<0x8, "bez32", br_symbol>;
792 def BNEZ32 : I_16_X_L<0x9, "bnez32", br_symbol>;
793 def BHZ32 : I_16_X_L<0xA, "bhz32", br_symbol>;
794 def BLSZ32 : I_16_X_L<0xB, "blsz32", br_symbol>;
795 def BLZ32 : I_16_X_L<0xC, "blz32", br_symbol>;
796 def BHSZ32 : I_16_X_L<0xD, "bhsz32", br_symbol>;
798 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
799 def JMP32 : I_16_JX<0x6, "jmp32", [(brind GPR:$rx)]>; // jmp to register
800 def JMPI32 : I_16_L<0x16, (outs), (ins constpool_symbol:$imm16),
801 "jmpi32\t$imm16", []>;
804 let isCall = 1, Defs = [ R15 ] in
805 def JSR32 : I_16_JX<0x7, "jsr32", []>;
807 let isCall = 1, Defs = [ R15 ] , mayLoad = 1 in
808 def JSRI32: I_16_L<0x17, (outs),
809 (ins constpool_symbol:$imm16), "jsri32\t$imm16", []>;
812 def BNEZAD32 : CSKY32Inst<AddrModeNone, 0x3a,
813 (outs GPR:$rx_u), (ins GPR:$rx, br_symbol:$imm16), "bnezad32\t$rx, $imm16", []> {
816 let Inst{25 - 21} = 0x1;
817 let Inst{20 - 16} = rx;
818 let Inst{15 - 0} = imm16;
820 let isTerminator = 1;
821 let Constraints = "$rx_u = $rx";
822 let Predicates = [iHas2E3, iHas10E60];
825 def BSR32 : J<0x38, (outs), (ins call_symbol:$offset), "bsr32", []>;
827 def BSR32_BR : J<0x38, (outs), (ins call_symbol:$offset), "bsr32", []>{
828 let isCodeGenOnly = 1;
830 let isTerminator = 1;
832 let isPredicable = 1;
836 //===----------------------------------------------------------------------===//
837 // Symbol address instructions.
838 //===----------------------------------------------------------------------===//
840 def data_symbol_b : data_symbol<"CSKY::fixup_csky_doffset_imm18", 0>;
841 def data_symbol_h : data_symbol<"CSKY::fixup_csky_doffset_imm18_scale2", 1>;
842 def data_symbol_w : data_symbol<"CSKY::fixup_csky_doffset_imm18_scale4", 2> {
843 let ParserMatchClass = DataAsmClass;
846 let Predicates = [iHas2E3] in {
848 def GRS32 : I_18_Z_L<0x3, "grs32\t$rz, $offset",
849 (outs GPR:$rz), (ins bare_symbol:$offset), []>;
851 let Uses = [R28] in {
852 def LRS32B : I_18_Z_L<0x0, "lrs32.b\t$rz, $offset",
853 (outs GPR:$rz), (ins data_symbol_b:$offset), []>;
854 def LRS32H : I_18_Z_L<0x1, "lrs32.h\t$rz, $offset",
855 (outs GPR:$rz), (ins data_symbol_h:$offset), []>;
856 def LRS32W : I_18_Z_L<0x2, "lrs32.w\t$rz, $offset",
857 (outs GPR:$rz), (ins data_symbol_w:$offset), []>;
858 def SRS32B : I_18_Z_L<0x4, "srs32.b\t$rz, $offset",
859 (outs), (ins GPR:$rz, data_symbol_b:$offset), []>;
860 def SRS32H : I_18_Z_L<0x5, "srs32.h\t$rz, $offset",
861 (outs), (ins GPR:$rz, data_symbol_h:$offset), []>;
862 def SRS32W : I_18_Z_L<0x6, "srs32.w\t$rz, $offset",
863 (outs), (ins GPR:$rz, data_symbol_w:$offset), []>;
866 def PUSH32 : I_12_PP<0b11111, 0b00000, (outs), (ins reglist:$regs, variable_ops), "push32 $regs">;
868 let Uses = [R14, R15], isReturn = 1, isTerminator = 1, isBarrier = 1 in
869 def POP32 : I_12_PP<0b11110, 0b00000, (outs), (ins reglist:$regs, variable_ops), "pop32 $regs">;
873 let mayLoad = 1, mayStore = 0 in {
874 def LRW32 : I_16_Z_L<0x14, "lrw32", (ins constpool_symbol:$imm16), []>;
875 let isCodeGenOnly = 1 in
876 def LRW32_Gen : I_16_Z_L<0x14, "lrw32", (ins bare_symbol:$src1, constpool_symbol:$imm16), []>;
879 //===----------------------------------------------------------------------===//
880 // Atomic and fence instructions.
881 //===----------------------------------------------------------------------===//
883 let Predicates = [iHasMP1E2] in {
884 def BRWARW : BAR<0b01111, "bar.brwarw", 0>;
885 def BRWARWS : BAR<0b01111, "bar.brwarws", 1>;
886 def BRARW : BAR<0b00111, "bar.brarw", 0>;
887 def BRARWS : BAR<0b00111, "bar.brarws", 1>;
888 def BRWAW : BAR<0b01110, "bar.brwaw", 0>;
889 def BRWAWS : BAR<0b01110, "bar.brwaws", 1>;
890 def BRAR : BAR<0b00101, "bar.brar", 0>;
891 def BRARS : BAR<0b00101, "bar.brars", 1>;
892 def BWAW : BAR<0b01010, "bar.bwaw", 0>;
893 def BWAWS : BAR<0b01010, "bar.bwaws", 1>;
895 def LDEX32W : I_LD<AddrMode32WD, 0x7, "ldex32.w", uimm12_2>;
896 let Constraints = "$rd = $rz" in
897 def STEX32W : I_LDST<AddrMode32WD, 0x37, 7,
898 (outs GPR:$rd), (ins GPR:$rz, GPR:$rx, uimm12_2:$imm12), "stex32.w", []>;
901 //===----------------------------------------------------------------------===//
902 // Other operation instructions.
903 //===----------------------------------------------------------------------===//
905 let Predicates = [iHas2E3] in {
906 def BREV32 : R_XZ<0x18, 0x10, "brev32">;
907 def ABS32 : R_XZ<0x0, 0x10, "abs32">;
908 def BGENR32 : R_XZ<0x14, 0x2, "bgenr32">;
909 def REVB32 : R_XZ<0x18, 0x4, "revb32">;
910 def REVH32 : R_XZ<0x18, 0x8, "revh32">;
913 let Predicates = [iHasE2] in {
914 def FF0 : R_XZ<0x1F, 0x1, "ff0.32">;
915 def FF1 : R_XZ<0x1F, 0x2, "ff1.32">;
916 def XTRB0 : R_XZ<0x1C, 0x1, "xtrb0.32">;
917 def XTRB1 : R_XZ<0x1C, 0x2, "xtrb1.32">;
918 def XTRB2 : R_XZ<0x1C, 0x4, "xtrb2.32">;
919 def XTRB3 : R_XZ<0x1C, 0x8, "xtrb3.32">;
920 def BTSTI32 : I_5_X<0x0A, 0x4, "btsti32", uimm5, []>;
921 def BCLRI32 : I_5_XZ<0xA, 0x1, "bclri32",
922 (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), []>;
923 def BSETI32 : I_5_XZ<0xA, 0x2, "bseti32",
924 (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), []>;
927 //===----------------------------------------------------------------------===//
928 // Special instructions.
929 //===----------------------------------------------------------------------===//
931 def MFFCR : CSKY32Inst<AddrModeNone, 0x30,
932 (outs GPR:$rx), (ins), "mfcr\t$rx, fcr", []> {
935 let Inst{25 - 21} = 0b00010;
936 let Inst{20 - 16} = 0b00001;
937 let Inst{15 - 10} = 0b011000;
938 let Inst{9 - 5} = 0b00001;
939 let Inst{4 - 0} = rx;
940 let hasSideEffects = 1;
941 let isCodeGenOnly = 1;
944 def MTFCR : CSKY32Inst<AddrModeNone, 0x30,
945 (outs), (ins GPR:$rx), "mtcr\t$rx, fcr", []> {
948 let Inst{25 - 21} = 0b00010;
949 let Inst{20 - 16} = rx;
950 let Inst{15 - 10} = 0b011001;
951 let Inst{9 - 5} = 0b00001;
952 let Inst{4 - 0} = 0b00001;
953 let hasSideEffects = 1;
954 let isCodeGenOnly = 1;
957 def SYNC32 : I_5_IMM5<0x30, 0b000001, 0b00001, "sync32", uimm5, []>;
959 def SYNC0_32 : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins),
961 let Inst{25 - 21} = 0;
962 let Inst{20 - 16} = 0;
963 let Inst{15 - 10} = 0b000001;
964 let Inst{9 - 5} = 0b00001;
968 def SYNC_32_I : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins),
970 let Inst{25 - 21} = 1;
971 let Inst{20 - 16} = 0;
972 let Inst{15 - 10} = 0b000001;
973 let Inst{9 - 5} = 0b00001;
977 def SYNC_32_S : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins),
979 let Inst{25 - 21} = 0b10000;
980 let Inst{20 - 16} = 0;
981 let Inst{15 - 10} = 0b000001;
982 let Inst{9 - 5} = 0b00001;
986 def SYNC_32_IS : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins),
988 let Inst{25 - 21} = 0b10001;
989 let Inst{20 - 16} = 0;
990 let Inst{15 - 10} = 0b000001;
991 let Inst{9 - 5} = 0b00001;
995 let Predicates = [iHas2E3] in {
996 def RFI32 : I_5_XZ_PRIVI<0x11, 0x1, "rfi32">;
997 def SCE32 : I_5_IMM5<0x30, 0b000110, 0b00001, "sce32", uimm4, []>;
999 let Predicates = [HasExtendLrw] in
1000 def IDLY32 : I_5_IMM5<0x30, 0b000111, 0b00001, "idly32", imm5_idly, []>;
1001 def STOP32 : I_5_XZ_PRIVI<0x12, 0x1, "stop32">;
1002 def WAIT32 : I_5_XZ_PRIVI<0x13, 0x1, "wait32">;
1003 def DOZE32 : I_5_XZ_PRIVI<0x14, 0x1, "doze32">;
1004 def WE32 : I_5_XZ_PRIVI<0b010101, 0x1, "we32">;
1005 def SE32 : I_5_XZ_PRIVI<0b010110, 0x1, "se32">;
1006 def WSC32 : I_5_XZ_PRIVI<0b001111, 0x1, "wsc32">;
1008 def CPOP32 : I_CPOP<(outs), (ins uimm5:$cpid, uimm20:$usdef), "cpop32 <$cpid, ${usdef}>">;
1009 def CPRC32 : I_CP<0b0100, (outs CARRY:$ca), (ins uimm5:$cpid, uimm12:$usdef), "cprc32 <$cpid, ${usdef}>">;
1010 def CPRCR32 : I_CP_Z<0b0010, (outs GPR:$rz), (ins uimm5:$cpid, uimm12:$usdef), "cprcr32 $rz, <$cpid, ${usdef}>">;
1011 def CPRGR32 : I_CP_Z<0b0000, (outs GPR:$rz), (ins uimm5:$cpid, uimm12:$usdef), "cprgr32 $rz, <$cpid, ${usdef}>">;
1012 def CPWCR32 : I_CP_Z<0b0011, (outs), (ins GPR:$rz, uimm5:$cpid, uimm12:$usdef), "cpwcr32 $rz, <$cpid, ${usdef}>">;
1013 def CPWGR32 : I_CP_Z<0b0001, (outs), (ins GPR:$rz, uimm5:$cpid, uimm12:$usdef), "cpwgr32 $rz, <$cpid, ${usdef}>">;
1015 let Predicates = [iHas3r2E3r3] in {
1016 def DCACHE_IALL32 : I_5_CACHE<0b100101, 0b01000, "dcache32.iall">;
1017 def DCACHE_CALL32 : I_5_CACHE<0b100101, 0b00100, "dcache32.call">;
1018 def DCACHE_CIALL32 : I_5_CACHE<0b100101, 0b01100, "dcache32.ciall">;
1019 def DCACHE_IVA32 : I_5_X_CACHE<0b100101, 0b01011, "dcache32.iva">;
1020 def DCACHE_ISW32: I_5_X_CACHE<0b100101, 0b01010, "dcache32.isw">;
1021 def DCACHE_CVA32 : I_5_X_CACHE<0b100101, 0b00111, "dcache32.cva">;
1022 def DCACHE_CVAL32 : I_5_X_CACHE<0b100101, 0b10111, "dcache32.cval1">;
1023 def DCACHE_CSW32 : I_5_X_CACHE<0b100101, 0b00110, "dcache32.csw">;
1024 def DCACHE_CIVA32 : I_5_X_CACHE<0b100101, 0b01111, "dcache32.civa">;
1025 def DCACHE_CISW32 : I_5_X_CACHE<0b100101, 0b01110, "dcache32.cisw">;
1027 def ICACHE_IALL32 : I_5_CACHE<0b100100, 0b01000, "icache32.iall">;
1028 def ICACHE_IALLS32 : I_5_CACHE<0b100100, 0b11000, "icache32.ialls">;
1029 def ICACHE_IVA32 : I_5_X_CACHE<0b100100, 0b01011, "icache32.iva">;
1031 def TLBI_VAA32 : I_5_X_CACHE<0b100010, 0b00010, "tlbi32.vaa">;
1032 def TLBI_VAAS32 : I_5_X_CACHE<0b100010, 0b10010, "tlbi32.vaas">;
1033 def TLBI_ASID32 : I_5_X_CACHE<0b100010, 0b00001, "tlbi32.asid">;
1034 def TLBI_ASIDS32 : I_5_X_CACHE<0b100010, 0b10001, "tlbi32.asids">;
1035 def TLBI_VA32 : I_5_X_CACHE<0b100010, 0b00011, "tlbi32.va">;
1036 def TLBI_VAS32 : I_5_X_CACHE<0b100010, 0b10011, "tlbi32.vas">;
1037 def TLBI_ALL32 : I_5_CACHE<0b100010, 0b00000, "tlbi32.all">;
1038 def TLBI_ALLS32 : I_5_CACHE<0b100010, 0b10000, "tlbi32.alls">;
1040 def L2CACHE_IALL : I_5_CACHE<0b100110, 0b01000, "l2cache.iall">;
1041 def L2CACHE_CALL : I_5_CACHE<0b100110, 0b00100, "l2cache.call">;
1042 def L2CACHE_CIALL : I_5_CACHE<0b100110, 0b01100, "l2cache.ciall">;
1045 def PLDR32 :I_PLDR<AddrMode32WD, 0x36, 0b0110, (outs), (ins GPR:$rx, uimm12_2:$imm12), "pldr32", []>;
1046 def PLDW32 :I_PLDR<AddrMode32WD, 0x37, 0b0110, (outs), (ins GPR:$rx, uimm12_2:$imm12), "pldw32", []>;
1048 def TRAP32 : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins uimm2:$imm2), "trap32 ${imm2}", []> {
1051 let Inst{25 - 21} = 0;
1052 let Inst{20 - 16} = 0;
1053 let Inst{15 - 12} = 0b0010;
1054 let Inst{11 - 10} = imm2;
1055 let Inst{9 - 5} = 0b00001;
1056 let Inst{4 - 0} = 0;
1060 //===----------------------------------------------------------------------===//
1061 // Instruction Patterns.
1062 //===----------------------------------------------------------------------===//
1064 // Load & Store Patterns
1065 multiclass LdPat<PatFrag LoadOp, ImmLeaf imm_type, Instruction Inst, ValueType Type> {
1066 def : Pat<(Type (LoadOp GPR:$rs1)), (Inst GPR:$rs1, 0)>;
1067 def : Pat<(Type (LoadOp (i32 frameindex:$rs1))), (Inst (i32 (to_tframeindex tframeindex:$rs1)), 0)>;
1068 def : Pat<(Type (LoadOp (add GPR:$rs1, imm_type:$uimm))),
1069 (Inst GPR:$rs1, imm_type:$uimm)>;
1070 def : Pat<(Type (LoadOp (add frameindex:$rs1, imm_type:$uimm))),
1071 (Inst (i32 (to_tframeindex tframeindex:$rs1)), imm_type:$uimm)>;
1072 def : Pat<(Type (LoadOp (eqToAdd frameindex:$rs1, imm_type:$uimm))),
1073 (Inst (i32 (to_tframeindex tframeindex:$rs1)), imm_type:$uimm)>;
1074 def : Pat<(Type (LoadOp (add GPR:$rs1, tglobaladdr:$gd))),
1075 (Inst GPR:$rs1, tglobaladdr:$gd)>;
1078 defm : LdPat<extloadi8, uimm12, LD32B, i32>;
1079 defm : LdPat<zextloadi8, uimm12, LD32B, i32>;
1080 let Predicates = [iHasE2] in {
1081 defm : LdPat<sextloadi8, uimm12, LD32BS, i32>;
1083 defm : LdPat<extloadi16, uimm12_1, LD32H, i32>;
1084 defm : LdPat<zextloadi16, uimm12_1, LD32H, i32>;
1085 let Predicates = [iHasE2] in {
1086 defm : LdPat<sextloadi16, uimm12_1, LD32HS, i32>;
1088 defm : LdPat<load, uimm12_2, LD32W, i32>;
1090 multiclass LdrPat<PatFrag LoadOp, Instruction Inst, ValueType Type> {
1091 def : Pat<(Type (LoadOp (add GPR:$rs1, GPR:$rs2))), (Inst GPR:$rs1, GPR:$rs2, 0)>;
1092 def : Pat<(Type (LoadOp (add GPR:$rs1, (shl GPR:$rs2, (i32 1))))), (Inst GPR:$rs1, GPR:$rs2, 1)>;
1093 def : Pat<(Type (LoadOp (add GPR:$rs1, (shl GPR:$rs2, (i32 2))))), (Inst GPR:$rs1, GPR:$rs2, 2)>;
1094 def : Pat<(Type (LoadOp (add GPR:$rs1, (shl GPR:$rs2, (i32 3))))), (Inst GPR:$rs1, GPR:$rs2, 3)>;
1097 let Predicates = [iHas2E3] in {
1098 defm : LdrPat<zextloadi8, LDR32B, i32>;
1099 defm : LdrPat<sextloadi8, LDR32BS, i32>;
1100 defm : LdrPat<extloadi8, LDR32BS, i32>;
1101 defm : LdrPat<zextloadi16, LDR32H, i32>;
1102 defm : LdrPat<sextloadi16, LDR32HS, i32>;
1103 defm : LdrPat<extloadi16, LDR32HS, i32>;
1104 defm : LdrPat<load, LDR32W, i32>;
1107 multiclass StPat<PatFrag StoreOp, ValueType Type, ImmLeaf imm_type, Instruction Inst> {
1108 def : Pat<(StoreOp Type:$rs2, GPR:$rs1), (Inst Type:$rs2, GPR:$rs1, 0)>;
1109 def : Pat<(StoreOp Type:$rs2, frameindex:$rs1), (Inst Type:$rs2, (i32 (to_tframeindex tframeindex:$rs1)), 0)>;
1110 def : Pat<(StoreOp Type:$rs2, (add GPR:$rs1, imm_type:$uimm12)),
1111 (Inst Type:$rs2, GPR:$rs1, imm_type:$uimm12)>;
1112 def : Pat<(StoreOp Type:$rs2, (add frameindex:$rs1, imm_type:$uimm12)),
1113 (Inst Type:$rs2, (i32 (to_tframeindex tframeindex:$rs1)), imm_type:$uimm12)>;
1114 def : Pat<(StoreOp Type:$rs2, (eqToAdd frameindex:$rs1, imm_type:$uimm12)),
1115 (Inst Type:$rs2, (i32 (to_tframeindex tframeindex:$rs1)), imm_type:$uimm12)>;
1118 defm : StPat<truncstorei8, i32, uimm12, ST32B>;
1119 defm : StPat<truncstorei16, i32, uimm12_1, ST32H>;
1120 defm : StPat<store, i32, uimm12_2, ST32W>;
1122 multiclass StrPat<PatFrag StoreOp, ValueType Type, Instruction Inst> {
1123 def : Pat<(StoreOp Type:$rz, (add GPR:$rs1, GPR:$rs2)), (Inst Type:$rz, GPR:$rs1, GPR:$rs2, 0)>;
1124 def : Pat<(StoreOp Type:$rz, (add GPR:$rs1, (shl GPR:$rs2, (i32 1)))), (Inst Type:$rz, GPR:$rs1, GPR:$rs2, 1)>;
1125 def : Pat<(StoreOp Type:$rz, (add GPR:$rs1, (shl GPR:$rs2, (i32 2)))), (Inst Type:$rz, GPR:$rs1, GPR:$rs2, 2)>;
1126 def : Pat<(StoreOp Type:$rz, (add GPR:$rs1, (shl GPR:$rs2, (i32 3)))), (Inst Type:$rz, GPR:$rs1, GPR:$rs2, 3)>;
1129 let Predicates = [iHas2E3] in {
1130 defm : StrPat<truncstorei8, i32, STR32B>;
1131 defm : StrPat<truncstorei16, i32, STR32H>;
1132 defm : StrPat<store, i32, STR32W>;
1134 // Sext & Zext Patterns
1135 def : Pat<(sext_inreg GPR:$src, i1), (SEXT32 GPR:$src, 0, 0)>;
1136 def : Pat<(and GPR:$src, 255), (ZEXT32 GPR:$src, 7, 0)>;
1137 def : Pat<(and GPR:$src, 65535), (ZEXT32 GPR:$src, 15, 0)>;
1140 def : Pat<(CSKY_CALL tglobaladdr, tconstpool:$src2), (JSRI32 tconstpool:$src2)>;
1141 def : Pat<(CSKY_CALL texternalsym, tconstpool:$src2), (JSRI32 tconstpool:$src2)>;
1142 def : Pat<(CSKY_TAIL tglobaladdr, tconstpool:$src2), (JMPI32 tconstpool:$src2)>;
1143 def : Pat<(CSKY_TAIL texternalsym, tconstpool:$src2), (JMPI32 tconstpool:$src2)>;
1145 def : Pat<(CSKY_CALLReg GPR:$src), (JSR32 GPR:$src)>;
1146 def : Pat<(CSKY_TAILReg GPR:$src), (JMP32 GPR:$src)>;
1149 // Symbol address Patterns
1150 def : Pat<(CSKY_LOAD_ADDR tglobaladdr, tconstpool:$src2), (LRW32 tconstpool:$src2)>;
1151 def : Pat<(CSKY_LOAD_ADDR tblockaddress, tconstpool:$src2), (LRW32 tconstpool:$src2)>;
1152 def : Pat<(CSKY_LOAD_ADDR tjumptable:$src1, tconstpool:$src2), (LRW32_Gen tjumptable:$src1, tconstpool:$src2)>;
1153 def : Pat<(CSKY_LOAD_ADDR texternalsym, tconstpool:$src2), (LRW32 tconstpool:$src2)>;
1154 def : Pat<(CSKY_LOAD_ADDR tconstpool:$src1, tconstpool:$src2), (LRW32_Gen tconstpool:$src1, tconstpool:$src2)>;
1156 let Predicates = [iHas2E3] in
1157 def : Pat<(i32 constpool:$src), (GRS32 (to_tconstpool tconstpool:$src))>;
1159 let Predicates = [iHasE2] in
1160 def : Pat<(i32 constpool:$src),
1161 (ORI32 (MOVIH32 (to_tconstpool_hi16 tconstpool:$src)),
1162 (to_tconstpool_lo16 tconstpool:$src))>;
1164 def : Pat<(i32 (load constpool:$src)), (LRW32 (to_tconstpool tconstpool:$src))>;
1167 let Predicates = [iHasE2] in {
1168 def : Pat<(brcond CARRY:$ca, bb:$imm16),
1169 (BT32 CARRY:$ca, bb:$imm16)>;
1171 multiclass BTF32Pat0<PatFrag cond0, PatFrag cond1, ImmLeaf imm_ty, Instruction inst> {
1172 def : Pat<(brcond (i32 (cond0 GPR:$rs1, uimm16:$rs2)), bb:$imm16),
1173 (BT32 (inst GPR:$rs1, imm_ty:$rs2), bb:$imm16)>;
1174 def : Pat<(brcond (i32 (cond1 GPR:$rs1, uimm16:$rs2)), bb:$imm16),
1175 (BF32 (inst GPR:$rs1, imm_ty:$rs2), bb:$imm16)>;
1178 defm : BTF32Pat0<setne, seteq, uimm16, CMPNEI32>;
1179 defm : BTF32Pat0<setuge, setult, oimm16, CMPHSI32>;
1180 defm : BTF32Pat0<setlt, setge, oimm16, CMPLTI32>;
1183 let Predicates = [iHas2E3] in {
1185 def : Pat<(brcond (i32 (setne GPR:$rs1, GPR:$rs2)), bb:$imm16),
1186 (BT32 (CMPNE32 GPR:$rs1, GPR:$rs2), bb:$imm16)>;
1187 def : Pat<(brcond (i32 (seteq GPR:$rs1, GPR:$rs2)), bb:$imm16),
1188 (BF32 (CMPNE32 GPR:$rs1, GPR:$rs2), bb:$imm16)>;
1190 multiclass BTF32Pat1<PatFrag cond0, PatFrag cond1, Instruction cmp,
1192 def : Pat<(brcond (i32 (cond0 GPR:$rs1, GPR:$rs2)), bb:$imm16),
1193 (br (cmp GPR:$rs1, GPR:$rs2), bb:$imm16)>;
1194 def : Pat<(brcond (i32 (cond1 GPR:$rs1, GPR:$rs2)), bb:$imm16),
1195 (br (cmp GPR:$rs2, GPR:$rs1), bb:$imm16)>;
1198 defm : BTF32Pat1<setuge, setule, CMPHS32, BT32>;
1199 defm : BTF32Pat1<setult, setugt, CMPHS32, BF32>;
1200 defm : BTF32Pat1<setlt, setgt, CMPLT32, BT32>;
1201 defm : BTF32Pat1<setge, setle, CMPLT32, BF32>;
1203 def : Pat<(brcond (i32 (seteq GPR:$rs1, (i32 0))), bb:$imm16),
1204 (BEZ32 GPR:$rs1, bb:$imm16)>;
1205 def : Pat<(brcond (i32 (setne GPR:$rs1, (i32 0))), bb:$imm16),
1206 (BNEZ32 GPR:$rs1, bb:$imm16)>;
1207 def : Pat<(brcond (i32 (setlt GPR:$rs1, (i32 0))), bb:$imm16),
1208 (BLZ32 GPR:$rs1, bb:$imm16)>;
1209 def : Pat<(brcond (i32 (setlt GPR:$rs1, (i32 1))), bb:$imm16),
1210 (BLSZ32 GPR:$rs1, bb:$imm16)>;
1211 def : Pat<(brcond (i32 (setge GPR:$rs1, (i32 0))), bb:$imm16),
1212 (BHSZ32 GPR:$rs1, bb:$imm16)>;
1213 def : Pat<(brcond (i32 (setge GPR:$rs1, (i32 1))), bb:$imm16),
1214 (BHZ32 GPR:$rs1, bb:$imm16)>;
1215 def : Pat<(brcond (i32 (setgt GPR:$rs1, (i32 0))), bb:$imm16),
1216 (BHZ32 GPR:$rs1, bb:$imm16)>;
1217 def : Pat<(brcond (i32 (setgt GPR:$rs1, (i32 -1))), bb:$imm16),
1218 (BHSZ32 GPR:$rs1, bb:$imm16)>;
1219 def : Pat<(brcond (i32 (setle GPR:$rs1, (i32 0))), bb:$imm16),
1220 (BLSZ32 GPR:$rs1, bb:$imm16)>;
1221 def : Pat<(brcond (i32 (setle GPR:$rs1, (i32 -1))), bb:$imm16),
1222 (BLZ32 GPR:$rs1, bb:$imm16)>;
1225 // Compare Patterns.
1226 let Predicates = [iHas2E3] in {
1227 def : Pat<(setne GPR:$rs1, GPR:$rs2),
1228 (CMPNE32 GPR:$rs1, GPR:$rs2)>;
1229 def : Pat<(i32 (seteq GPR:$rs1, GPR:$rs2)),
1230 (MVCV32 (CMPNE32 GPR:$rs1, GPR:$rs2))>;
1231 def : Pat<(setuge GPR:$rs1, GPR:$rs2),
1232 (CMPHS32 GPR:$rs1, GPR:$rs2)>;
1233 def : Pat<(setule GPR:$rs1, GPR:$rs2),
1234 (CMPHS32 GPR:$rs2, GPR:$rs1)>;
1235 def : Pat<(i32 (setult GPR:$rs1, GPR:$rs2)),
1236 (MVCV32 (CMPHS32 GPR:$rs1, GPR:$rs2))>;
1237 def : Pat<(i32 (setugt GPR:$rs1, GPR:$rs2)),
1238 (MVCV32 (CMPHS32 GPR:$rs2, GPR:$rs1))>;
1239 def : Pat<(setlt GPR:$rs1, GPR:$rs2),
1240 (CMPLT32 GPR:$rs1, GPR:$rs2)>;
1241 def : Pat<(setgt GPR:$rs1, GPR:$rs2),
1242 (CMPLT32 GPR:$rs2, GPR:$rs1)>;
1243 def : Pat<(i32 (setge GPR:$rs1, GPR:$rs2)),
1244 (MVCV32 (CMPLT32 GPR:$rs1, GPR:$rs2))>;
1245 def : Pat<(i32 (setle GPR:$rs1, GPR:$rs2)),
1246 (MVCV32 (CMPLT32 GPR:$rs2, GPR:$rs1))>;
1249 let Predicates = [iHasE2] in {
1250 def : Pat<(setne GPR:$rs1, uimm16:$rs2),
1251 (CMPNEI32 GPR:$rs1, uimm16:$rs2)>;
1252 let Predicates = [iHas2E3] in
1253 def : Pat<(i32 (seteq GPR:$rs1, uimm16:$rs2)),
1254 (MVCV32 (CMPNEI32 GPR:$rs1, uimm16:$rs2))>;
1255 def : Pat<(setuge GPR:$rs1, oimm16:$rs2),
1256 (CMPHSI32 GPR:$rs1, oimm16:$rs2)>;
1257 let Predicates = [iHas2E3] in
1258 def : Pat<(i32 (setult GPR:$rs1, oimm16:$rs2)),
1259 (MVCV32 (CMPHSI32 GPR:$rs1, oimm16:$rs2))>;
1260 def : Pat<(setlt GPR:$rs1, oimm16:$rs2),
1261 (CMPLTI32 GPR:$rs1, oimm16:$rs2)>;
1262 let Predicates = [iHas2E3] in
1263 def : Pat<(i32 (setge GPR:$rs1, oimm16:$rs2)),
1264 (MVCV32 (CMPLTI32 GPR:$rs1, oimm16:$rs2))>;
1268 let Predicates = [iHasE2] in {
1270 def : Pat<(select (i32 (setne GPR:$rs1, uimm16:$rs2)), (add GPR:$rx, uimm5:$imm), GPR:$false),
1271 (INCT32 (CMPNEI32 GPR:$rs1, uimm16:$rs2), GPR:$false, GPR:$rx, uimm5:$imm)>;
1272 def : Pat<(select (i32 (seteq GPR:$rs1, uimm16:$rs2)), (add GPR:$rx, uimm5:$imm), GPR:$false),
1273 (INCF32 (CMPNEI32 GPR:$rs1, uimm16:$rs2), GPR:$false, GPR:$rx, uimm5:$imm)>;
1274 def : Pat<(select (i32 (setne GPR:$rs1, uimm16:$rs2)), (add GPR:$rx, uimm5_neg:$imm), GPR:$false),
1275 (DECT32 (CMPNEI32 GPR:$rs1, uimm16:$rs2), GPR:$false, GPR:$rx,
1276 (imm_neg_XFORM uimm5_neg:$imm))>;
1277 def : Pat<(select (i32 (seteq GPR:$rs1, uimm16:$rs2)), (add GPR:$rx, uimm5_neg:$imm), GPR:$false),
1278 (DECF32 (CMPNEI32 GPR:$rs1, uimm16:$rs2), GPR:$false, GPR:$rx,
1279 (imm_neg_XFORM uimm5:$imm))>;
1281 multiclass INCDECPat<PatFrag cond0, PatFrag cond1, Instruction cmp> {
1282 def : Pat<(select (i32 (cond0 GPR:$rs1, oimm16:$rs2)), (add GPR:$rx, uimm5:$imm), GPR:$other),
1283 (INCT32 (cmp GPR:$rs1, oimm16:$rs2), GPR:$other, GPR:$rx, uimm5:$imm)>;
1284 def : Pat<(select (i32 (cond1 GPR:$rs1, oimm16:$rs2)), (add GPR:$rx, uimm5:$imm), GPR:$other),
1285 (INCF32 (cmp GPR:$rs1, oimm16:$rs2), GPR:$other, GPR:$rx, uimm5:$imm)>;
1286 def : Pat<(select (i32 (cond0 GPR:$rs1, oimm16:$rs2)), GPR:$other, (add GPR:$rx, uimm5:$imm)),
1287 (INCF32 (cmp GPR:$rs1, oimm16:$rs2), GPR:$other, GPR:$rx, uimm5:$imm)>;
1288 def : Pat<(select (i32 (cond1 GPR:$rs1, oimm16:$rs2)), GPR:$other, (add GPR:$rx, uimm5:$imm)),
1289 (INCT32 (cmp GPR:$rs1, oimm16:$rs2), GPR:$other, GPR:$rx, uimm5:$imm)>;
1290 def : Pat<(select (i32 (cond0 GPR:$rs1, oimm16:$rs2)), (add GPR:$rx, uimm5_neg:$imm), GPR:$other),
1291 (DECT32 (cmp GPR:$rs1, oimm16:$rs2), GPR:$other, GPR:$rx,
1292 (imm_neg_XFORM uimm5_neg:$imm))>;
1293 def : Pat<(select (i32 (cond1 GPR:$rs1, oimm16:$rs2)), (add GPR:$rx, uimm5_neg:$imm), GPR:$other),
1294 (DECF32 (cmp GPR:$rs1, oimm16:$rs2), GPR:$other, GPR:$rx,
1295 (imm_neg_XFORM uimm5_neg:$imm))>;
1296 def : Pat<(select (i32 (cond0 GPR:$rs1, oimm16:$rs2)), GPR:$other, (add GPR:$rx, uimm5_neg:$imm)),
1297 (DECF32 (cmp GPR:$rs1, oimm16:$rs2), GPR:$other, GPR:$rx,
1298 (imm_neg_XFORM uimm5_neg:$imm))>;
1299 def : Pat<(select (i32 (cond1 GPR:$rs1, oimm16:$rs2)), GPR:$other, (add GPR:$rx, uimm5_neg:$imm)),
1300 (DECT32 (cmp GPR:$rs1, oimm16:$rs2), GPR:$other, GPR:$rx,
1301 (imm_neg_XFORM uimm5_neg:$imm))>;
1304 defm : INCDECPat<setuge, setult, CMPHSI32>;
1305 defm : INCDECPat<setlt, setge, CMPLTI32>;
1307 def : Pat<(select CARRY:$ca, (add GPR:$rx, uimm5:$imm), GPR:$other),
1308 (INCT32 CARRY:$ca, GPR:$other, GPR:$rx, uimm5:$imm)>;
1309 def : Pat<(select CARRY:$ca, GPR:$other, (add GPR:$rx, uimm5:$imm)),
1310 (INCF32 CARRY:$ca, GPR:$other, GPR:$rx, uimm5:$imm)>;
1311 def : Pat<(select (and CARRY:$ca, 1), (add GPR:$rx, uimm5:$imm), GPR:$other),
1312 (INCT32 CARRY:$ca, GPR:$other, GPR:$rx, uimm5:$imm)>;
1313 def : Pat<(select (and CARRY:$ca, 1), GPR:$other, (add GPR:$rx, uimm5:$imm)),
1314 (INCF32 CARRY:$ca, GPR:$other, GPR:$rx, uimm5:$imm)>;
1316 def : Pat<(select CARRY:$ca, (add GPR:$rx, uimm5_neg:$imm), GPR:$other),
1317 (DECT32 CARRY:$ca, GPR:$other, GPR:$rx, (imm_neg_XFORM uimm5_neg:$imm))>;
1318 def : Pat<(select CARRY:$ca, GPR:$other, (add GPR:$rx, uimm5_neg:$imm)),
1319 (DECF32 CARRY:$ca, GPR:$other, GPR:$rx, (imm_neg_XFORM uimm5_neg:$imm))>;
1320 def : Pat<(select (and CARRY:$ca, 1), (add GPR:$rx, uimm5_neg:$imm), GPR:$other),
1321 (DECT32 CARRY:$ca, GPR:$other, GPR:$rx, (imm_neg_XFORM uimm5_neg:$imm))>;
1322 def : Pat<(select (and CARRY:$ca, 1), GPR:$other, (add GPR:$rx, uimm5_neg:$imm)),
1323 (DECF32 CARRY:$ca, GPR:$other, GPR:$rx, (imm_neg_XFORM uimm5_neg:$imm))>;
1325 def : Pat<(select CARRY:$ca, GPR:$rx, GPR:$false),
1326 (MOVT32 CARRY:$ca, GPR:$rx, GPR:$false)>;
1327 def : Pat<(select (and CARRY:$ca, 1), GPR:$rx, GPR:$false),
1328 (MOVT32 CARRY:$ca, GPR:$rx, GPR:$false)>;
1330 multiclass MOVTF32Pat0<PatFrag cond0, PatFrag cond1, ImmLeaf imm_ty, Instruction inst> {
1331 def : Pat<(select (i32 (cond0 GPR:$rs1, imm_ty:$rs2)), GPR:$rx, GPR:$false),
1332 (MOVT32 (inst GPR:$rs1, imm_ty:$rs2), GPR:$rx, GPR:$false)>;
1333 def : Pat<(select (i32 (cond1 GPR:$rs1, imm_ty:$rs2)), GPR:$rx, GPR:$false),
1334 (MOVF32 (inst GPR:$rs1, imm_ty:$rs2), GPR:$rx, GPR:$false)>;
1337 defm : MOVTF32Pat0<setne, seteq, uimm16, CMPNEI32>;
1338 defm : MOVTF32Pat0<setuge, setult, oimm16, CMPHSI32>;
1339 defm : MOVTF32Pat0<setlt, setge, oimm16, CMPLTI32>;
1341 def : Pat<(select CARRY:$ca, GPR:$rx, GPR:$false),
1342 (ISEL32 CARRY:$ca, GPR:$rx, GPR:$false)>;
1343 def : Pat<(select (and CARRY:$ca, 1), GPR:$rx, GPR:$false),
1344 (ISEL32 CARRY:$ca, GPR:$rx, GPR:$false)>;
1348 let Predicates = [iHas2E3] in {
1349 def : Pat<(select (i32 (setne GPR:$rs1, GPR:$rs2)), (add GPR:$rx, uimm5:$imm), GPR:$false),
1350 (INCT32 (CMPNE32 GPR:$rs1, GPR:$rs2), GPR:$false, GPR:$rx, uimm5:$imm)>;
1351 def : Pat<(select (i32 (seteq GPR:$rs1, GPR:$rs2)), (add GPR:$rx, uimm5:$imm), GPR:$false),
1352 (INCF32 (CMPNE32 GPR:$rs1, GPR:$rs2), GPR:$false, GPR:$rx, uimm5:$imm)>;
1353 def : Pat<(select (i32 (setne GPR:$rs1, GPR:$rs2)), (add GPR:$rx, uimm5_neg:$imm), GPR:$false),
1354 (DECT32 (CMPNE32 GPR:$rs1, GPR:$rs2), GPR:$false, GPR:$rx,
1355 (imm_neg_XFORM uimm5_neg:$imm))>;
1356 def : Pat<(select (i32 (seteq GPR:$rs1, GPR:$rs2)), (add GPR:$rx, uimm5_neg:$imm), GPR:$false),
1357 (DECF32 (CMPNE32 GPR:$rs1, GPR:$rs2), GPR:$false, GPR:$rx,
1358 (imm_neg_XFORM uimm5_neg:$imm))>;
1360 multiclass INCPat<PatFrag cond0, PatFrag cond1, Instruction cmp, Instruction inc0, Instruction inc1> {
1361 def : Pat<(select (i32 (cond0 GPR:$rs1, GPR:$rs2)), (add GPR:$rx, uimm5:$imm), GPR:$other),
1362 (inc0 (cmp GPR:$rs1, GPR:$rs2), GPR:$other, GPR:$rx, uimm5:$imm)>;
1363 def : Pat<(select (i32 (cond0 GPR:$rs1, GPR:$rs2)), GPR:$other, (add GPR:$rx, uimm5:$imm)),
1364 (inc1 (cmp GPR:$rs1, GPR:$rs2), GPR:$other, GPR:$rx, uimm5:$imm)>;
1365 def : Pat<(select (i32 (cond1 GPR:$rs1, GPR:$rs2)), (add GPR:$rx, uimm5:$imm), GPR:$other),
1366 (inc0 (cmp GPR:$rs2, GPR:$rs1), GPR:$other, GPR:$rx, uimm5:$imm)>;
1367 def : Pat<(select (i32 (cond1 GPR:$rs1, GPR:$rs2)), GPR:$other, (add GPR:$rx, uimm5:$imm)),
1368 (inc1 (cmp GPR:$rs2, GPR:$rs1), GPR:$other, GPR:$rx, uimm5:$imm)>;
1371 defm : INCPat<setuge, setule, CMPHS32, INCT32, INCF32>;
1372 defm : INCPat<setult, setugt, CMPHS32, INCF32, INCT32>;
1373 defm : INCPat<setlt, setgt, CMPLT32, INCT32, INCF32>;
1374 defm : INCPat<setge, setle, CMPLT32, INCF32, INCT32>;
1376 multiclass DECPat<PatFrag cond0, PatFrag cond1, Instruction cmp, Instruction dec0, Instruction dec1> {
1377 def : Pat<(select (i32 (cond0 GPR:$rs1, GPR:$rs2)), (add GPR:$rx, uimm5_neg:$imm), GPR:$other),
1378 (dec0 (cmp GPR:$rs1, GPR:$rs2), GPR:$other, GPR:$rx,
1379 (imm_neg_XFORM uimm5_neg:$imm))>;
1380 def : Pat<(select (i32 (cond0 GPR:$rs1, GPR:$rs2)), GPR:$other, (add GPR:$rx, uimm5_neg:$imm)),
1381 (dec1 (cmp GPR:$rs1, GPR:$rs2), GPR:$other, GPR:$rx,
1382 (imm_neg_XFORM uimm5_neg:$imm))>;
1383 def : Pat<(select (i32 (cond1 GPR:$rs1, GPR:$rs2)), (add GPR:$rx, uimm5_neg:$imm), GPR:$other),
1384 (dec0 (cmp GPR:$rs2, GPR:$rs1), GPR:$other, GPR:$rx,
1385 (imm_neg_XFORM uimm5_neg:$imm))>;
1386 def : Pat<(select (i32 (cond1 GPR:$rs1, GPR:$rs2)), GPR:$other, (add GPR:$rx, uimm5_neg:$imm)),
1387 (dec1 (cmp GPR:$rs2, GPR:$rs1), GPR:$other, GPR:$rx,
1388 (imm_neg_XFORM uimm5_neg:$imm))>;
1391 defm : DECPat<setuge, setule, CMPHS32, DECT32, DECF32>;
1392 defm : DECPat<setult, setugt, CMPHS32, DECF32, DECT32>;
1393 defm : DECPat<setlt, setgt, CMPLT32, DECT32, DECF32>;
1394 defm : DECPat<setge, setle, CMPLT32, DECF32, DECT32>;
1396 def : Pat<(select (i32 (setne GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false),
1397 (MOVT32 (CMPNE32 GPR:$rs1, GPR:$rs2), GPR:$rx, GPR:$false)>;
1398 def : Pat<(select (i32 (seteq GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false),
1399 (MOVF32 (CMPNE32 GPR:$rs1, GPR:$rs2), GPR:$rx, GPR:$false)>;
1401 multiclass MOVTF32Pat1<PatFrag cond0, PatFrag cond1, Instruction cmp_inst,
1402 Instruction mov_inst> {
1403 def : Pat<(select (i32 (cond0 GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false),
1404 (mov_inst (cmp_inst GPR:$rs1, GPR:$rs2), GPR:$rx, GPR:$false)>;
1405 def : Pat<(select (i32 (cond1 GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false),
1406 (mov_inst (cmp_inst GPR:$rs2, GPR:$rs1), GPR:$rx, GPR:$false)>;
1409 defm : MOVTF32Pat1<setuge, setule, CMPHS32, MOVT32>;
1410 defm : MOVTF32Pat1<setult, setugt, CMPHS32, MOVF32>;
1411 defm : MOVTF32Pat1<setlt, setgt, CMPLT32, MOVT32>;
1412 defm : MOVTF32Pat1<setge, setle, CMPLT32, MOVF32>;
1414 def : Pat<(select CARRY:$ca, (i32 0), GPR:$other),
1415 (CLRT32 CARRY:$ca, GPR:$other)>;
1416 def : Pat<(select CARRY:$ca, GPR:$other, (i32 0)),
1417 (CLRF32 CARRY:$ca, GPR:$other)>;
1420 // Constant materialize patterns.
1421 let Predicates = [iHasE2] in
1422 def : Pat<(i32 imm:$imm),
1423 (ORI32 (MOVIH32 (uimm32_hi16 imm:$imm)), (uimm32_lo16 imm:$imm))>;
1425 // Other operations.
1426 let Predicates = [iHasE2] in {
1427 def : Pat<(rotl GPR:$rs1, GPR:$rs2),
1428 (ROTL32 GPR:$rs1, (ANDI32 GPR:$rs2, 0x1f))>;
1429 let Predicates = [iHas2E3] in {
1430 def : Pat<(bitreverse GPR:$rx), (BREV32 GPR:$rx)>;
1431 def : Pat<(bswap GPR:$rx), (REVB32 GPR:$rx)>;
1433 def : Pat<(i32 (ctlz GPR:$rx)), (FF1 GPR:$rx)>;
1436 //===----------------------------------------------------------------------===//
1437 // Pseudo for assembly
1438 //===----------------------------------------------------------------------===//
1440 let isCall = 1, Defs = [ R15 ], mayLoad = 1, Size = 4, isCodeGenOnly = 0 in
1441 def JBSR32 : CSKYPseudo<(outs), (ins call_symbol:$src1), "jbsr32\t$src1", []>;
1443 def JBR32 : CSKYPseudo<(outs), (ins br_symbol:$src1), "jbr32\t$src1", []> {
1445 let isTerminator = 1;
1447 let isIndirectBranch = 1;
1452 def JBT32 : CSKYPseudo<(outs), (ins CARRY:$ca, br_symbol:$src1), "jbt32\t$src1", []> {
1454 let isTerminator = 1;
1455 let isIndirectBranch = 1;
1460 def JBF32 : CSKYPseudo<(outs), (ins CARRY:$ca, br_symbol:$src1), "jbf32\t$src1", []> {
1462 let isTerminator = 1;
1463 let isIndirectBranch = 1;
1468 def JBT_E : CSKYPseudo<(outs), (ins CARRY:$ca, br_symbol:$src1), "!jbt_e\t$src1", []> {
1470 let isTerminator = 1;
1471 let isIndirectBranch = 1;
1476 def JBF_E : CSKYPseudo<(outs), (ins CARRY:$ca, br_symbol:$src1), "!jbf_e\t$src1", []> {
1478 let isTerminator = 1;
1479 let isIndirectBranch = 1;
1484 let mayLoad = 1, Size = 2, isCodeGenOnly = 0 in
1485 def PseudoLRW32 : CSKYPseudo<(outs GPR:$rz), (ins bare_symbol:$src), "lrw32 $rz, $src", []>;
1487 let mayLoad = 1, Size = 4, isCodeGenOnly = 0 in
1488 def PseudoJSRI32 : CSKYPseudo<(outs), (ins call_symbol:$src), "jsri32 $src", []>;
1490 let mayLoad = 1, Size = 4, isCodeGenOnly = 0 in
1491 def PseudoJMPI32 : CSKYPseudo<(outs), (ins br_symbol:$src), "jmpi32 $src", []>;
1493 let isNotDuplicable = 1, mayLoad = 1, mayStore = 0, Size = 8 in
1494 def PseudoTLSLA32 : CSKYPseudo<(outs GPR:$dst1, GPR:$dst2),
1495 (ins constpool_symbol:$src, i32imm:$label), "!tlslrw32\t$dst1, $dst2, $src, $label", []>;
1497 let hasSideEffects = 0, isNotDuplicable = 1 in
1498 def CONSTPOOL_ENTRY : CSKYPseudo<(outs),
1499 (ins i32imm:$instid, i32imm:$cpidx, i32imm:$size), "", []>;
1501 include "CSKYInstrInfo16Instr.td"
1502 include "CSKYInstrInfoF1.td"
1503 include "CSKYInstrInfoF2.td"
1504 include "CSKYInstrAlias.td"