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