xref: /freebsd/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoC.td (revision a7dea1671b87c07d2d266f836bfa8b58efc7c134)
1//===- RISCVInstrInfoC.td - Compressed RISCV instructions -*- tblgen-*-----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9include "RISCVInstrFormatsC.td"
10
11//===----------------------------------------------------------------------===//
12// Operand definitions.
13//===----------------------------------------------------------------------===//
14
15def UImmLog2XLenNonZeroAsmOperand : AsmOperandClass {
16  let Name = "UImmLog2XLenNonZero";
17  let RenderMethod = "addImmOperands";
18  let DiagnosticType = "InvalidUImmLog2XLenNonZero";
19}
20
21def uimmlog2xlennonzero : Operand<XLenVT>, ImmLeaf<XLenVT, [{
22  if (Subtarget->is64Bit())
23    return isUInt<6>(Imm) && (Imm != 0);
24  return isUInt<5>(Imm) && (Imm != 0);
25}]> {
26  let ParserMatchClass = UImmLog2XLenNonZeroAsmOperand;
27  // TODO: should ensure invalid shamt is rejected when decoding.
28  let DecoderMethod = "decodeUImmOperand<6>";
29  let MCOperandPredicate = [{
30    int64_t Imm;
31    if (!MCOp.evaluateAsConstantImm(Imm))
32      return false;
33    if (STI.getTargetTriple().isArch64Bit())
34      return  isUInt<6>(Imm) && (Imm != 0);
35    return isUInt<5>(Imm) && (Imm != 0);
36  }];
37}
38
39def simm6 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isInt<6>(Imm);}]> {
40  let ParserMatchClass = SImmAsmOperand<6>;
41  let EncoderMethod = "getImmOpValue";
42  let DecoderMethod = "decodeSImmOperand<6>";
43  let MCOperandPredicate = [{
44    int64_t Imm;
45    if (MCOp.evaluateAsConstantImm(Imm))
46      return isInt<6>(Imm);
47    return MCOp.isBareSymbolRef();
48  }];
49}
50
51def simm6nonzero : Operand<XLenVT>,
52                   ImmLeaf<XLenVT, [{return (Imm != 0) && isInt<6>(Imm);}]> {
53  let ParserMatchClass = SImmAsmOperand<6, "NonZero">;
54  let EncoderMethod = "getImmOpValue";
55  let DecoderMethod = "decodeSImmOperand<6>";
56  let MCOperandPredicate = [{
57    int64_t Imm;
58    if (MCOp.evaluateAsConstantImm(Imm))
59      return (Imm != 0) && isInt<6>(Imm);
60    return MCOp.isBareSymbolRef();
61  }];
62}
63
64def immzero : Operand<XLenVT>,
65              ImmLeaf<XLenVT, [{return (Imm == 0);}]> {
66  let ParserMatchClass = ImmZeroAsmOperand;
67}
68
69def CLUIImmAsmOperand : AsmOperandClass {
70  let Name = "CLUIImm";
71  let RenderMethod = "addImmOperands";
72  let DiagnosticType = !strconcat("Invalid", Name);
73}
74
75
76// c_lui_imm checks the immediate range is in [1, 31] or [0xfffe0, 0xfffff].
77// The RISC-V ISA describes the constraint as [1, 63], with that value being
78// loaded in to bits 17-12 of the destination register and sign extended from
79// bit 17. Therefore, this 6-bit immediate can represent values in the ranges
80// [1, 31] and [0xfffe0, 0xfffff].
81def c_lui_imm : Operand<XLenVT>,
82                ImmLeaf<XLenVT, [{return (Imm != 0) &&
83                                 (isUInt<5>(Imm) ||
84                                  (Imm >= 0xfffe0 && Imm <= 0xfffff));}]> {
85  let ParserMatchClass = CLUIImmAsmOperand;
86  let EncoderMethod = "getImmOpValue";
87  let DecoderMethod = "decodeCLUIImmOperand";
88  let MCOperandPredicate = [{
89    int64_t Imm;
90    if (MCOp.evaluateAsConstantImm(Imm))
91      return (Imm != 0) && (isUInt<5>(Imm) ||
92             (Imm >= 0xfffe0 && Imm <= 0xfffff));
93    return MCOp.isBareSymbolRef();
94  }];
95}
96
97// A 7-bit unsigned immediate where the least significant two bits are zero.
98def uimm7_lsb00 : Operand<XLenVT>,
99                  ImmLeaf<XLenVT, [{return isShiftedUInt<5, 2>(Imm);}]> {
100  let ParserMatchClass = UImmAsmOperand<7, "Lsb00">;
101  let EncoderMethod = "getImmOpValue";
102  let DecoderMethod = "decodeUImmOperand<7>";
103  let MCOperandPredicate = [{
104    int64_t Imm;
105    if (!MCOp.evaluateAsConstantImm(Imm))
106      return false;
107    return isShiftedUInt<5, 2>(Imm);
108  }];
109}
110
111// A 8-bit unsigned immediate where the least significant two bits are zero.
112def uimm8_lsb00 : Operand<XLenVT>,
113                  ImmLeaf<XLenVT, [{return isShiftedUInt<6, 2>(Imm);}]> {
114  let ParserMatchClass = UImmAsmOperand<8, "Lsb00">;
115  let EncoderMethod = "getImmOpValue";
116  let DecoderMethod = "decodeUImmOperand<8>";
117  let MCOperandPredicate = [{
118    int64_t Imm;
119    if (!MCOp.evaluateAsConstantImm(Imm))
120      return false;
121    return isShiftedUInt<6, 2>(Imm);
122  }];
123}
124
125// A 8-bit unsigned immediate where the least significant three bits are zero.
126def uimm8_lsb000 : Operand<XLenVT>,
127                   ImmLeaf<XLenVT, [{return isShiftedUInt<5, 3>(Imm);}]> {
128  let ParserMatchClass = UImmAsmOperand<8, "Lsb000">;
129  let EncoderMethod = "getImmOpValue";
130  let DecoderMethod = "decodeUImmOperand<8>";
131  let MCOperandPredicate = [{
132    int64_t Imm;
133    if (!MCOp.evaluateAsConstantImm(Imm))
134      return false;
135    return isShiftedUInt<5, 3>(Imm);
136  }];
137}
138
139// A 9-bit signed immediate where the least significant bit is zero.
140def simm9_lsb0 : Operand<OtherVT>,
141                 ImmLeaf<XLenVT, [{return isShiftedInt<8, 1>(Imm);}]> {
142  let ParserMatchClass = SImmAsmOperand<9, "Lsb0">;
143  let EncoderMethod = "getImmOpValueAsr1";
144  let DecoderMethod = "decodeSImmOperandAndLsl1<9>";
145  let MCOperandPredicate = [{
146    int64_t Imm;
147    if (MCOp.evaluateAsConstantImm(Imm))
148      return isShiftedInt<8, 1>(Imm);
149    return MCOp.isBareSymbolRef();
150
151  }];
152}
153
154// A 9-bit unsigned immediate where the least significant three bits are zero.
155def uimm9_lsb000 : Operand<XLenVT>,
156                   ImmLeaf<XLenVT, [{return isShiftedUInt<6, 3>(Imm);}]> {
157  let ParserMatchClass = UImmAsmOperand<9, "Lsb000">;
158  let EncoderMethod = "getImmOpValue";
159  let DecoderMethod = "decodeUImmOperand<9>";
160  let MCOperandPredicate = [{
161    int64_t Imm;
162    if (!MCOp.evaluateAsConstantImm(Imm))
163      return false;
164    return isShiftedUInt<6, 3>(Imm);
165  }];
166}
167
168// A 10-bit unsigned immediate where the least significant two bits are zero
169// and the immediate can't be zero.
170def uimm10_lsb00nonzero : Operand<XLenVT>,
171                          ImmLeaf<XLenVT,
172                          [{return isShiftedUInt<8, 2>(Imm) && (Imm != 0);}]> {
173  let ParserMatchClass = UImmAsmOperand<10, "Lsb00NonZero">;
174  let EncoderMethod = "getImmOpValue";
175  let DecoderMethod = "decodeUImmNonZeroOperand<10>";
176  let MCOperandPredicate = [{
177    int64_t Imm;
178    if (!MCOp.evaluateAsConstantImm(Imm))
179      return false;
180    return isShiftedUInt<8, 2>(Imm) && (Imm != 0);
181  }];
182}
183
184// A 10-bit signed immediate where the least significant four bits are zero.
185def simm10_lsb0000nonzero : Operand<XLenVT>,
186                            ImmLeaf<XLenVT,
187                            [{return (Imm != 0) && isShiftedInt<6, 4>(Imm);}]> {
188  let ParserMatchClass = SImmAsmOperand<10, "Lsb0000NonZero">;
189  let EncoderMethod = "getImmOpValue";
190  let DecoderMethod = "decodeSImmNonZeroOperand<10>";
191  let MCOperandPredicate = [{
192    int64_t Imm;
193    if (!MCOp.evaluateAsConstantImm(Imm))
194      return false;
195    return isShiftedInt<6, 4>(Imm) && (Imm != 0);
196  }];
197}
198
199// A 12-bit signed immediate where the least significant bit is zero.
200def simm12_lsb0 : Operand<XLenVT>,
201                  ImmLeaf<XLenVT, [{return isShiftedInt<11, 1>(Imm);}]> {
202  let ParserMatchClass = SImmAsmOperand<12, "Lsb0">;
203  let EncoderMethod = "getImmOpValueAsr1";
204  let DecoderMethod = "decodeSImmOperandAndLsl1<12>";
205  let MCOperandPredicate = [{
206    int64_t Imm;
207    if (MCOp.evaluateAsConstantImm(Imm))
208      return isShiftedInt<11, 1>(Imm);
209    return MCOp.isBareSymbolRef();
210  }];
211}
212
213//===----------------------------------------------------------------------===//
214// Instruction Class Templates
215//===----------------------------------------------------------------------===//
216
217let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
218class CStackLoad<bits<3> funct3, string OpcodeStr,
219                 RegisterClass cls, DAGOperand opnd>
220    : RVInst16CI<funct3, 0b10, (outs cls:$rd), (ins SP:$rs1, opnd:$imm),
221                 OpcodeStr, "$rd, ${imm}(${rs1})">;
222
223let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
224class CStackStore<bits<3> funct3, string OpcodeStr,
225                  RegisterClass cls, DAGOperand opnd>
226    : RVInst16CSS<funct3, 0b10, (outs), (ins cls:$rs2, SP:$rs1, opnd:$imm),
227                  OpcodeStr, "$rs2, ${imm}(${rs1})">;
228
229let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
230class CLoad_ri<bits<3> funct3, string OpcodeStr,
231               RegisterClass cls, DAGOperand opnd>
232    : RVInst16CL<funct3, 0b00, (outs cls:$rd), (ins GPRC:$rs1, opnd:$imm),
233                 OpcodeStr, "$rd, ${imm}(${rs1})">;
234
235let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
236class CStore_rri<bits<3> funct3, string OpcodeStr,
237                 RegisterClass cls, DAGOperand opnd>
238    : RVInst16CS<funct3, 0b00, (outs), (ins cls:$rs2, GPRC:$rs1, opnd:$imm),
239                 OpcodeStr, "$rs2, ${imm}(${rs1})">;
240
241let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
242class Bcz<bits<3> funct3, string OpcodeStr, PatFrag CondOp,
243          RegisterClass cls>
244    : RVInst16CB<funct3, 0b01, (outs), (ins cls:$rs1, simm9_lsb0:$imm),
245                 OpcodeStr, "$rs1, $imm"> {
246  let isBranch = 1;
247  let isTerminator = 1;
248  let Inst{12} = imm{7};
249  let Inst{11-10} = imm{3-2};
250  let Inst{6-5} = imm{6-5};
251  let Inst{4-3} = imm{1-0};
252  let Inst{2} = imm{4};
253}
254
255let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
256class Shift_right<bits<2> funct2, string OpcodeStr, RegisterClass cls,
257                  Operand ImmOpnd>
258    : RVInst16CB<0b100, 0b01, (outs cls:$rs1_wb), (ins cls:$rs1, ImmOpnd:$imm),
259                 OpcodeStr, "$rs1, $imm"> {
260  let Constraints = "$rs1 = $rs1_wb";
261  let Inst{12} = imm{5};
262  let Inst{11-10} = funct2;
263  let Inst{6-2} = imm{4-0};
264}
265
266let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
267class CS_ALU<bits<6> funct6, bits<2> funct2, string OpcodeStr,
268             RegisterClass cls>
269    : RVInst16CA<funct6, funct2, 0b01, (outs cls:$rd_wb), (ins cls:$rd, cls:$rs2),
270                 OpcodeStr, "$rd, $rs2"> {
271  bits<3> rd;
272  let Constraints = "$rd = $rd_wb";
273  let Inst{9-7} = rd;
274}
275
276//===----------------------------------------------------------------------===//
277// Instructions
278//===----------------------------------------------------------------------===//
279
280let Predicates = [HasStdExtC] in {
281
282let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Uses = [X2] in
283def C_ADDI4SPN : RVInst16CIW<0b000, 0b00, (outs GPRC:$rd),
284                             (ins SP:$rs1, uimm10_lsb00nonzero:$imm),
285                             "c.addi4spn", "$rd, $rs1, $imm"> {
286  bits<5> rs1;
287  let Inst{12-11} = imm{5-4};
288  let Inst{10-7} = imm{9-6};
289  let Inst{6} = imm{2};
290  let Inst{5} = imm{3};
291}
292
293let Predicates = [HasStdExtC, HasStdExtD] in
294def C_FLD  : CLoad_ri<0b001, "c.fld", FPR64C, uimm8_lsb000> {
295  bits<8> imm;
296  let Inst{12-10} = imm{5-3};
297  let Inst{6-5} = imm{7-6};
298}
299
300def C_LW : CLoad_ri<0b010, "c.lw", GPRC, uimm7_lsb00> {
301  bits<7> imm;
302  let Inst{12-10} = imm{5-3};
303  let Inst{6} = imm{2};
304  let Inst{5} = imm{6};
305}
306
307let DecoderNamespace = "RISCV32Only_",
308    Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
309def C_FLW  : CLoad_ri<0b011, "c.flw", FPR32C, uimm7_lsb00> {
310  bits<7> imm;
311  let Inst{12-10} = imm{5-3};
312  let Inst{6} = imm{2};
313  let Inst{5} = imm{6};
314}
315
316let Predicates = [HasStdExtC, IsRV64] in
317def C_LD : CLoad_ri<0b011, "c.ld", GPRC, uimm8_lsb000> {
318  bits<8> imm;
319  let Inst{12-10} = imm{5-3};
320  let Inst{6-5} = imm{7-6};
321}
322
323let Predicates = [HasStdExtC, HasStdExtD] in
324def C_FSD  : CStore_rri<0b101, "c.fsd", FPR64C, uimm8_lsb000> {
325  bits<8> imm;
326  let Inst{12-10} = imm{5-3};
327  let Inst{6-5} = imm{7-6};
328}
329
330def C_SW : CStore_rri<0b110, "c.sw", GPRC, uimm7_lsb00> {
331  bits<7> imm;
332  let Inst{12-10} = imm{5-3};
333  let Inst{6} = imm{2};
334  let Inst{5} = imm{6};
335}
336
337let DecoderNamespace = "RISCV32Only_",
338    Predicates = [HasStdExtC, HasStdExtF, IsRV32]  in
339def C_FSW  : CStore_rri<0b111, "c.fsw", FPR32C, uimm7_lsb00> {
340  bits<7> imm;
341  let Inst{12-10} = imm{5-3};
342  let Inst{6} = imm{2};
343  let Inst{5} = imm{6};
344}
345
346let Predicates = [HasStdExtC, IsRV64] in
347def C_SD : CStore_rri<0b111, "c.sd", GPRC, uimm8_lsb000> {
348  bits<8> imm;
349  let Inst{12-10} = imm{5-3};
350  let Inst{6-5} = imm{7-6};
351}
352
353let rd = 0, imm = 0, hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
354def C_NOP : RVInst16CI<0b000, 0b01, (outs), (ins), "c.nop", "">
355{
356  let Inst{6-2} = 0;
357}
358
359let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
360def C_ADDI : RVInst16CI<0b000, 0b01, (outs GPRNoX0:$rd_wb),
361                        (ins GPRNoX0:$rd, simm6nonzero:$imm),
362                        "c.addi", "$rd, $imm"> {
363  let Constraints = "$rd = $rd_wb";
364  let Inst{6-2} = imm{4-0};
365}
366
367let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
368def C_ADDI_NOP : RVInst16CI<0b000, 0b01, (outs GPRX0:$rd_wb),
369                            (ins GPRX0:$rd, immzero:$imm),
370                            "c.addi", "$rd, $imm"> {
371  let Constraints = "$rd = $rd_wb";
372  let Inst{6-2} = 0;
373  let isAsmParserOnly = 1;
374}
375
376let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCall = 1,
377    DecoderNamespace = "RISCV32Only_", Defs = [X1],
378    Predicates = [HasStdExtC, IsRV32]  in
379def C_JAL : RVInst16CJ<0b001, 0b01, (outs), (ins simm12_lsb0:$offset),
380                       "c.jal", "$offset">;
381
382let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
383    Predicates = [HasStdExtC, IsRV64] in
384def C_ADDIW : RVInst16CI<0b001, 0b01, (outs GPRNoX0:$rd_wb),
385                         (ins GPRNoX0:$rd, simm6:$imm),
386                         "c.addiw", "$rd, $imm"> {
387  let Constraints = "$rd = $rd_wb";
388  let Inst{6-2} = imm{4-0};
389}
390
391let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
392def C_LI : RVInst16CI<0b010, 0b01, (outs GPRNoX0:$rd), (ins simm6:$imm),
393                      "c.li", "$rd, $imm"> {
394  let Inst{6-2} = imm{4-0};
395}
396
397let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
398def C_ADDI16SP : RVInst16CI<0b011, 0b01, (outs SP:$rd_wb),
399                            (ins SP:$rd, simm10_lsb0000nonzero:$imm),
400                            "c.addi16sp", "$rd, $imm"> {
401  let Constraints = "$rd = $rd_wb";
402  let Inst{12} = imm{9};
403  let Inst{11-7} = 2;
404  let Inst{6} = imm{4};
405  let Inst{5} = imm{6};
406  let Inst{4-3} = imm{8-7};
407  let Inst{2} = imm{5};
408}
409
410let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
411def C_LUI : RVInst16CI<0b011, 0b01, (outs GPRNoX0X2:$rd),
412                       (ins c_lui_imm:$imm),
413                       "c.lui", "$rd, $imm"> {
414  let Inst{6-2} = imm{4-0};
415}
416
417def C_SRLI : Shift_right<0b00, "c.srli", GPRC, uimmlog2xlennonzero>;
418def C_SRAI : Shift_right<0b01, "c.srai", GPRC, uimmlog2xlennonzero>;
419
420let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
421def C_ANDI : RVInst16CB<0b100, 0b01, (outs GPRC:$rs1_wb), (ins GPRC:$rs1, simm6:$imm),
422                        "c.andi", "$rs1, $imm"> {
423  let Constraints = "$rs1 = $rs1_wb";
424  let Inst{12} = imm{5};
425  let Inst{11-10} = 0b10;
426  let Inst{6-2} = imm{4-0};
427}
428
429def C_SUB  : CS_ALU<0b100011, 0b00, "c.sub", GPRC>;
430def C_XOR  : CS_ALU<0b100011, 0b01, "c.xor", GPRC>;
431def C_OR   : CS_ALU<0b100011, 0b10, "c.or" , GPRC>;
432def C_AND  : CS_ALU<0b100011, 0b11, "c.and", GPRC>;
433
434let Predicates = [HasStdExtC, IsRV64] in {
435def C_SUBW : CS_ALU<0b100111, 0b00, "c.subw", GPRC>;
436def C_ADDW : CS_ALU<0b100111, 0b01, "c.addw", GPRC>;
437}
438
439let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
440def C_J : RVInst16CJ<0b101, 0b01, (outs), (ins simm12_lsb0:$offset),
441                     "c.j", "$offset"> {
442  let isBranch = 1;
443  let isTerminator=1;
444  let isBarrier=1;
445}
446
447def C_BEQZ : Bcz<0b110, "c.beqz",  seteq, GPRC>;
448def C_BNEZ : Bcz<0b111, "c.bnez",  setne, GPRC>;
449
450let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
451def C_SLLI : RVInst16CI<0b000, 0b10, (outs GPRNoX0:$rd_wb),
452                        (ins GPRNoX0:$rd, uimmlog2xlennonzero:$imm),
453                        "c.slli" ,"$rd, $imm"> {
454  let Constraints = "$rd = $rd_wb";
455  let Inst{6-2} = imm{4-0};
456}
457
458let Predicates = [HasStdExtC, HasStdExtD] in
459def C_FLDSP  : CStackLoad<0b001, "c.fldsp", FPR64, uimm9_lsb000> {
460  let Inst{6-5} = imm{4-3};
461  let Inst{4-2} = imm{8-6};
462}
463
464def C_LWSP : CStackLoad<0b010, "c.lwsp", GPRNoX0, uimm8_lsb00> {
465  let Inst{6-4} = imm{4-2};
466  let Inst{3-2} = imm{7-6};
467}
468
469let DecoderNamespace = "RISCV32Only_",
470    Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
471def C_FLWSP  : CStackLoad<0b011, "c.flwsp", FPR32, uimm8_lsb00> {
472  let Inst{6-4} = imm{4-2};
473  let Inst{3-2} = imm{7-6};
474}
475
476let Predicates = [HasStdExtC, IsRV64] in
477def C_LDSP : CStackLoad<0b011, "c.ldsp", GPRNoX0, uimm9_lsb000> {
478  let Inst{6-5} = imm{4-3};
479  let Inst{4-2} = imm{8-6};
480}
481
482let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
483def C_JR : RVInst16CR<0b1000, 0b10, (outs), (ins GPRNoX0:$rs1),
484                      "c.jr", "$rs1"> {
485  let isBranch = 1;
486  let isBarrier = 1;
487  let isTerminator = 1;
488  let isIndirectBranch = 1;
489  let rs2 = 0;
490}
491
492let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
493def C_MV : RVInst16CR<0b1000, 0b10, (outs GPRNoX0:$rs1), (ins GPRNoX0:$rs2),
494                      "c.mv", "$rs1, $rs2">;
495
496let rs1 = 0, rs2 = 0, hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
497def C_EBREAK : RVInst16CR<0b1001, 0b10, (outs), (ins), "c.ebreak", "">;
498
499let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
500    isCall=1, Defs=[X1], rs2 = 0 in
501def C_JALR : RVInst16CR<0b1001, 0b10, (outs), (ins GPRNoX0:$rs1),
502                        "c.jalr", "$rs1">;
503
504let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
505def C_ADD : RVInst16CR<0b1001, 0b10, (outs GPRNoX0:$rs1_wb),
506                       (ins GPRNoX0:$rs1, GPRNoX0:$rs2),
507                       "c.add", "$rs1, $rs2"> {
508  let Constraints = "$rs1 = $rs1_wb";
509}
510
511let Predicates = [HasStdExtC, HasStdExtD] in
512def C_FSDSP  : CStackStore<0b101, "c.fsdsp", FPR64, uimm9_lsb000> {
513  let Inst{12-10} = imm{5-3};
514  let Inst{9-7}   = imm{8-6};
515}
516
517def C_SWSP : CStackStore<0b110, "c.swsp", GPR, uimm8_lsb00> {
518  let Inst{12-9} = imm{5-2};
519  let Inst{8-7}  = imm{7-6};
520}
521
522let DecoderNamespace = "RISCV32Only_",
523    Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
524def C_FSWSP  : CStackStore<0b111, "c.fswsp", FPR32, uimm8_lsb00> {
525  let Inst{12-9} = imm{5-2};
526  let Inst{8-7}  = imm{7-6};
527}
528
529let Predicates = [HasStdExtC, IsRV64] in
530def C_SDSP : CStackStore<0b111, "c.sdsp", GPR, uimm9_lsb000> {
531  let Inst{12-10} = imm{5-3};
532  let Inst{9-7}   = imm{8-6};
533}
534
535// The all zeros pattern isn't a valid RISC-V instruction. It's used by GNU
536// binutils as 16-bit instruction known to be unimplemented (i.e., trapping).
537let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
538def C_UNIMP : RVInst16<(outs), (ins), "c.unimp", "", [], InstFormatOther> {
539  let Inst{15-0} = 0;
540}
541
542} // Predicates = [HasStdExtC]
543
544//===----------------------------------------------------------------------===//
545// HINT Instructions
546//===----------------------------------------------------------------------===//
547
548let Predicates = [HasStdExtC, HasRVCHints], hasSideEffects = 0, mayLoad = 0,
549    mayStore = 0 in
550{
551
552let rd = 0 in
553def C_NOP_HINT : RVInst16CI<0b000, 0b01, (outs), (ins simm6nonzero:$imm),
554                            "c.nop", "$imm"> {
555  let Inst{6-2} = imm{4-0};
556  let DecoderMethod = "decodeRVCInstrSImm";
557}
558
559// Just a different syntax for the c.nop hint: c.addi x0, simm6 vs c.nop simm6.
560def C_ADDI_HINT_X0 : RVInst16CI<0b000, 0b01, (outs GPRX0:$rd_wb),
561                                (ins GPRX0:$rd, simm6nonzero:$imm),
562                                "c.addi", "$rd, $imm"> {
563  let Constraints = "$rd = $rd_wb";
564  let Inst{6-2} = imm{4-0};
565  let isAsmParserOnly = 1;
566}
567
568def C_ADDI_HINT_IMM_ZERO : RVInst16CI<0b000, 0b01, (outs GPRNoX0:$rd_wb),
569                                      (ins GPRNoX0:$rd, immzero:$imm),
570                                      "c.addi", "$rd, $imm"> {
571  let Constraints = "$rd = $rd_wb";
572  let Inst{6-2} = 0;
573  let isAsmParserOnly = 1;
574}
575
576def C_LI_HINT : RVInst16CI<0b010, 0b01, (outs GPRX0:$rd), (ins simm6:$imm),
577                           "c.li", "$rd, $imm"> {
578  let Inst{6-2} = imm{4-0};
579  let Inst{11-7} = 0;
580  let DecoderMethod = "decodeRVCInstrRdSImm";
581}
582
583def C_LUI_HINT : RVInst16CI<0b011, 0b01, (outs GPRX0:$rd),
584                            (ins c_lui_imm:$imm),
585                            "c.lui", "$rd, $imm"> {
586  let Inst{6-2} = imm{4-0};
587  let Inst{11-7} = 0;
588  let DecoderMethod = "decodeRVCInstrRdSImm";
589}
590
591def C_MV_HINT : RVInst16CR<0b1000, 0b10, (outs GPRX0:$rs1), (ins GPRNoX0:$rs2),
592                           "c.mv", "$rs1, $rs2">
593{
594  let Inst{11-7} = 0;
595  let DecoderMethod = "decodeRVCInstrRdRs2";
596}
597
598def C_ADD_HINT : RVInst16CR<0b1001, 0b10, (outs GPRX0:$rs1_wb),
599                            (ins GPRX0:$rs1, GPRNoX0:$rs2),
600                            "c.add", "$rs1, $rs2"> {
601  let Constraints = "$rs1 = $rs1_wb";
602  let Inst{11-7} = 0;
603  let DecoderMethod = "decodeRVCInstrRdRs1Rs2";
604}
605
606def C_SLLI_HINT : RVInst16CI<0b000, 0b10, (outs GPRX0:$rd_wb),
607                             (ins GPRX0:$rd, uimmlog2xlennonzero:$imm),
608                             "c.slli" ,"$rd, $imm"> {
609  let Constraints = "$rd = $rd_wb";
610  let Inst{6-2} = imm{4-0};
611  let Inst{11-7} = 0;
612  let DecoderMethod = "decodeRVCInstrRdRs1UImm";
613}
614
615def C_SLLI64_HINT : RVInst16CI<0b000, 0b10, (outs GPR:$rd_wb), (ins GPR:$rd),
616                               "c.slli64" ,"$rd"> {
617  let Constraints = "$rd = $rd_wb";
618  let Inst{6-2} = 0;
619  let Inst{12} = 0;
620}
621
622def C_SRLI64_HINT : RVInst16CI<0b100, 0b01, (outs GPRC:$rd_wb),
623                               (ins GPRC:$rd),
624                               "c.srli64", "$rd"> {
625  let Constraints = "$rd = $rd_wb";
626  let Inst{6-2} = 0;
627  let Inst{11-10} = 0;
628  let Inst{12} = 0;
629}
630
631def C_SRAI64_HINT : RVInst16CI<0b100, 0b01, (outs GPRC:$rd_wb),
632                               (ins GPRC:$rd),
633                               "c.srai64", "$rd"> {
634  let Constraints = "$rd = $rd_wb";
635  let Inst{6-2} = 0;
636  let Inst{11-10} = 1;
637  let Inst{12} = 0;
638}
639
640} // Predicates = [HasStdExtC, HasRVCHints], hasSideEffects = 0, mayLoad = 0,
641  // mayStore = 0
642
643//===----------------------------------------------------------------------===//
644// Assembler Pseudo Instructions
645//===----------------------------------------------------------------------===//
646
647let EmitPriority = 0 in {
648let Predicates = [HasStdExtC, HasStdExtD] in
649def : InstAlias<"c.fld $rd, (${rs1})", (C_FLD FPR64C:$rd, GPRC:$rs1, 0)>;
650
651def : InstAlias<"c.lw $rd, (${rs1})", (C_LW GPRC:$rd, GPRC:$rs1, 0)>;
652
653let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
654def : InstAlias<"c.flw $rd, (${rs1})", (C_FLW FPR32C:$rd, GPRC:$rs1, 0)>;
655
656let Predicates = [HasStdExtC, IsRV64] in
657def : InstAlias<"c.ld $rd, (${rs1})", (C_LD GPRC:$rd, GPRC:$rs1, 0)>;
658
659let Predicates = [HasStdExtC, HasStdExtD] in
660def : InstAlias<"c.fsd $rs2, (${rs1})", (C_FSD FPR64C:$rs2, GPRC:$rs1, 0)>;
661
662def : InstAlias<"c.sw $rs2, (${rs1})", (C_SW GPRC:$rs2, GPRC:$rs1, 0)>;
663
664let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
665def : InstAlias<"c.fsw $rs2, (${rs1})", (C_FSW FPR32C:$rs2, GPRC:$rs1, 0)>;
666
667let Predicates = [HasStdExtC, IsRV64] in
668def : InstAlias<"c.sd $rs2, (${rs1})", (C_SD GPRC:$rs2, GPRC:$rs1, 0)>;
669
670let Predicates = [HasStdExtC, HasStdExtD] in
671def : InstAlias<"c.fldsp $rd, (${rs1})", (C_FLDSP FPR64C:$rd, SP:$rs1, 0)>;
672
673def : InstAlias<"c.lwsp $rd, (${rs1})", (C_LWSP GPRC:$rd, SP:$rs1, 0)>;
674
675let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
676def : InstAlias<"c.flwsp $rd, (${rs1})", (C_FLWSP FPR32C:$rd, SP:$rs1, 0)>;
677
678let Predicates = [HasStdExtC, IsRV64] in
679def : InstAlias<"c.ldsp $rd, (${rs1})", (C_LDSP GPRC:$rd, SP:$rs1, 0)>;
680
681let Predicates = [HasStdExtC, HasStdExtD] in
682def : InstAlias<"c.fsdsp $rs2, (${rs1})", (C_FSDSP FPR64C:$rs2, SP:$rs1, 0)>;
683
684def : InstAlias<"c.swsp $rs2, (${rs1})", (C_SWSP GPRC:$rs2, SP:$rs1, 0)>;
685
686let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
687def : InstAlias<"c.fswsp $rs2, (${rs1})", (C_FSWSP FPR32C:$rs2, SP:$rs1, 0)>;
688
689let Predicates = [HasStdExtC, IsRV64] in
690def : InstAlias<"c.sdsp $rs2, (${rs1})", (C_SDSP GPRC:$rs2, SP:$rs1, 0)>;
691}
692
693//===----------------------------------------------------------------------===//
694// Compress Instruction tablegen backend.
695//===----------------------------------------------------------------------===//
696
697class CompressPat<dag input, dag output> {
698  dag Input  = input;
699  dag Output    = output;
700  list<Predicate> Predicates = [];
701}
702
703// Patterns are defined in the same order the compressed instructions appear
704// on page 82 of the ISA manual.
705
706// Quadrant 0
707let Predicates = [HasStdExtC] in {
708def : CompressPat<(ADDI GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm),
709                  (C_ADDI4SPN GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm)>;
710} // Predicates = [HasStdExtC]
711
712let Predicates = [HasStdExtC, HasStdExtD] in {
713def : CompressPat<(FLD FPR64C:$rd, GPRC:$rs1, uimm8_lsb000:$imm),
714                  (C_FLD FPR64C:$rd, GPRC:$rs1, uimm8_lsb000:$imm)>;
715} // Predicates = [HasStdExtC, HasStdExtD]
716
717let Predicates = [HasStdExtC] in {
718def : CompressPat<(LW GPRC:$rd, GPRC:$rs1, uimm7_lsb00:$imm),
719                  (C_LW GPRC:$rd, GPRC:$rs1, uimm7_lsb00:$imm)>;
720} // Predicates = [HasStdExtC]
721
722let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
723def : CompressPat<(FLW FPR32C:$rd, GPRC:$rs1, uimm7_lsb00:$imm),
724                  (C_FLW FPR32C:$rd, GPRC:$rs1, uimm7_lsb00:$imm)>;
725} // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
726
727let Predicates = [HasStdExtC, IsRV64] in {
728def : CompressPat<(LD GPRC:$rd, GPRC:$rs1, uimm8_lsb000:$imm),
729                  (C_LD GPRC:$rd, GPRC:$rs1, uimm8_lsb000:$imm)>;
730} // Predicates = [HasStdExtC, IsRV64]
731
732let Predicates = [HasStdExtC, HasStdExtD] in {
733def : CompressPat<(FSD FPR64C:$rs2, GPRC:$rs1, uimm8_lsb000:$imm),
734                  (C_FSD FPR64C:$rs2, GPRC:$rs1, uimm8_lsb000:$imm)>;
735} // Predicates = [HasStdExtC, HasStdExtD]
736
737let Predicates = [HasStdExtC] in {
738def : CompressPat<(SW GPRC:$rs2, GPRC:$rs1, uimm7_lsb00:$imm),
739                  (C_SW GPRC:$rs2, GPRC:$rs1, uimm7_lsb00:$imm)>;
740} // Predicates = [HasStdExtC]
741
742let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
743def : CompressPat<(FSW FPR32C:$rs2, GPRC:$rs1,uimm7_lsb00:$imm),
744                  (C_FSW FPR32C:$rs2, GPRC:$rs1, uimm7_lsb00:$imm)>;
745} // Predicate = [HasStdExtC, HasStdExtF, IsRV32]
746
747let Predicates = [HasStdExtC, IsRV64] in {
748def : CompressPat<(SD GPRC:$rs2, GPRC:$rs1, uimm8_lsb000:$imm),
749                  (C_SD GPRC:$rs2, GPRC:$rs1, uimm8_lsb000:$imm)>;
750} // Predicates = [HasStdExtC, IsRV64]
751
752// Quadrant 1
753let Predicates = [HasStdExtC] in {
754def : CompressPat<(ADDI X0, X0, 0), (C_NOP)>;
755def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs1, simm6nonzero:$imm),
756                  (C_ADDI GPRNoX0:$rs1, simm6nonzero:$imm)>;
757} // Predicates = [HasStdExtC]
758
759let Predicates = [HasStdExtC, IsRV32] in {
760def : CompressPat<(JAL X1, simm12_lsb0:$offset),
761                  (C_JAL simm12_lsb0:$offset)>;
762} // Predicates = [HasStdExtC, IsRV32]
763
764let Predicates = [HasStdExtC, IsRV64] in {
765def : CompressPat<(ADDIW GPRNoX0:$rs1, GPRNoX0:$rs1, simm6:$imm),
766                  (C_ADDIW GPRNoX0:$rs1, simm6:$imm)>;
767} // Predicates = [HasStdExtC, IsRV64]
768
769let Predicates = [HasStdExtC] in {
770def : CompressPat<(ADDI GPRNoX0:$rd, X0, simm6:$imm),
771                  (C_LI GPRNoX0:$rd, simm6:$imm)>;
772def : CompressPat<(ADDI X2, X2, simm10_lsb0000nonzero:$imm),
773                  (C_ADDI16SP X2, simm10_lsb0000nonzero:$imm)>;
774def : CompressPat<(LUI GPRNoX0X2:$rd, c_lui_imm:$imm),
775                  (C_LUI GPRNoX0X2:$rd, c_lui_imm:$imm)>;
776def : CompressPat<(SRLI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm),
777                  (C_SRLI GPRC:$rs1, uimmlog2xlennonzero:$imm)>;
778def : CompressPat<(SRAI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm),
779                  (C_SRAI GPRC:$rs1, uimmlog2xlennonzero:$imm)>;
780def : CompressPat<(ANDI GPRC:$rs1, GPRC:$rs1, simm6:$imm),
781                  (C_ANDI GPRC:$rs1, simm6:$imm)>;
782def : CompressPat<(SUB GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
783                  (C_SUB GPRC:$rs1, GPRC:$rs2)>;
784def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
785                  (C_XOR GPRC:$rs1, GPRC:$rs2)>;
786def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
787                  (C_XOR GPRC:$rs1, GPRC:$rs2)>;
788def : CompressPat<(OR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
789                  (C_OR GPRC:$rs1, GPRC:$rs2)>;
790def : CompressPat<(OR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
791                  (C_OR GPRC:$rs1, GPRC:$rs2)>;
792def : CompressPat<(AND GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
793                  (C_AND GPRC:$rs1, GPRC:$rs2)>;
794def : CompressPat<(AND GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
795                  (C_AND GPRC:$rs1, GPRC:$rs2)>;
796} //  Predicates = [HasStdExtC]
797
798let Predicates = [HasStdExtC, IsRV64] in {
799def : CompressPat<(ADDIW GPRNoX0:$rd, X0, simm6:$imm),
800                  (C_LI GPRNoX0:$rd, simm6:$imm)>;
801def : CompressPat<(SUBW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
802                  (C_SUBW GPRC:$rs1, GPRC:$rs2)>;
803def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
804                   (C_ADDW GPRC:$rs1, GPRC:$rs2)>;
805def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
806                   (C_ADDW GPRC:$rs1, GPRC:$rs2)>;
807} // Predicates = [HasStdExtC, IsRV64]
808
809let Predicates = [HasStdExtC] in {
810def : CompressPat<(JAL X0, simm12_lsb0:$offset),
811                  (C_J simm12_lsb0:$offset)>;
812def : CompressPat<(BEQ GPRC:$rs1, X0, simm9_lsb0:$imm),
813                  (C_BEQZ GPRC:$rs1, simm9_lsb0:$imm)>;
814def : CompressPat<(BNE GPRC:$rs1, X0, simm9_lsb0:$imm),
815                  (C_BNEZ GPRC:$rs1, simm9_lsb0:$imm)>;
816} //  Predicates = [HasStdExtC]
817
818// Quadrant 2
819let Predicates = [HasStdExtC] in {
820def : CompressPat<(SLLI GPRNoX0:$rs1, GPRNoX0:$rs1, uimmlog2xlennonzero:$imm),
821                  (C_SLLI GPRNoX0:$rs1, uimmlog2xlennonzero:$imm)>;
822} //  Predicates = [HasStdExtC]
823
824let Predicates = [HasStdExtC, HasStdExtD] in {
825def : CompressPat<(FLD FPR64:$rd, SP:$rs1, uimm9_lsb000:$imm),
826                  (C_FLDSP FPR64:$rd, SP:$rs1, uimm9_lsb000:$imm)>;
827} // Predicates = [HasStdExtC, HasStdExtD]
828
829let Predicates = [HasStdExtC] in {
830def : CompressPat<(LW GPRNoX0:$rd, SP:$rs1,  uimm8_lsb00:$imm),
831                  (C_LWSP GPRNoX0:$rd, SP:$rs1, uimm8_lsb00:$imm)>;
832} // Predicates = [HasStdExtC]
833
834let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
835def : CompressPat<(FLW FPR32:$rd, SP:$rs1, uimm8_lsb00:$imm),
836                  (C_FLWSP FPR32:$rd, SP:$rs1, uimm8_lsb00:$imm)>;
837} // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
838
839let Predicates = [HasStdExtC, IsRV64] in {
840def : CompressPat<(LD GPRNoX0:$rd, SP:$rs1, uimm9_lsb000:$imm),
841                  (C_LDSP GPRNoX0:$rd, SP:$rs1, uimm9_lsb000:$imm)>;
842} // Predicates = [HasStdExtC, IsRV64]
843
844let Predicates = [HasStdExtC] in {
845def : CompressPat<(JALR X0, GPRNoX0:$rs1, 0),
846                  (C_JR GPRNoX0:$rs1)>;
847def : CompressPat<(ADD GPRNoX0:$rs1, X0, GPRNoX0:$rs2),
848                  (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
849def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, X0),
850                  (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
851def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs2, 0),
852                  (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
853def : CompressPat<(EBREAK), (C_EBREAK)>;
854def : CompressPat<(UNIMP), (C_UNIMP)>;
855def : CompressPat<(JALR X1, GPRNoX0:$rs1, 0),
856                  (C_JALR GPRNoX0:$rs1)>;
857def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs1, GPRNoX0:$rs2),
858                  (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
859def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, GPRNoX0:$rs1),
860                  (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
861} // Predicates = [HasStdExtC]
862
863let Predicates = [HasStdExtC, HasStdExtD] in {
864def : CompressPat<(FSD FPR64:$rs2, SP:$rs1, uimm9_lsb000:$imm),
865                  (C_FSDSP FPR64:$rs2, SP:$rs1, uimm9_lsb000:$imm)>;
866} // Predicates = [HasStdExtC, HasStdExtD]
867
868let Predicates = [HasStdExtC] in {
869def : CompressPat<(SW GPR:$rs2, SP:$rs1, uimm8_lsb00:$imm),
870                  (C_SWSP GPR:$rs2, SP:$rs1, uimm8_lsb00:$imm)>;
871} // Predicates = [HasStdExtC]
872
873let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
874def : CompressPat<(FSW FPR32:$rs2, SP:$rs1, uimm8_lsb00:$imm),
875                  (C_FSWSP FPR32:$rs2, SP:$rs1, uimm8_lsb00:$imm)>;
876} // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
877
878let Predicates = [HasStdExtC, IsRV64] in {
879def : CompressPat<(SD GPR:$rs2, SP:$rs1, uimm9_lsb000:$imm),
880                  (C_SDSP GPR:$rs2, SP:$rs1, uimm9_lsb000:$imm)>;
881} //  Predicates = [HasStdExtC, IsRV64]
882