xref: /freebsd/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrInfo.td (revision 59c8e88e72633afbc47a4ace0d2170d00d51f7dc)
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
105def imm_neg_XFORM : SDNodeXForm<imm, [{
106  return CurDAG->getTargetConstant(-N->getSExtValue(), SDLoc(N), MVT::i32);
107}]>;
108
109class oimm_neg<int num> : Operand<i32>,
110  ImmLeaf<i32, "return isUInt<"#num#">(-Imm - 1);"> {
111}
112
113class uimm<int num, int shift = 0> : Operand<i32>,
114  ImmLeaf<i32, "return isShiftedUInt<"#num#", "#shift#">(Imm);"> {
115  let EncoderMethod = "getImmOpValue<"#shift#">";
116  let ParserMatchClass =
117    !if(!ne(shift, 0),
118        UImmAsmOperand<num, "Shift"#shift>,
119        UImmAsmOperand<num>);
120  let DecoderMethod = "decodeUImmOperand<"#num#", "#shift#">";
121}
122
123class uimm_neg<int num, int shift = 0> : Operand<i32>,
124  ImmLeaf<i32, "return isShiftedUInt<"#num#", "#shift#">(-Imm);"> {
125}
126
127class 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#">";
132}
133
134def nimm_XFORM : SDNodeXForm<imm, [{
135  return CurDAG->getTargetConstant(~N->getSExtValue(), SDLoc(N), MVT::i32);
136}]>;
137class nimm<int num> : Operand<i32>,
138  ImmLeaf<i32, "return isUInt<"#num#">(~Imm);", nimm_XFORM> {
139  let ParserMatchClass = UImmAsmOperand<num>;
140}
141
142def uimm32_hi16 : SDNodeXForm<imm, [{
143  return CurDAG->getTargetConstant((N->getZExtValue() >> 16) & 0xFFFF,
144    SDLoc(N), MVT::i32);
145}]>;
146def uimm32_lo16 : SDNodeXForm<imm, [{
147  return CurDAG->getTargetConstant(N->getZExtValue()& 0xFFFF, SDLoc(N), MVT::i32);
148}]>;
149def uimm16_16_xform : Operand<i32>,
150  ImmLeaf<i32, "return isShiftedUInt<16, 16>(Imm);", uimm32_hi16> {
151  let ParserMatchClass = UImmAsmOperand<16>;
152  let EncoderMethod = "getImmOpValue";
153}
154
155def uimm_shift : Operand<i32>, ImmLeaf<i32, "return isUInt<2>(Imm);"> {
156  let EncoderMethod = "getImmShiftOpValue";
157  let ParserMatchClass = UImmAsmOperand<2>;
158  let DecoderMethod = "decodeImmShiftOpValue";
159}
160
161def CSKYSymbol : AsmOperandClass {
162  let Name = "CSKYSymbol";
163  let RenderMethod = "addImmOperands";
164  let DiagnosticType = "InvalidCSKYSymbol";
165  let ParserMethod = "parseCSKYSymbol";
166}
167
168def br_symbol : Operand<OtherVT> {
169  let EncoderMethod =
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";
175}
176
177def 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";
183}
184
185def Constpool : AsmOperandClass {
186  let Name = "Constpool";
187  let RenderMethod = "addConstpoolOperands";
188  let DiagnosticType = "InvalidConstpool";
189  let ParserMethod = "parseConstpoolSymbol";
190}
191
192def constpool_symbol : Operand<iPTR> {
193  let ParserMatchClass = Constpool;
194  let EncoderMethod =
195    "getConstpoolSymbolOpValue<CSKY::fixup_csky_pcrel_uimm16_scale4>";
196  let DecoderMethod = "decodeUImmOperand<16, 2>";
197  let PrintMethod = "printConstpool";
198  let OperandType = "OPERAND_PCREL";
199}
200
201def DataAsmClass : AsmOperandClass {
202  let Name = "DataSymbol";
203  let RenderMethod = "addConstpoolOperands";
204  let DiagnosticType = "InvalidConstpool";
205  let ParserMethod = "parseDataSymbol";
206}
207
208class data_symbol<string reloc, int shift> : Operand<iPTR> {
209  let ParserMatchClass = Constpool;
210  let EncoderMethod =
211    "getDataSymbolOpValue<"#reloc#">";
212  let DecoderMethod = "decodeUImmOperand<18, "#shift#">";
213  let PrintMethod = "printDataSymbol";
214}
215
216def 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";
222}
223
224def oimm3 : oimm<3> {
225  let MCOperandPredicate = [{
226    int64_t Imm;
227    if (MCOp.evaluateAsConstantImm(Imm))
228      return isUInt<3>(Imm - 1);
229    return MCOp.isBareSymbolRef();
230  }];
231}
232def oimm4 : oimm<4>;
233def oimm5 : oimm<5> {
234  let MCOperandPredicate = [{
235    int64_t Imm;
236    if (MCOp.evaluateAsConstantImm(Imm))
237      return isUInt<5>(Imm - 1);
238    return MCOp.isBareSymbolRef();
239  }];
240}
241def oimm6 : oimm<6>;
242
243def imm5_idly : Operand<i32>, ImmLeaf<i32,
244  "return Imm <= 32 && Imm >= 0;"> {
245  let EncoderMethod = "getImmOpValueIDLY";
246  let DecoderMethod = "decodeOImmOperand<5>";
247}
248
249def oimm8 : oimm<8> {
250  let MCOperandPredicate = [{
251    int64_t Imm;
252    if (MCOp.evaluateAsConstantImm(Imm))
253      return isUInt<8>(Imm - 1);
254    return MCOp.isBareSymbolRef();
255  }];
256}
257def oimm12 : oimm<12> {
258  let MCOperandPredicate = [{
259    int64_t Imm;
260    if (MCOp.evaluateAsConstantImm(Imm))
261      return isUInt<12>(Imm - 1);
262    return MCOp.isBareSymbolRef();
263  }];
264}
265def oimm16 : oimm<16> {
266  let MCOperandPredicate = [{
267    int64_t Imm;
268    if (MCOp.evaluateAsConstantImm(Imm))
269      return isUInt<16>(Imm - 1);
270    return MCOp.isBareSymbolRef();
271  }];
272}
273
274def oimm8_neg : oimm_neg<8> {
275  let MCOperandPredicate = [{
276    int64_t Imm;
277    if (MCOp.evaluateAsConstantImm(Imm))
278      return isUInt<8>(-Imm - 1);
279    return MCOp.isBareSymbolRef();
280  }];
281}
282def oimm12_neg : oimm_neg<12> {
283  let MCOperandPredicate = [{
284    int64_t Imm;
285    if (MCOp.evaluateAsConstantImm(Imm))
286      return isUInt<12>(-Imm - 1);
287    return MCOp.isBareSymbolRef();
288  }];
289}
290
291def nimm12 : nimm<12>;
292
293def uimm1 : uimm<1>;
294def uimm2 : uimm<2>;
295
296
297def uimm2_jmpix : Operand<i32>,
298  ImmLeaf<i32, "return Imm == 16 || Imm == 24 || Imm == 32 || Imm == 40;"> {
299  let EncoderMethod = "getImmJMPIX";
300  let DecoderMethod = "decodeJMPIXImmOperand";
301}
302
303def uimm3 : uimm<3>;
304def uimm4 : uimm<4>;
305def uimm5 : uimm<5> {
306  let MCOperandPredicate = [{
307    int64_t Imm;
308    if (MCOp.evaluateAsConstantImm(Imm))
309      return isShiftedUInt<5, 0>(Imm);
310    return MCOp.isBareSymbolRef();
311  }];
312}
313def uimm5_msb_size : uimm<5> {
314  let EncoderMethod = "getImmOpValueMSBSize";
315}
316
317def uimm5_1 : uimm<5, 1> {
318  let MCOperandPredicate = [{
319    int64_t Imm;
320    if (MCOp.evaluateAsConstantImm(Imm))
321      return isShiftedUInt<5, 1>(Imm);
322    return MCOp.isBareSymbolRef();
323  }];
324}
325def uimm5_2 : uimm<5, 2> {
326  let MCOperandPredicate = [{
327    int64_t Imm;
328    if (MCOp.evaluateAsConstantImm(Imm))
329      return isShiftedUInt<5, 2>(Imm);
330    return MCOp.isBareSymbolRef();
331  }];
332}
333def uimm6 : uimm<6>;
334def uimm7 : uimm<7>;
335def uimm7_1 : uimm<7, 1>;
336def uimm7_2 : uimm<7, 2>{
337  let MCOperandPredicate = [{
338    int64_t Imm;
339    if (MCOp.evaluateAsConstantImm(Imm))
340      return isShiftedUInt<7, 2>(Imm);
341    return MCOp.isBareSymbolRef();
342  }];
343}
344def uimm7_3 : uimm<7, 3>;
345def uimm8 : uimm<8> {
346  let MCOperandPredicate = [{
347    int64_t Imm;
348    if (MCOp.evaluateAsConstantImm(Imm))
349      return isShiftedUInt<8, 0>(Imm);
350    return MCOp.isBareSymbolRef();
351  }];
352}
353def uimm8_2 : uimm<8, 2> {
354  let MCOperandPredicate = [{
355    int64_t Imm;
356    if (MCOp.evaluateAsConstantImm(Imm))
357      return isShiftedUInt<8, 2>(Imm);
358    return MCOp.isBareSymbolRef();
359  }];
360}
361def uimm8_3 : uimm<8, 3>;
362def uimm8_8 : uimm<8, 8>;
363def uimm8_16 : uimm<8, 16>;
364def uimm8_24 : uimm<8, 24>;
365def uimm12 : uimm<12>  {
366  let MCOperandPredicate = [{
367    int64_t Imm;
368    if (MCOp.evaluateAsConstantImm(Imm))
369      return isShiftedUInt<12, 0>(Imm);
370    return MCOp.isBareSymbolRef();
371  }];
372}
373def uimm12_1 : uimm<12, 1> {
374  let MCOperandPredicate = [{
375    int64_t Imm;
376    if (MCOp.evaluateAsConstantImm(Imm))
377      return isShiftedUInt<12, 1>(Imm);
378    return MCOp.isBareSymbolRef();
379  }];
380}
381def uimm12_2 : uimm<12, 2> {
382  let MCOperandPredicate = [{
383    int64_t Imm;
384    if (MCOp.evaluateAsConstantImm(Imm))
385      return isShiftedUInt<12, 2>(Imm);
386    return MCOp.isBareSymbolRef();
387  }];
388}
389def uimm16 : uimm<16> {
390  let MCOperandPredicate = [{
391    int64_t Imm;
392    if (MCOp.evaluateAsConstantImm(Imm))
393      return isShiftedUInt<16, 0>(Imm);
394    return MCOp.isBareSymbolRef();
395  }];
396}
397def uimm16_8 : uimm<16, 8>;
398def uimm16_16 : uimm<16, 16>;
399def uimm20 : uimm<20>;
400def uimm24 : uimm<24>;
401def uimm24_8 : uimm<24, 8>;
402
403def uimm5_neg : uimm_neg<5>;
404
405def simm8_2 : simm<8, 2>;
406
407class RegSeqAsmOperand<string Suffix = ""> : AsmOperandClass {
408  let Name = "RegSeq"#Suffix;
409  let RenderMethod = "addRegSeqOperands";
410  let DiagnosticType = "InvalidRegSeq";
411  let ParserMethod = "parseRegSeq";
412}
413
414def 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);
420}
421
422def RegListAsmOperand : AsmOperandClass {
423  let Name = "RegList";
424  let RenderMethod = "addRegListOperands";
425  let DiagnosticType = "InvalidRegList";
426  let ParserMethod = "parseRegList";
427}
428
429def reglist : Operand<iPTR> {
430  let ParserMatchClass = RegListAsmOperand;
431  let PrintMethod = "printRegisterList";
432}
433
434def PSRFlag : AsmOperandClass {
435  let Name = "PSRFlag";
436  let RenderMethod = "addImmOperands";
437  let DiagnosticType = "InvalidPSRFlag";
438  let ParserMethod = "parsePSRFlag";
439}
440
441def psrflag : Operand<i32>, ImmLeaf<i32, "return isShiftedUInt<5, 0>(Imm);"> {
442  let EncoderMethod = "getImmOpValue";
443  let ParserMatchClass = PSRFlag;
444  let PrintMethod = "printPSRFlag";
445}
446
447multiclass 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);}]>;
456}
457
458defm uimm8SRL : uimm8SRLXForm<imm>;
459
460//===----------------------------------------------------------------------===//
461// Instruction Formats
462//===----------------------------------------------------------------------===//
463
464include "CSKYInstrFormats.td"
465
466//===----------------------------------------------------------------------===//
467// Instruction definitions.
468//===----------------------------------------------------------------------===//
469
470class TriOpFrag<dag res> : PatFrag<(ops node: $LHS, node:$MHS, node:$RHS), res>;
471class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
472class UnOpFrag<dag res> : PatFrag<(ops node:$Src), res>;
473
474def eqToAdd : PatFrag<(ops node:$lhs, node:$rhs), (or node:$lhs, node:$rhs), [{
475  return isOrEquivalentToAdd(N);
476}]>;
477
478def BaseAddr : ComplexPattern<iPTR, 1, "SelectBaseAddr">;
479
480
481//===----------------------------------------------------------------------===//
482// CSKYPseudo
483//===----------------------------------------------------------------------===//
484
485// Pessimistically assume the stack pointer will be clobbered
486let Defs = [R14], Uses = [R14] in {
487def ADJCALLSTACKDOWN : CSKYPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
488  "!ADJCALLSTACKDOWN $amt1, $amt2", [(callseq_start timm:$amt1, timm:$amt2)]>;
489def ADJCALLSTACKUP   : CSKYPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
490  "!ADJCALLSTACKUP $amt1, $amt2", [(callseq_end timm:$amt1, timm:$amt2)]>;
491} // Defs = [R14], Uses = [R14]
492
493
494//===----------------------------------------------------------------------===//
495// Basic ALU instructions.
496//===----------------------------------------------------------------------===//
497
498let Predicates = [iHasE2] in {
499  let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
500  let isAdd = 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))]>;
520
521  def ROTRI32 : CSKYPseudo<(outs GPR:$rz), (ins GPR:$rx, oimm5:$imm5),
522                            "rotri32 $rz, $rx, $imm5", []>;
523  }
524  let isAdd = 1 in
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">;
529
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))]>;
545
546  let Size = 8 in
547  def NEG32 : CSKYPseudo<(outs GPR:$rd), (ins GPR:$rx), "neg32 $rd, $rx", []>;
548
549  let Size = 8 in
550  def RSUBI32 : CSKYPseudo<(outs GPR:$rd), (ins GPR:$rx, uimm12:$imm12), "rsubi32 $rd, $rx, $imm12", []>;
551
552  def : Pat<(add GPR:$rs1, (oimm12_neg:$im)),
553            (SUBI32 GPR:$rs1, (imm_neg_XFORM oimm12_neg:$im))>;
554
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">;
563
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), []>;
573
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">;
581
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", []>;
587
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, []>;
592}
593
594let 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">;
599
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), []>;
606
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>;
613  }
614  def ZEXT32 : I_5_XZ_U<0x15, (outs GPR:$rz), (ins GPR:$rx, uimm5:$msb, uimm5:$lsb), "zext32",[]>;
615
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", []>;
618}
619
620let Predicates = [iHas3E3r1] in {
621def MULTS32 : R_YXZ<0x3e, 0x20, 0x10, (outs GPRPair:$rz),
622    (ins GPR:$rx, GPR:$ry), "mul.s32", []>;
623def MULTU32 : R_YXZ<0x3e, 0x20, 0x00, (outs GPRPair:$rz),
624    (ins GPR:$rx, GPR:$ry), "mul.u32", []>;
625
626let Constraints = "$rZ = $rz" in {
627def MULATS32 : R_YXZ<0x3e, 0x20, 0x14, (outs GPRPair:$rZ),
628    (ins GPRPair:$rz, GPR:$rx, GPR:$ry), "mula.s32", []>;
629def MULATU32 : R_YXZ<0x3e, 0x20, 0x04, (outs GPRPair:$rZ),
630    (ins GPRPair:$rz, GPR:$rx, GPR:$ry), "mula.u32", []>;
631}
632}
633
634def MULSH32 : R_YXZ<0x31, 0b100100, 0b00001, (outs GPR:$rz),
635    (ins GPR:$rx, GPR:$ry), "mulsh32", []>;
636
637//===----------------------------------------------------------------------===//
638// Load & Store instructions.
639//===----------------------------------------------------------------------===//
640
641def LD32B : I_LD<AddrMode32B, 0x0, "ld32.b", uimm12>;
642def LD32H : I_LD<AddrMode32H, 0x1, "ld32.h", uimm12_1>;
643def LD32W : I_LD<AddrMode32WD, 0x2, "ld32.w", uimm12_2>;
644
645let OutOperandList = (outs GPRPair:$rz) in
646def LD32D : I_LD<AddrMode32WD, 0x3, "ld32.d", uimm12_2>;
647
648let Predicates = [iHasE2] in {
649  def LD32BS : I_LD<AddrMode32B, 0x4, "ld32.bs", uimm12>;
650  def LD32HS : I_LD<AddrMode32H, 0x5, "ld32.hs", uimm12_1>;
651
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})", []>;
656
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})", []>;
662  }
663
664}
665
666def ST32B : I_ST<AddrMode32B, 0x0, "st32.b", uimm12>;
667def ST32H : I_ST<AddrMode32H, 0x1, "st32.h", uimm12_1>;
668def ST32W : I_ST<AddrMode32WD, 0x2, "st32.w", uimm12_2>;
669
670let InOperandList = (ins GPRPair:$rz, GPR:$rx, uimm12_2:$imm12 ) in
671def ST32D : I_ST<AddrMode32WD, 0x3, "st32.d", uimm12_2>;
672
673let 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">;
682}
683
684// Indicate that we're dumping the CR register, so we'll need to
685// scavenge a register for it.
686let mayStore = 1 in {
687def SPILL_CARRY : CSKYPseudo<(outs), (ins CARRY:$cond, GPR:$rx, uimm12_2:$imm),
688                             "!SPILL_CARRY $cond, $rx, $imm", []>;
689}
690
691// Indicate that we're restoring the CR register (previously
692// spilled), so we'll need to scavenge a register for it.
693let mayLoad = 1 in {
694def RESTORE_CARRY : CSKYPseudo<(outs CARRY:$cond), (ins GPR:$rx, uimm12_2:$imm),
695                                "!RESTORE_CARRY $cond, $rx, $imm", []>;
696}
697
698let mayLoad = 1 in {
699def STORE_PAIR : CSKYPseudo<(outs), (ins GPRPair:$rz, GPR:$rx, uimm12_2:$imm),
700                            "!STORE_PAIR $rz, $rx, $imm", []>;
701}
702
703let mayLoad = 1 in {
704def LOAD_PAIR : CSKYPseudo<(outs GPRPair:$rz), (ins GPR:$rx, uimm12_2:$imm),
705                            "!LOAD_PAIR $rz, $rx, $imm", []>;
706}
707
708//===----------------------------------------------------------------------===//
709// Compare instructions.
710//===----------------------------------------------------------------------===//
711let 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", []>;
717}
718let 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">;
722
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;
729    let Inst{4 - 0} = 0;
730    let isCompare = 1;
731  }
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;
738    let Inst{4 - 0} = 0;
739    let isCompare = 1;
740  }
741
742  def TST32 : R_YX<0x8, 0x4, "tst32">;
743  def TSTNBZ32 : R_X<0x8, 0x8,
744    (outs CARRY:$ca), (ins GPR:$rx), "tstnbz32", []>;
745}
746
747//===----------------------------------------------------------------------===//
748// Data move instructions.
749//===----------------------------------------------------------------------===//
750
751let Predicates= [iHasE2] in {
752  let isCodeGenOnly = 1 in {
753  def MOVT32 : R_ZX<0x3, 0x2, "movt32", []>;
754  def MOVF32 : R_ZX<0x3, 0x1, "movf32", []>;
755  }
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">;
763
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))]>;
767}
768
769let 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">;
773}
774
775//===----------------------------------------------------------------------===//
776// Branch and call instructions.
777//===----------------------------------------------------------------------===//
778
779let 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",
782                     [(br bb:$imm16)]>;
783
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]>;
788}
789
790let 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>;
797
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", []>;
802  }
803
804  let isCall = 1, Defs = [ R15 ] in
805    def JSR32 : I_16_JX<0x7, "jsr32", []>;
806
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", []>;
810}
811
812def BNEZAD32 : CSKY32Inst<AddrModeNone, 0x3a,
813  (outs GPR:$rx_u), (ins GPR:$rx, br_symbol:$imm16), "bnezad32\t$rx, $imm16", []> {
814  bits<5> rx;
815  bits<16> imm16;
816  let Inst{25 - 21} = 0x1;
817  let Inst{20 - 16} = rx;
818  let Inst{15 - 0} = imm16;
819  let isBranch = 1;
820  let isTerminator = 1;
821  let Constraints = "$rx_u = $rx";
822  let Predicates = [iHas2E3, iHas10E60];
823}
824
825def BSR32 : J<0x38, (outs), (ins call_symbol:$offset), "bsr32", []>;
826
827def BSR32_BR : J<0x38, (outs), (ins call_symbol:$offset), "bsr32", []>{
828  let isCodeGenOnly = 1;
829  let isBranch = 1;
830  let isTerminator = 1;
831  let isBarrier = 1;
832  let isPredicable = 1;
833  let Defs = [ R15 ];
834}
835
836//===----------------------------------------------------------------------===//
837// Symbol address instructions.
838//===----------------------------------------------------------------------===//
839
840def data_symbol_b : data_symbol<"CSKY::fixup_csky_doffset_imm18", 0>;
841def data_symbol_h : data_symbol<"CSKY::fixup_csky_doffset_imm18_scale2", 1>;
842def data_symbol_w : data_symbol<"CSKY::fixup_csky_doffset_imm18_scale4", 2> {
843  let ParserMatchClass = DataAsmClass;
844}
845
846let Predicates = [iHas2E3] in {
847
848def GRS32 : I_18_Z_L<0x3, "grs32\t$rz, $offset",
849                    (outs GPR:$rz), (ins bare_symbol:$offset), []>;
850
851let Uses = [R28] in {
852def LRS32B : I_18_Z_L<0x0, "lrs32.b\t$rz, $offset",
853                    (outs GPR:$rz), (ins data_symbol_b:$offset), []>;
854def LRS32H : I_18_Z_L<0x1, "lrs32.h\t$rz, $offset",
855                    (outs GPR:$rz), (ins data_symbol_h:$offset), []>;
856def LRS32W : I_18_Z_L<0x2, "lrs32.w\t$rz, $offset",
857                    (outs GPR:$rz), (ins data_symbol_w:$offset), []>;
858def SRS32B : I_18_Z_L<0x4, "srs32.b\t$rz, $offset",
859                    (outs), (ins GPR:$rz, data_symbol_b:$offset), []>;
860def SRS32H : I_18_Z_L<0x5, "srs32.h\t$rz, $offset",
861                    (outs), (ins GPR:$rz, data_symbol_h:$offset), []>;
862def SRS32W : I_18_Z_L<0x6, "srs32.w\t$rz, $offset",
863                    (outs), (ins GPR:$rz, data_symbol_w:$offset), []>;
864}
865
866def PUSH32 : I_12_PP<0b11111, 0b00000, (outs), (ins reglist:$regs, variable_ops), "push32 $regs">;
867
868let Uses = [R14, R15], isReturn = 1, isTerminator = 1, isBarrier = 1 in
869def POP32 : I_12_PP<0b11110, 0b00000, (outs), (ins reglist:$regs, variable_ops), "pop32 $regs">;
870
871}
872
873let mayLoad = 1, mayStore = 0 in {
874def LRW32 : I_16_Z_L<0x14, "lrw32", (ins constpool_symbol:$imm16), []>;
875let isCodeGenOnly = 1 in
876def LRW32_Gen : I_16_Z_L<0x14, "lrw32", (ins bare_symbol:$src1, constpool_symbol:$imm16), []>;
877}
878
879//===----------------------------------------------------------------------===//
880// Atomic and fence instructions.
881//===----------------------------------------------------------------------===//
882
883let 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>;
894
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", []>;
899}
900
901//===----------------------------------------------------------------------===//
902// Other operation instructions.
903//===----------------------------------------------------------------------===//
904
905let 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">;
911}
912
913let 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), []>;
925}
926
927//===----------------------------------------------------------------------===//
928// Special instructions.
929//===----------------------------------------------------------------------===//
930
931def MFFCR : CSKY32Inst<AddrModeNone, 0x30,
932  (outs GPR:$rx), (ins), "mfcr\t$rx, fcr", []> {
933  bits<5> rx;
934
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;
942}
943
944def MTFCR : CSKY32Inst<AddrModeNone, 0x30,
945  (outs), (ins GPR:$rx), "mtcr\t$rx, fcr", []> {
946  bits<5> rx;
947
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;
955}
956
957def SYNC32 : I_5_IMM5<0x30, 0b000001, 0b00001, "sync32", uimm5, []>;
958
959def SYNC0_32 : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins),
960                 "sync32", []> {
961  let Inst{25 - 21} = 0;
962  let Inst{20 - 16} = 0;
963  let Inst{15 - 10} = 0b000001;
964  let Inst{9 - 5} = 0b00001;
965  let Inst{4 - 0} = 0;
966}
967
968def SYNC_32_I : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins),
969                 "sync32.i", []> {
970  let Inst{25 - 21} = 1;
971  let Inst{20 - 16} = 0;
972  let Inst{15 - 10} = 0b000001;
973  let Inst{9 - 5} = 0b00001;
974  let Inst{4 - 0} = 0;
975}
976
977def SYNC_32_S : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins),
978                 "sync32.s", []> {
979  let Inst{25 - 21} = 0b10000;
980  let Inst{20 - 16} = 0;
981  let Inst{15 - 10} = 0b000001;
982  let Inst{9 - 5} = 0b00001;
983  let Inst{4 - 0} = 0;
984}
985
986def SYNC_32_IS : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins),
987                 "sync32.is", []> {
988  let Inst{25 - 21} = 0b10001;
989  let Inst{20 - 16} = 0;
990  let Inst{15 - 10} = 0b000001;
991  let Inst{9 - 5} = 0b00001;
992  let Inst{4 - 0} = 0;
993}
994
995let Predicates = [iHas2E3] in {
996  def RFI32 : I_5_XZ_PRIVI<0x11, 0x1, "rfi32">;
997  def SCE32 : I_5_IMM5<0x30, 0b000110, 0b00001, "sce32", uimm4, []>;
998}
999let Predicates = [HasExtendLrw] in
1000def IDLY32 : I_5_IMM5<0x30, 0b000111, 0b00001, "idly32", imm5_idly, []>;
1001def STOP32 : I_5_XZ_PRIVI<0x12, 0x1, "stop32">;
1002def WAIT32 : I_5_XZ_PRIVI<0x13, 0x1, "wait32">;
1003def DOZE32 : I_5_XZ_PRIVI<0x14, 0x1, "doze32">;
1004def WE32 : I_5_XZ_PRIVI<0b010101, 0x1, "we32">;
1005def SE32 : I_5_XZ_PRIVI<0b010110, 0x1, "se32">;
1006def WSC32 : I_5_XZ_PRIVI<0b001111, 0x1, "wsc32">;
1007
1008def CPOP32 : I_CPOP<(outs), (ins uimm5:$cpid, uimm20:$usdef), "cpop32 <$cpid, ${usdef}>">;
1009def CPRC32 : I_CP<0b0100, (outs CARRY:$ca), (ins uimm5:$cpid, uimm12:$usdef), "cprc32 <$cpid, ${usdef}>">;
1010def CPRCR32 : I_CP_Z<0b0010, (outs GPR:$rz), (ins uimm5:$cpid, uimm12:$usdef), "cprcr32 $rz, <$cpid, ${usdef}>">;
1011def CPRGR32 : I_CP_Z<0b0000, (outs GPR:$rz), (ins uimm5:$cpid, uimm12:$usdef), "cprgr32 $rz, <$cpid, ${usdef}>">;
1012def CPWCR32 : I_CP_Z<0b0011, (outs), (ins GPR:$rz, uimm5:$cpid, uimm12:$usdef), "cpwcr32 $rz, <$cpid, ${usdef}>">;
1013def CPWGR32 : I_CP_Z<0b0001, (outs), (ins GPR:$rz, uimm5:$cpid, uimm12:$usdef), "cpwgr32 $rz, <$cpid, ${usdef}>">;
1014
1015let Predicates = [iHas3r2E3r3] in {
1016def DCACHE_IALL32 : I_5_CACHE<0b100101, 0b01000, "dcache32.iall">;
1017def DCACHE_CALL32 : I_5_CACHE<0b100101, 0b00100, "dcache32.call">;
1018def DCACHE_CIALL32 : I_5_CACHE<0b100101, 0b01100, "dcache32.ciall">;
1019def DCACHE_IVA32 : I_5_X_CACHE<0b100101, 0b01011, "dcache32.iva">;
1020def DCACHE_ISW32: I_5_X_CACHE<0b100101, 0b01010, "dcache32.isw">;
1021def DCACHE_CVA32 : I_5_X_CACHE<0b100101, 0b00111, "dcache32.cva">;
1022def DCACHE_CVAL32 : I_5_X_CACHE<0b100101, 0b10111, "dcache32.cval1">;
1023def DCACHE_CSW32 : I_5_X_CACHE<0b100101, 0b00110, "dcache32.csw">;
1024def DCACHE_CIVA32 : I_5_X_CACHE<0b100101, 0b01111, "dcache32.civa">;
1025def DCACHE_CISW32 : I_5_X_CACHE<0b100101, 0b01110, "dcache32.cisw">;
1026
1027def ICACHE_IALL32 : I_5_CACHE<0b100100, 0b01000, "icache32.iall">;
1028def ICACHE_IALLS32 : I_5_CACHE<0b100100, 0b11000, "icache32.ialls">;
1029def ICACHE_IVA32 : I_5_X_CACHE<0b100100, 0b01011, "icache32.iva">;
1030
1031def TLBI_VAA32 : I_5_X_CACHE<0b100010, 0b00010, "tlbi32.vaa">;
1032def TLBI_VAAS32 : I_5_X_CACHE<0b100010, 0b10010, "tlbi32.vaas">;
1033def TLBI_ASID32 : I_5_X_CACHE<0b100010, 0b00001, "tlbi32.asid">;
1034def TLBI_ASIDS32 : I_5_X_CACHE<0b100010, 0b10001, "tlbi32.asids">;
1035def TLBI_VA32 : I_5_X_CACHE<0b100010, 0b00011, "tlbi32.va">;
1036def TLBI_VAS32 : I_5_X_CACHE<0b100010, 0b10011, "tlbi32.vas">;
1037def TLBI_ALL32 : I_5_CACHE<0b100010, 0b00000, "tlbi32.all">;
1038def TLBI_ALLS32 : I_5_CACHE<0b100010, 0b10000, "tlbi32.alls">;
1039
1040def L2CACHE_IALL : I_5_CACHE<0b100110, 0b01000, "l2cache.iall">;
1041def L2CACHE_CALL : I_5_CACHE<0b100110, 0b00100, "l2cache.call">;
1042def L2CACHE_CIALL : I_5_CACHE<0b100110, 0b01100, "l2cache.ciall">;
1043}
1044
1045def PLDR32 :I_PLDR<AddrMode32WD, 0x36, 0b0110, (outs), (ins GPR:$rx, uimm12_2:$imm12), "pldr32", []>;
1046def PLDW32 :I_PLDR<AddrMode32WD, 0x37, 0b0110, (outs), (ins GPR:$rx, uimm12_2:$imm12), "pldw32", []>;
1047
1048def TRAP32 : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins uimm2:$imm2), "trap32 ${imm2}", []> {
1049  bits<2> imm2;
1050
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;
1057
1058}
1059
1060//===----------------------------------------------------------------------===//
1061// Instruction Patterns.
1062//===----------------------------------------------------------------------===//
1063
1064// Load & Store Patterns
1065multiclass 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)>;
1076}
1077
1078defm : LdPat<extloadi8, uimm12, LD32B, i32>;
1079defm : LdPat<zextloadi8, uimm12, LD32B, i32>;
1080let Predicates = [iHasE2] in {
1081  defm : LdPat<sextloadi8, uimm12, LD32BS, i32>;
1082}
1083defm : LdPat<extloadi16, uimm12_1, LD32H, i32>;
1084defm : LdPat<zextloadi16, uimm12_1, LD32H, i32>;
1085let Predicates = [iHasE2] in {
1086defm : LdPat<sextloadi16, uimm12_1, LD32HS, i32>;
1087}
1088defm : LdPat<load, uimm12_2, LD32W, i32>;
1089
1090multiclass 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)>;
1095}
1096
1097let 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>;
1105}
1106
1107multiclass 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)>;
1116}
1117
1118defm : StPat<truncstorei8, i32, uimm12, ST32B>;
1119defm : StPat<truncstorei16, i32, uimm12_1, ST32H>;
1120defm : StPat<store, i32, uimm12_2, ST32W>;
1121
1122multiclass 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)>;
1127}
1128
1129let Predicates = [iHas2E3] in {
1130  defm : StrPat<truncstorei8, i32, STR32B>;
1131  defm : StrPat<truncstorei16, i32, STR32H>;
1132  defm : StrPat<store, i32, STR32W>;
1133
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)>;
1138
1139   // Call Patterns
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)>;
1144
1145  def : Pat<(CSKY_CALLReg GPR:$src), (JSR32 GPR:$src)>;
1146  def : Pat<(CSKY_TAILReg GPR:$src), (JMP32 GPR:$src)>;
1147}
1148
1149// Symbol address Patterns
1150def : Pat<(CSKY_LOAD_ADDR tglobaladdr, tconstpool:$src2), (LRW32 tconstpool:$src2)>;
1151def : Pat<(CSKY_LOAD_ADDR tblockaddress, tconstpool:$src2), (LRW32 tconstpool:$src2)>;
1152def : Pat<(CSKY_LOAD_ADDR tjumptable:$src1, tconstpool:$src2), (LRW32_Gen tjumptable:$src1, tconstpool:$src2)>;
1153def : Pat<(CSKY_LOAD_ADDR texternalsym, tconstpool:$src2), (LRW32 tconstpool:$src2)>;
1154def : Pat<(CSKY_LOAD_ADDR tconstpool:$src1, tconstpool:$src2), (LRW32_Gen tconstpool:$src1, tconstpool:$src2)>;
1155
1156let Predicates = [iHas2E3] in
1157  def : Pat<(i32 constpool:$src), (GRS32 (to_tconstpool tconstpool:$src))>;
1158
1159let Predicates = [iHasE2] in
1160  def : Pat<(i32 constpool:$src),
1161    (ORI32 (MOVIH32 (to_tconstpool_hi16 tconstpool:$src)),
1162           (to_tconstpool_lo16 tconstpool:$src))>;
1163
1164def : Pat<(i32 (load constpool:$src)), (LRW32 (to_tconstpool tconstpool:$src))>;
1165
1166// Branch Patterns.
1167let Predicates = [iHasE2] in {
1168def : Pat<(brcond CARRY:$ca, bb:$imm16),
1169          (BT32 CARRY:$ca, bb:$imm16)>;
1170
1171multiclass 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)>;
1176}
1177
1178defm : BTF32Pat0<setne, seteq, uimm16, CMPNEI32>;
1179defm : BTF32Pat0<setuge, setult, oimm16, CMPHSI32>;
1180defm : BTF32Pat0<setlt, setge, oimm16, CMPLTI32>;
1181}
1182
1183let Predicates = [iHas2E3] in {
1184
1185def : Pat<(brcond (i32 (setne GPR:$rs1, GPR:$rs2)), bb:$imm16),
1186          (BT32 (CMPNE32 GPR:$rs1, GPR:$rs2), bb:$imm16)>;
1187def : Pat<(brcond (i32 (seteq GPR:$rs1, GPR:$rs2)), bb:$imm16),
1188          (BF32 (CMPNE32 GPR:$rs1, GPR:$rs2), bb:$imm16)>;
1189
1190multiclass BTF32Pat1<PatFrag cond0, PatFrag cond1, Instruction cmp,
1191                     Instruction br> {
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)>;
1196}
1197
1198defm : BTF32Pat1<setuge, setule, CMPHS32, BT32>;
1199defm : BTF32Pat1<setult, setugt, CMPHS32, BF32>;
1200defm : BTF32Pat1<setlt, setgt, CMPLT32, BT32>;
1201defm : BTF32Pat1<setge, setle, CMPLT32, BF32>;
1202
1203def : Pat<(brcond (i32 (seteq GPR:$rs1, (i32 0))), bb:$imm16),
1204          (BEZ32 GPR:$rs1, bb:$imm16)>;
1205def : Pat<(brcond (i32 (setne GPR:$rs1, (i32 0))), bb:$imm16),
1206          (BNEZ32 GPR:$rs1, bb:$imm16)>;
1207def : Pat<(brcond (i32 (setlt GPR:$rs1, (i32 0))), bb:$imm16),
1208          (BLZ32 GPR:$rs1, bb:$imm16)>;
1209def : Pat<(brcond (i32 (setlt GPR:$rs1, (i32 1))), bb:$imm16),
1210          (BLSZ32 GPR:$rs1, bb:$imm16)>;
1211def : Pat<(brcond (i32 (setge GPR:$rs1, (i32 0))), bb:$imm16),
1212          (BHSZ32 GPR:$rs1, bb:$imm16)>;
1213def : Pat<(brcond (i32 (setge GPR:$rs1, (i32 1))), bb:$imm16),
1214          (BHZ32 GPR:$rs1, bb:$imm16)>;
1215def : Pat<(brcond (i32 (setgt GPR:$rs1, (i32 0))), bb:$imm16),
1216          (BHZ32 GPR:$rs1, bb:$imm16)>;
1217def : Pat<(brcond (i32 (setgt GPR:$rs1, (i32 -1))), bb:$imm16),
1218          (BHSZ32 GPR:$rs1, bb:$imm16)>;
1219def : Pat<(brcond (i32 (setle GPR:$rs1, (i32 0))), bb:$imm16),
1220          (BLSZ32 GPR:$rs1, bb:$imm16)>;
1221def : Pat<(brcond (i32 (setle GPR:$rs1, (i32 -1))), bb:$imm16),
1222          (BLZ32 GPR:$rs1, bb:$imm16)>;
1223}
1224
1225// Compare Patterns.
1226let 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))>;
1247}
1248
1249let 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))>;
1265}
1266
1267// Select Patterns.
1268let Predicates = [iHasE2] in {
1269
1270def : 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)>;
1272def : 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)>;
1274def : 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))>;
1277def : 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))>;
1280
1281multiclass 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))>;
1302}
1303
1304defm : INCDECPat<setuge, setult, CMPHSI32>;
1305defm : INCDECPat<setlt, setge, CMPLTI32>;
1306
1307def : Pat<(select CARRY:$ca, (add GPR:$rx, uimm5:$imm), GPR:$other),
1308          (INCT32 CARRY:$ca, GPR:$other, GPR:$rx, uimm5:$imm)>;
1309def : Pat<(select CARRY:$ca, GPR:$other, (add GPR:$rx, uimm5:$imm)),
1310          (INCF32 CARRY:$ca, GPR:$other, GPR:$rx, uimm5:$imm)>;
1311def : Pat<(select (and CARRY:$ca, 1), (add GPR:$rx, uimm5:$imm), GPR:$other),
1312          (INCT32 CARRY:$ca, GPR:$other, GPR:$rx, uimm5:$imm)>;
1313def : Pat<(select (and CARRY:$ca, 1), GPR:$other, (add GPR:$rx, uimm5:$imm)),
1314          (INCF32 CARRY:$ca, GPR:$other, GPR:$rx, uimm5:$imm)>;
1315
1316def : 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))>;
1318def : 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))>;
1320def : 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))>;
1322def : 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))>;
1324
1325def : Pat<(select CARRY:$ca, GPR:$rx, GPR:$false),
1326          (MOVT32 CARRY:$ca, GPR:$rx, GPR:$false)>;
1327def : Pat<(select (and CARRY:$ca, 1), GPR:$rx, GPR:$false),
1328          (MOVT32 CARRY:$ca, GPR:$rx, GPR:$false)>;
1329
1330multiclass 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)>;
1335}
1336
1337defm : MOVTF32Pat0<setne, seteq, uimm16, CMPNEI32>;
1338defm : MOVTF32Pat0<setuge, setult, oimm16, CMPHSI32>;
1339defm : MOVTF32Pat0<setlt, setge, oimm16, CMPLTI32>;
1340
1341def : Pat<(select CARRY:$ca, GPR:$rx, GPR:$false),
1342          (ISEL32 CARRY:$ca, GPR:$rx, GPR:$false)>;
1343def : Pat<(select (and CARRY:$ca, 1), GPR:$rx, GPR:$false),
1344          (ISEL32 CARRY:$ca, GPR:$rx, GPR:$false)>;
1345}
1346
1347
1348let Predicates = [iHas2E3] in {
1349def : 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)>;
1351def : 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)>;
1353def : 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))>;
1356def : 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))>;
1359
1360multiclass 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)>;
1369}
1370
1371defm : INCPat<setuge, setule, CMPHS32, INCT32, INCF32>;
1372defm : INCPat<setult, setugt, CMPHS32, INCF32, INCT32>;
1373defm : INCPat<setlt, setgt, CMPLT32, INCT32, INCF32>;
1374defm : INCPat<setge, setle, CMPLT32, INCF32, INCT32>;
1375
1376multiclass 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))>;
1389}
1390
1391defm : DECPat<setuge, setule, CMPHS32, DECT32, DECF32>;
1392defm : DECPat<setult, setugt, CMPHS32, DECF32, DECT32>;
1393defm : DECPat<setlt, setgt, CMPLT32, DECT32, DECF32>;
1394defm : DECPat<setge, setle, CMPLT32, DECF32, DECT32>;
1395
1396def : Pat<(select (i32 (setne GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false),
1397          (MOVT32 (CMPNE32 GPR:$rs1, GPR:$rs2), GPR:$rx, GPR:$false)>;
1398def : Pat<(select (i32 (seteq GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false),
1399          (MOVF32 (CMPNE32 GPR:$rs1, GPR:$rs2), GPR:$rx, GPR:$false)>;
1400
1401multiclass 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)>;
1407}
1408
1409defm : MOVTF32Pat1<setuge, setule, CMPHS32, MOVT32>;
1410defm : MOVTF32Pat1<setult, setugt, CMPHS32, MOVF32>;
1411defm : MOVTF32Pat1<setlt, setgt, CMPLT32, MOVT32>;
1412defm : MOVTF32Pat1<setge, setle, CMPLT32, MOVF32>;
1413
1414def : Pat<(select CARRY:$ca, (i32 0), GPR:$other),
1415          (CLRT32 CARRY:$ca, GPR:$other)>;
1416def : Pat<(select CARRY:$ca, GPR:$other, (i32 0)),
1417          (CLRF32 CARRY:$ca, GPR:$other)>;
1418}
1419
1420// Constant materialize patterns.
1421let Predicates = [iHasE2] in
1422  def : Pat<(i32 imm:$imm),
1423            (ORI32 (MOVIH32 (uimm32_hi16 imm:$imm)), (uimm32_lo16 imm:$imm))>;
1424
1425// Other operations.
1426let 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)>;
1432  }
1433  def : Pat<(i32 (ctlz GPR:$rx)), (FF1 GPR:$rx)>;
1434}
1435
1436//===----------------------------------------------------------------------===//
1437// Pseudo for assembly
1438//===----------------------------------------------------------------------===//
1439
1440let isCall = 1, Defs = [ R15 ], mayLoad = 1, Size = 4, isCodeGenOnly = 0 in
1441def JBSR32 : CSKYPseudo<(outs), (ins call_symbol:$src1), "jbsr32\t$src1", []>;
1442
1443def JBR32 : CSKYPseudo<(outs), (ins br_symbol:$src1), "jbr32\t$src1", []> {
1444  let isBranch = 1;
1445  let isTerminator = 1;
1446  let isBarrier = 1;
1447  let isIndirectBranch = 1;
1448  let mayLoad = 1;
1449  let Size = 4;
1450}
1451
1452def JBT32 : CSKYPseudo<(outs), (ins CARRY:$ca, br_symbol:$src1), "jbt32\t$src1", []> {
1453  let isBranch = 1;
1454  let isTerminator = 1;
1455  let isIndirectBranch = 1;
1456  let mayLoad = 1;
1457  let Size = 4;
1458}
1459
1460def JBF32 : CSKYPseudo<(outs), (ins CARRY:$ca, br_symbol:$src1), "jbf32\t$src1", []> {
1461  let isBranch = 1;
1462  let isTerminator = 1;
1463  let isIndirectBranch = 1;
1464  let mayLoad = 1;
1465  let Size = 4;
1466}
1467
1468def JBT_E : CSKYPseudo<(outs), (ins CARRY:$ca, br_symbol:$src1), "!jbt_e\t$src1", []> {
1469  let isBranch = 1;
1470  let isTerminator = 1;
1471  let isIndirectBranch = 1;
1472  let mayLoad = 1;
1473  let Size = 6;
1474}
1475
1476def JBF_E : CSKYPseudo<(outs), (ins CARRY:$ca, br_symbol:$src1), "!jbf_e\t$src1", []> {
1477  let isBranch = 1;
1478  let isTerminator = 1;
1479  let isIndirectBranch = 1;
1480  let mayLoad = 1;
1481  let Size = 6;
1482}
1483
1484let mayLoad = 1, Size = 2, isCodeGenOnly = 0 in
1485def PseudoLRW32 : CSKYPseudo<(outs GPR:$rz), (ins bare_symbol:$src), "lrw32 $rz, $src", []>;
1486
1487let mayLoad = 1, Size = 4, isCodeGenOnly = 0 in
1488def PseudoJSRI32 : CSKYPseudo<(outs), (ins call_symbol:$src), "jsri32 $src", []>;
1489
1490let mayLoad = 1, Size = 4, isCodeGenOnly = 0 in
1491def PseudoJMPI32 : CSKYPseudo<(outs), (ins br_symbol:$src), "jmpi32 $src", []>;
1492
1493let isNotDuplicable = 1, mayLoad = 1, mayStore = 0, Size = 8 in
1494def PseudoTLSLA32 : CSKYPseudo<(outs GPR:$dst1, GPR:$dst2),
1495  (ins constpool_symbol:$src, i32imm:$label), "!tlslrw32\t$dst1, $dst2, $src, $label", []>;
1496
1497let hasSideEffects = 0, isNotDuplicable = 1 in
1498def CONSTPOOL_ENTRY : CSKYPseudo<(outs),
1499  (ins i32imm:$instid, i32imm:$cpidx, i32imm:$size), "", []>;
1500
1501include "CSKYInstrInfo16Instr.td"
1502include "CSKYInstrInfoF1.td"
1503include "CSKYInstrInfoF2.td"
1504include "CSKYInstrAlias.td"
1505