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