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 immzero : Operand<XLenVT>,
65 ImmLeaf<XLenVT, [{return (Imm == 0);}]> {
66 let ParserMatchClass = ImmZeroAsmOperand;
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 : Operand<XLenVT>,
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 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 : Operand<XLenVT>,
99 ImmLeaf<XLenVT, [{return isShiftedUInt<5, 2>(Imm);}]> {
100 let ParserMatchClass = UImmAsmOperand<7, "Lsb00">;
101 let EncoderMethod = "getImmOpValue";
102 let DecoderMethod = "decodeUImmOperand<7>";
103 let MCOperandPredicate = [{
105 if (!MCOp.evaluateAsConstantImm(Imm))
107 return isShiftedUInt<5, 2>(Imm);
111 // A 8-bit unsigned immediate where the least significant two bits are zero.
112 def uimm8_lsb00 : Operand<XLenVT>,
113 ImmLeaf<XLenVT, [{return isShiftedUInt<6, 2>(Imm);}]> {
114 let ParserMatchClass = UImmAsmOperand<8, "Lsb00">;
115 let EncoderMethod = "getImmOpValue";
116 let DecoderMethod = "decodeUImmOperand<8>";
117 let MCOperandPredicate = [{
119 if (!MCOp.evaluateAsConstantImm(Imm))
121 return isShiftedUInt<6, 2>(Imm);
125 // A 8-bit unsigned immediate where the least significant three bits are zero.
126 def uimm8_lsb000 : Operand<XLenVT>,
127 ImmLeaf<XLenVT, [{return isShiftedUInt<5, 3>(Imm);}]> {
128 let ParserMatchClass = UImmAsmOperand<8, "Lsb000">;
129 let EncoderMethod = "getImmOpValue";
130 let DecoderMethod = "decodeUImmOperand<8>";
131 let MCOperandPredicate = [{
133 if (!MCOp.evaluateAsConstantImm(Imm))
135 return isShiftedUInt<5, 3>(Imm);
139 // A 9-bit signed immediate where the least significant bit is zero.
140 def simm9_lsb0 : Operand<OtherVT> {
141 let ParserMatchClass = SImmAsmOperand<9, "Lsb0">;
142 let EncoderMethod = "getImmOpValueAsr1";
143 let DecoderMethod = "decodeSImmOperandAndLsl1<9>";
144 let MCOperandPredicate = [{
146 if (MCOp.evaluateAsConstantImm(Imm))
147 return isShiftedInt<8, 1>(Imm);
148 return MCOp.isBareSymbolRef();
153 // A 9-bit unsigned immediate where the least significant three bits are zero.
154 def uimm9_lsb000 : Operand<XLenVT>,
155 ImmLeaf<XLenVT, [{return isShiftedUInt<6, 3>(Imm);}]> {
156 let ParserMatchClass = UImmAsmOperand<9, "Lsb000">;
157 let EncoderMethod = "getImmOpValue";
158 let DecoderMethod = "decodeUImmOperand<9>";
159 let MCOperandPredicate = [{
161 if (!MCOp.evaluateAsConstantImm(Imm))
163 return isShiftedUInt<6, 3>(Imm);
167 // A 10-bit unsigned immediate where the least significant two bits are zero
168 // and the immediate can't be zero.
169 def uimm10_lsb00nonzero : Operand<XLenVT>,
171 [{return isShiftedUInt<8, 2>(Imm) && (Imm != 0);}]> {
172 let ParserMatchClass = UImmAsmOperand<10, "Lsb00NonZero">;
173 let EncoderMethod = "getImmOpValue";
174 let DecoderMethod = "decodeUImmNonZeroOperand<10>";
175 let MCOperandPredicate = [{
177 if (!MCOp.evaluateAsConstantImm(Imm))
179 return isShiftedUInt<8, 2>(Imm) && (Imm != 0);
183 // A 10-bit signed immediate where the least significant four bits are zero.
184 def simm10_lsb0000nonzero : Operand<XLenVT>,
186 [{return (Imm != 0) && isShiftedInt<6, 4>(Imm);}]> {
187 let ParserMatchClass = SImmAsmOperand<10, "Lsb0000NonZero">;
188 let EncoderMethod = "getImmOpValue";
189 let DecoderMethod = "decodeSImmNonZeroOperand<10>";
190 let MCOperandPredicate = [{
192 if (!MCOp.evaluateAsConstantImm(Imm))
194 return isShiftedInt<6, 4>(Imm) && (Imm != 0);
198 // A 12-bit signed immediate where the least significant bit is zero.
199 def simm12_lsb0 : Operand<XLenVT> {
200 let ParserMatchClass = SImmAsmOperand<12, "Lsb0">;
201 let EncoderMethod = "getImmOpValueAsr1";
202 let DecoderMethod = "decodeSImmOperandAndLsl1<12>";
203 let MCOperandPredicate = [{
205 if (MCOp.evaluateAsConstantImm(Imm))
206 return isShiftedInt<11, 1>(Imm);
207 return MCOp.isBareSymbolRef();
211 //===----------------------------------------------------------------------===//
212 // Instruction Class Templates
213 //===----------------------------------------------------------------------===//
215 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
216 class CStackLoad<bits<3> funct3, string OpcodeStr,
217 RegisterClass cls, DAGOperand opnd>
218 : RVInst16CI<funct3, 0b10, (outs cls:$rd), (ins SP:$rs1, opnd:$imm),
219 OpcodeStr, "$rd, ${imm}(${rs1})">;
221 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
222 class CStackStore<bits<3> funct3, string OpcodeStr,
223 RegisterClass cls, DAGOperand opnd>
224 : RVInst16CSS<funct3, 0b10, (outs), (ins cls:$rs2, SP:$rs1, opnd:$imm),
225 OpcodeStr, "$rs2, ${imm}(${rs1})">;
227 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
228 class CLoad_ri<bits<3> funct3, string OpcodeStr,
229 RegisterClass cls, DAGOperand opnd>
230 : RVInst16CL<funct3, 0b00, (outs cls:$rd), (ins GPRC:$rs1, opnd:$imm),
231 OpcodeStr, "$rd, ${imm}(${rs1})">;
233 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
234 class CStore_rri<bits<3> funct3, string OpcodeStr,
235 RegisterClass cls, DAGOperand opnd>
236 : RVInst16CS<funct3, 0b00, (outs), (ins cls:$rs2, GPRC:$rs1, opnd:$imm),
237 OpcodeStr, "$rs2, ${imm}(${rs1})">;
239 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
240 class Bcz<bits<3> funct3, string OpcodeStr, PatFrag CondOp,
242 : RVInst16CB<funct3, 0b01, (outs), (ins cls:$rs1, simm9_lsb0:$imm),
243 OpcodeStr, "$rs1, $imm"> {
245 let isTerminator = 1;
246 let Inst{12} = imm{7};
247 let Inst{11-10} = imm{3-2};
248 let Inst{6-5} = imm{6-5};
249 let Inst{4-3} = imm{1-0};
250 let Inst{2} = imm{4};
253 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
254 class Shift_right<bits<2> funct2, string OpcodeStr, RegisterClass cls,
256 : RVInst16CB<0b100, 0b01, (outs cls:$rs1_wb), (ins cls:$rs1, ImmOpnd:$imm),
257 OpcodeStr, "$rs1, $imm"> {
258 let Constraints = "$rs1 = $rs1_wb";
259 let Inst{12} = imm{5};
260 let Inst{11-10} = funct2;
261 let Inst{6-2} = imm{4-0};
264 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
265 class CS_ALU<bits<6> funct6, bits<2> funct2, string OpcodeStr,
267 : RVInst16CA<funct6, funct2, 0b01, (outs cls:$rd_wb), (ins cls:$rd, cls:$rs2),
268 OpcodeStr, "$rd, $rs2"> {
270 let Constraints = "$rd = $rd_wb";
274 //===----------------------------------------------------------------------===//
276 //===----------------------------------------------------------------------===//
278 let Predicates = [HasStdExtC] in {
280 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Uses = [X2] in
281 def C_ADDI4SPN : RVInst16CIW<0b000, 0b00, (outs GPRC:$rd),
282 (ins SP:$rs1, uimm10_lsb00nonzero:$imm),
283 "c.addi4spn", "$rd, $rs1, $imm"> {
285 let Inst{12-11} = imm{5-4};
286 let Inst{10-7} = imm{9-6};
287 let Inst{6} = imm{2};
288 let Inst{5} = imm{3};
291 let Predicates = [HasStdExtC, HasStdExtD] in
292 def C_FLD : CLoad_ri<0b001, "c.fld", FPR64C, uimm8_lsb000> {
294 let Inst{12-10} = imm{5-3};
295 let Inst{6-5} = imm{7-6};
298 def C_LW : CLoad_ri<0b010, "c.lw", GPRC, uimm7_lsb00> {
300 let Inst{12-10} = imm{5-3};
301 let Inst{6} = imm{2};
302 let Inst{5} = imm{6};
305 let DecoderNamespace = "RISCV32Only_",
306 Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
307 def C_FLW : CLoad_ri<0b011, "c.flw", FPR32C, uimm7_lsb00> {
309 let Inst{12-10} = imm{5-3};
310 let Inst{6} = imm{2};
311 let Inst{5} = imm{6};
314 let Predicates = [HasStdExtC, IsRV64] in
315 def C_LD : CLoad_ri<0b011, "c.ld", GPRC, uimm8_lsb000> {
317 let Inst{12-10} = imm{5-3};
318 let Inst{6-5} = imm{7-6};
321 let Predicates = [HasStdExtC, HasStdExtD] in
322 def C_FSD : CStore_rri<0b101, "c.fsd", FPR64C, uimm8_lsb000> {
324 let Inst{12-10} = imm{5-3};
325 let Inst{6-5} = imm{7-6};
328 def C_SW : CStore_rri<0b110, "c.sw", GPRC, uimm7_lsb00> {
330 let Inst{12-10} = imm{5-3};
331 let Inst{6} = imm{2};
332 let Inst{5} = imm{6};
335 let DecoderNamespace = "RISCV32Only_",
336 Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
337 def C_FSW : CStore_rri<0b111, "c.fsw", FPR32C, uimm7_lsb00> {
339 let Inst{12-10} = imm{5-3};
340 let Inst{6} = imm{2};
341 let Inst{5} = imm{6};
344 let Predicates = [HasStdExtC, IsRV64] in
345 def C_SD : CStore_rri<0b111, "c.sd", GPRC, uimm8_lsb000> {
347 let Inst{12-10} = imm{5-3};
348 let Inst{6-5} = imm{7-6};
351 let rd = 0, imm = 0, hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
352 def C_NOP : RVInst16CI<0b000, 0b01, (outs), (ins), "c.nop", "">
357 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
358 def C_ADDI : RVInst16CI<0b000, 0b01, (outs GPRNoX0:$rd_wb),
359 (ins GPRNoX0:$rd, simm6nonzero:$imm),
360 "c.addi", "$rd, $imm"> {
361 let Constraints = "$rd = $rd_wb";
362 let Inst{6-2} = imm{4-0};
365 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
366 def C_ADDI_NOP : RVInst16CI<0b000, 0b01, (outs GPRX0:$rd_wb),
367 (ins GPRX0:$rd, immzero:$imm),
368 "c.addi", "$rd, $imm"> {
369 let Constraints = "$rd = $rd_wb";
371 let isAsmParserOnly = 1;
374 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCall = 1,
375 DecoderNamespace = "RISCV32Only_", Defs = [X1],
376 Predicates = [HasStdExtC, IsRV32] in
377 def C_JAL : RVInst16CJ<0b001, 0b01, (outs), (ins simm12_lsb0:$offset),
380 let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
381 Predicates = [HasStdExtC, IsRV64] in
382 def C_ADDIW : RVInst16CI<0b001, 0b01, (outs GPRNoX0:$rd_wb),
383 (ins GPRNoX0:$rd, simm6:$imm),
384 "c.addiw", "$rd, $imm"> {
385 let Constraints = "$rd = $rd_wb";
386 let Inst{6-2} = imm{4-0};
389 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
390 def C_LI : RVInst16CI<0b010, 0b01, (outs GPRNoX0:$rd), (ins simm6:$imm),
391 "c.li", "$rd, $imm"> {
392 let Inst{6-2} = imm{4-0};
395 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
396 def C_ADDI16SP : RVInst16CI<0b011, 0b01, (outs SP:$rd_wb),
397 (ins SP:$rd, simm10_lsb0000nonzero:$imm),
398 "c.addi16sp", "$rd, $imm"> {
399 let Constraints = "$rd = $rd_wb";
400 let Inst{12} = imm{9};
402 let Inst{6} = imm{4};
403 let Inst{5} = imm{6};
404 let Inst{4-3} = imm{8-7};
405 let Inst{2} = imm{5};
408 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
409 def C_LUI : RVInst16CI<0b011, 0b01, (outs GPRNoX0X2:$rd),
410 (ins c_lui_imm:$imm),
411 "c.lui", "$rd, $imm"> {
412 let Inst{6-2} = imm{4-0};
415 def C_SRLI : Shift_right<0b00, "c.srli", GPRC, uimmlog2xlennonzero>;
416 def C_SRAI : Shift_right<0b01, "c.srai", GPRC, uimmlog2xlennonzero>;
418 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
419 def C_ANDI : RVInst16CB<0b100, 0b01, (outs GPRC:$rs1_wb), (ins GPRC:$rs1, simm6:$imm),
420 "c.andi", "$rs1, $imm"> {
421 let Constraints = "$rs1 = $rs1_wb";
422 let Inst{12} = imm{5};
423 let Inst{11-10} = 0b10;
424 let Inst{6-2} = imm{4-0};
427 def C_SUB : CS_ALU<0b100011, 0b00, "c.sub", GPRC>;
428 def C_XOR : CS_ALU<0b100011, 0b01, "c.xor", GPRC>;
429 def C_OR : CS_ALU<0b100011, 0b10, "c.or" , GPRC>;
430 def C_AND : CS_ALU<0b100011, 0b11, "c.and", GPRC>;
432 let Predicates = [HasStdExtC, IsRV64] in {
433 def C_SUBW : CS_ALU<0b100111, 0b00, "c.subw", GPRC>;
434 def C_ADDW : CS_ALU<0b100111, 0b01, "c.addw", GPRC>;
437 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
438 def C_J : RVInst16CJ<0b101, 0b01, (outs), (ins simm12_lsb0:$offset),
445 def C_BEQZ : Bcz<0b110, "c.beqz", seteq, GPRC>;
446 def C_BNEZ : Bcz<0b111, "c.bnez", setne, GPRC>;
448 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
449 def C_SLLI : RVInst16CI<0b000, 0b10, (outs GPRNoX0:$rd_wb),
450 (ins GPRNoX0:$rd, uimmlog2xlennonzero:$imm),
451 "c.slli" ,"$rd, $imm"> {
452 let Constraints = "$rd = $rd_wb";
453 let Inst{6-2} = imm{4-0};
456 let Predicates = [HasStdExtC, HasStdExtD] in
457 def C_FLDSP : CStackLoad<0b001, "c.fldsp", FPR64, uimm9_lsb000> {
458 let Inst{6-5} = imm{4-3};
459 let Inst{4-2} = imm{8-6};
462 def C_LWSP : CStackLoad<0b010, "c.lwsp", GPRNoX0, uimm8_lsb00> {
463 let Inst{6-4} = imm{4-2};
464 let Inst{3-2} = imm{7-6};
467 let DecoderNamespace = "RISCV32Only_",
468 Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
469 def C_FLWSP : CStackLoad<0b011, "c.flwsp", FPR32, uimm8_lsb00> {
470 let Inst{6-4} = imm{4-2};
471 let Inst{3-2} = imm{7-6};
474 let Predicates = [HasStdExtC, IsRV64] in
475 def C_LDSP : CStackLoad<0b011, "c.ldsp", GPRNoX0, uimm9_lsb000> {
476 let Inst{6-5} = imm{4-3};
477 let Inst{4-2} = imm{8-6};
480 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
481 def C_JR : RVInst16CR<0b1000, 0b10, (outs), (ins GPRNoX0:$rs1),
485 let isTerminator = 1;
486 let isIndirectBranch = 1;
490 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
491 def C_MV : RVInst16CR<0b1000, 0b10, (outs GPRNoX0:$rs1), (ins GPRNoX0:$rs2),
492 "c.mv", "$rs1, $rs2">;
494 let rs1 = 0, rs2 = 0, hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
495 def C_EBREAK : RVInst16CR<0b1001, 0b10, (outs), (ins), "c.ebreak", "">;
497 let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
498 isCall=1, Defs=[X1], rs2 = 0 in
499 def C_JALR : RVInst16CR<0b1001, 0b10, (outs), (ins GPRNoX0:$rs1),
502 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
503 def C_ADD : RVInst16CR<0b1001, 0b10, (outs GPRNoX0:$rs1_wb),
504 (ins GPRNoX0:$rs1, GPRNoX0:$rs2),
505 "c.add", "$rs1, $rs2"> {
506 let Constraints = "$rs1 = $rs1_wb";
509 let Predicates = [HasStdExtC, HasStdExtD] in
510 def C_FSDSP : CStackStore<0b101, "c.fsdsp", FPR64, uimm9_lsb000> {
511 let Inst{12-10} = imm{5-3};
512 let Inst{9-7} = imm{8-6};
515 def C_SWSP : CStackStore<0b110, "c.swsp", GPR, uimm8_lsb00> {
516 let Inst{12-9} = imm{5-2};
517 let Inst{8-7} = imm{7-6};
520 let DecoderNamespace = "RISCV32Only_",
521 Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
522 def C_FSWSP : CStackStore<0b111, "c.fswsp", FPR32, uimm8_lsb00> {
523 let Inst{12-9} = imm{5-2};
524 let Inst{8-7} = imm{7-6};
527 let Predicates = [HasStdExtC, IsRV64] in
528 def C_SDSP : CStackStore<0b111, "c.sdsp", GPR, uimm9_lsb000> {
529 let Inst{12-10} = imm{5-3};
530 let Inst{9-7} = imm{8-6};
533 // The all zeros pattern isn't a valid RISC-V instruction. It's used by GNU
534 // binutils as 16-bit instruction known to be unimplemented (i.e., trapping).
535 let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
536 def C_UNIMP : RVInst16<(outs), (ins), "c.unimp", "", [], InstFormatOther> {
540 } // Predicates = [HasStdExtC]
542 //===----------------------------------------------------------------------===//
544 //===----------------------------------------------------------------------===//
546 let Predicates = [HasStdExtC, HasRVCHints], hasSideEffects = 0, mayLoad = 0,
551 def C_NOP_HINT : RVInst16CI<0b000, 0b01, (outs), (ins simm6nonzero:$imm),
553 let Inst{6-2} = imm{4-0};
554 let DecoderMethod = "decodeRVCInstrSImm";
557 // Just a different syntax for the c.nop hint: c.addi x0, simm6 vs c.nop simm6.
558 def C_ADDI_HINT_X0 : RVInst16CI<0b000, 0b01, (outs GPRX0:$rd_wb),
559 (ins GPRX0:$rd, simm6nonzero:$imm),
560 "c.addi", "$rd, $imm"> {
561 let Constraints = "$rd = $rd_wb";
562 let Inst{6-2} = imm{4-0};
563 let isAsmParserOnly = 1;
566 def C_ADDI_HINT_IMM_ZERO : RVInst16CI<0b000, 0b01, (outs GPRNoX0:$rd_wb),
567 (ins GPRNoX0:$rd, immzero:$imm),
568 "c.addi", "$rd, $imm"> {
569 let Constraints = "$rd = $rd_wb";
571 let isAsmParserOnly = 1;
574 def C_LI_HINT : RVInst16CI<0b010, 0b01, (outs GPRX0:$rd), (ins simm6:$imm),
575 "c.li", "$rd, $imm"> {
576 let Inst{6-2} = imm{4-0};
578 let DecoderMethod = "decodeRVCInstrRdSImm";
581 def C_LUI_HINT : RVInst16CI<0b011, 0b01, (outs GPRX0:$rd),
582 (ins c_lui_imm:$imm),
583 "c.lui", "$rd, $imm"> {
584 let Inst{6-2} = imm{4-0};
586 let DecoderMethod = "decodeRVCInstrRdSImm";
589 def C_MV_HINT : RVInst16CR<0b1000, 0b10, (outs GPRX0:$rs1), (ins GPRNoX0:$rs2),
590 "c.mv", "$rs1, $rs2">
593 let DecoderMethod = "decodeRVCInstrRdRs2";
596 def C_ADD_HINT : RVInst16CR<0b1001, 0b10, (outs GPRX0:$rs1_wb),
597 (ins GPRX0:$rs1, GPRNoX0:$rs2),
598 "c.add", "$rs1, $rs2"> {
599 let Constraints = "$rs1 = $rs1_wb";
601 let DecoderMethod = "decodeRVCInstrRdRs1Rs2";
604 def C_SLLI_HINT : RVInst16CI<0b000, 0b10, (outs GPRX0:$rd_wb),
605 (ins GPRX0:$rd, uimmlog2xlennonzero:$imm),
606 "c.slli" ,"$rd, $imm"> {
607 let Constraints = "$rd = $rd_wb";
608 let Inst{6-2} = imm{4-0};
610 let DecoderMethod = "decodeRVCInstrRdRs1UImm";
613 def C_SLLI64_HINT : RVInst16CI<0b000, 0b10, (outs GPR:$rd_wb), (ins GPR:$rd),
615 let Constraints = "$rd = $rd_wb";
620 def C_SRLI64_HINT : RVInst16CI<0b100, 0b01, (outs GPRC:$rd_wb),
623 let Constraints = "$rd = $rd_wb";
629 def C_SRAI64_HINT : RVInst16CI<0b100, 0b01, (outs GPRC:$rd_wb),
632 let Constraints = "$rd = $rd_wb";
638 } // Predicates = [HasStdExtC, HasRVCHints], hasSideEffects = 0, mayLoad = 0,
641 //===----------------------------------------------------------------------===//
642 // Assembler Pseudo Instructions
643 //===----------------------------------------------------------------------===//
645 let EmitPriority = 0 in {
646 let Predicates = [HasStdExtC, HasStdExtD] in
647 def : InstAlias<"c.fld $rd, (${rs1})", (C_FLD FPR64C:$rd, GPRC:$rs1, 0)>;
649 def : InstAlias<"c.lw $rd, (${rs1})", (C_LW GPRC:$rd, GPRC:$rs1, 0)>;
651 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
652 def : InstAlias<"c.flw $rd, (${rs1})", (C_FLW FPR32C:$rd, GPRC:$rs1, 0)>;
654 let Predicates = [HasStdExtC, IsRV64] in
655 def : InstAlias<"c.ld $rd, (${rs1})", (C_LD GPRC:$rd, GPRC:$rs1, 0)>;
657 let Predicates = [HasStdExtC, HasStdExtD] in
658 def : InstAlias<"c.fsd $rs2, (${rs1})", (C_FSD FPR64C:$rs2, GPRC:$rs1, 0)>;
660 def : InstAlias<"c.sw $rs2, (${rs1})", (C_SW GPRC:$rs2, GPRC:$rs1, 0)>;
662 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
663 def : InstAlias<"c.fsw $rs2, (${rs1})", (C_FSW FPR32C:$rs2, GPRC:$rs1, 0)>;
665 let Predicates = [HasStdExtC, IsRV64] in
666 def : InstAlias<"c.sd $rs2, (${rs1})", (C_SD GPRC:$rs2, GPRC:$rs1, 0)>;
668 let Predicates = [HasStdExtC, HasStdExtD] in
669 def : InstAlias<"c.fldsp $rd, (${rs1})", (C_FLDSP FPR64C:$rd, SP:$rs1, 0)>;
671 def : InstAlias<"c.lwsp $rd, (${rs1})", (C_LWSP GPRC:$rd, SP:$rs1, 0)>;
673 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
674 def : InstAlias<"c.flwsp $rd, (${rs1})", (C_FLWSP FPR32C:$rd, SP:$rs1, 0)>;
676 let Predicates = [HasStdExtC, IsRV64] in
677 def : InstAlias<"c.ldsp $rd, (${rs1})", (C_LDSP GPRC:$rd, SP:$rs1, 0)>;
679 let Predicates = [HasStdExtC, HasStdExtD] in
680 def : InstAlias<"c.fsdsp $rs2, (${rs1})", (C_FSDSP FPR64C:$rs2, SP:$rs1, 0)>;
682 def : InstAlias<"c.swsp $rs2, (${rs1})", (C_SWSP GPRC:$rs2, SP:$rs1, 0)>;
684 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
685 def : InstAlias<"c.fswsp $rs2, (${rs1})", (C_FSWSP FPR32C:$rs2, SP:$rs1, 0)>;
687 let Predicates = [HasStdExtC, IsRV64] in
688 def : InstAlias<"c.sdsp $rs2, (${rs1})", (C_SDSP GPRC:$rs2, SP:$rs1, 0)>;
691 //===----------------------------------------------------------------------===//
692 // Compress Instruction tablegen backend.
693 //===----------------------------------------------------------------------===//
695 class CompressPat<dag input, dag output> {
698 list<Predicate> Predicates = [];
701 // Patterns are defined in the same order the compressed instructions appear
702 // on page 82 of the ISA manual.
705 let Predicates = [HasStdExtC] in {
706 def : CompressPat<(ADDI GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm),
707 (C_ADDI4SPN GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm)>;
708 } // Predicates = [HasStdExtC]
710 let Predicates = [HasStdExtC, HasStdExtD] in {
711 def : CompressPat<(FLD FPR64C:$rd, GPRC:$rs1, uimm8_lsb000:$imm),
712 (C_FLD FPR64C:$rd, GPRC:$rs1, uimm8_lsb000:$imm)>;
713 } // Predicates = [HasStdExtC, HasStdExtD]
715 let Predicates = [HasStdExtC] in {
716 def : CompressPat<(LW GPRC:$rd, GPRC:$rs1, uimm7_lsb00:$imm),
717 (C_LW GPRC:$rd, GPRC:$rs1, uimm7_lsb00:$imm)>;
718 } // Predicates = [HasStdExtC]
720 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
721 def : CompressPat<(FLW FPR32C:$rd, GPRC:$rs1, uimm7_lsb00:$imm),
722 (C_FLW FPR32C:$rd, GPRC:$rs1, uimm7_lsb00:$imm)>;
723 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
725 let Predicates = [HasStdExtC, IsRV64] in {
726 def : CompressPat<(LD GPRC:$rd, GPRC:$rs1, uimm8_lsb000:$imm),
727 (C_LD GPRC:$rd, GPRC:$rs1, uimm8_lsb000:$imm)>;
728 } // Predicates = [HasStdExtC, IsRV64]
730 let Predicates = [HasStdExtC, HasStdExtD] in {
731 def : CompressPat<(FSD FPR64C:$rs2, GPRC:$rs1, uimm8_lsb000:$imm),
732 (C_FSD FPR64C:$rs2, GPRC:$rs1, uimm8_lsb000:$imm)>;
733 } // Predicates = [HasStdExtC, HasStdExtD]
735 let Predicates = [HasStdExtC] in {
736 def : CompressPat<(SW GPRC:$rs2, GPRC:$rs1, uimm7_lsb00:$imm),
737 (C_SW GPRC:$rs2, GPRC:$rs1, uimm7_lsb00:$imm)>;
738 } // Predicates = [HasStdExtC]
740 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
741 def : CompressPat<(FSW FPR32C:$rs2, GPRC:$rs1,uimm7_lsb00:$imm),
742 (C_FSW FPR32C:$rs2, GPRC:$rs1, uimm7_lsb00:$imm)>;
743 } // Predicate = [HasStdExtC, HasStdExtF, IsRV32]
745 let Predicates = [HasStdExtC, IsRV64] in {
746 def : CompressPat<(SD GPRC:$rs2, GPRC:$rs1, uimm8_lsb000:$imm),
747 (C_SD GPRC:$rs2, GPRC:$rs1, uimm8_lsb000:$imm)>;
748 } // Predicates = [HasStdExtC, IsRV64]
751 let Predicates = [HasStdExtC] in {
752 def : CompressPat<(ADDI X0, X0, 0), (C_NOP)>;
753 def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs1, simm6nonzero:$imm),
754 (C_ADDI GPRNoX0:$rs1, simm6nonzero:$imm)>;
755 } // Predicates = [HasStdExtC]
757 let Predicates = [HasStdExtC, IsRV32] in {
758 def : CompressPat<(JAL X1, simm12_lsb0:$offset),
759 (C_JAL simm12_lsb0:$offset)>;
760 } // Predicates = [HasStdExtC, IsRV32]
762 let Predicates = [HasStdExtC, IsRV64] in {
763 def : CompressPat<(ADDIW GPRNoX0:$rs1, GPRNoX0:$rs1, simm6:$imm),
764 (C_ADDIW GPRNoX0:$rs1, simm6:$imm)>;
765 } // Predicates = [HasStdExtC, IsRV64]
767 let Predicates = [HasStdExtC] in {
768 def : CompressPat<(ADDI GPRNoX0:$rd, X0, simm6:$imm),
769 (C_LI GPRNoX0:$rd, simm6:$imm)>;
770 def : CompressPat<(ADDI X2, X2, simm10_lsb0000nonzero:$imm),
771 (C_ADDI16SP X2, simm10_lsb0000nonzero:$imm)>;
772 def : CompressPat<(LUI GPRNoX0X2:$rd, c_lui_imm:$imm),
773 (C_LUI GPRNoX0X2:$rd, c_lui_imm:$imm)>;
774 def : CompressPat<(SRLI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm),
775 (C_SRLI GPRC:$rs1, uimmlog2xlennonzero:$imm)>;
776 def : CompressPat<(SRAI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm),
777 (C_SRAI GPRC:$rs1, uimmlog2xlennonzero:$imm)>;
778 def : CompressPat<(ANDI GPRC:$rs1, GPRC:$rs1, simm6:$imm),
779 (C_ANDI GPRC:$rs1, simm6:$imm)>;
780 def : CompressPat<(SUB GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
781 (C_SUB GPRC:$rs1, GPRC:$rs2)>;
782 def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
783 (C_XOR GPRC:$rs1, GPRC:$rs2)>;
784 def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
785 (C_XOR GPRC:$rs1, GPRC:$rs2)>;
786 def : CompressPat<(OR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
787 (C_OR GPRC:$rs1, GPRC:$rs2)>;
788 def : CompressPat<(OR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
789 (C_OR GPRC:$rs1, GPRC:$rs2)>;
790 def : CompressPat<(AND GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
791 (C_AND GPRC:$rs1, GPRC:$rs2)>;
792 def : CompressPat<(AND GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
793 (C_AND GPRC:$rs1, GPRC:$rs2)>;
794 } // Predicates = [HasStdExtC]
796 let Predicates = [HasStdExtC, IsRV64] in {
797 def : CompressPat<(ADDIW GPRNoX0:$rd, X0, simm6:$imm),
798 (C_LI GPRNoX0:$rd, simm6:$imm)>;
799 def : CompressPat<(SUBW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
800 (C_SUBW GPRC:$rs1, GPRC:$rs2)>;
801 def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
802 (C_ADDW GPRC:$rs1, GPRC:$rs2)>;
803 def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
804 (C_ADDW GPRC:$rs1, GPRC:$rs2)>;
805 } // Predicates = [HasStdExtC, IsRV64]
807 let Predicates = [HasStdExtC] in {
808 def : CompressPat<(JAL X0, simm12_lsb0:$offset),
809 (C_J simm12_lsb0:$offset)>;
810 def : CompressPat<(BEQ GPRC:$rs1, X0, simm9_lsb0:$imm),
811 (C_BEQZ GPRC:$rs1, simm9_lsb0:$imm)>;
812 def : CompressPat<(BNE GPRC:$rs1, X0, simm9_lsb0:$imm),
813 (C_BNEZ GPRC:$rs1, simm9_lsb0:$imm)>;
814 } // Predicates = [HasStdExtC]
817 let Predicates = [HasStdExtC] in {
818 def : CompressPat<(SLLI GPRNoX0:$rs1, GPRNoX0:$rs1, uimmlog2xlennonzero:$imm),
819 (C_SLLI GPRNoX0:$rs1, uimmlog2xlennonzero:$imm)>;
820 } // Predicates = [HasStdExtC]
822 let Predicates = [HasStdExtC, HasStdExtD] in {
823 def : CompressPat<(FLD FPR64:$rd, SP:$rs1, uimm9_lsb000:$imm),
824 (C_FLDSP FPR64:$rd, SP:$rs1, uimm9_lsb000:$imm)>;
825 } // Predicates = [HasStdExtC, HasStdExtD]
827 let Predicates = [HasStdExtC] in {
828 def : CompressPat<(LW GPRNoX0:$rd, SP:$rs1, uimm8_lsb00:$imm),
829 (C_LWSP GPRNoX0:$rd, SP:$rs1, uimm8_lsb00:$imm)>;
830 } // Predicates = [HasStdExtC]
832 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
833 def : CompressPat<(FLW FPR32:$rd, SP:$rs1, uimm8_lsb00:$imm),
834 (C_FLWSP FPR32:$rd, SP:$rs1, uimm8_lsb00:$imm)>;
835 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
837 let Predicates = [HasStdExtC, IsRV64] in {
838 def : CompressPat<(LD GPRNoX0:$rd, SP:$rs1, uimm9_lsb000:$imm),
839 (C_LDSP GPRNoX0:$rd, SP:$rs1, uimm9_lsb000:$imm)>;
840 } // Predicates = [HasStdExtC, IsRV64]
842 let Predicates = [HasStdExtC] in {
843 def : CompressPat<(JALR X0, GPRNoX0:$rs1, 0),
844 (C_JR GPRNoX0:$rs1)>;
845 def : CompressPat<(ADD GPRNoX0:$rs1, X0, GPRNoX0:$rs2),
846 (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
847 def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, X0),
848 (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
849 def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs2, 0),
850 (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
851 def : CompressPat<(EBREAK), (C_EBREAK)>;
852 def : CompressPat<(UNIMP), (C_UNIMP)>;
853 def : CompressPat<(JALR X1, GPRNoX0:$rs1, 0),
854 (C_JALR GPRNoX0:$rs1)>;
855 def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs1, GPRNoX0:$rs2),
856 (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
857 def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, GPRNoX0:$rs1),
858 (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
859 } // Predicates = [HasStdExtC]
861 let Predicates = [HasStdExtC, HasStdExtD] in {
862 def : CompressPat<(FSD FPR64:$rs2, SP:$rs1, uimm9_lsb000:$imm),
863 (C_FSDSP FPR64:$rs2, SP:$rs1, uimm9_lsb000:$imm)>;
864 } // Predicates = [HasStdExtC, HasStdExtD]
866 let Predicates = [HasStdExtC] in {
867 def : CompressPat<(SW GPR:$rs2, SP:$rs1, uimm8_lsb00:$imm),
868 (C_SWSP GPR:$rs2, SP:$rs1, uimm8_lsb00:$imm)>;
869 } // Predicates = [HasStdExtC]
871 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
872 def : CompressPat<(FSW FPR32:$rs2, SP:$rs1, uimm8_lsb00:$imm),
873 (C_FSWSP FPR32:$rs2, SP:$rs1, uimm8_lsb00:$imm)>;
874 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
876 let Predicates = [HasStdExtC, IsRV64] in {
877 def : CompressPat<(SD GPR:$rs2, SP:$rs1, uimm9_lsb000:$imm),
878 (C_SDSP GPR:$rs2, SP:$rs1, uimm9_lsb000:$imm)>;
879 } // Predicates = [HasStdExtC, IsRV64]