xref: /llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoC.td (revision 7979e1ba298e3602d569f05a46c10b8efca9fd6f)
1//===- RISCVInstrInfoC.td - Compressed RISC-V 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 : RISCVOp, 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  let DecoderMethod = "decodeUImmLog2XLenNonZeroOperand";
28  let OperandType = "OPERAND_UIMMLOG2XLEN_NONZERO";
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 : RISCVSImmLeafOp<6> {
40  let MCOperandPredicate = [{
41    int64_t Imm;
42    if (MCOp.evaluateAsConstantImm(Imm))
43      return isInt<6>(Imm);
44    return MCOp.isBareSymbolRef();
45  }];
46}
47
48def simm6nonzero : RISCVOp,
49                   ImmLeaf<XLenVT, [{return (Imm != 0) && isInt<6>(Imm);}]> {
50  let ParserMatchClass = SImmAsmOperand<6, "NonZero">;
51  let EncoderMethod = "getImmOpValue";
52  let DecoderMethod = "decodeSImmNonZeroOperand<6>";
53  let OperandType = "OPERAND_SIMM6_NONZERO";
54  let MCOperandPredicate = [{
55    int64_t Imm;
56    if (MCOp.evaluateAsConstantImm(Imm))
57      return (Imm != 0) && isInt<6>(Imm);
58    return MCOp.isBareSymbolRef();
59  }];
60}
61
62def immzero : RISCVOp,
63              ImmLeaf<XLenVT, [{return (Imm == 0);}]> {
64  let ParserMatchClass = ImmZeroAsmOperand;
65  let OperandType = "OPERAND_ZERO";
66}
67
68def CLUIImmAsmOperand : AsmOperandClass {
69  let Name = "CLUIImm";
70  let RenderMethod = "addImmOperands";
71  let DiagnosticType = !strconcat("Invalid", Name);
72}
73
74
75// c_lui_imm checks the immediate range is in [1, 31] or [0xfffe0, 0xfffff].
76// The RISC-V ISA describes the constraint as [1, 63], with that value being
77// loaded in to bits 17-12 of the destination register and sign extended from
78// bit 17. Therefore, this 6-bit immediate can represent values in the ranges
79// [1, 31] and [0xfffe0, 0xfffff].
80def c_lui_imm : RISCVOp,
81                ImmLeaf<XLenVT, [{return (Imm != 0) &&
82                                 (isUInt<5>(Imm) ||
83                                  (Imm >= 0xfffe0 && Imm <= 0xfffff));}]> {
84  let ParserMatchClass = CLUIImmAsmOperand;
85  let EncoderMethod = "getImmOpValue";
86  let DecoderMethod = "decodeCLUIImmOperand";
87  let OperandType = "OPERAND_CLUI_IMM";
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 : RISCVOp,
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 OperandType = "OPERAND_UIMM7_LSB00";
104  let MCOperandPredicate = [{
105    int64_t Imm;
106    if (!MCOp.evaluateAsConstantImm(Imm))
107      return false;
108    return isShiftedUInt<5, 2>(Imm);
109  }];
110}
111
112// A 8-bit unsigned immediate where the least significant two bits are zero.
113def uimm8_lsb00 : RISCVOp,
114                  ImmLeaf<XLenVT, [{return isShiftedUInt<6, 2>(Imm);}]> {
115  let ParserMatchClass = UImmAsmOperand<8, "Lsb00">;
116  let EncoderMethod = "getImmOpValue";
117  let DecoderMethod = "decodeUImmOperand<8>";
118  let OperandType = "OPERAND_UIMM8_LSB00";
119  let MCOperandPredicate = [{
120    int64_t Imm;
121    if (!MCOp.evaluateAsConstantImm(Imm))
122      return false;
123    return isShiftedUInt<6, 2>(Imm);
124  }];
125}
126
127// A 8-bit unsigned immediate where the least significant three bits are zero.
128def uimm8_lsb000 : RISCVOp,
129                   ImmLeaf<XLenVT, [{return isShiftedUInt<5, 3>(Imm);}]> {
130  let ParserMatchClass = UImmAsmOperand<8, "Lsb000">;
131  let EncoderMethod = "getImmOpValue";
132  let DecoderMethod = "decodeUImmOperand<8>";
133  let OperandType = "OPERAND_UIMM8_LSB000";
134  let MCOperandPredicate = [{
135    int64_t Imm;
136    if (!MCOp.evaluateAsConstantImm(Imm))
137      return false;
138    return isShiftedUInt<5, 3>(Imm);
139  }];
140}
141
142// A 9-bit signed immediate where the least significant bit is zero.
143def simm9_lsb0 : Operand<OtherVT>,
144                 ImmLeaf<XLenVT, [{return isShiftedInt<8, 1>(Imm);}]> {
145  let ParserMatchClass = SImmAsmOperand<9, "Lsb0">;
146  let PrintMethod = "printBranchOperand";
147  let EncoderMethod = "getImmOpValueAsr1";
148  let DecoderMethod = "decodeSImmOperandAndLsl1<9>";
149  let MCOperandPredicate = [{
150    int64_t Imm;
151    if (MCOp.evaluateAsConstantImm(Imm))
152      return isShiftedInt<8, 1>(Imm);
153    return MCOp.isBareSymbolRef();
154  }];
155  let OperandType = "OPERAND_PCREL";
156}
157
158// A 9-bit unsigned immediate where the least significant three bits are zero.
159def uimm9_lsb000 : RISCVOp,
160                   ImmLeaf<XLenVT, [{return isShiftedUInt<6, 3>(Imm);}]> {
161  let ParserMatchClass = UImmAsmOperand<9, "Lsb000">;
162  let EncoderMethod = "getImmOpValue";
163  let DecoderMethod = "decodeUImmOperand<9>";
164  let OperandType = "OPERAND_UIMM9_LSB000";
165  let MCOperandPredicate = [{
166    int64_t Imm;
167    if (!MCOp.evaluateAsConstantImm(Imm))
168      return false;
169    return isShiftedUInt<6, 3>(Imm);
170  }];
171}
172
173// A 10-bit unsigned immediate where the least significant two bits are zero
174// and the immediate can't be zero.
175def uimm10_lsb00nonzero : RISCVOp,
176                          ImmLeaf<XLenVT,
177                          [{return isShiftedUInt<8, 2>(Imm) && (Imm != 0);}]> {
178  let ParserMatchClass = UImmAsmOperand<10, "Lsb00NonZero">;
179  let EncoderMethod = "getImmOpValue";
180  let DecoderMethod = "decodeUImmNonZeroOperand<10>";
181  let OperandType = "OPERAND_UIMM10_LSB00_NONZERO";
182  let MCOperandPredicate = [{
183    int64_t Imm;
184    if (!MCOp.evaluateAsConstantImm(Imm))
185      return false;
186    return isShiftedUInt<8, 2>(Imm) && (Imm != 0);
187  }];
188}
189
190// A 10-bit signed immediate where the least significant four bits are zero.
191def simm10_lsb0000nonzero : RISCVOp,
192                            ImmLeaf<XLenVT,
193                            [{return (Imm != 0) && isShiftedInt<6, 4>(Imm);}]> {
194  let ParserMatchClass = SImmAsmOperand<10, "Lsb0000NonZero">;
195  let EncoderMethod = "getImmOpValue";
196  let DecoderMethod = "decodeSImmNonZeroOperand<10>";
197  let OperandType = "OPERAND_SIMM10_LSB0000_NONZERO";
198  let MCOperandPredicate = [{
199    int64_t Imm;
200    if (!MCOp.evaluateAsConstantImm(Imm))
201      return false;
202    return isShiftedInt<6, 4>(Imm) && (Imm != 0);
203  }];
204}
205
206// A 12-bit signed immediate where the least significant bit is zero.
207def simm12_lsb0 : Operand<XLenVT>,
208                  ImmLeaf<XLenVT, [{return isShiftedInt<11, 1>(Imm);}]> {
209  let ParserMatchClass = SImmAsmOperand<12, "Lsb0">;
210  let PrintMethod = "printBranchOperand";
211  let EncoderMethod = "getImmOpValueAsr1";
212  let DecoderMethod = "decodeSImmOperandAndLsl1<12>";
213  let MCOperandPredicate = [{
214    int64_t Imm;
215    if (MCOp.evaluateAsConstantImm(Imm))
216      return isShiftedInt<11, 1>(Imm);
217    return MCOp.isBareSymbolRef();
218  }];
219  let OperandType = "OPERAND_PCREL";
220}
221
222def InsnCDirectiveOpcode : AsmOperandClass {
223  let Name = "InsnCDirectiveOpcode";
224  let ParserMethod = "parseInsnCDirectiveOpcode";
225  let RenderMethod = "addImmOperands";
226  let PredicateMethod = "isImm";
227}
228
229def uimm2_opcode : RISCVUImmOp<2> {
230  let ParserMatchClass = InsnCDirectiveOpcode;
231}
232
233//===----------------------------------------------------------------------===//
234// Instruction Class Templates
235//===----------------------------------------------------------------------===//
236
237let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
238class CStackLoad<bits<3> funct3, string OpcodeStr,
239                 RegisterClass cls, DAGOperand opnd>
240    : RVInst16CI<funct3, 0b10, (outs cls:$rd), (ins SPMem:$rs1, opnd:$imm),
241                 OpcodeStr, "$rd, ${imm}(${rs1})">;
242
243let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
244class CStackStore<bits<3> funct3, string OpcodeStr,
245                  RegisterClass cls, DAGOperand opnd>
246    : RVInst16CSS<funct3, 0b10, (outs), (ins cls:$rs2, SPMem:$rs1, opnd:$imm),
247                  OpcodeStr, "$rs2, ${imm}(${rs1})">;
248
249let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
250class CLoad_ri<bits<3> funct3, string OpcodeStr,
251               RegisterClass cls, DAGOperand opnd>
252    : RVInst16CL<funct3, 0b00, (outs cls:$rd), (ins GPRCMem:$rs1, opnd:$imm),
253                 OpcodeStr, "$rd, ${imm}(${rs1})">;
254
255let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
256class CStore_rri<bits<3> funct3, string OpcodeStr,
257                 RegisterClass cls, DAGOperand opnd>
258    : RVInst16CS<funct3, 0b00, (outs), (ins cls:$rs2,GPRCMem:$rs1, opnd:$imm),
259                 OpcodeStr, "$rs2, ${imm}(${rs1})">;
260
261let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
262class Bcz<bits<3> funct3, string OpcodeStr>
263    : RVInst16CB<funct3, 0b01, (outs), (ins GPRC:$rs1, simm9_lsb0:$imm),
264                 OpcodeStr, "$rs1, $imm"> {
265  let isBranch = 1;
266  let isTerminator = 1;
267  let Inst{12} = imm{7};
268  let Inst{11-10} = imm{3-2};
269  let Inst{6-5} = imm{6-5};
270  let Inst{4-3} = imm{1-0};
271  let Inst{2} = imm{4};
272}
273
274let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
275class Shift_right<bits<2> funct2, string OpcodeStr>
276    : RVInst16CB<0b100, 0b01, (outs GPRC:$rd),
277                 (ins GPRC:$rs1, uimmlog2xlennonzero:$imm),
278                 OpcodeStr, "$rs1, $imm"> {
279  let Constraints = "$rs1 = $rd";
280  let Inst{12} = imm{5};
281  let Inst{11-10} = funct2;
282  let Inst{6-2} = imm{4-0};
283}
284
285let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
286class CA_ALU<bits<6> funct6, bits<2> funct2, string OpcodeStr>
287    : RVInst16CA<funct6, funct2, 0b01, (outs GPRC:$rd_wb),
288                 (ins GPRC:$rd, GPRC:$rs2), OpcodeStr, "$rd, $rs2"> {
289  bits<3> rd;
290  let Constraints = "$rd = $rd_wb";
291  let Inst{9-7} = rd;
292}
293
294//===----------------------------------------------------------------------===//
295// Instructions
296//===----------------------------------------------------------------------===//
297
298let Predicates = [HasStdExtCOrZca] in {
299
300let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Uses = [X2] in
301def C_ADDI4SPN : RVInst16CIW<0b000, 0b00, (outs GPRC:$rd),
302                             (ins SP:$rs1, uimm10_lsb00nonzero:$imm),
303                             "c.addi4spn", "$rd, $rs1, $imm">,
304                             Sched<[WriteIALU, ReadIALU]> {
305  bits<5> rs1;
306  let Inst{12-11} = imm{5-4};
307  let Inst{10-7} = imm{9-6};
308  let Inst{6} = imm{2};
309  let Inst{5} = imm{3};
310}
311
312let Predicates = [HasStdExtCOrZcd, HasStdExtD] in
313def C_FLD  : CLoad_ri<0b001, "c.fld", FPR64C, uimm8_lsb000>,
314             Sched<[WriteFLD64, ReadFMemBase]> {
315  bits<8> imm;
316  let Inst{12-10} = imm{5-3};
317  let Inst{6-5} = imm{7-6};
318}
319
320def C_LW : CLoad_ri<0b010, "c.lw", GPRC, uimm7_lsb00>,
321           Sched<[WriteLDW, ReadMemBase]> {
322  bits<7> imm;
323  let Inst{12-10} = imm{5-3};
324  let Inst{6} = imm{2};
325  let Inst{5} = imm{6};
326}
327
328let isCodeGenOnly = 1 in
329def C_LW_INX : CLoad_ri<0b010, "c.lw", GPRF32C, uimm7_lsb00>,
330               Sched<[WriteLDW, ReadMemBase]> {
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 = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in
339def C_FLW  : CLoad_ri<0b011, "c.flw", FPR32C, uimm7_lsb00>,
340             Sched<[WriteFLD32, ReadFMemBase]> {
341  bits<7> imm;
342  let Inst{12-10} = imm{5-3};
343  let Inst{6} = imm{2};
344  let Inst{5} = imm{6};
345}
346
347let Predicates = [HasStdExtCOrZca, IsRV64] in
348def C_LD : CLoad_ri<0b011, "c.ld", GPRC, uimm8_lsb000>,
349           Sched<[WriteLDD, ReadMemBase]> {
350  bits<8> imm;
351  let Inst{12-10} = imm{5-3};
352  let Inst{6-5} = imm{7-6};
353}
354
355let Predicates = [HasStdExtCOrZcd, HasStdExtD] in
356def C_FSD  : CStore_rri<0b101, "c.fsd", FPR64C, uimm8_lsb000>,
357             Sched<[WriteFST64, ReadFStoreData, ReadFMemBase]> {
358  bits<8> imm;
359  let Inst{12-10} = imm{5-3};
360  let Inst{6-5} = imm{7-6};
361}
362
363def C_SW : CStore_rri<0b110, "c.sw", GPRC, uimm7_lsb00>,
364           Sched<[WriteSTW, ReadStoreData, ReadMemBase]> {
365  bits<7> imm;
366  let Inst{12-10} = imm{5-3};
367  let Inst{6} = imm{2};
368  let Inst{5} = imm{6};
369}
370
371let isCodeGenOnly = 1 in
372def C_SW_INX : CStore_rri<0b110, "c.sw", GPRF32C, uimm7_lsb00>,
373               Sched<[WriteSTW, ReadStoreData, ReadMemBase]> {
374  bits<7> imm;
375  let Inst{12-10} = imm{5-3};
376  let Inst{6} = imm{2};
377  let Inst{5} = imm{6};
378}
379
380let DecoderNamespace = "RISCV32Only_",
381    Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32]  in
382def C_FSW  : CStore_rri<0b111, "c.fsw", FPR32C, uimm7_lsb00>,
383             Sched<[WriteFST32, ReadFStoreData, ReadFMemBase]> {
384  bits<7> imm;
385  let Inst{12-10} = imm{5-3};
386  let Inst{6} = imm{2};
387  let Inst{5} = imm{6};
388}
389
390let Predicates = [HasStdExtCOrZca, IsRV64] in
391def C_SD : CStore_rri<0b111, "c.sd", GPRC, uimm8_lsb000>,
392           Sched<[WriteSTD, ReadStoreData, ReadMemBase]> {
393  bits<8> imm;
394  let Inst{12-10} = imm{5-3};
395  let Inst{6-5} = imm{7-6};
396}
397
398let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
399def C_NOP : RVInst16CI<0b000, 0b01, (outs), (ins), "c.nop", "">,
400            Sched<[WriteNop]> {
401  let rd = 0;
402  let imm = 0;
403}
404
405let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
406def C_ADDI : RVInst16CI<0b000, 0b01, (outs GPRNoX0:$rd_wb),
407                        (ins GPRNoX0:$rd, simm6nonzero:$imm),
408                        "c.addi", "$rd, $imm">,
409             Sched<[WriteIALU, ReadIALU]> {
410  let Constraints = "$rd = $rd_wb";
411}
412
413// Alternate syntax for c.nop. Converted to C_NOP by the assembler.
414let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0,
415    isAsmParserOnly = 1 in
416def PseudoC_ADDI_NOP : Pseudo<(outs GPRX0:$rd), (ins GPRX0:$rs1, immzero:$imm),
417                              [], "c.addi", "$rd, $imm">;
418
419let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCall = 1,
420    DecoderNamespace = "RISCV32Only_", Defs = [X1],
421    Predicates = [HasStdExtCOrZca, IsRV32]  in
422def C_JAL : RVInst16CJ<0b001, 0b01, (outs), (ins simm12_lsb0:$offset),
423                       "c.jal", "$offset">, Sched<[WriteJal]>;
424
425let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
426    Predicates = [HasStdExtCOrZca, IsRV64] in
427def C_ADDIW : RVInst16CI<0b001, 0b01, (outs GPRNoX0:$rd_wb),
428                         (ins GPRNoX0:$rd, simm6:$imm),
429                         "c.addiw", "$rd, $imm">,
430              Sched<[WriteIALU32, ReadIALU32]> {
431  let Constraints = "$rd = $rd_wb";
432}
433
434let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
435def C_LI : RVInst16CI<0b010, 0b01, (outs GPRNoX0:$rd), (ins simm6:$imm),
436                      "c.li", "$rd, $imm">,
437           Sched<[WriteIALU]>;
438
439let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
440def C_ADDI16SP : RVInst16CI<0b011, 0b01, (outs SP:$rd_wb),
441                            (ins SP:$rd, simm10_lsb0000nonzero:$imm),
442                            "c.addi16sp", "$rd, $imm">,
443                 Sched<[WriteIALU, ReadIALU]> {
444  let Constraints = "$rd = $rd_wb";
445  let Inst{12} = imm{9};
446  let Inst{11-7} = 2;
447  let Inst{6} = imm{4};
448  let Inst{5} = imm{6};
449  let Inst{4-3} = imm{8-7};
450  let Inst{2} = imm{5};
451}
452
453let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
454def C_LUI : RVInst16CI<0b011, 0b01, (outs GPRNoX0X2:$rd),
455                       (ins c_lui_imm:$imm),
456                       "c.lui", "$rd, $imm">,
457            Sched<[WriteIALU]>;
458
459def C_SRLI : Shift_right<0b00, "c.srli">,
460             Sched<[WriteShiftImm, ReadShiftImm]>;
461def C_SRAI : Shift_right<0b01, "c.srai">,
462             Sched<[WriteShiftImm, ReadShiftImm]>;
463
464let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
465def C_ANDI : RVInst16CB<0b100, 0b01, (outs GPRC:$rd), (ins GPRC:$rs1, simm6:$imm),
466                        "c.andi", "$rs1, $imm">,
467             Sched<[WriteIALU, ReadIALU]> {
468  let Constraints = "$rs1 = $rd";
469  let Inst{12} = imm{5};
470  let Inst{11-10} = 0b10;
471  let Inst{6-2} = imm{4-0};
472}
473
474def C_SUB  : CA_ALU<0b100011, 0b00, "c.sub">,
475             Sched<[WriteIALU, ReadIALU, ReadIALU]>;
476def C_XOR  : CA_ALU<0b100011, 0b01, "c.xor">,
477             Sched<[WriteIALU, ReadIALU, ReadIALU]>;
478def C_OR   : CA_ALU<0b100011, 0b10, "c.or">,
479             Sched<[WriteIALU, ReadIALU, ReadIALU]>;
480def C_AND  : CA_ALU<0b100011, 0b11, "c.and">,
481             Sched<[WriteIALU, ReadIALU, ReadIALU]>;
482
483let Predicates = [HasStdExtCOrZca, IsRV64] in {
484def C_SUBW : CA_ALU<0b100111, 0b00, "c.subw">,
485             Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>;
486def C_ADDW : CA_ALU<0b100111, 0b01, "c.addw">,
487             Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>;
488}
489
490let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
491def C_J : RVInst16CJ<0b101, 0b01, (outs), (ins simm12_lsb0:$offset),
492                     "c.j", "$offset">, Sched<[WriteJmp]> {
493  let isBranch = 1;
494  let isTerminator=1;
495  let isBarrier=1;
496}
497
498def C_BEQZ : Bcz<0b110, "c.beqz">, Sched<[WriteJmp, ReadJmp]>;
499def C_BNEZ : Bcz<0b111, "c.bnez">, Sched<[WriteJmp, ReadJmp]>;
500
501let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
502def C_SLLI : RVInst16CI<0b000, 0b10, (outs GPRNoX0:$rd_wb),
503                        (ins GPRNoX0:$rd, uimmlog2xlennonzero:$imm),
504                        "c.slli", "$rd, $imm">,
505             Sched<[WriteShiftImm, ReadShiftImm]> {
506  let Constraints = "$rd = $rd_wb";
507}
508
509let Predicates = [HasStdExtCOrZcd, HasStdExtD] in
510def C_FLDSP  : CStackLoad<0b001, "c.fldsp", FPR64, uimm9_lsb000>,
511               Sched<[WriteFLD64, ReadFMemBase]> {
512  let Inst{4-2} = imm{8-6};
513}
514
515def C_LWSP : CStackLoad<0b010, "c.lwsp", GPRNoX0, uimm8_lsb00>,
516             Sched<[WriteLDW, ReadMemBase]> {
517  let Inst{3-2} = imm{7-6};
518}
519
520let isCodeGenOnly = 1 in
521def C_LWSP_INX : CStackLoad<0b010, "c.lwsp", GPRF32NoX0, uimm8_lsb00>,
522                 Sched<[WriteLDW, ReadMemBase]> {
523  let Inst{3-2} = imm{7-6};
524}
525
526let DecoderNamespace = "RISCV32Only_",
527    Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in
528def C_FLWSP  : CStackLoad<0b011, "c.flwsp", FPR32, uimm8_lsb00>,
529               Sched<[WriteFLD32, ReadFMemBase]> {
530  let Inst{3-2} = imm{7-6};
531}
532
533let Predicates = [HasStdExtCOrZca, IsRV64] in
534def C_LDSP : CStackLoad<0b011, "c.ldsp", GPRNoX0, uimm9_lsb000>,
535             Sched<[WriteLDD, ReadMemBase]> {
536  let Inst{4-2} = imm{8-6};
537}
538
539let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
540def C_JR : RVInst16CR<0b1000, 0b10, (outs), (ins GPRNoX0:$rs1),
541                      "c.jr", "$rs1">, Sched<[WriteJalr, ReadJalr]> {
542  let isBarrier = 1;
543  let isTerminator = 1;
544  let rs2 = 0;
545}
546
547let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isMoveReg = 1,
548    isAsCheapAsAMove = 1 in
549def C_MV : RVInst16CR<0b1000, 0b10, (outs GPRNoX0:$rs1), (ins GPRNoX0:$rs2),
550                      "c.mv", "$rs1, $rs2">,
551           Sched<[WriteIALU, ReadIALU]>;
552
553let rs1 = 0, rs2 = 0, hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
554def C_EBREAK : RVInst16CR<0b1001, 0b10, (outs), (ins), "c.ebreak", "">, Sched<[]>;
555
556let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
557    isCall=1, Defs=[X1], rs2 = 0 in
558def C_JALR : RVInst16CR<0b1001, 0b10, (outs), (ins GPRNoX0:$rs1),
559                        "c.jalr", "$rs1">, Sched<[WriteJalr, ReadJalr]>;
560
561let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
562def C_ADD : RVInst16CR<0b1001, 0b10, (outs GPRNoX0:$rd),
563                       (ins GPRNoX0:$rs1, GPRNoX0:$rs2),
564                       "c.add", "$rs1, $rs2">,
565            Sched<[WriteIALU, ReadIALU, ReadIALU]> {
566  let Constraints = "$rs1 = $rd";
567}
568
569let Predicates = [HasStdExtCOrZcd, HasStdExtD] in
570def C_FSDSP  : CStackStore<0b101, "c.fsdsp", FPR64, uimm9_lsb000>,
571               Sched<[WriteFST64, ReadFStoreData, ReadFMemBase]> {
572  let Inst{9-7}   = imm{8-6};
573}
574
575def C_SWSP : CStackStore<0b110, "c.swsp", GPR, uimm8_lsb00>,
576             Sched<[WriteSTW, ReadStoreData, ReadMemBase]> {
577  let Inst{8-7}  = imm{7-6};
578}
579
580let isCodeGenOnly = 1 in
581def C_SWSP_INX : CStackStore<0b110, "c.swsp", GPRF32, uimm8_lsb00>,
582                 Sched<[WriteSTW, ReadStoreData, ReadMemBase]> {
583  let Inst{8-7}  = imm{7-6};
584}
585
586let DecoderNamespace = "RISCV32Only_",
587    Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in
588def C_FSWSP  : CStackStore<0b111, "c.fswsp", FPR32, uimm8_lsb00>,
589               Sched<[WriteFST32, ReadFStoreData, ReadFMemBase]> {
590  let Inst{8-7}  = imm{7-6};
591}
592
593let Predicates = [HasStdExtCOrZca, IsRV64] in
594def C_SDSP : CStackStore<0b111, "c.sdsp", GPR, uimm9_lsb000>,
595             Sched<[WriteSTD, ReadStoreData, ReadMemBase]> {
596  let Inst{9-7}   = imm{8-6};
597}
598
599// The all zeros pattern isn't a valid RISC-V instruction. It's used by GNU
600// binutils as 16-bit instruction known to be unimplemented (i.e., trapping).
601let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
602def C_UNIMP : RVInst16<(outs), (ins), "c.unimp", "", [], InstFormatOther>,
603              Sched<[]> {
604  let Inst{15-0} = 0;
605}
606
607} // Predicates = [HasStdExtCOrZca]
608
609//===----------------------------------------------------------------------===//
610// HINT Instructions
611//===----------------------------------------------------------------------===//
612
613let Predicates = [HasStdExtCOrZca, HasRVCHints], hasSideEffects = 0, mayLoad = 0,
614    mayStore = 0 in {
615
616def C_NOP_HINT : RVInst16CI<0b000, 0b01, (outs), (ins simm6nonzero:$imm),
617                            "c.nop", "$imm">, Sched<[WriteNop]> {
618  let rd = 0;
619}
620
621def C_ADDI_HINT_IMM_ZERO : RVInst16CI<0b000, 0b01, (outs GPRNoX0:$rd_wb),
622                                      (ins GPRNoX0:$rd, immzero:$imm),
623                                      "c.addi", "$rd, $imm">,
624                           Sched<[WriteIALU, ReadIALU]> {
625  let Constraints = "$rd = $rd_wb";
626  let imm = 0;
627  let DecoderMethod = "decodeRVCInstrRdRs1ImmZero";
628}
629
630def C_LI_HINT : RVInst16CI<0b010, 0b01, (outs GPRX0:$rd), (ins simm6:$imm),
631                           "c.li", "$rd, $imm">,
632                Sched<[WriteIALU]> {
633  let Inst{11-7} = 0;
634  let DecoderMethod = "decodeRVCInstrRdSImm";
635}
636
637def C_LUI_HINT : RVInst16CI<0b011, 0b01, (outs GPRX0:$rd),
638                            (ins c_lui_imm:$imm),
639                            "c.lui", "$rd, $imm">,
640                 Sched<[WriteIALU]> {
641  let Inst{11-7} = 0;
642  let DecoderMethod = "decodeRVCInstrRdSImm";
643}
644
645def C_MV_HINT : RVInst16CR<0b1000, 0b10, (outs GPRX0:$rs1), (ins GPRNoX0:$rs2),
646                           "c.mv", "$rs1, $rs2">, Sched<[WriteIALU, ReadIALU]> {
647  let Inst{11-7} = 0;
648  let DecoderMethod = "decodeRVCInstrRdRs2";
649}
650
651def C_ADD_HINT : RVInst16CR<0b1001, 0b10, (outs GPRX0:$rd),
652                            (ins GPRX0:$rs1, GPRNoX0:$rs2),
653                            "c.add", "$rs1, $rs2">,
654                 Sched<[WriteIALU, ReadIALU, ReadIALU]> {
655  let Constraints = "$rs1 = $rd";
656  let Inst{11-7} = 0;
657  let DecoderMethod = "decodeRVCInstrRdRs1Rs2";
658}
659
660def C_SLLI_HINT : RVInst16CI<0b000, 0b10, (outs GPRX0:$rd_wb),
661                             (ins GPRX0:$rd, uimmlog2xlennonzero:$imm),
662                             "c.slli", "$rd, $imm">,
663                  Sched<[WriteShiftImm, ReadShiftImm]> {
664  let Constraints = "$rd = $rd_wb";
665  let Inst{11-7} = 0;
666  let DecoderMethod = "decodeRVCInstrRdRs1UImm";
667}
668
669def C_SLLI64_HINT : RVInst16CI<0b000, 0b10, (outs GPR:$rd_wb), (ins GPR:$rd),
670                               "c.slli64", "$rd">,
671                    Sched<[WriteShiftImm, ReadShiftImm]> {
672  let Constraints = "$rd = $rd_wb";
673  let imm = 0;
674}
675
676def C_SRLI64_HINT : RVInst16CB<0b100, 0b01, (outs GPRC:$rd),
677                               (ins GPRC:$rs1),
678                               "c.srli64", "$rs1">,
679                    Sched<[WriteShiftImm, ReadShiftImm]> {
680  let Constraints = "$rs1 = $rd";
681  let Inst{6-2} = 0;
682  let Inst{11-10} = 0b00;
683  let Inst{12} = 0;
684}
685
686def C_SRAI64_HINT : RVInst16CB<0b100, 0b01, (outs GPRC:$rd),
687                               (ins GPRC:$rs1),
688                               "c.srai64", "$rs1">,
689                    Sched<[WriteShiftImm, ReadShiftImm]> {
690  let Constraints = "$rs1 = $rd";
691  let Inst{6-2} = 0;
692  let Inst{11-10} = 0b01;
693  let Inst{12} = 0;
694}
695
696} // Predicates = [HasStdExtCOrZca, HasRVCHints], hasSideEffects = 0, mayLoad = 0,
697  // mayStore = 0
698
699//===----------------------------------------------------------------------===//
700// Assembler Pseudo Instructions
701//===----------------------------------------------------------------------===//
702
703let Predicates = [HasStdExtCOrZca, HasRVCHints] in {
704// Just a different syntax for the c.nop hint: c.addi x0, simm6 vs c.nop simm6.
705def : InstAlias<"c.addi x0, $imm", (C_NOP_HINT simm6nonzero:$imm), 0>;
706}
707
708let Predicates = [HasStdExtC, HasRVCHints, HasStdExtZihintntl] in {
709def : InstAlias<"c.ntl.p1", (C_ADD_HINT X0, X2)>;
710def : InstAlias<"c.ntl.pall", (C_ADD_HINT X0, X3)>;
711def : InstAlias<"c.ntl.s1", (C_ADD_HINT X0, X4)>;
712def : InstAlias<"c.ntl.all", (C_ADD_HINT X0, X5)>;
713} // Predicates = [HasStdExtC, HasRVCHints, HasStdExtZihintntl]
714
715let EmitPriority = 0 in {
716let Predicates = [HasStdExtCOrZca] in {
717def : InstAlias<"c.lw $rd, (${rs1})", (C_LW GPRC:$rd, GPRCMem:$rs1, 0)>;
718def : InstAlias<"c.sw $rs2, (${rs1})", (C_SW GPRC:$rs2, GPRCMem:$rs1, 0)>;
719def : InstAlias<"c.lwsp $rd, (${rs1})", (C_LWSP GPRNoX0:$rd, SPMem:$rs1, 0)>;
720def : InstAlias<"c.swsp $rs2, (${rs1})", (C_SWSP GPRNoX0:$rs2, SPMem:$rs1, 0)>;
721}
722
723let Predicates = [HasStdExtCOrZca, IsRV64] in {
724def : InstAlias<"c.ld $rd, (${rs1})", (C_LD GPRC:$rd, GPRCMem:$rs1, 0)>;
725def : InstAlias<"c.sd $rs2, (${rs1})", (C_SD GPRC:$rs2, GPRCMem:$rs1, 0)>;
726def : InstAlias<"c.ldsp $rd, (${rs1})", (C_LDSP GPRNoX0:$rd, SPMem:$rs1, 0)>;
727def : InstAlias<"c.sdsp $rs2, (${rs1})", (C_SDSP GPRNoX0:$rs2, SPMem:$rs1, 0)>;
728}
729
730let Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in {
731def : InstAlias<"c.flw $rd, (${rs1})", (C_FLW FPR32C:$rd, GPRCMem:$rs1, 0)>;
732def : InstAlias<"c.fsw $rs2, (${rs1})", (C_FSW FPR32C:$rs2, GPRCMem:$rs1, 0)>;
733def : InstAlias<"c.flwsp $rd, (${rs1})", (C_FLWSP FPR32:$rd, SPMem:$rs1, 0)>;
734def : InstAlias<"c.fswsp $rs2, (${rs1})", (C_FSWSP FPR32:$rs2, SPMem:$rs1, 0)>;
735}
736
737let Predicates = [HasStdExtCOrZcd, HasStdExtD] in {
738def : InstAlias<"c.fld $rd, (${rs1})", (C_FLD FPR64C:$rd, GPRCMem:$rs1, 0)>;
739def : InstAlias<"c.fsd $rs2, (${rs1})", (C_FSD FPR64C:$rs2, GPRCMem:$rs1, 0)>;
740def : InstAlias<"c.fldsp $rd, (${rs1})", (C_FLDSP FPR64:$rd, SPMem:$rs1, 0)>;
741def : InstAlias<"c.fsdsp $rs2, (${rs1})", (C_FSDSP FPR64:$rs2, SPMem:$rs1, 0)>;
742}
743} // EmitPriority = 0
744
745//===----------------------------------------------------------------------===//
746// .insn directive instructions
747//===----------------------------------------------------------------------===//
748
749def AnyRegCOperand : AsmOperandClass {
750  let Name = "AnyRegCOperand";
751  let RenderMethod = "addRegOperands";
752  let PredicateMethod = "isAnyRegC";
753}
754
755def AnyRegC : Operand<XLenVT> {
756  let OperandType = "OPERAND_REGISTER";
757  let ParserMatchClass = AnyRegCOperand;
758}
759
760// isCodeGenOnly = 1 to hide them from the tablegened assembly parser.
761let isCodeGenOnly = 1, hasSideEffects = 1, mayLoad = 1, mayStore = 1,
762    hasNoSchedulingInfo = 1, Predicates = [HasStdExtCOrZca] in {
763def InsnCR : DirectiveInsnCR<(outs AnyReg:$rd), (ins uimm2_opcode:$opcode,
764                                                     uimm4:$funct4,
765                                                     AnyReg:$rs2),
766                             "$opcode, $funct4, $rd, $rs2">;
767def InsnCI : DirectiveInsnCI<(outs AnyReg:$rd), (ins uimm2_opcode:$opcode,
768                                                     uimm3:$funct3,
769                                                     simm6:$imm6),
770                             "$opcode, $funct3, $rd, $imm6">;
771def InsnCIW : DirectiveInsnCIW<(outs AnyRegC:$rd), (ins uimm2_opcode:$opcode,
772                                                        uimm3:$funct3,
773                                                        uimm8:$imm8),
774                               "$opcode, $funct3, $rd, $imm8">;
775def InsnCSS : DirectiveInsnCSS<(outs), (ins uimm2_opcode:$opcode,
776                                            uimm3:$funct3,
777                                            AnyReg:$rs2,
778                                            uimm6:$imm6),
779                               "$opcode, $funct3, $rs2, $imm6">;
780def InsnCL : DirectiveInsnCL<(outs AnyRegC:$rd), (ins uimm2_opcode:$opcode,
781                                                      uimm3:$funct3,
782                                                      AnyRegC:$rs1,
783                                                      uimm5:$imm5),
784                             "$opcode, $funct3, $rd, ${imm5}(${rs1})">;
785def InsnCS : DirectiveInsnCS<(outs), (ins uimm2_opcode:$opcode,
786                                          uimm3:$funct3,
787                                          AnyRegC:$rs2,
788                                          AnyRegC:$rs1,
789                                          uimm5:$imm5),
790                             "$opcode, $funct3, $rs2, ${imm5}(${rs1})">;
791def InsnCA : DirectiveInsnCA<(outs AnyRegC:$rd), (ins uimm2_opcode:$opcode,
792                                                      uimm6:$funct6,
793                                                      uimm2:$funct2,
794                                                      AnyRegC:$rs2),
795                             "$opcode, $funct6, $funct2, $rd, $rs2">;
796def InsnCB : DirectiveInsnCB<(outs), (ins uimm2_opcode:$opcode, uimm3:$funct3,
797                                          AnyRegC:$rs1,
798                                          simm9_lsb0:$imm8),
799                             "$opcode, $funct3, $rs1, $imm8">;
800def InsnCJ : DirectiveInsnCJ<(outs), (ins uimm2_opcode:$opcode,
801                                          uimm3:$funct3,
802                                          simm12_lsb0:$imm11),
803                             "$opcode, $funct3, $imm11">;
804def Insn16 : RVInst16<(outs), (ins uimm16:$value), "", "", [], InstFormatOther> {
805  bits<16> value;
806
807  let Inst{15-0} = value;
808  let AsmString = ".insn 0x2, $value";
809}
810}
811
812// Use InstAliases to match these so that we can combine the insn and format
813// into a mnemonic to use as the key for the tablegened asm matcher table. The
814// parser will take care of creating these fake mnemonics and will only do it
815// for known formats.
816let EmitPriority = 0, Predicates = [HasStdExtCOrZca] in {
817def : InstAlias<".insn_cr $opcode, $funct4, $rd, $rs2",
818                (InsnCR AnyReg:$rd, uimm2_opcode:$opcode, uimm4:$funct4,
819                        AnyReg:$rs2)>;
820def : InstAlias<".insn_ci $opcode, $funct3, $rd, $imm6",
821                (InsnCI AnyReg:$rd, uimm2_opcode:$opcode, uimm3:$funct3,
822                        simm6:$imm6)>;
823def : InstAlias<".insn_ciw $opcode, $funct3, $rd, $imm8",
824                (InsnCIW AnyRegC:$rd, uimm2_opcode:$opcode, uimm3:$funct3,
825                         uimm8:$imm8)>;
826def : InstAlias<".insn_css $opcode, $funct3, $rs2, $imm6",
827                (InsnCSS uimm2_opcode:$opcode, uimm3:$funct3, AnyReg:$rs2,
828                         uimm6:$imm6)>;
829def : InstAlias<".insn_cl $opcode, $funct3, $rd, ${imm5}(${rs1})",
830                (InsnCL AnyRegC:$rd, uimm2_opcode:$opcode, uimm3:$funct3,
831                        AnyRegC:$rs1, uimm5:$imm5)>;
832def : InstAlias<".insn_cl $opcode, $funct3, $rd, (${rs1})",
833                (InsnCL AnyRegC:$rd, uimm2_opcode:$opcode, uimm3:$funct3,
834                        AnyRegC:$rs1, 0)>;
835def : InstAlias<".insn_cs $opcode, $funct3, $rs2, ${imm5}(${rs1})",
836                (InsnCS uimm2_opcode:$opcode, uimm3:$funct3, AnyRegC:$rs2,
837                        AnyRegC:$rs1, uimm5:$imm5)>;
838def : InstAlias<".insn_cs $opcode, $funct3, $rs2, (${rs1})",
839                (InsnCS uimm2_opcode:$opcode, uimm3:$funct3, AnyRegC:$rs2,
840                        AnyRegC:$rs1, 0)>;
841def : InstAlias<".insn_ca $opcode, $funct6, $funct2, $rd, $rs2",
842                (InsnCA AnyRegC:$rd, uimm2_opcode:$opcode, uimm6:$funct6,
843                        uimm2:$funct2, AnyRegC:$rs2)>;
844def : InstAlias<".insn_cb $opcode, $funct3, $rs1, $imm8",
845                (InsnCB uimm2_opcode:$opcode, uimm3:$funct3, AnyRegC:$rs1,
846                        simm9_lsb0:$imm8)>;
847def : InstAlias<".insn_cj $opcode, $funct3, $imm11",
848                (InsnCJ uimm2_opcode:$opcode, uimm3:$funct3, simm12_lsb0:$imm11)>;
849}
850
851//===----------------------------------------------------------------------===/i
852// Compress Instruction tablegen backend.
853//===----------------------------------------------------------------------===//
854
855// Patterns are defined in the same order the compressed instructions appear
856// under the "RVC Instruction Set Listings" section of the ISA manual.
857
858// Quadrant 0
859let Predicates = [HasStdExtCOrZca] in {
860def : CompressPat<(ADDI GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm),
861                  (C_ADDI4SPN GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm)>;
862} // Predicates = [HasStdExtCOrZca]
863
864let Predicates = [HasStdExtCOrZcd, HasStdExtD] in {
865def : CompressPat<(FLD FPR64C:$rd, GPRCMem:$rs1, uimm8_lsb000:$imm),
866                  (C_FLD FPR64C:$rd, GPRCMem:$rs1, uimm8_lsb000:$imm)>;
867} // Predicates = [HasStdExtCOrZcd, HasStdExtD]
868
869let Predicates = [HasStdExtCOrZca] in {
870def : CompressPat<(LW GPRC:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm),
871                  (C_LW GPRC:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm)>;
872
873let isCompressOnly = true in
874def : CompressPat<(LW_INX GPRF32C:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm),
875                  (C_LW_INX GPRF32C:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm)>;
876} // Predicates = [HasStdExtCOrZca]
877
878let Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in {
879def : CompressPat<(FLW FPR32C:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm),
880                  (C_FLW FPR32C:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm)>;
881} // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
882
883let Predicates = [HasStdExtCOrZca, IsRV64] in {
884def : CompressPat<(LD GPRC:$rd, GPRCMem:$rs1, uimm8_lsb000:$imm),
885                  (C_LD GPRC:$rd, GPRCMem:$rs1, uimm8_lsb000:$imm)>;
886} // Predicates = [HasStdExtCOrZca, IsRV64]
887
888let Predicates = [HasStdExtCOrZcd, HasStdExtD] in {
889def : CompressPat<(FSD FPR64C:$rs2, GPRCMem:$rs1, uimm8_lsb000:$imm),
890                  (C_FSD FPR64C:$rs2, GPRCMem:$rs1, uimm8_lsb000:$imm)>;
891} // Predicates = [HasStdExtCOrZcd, HasStdExtD]
892
893let Predicates = [HasStdExtCOrZca] in {
894def : CompressPat<(SW GPRC:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm),
895                  (C_SW GPRC:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm)>;
896
897let isCompressOnly = true in
898def : CompressPat<(SW_INX GPRF32C:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm),
899                  (C_SW_INX GPRF32C:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm)>;
900} // Predicates = [HasStdExtCOrZca]
901
902let Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in {
903def : CompressPat<(FSW FPR32C:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm),
904                  (C_FSW FPR32C:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm)>;
905} // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
906
907let Predicates = [HasStdExtCOrZca, IsRV64] in {
908def : CompressPat<(SD GPRC:$rs2, GPRCMem:$rs1, uimm8_lsb000:$imm),
909                  (C_SD GPRC:$rs2, GPRCMem:$rs1, uimm8_lsb000:$imm)>;
910} // Predicates = [HasStdExtCOrZca, IsRV64]
911
912// Quadrant 1
913let Predicates = [HasStdExtCOrZca] in {
914def : CompressPat<(ADDI X0, X0, 0), (C_NOP)>;
915def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs1, simm6nonzero:$imm),
916                  (C_ADDI GPRNoX0:$rs1, simm6nonzero:$imm)>;
917} // Predicates = [HasStdExtCOrZca]
918
919let Predicates = [HasStdExtCOrZca, IsRV32] in {
920def : CompressPat<(JAL X1, simm12_lsb0:$offset),
921                  (C_JAL simm12_lsb0:$offset)>;
922} // Predicates = [HasStdExtCOrZca, IsRV32]
923
924let Predicates = [HasStdExtCOrZca, IsRV64] in {
925def : CompressPat<(ADDIW GPRNoX0:$rs1, GPRNoX0:$rs1, simm6:$imm),
926                  (C_ADDIW GPRNoX0:$rs1, simm6:$imm)>;
927} // Predicates = [HasStdExtCOrZca, IsRV64]
928
929let Predicates = [HasStdExtCOrZca] in {
930def : CompressPat<(ADDI GPRNoX0:$rd, X0, simm6:$imm),
931                  (C_LI GPRNoX0:$rd, simm6:$imm)>;
932def : CompressPat<(ADDI X2, X2, simm10_lsb0000nonzero:$imm),
933                  (C_ADDI16SP X2, simm10_lsb0000nonzero:$imm)>;
934def : CompressPat<(LUI GPRNoX0X2:$rd, c_lui_imm:$imm),
935                  (C_LUI GPRNoX0X2:$rd, c_lui_imm:$imm)>;
936def : CompressPat<(SRLI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm),
937                  (C_SRLI GPRC:$rs1, uimmlog2xlennonzero:$imm)>;
938def : CompressPat<(SRAI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm),
939                  (C_SRAI GPRC:$rs1, uimmlog2xlennonzero:$imm)>;
940def : CompressPat<(ANDI GPRC:$rs1, GPRC:$rs1, simm6:$imm),
941                  (C_ANDI GPRC:$rs1, simm6:$imm)>;
942def : CompressPat<(SUB GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
943                  (C_SUB GPRC:$rs1, GPRC:$rs2)>;
944def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
945                  (C_XOR GPRC:$rs1, GPRC:$rs2)>;
946let isCompressOnly = true in
947def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
948                  (C_XOR GPRC:$rs1, GPRC:$rs2)>;
949def : CompressPat<(OR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
950                  (C_OR GPRC:$rs1, GPRC:$rs2)>;
951let isCompressOnly = true in
952def : CompressPat<(OR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
953                  (C_OR GPRC:$rs1, GPRC:$rs2)>;
954def : CompressPat<(AND GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
955                  (C_AND GPRC:$rs1, GPRC:$rs2)>;
956let isCompressOnly = true in
957def : CompressPat<(AND GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
958                  (C_AND GPRC:$rs1, GPRC:$rs2)>;
959} // Predicates = [HasStdExtCOrZca]
960
961let Predicates = [HasStdExtCOrZca, IsRV64] in {
962let isCompressOnly = true in
963def : CompressPat<(ADDIW GPRNoX0:$rd, X0, simm6:$imm),
964                  (C_LI GPRNoX0:$rd, simm6:$imm)>;
965def : CompressPat<(SUBW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
966                  (C_SUBW GPRC:$rs1, GPRC:$rs2)>;
967def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
968                   (C_ADDW GPRC:$rs1, GPRC:$rs2)>;
969let isCompressOnly = true in
970def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
971                   (C_ADDW GPRC:$rs1, GPRC:$rs2)>;
972} // Predicates = [HasStdExtCOrZca, IsRV64]
973
974let Predicates = [HasStdExtCOrZca] in {
975def : CompressPat<(JAL X0, simm12_lsb0:$offset),
976                  (C_J simm12_lsb0:$offset)>;
977def : CompressPat<(BEQ GPRC:$rs1, X0, simm9_lsb0:$imm),
978                  (C_BEQZ GPRC:$rs1, simm9_lsb0:$imm)>;
979let isCompressOnly = true in
980def : CompressPat<(BEQ X0, GPRC:$rs1, simm9_lsb0:$imm),
981                  (C_BEQZ GPRC:$rs1, simm9_lsb0:$imm)>;
982def : CompressPat<(BNE GPRC:$rs1, X0, simm9_lsb0:$imm),
983                  (C_BNEZ GPRC:$rs1, simm9_lsb0:$imm)>;
984let isCompressOnly = true in
985def : CompressPat<(BNE X0, GPRC:$rs1, simm9_lsb0:$imm),
986                  (C_BNEZ GPRC:$rs1, simm9_lsb0:$imm)>;
987} // Predicates = [HasStdExtCOrZca]
988
989// Quadrant 2
990let Predicates = [HasStdExtCOrZca] in {
991def : CompressPat<(SLLI GPRNoX0:$rs1, GPRNoX0:$rs1, uimmlog2xlennonzero:$imm),
992                  (C_SLLI GPRNoX0:$rs1, uimmlog2xlennonzero:$imm)>;
993} // Predicates = [HasStdExtCOrZca]
994
995let Predicates = [HasStdExtCOrZcd, HasStdExtD] in {
996def : CompressPat<(FLD FPR64:$rd, SPMem:$rs1, uimm9_lsb000:$imm),
997                  (C_FLDSP FPR64:$rd, SPMem:$rs1, uimm9_lsb000:$imm)>;
998} // Predicates = [HasStdExtCOrZcd, HasStdExtD]
999
1000let Predicates = [HasStdExtCOrZca] in {
1001def : CompressPat<(LW GPRNoX0:$rd, SPMem:$rs1,  uimm8_lsb00:$imm),
1002                  (C_LWSP GPRNoX0:$rd, SPMem:$rs1, uimm8_lsb00:$imm)>;
1003
1004let isCompressOnly = true in
1005def : CompressPat<(LW_INX GPRF32NoX0:$rd, SPMem:$rs1,  uimm8_lsb00:$imm),
1006                  (C_LWSP_INX GPRF32NoX0:$rd, SPMem:$rs1, uimm8_lsb00:$imm)>;
1007} // Predicates = [HasStdExtCOrZca]
1008
1009let Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in {
1010def : CompressPat<(FLW FPR32:$rd, SPMem:$rs1, uimm8_lsb00:$imm),
1011                  (C_FLWSP FPR32:$rd, SPMem:$rs1, uimm8_lsb00:$imm)>;
1012} // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
1013
1014let Predicates = [HasStdExtCOrZca, IsRV64] in {
1015def : CompressPat<(LD GPRNoX0:$rd, SPMem:$rs1, uimm9_lsb000:$imm),
1016                  (C_LDSP GPRNoX0:$rd, SPMem:$rs1, uimm9_lsb000:$imm)>;
1017} // Predicates = [HasStdExtCOrZca, IsRV64]
1018
1019let Predicates = [HasStdExtCOrZca] in {
1020def : CompressPat<(JALR X0, GPRNoX0:$rs1, 0),
1021                  (C_JR GPRNoX0:$rs1)>;
1022let isCompressOnly = true in {
1023def : CompressPat<(ADD GPRNoX0:$rs1, X0, GPRNoX0:$rs2),
1024                  (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
1025def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, X0),
1026                  (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
1027}
1028def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs2, 0),
1029                  (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
1030def : CompressPat<(EBREAK), (C_EBREAK)>;
1031def : CompressPat<(UNIMP), (C_UNIMP)>;
1032def : CompressPat<(JALR X1, GPRNoX0:$rs1, 0),
1033                  (C_JALR GPRNoX0:$rs1)>;
1034def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs1, GPRNoX0:$rs2),
1035                  (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
1036let isCompressOnly = true in
1037def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, GPRNoX0:$rs1),
1038                  (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
1039} // Predicates = [HasStdExtCOrZca]
1040
1041let Predicates = [HasStdExtCOrZcd, HasStdExtD] in {
1042def : CompressPat<(FSD FPR64:$rs2, SPMem:$rs1, uimm9_lsb000:$imm),
1043                  (C_FSDSP FPR64:$rs2, SPMem:$rs1, uimm9_lsb000:$imm)>;
1044} // Predicates = [HasStdExtCOrZcd, HasStdExtD]
1045
1046let Predicates = [HasStdExtCOrZca] in {
1047def : CompressPat<(SW GPR:$rs2, SPMem:$rs1, uimm8_lsb00:$imm),
1048                  (C_SWSP GPR:$rs2, SPMem:$rs1, uimm8_lsb00:$imm)>;
1049
1050let isCompressOnly = true in
1051def : CompressPat<(SW_INX GPRF32:$rs2, SPMem:$rs1, uimm8_lsb00:$imm),
1052                  (C_SWSP_INX GPRF32:$rs2, SPMem:$rs1, uimm8_lsb00:$imm)>;
1053} // Predicates = [HasStdExtCOrZca]
1054
1055let Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in {
1056def : CompressPat<(FSW FPR32:$rs2, SPMem:$rs1, uimm8_lsb00:$imm),
1057                  (C_FSWSP FPR32:$rs2, SPMem:$rs1, uimm8_lsb00:$imm)>;
1058} // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
1059
1060let Predicates = [HasStdExtCOrZca, IsRV64] in {
1061def : CompressPat<(SD GPR:$rs2, SPMem:$rs1, uimm9_lsb000:$imm),
1062                  (C_SDSP GPR:$rs2, SPMem:$rs1, uimm9_lsb000:$imm)>;
1063} // Predicates = [HasStdExtCOrZca, IsRV64]
1064