1//===- RISCVInstrInfoC.td - Compressed RISCV instructions -*- tblgen-*-----===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10include "RISCVInstrFormatsC.td"
11
12//===----------------------------------------------------------------------===//
13// Operand definitions.
14//===----------------------------------------------------------------------===//
15
16def UImmLog2XLenNonZeroAsmOperand : AsmOperandClass {
17  let Name = "UImmLog2XLenNonZero";
18  let RenderMethod = "addImmOperands";
19  let DiagnosticType = "InvalidUImmLog2XLenNonZero";
20}
21
22def uimmlog2xlennonzero : Operand<XLenVT>, ImmLeaf<XLenVT, [{
23  if (Subtarget->is64Bit())
24    return isUInt<6>(Imm) && (Imm != 0);
25  return isUInt<5>(Imm) && (Imm != 0);
26}]> {
27  let ParserMatchClass = UImmLog2XLenNonZeroAsmOperand;
28  // TODO: should ensure invalid shamt is rejected when decoding.
29  let DecoderMethod = "decodeUImmOperand<6>";
30  let MCOperandPredicate = [{
31    int64_t Imm;
32    if (!MCOp.evaluateAsConstantImm(Imm))
33      return false;
34    if (STI.getTargetTriple().isArch64Bit())
35      return  isUInt<6>(Imm) && (Imm != 0);
36    return isUInt<5>(Imm) && (Imm != 0);
37  }];
38}
39
40def simm6 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isInt<6>(Imm);}]> {
41  let ParserMatchClass = SImmAsmOperand<6>;
42  let EncoderMethod = "getImmOpValue";
43  let DecoderMethod = "decodeSImmOperand<6>";
44  let MCOperandPredicate = [{
45    int64_t Imm;
46    if (MCOp.evaluateAsConstantImm(Imm))
47      return isInt<6>(Imm);
48    return MCOp.isBareSymbolRef();
49  }];
50}
51
52def simm6nonzero : Operand<XLenVT>,
53                   ImmLeaf<XLenVT, [{return (Imm != 0) && isInt<6>(Imm);}]> {
54  let ParserMatchClass = SImmAsmOperand<6, "NonZero">;
55  let EncoderMethod = "getImmOpValue";
56  let DecoderMethod = "decodeSImmOperand<6>";
57  let MCOperandPredicate = [{
58    int64_t Imm;
59    if (MCOp.evaluateAsConstantImm(Imm))
60      return (Imm != 0) && isInt<6>(Imm);
61    return MCOp.isBareSymbolRef();
62  }];
63}
64
65def CLUIImmAsmOperand : AsmOperandClass {
66  let Name = "CLUIImm";
67  let RenderMethod = "addImmOperands";
68  let DiagnosticType = !strconcat("Invalid", Name);
69}
70
71
72// c_lui_imm checks the immediate range is in [1, 31] or [0xfffe0, 0xfffff].
73// The RISC-V ISA describes the constraint as [1, 63], with that value being
74// loaded in to bits 17-12 of the destination register and sign extended from
75// bit 17. Therefore, this 6-bit immediate can represent values in the ranges
76// [1, 31] and [0xfffe0, 0xfffff].
77def c_lui_imm : Operand<XLenVT>,
78                ImmLeaf<XLenVT, [{return (Imm != 0) &&
79                                 (isUInt<5>(Imm) ||
80                                  (Imm >= 0xfffe0 && Imm <= 0xfffff));}]> {
81  let ParserMatchClass = CLUIImmAsmOperand;
82  let EncoderMethod = "getImmOpValue";
83  let DecoderMethod = "decodeCLUIImmOperand";
84  let MCOperandPredicate = [{
85    int64_t Imm;
86    if (MCOp.evaluateAsConstantImm(Imm))
87      return (Imm != 0) && (isUInt<5>(Imm) ||
88             (Imm >= 0xfffe0 && Imm <= 0xfffff));
89    return MCOp.isBareSymbolRef();
90  }];
91}
92
93// A 7-bit unsigned immediate where the least significant two bits are zero.
94def uimm7_lsb00 : Operand<XLenVT>,
95                  ImmLeaf<XLenVT, [{return isShiftedUInt<5, 2>(Imm);}]> {
96  let ParserMatchClass = UImmAsmOperand<7, "Lsb00">;
97  let EncoderMethod = "getImmOpValue";
98  let DecoderMethod = "decodeUImmOperand<7>";
99  let MCOperandPredicate = [{
100    int64_t Imm;
101    if (!MCOp.evaluateAsConstantImm(Imm))
102      return false;
103    return isShiftedUInt<5, 2>(Imm);
104  }];
105}
106
107// A 8-bit unsigned immediate where the least significant two bits are zero.
108def uimm8_lsb00 : Operand<XLenVT>,
109                  ImmLeaf<XLenVT, [{return isShiftedUInt<6, 2>(Imm);}]> {
110  let ParserMatchClass = UImmAsmOperand<8, "Lsb00">;
111  let EncoderMethod = "getImmOpValue";
112  let DecoderMethod = "decodeUImmOperand<8>";
113  let MCOperandPredicate = [{
114    int64_t Imm;
115    if (!MCOp.evaluateAsConstantImm(Imm))
116      return false;
117    return isShiftedUInt<6, 2>(Imm);
118  }];
119}
120
121// A 8-bit unsigned immediate where the least significant three bits are zero.
122def uimm8_lsb000 : Operand<XLenVT>,
123                   ImmLeaf<XLenVT, [{return isShiftedUInt<5, 3>(Imm);}]> {
124  let ParserMatchClass = UImmAsmOperand<8, "Lsb000">;
125  let EncoderMethod = "getImmOpValue";
126  let DecoderMethod = "decodeUImmOperand<8>";
127  let MCOperandPredicate = [{
128    int64_t Imm;
129    if (!MCOp.evaluateAsConstantImm(Imm))
130      return false;
131    return isShiftedUInt<5, 3>(Imm);
132  }];
133}
134
135// A 9-bit signed immediate where the least significant bit is zero.
136def simm9_lsb0 : Operand<OtherVT> {
137  let ParserMatchClass = SImmAsmOperand<9, "Lsb0">;
138  let EncoderMethod = "getImmOpValueAsr1";
139  let DecoderMethod = "decodeSImmOperandAndLsl1<9>";
140  let MCOperandPredicate = [{
141    int64_t Imm;
142    if (MCOp.evaluateAsConstantImm(Imm))
143      return isShiftedInt<8, 1>(Imm);
144    return MCOp.isBareSymbolRef();
145
146  }];
147}
148
149// A 9-bit unsigned immediate where the least significant three bits are zero.
150def uimm9_lsb000 : Operand<XLenVT>,
151                   ImmLeaf<XLenVT, [{return isShiftedUInt<6, 3>(Imm);}]> {
152  let ParserMatchClass = UImmAsmOperand<9, "Lsb000">;
153  let EncoderMethod = "getImmOpValue";
154  let DecoderMethod = "decodeUImmOperand<9>";
155  let MCOperandPredicate = [{
156    int64_t Imm;
157    if (!MCOp.evaluateAsConstantImm(Imm))
158      return false;
159    return isShiftedUInt<6, 3>(Imm);
160  }];
161}
162
163// A 10-bit unsigned immediate where the least significant two bits are zero
164// and the immediate can't be zero.
165def uimm10_lsb00nonzero : Operand<XLenVT>,
166                          ImmLeaf<XLenVT,
167                          [{return isShiftedUInt<8, 2>(Imm) && (Imm != 0);}]> {
168  let ParserMatchClass = UImmAsmOperand<10, "Lsb00NonZero">;
169  let EncoderMethod = "getImmOpValue";
170  let DecoderMethod = "decodeUImmOperand<10>";
171  let MCOperandPredicate = [{
172    int64_t Imm;
173    if (!MCOp.evaluateAsConstantImm(Imm))
174      return false;
175    return isShiftedUInt<8, 2>(Imm) && (Imm != 0);
176  }];
177}
178
179// A 10-bit signed immediate where the least significant four bits are zero.
180def simm10_lsb0000nonzero : Operand<XLenVT>,
181                            ImmLeaf<XLenVT,
182                            [{return (Imm != 0) && isShiftedInt<6, 4>(Imm);}]> {
183  let ParserMatchClass = SImmAsmOperand<10, "Lsb0000NonZero">;
184  let EncoderMethod = "getImmOpValue";
185  let DecoderMethod = "decodeSImmOperand<10>";
186  let MCOperandPredicate = [{
187    int64_t Imm;
188    if (!MCOp.evaluateAsConstantImm(Imm))
189      return false;
190    return isShiftedInt<6, 4>(Imm);
191  }];
192}
193
194// A 12-bit signed immediate where the least significant bit is zero.
195def simm12_lsb0 : Operand<XLenVT> {
196  let ParserMatchClass = SImmAsmOperand<12, "Lsb0">;
197  let EncoderMethod = "getImmOpValueAsr1";
198  let DecoderMethod = "decodeSImmOperandAndLsl1<12>";
199  let MCOperandPredicate = [{
200    int64_t Imm;
201    if (MCOp.evaluateAsConstantImm(Imm))
202      return isShiftedInt<11, 1>(Imm);
203    return MCOp.isBareSymbolRef();
204  }];
205}
206
207//===----------------------------------------------------------------------===//
208// Instruction Class Templates
209//===----------------------------------------------------------------------===//
210
211let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
212class CStackLoad<bits<3> funct3, string OpcodeStr,
213                 RegisterClass cls, DAGOperand opnd>
214    : RVInst16CI<funct3, 0b10, (outs cls:$rd), (ins SP:$rs1, opnd:$imm),
215                 OpcodeStr, "$rd, ${imm}(${rs1})">;
216
217let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
218class CStackStore<bits<3> funct3, string OpcodeStr,
219                  RegisterClass cls, DAGOperand opnd>
220    : RVInst16CSS<funct3, 0b10, (outs), (ins cls:$rs2, SP:$rs1, opnd:$imm),
221                  OpcodeStr, "$rs2, ${imm}(${rs1})">;
222
223let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
224class CLoad_ri<bits<3> funct3, string OpcodeStr,
225               RegisterClass cls, DAGOperand opnd>
226    : RVInst16CL<funct3, 0b00, (outs cls:$rd), (ins GPRC:$rs1, opnd:$imm),
227                 OpcodeStr, "$rd, ${imm}(${rs1})">;
228
229let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
230class CStore_rri<bits<3> funct3, string OpcodeStr,
231                 RegisterClass cls, DAGOperand opnd>
232    : RVInst16CS<funct3, 0b00, (outs), (ins cls:$rs2, GPRC:$rs1, opnd:$imm),
233                 OpcodeStr, "$rs2, ${imm}(${rs1})">;
234
235let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
236class Bcz<bits<3> funct3, string OpcodeStr, PatFrag CondOp,
237          RegisterClass cls>
238    : RVInst16CB<funct3, 0b01, (outs), (ins cls:$rs1, simm9_lsb0:$imm),
239                 OpcodeStr, "$rs1, $imm"> {
240  let isBranch = 1;
241  let isTerminator = 1;
242  let Inst{12} = imm{7};
243  let Inst{11-10} = imm{3-2};
244  let Inst{6-5} = imm{6-5};
245  let Inst{4-3} = imm{1-0};
246  let Inst{2} = imm{4};
247}
248
249let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
250class Shift_right<bits<2> funct2, string OpcodeStr, RegisterClass cls,
251                  Operand ImmOpnd>
252    : RVInst16CB<0b100, 0b01, (outs cls:$rs1_wb), (ins cls:$rs1, ImmOpnd:$imm),
253                 OpcodeStr, "$rs1, $imm"> {
254  let Constraints = "$rs1 = $rs1_wb";
255  let Inst{12} = imm{5};
256  let Inst{11-10} = funct2;
257  let Inst{6-2} = imm{4-0};
258}
259
260let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
261class CS_ALU<bits<2> funct2, string OpcodeStr, RegisterClass cls,
262             bit RV64only>
263    : RVInst16CS<0b100, 0b01, (outs cls:$rd_wb), (ins cls:$rd, cls:$rs2),
264                 OpcodeStr, "$rd, $rs2"> {
265  bits<3> rd;
266  let Constraints = "$rd = $rd_wb";
267  let Inst{12} = RV64only;
268  let Inst{11-10} = 0b11;
269  let Inst{9-7} = rd;
270  let Inst{6-5} = funct2;
271}
272
273//===----------------------------------------------------------------------===//
274// Instructions
275//===----------------------------------------------------------------------===//
276
277let Predicates = [HasStdExtC] in {
278
279let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Uses = [X2] in
280def C_ADDI4SPN : RVInst16CIW<0b000, 0b00, (outs GPRC:$rd),
281                             (ins SP:$rs1, uimm10_lsb00nonzero:$imm),
282                             "c.addi4spn", "$rd, $rs1, $imm"> {
283  bits<5> rs1;
284  let Inst{12-11} = imm{5-4};
285  let Inst{10-7} = imm{9-6};
286  let Inst{6} = imm{2};
287  let Inst{5} = imm{3};
288}
289
290let Predicates = [HasStdExtC, HasStdExtD] in
291def C_FLD  : CLoad_ri<0b001, "c.fld", FPR64C, uimm8_lsb000> {
292  bits<8> imm;
293  let Inst{12-10} = imm{5-3};
294  let Inst{6-5} = imm{7-6};
295}
296
297def C_LW : CLoad_ri<0b010, "c.lw", GPRC, uimm7_lsb00> {
298  bits<7> imm;
299  let Inst{12-10} = imm{5-3};
300  let Inst{6} = imm{2};
301  let Inst{5} = imm{6};
302}
303
304let DecoderNamespace = "RISCV32Only_",
305    Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
306def C_FLW  : CLoad_ri<0b011, "c.flw", FPR32C, uimm7_lsb00> {
307  bits<7> imm;
308  let Inst{12-10} = imm{5-3};
309  let Inst{6} = imm{2};
310  let Inst{5} = imm{6};
311}
312
313let Predicates = [HasStdExtC, IsRV64] in
314def C_LD : CLoad_ri<0b011, "c.ld", GPRC, uimm8_lsb000> {
315  bits<8> imm;
316  let Inst{12-10} = imm{5-3};
317  let Inst{6-5} = imm{7-6};
318}
319
320let Predicates = [HasStdExtC, HasStdExtD] in
321def C_FSD  : CStore_rri<0b101, "c.fsd", FPR64C, uimm8_lsb000> {
322  bits<8> imm;
323  let Inst{12-10} = imm{5-3};
324  let Inst{6-5} = imm{7-6};
325}
326
327def C_SW : CStore_rri<0b110, "c.sw", GPRC, uimm7_lsb00> {
328  bits<7> imm;
329  let Inst{12-10} = imm{5-3};
330  let Inst{6} = imm{2};
331  let Inst{5} = imm{6};
332}
333
334let DecoderNamespace = "RISCV32Only_",
335    Predicates = [HasStdExtC, HasStdExtF, IsRV32]  in
336def C_FSW  : CStore_rri<0b111, "c.fsw", FPR32C, uimm7_lsb00> {
337  bits<7> imm;
338  let Inst{12-10} = imm{5-3};
339  let Inst{6} = imm{2};
340  let Inst{5} = imm{6};
341}
342
343let Predicates = [HasStdExtC, IsRV64] in
344def C_SD : CStore_rri<0b111, "c.sd", GPRC, uimm8_lsb000> {
345  bits<8> imm;
346  let Inst{12-10} = imm{5-3};
347  let Inst{6-5} = imm{7-6};
348}
349
350let rd = 0, imm = 0, hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
351def C_NOP : RVInst16CI<0b000, 0b01, (outs), (ins), "c.nop", "">;
352
353let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
354def C_ADDI : RVInst16CI<0b000, 0b01, (outs GPRNoX0:$rd_wb),
355                        (ins GPRNoX0:$rd, simm6nonzero:$imm),
356                        "c.addi", "$rd, $imm"> {
357  let Constraints = "$rd = $rd_wb";
358  let Inst{6-2} = imm{4-0};
359}
360
361let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCall = 1,
362    DecoderNamespace = "RISCV32Only_", Defs = [X1],
363    Predicates = [HasStdExtC, IsRV32]  in
364def C_JAL : RVInst16CJ<0b001, 0b01, (outs), (ins simm12_lsb0:$offset),
365                       "c.jal", "$offset">;
366
367let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
368    Predicates = [HasStdExtC, IsRV64] in
369def C_ADDIW : RVInst16CI<0b001, 0b01, (outs GPRNoX0:$rd_wb),
370                         (ins GPRNoX0:$rd, simm6:$imm),
371                         "c.addiw", "$rd, $imm"> {
372  let Constraints = "$rd = $rd_wb";
373  let Inst{6-2} = imm{4-0};
374}
375
376let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
377def C_LI : RVInst16CI<0b010, 0b01, (outs GPRNoX0:$rd), (ins simm6:$imm),
378                      "c.li", "$rd, $imm"> {
379  let Inst{6-2} = imm{4-0};
380}
381
382let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
383def C_ADDI16SP : RVInst16CI<0b011, 0b01, (outs SP:$rd_wb),
384                            (ins SP:$rd, simm10_lsb0000nonzero:$imm),
385                            "c.addi16sp", "$rd, $imm"> {
386  let Constraints = "$rd = $rd_wb";
387  let Inst{12} = imm{9};
388  let Inst{11-7} = 2;
389  let Inst{6} = imm{4};
390  let Inst{5} = imm{6};
391  let Inst{4-3} = imm{8-7};
392  let Inst{2} = imm{5};
393}
394
395let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
396def C_LUI : RVInst16CI<0b011, 0b01, (outs GPRNoX0X2:$rd),
397                       (ins c_lui_imm:$imm),
398                       "c.lui", "$rd, $imm"> {
399  let Inst{6-2} = imm{4-0};
400}
401
402def C_SRLI : Shift_right<0b00, "c.srli", GPRC, uimmlog2xlennonzero>;
403def C_SRAI : Shift_right<0b01, "c.srai", GPRC, uimmlog2xlennonzero>;
404
405let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
406def C_ANDI : RVInst16CB<0b100, 0b01, (outs GPRC:$rs1_wb), (ins GPRC:$rs1, simm6:$imm),
407                        "c.andi", "$rs1, $imm"> {
408  let Constraints = "$rs1 = $rs1_wb";
409  let Inst{12} = imm{5};
410  let Inst{11-10} = 0b10;
411  let Inst{6-2} = imm{4-0};
412}
413
414def C_SUB  : CS_ALU<0b00, "c.sub", GPRC, 0>;
415def C_XOR  : CS_ALU<0b01, "c.xor", GPRC, 0>;
416def C_OR   : CS_ALU<0b10, "c.or" , GPRC, 0>;
417def C_AND  : CS_ALU<0b11, "c.and", GPRC, 0>;
418
419let Predicates = [HasStdExtC, IsRV64] in {
420def C_SUBW : CS_ALU<0b00, "c.subw", GPRC, 1>;
421def C_ADDW : CS_ALU<0b01, "c.addw", GPRC, 1>;
422}
423
424let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
425def C_J : RVInst16CJ<0b101, 0b01, (outs), (ins simm12_lsb0:$offset),
426                     "c.j", "$offset"> {
427  let isBranch = 1;
428  let isTerminator=1;
429  let isBarrier=1;
430}
431
432def C_BEQZ : Bcz<0b110, "c.beqz",  seteq, GPRC>;
433def C_BNEZ : Bcz<0b111, "c.bnez",  setne, GPRC>;
434
435let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
436def C_SLLI : RVInst16CI<0b000, 0b10, (outs GPRNoX0:$rd_wb),
437                        (ins GPRNoX0:$rd, uimmlog2xlennonzero:$imm),
438                        "c.slli" ,"$rd, $imm"> {
439  let Constraints = "$rd = $rd_wb";
440  let Inst{6-2} = imm{4-0};
441}
442
443let Predicates = [HasStdExtC, HasStdExtD] in
444def C_FLDSP  : CStackLoad<0b001, "c.fldsp", FPR64, uimm9_lsb000> {
445  let Inst{6-5} = imm{4-3};
446  let Inst{4-2} = imm{8-6};
447}
448
449def C_LWSP : CStackLoad<0b010, "c.lwsp", GPRNoX0, uimm8_lsb00> {
450  let Inst{6-4} = imm{4-2};
451  let Inst{3-2} = imm{7-6};
452}
453
454let DecoderNamespace = "RISCV32Only_",
455    Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
456def C_FLWSP  : CStackLoad<0b011, "c.flwsp", FPR32, uimm8_lsb00> {
457  let Inst{6-4} = imm{4-2};
458  let Inst{3-2} = imm{7-6};
459}
460
461let Predicates = [HasStdExtC, IsRV64] in
462def C_LDSP : CStackLoad<0b011, "c.ldsp", GPRNoX0, uimm9_lsb000> {
463  let Inst{6-5} = imm{4-3};
464  let Inst{4-2} = imm{8-6};
465}
466
467let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
468def C_JR : RVInst16CR<0b1000, 0b10, (outs), (ins GPRNoX0:$rs1),
469                      "c.jr", "$rs1"> {
470  let isBranch = 1;
471  let isBarrier = 1;
472  let isTerminator = 1;
473  let isIndirectBranch = 1;
474  let rs2 = 0;
475}
476
477let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
478def C_MV : RVInst16CR<0b1000, 0b10, (outs GPRNoX0:$rs1), (ins GPRNoX0:$rs2),
479                      "c.mv", "$rs1, $rs2">;
480
481let rs1 = 0, rs2 = 0, hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
482def C_EBREAK : RVInst16CR<0b1001, 0b10, (outs), (ins), "c.ebreak", "">;
483
484let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
485    isCall=1, Defs=[X1], rs2 = 0 in
486def C_JALR : RVInst16CR<0b1001, 0b10, (outs), (ins GPRNoX0:$rs1),
487                        "c.jalr", "$rs1">;
488
489let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
490def C_ADD : RVInst16CR<0b1001, 0b10, (outs GPRNoX0:$rs1_wb),
491                       (ins GPRNoX0:$rs1, GPRNoX0:$rs2),
492                       "c.add", "$rs1, $rs2"> {
493  let Constraints = "$rs1 = $rs1_wb";
494}
495
496let Predicates = [HasStdExtC, HasStdExtD] in
497def C_FSDSP  : CStackStore<0b101, "c.fsdsp", FPR64, uimm9_lsb000> {
498  let Inst{12-10} = imm{5-3};
499  let Inst{9-7}   = imm{8-6};
500}
501
502def C_SWSP : CStackStore<0b110, "c.swsp", GPR, uimm8_lsb00> {
503  let Inst{12-9} = imm{5-2};
504  let Inst{8-7}  = imm{7-6};
505}
506
507let DecoderNamespace = "RISCV32Only_",
508    Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
509def C_FSWSP  : CStackStore<0b111, "c.fswsp", FPR32, uimm8_lsb00> {
510  let Inst{12-9} = imm{5-2};
511  let Inst{8-7}  = imm{7-6};
512}
513
514let Predicates = [HasStdExtC, IsRV64] in
515def C_SDSP : CStackStore<0b111, "c.sdsp", GPR, uimm9_lsb000> {
516  let Inst{12-10} = imm{5-3};
517  let Inst{9-7}   = imm{8-6};
518}
519
520} // Predicates = [HasStdExtC]
521
522//===----------------------------------------------------------------------===//
523// Compress Instruction tablegen backend.
524//===----------------------------------------------------------------------===//
525
526class CompressPat<dag input, dag output> {
527  dag Input  = input;
528  dag Output    = output;
529  list<Predicate> Predicates = [];
530}
531
532// Patterns are defined in the same order the compressed instructions appear
533// on page 82 of the ISA manual.
534
535// Quadrant 0
536let Predicates = [HasStdExtC] in {
537def : CompressPat<(ADDI GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm),
538                  (C_ADDI4SPN GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm)>;
539} // Predicates = [HasStdExtC]
540
541let Predicates = [HasStdExtC, HasStdExtD] in {
542def : CompressPat<(FLD FPR64C:$rd, GPRC:$rs1, uimm8_lsb000:$imm),
543                  (C_FLD FPR64C:$rd, GPRC:$rs1, uimm8_lsb000:$imm)>;
544} // Predicates = [HasStdExtC, HasStdExtD]
545
546let Predicates = [HasStdExtC] in {
547def : CompressPat<(LW GPRC:$rd, GPRC:$rs1, uimm7_lsb00:$imm),
548                  (C_LW GPRC:$rd, GPRC:$rs1, uimm7_lsb00:$imm)>;
549} // Predicates = [HasStdExtC]
550
551let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
552def : CompressPat<(FLW FPR32C:$rd, GPRC:$rs1, uimm7_lsb00:$imm),
553                  (C_FLW FPR32C:$rd, GPRC:$rs1, uimm7_lsb00:$imm)>;
554} // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
555
556let Predicates = [HasStdExtC, IsRV64] in {
557def : CompressPat<(LD GPRC:$rd, GPRC:$rs1, uimm8_lsb000:$imm),
558                  (C_LD GPRC:$rd, GPRC:$rs1, uimm8_lsb000:$imm)>;
559} // Predicates = [HasStdExtC, IsRV64]
560
561let Predicates = [HasStdExtC, HasStdExtD] in {
562def : CompressPat<(FSD FPR64C:$rs2, GPRC:$rs1, uimm8_lsb000:$imm),
563                  (C_FSD FPR64C:$rs2, GPRC:$rs1, uimm8_lsb000:$imm)>;
564} // Predicates = [HasStdExtC, HasStdExtD]
565
566let Predicates = [HasStdExtC] in {
567def : CompressPat<(SW GPRC:$rs2, GPRC:$rs1, uimm7_lsb00:$imm),
568                  (C_SW GPRC:$rs2, GPRC:$rs1, uimm7_lsb00:$imm)>;
569} // Predicates = [HasStdExtC]
570
571let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
572def : CompressPat<(FSW FPR32C:$rs2, GPRC:$rs1,uimm7_lsb00:$imm),
573                  (C_FSW FPR32C:$rs2, GPRC:$rs1, uimm7_lsb00:$imm)>;
574} // Predicate = [HasStdExtC, HasStdExtF, IsRV32]
575
576let Predicates = [HasStdExtC, IsRV64] in {
577def : CompressPat<(SD GPRC:$rs2, GPRC:$rs1, uimm8_lsb000:$imm),
578                  (C_SD GPRC:$rs2, GPRC:$rs1, uimm8_lsb000:$imm)>;
579} // Predicates = [HasStdExtC, IsRV64]
580
581// Quadrant 1
582let Predicates = [HasStdExtC] in {
583def : CompressPat<(ADDI X0, X0, 0), (C_NOP)>;
584def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs1, simm6nonzero:$imm),
585                  (C_ADDI GPRNoX0:$rs1, simm6nonzero:$imm)>;
586} // Predicates = [HasStdExtC]
587
588let Predicates = [HasStdExtC, IsRV32] in {
589def : CompressPat<(JAL X1, simm12_lsb0:$offset),
590                  (C_JAL simm12_lsb0:$offset)>;
591} // Predicates = [HasStdExtC, IsRV32]
592
593let Predicates = [HasStdExtC, IsRV64] in {
594def : CompressPat<(ADDIW GPRNoX0:$rs1, GPRNoX0:$rs1, simm6:$imm),
595                  (C_ADDIW GPRNoX0:$rs1, simm6:$imm)>;
596} // Predicates = [HasStdExtC, IsRV64]
597
598let Predicates = [HasStdExtC] in {
599def : CompressPat<(ADDI GPRNoX0:$rd, X0, simm6:$imm),
600                  (C_LI GPRNoX0:$rd, simm6:$imm)>;
601def : CompressPat<(ADDI X2, X2, simm10_lsb0000nonzero:$imm),
602                  (C_ADDI16SP X2, simm10_lsb0000nonzero:$imm)>;
603def : CompressPat<(LUI GPRNoX0X2:$rd, c_lui_imm:$imm),
604                  (C_LUI GPRNoX0X2:$rd, c_lui_imm:$imm)>;
605def : CompressPat<(SRLI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm),
606                  (C_SRLI GPRC:$rs1, uimmlog2xlennonzero:$imm)>;
607def : CompressPat<(SRAI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm),
608                  (C_SRAI GPRC:$rs1, uimmlog2xlennonzero:$imm)>;
609def : CompressPat<(ANDI GPRC:$rs1, GPRC:$rs1, simm6:$imm),
610                  (C_ANDI GPRC:$rs1, simm6:$imm)>;
611def : CompressPat<(SUB GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
612                  (C_SUB GPRC:$rs1, GPRC:$rs2)>;
613def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
614                  (C_XOR GPRC:$rs1, GPRC:$rs2)>;
615def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
616                  (C_XOR GPRC:$rs1, GPRC:$rs2)>;
617def : CompressPat<(OR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
618                  (C_OR GPRC:$rs1, GPRC:$rs2)>;
619def : CompressPat<(OR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
620                  (C_OR GPRC:$rs1, GPRC:$rs2)>;
621def : CompressPat<(AND GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
622                  (C_AND GPRC:$rs1, GPRC:$rs2)>;
623def : CompressPat<(AND GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
624                  (C_AND GPRC:$rs1, GPRC:$rs2)>;
625} //  Predicates = [HasStdExtC]
626
627let Predicates = [HasStdExtC, IsRV64] in {
628def : CompressPat<(SUBW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
629                  (C_SUBW GPRC:$rs1, GPRC:$rs2)>;
630def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
631                   (C_ADDW GPRC:$rs1, GPRC:$rs2)>;
632def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
633                   (C_ADDW GPRC:$rs1, GPRC:$rs2)>;
634} // Predicates = [HasStdExtC, IsRV64]
635
636let Predicates = [HasStdExtC] in {
637def : CompressPat<(JAL X0, simm12_lsb0:$offset),
638                  (C_J simm12_lsb0:$offset)>;
639def : CompressPat<(BEQ GPRC:$rs1, X0, simm9_lsb0:$imm),
640                  (C_BEQZ GPRC:$rs1, simm9_lsb0:$imm)>;
641def : CompressPat<(BNE GPRC:$rs1, X0, simm9_lsb0:$imm),
642                  (C_BNEZ GPRC:$rs1, simm9_lsb0:$imm)>;
643} //  Predicates = [HasStdExtC]
644
645// Quadrant 2
646let Predicates = [HasStdExtC] in {
647def : CompressPat<(SLLI GPRNoX0:$rs1, GPRNoX0:$rs1, uimmlog2xlennonzero:$imm),
648                  (C_SLLI GPRNoX0:$rs1, uimmlog2xlennonzero:$imm)>;
649} //  Predicates = [HasStdExtC]
650
651let Predicates = [HasStdExtC, HasStdExtD] in {
652def : CompressPat<(FLD FPR64:$rd, SP:$rs1, uimm9_lsb000:$imm),
653                  (C_FLDSP FPR64:$rd, SP:$rs1, uimm9_lsb000:$imm)>;
654} // Predicates = [HasStdExtC, HasStdExtD]
655
656let Predicates = [HasStdExtC] in {
657def : CompressPat<(LW GPRNoX0:$rd, SP:$rs1,  uimm8_lsb00:$imm),
658                  (C_LWSP GPRNoX0:$rd, SP:$rs1, uimm8_lsb00:$imm)>;
659} // Predicates = [HasStdExtC]
660
661let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
662def : CompressPat<(FLW FPR32:$rd, SP:$rs1, uimm8_lsb00:$imm),
663                  (C_FLWSP FPR32:$rd, SP:$rs1, uimm8_lsb00:$imm)>;
664} // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
665
666let Predicates = [HasStdExtC, IsRV64] in {
667def : CompressPat<(LD GPRNoX0:$rd, SP:$rs1, uimm9_lsb000:$imm),
668                  (C_LDSP GPRNoX0:$rd, SP:$rs1, uimm9_lsb000:$imm)>;
669} // Predicates = [HasStdExtC, IsRV64]
670
671let Predicates = [HasStdExtC] in {
672def : CompressPat<(JALR X0, GPRNoX0:$rs1, 0),
673                  (C_JR GPRNoX0:$rs1)>;
674def : CompressPat<(ADD GPRNoX0:$rs1, X0, GPRNoX0:$rs2),
675                  (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
676def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, X0),
677                  (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
678def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs2, 0),
679                  (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
680def : CompressPat<(EBREAK), (C_EBREAK)>;
681def : CompressPat<(JALR X1, GPRNoX0:$rs1, 0),
682                  (C_JALR GPRNoX0:$rs1)>;
683def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs1, GPRNoX0:$rs2),
684                  (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
685def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, GPRNoX0:$rs1),
686                  (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
687} // Predicates = [HasStdExtC]
688
689let Predicates = [HasStdExtC, HasStdExtD] in {
690def : CompressPat<(FSD FPR64:$rs2, SP:$rs1, uimm9_lsb000:$imm),
691                  (C_FSDSP FPR64:$rs2, SP:$rs1, uimm9_lsb000:$imm)>;
692} // Predicates = [HasStdExtC, HasStdExtD]
693
694let Predicates = [HasStdExtC] in {
695def : CompressPat<(SW GPR:$rs2, SP:$rs1, uimm8_lsb00:$imm),
696                  (C_SWSP GPR:$rs2, SP:$rs1, uimm8_lsb00:$imm)>;
697} // Predicates = [HasStdExtC]
698
699let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
700def : CompressPat<(FSW FPR32:$rs2, SP:$rs1, uimm8_lsb00:$imm),
701                  (C_FSWSP FPR32:$rs2, SP:$rs1, uimm8_lsb00:$imm)>;
702} // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
703
704let Predicates = [HasStdExtC, IsRV64] in {
705def : CompressPat<(SD GPR:$rs2, SP:$rs1, uimm9_lsb000:$imm),
706                  (C_SDSP GPR:$rs2, SP:$rs1, uimm9_lsb000:$imm)>;
707} //  Predicates = [HasStdExtC, IsRV64]
708