xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrInfo.td (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
1e8d8bef9SDimitry Andric//===-- CSKYInstrInfo.td - Target Description for CSKY -----*- tablegen -*-===//
2e8d8bef9SDimitry Andric//
3e8d8bef9SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e8d8bef9SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
5e8d8bef9SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e8d8bef9SDimitry Andric//
7e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
8e8d8bef9SDimitry Andric//
9e8d8bef9SDimitry Andric// This file describes the CSKY instructions in TableGen format.
10e8d8bef9SDimitry Andric//
11e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
12e8d8bef9SDimitry Andric
13e8d8bef9SDimitry Andric
14e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
15e8d8bef9SDimitry Andric// CSKY specific DAG Nodes.
16e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
17e8d8bef9SDimitry Andric
1804eeddc0SDimitry Andric// Target-independent type requirements, but with target-specific formats.
19349cc55cSDimitry Andricdef SDT_CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>,
20349cc55cSDimitry Andric                                       SDTCisVT<1, i32>]>;
21349cc55cSDimitry Andric
22349cc55cSDimitry Andricdef SDT_CallSeqEnd   : SDCallSeqEnd<[SDTCisVT<0, i32>,
23349cc55cSDimitry Andric                                     SDTCisVT<1, i32>]>;
24349cc55cSDimitry Andric
2504eeddc0SDimitry Andricdef SDT_CSKYCall : SDTypeProfile<0, 2, [SDTCisVT<0, iPTR>, SDTCisVT<1, iPTR>]>;
2604eeddc0SDimitry Andric
2704eeddc0SDimitry Andricdef SDT_CSKYCallReg : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;
2804eeddc0SDimitry Andric
2904eeddc0SDimitry Andricdef SDT_CSKY_LOADADDR : SDTypeProfile<1, 2, [SDTCisVT<0, i32>,
3004eeddc0SDimitry Andric                        SDTCisVT<1, iPTR>, SDTCisVT<2, iPTR>]>;
3104eeddc0SDimitry Andric
32349cc55cSDimitry Andricdef callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_CallSeqStart,
33349cc55cSDimitry Andric                           [SDNPHasChain, SDNPOutGlue]>;
34349cc55cSDimitry Andricdef callseq_end   : SDNode<"ISD::CALLSEQ_END", SDT_CallSeqEnd,
35349cc55cSDimitry Andric                           [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
36349cc55cSDimitry Andric
37fe6060f1SDimitry Andricdef CSKY_RET : SDNode<"CSKYISD::RET", SDTNone,
38fe6060f1SDimitry Andric    [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
39e8d8bef9SDimitry Andric
4004eeddc0SDimitry Andricdef CSKY_CALL : SDNode<"CSKYISD::CALL", SDT_CSKYCall,
4104eeddc0SDimitry Andric  [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, SDNPVariadic]>;
4204eeddc0SDimitry Andric
4304eeddc0SDimitry Andricdef CSKY_CALLReg : SDNode<"CSKYISD::CALLReg", SDT_CSKYCallReg,
4404eeddc0SDimitry Andric  [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, SDNPVariadic]>;
4504eeddc0SDimitry Andric
4604eeddc0SDimitry Andricdef CSKY_TAIL : SDNode<"CSKYISD::TAIL", SDT_CSKYCall,
4704eeddc0SDimitry Andric  [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, SDNPVariadic]>;
4804eeddc0SDimitry Andric
4904eeddc0SDimitry Andricdef CSKY_TAILReg : SDNode<"CSKYISD::TAILReg", SDT_CSKYCallReg,
5004eeddc0SDimitry Andric  [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, SDNPVariadic]>;
5104eeddc0SDimitry Andric
5204eeddc0SDimitry Andricdef CSKY_LOAD_ADDR : SDNode<"CSKYISD::LOAD_ADDR", SDT_CSKY_LOADADDR>;
5304eeddc0SDimitry Andric
54e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
55e8d8bef9SDimitry Andric// Operand and SDNode transformation definitions.
56e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
57fe6060f1SDimitry Andricclass ImmAsmOperand<string prefix, int width, string suffix> : AsmOperandClass {
58fe6060f1SDimitry Andric  let Name = prefix # "Imm" # width # suffix;
59fe6060f1SDimitry Andric  let RenderMethod = "addImmOperands";
60fe6060f1SDimitry Andric  let DiagnosticType = !strconcat("Invalid", Name);
61fe6060f1SDimitry Andric}
62fe6060f1SDimitry Andric
63fe6060f1SDimitry Andricclass SImmAsmOperand<int width, string suffix = "">
64fe6060f1SDimitry Andric    : ImmAsmOperand<"S", width, suffix> {
65fe6060f1SDimitry Andric}
66fe6060f1SDimitry Andric
67fe6060f1SDimitry Andricclass UImmAsmOperand<int width, string suffix = "">
68fe6060f1SDimitry Andric    : ImmAsmOperand<"U", width, suffix> {
69fe6060f1SDimitry Andric}
70fe6060f1SDimitry Andric
71fe6060f1SDimitry Andricclass OImmAsmOperand<int width, string suffix = "">
72fe6060f1SDimitry Andric    : ImmAsmOperand<"O", width, suffix> {
73fe6060f1SDimitry Andric}
74e8d8bef9SDimitry Andric
750eae32dcSDimitry Andricdef to_tframeindex : SDNodeXForm<frameindex, [{
760eae32dcSDimitry Andric  auto FI = cast<FrameIndexSDNode>(N);
770eae32dcSDimitry Andric  return CurDAG->getTargetFrameIndex(FI->getIndex(), TLI->getPointerTy(CurDAG->getDataLayout()));
780eae32dcSDimitry Andric}]>;
790eae32dcSDimitry Andric
8004eeddc0SDimitry Andricdef to_tconstpool : SDNodeXForm<constpool, [{
8104eeddc0SDimitry Andric  auto CP = cast<ConstantPoolSDNode>(N);
8204eeddc0SDimitry Andric  return CurDAG->getTargetConstantPool(CP->getConstVal(), TLI->getPointerTy(CurDAG->getDataLayout()),
8304eeddc0SDimitry Andric                    CP->getAlign(), CP->getOffset(), CSKYII::MO_None);
8404eeddc0SDimitry Andric}]>;
8504eeddc0SDimitry Andric
8604eeddc0SDimitry Andricdef to_tconstpool_hi16 : SDNodeXForm<constpool, [{
8704eeddc0SDimitry Andric  auto CP = cast<ConstantPoolSDNode>(N);
8804eeddc0SDimitry Andric  return CurDAG->getTargetConstantPool(CP->getConstVal(), TLI->getPointerTy(CurDAG->getDataLayout()),
8904eeddc0SDimitry Andric                    CP->getAlign(), CP->getOffset(), CSKYII::MO_ADDR_HI16);
9004eeddc0SDimitry Andric}]>;
9104eeddc0SDimitry Andric
9204eeddc0SDimitry Andricdef to_tconstpool_lo16 : SDNodeXForm<constpool, [{
9304eeddc0SDimitry Andric  auto CP = cast<ConstantPoolSDNode>(N);
9404eeddc0SDimitry Andric  return CurDAG->getTargetConstantPool(CP->getConstVal(), TLI->getPointerTy(CurDAG->getDataLayout()),
9504eeddc0SDimitry Andric                    CP->getAlign(), CP->getOffset(), CSKYII::MO_ADDR_LO16);
9604eeddc0SDimitry Andric}]>;
9704eeddc0SDimitry Andric
98e8d8bef9SDimitry Andricclass oimm<int num> : Operand<i32>,
99e8d8bef9SDimitry Andric  ImmLeaf<i32, "return isUInt<"#num#">(Imm - 1);"> {
100e8d8bef9SDimitry Andric  let EncoderMethod = "getOImmOpValue";
101fe6060f1SDimitry Andric  let ParserMatchClass = OImmAsmOperand<num>;
102349cc55cSDimitry Andric  let DecoderMethod = "decodeOImmOperand<"#num#">";
103e8d8bef9SDimitry Andric}
104e8d8bef9SDimitry Andric
10506c3fb27SDimitry Andricdef imm_neg_XFORM : SDNodeXForm<imm, [{
10606c3fb27SDimitry Andric  return CurDAG->getTargetConstant(-N->getSExtValue(), SDLoc(N), MVT::i32);
10706c3fb27SDimitry Andric}]>;
10806c3fb27SDimitry Andric
10906c3fb27SDimitry Andricclass oimm_neg<int num> : Operand<i32>,
11006c3fb27SDimitry Andric  ImmLeaf<i32, "return isUInt<"#num#">(-Imm - 1);"> {
11106c3fb27SDimitry Andric}
11206c3fb27SDimitry Andric
113e8d8bef9SDimitry Andricclass uimm<int num, int shift = 0> : Operand<i32>,
114e8d8bef9SDimitry Andric  ImmLeaf<i32, "return isShiftedUInt<"#num#", "#shift#">(Imm);"> {
115e8d8bef9SDimitry Andric  let EncoderMethod = "getImmOpValue<"#shift#">";
116fe6060f1SDimitry Andric  let ParserMatchClass =
117fe6060f1SDimitry Andric    !if(!ne(shift, 0),
118fe6060f1SDimitry Andric        UImmAsmOperand<num, "Shift"#shift>,
119fe6060f1SDimitry Andric        UImmAsmOperand<num>);
120349cc55cSDimitry Andric  let DecoderMethod = "decodeUImmOperand<"#num#", "#shift#">";
121e8d8bef9SDimitry Andric}
122e8d8bef9SDimitry Andric
12306c3fb27SDimitry Andricclass uimm_neg<int num, int shift = 0> : Operand<i32>,
12406c3fb27SDimitry Andric  ImmLeaf<i32, "return isShiftedUInt<"#num#", "#shift#">(-Imm);"> {
12506c3fb27SDimitry Andric}
12606c3fb27SDimitry Andric
127e8d8bef9SDimitry Andricclass simm<int num, int shift = 0> : Operand<i32>,
128e8d8bef9SDimitry Andric  ImmLeaf<i32, "return isShiftedInt<"#num#", "#shift#">(Imm);"> {
129e8d8bef9SDimitry Andric  let EncoderMethod = "getImmOpValue<"#shift#">";
130fe6060f1SDimitry Andric  let ParserMatchClass = SImmAsmOperand<num>;
131349cc55cSDimitry Andric  let DecoderMethod = "decodeSImmOperand<"#num#", "#shift#">";
132e8d8bef9SDimitry Andric}
133e8d8bef9SDimitry Andric
134e8d8bef9SDimitry Andricdef nimm_XFORM : SDNodeXForm<imm, [{
135e8d8bef9SDimitry Andric  return CurDAG->getTargetConstant(~N->getSExtValue(), SDLoc(N), MVT::i32);
136e8d8bef9SDimitry Andric}]>;
137e8d8bef9SDimitry Andricclass nimm<int num> : Operand<i32>,
138e8d8bef9SDimitry Andric  ImmLeaf<i32, "return isUInt<"#num#">(~Imm);", nimm_XFORM> {
139fe6060f1SDimitry Andric  let ParserMatchClass = UImmAsmOperand<num>;
140e8d8bef9SDimitry Andric}
141e8d8bef9SDimitry Andric
142fe6060f1SDimitry Andricdef uimm32_hi16 : SDNodeXForm<imm, [{
143fe6060f1SDimitry Andric  return CurDAG->getTargetConstant((N->getZExtValue() >> 16) & 0xFFFF,
144fe6060f1SDimitry Andric    SDLoc(N), MVT::i32);
145fe6060f1SDimitry Andric}]>;
146349cc55cSDimitry Andricdef uimm32_lo16 : SDNodeXForm<imm, [{
147349cc55cSDimitry Andric  return CurDAG->getTargetConstant(N->getZExtValue()& 0xFFFF, SDLoc(N), MVT::i32);
148349cc55cSDimitry Andric}]>;
149fe6060f1SDimitry Andricdef uimm16_16_xform : Operand<i32>,
150fe6060f1SDimitry Andric  ImmLeaf<i32, "return isShiftedUInt<16, 16>(Imm);", uimm32_hi16> {
151fe6060f1SDimitry Andric  let ParserMatchClass = UImmAsmOperand<16>;
152349cc55cSDimitry Andric  let EncoderMethod = "getImmOpValue";
153fe6060f1SDimitry Andric}
154fe6060f1SDimitry Andric
155fe6060f1SDimitry Andricdef uimm_shift : Operand<i32>, ImmLeaf<i32, "return isUInt<2>(Imm);"> {
156fe6060f1SDimitry Andric  let EncoderMethod = "getImmShiftOpValue";
157fe6060f1SDimitry Andric  let ParserMatchClass = UImmAsmOperand<2>;
158349cc55cSDimitry Andric  let DecoderMethod = "decodeImmShiftOpValue";
159fe6060f1SDimitry Andric}
160fe6060f1SDimitry Andric
161*5f757f3fSDimitry Andric// Optimize (or x, imm) to (BSETI x, log2(imm)). We should exclude the
162*5f757f3fSDimitry Andric// case can be opimized to (ORI32/ORI16 x, imm).
163*5f757f3fSDimitry Andricdef imm32_1_pop_bit_XFORM : SDNodeXForm<imm, [{
164*5f757f3fSDimitry Andric  uint32_t I = N->getZExtValue();
165*5f757f3fSDimitry Andric  return CurDAG->getTargetConstant(llvm::Log2_32(I), SDLoc(N),
166*5f757f3fSDimitry Andric                                   N->getValueType(0));
167*5f757f3fSDimitry Andric}]>;
168*5f757f3fSDimitry Andricdef imm32_1_pop_bit : PatLeaf<(imm), [{
169*5f757f3fSDimitry Andric  uint32_t I = N->getZExtValue();
170*5f757f3fSDimitry Andric  return llvm::popcount(I) == 1 && I > 0xfff;
171*5f757f3fSDimitry Andric}]>;
172*5f757f3fSDimitry Andric
173*5f757f3fSDimitry Andric// Optimize (and x, imm) to (BCLRI x, log2(~imm)). We should exclude the
174*5f757f3fSDimitry Andric// case can be opimized to (ANDNI x, ~imm).
175*5f757f3fSDimitry Andricdef imm32_1_zero_bit_XFORM : SDNodeXForm<imm, [{
176*5f757f3fSDimitry Andric  uint32_t I = ~N->getZExtValue();
177*5f757f3fSDimitry Andric  return CurDAG->getTargetConstant(llvm::Log2_32(I), SDLoc(N),
178*5f757f3fSDimitry Andric                                   N->getValueType(0));
179*5f757f3fSDimitry Andric}]>;
180*5f757f3fSDimitry Andricdef imm32_1_zero_bit : PatLeaf<(imm), [{
181*5f757f3fSDimitry Andric  uint32_t I = ~N->getZExtValue();
182*5f757f3fSDimitry Andric  return llvm::popcount(I) == 1 && I > 0xfff;
183*5f757f3fSDimitry Andric}]>;
184*5f757f3fSDimitry Andric
185fe6060f1SDimitry Andricdef CSKYSymbol : AsmOperandClass {
186fe6060f1SDimitry Andric  let Name = "CSKYSymbol";
187fe6060f1SDimitry Andric  let RenderMethod = "addImmOperands";
188fe6060f1SDimitry Andric  let DiagnosticType = "InvalidCSKYSymbol";
189fe6060f1SDimitry Andric  let ParserMethod = "parseCSKYSymbol";
190fe6060f1SDimitry Andric}
191fe6060f1SDimitry Andric
192753f127fSDimitry Andricdef br_symbol : Operand<OtherVT> {
193fe6060f1SDimitry Andric  let EncoderMethod =
194fe6060f1SDimitry Andric    "getBranchSymbolOpValue<CSKY::fixup_csky_pcrel_imm16_scale2>";
195fe6060f1SDimitry Andric  let ParserMatchClass = CSKYSymbol;
196349cc55cSDimitry Andric  let DecoderMethod = "decodeSImmOperand<16, 1>";
197349cc55cSDimitry Andric  let PrintMethod = "printCSKYSymbolOperand";
198349cc55cSDimitry Andric  let OperandType = "OPERAND_PCREL";
199fe6060f1SDimitry Andric}
200fe6060f1SDimitry Andric
201fe6060f1SDimitry Andricdef call_symbol : Operand<iPTR> {
202fe6060f1SDimitry Andric  let ParserMatchClass = CSKYSymbol;
203fe6060f1SDimitry Andric  let EncoderMethod = "getCallSymbolOpValue";
204349cc55cSDimitry Andric  let DecoderMethod = "decodeSImmOperand<26, 1>";
205349cc55cSDimitry Andric  let PrintMethod = "printCSKYSymbolOperand";
206349cc55cSDimitry Andric  let OperandType = "OPERAND_PCREL";
207fe6060f1SDimitry Andric}
208fe6060f1SDimitry Andric
209fe6060f1SDimitry Andricdef Constpool : AsmOperandClass {
210349cc55cSDimitry Andric  let Name = "Constpool";
211349cc55cSDimitry Andric  let RenderMethod = "addConstpoolOperands";
212fe6060f1SDimitry Andric  let DiagnosticType = "InvalidConstpool";
213fe6060f1SDimitry Andric  let ParserMethod = "parseConstpoolSymbol";
214fe6060f1SDimitry Andric}
215fe6060f1SDimitry Andric
216fe6060f1SDimitry Andricdef constpool_symbol : Operand<iPTR> {
217fe6060f1SDimitry Andric  let ParserMatchClass = Constpool;
218fe6060f1SDimitry Andric  let EncoderMethod =
219fe6060f1SDimitry Andric    "getConstpoolSymbolOpValue<CSKY::fixup_csky_pcrel_uimm16_scale4>";
220349cc55cSDimitry Andric  let DecoderMethod = "decodeUImmOperand<16, 2>";
221349cc55cSDimitry Andric  let PrintMethod = "printConstpool";
222349cc55cSDimitry Andric  let OperandType = "OPERAND_PCREL";
223349cc55cSDimitry Andric}
224349cc55cSDimitry Andric
225349cc55cSDimitry Andricdef DataAsmClass : AsmOperandClass {
226349cc55cSDimitry Andric  let Name = "DataSymbol";
227349cc55cSDimitry Andric  let RenderMethod = "addConstpoolOperands";
228349cc55cSDimitry Andric  let DiagnosticType = "InvalidConstpool";
229349cc55cSDimitry Andric  let ParserMethod = "parseDataSymbol";
230349cc55cSDimitry Andric}
231349cc55cSDimitry Andric
232349cc55cSDimitry Andricclass data_symbol<string reloc, int shift> : Operand<iPTR> {
233349cc55cSDimitry Andric  let ParserMatchClass = Constpool;
234349cc55cSDimitry Andric  let EncoderMethod =
235349cc55cSDimitry Andric    "getDataSymbolOpValue<"#reloc#">";
236349cc55cSDimitry Andric  let DecoderMethod = "decodeUImmOperand<18, "#shift#">";
237349cc55cSDimitry Andric  let PrintMethod = "printDataSymbol";
238fe6060f1SDimitry Andric}
239fe6060f1SDimitry Andric
240fe6060f1SDimitry Andricdef bare_symbol : Operand<iPTR> {
241fe6060f1SDimitry Andric  let ParserMatchClass = CSKYSymbol;
242fe6060f1SDimitry Andric  let EncoderMethod = "getBareSymbolOpValue";
243349cc55cSDimitry Andric  let PrintMethod = "printCSKYSymbolOperand";
244349cc55cSDimitry Andric  let DecoderMethod = "decodeSImmOperand<18, 1>";
245349cc55cSDimitry Andric  let OperandType = "OPERAND_PCREL";
246fe6060f1SDimitry Andric}
247e8d8bef9SDimitry Andric
2480eae32dcSDimitry Andricdef oimm3 : oimm<3> {
2490eae32dcSDimitry Andric  let MCOperandPredicate = [{
2500eae32dcSDimitry Andric    int64_t Imm;
2510eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
2520eae32dcSDimitry Andric      return isUInt<3>(Imm - 1);
2530eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
2540eae32dcSDimitry Andric  }];
2550eae32dcSDimitry Andric}
256349cc55cSDimitry Andricdef oimm4 : oimm<4>;
2570eae32dcSDimitry Andricdef oimm5 : oimm<5> {
2580eae32dcSDimitry Andric  let MCOperandPredicate = [{
2590eae32dcSDimitry Andric    int64_t Imm;
2600eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
2610eae32dcSDimitry Andric      return isUInt<5>(Imm - 1);
2620eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
2630eae32dcSDimitry Andric  }];
2640eae32dcSDimitry Andric}
265349cc55cSDimitry Andricdef oimm6 : oimm<6>;
266349cc55cSDimitry Andric
267349cc55cSDimitry Andricdef imm5_idly : Operand<i32>, ImmLeaf<i32,
268349cc55cSDimitry Andric  "return Imm <= 32 && Imm >= 0;"> {
269349cc55cSDimitry Andric  let EncoderMethod = "getImmOpValueIDLY";
270349cc55cSDimitry Andric  let DecoderMethod = "decodeOImmOperand<5>";
271349cc55cSDimitry Andric}
272349cc55cSDimitry Andric
2730eae32dcSDimitry Andricdef oimm8 : oimm<8> {
2740eae32dcSDimitry Andric  let MCOperandPredicate = [{
2750eae32dcSDimitry Andric    int64_t Imm;
2760eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
2770eae32dcSDimitry Andric      return isUInt<8>(Imm - 1);
2780eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
2790eae32dcSDimitry Andric  }];
2800eae32dcSDimitry Andric}
2810eae32dcSDimitry Andricdef oimm12 : oimm<12> {
2820eae32dcSDimitry Andric  let MCOperandPredicate = [{
2830eae32dcSDimitry Andric    int64_t Imm;
2840eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
2850eae32dcSDimitry Andric      return isUInt<12>(Imm - 1);
2860eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
2870eae32dcSDimitry Andric  }];
2880eae32dcSDimitry Andric}
2890eae32dcSDimitry Andricdef oimm16 : oimm<16> {
2900eae32dcSDimitry Andric  let MCOperandPredicate = [{
2910eae32dcSDimitry Andric    int64_t Imm;
2920eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
2930eae32dcSDimitry Andric      return isUInt<16>(Imm - 1);
2940eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
2950eae32dcSDimitry Andric  }];
2960eae32dcSDimitry Andric}
297e8d8bef9SDimitry Andric
29806c3fb27SDimitry Andricdef oimm8_neg : oimm_neg<8> {
29906c3fb27SDimitry Andric  let MCOperandPredicate = [{
30006c3fb27SDimitry Andric    int64_t Imm;
30106c3fb27SDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
30206c3fb27SDimitry Andric      return isUInt<8>(-Imm - 1);
30306c3fb27SDimitry Andric    return MCOp.isBareSymbolRef();
30406c3fb27SDimitry Andric  }];
30506c3fb27SDimitry Andric}
30606c3fb27SDimitry Andricdef oimm12_neg : oimm_neg<12> {
30706c3fb27SDimitry Andric  let MCOperandPredicate = [{
30806c3fb27SDimitry Andric    int64_t Imm;
30906c3fb27SDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
31006c3fb27SDimitry Andric      return isUInt<12>(-Imm - 1);
31106c3fb27SDimitry Andric    return MCOp.isBareSymbolRef();
31206c3fb27SDimitry Andric  }];
31306c3fb27SDimitry Andric}
31406c3fb27SDimitry Andric
315e8d8bef9SDimitry Andricdef nimm12 : nimm<12>;
316e8d8bef9SDimitry Andric
317349cc55cSDimitry Andricdef uimm1 : uimm<1>;
318349cc55cSDimitry Andricdef uimm2 : uimm<2>;
319349cc55cSDimitry Andric
320349cc55cSDimitry Andric
321349cc55cSDimitry Andricdef uimm2_jmpix : Operand<i32>,
322349cc55cSDimitry Andric  ImmLeaf<i32, "return Imm == 16 || Imm == 24 || Imm == 32 || Imm == 40;"> {
323349cc55cSDimitry Andric  let EncoderMethod = "getImmJMPIX";
324349cc55cSDimitry Andric  let DecoderMethod = "decodeJMPIXImmOperand";
325349cc55cSDimitry Andric}
326349cc55cSDimitry Andric
327349cc55cSDimitry Andricdef uimm3 : uimm<3>;
328349cc55cSDimitry Andricdef uimm4 : uimm<4>;
3290eae32dcSDimitry Andricdef uimm5 : uimm<5> {
3300eae32dcSDimitry Andric  let MCOperandPredicate = [{
3310eae32dcSDimitry Andric    int64_t Imm;
3320eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
3330eae32dcSDimitry Andric      return isShiftedUInt<5, 0>(Imm);
3340eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
3350eae32dcSDimitry Andric  }];
3360eae32dcSDimitry Andric}
337349cc55cSDimitry Andricdef uimm5_msb_size : uimm<5> {
338349cc55cSDimitry Andric  let EncoderMethod = "getImmOpValueMSBSize";
339349cc55cSDimitry Andric}
340349cc55cSDimitry Andric
3410eae32dcSDimitry Andricdef uimm5_1 : uimm<5, 1> {
3420eae32dcSDimitry Andric  let MCOperandPredicate = [{
3430eae32dcSDimitry Andric    int64_t Imm;
3440eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
3450eae32dcSDimitry Andric      return isShiftedUInt<5, 1>(Imm);
3460eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
3470eae32dcSDimitry Andric  }];
3480eae32dcSDimitry Andric}
3490eae32dcSDimitry Andricdef uimm5_2 : uimm<5, 2> {
3500eae32dcSDimitry Andric  let MCOperandPredicate = [{
3510eae32dcSDimitry Andric    int64_t Imm;
3520eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
3530eae32dcSDimitry Andric      return isShiftedUInt<5, 2>(Imm);
3540eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
3550eae32dcSDimitry Andric  }];
3560eae32dcSDimitry Andric}
357349cc55cSDimitry Andricdef uimm6 : uimm<6>;
358349cc55cSDimitry Andricdef uimm7 : uimm<7>;
359349cc55cSDimitry Andricdef uimm7_1 : uimm<7, 1>;
3600eae32dcSDimitry Andricdef uimm7_2 : uimm<7, 2>{
3610eae32dcSDimitry Andric  let MCOperandPredicate = [{
3620eae32dcSDimitry Andric    int64_t Imm;
3630eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
3640eae32dcSDimitry Andric      return isShiftedUInt<7, 2>(Imm);
3650eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
3660eae32dcSDimitry Andric  }];
3670eae32dcSDimitry Andric}
368349cc55cSDimitry Andricdef uimm7_3 : uimm<7, 3>;
3690eae32dcSDimitry Andricdef uimm8 : uimm<8> {
3700eae32dcSDimitry Andric  let MCOperandPredicate = [{
3710eae32dcSDimitry Andric    int64_t Imm;
3720eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
3730eae32dcSDimitry Andric      return isShiftedUInt<8, 0>(Imm);
3740eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
3750eae32dcSDimitry Andric  }];
3760eae32dcSDimitry Andric}
3770eae32dcSDimitry Andricdef uimm8_2 : uimm<8, 2> {
3780eae32dcSDimitry Andric  let MCOperandPredicate = [{
3790eae32dcSDimitry Andric    int64_t Imm;
3800eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
3810eae32dcSDimitry Andric      return isShiftedUInt<8, 2>(Imm);
3820eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
3830eae32dcSDimitry Andric  }];
3840eae32dcSDimitry Andric}
385349cc55cSDimitry Andricdef uimm8_3 : uimm<8, 3>;
386349cc55cSDimitry Andricdef uimm8_8 : uimm<8, 8>;
387349cc55cSDimitry Andricdef uimm8_16 : uimm<8, 16>;
388349cc55cSDimitry Andricdef uimm8_24 : uimm<8, 24>;
3890eae32dcSDimitry Andricdef uimm12 : uimm<12>  {
3900eae32dcSDimitry Andric  let MCOperandPredicate = [{
3910eae32dcSDimitry Andric    int64_t Imm;
3920eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
3930eae32dcSDimitry Andric      return isShiftedUInt<12, 0>(Imm);
3940eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
3950eae32dcSDimitry Andric  }];
3960eae32dcSDimitry Andric}
3970eae32dcSDimitry Andricdef uimm12_1 : uimm<12, 1> {
3980eae32dcSDimitry Andric  let MCOperandPredicate = [{
3990eae32dcSDimitry Andric    int64_t Imm;
4000eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
4010eae32dcSDimitry Andric      return isShiftedUInt<12, 1>(Imm);
4020eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
4030eae32dcSDimitry Andric  }];
4040eae32dcSDimitry Andric}
4050eae32dcSDimitry Andricdef uimm12_2 : uimm<12, 2> {
4060eae32dcSDimitry Andric  let MCOperandPredicate = [{
4070eae32dcSDimitry Andric    int64_t Imm;
4080eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
4090eae32dcSDimitry Andric      return isShiftedUInt<12, 2>(Imm);
4100eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
4110eae32dcSDimitry Andric  }];
4120eae32dcSDimitry Andric}
4130eae32dcSDimitry Andricdef uimm16 : uimm<16> {
4140eae32dcSDimitry Andric  let MCOperandPredicate = [{
4150eae32dcSDimitry Andric    int64_t Imm;
4160eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
4170eae32dcSDimitry Andric      return isShiftedUInt<16, 0>(Imm);
4180eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
4190eae32dcSDimitry Andric  }];
4200eae32dcSDimitry Andric}
421349cc55cSDimitry Andricdef uimm16_8 : uimm<16, 8>;
422349cc55cSDimitry Andricdef uimm16_16 : uimm<16, 16>;
423349cc55cSDimitry Andricdef uimm20 : uimm<20>;
424349cc55cSDimitry Andricdef uimm24 : uimm<24>;
425349cc55cSDimitry Andricdef uimm24_8 : uimm<24, 8>;
426fe6060f1SDimitry Andric
42706c3fb27SDimitry Andricdef uimm5_neg : uimm_neg<5>;
42806c3fb27SDimitry Andric
429349cc55cSDimitry Andricdef simm8_2 : simm<8, 2>;
430349cc55cSDimitry Andric
431349cc55cSDimitry Andricclass RegSeqAsmOperand<string Suffix = ""> : AsmOperandClass {
432349cc55cSDimitry Andric  let Name = "RegSeq"#Suffix;
433349cc55cSDimitry Andric  let RenderMethod = "addRegSeqOperands";
434349cc55cSDimitry Andric  let DiagnosticType = "InvalidRegSeq";
435349cc55cSDimitry Andric  let ParserMethod = "parseRegSeq";
436349cc55cSDimitry Andric}
437349cc55cSDimitry Andric
438349cc55cSDimitry Andricdef regseq : Operand<iPTR> {
439349cc55cSDimitry Andric  let EncoderMethod = "getRegisterSeqOpValue";
440349cc55cSDimitry Andric  let ParserMatchClass = RegSeqAsmOperand<"">;
441349cc55cSDimitry Andric  let PrintMethod = "printRegisterSeq";
442349cc55cSDimitry Andric  let DecoderMethod = "DecodeRegSeqOperand";
443349cc55cSDimitry Andric  let MIOperandInfo = (ops GPR, uimm5);
444349cc55cSDimitry Andric}
445349cc55cSDimitry Andric
446349cc55cSDimitry Andricdef RegListAsmOperand : AsmOperandClass {
447349cc55cSDimitry Andric  let Name = "RegList";
448349cc55cSDimitry Andric  let RenderMethod = "addRegListOperands";
449349cc55cSDimitry Andric  let DiagnosticType = "InvalidRegList";
450349cc55cSDimitry Andric  let ParserMethod = "parseRegList";
451349cc55cSDimitry Andric}
452349cc55cSDimitry Andric
453349cc55cSDimitry Andricdef reglist : Operand<iPTR> {
454349cc55cSDimitry Andric  let ParserMatchClass = RegListAsmOperand;
455349cc55cSDimitry Andric  let PrintMethod = "printRegisterList";
456349cc55cSDimitry Andric}
457349cc55cSDimitry Andric
458349cc55cSDimitry Andricdef PSRFlag : AsmOperandClass {
459349cc55cSDimitry Andric  let Name = "PSRFlag";
460349cc55cSDimitry Andric  let RenderMethod = "addImmOperands";
461349cc55cSDimitry Andric  let DiagnosticType = "InvalidPSRFlag";
462349cc55cSDimitry Andric  let ParserMethod = "parsePSRFlag";
463349cc55cSDimitry Andric}
464349cc55cSDimitry Andric
465349cc55cSDimitry Andricdef psrflag : Operand<i32>, ImmLeaf<i32, "return isShiftedUInt<5, 0>(Imm);"> {
466349cc55cSDimitry Andric  let EncoderMethod = "getImmOpValue";
467349cc55cSDimitry Andric  let ParserMatchClass = PSRFlag;
468349cc55cSDimitry Andric  let PrintMethod = "printPSRFlag";
469349cc55cSDimitry Andric}
470fe6060f1SDimitry Andric
47181ad6265SDimitry Andricmulticlass uimm8SRLXForm<SDNode opc> {
47281ad6265SDimitry Andric  def _0: SDNodeXForm<opc,
47381ad6265SDimitry Andric    [{return CurDAG->getTargetConstant((N->getZExtValue() >> 0) & 0xFF, SDLoc(N), MVT::i32);}]>;
47481ad6265SDimitry Andric  def _8: SDNodeXForm<opc,
47581ad6265SDimitry Andric    [{return CurDAG->getTargetConstant((N->getZExtValue() >> 8) & 0xFF, SDLoc(N), MVT::i32);}]>;
47681ad6265SDimitry Andric  def _16: SDNodeXForm<opc,
47781ad6265SDimitry Andric    [{return CurDAG->getTargetConstant((N->getZExtValue() >> 16) & 0xFF, SDLoc(N), MVT::i32);}]>;
47881ad6265SDimitry Andric  def _24: SDNodeXForm<opc,
47981ad6265SDimitry Andric    [{return CurDAG->getTargetConstant((N->getZExtValue() >> 24) & 0xFF, SDLoc(N), MVT::i32);}]>;
48081ad6265SDimitry Andric}
48181ad6265SDimitry Andric
48281ad6265SDimitry Andricdefm uimm8SRL : uimm8SRLXForm<imm>;
48381ad6265SDimitry Andric
484fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
485fe6060f1SDimitry Andric// Instruction Formats
486fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
487fe6060f1SDimitry Andric
488fe6060f1SDimitry Andricinclude "CSKYInstrFormats.td"
489e8d8bef9SDimitry Andric
490e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
491e8d8bef9SDimitry Andric// Instruction definitions.
492e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
493e8d8bef9SDimitry Andric
494e8d8bef9SDimitry Andricclass TriOpFrag<dag res> : PatFrag<(ops node: $LHS, node:$MHS, node:$RHS), res>;
495e8d8bef9SDimitry Andricclass BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
496e8d8bef9SDimitry Andricclass UnOpFrag<dag res> : PatFrag<(ops node:$Src), res>;
497e8d8bef9SDimitry Andric
498349cc55cSDimitry Andricdef eqToAdd : PatFrag<(ops node:$lhs, node:$rhs), (or node:$lhs, node:$rhs), [{
499349cc55cSDimitry Andric  return isOrEquivalentToAdd(N);
500349cc55cSDimitry Andric}]>;
501349cc55cSDimitry Andric
502349cc55cSDimitry Andricdef BaseAddr : ComplexPattern<iPTR, 1, "SelectBaseAddr">;
503349cc55cSDimitry Andric
504349cc55cSDimitry Andric
505349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
506349cc55cSDimitry Andric// CSKYPseudo
507349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
508349cc55cSDimitry Andric
509349cc55cSDimitry Andric// Pessimistically assume the stack pointer will be clobbered
510349cc55cSDimitry Andriclet Defs = [R14], Uses = [R14] in {
511349cc55cSDimitry Andricdef ADJCALLSTACKDOWN : CSKYPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
512349cc55cSDimitry Andric  "!ADJCALLSTACKDOWN $amt1, $amt2", [(callseq_start timm:$amt1, timm:$amt2)]>;
513349cc55cSDimitry Andricdef ADJCALLSTACKUP   : CSKYPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
514349cc55cSDimitry Andric  "!ADJCALLSTACKUP $amt1, $amt2", [(callseq_end timm:$amt1, timm:$amt2)]>;
515349cc55cSDimitry Andric} // Defs = [R14], Uses = [R14]
516fe6060f1SDimitry Andric
517fe6060f1SDimitry Andric
518fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
519fe6060f1SDimitry Andric// Basic ALU instructions.
520fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
521fe6060f1SDimitry Andric
522349cc55cSDimitry Andriclet Predicates = [iHasE2] in {
523349cc55cSDimitry Andric  let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
524349cc55cSDimitry Andric  let isAdd = 1 in
525e8d8bef9SDimitry Andric  def ADDI32 : I_12<0x0, "addi32", add, oimm12>;
526e8d8bef9SDimitry Andric  def SUBI32 : I_12<0x1, "subi32", sub, oimm12>;
527fe6060f1SDimitry Andric  def ORI32 : I_16_ZX<"ori32", uimm16,
528fe6060f1SDimitry Andric  [(set GPR:$rz, (or GPR:$rx, uimm16:$imm16))]>;
529fe6060f1SDimitry Andric  def XORI32 : I_12<0x4, "xori32", xor, uimm12>;
530e8d8bef9SDimitry Andric  def ANDI32 : I_12<0x2, "andi32", and, uimm12>;
531e8d8bef9SDimitry Andric  def ANDNI32 : I_12<0x3, "andni32", and, nimm12>;
532e8d8bef9SDimitry Andric  def LSLI32 : I_5_XZ<0x12, 0x1, "lsli32",
533e8d8bef9SDimitry Andric    (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5),
534e8d8bef9SDimitry Andric    [(set GPR:$rz, (shl GPR:$rx, uimm5:$imm5))]>;
535e8d8bef9SDimitry Andric  def LSRI32 : I_5_XZ<0x12, 0x2, "lsri32",
536e8d8bef9SDimitry Andric    (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5),
537e8d8bef9SDimitry Andric    [(set GPR:$rz, (srl GPR:$rx, uimm5:$imm5))]>;
538e8d8bef9SDimitry Andric  def ASRI32 : I_5_XZ<0x12, 0x4, "asri32",
539e8d8bef9SDimitry Andric    (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5),
540e8d8bef9SDimitry Andric    [(set GPR:$rz, (sra GPR:$rx, uimm5:$imm5))]>;
541fe6060f1SDimitry Andric  def ROTLI32 : I_5_XZ<0x12, 0x8, "rotli32",
542fe6060f1SDimitry Andric    (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5),
543fe6060f1SDimitry Andric    [(set GPR:$rz, (rotl GPR:$rx, uimm5:$imm5))]>;
544e8d8bef9SDimitry Andric
545349cc55cSDimitry Andric  def ROTRI32 : CSKYPseudo<(outs GPR:$rz), (ins GPR:$rx, oimm5:$imm5),
546349cc55cSDimitry Andric                            "rotri32 $rz, $rx, $imm5", []>;
547349cc55cSDimitry Andric  }
548349cc55cSDimitry Andric  let isAdd = 1 in
549e8d8bef9SDimitry Andric  def ADDU32 : R_YXZ_SP_F1<0x0, 0x1,
550e8d8bef9SDimitry Andric    BinOpFrag<(add node:$LHS, node:$RHS)>, "addu32", 1>;
551e8d8bef9SDimitry Andric  def SUBU32 : R_YXZ_SP_F1<0x0, 0x4,
552e8d8bef9SDimitry Andric    BinOpFrag<(sub node:$LHS, node:$RHS)>, "subu32">;
553349cc55cSDimitry Andric
554fe6060f1SDimitry Andric  def MULT32 : R_YXZ_SP_F1<0x21, 0x1,
555fe6060f1SDimitry Andric    BinOpFrag<(mul node:$LHS, node:$RHS)>, "mult32", 1>;
556e8d8bef9SDimitry Andric  def AND32 : R_YXZ_SP_F1<0x8, 0x1,
557e8d8bef9SDimitry Andric    BinOpFrag<(and node:$LHS, node:$RHS)>, "and32", 1>;
558e8d8bef9SDimitry Andric  def ANDN32 : R_YXZ_SP_F1<0x8, 0x2,
559e8d8bef9SDimitry Andric    BinOpFrag<(and node:$LHS, (not node:$RHS))>, "andn32">;
560e8d8bef9SDimitry Andric  def OR32: R_YXZ_SP_F1<0x9, 0x1,
561e8d8bef9SDimitry Andric    BinOpFrag<(or node:$LHS, node:$RHS)>, "or32", 1>;
562e8d8bef9SDimitry Andric  def XOR32 : R_YXZ_SP_F1<0x9, 0x2,
563e8d8bef9SDimitry Andric    BinOpFrag<(xor node:$LHS, node:$RHS)>, "xor32", 1>;
564e8d8bef9SDimitry Andric  def NOR32 : R_YXZ_SP_F1<0x9, 0x4,
565e8d8bef9SDimitry Andric    BinOpFrag<(not (or node:$LHS, node:$RHS))>, "nor32", 1>;
566349cc55cSDimitry Andric  let isCodeGenOnly = 1 in
567fe6060f1SDimitry Andric  def NOT32 : R_XXZ<0b001001, 0b00100, (outs GPR:$rz), (ins GPR:$rx),
568fe6060f1SDimitry Andric    "not32", [(set GPR:$rz, (not GPR:$rx))]>;
569349cc55cSDimitry Andric
570349cc55cSDimitry Andric  let Size = 8 in
571349cc55cSDimitry Andric  def NEG32 : CSKYPseudo<(outs GPR:$rd), (ins GPR:$rx), "neg32 $rd, $rx", []>;
572349cc55cSDimitry Andric
573349cc55cSDimitry Andric  let Size = 8 in
574349cc55cSDimitry Andric  def RSUBI32 : CSKYPseudo<(outs GPR:$rd), (ins GPR:$rx, uimm12:$imm12), "rsubi32 $rd, $rx, $imm12", []>;
575349cc55cSDimitry Andric
57606c3fb27SDimitry Andric  def : Pat<(add GPR:$rs1, (oimm12_neg:$im)),
57706c3fb27SDimitry Andric            (SUBI32 GPR:$rs1, (imm_neg_XFORM oimm12_neg:$im))>;
57806c3fb27SDimitry Andric
579e8d8bef9SDimitry Andric  def LSL32 : R_YXZ_SP_F1<0x10, 0x1,
580e8d8bef9SDimitry Andric    BinOpFrag<(shl node:$LHS, node:$RHS)>, "lsl32">;
581e8d8bef9SDimitry Andric  def LSR32 : R_YXZ_SP_F1<0x10, 0x2,
582e8d8bef9SDimitry Andric    BinOpFrag<(srl node:$LHS, node:$RHS)>, "lsr32">;
583e8d8bef9SDimitry Andric  def ASR32 : R_YXZ_SP_F1<0x10, 0x4,
584e8d8bef9SDimitry Andric    BinOpFrag<(sra node:$LHS, node:$RHS)>, "asr32">;
585fe6060f1SDimitry Andric  def ROTL32 : R_YXZ_SP_F1<0x10, 0x8,
586fe6060f1SDimitry Andric    BinOpFrag<(rotl node:$LHS, (and node:$RHS, 0x1f))>, "rotl32">;
587fe6060f1SDimitry Andric
588349cc55cSDimitry Andric  def BMASKI32 : I_5_Z<0b010100, 0x1, "bmaski32", oimm5, []>;
589349cc55cSDimitry Andric  def LSLC32 : I_5_XZ<0x13, 0x1, "lslc32",
590349cc55cSDimitry Andric    (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, oimm5:$imm5), []>;
591349cc55cSDimitry Andric  def LSRC32 : I_5_XZ<0x13, 0x2, "lsrc32",
592349cc55cSDimitry Andric    (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, oimm5:$imm5), []>;
593349cc55cSDimitry Andric  def ASRC32 : I_5_XZ<0x13, 0x4, "asrc32",
594349cc55cSDimitry Andric    (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, oimm5:$imm5), []>;
595349cc55cSDimitry Andric  def XSR32 : I_5_XZ<0x13, 0x8, "xsr32",
596349cc55cSDimitry Andric    (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, oimm5:$imm5, CARRY:$cin), []>;
597fe6060f1SDimitry Andric
598fe6060f1SDimitry Andric  def IXH32 : R_YXZ_SP_F1<0x2, 0x1,
599fe6060f1SDimitry Andric    BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 1)))>, "ixh32">;
600fe6060f1SDimitry Andric  def IXW32 : R_YXZ_SP_F1<0x2, 0x2,
601fe6060f1SDimitry Andric    BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 2)))>, "ixw32">;
602349cc55cSDimitry Andric  let Predicates = [iHas2E3] in
603fe6060f1SDimitry Andric  def IXD32 : R_YXZ_SP_F1<0x2, 0x4,
604fe6060f1SDimitry Andric    BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 3)))>, "ixd32">;
605fe6060f1SDimitry Andric
606349cc55cSDimitry Andric  let isCommutable = 1, isAdd = 1 in
607fe6060f1SDimitry Andric  def ADDC32 : R_YXZ<0x31, 0x0, 0x2, (outs GPR:$rz, CARRY:$cout),
608fe6060f1SDimitry Andric    (ins GPR:$rx, GPR:$ry, CARRY:$cin), "addc32", []>;
609fe6060f1SDimitry Andric  def SUBC32 : R_YXZ<0x31, 0x0, 0x8, (outs GPR:$rz, CARRY:$cout),
610fe6060f1SDimitry Andric    (ins GPR:$rx, GPR:$ry, CARRY:$cin), "subc32", []>;
611fe6060f1SDimitry Andric
612349cc55cSDimitry Andric  def INCF32 : I_5_ZX<0x3, 0x1, "incf32", uimm5, []>;
613349cc55cSDimitry Andric  def INCT32 : I_5_ZX<0x3, 0x2, "inct32", uimm5, []>;
614349cc55cSDimitry Andric  def DECF32 : I_5_ZX<0x3, 0x4, "decf32", uimm5, []>;
615349cc55cSDimitry Andric  def DECT32 : I_5_ZX<0x3, 0x8, "dect32", uimm5, []>;
616349cc55cSDimitry Andric}
617349cc55cSDimitry Andric
618349cc55cSDimitry Andriclet Predicates = [iHas2E3] in {
619e8d8bef9SDimitry Andric  def DIVS32 : R_YXZ_SP_F1<0x20, 0x2,
620e8d8bef9SDimitry Andric    BinOpFrag<(sdiv node:$LHS, node:$RHS)>, "divs32">;
621e8d8bef9SDimitry Andric  def DIVU32 : R_YXZ_SP_F1<0x20, 0x1,
622e8d8bef9SDimitry Andric    BinOpFrag<(udiv node:$LHS, node:$RHS)>, "divu32">;
623e8d8bef9SDimitry Andric
624fe6060f1SDimitry Andric  def DECGT32 : I_5_XZ<0x4, 0x1, "decgt32",
625fe6060f1SDimitry Andric    (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, uimm5:$imm5), []>;
626fe6060f1SDimitry Andric  def DECLT32 : I_5_XZ<0x4, 0x2, "declt32",
627fe6060f1SDimitry Andric    (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, uimm5:$imm5), []>;
628fe6060f1SDimitry Andric  def DECNE32 : I_5_XZ<0x4, 0x4, "decne32",
629fe6060f1SDimitry Andric    (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, uimm5:$imm5), []>;
630fe6060f1SDimitry Andric
631349cc55cSDimitry Andric  def SEXT32 : I_5_XZ_U<0x16, (outs GPR:$rz), (ins GPR:$rx, uimm5:$msb, uimm5:$lsb), "sext32", []>;
632349cc55cSDimitry Andric  let isCodeGenOnly = 1 in {
633349cc55cSDimitry Andric  def SEXTB32 : I_5_XZ_US<0x16, 0, 7, "sextb32", sext_inreg, i8>;
634349cc55cSDimitry Andric  def SEXTH32 : I_5_XZ_US<0x16, 0, 15, "sexth32", sext_inreg, i16>;
635349cc55cSDimitry Andric  def ZEXTB32 : I_5_XZ_UZ<0x15, 0, 7, "zextb32", 255>;
636349cc55cSDimitry Andric  def ZEXTH32 : I_5_XZ_UZ<0x15, 0, 15, "zexth32", 65535>;
637349cc55cSDimitry Andric  }
638349cc55cSDimitry Andric  def ZEXT32 : I_5_XZ_U<0x15, (outs GPR:$rz), (ins GPR:$rx, uimm5:$msb, uimm5:$lsb), "zext32",[]>;
639349cc55cSDimitry Andric
640349cc55cSDimitry Andric  let Constraints = "$rZ = $rz" in
641349cc55cSDimitry Andric  def INS32 : I_5_XZ_INS<0b010111, (outs GPR:$rz), (ins GPR:$rZ, GPR:$rx, uimm5_msb_size:$msb, uimm5:$lsb), "ins32", []>;
642349cc55cSDimitry Andric}
643349cc55cSDimitry Andric
644349cc55cSDimitry Andriclet Predicates = [iHas3E3r1] in {
645349cc55cSDimitry Andricdef MULTS32 : R_YXZ<0x3e, 0x20, 0x10, (outs GPRPair:$rz),
646349cc55cSDimitry Andric    (ins GPR:$rx, GPR:$ry), "mul.s32", []>;
647349cc55cSDimitry Andricdef MULTU32 : R_YXZ<0x3e, 0x20, 0x00, (outs GPRPair:$rz),
648349cc55cSDimitry Andric    (ins GPR:$rx, GPR:$ry), "mul.u32", []>;
649349cc55cSDimitry Andric
650349cc55cSDimitry Andriclet Constraints = "$rZ = $rz" in {
651349cc55cSDimitry Andricdef MULATS32 : R_YXZ<0x3e, 0x20, 0x14, (outs GPRPair:$rZ),
652349cc55cSDimitry Andric    (ins GPRPair:$rz, GPR:$rx, GPR:$ry), "mula.s32", []>;
653349cc55cSDimitry Andricdef MULATU32 : R_YXZ<0x3e, 0x20, 0x04, (outs GPRPair:$rZ),
654349cc55cSDimitry Andric    (ins GPRPair:$rz, GPR:$rx, GPR:$ry), "mula.u32", []>;
655349cc55cSDimitry Andric}
656349cc55cSDimitry Andric}
657349cc55cSDimitry Andric
658349cc55cSDimitry Andricdef MULSH32 : R_YXZ<0x31, 0b100100, 0b00001, (outs GPR:$rz),
659349cc55cSDimitry Andric    (ins GPR:$rx, GPR:$ry), "mulsh32", []>;
660fe6060f1SDimitry Andric
661fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
662fe6060f1SDimitry Andric// Load & Store instructions.
663fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
664fe6060f1SDimitry Andric
665fe6060f1SDimitry Andricdef LD32B : I_LD<AddrMode32B, 0x0, "ld32.b", uimm12>;
666fe6060f1SDimitry Andricdef LD32H : I_LD<AddrMode32H, 0x1, "ld32.h", uimm12_1>;
667fe6060f1SDimitry Andricdef LD32W : I_LD<AddrMode32WD, 0x2, "ld32.w", uimm12_2>;
668fe6060f1SDimitry Andric
669349cc55cSDimitry Andriclet OutOperandList = (outs GPRPair:$rz) in
670349cc55cSDimitry Andricdef LD32D : I_LD<AddrMode32WD, 0x3, "ld32.d", uimm12_2>;
671fe6060f1SDimitry Andric
672349cc55cSDimitry Andriclet Predicates = [iHasE2] in {
673fe6060f1SDimitry Andric  def LD32BS : I_LD<AddrMode32B, 0x4, "ld32.bs", uimm12>;
674fe6060f1SDimitry Andric  def LD32HS : I_LD<AddrMode32H, 0x5, "ld32.hs", uimm12_1>;
675fe6060f1SDimitry Andric
676349cc55cSDimitry Andric  def LDM32 : I_5_YX<0b110100, 0b000111,
677349cc55cSDimitry Andric    (outs), (ins GPR:$rx, regseq:$regs, variable_ops), "ldm32\t$regs, (${rx})", []>;
678349cc55cSDimitry Andric  def STM32 : I_5_YX<0b110101, 0b000111,
679349cc55cSDimitry Andric    (outs), (ins GPR:$rx, regseq:$regs, variable_ops), "stm32\t$regs, (${rx})", []>;
680fe6060f1SDimitry Andric
681349cc55cSDimitry Andric  let Size = 4, isCodeGenOnly = 0 in {
682349cc55cSDimitry Andric  def LDQ32 : CSKYPseudo<(outs), (ins GPR:$rx, regseq:$regs, variable_ops),
683349cc55cSDimitry Andric                             "ldq32\t$regs, (${rx})", []>;
684349cc55cSDimitry Andric  def STQ32 : CSKYPseudo<(outs), (ins GPR:$rx, regseq:$regs, variable_ops),
685349cc55cSDimitry Andric                             "stq32\t$regs, (${rx})", []>;
686349cc55cSDimitry Andric  }
687349cc55cSDimitry Andric
688349cc55cSDimitry Andric}
689fe6060f1SDimitry Andric
690fe6060f1SDimitry Andricdef ST32B : I_ST<AddrMode32B, 0x0, "st32.b", uimm12>;
691fe6060f1SDimitry Andricdef ST32H : I_ST<AddrMode32H, 0x1, "st32.h", uimm12_1>;
692fe6060f1SDimitry Andricdef ST32W : I_ST<AddrMode32WD, 0x2, "st32.w", uimm12_2>;
693fe6060f1SDimitry Andric
694349cc55cSDimitry Andriclet InOperandList = (ins GPRPair:$rz, GPR:$rx, uimm12_2:$imm12 ) in
695349cc55cSDimitry Andricdef ST32D : I_ST<AddrMode32WD, 0x3, "st32.d", uimm12_2>;
696fe6060f1SDimitry Andric
697349cc55cSDimitry Andriclet Predicates = [iHas2E3] in {
698fe6060f1SDimitry Andric  def LDR32B :  I_LDR<0x0, "ldr32.b">;
699fe6060f1SDimitry Andric  def LDR32BS :  I_LDR<0x4, "ldr32.bs">;
700fe6060f1SDimitry Andric  def LDR32H :  I_LDR<0x1, "ldr32.h">;
701fe6060f1SDimitry Andric  def LDR32HS :  I_LDR<0x5, "ldr32.hs">;
702fe6060f1SDimitry Andric  def LDR32W :  I_LDR<0x2, "ldr32.w">;
703fe6060f1SDimitry Andric  def STR32B :  I_STR<0x0, "str32.b">;
704fe6060f1SDimitry Andric  def STR32H :  I_STR<0x1, "str32.h">;
705fe6060f1SDimitry Andric  def STR32W :  I_STR<0x2, "str32.w">;
706349cc55cSDimitry Andric}
707fe6060f1SDimitry Andric
708349cc55cSDimitry Andric// Indicate that we're dumping the CR register, so we'll need to
709349cc55cSDimitry Andric// scavenge a register for it.
710349cc55cSDimitry Andriclet mayStore = 1 in {
711349cc55cSDimitry Andricdef SPILL_CARRY : CSKYPseudo<(outs), (ins CARRY:$cond, GPR:$rx, uimm12_2:$imm),
712349cc55cSDimitry Andric                             "!SPILL_CARRY $cond, $rx, $imm", []>;
713349cc55cSDimitry Andric}
714349cc55cSDimitry Andric
715349cc55cSDimitry Andric// Indicate that we're restoring the CR register (previously
716349cc55cSDimitry Andric// spilled), so we'll need to scavenge a register for it.
717349cc55cSDimitry Andriclet mayLoad = 1 in {
718349cc55cSDimitry Andricdef RESTORE_CARRY : CSKYPseudo<(outs CARRY:$cond), (ins GPR:$rx, uimm12_2:$imm),
719349cc55cSDimitry Andric                                "!RESTORE_CARRY $cond, $rx, $imm", []>;
720349cc55cSDimitry Andric}
721349cc55cSDimitry Andric
722349cc55cSDimitry Andriclet mayLoad = 1 in {
723349cc55cSDimitry Andricdef STORE_PAIR : CSKYPseudo<(outs), (ins GPRPair:$rz, GPR:$rx, uimm12_2:$imm),
724349cc55cSDimitry Andric                            "!STORE_PAIR $rz, $rx, $imm", []>;
725349cc55cSDimitry Andric}
726349cc55cSDimitry Andric
727349cc55cSDimitry Andriclet mayLoad = 1 in {
728349cc55cSDimitry Andricdef LOAD_PAIR : CSKYPseudo<(outs GPRPair:$rz), (ins GPR:$rx, uimm12_2:$imm),
729349cc55cSDimitry Andric                            "!LOAD_PAIR $rz, $rx, $imm", []>;
730349cc55cSDimitry Andric}
731fe6060f1SDimitry Andric
732fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
733fe6060f1SDimitry Andric// Compare instructions.
734fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
735349cc55cSDimitry Andriclet Predicates = [iHasE2] in {
736fe6060f1SDimitry Andric  def CMPNEI32 : I_16_X<0x1A, "cmpnei32", uimm16>;
737fe6060f1SDimitry Andric  def CMPHSI32 : I_16_X<0x18, "cmphsi32", oimm16>;
738fe6060f1SDimitry Andric  def CMPLTI32 : I_16_X<0x19, "cmplti32", oimm16>;
739349cc55cSDimitry Andric  def CMPLEI32 : CSKYPseudo<(outs CARRY:$ca), (ins GPR:$rx, uimm16:$imm16),
740349cc55cSDimitry Andric    "cmplei32\t$rx, $imm16", []>;
741349cc55cSDimitry Andric}
742349cc55cSDimitry Andriclet Predicates = [iHas2E3] in {
743fe6060f1SDimitry Andric  def CMPNE32 : R_YX<0x1, 0x4, "cmpne32">;
744fe6060f1SDimitry Andric  def CMPHS32 : R_YX<0x1, 0x1, "cmphs32">;
745fe6060f1SDimitry Andric  def CMPLT32 : R_YX<0x1, 0x2, "cmplt32">;
746fe6060f1SDimitry Andric
747349cc55cSDimitry Andric  def SETC32 : CSKY32Inst<AddrModeNone, 0x31,
748349cc55cSDimitry Andric    (outs CARRY:$ca), (ins), "setc32", []> {
749349cc55cSDimitry Andric    let Inst{25 - 21} = 0; //rx
750349cc55cSDimitry Andric    let Inst{20 - 16} = 0; //ry
751349cc55cSDimitry Andric    let Inst{15 - 10} = 0x1;
752349cc55cSDimitry Andric    let Inst{9 - 5} = 0x1;
753349cc55cSDimitry Andric    let Inst{4 - 0} = 0;
754349cc55cSDimitry Andric    let isCompare = 1;
755349cc55cSDimitry Andric  }
756349cc55cSDimitry Andric  def CLRC32 : CSKY32Inst<AddrModeNone, 0x31,
757349cc55cSDimitry Andric    (outs CARRY:$ca), (ins), "clrc32", []> {
758349cc55cSDimitry Andric    let Inst{25 - 21} = 0; //rx
759349cc55cSDimitry Andric    let Inst{20 - 16} = 0; //ry
760349cc55cSDimitry Andric    let Inst{15 - 10} = 0x1;
761349cc55cSDimitry Andric    let Inst{9 - 5} = 0x4;
762349cc55cSDimitry Andric    let Inst{4 - 0} = 0;
763349cc55cSDimitry Andric    let isCompare = 1;
764349cc55cSDimitry Andric  }
765349cc55cSDimitry Andric
766349cc55cSDimitry Andric  def TST32 : R_YX<0x8, 0x4, "tst32">;
767349cc55cSDimitry Andric  def TSTNBZ32 : R_X<0x8, 0x8,
768349cc55cSDimitry Andric    (outs CARRY:$ca), (ins GPR:$rx), "tstnbz32", []>;
769349cc55cSDimitry Andric}
770fe6060f1SDimitry Andric
771fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
772fe6060f1SDimitry Andric// Data move instructions.
773fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
774fe6060f1SDimitry Andric
775349cc55cSDimitry Andriclet Predicates= [iHasE2] in {
776349cc55cSDimitry Andric  let isCodeGenOnly = 1 in {
777fe6060f1SDimitry Andric  def MOVT32 : R_ZX<0x3, 0x2, "movt32", []>;
778fe6060f1SDimitry Andric  def MOVF32 : R_ZX<0x3, 0x1, "movf32", []>;
779349cc55cSDimitry Andric  }
780fe6060f1SDimitry Andric  def MOVI32 : I_16_MOV<0x10, "movi32", uimm16>;
781349cc55cSDimitry Andric  let Size = 4, isCodeGenOnly = 0 in
782349cc55cSDimitry Andric  def BGENI : CSKYPseudo<(outs GPR:$dst), (ins uimm5:$imm), "bgeni\t$dst, $imm", []>;
783fe6060f1SDimitry Andric  def MOVIH32 : I_16_MOV<0x11, "movih32", uimm16_16_xform>;
784fe6060f1SDimitry Andric  def MVC32 : R_Z_1<0x1, 0x8, "mvc32">;
785349cc55cSDimitry Andric  let isCodeGenOnly = 1 in
786fe6060f1SDimitry Andric  def MOV32 : R_XZ<0x12, 0x1, "mov32">;
787fe6060f1SDimitry Andric
788349cc55cSDimitry Andric  let usesCustomInserter = 1 in
789349cc55cSDimitry Andric  def ISEL32 : CSKYPseudo<(outs GPR:$dst), (ins CARRY:$cond, GPR:$src1, GPR:$src2),
790349cc55cSDimitry Andric    "!isel32\t$dst, $src1, src2", [(set GPR:$dst, (select CARRY:$cond, GPR:$src1, GPR:$src2))]>;
791349cc55cSDimitry Andric}
792fe6060f1SDimitry Andric
793349cc55cSDimitry Andriclet Predicates = [iHas2E3] in {
794fe6060f1SDimitry Andric  def MVCV32 : R_Z_1<0x1, 0x10, "mvcv32">;
79581ad6265SDimitry Andric  def CLRF32 : R_Z_2<0xB, 0x1, "clrf32">;
79681ad6265SDimitry Andric  def CLRT32 : R_Z_2<0xB, 0x2, "clrt32">;
797349cc55cSDimitry Andric}
798fe6060f1SDimitry Andric
799fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
800fe6060f1SDimitry Andric// Branch and call instructions.
801fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
802fe6060f1SDimitry Andric
803fe6060f1SDimitry Andriclet isBranch = 1, isTerminator = 1 in {
804fe6060f1SDimitry Andric  let isBarrier = 1, isPredicable = 1 in
805fe6060f1SDimitry Andric    def BR32 : I_16_L<0x0, (outs), (ins br_symbol:$imm16), "br32\t$imm16",
806fe6060f1SDimitry Andric                     [(br bb:$imm16)]>;
807fe6060f1SDimitry Andric
808fe6060f1SDimitry Andric  def BT32 : I_16_L<0x3, (outs), (ins CARRY:$ca, br_symbol:$imm16),
809349cc55cSDimitry Andric    "bt32\t$imm16", [(brcond CARRY:$ca, bb:$imm16)]>, Requires<[iHasE2]>;
810fe6060f1SDimitry Andric  def BF32 : I_16_L<0x2, (outs), (ins CARRY:$ca, br_symbol:$imm16),
811349cc55cSDimitry Andric    "bf32\t$imm16", []>, Requires<[iHasE2]>;
812fe6060f1SDimitry Andric}
813fe6060f1SDimitry Andric
814349cc55cSDimitry Andriclet Predicates = [iHas2E3] in {
815fe6060f1SDimitry Andric  def BEZ32 : I_16_X_L<0x8, "bez32", br_symbol>;
816fe6060f1SDimitry Andric  def BNEZ32 : I_16_X_L<0x9, "bnez32", br_symbol>;
817fe6060f1SDimitry Andric  def BHZ32 : I_16_X_L<0xA, "bhz32", br_symbol>;
818fe6060f1SDimitry Andric  def BLSZ32 : I_16_X_L<0xB, "blsz32", br_symbol>;
819fe6060f1SDimitry Andric  def BLZ32 : I_16_X_L<0xC, "blz32", br_symbol>;
820fe6060f1SDimitry Andric  def BHSZ32 : I_16_X_L<0xD, "bhsz32", br_symbol>;
821fe6060f1SDimitry Andric
822fe6060f1SDimitry Andric  let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
823fe6060f1SDimitry Andric    def JMP32 : I_16_JX<0x6, "jmp32", [(brind GPR:$rx)]>; // jmp to register
824fe6060f1SDimitry Andric    def JMPI32 : I_16_L<0x16, (outs), (ins constpool_symbol:$imm16),
825fe6060f1SDimitry Andric                   "jmpi32\t$imm16", []>;
826fe6060f1SDimitry Andric  }
827fe6060f1SDimitry Andric
828fe6060f1SDimitry Andric  let isCall = 1, Defs = [ R15 ] in
829fe6060f1SDimitry Andric    def JSR32 : I_16_JX<0x7, "jsr32", []>;
830fe6060f1SDimitry Andric
831fe6060f1SDimitry Andric  let isCall = 1, Defs = [ R15 ] , mayLoad = 1 in
832fe6060f1SDimitry Andric    def JSRI32: I_16_L<0x17, (outs),
833fe6060f1SDimitry Andric      (ins constpool_symbol:$imm16), "jsri32\t$imm16", []>;
834349cc55cSDimitry Andric}
835fe6060f1SDimitry Andric
836349cc55cSDimitry Andricdef BNEZAD32 : CSKY32Inst<AddrModeNone, 0x3a,
837349cc55cSDimitry Andric  (outs GPR:$rx_u), (ins GPR:$rx, br_symbol:$imm16), "bnezad32\t$rx, $imm16", []> {
838349cc55cSDimitry Andric  bits<5> rx;
839349cc55cSDimitry Andric  bits<16> imm16;
840349cc55cSDimitry Andric  let Inst{25 - 21} = 0x1;
841349cc55cSDimitry Andric  let Inst{20 - 16} = rx;
842349cc55cSDimitry Andric  let Inst{15 - 0} = imm16;
843349cc55cSDimitry Andric  let isBranch = 1;
844349cc55cSDimitry Andric  let isTerminator = 1;
845349cc55cSDimitry Andric  let Constraints = "$rx_u = $rx";
846349cc55cSDimitry Andric  let Predicates = [iHas2E3, iHas10E60];
847349cc55cSDimitry Andric}
848fe6060f1SDimitry Andric
849fe6060f1SDimitry Andricdef BSR32 : J<0x38, (outs), (ins call_symbol:$offset), "bsr32", []>;
850fe6060f1SDimitry Andric
851fe6060f1SDimitry Andricdef BSR32_BR : J<0x38, (outs), (ins call_symbol:$offset), "bsr32", []>{
852fe6060f1SDimitry Andric  let isCodeGenOnly = 1;
853fe6060f1SDimitry Andric  let isBranch = 1;
854fe6060f1SDimitry Andric  let isTerminator = 1;
855fe6060f1SDimitry Andric  let isBarrier = 1;
856fe6060f1SDimitry Andric  let isPredicable = 1;
857fe6060f1SDimitry Andric  let Defs = [ R15 ];
858fe6060f1SDimitry Andric}
859fe6060f1SDimitry Andric
860fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
861fe6060f1SDimitry Andric// Symbol address instructions.
862fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
863fe6060f1SDimitry Andric
864349cc55cSDimitry Andricdef data_symbol_b : data_symbol<"CSKY::fixup_csky_doffset_imm18", 0>;
865349cc55cSDimitry Andricdef data_symbol_h : data_symbol<"CSKY::fixup_csky_doffset_imm18_scale2", 1>;
866349cc55cSDimitry Andricdef data_symbol_w : data_symbol<"CSKY::fixup_csky_doffset_imm18_scale4", 2> {
867349cc55cSDimitry Andric  let ParserMatchClass = DataAsmClass;
868349cc55cSDimitry Andric}
869349cc55cSDimitry Andric
870349cc55cSDimitry Andriclet Predicates = [iHas2E3] in {
871349cc55cSDimitry Andric
872fe6060f1SDimitry Andricdef GRS32 : I_18_Z_L<0x3, "grs32\t$rz, $offset",
873fe6060f1SDimitry Andric                    (outs GPR:$rz), (ins bare_symbol:$offset), []>;
874349cc55cSDimitry Andric
875349cc55cSDimitry Andriclet Uses = [R28] in {
876349cc55cSDimitry Andricdef LRS32B : I_18_Z_L<0x0, "lrs32.b\t$rz, $offset",
877349cc55cSDimitry Andric                    (outs GPR:$rz), (ins data_symbol_b:$offset), []>;
878349cc55cSDimitry Andricdef LRS32H : I_18_Z_L<0x1, "lrs32.h\t$rz, $offset",
879349cc55cSDimitry Andric                    (outs GPR:$rz), (ins data_symbol_h:$offset), []>;
880349cc55cSDimitry Andricdef LRS32W : I_18_Z_L<0x2, "lrs32.w\t$rz, $offset",
881349cc55cSDimitry Andric                    (outs GPR:$rz), (ins data_symbol_w:$offset), []>;
882349cc55cSDimitry Andricdef SRS32B : I_18_Z_L<0x4, "srs32.b\t$rz, $offset",
883349cc55cSDimitry Andric                    (outs), (ins GPR:$rz, data_symbol_b:$offset), []>;
884349cc55cSDimitry Andricdef SRS32H : I_18_Z_L<0x5, "srs32.h\t$rz, $offset",
885349cc55cSDimitry Andric                    (outs), (ins GPR:$rz, data_symbol_h:$offset), []>;
886349cc55cSDimitry Andricdef SRS32W : I_18_Z_L<0x6, "srs32.w\t$rz, $offset",
887349cc55cSDimitry Andric                    (outs), (ins GPR:$rz, data_symbol_w:$offset), []>;
888349cc55cSDimitry Andric}
889349cc55cSDimitry Andric
890349cc55cSDimitry Andricdef PUSH32 : I_12_PP<0b11111, 0b00000, (outs), (ins reglist:$regs, variable_ops), "push32 $regs">;
891349cc55cSDimitry Andric
892349cc55cSDimitry Andriclet Uses = [R14, R15], isReturn = 1, isTerminator = 1, isBarrier = 1 in
893349cc55cSDimitry Andricdef POP32 : I_12_PP<0b11110, 0b00000, (outs), (ins reglist:$regs, variable_ops), "pop32 $regs">;
894349cc55cSDimitry Andric
895349cc55cSDimitry Andric}
896fe6060f1SDimitry Andric
897fe6060f1SDimitry Andriclet mayLoad = 1, mayStore = 0 in {
898fe6060f1SDimitry Andricdef LRW32 : I_16_Z_L<0x14, "lrw32", (ins constpool_symbol:$imm16), []>;
899fe6060f1SDimitry Andriclet isCodeGenOnly = 1 in
900349cc55cSDimitry Andricdef LRW32_Gen : I_16_Z_L<0x14, "lrw32", (ins bare_symbol:$src1, constpool_symbol:$imm16), []>;
901fe6060f1SDimitry Andric}
902fe6060f1SDimitry Andric
903349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
904349cc55cSDimitry Andric// Atomic and fence instructions.
905349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
906349cc55cSDimitry Andric
907349cc55cSDimitry Andriclet Predicates = [iHasMP1E2] in {
908349cc55cSDimitry Andric  def BRWARW : BAR<0b01111, "bar.brwarw", 0>;
909349cc55cSDimitry Andric  def BRWARWS : BAR<0b01111, "bar.brwarws", 1>;
910349cc55cSDimitry Andric  def BRARW : BAR<0b00111, "bar.brarw", 0>;
911349cc55cSDimitry Andric  def BRARWS : BAR<0b00111, "bar.brarws", 1>;
912349cc55cSDimitry Andric  def BRWAW : BAR<0b01110, "bar.brwaw", 0>;
913349cc55cSDimitry Andric  def BRWAWS : BAR<0b01110, "bar.brwaws", 1>;
914349cc55cSDimitry Andric  def BRAR : BAR<0b00101, "bar.brar", 0>;
915349cc55cSDimitry Andric  def BRARS : BAR<0b00101, "bar.brars", 1>;
916349cc55cSDimitry Andric  def BWAW : BAR<0b01010, "bar.bwaw", 0>;
917349cc55cSDimitry Andric  def BWAWS : BAR<0b01010, "bar.bwaws", 1>;
918349cc55cSDimitry Andric
919349cc55cSDimitry Andric  def LDEX32W : I_LD<AddrMode32WD, 0x7, "ldex32.w", uimm12_2>;
920349cc55cSDimitry Andric  let Constraints = "$rd = $rz" in
921349cc55cSDimitry Andric    def STEX32W : I_LDST<AddrMode32WD, 0x37, 7,
922349cc55cSDimitry Andric      (outs GPR:$rd), (ins GPR:$rz, GPR:$rx, uimm12_2:$imm12), "stex32.w", []>;
923349cc55cSDimitry Andric}
924349cc55cSDimitry Andric
925349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
926349cc55cSDimitry Andric// Other operation instructions.
927349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
928349cc55cSDimitry Andric
929349cc55cSDimitry Andriclet Predicates = [iHas2E3] in {
930349cc55cSDimitry Andric  def BREV32 : R_XZ<0x18, 0x10, "brev32">;
931349cc55cSDimitry Andric  def ABS32 : R_XZ<0x0, 0x10, "abs32">;
932349cc55cSDimitry Andric  def BGENR32 : R_XZ<0x14, 0x2, "bgenr32">;
933bdd1243dSDimitry Andric  def REVB32 : R_XZ<0x18, 0x4, "revb32">;
934bdd1243dSDimitry Andric  def REVH32 : R_XZ<0x18, 0x8, "revh32">;
935349cc55cSDimitry Andric}
936349cc55cSDimitry Andric
937349cc55cSDimitry Andriclet Predicates = [iHasE2] in {
938349cc55cSDimitry Andric  def FF0 : R_XZ<0x1F, 0x1, "ff0.32">;
939349cc55cSDimitry Andric  def FF1 : R_XZ<0x1F, 0x2, "ff1.32">;
940349cc55cSDimitry Andric  def XTRB0 : R_XZ<0x1C, 0x1, "xtrb0.32">;
941349cc55cSDimitry Andric  def XTRB1 : R_XZ<0x1C, 0x2, "xtrb1.32">;
942349cc55cSDimitry Andric  def XTRB2 : R_XZ<0x1C, 0x4, "xtrb2.32">;
943349cc55cSDimitry Andric  def XTRB3 : R_XZ<0x1C, 0x8, "xtrb3.32">;
944349cc55cSDimitry Andric  def BTSTI32 : I_5_X<0x0A, 0x4, "btsti32", uimm5, []>;
945349cc55cSDimitry Andric  def BCLRI32 : I_5_XZ<0xA, 0x1, "bclri32",
946349cc55cSDimitry Andric    (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), []>;
947349cc55cSDimitry Andric  def BSETI32 : I_5_XZ<0xA, 0x2, "bseti32",
948349cc55cSDimitry Andric    (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), []>;
949349cc55cSDimitry Andric}
950349cc55cSDimitry Andric
951349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
952349cc55cSDimitry Andric// Special instructions.
953349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
954349cc55cSDimitry Andric
955349cc55cSDimitry Andricdef MFFCR : CSKY32Inst<AddrModeNone, 0x30,
956349cc55cSDimitry Andric  (outs GPR:$rx), (ins), "mfcr\t$rx, fcr", []> {
957349cc55cSDimitry Andric  bits<5> rx;
958349cc55cSDimitry Andric
959349cc55cSDimitry Andric  let Inst{25 - 21} = 0b00010;
960349cc55cSDimitry Andric  let Inst{20 - 16} = 0b00001;
961349cc55cSDimitry Andric  let Inst{15 - 10} = 0b011000;
962349cc55cSDimitry Andric  let Inst{9 - 5} = 0b00001;
963349cc55cSDimitry Andric  let Inst{4 - 0} = rx;
964349cc55cSDimitry Andric  let hasSideEffects = 1;
965349cc55cSDimitry Andric  let isCodeGenOnly = 1;
966349cc55cSDimitry Andric}
967349cc55cSDimitry Andric
968349cc55cSDimitry Andricdef MTFCR : CSKY32Inst<AddrModeNone, 0x30,
969349cc55cSDimitry Andric  (outs), (ins GPR:$rx), "mtcr\t$rx, fcr", []> {
970349cc55cSDimitry Andric  bits<5> rx;
971349cc55cSDimitry Andric
972349cc55cSDimitry Andric  let Inst{25 - 21} = 0b00010;
973349cc55cSDimitry Andric  let Inst{20 - 16} = rx;
974349cc55cSDimitry Andric  let Inst{15 - 10} = 0b011001;
975349cc55cSDimitry Andric  let Inst{9 - 5} = 0b00001;
976349cc55cSDimitry Andric  let Inst{4 - 0} = 0b00001;
977349cc55cSDimitry Andric  let hasSideEffects = 1;
978349cc55cSDimitry Andric  let isCodeGenOnly = 1;
979349cc55cSDimitry Andric}
980349cc55cSDimitry Andric
981349cc55cSDimitry Andricdef SYNC32 : I_5_IMM5<0x30, 0b000001, 0b00001, "sync32", uimm5, []>;
982349cc55cSDimitry Andric
983349cc55cSDimitry Andricdef SYNC0_32 : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins),
984349cc55cSDimitry Andric                 "sync32", []> {
985349cc55cSDimitry Andric  let Inst{25 - 21} = 0;
986349cc55cSDimitry Andric  let Inst{20 - 16} = 0;
987349cc55cSDimitry Andric  let Inst{15 - 10} = 0b000001;
988349cc55cSDimitry Andric  let Inst{9 - 5} = 0b00001;
989349cc55cSDimitry Andric  let Inst{4 - 0} = 0;
990349cc55cSDimitry Andric}
991349cc55cSDimitry Andric
992349cc55cSDimitry Andricdef SYNC_32_I : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins),
993349cc55cSDimitry Andric                 "sync32.i", []> {
994349cc55cSDimitry Andric  let Inst{25 - 21} = 1;
995349cc55cSDimitry Andric  let Inst{20 - 16} = 0;
996349cc55cSDimitry Andric  let Inst{15 - 10} = 0b000001;
997349cc55cSDimitry Andric  let Inst{9 - 5} = 0b00001;
998349cc55cSDimitry Andric  let Inst{4 - 0} = 0;
999349cc55cSDimitry Andric}
1000349cc55cSDimitry Andric
1001349cc55cSDimitry Andricdef SYNC_32_S : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins),
1002349cc55cSDimitry Andric                 "sync32.s", []> {
1003349cc55cSDimitry Andric  let Inst{25 - 21} = 0b10000;
1004349cc55cSDimitry Andric  let Inst{20 - 16} = 0;
1005349cc55cSDimitry Andric  let Inst{15 - 10} = 0b000001;
1006349cc55cSDimitry Andric  let Inst{9 - 5} = 0b00001;
1007349cc55cSDimitry Andric  let Inst{4 - 0} = 0;
1008349cc55cSDimitry Andric}
1009349cc55cSDimitry Andric
1010349cc55cSDimitry Andricdef SYNC_32_IS : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins),
1011349cc55cSDimitry Andric                 "sync32.is", []> {
1012349cc55cSDimitry Andric  let Inst{25 - 21} = 0b10001;
1013349cc55cSDimitry Andric  let Inst{20 - 16} = 0;
1014349cc55cSDimitry Andric  let Inst{15 - 10} = 0b000001;
1015349cc55cSDimitry Andric  let Inst{9 - 5} = 0b00001;
1016349cc55cSDimitry Andric  let Inst{4 - 0} = 0;
1017349cc55cSDimitry Andric}
1018349cc55cSDimitry Andric
1019349cc55cSDimitry Andriclet Predicates = [iHas2E3] in {
1020349cc55cSDimitry Andric  def RFI32 : I_5_XZ_PRIVI<0x11, 0x1, "rfi32">;
1021349cc55cSDimitry Andric  def SCE32 : I_5_IMM5<0x30, 0b000110, 0b00001, "sce32", uimm4, []>;
1022349cc55cSDimitry Andric}
1023349cc55cSDimitry Andriclet Predicates = [HasExtendLrw] in
1024349cc55cSDimitry Andricdef IDLY32 : I_5_IMM5<0x30, 0b000111, 0b00001, "idly32", imm5_idly, []>;
1025349cc55cSDimitry Andricdef STOP32 : I_5_XZ_PRIVI<0x12, 0x1, "stop32">;
1026349cc55cSDimitry Andricdef WAIT32 : I_5_XZ_PRIVI<0x13, 0x1, "wait32">;
1027349cc55cSDimitry Andricdef DOZE32 : I_5_XZ_PRIVI<0x14, 0x1, "doze32">;
1028349cc55cSDimitry Andricdef WE32 : I_5_XZ_PRIVI<0b010101, 0x1, "we32">;
1029349cc55cSDimitry Andricdef SE32 : I_5_XZ_PRIVI<0b010110, 0x1, "se32">;
1030349cc55cSDimitry Andricdef WSC32 : I_5_XZ_PRIVI<0b001111, 0x1, "wsc32">;
1031349cc55cSDimitry Andric
1032349cc55cSDimitry Andricdef CPOP32 : I_CPOP<(outs), (ins uimm5:$cpid, uimm20:$usdef), "cpop32 <$cpid, ${usdef}>">;
1033349cc55cSDimitry Andricdef CPRC32 : I_CP<0b0100, (outs CARRY:$ca), (ins uimm5:$cpid, uimm12:$usdef), "cprc32 <$cpid, ${usdef}>">;
1034349cc55cSDimitry Andricdef CPRCR32 : I_CP_Z<0b0010, (outs GPR:$rz), (ins uimm5:$cpid, uimm12:$usdef), "cprcr32 $rz, <$cpid, ${usdef}>">;
1035349cc55cSDimitry Andricdef CPRGR32 : I_CP_Z<0b0000, (outs GPR:$rz), (ins uimm5:$cpid, uimm12:$usdef), "cprgr32 $rz, <$cpid, ${usdef}>">;
1036349cc55cSDimitry Andricdef CPWCR32 : I_CP_Z<0b0011, (outs), (ins GPR:$rz, uimm5:$cpid, uimm12:$usdef), "cpwcr32 $rz, <$cpid, ${usdef}>">;
1037349cc55cSDimitry Andricdef CPWGR32 : I_CP_Z<0b0001, (outs), (ins GPR:$rz, uimm5:$cpid, uimm12:$usdef), "cpwgr32 $rz, <$cpid, ${usdef}>">;
1038349cc55cSDimitry Andric
1039349cc55cSDimitry Andriclet Predicates = [iHas3r2E3r3] in {
1040349cc55cSDimitry Andricdef DCACHE_IALL32 : I_5_CACHE<0b100101, 0b01000, "dcache32.iall">;
1041349cc55cSDimitry Andricdef DCACHE_CALL32 : I_5_CACHE<0b100101, 0b00100, "dcache32.call">;
1042349cc55cSDimitry Andricdef DCACHE_CIALL32 : I_5_CACHE<0b100101, 0b01100, "dcache32.ciall">;
1043349cc55cSDimitry Andricdef DCACHE_IVA32 : I_5_X_CACHE<0b100101, 0b01011, "dcache32.iva">;
1044349cc55cSDimitry Andricdef DCACHE_ISW32: I_5_X_CACHE<0b100101, 0b01010, "dcache32.isw">;
1045349cc55cSDimitry Andricdef DCACHE_CVA32 : I_5_X_CACHE<0b100101, 0b00111, "dcache32.cva">;
1046349cc55cSDimitry Andricdef DCACHE_CVAL32 : I_5_X_CACHE<0b100101, 0b10111, "dcache32.cval1">;
1047349cc55cSDimitry Andricdef DCACHE_CSW32 : I_5_X_CACHE<0b100101, 0b00110, "dcache32.csw">;
1048349cc55cSDimitry Andricdef DCACHE_CIVA32 : I_5_X_CACHE<0b100101, 0b01111, "dcache32.civa">;
1049349cc55cSDimitry Andricdef DCACHE_CISW32 : I_5_X_CACHE<0b100101, 0b01110, "dcache32.cisw">;
1050349cc55cSDimitry Andric
1051349cc55cSDimitry Andricdef ICACHE_IALL32 : I_5_CACHE<0b100100, 0b01000, "icache32.iall">;
1052349cc55cSDimitry Andricdef ICACHE_IALLS32 : I_5_CACHE<0b100100, 0b11000, "icache32.ialls">;
1053349cc55cSDimitry Andricdef ICACHE_IVA32 : I_5_X_CACHE<0b100100, 0b01011, "icache32.iva">;
1054349cc55cSDimitry Andric
1055349cc55cSDimitry Andricdef TLBI_VAA32 : I_5_X_CACHE<0b100010, 0b00010, "tlbi32.vaa">;
1056349cc55cSDimitry Andricdef TLBI_VAAS32 : I_5_X_CACHE<0b100010, 0b10010, "tlbi32.vaas">;
1057349cc55cSDimitry Andricdef TLBI_ASID32 : I_5_X_CACHE<0b100010, 0b00001, "tlbi32.asid">;
1058349cc55cSDimitry Andricdef TLBI_ASIDS32 : I_5_X_CACHE<0b100010, 0b10001, "tlbi32.asids">;
1059349cc55cSDimitry Andricdef TLBI_VA32 : I_5_X_CACHE<0b100010, 0b00011, "tlbi32.va">;
1060349cc55cSDimitry Andricdef TLBI_VAS32 : I_5_X_CACHE<0b100010, 0b10011, "tlbi32.vas">;
1061349cc55cSDimitry Andricdef TLBI_ALL32 : I_5_CACHE<0b100010, 0b00000, "tlbi32.all">;
1062349cc55cSDimitry Andricdef TLBI_ALLS32 : I_5_CACHE<0b100010, 0b10000, "tlbi32.alls">;
1063349cc55cSDimitry Andric
1064349cc55cSDimitry Andricdef L2CACHE_IALL : I_5_CACHE<0b100110, 0b01000, "l2cache.iall">;
1065349cc55cSDimitry Andricdef L2CACHE_CALL : I_5_CACHE<0b100110, 0b00100, "l2cache.call">;
1066349cc55cSDimitry Andricdef L2CACHE_CIALL : I_5_CACHE<0b100110, 0b01100, "l2cache.ciall">;
1067349cc55cSDimitry Andric}
1068349cc55cSDimitry Andric
1069349cc55cSDimitry Andricdef PLDR32 :I_PLDR<AddrMode32WD, 0x36, 0b0110, (outs), (ins GPR:$rx, uimm12_2:$imm12), "pldr32", []>;
1070349cc55cSDimitry Andricdef PLDW32 :I_PLDR<AddrMode32WD, 0x37, 0b0110, (outs), (ins GPR:$rx, uimm12_2:$imm12), "pldw32", []>;
1071349cc55cSDimitry Andric
1072349cc55cSDimitry Andricdef TRAP32 : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins uimm2:$imm2), "trap32 ${imm2}", []> {
1073349cc55cSDimitry Andric  bits<2> imm2;
1074349cc55cSDimitry Andric
1075349cc55cSDimitry Andric  let Inst{25 - 21} = 0;
1076349cc55cSDimitry Andric  let Inst{20 - 16} = 0;
1077349cc55cSDimitry Andric  let Inst{15 - 12} = 0b0010;
1078349cc55cSDimitry Andric  let Inst{11 - 10} = imm2;
1079349cc55cSDimitry Andric  let Inst{9 - 5} = 0b00001;
1080349cc55cSDimitry Andric  let Inst{4 - 0} = 0;
1081349cc55cSDimitry Andric
1082349cc55cSDimitry Andric}
1083349cc55cSDimitry Andric
10840eae32dcSDimitry Andric//===----------------------------------------------------------------------===//
10850eae32dcSDimitry Andric// Instruction Patterns.
10860eae32dcSDimitry Andric//===----------------------------------------------------------------------===//
10870eae32dcSDimitry Andric
10880eae32dcSDimitry Andric// Load & Store Patterns
10890eae32dcSDimitry Andricmulticlass LdPat<PatFrag LoadOp, ImmLeaf imm_type, Instruction Inst, ValueType Type> {
10900eae32dcSDimitry Andric  def : Pat<(Type (LoadOp GPR:$rs1)), (Inst GPR:$rs1, 0)>;
10910eae32dcSDimitry Andric  def : Pat<(Type (LoadOp (i32 frameindex:$rs1))), (Inst (i32 (to_tframeindex tframeindex:$rs1)), 0)>;
10920eae32dcSDimitry Andric  def : Pat<(Type (LoadOp (add GPR:$rs1, imm_type:$uimm))),
10930eae32dcSDimitry Andric            (Inst GPR:$rs1, imm_type:$uimm)>;
10940eae32dcSDimitry Andric  def : Pat<(Type (LoadOp (add frameindex:$rs1, imm_type:$uimm))),
10950eae32dcSDimitry Andric            (Inst (i32 (to_tframeindex tframeindex:$rs1)), imm_type:$uimm)>;
10960eae32dcSDimitry Andric  def : Pat<(Type (LoadOp (eqToAdd frameindex:$rs1, imm_type:$uimm))),
10970eae32dcSDimitry Andric            (Inst (i32 (to_tframeindex tframeindex:$rs1)), imm_type:$uimm)>;
10980eae32dcSDimitry Andric  def : Pat<(Type (LoadOp (add GPR:$rs1, tglobaladdr:$gd))),
10990eae32dcSDimitry Andric            (Inst GPR:$rs1, tglobaladdr:$gd)>;
11000eae32dcSDimitry Andric}
11010eae32dcSDimitry Andric
11020eae32dcSDimitry Andricdefm : LdPat<extloadi8, uimm12, LD32B, i32>;
11030eae32dcSDimitry Andricdefm : LdPat<zextloadi8, uimm12, LD32B, i32>;
11040eae32dcSDimitry Andriclet Predicates = [iHasE2] in {
11050eae32dcSDimitry Andric  defm : LdPat<sextloadi8, uimm12, LD32BS, i32>;
11060eae32dcSDimitry Andric}
11070eae32dcSDimitry Andricdefm : LdPat<extloadi16, uimm12_1, LD32H, i32>;
11080eae32dcSDimitry Andricdefm : LdPat<zextloadi16, uimm12_1, LD32H, i32>;
11090eae32dcSDimitry Andriclet Predicates = [iHasE2] in {
11100eae32dcSDimitry Andricdefm : LdPat<sextloadi16, uimm12_1, LD32HS, i32>;
11110eae32dcSDimitry Andric}
11120eae32dcSDimitry Andricdefm : LdPat<load, uimm12_2, LD32W, i32>;
11130eae32dcSDimitry Andric
11140eae32dcSDimitry Andricmulticlass LdrPat<PatFrag LoadOp, Instruction Inst, ValueType Type> {
11150eae32dcSDimitry Andric  def : Pat<(Type (LoadOp (add GPR:$rs1, GPR:$rs2))), (Inst GPR:$rs1, GPR:$rs2, 0)>;
11160eae32dcSDimitry Andric  def : Pat<(Type (LoadOp (add GPR:$rs1, (shl GPR:$rs2, (i32 1))))), (Inst GPR:$rs1, GPR:$rs2, 1)>;
11170eae32dcSDimitry Andric  def : Pat<(Type (LoadOp (add GPR:$rs1, (shl GPR:$rs2, (i32 2))))), (Inst GPR:$rs1, GPR:$rs2, 2)>;
11180eae32dcSDimitry Andric  def : Pat<(Type (LoadOp (add GPR:$rs1, (shl GPR:$rs2, (i32 3))))), (Inst GPR:$rs1, GPR:$rs2, 3)>;
11190eae32dcSDimitry Andric}
11200eae32dcSDimitry Andric
11210eae32dcSDimitry Andriclet Predicates = [iHas2E3] in {
11220eae32dcSDimitry Andric  defm : LdrPat<zextloadi8, LDR32B, i32>;
11230eae32dcSDimitry Andric  defm : LdrPat<sextloadi8, LDR32BS, i32>;
11240eae32dcSDimitry Andric  defm : LdrPat<extloadi8, LDR32BS, i32>;
11250eae32dcSDimitry Andric  defm : LdrPat<zextloadi16, LDR32H, i32>;
11260eae32dcSDimitry Andric  defm : LdrPat<sextloadi16, LDR32HS, i32>;
11270eae32dcSDimitry Andric  defm : LdrPat<extloadi16, LDR32HS, i32>;
11280eae32dcSDimitry Andric  defm : LdrPat<load, LDR32W, i32>;
11290eae32dcSDimitry Andric}
11300eae32dcSDimitry Andric
11310eae32dcSDimitry Andricmulticlass StPat<PatFrag StoreOp, ValueType Type, ImmLeaf imm_type, Instruction Inst> {
11320eae32dcSDimitry Andric  def : Pat<(StoreOp Type:$rs2, GPR:$rs1), (Inst Type:$rs2, GPR:$rs1, 0)>;
11330eae32dcSDimitry Andric  def : Pat<(StoreOp Type:$rs2, frameindex:$rs1), (Inst Type:$rs2, (i32 (to_tframeindex tframeindex:$rs1)), 0)>;
11340eae32dcSDimitry Andric  def : Pat<(StoreOp Type:$rs2, (add GPR:$rs1, imm_type:$uimm12)),
11350eae32dcSDimitry Andric            (Inst Type:$rs2, GPR:$rs1, imm_type:$uimm12)>;
11360eae32dcSDimitry Andric  def : Pat<(StoreOp Type:$rs2, (add frameindex:$rs1, imm_type:$uimm12)),
11370eae32dcSDimitry Andric            (Inst Type:$rs2, (i32 (to_tframeindex tframeindex:$rs1)), imm_type:$uimm12)>;
11380eae32dcSDimitry Andric  def : Pat<(StoreOp Type:$rs2, (eqToAdd frameindex:$rs1, imm_type:$uimm12)),
11390eae32dcSDimitry Andric            (Inst Type:$rs2, (i32 (to_tframeindex tframeindex:$rs1)), imm_type:$uimm12)>;
11400eae32dcSDimitry Andric}
11410eae32dcSDimitry Andric
11420eae32dcSDimitry Andricdefm : StPat<truncstorei8, i32, uimm12, ST32B>;
11430eae32dcSDimitry Andricdefm : StPat<truncstorei16, i32, uimm12_1, ST32H>;
11440eae32dcSDimitry Andricdefm : StPat<store, i32, uimm12_2, ST32W>;
11450eae32dcSDimitry Andric
11460eae32dcSDimitry Andricmulticlass StrPat<PatFrag StoreOp, ValueType Type, Instruction Inst> {
11470eae32dcSDimitry Andric  def : Pat<(StoreOp Type:$rz, (add GPR:$rs1, GPR:$rs2)), (Inst Type:$rz, GPR:$rs1, GPR:$rs2, 0)>;
11480eae32dcSDimitry Andric  def : Pat<(StoreOp Type:$rz, (add GPR:$rs1, (shl GPR:$rs2, (i32 1)))), (Inst Type:$rz, GPR:$rs1, GPR:$rs2, 1)>;
11490eae32dcSDimitry Andric  def : Pat<(StoreOp Type:$rz, (add GPR:$rs1, (shl GPR:$rs2, (i32 2)))), (Inst Type:$rz, GPR:$rs1, GPR:$rs2, 2)>;
11500eae32dcSDimitry Andric  def : Pat<(StoreOp Type:$rz, (add GPR:$rs1, (shl GPR:$rs2, (i32 3)))), (Inst Type:$rz, GPR:$rs1, GPR:$rs2, 3)>;
11510eae32dcSDimitry Andric}
11520eae32dcSDimitry Andric
11530eae32dcSDimitry Andriclet Predicates = [iHas2E3] in {
11540eae32dcSDimitry Andric  defm : StrPat<truncstorei8, i32, STR32B>;
11550eae32dcSDimitry Andric  defm : StrPat<truncstorei16, i32, STR32H>;
11560eae32dcSDimitry Andric  defm : StrPat<store, i32, STR32W>;
11570eae32dcSDimitry Andric
11580eae32dcSDimitry Andric  // Sext & Zext Patterns
11590eae32dcSDimitry Andric  def : Pat<(sext_inreg GPR:$src, i1), (SEXT32 GPR:$src, 0, 0)>;
11600eae32dcSDimitry Andric  def : Pat<(and GPR:$src, 255), (ZEXT32 GPR:$src, 7, 0)>;
11610eae32dcSDimitry Andric  def : Pat<(and GPR:$src, 65535), (ZEXT32 GPR:$src, 15, 0)>;
116204eeddc0SDimitry Andric
116304eeddc0SDimitry Andric   // Call Patterns
116404eeddc0SDimitry Andric  def : Pat<(CSKY_CALL tglobaladdr, tconstpool:$src2), (JSRI32 tconstpool:$src2)>;
116504eeddc0SDimitry Andric  def : Pat<(CSKY_CALL texternalsym, tconstpool:$src2), (JSRI32 tconstpool:$src2)>;
116604eeddc0SDimitry Andric  def : Pat<(CSKY_TAIL tglobaladdr, tconstpool:$src2), (JMPI32 tconstpool:$src2)>;
116704eeddc0SDimitry Andric  def : Pat<(CSKY_TAIL texternalsym, tconstpool:$src2), (JMPI32 tconstpool:$src2)>;
116804eeddc0SDimitry Andric
116904eeddc0SDimitry Andric  def : Pat<(CSKY_CALLReg GPR:$src), (JSR32 GPR:$src)>;
117004eeddc0SDimitry Andric  def : Pat<(CSKY_TAILReg GPR:$src), (JMP32 GPR:$src)>;
117104eeddc0SDimitry Andric}
117204eeddc0SDimitry Andric
117304eeddc0SDimitry Andric// Symbol address Patterns
117404eeddc0SDimitry Andricdef : Pat<(CSKY_LOAD_ADDR tglobaladdr, tconstpool:$src2), (LRW32 tconstpool:$src2)>;
117504eeddc0SDimitry Andricdef : Pat<(CSKY_LOAD_ADDR tblockaddress, tconstpool:$src2), (LRW32 tconstpool:$src2)>;
117604eeddc0SDimitry Andricdef : Pat<(CSKY_LOAD_ADDR tjumptable:$src1, tconstpool:$src2), (LRW32_Gen tjumptable:$src1, tconstpool:$src2)>;
117704eeddc0SDimitry Andricdef : Pat<(CSKY_LOAD_ADDR texternalsym, tconstpool:$src2), (LRW32 tconstpool:$src2)>;
1178bdd1243dSDimitry Andricdef : Pat<(CSKY_LOAD_ADDR tconstpool:$src1, tconstpool:$src2), (LRW32_Gen tconstpool:$src1, tconstpool:$src2)>;
117904eeddc0SDimitry Andric
118004eeddc0SDimitry Andriclet Predicates = [iHas2E3] in
118104eeddc0SDimitry Andric  def : Pat<(i32 constpool:$src), (GRS32 (to_tconstpool tconstpool:$src))>;
118204eeddc0SDimitry Andric
118304eeddc0SDimitry Andriclet Predicates = [iHasE2] in
118404eeddc0SDimitry Andric  def : Pat<(i32 constpool:$src),
118504eeddc0SDimitry Andric    (ORI32 (MOVIH32 (to_tconstpool_hi16 tconstpool:$src)),
118604eeddc0SDimitry Andric           (to_tconstpool_lo16 tconstpool:$src))>;
118704eeddc0SDimitry Andric
118804eeddc0SDimitry Andricdef : Pat<(i32 (load constpool:$src)), (LRW32 (to_tconstpool tconstpool:$src))>;
118904eeddc0SDimitry Andric
119004eeddc0SDimitry Andric// Branch Patterns.
119104eeddc0SDimitry Andriclet Predicates = [iHasE2] in {
119204eeddc0SDimitry Andricdef : Pat<(brcond CARRY:$ca, bb:$imm16),
119304eeddc0SDimitry Andric          (BT32 CARRY:$ca, bb:$imm16)>;
119404eeddc0SDimitry Andric
119506c3fb27SDimitry Andricmulticlass BTF32Pat0<PatFrag cond0, PatFrag cond1, ImmLeaf imm_ty, Instruction inst> {
119606c3fb27SDimitry Andric  def : Pat<(brcond (i32 (cond0 GPR:$rs1, uimm16:$rs2)), bb:$imm16),
119706c3fb27SDimitry Andric          (BT32 (inst GPR:$rs1, imm_ty:$rs2), bb:$imm16)>;
119806c3fb27SDimitry Andric  def : Pat<(brcond (i32 (cond1 GPR:$rs1, uimm16:$rs2)), bb:$imm16),
119906c3fb27SDimitry Andric          (BF32 (inst GPR:$rs1, imm_ty:$rs2), bb:$imm16)>;
120006c3fb27SDimitry Andric}
120104eeddc0SDimitry Andric
120206c3fb27SDimitry Andricdefm : BTF32Pat0<setne, seteq, uimm16, CMPNEI32>;
120306c3fb27SDimitry Andricdefm : BTF32Pat0<setuge, setult, oimm16, CMPHSI32>;
120406c3fb27SDimitry Andricdefm : BTF32Pat0<setlt, setge, oimm16, CMPLTI32>;
1205*5f757f3fSDimitry Andric
1206*5f757f3fSDimitry Andricdef : Pat<(brcond (i32 (setne (and GPR:$rs, imm32_1_pop_bit:$im), 0)), bb:$imm16),
1207*5f757f3fSDimitry Andric          (BT32 (BTSTI32 GPR:$rs, (imm32_1_pop_bit_XFORM imm32_1_pop_bit:$im)),
1208*5f757f3fSDimitry Andric                bb:$imm16)>;
1209*5f757f3fSDimitry Andricdef : Pat<(brcond (i32 (seteq (and GPR:$rs, imm32_1_pop_bit:$im), 0)), bb:$imm16),
1210*5f757f3fSDimitry Andric          (BF32 (BTSTI32 GPR:$rs, (imm32_1_pop_bit_XFORM imm32_1_pop_bit:$im)),
1211*5f757f3fSDimitry Andric                bb:$imm16)>;
121204eeddc0SDimitry Andric}
121304eeddc0SDimitry Andric
121404eeddc0SDimitry Andriclet Predicates = [iHas2E3] in {
121504eeddc0SDimitry Andric
121604eeddc0SDimitry Andricdef : Pat<(brcond (i32 (setne GPR:$rs1, GPR:$rs2)), bb:$imm16),
121704eeddc0SDimitry Andric          (BT32 (CMPNE32 GPR:$rs1, GPR:$rs2), bb:$imm16)>;
121804eeddc0SDimitry Andricdef : Pat<(brcond (i32 (seteq GPR:$rs1, GPR:$rs2)), bb:$imm16),
121904eeddc0SDimitry Andric          (BF32 (CMPNE32 GPR:$rs1, GPR:$rs2), bb:$imm16)>;
122006c3fb27SDimitry Andric
122106c3fb27SDimitry Andricmulticlass BTF32Pat1<PatFrag cond0, PatFrag cond1, Instruction cmp,
122206c3fb27SDimitry Andric                     Instruction br> {
122306c3fb27SDimitry Andric  def : Pat<(brcond (i32 (cond0 GPR:$rs1, GPR:$rs2)), bb:$imm16),
122406c3fb27SDimitry Andric            (br (cmp GPR:$rs1, GPR:$rs2), bb:$imm16)>;
122506c3fb27SDimitry Andric  def : Pat<(brcond (i32 (cond1 GPR:$rs1, GPR:$rs2)), bb:$imm16),
122606c3fb27SDimitry Andric            (br (cmp GPR:$rs2, GPR:$rs1), bb:$imm16)>;
122706c3fb27SDimitry Andric}
122806c3fb27SDimitry Andric
122906c3fb27SDimitry Andricdefm : BTF32Pat1<setuge, setule, CMPHS32, BT32>;
123006c3fb27SDimitry Andricdefm : BTF32Pat1<setult, setugt, CMPHS32, BF32>;
123106c3fb27SDimitry Andricdefm : BTF32Pat1<setlt, setgt, CMPLT32, BT32>;
123206c3fb27SDimitry Andricdefm : BTF32Pat1<setge, setle, CMPLT32, BF32>;
123304eeddc0SDimitry Andric
123404eeddc0SDimitry Andricdef : Pat<(brcond (i32 (seteq GPR:$rs1, (i32 0))), bb:$imm16),
123504eeddc0SDimitry Andric          (BEZ32 GPR:$rs1, bb:$imm16)>;
123604eeddc0SDimitry Andricdef : Pat<(brcond (i32 (setne GPR:$rs1, (i32 0))), bb:$imm16),
123704eeddc0SDimitry Andric          (BNEZ32 GPR:$rs1, bb:$imm16)>;
123804eeddc0SDimitry Andricdef : Pat<(brcond (i32 (setlt GPR:$rs1, (i32 0))), bb:$imm16),
123904eeddc0SDimitry Andric          (BLZ32 GPR:$rs1, bb:$imm16)>;
124006c3fb27SDimitry Andricdef : Pat<(brcond (i32 (setlt GPR:$rs1, (i32 1))), bb:$imm16),
124106c3fb27SDimitry Andric          (BLSZ32 GPR:$rs1, bb:$imm16)>;
124204eeddc0SDimitry Andricdef : Pat<(brcond (i32 (setge GPR:$rs1, (i32 0))), bb:$imm16),
124304eeddc0SDimitry Andric          (BHSZ32 GPR:$rs1, bb:$imm16)>;
124406c3fb27SDimitry Andricdef : Pat<(brcond (i32 (setge GPR:$rs1, (i32 1))), bb:$imm16),
124506c3fb27SDimitry Andric          (BHZ32 GPR:$rs1, bb:$imm16)>;
124604eeddc0SDimitry Andricdef : Pat<(brcond (i32 (setgt GPR:$rs1, (i32 0))), bb:$imm16),
124704eeddc0SDimitry Andric          (BHZ32 GPR:$rs1, bb:$imm16)>;
124806c3fb27SDimitry Andricdef : Pat<(brcond (i32 (setgt GPR:$rs1, (i32 -1))), bb:$imm16),
124906c3fb27SDimitry Andric          (BHSZ32 GPR:$rs1, bb:$imm16)>;
125004eeddc0SDimitry Andricdef : Pat<(brcond (i32 (setle GPR:$rs1, (i32 0))), bb:$imm16),
125104eeddc0SDimitry Andric          (BLSZ32 GPR:$rs1, bb:$imm16)>;
125206c3fb27SDimitry Andricdef : Pat<(brcond (i32 (setle GPR:$rs1, (i32 -1))), bb:$imm16),
125306c3fb27SDimitry Andric          (BLZ32 GPR:$rs1, bb:$imm16)>;
125404eeddc0SDimitry Andric}
125504eeddc0SDimitry Andric
125604eeddc0SDimitry Andric// Compare Patterns.
125704eeddc0SDimitry Andriclet Predicates = [iHas2E3] in {
125804eeddc0SDimitry Andric  def : Pat<(setne GPR:$rs1, GPR:$rs2),
125904eeddc0SDimitry Andric            (CMPNE32 GPR:$rs1, GPR:$rs2)>;
1260*5f757f3fSDimitry Andric  def : Pat<(setne (and GPR:$rs, imm32_1_pop_bit:$im), 0),
1261*5f757f3fSDimitry Andric            (BTSTI32 GPR:$rs, (imm32_1_pop_bit_XFORM imm32_1_pop_bit:$im))>;
126204eeddc0SDimitry Andric  def : Pat<(i32 (seteq GPR:$rs1, GPR:$rs2)),
126304eeddc0SDimitry Andric            (MVCV32 (CMPNE32 GPR:$rs1, GPR:$rs2))>;
126404eeddc0SDimitry Andric  def : Pat<(setuge GPR:$rs1, GPR:$rs2),
126504eeddc0SDimitry Andric            (CMPHS32 GPR:$rs1, GPR:$rs2)>;
126604eeddc0SDimitry Andric  def : Pat<(setule GPR:$rs1, GPR:$rs2),
126704eeddc0SDimitry Andric            (CMPHS32 GPR:$rs2, GPR:$rs1)>;
126804eeddc0SDimitry Andric  def : Pat<(i32 (setult GPR:$rs1, GPR:$rs2)),
126904eeddc0SDimitry Andric            (MVCV32 (CMPHS32 GPR:$rs1, GPR:$rs2))>;
127004eeddc0SDimitry Andric  def : Pat<(i32 (setugt GPR:$rs1, GPR:$rs2)),
127104eeddc0SDimitry Andric            (MVCV32 (CMPHS32 GPR:$rs2, GPR:$rs1))>;
127204eeddc0SDimitry Andric  def : Pat<(setlt GPR:$rs1, GPR:$rs2),
127304eeddc0SDimitry Andric            (CMPLT32 GPR:$rs1, GPR:$rs2)>;
127404eeddc0SDimitry Andric  def : Pat<(setgt GPR:$rs1, GPR:$rs2),
127504eeddc0SDimitry Andric            (CMPLT32 GPR:$rs2, GPR:$rs1)>;
127604eeddc0SDimitry Andric  def : Pat<(i32 (setge GPR:$rs1, GPR:$rs2)),
127704eeddc0SDimitry Andric            (MVCV32 (CMPLT32 GPR:$rs1, GPR:$rs2))>;
127804eeddc0SDimitry Andric  def : Pat<(i32 (setle GPR:$rs1, GPR:$rs2)),
127904eeddc0SDimitry Andric            (MVCV32 (CMPLT32 GPR:$rs2, GPR:$rs1))>;
128004eeddc0SDimitry Andric}
128104eeddc0SDimitry Andric
128204eeddc0SDimitry Andriclet Predicates = [iHasE2] in {
128304eeddc0SDimitry Andric  def : Pat<(setne GPR:$rs1, uimm16:$rs2),
128404eeddc0SDimitry Andric            (CMPNEI32 GPR:$rs1, uimm16:$rs2)>;
128504eeddc0SDimitry Andric  let Predicates = [iHas2E3] in
128604eeddc0SDimitry Andric  def : Pat<(i32 (seteq GPR:$rs1, uimm16:$rs2)),
128704eeddc0SDimitry Andric            (MVCV32 (CMPNEI32 GPR:$rs1, uimm16:$rs2))>;
128804eeddc0SDimitry Andric  def : Pat<(setuge GPR:$rs1, oimm16:$rs2),
128904eeddc0SDimitry Andric            (CMPHSI32 GPR:$rs1, oimm16:$rs2)>;
129004eeddc0SDimitry Andric  let Predicates = [iHas2E3] in
129104eeddc0SDimitry Andric  def : Pat<(i32 (setult GPR:$rs1, oimm16:$rs2)),
129204eeddc0SDimitry Andric            (MVCV32 (CMPHSI32 GPR:$rs1, oimm16:$rs2))>;
129304eeddc0SDimitry Andric  def : Pat<(setlt GPR:$rs1, oimm16:$rs2),
129404eeddc0SDimitry Andric            (CMPLTI32 GPR:$rs1, oimm16:$rs2)>;
129504eeddc0SDimitry Andric  let Predicates = [iHas2E3] in
129604eeddc0SDimitry Andric  def : Pat<(i32 (setge GPR:$rs1, oimm16:$rs2)),
129704eeddc0SDimitry Andric            (MVCV32 (CMPLTI32 GPR:$rs1, oimm16:$rs2))>;
129804eeddc0SDimitry Andric}
129904eeddc0SDimitry Andric
130004eeddc0SDimitry Andric// Select Patterns.
130104eeddc0SDimitry Andriclet Predicates = [iHasE2] in {
1302bdd1243dSDimitry Andric
130306c3fb27SDimitry Andricdef : Pat<(select (i32 (setne GPR:$rs1, uimm16:$rs2)), (add GPR:$rx, uimm5:$imm), GPR:$false),
130406c3fb27SDimitry Andric          (INCT32 (CMPNEI32 GPR:$rs1, uimm16:$rs2), GPR:$false, GPR:$rx, uimm5:$imm)>;
130506c3fb27SDimitry Andricdef : Pat<(select (i32 (seteq GPR:$rs1, uimm16:$rs2)), (add GPR:$rx, uimm5:$imm), GPR:$false),
130606c3fb27SDimitry Andric          (INCF32 (CMPNEI32 GPR:$rs1, uimm16:$rs2), GPR:$false, GPR:$rx, uimm5:$imm)>;
130706c3fb27SDimitry Andricdef : Pat<(select (i32 (setne GPR:$rs1, uimm16:$rs2)), (add GPR:$rx, uimm5_neg:$imm), GPR:$false),
130806c3fb27SDimitry Andric          (DECT32 (CMPNEI32 GPR:$rs1, uimm16:$rs2), GPR:$false, GPR:$rx,
130906c3fb27SDimitry Andric                  (imm_neg_XFORM uimm5_neg:$imm))>;
131006c3fb27SDimitry Andricdef : Pat<(select (i32 (seteq GPR:$rs1, uimm16:$rs2)), (add GPR:$rx, uimm5_neg:$imm), GPR:$false),
131106c3fb27SDimitry Andric          (DECF32 (CMPNEI32 GPR:$rs1, uimm16:$rs2), GPR:$false, GPR:$rx,
131206c3fb27SDimitry Andric                  (imm_neg_XFORM uimm5:$imm))>;
131306c3fb27SDimitry Andric
131406c3fb27SDimitry Andricmulticlass INCDECPat<PatFrag cond0, PatFrag cond1, Instruction cmp> {
131506c3fb27SDimitry Andric  def : Pat<(select (i32 (cond0 GPR:$rs1, oimm16:$rs2)), (add GPR:$rx, uimm5:$imm), GPR:$other),
131606c3fb27SDimitry Andric            (INCT32 (cmp GPR:$rs1, oimm16:$rs2), GPR:$other, GPR:$rx, uimm5:$imm)>;
131706c3fb27SDimitry Andric  def : Pat<(select (i32 (cond1 GPR:$rs1, oimm16:$rs2)), (add GPR:$rx, uimm5:$imm), GPR:$other),
131806c3fb27SDimitry Andric            (INCF32 (cmp GPR:$rs1, oimm16:$rs2), GPR:$other, GPR:$rx, uimm5:$imm)>;
131906c3fb27SDimitry Andric  def : Pat<(select (i32 (cond0 GPR:$rs1, oimm16:$rs2)), GPR:$other, (add GPR:$rx, uimm5:$imm)),
132006c3fb27SDimitry Andric            (INCF32 (cmp GPR:$rs1, oimm16:$rs2), GPR:$other, GPR:$rx, uimm5:$imm)>;
132106c3fb27SDimitry Andric  def : Pat<(select (i32 (cond1 GPR:$rs1, oimm16:$rs2)), GPR:$other, (add GPR:$rx, uimm5:$imm)),
132206c3fb27SDimitry Andric            (INCT32 (cmp GPR:$rs1, oimm16:$rs2), GPR:$other, GPR:$rx, uimm5:$imm)>;
132306c3fb27SDimitry Andric  def : Pat<(select (i32 (cond0 GPR:$rs1, oimm16:$rs2)), (add GPR:$rx, uimm5_neg:$imm), GPR:$other),
132406c3fb27SDimitry Andric            (DECT32 (cmp GPR:$rs1, oimm16:$rs2), GPR:$other, GPR:$rx,
132506c3fb27SDimitry Andric                    (imm_neg_XFORM uimm5_neg:$imm))>;
132606c3fb27SDimitry Andric  def : Pat<(select (i32 (cond1 GPR:$rs1, oimm16:$rs2)), (add GPR:$rx, uimm5_neg:$imm), GPR:$other),
132706c3fb27SDimitry Andric            (DECF32 (cmp GPR:$rs1, oimm16:$rs2), GPR:$other, GPR:$rx,
132806c3fb27SDimitry Andric                    (imm_neg_XFORM uimm5_neg:$imm))>;
132906c3fb27SDimitry Andric  def : Pat<(select (i32 (cond0 GPR:$rs1, oimm16:$rs2)), GPR:$other, (add GPR:$rx, uimm5_neg:$imm)),
133006c3fb27SDimitry Andric            (DECF32 (cmp GPR:$rs1, oimm16:$rs2), GPR:$other, GPR:$rx,
133106c3fb27SDimitry Andric                    (imm_neg_XFORM uimm5_neg:$imm))>;
133206c3fb27SDimitry Andric  def : Pat<(select (i32 (cond1 GPR:$rs1, oimm16:$rs2)), GPR:$other, (add GPR:$rx, uimm5_neg:$imm)),
133306c3fb27SDimitry Andric            (DECT32 (cmp GPR:$rs1, oimm16:$rs2), GPR:$other, GPR:$rx,
133406c3fb27SDimitry Andric                    (imm_neg_XFORM uimm5_neg:$imm))>;
133506c3fb27SDimitry Andric}
133606c3fb27SDimitry Andric
133706c3fb27SDimitry Andricdefm : INCDECPat<setuge, setult, CMPHSI32>;
133806c3fb27SDimitry Andricdefm : INCDECPat<setlt, setge, CMPLTI32>;
133906c3fb27SDimitry Andric
134006c3fb27SDimitry Andricdef : Pat<(select CARRY:$ca, (add GPR:$rx, uimm5:$imm), GPR:$other),
134106c3fb27SDimitry Andric          (INCT32 CARRY:$ca, GPR:$other, GPR:$rx, uimm5:$imm)>;
134206c3fb27SDimitry Andricdef : Pat<(select CARRY:$ca, GPR:$other, (add GPR:$rx, uimm5:$imm)),
134306c3fb27SDimitry Andric          (INCF32 CARRY:$ca, GPR:$other, GPR:$rx, uimm5:$imm)>;
134406c3fb27SDimitry Andricdef : Pat<(select (and CARRY:$ca, 1), (add GPR:$rx, uimm5:$imm), GPR:$other),
134506c3fb27SDimitry Andric          (INCT32 CARRY:$ca, GPR:$other, GPR:$rx, uimm5:$imm)>;
134606c3fb27SDimitry Andricdef : Pat<(select (and CARRY:$ca, 1), GPR:$other, (add GPR:$rx, uimm5:$imm)),
134706c3fb27SDimitry Andric          (INCF32 CARRY:$ca, GPR:$other, GPR:$rx, uimm5:$imm)>;
134806c3fb27SDimitry Andric
134906c3fb27SDimitry Andricdef : Pat<(select CARRY:$ca, (add GPR:$rx, uimm5_neg:$imm), GPR:$other),
135006c3fb27SDimitry Andric          (DECT32 CARRY:$ca, GPR:$other, GPR:$rx, (imm_neg_XFORM uimm5_neg:$imm))>;
135106c3fb27SDimitry Andricdef : Pat<(select CARRY:$ca, GPR:$other, (add GPR:$rx, uimm5_neg:$imm)),
135206c3fb27SDimitry Andric          (DECF32 CARRY:$ca, GPR:$other, GPR:$rx, (imm_neg_XFORM uimm5_neg:$imm))>;
135306c3fb27SDimitry Andricdef : Pat<(select (and CARRY:$ca, 1), (add GPR:$rx, uimm5_neg:$imm), GPR:$other),
135406c3fb27SDimitry Andric          (DECT32 CARRY:$ca, GPR:$other, GPR:$rx, (imm_neg_XFORM uimm5_neg:$imm))>;
135506c3fb27SDimitry Andricdef : Pat<(select (and CARRY:$ca, 1), GPR:$other, (add GPR:$rx, uimm5_neg:$imm)),
135606c3fb27SDimitry Andric          (DECF32 CARRY:$ca, GPR:$other, GPR:$rx, (imm_neg_XFORM uimm5_neg:$imm))>;
135706c3fb27SDimitry Andric
135804eeddc0SDimitry Andricdef : Pat<(select CARRY:$ca, GPR:$rx, GPR:$false),
135904eeddc0SDimitry Andric          (MOVT32 CARRY:$ca, GPR:$rx, GPR:$false)>;
136004eeddc0SDimitry Andricdef : Pat<(select (and CARRY:$ca, 1), GPR:$rx, GPR:$false),
136104eeddc0SDimitry Andric          (MOVT32 CARRY:$ca, GPR:$rx, GPR:$false)>;
136204eeddc0SDimitry Andric
136306c3fb27SDimitry Andricmulticlass MOVTF32Pat0<PatFrag cond0, PatFrag cond1, ImmLeaf imm_ty, Instruction inst> {
136406c3fb27SDimitry Andric  def : Pat<(select (i32 (cond0 GPR:$rs1, imm_ty:$rs2)), GPR:$rx, GPR:$false),
136506c3fb27SDimitry Andric            (MOVT32 (inst GPR:$rs1, imm_ty:$rs2), GPR:$rx, GPR:$false)>;
136606c3fb27SDimitry Andric  def : Pat<(select (i32 (cond1 GPR:$rs1, imm_ty:$rs2)), GPR:$rx, GPR:$false),
136706c3fb27SDimitry Andric            (MOVF32 (inst GPR:$rs1, imm_ty:$rs2), GPR:$rx, GPR:$false)>;
136806c3fb27SDimitry Andric}
136904eeddc0SDimitry Andric
137006c3fb27SDimitry Andricdefm : MOVTF32Pat0<setne, seteq, uimm16, CMPNEI32>;
137106c3fb27SDimitry Andricdefm : MOVTF32Pat0<setuge, setult, oimm16, CMPHSI32>;
137206c3fb27SDimitry Andricdefm : MOVTF32Pat0<setlt, setge, oimm16, CMPLTI32>;
1373bdd1243dSDimitry Andric
1374bdd1243dSDimitry Andricdef : Pat<(select CARRY:$ca, GPR:$rx, GPR:$false),
1375bdd1243dSDimitry Andric          (ISEL32 CARRY:$ca, GPR:$rx, GPR:$false)>;
1376bdd1243dSDimitry Andricdef : Pat<(select (and CARRY:$ca, 1), GPR:$rx, GPR:$false),
1377bdd1243dSDimitry Andric          (ISEL32 CARRY:$ca, GPR:$rx, GPR:$false)>;
1378bdd1243dSDimitry Andric
1379*5f757f3fSDimitry Andricdef : Pat<(select (i32 (setne (and GPR:$rs, imm32_1_pop_bit:$im), 0)),
1380*5f757f3fSDimitry Andric                  GPR:$true, GPR:$false),
1381*5f757f3fSDimitry Andric          (MOVT32 (BTSTI32 GPR:$rs, (imm32_1_pop_bit_XFORM imm32_1_pop_bit:$im)),
1382*5f757f3fSDimitry Andric                  GPR:$true, GPR:$false)>;
1383*5f757f3fSDimitry Andricdef : Pat<(select (i32 (seteq (and GPR:$rs, imm32_1_pop_bit:$im), 0)),
1384*5f757f3fSDimitry Andric                  GPR:$true, GPR:$false),
1385*5f757f3fSDimitry Andric          (MOVF32 (BTSTI32 GPR:$rs, (imm32_1_pop_bit_XFORM imm32_1_pop_bit:$im)),
1386*5f757f3fSDimitry Andric                  GPR:$true, GPR:$false)>;
1387*5f757f3fSDimitry Andric}
1388bdd1243dSDimitry Andric
1389bdd1243dSDimitry Andriclet Predicates = [iHas2E3] in {
139006c3fb27SDimitry Andricdef : Pat<(select (i32 (setne GPR:$rs1, GPR:$rs2)), (add GPR:$rx, uimm5:$imm), GPR:$false),
139106c3fb27SDimitry Andric          (INCT32 (CMPNE32 GPR:$rs1, GPR:$rs2), GPR:$false, GPR:$rx, uimm5:$imm)>;
139206c3fb27SDimitry Andricdef : Pat<(select (i32 (seteq GPR:$rs1, GPR:$rs2)), (add GPR:$rx, uimm5:$imm), GPR:$false),
139306c3fb27SDimitry Andric          (INCF32 (CMPNE32 GPR:$rs1, GPR:$rs2), GPR:$false, GPR:$rx, uimm5:$imm)>;
139406c3fb27SDimitry Andricdef : Pat<(select (i32 (setne GPR:$rs1, GPR:$rs2)), (add GPR:$rx, uimm5_neg:$imm), GPR:$false),
139506c3fb27SDimitry Andric          (DECT32 (CMPNE32 GPR:$rs1, GPR:$rs2), GPR:$false, GPR:$rx,
139606c3fb27SDimitry Andric                  (imm_neg_XFORM uimm5_neg:$imm))>;
139706c3fb27SDimitry Andricdef : Pat<(select (i32 (seteq GPR:$rs1, GPR:$rs2)), (add GPR:$rx, uimm5_neg:$imm), GPR:$false),
139806c3fb27SDimitry Andric          (DECF32 (CMPNE32 GPR:$rs1, GPR:$rs2), GPR:$false, GPR:$rx,
139906c3fb27SDimitry Andric                  (imm_neg_XFORM uimm5_neg:$imm))>;
140006c3fb27SDimitry Andric
140106c3fb27SDimitry Andricmulticlass INCPat<PatFrag cond0, PatFrag cond1, Instruction cmp, Instruction inc0, Instruction inc1> {
140206c3fb27SDimitry Andric  def : Pat<(select (i32 (cond0 GPR:$rs1, GPR:$rs2)), (add GPR:$rx, uimm5:$imm), GPR:$other),
140306c3fb27SDimitry Andric            (inc0 (cmp GPR:$rs1, GPR:$rs2), GPR:$other, GPR:$rx, uimm5:$imm)>;
140406c3fb27SDimitry Andric  def : Pat<(select (i32 (cond0 GPR:$rs1, GPR:$rs2)), GPR:$other, (add GPR:$rx, uimm5:$imm)),
140506c3fb27SDimitry Andric            (inc1 (cmp GPR:$rs1, GPR:$rs2), GPR:$other, GPR:$rx, uimm5:$imm)>;
140606c3fb27SDimitry Andric  def : Pat<(select (i32 (cond1 GPR:$rs1, GPR:$rs2)), (add GPR:$rx, uimm5:$imm), GPR:$other),
140706c3fb27SDimitry Andric            (inc0 (cmp GPR:$rs2, GPR:$rs1), GPR:$other, GPR:$rx, uimm5:$imm)>;
140806c3fb27SDimitry Andric  def : Pat<(select (i32 (cond1 GPR:$rs1, GPR:$rs2)), GPR:$other, (add GPR:$rx, uimm5:$imm)),
140906c3fb27SDimitry Andric            (inc1 (cmp GPR:$rs2, GPR:$rs1), GPR:$other, GPR:$rx, uimm5:$imm)>;
141006c3fb27SDimitry Andric}
141106c3fb27SDimitry Andric
141206c3fb27SDimitry Andricdefm : INCPat<setuge, setule, CMPHS32, INCT32, INCF32>;
141306c3fb27SDimitry Andricdefm : INCPat<setult, setugt, CMPHS32, INCF32, INCT32>;
141406c3fb27SDimitry Andricdefm : INCPat<setlt, setgt, CMPLT32, INCT32, INCF32>;
141506c3fb27SDimitry Andricdefm : INCPat<setge, setle, CMPLT32, INCF32, INCT32>;
141606c3fb27SDimitry Andric
141706c3fb27SDimitry Andricmulticlass DECPat<PatFrag cond0, PatFrag cond1, Instruction cmp, Instruction dec0, Instruction dec1> {
141806c3fb27SDimitry Andric  def : Pat<(select (i32 (cond0 GPR:$rs1, GPR:$rs2)), (add GPR:$rx, uimm5_neg:$imm), GPR:$other),
141906c3fb27SDimitry Andric            (dec0 (cmp GPR:$rs1, GPR:$rs2), GPR:$other, GPR:$rx,
142006c3fb27SDimitry Andric                  (imm_neg_XFORM uimm5_neg:$imm))>;
142106c3fb27SDimitry Andric  def : Pat<(select (i32 (cond0 GPR:$rs1, GPR:$rs2)), GPR:$other, (add GPR:$rx, uimm5_neg:$imm)),
142206c3fb27SDimitry Andric            (dec1 (cmp GPR:$rs1, GPR:$rs2), GPR:$other, GPR:$rx,
142306c3fb27SDimitry Andric                  (imm_neg_XFORM uimm5_neg:$imm))>;
142406c3fb27SDimitry Andric  def : Pat<(select (i32 (cond1 GPR:$rs1, GPR:$rs2)), (add GPR:$rx, uimm5_neg:$imm), GPR:$other),
142506c3fb27SDimitry Andric            (dec0 (cmp GPR:$rs2, GPR:$rs1), GPR:$other, GPR:$rx,
142606c3fb27SDimitry Andric                  (imm_neg_XFORM uimm5_neg:$imm))>;
142706c3fb27SDimitry Andric  def : Pat<(select (i32 (cond1 GPR:$rs1, GPR:$rs2)), GPR:$other, (add GPR:$rx, uimm5_neg:$imm)),
142806c3fb27SDimitry Andric            (dec1 (cmp GPR:$rs2, GPR:$rs1), GPR:$other, GPR:$rx,
142906c3fb27SDimitry Andric                  (imm_neg_XFORM uimm5_neg:$imm))>;
143006c3fb27SDimitry Andric}
143106c3fb27SDimitry Andric
143206c3fb27SDimitry Andricdefm : DECPat<setuge, setule, CMPHS32, DECT32, DECF32>;
143306c3fb27SDimitry Andricdefm : DECPat<setult, setugt, CMPHS32, DECF32, DECT32>;
143406c3fb27SDimitry Andricdefm : DECPat<setlt, setgt, CMPLT32, DECT32, DECF32>;
143506c3fb27SDimitry Andricdefm : DECPat<setge, setle, CMPLT32, DECF32, DECT32>;
1436bdd1243dSDimitry Andric
1437bdd1243dSDimitry Andricdef : Pat<(select (i32 (setne GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false),
1438bdd1243dSDimitry Andric          (MOVT32 (CMPNE32 GPR:$rs1, GPR:$rs2), GPR:$rx, GPR:$false)>;
1439bdd1243dSDimitry Andricdef : Pat<(select (i32 (seteq GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false),
1440bdd1243dSDimitry Andric          (MOVF32 (CMPNE32 GPR:$rs1, GPR:$rs2), GPR:$rx, GPR:$false)>;
1441bdd1243dSDimitry Andric
144206c3fb27SDimitry Andricmulticlass MOVTF32Pat1<PatFrag cond0, PatFrag cond1, Instruction cmp_inst,
144306c3fb27SDimitry Andric                       Instruction mov_inst> {
144406c3fb27SDimitry Andric  def : Pat<(select (i32 (cond0 GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false),
144506c3fb27SDimitry Andric            (mov_inst (cmp_inst GPR:$rs1, GPR:$rs2), GPR:$rx, GPR:$false)>;
144606c3fb27SDimitry Andric  def : Pat<(select (i32 (cond1 GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false),
144706c3fb27SDimitry Andric            (mov_inst (cmp_inst GPR:$rs2, GPR:$rs1), GPR:$rx, GPR:$false)>;
144806c3fb27SDimitry Andric}
144904eeddc0SDimitry Andric
145006c3fb27SDimitry Andricdefm : MOVTF32Pat1<setuge, setule, CMPHS32, MOVT32>;
145106c3fb27SDimitry Andricdefm : MOVTF32Pat1<setult, setugt, CMPHS32, MOVF32>;
145206c3fb27SDimitry Andricdefm : MOVTF32Pat1<setlt, setgt, CMPLT32, MOVT32>;
145306c3fb27SDimitry Andricdefm : MOVTF32Pat1<setge, setle, CMPLT32, MOVF32>;
145404eeddc0SDimitry Andric
145506c3fb27SDimitry Andricdef : Pat<(select CARRY:$ca, (i32 0), GPR:$other),
145606c3fb27SDimitry Andric          (CLRT32 CARRY:$ca, GPR:$other)>;
145706c3fb27SDimitry Andricdef : Pat<(select CARRY:$ca, GPR:$other, (i32 0)),
145806c3fb27SDimitry Andric          (CLRF32 CARRY:$ca, GPR:$other)>;
14590eae32dcSDimitry Andric}
14600eae32dcSDimitry Andric
14610eae32dcSDimitry Andric// Constant materialize patterns.
14620eae32dcSDimitry Andriclet Predicates = [iHasE2] in
14630eae32dcSDimitry Andric  def : Pat<(i32 imm:$imm),
14640eae32dcSDimitry Andric            (ORI32 (MOVIH32 (uimm32_hi16 imm:$imm)), (uimm32_lo16 imm:$imm))>;
14650eae32dcSDimitry Andric
1466*5f757f3fSDimitry Andric// Bit operations.
1467*5f757f3fSDimitry Andriclet Predicates = [iHasE2] in {
1468*5f757f3fSDimitry Andric  def : Pat<(or GPR:$rs, imm32_1_pop_bit:$imm),
1469*5f757f3fSDimitry Andric            (BSETI32 GPR:$rs, (imm32_1_pop_bit_XFORM imm32_1_pop_bit:$imm))>;
1470*5f757f3fSDimitry Andric  def : Pat<(and GPR:$rs, imm32_1_zero_bit:$imm),
1471*5f757f3fSDimitry Andric            (BCLRI32 GPR:$rs, (imm32_1_zero_bit_XFORM imm32_1_zero_bit:$imm))>;
1472*5f757f3fSDimitry Andric}
1473*5f757f3fSDimitry Andric
14740eae32dcSDimitry Andric// Other operations.
14750eae32dcSDimitry Andriclet Predicates = [iHasE2] in {
14760eae32dcSDimitry Andric  def : Pat<(rotl GPR:$rs1, GPR:$rs2),
14770eae32dcSDimitry Andric            (ROTL32 GPR:$rs1, (ANDI32 GPR:$rs2, 0x1f))>;
14780eae32dcSDimitry Andric  let Predicates = [iHas2E3] in {
14790eae32dcSDimitry Andric    def : Pat<(bitreverse GPR:$rx), (BREV32 GPR:$rx)>;
14800eae32dcSDimitry Andric    def : Pat<(bswap GPR:$rx), (REVB32 GPR:$rx)>;
1481*5f757f3fSDimitry Andric    def : Pat<(i32 (cttz GPR:$rx)), (FF1 (BREV32 GPR:$rx))>;
14820eae32dcSDimitry Andric  }
14830eae32dcSDimitry Andric  def : Pat<(i32 (ctlz GPR:$rx)), (FF1 GPR:$rx)>;
14840eae32dcSDimitry Andric}
1485349cc55cSDimitry Andric
1486349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
1487349cc55cSDimitry Andric// Pseudo for assembly
1488349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
1489349cc55cSDimitry Andric
1490349cc55cSDimitry Andriclet isCall = 1, Defs = [ R15 ], mayLoad = 1, Size = 4, isCodeGenOnly = 0 in
1491349cc55cSDimitry Andricdef JBSR32 : CSKYPseudo<(outs), (ins call_symbol:$src1), "jbsr32\t$src1", []>;
1492349cc55cSDimitry Andric
1493349cc55cSDimitry Andricdef JBR32 : CSKYPseudo<(outs), (ins br_symbol:$src1), "jbr32\t$src1", []> {
1494349cc55cSDimitry Andric  let isBranch = 1;
1495349cc55cSDimitry Andric  let isTerminator = 1;
1496349cc55cSDimitry Andric  let isBarrier = 1;
1497349cc55cSDimitry Andric  let isIndirectBranch = 1;
1498349cc55cSDimitry Andric  let mayLoad = 1;
1499349cc55cSDimitry Andric  let Size = 4;
1500349cc55cSDimitry Andric}
1501349cc55cSDimitry Andric
1502349cc55cSDimitry Andricdef JBT32 : CSKYPseudo<(outs), (ins CARRY:$ca, br_symbol:$src1), "jbt32\t$src1", []> {
1503349cc55cSDimitry Andric  let isBranch = 1;
1504349cc55cSDimitry Andric  let isTerminator = 1;
1505349cc55cSDimitry Andric  let isIndirectBranch = 1;
1506349cc55cSDimitry Andric  let mayLoad = 1;
1507349cc55cSDimitry Andric  let Size = 4;
1508349cc55cSDimitry Andric}
1509349cc55cSDimitry Andric
1510349cc55cSDimitry Andricdef JBF32 : CSKYPseudo<(outs), (ins CARRY:$ca, br_symbol:$src1), "jbf32\t$src1", []> {
1511349cc55cSDimitry Andric  let isBranch = 1;
1512349cc55cSDimitry Andric  let isTerminator = 1;
1513349cc55cSDimitry Andric  let isIndirectBranch = 1;
1514349cc55cSDimitry Andric  let mayLoad = 1;
1515349cc55cSDimitry Andric  let Size = 4;
1516349cc55cSDimitry Andric}
1517349cc55cSDimitry Andric
1518349cc55cSDimitry Andricdef JBT_E : CSKYPseudo<(outs), (ins CARRY:$ca, br_symbol:$src1), "!jbt_e\t$src1", []> {
1519349cc55cSDimitry Andric  let isBranch = 1;
1520349cc55cSDimitry Andric  let isTerminator = 1;
1521349cc55cSDimitry Andric  let isIndirectBranch = 1;
1522349cc55cSDimitry Andric  let mayLoad = 1;
1523349cc55cSDimitry Andric  let Size = 6;
1524349cc55cSDimitry Andric}
1525349cc55cSDimitry Andric
1526349cc55cSDimitry Andricdef JBF_E : CSKYPseudo<(outs), (ins CARRY:$ca, br_symbol:$src1), "!jbf_e\t$src1", []> {
1527349cc55cSDimitry Andric  let isBranch = 1;
1528349cc55cSDimitry Andric  let isTerminator = 1;
1529349cc55cSDimitry Andric  let isIndirectBranch = 1;
1530349cc55cSDimitry Andric  let mayLoad = 1;
1531349cc55cSDimitry Andric  let Size = 6;
1532349cc55cSDimitry Andric}
1533349cc55cSDimitry Andric
1534349cc55cSDimitry Andriclet mayLoad = 1, Size = 2, isCodeGenOnly = 0 in
1535349cc55cSDimitry Andricdef PseudoLRW32 : CSKYPseudo<(outs GPR:$rz), (ins bare_symbol:$src), "lrw32 $rz, $src", []>;
1536349cc55cSDimitry Andric
1537349cc55cSDimitry Andriclet mayLoad = 1, Size = 4, isCodeGenOnly = 0 in
1538349cc55cSDimitry Andricdef PseudoJSRI32 : CSKYPseudo<(outs), (ins call_symbol:$src), "jsri32 $src", []>;
1539349cc55cSDimitry Andric
1540349cc55cSDimitry Andriclet mayLoad = 1, Size = 4, isCodeGenOnly = 0 in
1541349cc55cSDimitry Andricdef PseudoJMPI32 : CSKYPseudo<(outs), (ins br_symbol:$src), "jmpi32 $src", []>;
1542349cc55cSDimitry Andric
1543349cc55cSDimitry Andriclet isNotDuplicable = 1, mayLoad = 1, mayStore = 0, Size = 8 in
1544349cc55cSDimitry Andricdef PseudoTLSLA32 : CSKYPseudo<(outs GPR:$dst1, GPR:$dst2),
1545349cc55cSDimitry Andric  (ins constpool_symbol:$src, i32imm:$label), "!tlslrw32\t$dst1, $dst2, $src, $label", []>;
1546349cc55cSDimitry Andric
1547349cc55cSDimitry Andriclet hasSideEffects = 0, isNotDuplicable = 1 in
1548349cc55cSDimitry Andricdef CONSTPOOL_ENTRY : CSKYPseudo<(outs),
1549349cc55cSDimitry Andric  (ins i32imm:$instid, i32imm:$cpidx, i32imm:$size), "", []>;
1550349cc55cSDimitry Andric
1551349cc55cSDimitry Andricinclude "CSKYInstrInfo16Instr.td"
155204eeddc0SDimitry Andricinclude "CSKYInstrInfoF1.td"
155304eeddc0SDimitry Andricinclude "CSKYInstrInfoF2.td"
155481ad6265SDimitry Andricinclude "CSKYInstrAlias.td"
1555