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