xref: /freebsd/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrInfo.td (revision 0eae32dcef82f6f06de6419a0d623d7def0cc8f6)
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
18349cc55cSDimitry Andricdef SDT_CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>,
19349cc55cSDimitry Andric                                       SDTCisVT<1, i32>]>;
20349cc55cSDimitry Andric
21349cc55cSDimitry Andricdef SDT_CallSeqEnd   : SDCallSeqEnd<[SDTCisVT<0, i32>,
22349cc55cSDimitry Andric                                     SDTCisVT<1, i32>]>;
23349cc55cSDimitry Andric
24349cc55cSDimitry Andricdef callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_CallSeqStart,
25349cc55cSDimitry Andric                           [SDNPHasChain, SDNPOutGlue]>;
26349cc55cSDimitry Andric
27349cc55cSDimitry Andricdef callseq_end   : SDNode<"ISD::CALLSEQ_END", SDT_CallSeqEnd,
28349cc55cSDimitry Andric                           [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
29349cc55cSDimitry Andric
30fe6060f1SDimitry Andric// Target-dependent nodes.
31fe6060f1SDimitry Andricdef CSKY_RET : SDNode<"CSKYISD::RET", SDTNone,
32fe6060f1SDimitry Andric    [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
33e8d8bef9SDimitry Andric
34e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
35e8d8bef9SDimitry Andric// Operand and SDNode transformation definitions.
36e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
37fe6060f1SDimitry Andricclass ImmAsmOperand<string prefix, int width, string suffix> : AsmOperandClass {
38fe6060f1SDimitry Andric  let Name = prefix # "Imm" # width # suffix;
39fe6060f1SDimitry Andric  let RenderMethod = "addImmOperands";
40fe6060f1SDimitry Andric  let DiagnosticType = !strconcat("Invalid", Name);
41fe6060f1SDimitry Andric}
42fe6060f1SDimitry Andric
43fe6060f1SDimitry Andricclass SImmAsmOperand<int width, string suffix = "">
44fe6060f1SDimitry Andric    : ImmAsmOperand<"S", width, suffix> {
45fe6060f1SDimitry Andric}
46fe6060f1SDimitry Andric
47fe6060f1SDimitry Andricclass UImmAsmOperand<int width, string suffix = "">
48fe6060f1SDimitry Andric    : ImmAsmOperand<"U", width, suffix> {
49fe6060f1SDimitry Andric}
50fe6060f1SDimitry Andric
51fe6060f1SDimitry Andricclass OImmAsmOperand<int width, string suffix = "">
52fe6060f1SDimitry Andric    : ImmAsmOperand<"O", width, suffix> {
53fe6060f1SDimitry Andric}
54e8d8bef9SDimitry Andric
55*0eae32dcSDimitry Andricdef to_tframeindex : SDNodeXForm<frameindex, [{
56*0eae32dcSDimitry Andric  auto FI = cast<FrameIndexSDNode>(N);
57*0eae32dcSDimitry Andric  return CurDAG->getTargetFrameIndex(FI->getIndex(), TLI->getPointerTy(CurDAG->getDataLayout()));
58*0eae32dcSDimitry Andric}]>;
59*0eae32dcSDimitry Andric
60e8d8bef9SDimitry Andricclass oimm<int num> : Operand<i32>,
61e8d8bef9SDimitry Andric  ImmLeaf<i32, "return isUInt<"#num#">(Imm - 1);"> {
62e8d8bef9SDimitry Andric  let EncoderMethod = "getOImmOpValue";
63fe6060f1SDimitry Andric  let ParserMatchClass = OImmAsmOperand<num>;
64349cc55cSDimitry Andric  let DecoderMethod = "decodeOImmOperand<"#num#">";
65e8d8bef9SDimitry Andric}
66e8d8bef9SDimitry Andric
67e8d8bef9SDimitry Andricclass uimm<int num, int shift = 0> : Operand<i32>,
68e8d8bef9SDimitry Andric  ImmLeaf<i32, "return isShiftedUInt<"#num#", "#shift#">(Imm);"> {
69e8d8bef9SDimitry Andric  let EncoderMethod = "getImmOpValue<"#shift#">";
70fe6060f1SDimitry Andric  let ParserMatchClass =
71fe6060f1SDimitry Andric    !if(!ne(shift, 0),
72fe6060f1SDimitry Andric        UImmAsmOperand<num, "Shift"#shift>,
73fe6060f1SDimitry Andric        UImmAsmOperand<num>);
74349cc55cSDimitry Andric  let DecoderMethod = "decodeUImmOperand<"#num#", "#shift#">";
75e8d8bef9SDimitry Andric}
76e8d8bef9SDimitry Andric
77e8d8bef9SDimitry Andricclass simm<int num, int shift = 0> : Operand<i32>,
78e8d8bef9SDimitry Andric  ImmLeaf<i32, "return isShiftedInt<"#num#", "#shift#">(Imm);"> {
79e8d8bef9SDimitry Andric  let EncoderMethod = "getImmOpValue<"#shift#">";
80fe6060f1SDimitry Andric  let ParserMatchClass = SImmAsmOperand<num>;
81349cc55cSDimitry Andric  let DecoderMethod = "decodeSImmOperand<"#num#", "#shift#">";
82e8d8bef9SDimitry Andric}
83e8d8bef9SDimitry Andric
84e8d8bef9SDimitry Andricdef nimm_XFORM : SDNodeXForm<imm, [{
85e8d8bef9SDimitry Andric  return CurDAG->getTargetConstant(~N->getSExtValue(), SDLoc(N), MVT::i32);
86e8d8bef9SDimitry Andric}]>;
87e8d8bef9SDimitry Andricclass nimm<int num> : Operand<i32>,
88e8d8bef9SDimitry Andric  ImmLeaf<i32, "return isUInt<"#num#">(~Imm);", nimm_XFORM> {
89fe6060f1SDimitry Andric  let ParserMatchClass = UImmAsmOperand<num>;
90e8d8bef9SDimitry Andric}
91e8d8bef9SDimitry Andric
92fe6060f1SDimitry Andricdef uimm32_hi16 : SDNodeXForm<imm, [{
93fe6060f1SDimitry Andric  return CurDAG->getTargetConstant((N->getZExtValue() >> 16) & 0xFFFF,
94fe6060f1SDimitry Andric    SDLoc(N), MVT::i32);
95fe6060f1SDimitry Andric}]>;
96349cc55cSDimitry Andricdef uimm32_lo16 : SDNodeXForm<imm, [{
97349cc55cSDimitry Andric  return CurDAG->getTargetConstant(N->getZExtValue()& 0xFFFF, SDLoc(N), MVT::i32);
98349cc55cSDimitry Andric}]>;
99fe6060f1SDimitry Andricdef uimm16_16_xform : Operand<i32>,
100fe6060f1SDimitry Andric  ImmLeaf<i32, "return isShiftedUInt<16, 16>(Imm);", uimm32_hi16> {
101fe6060f1SDimitry Andric  let ParserMatchClass = UImmAsmOperand<16>;
102349cc55cSDimitry Andric  let EncoderMethod = "getImmOpValue";
103fe6060f1SDimitry Andric}
104fe6060f1SDimitry Andric
105fe6060f1SDimitry Andricdef uimm_shift : Operand<i32>, ImmLeaf<i32, "return isUInt<2>(Imm);"> {
106fe6060f1SDimitry Andric  let EncoderMethod = "getImmShiftOpValue";
107fe6060f1SDimitry Andric  let ParserMatchClass = UImmAsmOperand<2>;
108349cc55cSDimitry Andric  let DecoderMethod = "decodeImmShiftOpValue";
109fe6060f1SDimitry Andric}
110fe6060f1SDimitry Andric
111fe6060f1SDimitry Andricdef CSKYSymbol : AsmOperandClass {
112fe6060f1SDimitry Andric  let Name = "CSKYSymbol";
113fe6060f1SDimitry Andric  let RenderMethod = "addImmOperands";
114fe6060f1SDimitry Andric  let DiagnosticType = "InvalidCSKYSymbol";
115fe6060f1SDimitry Andric  let ParserMethod = "parseCSKYSymbol";
116fe6060f1SDimitry Andric}
117fe6060f1SDimitry Andric
118fe6060f1SDimitry Andricdef br_symbol : Operand<iPTR> {
119fe6060f1SDimitry Andric  let EncoderMethod =
120fe6060f1SDimitry Andric    "getBranchSymbolOpValue<CSKY::fixup_csky_pcrel_imm16_scale2>";
121fe6060f1SDimitry Andric  let ParserMatchClass = CSKYSymbol;
122349cc55cSDimitry Andric  let DecoderMethod = "decodeSImmOperand<16, 1>";
123349cc55cSDimitry Andric  let PrintMethod = "printCSKYSymbolOperand";
124349cc55cSDimitry Andric  let OperandType = "OPERAND_PCREL";
125fe6060f1SDimitry Andric}
126fe6060f1SDimitry Andric
127fe6060f1SDimitry Andricdef call_symbol : Operand<iPTR> {
128fe6060f1SDimitry Andric  let ParserMatchClass = CSKYSymbol;
129fe6060f1SDimitry Andric  let EncoderMethod = "getCallSymbolOpValue";
130349cc55cSDimitry Andric  let DecoderMethod = "decodeSImmOperand<26, 1>";
131349cc55cSDimitry Andric  let PrintMethod = "printCSKYSymbolOperand";
132349cc55cSDimitry Andric  let OperandType = "OPERAND_PCREL";
133fe6060f1SDimitry Andric}
134fe6060f1SDimitry Andric
135fe6060f1SDimitry Andricdef Constpool : AsmOperandClass {
136349cc55cSDimitry Andric  let Name = "Constpool";
137349cc55cSDimitry Andric  let RenderMethod = "addConstpoolOperands";
138fe6060f1SDimitry Andric  let DiagnosticType = "InvalidConstpool";
139fe6060f1SDimitry Andric  let ParserMethod = "parseConstpoolSymbol";
140fe6060f1SDimitry Andric}
141fe6060f1SDimitry Andric
142fe6060f1SDimitry Andricdef constpool_symbol : Operand<iPTR> {
143fe6060f1SDimitry Andric  let ParserMatchClass = Constpool;
144fe6060f1SDimitry Andric  let EncoderMethod =
145fe6060f1SDimitry Andric    "getConstpoolSymbolOpValue<CSKY::fixup_csky_pcrel_uimm16_scale4>";
146349cc55cSDimitry Andric  let DecoderMethod = "decodeUImmOperand<16, 2>";
147349cc55cSDimitry Andric  let PrintMethod = "printConstpool";
148349cc55cSDimitry Andric  let OperandType = "OPERAND_PCREL";
149349cc55cSDimitry Andric}
150349cc55cSDimitry Andric
151349cc55cSDimitry Andricdef DataAsmClass : AsmOperandClass {
152349cc55cSDimitry Andric  let Name = "DataSymbol";
153349cc55cSDimitry Andric  let RenderMethod = "addConstpoolOperands";
154349cc55cSDimitry Andric  let DiagnosticType = "InvalidConstpool";
155349cc55cSDimitry Andric  let ParserMethod = "parseDataSymbol";
156349cc55cSDimitry Andric}
157349cc55cSDimitry Andric
158349cc55cSDimitry Andricclass data_symbol<string reloc, int shift> : Operand<iPTR> {
159349cc55cSDimitry Andric  let ParserMatchClass = Constpool;
160349cc55cSDimitry Andric  let EncoderMethod =
161349cc55cSDimitry Andric    "getDataSymbolOpValue<"#reloc#">";
162349cc55cSDimitry Andric  let DecoderMethod = "decodeUImmOperand<18, "#shift#">";
163349cc55cSDimitry Andric  let PrintMethod = "printDataSymbol";
164fe6060f1SDimitry Andric}
165fe6060f1SDimitry Andric
166fe6060f1SDimitry Andricdef bare_symbol : Operand<iPTR> {
167fe6060f1SDimitry Andric  let ParserMatchClass = CSKYSymbol;
168fe6060f1SDimitry Andric  let EncoderMethod = "getBareSymbolOpValue";
169349cc55cSDimitry Andric  let PrintMethod = "printCSKYSymbolOperand";
170349cc55cSDimitry Andric  let DecoderMethod = "decodeSImmOperand<18, 1>";
171349cc55cSDimitry Andric  let OperandType = "OPERAND_PCREL";
172fe6060f1SDimitry Andric}
173e8d8bef9SDimitry Andric
174*0eae32dcSDimitry Andricdef oimm3 : oimm<3> {
175*0eae32dcSDimitry Andric  let MCOperandPredicate = [{
176*0eae32dcSDimitry Andric    int64_t Imm;
177*0eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
178*0eae32dcSDimitry Andric      return isUInt<3>(Imm - 1);
179*0eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
180*0eae32dcSDimitry Andric  }];
181*0eae32dcSDimitry Andric}
182349cc55cSDimitry Andricdef oimm4 : oimm<4>;
183*0eae32dcSDimitry Andricdef oimm5 : oimm<5> {
184*0eae32dcSDimitry Andric  let MCOperandPredicate = [{
185*0eae32dcSDimitry Andric    int64_t Imm;
186*0eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
187*0eae32dcSDimitry Andric      return isUInt<5>(Imm - 1);
188*0eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
189*0eae32dcSDimitry Andric  }];
190*0eae32dcSDimitry Andric}
191349cc55cSDimitry Andricdef oimm6 : oimm<6>;
192349cc55cSDimitry Andric
193349cc55cSDimitry Andricdef imm5_idly : Operand<i32>, ImmLeaf<i32,
194349cc55cSDimitry Andric  "return Imm <= 32 && Imm >= 0;"> {
195349cc55cSDimitry Andric  let EncoderMethod = "getImmOpValueIDLY";
196349cc55cSDimitry Andric  let DecoderMethod = "decodeOImmOperand<5>";
197349cc55cSDimitry Andric}
198349cc55cSDimitry Andric
199*0eae32dcSDimitry Andricdef oimm8 : oimm<8> {
200*0eae32dcSDimitry Andric  let MCOperandPredicate = [{
201*0eae32dcSDimitry Andric    int64_t Imm;
202*0eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
203*0eae32dcSDimitry Andric      return isUInt<8>(Imm - 1);
204*0eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
205*0eae32dcSDimitry Andric  }];
206*0eae32dcSDimitry Andric}
207*0eae32dcSDimitry Andricdef oimm12 : oimm<12> {
208*0eae32dcSDimitry Andric  let MCOperandPredicate = [{
209*0eae32dcSDimitry Andric    int64_t Imm;
210*0eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
211*0eae32dcSDimitry Andric      return isUInt<12>(Imm - 1);
212*0eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
213*0eae32dcSDimitry Andric  }];
214*0eae32dcSDimitry Andric}
215*0eae32dcSDimitry Andricdef oimm16 : oimm<16> {
216*0eae32dcSDimitry Andric  let MCOperandPredicate = [{
217*0eae32dcSDimitry Andric    int64_t Imm;
218*0eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
219*0eae32dcSDimitry Andric      return isUInt<16>(Imm - 1);
220*0eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
221*0eae32dcSDimitry Andric  }];
222*0eae32dcSDimitry Andric}
223e8d8bef9SDimitry Andric
224e8d8bef9SDimitry Andricdef nimm12 : nimm<12>;
225e8d8bef9SDimitry Andric
226349cc55cSDimitry Andricdef uimm1 : uimm<1>;
227349cc55cSDimitry Andricdef uimm2 : uimm<2>;
228349cc55cSDimitry Andric
229349cc55cSDimitry Andric
230349cc55cSDimitry Andricdef uimm2_jmpix : Operand<i32>,
231349cc55cSDimitry Andric  ImmLeaf<i32, "return Imm == 16 || Imm == 24 || Imm == 32 || Imm == 40;"> {
232349cc55cSDimitry Andric  let EncoderMethod = "getImmJMPIX";
233349cc55cSDimitry Andric  let DecoderMethod = "decodeJMPIXImmOperand";
234349cc55cSDimitry Andric}
235349cc55cSDimitry Andric
236349cc55cSDimitry Andricdef uimm3 : uimm<3>;
237349cc55cSDimitry Andricdef uimm4 : uimm<4>;
238*0eae32dcSDimitry Andricdef uimm5 : uimm<5> {
239*0eae32dcSDimitry Andric  let MCOperandPredicate = [{
240*0eae32dcSDimitry Andric    int64_t Imm;
241*0eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
242*0eae32dcSDimitry Andric      return isShiftedUInt<5, 0>(Imm);
243*0eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
244*0eae32dcSDimitry Andric  }];
245*0eae32dcSDimitry Andric}
246349cc55cSDimitry Andricdef uimm5_msb_size : uimm<5> {
247349cc55cSDimitry Andric  let EncoderMethod = "getImmOpValueMSBSize";
248349cc55cSDimitry Andric}
249349cc55cSDimitry Andric
250*0eae32dcSDimitry Andricdef uimm5_1 : uimm<5, 1> {
251*0eae32dcSDimitry Andric  let MCOperandPredicate = [{
252*0eae32dcSDimitry Andric    int64_t Imm;
253*0eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
254*0eae32dcSDimitry Andric      return isShiftedUInt<5, 1>(Imm);
255*0eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
256*0eae32dcSDimitry Andric  }];
257*0eae32dcSDimitry Andric}
258*0eae32dcSDimitry Andricdef uimm5_2 : uimm<5, 2> {
259*0eae32dcSDimitry Andric  let MCOperandPredicate = [{
260*0eae32dcSDimitry Andric    int64_t Imm;
261*0eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
262*0eae32dcSDimitry Andric      return isShiftedUInt<5, 2>(Imm);
263*0eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
264*0eae32dcSDimitry Andric  }];
265*0eae32dcSDimitry Andric}
266349cc55cSDimitry Andricdef uimm6 : uimm<6>;
267349cc55cSDimitry Andricdef uimm7 : uimm<7>;
268349cc55cSDimitry Andricdef uimm7_1 : uimm<7, 1>;
269*0eae32dcSDimitry Andricdef uimm7_2 : uimm<7, 2>{
270*0eae32dcSDimitry Andric  let MCOperandPredicate = [{
271*0eae32dcSDimitry Andric    int64_t Imm;
272*0eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
273*0eae32dcSDimitry Andric      return isShiftedUInt<7, 2>(Imm);
274*0eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
275*0eae32dcSDimitry Andric  }];
276*0eae32dcSDimitry Andric}
277349cc55cSDimitry Andricdef uimm7_3 : uimm<7, 3>;
278*0eae32dcSDimitry Andricdef uimm8 : uimm<8> {
279*0eae32dcSDimitry Andric  let MCOperandPredicate = [{
280*0eae32dcSDimitry Andric    int64_t Imm;
281*0eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
282*0eae32dcSDimitry Andric      return isShiftedUInt<8, 0>(Imm);
283*0eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
284*0eae32dcSDimitry Andric  }];
285*0eae32dcSDimitry Andric}
286*0eae32dcSDimitry Andricdef uimm8_2 : uimm<8, 2> {
287*0eae32dcSDimitry Andric  let MCOperandPredicate = [{
288*0eae32dcSDimitry Andric    int64_t Imm;
289*0eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
290*0eae32dcSDimitry Andric      return isShiftedUInt<8, 2>(Imm);
291*0eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
292*0eae32dcSDimitry Andric  }];
293*0eae32dcSDimitry Andric}
294349cc55cSDimitry Andricdef uimm8_3 : uimm<8, 3>;
295349cc55cSDimitry Andricdef uimm8_8 : uimm<8, 8>;
296349cc55cSDimitry Andricdef uimm8_16 : uimm<8, 16>;
297349cc55cSDimitry Andricdef uimm8_24 : uimm<8, 24>;
298*0eae32dcSDimitry Andricdef uimm12 : uimm<12>  {
299*0eae32dcSDimitry Andric  let MCOperandPredicate = [{
300*0eae32dcSDimitry Andric    int64_t Imm;
301*0eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
302*0eae32dcSDimitry Andric      return isShiftedUInt<12, 0>(Imm);
303*0eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
304*0eae32dcSDimitry Andric  }];
305*0eae32dcSDimitry Andric}
306*0eae32dcSDimitry Andricdef uimm12_1 : uimm<12, 1> {
307*0eae32dcSDimitry Andric  let MCOperandPredicate = [{
308*0eae32dcSDimitry Andric    int64_t Imm;
309*0eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
310*0eae32dcSDimitry Andric      return isShiftedUInt<12, 1>(Imm);
311*0eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
312*0eae32dcSDimitry Andric  }];
313*0eae32dcSDimitry Andric}
314*0eae32dcSDimitry Andricdef uimm12_2 : uimm<12, 2> {
315*0eae32dcSDimitry Andric  let MCOperandPredicate = [{
316*0eae32dcSDimitry Andric    int64_t Imm;
317*0eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
318*0eae32dcSDimitry Andric      return isShiftedUInt<12, 2>(Imm);
319*0eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
320*0eae32dcSDimitry Andric  }];
321*0eae32dcSDimitry Andric}
322*0eae32dcSDimitry Andricdef uimm16 : uimm<16> {
323*0eae32dcSDimitry Andric  let MCOperandPredicate = [{
324*0eae32dcSDimitry Andric    int64_t Imm;
325*0eae32dcSDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
326*0eae32dcSDimitry Andric      return isShiftedUInt<16, 0>(Imm);
327*0eae32dcSDimitry Andric    return MCOp.isBareSymbolRef();
328*0eae32dcSDimitry Andric  }];
329*0eae32dcSDimitry Andric}
330349cc55cSDimitry Andricdef uimm16_8 : uimm<16, 8>;
331349cc55cSDimitry Andricdef uimm16_16 : uimm<16, 16>;
332349cc55cSDimitry Andricdef uimm20 : uimm<20>;
333349cc55cSDimitry Andricdef uimm24 : uimm<24>;
334349cc55cSDimitry Andricdef uimm24_8 : uimm<24, 8>;
335fe6060f1SDimitry Andric
336349cc55cSDimitry Andricdef simm8_2 : simm<8, 2>;
337349cc55cSDimitry Andric
338349cc55cSDimitry Andricclass RegSeqAsmOperand<string Suffix = ""> : AsmOperandClass {
339349cc55cSDimitry Andric  let Name = "RegSeq"#Suffix;
340349cc55cSDimitry Andric  let RenderMethod = "addRegSeqOperands";
341349cc55cSDimitry Andric  let DiagnosticType = "InvalidRegSeq";
342349cc55cSDimitry Andric  let ParserMethod = "parseRegSeq";
343349cc55cSDimitry Andric}
344349cc55cSDimitry Andric
345349cc55cSDimitry Andricdef regseq : Operand<iPTR> {
346349cc55cSDimitry Andric  let EncoderMethod = "getRegisterSeqOpValue";
347349cc55cSDimitry Andric  let ParserMatchClass = RegSeqAsmOperand<"">;
348349cc55cSDimitry Andric  let PrintMethod = "printRegisterSeq";
349349cc55cSDimitry Andric  let DecoderMethod = "DecodeRegSeqOperand";
350349cc55cSDimitry Andric  let MIOperandInfo = (ops GPR, uimm5);
351349cc55cSDimitry Andric}
352349cc55cSDimitry Andric
353349cc55cSDimitry Andricdef RegListAsmOperand : AsmOperandClass {
354349cc55cSDimitry Andric  let Name = "RegList";
355349cc55cSDimitry Andric  let RenderMethod = "addRegListOperands";
356349cc55cSDimitry Andric  let DiagnosticType = "InvalidRegList";
357349cc55cSDimitry Andric  let ParserMethod = "parseRegList";
358349cc55cSDimitry Andric}
359349cc55cSDimitry Andric
360349cc55cSDimitry Andricdef reglist : Operand<iPTR> {
361349cc55cSDimitry Andric  let ParserMatchClass = RegListAsmOperand;
362349cc55cSDimitry Andric  let PrintMethod = "printRegisterList";
363349cc55cSDimitry Andric}
364349cc55cSDimitry Andric
365349cc55cSDimitry Andricdef PSRFlag : AsmOperandClass {
366349cc55cSDimitry Andric  let Name = "PSRFlag";
367349cc55cSDimitry Andric  let RenderMethod = "addImmOperands";
368349cc55cSDimitry Andric  let DiagnosticType = "InvalidPSRFlag";
369349cc55cSDimitry Andric  let ParserMethod = "parsePSRFlag";
370349cc55cSDimitry Andric}
371349cc55cSDimitry Andric
372349cc55cSDimitry Andricdef psrflag : Operand<i32>, ImmLeaf<i32, "return isShiftedUInt<5, 0>(Imm);"> {
373349cc55cSDimitry Andric  let EncoderMethod = "getImmOpValue";
374349cc55cSDimitry Andric  let ParserMatchClass = PSRFlag;
375349cc55cSDimitry Andric  let PrintMethod = "printPSRFlag";
376349cc55cSDimitry Andric}
377fe6060f1SDimitry Andric
378fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
379fe6060f1SDimitry Andric// Instruction Formats
380fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
381fe6060f1SDimitry Andric
382fe6060f1SDimitry Andricinclude "CSKYInstrFormats.td"
383e8d8bef9SDimitry Andric
384e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
385e8d8bef9SDimitry Andric// Instruction definitions.
386e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
387e8d8bef9SDimitry Andric
388e8d8bef9SDimitry Andricclass TriOpFrag<dag res> : PatFrag<(ops node: $LHS, node:$MHS, node:$RHS), res>;
389e8d8bef9SDimitry Andricclass BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
390e8d8bef9SDimitry Andricclass UnOpFrag<dag res> : PatFrag<(ops node:$Src), res>;
391e8d8bef9SDimitry Andric
392349cc55cSDimitry Andricdef eqToAdd : PatFrag<(ops node:$lhs, node:$rhs), (or node:$lhs, node:$rhs), [{
393349cc55cSDimitry Andric  return isOrEquivalentToAdd(N);
394349cc55cSDimitry Andric}]>;
395349cc55cSDimitry Andric
396349cc55cSDimitry Andricdef BaseAddr : ComplexPattern<iPTR, 1, "SelectBaseAddr">;
397349cc55cSDimitry Andric
398349cc55cSDimitry Andric
399349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
400349cc55cSDimitry Andric// CSKYPseudo
401349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
402349cc55cSDimitry Andric
403349cc55cSDimitry Andric// Pessimistically assume the stack pointer will be clobbered
404349cc55cSDimitry Andriclet Defs = [R14], Uses = [R14] in {
405349cc55cSDimitry Andricdef ADJCALLSTACKDOWN : CSKYPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
406349cc55cSDimitry Andric  "!ADJCALLSTACKDOWN $amt1, $amt2", [(callseq_start timm:$amt1, timm:$amt2)]>;
407349cc55cSDimitry Andricdef ADJCALLSTACKUP   : CSKYPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
408349cc55cSDimitry Andric  "!ADJCALLSTACKUP $amt1, $amt2", [(callseq_end timm:$amt1, timm:$amt2)]>;
409349cc55cSDimitry Andric} // Defs = [R14], Uses = [R14]
410fe6060f1SDimitry Andric
411fe6060f1SDimitry Andric
412fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
413fe6060f1SDimitry Andric// Basic ALU instructions.
414fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
415fe6060f1SDimitry Andric
416349cc55cSDimitry Andriclet Predicates = [iHasE2] in {
417349cc55cSDimitry Andric  let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
418349cc55cSDimitry Andric  let isAdd = 1 in
419e8d8bef9SDimitry Andric  def ADDI32 : I_12<0x0, "addi32", add, oimm12>;
420e8d8bef9SDimitry Andric  def SUBI32 : I_12<0x1, "subi32", sub, oimm12>;
421fe6060f1SDimitry Andric  def ORI32 : I_16_ZX<"ori32", uimm16,
422fe6060f1SDimitry Andric  [(set GPR:$rz, (or GPR:$rx, uimm16:$imm16))]>;
423fe6060f1SDimitry Andric  def XORI32 : I_12<0x4, "xori32", xor, uimm12>;
424e8d8bef9SDimitry Andric  def ANDI32 : I_12<0x2, "andi32", and, uimm12>;
425e8d8bef9SDimitry Andric  def ANDNI32 : I_12<0x3, "andni32", and, nimm12>;
426e8d8bef9SDimitry Andric  def LSLI32 : I_5_XZ<0x12, 0x1, "lsli32",
427e8d8bef9SDimitry Andric    (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5),
428e8d8bef9SDimitry Andric    [(set GPR:$rz, (shl GPR:$rx, uimm5:$imm5))]>;
429e8d8bef9SDimitry Andric  def LSRI32 : I_5_XZ<0x12, 0x2, "lsri32",
430e8d8bef9SDimitry Andric    (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5),
431e8d8bef9SDimitry Andric    [(set GPR:$rz, (srl GPR:$rx, uimm5:$imm5))]>;
432e8d8bef9SDimitry Andric  def ASRI32 : I_5_XZ<0x12, 0x4, "asri32",
433e8d8bef9SDimitry Andric    (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5),
434e8d8bef9SDimitry Andric    [(set GPR:$rz, (sra GPR:$rx, uimm5:$imm5))]>;
435fe6060f1SDimitry Andric  def ROTLI32 : I_5_XZ<0x12, 0x8, "rotli32",
436fe6060f1SDimitry Andric    (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5),
437fe6060f1SDimitry Andric    [(set GPR:$rz, (rotl GPR:$rx, uimm5:$imm5))]>;
438e8d8bef9SDimitry Andric
439349cc55cSDimitry Andric  def ROTRI32 : CSKYPseudo<(outs GPR:$rz), (ins GPR:$rx, oimm5:$imm5),
440349cc55cSDimitry Andric                            "rotri32 $rz, $rx, $imm5", []>;
441349cc55cSDimitry Andric  }
442349cc55cSDimitry Andric  let isAdd = 1 in
443e8d8bef9SDimitry Andric  def ADDU32 : R_YXZ_SP_F1<0x0, 0x1,
444e8d8bef9SDimitry Andric    BinOpFrag<(add node:$LHS, node:$RHS)>, "addu32", 1>;
445e8d8bef9SDimitry Andric  def SUBU32 : R_YXZ_SP_F1<0x0, 0x4,
446e8d8bef9SDimitry Andric    BinOpFrag<(sub node:$LHS, node:$RHS)>, "subu32">;
447349cc55cSDimitry Andric
448fe6060f1SDimitry Andric  def MULT32 : R_YXZ_SP_F1<0x21, 0x1,
449fe6060f1SDimitry Andric    BinOpFrag<(mul node:$LHS, node:$RHS)>, "mult32", 1>;
450e8d8bef9SDimitry Andric  def AND32 : R_YXZ_SP_F1<0x8, 0x1,
451e8d8bef9SDimitry Andric    BinOpFrag<(and node:$LHS, node:$RHS)>, "and32", 1>;
452e8d8bef9SDimitry Andric  def ANDN32 : R_YXZ_SP_F1<0x8, 0x2,
453e8d8bef9SDimitry Andric    BinOpFrag<(and node:$LHS, (not node:$RHS))>, "andn32">;
454e8d8bef9SDimitry Andric  def OR32: R_YXZ_SP_F1<0x9, 0x1,
455e8d8bef9SDimitry Andric    BinOpFrag<(or node:$LHS, node:$RHS)>, "or32", 1>;
456e8d8bef9SDimitry Andric  def XOR32 : R_YXZ_SP_F1<0x9, 0x2,
457e8d8bef9SDimitry Andric    BinOpFrag<(xor node:$LHS, node:$RHS)>, "xor32", 1>;
458e8d8bef9SDimitry Andric  def NOR32 : R_YXZ_SP_F1<0x9, 0x4,
459e8d8bef9SDimitry Andric    BinOpFrag<(not (or node:$LHS, node:$RHS))>, "nor32", 1>;
460349cc55cSDimitry Andric  let isCodeGenOnly = 1 in
461fe6060f1SDimitry Andric  def NOT32 : R_XXZ<0b001001, 0b00100, (outs GPR:$rz), (ins GPR:$rx),
462fe6060f1SDimitry Andric    "not32", [(set GPR:$rz, (not GPR:$rx))]>;
463349cc55cSDimitry Andric
464349cc55cSDimitry Andric  let Size = 8 in
465349cc55cSDimitry Andric  def NEG32 : CSKYPseudo<(outs GPR:$rd), (ins GPR:$rx), "neg32 $rd, $rx", []>;
466349cc55cSDimitry Andric
467349cc55cSDimitry Andric  let Size = 8 in
468349cc55cSDimitry Andric  def RSUBI32 : CSKYPseudo<(outs GPR:$rd), (ins GPR:$rx, uimm12:$imm12), "rsubi32 $rd, $rx, $imm12", []>;
469349cc55cSDimitry Andric
470e8d8bef9SDimitry Andric  def LSL32 : R_YXZ_SP_F1<0x10, 0x1,
471e8d8bef9SDimitry Andric    BinOpFrag<(shl node:$LHS, node:$RHS)>, "lsl32">;
472e8d8bef9SDimitry Andric  def LSR32 : R_YXZ_SP_F1<0x10, 0x2,
473e8d8bef9SDimitry Andric    BinOpFrag<(srl node:$LHS, node:$RHS)>, "lsr32">;
474e8d8bef9SDimitry Andric  def ASR32 : R_YXZ_SP_F1<0x10, 0x4,
475e8d8bef9SDimitry Andric    BinOpFrag<(sra node:$LHS, node:$RHS)>, "asr32">;
476fe6060f1SDimitry Andric  def ROTL32 : R_YXZ_SP_F1<0x10, 0x8,
477fe6060f1SDimitry Andric    BinOpFrag<(rotl node:$LHS, (and node:$RHS, 0x1f))>, "rotl32">;
478fe6060f1SDimitry Andric
479349cc55cSDimitry Andric  def BMASKI32 : I_5_Z<0b010100, 0x1, "bmaski32", oimm5, []>;
480349cc55cSDimitry Andric  def LSLC32 : I_5_XZ<0x13, 0x1, "lslc32",
481349cc55cSDimitry Andric    (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, oimm5:$imm5), []>;
482349cc55cSDimitry Andric  def LSRC32 : I_5_XZ<0x13, 0x2, "lsrc32",
483349cc55cSDimitry Andric    (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, oimm5:$imm5), []>;
484349cc55cSDimitry Andric  def ASRC32 : I_5_XZ<0x13, 0x4, "asrc32",
485349cc55cSDimitry Andric    (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, oimm5:$imm5), []>;
486349cc55cSDimitry Andric  def XSR32 : I_5_XZ<0x13, 0x8, "xsr32",
487349cc55cSDimitry Andric    (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, oimm5:$imm5, CARRY:$cin), []>;
488fe6060f1SDimitry Andric
489fe6060f1SDimitry Andric  def IXH32 : R_YXZ_SP_F1<0x2, 0x1,
490fe6060f1SDimitry Andric    BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 1)))>, "ixh32">;
491fe6060f1SDimitry Andric  def IXW32 : R_YXZ_SP_F1<0x2, 0x2,
492fe6060f1SDimitry Andric    BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 2)))>, "ixw32">;
493349cc55cSDimitry Andric  let Predicates = [iHas2E3] in
494fe6060f1SDimitry Andric  def IXD32 : R_YXZ_SP_F1<0x2, 0x4,
495fe6060f1SDimitry Andric    BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 3)))>, "ixd32">;
496fe6060f1SDimitry Andric
497349cc55cSDimitry Andric  let isCommutable = 1, isAdd = 1 in
498fe6060f1SDimitry Andric  def ADDC32 : R_YXZ<0x31, 0x0, 0x2, (outs GPR:$rz, CARRY:$cout),
499fe6060f1SDimitry Andric    (ins GPR:$rx, GPR:$ry, CARRY:$cin), "addc32", []>;
500fe6060f1SDimitry Andric  def SUBC32 : R_YXZ<0x31, 0x0, 0x8, (outs GPR:$rz, CARRY:$cout),
501fe6060f1SDimitry Andric    (ins GPR:$rx, GPR:$ry, CARRY:$cin), "subc32", []>;
502fe6060f1SDimitry Andric
503349cc55cSDimitry Andric  def INCF32 : I_5_ZX<0x3, 0x1, "incf32", uimm5, []>;
504349cc55cSDimitry Andric  def INCT32 : I_5_ZX<0x3, 0x2, "inct32", uimm5, []>;
505349cc55cSDimitry Andric  def DECF32 : I_5_ZX<0x3, 0x4, "decf32", uimm5, []>;
506349cc55cSDimitry Andric  def DECT32 : I_5_ZX<0x3, 0x8, "dect32", uimm5, []>;
507349cc55cSDimitry Andric}
508349cc55cSDimitry Andric
509349cc55cSDimitry Andriclet Predicates = [iHas2E3] in {
510e8d8bef9SDimitry Andric  def DIVS32 : R_YXZ_SP_F1<0x20, 0x2,
511e8d8bef9SDimitry Andric    BinOpFrag<(sdiv node:$LHS, node:$RHS)>, "divs32">;
512e8d8bef9SDimitry Andric  def DIVU32 : R_YXZ_SP_F1<0x20, 0x1,
513e8d8bef9SDimitry Andric    BinOpFrag<(udiv node:$LHS, node:$RHS)>, "divu32">;
514e8d8bef9SDimitry Andric
515fe6060f1SDimitry Andric  def DECGT32 : I_5_XZ<0x4, 0x1, "decgt32",
516fe6060f1SDimitry Andric    (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, uimm5:$imm5), []>;
517fe6060f1SDimitry Andric  def DECLT32 : I_5_XZ<0x4, 0x2, "declt32",
518fe6060f1SDimitry Andric    (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, uimm5:$imm5), []>;
519fe6060f1SDimitry Andric  def DECNE32 : I_5_XZ<0x4, 0x4, "decne32",
520fe6060f1SDimitry Andric    (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, uimm5:$imm5), []>;
521fe6060f1SDimitry Andric
522349cc55cSDimitry Andric  def SEXT32 : I_5_XZ_U<0x16, (outs GPR:$rz), (ins GPR:$rx, uimm5:$msb, uimm5:$lsb), "sext32", []>;
523349cc55cSDimitry Andric  let isCodeGenOnly = 1 in {
524349cc55cSDimitry Andric  def SEXTB32 : I_5_XZ_US<0x16, 0, 7, "sextb32", sext_inreg, i8>;
525349cc55cSDimitry Andric  def SEXTH32 : I_5_XZ_US<0x16, 0, 15, "sexth32", sext_inreg, i16>;
526349cc55cSDimitry Andric  def ZEXTB32 : I_5_XZ_UZ<0x15, 0, 7, "zextb32", 255>;
527349cc55cSDimitry Andric  def ZEXTH32 : I_5_XZ_UZ<0x15, 0, 15, "zexth32", 65535>;
528349cc55cSDimitry Andric  }
529349cc55cSDimitry Andric  def ZEXT32 : I_5_XZ_U<0x15, (outs GPR:$rz), (ins GPR:$rx, uimm5:$msb, uimm5:$lsb), "zext32",[]>;
530349cc55cSDimitry Andric
531349cc55cSDimitry Andric  let Constraints = "$rZ = $rz" in
532349cc55cSDimitry Andric  def INS32 : I_5_XZ_INS<0b010111, (outs GPR:$rz), (ins GPR:$rZ, GPR:$rx, uimm5_msb_size:$msb, uimm5:$lsb), "ins32", []>;
533349cc55cSDimitry Andric}
534349cc55cSDimitry Andric
535349cc55cSDimitry Andriclet Predicates = [iHas3E3r1] in {
536349cc55cSDimitry Andricdef MULTS32 : R_YXZ<0x3e, 0x20, 0x10, (outs GPRPair:$rz),
537349cc55cSDimitry Andric    (ins GPR:$rx, GPR:$ry), "mul.s32", []>;
538349cc55cSDimitry Andricdef MULTU32 : R_YXZ<0x3e, 0x20, 0x00, (outs GPRPair:$rz),
539349cc55cSDimitry Andric    (ins GPR:$rx, GPR:$ry), "mul.u32", []>;
540349cc55cSDimitry Andric
541349cc55cSDimitry Andriclet Constraints = "$rZ = $rz" in {
542349cc55cSDimitry Andricdef MULATS32 : R_YXZ<0x3e, 0x20, 0x14, (outs GPRPair:$rZ),
543349cc55cSDimitry Andric    (ins GPRPair:$rz, GPR:$rx, GPR:$ry), "mula.s32", []>;
544349cc55cSDimitry Andricdef MULATU32 : R_YXZ<0x3e, 0x20, 0x04, (outs GPRPair:$rZ),
545349cc55cSDimitry Andric    (ins GPRPair:$rz, GPR:$rx, GPR:$ry), "mula.u32", []>;
546349cc55cSDimitry Andric}
547349cc55cSDimitry Andric}
548349cc55cSDimitry Andric
549349cc55cSDimitry Andricdef MULSH32 : R_YXZ<0x31, 0b100100, 0b00001, (outs GPR:$rz),
550349cc55cSDimitry Andric    (ins GPR:$rx, GPR:$ry), "mulsh32", []>;
551fe6060f1SDimitry Andric
552fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
553fe6060f1SDimitry Andric// Load & Store instructions.
554fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
555fe6060f1SDimitry Andric
556fe6060f1SDimitry Andricdef LD32B : I_LD<AddrMode32B, 0x0, "ld32.b", uimm12>;
557fe6060f1SDimitry Andricdef LD32H : I_LD<AddrMode32H, 0x1, "ld32.h", uimm12_1>;
558fe6060f1SDimitry Andricdef LD32W : I_LD<AddrMode32WD, 0x2, "ld32.w", uimm12_2>;
559fe6060f1SDimitry Andric
560349cc55cSDimitry Andriclet OutOperandList = (outs GPRPair:$rz) in
561349cc55cSDimitry Andricdef LD32D : I_LD<AddrMode32WD, 0x3, "ld32.d", uimm12_2>;
562fe6060f1SDimitry Andric
563349cc55cSDimitry Andriclet Predicates = [iHasE2] in {
564fe6060f1SDimitry Andric  def LD32BS : I_LD<AddrMode32B, 0x4, "ld32.bs", uimm12>;
565fe6060f1SDimitry Andric  def LD32HS : I_LD<AddrMode32H, 0x5, "ld32.hs", uimm12_1>;
566fe6060f1SDimitry Andric
567349cc55cSDimitry Andric  def LDM32 : I_5_YX<0b110100, 0b000111,
568349cc55cSDimitry Andric    (outs), (ins GPR:$rx, regseq:$regs, variable_ops), "ldm32\t$regs, (${rx})", []>;
569349cc55cSDimitry Andric  def STM32 : I_5_YX<0b110101, 0b000111,
570349cc55cSDimitry Andric    (outs), (ins GPR:$rx, regseq:$regs, variable_ops), "stm32\t$regs, (${rx})", []>;
571fe6060f1SDimitry Andric
572349cc55cSDimitry Andric  let Size = 4, isCodeGenOnly = 0 in {
573349cc55cSDimitry Andric  def LDQ32 : CSKYPseudo<(outs), (ins GPR:$rx, regseq:$regs, variable_ops),
574349cc55cSDimitry Andric                             "ldq32\t$regs, (${rx})", []>;
575349cc55cSDimitry Andric  def STQ32 : CSKYPseudo<(outs), (ins GPR:$rx, regseq:$regs, variable_ops),
576349cc55cSDimitry Andric                             "stq32\t$regs, (${rx})", []>;
577349cc55cSDimitry Andric  }
578349cc55cSDimitry Andric
579349cc55cSDimitry Andric}
580fe6060f1SDimitry Andric
581fe6060f1SDimitry Andricdef ST32B : I_ST<AddrMode32B, 0x0, "st32.b", uimm12>;
582fe6060f1SDimitry Andricdef ST32H : I_ST<AddrMode32H, 0x1, "st32.h", uimm12_1>;
583fe6060f1SDimitry Andricdef ST32W : I_ST<AddrMode32WD, 0x2, "st32.w", uimm12_2>;
584fe6060f1SDimitry Andric
585349cc55cSDimitry Andriclet InOperandList = (ins GPRPair:$rz, GPR:$rx, uimm12_2:$imm12 ) in
586349cc55cSDimitry Andricdef ST32D : I_ST<AddrMode32WD, 0x3, "st32.d", uimm12_2>;
587fe6060f1SDimitry Andric
588349cc55cSDimitry Andriclet Predicates = [iHas2E3] in {
589fe6060f1SDimitry Andric  def LDR32B :  I_LDR<0x0, "ldr32.b">;
590fe6060f1SDimitry Andric  def LDR32BS :  I_LDR<0x4, "ldr32.bs">;
591fe6060f1SDimitry Andric  def LDR32H :  I_LDR<0x1, "ldr32.h">;
592fe6060f1SDimitry Andric  def LDR32HS :  I_LDR<0x5, "ldr32.hs">;
593fe6060f1SDimitry Andric  def LDR32W :  I_LDR<0x2, "ldr32.w">;
594fe6060f1SDimitry Andric  def STR32B :  I_STR<0x0, "str32.b">;
595fe6060f1SDimitry Andric  def STR32H :  I_STR<0x1, "str32.h">;
596fe6060f1SDimitry Andric  def STR32W :  I_STR<0x2, "str32.w">;
597349cc55cSDimitry Andric}
598fe6060f1SDimitry Andric
599349cc55cSDimitry Andric// Indicate that we're dumping the CR register, so we'll need to
600349cc55cSDimitry Andric// scavenge a register for it.
601349cc55cSDimitry Andriclet mayStore = 1 in {
602349cc55cSDimitry Andricdef SPILL_CARRY : CSKYPseudo<(outs), (ins CARRY:$cond, GPR:$rx, uimm12_2:$imm),
603349cc55cSDimitry Andric                             "!SPILL_CARRY $cond, $rx, $imm", []>;
604349cc55cSDimitry Andric}
605349cc55cSDimitry Andric
606349cc55cSDimitry Andric// Indicate that we're restoring the CR register (previously
607349cc55cSDimitry Andric// spilled), so we'll need to scavenge a register for it.
608349cc55cSDimitry Andriclet mayLoad = 1 in {
609349cc55cSDimitry Andricdef RESTORE_CARRY : CSKYPseudo<(outs CARRY:$cond), (ins GPR:$rx, uimm12_2:$imm),
610349cc55cSDimitry Andric                                "!RESTORE_CARRY $cond, $rx, $imm", []>;
611349cc55cSDimitry Andric}
612349cc55cSDimitry Andric
613349cc55cSDimitry Andriclet mayLoad = 1 in {
614349cc55cSDimitry Andricdef STORE_PAIR : CSKYPseudo<(outs), (ins GPRPair:$rz, GPR:$rx, uimm12_2:$imm),
615349cc55cSDimitry Andric                            "!STORE_PAIR $rz, $rx, $imm", []>;
616349cc55cSDimitry Andric}
617349cc55cSDimitry Andric
618349cc55cSDimitry Andriclet mayLoad = 1 in {
619349cc55cSDimitry Andricdef LOAD_PAIR : CSKYPseudo<(outs GPRPair:$rz), (ins GPR:$rx, uimm12_2:$imm),
620349cc55cSDimitry Andric                            "!LOAD_PAIR $rz, $rx, $imm", []>;
621349cc55cSDimitry Andric}
622fe6060f1SDimitry Andric
623fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
624fe6060f1SDimitry Andric// Compare instructions.
625fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
626349cc55cSDimitry Andriclet Predicates = [iHasE2] in {
627fe6060f1SDimitry Andric  def CMPNEI32 : I_16_X<0x1A, "cmpnei32", uimm16>;
628fe6060f1SDimitry Andric  def CMPHSI32 : I_16_X<0x18, "cmphsi32", oimm16>;
629fe6060f1SDimitry Andric  def CMPLTI32 : I_16_X<0x19, "cmplti32", oimm16>;
630349cc55cSDimitry Andric  def CMPLEI32 : CSKYPseudo<(outs CARRY:$ca), (ins GPR:$rx, uimm16:$imm16),
631349cc55cSDimitry Andric    "cmplei32\t$rx, $imm16", []>;
632349cc55cSDimitry Andric}
633349cc55cSDimitry Andriclet Predicates = [iHas2E3] in {
634fe6060f1SDimitry Andric  def CMPNE32 : R_YX<0x1, 0x4, "cmpne32">;
635fe6060f1SDimitry Andric  def CMPHS32 : R_YX<0x1, 0x1, "cmphs32">;
636fe6060f1SDimitry Andric  def CMPLT32 : R_YX<0x1, 0x2, "cmplt32">;
637fe6060f1SDimitry Andric
638349cc55cSDimitry Andric  def SETC32 : CSKY32Inst<AddrModeNone, 0x31,
639349cc55cSDimitry Andric    (outs CARRY:$ca), (ins), "setc32", []> {
640349cc55cSDimitry Andric    let Inst{25 - 21} = 0; //rx
641349cc55cSDimitry Andric    let Inst{20 - 16} = 0; //ry
642349cc55cSDimitry Andric    let Inst{15 - 10} = 0x1;
643349cc55cSDimitry Andric    let Inst{9 - 5} = 0x1;
644349cc55cSDimitry Andric    let Inst{4 - 0} = 0;
645349cc55cSDimitry Andric    let isCompare = 1;
646349cc55cSDimitry Andric  }
647349cc55cSDimitry Andric  def CLRC32 : CSKY32Inst<AddrModeNone, 0x31,
648349cc55cSDimitry Andric    (outs CARRY:$ca), (ins), "clrc32", []> {
649349cc55cSDimitry Andric    let Inst{25 - 21} = 0; //rx
650349cc55cSDimitry Andric    let Inst{20 - 16} = 0; //ry
651349cc55cSDimitry Andric    let Inst{15 - 10} = 0x1;
652349cc55cSDimitry Andric    let Inst{9 - 5} = 0x4;
653349cc55cSDimitry Andric    let Inst{4 - 0} = 0;
654349cc55cSDimitry Andric    let isCompare = 1;
655349cc55cSDimitry Andric  }
656349cc55cSDimitry Andric
657349cc55cSDimitry Andric  def TST32 : R_YX<0x8, 0x4, "tst32">;
658349cc55cSDimitry Andric  def TSTNBZ32 : R_X<0x8, 0x8,
659349cc55cSDimitry Andric    (outs CARRY:$ca), (ins GPR:$rx), "tstnbz32", []>;
660349cc55cSDimitry Andric}
661fe6060f1SDimitry Andric
662fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
663fe6060f1SDimitry Andric// Data move instructions.
664fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
665fe6060f1SDimitry Andric
666349cc55cSDimitry Andriclet Predicates= [iHasE2] in {
667349cc55cSDimitry Andric  let isCodeGenOnly = 1 in {
668fe6060f1SDimitry Andric  def MOVT32 : R_ZX<0x3, 0x2, "movt32", []>;
669fe6060f1SDimitry Andric  def MOVF32 : R_ZX<0x3, 0x1, "movf32", []>;
670349cc55cSDimitry Andric  }
671fe6060f1SDimitry Andric  def MOVI32 : I_16_MOV<0x10, "movi32", uimm16>;
672349cc55cSDimitry Andric  let Size = 4, isCodeGenOnly = 0 in
673349cc55cSDimitry Andric  def BGENI : CSKYPseudo<(outs GPR:$dst), (ins uimm5:$imm), "bgeni\t$dst, $imm", []>;
674349cc55cSDimitry Andric  def : InstAlias<"bgeni16 $dst, $imm", (BGENI GPR:$dst, uimm5:$imm)>;
675349cc55cSDimitry Andric  def : InstAlias<"bgeni32 $dst, $imm", (BGENI GPR:$dst, uimm5:$imm)>;
676fe6060f1SDimitry Andric  def MOVIH32 : I_16_MOV<0x11, "movih32", uimm16_16_xform>;
677fe6060f1SDimitry Andric  def MVC32 : R_Z_1<0x1, 0x8, "mvc32">;
678349cc55cSDimitry Andric  let isCodeGenOnly = 1 in
679fe6060f1SDimitry Andric  def MOV32 : R_XZ<0x12, 0x1, "mov32">;
680fe6060f1SDimitry Andric
681349cc55cSDimitry Andric  let usesCustomInserter = 1 in
682349cc55cSDimitry Andric  def ISEL32 : CSKYPseudo<(outs GPR:$dst), (ins CARRY:$cond, GPR:$src1, GPR:$src2),
683349cc55cSDimitry Andric    "!isel32\t$dst, $src1, src2", [(set GPR:$dst, (select CARRY:$cond, GPR:$src1, GPR:$src2))]>;
684349cc55cSDimitry Andric}
685fe6060f1SDimitry Andric
686349cc55cSDimitry Andriclet Predicates = [iHas2E3] in {
687fe6060f1SDimitry Andric  def MVCV32 : R_Z_1<0x1, 0x10, "mvcv32">;
688fe6060f1SDimitry Andric  def CLRF32 : R_Z_2<0xB, 0x1, "clrf32", []>;
689fe6060f1SDimitry Andric  def CLRT32 : R_Z_2<0xB, 0x2, "clrt32", []>;
690349cc55cSDimitry Andric}
691fe6060f1SDimitry Andric
692fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
693fe6060f1SDimitry Andric// Branch and call instructions.
694fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
695fe6060f1SDimitry Andric
696fe6060f1SDimitry Andriclet isBranch = 1, isTerminator = 1 in {
697fe6060f1SDimitry Andric  let isBarrier = 1, isPredicable = 1 in
698fe6060f1SDimitry Andric    def BR32 : I_16_L<0x0, (outs), (ins br_symbol:$imm16), "br32\t$imm16",
699fe6060f1SDimitry Andric                     [(br bb:$imm16)]>;
700fe6060f1SDimitry Andric
701fe6060f1SDimitry Andric  def BT32 : I_16_L<0x3, (outs), (ins CARRY:$ca, br_symbol:$imm16),
702349cc55cSDimitry Andric    "bt32\t$imm16", [(brcond CARRY:$ca, bb:$imm16)]>, Requires<[iHasE2]>;
703fe6060f1SDimitry Andric  def BF32 : I_16_L<0x2, (outs), (ins CARRY:$ca, br_symbol:$imm16),
704349cc55cSDimitry Andric    "bf32\t$imm16", []>, Requires<[iHasE2]>;
705fe6060f1SDimitry Andric}
706fe6060f1SDimitry Andric
707349cc55cSDimitry Andriclet Predicates = [iHas2E3] in {
708fe6060f1SDimitry Andric  def BEZ32 : I_16_X_L<0x8, "bez32", br_symbol>;
709fe6060f1SDimitry Andric  def BNEZ32 : I_16_X_L<0x9, "bnez32", br_symbol>;
710fe6060f1SDimitry Andric  def BHZ32 : I_16_X_L<0xA, "bhz32", br_symbol>;
711fe6060f1SDimitry Andric  def BLSZ32 : I_16_X_L<0xB, "blsz32", br_symbol>;
712fe6060f1SDimitry Andric  def BLZ32 : I_16_X_L<0xC, "blz32", br_symbol>;
713fe6060f1SDimitry Andric  def BHSZ32 : I_16_X_L<0xD, "bhsz32", br_symbol>;
714fe6060f1SDimitry Andric
715fe6060f1SDimitry Andric  let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
716fe6060f1SDimitry Andric    def JMP32 : I_16_JX<0x6, "jmp32", [(brind GPR:$rx)]>; // jmp to register
717fe6060f1SDimitry Andric    def JMPI32 : I_16_L<0x16, (outs), (ins constpool_symbol:$imm16),
718fe6060f1SDimitry Andric                   "jmpi32\t$imm16", []>;
719fe6060f1SDimitry Andric  }
720fe6060f1SDimitry Andric
721fe6060f1SDimitry Andric  let isCall = 1, Defs = [ R15 ] in
722fe6060f1SDimitry Andric    def JSR32 : I_16_JX<0x7, "jsr32", []>;
723fe6060f1SDimitry Andric
724fe6060f1SDimitry Andric  let isCall = 1, Defs = [ R15 ] , mayLoad = 1 in
725fe6060f1SDimitry Andric    def JSRI32: I_16_L<0x17, (outs),
726fe6060f1SDimitry Andric      (ins constpool_symbol:$imm16), "jsri32\t$imm16", []>;
727349cc55cSDimitry Andric}
728fe6060f1SDimitry Andric
729349cc55cSDimitry Andricdef BNEZAD32 : CSKY32Inst<AddrModeNone, 0x3a,
730349cc55cSDimitry Andric  (outs GPR:$rx_u), (ins GPR:$rx, br_symbol:$imm16), "bnezad32\t$rx, $imm16", []> {
731349cc55cSDimitry Andric  bits<5> rx;
732349cc55cSDimitry Andric  bits<16> imm16;
733349cc55cSDimitry Andric  let Inst{25 - 21} = 0x1;
734349cc55cSDimitry Andric  let Inst{20 - 16} = rx;
735349cc55cSDimitry Andric  let Inst{15 - 0} = imm16;
736349cc55cSDimitry Andric  let isBranch = 1;
737349cc55cSDimitry Andric  let isTerminator = 1;
738349cc55cSDimitry Andric  let Constraints = "$rx_u = $rx";
739349cc55cSDimitry Andric  let Predicates = [iHas2E3, iHas10E60];
740349cc55cSDimitry Andric}
741fe6060f1SDimitry Andric
742fe6060f1SDimitry Andricdef BSR32 : J<0x38, (outs), (ins call_symbol:$offset), "bsr32", []>;
743fe6060f1SDimitry Andric
744349cc55cSDimitry Andricdef : InstAlias<"bsr $dst", (BSR32 call_symbol:$dst)>;
745349cc55cSDimitry Andric
746fe6060f1SDimitry Andricdef BSR32_BR : J<0x38, (outs), (ins call_symbol:$offset), "bsr32", []>{
747fe6060f1SDimitry Andric  let isCodeGenOnly = 1;
748fe6060f1SDimitry Andric  let isBranch = 1;
749fe6060f1SDimitry Andric  let isTerminator = 1;
750fe6060f1SDimitry Andric  let isBarrier = 1;
751fe6060f1SDimitry Andric  let isPredicable = 1;
752fe6060f1SDimitry Andric  let Defs = [ R15 ];
753fe6060f1SDimitry Andric}
754fe6060f1SDimitry Andric
755fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
756fe6060f1SDimitry Andric// Symbol address instructions.
757fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
758fe6060f1SDimitry Andric
759349cc55cSDimitry Andricdef data_symbol_b : data_symbol<"CSKY::fixup_csky_doffset_imm18", 0>;
760349cc55cSDimitry Andricdef data_symbol_h : data_symbol<"CSKY::fixup_csky_doffset_imm18_scale2", 1>;
761349cc55cSDimitry Andricdef data_symbol_w : data_symbol<"CSKY::fixup_csky_doffset_imm18_scale4", 2> {
762349cc55cSDimitry Andric  let ParserMatchClass = DataAsmClass;
763349cc55cSDimitry Andric}
764349cc55cSDimitry Andric
765349cc55cSDimitry Andriclet Predicates = [iHas2E3] in {
766349cc55cSDimitry Andric
767fe6060f1SDimitry Andricdef GRS32 : I_18_Z_L<0x3, "grs32\t$rz, $offset",
768fe6060f1SDimitry Andric                    (outs GPR:$rz), (ins bare_symbol:$offset), []>;
769349cc55cSDimitry Andricdef : InstAlias<"grs\t$rz, $offset", (GRS32 GPR:$rz, bare_symbol:$offset)>;
770349cc55cSDimitry Andric
771349cc55cSDimitry Andriclet Uses = [R28] in {
772349cc55cSDimitry Andricdef LRS32B : I_18_Z_L<0x0, "lrs32.b\t$rz, $offset",
773349cc55cSDimitry Andric                    (outs GPR:$rz), (ins data_symbol_b:$offset), []>;
774349cc55cSDimitry Andricdef LRS32H : I_18_Z_L<0x1, "lrs32.h\t$rz, $offset",
775349cc55cSDimitry Andric                    (outs GPR:$rz), (ins data_symbol_h:$offset), []>;
776349cc55cSDimitry Andricdef LRS32W : I_18_Z_L<0x2, "lrs32.w\t$rz, $offset",
777349cc55cSDimitry Andric                    (outs GPR:$rz), (ins data_symbol_w:$offset), []>;
778349cc55cSDimitry Andricdef SRS32B : I_18_Z_L<0x4, "srs32.b\t$rz, $offset",
779349cc55cSDimitry Andric                    (outs), (ins GPR:$rz, data_symbol_b:$offset), []>;
780349cc55cSDimitry Andricdef SRS32H : I_18_Z_L<0x5, "srs32.h\t$rz, $offset",
781349cc55cSDimitry Andric                    (outs), (ins GPR:$rz, data_symbol_h:$offset), []>;
782349cc55cSDimitry Andricdef SRS32W : I_18_Z_L<0x6, "srs32.w\t$rz, $offset",
783349cc55cSDimitry Andric                    (outs), (ins GPR:$rz, data_symbol_w:$offset), []>;
784349cc55cSDimitry Andric}
785349cc55cSDimitry Andric
786349cc55cSDimitry Andricdef PUSH32 : I_12_PP<0b11111, 0b00000, (outs), (ins reglist:$regs, variable_ops), "push32 $regs">;
787349cc55cSDimitry Andric
788349cc55cSDimitry Andriclet Uses = [R14, R15], isReturn = 1, isTerminator = 1, isBarrier = 1 in
789349cc55cSDimitry Andricdef POP32 : I_12_PP<0b11110, 0b00000, (outs), (ins reglist:$regs, variable_ops), "pop32 $regs">;
790349cc55cSDimitry Andric
791349cc55cSDimitry Andric}
792fe6060f1SDimitry Andric
793fe6060f1SDimitry Andriclet mayLoad = 1, mayStore = 0 in {
794fe6060f1SDimitry Andricdef LRW32 : I_16_Z_L<0x14, "lrw32", (ins constpool_symbol:$imm16), []>;
795fe6060f1SDimitry Andriclet isCodeGenOnly = 1 in
796349cc55cSDimitry Andricdef LRW32_Gen : I_16_Z_L<0x14, "lrw32", (ins bare_symbol:$src1, constpool_symbol:$imm16), []>;
797fe6060f1SDimitry Andric}
798fe6060f1SDimitry Andric
799349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
800349cc55cSDimitry Andric// Atomic and fence instructions.
801349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
802349cc55cSDimitry Andric
803349cc55cSDimitry Andriclet Predicates = [iHasMP1E2] in {
804349cc55cSDimitry Andric  def BRWARW : BAR<0b01111, "bar.brwarw", 0>;
805349cc55cSDimitry Andric  def BRWARWS : BAR<0b01111, "bar.brwarws", 1>;
806349cc55cSDimitry Andric  def BRARW : BAR<0b00111, "bar.brarw", 0>;
807349cc55cSDimitry Andric  def BRARWS : BAR<0b00111, "bar.brarws", 1>;
808349cc55cSDimitry Andric  def BRWAW : BAR<0b01110, "bar.brwaw", 0>;
809349cc55cSDimitry Andric  def BRWAWS : BAR<0b01110, "bar.brwaws", 1>;
810349cc55cSDimitry Andric  def BRAR : BAR<0b00101, "bar.brar", 0>;
811349cc55cSDimitry Andric  def BRARS : BAR<0b00101, "bar.brars", 1>;
812349cc55cSDimitry Andric  def BWAW : BAR<0b01010, "bar.bwaw", 0>;
813349cc55cSDimitry Andric  def BWAWS : BAR<0b01010, "bar.bwaws", 1>;
814349cc55cSDimitry Andric
815349cc55cSDimitry Andric  def LDEX32W : I_LD<AddrMode32WD, 0x7, "ldex32.w", uimm12_2>;
816349cc55cSDimitry Andric  let Constraints = "$rd = $rz" in
817349cc55cSDimitry Andric    def STEX32W : I_LDST<AddrMode32WD, 0x37, 7,
818349cc55cSDimitry Andric      (outs GPR:$rd), (ins GPR:$rz, GPR:$rx, uimm12_2:$imm12), "stex32.w", []>;
819349cc55cSDimitry Andric}
820349cc55cSDimitry Andric
821349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
822349cc55cSDimitry Andric// Other operation instructions.
823349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
824349cc55cSDimitry Andric
825349cc55cSDimitry Andriclet Predicates = [iHas2E3] in {
826349cc55cSDimitry Andric  def BREV32 : R_XZ<0x18, 0x10, "brev32">;
827349cc55cSDimitry Andric  def ABS32 : R_XZ<0x0, 0x10, "abs32">;
828349cc55cSDimitry Andric  def BGENR32 : R_XZ<0x14, 0x2, "bgenr32">;
829349cc55cSDimitry Andric}
830349cc55cSDimitry Andric
831349cc55cSDimitry Andriclet Predicates = [iHasE2] in {
832349cc55cSDimitry Andric  def REVB32 : R_XZ<0x18, 0x4, "revb32">;
833349cc55cSDimitry Andric  def REVH32 : R_XZ<0x18, 0x8, "revh32">;
834349cc55cSDimitry Andric  def FF0 : R_XZ<0x1F, 0x1, "ff0.32">;
835349cc55cSDimitry Andric  def FF1 : R_XZ<0x1F, 0x2, "ff1.32">;
836349cc55cSDimitry Andric  def XTRB0 : R_XZ<0x1C, 0x1, "xtrb0.32">;
837349cc55cSDimitry Andric  def XTRB1 : R_XZ<0x1C, 0x2, "xtrb1.32">;
838349cc55cSDimitry Andric  def XTRB2 : R_XZ<0x1C, 0x4, "xtrb2.32">;
839349cc55cSDimitry Andric  def XTRB3 : R_XZ<0x1C, 0x8, "xtrb3.32">;
840349cc55cSDimitry Andric  def BTSTI32 : I_5_X<0x0A, 0x4, "btsti32", uimm5, []>;
841349cc55cSDimitry Andric  def BCLRI32 : I_5_XZ<0xA, 0x1, "bclri32",
842349cc55cSDimitry Andric  (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), []>;
843349cc55cSDimitry Andric  def BSETI32 : I_5_XZ<0xA, 0x2, "bseti32",
844349cc55cSDimitry Andric  (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), []>;
845349cc55cSDimitry Andric}
846349cc55cSDimitry Andric
847349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
848349cc55cSDimitry Andric// Special instructions.
849349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
850349cc55cSDimitry Andric
851349cc55cSDimitry Andricdef MFFCR : CSKY32Inst<AddrModeNone, 0x30,
852349cc55cSDimitry Andric  (outs GPR:$rx), (ins), "mfcr\t$rx, fcr", []> {
853349cc55cSDimitry Andric  bits<5> rx;
854349cc55cSDimitry Andric
855349cc55cSDimitry Andric  let Inst{25 - 21} = 0b00010;
856349cc55cSDimitry Andric  let Inst{20 - 16} = 0b00001;
857349cc55cSDimitry Andric  let Inst{15 - 10} = 0b011000;
858349cc55cSDimitry Andric  let Inst{9 - 5} = 0b00001;
859349cc55cSDimitry Andric  let Inst{4 - 0} = rx;
860349cc55cSDimitry Andric  let hasSideEffects = 1;
861349cc55cSDimitry Andric  let isCodeGenOnly = 1;
862349cc55cSDimitry Andric}
863349cc55cSDimitry Andric
864349cc55cSDimitry Andricdef MTFCR : CSKY32Inst<AddrModeNone, 0x30,
865349cc55cSDimitry Andric  (outs), (ins GPR:$rx), "mtcr\t$rx, fcr", []> {
866349cc55cSDimitry Andric  bits<5> rx;
867349cc55cSDimitry Andric
868349cc55cSDimitry Andric  let Inst{25 - 21} = 0b00010;
869349cc55cSDimitry Andric  let Inst{20 - 16} = rx;
870349cc55cSDimitry Andric  let Inst{15 - 10} = 0b011001;
871349cc55cSDimitry Andric  let Inst{9 - 5} = 0b00001;
872349cc55cSDimitry Andric  let Inst{4 - 0} = 0b00001;
873349cc55cSDimitry Andric  let hasSideEffects = 1;
874349cc55cSDimitry Andric  let isCodeGenOnly = 1;
875349cc55cSDimitry Andric}
876349cc55cSDimitry Andric
877349cc55cSDimitry Andricdef SYNC32 : I_5_IMM5<0x30, 0b000001, 0b00001, "sync32", uimm5, []>;
878349cc55cSDimitry Andric
879349cc55cSDimitry Andricdef SYNC0_32 : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins),
880349cc55cSDimitry Andric                 "sync32", []> {
881349cc55cSDimitry Andric  let Inst{25 - 21} = 0;
882349cc55cSDimitry Andric  let Inst{20 - 16} = 0;
883349cc55cSDimitry Andric  let Inst{15 - 10} = 0b000001;
884349cc55cSDimitry Andric  let Inst{9 - 5} = 0b00001;
885349cc55cSDimitry Andric  let Inst{4 - 0} = 0;
886349cc55cSDimitry Andric}
887349cc55cSDimitry Andric
888349cc55cSDimitry Andricdef SYNC_32_I : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins),
889349cc55cSDimitry Andric                 "sync32.i", []> {
890349cc55cSDimitry Andric  let Inst{25 - 21} = 1;
891349cc55cSDimitry Andric  let Inst{20 - 16} = 0;
892349cc55cSDimitry Andric  let Inst{15 - 10} = 0b000001;
893349cc55cSDimitry Andric  let Inst{9 - 5} = 0b00001;
894349cc55cSDimitry Andric  let Inst{4 - 0} = 0;
895349cc55cSDimitry Andric}
896349cc55cSDimitry Andric
897349cc55cSDimitry Andricdef SYNC_32_S : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins),
898349cc55cSDimitry Andric                 "sync32.s", []> {
899349cc55cSDimitry Andric  let Inst{25 - 21} = 0b10000;
900349cc55cSDimitry Andric  let Inst{20 - 16} = 0;
901349cc55cSDimitry Andric  let Inst{15 - 10} = 0b000001;
902349cc55cSDimitry Andric  let Inst{9 - 5} = 0b00001;
903349cc55cSDimitry Andric  let Inst{4 - 0} = 0;
904349cc55cSDimitry Andric}
905349cc55cSDimitry Andric
906349cc55cSDimitry Andricdef SYNC_32_IS : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins),
907349cc55cSDimitry Andric                 "sync32.is", []> {
908349cc55cSDimitry Andric  let Inst{25 - 21} = 0b10001;
909349cc55cSDimitry Andric  let Inst{20 - 16} = 0;
910349cc55cSDimitry Andric  let Inst{15 - 10} = 0b000001;
911349cc55cSDimitry Andric  let Inst{9 - 5} = 0b00001;
912349cc55cSDimitry Andric  let Inst{4 - 0} = 0;
913349cc55cSDimitry Andric}
914349cc55cSDimitry Andric
915349cc55cSDimitry Andriclet Predicates = [iHas2E3] in {
916349cc55cSDimitry Andric  def RFI32 : I_5_XZ_PRIVI<0x11, 0x1, "rfi32">;
917349cc55cSDimitry Andric  def SCE32 : I_5_IMM5<0x30, 0b000110, 0b00001, "sce32", uimm4, []>;
918349cc55cSDimitry Andric}
919349cc55cSDimitry Andriclet Predicates = [HasExtendLrw] in
920349cc55cSDimitry Andricdef IDLY32 : I_5_IMM5<0x30, 0b000111, 0b00001, "idly32", imm5_idly, []>;
921349cc55cSDimitry Andricdef STOP32 : I_5_XZ_PRIVI<0x12, 0x1, "stop32">;
922349cc55cSDimitry Andricdef WAIT32 : I_5_XZ_PRIVI<0x13, 0x1, "wait32">;
923349cc55cSDimitry Andricdef DOZE32 : I_5_XZ_PRIVI<0x14, 0x1, "doze32">;
924349cc55cSDimitry Andricdef WE32 : I_5_XZ_PRIVI<0b010101, 0x1, "we32">;
925349cc55cSDimitry Andricdef SE32 : I_5_XZ_PRIVI<0b010110, 0x1, "se32">;
926349cc55cSDimitry Andricdef WSC32 : I_5_XZ_PRIVI<0b001111, 0x1, "wsc32">;
927349cc55cSDimitry Andric
928349cc55cSDimitry Andricdef CPOP32 : I_CPOP<(outs), (ins uimm5:$cpid, uimm20:$usdef), "cpop32 <$cpid, ${usdef}>">;
929349cc55cSDimitry Andricdef CPRC32 : I_CP<0b0100, (outs CARRY:$ca), (ins uimm5:$cpid, uimm12:$usdef), "cprc32 <$cpid, ${usdef}>">;
930349cc55cSDimitry Andricdef CPRCR32 : I_CP_Z<0b0010, (outs GPR:$rz), (ins uimm5:$cpid, uimm12:$usdef), "cprcr32 $rz, <$cpid, ${usdef}>">;
931349cc55cSDimitry Andricdef CPRGR32 : I_CP_Z<0b0000, (outs GPR:$rz), (ins uimm5:$cpid, uimm12:$usdef), "cprgr32 $rz, <$cpid, ${usdef}>">;
932349cc55cSDimitry Andricdef CPWCR32 : I_CP_Z<0b0011, (outs), (ins GPR:$rz, uimm5:$cpid, uimm12:$usdef), "cpwcr32 $rz, <$cpid, ${usdef}>">;
933349cc55cSDimitry Andricdef CPWGR32 : I_CP_Z<0b0001, (outs), (ins GPR:$rz, uimm5:$cpid, uimm12:$usdef), "cpwgr32 $rz, <$cpid, ${usdef}>">;
934349cc55cSDimitry Andric
935349cc55cSDimitry Andriclet Predicates = [iHas3r2E3r3] in {
936349cc55cSDimitry Andricdef DCACHE_IALL32 : I_5_CACHE<0b100101, 0b01000, "dcache32.iall">;
937349cc55cSDimitry Andricdef DCACHE_CALL32 : I_5_CACHE<0b100101, 0b00100, "dcache32.call">;
938349cc55cSDimitry Andricdef DCACHE_CIALL32 : I_5_CACHE<0b100101, 0b01100, "dcache32.ciall">;
939349cc55cSDimitry Andricdef DCACHE_IVA32 : I_5_X_CACHE<0b100101, 0b01011, "dcache32.iva">;
940349cc55cSDimitry Andricdef DCACHE_ISW32: I_5_X_CACHE<0b100101, 0b01010, "dcache32.isw">;
941349cc55cSDimitry Andricdef DCACHE_CVA32 : I_5_X_CACHE<0b100101, 0b00111, "dcache32.cva">;
942349cc55cSDimitry Andricdef DCACHE_CVAL32 : I_5_X_CACHE<0b100101, 0b10111, "dcache32.cval1">;
943349cc55cSDimitry Andricdef DCACHE_CSW32 : I_5_X_CACHE<0b100101, 0b00110, "dcache32.csw">;
944349cc55cSDimitry Andricdef DCACHE_CIVA32 : I_5_X_CACHE<0b100101, 0b01111, "dcache32.civa">;
945349cc55cSDimitry Andricdef DCACHE_CISW32 : I_5_X_CACHE<0b100101, 0b01110, "dcache32.cisw">;
946349cc55cSDimitry Andric
947349cc55cSDimitry Andricdef ICACHE_IALL32 : I_5_CACHE<0b100100, 0b01000, "icache32.iall">;
948349cc55cSDimitry Andricdef ICACHE_IALLS32 : I_5_CACHE<0b100100, 0b11000, "icache32.ialls">;
949349cc55cSDimitry Andricdef ICACHE_IVA32 : I_5_X_CACHE<0b100100, 0b01011, "icache32.iva">;
950349cc55cSDimitry Andric
951349cc55cSDimitry Andricdef TLBI_VAA32 : I_5_X_CACHE<0b100010, 0b00010, "tlbi32.vaa">;
952349cc55cSDimitry Andricdef TLBI_VAAS32 : I_5_X_CACHE<0b100010, 0b10010, "tlbi32.vaas">;
953349cc55cSDimitry Andricdef TLBI_ASID32 : I_5_X_CACHE<0b100010, 0b00001, "tlbi32.asid">;
954349cc55cSDimitry Andricdef TLBI_ASIDS32 : I_5_X_CACHE<0b100010, 0b10001, "tlbi32.asids">;
955349cc55cSDimitry Andricdef TLBI_VA32 : I_5_X_CACHE<0b100010, 0b00011, "tlbi32.va">;
956349cc55cSDimitry Andricdef TLBI_VAS32 : I_5_X_CACHE<0b100010, 0b10011, "tlbi32.vas">;
957349cc55cSDimitry Andricdef TLBI_ALL32 : I_5_CACHE<0b100010, 0b00000, "tlbi32.all">;
958349cc55cSDimitry Andricdef TLBI_ALLS32 : I_5_CACHE<0b100010, 0b10000, "tlbi32.alls">;
959349cc55cSDimitry Andric
960349cc55cSDimitry Andricdef L2CACHE_IALL : I_5_CACHE<0b100110, 0b01000, "l2cache.iall">;
961349cc55cSDimitry Andricdef L2CACHE_CALL : I_5_CACHE<0b100110, 0b00100, "l2cache.call">;
962349cc55cSDimitry Andricdef L2CACHE_CIALL : I_5_CACHE<0b100110, 0b01100, "l2cache.ciall">;
963349cc55cSDimitry Andric}
964349cc55cSDimitry Andric
965349cc55cSDimitry Andricdef PLDR32 :I_PLDR<AddrMode32WD, 0x36, 0b0110, (outs), (ins GPR:$rx, uimm12_2:$imm12), "pldr32", []>;
966349cc55cSDimitry Andricdef PLDW32 :I_PLDR<AddrMode32WD, 0x37, 0b0110, (outs), (ins GPR:$rx, uimm12_2:$imm12), "pldw32", []>;
967349cc55cSDimitry Andric
968349cc55cSDimitry Andricdef TRAP32 : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins uimm2:$imm2), "trap32 ${imm2}", []> {
969349cc55cSDimitry Andric  bits<2> imm2;
970349cc55cSDimitry Andric
971349cc55cSDimitry Andric  let Inst{25 - 21} = 0;
972349cc55cSDimitry Andric  let Inst{20 - 16} = 0;
973349cc55cSDimitry Andric  let Inst{15 - 12} = 0b0010;
974349cc55cSDimitry Andric  let Inst{11 - 10} = imm2;
975349cc55cSDimitry Andric  let Inst{9 - 5} = 0b00001;
976349cc55cSDimitry Andric  let Inst{4 - 0} = 0;
977349cc55cSDimitry Andric
978349cc55cSDimitry Andric}
979349cc55cSDimitry Andric
980*0eae32dcSDimitry Andric//===----------------------------------------------------------------------===//
981*0eae32dcSDimitry Andric// Instruction Patterns.
982*0eae32dcSDimitry Andric//===----------------------------------------------------------------------===//
983*0eae32dcSDimitry Andric
984*0eae32dcSDimitry Andric// Load & Store Patterns
985*0eae32dcSDimitry Andricmulticlass LdPat<PatFrag LoadOp, ImmLeaf imm_type, Instruction Inst, ValueType Type> {
986*0eae32dcSDimitry Andric  def : Pat<(Type (LoadOp GPR:$rs1)), (Inst GPR:$rs1, 0)>;
987*0eae32dcSDimitry Andric  def : Pat<(Type (LoadOp (i32 frameindex:$rs1))), (Inst (i32 (to_tframeindex tframeindex:$rs1)), 0)>;
988*0eae32dcSDimitry Andric  def : Pat<(Type (LoadOp (add GPR:$rs1, imm_type:$uimm))),
989*0eae32dcSDimitry Andric            (Inst GPR:$rs1, imm_type:$uimm)>;
990*0eae32dcSDimitry Andric  def : Pat<(Type (LoadOp (add frameindex:$rs1, imm_type:$uimm))),
991*0eae32dcSDimitry Andric            (Inst (i32 (to_tframeindex tframeindex:$rs1)), imm_type:$uimm)>;
992*0eae32dcSDimitry Andric  def : Pat<(Type (LoadOp (eqToAdd frameindex:$rs1, imm_type:$uimm))),
993*0eae32dcSDimitry Andric            (Inst (i32 (to_tframeindex tframeindex:$rs1)), imm_type:$uimm)>;
994*0eae32dcSDimitry Andric  def : Pat<(Type (LoadOp (add GPR:$rs1, tglobaladdr:$gd))),
995*0eae32dcSDimitry Andric            (Inst GPR:$rs1, tglobaladdr:$gd)>;
996*0eae32dcSDimitry Andric}
997*0eae32dcSDimitry Andric
998*0eae32dcSDimitry Andricdefm : LdPat<extloadi8, uimm12, LD32B, i32>;
999*0eae32dcSDimitry Andricdefm : LdPat<zextloadi8, uimm12, LD32B, i32>;
1000*0eae32dcSDimitry Andriclet Predicates = [iHasE2] in {
1001*0eae32dcSDimitry Andric  defm : LdPat<sextloadi8, uimm12, LD32BS, i32>;
1002*0eae32dcSDimitry Andric}
1003*0eae32dcSDimitry Andricdefm : LdPat<extloadi16, uimm12_1, LD32H, i32>;
1004*0eae32dcSDimitry Andricdefm : LdPat<zextloadi16, uimm12_1, LD32H, i32>;
1005*0eae32dcSDimitry Andriclet Predicates = [iHasE2] in {
1006*0eae32dcSDimitry Andricdefm : LdPat<sextloadi16, uimm12_1, LD32HS, i32>;
1007*0eae32dcSDimitry Andric}
1008*0eae32dcSDimitry Andricdefm : LdPat<load, uimm12_2, LD32W, i32>;
1009*0eae32dcSDimitry Andric
1010*0eae32dcSDimitry Andricmulticlass LdrPat<PatFrag LoadOp, Instruction Inst, ValueType Type> {
1011*0eae32dcSDimitry Andric  def : Pat<(Type (LoadOp (add GPR:$rs1, GPR:$rs2))), (Inst GPR:$rs1, GPR:$rs2, 0)>;
1012*0eae32dcSDimitry Andric  def : Pat<(Type (LoadOp (add GPR:$rs1, (shl GPR:$rs2, (i32 1))))), (Inst GPR:$rs1, GPR:$rs2, 1)>;
1013*0eae32dcSDimitry Andric  def : Pat<(Type (LoadOp (add GPR:$rs1, (shl GPR:$rs2, (i32 2))))), (Inst GPR:$rs1, GPR:$rs2, 2)>;
1014*0eae32dcSDimitry Andric  def : Pat<(Type (LoadOp (add GPR:$rs1, (shl GPR:$rs2, (i32 3))))), (Inst GPR:$rs1, GPR:$rs2, 3)>;
1015*0eae32dcSDimitry Andric}
1016*0eae32dcSDimitry Andric
1017*0eae32dcSDimitry Andriclet Predicates = [iHas2E3] in {
1018*0eae32dcSDimitry Andric  defm : LdrPat<zextloadi8, LDR32B, i32>;
1019*0eae32dcSDimitry Andric  defm : LdrPat<sextloadi8, LDR32BS, i32>;
1020*0eae32dcSDimitry Andric  defm : LdrPat<extloadi8, LDR32BS, i32>;
1021*0eae32dcSDimitry Andric  defm : LdrPat<zextloadi16, LDR32H, i32>;
1022*0eae32dcSDimitry Andric  defm : LdrPat<sextloadi16, LDR32HS, i32>;
1023*0eae32dcSDimitry Andric  defm : LdrPat<extloadi16, LDR32HS, i32>;
1024*0eae32dcSDimitry Andric  defm : LdrPat<load, LDR32W, i32>;
1025*0eae32dcSDimitry Andric}
1026*0eae32dcSDimitry Andric
1027*0eae32dcSDimitry Andricmulticlass StPat<PatFrag StoreOp, ValueType Type, ImmLeaf imm_type, Instruction Inst> {
1028*0eae32dcSDimitry Andric  def : Pat<(StoreOp Type:$rs2, GPR:$rs1), (Inst Type:$rs2, GPR:$rs1, 0)>;
1029*0eae32dcSDimitry Andric  def : Pat<(StoreOp Type:$rs2, frameindex:$rs1), (Inst Type:$rs2, (i32 (to_tframeindex tframeindex:$rs1)), 0)>;
1030*0eae32dcSDimitry Andric  def : Pat<(StoreOp Type:$rs2, (add GPR:$rs1, imm_type:$uimm12)),
1031*0eae32dcSDimitry Andric            (Inst Type:$rs2, GPR:$rs1, imm_type:$uimm12)>;
1032*0eae32dcSDimitry Andric  def : Pat<(StoreOp Type:$rs2, (add frameindex:$rs1, imm_type:$uimm12)),
1033*0eae32dcSDimitry Andric            (Inst Type:$rs2, (i32 (to_tframeindex tframeindex:$rs1)), imm_type:$uimm12)>;
1034*0eae32dcSDimitry Andric  def : Pat<(StoreOp Type:$rs2, (eqToAdd frameindex:$rs1, imm_type:$uimm12)),
1035*0eae32dcSDimitry Andric            (Inst Type:$rs2, (i32 (to_tframeindex tframeindex:$rs1)), imm_type:$uimm12)>;
1036*0eae32dcSDimitry Andric}
1037*0eae32dcSDimitry Andric
1038*0eae32dcSDimitry Andricdefm : StPat<truncstorei8, i32, uimm12, ST32B>;
1039*0eae32dcSDimitry Andricdefm : StPat<truncstorei16, i32, uimm12_1, ST32H>;
1040*0eae32dcSDimitry Andricdefm : StPat<store, i32, uimm12_2, ST32W>;
1041*0eae32dcSDimitry Andric
1042*0eae32dcSDimitry Andricmulticlass StrPat<PatFrag StoreOp, ValueType Type, Instruction Inst> {
1043*0eae32dcSDimitry Andric  def : Pat<(StoreOp Type:$rz, (add GPR:$rs1, GPR:$rs2)), (Inst Type:$rz, GPR:$rs1, GPR:$rs2, 0)>;
1044*0eae32dcSDimitry Andric  def : Pat<(StoreOp Type:$rz, (add GPR:$rs1, (shl GPR:$rs2, (i32 1)))), (Inst Type:$rz, GPR:$rs1, GPR:$rs2, 1)>;
1045*0eae32dcSDimitry Andric  def : Pat<(StoreOp Type:$rz, (add GPR:$rs1, (shl GPR:$rs2, (i32 2)))), (Inst Type:$rz, GPR:$rs1, GPR:$rs2, 2)>;
1046*0eae32dcSDimitry Andric  def : Pat<(StoreOp Type:$rz, (add GPR:$rs1, (shl GPR:$rs2, (i32 3)))), (Inst Type:$rz, GPR:$rs1, GPR:$rs2, 3)>;
1047*0eae32dcSDimitry Andric}
1048*0eae32dcSDimitry Andric
1049*0eae32dcSDimitry Andriclet Predicates = [iHas2E3] in {
1050*0eae32dcSDimitry Andric  defm : StrPat<truncstorei8, i32, STR32B>;
1051*0eae32dcSDimitry Andric  defm : StrPat<truncstorei16, i32, STR32H>;
1052*0eae32dcSDimitry Andric  defm : StrPat<store, i32, STR32W>;
1053*0eae32dcSDimitry Andric
1054*0eae32dcSDimitry Andric  // Sext & Zext Patterns
1055*0eae32dcSDimitry Andric  def : Pat<(sext_inreg GPR:$src, i1), (SEXT32 GPR:$src, 0, 0)>;
1056*0eae32dcSDimitry Andric  def : Pat<(and GPR:$src, 255), (ZEXT32 GPR:$src, 7, 0)>;
1057*0eae32dcSDimitry Andric  def : Pat<(and GPR:$src, 65535), (ZEXT32 GPR:$src, 15, 0)>;
1058*0eae32dcSDimitry Andric}
1059*0eae32dcSDimitry Andric
1060*0eae32dcSDimitry Andric// Constant materialize patterns.
1061*0eae32dcSDimitry Andriclet Predicates = [iHasE2] in
1062*0eae32dcSDimitry Andric  def : Pat<(i32 imm:$imm),
1063*0eae32dcSDimitry Andric            (ORI32 (MOVIH32 (uimm32_hi16 imm:$imm)), (uimm32_lo16 imm:$imm))>;
1064*0eae32dcSDimitry Andric
1065*0eae32dcSDimitry Andric
1066*0eae32dcSDimitry Andric// Other operations.
1067*0eae32dcSDimitry Andriclet Predicates = [iHasE2] in {
1068*0eae32dcSDimitry Andric  def : Pat<(rotl GPR:$rs1, GPR:$rs2),
1069*0eae32dcSDimitry Andric            (ROTL32 GPR:$rs1, (ANDI32 GPR:$rs2, 0x1f))>;
1070*0eae32dcSDimitry Andric  let Predicates = [iHas2E3] in {
1071*0eae32dcSDimitry Andric    def : Pat<(bitreverse GPR:$rx), (BREV32 GPR:$rx)>;
1072*0eae32dcSDimitry Andric    def : Pat<(bswap GPR:$rx), (REVB32 GPR:$rx)>;
1073*0eae32dcSDimitry Andric  }
1074*0eae32dcSDimitry Andric  def : Pat<(i32 (ctlz GPR:$rx)), (FF1 GPR:$rx)>;
1075*0eae32dcSDimitry Andric}
1076349cc55cSDimitry Andric
1077349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
1078349cc55cSDimitry Andric// Pseudo for assembly
1079349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
1080349cc55cSDimitry Andric
1081349cc55cSDimitry Andriclet isCall = 1, Defs = [ R15 ], mayLoad = 1, Size = 4, isCodeGenOnly = 0 in
1082349cc55cSDimitry Andricdef JBSR32 : CSKYPseudo<(outs), (ins call_symbol:$src1), "jbsr32\t$src1", []>;
1083349cc55cSDimitry Andric
1084349cc55cSDimitry Andricdef : InstAlias<"jbsr\t$src1", (JBSR32 call_symbol:$src1)>;
1085349cc55cSDimitry Andric
1086349cc55cSDimitry Andricdef JBR32 : CSKYPseudo<(outs), (ins br_symbol:$src1), "jbr32\t$src1", []> {
1087349cc55cSDimitry Andric  let isBranch = 1;
1088349cc55cSDimitry Andric  let isTerminator = 1;
1089349cc55cSDimitry Andric  let isBarrier = 1;
1090349cc55cSDimitry Andric  let isIndirectBranch = 1;
1091349cc55cSDimitry Andric  let mayLoad = 1;
1092349cc55cSDimitry Andric  let Size = 4;
1093349cc55cSDimitry Andric}
1094349cc55cSDimitry Andric
1095349cc55cSDimitry Andricdef JBT32 : CSKYPseudo<(outs), (ins CARRY:$ca, br_symbol:$src1), "jbt32\t$src1", []> {
1096349cc55cSDimitry Andric  let isBranch = 1;
1097349cc55cSDimitry Andric  let isTerminator = 1;
1098349cc55cSDimitry Andric  let isIndirectBranch = 1;
1099349cc55cSDimitry Andric  let mayLoad = 1;
1100349cc55cSDimitry Andric  let Size = 4;
1101349cc55cSDimitry Andric}
1102349cc55cSDimitry Andric
1103349cc55cSDimitry Andricdef JBF32 : CSKYPseudo<(outs), (ins CARRY:$ca, br_symbol:$src1), "jbf32\t$src1", []> {
1104349cc55cSDimitry Andric  let isBranch = 1;
1105349cc55cSDimitry Andric  let isTerminator = 1;
1106349cc55cSDimitry Andric  let isIndirectBranch = 1;
1107349cc55cSDimitry Andric  let mayLoad = 1;
1108349cc55cSDimitry Andric  let Size = 4;
1109349cc55cSDimitry Andric}
1110349cc55cSDimitry Andric
1111349cc55cSDimitry Andricdef JBT_E : CSKYPseudo<(outs), (ins CARRY:$ca, br_symbol:$src1), "!jbt_e\t$src1", []> {
1112349cc55cSDimitry Andric  let isBranch = 1;
1113349cc55cSDimitry Andric  let isTerminator = 1;
1114349cc55cSDimitry Andric  let isIndirectBranch = 1;
1115349cc55cSDimitry Andric  let mayLoad = 1;
1116349cc55cSDimitry Andric  let Size = 6;
1117349cc55cSDimitry Andric}
1118349cc55cSDimitry Andric
1119349cc55cSDimitry Andricdef JBF_E : CSKYPseudo<(outs), (ins CARRY:$ca, br_symbol:$src1), "!jbf_e\t$src1", []> {
1120349cc55cSDimitry Andric  let isBranch = 1;
1121349cc55cSDimitry Andric  let isTerminator = 1;
1122349cc55cSDimitry Andric  let isIndirectBranch = 1;
1123349cc55cSDimitry Andric  let mayLoad = 1;
1124349cc55cSDimitry Andric  let Size = 6;
1125349cc55cSDimitry Andric}
1126349cc55cSDimitry Andric
1127349cc55cSDimitry Andriclet mayLoad = 1, Size = 2, isCodeGenOnly = 0 in
1128349cc55cSDimitry Andricdef PseudoLRW32 : CSKYPseudo<(outs GPR:$rz), (ins bare_symbol:$src), "lrw32 $rz, $src", []>;
1129349cc55cSDimitry Andric
1130349cc55cSDimitry Andric
1131349cc55cSDimitry Andricdef : InstAlias<"lrw $rz, $src", (PseudoLRW32 GPR:$rz, bare_symbol:$src)>;
1132349cc55cSDimitry Andricdef : InstAlias<"lrw $rz, $src", (LRW32 GPR:$rz, constpool_symbol:$src)>;
1133349cc55cSDimitry Andric
1134349cc55cSDimitry Andriclet mayLoad = 1, Size = 4, isCodeGenOnly = 0 in
1135349cc55cSDimitry Andricdef PseudoJSRI32 : CSKYPseudo<(outs), (ins call_symbol:$src), "jsri32 $src", []>;
1136349cc55cSDimitry Andricdef : InstAlias<"jsri $dst", (PseudoJSRI32 call_symbol:$dst)>;
1137349cc55cSDimitry Andricdef : InstAlias<"jsri $dst", (JSRI32 constpool_symbol:$dst)>;
1138349cc55cSDimitry Andric
1139349cc55cSDimitry Andriclet mayLoad = 1, Size = 4, isCodeGenOnly = 0 in
1140349cc55cSDimitry Andricdef PseudoJMPI32 : CSKYPseudo<(outs), (ins br_symbol:$src), "jmpi32 $src", []>;
1141349cc55cSDimitry Andricdef : InstAlias<"jmpi $dst", (PseudoJMPI32 br_symbol:$dst)>;
1142349cc55cSDimitry Andricdef : InstAlias<"jmpi $dst", (JMPI32 constpool_symbol:$dst)>;
1143349cc55cSDimitry Andric
1144349cc55cSDimitry Andriclet isNotDuplicable = 1, mayLoad = 1, mayStore = 0, Size = 8 in
1145349cc55cSDimitry Andricdef PseudoTLSLA32 : CSKYPseudo<(outs GPR:$dst1, GPR:$dst2),
1146349cc55cSDimitry Andric  (ins constpool_symbol:$src, i32imm:$label), "!tlslrw32\t$dst1, $dst2, $src, $label", []>;
1147349cc55cSDimitry Andric
1148349cc55cSDimitry Andriclet hasSideEffects = 0, isNotDuplicable = 1 in
1149349cc55cSDimitry Andricdef CONSTPOOL_ENTRY : CSKYPseudo<(outs),
1150349cc55cSDimitry Andric  (ins i32imm:$instid, i32imm:$cpidx, i32imm:$size), "", []>;
1151349cc55cSDimitry Andric
1152349cc55cSDimitry Andricinclude "CSKYInstrInfo16Instr.td"
1153