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