[gn build] Port 077cc3deeebe
[llvm-project.git] / llvm / lib / Target / RISCV / RISCVInstrInfoC.td
blobe5a5f60f9fec1000b92839c4a0ae2bf0eb337101
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 //===----------------------------------------------------------------------===//
9 include "RISCVInstrFormatsC.td"
11 //===----------------------------------------------------------------------===//
12 // Operand definitions.
13 //===----------------------------------------------------------------------===//
15 def UImmLog2XLenNonZeroAsmOperand : AsmOperandClass {
16   let Name = "UImmLog2XLenNonZero";
17   let RenderMethod = "addImmOperands";
18   let DiagnosticType = "InvalidUImmLog2XLenNonZero";
21 def 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   }];
39 def 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   }];
48 def 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   }];
62 def immzero : RISCVOp,
63               ImmLeaf<XLenVT, [{return (Imm == 0);}]> {
64   let ParserMatchClass = ImmZeroAsmOperand;
65   let OperandType = "OPERAND_ZERO";
68 def CLUIImmAsmOperand : AsmOperandClass {
69   let Name = "CLUIImm";
70   let RenderMethod = "addImmOperands";
71   let DiagnosticType = !strconcat("Invalid", Name);
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].
80 def 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   }];
97 // A 7-bit unsigned immediate where the least significant two bits are zero.
98 def 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   }];
112 // A 8-bit unsigned immediate where the least significant two bits are zero.
113 def 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   }];
127 // A 8-bit unsigned immediate where the least significant three bits are zero.
128 def 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   }];
142 // A 9-bit signed immediate where the least significant bit is zero.
143 def 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();
155   }];
156   let OperandType = "OPERAND_PCREL";
159 // A 9-bit unsigned immediate where the least significant three bits are zero.
160 def uimm9_lsb000 : RISCVOp,
161                    ImmLeaf<XLenVT, [{return isShiftedUInt<6, 3>(Imm);}]> {
162   let ParserMatchClass = UImmAsmOperand<9, "Lsb000">;
163   let EncoderMethod = "getImmOpValue";
164   let DecoderMethod = "decodeUImmOperand<9>";
165   let OperandType = "OPERAND_UIMM9_LSB000";
166   let MCOperandPredicate = [{
167     int64_t Imm;
168     if (!MCOp.evaluateAsConstantImm(Imm))
169       return false;
170     return isShiftedUInt<6, 3>(Imm);
171   }];
174 // A 10-bit unsigned immediate where the least significant two bits are zero
175 // and the immediate can't be zero.
176 def uimm10_lsb00nonzero : RISCVOp,
177                           ImmLeaf<XLenVT,
178                           [{return isShiftedUInt<8, 2>(Imm) && (Imm != 0);}]> {
179   let ParserMatchClass = UImmAsmOperand<10, "Lsb00NonZero">;
180   let EncoderMethod = "getImmOpValue";
181   let DecoderMethod = "decodeUImmNonZeroOperand<10>";
182   let OperandType = "OPERAND_UIMM10_LSB00_NONZERO";
183   let MCOperandPredicate = [{
184     int64_t Imm;
185     if (!MCOp.evaluateAsConstantImm(Imm))
186       return false;
187     return isShiftedUInt<8, 2>(Imm) && (Imm != 0);
188   }];
191 // A 10-bit signed immediate where the least significant four bits are zero.
192 def simm10_lsb0000nonzero : RISCVOp,
193                             ImmLeaf<XLenVT,
194                             [{return (Imm != 0) && isShiftedInt<6, 4>(Imm);}]> {
195   let ParserMatchClass = SImmAsmOperand<10, "Lsb0000NonZero">;
196   let EncoderMethod = "getImmOpValue";
197   let DecoderMethod = "decodeSImmNonZeroOperand<10>";
198   let OperandType = "OPERAND_SIMM10_LSB0000_NONZERO";
199   let MCOperandPredicate = [{
200     int64_t Imm;
201     if (!MCOp.evaluateAsConstantImm(Imm))
202       return false;
203     return isShiftedInt<6, 4>(Imm) && (Imm != 0);
204   }];
207 // A 12-bit signed immediate where the least significant bit is zero.
208 def simm12_lsb0 : Operand<XLenVT>,
209                   ImmLeaf<XLenVT, [{return isShiftedInt<11, 1>(Imm);}]> {
210   let ParserMatchClass = SImmAsmOperand<12, "Lsb0">;
211   let PrintMethod = "printBranchOperand";
212   let EncoderMethod = "getImmOpValueAsr1";
213   let DecoderMethod = "decodeSImmOperandAndLsl1<12>";
214   let MCOperandPredicate = [{
215     int64_t Imm;
216     if (MCOp.evaluateAsConstantImm(Imm))
217       return isShiftedInt<11, 1>(Imm);
218     return MCOp.isBareSymbolRef();
219   }];
220   let OperandType = "OPERAND_PCREL";
223 def InsnCDirectiveOpcode : AsmOperandClass {
224   let Name = "InsnCDirectiveOpcode";
225   let ParserMethod = "parseInsnCDirectiveOpcode";
226   let RenderMethod = "addImmOperands";
227   let PredicateMethod = "isImm";
230 def uimm2_opcode : RISCVOp {
231   let ParserMatchClass = InsnCDirectiveOpcode;
232   let DecoderMethod = "decodeUImmOperand<2>";
233   let OperandType = "OPERAND_UIMM2";
236 //===----------------------------------------------------------------------===//
237 // Instruction Class Templates
238 //===----------------------------------------------------------------------===//
240 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
241 class CStackLoad<bits<3> funct3, string OpcodeStr,
242                  RegisterClass cls, DAGOperand opnd>
243     : RVInst16CI<funct3, 0b10, (outs cls:$rd), (ins SPMem:$rs1, opnd:$imm),
244                  OpcodeStr, "$rd, ${imm}(${rs1})">;
246 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
247 class CStackStore<bits<3> funct3, string OpcodeStr,
248                   RegisterClass cls, DAGOperand opnd>
249     : RVInst16CSS<funct3, 0b10, (outs), (ins cls:$rs2, SPMem:$rs1, opnd:$imm),
250                   OpcodeStr, "$rs2, ${imm}(${rs1})">;
252 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
253 class CLoad_ri<bits<3> funct3, string OpcodeStr,
254                RegisterClass cls, DAGOperand opnd>
255     : RVInst16CL<funct3, 0b00, (outs cls:$rd), (ins GPRCMem:$rs1, opnd:$imm),
256                  OpcodeStr, "$rd, ${imm}(${rs1})">;
258 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
259 class CStore_rri<bits<3> funct3, string OpcodeStr,
260                  RegisterClass cls, DAGOperand opnd>
261     : RVInst16CS<funct3, 0b00, (outs), (ins cls:$rs2,GPRCMem:$rs1, opnd:$imm),
262                  OpcodeStr, "$rs2, ${imm}(${rs1})">;
264 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
265 class Bcz<bits<3> funct3, string OpcodeStr,
266           RegisterClass cls>
267     : RVInst16CB<funct3, 0b01, (outs), (ins cls:$rs1, simm9_lsb0:$imm),
268                  OpcodeStr, "$rs1, $imm"> {
269   let isBranch = 1;
270   let isTerminator = 1;
271   let Inst{12} = imm{7};
272   let Inst{11-10} = imm{3-2};
273   let Inst{6-5} = imm{6-5};
274   let Inst{4-3} = imm{1-0};
275   let Inst{2} = imm{4};
278 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
279 class Shift_right<bits<2> funct2, string OpcodeStr, RegisterClass cls,
280                   Operand ImmOpnd>
281     : RVInst16CB<0b100, 0b01, (outs cls:$rd), (ins cls:$rs1, ImmOpnd:$imm),
282                  OpcodeStr, "$rs1, $imm"> {
283   let Constraints = "$rs1 = $rd";
284   let Inst{12} = imm{5};
285   let Inst{11-10} = funct2;
286   let Inst{6-2} = imm{4-0};
289 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
290 class CA_ALU<bits<6> funct6, bits<2> funct2, string OpcodeStr,
291              RegisterClass cls>
292     : RVInst16CA<funct6, funct2, 0b01, (outs cls:$rd_wb), (ins cls:$rd, cls:$rs2),
293                  OpcodeStr, "$rd, $rs2"> {
294   bits<3> rd;
295   let Constraints = "$rd = $rd_wb";
296   let Inst{9-7} = rd;
299 //===----------------------------------------------------------------------===//
300 // Instructions
301 //===----------------------------------------------------------------------===//
303 let Predicates = [HasStdExtCOrZca] in {
305 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Uses = [X2] in
306 def C_ADDI4SPN : RVInst16CIW<0b000, 0b00, (outs GPRC:$rd),
307                              (ins SP:$rs1, uimm10_lsb00nonzero:$imm),
308                              "c.addi4spn", "$rd, $rs1, $imm">,
309                              Sched<[WriteIALU, ReadIALU]> {
310   bits<5> rs1;
311   let Inst{12-11} = imm{5-4};
312   let Inst{10-7} = imm{9-6};
313   let Inst{6} = imm{2};
314   let Inst{5} = imm{3};
317 let Predicates = [HasStdExtCOrZcd, HasStdExtD] in
318 def C_FLD  : CLoad_ri<0b001, "c.fld", FPR64C, uimm8_lsb000>,
319              Sched<[WriteFLD64, ReadFMemBase]> {
320   bits<8> imm;
321   let Inst{12-10} = imm{5-3};
322   let Inst{6-5} = imm{7-6};
325 def C_LW : CLoad_ri<0b010, "c.lw", GPRC, uimm7_lsb00>,
326            Sched<[WriteLDW, ReadMemBase]> {
327   bits<7> imm;
328   let Inst{12-10} = imm{5-3};
329   let Inst{6} = imm{2};
330   let Inst{5} = imm{6};
333 let isCodeGenOnly = 1 in
334 def C_LW_INX : CLoad_ri<0b010, "c.lw", GPRF32C, uimm7_lsb00>,
335                Sched<[WriteLDW, ReadMemBase]> {
336   bits<7> imm;
337   let Inst{12-10} = imm{5-3};
338   let Inst{6} = imm{2};
339   let Inst{5} = imm{6};
342 let DecoderNamespace = "RISCV32Only_",
343     Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in
344 def C_FLW  : CLoad_ri<0b011, "c.flw", FPR32C, uimm7_lsb00>,
345              Sched<[WriteFLD32, ReadFMemBase]> {
346   bits<7> imm;
347   let Inst{12-10} = imm{5-3};
348   let Inst{6} = imm{2};
349   let Inst{5} = imm{6};
352 let Predicates = [HasStdExtCOrZca, IsRV64] in
353 def C_LD : CLoad_ri<0b011, "c.ld", GPRC, uimm8_lsb000>,
354            Sched<[WriteLDD, ReadMemBase]> {
355   bits<8> imm;
356   let Inst{12-10} = imm{5-3};
357   let Inst{6-5} = imm{7-6};
360 let Predicates = [HasStdExtCOrZcd, HasStdExtD] in
361 def C_FSD  : CStore_rri<0b101, "c.fsd", FPR64C, uimm8_lsb000>,
362              Sched<[WriteFST64, ReadFStoreData, ReadFMemBase]> {
363   bits<8> imm;
364   let Inst{12-10} = imm{5-3};
365   let Inst{6-5} = imm{7-6};
368 def C_SW : CStore_rri<0b110, "c.sw", GPRC, uimm7_lsb00>,
369            Sched<[WriteSTW, ReadStoreData, ReadMemBase]> {
370   bits<7> imm;
371   let Inst{12-10} = imm{5-3};
372   let Inst{6} = imm{2};
373   let Inst{5} = imm{6};
376 let isCodeGenOnly = 1 in
377 def C_SW_INX : CStore_rri<0b110, "c.sw", GPRF32C, uimm7_lsb00>,
378                Sched<[WriteSTW, ReadStoreData, ReadMemBase]> {
379   bits<7> imm;
380   let Inst{12-10} = imm{5-3};
381   let Inst{6} = imm{2};
382   let Inst{5} = imm{6};
385 let DecoderNamespace = "RISCV32Only_",
386     Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32]  in
387 def C_FSW  : CStore_rri<0b111, "c.fsw", FPR32C, uimm7_lsb00>,
388              Sched<[WriteFST32, ReadFStoreData, ReadFMemBase]> {
389   bits<7> imm;
390   let Inst{12-10} = imm{5-3};
391   let Inst{6} = imm{2};
392   let Inst{5} = imm{6};
395 let Predicates = [HasStdExtCOrZca, IsRV64] in
396 def C_SD : CStore_rri<0b111, "c.sd", GPRC, uimm8_lsb000>,
397            Sched<[WriteSTD, ReadStoreData, ReadMemBase]> {
398   bits<8> imm;
399   let Inst{12-10} = imm{5-3};
400   let Inst{6-5} = imm{7-6};
403 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
404 def C_NOP : RVInst16CI<0b000, 0b01, (outs), (ins), "c.nop", "">,
405             Sched<[WriteNop]> {
406   let rd = 0;
407   let imm = 0;
408   let Inst{6-2} = 0;
411 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
412 def C_ADDI : RVInst16CI<0b000, 0b01, (outs GPRNoX0:$rd_wb),
413                         (ins GPRNoX0:$rd, simm6nonzero:$imm),
414                         "c.addi", "$rd, $imm">,
415              Sched<[WriteIALU, ReadIALU]> {
416   let Constraints = "$rd = $rd_wb";
417   let Inst{6-2} = imm{4-0};
420 // Alternate syntax for c.nop. Converted to C_NOP by the assembler.
421 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0,
422     isAsmParserOnly = 1 in
423 def PseudoC_ADDI_NOP : Pseudo<(outs GPRX0:$rd), (ins GPRX0:$rs1, immzero:$imm),
424                               [], "c.addi", "$rd, $imm">;
426 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCall = 1,
427     DecoderNamespace = "RISCV32Only_", Defs = [X1],
428     Predicates = [HasStdExtCOrZca, IsRV32]  in
429 def C_JAL : RVInst16CJ<0b001, 0b01, (outs), (ins simm12_lsb0:$offset),
430                        "c.jal", "$offset">, Sched<[WriteJal]>;
432 let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
433     Predicates = [HasStdExtCOrZca, IsRV64] in
434 def C_ADDIW : RVInst16CI<0b001, 0b01, (outs GPRNoX0:$rd_wb),
435                          (ins GPRNoX0:$rd, simm6:$imm),
436                          "c.addiw", "$rd, $imm">,
437               Sched<[WriteIALU32, ReadIALU32]> {
438   let Constraints = "$rd = $rd_wb";
439   let Inst{6-2} = imm{4-0};
442 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
443 def C_LI : RVInst16CI<0b010, 0b01, (outs GPRNoX0:$rd), (ins simm6:$imm),
444                       "c.li", "$rd, $imm">,
445            Sched<[WriteIALU]> {
446   let Inst{6-2} = imm{4-0};
449 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
450 def C_ADDI16SP : RVInst16CI<0b011, 0b01, (outs SP:$rd_wb),
451                             (ins SP:$rd, simm10_lsb0000nonzero:$imm),
452                             "c.addi16sp", "$rd, $imm">,
453                  Sched<[WriteIALU, ReadIALU]> {
454   let Constraints = "$rd = $rd_wb";
455   let Inst{12} = imm{9};
456   let Inst{11-7} = 2;
457   let Inst{6} = imm{4};
458   let Inst{5} = imm{6};
459   let Inst{4-3} = imm{8-7};
460   let Inst{2} = imm{5};
463 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
464 def C_LUI : RVInst16CI<0b011, 0b01, (outs GPRNoX0X2:$rd),
465                        (ins c_lui_imm:$imm),
466                        "c.lui", "$rd, $imm">,
467             Sched<[WriteIALU]> {
468   let Inst{6-2} = imm{4-0};
471 def C_SRLI : Shift_right<0b00, "c.srli", GPRC, uimmlog2xlennonzero>,
472              Sched<[WriteShiftImm, ReadShiftImm]>;
473 def C_SRAI : Shift_right<0b01, "c.srai", GPRC, uimmlog2xlennonzero>,
474              Sched<[WriteShiftImm, ReadShiftImm]>;
476 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
477 def C_ANDI : RVInst16CB<0b100, 0b01, (outs GPRC:$rd), (ins GPRC:$rs1, simm6:$imm),
478                         "c.andi", "$rs1, $imm">,
479              Sched<[WriteIALU, ReadIALU]> {
480   let Constraints = "$rs1 = $rd";
481   let Inst{12} = imm{5};
482   let Inst{11-10} = 0b10;
483   let Inst{6-2} = imm{4-0};
486 def C_SUB  : CA_ALU<0b100011, 0b00, "c.sub", GPRC>,
487              Sched<[WriteIALU, ReadIALU, ReadIALU]>;
488 def C_XOR  : CA_ALU<0b100011, 0b01, "c.xor", GPRC>,
489              Sched<[WriteIALU, ReadIALU, ReadIALU]>;
490 def C_OR   : CA_ALU<0b100011, 0b10, "c.or" , GPRC>,
491              Sched<[WriteIALU, ReadIALU, ReadIALU]>;
492 def C_AND  : CA_ALU<0b100011, 0b11, "c.and", GPRC>,
493              Sched<[WriteIALU, ReadIALU, ReadIALU]>;
495 let Predicates = [HasStdExtCOrZca, IsRV64] in {
496 def C_SUBW : CA_ALU<0b100111, 0b00, "c.subw", GPRC>,
497              Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>;
498 def C_ADDW : CA_ALU<0b100111, 0b01, "c.addw", GPRC>,
499              Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>;
502 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
503 def C_J : RVInst16CJ<0b101, 0b01, (outs), (ins simm12_lsb0:$offset),
504                      "c.j", "$offset">, Sched<[WriteJmp]> {
505   let isBranch = 1;
506   let isTerminator=1;
507   let isBarrier=1;
510 def C_BEQZ : Bcz<0b110, "c.beqz", GPRC>, Sched<[WriteJmp, ReadJmp]>;
511 def C_BNEZ : Bcz<0b111, "c.bnez", GPRC>, Sched<[WriteJmp, ReadJmp]>;
513 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
514 def C_SLLI : RVInst16CI<0b000, 0b10, (outs GPRNoX0:$rd_wb),
515                         (ins GPRNoX0:$rd, uimmlog2xlennonzero:$imm),
516                         "c.slli", "$rd, $imm">,
517              Sched<[WriteShiftImm, ReadShiftImm]> {
518   let Constraints = "$rd = $rd_wb";
519   let Inst{6-2} = imm{4-0};
522 let Predicates = [HasStdExtCOrZcd, HasStdExtD] in
523 def C_FLDSP  : CStackLoad<0b001, "c.fldsp", FPR64, uimm9_lsb000>,
524                Sched<[WriteFLD64, ReadFMemBase]> {
525   let Inst{6-5} = imm{4-3};
526   let Inst{4-2} = imm{8-6};
529 def C_LWSP : CStackLoad<0b010, "c.lwsp", GPRNoX0, uimm8_lsb00>,
530              Sched<[WriteLDW, ReadMemBase]> {
531   let Inst{6-4} = imm{4-2};
532   let Inst{3-2} = imm{7-6};
535 let isCodeGenOnly = 1 in
536 def C_LWSP_INX : CStackLoad<0b010, "c.lwsp", GPRF32NoX0, uimm8_lsb00>,
537                  Sched<[WriteLDW, ReadMemBase]> {
538   let Inst{6-4} = imm{4-2};
539   let Inst{3-2} = imm{7-6};
542 let DecoderNamespace = "RISCV32Only_",
543     Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in
544 def C_FLWSP  : CStackLoad<0b011, "c.flwsp", FPR32, uimm8_lsb00>,
545                Sched<[WriteFLD32, ReadFMemBase]> {
546   let Inst{6-4} = imm{4-2};
547   let Inst{3-2} = imm{7-6};
550 let Predicates = [HasStdExtCOrZca, IsRV64] in
551 def C_LDSP : CStackLoad<0b011, "c.ldsp", GPRNoX0, uimm9_lsb000>,
552              Sched<[WriteLDD, ReadMemBase]> {
553   let Inst{6-5} = imm{4-3};
554   let Inst{4-2} = imm{8-6};
557 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
558 def C_JR : RVInst16CR<0b1000, 0b10, (outs), (ins GPRNoX0:$rs1),
559                       "c.jr", "$rs1">, Sched<[WriteJalr, ReadJalr]> {
560   let isBarrier = 1;
561   let isTerminator = 1;
562   let rs2 = 0;
565 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isMoveReg = 1,
566     isAsCheapAsAMove = 1 in
567 def C_MV : RVInst16CR<0b1000, 0b10, (outs GPRNoX0:$rs1), (ins GPRNoX0:$rs2),
568                       "c.mv", "$rs1, $rs2">,
569            Sched<[WriteIALU, ReadIALU]>;
571 let rs1 = 0, rs2 = 0, hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
572 def C_EBREAK : RVInst16CR<0b1001, 0b10, (outs), (ins), "c.ebreak", "">, Sched<[]>;
574 let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
575     isCall=1, Defs=[X1], rs2 = 0 in
576 def C_JALR : RVInst16CR<0b1001, 0b10, (outs), (ins GPRNoX0:$rs1),
577                         "c.jalr", "$rs1">, Sched<[WriteJalr, ReadJalr]>;
579 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
580 def C_ADD : RVInst16CR<0b1001, 0b10, (outs GPRNoX0:$rd),
581                        (ins GPRNoX0:$rs1, GPRNoX0:$rs2),
582                        "c.add", "$rs1, $rs2">,
583             Sched<[WriteIALU, ReadIALU, ReadIALU]> {
584   let Constraints = "$rs1 = $rd";
587 let Predicates = [HasStdExtCOrZcd, HasStdExtD] in
588 def C_FSDSP  : CStackStore<0b101, "c.fsdsp", FPR64, uimm9_lsb000>,
589                Sched<[WriteFST64, ReadFStoreData, ReadFMemBase]> {
590   let Inst{12-10} = imm{5-3};
591   let Inst{9-7}   = imm{8-6};
594 def C_SWSP : CStackStore<0b110, "c.swsp", GPR, uimm8_lsb00>,
595              Sched<[WriteSTW, ReadStoreData, ReadMemBase]> {
596   let Inst{12-9} = imm{5-2};
597   let Inst{8-7}  = imm{7-6};
600 let isCodeGenOnly = 1 in
601 def C_SWSP_INX : CStackStore<0b110, "c.swsp", GPRF32, uimm8_lsb00>,
602                  Sched<[WriteSTW, ReadStoreData, ReadMemBase]> {
603   let Inst{12-9} = imm{5-2};
604   let Inst{8-7}  = imm{7-6};
607 let DecoderNamespace = "RISCV32Only_",
608     Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in
609 def C_FSWSP  : CStackStore<0b111, "c.fswsp", FPR32, uimm8_lsb00>,
610                Sched<[WriteFST32, ReadFStoreData, ReadFMemBase]> {
611   let Inst{12-9} = imm{5-2};
612   let Inst{8-7}  = imm{7-6};
615 let Predicates = [HasStdExtCOrZca, IsRV64] in
616 def C_SDSP : CStackStore<0b111, "c.sdsp", GPR, uimm9_lsb000>,
617              Sched<[WriteSTD, ReadStoreData, ReadMemBase]> {
618   let Inst{12-10} = imm{5-3};
619   let Inst{9-7}   = imm{8-6};
622 // The all zeros pattern isn't a valid RISC-V instruction. It's used by GNU
623 // binutils as 16-bit instruction known to be unimplemented (i.e., trapping).
624 let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
625 def C_UNIMP : RVInst16<(outs), (ins), "c.unimp", "", [], InstFormatOther>,
626               Sched<[]> {
627   let Inst{15-0} = 0;
630 } // Predicates = [HasStdExtCOrZca]
632 //===----------------------------------------------------------------------===//
633 // HINT Instructions
634 //===----------------------------------------------------------------------===//
636 let Predicates = [HasStdExtCOrZca, HasRVCHints], hasSideEffects = 0, mayLoad = 0,
637     mayStore = 0 in {
639 def C_NOP_HINT : RVInst16CI<0b000, 0b01, (outs), (ins simm6nonzero:$imm),
640                             "c.nop", "$imm">, Sched<[WriteNop]> {
641   let rd = 0;
642   let Inst{6-2} = imm{4-0};
645 def C_ADDI_HINT_IMM_ZERO : RVInst16CI<0b000, 0b01, (outs GPRNoX0:$rd_wb),
646                                       (ins GPRNoX0:$rd, immzero:$imm),
647                                       "c.addi", "$rd, $imm">,
648                            Sched<[WriteIALU, ReadIALU]> {
649   let Constraints = "$rd = $rd_wb";
650   let Inst{12} = 0;
651   let Inst{6-2} = 0;
652   let DecoderMethod = "decodeRVCInstrRdRs1ImmZero";
655 def C_LI_HINT : RVInst16CI<0b010, 0b01, (outs GPRX0:$rd), (ins simm6:$imm),
656                            "c.li", "$rd, $imm">,
657                 Sched<[WriteIALU]> {
658   let Inst{6-2} = imm{4-0};
659   let Inst{11-7} = 0;
660   let DecoderMethod = "decodeRVCInstrRdSImm";
663 def C_LUI_HINT : RVInst16CI<0b011, 0b01, (outs GPRX0:$rd),
664                             (ins c_lui_imm:$imm),
665                             "c.lui", "$rd, $imm">,
666                  Sched<[WriteIALU]> {
667   let Inst{6-2} = imm{4-0};
668   let Inst{11-7} = 0;
669   let DecoderMethod = "decodeRVCInstrRdSImm";
672 def C_MV_HINT : RVInst16CR<0b1000, 0b10, (outs GPRX0:$rs1), (ins GPRNoX0:$rs2),
673                            "c.mv", "$rs1, $rs2">, Sched<[WriteIALU, ReadIALU]> {
674   let Inst{11-7} = 0;
675   let DecoderMethod = "decodeRVCInstrRdRs2";
678 def C_ADD_HINT : RVInst16CR<0b1001, 0b10, (outs GPRX0:$rd),
679                             (ins GPRX0:$rs1, GPRNoX0:$rs2),
680                             "c.add", "$rs1, $rs2">,
681                  Sched<[WriteIALU, ReadIALU, ReadIALU]> {
682   let Constraints = "$rs1 = $rd";
683   let Inst{11-7} = 0;
684   let DecoderMethod = "decodeRVCInstrRdRs1Rs2";
687 def C_SLLI_HINT : RVInst16CI<0b000, 0b10, (outs GPRX0:$rd_wb),
688                              (ins GPRX0:$rd, uimmlog2xlennonzero:$imm),
689                              "c.slli", "$rd, $imm">,
690                   Sched<[WriteShiftImm, ReadShiftImm]> {
691   let Constraints = "$rd = $rd_wb";
692   let Inst{6-2} = imm{4-0};
693   let Inst{11-7} = 0;
694   let DecoderMethod = "decodeRVCInstrRdRs1UImm";
697 def C_SLLI64_HINT : RVInst16CI<0b000, 0b10, (outs GPR:$rd_wb), (ins GPR:$rd),
698                                "c.slli64", "$rd">,
699                     Sched<[WriteShiftImm, ReadShiftImm]> {
700   let Constraints = "$rd = $rd_wb";
701   let Inst{6-2} = 0;
702   let Inst{12} = 0;
705 def C_SRLI64_HINT : RVInst16CB<0b100, 0b01, (outs GPRC:$rd),
706                                (ins GPRC:$rs1),
707                                "c.srli64", "$rs1">,
708                     Sched<[WriteShiftImm, ReadShiftImm]> {
709   let Constraints = "$rs1 = $rd";
710   let Inst{6-2} = 0;
711   let Inst{11-10} = 0b00;
712   let Inst{12} = 0;
715 def C_SRAI64_HINT : RVInst16CB<0b100, 0b01, (outs GPRC:$rd),
716                                (ins GPRC:$rs1),
717                                "c.srai64", "$rs1">,
718                     Sched<[WriteShiftImm, ReadShiftImm]> {
719   let Constraints = "$rs1 = $rd";
720   let Inst{6-2} = 0;
721   let Inst{11-10} = 0b01;
722   let Inst{12} = 0;
725 } // Predicates = [HasStdExtCOrZca, HasRVCHints], hasSideEffects = 0, mayLoad = 0,
726   // mayStore = 0
728 //===----------------------------------------------------------------------===//
729 // Assembler Pseudo Instructions
730 //===----------------------------------------------------------------------===//
732 let Predicates = [HasStdExtCOrZca, HasRVCHints] in {
733 // Just a different syntax for the c.nop hint: c.addi x0, simm6 vs c.nop simm6.
734 def : InstAlias<"c.addi x0, $imm", (C_NOP_HINT simm6nonzero:$imm), 0>;
737 let Predicates = [HasStdExtC, HasRVCHints, HasStdExtZihintntl] in {
738 def : InstAlias<"c.ntl.p1", (C_ADD_HINT X0, X2)>;
739 def : InstAlias<"c.ntl.pall", (C_ADD_HINT X0, X3)>;
740 def : InstAlias<"c.ntl.s1", (C_ADD_HINT X0, X4)>;
741 def : InstAlias<"c.ntl.all", (C_ADD_HINT X0, X5)>;
742 } // Predicates = [HasStdExtC, HasRVCHints, HasStdExtZihintntl]
744 let EmitPriority = 0 in {
745 let Predicates = [HasStdExtCOrZca] in {
746 def : InstAlias<"c.lw $rd, (${rs1})", (C_LW GPRC:$rd, GPRCMem:$rs1, 0)>;
747 def : InstAlias<"c.sw $rs2, (${rs1})", (C_SW GPRC:$rs2, GPRCMem:$rs1, 0)>;
748 def : InstAlias<"c.lwsp $rd, (${rs1})", (C_LWSP GPRNoX0:$rd, SPMem:$rs1, 0)>;
749 def : InstAlias<"c.swsp $rs2, (${rs1})", (C_SWSP GPRNoX0:$rs2, SPMem:$rs1, 0)>;
752 let Predicates = [HasStdExtCOrZca, IsRV64] in {
753 def : InstAlias<"c.ld $rd, (${rs1})", (C_LD GPRC:$rd, GPRCMem:$rs1, 0)>;
754 def : InstAlias<"c.sd $rs2, (${rs1})", (C_SD GPRC:$rs2, GPRCMem:$rs1, 0)>;
755 def : InstAlias<"c.ldsp $rd, (${rs1})", (C_LDSP GPRNoX0:$rd, SPMem:$rs1, 0)>;
756 def : InstAlias<"c.sdsp $rs2, (${rs1})", (C_SDSP GPRNoX0:$rs2, SPMem:$rs1, 0)>;
759 let Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in {
760 def : InstAlias<"c.flw $rd, (${rs1})", (C_FLW FPR32C:$rd, GPRCMem:$rs1, 0)>;
761 def : InstAlias<"c.fsw $rs2, (${rs1})", (C_FSW FPR32C:$rs2, GPRCMem:$rs1, 0)>;
762 def : InstAlias<"c.flwsp $rd, (${rs1})", (C_FLWSP FPR32:$rd, SPMem:$rs1, 0)>;
763 def : InstAlias<"c.fswsp $rs2, (${rs1})", (C_FSWSP FPR32:$rs2, SPMem:$rs1, 0)>;
766 let Predicates = [HasStdExtCOrZcd, HasStdExtD] in {
767 def : InstAlias<"c.fld $rd, (${rs1})", (C_FLD FPR64C:$rd, GPRCMem:$rs1, 0)>;
768 def : InstAlias<"c.fsd $rs2, (${rs1})", (C_FSD FPR64C:$rs2, GPRCMem:$rs1, 0)>;
769 def : InstAlias<"c.fldsp $rd, (${rs1})", (C_FLDSP FPR64:$rd, SPMem:$rs1, 0)>;
770 def : InstAlias<"c.fsdsp $rs2, (${rs1})", (C_FSDSP FPR64:$rs2, SPMem:$rs1, 0)>;
772 } // EmitPriority = 0
774 //===----------------------------------------------------------------------===//
775 // .insn directive instructions
776 //===----------------------------------------------------------------------===//
778 def AnyRegCOperand : AsmOperandClass {
779   let Name = "AnyRegCOperand";
780   let RenderMethod = "addRegOperands";
781   let PredicateMethod = "isAnyRegC";
784 def AnyRegC : Operand<XLenVT> {
785   let OperandType = "OPERAND_REGISTER";
786   let ParserMatchClass = AnyRegCOperand;
789 // isCodeGenOnly = 1 to hide them from the tablegened assembly parser.
790 let isCodeGenOnly = 1, hasSideEffects = 1, mayLoad = 1, mayStore = 1,
791     hasNoSchedulingInfo = 1, Predicates = [HasStdExtCOrZca] in {
792 def InsnCR : DirectiveInsnCR<(outs AnyReg:$rd), (ins uimm2_opcode:$opcode,
793                                                      uimm4:$funct4,
794                                                      AnyReg:$rs2),
795                              "$opcode, $funct4, $rd, $rs2">;
796 def InsnCI : DirectiveInsnCI<(outs AnyReg:$rd), (ins uimm2_opcode:$opcode,
797                                                      uimm3:$funct3,
798                                                      simm6:$imm6),
799                              "$opcode, $funct3, $rd, $imm6">;
800 def InsnCIW : DirectiveInsnCIW<(outs AnyRegC:$rd), (ins uimm2_opcode:$opcode,
801                                                         uimm3:$funct3,
802                                                         uimm8:$imm8),
803                                "$opcode, $funct3, $rd, $imm8">;
804 def InsnCSS : DirectiveInsnCSS<(outs), (ins uimm2_opcode:$opcode,
805                                             uimm3:$funct3,
806                                             AnyReg:$rs2,
807                                             uimm6:$imm6),
808                                "$opcode, $funct3, $rs2, $imm6">;
809 def InsnCL : DirectiveInsnCL<(outs AnyRegC:$rd), (ins uimm2_opcode:$opcode,
810                                                       uimm3:$funct3,
811                                                       AnyRegC:$rs1,
812                                                       uimm5:$imm5),
813                              "$opcode, $funct3, $rd, ${imm5}(${rs1})">;
814 def InsnCS : DirectiveInsnCS<(outs), (ins uimm2_opcode:$opcode,
815                                           uimm3:$funct3,
816                                           AnyRegC:$rs2,
817                                           AnyRegC:$rs1,
818                                           uimm5:$imm5),
819                              "$opcode, $funct3, $rs2, ${imm5}(${rs1})">;
820 def InsnCA : DirectiveInsnCA<(outs AnyRegC:$rd), (ins uimm2_opcode:$opcode,
821                                                       uimm6:$funct6,
822                                                       uimm2:$funct2,
823                                                       AnyRegC:$rs2),
824                              "$opcode, $funct6, $funct2, $rd, $rs2">;
825 def InsnCB : DirectiveInsnCB<(outs), (ins uimm2_opcode:$opcode, uimm3:$funct3,
826                                           AnyRegC:$rs1,
827                                           simm9_lsb0:$imm8),
828                              "$opcode, $funct3, $rs1, $imm8">;
829 def InsnCJ : DirectiveInsnCJ<(outs), (ins uimm2_opcode:$opcode,
830                                           uimm3:$funct3,
831                                           simm12_lsb0:$imm11),
832                              "$opcode, $funct3, $imm11">;
833 def Insn16 : RVInst16<(outs), (ins uimm16:$value), "", "", [], InstFormatOther> {
834   bits<16> value;
836   let Inst{15-0} = value;
837   let AsmString = ".insn 0x2, $value";
841 // Use InstAliases to match these so that we can combine the insn and format
842 // into a mnemonic to use as the key for the tablegened asm matcher table. The
843 // parser will take care of creating these fake mnemonics and will only do it
844 // for known formats.
845 let EmitPriority = 0, Predicates = [HasStdExtCOrZca] in {
846 def : InstAlias<".insn_cr $opcode, $funct4, $rd, $rs2",
847                 (InsnCR AnyReg:$rd, uimm2_opcode:$opcode, uimm4:$funct4,
848                         AnyReg:$rs2)>;
849 def : InstAlias<".insn_ci $opcode, $funct3, $rd, $imm6",
850                 (InsnCI AnyReg:$rd, uimm2_opcode:$opcode, uimm3:$funct3,
851                         simm6:$imm6)>;
852 def : InstAlias<".insn_ciw $opcode, $funct3, $rd, $imm8",
853                 (InsnCIW AnyRegC:$rd, uimm2_opcode:$opcode, uimm3:$funct3,
854                          uimm8:$imm8)>;
855 def : InstAlias<".insn_css $opcode, $funct3, $rs2, $imm6",
856                 (InsnCSS uimm2_opcode:$opcode, uimm3:$funct3, AnyReg:$rs2,
857                          uimm6:$imm6)>;
858 def : InstAlias<".insn_cl $opcode, $funct3, $rd, ${imm5}(${rs1})",
859                 (InsnCL AnyRegC:$rd, uimm2_opcode:$opcode, uimm3:$funct3,
860                         AnyRegC:$rs1, uimm5:$imm5)>;
861 def : InstAlias<".insn_cl $opcode, $funct3, $rd, (${rs1})",
862                 (InsnCL AnyRegC:$rd, uimm2_opcode:$opcode, uimm3:$funct3,
863                         AnyRegC:$rs1, 0)>;
864 def : InstAlias<".insn_cs $opcode, $funct3, $rs2, ${imm5}(${rs1})",
865                 (InsnCS uimm2_opcode:$opcode, uimm3:$funct3, AnyRegC:$rs2,
866                         AnyRegC:$rs1, uimm5:$imm5)>;
867 def : InstAlias<".insn_cs $opcode, $funct3, $rs2, (${rs1})",
868                 (InsnCS uimm2_opcode:$opcode, uimm3:$funct3, AnyRegC:$rs2,
869                         AnyRegC:$rs1, 0)>;
870 def : InstAlias<".insn_ca $opcode, $funct6, $funct2, $rd, $rs2",
871                 (InsnCA AnyRegC:$rd, uimm2_opcode:$opcode, uimm6:$funct6,
872                         uimm2:$funct2, AnyRegC:$rs2)>;
873 def : InstAlias<".insn_cb $opcode, $funct3, $rs1, $imm8",
874                 (InsnCB uimm2_opcode:$opcode, uimm3:$funct3, AnyRegC:$rs1,
875                         simm9_lsb0:$imm8)>;
876 def : InstAlias<".insn_cj $opcode, $funct3, $imm11",
877                 (InsnCJ uimm2_opcode:$opcode, uimm3:$funct3, simm12_lsb0:$imm11)>;
880 //===----------------------------------------------------------------------===/i
881 // Compress Instruction tablegen backend.
882 //===----------------------------------------------------------------------===//
884 // Patterns are defined in the same order the compressed instructions appear
885 // under the "RVC Instruction Set Listings" section of the ISA manual.
887 // Quadrant 0
888 let Predicates = [HasStdExtCOrZca] in {
889 def : CompressPat<(ADDI GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm),
890                   (C_ADDI4SPN GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm)>;
891 } // Predicates = [HasStdExtCOrZca]
893 let Predicates = [HasStdExtCOrZcd, HasStdExtD] in {
894 def : CompressPat<(FLD FPR64C:$rd, GPRCMem:$rs1, uimm8_lsb000:$imm),
895                   (C_FLD FPR64C:$rd, GPRCMem:$rs1, uimm8_lsb000:$imm)>;
896 } // Predicates = [HasStdExtCOrZcd, HasStdExtD]
898 let Predicates = [HasStdExtCOrZca] in {
899 def : CompressPat<(LW GPRC:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm),
900                   (C_LW GPRC:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm)>;
902 let isCompressOnly = true in
903 def : CompressPat<(LW_INX GPRF32C:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm),
904                   (C_LW_INX GPRF32C:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm)>;
905 } // Predicates = [HasStdExtCOrZca]
907 let Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in {
908 def : CompressPat<(FLW FPR32C:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm),
909                   (C_FLW FPR32C:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm)>;
910 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
912 let Predicates = [HasStdExtCOrZca, IsRV64] in {
913 def : CompressPat<(LD GPRC:$rd, GPRCMem:$rs1, uimm8_lsb000:$imm),
914                   (C_LD GPRC:$rd, GPRCMem:$rs1, uimm8_lsb000:$imm)>;
915 } // Predicates = [HasStdExtCOrZca, IsRV64]
917 let Predicates = [HasStdExtCOrZcd, HasStdExtD] in {
918 def : CompressPat<(FSD FPR64C:$rs2, GPRCMem:$rs1, uimm8_lsb000:$imm),
919                   (C_FSD FPR64C:$rs2, GPRCMem:$rs1, uimm8_lsb000:$imm)>;
920 } // Predicates = [HasStdExtCOrZcd, HasStdExtD]
922 let Predicates = [HasStdExtCOrZca] in {
923 def : CompressPat<(SW GPRC:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm),
924                   (C_SW GPRC:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm)>;
926 let isCompressOnly = true in
927 def : CompressPat<(SW_INX GPRF32C:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm),
928                   (C_SW_INX GPRF32C:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm)>;
929 } // Predicates = [HasStdExtCOrZca]
931 let Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in {
932 def : CompressPat<(FSW FPR32C:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm),
933                   (C_FSW FPR32C:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm)>;
934 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
936 let Predicates = [HasStdExtCOrZca, IsRV64] in {
937 def : CompressPat<(SD GPRC:$rs2, GPRCMem:$rs1, uimm8_lsb000:$imm),
938                   (C_SD GPRC:$rs2, GPRCMem:$rs1, uimm8_lsb000:$imm)>;
939 } // Predicates = [HasStdExtCOrZca, IsRV64]
941 // Quadrant 1
942 let Predicates = [HasStdExtCOrZca] in {
943 def : CompressPat<(ADDI X0, X0, 0), (C_NOP)>;
944 def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs1, simm6nonzero:$imm),
945                   (C_ADDI GPRNoX0:$rs1, simm6nonzero:$imm)>;
946 } // Predicates = [HasStdExtCOrZca]
948 let Predicates = [HasStdExtCOrZca, IsRV32] in {
949 def : CompressPat<(JAL X1, simm12_lsb0:$offset),
950                   (C_JAL simm12_lsb0:$offset)>;
951 } // Predicates = [HasStdExtCOrZca, IsRV32]
953 let Predicates = [HasStdExtCOrZca, IsRV64] in {
954 def : CompressPat<(ADDIW GPRNoX0:$rs1, GPRNoX0:$rs1, simm6:$imm),
955                   (C_ADDIW GPRNoX0:$rs1, simm6:$imm)>;
956 } // Predicates = [HasStdExtCOrZca, IsRV64]
958 let Predicates = [HasStdExtCOrZca] in {
959 def : CompressPat<(ADDI GPRNoX0:$rd, X0, simm6:$imm),
960                   (C_LI GPRNoX0:$rd, simm6:$imm)>;
961 def : CompressPat<(ADDI X2, X2, simm10_lsb0000nonzero:$imm),
962                   (C_ADDI16SP X2, simm10_lsb0000nonzero:$imm)>;
963 def : CompressPat<(LUI GPRNoX0X2:$rd, c_lui_imm:$imm),
964                   (C_LUI GPRNoX0X2:$rd, c_lui_imm:$imm)>;
965 def : CompressPat<(SRLI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm),
966                   (C_SRLI GPRC:$rs1, uimmlog2xlennonzero:$imm)>;
967 def : CompressPat<(SRAI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm),
968                   (C_SRAI GPRC:$rs1, uimmlog2xlennonzero:$imm)>;
969 def : CompressPat<(ANDI GPRC:$rs1, GPRC:$rs1, simm6:$imm),
970                   (C_ANDI GPRC:$rs1, simm6:$imm)>;
971 def : CompressPat<(SUB GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
972                   (C_SUB GPRC:$rs1, GPRC:$rs2)>;
973 def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
974                   (C_XOR GPRC:$rs1, GPRC:$rs2)>;
975 let isCompressOnly = true in
976 def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
977                   (C_XOR GPRC:$rs1, GPRC:$rs2)>;
978 def : CompressPat<(OR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
979                   (C_OR GPRC:$rs1, GPRC:$rs2)>;
980 let isCompressOnly = true in
981 def : CompressPat<(OR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
982                   (C_OR GPRC:$rs1, GPRC:$rs2)>;
983 def : CompressPat<(AND GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
984                   (C_AND GPRC:$rs1, GPRC:$rs2)>;
985 let isCompressOnly = true in
986 def : CompressPat<(AND GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
987                   (C_AND GPRC:$rs1, GPRC:$rs2)>;
988 } // Predicates = [HasStdExtCOrZca]
990 let Predicates = [HasStdExtCOrZca, IsRV64] in {
991 let isCompressOnly = true in
992 def : CompressPat<(ADDIW GPRNoX0:$rd, X0, simm6:$imm),
993                   (C_LI GPRNoX0:$rd, simm6:$imm)>;
994 def : CompressPat<(SUBW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
995                   (C_SUBW GPRC:$rs1, GPRC:$rs2)>;
996 def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
997                    (C_ADDW GPRC:$rs1, GPRC:$rs2)>;
998 let isCompressOnly = true in
999 def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
1000                    (C_ADDW GPRC:$rs1, GPRC:$rs2)>;
1001 } // Predicates = [HasStdExtCOrZca, IsRV64]
1003 let Predicates = [HasStdExtCOrZca] in {
1004 def : CompressPat<(JAL X0, simm12_lsb0:$offset),
1005                   (C_J simm12_lsb0:$offset)>;
1006 def : CompressPat<(BEQ GPRC:$rs1, X0, simm9_lsb0:$imm),
1007                   (C_BEQZ GPRC:$rs1, simm9_lsb0:$imm)>;
1008 let isCompressOnly = true in
1009 def : CompressPat<(BEQ X0, GPRC:$rs1, simm9_lsb0:$imm),
1010                   (C_BEQZ GPRC:$rs1, simm9_lsb0:$imm)>;
1011 def : CompressPat<(BNE GPRC:$rs1, X0, simm9_lsb0:$imm),
1012                   (C_BNEZ GPRC:$rs1, simm9_lsb0:$imm)>;
1013 let isCompressOnly = true in
1014 def : CompressPat<(BNE X0, GPRC:$rs1, simm9_lsb0:$imm),
1015                   (C_BNEZ GPRC:$rs1, simm9_lsb0:$imm)>;
1016 } // Predicates = [HasStdExtCOrZca]
1018 // Quadrant 2
1019 let Predicates = [HasStdExtCOrZca] in {
1020 def : CompressPat<(SLLI GPRNoX0:$rs1, GPRNoX0:$rs1, uimmlog2xlennonzero:$imm),
1021                   (C_SLLI GPRNoX0:$rs1, uimmlog2xlennonzero:$imm)>;
1022 } // Predicates = [HasStdExtCOrZca]
1024 let Predicates = [HasStdExtCOrZcd, HasStdExtD] in {
1025 def : CompressPat<(FLD FPR64:$rd, SPMem:$rs1, uimm9_lsb000:$imm),
1026                   (C_FLDSP FPR64:$rd, SPMem:$rs1, uimm9_lsb000:$imm)>;
1027 } // Predicates = [HasStdExtCOrZcd, HasStdExtD]
1029 let Predicates = [HasStdExtCOrZca] in {
1030 def : CompressPat<(LW GPRNoX0:$rd, SPMem:$rs1,  uimm8_lsb00:$imm),
1031                   (C_LWSP GPRNoX0:$rd, SPMem:$rs1, uimm8_lsb00:$imm)>;
1033 let isCompressOnly = true in
1034 def : CompressPat<(LW_INX GPRF32NoX0:$rd, SPMem:$rs1,  uimm8_lsb00:$imm),
1035                   (C_LWSP_INX GPRF32NoX0:$rd, SPMem:$rs1, uimm8_lsb00:$imm)>;
1036 } // Predicates = [HasStdExtCOrZca]
1038 let Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in {
1039 def : CompressPat<(FLW FPR32:$rd, SPMem:$rs1, uimm8_lsb00:$imm),
1040                   (C_FLWSP FPR32:$rd, SPMem:$rs1, uimm8_lsb00:$imm)>;
1041 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
1043 let Predicates = [HasStdExtCOrZca, IsRV64] in {
1044 def : CompressPat<(LD GPRNoX0:$rd, SPMem:$rs1, uimm9_lsb000:$imm),
1045                   (C_LDSP GPRNoX0:$rd, SPMem:$rs1, uimm9_lsb000:$imm)>;
1046 } // Predicates = [HasStdExtCOrZca, IsRV64]
1048 let Predicates = [HasStdExtCOrZca] in {
1049 def : CompressPat<(JALR X0, GPRNoX0:$rs1, 0),
1050                   (C_JR GPRNoX0:$rs1)>;
1051 let isCompressOnly = true in {
1052 def : CompressPat<(ADD GPRNoX0:$rs1, X0, GPRNoX0:$rs2),
1053                   (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
1054 def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, X0),
1055                   (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
1057 def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs2, 0),
1058                   (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
1059 def : CompressPat<(EBREAK), (C_EBREAK)>;
1060 def : CompressPat<(UNIMP), (C_UNIMP)>;
1061 def : CompressPat<(JALR X1, GPRNoX0:$rs1, 0),
1062                   (C_JALR GPRNoX0:$rs1)>;
1063 def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs1, GPRNoX0:$rs2),
1064                   (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
1065 let isCompressOnly = true in
1066 def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, GPRNoX0:$rs1),
1067                   (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
1068 } // Predicates = [HasStdExtCOrZca]
1070 let Predicates = [HasStdExtCOrZcd, HasStdExtD] in {
1071 def : CompressPat<(FSD FPR64:$rs2, SPMem:$rs1, uimm9_lsb000:$imm),
1072                   (C_FSDSP FPR64:$rs2, SPMem:$rs1, uimm9_lsb000:$imm)>;
1073 } // Predicates = [HasStdExtCOrZcd, HasStdExtD]
1075 let Predicates = [HasStdExtCOrZca] in {
1076 def : CompressPat<(SW GPR:$rs2, SPMem:$rs1, uimm8_lsb00:$imm),
1077                   (C_SWSP GPR:$rs2, SPMem:$rs1, uimm8_lsb00:$imm)>;
1079 let isCompressOnly = true in
1080 def : CompressPat<(SW_INX GPRF32:$rs2, SPMem:$rs1, uimm8_lsb00:$imm),
1081                   (C_SWSP_INX GPRF32:$rs2, SPMem:$rs1, uimm8_lsb00:$imm)>;
1082 } // Predicates = [HasStdExtCOrZca]
1084 let Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in {
1085 def : CompressPat<(FSW FPR32:$rs2, SPMem:$rs1, uimm8_lsb00:$imm),
1086                   (C_FSWSP FPR32:$rs2, SPMem:$rs1, uimm8_lsb00:$imm)>;
1087 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
1089 let Predicates = [HasStdExtCOrZca, IsRV64] in {
1090 def : CompressPat<(SD GPR:$rs2, SPMem:$rs1, uimm9_lsb000:$imm),
1091                   (C_SDSP GPR:$rs2, SPMem:$rs1, uimm9_lsb000:$imm)>;
1092 } // Predicates = [HasStdExtCOrZca, IsRV64]