Home | History | Annotate | Download | only in RISCV
      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 
     10 include "RISCVInstrFormatsC.td"
     11 
     12 //===----------------------------------------------------------------------===//
     13 // Operand definitions.
     14 //===----------------------------------------------------------------------===//
     15 
     16 def UImmLog2XLenNonZeroAsmOperand : AsmOperandClass {
     17   let Name = "UImmLog2XLenNonZero";
     18   let RenderMethod = "addImmOperands";
     19   let DiagnosticType = "InvalidUImmLog2XLenNonZero";
     20 }
     21 
     22 def 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 
     40 def 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 
     52 def 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 
     65 def 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].
     77 def 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.
     94 def 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.
    108 def 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.
    122 def 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.
    136 def 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.
    150 def 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.
    165 def 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.
    180 def 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.
    195 def 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 
    211 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
    212 class 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 
    217 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
    218 class 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 
    223 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
    224 class 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 
    229 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
    230 class 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 
    235 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
    236 class 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 
    249 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
    250 class 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 
    260 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
    261 class 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 
    277 let Predicates = [HasStdExtC] in {
    278 
    279 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Uses = [X2] in
    280 def 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 
    290 let Predicates = [HasStdExtC, HasStdExtD] in
    291 def 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 
    297 def 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 
    304 let DecoderNamespace = "RISCV32Only_",
    305     Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
    306 def 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 
    313 let Predicates = [HasStdExtC, IsRV64] in
    314 def 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 
    320 let Predicates = [HasStdExtC, HasStdExtD] in
    321 def 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 
    327 def 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 
    334 let DecoderNamespace = "RISCV32Only_",
    335     Predicates = [HasStdExtC, HasStdExtF, IsRV32]  in
    336 def 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 
    343 let Predicates = [HasStdExtC, IsRV64] in
    344 def 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 
    350 let rd = 0, imm = 0, hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
    351 def C_NOP : RVInst16CI<0b000, 0b01, (outs), (ins), "c.nop", "">;
    352 
    353 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
    354 def 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 
    361 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCall = 1,
    362     DecoderNamespace = "RISCV32Only_", Defs = [X1],
    363     Predicates = [HasStdExtC, IsRV32]  in
    364 def C_JAL : RVInst16CJ<0b001, 0b01, (outs), (ins simm12_lsb0:$offset),
    365                        "c.jal", "$offset">;
    366 
    367 let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
    368     Predicates = [HasStdExtC, IsRV64] in
    369 def 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 
    376 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
    377 def 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 
    382 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
    383 def 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 
    395 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
    396 def 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 
    402 def C_SRLI : Shift_right<0b00, "c.srli", GPRC, uimmlog2xlennonzero>;
    403 def C_SRAI : Shift_right<0b01, "c.srai", GPRC, uimmlog2xlennonzero>;
    404 
    405 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
    406 def 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 
    414 def C_SUB  : CS_ALU<0b00, "c.sub", GPRC, 0>;
    415 def C_XOR  : CS_ALU<0b01, "c.xor", GPRC, 0>;
    416 def C_OR   : CS_ALU<0b10, "c.or" , GPRC, 0>;
    417 def C_AND  : CS_ALU<0b11, "c.and", GPRC, 0>;
    418 
    419 let Predicates = [HasStdExtC, IsRV64] in {
    420 def C_SUBW : CS_ALU<0b00, "c.subw", GPRC, 1>;
    421 def C_ADDW : CS_ALU<0b01, "c.addw", GPRC, 1>;
    422 }
    423 
    424 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
    425 def 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 
    432 def C_BEQZ : Bcz<0b110, "c.beqz",  seteq, GPRC>;
    433 def C_BNEZ : Bcz<0b111, "c.bnez",  setne, GPRC>;
    434 
    435 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
    436 def 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 
    443 let Predicates = [HasStdExtC, HasStdExtD] in
    444 def 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 
    449 def 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 
    454 let DecoderNamespace = "RISCV32Only_",
    455     Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
    456 def 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 
    461 let Predicates = [HasStdExtC, IsRV64] in
    462 def 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 
    467 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
    468 def 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 
    477 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
    478 def C_MV : RVInst16CR<0b1000, 0b10, (outs GPRNoX0:$rs1), (ins GPRNoX0:$rs2),
    479                       "c.mv", "$rs1, $rs2">;
    480 
    481 let rs1 = 0, rs2 = 0, hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
    482 def C_EBREAK : RVInst16CR<0b1001, 0b10, (outs), (ins), "c.ebreak", "">;
    483 
    484 let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
    485     isCall=1, Defs=[X1], rs2 = 0 in
    486 def C_JALR : RVInst16CR<0b1001, 0b10, (outs), (ins GPRNoX0:$rs1),
    487                         "c.jalr", "$rs1">;
    488 
    489 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
    490 def 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 
    496 let Predicates = [HasStdExtC, HasStdExtD] in
    497 def 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 
    502 def 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 
    507 let DecoderNamespace = "RISCV32Only_",
    508     Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
    509 def 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 
    514 let Predicates = [HasStdExtC, IsRV64] in
    515 def 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 
    526 class 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
    536 let Predicates = [HasStdExtC] in {
    537 def : CompressPat<(ADDI GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm),
    538                   (C_ADDI4SPN GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm)>;
    539 } // Predicates = [HasStdExtC]
    540 
    541 let Predicates = [HasStdExtC, HasStdExtD] in {
    542 def : CompressPat<(FLD FPR64C:$rd, GPRC:$rs1, uimm8_lsb000:$imm),
    543                   (C_FLD FPR64C:$rd, GPRC:$rs1, uimm8_lsb000:$imm)>;
    544 } // Predicates = [HasStdExtC, HasStdExtD]
    545 
    546 let Predicates = [HasStdExtC] in {
    547 def : CompressPat<(LW GPRC:$rd, GPRC:$rs1, uimm7_lsb00:$imm),
    548                   (C_LW GPRC:$rd, GPRC:$rs1, uimm7_lsb00:$imm)>;
    549 } // Predicates = [HasStdExtC]
    550 
    551 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
    552 def : 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 
    556 let Predicates = [HasStdExtC, IsRV64] in {
    557 def : CompressPat<(LD GPRC:$rd, GPRC:$rs1, uimm8_lsb000:$imm),
    558                   (C_LD GPRC:$rd, GPRC:$rs1, uimm8_lsb000:$imm)>;
    559 } // Predicates = [HasStdExtC, IsRV64]
    560 
    561 let Predicates = [HasStdExtC, HasStdExtD] in {
    562 def : CompressPat<(FSD FPR64C:$rs2, GPRC:$rs1, uimm8_lsb000:$imm),
    563                   (C_FSD FPR64C:$rs2, GPRC:$rs1, uimm8_lsb000:$imm)>;
    564 } // Predicates = [HasStdExtC, HasStdExtD]
    565 
    566 let Predicates = [HasStdExtC] in {
    567 def : CompressPat<(SW GPRC:$rs2, GPRC:$rs1, uimm7_lsb00:$imm),
    568                   (C_SW GPRC:$rs2, GPRC:$rs1, uimm7_lsb00:$imm)>;
    569 } // Predicates = [HasStdExtC]
    570 
    571 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
    572 def : 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 
    576 let Predicates = [HasStdExtC, IsRV64] in {
    577 def : 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
    582 let Predicates = [HasStdExtC] in {
    583 def : CompressPat<(ADDI X0, X0, 0), (C_NOP)>;
    584 def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs1, simm6nonzero:$imm),
    585                   (C_ADDI GPRNoX0:$rs1, simm6nonzero:$imm)>;
    586 } // Predicates = [HasStdExtC]
    587 
    588 let Predicates = [HasStdExtC, IsRV32] in {
    589 def : CompressPat<(JAL X1, simm12_lsb0:$offset),
    590                   (C_JAL simm12_lsb0:$offset)>;
    591 } // Predicates = [HasStdExtC, IsRV32]
    592 
    593 let Predicates = [HasStdExtC, IsRV64] in {
    594 def : CompressPat<(ADDIW GPRNoX0:$rs1, GPRNoX0:$rs1, simm6:$imm),
    595                   (C_ADDIW GPRNoX0:$rs1, simm6:$imm)>;
    596 } // Predicates = [HasStdExtC, IsRV64]
    597 
    598 let Predicates = [HasStdExtC] in {
    599 def : CompressPat<(ADDI GPRNoX0:$rd, X0, simm6:$imm),
    600                   (C_LI GPRNoX0:$rd, simm6:$imm)>;
    601 def : CompressPat<(ADDI X2, X2, simm10_lsb0000nonzero:$imm),
    602                   (C_ADDI16SP X2, simm10_lsb0000nonzero:$imm)>;
    603 def : CompressPat<(LUI GPRNoX0X2:$rd, c_lui_imm:$imm),
    604                   (C_LUI GPRNoX0X2:$rd, c_lui_imm:$imm)>;
    605 def : CompressPat<(SRLI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm),
    606                   (C_SRLI GPRC:$rs1, uimmlog2xlennonzero:$imm)>;
    607 def : CompressPat<(SRAI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm),
    608                   (C_SRAI GPRC:$rs1, uimmlog2xlennonzero:$imm)>;
    609 def : CompressPat<(ANDI GPRC:$rs1, GPRC:$rs1, simm6:$imm),
    610                   (C_ANDI GPRC:$rs1, simm6:$imm)>;
    611 def : CompressPat<(SUB GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
    612                   (C_SUB GPRC:$rs1, GPRC:$rs2)>;
    613 def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
    614                   (C_XOR GPRC:$rs1, GPRC:$rs2)>;
    615 def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
    616                   (C_XOR GPRC:$rs1, GPRC:$rs2)>;
    617 def : CompressPat<(OR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
    618                   (C_OR GPRC:$rs1, GPRC:$rs2)>;
    619 def : CompressPat<(OR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
    620                   (C_OR GPRC:$rs1, GPRC:$rs2)>;
    621 def : CompressPat<(AND GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
    622                   (C_AND GPRC:$rs1, GPRC:$rs2)>;
    623 def : CompressPat<(AND GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
    624                   (C_AND GPRC:$rs1, GPRC:$rs2)>;
    625 } //  Predicates = [HasStdExtC]
    626 
    627 let Predicates = [HasStdExtC, IsRV64] in {
    628 def : CompressPat<(SUBW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
    629                   (C_SUBW GPRC:$rs1, GPRC:$rs2)>;
    630 def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
    631                    (C_ADDW GPRC:$rs1, GPRC:$rs2)>;
    632 def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
    633                    (C_ADDW GPRC:$rs1, GPRC:$rs2)>;
    634 } // Predicates = [HasStdExtC, IsRV64]
    635 
    636 let Predicates = [HasStdExtC] in {
    637 def : CompressPat<(JAL X0, simm12_lsb0:$offset),
    638                   (C_J simm12_lsb0:$offset)>;
    639 def : CompressPat<(BEQ GPRC:$rs1, X0, simm9_lsb0:$imm),
    640                   (C_BEQZ GPRC:$rs1, simm9_lsb0:$imm)>;
    641 def : CompressPat<(BNE GPRC:$rs1, X0, simm9_lsb0:$imm),
    642                   (C_BNEZ GPRC:$rs1, simm9_lsb0:$imm)>;
    643 } //  Predicates = [HasStdExtC]
    644 
    645 // Quadrant 2
    646 let Predicates = [HasStdExtC] in {
    647 def : CompressPat<(SLLI GPRNoX0:$rs1, GPRNoX0:$rs1, uimmlog2xlennonzero:$imm),
    648                   (C_SLLI GPRNoX0:$rs1, uimmlog2xlennonzero:$imm)>;
    649 } //  Predicates = [HasStdExtC]
    650 
    651 let Predicates = [HasStdExtC, HasStdExtD] in {
    652 def : CompressPat<(FLD FPR64:$rd, SP:$rs1, uimm9_lsb000:$imm),
    653                   (C_FLDSP FPR64:$rd, SP:$rs1, uimm9_lsb000:$imm)>;
    654 } // Predicates = [HasStdExtC, HasStdExtD]
    655 
    656 let Predicates = [HasStdExtC] in {
    657 def : CompressPat<(LW GPRNoX0:$rd, SP:$rs1,  uimm8_lsb00:$imm),
    658                   (C_LWSP GPRNoX0:$rd, SP:$rs1, uimm8_lsb00:$imm)>;
    659 } // Predicates = [HasStdExtC]
    660 
    661 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
    662 def : 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 
    666 let Predicates = [HasStdExtC, IsRV64] in {
    667 def : CompressPat<(LD GPRNoX0:$rd, SP:$rs1, uimm9_lsb000:$imm),
    668                   (C_LDSP GPRNoX0:$rd, SP:$rs1, uimm9_lsb000:$imm)>;
    669 } // Predicates = [HasStdExtC, IsRV64]
    670 
    671 let Predicates = [HasStdExtC] in {
    672 def : CompressPat<(JALR X0, GPRNoX0:$rs1, 0),
    673                   (C_JR GPRNoX0:$rs1)>;
    674 def : CompressPat<(ADD GPRNoX0:$rs1, X0, GPRNoX0:$rs2),
    675                   (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
    676 def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, X0),
    677                   (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
    678 def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs2, 0),
    679                   (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
    680 def : CompressPat<(EBREAK), (C_EBREAK)>;
    681 def : CompressPat<(JALR X1, GPRNoX0:$rs1, 0),
    682                   (C_JALR GPRNoX0:$rs1)>;
    683 def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs1, GPRNoX0:$rs2),
    684                   (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
    685 def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, GPRNoX0:$rs1),
    686                   (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
    687 } // Predicates = [HasStdExtC]
    688 
    689 let Predicates = [HasStdExtC, HasStdExtD] in {
    690 def : CompressPat<(FSD FPR64:$rs2, SP:$rs1, uimm9_lsb000:$imm),
    691                   (C_FSDSP FPR64:$rs2, SP:$rs1, uimm9_lsb000:$imm)>;
    692 } // Predicates = [HasStdExtC, HasStdExtD]
    693 
    694 let Predicates = [HasStdExtC] in {
    695 def : CompressPat<(SW GPR:$rs2, SP:$rs1, uimm8_lsb00:$imm),
    696                   (C_SWSP GPR:$rs2, SP:$rs1, uimm8_lsb00:$imm)>;
    697 } // Predicates = [HasStdExtC]
    698 
    699 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
    700 def : 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 
    704 let Predicates = [HasStdExtC, IsRV64] in {
    705 def : CompressPat<(SD GPR:$rs2, SP:$rs1, uimm9_lsb000:$imm),
    706                   (C_SDSP GPR:$rs2, SP:$rs1, uimm9_lsb000:$imm)>;
    707 } //  Predicates = [HasStdExtC, IsRV64]
    708