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 let DecoderMethod = "decodeUImmLog2XLenNonZeroOperand";
28 let OperandType = "OPERAND_UIMMLOG2XLEN_NONZERO";
29 let MCOperandPredicate = [{
31 if (!MCOp.evaluateAsConstantImm(Imm))
33 if (STI.getTargetTriple().isArch64Bit())
34 return isUInt<6>(Imm) && (Imm != 0);
35 return isUInt<5>(Imm) && (Imm != 0);
39 def simm6 : RISCVSImmLeafOp<6> {
40 let MCOperandPredicate = [{
42 if (MCOp.evaluateAsConstantImm(Imm))
44 return MCOp.isBareSymbolRef();
48 def simm6nonzero : RISCVOp,
49 ImmLeaf<XLenVT, [{return (Imm != 0) && isInt<6>(Imm);}]> {
50 let ParserMatchClass = SImmAsmOperand<6, "NonZero">;
51 let EncoderMethod = "getImmOpValue";
52 let DecoderMethod = "decodeSImmNonZeroOperand<6>";
53 let OperandType = "OPERAND_SIMM6_NONZERO";
54 let MCOperandPredicate = [{
56 if (MCOp.evaluateAsConstantImm(Imm))
57 return (Imm != 0) && isInt<6>(Imm);
58 return MCOp.isBareSymbolRef();
62 def immzero : RISCVOp,
63 ImmLeaf<XLenVT, [{return (Imm == 0);}]> {
64 let ParserMatchClass = ImmZeroAsmOperand;
65 let OperandType = "OPERAND_ZERO";
68 def CLUIImmAsmOperand : AsmOperandClass {
70 let RenderMethod = "addImmOperands";
71 let DiagnosticType = !strconcat("Invalid", Name);
75 // c_lui_imm checks the immediate range is in [1, 31] or [0xfffe0, 0xfffff].
76 // The RISC-V ISA describes the constraint as [1, 63], with that value being
77 // loaded in to bits 17-12 of the destination register and sign extended from
78 // bit 17. Therefore, this 6-bit immediate can represent values in the ranges
79 // [1, 31] and [0xfffe0, 0xfffff].
80 def c_lui_imm : RISCVOp,
81 ImmLeaf<XLenVT, [{return (Imm != 0) &&
83 (Imm >= 0xfffe0 && Imm <= 0xfffff));}]> {
84 let ParserMatchClass = CLUIImmAsmOperand;
85 let EncoderMethod = "getImmOpValue";
86 let DecoderMethod = "decodeCLUIImmOperand";
87 let OperandType = "OPERAND_CLUI_IMM";
88 let MCOperandPredicate = [{
90 if (MCOp.evaluateAsConstantImm(Imm))
91 return (Imm != 0) && (isUInt<5>(Imm) ||
92 (Imm >= 0xfffe0 && Imm <= 0xfffff));
93 return MCOp.isBareSymbolRef();
97 // A 7-bit unsigned immediate where the least significant two bits are zero.
98 def uimm7_lsb00 : RISCVOp,
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 OperandType = "OPERAND_UIMM7_LSB00";
104 let MCOperandPredicate = [{
106 if (!MCOp.evaluateAsConstantImm(Imm))
108 return isShiftedUInt<5, 2>(Imm);
112 // A 8-bit unsigned immediate where the least significant two bits are zero.
113 def uimm8_lsb00 : RISCVOp,
114 ImmLeaf<XLenVT, [{return isShiftedUInt<6, 2>(Imm);}]> {
115 let ParserMatchClass = UImmAsmOperand<8, "Lsb00">;
116 let EncoderMethod = "getImmOpValue";
117 let DecoderMethod = "decodeUImmOperand<8>";
118 let OperandType = "OPERAND_UIMM8_LSB00";
119 let MCOperandPredicate = [{
121 if (!MCOp.evaluateAsConstantImm(Imm))
123 return isShiftedUInt<6, 2>(Imm);
127 // A 8-bit unsigned immediate where the least significant three bits are zero.
128 def uimm8_lsb000 : RISCVOp,
129 ImmLeaf<XLenVT, [{return isShiftedUInt<5, 3>(Imm);}]> {
130 let ParserMatchClass = UImmAsmOperand<8, "Lsb000">;
131 let EncoderMethod = "getImmOpValue";
132 let DecoderMethod = "decodeUImmOperand<8>";
133 let OperandType = "OPERAND_UIMM8_LSB000";
134 let MCOperandPredicate = [{
136 if (!MCOp.evaluateAsConstantImm(Imm))
138 return isShiftedUInt<5, 3>(Imm);
142 // A 9-bit signed immediate where the least significant bit is zero.
143 def simm9_lsb0 : Operand<OtherVT>,
144 ImmLeaf<XLenVT, [{return isShiftedInt<8, 1>(Imm);}]> {
145 let ParserMatchClass = SImmAsmOperand<9, "Lsb0">;
146 let PrintMethod = "printBranchOperand";
147 let EncoderMethod = "getImmOpValueAsr1";
148 let DecoderMethod = "decodeSImmOperandAndLsl1<9>";
149 let MCOperandPredicate = [{
151 if (MCOp.evaluateAsConstantImm(Imm))
152 return isShiftedInt<8, 1>(Imm);
153 return MCOp.isBareSymbolRef();
156 let OperandType = "OPERAND_PCREL";
159 // A 9-bit unsigned immediate where the least significant three bits are zero.
160 def uimm9_lsb000 : RISCVOp,
161 ImmLeaf<XLenVT, [{return isShiftedUInt<6, 3>(Imm);}]> {
162 let ParserMatchClass = UImmAsmOperand<9, "Lsb000">;
163 let EncoderMethod = "getImmOpValue";
164 let DecoderMethod = "decodeUImmOperand<9>";
165 let OperandType = "OPERAND_UIMM9_LSB000";
166 let MCOperandPredicate = [{
168 if (!MCOp.evaluateAsConstantImm(Imm))
170 return isShiftedUInt<6, 3>(Imm);
174 // A 10-bit unsigned immediate where the least significant two bits are zero
175 // and the immediate can't be zero.
176 def uimm10_lsb00nonzero : RISCVOp,
178 [{return isShiftedUInt<8, 2>(Imm) && (Imm != 0);}]> {
179 let ParserMatchClass = UImmAsmOperand<10, "Lsb00NonZero">;
180 let EncoderMethod = "getImmOpValue";
181 let DecoderMethod = "decodeUImmNonZeroOperand<10>";
182 let OperandType = "OPERAND_UIMM10_LSB00_NONZERO";
183 let MCOperandPredicate = [{
185 if (!MCOp.evaluateAsConstantImm(Imm))
187 return isShiftedUInt<8, 2>(Imm) && (Imm != 0);
191 // A 10-bit signed immediate where the least significant four bits are zero.
192 def simm10_lsb0000nonzero : RISCVOp,
194 [{return (Imm != 0) && isShiftedInt<6, 4>(Imm);}]> {
195 let ParserMatchClass = SImmAsmOperand<10, "Lsb0000NonZero">;
196 let EncoderMethod = "getImmOpValue";
197 let DecoderMethod = "decodeSImmNonZeroOperand<10>";
198 let OperandType = "OPERAND_SIMM10_LSB0000_NONZERO";
199 let MCOperandPredicate = [{
201 if (!MCOp.evaluateAsConstantImm(Imm))
203 return isShiftedInt<6, 4>(Imm) && (Imm != 0);
207 // A 12-bit signed immediate where the least significant bit is zero.
208 def simm12_lsb0 : Operand<XLenVT>,
209 ImmLeaf<XLenVT, [{return isShiftedInt<11, 1>(Imm);}]> {
210 let ParserMatchClass = SImmAsmOperand<12, "Lsb0">;
211 let PrintMethod = "printBranchOperand";
212 let EncoderMethod = "getImmOpValueAsr1";
213 let DecoderMethod = "decodeSImmOperandAndLsl1<12>";
214 let MCOperandPredicate = [{
216 if (MCOp.evaluateAsConstantImm(Imm))
217 return isShiftedInt<11, 1>(Imm);
218 return MCOp.isBareSymbolRef();
220 let OperandType = "OPERAND_PCREL";
223 def InsnCDirectiveOpcode : AsmOperandClass {
224 let Name = "InsnCDirectiveOpcode";
225 let ParserMethod = "parseInsnCDirectiveOpcode";
226 let RenderMethod = "addImmOperands";
227 let PredicateMethod = "isImm";
230 def uimm2_opcode : RISCVOp {
231 let ParserMatchClass = InsnCDirectiveOpcode;
232 let DecoderMethod = "decodeUImmOperand<2>";
233 let OperandType = "OPERAND_UIMM2";
236 //===----------------------------------------------------------------------===//
237 // Instruction Class Templates
238 //===----------------------------------------------------------------------===//
240 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
241 class CStackLoad<bits<3> funct3, string OpcodeStr,
242 RegisterClass cls, DAGOperand opnd>
243 : RVInst16CI<funct3, 0b10, (outs cls:$rd), (ins SPMem:$rs1, opnd:$imm),
244 OpcodeStr, "$rd, ${imm}(${rs1})">;
246 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
247 class CStackStore<bits<3> funct3, string OpcodeStr,
248 RegisterClass cls, DAGOperand opnd>
249 : RVInst16CSS<funct3, 0b10, (outs), (ins cls:$rs2, SPMem:$rs1, opnd:$imm),
250 OpcodeStr, "$rs2, ${imm}(${rs1})">;
252 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
253 class CLoad_ri<bits<3> funct3, string OpcodeStr,
254 RegisterClass cls, DAGOperand opnd>
255 : RVInst16CL<funct3, 0b00, (outs cls:$rd), (ins GPRCMem:$rs1, opnd:$imm),
256 OpcodeStr, "$rd, ${imm}(${rs1})">;
258 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
259 class CStore_rri<bits<3> funct3, string OpcodeStr,
260 RegisterClass cls, DAGOperand opnd>
261 : RVInst16CS<funct3, 0b00, (outs), (ins cls:$rs2,GPRCMem:$rs1, opnd:$imm),
262 OpcodeStr, "$rs2, ${imm}(${rs1})">;
264 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
265 class Bcz<bits<3> funct3, string OpcodeStr,
267 : RVInst16CB<funct3, 0b01, (outs), (ins cls:$rs1, simm9_lsb0:$imm),
268 OpcodeStr, "$rs1, $imm"> {
270 let isTerminator = 1;
271 let Inst{12} = imm{7};
272 let Inst{11-10} = imm{3-2};
273 let Inst{6-5} = imm{6-5};
274 let Inst{4-3} = imm{1-0};
275 let Inst{2} = imm{4};
278 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
279 class Shift_right<bits<2> funct2, string OpcodeStr, RegisterClass cls,
281 : RVInst16CB<0b100, 0b01, (outs cls:$rd), (ins cls:$rs1, ImmOpnd:$imm),
282 OpcodeStr, "$rs1, $imm"> {
283 let Constraints = "$rs1 = $rd";
284 let Inst{12} = imm{5};
285 let Inst{11-10} = funct2;
286 let Inst{6-2} = imm{4-0};
289 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
290 class CA_ALU<bits<6> funct6, bits<2> funct2, string OpcodeStr,
292 : RVInst16CA<funct6, funct2, 0b01, (outs cls:$rd_wb), (ins cls:$rd, cls:$rs2),
293 OpcodeStr, "$rd, $rs2"> {
295 let Constraints = "$rd = $rd_wb";
299 //===----------------------------------------------------------------------===//
301 //===----------------------------------------------------------------------===//
303 let Predicates = [HasStdExtCOrZca] in {
305 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Uses = [X2] in
306 def C_ADDI4SPN : RVInst16CIW<0b000, 0b00, (outs GPRC:$rd),
307 (ins SP:$rs1, uimm10_lsb00nonzero:$imm),
308 "c.addi4spn", "$rd, $rs1, $imm">,
309 Sched<[WriteIALU, ReadIALU]> {
311 let Inst{12-11} = imm{5-4};
312 let Inst{10-7} = imm{9-6};
313 let Inst{6} = imm{2};
314 let Inst{5} = imm{3};
317 let Predicates = [HasStdExtCOrZcd, HasStdExtD] in
318 def C_FLD : CLoad_ri<0b001, "c.fld", FPR64C, uimm8_lsb000>,
319 Sched<[WriteFLD64, ReadFMemBase]> {
321 let Inst{12-10} = imm{5-3};
322 let Inst{6-5} = imm{7-6};
325 def C_LW : CLoad_ri<0b010, "c.lw", GPRC, uimm7_lsb00>,
326 Sched<[WriteLDW, ReadMemBase]> {
328 let Inst{12-10} = imm{5-3};
329 let Inst{6} = imm{2};
330 let Inst{5} = imm{6};
333 let isCodeGenOnly = 1 in
334 def C_LW_INX : CLoad_ri<0b010, "c.lw", GPRF32C, uimm7_lsb00>,
335 Sched<[WriteLDW, ReadMemBase]> {
337 let Inst{12-10} = imm{5-3};
338 let Inst{6} = imm{2};
339 let Inst{5} = imm{6};
342 let DecoderNamespace = "RISCV32Only_",
343 Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in
344 def C_FLW : CLoad_ri<0b011, "c.flw", FPR32C, uimm7_lsb00>,
345 Sched<[WriteFLD32, ReadFMemBase]> {
347 let Inst{12-10} = imm{5-3};
348 let Inst{6} = imm{2};
349 let Inst{5} = imm{6};
352 let Predicates = [HasStdExtCOrZca, IsRV64] in
353 def C_LD : CLoad_ri<0b011, "c.ld", GPRC, uimm8_lsb000>,
354 Sched<[WriteLDD, ReadMemBase]> {
356 let Inst{12-10} = imm{5-3};
357 let Inst{6-5} = imm{7-6};
360 let Predicates = [HasStdExtCOrZcd, HasStdExtD] in
361 def C_FSD : CStore_rri<0b101, "c.fsd", FPR64C, uimm8_lsb000>,
362 Sched<[WriteFST64, ReadFStoreData, ReadFMemBase]> {
364 let Inst{12-10} = imm{5-3};
365 let Inst{6-5} = imm{7-6};
368 def C_SW : CStore_rri<0b110, "c.sw", GPRC, uimm7_lsb00>,
369 Sched<[WriteSTW, ReadStoreData, ReadMemBase]> {
371 let Inst{12-10} = imm{5-3};
372 let Inst{6} = imm{2};
373 let Inst{5} = imm{6};
376 let isCodeGenOnly = 1 in
377 def C_SW_INX : CStore_rri<0b110, "c.sw", GPRF32C, uimm7_lsb00>,
378 Sched<[WriteSTW, ReadStoreData, ReadMemBase]> {
380 let Inst{12-10} = imm{5-3};
381 let Inst{6} = imm{2};
382 let Inst{5} = imm{6};
385 let DecoderNamespace = "RISCV32Only_",
386 Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in
387 def C_FSW : CStore_rri<0b111, "c.fsw", FPR32C, uimm7_lsb00>,
388 Sched<[WriteFST32, ReadFStoreData, ReadFMemBase]> {
390 let Inst{12-10} = imm{5-3};
391 let Inst{6} = imm{2};
392 let Inst{5} = imm{6};
395 let Predicates = [HasStdExtCOrZca, IsRV64] in
396 def C_SD : CStore_rri<0b111, "c.sd", GPRC, uimm8_lsb000>,
397 Sched<[WriteSTD, ReadStoreData, ReadMemBase]> {
399 let Inst{12-10} = imm{5-3};
400 let Inst{6-5} = imm{7-6};
403 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
404 def C_NOP : RVInst16CI<0b000, 0b01, (outs), (ins), "c.nop", "">,
411 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
412 def C_ADDI : RVInst16CI<0b000, 0b01, (outs GPRNoX0:$rd_wb),
413 (ins GPRNoX0:$rd, simm6nonzero:$imm),
414 "c.addi", "$rd, $imm">,
415 Sched<[WriteIALU, ReadIALU]> {
416 let Constraints = "$rd = $rd_wb";
417 let Inst{6-2} = imm{4-0};
420 // Alternate syntax for c.nop. Converted to C_NOP by the assembler.
421 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0,
422 isAsmParserOnly = 1 in
423 def PseudoC_ADDI_NOP : Pseudo<(outs GPRX0:$rd), (ins GPRX0:$rs1, immzero:$imm),
424 [], "c.addi", "$rd, $imm">;
426 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCall = 1,
427 DecoderNamespace = "RISCV32Only_", Defs = [X1],
428 Predicates = [HasStdExtCOrZca, IsRV32] in
429 def C_JAL : RVInst16CJ<0b001, 0b01, (outs), (ins simm12_lsb0:$offset),
430 "c.jal", "$offset">, Sched<[WriteJal]>;
432 let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
433 Predicates = [HasStdExtCOrZca, IsRV64] in
434 def C_ADDIW : RVInst16CI<0b001, 0b01, (outs GPRNoX0:$rd_wb),
435 (ins GPRNoX0:$rd, simm6:$imm),
436 "c.addiw", "$rd, $imm">,
437 Sched<[WriteIALU32, ReadIALU32]> {
438 let Constraints = "$rd = $rd_wb";
439 let Inst{6-2} = imm{4-0};
442 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
443 def C_LI : RVInst16CI<0b010, 0b01, (outs GPRNoX0:$rd), (ins simm6:$imm),
444 "c.li", "$rd, $imm">,
446 let Inst{6-2} = imm{4-0};
449 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
450 def C_ADDI16SP : RVInst16CI<0b011, 0b01, (outs SP:$rd_wb),
451 (ins SP:$rd, simm10_lsb0000nonzero:$imm),
452 "c.addi16sp", "$rd, $imm">,
453 Sched<[WriteIALU, ReadIALU]> {
454 let Constraints = "$rd = $rd_wb";
455 let Inst{12} = imm{9};
457 let Inst{6} = imm{4};
458 let Inst{5} = imm{6};
459 let Inst{4-3} = imm{8-7};
460 let Inst{2} = imm{5};
463 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
464 def C_LUI : RVInst16CI<0b011, 0b01, (outs GPRNoX0X2:$rd),
465 (ins c_lui_imm:$imm),
466 "c.lui", "$rd, $imm">,
468 let Inst{6-2} = imm{4-0};
471 def C_SRLI : Shift_right<0b00, "c.srli", GPRC, uimmlog2xlennonzero>,
472 Sched<[WriteShiftImm, ReadShiftImm]>;
473 def C_SRAI : Shift_right<0b01, "c.srai", GPRC, uimmlog2xlennonzero>,
474 Sched<[WriteShiftImm, ReadShiftImm]>;
476 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
477 def C_ANDI : RVInst16CB<0b100, 0b01, (outs GPRC:$rd), (ins GPRC:$rs1, simm6:$imm),
478 "c.andi", "$rs1, $imm">,
479 Sched<[WriteIALU, ReadIALU]> {
480 let Constraints = "$rs1 = $rd";
481 let Inst{12} = imm{5};
482 let Inst{11-10} = 0b10;
483 let Inst{6-2} = imm{4-0};
486 def C_SUB : CA_ALU<0b100011, 0b00, "c.sub", GPRC>,
487 Sched<[WriteIALU, ReadIALU, ReadIALU]>;
488 def C_XOR : CA_ALU<0b100011, 0b01, "c.xor", GPRC>,
489 Sched<[WriteIALU, ReadIALU, ReadIALU]>;
490 def C_OR : CA_ALU<0b100011, 0b10, "c.or" , GPRC>,
491 Sched<[WriteIALU, ReadIALU, ReadIALU]>;
492 def C_AND : CA_ALU<0b100011, 0b11, "c.and", GPRC>,
493 Sched<[WriteIALU, ReadIALU, ReadIALU]>;
495 let Predicates = [HasStdExtCOrZca, IsRV64] in {
496 def C_SUBW : CA_ALU<0b100111, 0b00, "c.subw", GPRC>,
497 Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>;
498 def C_ADDW : CA_ALU<0b100111, 0b01, "c.addw", GPRC>,
499 Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>;
502 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
503 def C_J : RVInst16CJ<0b101, 0b01, (outs), (ins simm12_lsb0:$offset),
504 "c.j", "$offset">, Sched<[WriteJmp]> {
510 def C_BEQZ : Bcz<0b110, "c.beqz", GPRC>, Sched<[WriteJmp, ReadJmp]>;
511 def C_BNEZ : Bcz<0b111, "c.bnez", GPRC>, Sched<[WriteJmp, ReadJmp]>;
513 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
514 def C_SLLI : RVInst16CI<0b000, 0b10, (outs GPRNoX0:$rd_wb),
515 (ins GPRNoX0:$rd, uimmlog2xlennonzero:$imm),
516 "c.slli", "$rd, $imm">,
517 Sched<[WriteShiftImm, ReadShiftImm]> {
518 let Constraints = "$rd = $rd_wb";
519 let Inst{6-2} = imm{4-0};
522 let Predicates = [HasStdExtCOrZcd, HasStdExtD] in
523 def C_FLDSP : CStackLoad<0b001, "c.fldsp", FPR64, uimm9_lsb000>,
524 Sched<[WriteFLD64, ReadFMemBase]> {
525 let Inst{6-5} = imm{4-3};
526 let Inst{4-2} = imm{8-6};
529 def C_LWSP : CStackLoad<0b010, "c.lwsp", GPRNoX0, uimm8_lsb00>,
530 Sched<[WriteLDW, ReadMemBase]> {
531 let Inst{6-4} = imm{4-2};
532 let Inst{3-2} = imm{7-6};
535 let isCodeGenOnly = 1 in
536 def C_LWSP_INX : CStackLoad<0b010, "c.lwsp", GPRF32NoX0, uimm8_lsb00>,
537 Sched<[WriteLDW, ReadMemBase]> {
538 let Inst{6-4} = imm{4-2};
539 let Inst{3-2} = imm{7-6};
542 let DecoderNamespace = "RISCV32Only_",
543 Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in
544 def C_FLWSP : CStackLoad<0b011, "c.flwsp", FPR32, uimm8_lsb00>,
545 Sched<[WriteFLD32, ReadFMemBase]> {
546 let Inst{6-4} = imm{4-2};
547 let Inst{3-2} = imm{7-6};
550 let Predicates = [HasStdExtCOrZca, IsRV64] in
551 def C_LDSP : CStackLoad<0b011, "c.ldsp", GPRNoX0, uimm9_lsb000>,
552 Sched<[WriteLDD, ReadMemBase]> {
553 let Inst{6-5} = imm{4-3};
554 let Inst{4-2} = imm{8-6};
557 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
558 def C_JR : RVInst16CR<0b1000, 0b10, (outs), (ins GPRNoX0:$rs1),
559 "c.jr", "$rs1">, Sched<[WriteJalr, ReadJalr]> {
561 let isTerminator = 1;
565 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isMoveReg = 1,
566 isAsCheapAsAMove = 1 in
567 def C_MV : RVInst16CR<0b1000, 0b10, (outs GPRNoX0:$rs1), (ins GPRNoX0:$rs2),
568 "c.mv", "$rs1, $rs2">,
569 Sched<[WriteIALU, ReadIALU]>;
571 let rs1 = 0, rs2 = 0, hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
572 def C_EBREAK : RVInst16CR<0b1001, 0b10, (outs), (ins), "c.ebreak", "">, Sched<[]>;
574 let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
575 isCall=1, Defs=[X1], rs2 = 0 in
576 def C_JALR : RVInst16CR<0b1001, 0b10, (outs), (ins GPRNoX0:$rs1),
577 "c.jalr", "$rs1">, Sched<[WriteJalr, ReadJalr]>;
579 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
580 def C_ADD : RVInst16CR<0b1001, 0b10, (outs GPRNoX0:$rd),
581 (ins GPRNoX0:$rs1, GPRNoX0:$rs2),
582 "c.add", "$rs1, $rs2">,
583 Sched<[WriteIALU, ReadIALU, ReadIALU]> {
584 let Constraints = "$rs1 = $rd";
587 let Predicates = [HasStdExtCOrZcd, HasStdExtD] in
588 def C_FSDSP : CStackStore<0b101, "c.fsdsp", FPR64, uimm9_lsb000>,
589 Sched<[WriteFST64, ReadFStoreData, ReadFMemBase]> {
590 let Inst{12-10} = imm{5-3};
591 let Inst{9-7} = imm{8-6};
594 def C_SWSP : CStackStore<0b110, "c.swsp", GPR, uimm8_lsb00>,
595 Sched<[WriteSTW, ReadStoreData, ReadMemBase]> {
596 let Inst{12-9} = imm{5-2};
597 let Inst{8-7} = imm{7-6};
600 let isCodeGenOnly = 1 in
601 def C_SWSP_INX : CStackStore<0b110, "c.swsp", GPRF32, uimm8_lsb00>,
602 Sched<[WriteSTW, ReadStoreData, ReadMemBase]> {
603 let Inst{12-9} = imm{5-2};
604 let Inst{8-7} = imm{7-6};
607 let DecoderNamespace = "RISCV32Only_",
608 Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in
609 def C_FSWSP : CStackStore<0b111, "c.fswsp", FPR32, uimm8_lsb00>,
610 Sched<[WriteFST32, ReadFStoreData, ReadFMemBase]> {
611 let Inst{12-9} = imm{5-2};
612 let Inst{8-7} = imm{7-6};
615 let Predicates = [HasStdExtCOrZca, IsRV64] in
616 def C_SDSP : CStackStore<0b111, "c.sdsp", GPR, uimm9_lsb000>,
617 Sched<[WriteSTD, ReadStoreData, ReadMemBase]> {
618 let Inst{12-10} = imm{5-3};
619 let Inst{9-7} = imm{8-6};
622 // The all zeros pattern isn't a valid RISC-V instruction. It's used by GNU
623 // binutils as 16-bit instruction known to be unimplemented (i.e., trapping).
624 let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
625 def C_UNIMP : RVInst16<(outs), (ins), "c.unimp", "", [], InstFormatOther>,
630 } // Predicates = [HasStdExtCOrZca]
632 //===----------------------------------------------------------------------===//
634 //===----------------------------------------------------------------------===//
636 let Predicates = [HasStdExtCOrZca, HasRVCHints], hasSideEffects = 0, mayLoad = 0,
639 def C_NOP_HINT : RVInst16CI<0b000, 0b01, (outs), (ins simm6nonzero:$imm),
640 "c.nop", "$imm">, Sched<[WriteNop]> {
642 let Inst{6-2} = imm{4-0};
645 def C_ADDI_HINT_IMM_ZERO : RVInst16CI<0b000, 0b01, (outs GPRNoX0:$rd_wb),
646 (ins GPRNoX0:$rd, immzero:$imm),
647 "c.addi", "$rd, $imm">,
648 Sched<[WriteIALU, ReadIALU]> {
649 let Constraints = "$rd = $rd_wb";
652 let DecoderMethod = "decodeRVCInstrRdRs1ImmZero";
655 def C_LI_HINT : RVInst16CI<0b010, 0b01, (outs GPRX0:$rd), (ins simm6:$imm),
656 "c.li", "$rd, $imm">,
658 let Inst{6-2} = imm{4-0};
660 let DecoderMethod = "decodeRVCInstrRdSImm";
663 def C_LUI_HINT : RVInst16CI<0b011, 0b01, (outs GPRX0:$rd),
664 (ins c_lui_imm:$imm),
665 "c.lui", "$rd, $imm">,
667 let Inst{6-2} = imm{4-0};
669 let DecoderMethod = "decodeRVCInstrRdSImm";
672 def C_MV_HINT : RVInst16CR<0b1000, 0b10, (outs GPRX0:$rs1), (ins GPRNoX0:$rs2),
673 "c.mv", "$rs1, $rs2">, Sched<[WriteIALU, ReadIALU]> {
675 let DecoderMethod = "decodeRVCInstrRdRs2";
678 def C_ADD_HINT : RVInst16CR<0b1001, 0b10, (outs GPRX0:$rd),
679 (ins GPRX0:$rs1, GPRNoX0:$rs2),
680 "c.add", "$rs1, $rs2">,
681 Sched<[WriteIALU, ReadIALU, ReadIALU]> {
682 let Constraints = "$rs1 = $rd";
684 let DecoderMethod = "decodeRVCInstrRdRs1Rs2";
687 def C_SLLI_HINT : RVInst16CI<0b000, 0b10, (outs GPRX0:$rd_wb),
688 (ins GPRX0:$rd, uimmlog2xlennonzero:$imm),
689 "c.slli", "$rd, $imm">,
690 Sched<[WriteShiftImm, ReadShiftImm]> {
691 let Constraints = "$rd = $rd_wb";
692 let Inst{6-2} = imm{4-0};
694 let DecoderMethod = "decodeRVCInstrRdRs1UImm";
697 def C_SLLI64_HINT : RVInst16CI<0b000, 0b10, (outs GPR:$rd_wb), (ins GPR:$rd),
699 Sched<[WriteShiftImm, ReadShiftImm]> {
700 let Constraints = "$rd = $rd_wb";
705 def C_SRLI64_HINT : RVInst16CB<0b100, 0b01, (outs GPRC:$rd),
708 Sched<[WriteShiftImm, ReadShiftImm]> {
709 let Constraints = "$rs1 = $rd";
711 let Inst{11-10} = 0b00;
715 def C_SRAI64_HINT : RVInst16CB<0b100, 0b01, (outs GPRC:$rd),
718 Sched<[WriteShiftImm, ReadShiftImm]> {
719 let Constraints = "$rs1 = $rd";
721 let Inst{11-10} = 0b01;
725 } // Predicates = [HasStdExtCOrZca, HasRVCHints], hasSideEffects = 0, mayLoad = 0,
728 //===----------------------------------------------------------------------===//
729 // Assembler Pseudo Instructions
730 //===----------------------------------------------------------------------===//
732 let Predicates = [HasStdExtCOrZca, HasRVCHints] in {
733 // Just a different syntax for the c.nop hint: c.addi x0, simm6 vs c.nop simm6.
734 def : InstAlias<"c.addi x0, $imm", (C_NOP_HINT simm6nonzero:$imm), 0>;
737 let Predicates = [HasStdExtC, HasRVCHints, HasStdExtZihintntl] in {
738 def : InstAlias<"c.ntl.p1", (C_ADD_HINT X0, X2)>;
739 def : InstAlias<"c.ntl.pall", (C_ADD_HINT X0, X3)>;
740 def : InstAlias<"c.ntl.s1", (C_ADD_HINT X0, X4)>;
741 def : InstAlias<"c.ntl.all", (C_ADD_HINT X0, X5)>;
742 } // Predicates = [HasStdExtC, HasRVCHints, HasStdExtZihintntl]
744 let EmitPriority = 0 in {
745 let Predicates = [HasStdExtCOrZca] in {
746 def : InstAlias<"c.lw $rd, (${rs1})", (C_LW GPRC:$rd, GPRCMem:$rs1, 0)>;
747 def : InstAlias<"c.sw $rs2, (${rs1})", (C_SW GPRC:$rs2, GPRCMem:$rs1, 0)>;
748 def : InstAlias<"c.lwsp $rd, (${rs1})", (C_LWSP GPRNoX0:$rd, SPMem:$rs1, 0)>;
749 def : InstAlias<"c.swsp $rs2, (${rs1})", (C_SWSP GPRNoX0:$rs2, SPMem:$rs1, 0)>;
752 let Predicates = [HasStdExtCOrZca, IsRV64] in {
753 def : InstAlias<"c.ld $rd, (${rs1})", (C_LD GPRC:$rd, GPRCMem:$rs1, 0)>;
754 def : InstAlias<"c.sd $rs2, (${rs1})", (C_SD GPRC:$rs2, GPRCMem:$rs1, 0)>;
755 def : InstAlias<"c.ldsp $rd, (${rs1})", (C_LDSP GPRNoX0:$rd, SPMem:$rs1, 0)>;
756 def : InstAlias<"c.sdsp $rs2, (${rs1})", (C_SDSP GPRNoX0:$rs2, SPMem:$rs1, 0)>;
759 let Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in {
760 def : InstAlias<"c.flw $rd, (${rs1})", (C_FLW FPR32C:$rd, GPRCMem:$rs1, 0)>;
761 def : InstAlias<"c.fsw $rs2, (${rs1})", (C_FSW FPR32C:$rs2, GPRCMem:$rs1, 0)>;
762 def : InstAlias<"c.flwsp $rd, (${rs1})", (C_FLWSP FPR32:$rd, SPMem:$rs1, 0)>;
763 def : InstAlias<"c.fswsp $rs2, (${rs1})", (C_FSWSP FPR32:$rs2, SPMem:$rs1, 0)>;
766 let Predicates = [HasStdExtCOrZcd, HasStdExtD] in {
767 def : InstAlias<"c.fld $rd, (${rs1})", (C_FLD FPR64C:$rd, GPRCMem:$rs1, 0)>;
768 def : InstAlias<"c.fsd $rs2, (${rs1})", (C_FSD FPR64C:$rs2, GPRCMem:$rs1, 0)>;
769 def : InstAlias<"c.fldsp $rd, (${rs1})", (C_FLDSP FPR64:$rd, SPMem:$rs1, 0)>;
770 def : InstAlias<"c.fsdsp $rs2, (${rs1})", (C_FSDSP FPR64:$rs2, SPMem:$rs1, 0)>;
772 } // EmitPriority = 0
774 //===----------------------------------------------------------------------===//
775 // .insn directive instructions
776 //===----------------------------------------------------------------------===//
778 def AnyRegCOperand : AsmOperandClass {
779 let Name = "AnyRegCOperand";
780 let RenderMethod = "addRegOperands";
781 let PredicateMethod = "isAnyRegC";
784 def AnyRegC : Operand<XLenVT> {
785 let OperandType = "OPERAND_REGISTER";
786 let ParserMatchClass = AnyRegCOperand;
789 // isCodeGenOnly = 1 to hide them from the tablegened assembly parser.
790 let isCodeGenOnly = 1, hasSideEffects = 1, mayLoad = 1, mayStore = 1,
791 hasNoSchedulingInfo = 1, Predicates = [HasStdExtCOrZca] in {
792 def InsnCR : DirectiveInsnCR<(outs AnyReg:$rd), (ins uimm2_opcode:$opcode,
795 "$opcode, $funct4, $rd, $rs2">;
796 def InsnCI : DirectiveInsnCI<(outs AnyReg:$rd), (ins uimm2_opcode:$opcode,
799 "$opcode, $funct3, $rd, $imm6">;
800 def InsnCIW : DirectiveInsnCIW<(outs AnyRegC:$rd), (ins uimm2_opcode:$opcode,
803 "$opcode, $funct3, $rd, $imm8">;
804 def InsnCSS : DirectiveInsnCSS<(outs), (ins uimm2_opcode:$opcode,
808 "$opcode, $funct3, $rs2, $imm6">;
809 def InsnCL : DirectiveInsnCL<(outs AnyRegC:$rd), (ins uimm2_opcode:$opcode,
813 "$opcode, $funct3, $rd, ${imm5}(${rs1})">;
814 def InsnCS : DirectiveInsnCS<(outs), (ins uimm2_opcode:$opcode,
819 "$opcode, $funct3, $rs2, ${imm5}(${rs1})">;
820 def InsnCA : DirectiveInsnCA<(outs AnyRegC:$rd), (ins uimm2_opcode:$opcode,
824 "$opcode, $funct6, $funct2, $rd, $rs2">;
825 def InsnCB : DirectiveInsnCB<(outs), (ins uimm2_opcode:$opcode, uimm3:$funct3,
828 "$opcode, $funct3, $rs1, $imm8">;
829 def InsnCJ : DirectiveInsnCJ<(outs), (ins uimm2_opcode:$opcode,
832 "$opcode, $funct3, $imm11">;
833 def Insn16 : RVInst16<(outs), (ins uimm16:$value), "", "", [], InstFormatOther> {
836 let Inst{15-0} = value;
837 let AsmString = ".insn 0x2, $value";
841 // Use InstAliases to match these so that we can combine the insn and format
842 // into a mnemonic to use as the key for the tablegened asm matcher table. The
843 // parser will take care of creating these fake mnemonics and will only do it
844 // for known formats.
845 let EmitPriority = 0, Predicates = [HasStdExtCOrZca] in {
846 def : InstAlias<".insn_cr $opcode, $funct4, $rd, $rs2",
847 (InsnCR AnyReg:$rd, uimm2_opcode:$opcode, uimm4:$funct4,
849 def : InstAlias<".insn_ci $opcode, $funct3, $rd, $imm6",
850 (InsnCI AnyReg:$rd, uimm2_opcode:$opcode, uimm3:$funct3,
852 def : InstAlias<".insn_ciw $opcode, $funct3, $rd, $imm8",
853 (InsnCIW AnyRegC:$rd, uimm2_opcode:$opcode, uimm3:$funct3,
855 def : InstAlias<".insn_css $opcode, $funct3, $rs2, $imm6",
856 (InsnCSS uimm2_opcode:$opcode, uimm3:$funct3, AnyReg:$rs2,
858 def : InstAlias<".insn_cl $opcode, $funct3, $rd, ${imm5}(${rs1})",
859 (InsnCL AnyRegC:$rd, uimm2_opcode:$opcode, uimm3:$funct3,
860 AnyRegC:$rs1, uimm5:$imm5)>;
861 def : InstAlias<".insn_cl $opcode, $funct3, $rd, (${rs1})",
862 (InsnCL AnyRegC:$rd, uimm2_opcode:$opcode, uimm3:$funct3,
864 def : InstAlias<".insn_cs $opcode, $funct3, $rs2, ${imm5}(${rs1})",
865 (InsnCS uimm2_opcode:$opcode, uimm3:$funct3, AnyRegC:$rs2,
866 AnyRegC:$rs1, uimm5:$imm5)>;
867 def : InstAlias<".insn_cs $opcode, $funct3, $rs2, (${rs1})",
868 (InsnCS uimm2_opcode:$opcode, uimm3:$funct3, AnyRegC:$rs2,
870 def : InstAlias<".insn_ca $opcode, $funct6, $funct2, $rd, $rs2",
871 (InsnCA AnyRegC:$rd, uimm2_opcode:$opcode, uimm6:$funct6,
872 uimm2:$funct2, AnyRegC:$rs2)>;
873 def : InstAlias<".insn_cb $opcode, $funct3, $rs1, $imm8",
874 (InsnCB uimm2_opcode:$opcode, uimm3:$funct3, AnyRegC:$rs1,
876 def : InstAlias<".insn_cj $opcode, $funct3, $imm11",
877 (InsnCJ uimm2_opcode:$opcode, uimm3:$funct3, simm12_lsb0:$imm11)>;
880 //===----------------------------------------------------------------------===/i
881 // Compress Instruction tablegen backend.
882 //===----------------------------------------------------------------------===//
884 // Patterns are defined in the same order the compressed instructions appear
885 // under the "RVC Instruction Set Listings" section of the ISA manual.
888 let Predicates = [HasStdExtCOrZca] in {
889 def : CompressPat<(ADDI GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm),
890 (C_ADDI4SPN GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm)>;
891 } // Predicates = [HasStdExtCOrZca]
893 let Predicates = [HasStdExtCOrZcd, HasStdExtD] in {
894 def : CompressPat<(FLD FPR64C:$rd, GPRCMem:$rs1, uimm8_lsb000:$imm),
895 (C_FLD FPR64C:$rd, GPRCMem:$rs1, uimm8_lsb000:$imm)>;
896 } // Predicates = [HasStdExtCOrZcd, HasStdExtD]
898 let Predicates = [HasStdExtCOrZca] in {
899 def : CompressPat<(LW GPRC:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm),
900 (C_LW GPRC:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm)>;
902 let isCompressOnly = true in
903 def : CompressPat<(LW_INX GPRF32C:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm),
904 (C_LW_INX GPRF32C:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm)>;
905 } // Predicates = [HasStdExtCOrZca]
907 let Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in {
908 def : CompressPat<(FLW FPR32C:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm),
909 (C_FLW FPR32C:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm)>;
910 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
912 let Predicates = [HasStdExtCOrZca, IsRV64] in {
913 def : CompressPat<(LD GPRC:$rd, GPRCMem:$rs1, uimm8_lsb000:$imm),
914 (C_LD GPRC:$rd, GPRCMem:$rs1, uimm8_lsb000:$imm)>;
915 } // Predicates = [HasStdExtCOrZca, IsRV64]
917 let Predicates = [HasStdExtCOrZcd, HasStdExtD] in {
918 def : CompressPat<(FSD FPR64C:$rs2, GPRCMem:$rs1, uimm8_lsb000:$imm),
919 (C_FSD FPR64C:$rs2, GPRCMem:$rs1, uimm8_lsb000:$imm)>;
920 } // Predicates = [HasStdExtCOrZcd, HasStdExtD]
922 let Predicates = [HasStdExtCOrZca] in {
923 def : CompressPat<(SW GPRC:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm),
924 (C_SW GPRC:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm)>;
926 let isCompressOnly = true in
927 def : CompressPat<(SW_INX GPRF32C:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm),
928 (C_SW_INX GPRF32C:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm)>;
929 } // Predicates = [HasStdExtCOrZca]
931 let Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in {
932 def : CompressPat<(FSW FPR32C:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm),
933 (C_FSW FPR32C:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm)>;
934 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
936 let Predicates = [HasStdExtCOrZca, IsRV64] in {
937 def : CompressPat<(SD GPRC:$rs2, GPRCMem:$rs1, uimm8_lsb000:$imm),
938 (C_SD GPRC:$rs2, GPRCMem:$rs1, uimm8_lsb000:$imm)>;
939 } // Predicates = [HasStdExtCOrZca, IsRV64]
942 let Predicates = [HasStdExtCOrZca] in {
943 def : CompressPat<(ADDI X0, X0, 0), (C_NOP)>;
944 def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs1, simm6nonzero:$imm),
945 (C_ADDI GPRNoX0:$rs1, simm6nonzero:$imm)>;
946 } // Predicates = [HasStdExtCOrZca]
948 let Predicates = [HasStdExtCOrZca, IsRV32] in {
949 def : CompressPat<(JAL X1, simm12_lsb0:$offset),
950 (C_JAL simm12_lsb0:$offset)>;
951 } // Predicates = [HasStdExtCOrZca, IsRV32]
953 let Predicates = [HasStdExtCOrZca, IsRV64] in {
954 def : CompressPat<(ADDIW GPRNoX0:$rs1, GPRNoX0:$rs1, simm6:$imm),
955 (C_ADDIW GPRNoX0:$rs1, simm6:$imm)>;
956 } // Predicates = [HasStdExtCOrZca, IsRV64]
958 let Predicates = [HasStdExtCOrZca] in {
959 def : CompressPat<(ADDI GPRNoX0:$rd, X0, simm6:$imm),
960 (C_LI GPRNoX0:$rd, simm6:$imm)>;
961 def : CompressPat<(ADDI X2, X2, simm10_lsb0000nonzero:$imm),
962 (C_ADDI16SP X2, simm10_lsb0000nonzero:$imm)>;
963 def : CompressPat<(LUI GPRNoX0X2:$rd, c_lui_imm:$imm),
964 (C_LUI GPRNoX0X2:$rd, c_lui_imm:$imm)>;
965 def : CompressPat<(SRLI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm),
966 (C_SRLI GPRC:$rs1, uimmlog2xlennonzero:$imm)>;
967 def : CompressPat<(SRAI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm),
968 (C_SRAI GPRC:$rs1, uimmlog2xlennonzero:$imm)>;
969 def : CompressPat<(ANDI GPRC:$rs1, GPRC:$rs1, simm6:$imm),
970 (C_ANDI GPRC:$rs1, simm6:$imm)>;
971 def : CompressPat<(SUB GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
972 (C_SUB GPRC:$rs1, GPRC:$rs2)>;
973 def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
974 (C_XOR GPRC:$rs1, GPRC:$rs2)>;
975 let isCompressOnly = true in
976 def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
977 (C_XOR GPRC:$rs1, GPRC:$rs2)>;
978 def : CompressPat<(OR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
979 (C_OR GPRC:$rs1, GPRC:$rs2)>;
980 let isCompressOnly = true in
981 def : CompressPat<(OR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
982 (C_OR GPRC:$rs1, GPRC:$rs2)>;
983 def : CompressPat<(AND GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
984 (C_AND GPRC:$rs1, GPRC:$rs2)>;
985 let isCompressOnly = true in
986 def : CompressPat<(AND GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
987 (C_AND GPRC:$rs1, GPRC:$rs2)>;
988 } // Predicates = [HasStdExtCOrZca]
990 let Predicates = [HasStdExtCOrZca, IsRV64] in {
991 let isCompressOnly = true in
992 def : CompressPat<(ADDIW GPRNoX0:$rd, X0, simm6:$imm),
993 (C_LI GPRNoX0:$rd, simm6:$imm)>;
994 def : CompressPat<(SUBW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
995 (C_SUBW GPRC:$rs1, GPRC:$rs2)>;
996 def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
997 (C_ADDW GPRC:$rs1, GPRC:$rs2)>;
998 let isCompressOnly = true in
999 def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
1000 (C_ADDW GPRC:$rs1, GPRC:$rs2)>;
1001 } // Predicates = [HasStdExtCOrZca, IsRV64]
1003 let Predicates = [HasStdExtCOrZca] in {
1004 def : CompressPat<(JAL X0, simm12_lsb0:$offset),
1005 (C_J simm12_lsb0:$offset)>;
1006 def : CompressPat<(BEQ GPRC:$rs1, X0, simm9_lsb0:$imm),
1007 (C_BEQZ GPRC:$rs1, simm9_lsb0:$imm)>;
1008 let isCompressOnly = true in
1009 def : CompressPat<(BEQ X0, GPRC:$rs1, simm9_lsb0:$imm),
1010 (C_BEQZ GPRC:$rs1, simm9_lsb0:$imm)>;
1011 def : CompressPat<(BNE GPRC:$rs1, X0, simm9_lsb0:$imm),
1012 (C_BNEZ GPRC:$rs1, simm9_lsb0:$imm)>;
1013 let isCompressOnly = true in
1014 def : CompressPat<(BNE X0, GPRC:$rs1, simm9_lsb0:$imm),
1015 (C_BNEZ GPRC:$rs1, simm9_lsb0:$imm)>;
1016 } // Predicates = [HasStdExtCOrZca]
1019 let Predicates = [HasStdExtCOrZca] in {
1020 def : CompressPat<(SLLI GPRNoX0:$rs1, GPRNoX0:$rs1, uimmlog2xlennonzero:$imm),
1021 (C_SLLI GPRNoX0:$rs1, uimmlog2xlennonzero:$imm)>;
1022 } // Predicates = [HasStdExtCOrZca]
1024 let Predicates = [HasStdExtCOrZcd, HasStdExtD] in {
1025 def : CompressPat<(FLD FPR64:$rd, SPMem:$rs1, uimm9_lsb000:$imm),
1026 (C_FLDSP FPR64:$rd, SPMem:$rs1, uimm9_lsb000:$imm)>;
1027 } // Predicates = [HasStdExtCOrZcd, HasStdExtD]
1029 let Predicates = [HasStdExtCOrZca] in {
1030 def : CompressPat<(LW GPRNoX0:$rd, SPMem:$rs1, uimm8_lsb00:$imm),
1031 (C_LWSP GPRNoX0:$rd, SPMem:$rs1, uimm8_lsb00:$imm)>;
1033 let isCompressOnly = true in
1034 def : CompressPat<(LW_INX GPRF32NoX0:$rd, SPMem:$rs1, uimm8_lsb00:$imm),
1035 (C_LWSP_INX GPRF32NoX0:$rd, SPMem:$rs1, uimm8_lsb00:$imm)>;
1036 } // Predicates = [HasStdExtCOrZca]
1038 let Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in {
1039 def : CompressPat<(FLW FPR32:$rd, SPMem:$rs1, uimm8_lsb00:$imm),
1040 (C_FLWSP FPR32:$rd, SPMem:$rs1, uimm8_lsb00:$imm)>;
1041 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
1043 let Predicates = [HasStdExtCOrZca, IsRV64] in {
1044 def : CompressPat<(LD GPRNoX0:$rd, SPMem:$rs1, uimm9_lsb000:$imm),
1045 (C_LDSP GPRNoX0:$rd, SPMem:$rs1, uimm9_lsb000:$imm)>;
1046 } // Predicates = [HasStdExtCOrZca, IsRV64]
1048 let Predicates = [HasStdExtCOrZca] in {
1049 def : CompressPat<(JALR X0, GPRNoX0:$rs1, 0),
1050 (C_JR GPRNoX0:$rs1)>;
1051 let isCompressOnly = true in {
1052 def : CompressPat<(ADD GPRNoX0:$rs1, X0, GPRNoX0:$rs2),
1053 (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
1054 def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, X0),
1055 (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
1057 def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs2, 0),
1058 (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
1059 def : CompressPat<(EBREAK), (C_EBREAK)>;
1060 def : CompressPat<(UNIMP), (C_UNIMP)>;
1061 def : CompressPat<(JALR X1, GPRNoX0:$rs1, 0),
1062 (C_JALR GPRNoX0:$rs1)>;
1063 def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs1, GPRNoX0:$rs2),
1064 (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
1065 let isCompressOnly = true in
1066 def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, GPRNoX0:$rs1),
1067 (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
1068 } // Predicates = [HasStdExtCOrZca]
1070 let Predicates = [HasStdExtCOrZcd, HasStdExtD] in {
1071 def : CompressPat<(FSD FPR64:$rs2, SPMem:$rs1, uimm9_lsb000:$imm),
1072 (C_FSDSP FPR64:$rs2, SPMem:$rs1, uimm9_lsb000:$imm)>;
1073 } // Predicates = [HasStdExtCOrZcd, HasStdExtD]
1075 let Predicates = [HasStdExtCOrZca] in {
1076 def : CompressPat<(SW GPR:$rs2, SPMem:$rs1, uimm8_lsb00:$imm),
1077 (C_SWSP GPR:$rs2, SPMem:$rs1, uimm8_lsb00:$imm)>;
1079 let isCompressOnly = true in
1080 def : CompressPat<(SW_INX GPRF32:$rs2, SPMem:$rs1, uimm8_lsb00:$imm),
1081 (C_SWSP_INX GPRF32:$rs2, SPMem:$rs1, uimm8_lsb00:$imm)>;
1082 } // Predicates = [HasStdExtCOrZca]
1084 let Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in {
1085 def : CompressPat<(FSW FPR32:$rs2, SPMem:$rs1, uimm8_lsb00:$imm),
1086 (C_FSWSP FPR32:$rs2, SPMem:$rs1, uimm8_lsb00:$imm)>;
1087 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
1089 let Predicates = [HasStdExtCOrZca, IsRV64] in {
1090 def : CompressPat<(SD GPR:$rs2, SPMem:$rs1, uimm9_lsb000:$imm),
1091 (C_SDSP GPR:$rs2, SPMem:$rs1, uimm9_lsb000:$imm)>;
1092 } // Predicates = [HasStdExtCOrZca, IsRV64]