1//===-- CSKYInstrInfo.td - Target Description for CSKY -----*- tablegen -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file describes the CSKY instructions in TableGen format.
10//
11//===----------------------------------------------------------------------===//
12
13
14//===----------------------------------------------------------------------===//
15// CSKY specific DAG Nodes.
16//===----------------------------------------------------------------------===//
17
18// Target-independent type requirements, but with target-specific formats.
19def SDT_CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>,
20                                       SDTCisVT<1, i32>]>;
21
22def SDT_CallSeqEnd   : SDCallSeqEnd<[SDTCisVT<0, i32>,
23                                     SDTCisVT<1, i32>]>;
24
25def SDT_CSKYCall : SDTypeProfile<0, 2, [SDTCisVT<0, iPTR>, SDTCisVT<1, iPTR>]>;
26
27def SDT_CSKYCallReg : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;
28
29def SDT_CSKY_LOADADDR : SDTypeProfile<1, 2, [SDTCisVT<0, i32>,
30                        SDTCisVT<1, iPTR>, SDTCisVT<2, iPTR>]>;
31
32def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_CallSeqStart,
33                           [SDNPHasChain, SDNPOutGlue]>;
34def callseq_end   : SDNode<"ISD::CALLSEQ_END", SDT_CallSeqEnd,
35                           [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
36
37def CSKY_RET : SDNode<"CSKYISD::RET", SDTNone,
38    [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
39
40def CSKY_CALL : SDNode<"CSKYISD::CALL", SDT_CSKYCall,
41  [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, SDNPVariadic]>;
42
43def CSKY_CALLReg : SDNode<"CSKYISD::CALLReg", SDT_CSKYCallReg,
44  [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, SDNPVariadic]>;
45
46def CSKY_TAIL : SDNode<"CSKYISD::TAIL", SDT_CSKYCall,
47  [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, SDNPVariadic]>;
48
49def CSKY_TAILReg : SDNode<"CSKYISD::TAILReg", SDT_CSKYCallReg,
50  [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, SDNPVariadic]>;
51
52def CSKY_LOAD_ADDR : SDNode<"CSKYISD::LOAD_ADDR", SDT_CSKY_LOADADDR>;
53
54//===----------------------------------------------------------------------===//
55// Operand and SDNode transformation definitions.
56//===----------------------------------------------------------------------===//
57class 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);
61}
62
63class SImmAsmOperand<int width, string suffix = "">
64    : ImmAsmOperand<"S", width, suffix> {
65}
66
67class UImmAsmOperand<int width, string suffix = "">
68    : ImmAsmOperand<"U", width, suffix> {
69}
70
71class OImmAsmOperand<int width, string suffix = "">
72    : ImmAsmOperand<"O", width, suffix> {
73}
74
75def to_tframeindex : SDNodeXForm<frameindex, [{
76  auto FI = cast<FrameIndexSDNode>(N);
77  return CurDAG->getTargetFrameIndex(FI->getIndex(), TLI->getPointerTy(CurDAG->getDataLayout()));
78}]>;
79
80def 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);
84}]>;
85
86def 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);
90}]>;
91
92def 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);
96}]>;
97
98class 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#">";
103}
104
105class uimm<int num, int shift = 0> : Operand<i32>,
106  ImmLeaf<i32, "return isShiftedUInt<"#num#", "#shift#">(Imm);"> {
107  let EncoderMethod = "getImmOpValue<"#shift#">";
108  let ParserMatchClass =
109    !if(!ne(shift, 0),
110        UImmAsmOperand<num, "Shift"#shift>,
111        UImmAsmOperand<num>);
112  let DecoderMethod = "decodeUImmOperand<"#num#", "#shift#">";
113}
114
115class simm<int num, int shift = 0> : Operand<i32>,
116  ImmLeaf<i32, "return isShiftedInt<"#num#", "#shift#">(Imm);"> {
117  let EncoderMethod = "getImmOpValue<"#shift#">";
118  let ParserMatchClass = SImmAsmOperand<num>;
119  let DecoderMethod = "decodeSImmOperand<"#num#", "#shift#">";
120}
121
122def nimm_XFORM : SDNodeXForm<imm, [{
123  return CurDAG->getTargetConstant(~N->getSExtValue(), SDLoc(N), MVT::i32);
124}]>;
125class nimm<int num> : Operand<i32>,
126  ImmLeaf<i32, "return isUInt<"#num#">(~Imm);", nimm_XFORM> {
127  let ParserMatchClass = UImmAsmOperand<num>;
128}
129
130def uimm32_hi16 : SDNodeXForm<imm, [{
131  return CurDAG->getTargetConstant((N->getZExtValue() >> 16) & 0xFFFF,
132    SDLoc(N), MVT::i32);
133}]>;
134def uimm32_lo16 : SDNodeXForm<imm, [{
135  return CurDAG->getTargetConstant(N->getZExtValue()& 0xFFFF, SDLoc(N), MVT::i32);
136}]>;
137def uimm16_16_xform : Operand<i32>,
138  ImmLeaf<i32, "return isShiftedUInt<16, 16>(Imm);", uimm32_hi16> {
139  let ParserMatchClass = UImmAsmOperand<16>;
140  let EncoderMethod = "getImmOpValue";
141}
142
143def uimm_shift : Operand<i32>, ImmLeaf<i32, "return isUInt<2>(Imm);"> {
144  let EncoderMethod = "getImmShiftOpValue";
145  let ParserMatchClass = UImmAsmOperand<2>;
146  let DecoderMethod = "decodeImmShiftOpValue";
147}
148
149def CSKYSymbol : AsmOperandClass {
150  let Name = "CSKYSymbol";
151  let RenderMethod = "addImmOperands";
152  let DiagnosticType = "InvalidCSKYSymbol";
153  let ParserMethod = "parseCSKYSymbol";
154}
155
156def br_symbol : Operand<iPTR> {
157  let EncoderMethod =
158    "getBranchSymbolOpValue<CSKY::fixup_csky_pcrel_imm16_scale2>";
159  let ParserMatchClass = CSKYSymbol;
160  let DecoderMethod = "decodeSImmOperand<16, 1>";
161  let PrintMethod = "printCSKYSymbolOperand";
162  let OperandType = "OPERAND_PCREL";
163}
164
165def call_symbol : Operand<iPTR> {
166  let ParserMatchClass = CSKYSymbol;
167  let EncoderMethod = "getCallSymbolOpValue";
168  let DecoderMethod = "decodeSImmOperand<26, 1>";
169  let PrintMethod = "printCSKYSymbolOperand";
170  let OperandType = "OPERAND_PCREL";
171}
172
173def Constpool : AsmOperandClass {
174  let Name = "Constpool";
175  let RenderMethod = "addConstpoolOperands";
176  let DiagnosticType = "InvalidConstpool";
177  let ParserMethod = "parseConstpoolSymbol";
178}
179
180def constpool_symbol : Operand<iPTR> {
181  let ParserMatchClass = Constpool;
182  let EncoderMethod =
183    "getConstpoolSymbolOpValue<CSKY::fixup_csky_pcrel_uimm16_scale4>";
184  let DecoderMethod = "decodeUImmOperand<16, 2>";
185  let PrintMethod = "printConstpool";
186  let OperandType = "OPERAND_PCREL";
187}
188
189def DataAsmClass : AsmOperandClass {
190  let Name = "DataSymbol";
191  let RenderMethod = "addConstpoolOperands";
192  let DiagnosticType = "InvalidConstpool";
193  let ParserMethod = "parseDataSymbol";
194}
195
196class data_symbol<string reloc, int shift> : Operand<iPTR> {
197  let ParserMatchClass = Constpool;
198  let EncoderMethod =
199    "getDataSymbolOpValue<"#reloc#">";
200  let DecoderMethod = "decodeUImmOperand<18, "#shift#">";
201  let PrintMethod = "printDataSymbol";
202}
203
204def bare_symbol : Operand<iPTR> {
205  let ParserMatchClass = CSKYSymbol;
206  let EncoderMethod = "getBareSymbolOpValue";
207  let PrintMethod = "printCSKYSymbolOperand";
208  let DecoderMethod = "decodeSImmOperand<18, 1>";
209  let OperandType = "OPERAND_PCREL";
210}
211
212def oimm3 : oimm<3> {
213  let MCOperandPredicate = [{
214    int64_t Imm;
215    if (MCOp.evaluateAsConstantImm(Imm))
216      return isUInt<3>(Imm - 1);
217    return MCOp.isBareSymbolRef();
218  }];
219}
220def oimm4 : oimm<4>;
221def oimm5 : oimm<5> {
222  let MCOperandPredicate = [{
223    int64_t Imm;
224    if (MCOp.evaluateAsConstantImm(Imm))
225      return isUInt<5>(Imm - 1);
226    return MCOp.isBareSymbolRef();
227  }];
228}
229def oimm6 : oimm<6>;
230
231def imm5_idly : Operand<i32>, ImmLeaf<i32,
232  "return Imm <= 32 && Imm >= 0;"> {
233  let EncoderMethod = "getImmOpValueIDLY";
234  let DecoderMethod = "decodeOImmOperand<5>";
235}
236
237def oimm8 : oimm<8> {
238  let MCOperandPredicate = [{
239    int64_t Imm;
240    if (MCOp.evaluateAsConstantImm(Imm))
241      return isUInt<8>(Imm - 1);
242    return MCOp.isBareSymbolRef();
243  }];
244}
245def oimm12 : oimm<12> {
246  let MCOperandPredicate = [{
247    int64_t Imm;
248    if (MCOp.evaluateAsConstantImm(Imm))
249      return isUInt<12>(Imm - 1);
250    return MCOp.isBareSymbolRef();
251  }];
252}
253def oimm16 : oimm<16> {
254  let MCOperandPredicate = [{
255    int64_t Imm;
256    if (MCOp.evaluateAsConstantImm(Imm))
257      return isUInt<16>(Imm - 1);
258    return MCOp.isBareSymbolRef();
259  }];
260}
261
262def nimm12 : nimm<12>;
263
264def uimm1 : uimm<1>;
265def uimm2 : uimm<2>;
266
267
268def uimm2_jmpix : Operand<i32>,
269  ImmLeaf<i32, "return Imm == 16 || Imm == 24 || Imm == 32 || Imm == 40;"> {
270  let EncoderMethod = "getImmJMPIX";
271  let DecoderMethod = "decodeJMPIXImmOperand";
272}
273
274def uimm3 : uimm<3>;
275def uimm4 : uimm<4>;
276def uimm5 : uimm<5> {
277  let MCOperandPredicate = [{
278    int64_t Imm;
279    if (MCOp.evaluateAsConstantImm(Imm))
280      return isShiftedUInt<5, 0>(Imm);
281    return MCOp.isBareSymbolRef();
282  }];
283}
284def uimm5_msb_size : uimm<5> {
285  let EncoderMethod = "getImmOpValueMSBSize";
286}
287
288def uimm5_1 : uimm<5, 1> {
289  let MCOperandPredicate = [{
290    int64_t Imm;
291    if (MCOp.evaluateAsConstantImm(Imm))
292      return isShiftedUInt<5, 1>(Imm);
293    return MCOp.isBareSymbolRef();
294  }];
295}
296def uimm5_2 : uimm<5, 2> {
297  let MCOperandPredicate = [{
298    int64_t Imm;
299    if (MCOp.evaluateAsConstantImm(Imm))
300      return isShiftedUInt<5, 2>(Imm);
301    return MCOp.isBareSymbolRef();
302  }];
303}
304def uimm6 : uimm<6>;
305def uimm7 : uimm<7>;
306def uimm7_1 : uimm<7, 1>;
307def uimm7_2 : uimm<7, 2>{
308  let MCOperandPredicate = [{
309    int64_t Imm;
310    if (MCOp.evaluateAsConstantImm(Imm))
311      return isShiftedUInt<7, 2>(Imm);
312    return MCOp.isBareSymbolRef();
313  }];
314}
315def uimm7_3 : uimm<7, 3>;
316def uimm8 : uimm<8> {
317  let MCOperandPredicate = [{
318    int64_t Imm;
319    if (MCOp.evaluateAsConstantImm(Imm))
320      return isShiftedUInt<8, 0>(Imm);
321    return MCOp.isBareSymbolRef();
322  }];
323}
324def uimm8_2 : uimm<8, 2> {
325  let MCOperandPredicate = [{
326    int64_t Imm;
327    if (MCOp.evaluateAsConstantImm(Imm))
328      return isShiftedUInt<8, 2>(Imm);
329    return MCOp.isBareSymbolRef();
330  }];
331}
332def uimm8_3 : uimm<8, 3>;
333def uimm8_8 : uimm<8, 8>;
334def uimm8_16 : uimm<8, 16>;
335def uimm8_24 : uimm<8, 24>;
336def uimm12 : uimm<12>  {
337  let MCOperandPredicate = [{
338    int64_t Imm;
339    if (MCOp.evaluateAsConstantImm(Imm))
340      return isShiftedUInt<12, 0>(Imm);
341    return MCOp.isBareSymbolRef();
342  }];
343}
344def uimm12_1 : uimm<12, 1> {
345  let MCOperandPredicate = [{
346    int64_t Imm;
347    if (MCOp.evaluateAsConstantImm(Imm))
348      return isShiftedUInt<12, 1>(Imm);
349    return MCOp.isBareSymbolRef();
350  }];
351}
352def uimm12_2 : uimm<12, 2> {
353  let MCOperandPredicate = [{
354    int64_t Imm;
355    if (MCOp.evaluateAsConstantImm(Imm))
356      return isShiftedUInt<12, 2>(Imm);
357    return MCOp.isBareSymbolRef();
358  }];
359}
360def uimm16 : uimm<16> {
361  let MCOperandPredicate = [{
362    int64_t Imm;
363    if (MCOp.evaluateAsConstantImm(Imm))
364      return isShiftedUInt<16, 0>(Imm);
365    return MCOp.isBareSymbolRef();
366  }];
367}
368def uimm16_8 : uimm<16, 8>;
369def uimm16_16 : uimm<16, 16>;
370def uimm20 : uimm<20>;
371def uimm24 : uimm<24>;
372def uimm24_8 : uimm<24, 8>;
373
374def simm8_2 : simm<8, 2>;
375
376class RegSeqAsmOperand<string Suffix = ""> : AsmOperandClass {
377  let Name = "RegSeq"#Suffix;
378  let RenderMethod = "addRegSeqOperands";
379  let DiagnosticType = "InvalidRegSeq";
380  let ParserMethod = "parseRegSeq";
381}
382
383def regseq : Operand<iPTR> {
384  let EncoderMethod = "getRegisterSeqOpValue";
385  let ParserMatchClass = RegSeqAsmOperand<"">;
386  let PrintMethod = "printRegisterSeq";
387  let DecoderMethod = "DecodeRegSeqOperand";
388  let MIOperandInfo = (ops GPR, uimm5);
389}
390
391def RegListAsmOperand : AsmOperandClass {
392  let Name = "RegList";
393  let RenderMethod = "addRegListOperands";
394  let DiagnosticType = "InvalidRegList";
395  let ParserMethod = "parseRegList";
396}
397
398def reglist : Operand<iPTR> {
399  let ParserMatchClass = RegListAsmOperand;
400  let PrintMethod = "printRegisterList";
401}
402
403def PSRFlag : AsmOperandClass {
404  let Name = "PSRFlag";
405  let RenderMethod = "addImmOperands";
406  let DiagnosticType = "InvalidPSRFlag";
407  let ParserMethod = "parsePSRFlag";
408}
409
410def psrflag : Operand<i32>, ImmLeaf<i32, "return isShiftedUInt<5, 0>(Imm);"> {
411  let EncoderMethod = "getImmOpValue";
412  let ParserMatchClass = PSRFlag;
413  let PrintMethod = "printPSRFlag";
414}
415
416//===----------------------------------------------------------------------===//
417// Instruction Formats
418//===----------------------------------------------------------------------===//
419
420include "CSKYInstrFormats.td"
421
422//===----------------------------------------------------------------------===//
423// Instruction definitions.
424//===----------------------------------------------------------------------===//
425
426class TriOpFrag<dag res> : PatFrag<(ops node: $LHS, node:$MHS, node:$RHS), res>;
427class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
428class UnOpFrag<dag res> : PatFrag<(ops node:$Src), res>;
429
430def eqToAdd : PatFrag<(ops node:$lhs, node:$rhs), (or node:$lhs, node:$rhs), [{
431  return isOrEquivalentToAdd(N);
432}]>;
433
434def BaseAddr : ComplexPattern<iPTR, 1, "SelectBaseAddr">;
435
436
437//===----------------------------------------------------------------------===//
438// CSKYPseudo
439//===----------------------------------------------------------------------===//
440
441// Pessimistically assume the stack pointer will be clobbered
442let Defs = [R14], Uses = [R14] in {
443def ADJCALLSTACKDOWN : CSKYPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
444  "!ADJCALLSTACKDOWN $amt1, $amt2", [(callseq_start timm:$amt1, timm:$amt2)]>;
445def ADJCALLSTACKUP   : CSKYPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
446  "!ADJCALLSTACKUP $amt1, $amt2", [(callseq_end timm:$amt1, timm:$amt2)]>;
447} // Defs = [R14], Uses = [R14]
448
449
450//===----------------------------------------------------------------------===//
451// Basic ALU instructions.
452//===----------------------------------------------------------------------===//
453
454let Predicates = [iHasE2] in {
455  let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
456  let isAdd = 1 in
457  def ADDI32 : I_12<0x0, "addi32", add, oimm12>;
458  def SUBI32 : I_12<0x1, "subi32", sub, oimm12>;
459  def ORI32 : I_16_ZX<"ori32", uimm16,
460  [(set GPR:$rz, (or GPR:$rx, uimm16:$imm16))]>;
461  def XORI32 : I_12<0x4, "xori32", xor, uimm12>;
462  def ANDI32 : I_12<0x2, "andi32", and, uimm12>;
463  def ANDNI32 : I_12<0x3, "andni32", and, nimm12>;
464  def LSLI32 : I_5_XZ<0x12, 0x1, "lsli32",
465    (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5),
466    [(set GPR:$rz, (shl GPR:$rx, uimm5:$imm5))]>;
467  def LSRI32 : I_5_XZ<0x12, 0x2, "lsri32",
468    (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5),
469    [(set GPR:$rz, (srl GPR:$rx, uimm5:$imm5))]>;
470  def ASRI32 : I_5_XZ<0x12, 0x4, "asri32",
471    (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5),
472    [(set GPR:$rz, (sra GPR:$rx, uimm5:$imm5))]>;
473  def ROTLI32 : I_5_XZ<0x12, 0x8, "rotli32",
474    (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5),
475    [(set GPR:$rz, (rotl GPR:$rx, uimm5:$imm5))]>;
476
477  def ROTRI32 : CSKYPseudo<(outs GPR:$rz), (ins GPR:$rx, oimm5:$imm5),
478                            "rotri32 $rz, $rx, $imm5", []>;
479  }
480  let isAdd = 1 in
481  def ADDU32 : R_YXZ_SP_F1<0x0, 0x1,
482    BinOpFrag<(add node:$LHS, node:$RHS)>, "addu32", 1>;
483  def SUBU32 : R_YXZ_SP_F1<0x0, 0x4,
484    BinOpFrag<(sub node:$LHS, node:$RHS)>, "subu32">;
485
486  def MULT32 : R_YXZ_SP_F1<0x21, 0x1,
487    BinOpFrag<(mul node:$LHS, node:$RHS)>, "mult32", 1>;
488  def AND32 : R_YXZ_SP_F1<0x8, 0x1,
489    BinOpFrag<(and node:$LHS, node:$RHS)>, "and32", 1>;
490  def ANDN32 : R_YXZ_SP_F1<0x8, 0x2,
491    BinOpFrag<(and node:$LHS, (not node:$RHS))>, "andn32">;
492  def OR32: R_YXZ_SP_F1<0x9, 0x1,
493    BinOpFrag<(or node:$LHS, node:$RHS)>, "or32", 1>;
494  def XOR32 : R_YXZ_SP_F1<0x9, 0x2,
495    BinOpFrag<(xor node:$LHS, node:$RHS)>, "xor32", 1>;
496  def NOR32 : R_YXZ_SP_F1<0x9, 0x4,
497    BinOpFrag<(not (or node:$LHS, node:$RHS))>, "nor32", 1>;
498  let isCodeGenOnly = 1 in
499  def NOT32 : R_XXZ<0b001001, 0b00100, (outs GPR:$rz), (ins GPR:$rx),
500    "not32", [(set GPR:$rz, (not GPR:$rx))]>;
501
502  let Size = 8 in
503  def NEG32 : CSKYPseudo<(outs GPR:$rd), (ins GPR:$rx), "neg32 $rd, $rx", []>;
504
505  let Size = 8 in
506  def RSUBI32 : CSKYPseudo<(outs GPR:$rd), (ins GPR:$rx, uimm12:$imm12), "rsubi32 $rd, $rx, $imm12", []>;
507
508  def LSL32 : R_YXZ_SP_F1<0x10, 0x1,
509    BinOpFrag<(shl node:$LHS, node:$RHS)>, "lsl32">;
510  def LSR32 : R_YXZ_SP_F1<0x10, 0x2,
511    BinOpFrag<(srl node:$LHS, node:$RHS)>, "lsr32">;
512  def ASR32 : R_YXZ_SP_F1<0x10, 0x4,
513    BinOpFrag<(sra node:$LHS, node:$RHS)>, "asr32">;
514  def ROTL32 : R_YXZ_SP_F1<0x10, 0x8,
515    BinOpFrag<(rotl node:$LHS, (and node:$RHS, 0x1f))>, "rotl32">;
516
517  def BMASKI32 : I_5_Z<0b010100, 0x1, "bmaski32", oimm5, []>;
518  def LSLC32 : I_5_XZ<0x13, 0x1, "lslc32",
519    (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, oimm5:$imm5), []>;
520  def LSRC32 : I_5_XZ<0x13, 0x2, "lsrc32",
521    (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, oimm5:$imm5), []>;
522  def ASRC32 : I_5_XZ<0x13, 0x4, "asrc32",
523    (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, oimm5:$imm5), []>;
524  def XSR32 : I_5_XZ<0x13, 0x8, "xsr32",
525    (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, oimm5:$imm5, CARRY:$cin), []>;
526
527  def IXH32 : R_YXZ_SP_F1<0x2, 0x1,
528    BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 1)))>, "ixh32">;
529  def IXW32 : R_YXZ_SP_F1<0x2, 0x2,
530    BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 2)))>, "ixw32">;
531  let Predicates = [iHas2E3] in
532  def IXD32 : R_YXZ_SP_F1<0x2, 0x4,
533    BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 3)))>, "ixd32">;
534
535  let isCommutable = 1, isAdd = 1 in
536  def ADDC32 : R_YXZ<0x31, 0x0, 0x2, (outs GPR:$rz, CARRY:$cout),
537    (ins GPR:$rx, GPR:$ry, CARRY:$cin), "addc32", []>;
538  def SUBC32 : R_YXZ<0x31, 0x0, 0x8, (outs GPR:$rz, CARRY:$cout),
539    (ins GPR:$rx, GPR:$ry, CARRY:$cin), "subc32", []>;
540
541  def INCF32 : I_5_ZX<0x3, 0x1, "incf32", uimm5, []>;
542  def INCT32 : I_5_ZX<0x3, 0x2, "inct32", uimm5, []>;
543  def DECF32 : I_5_ZX<0x3, 0x4, "decf32", uimm5, []>;
544  def DECT32 : I_5_ZX<0x3, 0x8, "dect32", uimm5, []>;
545}
546
547let Predicates = [iHas2E3] in {
548  def DIVS32 : R_YXZ_SP_F1<0x20, 0x2,
549    BinOpFrag<(sdiv node:$LHS, node:$RHS)>, "divs32">;
550  def DIVU32 : R_YXZ_SP_F1<0x20, 0x1,
551    BinOpFrag<(udiv node:$LHS, node:$RHS)>, "divu32">;
552
553  def DECGT32 : I_5_XZ<0x4, 0x1, "decgt32",
554    (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, uimm5:$imm5), []>;
555  def DECLT32 : I_5_XZ<0x4, 0x2, "declt32",
556    (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, uimm5:$imm5), []>;
557  def DECNE32 : I_5_XZ<0x4, 0x4, "decne32",
558    (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, uimm5:$imm5), []>;
559
560  def SEXT32 : I_5_XZ_U<0x16, (outs GPR:$rz), (ins GPR:$rx, uimm5:$msb, uimm5:$lsb), "sext32", []>;
561  let isCodeGenOnly = 1 in {
562  def SEXTB32 : I_5_XZ_US<0x16, 0, 7, "sextb32", sext_inreg, i8>;
563  def SEXTH32 : I_5_XZ_US<0x16, 0, 15, "sexth32", sext_inreg, i16>;
564  def ZEXTB32 : I_5_XZ_UZ<0x15, 0, 7, "zextb32", 255>;
565  def ZEXTH32 : I_5_XZ_UZ<0x15, 0, 15, "zexth32", 65535>;
566  }
567  def ZEXT32 : I_5_XZ_U<0x15, (outs GPR:$rz), (ins GPR:$rx, uimm5:$msb, uimm5:$lsb), "zext32",[]>;
568
569  let Constraints = "$rZ = $rz" in
570  def INS32 : I_5_XZ_INS<0b010111, (outs GPR:$rz), (ins GPR:$rZ, GPR:$rx, uimm5_msb_size:$msb, uimm5:$lsb), "ins32", []>;
571}
572
573let Predicates = [iHas3E3r1] in {
574def MULTS32 : R_YXZ<0x3e, 0x20, 0x10, (outs GPRPair:$rz),
575    (ins GPR:$rx, GPR:$ry), "mul.s32", []>;
576def MULTU32 : R_YXZ<0x3e, 0x20, 0x00, (outs GPRPair:$rz),
577    (ins GPR:$rx, GPR:$ry), "mul.u32", []>;
578
579let Constraints = "$rZ = $rz" in {
580def MULATS32 : R_YXZ<0x3e, 0x20, 0x14, (outs GPRPair:$rZ),
581    (ins GPRPair:$rz, GPR:$rx, GPR:$ry), "mula.s32", []>;
582def MULATU32 : R_YXZ<0x3e, 0x20, 0x04, (outs GPRPair:$rZ),
583    (ins GPRPair:$rz, GPR:$rx, GPR:$ry), "mula.u32", []>;
584}
585}
586
587def MULSH32 : R_YXZ<0x31, 0b100100, 0b00001, (outs GPR:$rz),
588    (ins GPR:$rx, GPR:$ry), "mulsh32", []>;
589
590//===----------------------------------------------------------------------===//
591// Load & Store instructions.
592//===----------------------------------------------------------------------===//
593
594def LD32B : I_LD<AddrMode32B, 0x0, "ld32.b", uimm12>;
595def LD32H : I_LD<AddrMode32H, 0x1, "ld32.h", uimm12_1>;
596def LD32W : I_LD<AddrMode32WD, 0x2, "ld32.w", uimm12_2>;
597
598let OutOperandList = (outs GPRPair:$rz) in
599def LD32D : I_LD<AddrMode32WD, 0x3, "ld32.d", uimm12_2>;
600
601let Predicates = [iHasE2] in {
602  def LD32BS : I_LD<AddrMode32B, 0x4, "ld32.bs", uimm12>;
603  def LD32HS : I_LD<AddrMode32H, 0x5, "ld32.hs", uimm12_1>;
604
605  def LDM32 : I_5_YX<0b110100, 0b000111,
606    (outs), (ins GPR:$rx, regseq:$regs, variable_ops), "ldm32\t$regs, (${rx})", []>;
607  def STM32 : I_5_YX<0b110101, 0b000111,
608    (outs), (ins GPR:$rx, regseq:$regs, variable_ops), "stm32\t$regs, (${rx})", []>;
609
610  let Size = 4, isCodeGenOnly = 0 in {
611  def LDQ32 : CSKYPseudo<(outs), (ins GPR:$rx, regseq:$regs, variable_ops),
612                             "ldq32\t$regs, (${rx})", []>;
613  def STQ32 : CSKYPseudo<(outs), (ins GPR:$rx, regseq:$regs, variable_ops),
614                             "stq32\t$regs, (${rx})", []>;
615  }
616
617}
618
619def ST32B : I_ST<AddrMode32B, 0x0, "st32.b", uimm12>;
620def ST32H : I_ST<AddrMode32H, 0x1, "st32.h", uimm12_1>;
621def ST32W : I_ST<AddrMode32WD, 0x2, "st32.w", uimm12_2>;
622
623let InOperandList = (ins GPRPair:$rz, GPR:$rx, uimm12_2:$imm12 ) in
624def ST32D : I_ST<AddrMode32WD, 0x3, "st32.d", uimm12_2>;
625
626let Predicates = [iHas2E3] in {
627  def LDR32B :  I_LDR<0x0, "ldr32.b">;
628  def LDR32BS :  I_LDR<0x4, "ldr32.bs">;
629  def LDR32H :  I_LDR<0x1, "ldr32.h">;
630  def LDR32HS :  I_LDR<0x5, "ldr32.hs">;
631  def LDR32W :  I_LDR<0x2, "ldr32.w">;
632  def STR32B :  I_STR<0x0, "str32.b">;
633  def STR32H :  I_STR<0x1, "str32.h">;
634  def STR32W :  I_STR<0x2, "str32.w">;
635}
636
637// Indicate that we're dumping the CR register, so we'll need to
638// scavenge a register for it.
639let mayStore = 1 in {
640def SPILL_CARRY : CSKYPseudo<(outs), (ins CARRY:$cond, GPR:$rx, uimm12_2:$imm),
641                             "!SPILL_CARRY $cond, $rx, $imm", []>;
642}
643
644// Indicate that we're restoring the CR register (previously
645// spilled), so we'll need to scavenge a register for it.
646let mayLoad = 1 in {
647def RESTORE_CARRY : CSKYPseudo<(outs CARRY:$cond), (ins GPR:$rx, uimm12_2:$imm),
648                                "!RESTORE_CARRY $cond, $rx, $imm", []>;
649}
650
651let mayLoad = 1 in {
652def STORE_PAIR : CSKYPseudo<(outs), (ins GPRPair:$rz, GPR:$rx, uimm12_2:$imm),
653                            "!STORE_PAIR $rz, $rx, $imm", []>;
654}
655
656let mayLoad = 1 in {
657def LOAD_PAIR : CSKYPseudo<(outs GPRPair:$rz), (ins GPR:$rx, uimm12_2:$imm),
658                            "!LOAD_PAIR $rz, $rx, $imm", []>;
659}
660
661//===----------------------------------------------------------------------===//
662// Compare instructions.
663//===----------------------------------------------------------------------===//
664let Predicates = [iHasE2] in {
665  def CMPNEI32 : I_16_X<0x1A, "cmpnei32", uimm16>;
666  def CMPHSI32 : I_16_X<0x18, "cmphsi32", oimm16>;
667  def CMPLTI32 : I_16_X<0x19, "cmplti32", oimm16>;
668  def CMPLEI32 : CSKYPseudo<(outs CARRY:$ca), (ins GPR:$rx, uimm16:$imm16),
669    "cmplei32\t$rx, $imm16", []>;
670}
671let Predicates = [iHas2E3] in {
672  def CMPNE32 : R_YX<0x1, 0x4, "cmpne32">;
673  def CMPHS32 : R_YX<0x1, 0x1, "cmphs32">;
674  def CMPLT32 : R_YX<0x1, 0x2, "cmplt32">;
675
676  def SETC32 : CSKY32Inst<AddrModeNone, 0x31,
677    (outs CARRY:$ca), (ins), "setc32", []> {
678    let Inst{25 - 21} = 0; //rx
679    let Inst{20 - 16} = 0; //ry
680    let Inst{15 - 10} = 0x1;
681    let Inst{9 - 5} = 0x1;
682    let Inst{4 - 0} = 0;
683    let isCompare = 1;
684  }
685  def CLRC32 : CSKY32Inst<AddrModeNone, 0x31,
686    (outs CARRY:$ca), (ins), "clrc32", []> {
687    let Inst{25 - 21} = 0; //rx
688    let Inst{20 - 16} = 0; //ry
689    let Inst{15 - 10} = 0x1;
690    let Inst{9 - 5} = 0x4;
691    let Inst{4 - 0} = 0;
692    let isCompare = 1;
693  }
694
695  def TST32 : R_YX<0x8, 0x4, "tst32">;
696  def TSTNBZ32 : R_X<0x8, 0x8,
697    (outs CARRY:$ca), (ins GPR:$rx), "tstnbz32", []>;
698}
699
700//===----------------------------------------------------------------------===//
701// Data move instructions.
702//===----------------------------------------------------------------------===//
703
704let Predicates= [iHasE2] in {
705  let isCodeGenOnly = 1 in {
706  def MOVT32 : R_ZX<0x3, 0x2, "movt32", []>;
707  def MOVF32 : R_ZX<0x3, 0x1, "movf32", []>;
708  }
709  def MOVI32 : I_16_MOV<0x10, "movi32", uimm16>;
710  let Size = 4, isCodeGenOnly = 0 in
711  def BGENI : CSKYPseudo<(outs GPR:$dst), (ins uimm5:$imm), "bgeni\t$dst, $imm", []>;
712  def : InstAlias<"bgeni16 $dst, $imm", (BGENI GPR:$dst, uimm5:$imm)>;
713  def : InstAlias<"bgeni32 $dst, $imm", (BGENI GPR:$dst, uimm5:$imm)>;
714  def MOVIH32 : I_16_MOV<0x11, "movih32", uimm16_16_xform>;
715  def MVC32 : R_Z_1<0x1, 0x8, "mvc32">;
716  let isCodeGenOnly = 1 in
717  def MOV32 : R_XZ<0x12, 0x1, "mov32">;
718
719  let usesCustomInserter = 1 in
720  def ISEL32 : CSKYPseudo<(outs GPR:$dst), (ins CARRY:$cond, GPR:$src1, GPR:$src2),
721    "!isel32\t$dst, $src1, src2", [(set GPR:$dst, (select CARRY:$cond, GPR:$src1, GPR:$src2))]>;
722}
723
724let Predicates = [iHas2E3] in {
725  def MVCV32 : R_Z_1<0x1, 0x10, "mvcv32">;
726  def CLRF32 : R_Z_2<0xB, 0x1, "clrf32", []>;
727  def CLRT32 : R_Z_2<0xB, 0x2, "clrt32", []>;
728}
729
730//===----------------------------------------------------------------------===//
731// Branch and call instructions.
732//===----------------------------------------------------------------------===//
733
734let isBranch = 1, isTerminator = 1 in {
735  let isBarrier = 1, isPredicable = 1 in
736    def BR32 : I_16_L<0x0, (outs), (ins br_symbol:$imm16), "br32\t$imm16",
737                     [(br bb:$imm16)]>;
738
739  def BT32 : I_16_L<0x3, (outs), (ins CARRY:$ca, br_symbol:$imm16),
740    "bt32\t$imm16", [(brcond CARRY:$ca, bb:$imm16)]>, Requires<[iHasE2]>;
741  def BF32 : I_16_L<0x2, (outs), (ins CARRY:$ca, br_symbol:$imm16),
742    "bf32\t$imm16", []>, Requires<[iHasE2]>;
743}
744
745let Predicates = [iHas2E3] in {
746  def BEZ32 : I_16_X_L<0x8, "bez32", br_symbol>;
747  def BNEZ32 : I_16_X_L<0x9, "bnez32", br_symbol>;
748  def BHZ32 : I_16_X_L<0xA, "bhz32", br_symbol>;
749  def BLSZ32 : I_16_X_L<0xB, "blsz32", br_symbol>;
750  def BLZ32 : I_16_X_L<0xC, "blz32", br_symbol>;
751  def BHSZ32 : I_16_X_L<0xD, "bhsz32", br_symbol>;
752
753  let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
754    def JMP32 : I_16_JX<0x6, "jmp32", [(brind GPR:$rx)]>; // jmp to register
755    def JMPI32 : I_16_L<0x16, (outs), (ins constpool_symbol:$imm16),
756                   "jmpi32\t$imm16", []>;
757  }
758
759  let isCall = 1, Defs = [ R15 ] in
760    def JSR32 : I_16_JX<0x7, "jsr32", []>;
761
762  let isCall = 1, Defs = [ R15 ] , mayLoad = 1 in
763    def JSRI32: I_16_L<0x17, (outs),
764      (ins constpool_symbol:$imm16), "jsri32\t$imm16", []>;
765}
766
767def BNEZAD32 : CSKY32Inst<AddrModeNone, 0x3a,
768  (outs GPR:$rx_u), (ins GPR:$rx, br_symbol:$imm16), "bnezad32\t$rx, $imm16", []> {
769  bits<5> rx;
770  bits<16> imm16;
771  let Inst{25 - 21} = 0x1;
772  let Inst{20 - 16} = rx;
773  let Inst{15 - 0} = imm16;
774  let isBranch = 1;
775  let isTerminator = 1;
776  let Constraints = "$rx_u = $rx";
777  let Predicates = [iHas2E3, iHas10E60];
778}
779
780def BSR32 : J<0x38, (outs), (ins call_symbol:$offset), "bsr32", []>;
781
782def : InstAlias<"bsr $dst", (BSR32 call_symbol:$dst)>;
783
784def BSR32_BR : J<0x38, (outs), (ins call_symbol:$offset), "bsr32", []>{
785  let isCodeGenOnly = 1;
786  let isBranch = 1;
787  let isTerminator = 1;
788  let isBarrier = 1;
789  let isPredicable = 1;
790  let Defs = [ R15 ];
791}
792
793//===----------------------------------------------------------------------===//
794// Symbol address instructions.
795//===----------------------------------------------------------------------===//
796
797def data_symbol_b : data_symbol<"CSKY::fixup_csky_doffset_imm18", 0>;
798def data_symbol_h : data_symbol<"CSKY::fixup_csky_doffset_imm18_scale2", 1>;
799def data_symbol_w : data_symbol<"CSKY::fixup_csky_doffset_imm18_scale4", 2> {
800  let ParserMatchClass = DataAsmClass;
801}
802
803let Predicates = [iHas2E3] in {
804
805def GRS32 : I_18_Z_L<0x3, "grs32\t$rz, $offset",
806                    (outs GPR:$rz), (ins bare_symbol:$offset), []>;
807def : InstAlias<"grs\t$rz, $offset", (GRS32 GPR:$rz, bare_symbol:$offset)>;
808
809let Uses = [R28] in {
810def LRS32B : I_18_Z_L<0x0, "lrs32.b\t$rz, $offset",
811                    (outs GPR:$rz), (ins data_symbol_b:$offset), []>;
812def LRS32H : I_18_Z_L<0x1, "lrs32.h\t$rz, $offset",
813                    (outs GPR:$rz), (ins data_symbol_h:$offset), []>;
814def LRS32W : I_18_Z_L<0x2, "lrs32.w\t$rz, $offset",
815                    (outs GPR:$rz), (ins data_symbol_w:$offset), []>;
816def SRS32B : I_18_Z_L<0x4, "srs32.b\t$rz, $offset",
817                    (outs), (ins GPR:$rz, data_symbol_b:$offset), []>;
818def SRS32H : I_18_Z_L<0x5, "srs32.h\t$rz, $offset",
819                    (outs), (ins GPR:$rz, data_symbol_h:$offset), []>;
820def SRS32W : I_18_Z_L<0x6, "srs32.w\t$rz, $offset",
821                    (outs), (ins GPR:$rz, data_symbol_w:$offset), []>;
822}
823
824def PUSH32 : I_12_PP<0b11111, 0b00000, (outs), (ins reglist:$regs, variable_ops), "push32 $regs">;
825
826let Uses = [R14, R15], isReturn = 1, isTerminator = 1, isBarrier = 1 in
827def POP32 : I_12_PP<0b11110, 0b00000, (outs), (ins reglist:$regs, variable_ops), "pop32 $regs">;
828
829}
830
831let mayLoad = 1, mayStore = 0 in {
832def LRW32 : I_16_Z_L<0x14, "lrw32", (ins constpool_symbol:$imm16), []>;
833let isCodeGenOnly = 1 in
834def LRW32_Gen : I_16_Z_L<0x14, "lrw32", (ins bare_symbol:$src1, constpool_symbol:$imm16), []>;
835}
836
837//===----------------------------------------------------------------------===//
838// Atomic and fence instructions.
839//===----------------------------------------------------------------------===//
840
841let Predicates = [iHasMP1E2] in {
842  def BRWARW : BAR<0b01111, "bar.brwarw", 0>;
843  def BRWARWS : BAR<0b01111, "bar.brwarws", 1>;
844  def BRARW : BAR<0b00111, "bar.brarw", 0>;
845  def BRARWS : BAR<0b00111, "bar.brarws", 1>;
846  def BRWAW : BAR<0b01110, "bar.brwaw", 0>;
847  def BRWAWS : BAR<0b01110, "bar.brwaws", 1>;
848  def BRAR : BAR<0b00101, "bar.brar", 0>;
849  def BRARS : BAR<0b00101, "bar.brars", 1>;
850  def BWAW : BAR<0b01010, "bar.bwaw", 0>;
851  def BWAWS : BAR<0b01010, "bar.bwaws", 1>;
852
853  def LDEX32W : I_LD<AddrMode32WD, 0x7, "ldex32.w", uimm12_2>;
854  let Constraints = "$rd = $rz" in
855    def STEX32W : I_LDST<AddrMode32WD, 0x37, 7,
856      (outs GPR:$rd), (ins GPR:$rz, GPR:$rx, uimm12_2:$imm12), "stex32.w", []>;
857}
858
859//===----------------------------------------------------------------------===//
860// Other operation instructions.
861//===----------------------------------------------------------------------===//
862
863let Predicates = [iHas2E3] in {
864  def BREV32 : R_XZ<0x18, 0x10, "brev32">;
865  def ABS32 : R_XZ<0x0, 0x10, "abs32">;
866  def BGENR32 : R_XZ<0x14, 0x2, "bgenr32">;
867}
868
869let Predicates = [iHasE2] in {
870  def REVB32 : R_XZ<0x18, 0x4, "revb32">;
871  def REVH32 : R_XZ<0x18, 0x8, "revh32">;
872  def FF0 : R_XZ<0x1F, 0x1, "ff0.32">;
873  def FF1 : R_XZ<0x1F, 0x2, "ff1.32">;
874  def XTRB0 : R_XZ<0x1C, 0x1, "xtrb0.32">;
875  def XTRB1 : R_XZ<0x1C, 0x2, "xtrb1.32">;
876  def XTRB2 : R_XZ<0x1C, 0x4, "xtrb2.32">;
877  def XTRB3 : R_XZ<0x1C, 0x8, "xtrb3.32">;
878  def BTSTI32 : I_5_X<0x0A, 0x4, "btsti32", uimm5, []>;
879  def BCLRI32 : I_5_XZ<0xA, 0x1, "bclri32",
880  (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), []>;
881  def BSETI32 : I_5_XZ<0xA, 0x2, "bseti32",
882  (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), []>;
883}
884
885//===----------------------------------------------------------------------===//
886// Special instructions.
887//===----------------------------------------------------------------------===//
888
889def MFFCR : CSKY32Inst<AddrModeNone, 0x30,
890  (outs GPR:$rx), (ins), "mfcr\t$rx, fcr", []> {
891  bits<5> rx;
892
893  let Inst{25 - 21} = 0b00010;
894  let Inst{20 - 16} = 0b00001;
895  let Inst{15 - 10} = 0b011000;
896  let Inst{9 - 5} = 0b00001;
897  let Inst{4 - 0} = rx;
898  let hasSideEffects = 1;
899  let isCodeGenOnly = 1;
900}
901
902def MTFCR : CSKY32Inst<AddrModeNone, 0x30,
903  (outs), (ins GPR:$rx), "mtcr\t$rx, fcr", []> {
904  bits<5> rx;
905
906  let Inst{25 - 21} = 0b00010;
907  let Inst{20 - 16} = rx;
908  let Inst{15 - 10} = 0b011001;
909  let Inst{9 - 5} = 0b00001;
910  let Inst{4 - 0} = 0b00001;
911  let hasSideEffects = 1;
912  let isCodeGenOnly = 1;
913}
914
915def SYNC32 : I_5_IMM5<0x30, 0b000001, 0b00001, "sync32", uimm5, []>;
916
917def SYNC0_32 : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins),
918                 "sync32", []> {
919  let Inst{25 - 21} = 0;
920  let Inst{20 - 16} = 0;
921  let Inst{15 - 10} = 0b000001;
922  let Inst{9 - 5} = 0b00001;
923  let Inst{4 - 0} = 0;
924}
925
926def SYNC_32_I : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins),
927                 "sync32.i", []> {
928  let Inst{25 - 21} = 1;
929  let Inst{20 - 16} = 0;
930  let Inst{15 - 10} = 0b000001;
931  let Inst{9 - 5} = 0b00001;
932  let Inst{4 - 0} = 0;
933}
934
935def SYNC_32_S : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins),
936                 "sync32.s", []> {
937  let Inst{25 - 21} = 0b10000;
938  let Inst{20 - 16} = 0;
939  let Inst{15 - 10} = 0b000001;
940  let Inst{9 - 5} = 0b00001;
941  let Inst{4 - 0} = 0;
942}
943
944def SYNC_32_IS : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins),
945                 "sync32.is", []> {
946  let Inst{25 - 21} = 0b10001;
947  let Inst{20 - 16} = 0;
948  let Inst{15 - 10} = 0b000001;
949  let Inst{9 - 5} = 0b00001;
950  let Inst{4 - 0} = 0;
951}
952
953let Predicates = [iHas2E3] in {
954  def RFI32 : I_5_XZ_PRIVI<0x11, 0x1, "rfi32">;
955  def SCE32 : I_5_IMM5<0x30, 0b000110, 0b00001, "sce32", uimm4, []>;
956}
957let Predicates = [HasExtendLrw] in
958def IDLY32 : I_5_IMM5<0x30, 0b000111, 0b00001, "idly32", imm5_idly, []>;
959def STOP32 : I_5_XZ_PRIVI<0x12, 0x1, "stop32">;
960def WAIT32 : I_5_XZ_PRIVI<0x13, 0x1, "wait32">;
961def DOZE32 : I_5_XZ_PRIVI<0x14, 0x1, "doze32">;
962def WE32 : I_5_XZ_PRIVI<0b010101, 0x1, "we32">;
963def SE32 : I_5_XZ_PRIVI<0b010110, 0x1, "se32">;
964def WSC32 : I_5_XZ_PRIVI<0b001111, 0x1, "wsc32">;
965
966def CPOP32 : I_CPOP<(outs), (ins uimm5:$cpid, uimm20:$usdef), "cpop32 <$cpid, ${usdef}>">;
967def CPRC32 : I_CP<0b0100, (outs CARRY:$ca), (ins uimm5:$cpid, uimm12:$usdef), "cprc32 <$cpid, ${usdef}>">;
968def CPRCR32 : I_CP_Z<0b0010, (outs GPR:$rz), (ins uimm5:$cpid, uimm12:$usdef), "cprcr32 $rz, <$cpid, ${usdef}>">;
969def CPRGR32 : I_CP_Z<0b0000, (outs GPR:$rz), (ins uimm5:$cpid, uimm12:$usdef), "cprgr32 $rz, <$cpid, ${usdef}>">;
970def CPWCR32 : I_CP_Z<0b0011, (outs), (ins GPR:$rz, uimm5:$cpid, uimm12:$usdef), "cpwcr32 $rz, <$cpid, ${usdef}>">;
971def CPWGR32 : I_CP_Z<0b0001, (outs), (ins GPR:$rz, uimm5:$cpid, uimm12:$usdef), "cpwgr32 $rz, <$cpid, ${usdef}>">;
972
973let Predicates = [iHas3r2E3r3] in {
974def DCACHE_IALL32 : I_5_CACHE<0b100101, 0b01000, "dcache32.iall">;
975def DCACHE_CALL32 : I_5_CACHE<0b100101, 0b00100, "dcache32.call">;
976def DCACHE_CIALL32 : I_5_CACHE<0b100101, 0b01100, "dcache32.ciall">;
977def DCACHE_IVA32 : I_5_X_CACHE<0b100101, 0b01011, "dcache32.iva">;
978def DCACHE_ISW32: I_5_X_CACHE<0b100101, 0b01010, "dcache32.isw">;
979def DCACHE_CVA32 : I_5_X_CACHE<0b100101, 0b00111, "dcache32.cva">;
980def DCACHE_CVAL32 : I_5_X_CACHE<0b100101, 0b10111, "dcache32.cval1">;
981def DCACHE_CSW32 : I_5_X_CACHE<0b100101, 0b00110, "dcache32.csw">;
982def DCACHE_CIVA32 : I_5_X_CACHE<0b100101, 0b01111, "dcache32.civa">;
983def DCACHE_CISW32 : I_5_X_CACHE<0b100101, 0b01110, "dcache32.cisw">;
984
985def ICACHE_IALL32 : I_5_CACHE<0b100100, 0b01000, "icache32.iall">;
986def ICACHE_IALLS32 : I_5_CACHE<0b100100, 0b11000, "icache32.ialls">;
987def ICACHE_IVA32 : I_5_X_CACHE<0b100100, 0b01011, "icache32.iva">;
988
989def TLBI_VAA32 : I_5_X_CACHE<0b100010, 0b00010, "tlbi32.vaa">;
990def TLBI_VAAS32 : I_5_X_CACHE<0b100010, 0b10010, "tlbi32.vaas">;
991def TLBI_ASID32 : I_5_X_CACHE<0b100010, 0b00001, "tlbi32.asid">;
992def TLBI_ASIDS32 : I_5_X_CACHE<0b100010, 0b10001, "tlbi32.asids">;
993def TLBI_VA32 : I_5_X_CACHE<0b100010, 0b00011, "tlbi32.va">;
994def TLBI_VAS32 : I_5_X_CACHE<0b100010, 0b10011, "tlbi32.vas">;
995def TLBI_ALL32 : I_5_CACHE<0b100010, 0b00000, "tlbi32.all">;
996def TLBI_ALLS32 : I_5_CACHE<0b100010, 0b10000, "tlbi32.alls">;
997
998def L2CACHE_IALL : I_5_CACHE<0b100110, 0b01000, "l2cache.iall">;
999def L2CACHE_CALL : I_5_CACHE<0b100110, 0b00100, "l2cache.call">;
1000def L2CACHE_CIALL : I_5_CACHE<0b100110, 0b01100, "l2cache.ciall">;
1001}
1002
1003def PLDR32 :I_PLDR<AddrMode32WD, 0x36, 0b0110, (outs), (ins GPR:$rx, uimm12_2:$imm12), "pldr32", []>;
1004def PLDW32 :I_PLDR<AddrMode32WD, 0x37, 0b0110, (outs), (ins GPR:$rx, uimm12_2:$imm12), "pldw32", []>;
1005
1006def TRAP32 : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins uimm2:$imm2), "trap32 ${imm2}", []> {
1007  bits<2> imm2;
1008
1009  let Inst{25 - 21} = 0;
1010  let Inst{20 - 16} = 0;
1011  let Inst{15 - 12} = 0b0010;
1012  let Inst{11 - 10} = imm2;
1013  let Inst{9 - 5} = 0b00001;
1014  let Inst{4 - 0} = 0;
1015
1016}
1017
1018//===----------------------------------------------------------------------===//
1019// Instruction Patterns.
1020//===----------------------------------------------------------------------===//
1021
1022// Load & Store Patterns
1023multiclass LdPat<PatFrag LoadOp, ImmLeaf imm_type, Instruction Inst, ValueType Type> {
1024  def : Pat<(Type (LoadOp GPR:$rs1)), (Inst GPR:$rs1, 0)>;
1025  def : Pat<(Type (LoadOp (i32 frameindex:$rs1))), (Inst (i32 (to_tframeindex tframeindex:$rs1)), 0)>;
1026  def : Pat<(Type (LoadOp (add GPR:$rs1, imm_type:$uimm))),
1027            (Inst GPR:$rs1, imm_type:$uimm)>;
1028  def : Pat<(Type (LoadOp (add frameindex:$rs1, imm_type:$uimm))),
1029            (Inst (i32 (to_tframeindex tframeindex:$rs1)), imm_type:$uimm)>;
1030  def : Pat<(Type (LoadOp (eqToAdd frameindex:$rs1, imm_type:$uimm))),
1031            (Inst (i32 (to_tframeindex tframeindex:$rs1)), imm_type:$uimm)>;
1032  def : Pat<(Type (LoadOp (add GPR:$rs1, tglobaladdr:$gd))),
1033            (Inst GPR:$rs1, tglobaladdr:$gd)>;
1034}
1035
1036defm : LdPat<extloadi8, uimm12, LD32B, i32>;
1037defm : LdPat<zextloadi8, uimm12, LD32B, i32>;
1038let Predicates = [iHasE2] in {
1039  defm : LdPat<sextloadi8, uimm12, LD32BS, i32>;
1040}
1041defm : LdPat<extloadi16, uimm12_1, LD32H, i32>;
1042defm : LdPat<zextloadi16, uimm12_1, LD32H, i32>;
1043let Predicates = [iHasE2] in {
1044defm : LdPat<sextloadi16, uimm12_1, LD32HS, i32>;
1045}
1046defm : LdPat<load, uimm12_2, LD32W, i32>;
1047
1048multiclass LdrPat<PatFrag LoadOp, Instruction Inst, ValueType Type> {
1049  def : Pat<(Type (LoadOp (add GPR:$rs1, GPR:$rs2))), (Inst GPR:$rs1, GPR:$rs2, 0)>;
1050  def : Pat<(Type (LoadOp (add GPR:$rs1, (shl GPR:$rs2, (i32 1))))), (Inst GPR:$rs1, GPR:$rs2, 1)>;
1051  def : Pat<(Type (LoadOp (add GPR:$rs1, (shl GPR:$rs2, (i32 2))))), (Inst GPR:$rs1, GPR:$rs2, 2)>;
1052  def : Pat<(Type (LoadOp (add GPR:$rs1, (shl GPR:$rs2, (i32 3))))), (Inst GPR:$rs1, GPR:$rs2, 3)>;
1053}
1054
1055let Predicates = [iHas2E3] in {
1056  defm : LdrPat<zextloadi8, LDR32B, i32>;
1057  defm : LdrPat<sextloadi8, LDR32BS, i32>;
1058  defm : LdrPat<extloadi8, LDR32BS, i32>;
1059  defm : LdrPat<zextloadi16, LDR32H, i32>;
1060  defm : LdrPat<sextloadi16, LDR32HS, i32>;
1061  defm : LdrPat<extloadi16, LDR32HS, i32>;
1062  defm : LdrPat<load, LDR32W, i32>;
1063}
1064
1065multiclass StPat<PatFrag StoreOp, ValueType Type, ImmLeaf imm_type, Instruction Inst> {
1066  def : Pat<(StoreOp Type:$rs2, GPR:$rs1), (Inst Type:$rs2, GPR:$rs1, 0)>;
1067  def : Pat<(StoreOp Type:$rs2, frameindex:$rs1), (Inst Type:$rs2, (i32 (to_tframeindex tframeindex:$rs1)), 0)>;
1068  def : Pat<(StoreOp Type:$rs2, (add GPR:$rs1, imm_type:$uimm12)),
1069            (Inst Type:$rs2, GPR:$rs1, imm_type:$uimm12)>;
1070  def : Pat<(StoreOp Type:$rs2, (add frameindex:$rs1, imm_type:$uimm12)),
1071            (Inst Type:$rs2, (i32 (to_tframeindex tframeindex:$rs1)), imm_type:$uimm12)>;
1072  def : Pat<(StoreOp Type:$rs2, (eqToAdd frameindex:$rs1, imm_type:$uimm12)),
1073            (Inst Type:$rs2, (i32 (to_tframeindex tframeindex:$rs1)), imm_type:$uimm12)>;
1074}
1075
1076defm : StPat<truncstorei8, i32, uimm12, ST32B>;
1077defm : StPat<truncstorei16, i32, uimm12_1, ST32H>;
1078defm : StPat<store, i32, uimm12_2, ST32W>;
1079
1080multiclass StrPat<PatFrag StoreOp, ValueType Type, Instruction Inst> {
1081  def : Pat<(StoreOp Type:$rz, (add GPR:$rs1, GPR:$rs2)), (Inst Type:$rz, GPR:$rs1, GPR:$rs2, 0)>;
1082  def : Pat<(StoreOp Type:$rz, (add GPR:$rs1, (shl GPR:$rs2, (i32 1)))), (Inst Type:$rz, GPR:$rs1, GPR:$rs2, 1)>;
1083  def : Pat<(StoreOp Type:$rz, (add GPR:$rs1, (shl GPR:$rs2, (i32 2)))), (Inst Type:$rz, GPR:$rs1, GPR:$rs2, 2)>;
1084  def : Pat<(StoreOp Type:$rz, (add GPR:$rs1, (shl GPR:$rs2, (i32 3)))), (Inst Type:$rz, GPR:$rs1, GPR:$rs2, 3)>;
1085}
1086
1087let Predicates = [iHas2E3] in {
1088  defm : StrPat<truncstorei8, i32, STR32B>;
1089  defm : StrPat<truncstorei16, i32, STR32H>;
1090  defm : StrPat<store, i32, STR32W>;
1091
1092  // Sext & Zext Patterns
1093  def : Pat<(sext_inreg GPR:$src, i1), (SEXT32 GPR:$src, 0, 0)>;
1094  def : Pat<(and GPR:$src, 255), (ZEXT32 GPR:$src, 7, 0)>;
1095  def : Pat<(and GPR:$src, 65535), (ZEXT32 GPR:$src, 15, 0)>;
1096
1097   // Call Patterns
1098  def : Pat<(CSKY_CALL tglobaladdr, tconstpool:$src2), (JSRI32 tconstpool:$src2)>;
1099  def : Pat<(CSKY_CALL texternalsym, tconstpool:$src2), (JSRI32 tconstpool:$src2)>;
1100  def : Pat<(CSKY_TAIL tglobaladdr, tconstpool:$src2), (JMPI32 tconstpool:$src2)>;
1101  def : Pat<(CSKY_TAIL texternalsym, tconstpool:$src2), (JMPI32 tconstpool:$src2)>;
1102
1103  def : Pat<(CSKY_CALLReg GPR:$src), (JSR32 GPR:$src)>;
1104  def : Pat<(CSKY_TAILReg GPR:$src), (JMP32 GPR:$src)>;
1105}
1106
1107// Symbol address Patterns
1108def : Pat<(CSKY_LOAD_ADDR tglobaladdr, tconstpool:$src2), (LRW32 tconstpool:$src2)>;
1109def : Pat<(CSKY_LOAD_ADDR tblockaddress, tconstpool:$src2), (LRW32 tconstpool:$src2)>;
1110def : Pat<(CSKY_LOAD_ADDR tjumptable:$src1, tconstpool:$src2), (LRW32_Gen tjumptable:$src1, tconstpool:$src2)>;
1111def : Pat<(CSKY_LOAD_ADDR texternalsym, tconstpool:$src2), (LRW32 tconstpool:$src2)>;
1112
1113let Predicates = [iHas2E3] in
1114  def : Pat<(i32 constpool:$src), (GRS32 (to_tconstpool tconstpool:$src))>;
1115
1116let Predicates = [iHasE2] in
1117  def : Pat<(i32 constpool:$src),
1118    (ORI32 (MOVIH32 (to_tconstpool_hi16 tconstpool:$src)),
1119           (to_tconstpool_lo16 tconstpool:$src))>;
1120
1121def : Pat<(i32 (load constpool:$src)), (LRW32 (to_tconstpool tconstpool:$src))>;
1122
1123// Branch Patterns.
1124let Predicates = [iHasE2] in {
1125  def : Pat<(brcond CARRY:$ca, bb:$imm16),
1126          (BT32 CARRY:$ca, bb:$imm16)>;
1127
1128  def : Pat<(brcond (i32 (setne GPR:$rs1, uimm16:$rs2)), bb:$imm16),
1129          (BT32 (CMPNEI32 GPR:$rs1, uimm16:$rs2), bb:$imm16)>;
1130  def : Pat<(brcond (i32 (seteq GPR:$rs1, uimm16:$rs2)), bb:$imm16),
1131          (BF32 (CMPNEI32 GPR:$rs1, uimm16:$rs2), bb:$imm16)>;
1132  def : Pat<(brcond (i32 (setuge GPR:$rs1, oimm16:$rs2)), bb:$imm16),
1133          (BT32 (CMPHSI32 GPR:$rs1, oimm16:$rs2), bb:$imm16)>;
1134  def : Pat<(brcond (i32 (setult GPR:$rs1, oimm16:$rs2)), bb:$imm16),
1135          (BF32 (CMPHSI32 GPR:$rs1, oimm16:$rs2), bb:$imm16)>;
1136  def : Pat<(brcond (i32 (setlt GPR:$rs1, oimm16:$rs2)), bb:$imm16),
1137          (BT32 (CMPLTI32 GPR:$rs1, oimm16:$rs2), bb:$imm16)>;
1138  def : Pat<(brcond (i32 (setge GPR:$rs1, oimm16:$rs2)), bb:$imm16),
1139          (BF32 (CMPLTI32 GPR:$rs1, oimm16:$rs2), bb:$imm16)>;
1140
1141}
1142
1143let Predicates = [iHas2E3] in {
1144
1145def : Pat<(brcond (i32 (setne GPR:$rs1, GPR:$rs2)), bb:$imm16),
1146          (BT32 (CMPNE32 GPR:$rs1, GPR:$rs2), bb:$imm16)>;
1147def : Pat<(brcond (i32 (seteq GPR:$rs1, GPR:$rs2)), bb:$imm16),
1148          (BF32 (CMPNE32 GPR:$rs1, GPR:$rs2), bb:$imm16)>;
1149def : Pat<(brcond (i32 (setuge GPR:$rs1, GPR:$rs2)), bb:$imm16),
1150          (BT32 (CMPHS32 GPR:$rs1, GPR:$rs2), bb:$imm16)>;
1151def : Pat<(brcond (i32 (setule GPR:$rs1, GPR:$rs2)), bb:$imm16),
1152          (BT32 (CMPHS32 GPR:$rs2, GPR:$rs1), bb:$imm16)>;
1153def : Pat<(brcond (i32 (setult GPR:$rs1, GPR:$rs2)), bb:$imm16),
1154          (BF32 (CMPHS32 GPR:$rs1, GPR:$rs2), bb:$imm16)>;
1155def : Pat<(brcond (i32 (setugt GPR:$rs1, GPR:$rs2)), bb:$imm16),
1156          (BF32 (CMPHS32 GPR:$rs2, GPR:$rs1), bb:$imm16)>;
1157def : Pat<(brcond (i32 (setlt GPR:$rs1, GPR:$rs2)), bb:$imm16),
1158          (BT32 (CMPLT32 GPR:$rs1, GPR:$rs2), bb:$imm16)>;
1159def : Pat<(brcond (i32 (setgt GPR:$rs1, GPR:$rs2)), bb:$imm16),
1160          (BT32 (CMPLT32 GPR:$rs2, GPR:$rs1), bb:$imm16)>;
1161def : Pat<(brcond (i32 (setge GPR:$rs1, GPR:$rs2)), bb:$imm16),
1162          (BF32 (CMPLT32 GPR:$rs1, GPR:$rs2), bb:$imm16)>;
1163def : Pat<(brcond (i32 (setle GPR:$rs1, GPR:$rs2)), bb:$imm16),
1164          (BF32 (CMPLT32 GPR:$rs2, GPR:$rs1), bb:$imm16)>;
1165
1166def : Pat<(brcond (i32 (seteq GPR:$rs1, (i32 0))), bb:$imm16),
1167          (BEZ32 GPR:$rs1, bb:$imm16)>;
1168def : Pat<(brcond (i32 (setne GPR:$rs1, (i32 0))), bb:$imm16),
1169          (BNEZ32 GPR:$rs1, bb:$imm16)>;
1170def : Pat<(brcond (i32 (setlt GPR:$rs1, (i32 0))), bb:$imm16),
1171          (BLZ32 GPR:$rs1, bb:$imm16)>;
1172def : Pat<(brcond (i32 (setge GPR:$rs1, (i32 0))), bb:$imm16),
1173          (BHSZ32 GPR:$rs1, bb:$imm16)>;
1174def : Pat<(brcond (i32 (setgt GPR:$rs1, (i32 0))), bb:$imm16),
1175          (BHZ32 GPR:$rs1, bb:$imm16)>;
1176def : Pat<(brcond (i32 (setle GPR:$rs1, (i32 0))), bb:$imm16),
1177          (BLSZ32 GPR:$rs1, bb:$imm16)>;
1178}
1179
1180// Compare Patterns.
1181let Predicates = [iHas2E3] in {
1182  def : Pat<(setne GPR:$rs1, GPR:$rs2),
1183            (CMPNE32 GPR:$rs1, GPR:$rs2)>;
1184  def : Pat<(i32 (seteq GPR:$rs1, GPR:$rs2)),
1185            (MVCV32 (CMPNE32 GPR:$rs1, GPR:$rs2))>;
1186  def : Pat<(setuge GPR:$rs1, GPR:$rs2),
1187            (CMPHS32 GPR:$rs1, GPR:$rs2)>;
1188  def : Pat<(setule GPR:$rs1, GPR:$rs2),
1189            (CMPHS32 GPR:$rs2, GPR:$rs1)>;
1190  def : Pat<(i32 (setult GPR:$rs1, GPR:$rs2)),
1191            (MVCV32 (CMPHS32 GPR:$rs1, GPR:$rs2))>;
1192  def : Pat<(i32 (setugt GPR:$rs1, GPR:$rs2)),
1193            (MVCV32 (CMPHS32 GPR:$rs2, GPR:$rs1))>;
1194  def : Pat<(setlt GPR:$rs1, GPR:$rs2),
1195            (CMPLT32 GPR:$rs1, GPR:$rs2)>;
1196  def : Pat<(setgt GPR:$rs1, GPR:$rs2),
1197            (CMPLT32 GPR:$rs2, GPR:$rs1)>;
1198  def : Pat<(i32 (setge GPR:$rs1, GPR:$rs2)),
1199            (MVCV32 (CMPLT32 GPR:$rs1, GPR:$rs2))>;
1200  def : Pat<(i32 (setle GPR:$rs1, GPR:$rs2)),
1201            (MVCV32 (CMPLT32 GPR:$rs2, GPR:$rs1))>;
1202}
1203
1204let Predicates = [iHasE2] in {
1205  def : Pat<(setne GPR:$rs1, uimm16:$rs2),
1206            (CMPNEI32 GPR:$rs1, uimm16:$rs2)>;
1207  let Predicates = [iHas2E3] in
1208  def : Pat<(i32 (seteq GPR:$rs1, uimm16:$rs2)),
1209            (MVCV32 (CMPNEI32 GPR:$rs1, uimm16:$rs2))>;
1210  def : Pat<(setuge GPR:$rs1, oimm16:$rs2),
1211            (CMPHSI32 GPR:$rs1, oimm16:$rs2)>;
1212  let Predicates = [iHas2E3] in
1213  def : Pat<(i32 (setult GPR:$rs1, oimm16:$rs2)),
1214            (MVCV32 (CMPHSI32 GPR:$rs1, oimm16:$rs2))>;
1215  def : Pat<(setlt GPR:$rs1, oimm16:$rs2),
1216            (CMPLTI32 GPR:$rs1, oimm16:$rs2)>;
1217  let Predicates = [iHas2E3] in
1218  def : Pat<(i32 (setge GPR:$rs1, oimm16:$rs2)),
1219            (MVCV32 (CMPLTI32 GPR:$rs1, oimm16:$rs2))>;
1220}
1221
1222// Select Patterns.
1223let Predicates = [iHasE2] in {
1224def : Pat<(select CARRY:$ca, GPR:$rx, GPR:$false),
1225          (MOVT32 CARRY:$ca, GPR:$rx, GPR:$false)>;
1226def : Pat<(select (and CARRY:$ca, 1), GPR:$rx, GPR:$false),
1227          (MOVT32 CARRY:$ca, GPR:$rx, GPR:$false)>;
1228
1229def : Pat<(select (i32 (setne GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false),
1230          (MOVT32 (CMPNE32 GPR:$rs1, GPR:$rs2), GPR:$rx, GPR:$false)>;
1231def : Pat<(select (i32 (setne GPR:$rs1, uimm16:$rs2)), GPR:$rx, GPR:$false),
1232          (MOVT32 (CMPNEI32 GPR:$rs1, uimm16:$rs2), GPR:$rx, GPR:$false)>;
1233def : Pat<(select (i32 (seteq GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false),
1234          (MOVF32 (CMPNE32 GPR:$rs1, GPR:$rs2), GPR:$rx, GPR:$false)>;
1235def : Pat<(select (i32 (seteq GPR:$rs1, uimm16:$rs2)), GPR:$rx, GPR:$false),
1236          (MOVF32 (CMPNEI32 GPR:$rs1, uimm16:$rs2), GPR:$rx, GPR:$false)>;
1237
1238def : Pat<(select (i32 (setuge GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false),
1239          (MOVT32 (CMPHS32 GPR:$rs1, GPR:$rs2), GPR:$rx, GPR:$false)>;
1240def : Pat<(select (i32 (setuge GPR:$rs1, oimm16:$rs2)), GPR:$rx, GPR:$false),
1241          (MOVT32 (CMPHSI32 GPR:$rs1, oimm16:$rs2), GPR:$rx, GPR:$false)>;
1242def : Pat<(select (i32 (setule GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false),
1243          (MOVT32 (CMPHS32 GPR:$rs2, GPR:$rs1), GPR:$rx, GPR:$false)>;
1244def : Pat<(select (i32 (setult GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false),
1245          (MOVF32 (CMPHS32 GPR:$rs1, GPR:$rs2), GPR:$rx, GPR:$false)>;
1246def : Pat<(select (i32 (setult GPR:$rs1, oimm16:$rs2)), GPR:$rx, GPR:$false),
1247          (MOVF32 (CMPHSI32 GPR:$rs1, oimm16:$rs2), GPR:$rx, GPR:$false)>;
1248def : Pat<(select (i32 (setugt GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false),
1249          (MOVF32 (CMPHS32 GPR:$rs2, GPR:$rs1), GPR:$rx, GPR:$false)>;
1250
1251def : Pat<(select (i32 (setlt GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false),
1252          (MOVT32 (CMPLT32 GPR:$rs1, GPR:$rs2), GPR:$rx, GPR:$false)>;
1253def : Pat<(select (i32 (setlt GPR:$rs1, oimm16:$rs2)), GPR:$rx, GPR:$false),
1254          (MOVT32 (CMPLTI32 GPR:$rs1, oimm16:$rs2), GPR:$rx, GPR:$false)>;
1255def : Pat<(select (i32 (setgt GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false),
1256          (MOVT32 (CMPLT32 GPR:$rs2, GPR:$rs1), GPR:$rx, GPR:$false)>;
1257def : Pat<(select (i32 (setge GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false),
1258          (MOVF32 (CMPLT32 GPR:$rs1, GPR:$rs2), GPR:$rx, GPR:$false)>;
1259def : Pat<(select (i32 (setge GPR:$rs1, oimm16:$rs2)), GPR:$rx, GPR:$false),
1260          (MOVF32 (CMPLTI32 GPR:$rs1, oimm16:$rs2), GPR:$rx, GPR:$false)>;
1261def : Pat<(select (i32 (setle GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false),
1262          (MOVF32 (CMPLT32 GPR:$rs2, GPR:$rs1), GPR:$rx, GPR:$false)>;
1263
1264def : Pat<(select CARRY:$ca, GPR:$rx, GPR:$false),
1265          (ISEL32 CARRY:$ca, GPR:$rx, GPR:$false)>;
1266def : Pat<(select (and CARRY:$ca, 1), GPR:$rx, GPR:$false),
1267          (ISEL32 CARRY:$ca, GPR:$rx, GPR:$false)>;
1268}
1269
1270// Constant materialize patterns.
1271let Predicates = [iHasE2] in
1272  def : Pat<(i32 imm:$imm),
1273            (ORI32 (MOVIH32 (uimm32_hi16 imm:$imm)), (uimm32_lo16 imm:$imm))>;
1274
1275
1276// Other operations.
1277let Predicates = [iHasE2] in {
1278  def : Pat<(rotl GPR:$rs1, GPR:$rs2),
1279            (ROTL32 GPR:$rs1, (ANDI32 GPR:$rs2, 0x1f))>;
1280  let Predicates = [iHas2E3] in {
1281    def : Pat<(bitreverse GPR:$rx), (BREV32 GPR:$rx)>;
1282    def : Pat<(bswap GPR:$rx), (REVB32 GPR:$rx)>;
1283  }
1284  def : Pat<(i32 (ctlz GPR:$rx)), (FF1 GPR:$rx)>;
1285}
1286
1287//===----------------------------------------------------------------------===//
1288// Pseudo for assembly
1289//===----------------------------------------------------------------------===//
1290
1291let isCall = 1, Defs = [ R15 ], mayLoad = 1, Size = 4, isCodeGenOnly = 0 in
1292def JBSR32 : CSKYPseudo<(outs), (ins call_symbol:$src1), "jbsr32\t$src1", []>;
1293
1294def : InstAlias<"jbsr\t$src1", (JBSR32 call_symbol:$src1)>;
1295
1296def JBR32 : CSKYPseudo<(outs), (ins br_symbol:$src1), "jbr32\t$src1", []> {
1297  let isBranch = 1;
1298  let isTerminator = 1;
1299  let isBarrier = 1;
1300  let isIndirectBranch = 1;
1301  let mayLoad = 1;
1302  let Size = 4;
1303}
1304
1305def JBT32 : CSKYPseudo<(outs), (ins CARRY:$ca, br_symbol:$src1), "jbt32\t$src1", []> {
1306  let isBranch = 1;
1307  let isTerminator = 1;
1308  let isIndirectBranch = 1;
1309  let mayLoad = 1;
1310  let Size = 4;
1311}
1312
1313def JBF32 : CSKYPseudo<(outs), (ins CARRY:$ca, br_symbol:$src1), "jbf32\t$src1", []> {
1314  let isBranch = 1;
1315  let isTerminator = 1;
1316  let isIndirectBranch = 1;
1317  let mayLoad = 1;
1318  let Size = 4;
1319}
1320
1321def JBT_E : CSKYPseudo<(outs), (ins CARRY:$ca, br_symbol:$src1), "!jbt_e\t$src1", []> {
1322  let isBranch = 1;
1323  let isTerminator = 1;
1324  let isIndirectBranch = 1;
1325  let mayLoad = 1;
1326  let Size = 6;
1327}
1328
1329def JBF_E : CSKYPseudo<(outs), (ins CARRY:$ca, br_symbol:$src1), "!jbf_e\t$src1", []> {
1330  let isBranch = 1;
1331  let isTerminator = 1;
1332  let isIndirectBranch = 1;
1333  let mayLoad = 1;
1334  let Size = 6;
1335}
1336
1337let mayLoad = 1, Size = 2, isCodeGenOnly = 0 in
1338def PseudoLRW32 : CSKYPseudo<(outs GPR:$rz), (ins bare_symbol:$src), "lrw32 $rz, $src", []>;
1339
1340
1341def : InstAlias<"lrw $rz, $src", (PseudoLRW32 GPR:$rz, bare_symbol:$src)>;
1342def : InstAlias<"lrw $rz, $src", (LRW32 GPR:$rz, constpool_symbol:$src)>;
1343
1344let mayLoad = 1, Size = 4, isCodeGenOnly = 0 in
1345def PseudoJSRI32 : CSKYPseudo<(outs), (ins call_symbol:$src), "jsri32 $src", []>;
1346def : InstAlias<"jsri $dst", (PseudoJSRI32 call_symbol:$dst)>;
1347def : InstAlias<"jsri $dst", (JSRI32 constpool_symbol:$dst)>;
1348
1349let mayLoad = 1, Size = 4, isCodeGenOnly = 0 in
1350def PseudoJMPI32 : CSKYPseudo<(outs), (ins br_symbol:$src), "jmpi32 $src", []>;
1351def : InstAlias<"jmpi $dst", (PseudoJMPI32 br_symbol:$dst)>;
1352def : InstAlias<"jmpi $dst", (JMPI32 constpool_symbol:$dst)>;
1353
1354let isNotDuplicable = 1, mayLoad = 1, mayStore = 0, Size = 8 in
1355def PseudoTLSLA32 : CSKYPseudo<(outs GPR:$dst1, GPR:$dst2),
1356  (ins constpool_symbol:$src, i32imm:$label), "!tlslrw32\t$dst1, $dst2, $src, $label", []>;
1357
1358let hasSideEffects = 0, isNotDuplicable = 1 in
1359def CONSTPOOL_ENTRY : CSKYPseudo<(outs),
1360  (ins i32imm:$instid, i32imm:$cpidx, i32imm:$size), "", []>;
1361
1362include "CSKYInstrInfo16Instr.td"
1363include "CSKYInstrInfoF1.td"
1364include "CSKYInstrInfoF2.td"
1365