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