RISCVInstrInfoC.td revision 360784
1//===- RISCVInstrInfoC.td - Compressed RISCV instructions -*- tblgen-*-----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9include "RISCVInstrFormatsC.td"
10
11//===----------------------------------------------------------------------===//
12// Operand definitions.
13//===----------------------------------------------------------------------===//
14
15def UImmLog2XLenNonZeroAsmOperand : AsmOperandClass {
16  let Name = "UImmLog2XLenNonZero";
17  let RenderMethod = "addImmOperands";
18  let DiagnosticType = "InvalidUImmLog2XLenNonZero";
19}
20
21def uimmlog2xlennonzero : Operand<XLenVT>, ImmLeaf<XLenVT, [{
22  if (Subtarget->is64Bit())
23    return isUInt<6>(Imm) && (Imm != 0);
24  return isUInt<5>(Imm) && (Imm != 0);
25}]> {
26  let ParserMatchClass = UImmLog2XLenNonZeroAsmOperand;
27  // TODO: should ensure invalid shamt is rejected when decoding.
28  let DecoderMethod = "decodeUImmOperand<6>";
29  let MCOperandPredicate = [{
30    int64_t Imm;
31    if (!MCOp.evaluateAsConstantImm(Imm))
32      return false;
33    if (STI.getTargetTriple().isArch64Bit())
34      return  isUInt<6>(Imm) && (Imm != 0);
35    return isUInt<5>(Imm) && (Imm != 0);
36  }];
37}
38
39def simm6 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isInt<6>(Imm);}]> {
40  let ParserMatchClass = SImmAsmOperand<6>;
41  let EncoderMethod = "getImmOpValue";
42  let DecoderMethod = "decodeSImmOperand<6>";
43  let MCOperandPredicate = [{
44    int64_t Imm;
45    if (MCOp.evaluateAsConstantImm(Imm))
46      return isInt<6>(Imm);
47    return MCOp.isBareSymbolRef();
48  }];
49}
50
51def simm6nonzero : Operand<XLenVT>,
52                   ImmLeaf<XLenVT, [{return (Imm != 0) && isInt<6>(Imm);}]> {
53  let ParserMatchClass = SImmAsmOperand<6, "NonZero">;
54  let EncoderMethod = "getImmOpValue";
55  let DecoderMethod = "decodeSImmOperand<6>";
56  let MCOperandPredicate = [{
57    int64_t Imm;
58    if (MCOp.evaluateAsConstantImm(Imm))
59      return (Imm != 0) && isInt<6>(Imm);
60    return MCOp.isBareSymbolRef();
61  }];
62}
63
64def immzero : Operand<XLenVT>,
65              ImmLeaf<XLenVT, [{return (Imm == 0);}]> {
66  let ParserMatchClass = ImmZeroAsmOperand;
67}
68
69def CLUIImmAsmOperand : AsmOperandClass {
70  let Name = "CLUIImm";
71  let RenderMethod = "addImmOperands";
72  let DiagnosticType = !strconcat("Invalid", Name);
73}
74
75
76// c_lui_imm checks the immediate range is in [1, 31] or [0xfffe0, 0xfffff].
77// The RISC-V ISA describes the constraint as [1, 63], with that value being
78// loaded in to bits 17-12 of the destination register and sign extended from
79// bit 17. Therefore, this 6-bit immediate can represent values in the ranges
80// [1, 31] and [0xfffe0, 0xfffff].
81def c_lui_imm : Operand<XLenVT>,
82                ImmLeaf<XLenVT, [{return (Imm != 0) &&
83                                 (isUInt<5>(Imm) ||
84                                  (Imm >= 0xfffe0 && Imm <= 0xfffff));}]> {
85  let ParserMatchClass = CLUIImmAsmOperand;
86  let EncoderMethod = "getImmOpValue";
87  let DecoderMethod = "decodeCLUIImmOperand";
88  let MCOperandPredicate = [{
89    int64_t Imm;
90    if (MCOp.evaluateAsConstantImm(Imm))
91      return (Imm != 0) && (isUInt<5>(Imm) ||
92             (Imm >= 0xfffe0 && Imm <= 0xfffff));
93    return MCOp.isBareSymbolRef();
94  }];
95}
96
97// A 7-bit unsigned immediate where the least significant two bits are zero.
98def uimm7_lsb00 : Operand<XLenVT>,
99                  ImmLeaf<XLenVT, [{return isShiftedUInt<5, 2>(Imm);}]> {
100  let ParserMatchClass = UImmAsmOperand<7, "Lsb00">;
101  let EncoderMethod = "getImmOpValue";
102  let DecoderMethod = "decodeUImmOperand<7>";
103  let MCOperandPredicate = [{
104    int64_t Imm;
105    if (!MCOp.evaluateAsConstantImm(Imm))
106      return false;
107    return isShiftedUInt<5, 2>(Imm);
108  }];
109}
110
111// A 8-bit unsigned immediate where the least significant two bits are zero.
112def uimm8_lsb00 : Operand<XLenVT>,
113                  ImmLeaf<XLenVT, [{return isShiftedUInt<6, 2>(Imm);}]> {
114  let ParserMatchClass = UImmAsmOperand<8, "Lsb00">;
115  let EncoderMethod = "getImmOpValue";
116  let DecoderMethod = "decodeUImmOperand<8>";
117  let MCOperandPredicate = [{
118    int64_t Imm;
119    if (!MCOp.evaluateAsConstantImm(Imm))
120      return false;
121    return isShiftedUInt<6, 2>(Imm);
122  }];
123}
124
125// A 8-bit unsigned immediate where the least significant three bits are zero.
126def uimm8_lsb000 : Operand<XLenVT>,
127                   ImmLeaf<XLenVT, [{return isShiftedUInt<5, 3>(Imm);}]> {
128  let ParserMatchClass = UImmAsmOperand<8, "Lsb000">;
129  let EncoderMethod = "getImmOpValue";
130  let DecoderMethod = "decodeUImmOperand<8>";
131  let MCOperandPredicate = [{
132    int64_t Imm;
133    if (!MCOp.evaluateAsConstantImm(Imm))
134      return false;
135    return isShiftedUInt<5, 3>(Imm);
136  }];
137}
138
139// A 9-bit signed immediate where the least significant bit is zero.
140def simm9_lsb0 : Operand<OtherVT>,
141                 ImmLeaf<XLenVT, [{return isShiftedInt<8, 1>(Imm);}]> {
142  let ParserMatchClass = SImmAsmOperand<9, "Lsb0">;
143  let EncoderMethod = "getImmOpValueAsr1";
144  let DecoderMethod = "decodeSImmOperandAndLsl1<9>";
145  let MCOperandPredicate = [{
146    int64_t Imm;
147    if (MCOp.evaluateAsConstantImm(Imm))
148      return isShiftedInt<8, 1>(Imm);
149    return MCOp.isBareSymbolRef();
150
151  }];
152}
153
154// A 9-bit unsigned immediate where the least significant three bits are zero.
155def uimm9_lsb000 : Operand<XLenVT>,
156                   ImmLeaf<XLenVT, [{return isShiftedUInt<6, 3>(Imm);}]> {
157  let ParserMatchClass = UImmAsmOperand<9, "Lsb000">;
158  let EncoderMethod = "getImmOpValue";
159  let DecoderMethod = "decodeUImmOperand<9>";
160  let MCOperandPredicate = [{
161    int64_t Imm;
162    if (!MCOp.evaluateAsConstantImm(Imm))
163      return false;
164    return isShiftedUInt<6, 3>(Imm);
165  }];
166}
167
168// A 10-bit unsigned immediate where the least significant two bits are zero
169// and the immediate can't be zero.
170def uimm10_lsb00nonzero : Operand<XLenVT>,
171                          ImmLeaf<XLenVT,
172                          [{return isShiftedUInt<8, 2>(Imm) && (Imm != 0);}]> {
173  let ParserMatchClass = UImmAsmOperand<10, "Lsb00NonZero">;
174  let EncoderMethod = "getImmOpValue";
175  let DecoderMethod = "decodeUImmNonZeroOperand<10>";
176  let MCOperandPredicate = [{
177    int64_t Imm;
178    if (!MCOp.evaluateAsConstantImm(Imm))
179      return false;
180    return isShiftedUInt<8, 2>(Imm) && (Imm != 0);
181  }];
182}
183
184// A 10-bit signed immediate where the least significant four bits are zero.
185def simm10_lsb0000nonzero : Operand<XLenVT>,
186                            ImmLeaf<XLenVT,
187                            [{return (Imm != 0) && isShiftedInt<6, 4>(Imm);}]> {
188  let ParserMatchClass = SImmAsmOperand<10, "Lsb0000NonZero">;
189  let EncoderMethod = "getImmOpValue";
190  let DecoderMethod = "decodeSImmNonZeroOperand<10>";
191  let MCOperandPredicate = [{
192    int64_t Imm;
193    if (!MCOp.evaluateAsConstantImm(Imm))
194      return false;
195    return isShiftedInt<6, 4>(Imm) && (Imm != 0);
196  }];
197}
198
199// A 12-bit signed immediate where the least significant bit is zero.
200def simm12_lsb0 : Operand<XLenVT>,
201                  ImmLeaf<XLenVT, [{return isShiftedInt<11, 1>(Imm);}]> {
202  let ParserMatchClass = SImmAsmOperand<12, "Lsb0">;
203  let EncoderMethod = "getImmOpValueAsr1";
204  let DecoderMethod = "decodeSImmOperandAndLsl1<12>";
205  let MCOperandPredicate = [{
206    int64_t Imm;
207    if (MCOp.evaluateAsConstantImm(Imm))
208      return isShiftedInt<11, 1>(Imm);
209    return MCOp.isBareSymbolRef();
210  }];
211}
212
213//===----------------------------------------------------------------------===//
214// Instruction Class Templates
215//===----------------------------------------------------------------------===//
216
217let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
218class CStackLoad<bits<3> funct3, string OpcodeStr,
219                 RegisterClass cls, DAGOperand opnd>
220    : RVInst16CI<funct3, 0b10, (outs cls:$rd), (ins SP:$rs1, opnd:$imm),
221                 OpcodeStr, "$rd, ${imm}(${rs1})">;
222
223let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
224class CStackStore<bits<3> funct3, string OpcodeStr,
225                  RegisterClass cls, DAGOperand opnd>
226    : RVInst16CSS<funct3, 0b10, (outs), (ins cls:$rs2, SP:$rs1, opnd:$imm),
227                  OpcodeStr, "$rs2, ${imm}(${rs1})">;
228
229let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
230class CLoad_ri<bits<3> funct3, string OpcodeStr,
231               RegisterClass cls, DAGOperand opnd>
232    : RVInst16CL<funct3, 0b00, (outs cls:$rd), (ins GPRC:$rs1, opnd:$imm),
233                 OpcodeStr, "$rd, ${imm}(${rs1})">;
234
235let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
236class CStore_rri<bits<3> funct3, string OpcodeStr,
237                 RegisterClass cls, DAGOperand opnd>
238    : RVInst16CS<funct3, 0b00, (outs), (ins cls:$rs2, GPRC:$rs1, opnd:$imm),
239                 OpcodeStr, "$rs2, ${imm}(${rs1})">;
240
241let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
242class Bcz<bits<3> funct3, string OpcodeStr, PatFrag CondOp,
243          RegisterClass cls>
244    : RVInst16CB<funct3, 0b01, (outs), (ins cls:$rs1, simm9_lsb0:$imm),
245                 OpcodeStr, "$rs1, $imm"> {
246  let isBranch = 1;
247  let isTerminator = 1;
248  let Inst{12} = imm{7};
249  let Inst{11-10} = imm{3-2};
250  let Inst{6-5} = imm{6-5};
251  let Inst{4-3} = imm{1-0};
252  let Inst{2} = imm{4};
253}
254
255let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
256class Shift_right<bits<2> funct2, string OpcodeStr, RegisterClass cls,
257                  Operand ImmOpnd>
258    : RVInst16CB<0b100, 0b01, (outs cls:$rs1_wb), (ins cls:$rs1, ImmOpnd:$imm),
259                 OpcodeStr, "$rs1, $imm"> {
260  let Constraints = "$rs1 = $rs1_wb";
261  let Inst{12} = imm{5};
262  let Inst{11-10} = funct2;
263  let Inst{6-2} = imm{4-0};
264}
265
266let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
267class CS_ALU<bits<6> funct6, bits<2> funct2, string OpcodeStr,
268             RegisterClass cls>
269    : RVInst16CA<funct6, funct2, 0b01, (outs cls:$rd_wb), (ins cls:$rd, cls:$rs2),
270                 OpcodeStr, "$rd, $rs2"> {
271  bits<3> rd;
272  let Constraints = "$rd = $rd_wb";
273  let Inst{9-7} = rd;
274}
275
276//===----------------------------------------------------------------------===//
277// Instructions
278//===----------------------------------------------------------------------===//
279
280let Predicates = [HasStdExtC] in {
281
282let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Uses = [X2] in
283def C_ADDI4SPN : RVInst16CIW<0b000, 0b00, (outs GPRC:$rd),
284                             (ins SP:$rs1, uimm10_lsb00nonzero:$imm),
285                             "c.addi4spn", "$rd, $rs1, $imm">,
286                             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
294let Predicates = [HasStdExtC, HasStdExtD] in
295def 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
302def 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
310let DecoderNamespace = "RISCV32Only_",
311    Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
312def 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
320let Predicates = [HasStdExtC, IsRV64] in
321def 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
328let Predicates = [HasStdExtC, HasStdExtD] in
329def 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
336def 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
344let DecoderNamespace = "RISCV32Only_",
345    Predicates = [HasStdExtC, HasStdExtF, IsRV32]  in
346def 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
354let Predicates = [HasStdExtC, IsRV64] in
355def 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
362let rd = 0, imm = 0, hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
363def C_NOP : RVInst16CI<0b000, 0b01, (outs), (ins), "c.nop", "">,
364            Sched<[WriteNop]>
365{
366  let Inst{6-2} = 0;
367}
368
369let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
370def 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
378let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
379def 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
388let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCall = 1,
389    DecoderNamespace = "RISCV32Only_", Defs = [X1],
390    Predicates = [HasStdExtC, IsRV32]  in
391def C_JAL : RVInst16CJ<0b001, 0b01, (outs), (ins simm12_lsb0:$offset),
392                       "c.jal", "$offset">, Sched<[WriteJal]>;
393
394let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
395    Predicates = [HasStdExtC, IsRV64] in
396def 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
404let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
405def 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
411let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
412def 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
425let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
426def 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
433def C_SRLI : Shift_right<0b00, "c.srli", GPRC, uimmlog2xlennonzero>,
434             Sched<[WriteShift, ReadShift]>;
435def C_SRAI : Shift_right<0b01, "c.srai", GPRC, uimmlog2xlennonzero>,
436             Sched<[WriteShift, ReadShift]>;
437
438let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
439def 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
448def C_SUB  : CS_ALU<0b100011, 0b00, "c.sub", GPRC>,
449             Sched<[WriteIALU, ReadIALU, ReadIALU]>;
450def C_XOR  : CS_ALU<0b100011, 0b01, "c.xor", GPRC>,
451             Sched<[WriteIALU, ReadIALU, ReadIALU]>;
452def C_OR   : CS_ALU<0b100011, 0b10, "c.or" , GPRC>,
453             Sched<[WriteIALU, ReadIALU, ReadIALU]>;
454def C_AND  : CS_ALU<0b100011, 0b11, "c.and", GPRC>,
455             Sched<[WriteIALU, ReadIALU, ReadIALU]>;
456
457let Predicates = [HasStdExtC, IsRV64] in {
458def C_SUBW : CS_ALU<0b100111, 0b00, "c.subw", GPRC>,
459             Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>;
460def C_ADDW : CS_ALU<0b100111, 0b01, "c.addw", GPRC>,
461             Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>;
462}
463
464let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
465def 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
472def C_BEQZ : Bcz<0b110, "c.beqz",  seteq, GPRC>, Sched<[WriteJmp]>;
473def C_BNEZ : Bcz<0b111, "c.bnez",  setne, GPRC>, Sched<[WriteJmp]>;
474
475let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
476def 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
484let Predicates = [HasStdExtC, HasStdExtD] in
485def 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
491def 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
497let DecoderNamespace = "RISCV32Only_",
498    Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
499def 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
505let Predicates = [HasStdExtC, IsRV64] in
506def 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
512let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
513def 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
522let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
523def C_MV : RVInst16CR<0b1000, 0b10, (outs GPRNoX0:$rs1), (ins GPRNoX0:$rs2),
524                      "c.mv", "$rs1, $rs2">,
525           Sched<[WriteIALU, ReadIALU]>;
526
527let rs1 = 0, rs2 = 0, hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
528def C_EBREAK : RVInst16CR<0b1001, 0b10, (outs), (ins), "c.ebreak", "">, Sched<[]>;
529
530let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
531    isCall=1, Defs=[X1], rs2 = 0 in
532def C_JALR : RVInst16CR<0b1001, 0b10, (outs), (ins GPRNoX0:$rs1),
533                        "c.jalr", "$rs1">, Sched<[WriteJalr, ReadJalr]>;
534
535let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
536def 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
543let Predicates = [HasStdExtC, HasStdExtD] in
544def 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
550def 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
556let DecoderNamespace = "RISCV32Only_",
557    Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
558def 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
564let Predicates = [HasStdExtC, IsRV64] in
565def 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).
573let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
574def 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
585let Predicates = [HasStdExtC, HasRVCHints], hasSideEffects = 0, mayLoad = 0,
586    mayStore = 0 in
587{
588
589let rd = 0 in
590def 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.
597def 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
606def 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
615def 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
623def 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
632def 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
639def 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
648def 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
658def 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
666def 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
676def 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
693let EmitPriority = 0 in {
694let Predicates = [HasStdExtC, HasStdExtD] in
695def : InstAlias<"c.fld $rd, (${rs1})", (C_FLD FPR64C:$rd, GPRC:$rs1, 0)>;
696
697def : InstAlias<"c.lw $rd, (${rs1})", (C_LW GPRC:$rd, GPRC:$rs1, 0)>;
698
699let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
700def : InstAlias<"c.flw $rd, (${rs1})", (C_FLW FPR32C:$rd, GPRC:$rs1, 0)>;
701
702let Predicates = [HasStdExtC, IsRV64] in
703def : InstAlias<"c.ld $rd, (${rs1})", (C_LD GPRC:$rd, GPRC:$rs1, 0)>;
704
705let Predicates = [HasStdExtC, HasStdExtD] in
706def : InstAlias<"c.fsd $rs2, (${rs1})", (C_FSD FPR64C:$rs2, GPRC:$rs1, 0)>;
707
708def : InstAlias<"c.sw $rs2, (${rs1})", (C_SW GPRC:$rs2, GPRC:$rs1, 0)>;
709
710let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
711def : InstAlias<"c.fsw $rs2, (${rs1})", (C_FSW FPR32C:$rs2, GPRC:$rs1, 0)>;
712
713let Predicates = [HasStdExtC, IsRV64] in
714def : InstAlias<"c.sd $rs2, (${rs1})", (C_SD GPRC:$rs2, GPRC:$rs1, 0)>;
715
716let Predicates = [HasStdExtC, HasStdExtD] in
717def : InstAlias<"c.fldsp $rd, (${rs1})", (C_FLDSP FPR64C:$rd, SP:$rs1, 0)>;
718
719def : InstAlias<"c.lwsp $rd, (${rs1})", (C_LWSP GPRC:$rd, SP:$rs1, 0)>;
720
721let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
722def : InstAlias<"c.flwsp $rd, (${rs1})", (C_FLWSP FPR32C:$rd, SP:$rs1, 0)>;
723
724let Predicates = [HasStdExtC, IsRV64] in
725def : InstAlias<"c.ldsp $rd, (${rs1})", (C_LDSP GPRC:$rd, SP:$rs1, 0)>;
726
727let Predicates = [HasStdExtC, HasStdExtD] in
728def : InstAlias<"c.fsdsp $rs2, (${rs1})", (C_FSDSP FPR64C:$rs2, SP:$rs1, 0)>;
729
730def : InstAlias<"c.swsp $rs2, (${rs1})", (C_SWSP GPRC:$rs2, SP:$rs1, 0)>;
731
732let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
733def : InstAlias<"c.fswsp $rs2, (${rs1})", (C_FSWSP FPR32C:$rs2, SP:$rs1, 0)>;
734
735let Predicates = [HasStdExtC, IsRV64] in
736def : InstAlias<"c.sdsp $rs2, (${rs1})", (C_SDSP GPRC:$rs2, SP:$rs1, 0)>;
737}
738
739//===----------------------------------------------------------------------===//
740// Compress Instruction tablegen backend.
741//===----------------------------------------------------------------------===//
742
743class 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
753let Predicates = [HasStdExtC] in {
754def : CompressPat<(ADDI GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm),
755                  (C_ADDI4SPN GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm)>;
756} // Predicates = [HasStdExtC]
757
758let Predicates = [HasStdExtC, HasStdExtD] in {
759def : CompressPat<(FLD FPR64C:$rd, GPRC:$rs1, uimm8_lsb000:$imm),
760                  (C_FLD FPR64C:$rd, GPRC:$rs1, uimm8_lsb000:$imm)>;
761} // Predicates = [HasStdExtC, HasStdExtD]
762
763let Predicates = [HasStdExtC] in {
764def : CompressPat<(LW GPRC:$rd, GPRC:$rs1, uimm7_lsb00:$imm),
765                  (C_LW GPRC:$rd, GPRC:$rs1, uimm7_lsb00:$imm)>;
766} // Predicates = [HasStdExtC]
767
768let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
769def : 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
773let Predicates = [HasStdExtC, IsRV64] in {
774def : CompressPat<(LD GPRC:$rd, GPRC:$rs1, uimm8_lsb000:$imm),
775                  (C_LD GPRC:$rd, GPRC:$rs1, uimm8_lsb000:$imm)>;
776} // Predicates = [HasStdExtC, IsRV64]
777
778let Predicates = [HasStdExtC, HasStdExtD] in {
779def : CompressPat<(FSD FPR64C:$rs2, GPRC:$rs1, uimm8_lsb000:$imm),
780                  (C_FSD FPR64C:$rs2, GPRC:$rs1, uimm8_lsb000:$imm)>;
781} // Predicates = [HasStdExtC, HasStdExtD]
782
783let Predicates = [HasStdExtC] in {
784def : CompressPat<(SW GPRC:$rs2, GPRC:$rs1, uimm7_lsb00:$imm),
785                  (C_SW GPRC:$rs2, GPRC:$rs1, uimm7_lsb00:$imm)>;
786} // Predicates = [HasStdExtC]
787
788let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
789def : 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
793let Predicates = [HasStdExtC, IsRV64] in {
794def : 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
799let Predicates = [HasStdExtC] in {
800def : CompressPat<(ADDI X0, X0, 0), (C_NOP)>;
801def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs1, simm6nonzero:$imm),
802                  (C_ADDI GPRNoX0:$rs1, simm6nonzero:$imm)>;
803} // Predicates = [HasStdExtC]
804
805let Predicates = [HasStdExtC, IsRV32] in {
806def : CompressPat<(JAL X1, simm12_lsb0:$offset),
807                  (C_JAL simm12_lsb0:$offset)>;
808} // Predicates = [HasStdExtC, IsRV32]
809
810let Predicates = [HasStdExtC, IsRV64] in {
811def : CompressPat<(ADDIW GPRNoX0:$rs1, GPRNoX0:$rs1, simm6:$imm),
812                  (C_ADDIW GPRNoX0:$rs1, simm6:$imm)>;
813} // Predicates = [HasStdExtC, IsRV64]
814
815let Predicates = [HasStdExtC] in {
816def : CompressPat<(ADDI GPRNoX0:$rd, X0, simm6:$imm),
817                  (C_LI GPRNoX0:$rd, simm6:$imm)>;
818def : CompressPat<(ADDI X2, X2, simm10_lsb0000nonzero:$imm),
819                  (C_ADDI16SP X2, simm10_lsb0000nonzero:$imm)>;
820def : CompressPat<(LUI GPRNoX0X2:$rd, c_lui_imm:$imm),
821                  (C_LUI GPRNoX0X2:$rd, c_lui_imm:$imm)>;
822def : CompressPat<(SRLI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm),
823                  (C_SRLI GPRC:$rs1, uimmlog2xlennonzero:$imm)>;
824def : CompressPat<(SRAI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm),
825                  (C_SRAI GPRC:$rs1, uimmlog2xlennonzero:$imm)>;
826def : CompressPat<(ANDI GPRC:$rs1, GPRC:$rs1, simm6:$imm),
827                  (C_ANDI GPRC:$rs1, simm6:$imm)>;
828def : CompressPat<(SUB GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
829                  (C_SUB GPRC:$rs1, GPRC:$rs2)>;
830def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
831                  (C_XOR GPRC:$rs1, GPRC:$rs2)>;
832def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
833                  (C_XOR GPRC:$rs1, GPRC:$rs2)>;
834def : CompressPat<(OR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
835                  (C_OR GPRC:$rs1, GPRC:$rs2)>;
836def : CompressPat<(OR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
837                  (C_OR GPRC:$rs1, GPRC:$rs2)>;
838def : CompressPat<(AND GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
839                  (C_AND GPRC:$rs1, GPRC:$rs2)>;
840def : CompressPat<(AND GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
841                  (C_AND GPRC:$rs1, GPRC:$rs2)>;
842} //  Predicates = [HasStdExtC]
843
844let Predicates = [HasStdExtC, IsRV64] in {
845def : CompressPat<(ADDIW GPRNoX0:$rd, X0, simm6:$imm),
846                  (C_LI GPRNoX0:$rd, simm6:$imm)>;
847def : CompressPat<(SUBW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
848                  (C_SUBW GPRC:$rs1, GPRC:$rs2)>;
849def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
850                   (C_ADDW GPRC:$rs1, GPRC:$rs2)>;
851def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
852                   (C_ADDW GPRC:$rs1, GPRC:$rs2)>;
853} // Predicates = [HasStdExtC, IsRV64]
854
855let Predicates = [HasStdExtC] in {
856def : CompressPat<(JAL X0, simm12_lsb0:$offset),
857                  (C_J simm12_lsb0:$offset)>;
858def : CompressPat<(BEQ GPRC:$rs1, X0, simm9_lsb0:$imm),
859                  (C_BEQZ GPRC:$rs1, simm9_lsb0:$imm)>;
860def : CompressPat<(BNE GPRC:$rs1, X0, simm9_lsb0:$imm),
861                  (C_BNEZ GPRC:$rs1, simm9_lsb0:$imm)>;
862} //  Predicates = [HasStdExtC]
863
864// Quadrant 2
865let Predicates = [HasStdExtC] in {
866def : CompressPat<(SLLI GPRNoX0:$rs1, GPRNoX0:$rs1, uimmlog2xlennonzero:$imm),
867                  (C_SLLI GPRNoX0:$rs1, uimmlog2xlennonzero:$imm)>;
868} //  Predicates = [HasStdExtC]
869
870let Predicates = [HasStdExtC, HasStdExtD] in {
871def : CompressPat<(FLD FPR64:$rd, SP:$rs1, uimm9_lsb000:$imm),
872                  (C_FLDSP FPR64:$rd, SP:$rs1, uimm9_lsb000:$imm)>;
873} // Predicates = [HasStdExtC, HasStdExtD]
874
875let Predicates = [HasStdExtC] in {
876def : CompressPat<(LW GPRNoX0:$rd, SP:$rs1,  uimm8_lsb00:$imm),
877                  (C_LWSP GPRNoX0:$rd, SP:$rs1, uimm8_lsb00:$imm)>;
878} // Predicates = [HasStdExtC]
879
880let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
881def : 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
885let Predicates = [HasStdExtC, IsRV64] in {
886def : CompressPat<(LD GPRNoX0:$rd, SP:$rs1, uimm9_lsb000:$imm),
887                  (C_LDSP GPRNoX0:$rd, SP:$rs1, uimm9_lsb000:$imm)>;
888} // Predicates = [HasStdExtC, IsRV64]
889
890let Predicates = [HasStdExtC] in {
891def : CompressPat<(JALR X0, GPRNoX0:$rs1, 0),
892                  (C_JR GPRNoX0:$rs1)>;
893def : CompressPat<(ADD GPRNoX0:$rs1, X0, GPRNoX0:$rs2),
894                  (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
895def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, X0),
896                  (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
897def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs2, 0),
898                  (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
899def : CompressPat<(EBREAK), (C_EBREAK)>;
900def : CompressPat<(UNIMP), (C_UNIMP)>;
901def : CompressPat<(JALR X1, GPRNoX0:$rs1, 0),
902                  (C_JALR GPRNoX0:$rs1)>;
903def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs1, GPRNoX0:$rs2),
904                  (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
905def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, GPRNoX0:$rs1),
906                  (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
907} // Predicates = [HasStdExtC]
908
909let Predicates = [HasStdExtC, HasStdExtD] in {
910def : CompressPat<(FSD FPR64:$rs2, SP:$rs1, uimm9_lsb000:$imm),
911                  (C_FSDSP FPR64:$rs2, SP:$rs1, uimm9_lsb000:$imm)>;
912} // Predicates = [HasStdExtC, HasStdExtD]
913
914let Predicates = [HasStdExtC] in {
915def : CompressPat<(SW GPR:$rs2, SP:$rs1, uimm8_lsb00:$imm),
916                  (C_SWSP GPR:$rs2, SP:$rs1, uimm8_lsb00:$imm)>;
917} // Predicates = [HasStdExtC]
918
919let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
920def : 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
924let Predicates = [HasStdExtC, IsRV64] in {
925def : CompressPat<(SD GPR:$rs2, SP:$rs1, uimm9_lsb000:$imm),
926                  (C_SDSP GPR:$rs2, SP:$rs1, uimm9_lsb000:$imm)>;
927} //  Predicates = [HasStdExtC, IsRV64]
928