1 //===- RISCVInstrInfoC.td - Compressed RISCV 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 : Operand<XLenVT>, 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 = "decodeUImmOperand<6>";
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 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isInt<6>(Imm);}]> {
40 let ParserMatchClass = SImmAsmOperand<6>;
41 let EncoderMethod = "getImmOpValue";
42 let DecoderMethod = "decodeSImmOperand<6>";
43 let MCOperandPredicate = [{
45 if (MCOp.evaluateAsConstantImm(Imm))
47 return MCOp.isBareSymbolRef();
51 def simm6nonzero : Operand<XLenVT>,
52 ImmLeaf<XLenVT, [{return (Imm != 0) && isInt<6>(Imm);}]> {
53 let ParserMatchClass = SImmAsmOperand<6, "NonZero">;
54 let EncoderMethod = "getImmOpValue";
55 let DecoderMethod = "decodeSImmOperand<6>";
56 let MCOperandPredicate = [{
58 if (MCOp.evaluateAsConstantImm(Imm))
59 return (Imm != 0) && isInt<6>(Imm);
60 return MCOp.isBareSymbolRef();
64 def CLUIImmAsmOperand : AsmOperandClass {
66 let RenderMethod = "addImmOperands";
67 let DiagnosticType = !strconcat("Invalid", Name);
71 // c_lui_imm checks the immediate range is in [1, 31] or [0xfffe0, 0xfffff].
72 // The RISC-V ISA describes the constraint as [1, 63], with that value being
73 // loaded in to bits 17-12 of the destination register and sign extended from
74 // bit 17. Therefore, this 6-bit immediate can represent values in the ranges
75 // [1, 31] and [0xfffe0, 0xfffff].
76 def c_lui_imm : Operand<XLenVT>,
77 ImmLeaf<XLenVT, [{return (Imm != 0) &&
79 (Imm >= 0xfffe0 && Imm <= 0xfffff));}]> {
80 let ParserMatchClass = CLUIImmAsmOperand;
81 let EncoderMethod = "getImmOpValue";
82 let DecoderMethod = "decodeCLUIImmOperand";
83 let MCOperandPredicate = [{
85 if (MCOp.evaluateAsConstantImm(Imm))
86 return (Imm != 0) && (isUInt<5>(Imm) ||
87 (Imm >= 0xfffe0 && Imm <= 0xfffff));
88 return MCOp.isBareSymbolRef();
92 // A 7-bit unsigned immediate where the least significant two bits are zero.
93 def uimm7_lsb00 : Operand<XLenVT>,
94 ImmLeaf<XLenVT, [{return isShiftedUInt<5, 2>(Imm);}]> {
95 let ParserMatchClass = UImmAsmOperand<7, "Lsb00">;
96 let EncoderMethod = "getImmOpValue";
97 let DecoderMethod = "decodeUImmOperand<7>";
98 let MCOperandPredicate = [{
100 if (!MCOp.evaluateAsConstantImm(Imm))
102 return isShiftedUInt<5, 2>(Imm);
106 // A 8-bit unsigned immediate where the least significant two bits are zero.
107 def uimm8_lsb00 : Operand<XLenVT>,
108 ImmLeaf<XLenVT, [{return isShiftedUInt<6, 2>(Imm);}]> {
109 let ParserMatchClass = UImmAsmOperand<8, "Lsb00">;
110 let EncoderMethod = "getImmOpValue";
111 let DecoderMethod = "decodeUImmOperand<8>";
112 let MCOperandPredicate = [{
114 if (!MCOp.evaluateAsConstantImm(Imm))
116 return isShiftedUInt<6, 2>(Imm);
120 // A 8-bit unsigned immediate where the least significant three bits are zero.
121 def uimm8_lsb000 : Operand<XLenVT>,
122 ImmLeaf<XLenVT, [{return isShiftedUInt<5, 3>(Imm);}]> {
123 let ParserMatchClass = UImmAsmOperand<8, "Lsb000">;
124 let EncoderMethod = "getImmOpValue";
125 let DecoderMethod = "decodeUImmOperand<8>";
126 let MCOperandPredicate = [{
128 if (!MCOp.evaluateAsConstantImm(Imm))
130 return isShiftedUInt<5, 3>(Imm);
134 // A 9-bit signed immediate where the least significant bit is zero.
135 def simm9_lsb0 : Operand<OtherVT> {
136 let ParserMatchClass = SImmAsmOperand<9, "Lsb0">;
137 let EncoderMethod = "getImmOpValueAsr1";
138 let DecoderMethod = "decodeSImmOperandAndLsl1<9>";
139 let MCOperandPredicate = [{
141 if (MCOp.evaluateAsConstantImm(Imm))
142 return isShiftedInt<8, 1>(Imm);
143 return MCOp.isBareSymbolRef();
148 // A 9-bit unsigned immediate where the least significant three bits are zero.
149 def uimm9_lsb000 : Operand<XLenVT>,
150 ImmLeaf<XLenVT, [{return isShiftedUInt<6, 3>(Imm);}]> {
151 let ParserMatchClass = UImmAsmOperand<9, "Lsb000">;
152 let EncoderMethod = "getImmOpValue";
153 let DecoderMethod = "decodeUImmOperand<9>";
154 let MCOperandPredicate = [{
156 if (!MCOp.evaluateAsConstantImm(Imm))
158 return isShiftedUInt<6, 3>(Imm);
162 // A 10-bit unsigned immediate where the least significant two bits are zero
163 // and the immediate can't be zero.
164 def uimm10_lsb00nonzero : Operand<XLenVT>,
166 [{return isShiftedUInt<8, 2>(Imm) && (Imm != 0);}]> {
167 let ParserMatchClass = UImmAsmOperand<10, "Lsb00NonZero">;
168 let EncoderMethod = "getImmOpValue";
169 let DecoderMethod = "decodeUImmNonZeroOperand<10>";
170 let MCOperandPredicate = [{
172 if (!MCOp.evaluateAsConstantImm(Imm))
174 return isShiftedUInt<8, 2>(Imm) && (Imm != 0);
178 // A 10-bit signed immediate where the least significant four bits are zero.
179 def simm10_lsb0000nonzero : Operand<XLenVT>,
181 [{return (Imm != 0) && isShiftedInt<6, 4>(Imm);}]> {
182 let ParserMatchClass = SImmAsmOperand<10, "Lsb0000NonZero">;
183 let EncoderMethod = "getImmOpValue";
184 let DecoderMethod = "decodeSImmNonZeroOperand<10>";
185 let MCOperandPredicate = [{
187 if (!MCOp.evaluateAsConstantImm(Imm))
189 return isShiftedInt<6, 4>(Imm) && (Imm != 0);
193 // A 12-bit signed immediate where the least significant bit is zero.
194 def simm12_lsb0 : Operand<XLenVT> {
195 let ParserMatchClass = SImmAsmOperand<12, "Lsb0">;
196 let EncoderMethod = "getImmOpValueAsr1";
197 let DecoderMethod = "decodeSImmOperandAndLsl1<12>";
198 let MCOperandPredicate = [{
200 if (MCOp.evaluateAsConstantImm(Imm))
201 return isShiftedInt<11, 1>(Imm);
202 return MCOp.isBareSymbolRef();
206 //===----------------------------------------------------------------------===//
207 // Instruction Class Templates
208 //===----------------------------------------------------------------------===//
210 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
211 class CStackLoad<bits<3> funct3, string OpcodeStr,
212 RegisterClass cls, DAGOperand opnd>
213 : RVInst16CI<funct3, 0b10, (outs cls:$rd), (ins SP:$rs1, opnd:$imm),
214 OpcodeStr, "$rd, ${imm}(${rs1})">;
216 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
217 class CStackStore<bits<3> funct3, string OpcodeStr,
218 RegisterClass cls, DAGOperand opnd>
219 : RVInst16CSS<funct3, 0b10, (outs), (ins cls:$rs2, SP:$rs1, opnd:$imm),
220 OpcodeStr, "$rs2, ${imm}(${rs1})">;
222 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
223 class CLoad_ri<bits<3> funct3, string OpcodeStr,
224 RegisterClass cls, DAGOperand opnd>
225 : RVInst16CL<funct3, 0b00, (outs cls:$rd), (ins GPRC:$rs1, opnd:$imm),
226 OpcodeStr, "$rd, ${imm}(${rs1})">;
228 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
229 class CStore_rri<bits<3> funct3, string OpcodeStr,
230 RegisterClass cls, DAGOperand opnd>
231 : RVInst16CS<funct3, 0b00, (outs), (ins cls:$rs2, GPRC:$rs1, opnd:$imm),
232 OpcodeStr, "$rs2, ${imm}(${rs1})">;
234 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
235 class Bcz<bits<3> funct3, string OpcodeStr, PatFrag CondOp,
237 : RVInst16CB<funct3, 0b01, (outs), (ins cls:$rs1, simm9_lsb0:$imm),
238 OpcodeStr, "$rs1, $imm"> {
240 let isTerminator = 1;
241 let Inst{12} = imm{7};
242 let Inst{11-10} = imm{3-2};
243 let Inst{6-5} = imm{6-5};
244 let Inst{4-3} = imm{1-0};
245 let Inst{2} = imm{4};
248 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
249 class Shift_right<bits<2> funct2, string OpcodeStr, RegisterClass cls,
251 : RVInst16CB<0b100, 0b01, (outs cls:$rs1_wb), (ins cls:$rs1, ImmOpnd:$imm),
252 OpcodeStr, "$rs1, $imm"> {
253 let Constraints = "$rs1 = $rs1_wb";
254 let Inst{12} = imm{5};
255 let Inst{11-10} = funct2;
256 let Inst{6-2} = imm{4-0};
259 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
260 class CS_ALU<bits<6> funct6, bits<2> funct2, string OpcodeStr,
262 : RVInst16CA<funct6, funct2, 0b01, (outs cls:$rd_wb), (ins cls:$rd, cls:$rs2),
263 OpcodeStr, "$rd, $rs2"> {
265 let Constraints = "$rd = $rd_wb";
269 //===----------------------------------------------------------------------===//
271 //===----------------------------------------------------------------------===//
273 let Predicates = [HasStdExtC] in {
275 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Uses = [X2] in
276 def C_ADDI4SPN : RVInst16CIW<0b000, 0b00, (outs GPRC:$rd),
277 (ins SP:$rs1, uimm10_lsb00nonzero:$imm),
278 "c.addi4spn", "$rd, $rs1, $imm"> {
280 let Inst{12-11} = imm{5-4};
281 let Inst{10-7} = imm{9-6};
282 let Inst{6} = imm{2};
283 let Inst{5} = imm{3};
286 let Predicates = [HasStdExtC, HasStdExtD] in
287 def C_FLD : CLoad_ri<0b001, "c.fld", FPR64C, uimm8_lsb000> {
289 let Inst{12-10} = imm{5-3};
290 let Inst{6-5} = imm{7-6};
293 def C_LW : CLoad_ri<0b010, "c.lw", GPRC, uimm7_lsb00> {
295 let Inst{12-10} = imm{5-3};
296 let Inst{6} = imm{2};
297 let Inst{5} = imm{6};
300 let DecoderNamespace = "RISCV32Only_",
301 Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
302 def C_FLW : CLoad_ri<0b011, "c.flw", FPR32C, uimm7_lsb00> {
304 let Inst{12-10} = imm{5-3};
305 let Inst{6} = imm{2};
306 let Inst{5} = imm{6};
309 let Predicates = [HasStdExtC, IsRV64] in
310 def C_LD : CLoad_ri<0b011, "c.ld", GPRC, uimm8_lsb000> {
312 let Inst{12-10} = imm{5-3};
313 let Inst{6-5} = imm{7-6};
316 let Predicates = [HasStdExtC, HasStdExtD] in
317 def C_FSD : CStore_rri<0b101, "c.fsd", FPR64C, uimm8_lsb000> {
319 let Inst{12-10} = imm{5-3};
320 let Inst{6-5} = imm{7-6};
323 def C_SW : CStore_rri<0b110, "c.sw", GPRC, uimm7_lsb00> {
325 let Inst{12-10} = imm{5-3};
326 let Inst{6} = imm{2};
327 let Inst{5} = imm{6};
330 let DecoderNamespace = "RISCV32Only_",
331 Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
332 def C_FSW : CStore_rri<0b111, "c.fsw", FPR32C, uimm7_lsb00> {
334 let Inst{12-10} = imm{5-3};
335 let Inst{6} = imm{2};
336 let Inst{5} = imm{6};
339 let Predicates = [HasStdExtC, IsRV64] in
340 def C_SD : CStore_rri<0b111, "c.sd", GPRC, uimm8_lsb000> {
342 let Inst{12-10} = imm{5-3};
343 let Inst{6-5} = imm{7-6};
346 let rd = 0, imm = 0, hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
347 def C_NOP : RVInst16CI<0b000, 0b01, (outs), (ins), "c.nop", "">;
349 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
350 def C_ADDI : RVInst16CI<0b000, 0b01, (outs GPRNoX0:$rd_wb),
351 (ins GPRNoX0:$rd, simm6nonzero:$imm),
352 "c.addi", "$rd, $imm"> {
353 let Constraints = "$rd = $rd_wb";
354 let Inst{6-2} = imm{4-0};
357 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCall = 1,
358 DecoderNamespace = "RISCV32Only_", Defs = [X1],
359 Predicates = [HasStdExtC, IsRV32] in
360 def C_JAL : RVInst16CJ<0b001, 0b01, (outs), (ins simm12_lsb0:$offset),
363 let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
364 Predicates = [HasStdExtC, IsRV64] in
365 def C_ADDIW : RVInst16CI<0b001, 0b01, (outs GPRNoX0:$rd_wb),
366 (ins GPRNoX0:$rd, simm6:$imm),
367 "c.addiw", "$rd, $imm"> {
368 let Constraints = "$rd = $rd_wb";
369 let Inst{6-2} = imm{4-0};
372 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
373 def C_LI : RVInst16CI<0b010, 0b01, (outs GPRNoX0:$rd), (ins simm6:$imm),
374 "c.li", "$rd, $imm"> {
375 let Inst{6-2} = imm{4-0};
378 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
379 def C_ADDI16SP : RVInst16CI<0b011, 0b01, (outs SP:$rd_wb),
380 (ins SP:$rd, simm10_lsb0000nonzero:$imm),
381 "c.addi16sp", "$rd, $imm"> {
382 let Constraints = "$rd = $rd_wb";
383 let Inst{12} = imm{9};
385 let Inst{6} = imm{4};
386 let Inst{5} = imm{6};
387 let Inst{4-3} = imm{8-7};
388 let Inst{2} = imm{5};
391 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
392 def C_LUI : RVInst16CI<0b011, 0b01, (outs GPRNoX0X2:$rd),
393 (ins c_lui_imm:$imm),
394 "c.lui", "$rd, $imm"> {
395 let Inst{6-2} = imm{4-0};
398 def C_SRLI : Shift_right<0b00, "c.srli", GPRC, uimmlog2xlennonzero>;
399 def C_SRAI : Shift_right<0b01, "c.srai", GPRC, uimmlog2xlennonzero>;
401 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
402 def C_ANDI : RVInst16CB<0b100, 0b01, (outs GPRC:$rs1_wb), (ins GPRC:$rs1, simm6:$imm),
403 "c.andi", "$rs1, $imm"> {
404 let Constraints = "$rs1 = $rs1_wb";
405 let Inst{12} = imm{5};
406 let Inst{11-10} = 0b10;
407 let Inst{6-2} = imm{4-0};
410 def C_SUB : CS_ALU<0b100011, 0b00, "c.sub", GPRC>;
411 def C_XOR : CS_ALU<0b100011, 0b01, "c.xor", GPRC>;
412 def C_OR : CS_ALU<0b100011, 0b10, "c.or" , GPRC>;
413 def C_AND : CS_ALU<0b100011, 0b11, "c.and", GPRC>;
415 let Predicates = [HasStdExtC, IsRV64] in {
416 def C_SUBW : CS_ALU<0b100111, 0b00, "c.subw", GPRC>;
417 def C_ADDW : CS_ALU<0b100111, 0b01, "c.addw", GPRC>;
420 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
421 def C_J : RVInst16CJ<0b101, 0b01, (outs), (ins simm12_lsb0:$offset),
428 def C_BEQZ : Bcz<0b110, "c.beqz", seteq, GPRC>;
429 def C_BNEZ : Bcz<0b111, "c.bnez", setne, GPRC>;
431 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
432 def C_SLLI : RVInst16CI<0b000, 0b10, (outs GPRNoX0:$rd_wb),
433 (ins GPRNoX0:$rd, uimmlog2xlennonzero:$imm),
434 "c.slli" ,"$rd, $imm"> {
435 let Constraints = "$rd = $rd_wb";
436 let Inst{6-2} = imm{4-0};
439 let Predicates = [HasStdExtC, HasStdExtD] in
440 def C_FLDSP : CStackLoad<0b001, "c.fldsp", FPR64, uimm9_lsb000> {
441 let Inst{6-5} = imm{4-3};
442 let Inst{4-2} = imm{8-6};
445 def C_LWSP : CStackLoad<0b010, "c.lwsp", GPRNoX0, uimm8_lsb00> {
446 let Inst{6-4} = imm{4-2};
447 let Inst{3-2} = imm{7-6};
450 let DecoderNamespace = "RISCV32Only_",
451 Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
452 def C_FLWSP : CStackLoad<0b011, "c.flwsp", FPR32, uimm8_lsb00> {
453 let Inst{6-4} = imm{4-2};
454 let Inst{3-2} = imm{7-6};
457 let Predicates = [HasStdExtC, IsRV64] in
458 def C_LDSP : CStackLoad<0b011, "c.ldsp", GPRNoX0, uimm9_lsb000> {
459 let Inst{6-5} = imm{4-3};
460 let Inst{4-2} = imm{8-6};
463 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
464 def C_JR : RVInst16CR<0b1000, 0b10, (outs), (ins GPRNoX0:$rs1),
468 let isTerminator = 1;
469 let isIndirectBranch = 1;
473 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
474 def C_MV : RVInst16CR<0b1000, 0b10, (outs GPRNoX0:$rs1), (ins GPRNoX0:$rs2),
475 "c.mv", "$rs1, $rs2">;
477 let rs1 = 0, rs2 = 0, hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
478 def C_EBREAK : RVInst16CR<0b1001, 0b10, (outs), (ins), "c.ebreak", "">;
480 let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
481 isCall=1, Defs=[X1], rs2 = 0 in
482 def C_JALR : RVInst16CR<0b1001, 0b10, (outs), (ins GPRNoX0:$rs1),
485 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
486 def C_ADD : RVInst16CR<0b1001, 0b10, (outs GPRNoX0:$rs1_wb),
487 (ins GPRNoX0:$rs1, GPRNoX0:$rs2),
488 "c.add", "$rs1, $rs2"> {
489 let Constraints = "$rs1 = $rs1_wb";
492 let Predicates = [HasStdExtC, HasStdExtD] in
493 def C_FSDSP : CStackStore<0b101, "c.fsdsp", FPR64, uimm9_lsb000> {
494 let Inst{12-10} = imm{5-3};
495 let Inst{9-7} = imm{8-6};
498 def C_SWSP : CStackStore<0b110, "c.swsp", GPR, uimm8_lsb00> {
499 let Inst{12-9} = imm{5-2};
500 let Inst{8-7} = imm{7-6};
503 let DecoderNamespace = "RISCV32Only_",
504 Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
505 def C_FSWSP : CStackStore<0b111, "c.fswsp", FPR32, uimm8_lsb00> {
506 let Inst{12-9} = imm{5-2};
507 let Inst{8-7} = imm{7-6};
510 let Predicates = [HasStdExtC, IsRV64] in
511 def C_SDSP : CStackStore<0b111, "c.sdsp", GPR, uimm9_lsb000> {
512 let Inst{12-10} = imm{5-3};
513 let Inst{9-7} = imm{8-6};
516 // The all zeros pattern isn't a valid RISC-V instruction. It's used by GNU
517 // binutils as 16-bit instruction known to be unimplemented (i.e., trapping).
518 let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
519 def C_UNIMP : RVInst16<(outs), (ins), "c.unimp", "", [], InstFormatOther> {
523 } // Predicates = [HasStdExtC]
525 //===----------------------------------------------------------------------===//
526 // Compress Instruction tablegen backend.
527 //===----------------------------------------------------------------------===//
529 class CompressPat<dag input, dag output> {
532 list<Predicate> Predicates = [];
535 // Patterns are defined in the same order the compressed instructions appear
536 // on page 82 of the ISA manual.
539 let Predicates = [HasStdExtC] in {
540 def : CompressPat<(ADDI GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm),
541 (C_ADDI4SPN GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm)>;
542 } // Predicates = [HasStdExtC]
544 let Predicates = [HasStdExtC, HasStdExtD] in {
545 def : CompressPat<(FLD FPR64C:$rd, GPRC:$rs1, uimm8_lsb000:$imm),
546 (C_FLD FPR64C:$rd, GPRC:$rs1, uimm8_lsb000:$imm)>;
547 } // Predicates = [HasStdExtC, HasStdExtD]
549 let Predicates = [HasStdExtC] in {
550 def : CompressPat<(LW GPRC:$rd, GPRC:$rs1, uimm7_lsb00:$imm),
551 (C_LW GPRC:$rd, GPRC:$rs1, uimm7_lsb00:$imm)>;
552 } // Predicates = [HasStdExtC]
554 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
555 def : CompressPat<(FLW FPR32C:$rd, GPRC:$rs1, uimm7_lsb00:$imm),
556 (C_FLW FPR32C:$rd, GPRC:$rs1, uimm7_lsb00:$imm)>;
557 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
559 let Predicates = [HasStdExtC, IsRV64] in {
560 def : CompressPat<(LD GPRC:$rd, GPRC:$rs1, uimm8_lsb000:$imm),
561 (C_LD GPRC:$rd, GPRC:$rs1, uimm8_lsb000:$imm)>;
562 } // Predicates = [HasStdExtC, IsRV64]
564 let Predicates = [HasStdExtC, HasStdExtD] in {
565 def : CompressPat<(FSD FPR64C:$rs2, GPRC:$rs1, uimm8_lsb000:$imm),
566 (C_FSD FPR64C:$rs2, GPRC:$rs1, uimm8_lsb000:$imm)>;
567 } // Predicates = [HasStdExtC, HasStdExtD]
569 let Predicates = [HasStdExtC] in {
570 def : CompressPat<(SW GPRC:$rs2, GPRC:$rs1, uimm7_lsb00:$imm),
571 (C_SW GPRC:$rs2, GPRC:$rs1, uimm7_lsb00:$imm)>;
572 } // Predicates = [HasStdExtC]
574 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
575 def : CompressPat<(FSW FPR32C:$rs2, GPRC:$rs1,uimm7_lsb00:$imm),
576 (C_FSW FPR32C:$rs2, GPRC:$rs1, uimm7_lsb00:$imm)>;
577 } // Predicate = [HasStdExtC, HasStdExtF, IsRV32]
579 let Predicates = [HasStdExtC, IsRV64] in {
580 def : CompressPat<(SD GPRC:$rs2, GPRC:$rs1, uimm8_lsb000:$imm),
581 (C_SD GPRC:$rs2, GPRC:$rs1, uimm8_lsb000:$imm)>;
582 } // Predicates = [HasStdExtC, IsRV64]
585 let Predicates = [HasStdExtC] in {
586 def : CompressPat<(ADDI X0, X0, 0), (C_NOP)>;
587 def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs1, simm6nonzero:$imm),
588 (C_ADDI GPRNoX0:$rs1, simm6nonzero:$imm)>;
589 } // Predicates = [HasStdExtC]
591 let Predicates = [HasStdExtC, IsRV32] in {
592 def : CompressPat<(JAL X1, simm12_lsb0:$offset),
593 (C_JAL simm12_lsb0:$offset)>;
594 } // Predicates = [HasStdExtC, IsRV32]
596 let Predicates = [HasStdExtC, IsRV64] in {
597 def : CompressPat<(ADDIW GPRNoX0:$rs1, GPRNoX0:$rs1, simm6:$imm),
598 (C_ADDIW GPRNoX0:$rs1, simm6:$imm)>;
599 } // Predicates = [HasStdExtC, IsRV64]
601 let Predicates = [HasStdExtC] in {
602 def : CompressPat<(ADDI GPRNoX0:$rd, X0, simm6:$imm),
603 (C_LI GPRNoX0:$rd, simm6:$imm)>;
604 def : CompressPat<(ADDI X2, X2, simm10_lsb0000nonzero:$imm),
605 (C_ADDI16SP X2, simm10_lsb0000nonzero:$imm)>;
606 def : CompressPat<(LUI GPRNoX0X2:$rd, c_lui_imm:$imm),
607 (C_LUI GPRNoX0X2:$rd, c_lui_imm:$imm)>;
608 def : CompressPat<(SRLI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm),
609 (C_SRLI GPRC:$rs1, uimmlog2xlennonzero:$imm)>;
610 def : CompressPat<(SRAI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm),
611 (C_SRAI GPRC:$rs1, uimmlog2xlennonzero:$imm)>;
612 def : CompressPat<(ANDI GPRC:$rs1, GPRC:$rs1, simm6:$imm),
613 (C_ANDI GPRC:$rs1, simm6:$imm)>;
614 def : CompressPat<(SUB GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
615 (C_SUB GPRC:$rs1, GPRC:$rs2)>;
616 def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
617 (C_XOR GPRC:$rs1, GPRC:$rs2)>;
618 def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
619 (C_XOR GPRC:$rs1, GPRC:$rs2)>;
620 def : CompressPat<(OR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
621 (C_OR GPRC:$rs1, GPRC:$rs2)>;
622 def : CompressPat<(OR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
623 (C_OR GPRC:$rs1, GPRC:$rs2)>;
624 def : CompressPat<(AND GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
625 (C_AND GPRC:$rs1, GPRC:$rs2)>;
626 def : CompressPat<(AND GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
627 (C_AND GPRC:$rs1, GPRC:$rs2)>;
628 } // Predicates = [HasStdExtC]
630 let Predicates = [HasStdExtC, IsRV64] in {
631 def : CompressPat<(ADDIW GPRNoX0:$rd, X0, simm6:$imm),
632 (C_LI GPRNoX0:$rd, simm6:$imm)>;
633 def : CompressPat<(SUBW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
634 (C_SUBW GPRC:$rs1, GPRC:$rs2)>;
635 def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
636 (C_ADDW GPRC:$rs1, GPRC:$rs2)>;
637 def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
638 (C_ADDW GPRC:$rs1, GPRC:$rs2)>;
639 } // Predicates = [HasStdExtC, IsRV64]
641 let Predicates = [HasStdExtC] in {
642 def : CompressPat<(JAL X0, simm12_lsb0:$offset),
643 (C_J simm12_lsb0:$offset)>;
644 def : CompressPat<(BEQ GPRC:$rs1, X0, simm9_lsb0:$imm),
645 (C_BEQZ GPRC:$rs1, simm9_lsb0:$imm)>;
646 def : CompressPat<(BNE GPRC:$rs1, X0, simm9_lsb0:$imm),
647 (C_BNEZ GPRC:$rs1, simm9_lsb0:$imm)>;
648 } // Predicates = [HasStdExtC]
651 let Predicates = [HasStdExtC] in {
652 def : CompressPat<(SLLI GPRNoX0:$rs1, GPRNoX0:$rs1, uimmlog2xlennonzero:$imm),
653 (C_SLLI GPRNoX0:$rs1, uimmlog2xlennonzero:$imm)>;
654 } // Predicates = [HasStdExtC]
656 let Predicates = [HasStdExtC, HasStdExtD] in {
657 def : CompressPat<(FLD FPR64:$rd, SP:$rs1, uimm9_lsb000:$imm),
658 (C_FLDSP FPR64:$rd, SP:$rs1, uimm9_lsb000:$imm)>;
659 } // Predicates = [HasStdExtC, HasStdExtD]
661 let Predicates = [HasStdExtC] in {
662 def : CompressPat<(LW GPRNoX0:$rd, SP:$rs1, uimm8_lsb00:$imm),
663 (C_LWSP GPRNoX0:$rd, SP:$rs1, uimm8_lsb00:$imm)>;
664 } // Predicates = [HasStdExtC]
666 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
667 def : CompressPat<(FLW FPR32:$rd, SP:$rs1, uimm8_lsb00:$imm),
668 (C_FLWSP FPR32:$rd, SP:$rs1, uimm8_lsb00:$imm)>;
669 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
671 let Predicates = [HasStdExtC, IsRV64] in {
672 def : CompressPat<(LD GPRNoX0:$rd, SP:$rs1, uimm9_lsb000:$imm),
673 (C_LDSP GPRNoX0:$rd, SP:$rs1, uimm9_lsb000:$imm)>;
674 } // Predicates = [HasStdExtC, IsRV64]
676 let Predicates = [HasStdExtC] in {
677 def : CompressPat<(JALR X0, GPRNoX0:$rs1, 0),
678 (C_JR GPRNoX0:$rs1)>;
679 def : CompressPat<(ADD GPRNoX0:$rs1, X0, GPRNoX0:$rs2),
680 (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
681 def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, X0),
682 (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
683 def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs2, 0),
684 (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
685 def : CompressPat<(EBREAK), (C_EBREAK)>;
686 def : CompressPat<(UNIMP), (C_UNIMP)>;
687 def : CompressPat<(JALR X1, GPRNoX0:$rs1, 0),
688 (C_JALR GPRNoX0:$rs1)>;
689 def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs1, GPRNoX0:$rs2),
690 (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
691 def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, GPRNoX0:$rs1),
692 (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
693 } // Predicates = [HasStdExtC]
695 let Predicates = [HasStdExtC, HasStdExtD] in {
696 def : CompressPat<(FSD FPR64:$rs2, SP:$rs1, uimm9_lsb000:$imm),
697 (C_FSDSP FPR64:$rs2, SP:$rs1, uimm9_lsb000:$imm)>;
698 } // Predicates = [HasStdExtC, HasStdExtD]
700 let Predicates = [HasStdExtC] in {
701 def : CompressPat<(SW GPR:$rs2, SP:$rs1, uimm8_lsb00:$imm),
702 (C_SWSP GPR:$rs2, SP:$rs1, uimm8_lsb00:$imm)>;
703 } // Predicates = [HasStdExtC]
705 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
706 def : CompressPat<(FSW FPR32:$rs2, SP:$rs1, uimm8_lsb00:$imm),
707 (C_FSWSP FPR32:$rs2, SP:$rs1, uimm8_lsb00:$imm)>;
708 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
710 let Predicates = [HasStdExtC, IsRV64] in {
711 def : CompressPat<(SD GPR:$rs2, SP:$rs1, uimm9_lsb000:$imm),
712 (C_SDSP GPR:$rs2, SP:$rs1, uimm9_lsb000:$imm)>;
713 } // Predicates = [HasStdExtC, IsRV64]