1//===- RISCVInstrInfoC.td - Compressed RISC-V instructions -*- tblgen-*----===// 2// 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 6// 7//===----------------------------------------------------------------------===// 8 9include "RISCVInstrFormatsC.td" 10 11//===----------------------------------------------------------------------===// 12// Operand definitions. 13//===----------------------------------------------------------------------===// 14 15def UImmLog2XLenNonZeroAsmOperand : AsmOperandClass { 16 let Name = "UImmLog2XLenNonZero"; 17 let RenderMethod = "addImmOperands"; 18 let DiagnosticType = "InvalidUImmLog2XLenNonZero"; 19} 20 21def uimmlog2xlennonzero : Operand<XLenVT>, ImmLeaf<XLenVT, [{ 22 if (Subtarget->is64Bit()) 23 return isUInt<6>(Imm) && (Imm != 0); 24 return isUInt<5>(Imm) && (Imm != 0); 25}]> { 26 let ParserMatchClass = UImmLog2XLenNonZeroAsmOperand; 27 // TODO: should ensure invalid shamt is rejected when decoding. 28 let DecoderMethod = "decodeUImmNonZeroOperand<6>"; 29 let OperandType = "OPERAND_UIMMLOG2XLEN_NONZERO"; 30 let OperandNamespace = "RISCVOp"; 31 let MCOperandPredicate = [{ 32 int64_t Imm; 33 if (!MCOp.evaluateAsConstantImm(Imm)) 34 return false; 35 if (STI.getTargetTriple().isArch64Bit()) 36 return isUInt<6>(Imm) && (Imm != 0); 37 return isUInt<5>(Imm) && (Imm != 0); 38 }]; 39} 40 41def simm6 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isInt<6>(Imm);}]> { 42 let ParserMatchClass = SImmAsmOperand<6>; 43 let EncoderMethod = "getImmOpValue"; 44 let DecoderMethod = "decodeSImmOperand<6>"; 45 let OperandType = "OPERAND_SIMM6"; 46 let OperandNamespace = "RISCVOp"; 47 let MCOperandPredicate = [{ 48 int64_t Imm; 49 if (MCOp.evaluateAsConstantImm(Imm)) 50 return isInt<6>(Imm); 51 return MCOp.isBareSymbolRef(); 52 }]; 53} 54 55def simm6nonzero : Operand<XLenVT>, 56 ImmLeaf<XLenVT, [{return (Imm != 0) && isInt<6>(Imm);}]> { 57 let ParserMatchClass = SImmAsmOperand<6, "NonZero">; 58 let EncoderMethod = "getImmOpValue"; 59 let DecoderMethod = "decodeSImmNonZeroOperand<6>"; 60 let OperandType = "OPERAND_SIMM6_NONZERO"; 61 let OperandNamespace = "RISCVOp"; 62 let MCOperandPredicate = [{ 63 int64_t Imm; 64 if (MCOp.evaluateAsConstantImm(Imm)) 65 return (Imm != 0) && isInt<6>(Imm); 66 return MCOp.isBareSymbolRef(); 67 }]; 68} 69 70def immzero : Operand<XLenVT>, 71 ImmLeaf<XLenVT, [{return (Imm == 0);}]> { 72 let ParserMatchClass = ImmZeroAsmOperand; 73 let OperandType = "OPERAND_ZERO"; 74 let OperandNamespace = "RISCVOp"; 75} 76 77def CLUIImmAsmOperand : AsmOperandClass { 78 let Name = "CLUIImm"; 79 let RenderMethod = "addImmOperands"; 80 let DiagnosticType = !strconcat("Invalid", Name); 81} 82 83 84// c_lui_imm checks the immediate range is in [1, 31] or [0xfffe0, 0xfffff]. 85// The RISC-V ISA describes the constraint as [1, 63], with that value being 86// loaded in to bits 17-12 of the destination register and sign extended from 87// bit 17. Therefore, this 6-bit immediate can represent values in the ranges 88// [1, 31] and [0xfffe0, 0xfffff]. 89def c_lui_imm : Operand<XLenVT>, 90 ImmLeaf<XLenVT, [{return (Imm != 0) && 91 (isUInt<5>(Imm) || 92 (Imm >= 0xfffe0 && Imm <= 0xfffff));}]> { 93 let ParserMatchClass = CLUIImmAsmOperand; 94 let EncoderMethod = "getImmOpValue"; 95 let DecoderMethod = "decodeCLUIImmOperand"; 96 let OperandType = "OPERAND_CLUI_IMM"; 97 let OperandNamespace = "RISCVOp"; 98 let MCOperandPredicate = [{ 99 int64_t Imm; 100 if (MCOp.evaluateAsConstantImm(Imm)) 101 return (Imm != 0) && (isUInt<5>(Imm) || 102 (Imm >= 0xfffe0 && Imm <= 0xfffff)); 103 return MCOp.isBareSymbolRef(); 104 }]; 105} 106 107// A 7-bit unsigned immediate where the least significant two bits are zero. 108def uimm7_lsb00 : Operand<XLenVT>, 109 ImmLeaf<XLenVT, [{return isShiftedUInt<5, 2>(Imm);}]> { 110 let ParserMatchClass = UImmAsmOperand<7, "Lsb00">; 111 let EncoderMethod = "getImmOpValue"; 112 let DecoderMethod = "decodeUImmOperand<7>"; 113 let OperandType = "OPERAND_UIMM7_LSB00"; 114 let OperandNamespace = "RISCVOp"; 115 let MCOperandPredicate = [{ 116 int64_t Imm; 117 if (!MCOp.evaluateAsConstantImm(Imm)) 118 return false; 119 return isShiftedUInt<5, 2>(Imm); 120 }]; 121} 122 123// A 8-bit unsigned immediate where the least significant two bits are zero. 124def uimm8_lsb00 : Operand<XLenVT>, 125 ImmLeaf<XLenVT, [{return isShiftedUInt<6, 2>(Imm);}]> { 126 let ParserMatchClass = UImmAsmOperand<8, "Lsb00">; 127 let EncoderMethod = "getImmOpValue"; 128 let DecoderMethod = "decodeUImmOperand<8>"; 129 let OperandType = "OPERAND_UIMM8_LSB00"; 130 let OperandNamespace = "RISCVOp"; 131 let MCOperandPredicate = [{ 132 int64_t Imm; 133 if (!MCOp.evaluateAsConstantImm(Imm)) 134 return false; 135 return isShiftedUInt<6, 2>(Imm); 136 }]; 137} 138 139// A 8-bit unsigned immediate where the least significant three bits are zero. 140def uimm8_lsb000 : Operand<XLenVT>, 141 ImmLeaf<XLenVT, [{return isShiftedUInt<5, 3>(Imm);}]> { 142 let ParserMatchClass = UImmAsmOperand<8, "Lsb000">; 143 let EncoderMethod = "getImmOpValue"; 144 let DecoderMethod = "decodeUImmOperand<8>"; 145 let OperandType = "OPERAND_UIMM8_LSB000"; 146 let OperandNamespace = "RISCVOp"; 147 let MCOperandPredicate = [{ 148 int64_t Imm; 149 if (!MCOp.evaluateAsConstantImm(Imm)) 150 return false; 151 return isShiftedUInt<5, 3>(Imm); 152 }]; 153} 154 155// A 9-bit signed immediate where the least significant bit is zero. 156def simm9_lsb0 : Operand<OtherVT>, 157 ImmLeaf<XLenVT, [{return isShiftedInt<8, 1>(Imm);}]> { 158 let ParserMatchClass = SImmAsmOperand<9, "Lsb0">; 159 let PrintMethod = "printBranchOperand"; 160 let EncoderMethod = "getImmOpValueAsr1"; 161 let DecoderMethod = "decodeSImmOperandAndLsl1<9>"; 162 let MCOperandPredicate = [{ 163 int64_t Imm; 164 if (MCOp.evaluateAsConstantImm(Imm)) 165 return isShiftedInt<8, 1>(Imm); 166 return MCOp.isBareSymbolRef(); 167 168 }]; 169 let OperandType = "OPERAND_PCREL"; 170} 171 172// A 9-bit unsigned immediate where the least significant three bits are zero. 173def uimm9_lsb000 : Operand<XLenVT>, 174 ImmLeaf<XLenVT, [{return isShiftedUInt<6, 3>(Imm);}]> { 175 let ParserMatchClass = UImmAsmOperand<9, "Lsb000">; 176 let EncoderMethod = "getImmOpValue"; 177 let DecoderMethod = "decodeUImmOperand<9>"; 178 let OperandType = "OPERAND_UIMM9_LSB000"; 179 let OperandNamespace = "RISCVOp"; 180 let MCOperandPredicate = [{ 181 int64_t Imm; 182 if (!MCOp.evaluateAsConstantImm(Imm)) 183 return false; 184 return isShiftedUInt<6, 3>(Imm); 185 }]; 186} 187 188// A 10-bit unsigned immediate where the least significant two bits are zero 189// and the immediate can't be zero. 190def uimm10_lsb00nonzero : Operand<XLenVT>, 191 ImmLeaf<XLenVT, 192 [{return isShiftedUInt<8, 2>(Imm) && (Imm != 0);}]> { 193 let ParserMatchClass = UImmAsmOperand<10, "Lsb00NonZero">; 194 let EncoderMethod = "getImmOpValue"; 195 let DecoderMethod = "decodeUImmNonZeroOperand<10>"; 196 let OperandType = "OPERAND_UIMM10_LSB00_NONZERO"; 197 let OperandNamespace = "RISCVOp"; 198 let MCOperandPredicate = [{ 199 int64_t Imm; 200 if (!MCOp.evaluateAsConstantImm(Imm)) 201 return false; 202 return isShiftedUInt<8, 2>(Imm) && (Imm != 0); 203 }]; 204} 205 206// A 10-bit signed immediate where the least significant four bits are zero. 207def simm10_lsb0000nonzero : Operand<XLenVT>, 208 ImmLeaf<XLenVT, 209 [{return (Imm != 0) && isShiftedInt<6, 4>(Imm);}]> { 210 let ParserMatchClass = SImmAsmOperand<10, "Lsb0000NonZero">; 211 let EncoderMethod = "getImmOpValue"; 212 let DecoderMethod = "decodeSImmNonZeroOperand<10>"; 213 let OperandType = "OPERAND_SIMM10_LSB0000_NONZERO"; 214 let OperandNamespace = "RISCVOp"; 215 let MCOperandPredicate = [{ 216 int64_t Imm; 217 if (!MCOp.evaluateAsConstantImm(Imm)) 218 return false; 219 return isShiftedInt<6, 4>(Imm) && (Imm != 0); 220 }]; 221} 222 223// A 12-bit signed immediate where the least significant bit is zero. 224def simm12_lsb0 : Operand<XLenVT>, 225 ImmLeaf<XLenVT, [{return isShiftedInt<11, 1>(Imm);}]> { 226 let ParserMatchClass = SImmAsmOperand<12, "Lsb0">; 227 let PrintMethod = "printBranchOperand"; 228 let EncoderMethod = "getImmOpValueAsr1"; 229 let DecoderMethod = "decodeSImmOperandAndLsl1<12>"; 230 let MCOperandPredicate = [{ 231 int64_t Imm; 232 if (MCOp.evaluateAsConstantImm(Imm)) 233 return isShiftedInt<11, 1>(Imm); 234 return MCOp.isBareSymbolRef(); 235 }]; 236 let OperandType = "OPERAND_PCREL"; 237} 238 239def InsnCDirectiveOpcode : AsmOperandClass { 240 let Name = "InsnCDirectiveOpcode"; 241 let ParserMethod = "parseInsnCDirectiveOpcode"; 242 let RenderMethod = "addImmOperands"; 243 let PredicateMethod = "isImm"; 244} 245 246def uimm2_opcode : Operand<XLenVT> { 247 let ParserMatchClass = InsnCDirectiveOpcode; 248 let DecoderMethod = "decodeUImmOperand<2>"; 249 let OperandType = "OPERAND_UIMM2"; 250 let OperandNamespace = "RISCVOp"; 251} 252 253//===----------------------------------------------------------------------===// 254// Instruction Class Templates 255//===----------------------------------------------------------------------===// 256 257let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in 258class CStackLoad<bits<3> funct3, string OpcodeStr, 259 RegisterClass cls, DAGOperand opnd> 260 : RVInst16CI<funct3, 0b10, (outs cls:$rd), (ins SPMem:$rs1, opnd:$imm), 261 OpcodeStr, "$rd, ${imm}(${rs1})">; 262 263let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 264class CStackStore<bits<3> funct3, string OpcodeStr, 265 RegisterClass cls, DAGOperand opnd> 266 : RVInst16CSS<funct3, 0b10, (outs), (ins cls:$rs2, SPMem:$rs1, opnd:$imm), 267 OpcodeStr, "$rs2, ${imm}(${rs1})">; 268 269let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in 270class CLoad_ri<bits<3> funct3, string OpcodeStr, 271 RegisterClass cls, DAGOperand opnd> 272 : RVInst16CL<funct3, 0b00, (outs cls:$rd), (ins GPRCMem:$rs1, opnd:$imm), 273 OpcodeStr, "$rd, ${imm}(${rs1})">; 274 275let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 276class CStore_rri<bits<3> funct3, string OpcodeStr, 277 RegisterClass cls, DAGOperand opnd> 278 : RVInst16CS<funct3, 0b00, (outs), (ins cls:$rs2,GPRCMem:$rs1, opnd:$imm), 279 OpcodeStr, "$rs2, ${imm}(${rs1})">; 280 281let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 282class Bcz<bits<3> funct3, string OpcodeStr, 283 RegisterClass cls> 284 : RVInst16CB<funct3, 0b01, (outs), (ins cls:$rs1, simm9_lsb0:$imm), 285 OpcodeStr, "$rs1, $imm"> { 286 let isBranch = 1; 287 let isTerminator = 1; 288 let Inst{12} = imm{7}; 289 let Inst{11-10} = imm{3-2}; 290 let Inst{6-5} = imm{6-5}; 291 let Inst{4-3} = imm{1-0}; 292 let Inst{2} = imm{4}; 293} 294 295let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 296class Shift_right<bits<2> funct2, string OpcodeStr, RegisterClass cls, 297 Operand ImmOpnd> 298 : RVInst16CB<0b100, 0b01, (outs cls:$rs1_wb), (ins cls:$rs1, ImmOpnd:$imm), 299 OpcodeStr, "$rs1, $imm"> { 300 let Constraints = "$rs1 = $rs1_wb"; 301 let Inst{12} = imm{5}; 302 let Inst{11-10} = funct2; 303 let Inst{6-2} = imm{4-0}; 304} 305 306let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 307class CA_ALU<bits<6> funct6, bits<2> funct2, string OpcodeStr, 308 RegisterClass cls> 309 : RVInst16CA<funct6, funct2, 0b01, (outs cls:$rd_wb), (ins cls:$rd, cls:$rs2), 310 OpcodeStr, "$rd, $rs2"> { 311 bits<3> rd; 312 let Constraints = "$rd = $rd_wb"; 313 let Inst{9-7} = rd; 314} 315 316//===----------------------------------------------------------------------===// 317// Instructions 318//===----------------------------------------------------------------------===// 319 320let Predicates = [HasStdExtCOrZca] in { 321 322let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Uses = [X2] in 323def C_ADDI4SPN : RVInst16CIW<0b000, 0b00, (outs GPRC:$rd), 324 (ins SP:$rs1, uimm10_lsb00nonzero:$imm), 325 "c.addi4spn", "$rd, $rs1, $imm">, 326 Sched<[WriteIALU, ReadIALU]> { 327 bits<5> rs1; 328 let Inst{12-11} = imm{5-4}; 329 let Inst{10-7} = imm{9-6}; 330 let Inst{6} = imm{2}; 331 let Inst{5} = imm{3}; 332} 333 334let Predicates = [HasStdExtCOrZcd, HasStdExtD] in 335def C_FLD : CLoad_ri<0b001, "c.fld", FPR64C, uimm8_lsb000>, 336 Sched<[WriteFLD64, ReadMemBase]> { 337 bits<8> imm; 338 let Inst{12-10} = imm{5-3}; 339 let Inst{6-5} = imm{7-6}; 340} 341 342def C_LW : CLoad_ri<0b010, "c.lw", GPRC, uimm7_lsb00>, 343 Sched<[WriteLDW, ReadMemBase]> { 344 bits<7> imm; 345 let Inst{12-10} = imm{5-3}; 346 let Inst{6} = imm{2}; 347 let Inst{5} = imm{6}; 348} 349 350let DecoderNamespace = "RISCV32Only_", 351 Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in 352def C_FLW : CLoad_ri<0b011, "c.flw", FPR32C, uimm7_lsb00>, 353 Sched<[WriteFLD32, ReadMemBase]> { 354 bits<7> imm; 355 let Inst{12-10} = imm{5-3}; 356 let Inst{6} = imm{2}; 357 let Inst{5} = imm{6}; 358} 359 360let Predicates = [HasStdExtCOrZca, IsRV64] in 361def C_LD : CLoad_ri<0b011, "c.ld", GPRC, uimm8_lsb000>, 362 Sched<[WriteLDD, ReadMemBase]> { 363 bits<8> imm; 364 let Inst{12-10} = imm{5-3}; 365 let Inst{6-5} = imm{7-6}; 366} 367 368let Predicates = [HasStdExtCOrZcd, HasStdExtD] in 369def C_FSD : CStore_rri<0b101, "c.fsd", FPR64C, uimm8_lsb000>, 370 Sched<[WriteFST64, ReadStoreData, ReadMemBase]> { 371 bits<8> imm; 372 let Inst{12-10} = imm{5-3}; 373 let Inst{6-5} = imm{7-6}; 374} 375 376def C_SW : CStore_rri<0b110, "c.sw", GPRC, uimm7_lsb00>, 377 Sched<[WriteSTW, ReadStoreData, ReadMemBase]> { 378 bits<7> imm; 379 let Inst{12-10} = imm{5-3}; 380 let Inst{6} = imm{2}; 381 let Inst{5} = imm{6}; 382} 383 384let DecoderNamespace = "RISCV32Only_", 385 Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in 386def C_FSW : CStore_rri<0b111, "c.fsw", FPR32C, uimm7_lsb00>, 387 Sched<[WriteFST32, ReadStoreData, ReadMemBase]> { 388 bits<7> imm; 389 let Inst{12-10} = imm{5-3}; 390 let Inst{6} = imm{2}; 391 let Inst{5} = imm{6}; 392} 393 394let Predicates = [HasStdExtCOrZca, IsRV64] in 395def C_SD : CStore_rri<0b111, "c.sd", GPRC, uimm8_lsb000>, 396 Sched<[WriteSTD, ReadStoreData, ReadMemBase]> { 397 bits<8> imm; 398 let Inst{12-10} = imm{5-3}; 399 let Inst{6-5} = imm{7-6}; 400} 401 402let rd = 0, imm = 0, hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 403def C_NOP : RVInst16CI<0b000, 0b01, (outs), (ins), "c.nop", "">, 404 Sched<[WriteNop]> { 405 let Inst{6-2} = 0; 406} 407 408let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 409def C_ADDI : RVInst16CI<0b000, 0b01, (outs GPRNoX0:$rd_wb), 410 (ins GPRNoX0:$rd, simm6nonzero:$imm), 411 "c.addi", "$rd, $imm">, 412 Sched<[WriteIALU, ReadIALU]> { 413 let Constraints = "$rd = $rd_wb"; 414 let Inst{6-2} = imm{4-0}; 415} 416 417let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 418def C_ADDI_NOP : RVInst16CI<0b000, 0b01, (outs GPRX0:$rd_wb), 419 (ins GPRX0:$rd, immzero:$imm), 420 "c.addi", "$rd, $imm">, 421 Sched<[WriteIALU, ReadIALU]> { 422 let Constraints = "$rd = $rd_wb"; 423 let Inst{6-2} = 0; 424 let isAsmParserOnly = 1; 425} 426 427let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCall = 1, 428 DecoderNamespace = "RISCV32Only_", Defs = [X1], 429 Predicates = [HasStdExtCOrZca, IsRV32] in 430def C_JAL : RVInst16CJ<0b001, 0b01, (outs), (ins simm12_lsb0:$offset), 431 "c.jal", "$offset">, Sched<[WriteJal]>; 432 433let hasSideEffects = 0, mayLoad = 0, mayStore = 0, 434 Predicates = [HasStdExtCOrZca, IsRV64] in 435def C_ADDIW : RVInst16CI<0b001, 0b01, (outs GPRNoX0:$rd_wb), 436 (ins GPRNoX0:$rd, simm6:$imm), 437 "c.addiw", "$rd, $imm">, 438 Sched<[WriteIALU32, ReadIALU32]> { 439 let Constraints = "$rd = $rd_wb"; 440 let Inst{6-2} = imm{4-0}; 441} 442 443let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 444def C_LI : RVInst16CI<0b010, 0b01, (outs GPRNoX0:$rd), (ins simm6:$imm), 445 "c.li", "$rd, $imm">, 446 Sched<[WriteIALU]> { 447 let Inst{6-2} = imm{4-0}; 448} 449 450let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 451def C_ADDI16SP : RVInst16CI<0b011, 0b01, (outs SP:$rd_wb), 452 (ins SP:$rd, simm10_lsb0000nonzero:$imm), 453 "c.addi16sp", "$rd, $imm">, 454 Sched<[WriteIALU, ReadIALU]> { 455 let Constraints = "$rd = $rd_wb"; 456 let Inst{12} = imm{9}; 457 let Inst{11-7} = 2; 458 let Inst{6} = imm{4}; 459 let Inst{5} = imm{6}; 460 let Inst{4-3} = imm{8-7}; 461 let Inst{2} = imm{5}; 462} 463 464let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 465def C_LUI : RVInst16CI<0b011, 0b01, (outs GPRNoX0X2:$rd), 466 (ins c_lui_imm:$imm), 467 "c.lui", "$rd, $imm">, 468 Sched<[WriteIALU]> { 469 let Inst{6-2} = imm{4-0}; 470} 471 472def C_SRLI : Shift_right<0b00, "c.srli", GPRC, uimmlog2xlennonzero>, 473 Sched<[WriteShiftImm, ReadShiftImm]>; 474def C_SRAI : Shift_right<0b01, "c.srai", GPRC, uimmlog2xlennonzero>, 475 Sched<[WriteShiftImm, ReadShiftImm]>; 476 477let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 478def C_ANDI : RVInst16CB<0b100, 0b01, (outs GPRC:$rs1_wb), (ins GPRC:$rs1, simm6:$imm), 479 "c.andi", "$rs1, $imm">, 480 Sched<[WriteIALU, ReadIALU]> { 481 let Constraints = "$rs1 = $rs1_wb"; 482 let Inst{12} = imm{5}; 483 let Inst{11-10} = 0b10; 484 let Inst{6-2} = imm{4-0}; 485} 486 487def C_SUB : CA_ALU<0b100011, 0b00, "c.sub", GPRC>, 488 Sched<[WriteIALU, ReadIALU, ReadIALU]>; 489def C_XOR : CA_ALU<0b100011, 0b01, "c.xor", GPRC>, 490 Sched<[WriteIALU, ReadIALU, ReadIALU]>; 491def C_OR : CA_ALU<0b100011, 0b10, "c.or" , GPRC>, 492 Sched<[WriteIALU, ReadIALU, ReadIALU]>; 493def C_AND : CA_ALU<0b100011, 0b11, "c.and", GPRC>, 494 Sched<[WriteIALU, ReadIALU, ReadIALU]>; 495 496let Predicates = [HasStdExtCOrZca, IsRV64] in { 497def C_SUBW : CA_ALU<0b100111, 0b00, "c.subw", GPRC>, 498 Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>; 499def C_ADDW : CA_ALU<0b100111, 0b01, "c.addw", GPRC>, 500 Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>; 501} 502 503let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 504def C_J : RVInst16CJ<0b101, 0b01, (outs), (ins simm12_lsb0:$offset), 505 "c.j", "$offset">, Sched<[WriteJmp]> { 506 let isBranch = 1; 507 let isTerminator=1; 508 let isBarrier=1; 509} 510 511def C_BEQZ : Bcz<0b110, "c.beqz", GPRC>, Sched<[WriteJmp, ReadJmp]>; 512def C_BNEZ : Bcz<0b111, "c.bnez", GPRC>, Sched<[WriteJmp, ReadJmp]>; 513 514let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 515def C_SLLI : RVInst16CI<0b000, 0b10, (outs GPRNoX0:$rd_wb), 516 (ins GPRNoX0:$rd, uimmlog2xlennonzero:$imm), 517 "c.slli", "$rd, $imm">, 518 Sched<[WriteShiftImm, ReadShiftImm]> { 519 let Constraints = "$rd = $rd_wb"; 520 let Inst{6-2} = imm{4-0}; 521} 522 523let Predicates = [HasStdExtCOrZcd, HasStdExtD] in 524def C_FLDSP : CStackLoad<0b001, "c.fldsp", FPR64, uimm9_lsb000>, 525 Sched<[WriteFLD64, ReadMemBase]> { 526 let Inst{6-5} = imm{4-3}; 527 let Inst{4-2} = imm{8-6}; 528} 529 530def C_LWSP : CStackLoad<0b010, "c.lwsp", GPRNoX0, uimm8_lsb00>, 531 Sched<[WriteLDW, ReadMemBase]> { 532 let Inst{6-4} = imm{4-2}; 533 let Inst{3-2} = imm{7-6}; 534} 535 536let DecoderNamespace = "RISCV32Only_", 537 Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in 538def C_FLWSP : CStackLoad<0b011, "c.flwsp", FPR32, uimm8_lsb00>, 539 Sched<[WriteFLD32, ReadMemBase]> { 540 let Inst{6-4} = imm{4-2}; 541 let Inst{3-2} = imm{7-6}; 542} 543 544let Predicates = [HasStdExtCOrZca, IsRV64] in 545def C_LDSP : CStackLoad<0b011, "c.ldsp", GPRNoX0, uimm9_lsb000>, 546 Sched<[WriteLDD, ReadMemBase]> { 547 let Inst{6-5} = imm{4-3}; 548 let Inst{4-2} = imm{8-6}; 549} 550 551let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 552def C_JR : RVInst16CR<0b1000, 0b10, (outs), (ins GPRNoX0:$rs1), 553 "c.jr", "$rs1">, Sched<[WriteJalr, ReadJalr]> { 554 let isBarrier = 1; 555 let isTerminator = 1; 556 let rs2 = 0; 557} 558 559let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isMoveReg = 1, 560 isAsCheapAsAMove = 1 in 561def C_MV : RVInst16CR<0b1000, 0b10, (outs GPRNoX0:$rs1), (ins GPRNoX0:$rs2), 562 "c.mv", "$rs1, $rs2">, 563 Sched<[WriteIALU, ReadIALU]>; 564 565let rs1 = 0, rs2 = 0, hasSideEffects = 1, mayLoad = 0, mayStore = 0 in 566def C_EBREAK : RVInst16CR<0b1001, 0b10, (outs), (ins), "c.ebreak", "">, Sched<[]>; 567 568let hasSideEffects = 0, mayLoad = 0, mayStore = 0, 569 isCall=1, Defs=[X1], rs2 = 0 in 570def C_JALR : RVInst16CR<0b1001, 0b10, (outs), (ins GPRNoX0:$rs1), 571 "c.jalr", "$rs1">, Sched<[WriteJalr, ReadJalr]>; 572 573let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 574def C_ADD : RVInst16CR<0b1001, 0b10, (outs GPRNoX0:$rs1_wb), 575 (ins GPRNoX0:$rs1, GPRNoX0:$rs2), 576 "c.add", "$rs1, $rs2">, 577 Sched<[WriteIALU, ReadIALU, ReadIALU]> { 578 let Constraints = "$rs1 = $rs1_wb"; 579} 580 581let Predicates = [HasStdExtCOrZcd, HasStdExtD] in 582def C_FSDSP : CStackStore<0b101, "c.fsdsp", FPR64, uimm9_lsb000>, 583 Sched<[WriteFST64, ReadStoreData, ReadMemBase]> { 584 let Inst{12-10} = imm{5-3}; 585 let Inst{9-7} = imm{8-6}; 586} 587 588def C_SWSP : CStackStore<0b110, "c.swsp", GPR, uimm8_lsb00>, 589 Sched<[WriteSTW, ReadStoreData, ReadMemBase]> { 590 let Inst{12-9} = imm{5-2}; 591 let Inst{8-7} = imm{7-6}; 592} 593 594let DecoderNamespace = "RISCV32Only_", 595 Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in 596def C_FSWSP : CStackStore<0b111, "c.fswsp", FPR32, uimm8_lsb00>, 597 Sched<[WriteFST32, ReadStoreData, ReadMemBase]> { 598 let Inst{12-9} = imm{5-2}; 599 let Inst{8-7} = imm{7-6}; 600} 601 602let Predicates = [HasStdExtCOrZca, IsRV64] in 603def C_SDSP : CStackStore<0b111, "c.sdsp", GPR, uimm9_lsb000>, 604 Sched<[WriteSTD, ReadStoreData, ReadMemBase]> { 605 let Inst{12-10} = imm{5-3}; 606 let Inst{9-7} = imm{8-6}; 607} 608 609// The all zeros pattern isn't a valid RISC-V instruction. It's used by GNU 610// binutils as 16-bit instruction known to be unimplemented (i.e., trapping). 611let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in 612def C_UNIMP : RVInst16<(outs), (ins), "c.unimp", "", [], InstFormatOther>, 613 Sched<[]> { 614 let Inst{15-0} = 0; 615} 616 617} // Predicates = [HasStdExtCOrZca] 618 619//===----------------------------------------------------------------------===// 620// HINT Instructions 621//===----------------------------------------------------------------------===// 622 623let Predicates = [HasStdExtCOrZca, HasRVCHints], hasSideEffects = 0, mayLoad = 0, 624 mayStore = 0 in { 625 626let rd = 0 in 627def C_NOP_HINT : RVInst16CI<0b000, 0b01, (outs), (ins simm6nonzero:$imm), 628 "c.nop", "$imm">, Sched<[WriteNop]> { 629 let Inst{6-2} = imm{4-0}; 630} 631 632def C_ADDI_HINT_IMM_ZERO : RVInst16CI<0b000, 0b01, (outs GPRNoX0:$rd_wb), 633 (ins GPRNoX0:$rd, immzero:$imm), 634 "c.addi", "$rd, $imm">, 635 Sched<[WriteIALU, ReadIALU]> { 636 let Constraints = "$rd = $rd_wb"; 637 let Inst{12} = 0; 638 let Inst{6-2} = 0; 639 let DecoderMethod = "decodeRVCInstrRdRs1ImmZero"; 640} 641 642def C_LI_HINT : RVInst16CI<0b010, 0b01, (outs GPRX0:$rd), (ins simm6:$imm), 643 "c.li", "$rd, $imm">, 644 Sched<[WriteIALU]> { 645 let Inst{6-2} = imm{4-0}; 646 let Inst{11-7} = 0; 647 let DecoderMethod = "decodeRVCInstrRdSImm"; 648} 649 650def C_LUI_HINT : RVInst16CI<0b011, 0b01, (outs GPRX0:$rd), 651 (ins c_lui_imm:$imm), 652 "c.lui", "$rd, $imm">, 653 Sched<[WriteIALU]> { 654 let Inst{6-2} = imm{4-0}; 655 let Inst{11-7} = 0; 656 let DecoderMethod = "decodeRVCInstrRdSImm"; 657} 658 659def C_MV_HINT : RVInst16CR<0b1000, 0b10, (outs GPRX0:$rs1), (ins GPRNoX0:$rs2), 660 "c.mv", "$rs1, $rs2">, Sched<[WriteIALU, ReadIALU]> { 661 let Inst{11-7} = 0; 662 let DecoderMethod = "decodeRVCInstrRdRs2"; 663} 664 665def C_ADD_HINT : RVInst16CR<0b1001, 0b10, (outs GPRX0:$rs1_wb), 666 (ins GPRX0:$rs1, GPRNoX0:$rs2), 667 "c.add", "$rs1, $rs2">, 668 Sched<[WriteIALU, ReadIALU, ReadIALU]> { 669 let Constraints = "$rs1 = $rs1_wb"; 670 let Inst{11-7} = 0; 671 let DecoderMethod = "decodeRVCInstrRdRs1Rs2"; 672} 673 674def C_SLLI_HINT : RVInst16CI<0b000, 0b10, (outs GPRX0:$rd_wb), 675 (ins GPRX0:$rd, uimmlog2xlennonzero:$imm), 676 "c.slli", "$rd, $imm">, 677 Sched<[WriteShiftImm, ReadShiftImm]> { 678 let Constraints = "$rd = $rd_wb"; 679 let Inst{6-2} = imm{4-0}; 680 let Inst{11-7} = 0; 681 let DecoderMethod = "decodeRVCInstrRdRs1UImm"; 682} 683 684def C_SLLI64_HINT : RVInst16CI<0b000, 0b10, (outs GPR:$rd_wb), (ins GPR:$rd), 685 "c.slli64", "$rd">, 686 Sched<[WriteShiftImm, ReadShiftImm]> { 687 let Constraints = "$rd = $rd_wb"; 688 let Inst{6-2} = 0; 689 let Inst{12} = 0; 690} 691 692def C_SRLI64_HINT : RVInst16CI<0b100, 0b01, (outs GPRC:$rd_wb), 693 (ins GPRC:$rd), 694 "c.srli64", "$rd">, 695 Sched<[WriteShiftImm, ReadShiftImm]> { 696 let Constraints = "$rd = $rd_wb"; 697 let Inst{6-2} = 0; 698 let Inst{11-10} = 0; 699 let Inst{12} = 0; 700} 701 702def C_SRAI64_HINT : RVInst16CI<0b100, 0b01, (outs GPRC:$rd_wb), 703 (ins GPRC:$rd), 704 "c.srai64", "$rd">, 705 Sched<[WriteShiftImm, ReadShiftImm]> { 706 let Constraints = "$rd = $rd_wb"; 707 let Inst{6-2} = 0; 708 let Inst{11-10} = 1; 709 let Inst{12} = 0; 710} 711 712} // Predicates = [HasStdExtCOrZca, HasRVCHints], hasSideEffects = 0, mayLoad = 0, 713 // mayStore = 0 714 715//===----------------------------------------------------------------------===// 716// Assembler Pseudo Instructions 717//===----------------------------------------------------------------------===// 718 719let Predicates = [HasStdExtCOrZca, HasRVCHints] in { 720// Just a different syntax for the c.nop hint: c.addi x0, simm6 vs c.nop simm6. 721def : InstAlias<"c.addi x0, $imm", (C_NOP_HINT simm6nonzero:$imm), 0>; 722} 723 724let Predicates = [HasStdExtC, HasRVCHints, HasStdExtZihintntl] in { 725def : InstAlias<"c.ntl.p1", (C_ADD_HINT X0, X2)>; 726def : InstAlias<"c.ntl.pall", (C_ADD_HINT X0, X3)>; 727def : InstAlias<"c.ntl.s1", (C_ADD_HINT X0, X4)>; 728def : InstAlias<"c.ntl.all", (C_ADD_HINT X0, X5)>; 729} // Predicates = [HasStdExtC, HasRVCHints, HasStdExtZihintntl] 730 731let EmitPriority = 0 in { 732let Predicates = [HasStdExtCOrZca] in { 733def : InstAlias<"c.lw $rd, (${rs1})", (C_LW GPRC:$rd, GPRCMem:$rs1, 0)>; 734def : InstAlias<"c.sw $rs2, (${rs1})", (C_SW GPRC:$rs2, GPRCMem:$rs1, 0)>; 735def : InstAlias<"c.lwsp $rd, (${rs1})", (C_LWSP GPRC:$rd, SPMem:$rs1, 0)>; 736def : InstAlias<"c.swsp $rs2, (${rs1})", (C_SWSP GPRC:$rs2, SPMem:$rs1, 0)>; 737} 738 739let Predicates = [HasStdExtCOrZca, IsRV64] in { 740def : InstAlias<"c.ld $rd, (${rs1})", (C_LD GPRC:$rd, GPRCMem:$rs1, 0)>; 741def : InstAlias<"c.sd $rs2, (${rs1})", (C_SD GPRC:$rs2, GPRCMem:$rs1, 0)>; 742def : InstAlias<"c.ldsp $rd, (${rs1})", (C_LDSP GPRC:$rd, SPMem:$rs1, 0)>; 743def : InstAlias<"c.sdsp $rs2, (${rs1})", (C_SDSP GPRC:$rs2, SPMem:$rs1, 0)>; 744} 745 746let Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in { 747def : InstAlias<"c.flw $rd, (${rs1})", (C_FLW FPR32C:$rd, GPRCMem:$rs1, 0)>; 748def : InstAlias<"c.fsw $rs2, (${rs1})", (C_FSW FPR32C:$rs2, GPRCMem:$rs1, 0)>; 749def : InstAlias<"c.flwsp $rd, (${rs1})", (C_FLWSP FPR32C:$rd, SPMem:$rs1, 0)>; 750def : InstAlias<"c.fswsp $rs2, (${rs1})", (C_FSWSP FPR32C:$rs2, SPMem:$rs1, 0)>; 751} 752 753let Predicates = [HasStdExtCOrZcd, HasStdExtD] in { 754def : InstAlias<"c.fld $rd, (${rs1})", (C_FLD FPR64C:$rd, GPRCMem:$rs1, 0)>; 755def : InstAlias<"c.fsd $rs2, (${rs1})", (C_FSD FPR64C:$rs2, GPRCMem:$rs1, 0)>; 756def : InstAlias<"c.fldsp $rd, (${rs1})", (C_FLDSP FPR64C:$rd, SPMem:$rs1, 0)>; 757def : InstAlias<"c.fsdsp $rs2, (${rs1})", (C_FSDSP FPR64C:$rs2, SPMem:$rs1, 0)>; 758} 759} // EmitPriority = 0 760 761//===----------------------------------------------------------------------===// 762// .insn directive instructions 763//===----------------------------------------------------------------------===// 764 765def AnyRegCOperand : AsmOperandClass { 766 let Name = "AnyRegCOperand"; 767 let RenderMethod = "addRegOperands"; 768 let PredicateMethod = "isAnyRegC"; 769} 770 771def AnyRegC : Operand<XLenVT> { 772 let OperandType = "OPERAND_REGISTER"; 773 let ParserMatchClass = AnyRegCOperand; 774} 775 776// isCodeGenOnly = 1 to hide them from the tablegened assembly parser. 777let isCodeGenOnly = 1, hasSideEffects = 1, mayLoad = 1, mayStore = 1, 778 hasNoSchedulingInfo = 1, Predicates = [HasStdExtCOrZca] in { 779def InsnCR : DirectiveInsnCR<(outs AnyReg:$rd), (ins uimm2_opcode:$opcode, 780 uimm4:$funct4, 781 AnyReg:$rs2), 782 "$opcode, $funct4, $rd, $rs2">; 783def InsnCI : DirectiveInsnCI<(outs AnyRegC:$rd), (ins uimm2_opcode:$opcode, 784 uimm3:$funct3, 785 simm6:$imm6), 786 "$opcode, $funct3, $rd, $imm6">; 787def InsnCIW : DirectiveInsnCIW<(outs AnyRegC:$rd), (ins uimm2_opcode:$opcode, 788 uimm3:$funct3, 789 uimm8:$imm8), 790 "$opcode, $funct3, $rd, $imm8">; 791def InsnCSS : DirectiveInsnCSS<(outs), (ins uimm2_opcode:$opcode, 792 uimm3:$funct3, 793 AnyReg:$rs2, 794 uimm6:$imm6), 795 "$opcode, $funct3, $rs2, $imm6">; 796def InsnCL : DirectiveInsnCL<(outs AnyRegC:$rd), (ins uimm2_opcode:$opcode, 797 uimm3:$funct3, 798 AnyRegC:$rs1, 799 uimm5:$imm5), 800 "$opcode, $funct3, $rd, ${imm5}(${rs1})">; 801def InsnCS : DirectiveInsnCS<(outs), (ins uimm2_opcode:$opcode, 802 uimm3:$funct3, 803 AnyRegC:$rs2, 804 AnyRegC:$rs1, 805 uimm5:$imm5), 806 "$opcode, $funct3, $rs2, ${imm5}(${rs1})">; 807def InsnCA : DirectiveInsnCA<(outs AnyRegC:$rd), (ins uimm2_opcode:$opcode, 808 uimm6:$funct6, 809 uimm2:$funct2, 810 AnyRegC:$rs2), 811 "$opcode, $funct6, $funct2, $rd, $rs2">; 812def InsnCB : DirectiveInsnCB<(outs), (ins uimm2_opcode:$opcode, uimm3:$funct3, 813 AnyRegC:$rs1, 814 simm9_lsb0:$imm8), 815 "$opcode, $funct3, $rs1, $imm8">; 816def InsnCJ : DirectiveInsnCJ<(outs), (ins uimm2_opcode:$opcode, 817 uimm3:$funct3, 818 simm12_lsb0:$imm11), 819 "$opcode, $funct3, $imm11">; 820} 821 822// Use InstAliases to match these so that we can combine the insn and format 823// into a mnemonic to use as the key for the tablegened asm matcher table. The 824// parser will take care of creating these fake mnemonics and will only do it 825// for known formats. 826let EmitPriority = 0, Predicates = [HasStdExtCOrZca] in { 827def : InstAlias<".insn_cr $opcode, $funct4, $rd, $rs2", 828 (InsnCR AnyReg:$rd, uimm2_opcode:$opcode, uimm4:$funct4, 829 AnyReg:$rs2)>; 830def : InstAlias<".insn_ci $opcode, $funct3, $rd, $imm6", 831 (InsnCI AnyRegC:$rd, uimm2_opcode:$opcode, uimm3:$funct3, 832 simm6:$imm6)>; 833def : InstAlias<".insn_ciw $opcode, $funct3, $rd, $imm8", 834 (InsnCIW AnyRegC:$rd, uimm2_opcode:$opcode, uimm3:$funct3, 835 uimm8:$imm8)>; 836def : InstAlias<".insn_css $opcode, $funct3, $rs2, $imm6", 837 (InsnCSS uimm2_opcode:$opcode, uimm3:$funct3, AnyReg:$rs2, 838 uimm6:$imm6)>; 839def : InstAlias<".insn_cl $opcode, $funct3, $rd, ${imm5}(${rs1})", 840 (InsnCL AnyRegC:$rd, uimm2_opcode:$opcode, uimm3:$funct3, 841 AnyRegC:$rs1, uimm5:$imm5)>; 842def : InstAlias<".insn_cs $opcode, $funct3, $rs2, ${imm5}(${rs1})", 843 (InsnCS uimm2_opcode:$opcode, uimm3:$funct3, AnyRegC:$rs2, 844 AnyRegC:$rs1, uimm5:$imm5)>; 845def : InstAlias<".insn_ca $opcode, $funct6, $funct2, $rd, $rs2", 846 (InsnCA AnyRegC:$rd, uimm2_opcode:$opcode, uimm6:$funct6, 847 uimm2:$funct2, AnyRegC:$rs2)>; 848def : InstAlias<".insn_cb $opcode, $funct3, $rs1, $imm8", 849 (InsnCB uimm2_opcode:$opcode, uimm3:$funct3, AnyRegC:$rs1, 850 simm9_lsb0:$imm8)>; 851def : InstAlias<".insn_cj $opcode, $funct3, $imm11", 852 (InsnCJ uimm2_opcode:$opcode, uimm3:$funct3, simm12_lsb0:$imm11)>; 853} 854 855//===----------------------------------------------------------------------===/i 856// Compress Instruction tablegen backend. 857//===----------------------------------------------------------------------===// 858 859// Patterns are defined in the same order the compressed instructions appear 860// on page 82 of the ISA manual. 861 862// Quadrant 0 863let Predicates = [HasStdExtCOrZca] in { 864def : CompressPat<(ADDI GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm), 865 (C_ADDI4SPN GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm)>; 866} // Predicates = [HasStdExtCOrZca] 867 868let Predicates = [HasStdExtCOrZcd, HasStdExtD] in { 869def : CompressPat<(FLD FPR64C:$rd, GPRCMem:$rs1, uimm8_lsb000:$imm), 870 (C_FLD FPR64C:$rd, GPRCMem:$rs1, uimm8_lsb000:$imm)>; 871} // Predicates = [HasStdExtCOrZcd, HasStdExtD] 872 873let Predicates = [HasStdExtCOrZca] in { 874def : CompressPat<(LW GPRC:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm), 875 (C_LW GPRC:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm)>; 876} // Predicates = [HasStdExtCOrZca] 877 878let Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in { 879def : CompressPat<(FLW FPR32C:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm), 880 (C_FLW FPR32C:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm)>; 881} // Predicates = [HasStdExtC, HasStdExtF, IsRV32] 882 883let Predicates = [HasStdExtCOrZca, IsRV64] in { 884def : CompressPat<(LD GPRC:$rd, GPRCMem:$rs1, uimm8_lsb000:$imm), 885 (C_LD GPRC:$rd, GPRCMem:$rs1, uimm8_lsb000:$imm)>; 886} // Predicates = [HasStdExtCOrZca, IsRV64] 887 888let Predicates = [HasStdExtCOrZcd, HasStdExtD] in { 889def : CompressPat<(FSD FPR64C:$rs2, GPRCMem:$rs1, uimm8_lsb000:$imm), 890 (C_FSD FPR64C:$rs2, GPRCMem:$rs1, uimm8_lsb000:$imm)>; 891} // Predicates = [HasStdExtCOrZcd, HasStdExtD] 892 893let Predicates = [HasStdExtCOrZca] in { 894def : CompressPat<(SW GPRC:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm), 895 (C_SW GPRC:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm)>; 896} // Predicates = [HasStdExtCOrZca] 897 898let Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in { 899def : CompressPat<(FSW FPR32C:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm), 900 (C_FSW FPR32C:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm)>; 901} // Predicates = [HasStdExtC, HasStdExtF, IsRV32] 902 903let Predicates = [HasStdExtCOrZca, IsRV64] in { 904def : CompressPat<(SD GPRC:$rs2, GPRCMem:$rs1, uimm8_lsb000:$imm), 905 (C_SD GPRC:$rs2, GPRCMem:$rs1, uimm8_lsb000:$imm)>; 906} // Predicates = [HasStdExtCOrZca, IsRV64] 907 908// Quadrant 1 909let Predicates = [HasStdExtCOrZca] in { 910def : CompressPat<(ADDI X0, X0, 0), (C_NOP)>; 911def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs1, simm6nonzero:$imm), 912 (C_ADDI GPRNoX0:$rs1, simm6nonzero:$imm)>; 913} // Predicates = [HasStdExtCOrZca] 914 915let Predicates = [HasStdExtCOrZca, IsRV32] in { 916def : CompressPat<(JAL X1, simm12_lsb0:$offset), 917 (C_JAL simm12_lsb0:$offset)>; 918} // Predicates = [HasStdExtCOrZca, IsRV32] 919 920let Predicates = [HasStdExtCOrZca, IsRV64] in { 921def : CompressPat<(ADDIW GPRNoX0:$rs1, GPRNoX0:$rs1, simm6:$imm), 922 (C_ADDIW GPRNoX0:$rs1, simm6:$imm)>; 923} // Predicates = [HasStdExtCOrZca, IsRV64] 924 925let Predicates = [HasStdExtCOrZca] in { 926def : CompressPat<(ADDI GPRNoX0:$rd, X0, simm6:$imm), 927 (C_LI GPRNoX0:$rd, simm6:$imm)>; 928def : CompressPat<(ADDI X2, X2, simm10_lsb0000nonzero:$imm), 929 (C_ADDI16SP X2, simm10_lsb0000nonzero:$imm)>; 930def : CompressPat<(LUI GPRNoX0X2:$rd, c_lui_imm:$imm), 931 (C_LUI GPRNoX0X2:$rd, c_lui_imm:$imm)>; 932def : CompressPat<(SRLI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm), 933 (C_SRLI GPRC:$rs1, uimmlog2xlennonzero:$imm)>; 934def : CompressPat<(SRAI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm), 935 (C_SRAI GPRC:$rs1, uimmlog2xlennonzero:$imm)>; 936def : CompressPat<(ANDI GPRC:$rs1, GPRC:$rs1, simm6:$imm), 937 (C_ANDI GPRC:$rs1, simm6:$imm)>; 938def : CompressPat<(SUB GPRC:$rs1, GPRC:$rs1, GPRC:$rs2), 939 (C_SUB GPRC:$rs1, GPRC:$rs2)>; 940def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2), 941 (C_XOR GPRC:$rs1, GPRC:$rs2)>; 942let isCompressOnly = true in 943def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1), 944 (C_XOR GPRC:$rs1, GPRC:$rs2)>; 945def : CompressPat<(OR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2), 946 (C_OR GPRC:$rs1, GPRC:$rs2)>; 947let isCompressOnly = true in 948def : CompressPat<(OR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1), 949 (C_OR GPRC:$rs1, GPRC:$rs2)>; 950def : CompressPat<(AND GPRC:$rs1, GPRC:$rs1, GPRC:$rs2), 951 (C_AND GPRC:$rs1, GPRC:$rs2)>; 952let isCompressOnly = true in 953def : CompressPat<(AND GPRC:$rs1, GPRC:$rs2, GPRC:$rs1), 954 (C_AND GPRC:$rs1, GPRC:$rs2)>; 955} // Predicates = [HasStdExtCOrZca] 956 957let Predicates = [HasStdExtCOrZca, IsRV64] in { 958let isCompressOnly = true in 959def : CompressPat<(ADDIW GPRNoX0:$rd, X0, simm6:$imm), 960 (C_LI GPRNoX0:$rd, simm6:$imm)>; 961def : CompressPat<(SUBW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2), 962 (C_SUBW GPRC:$rs1, GPRC:$rs2)>; 963def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2), 964 (C_ADDW GPRC:$rs1, GPRC:$rs2)>; 965let isCompressOnly = true in 966def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs2, GPRC:$rs1), 967 (C_ADDW GPRC:$rs1, GPRC:$rs2)>; 968} // Predicates = [HasStdExtCOrZca, IsRV64] 969 970let Predicates = [HasStdExtCOrZca] in { 971def : CompressPat<(JAL X0, simm12_lsb0:$offset), 972 (C_J simm12_lsb0:$offset)>; 973def : CompressPat<(BEQ GPRC:$rs1, X0, simm9_lsb0:$imm), 974 (C_BEQZ GPRC:$rs1, simm9_lsb0:$imm)>; 975def : CompressPat<(BNE GPRC:$rs1, X0, simm9_lsb0:$imm), 976 (C_BNEZ GPRC:$rs1, simm9_lsb0:$imm)>; 977} // Predicates = [HasStdExtCOrZca] 978 979// Quadrant 2 980let Predicates = [HasStdExtCOrZca] in { 981def : CompressPat<(SLLI GPRNoX0:$rs1, GPRNoX0:$rs1, uimmlog2xlennonzero:$imm), 982 (C_SLLI GPRNoX0:$rs1, uimmlog2xlennonzero:$imm)>; 983} // Predicates = [HasStdExtCOrZca] 984 985let Predicates = [HasStdExtCOrZcd, HasStdExtD] in { 986def : CompressPat<(FLD FPR64:$rd, SPMem:$rs1, uimm9_lsb000:$imm), 987 (C_FLDSP FPR64:$rd, SPMem:$rs1, uimm9_lsb000:$imm)>; 988} // Predicates = [HasStdExtCOrZcd, HasStdExtD] 989 990let Predicates = [HasStdExtCOrZca] in { 991def : CompressPat<(LW GPRNoX0:$rd, SPMem:$rs1, uimm8_lsb00:$imm), 992 (C_LWSP GPRNoX0:$rd, SPMem:$rs1, uimm8_lsb00:$imm)>; 993} // Predicates = [HasStdExtCOrZca] 994 995let Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in { 996def : CompressPat<(FLW FPR32:$rd, SPMem:$rs1, uimm8_lsb00:$imm), 997 (C_FLWSP FPR32:$rd, SPMem:$rs1, uimm8_lsb00:$imm)>; 998} // Predicates = [HasStdExtC, HasStdExtF, IsRV32] 999 1000let Predicates = [HasStdExtCOrZca, IsRV64] in { 1001def : CompressPat<(LD GPRNoX0:$rd, SPMem:$rs1, uimm9_lsb000:$imm), 1002 (C_LDSP GPRNoX0:$rd, SPMem:$rs1, uimm9_lsb000:$imm)>; 1003} // Predicates = [HasStdExtCOrZca, IsRV64] 1004 1005let Predicates = [HasStdExtCOrZca] in { 1006def : CompressPat<(JALR X0, GPRNoX0:$rs1, 0), 1007 (C_JR GPRNoX0:$rs1)>; 1008let isCompressOnly = true in { 1009def : CompressPat<(ADD GPRNoX0:$rs1, X0, GPRNoX0:$rs2), 1010 (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>; 1011def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, X0), 1012 (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>; 1013} 1014def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs2, 0), 1015 (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>; 1016def : CompressPat<(EBREAK), (C_EBREAK)>; 1017def : CompressPat<(UNIMP), (C_UNIMP)>; 1018def : CompressPat<(JALR X1, GPRNoX0:$rs1, 0), 1019 (C_JALR GPRNoX0:$rs1)>; 1020def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs1, GPRNoX0:$rs2), 1021 (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>; 1022let isCompressOnly = true in 1023def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, GPRNoX0:$rs1), 1024 (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>; 1025} // Predicates = [HasStdExtCOrZca] 1026 1027let Predicates = [HasStdExtCOrZcd, HasStdExtD] in { 1028def : CompressPat<(FSD FPR64:$rs2, SPMem:$rs1, uimm9_lsb000:$imm), 1029 (C_FSDSP FPR64:$rs2, SPMem:$rs1, uimm9_lsb000:$imm)>; 1030} // Predicates = [HasStdExtCOrZcd, HasStdExtD] 1031 1032let Predicates = [HasStdExtCOrZca] in { 1033def : CompressPat<(SW GPR:$rs2, SPMem:$rs1, uimm8_lsb00:$imm), 1034 (C_SWSP GPR:$rs2, SPMem:$rs1, uimm8_lsb00:$imm)>; 1035} // Predicates = [HasStdExtCOrZca] 1036 1037let Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in { 1038def : CompressPat<(FSW FPR32:$rs2, SPMem:$rs1, uimm8_lsb00:$imm), 1039 (C_FSWSP FPR32:$rs2, SPMem:$rs1, uimm8_lsb00:$imm)>; 1040} // Predicates = [HasStdExtC, HasStdExtF, IsRV32] 1041 1042let Predicates = [HasStdExtCOrZca, IsRV64] in { 1043def : CompressPat<(SD GPR:$rs2, SPMem:$rs1, uimm9_lsb000:$imm), 1044 (C_SDSP GPR:$rs2, SPMem:$rs1, uimm9_lsb000:$imm)>; 1045} // Predicates = [HasStdExtCOrZca, IsRV64] 1046