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