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 let DecoderMethod = "decodeUImmLog2XLenNonZeroOperand"; 28 let OperandType = "OPERAND_UIMMLOG2XLEN_NONZERO"; 29 let MCOperandPredicate = [{ 30 int64_t Imm; 31 if (!MCOp.evaluateAsConstantImm(Imm)) 32 return false; 33 if (STI.getTargetTriple().isArch64Bit()) 34 return isUInt<6>(Imm) && (Imm != 0); 35 return isUInt<5>(Imm) && (Imm != 0); 36 }]; 37} 38 39def simm6 : RISCVSImmLeafOp<6> { 40 let MCOperandPredicate = [{ 41 int64_t Imm; 42 if (MCOp.evaluateAsConstantImm(Imm)) 43 return isInt<6>(Imm); 44 return MCOp.isBareSymbolRef(); 45 }]; 46} 47 48def simm6nonzero : RISCVOp, 49 ImmLeaf<XLenVT, [{return (Imm != 0) && isInt<6>(Imm);}]> { 50 let ParserMatchClass = SImmAsmOperand<6, "NonZero">; 51 let EncoderMethod = "getImmOpValue"; 52 let DecoderMethod = "decodeSImmNonZeroOperand<6>"; 53 let OperandType = "OPERAND_SIMM6_NONZERO"; 54 let MCOperandPredicate = [{ 55 int64_t Imm; 56 if (MCOp.evaluateAsConstantImm(Imm)) 57 return (Imm != 0) && isInt<6>(Imm); 58 return MCOp.isBareSymbolRef(); 59 }]; 60} 61 62def immzero : RISCVOp, 63 ImmLeaf<XLenVT, [{return (Imm == 0);}]> { 64 let ParserMatchClass = ImmZeroAsmOperand; 65 let OperandType = "OPERAND_ZERO"; 66} 67 68def CLUIImmAsmOperand : AsmOperandClass { 69 let Name = "CLUIImm"; 70 let RenderMethod = "addImmOperands"; 71 let DiagnosticType = !strconcat("Invalid", Name); 72} 73 74 75// c_lui_imm checks the immediate range is in [1, 31] or [0xfffe0, 0xfffff]. 76// The RISC-V ISA describes the constraint as [1, 63], with that value being 77// loaded in to bits 17-12 of the destination register and sign extended from 78// bit 17. Therefore, this 6-bit immediate can represent values in the ranges 79// [1, 31] and [0xfffe0, 0xfffff]. 80def c_lui_imm : RISCVOp, 81 ImmLeaf<XLenVT, [{return (Imm != 0) && 82 (isUInt<5>(Imm) || 83 (Imm >= 0xfffe0 && Imm <= 0xfffff));}]> { 84 let ParserMatchClass = CLUIImmAsmOperand; 85 let EncoderMethod = "getImmOpValue"; 86 let DecoderMethod = "decodeCLUIImmOperand"; 87 let OperandType = "OPERAND_CLUI_IMM"; 88 let MCOperandPredicate = [{ 89 int64_t Imm; 90 if (MCOp.evaluateAsConstantImm(Imm)) 91 return (Imm != 0) && (isUInt<5>(Imm) || 92 (Imm >= 0xfffe0 && Imm <= 0xfffff)); 93 return MCOp.isBareSymbolRef(); 94 }]; 95} 96 97// A 7-bit unsigned immediate where the least significant two bits are zero. 98def uimm7_lsb00 : RISCVOp, 99 ImmLeaf<XLenVT, [{return isShiftedUInt<5, 2>(Imm);}]> { 100 let ParserMatchClass = UImmAsmOperand<7, "Lsb00">; 101 let EncoderMethod = "getImmOpValue"; 102 let DecoderMethod = "decodeUImmOperand<7>"; 103 let OperandType = "OPERAND_UIMM7_LSB00"; 104 let MCOperandPredicate = [{ 105 int64_t Imm; 106 if (!MCOp.evaluateAsConstantImm(Imm)) 107 return false; 108 return isShiftedUInt<5, 2>(Imm); 109 }]; 110} 111 112// A 8-bit unsigned immediate where the least significant two bits are zero. 113def uimm8_lsb00 : RISCVOp, 114 ImmLeaf<XLenVT, [{return isShiftedUInt<6, 2>(Imm);}]> { 115 let ParserMatchClass = UImmAsmOperand<8, "Lsb00">; 116 let EncoderMethod = "getImmOpValue"; 117 let DecoderMethod = "decodeUImmOperand<8>"; 118 let OperandType = "OPERAND_UIMM8_LSB00"; 119 let MCOperandPredicate = [{ 120 int64_t Imm; 121 if (!MCOp.evaluateAsConstantImm(Imm)) 122 return false; 123 return isShiftedUInt<6, 2>(Imm); 124 }]; 125} 126 127// A 8-bit unsigned immediate where the least significant three bits are zero. 128def uimm8_lsb000 : RISCVOp, 129 ImmLeaf<XLenVT, [{return isShiftedUInt<5, 3>(Imm);}]> { 130 let ParserMatchClass = UImmAsmOperand<8, "Lsb000">; 131 let EncoderMethod = "getImmOpValue"; 132 let DecoderMethod = "decodeUImmOperand<8>"; 133 let OperandType = "OPERAND_UIMM8_LSB000"; 134 let MCOperandPredicate = [{ 135 int64_t Imm; 136 if (!MCOp.evaluateAsConstantImm(Imm)) 137 return false; 138 return isShiftedUInt<5, 3>(Imm); 139 }]; 140} 141 142// A 9-bit signed immediate where the least significant bit is zero. 143def simm9_lsb0 : Operand<OtherVT>, 144 ImmLeaf<XLenVT, [{return isShiftedInt<8, 1>(Imm);}]> { 145 let ParserMatchClass = SImmAsmOperand<9, "Lsb0">; 146 let PrintMethod = "printBranchOperand"; 147 let EncoderMethod = "getImmOpValueAsr1"; 148 let DecoderMethod = "decodeSImmOperandAndLsl1<9>"; 149 let MCOperandPredicate = [{ 150 int64_t Imm; 151 if (MCOp.evaluateAsConstantImm(Imm)) 152 return isShiftedInt<8, 1>(Imm); 153 return MCOp.isBareSymbolRef(); 154 }]; 155 let OperandType = "OPERAND_PCREL"; 156} 157 158// A 9-bit unsigned immediate where the least significant three bits are zero. 159def uimm9_lsb000 : RISCVOp, 160 ImmLeaf<XLenVT, [{return isShiftedUInt<6, 3>(Imm);}]> { 161 let ParserMatchClass = UImmAsmOperand<9, "Lsb000">; 162 let EncoderMethod = "getImmOpValue"; 163 let DecoderMethod = "decodeUImmOperand<9>"; 164 let OperandType = "OPERAND_UIMM9_LSB000"; 165 let MCOperandPredicate = [{ 166 int64_t Imm; 167 if (!MCOp.evaluateAsConstantImm(Imm)) 168 return false; 169 return isShiftedUInt<6, 3>(Imm); 170 }]; 171} 172 173// A 10-bit unsigned immediate where the least significant two bits are zero 174// and the immediate can't be zero. 175def uimm10_lsb00nonzero : RISCVOp, 176 ImmLeaf<XLenVT, 177 [{return isShiftedUInt<8, 2>(Imm) && (Imm != 0);}]> { 178 let ParserMatchClass = UImmAsmOperand<10, "Lsb00NonZero">; 179 let EncoderMethod = "getImmOpValue"; 180 let DecoderMethod = "decodeUImmNonZeroOperand<10>"; 181 let OperandType = "OPERAND_UIMM10_LSB00_NONZERO"; 182 let MCOperandPredicate = [{ 183 int64_t Imm; 184 if (!MCOp.evaluateAsConstantImm(Imm)) 185 return false; 186 return isShiftedUInt<8, 2>(Imm) && (Imm != 0); 187 }]; 188} 189 190// A 10-bit signed immediate where the least significant four bits are zero. 191def simm10_lsb0000nonzero : RISCVOp, 192 ImmLeaf<XLenVT, 193 [{return (Imm != 0) && isShiftedInt<6, 4>(Imm);}]> { 194 let ParserMatchClass = SImmAsmOperand<10, "Lsb0000NonZero">; 195 let EncoderMethod = "getImmOpValue"; 196 let DecoderMethod = "decodeSImmNonZeroOperand<10>"; 197 let OperandType = "OPERAND_SIMM10_LSB0000_NONZERO"; 198 let MCOperandPredicate = [{ 199 int64_t Imm; 200 if (!MCOp.evaluateAsConstantImm(Imm)) 201 return false; 202 return isShiftedInt<6, 4>(Imm) && (Imm != 0); 203 }]; 204} 205 206// A 12-bit signed immediate where the least significant bit is zero. 207def simm12_lsb0 : Operand<XLenVT>, 208 ImmLeaf<XLenVT, [{return isShiftedInt<11, 1>(Imm);}]> { 209 let ParserMatchClass = SImmAsmOperand<12, "Lsb0">; 210 let PrintMethod = "printBranchOperand"; 211 let EncoderMethod = "getImmOpValueAsr1"; 212 let DecoderMethod = "decodeSImmOperandAndLsl1<12>"; 213 let MCOperandPredicate = [{ 214 int64_t Imm; 215 if (MCOp.evaluateAsConstantImm(Imm)) 216 return isShiftedInt<11, 1>(Imm); 217 return MCOp.isBareSymbolRef(); 218 }]; 219 let OperandType = "OPERAND_PCREL"; 220} 221 222def InsnCDirectiveOpcode : AsmOperandClass { 223 let Name = "InsnCDirectiveOpcode"; 224 let ParserMethod = "parseInsnCDirectiveOpcode"; 225 let RenderMethod = "addImmOperands"; 226 let PredicateMethod = "isImm"; 227} 228 229def uimm2_opcode : RISCVUImmOp<2> { 230 let ParserMatchClass = InsnCDirectiveOpcode; 231} 232 233//===----------------------------------------------------------------------===// 234// Instruction Class Templates 235//===----------------------------------------------------------------------===// 236 237let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in 238class CStackLoad<bits<3> funct3, string OpcodeStr, 239 RegisterClass cls, DAGOperand opnd> 240 : RVInst16CI<funct3, 0b10, (outs cls:$rd), (ins SPMem:$rs1, opnd:$imm), 241 OpcodeStr, "$rd, ${imm}(${rs1})">; 242 243let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 244class CStackStore<bits<3> funct3, string OpcodeStr, 245 RegisterClass cls, DAGOperand opnd> 246 : RVInst16CSS<funct3, 0b10, (outs), (ins cls:$rs2, SPMem:$rs1, opnd:$imm), 247 OpcodeStr, "$rs2, ${imm}(${rs1})">; 248 249let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in 250class CLoad_ri<bits<3> funct3, string OpcodeStr, 251 RegisterClass cls, DAGOperand opnd> 252 : RVInst16CL<funct3, 0b00, (outs cls:$rd), (ins GPRCMem:$rs1, opnd:$imm), 253 OpcodeStr, "$rd, ${imm}(${rs1})">; 254 255let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 256class CStore_rri<bits<3> funct3, string OpcodeStr, 257 RegisterClass cls, DAGOperand opnd> 258 : RVInst16CS<funct3, 0b00, (outs), (ins cls:$rs2,GPRCMem:$rs1, opnd:$imm), 259 OpcodeStr, "$rs2, ${imm}(${rs1})">; 260 261let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 262class Bcz<bits<3> funct3, string OpcodeStr> 263 : RVInst16CB<funct3, 0b01, (outs), (ins GPRC:$rs1, simm9_lsb0:$imm), 264 OpcodeStr, "$rs1, $imm"> { 265 let isBranch = 1; 266 let isTerminator = 1; 267 let Inst{12} = imm{7}; 268 let Inst{11-10} = imm{3-2}; 269 let Inst{6-5} = imm{6-5}; 270 let Inst{4-3} = imm{1-0}; 271 let Inst{2} = imm{4}; 272} 273 274let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 275class Shift_right<bits<2> funct2, string OpcodeStr> 276 : RVInst16CB<0b100, 0b01, (outs GPRC:$rd), 277 (ins GPRC:$rs1, uimmlog2xlennonzero:$imm), 278 OpcodeStr, "$rs1, $imm"> { 279 let Constraints = "$rs1 = $rd"; 280 let Inst{12} = imm{5}; 281 let Inst{11-10} = funct2; 282 let Inst{6-2} = imm{4-0}; 283} 284 285let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 286class CA_ALU<bits<6> funct6, bits<2> funct2, string OpcodeStr> 287 : RVInst16CA<funct6, funct2, 0b01, (outs GPRC:$rd_wb), 288 (ins GPRC:$rd, GPRC:$rs2), OpcodeStr, "$rd, $rs2"> { 289 bits<3> rd; 290 let Constraints = "$rd = $rd_wb"; 291 let Inst{9-7} = rd; 292} 293 294//===----------------------------------------------------------------------===// 295// Instructions 296//===----------------------------------------------------------------------===// 297 298let Predicates = [HasStdExtCOrZca] in { 299 300let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Uses = [X2] in 301def C_ADDI4SPN : RVInst16CIW<0b000, 0b00, (outs GPRC:$rd), 302 (ins SP:$rs1, uimm10_lsb00nonzero:$imm), 303 "c.addi4spn", "$rd, $rs1, $imm">, 304 Sched<[WriteIALU, ReadIALU]> { 305 bits<5> rs1; 306 let Inst{12-11} = imm{5-4}; 307 let Inst{10-7} = imm{9-6}; 308 let Inst{6} = imm{2}; 309 let Inst{5} = imm{3}; 310} 311 312let Predicates = [HasStdExtCOrZcd, HasStdExtD] in 313def C_FLD : CLoad_ri<0b001, "c.fld", FPR64C, uimm8_lsb000>, 314 Sched<[WriteFLD64, ReadFMemBase]> { 315 bits<8> imm; 316 let Inst{12-10} = imm{5-3}; 317 let Inst{6-5} = imm{7-6}; 318} 319 320def C_LW : CLoad_ri<0b010, "c.lw", GPRC, uimm7_lsb00>, 321 Sched<[WriteLDW, ReadMemBase]> { 322 bits<7> imm; 323 let Inst{12-10} = imm{5-3}; 324 let Inst{6} = imm{2}; 325 let Inst{5} = imm{6}; 326} 327 328let isCodeGenOnly = 1 in 329def C_LW_INX : CLoad_ri<0b010, "c.lw", GPRF32C, uimm7_lsb00>, 330 Sched<[WriteLDW, ReadMemBase]> { 331 bits<7> imm; 332 let Inst{12-10} = imm{5-3}; 333 let Inst{6} = imm{2}; 334 let Inst{5} = imm{6}; 335} 336 337let DecoderNamespace = "RISCV32Only_", 338 Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in 339def C_FLW : CLoad_ri<0b011, "c.flw", FPR32C, uimm7_lsb00>, 340 Sched<[WriteFLD32, ReadFMemBase]> { 341 bits<7> imm; 342 let Inst{12-10} = imm{5-3}; 343 let Inst{6} = imm{2}; 344 let Inst{5} = imm{6}; 345} 346 347let Predicates = [HasStdExtCOrZca, IsRV64] in 348def C_LD : CLoad_ri<0b011, "c.ld", GPRC, uimm8_lsb000>, 349 Sched<[WriteLDD, ReadMemBase]> { 350 bits<8> imm; 351 let Inst{12-10} = imm{5-3}; 352 let Inst{6-5} = imm{7-6}; 353} 354 355let Predicates = [HasStdExtCOrZcd, HasStdExtD] in 356def C_FSD : CStore_rri<0b101, "c.fsd", FPR64C, uimm8_lsb000>, 357 Sched<[WriteFST64, ReadFStoreData, ReadFMemBase]> { 358 bits<8> imm; 359 let Inst{12-10} = imm{5-3}; 360 let Inst{6-5} = imm{7-6}; 361} 362 363def C_SW : CStore_rri<0b110, "c.sw", GPRC, uimm7_lsb00>, 364 Sched<[WriteSTW, ReadStoreData, ReadMemBase]> { 365 bits<7> imm; 366 let Inst{12-10} = imm{5-3}; 367 let Inst{6} = imm{2}; 368 let Inst{5} = imm{6}; 369} 370 371let isCodeGenOnly = 1 in 372def C_SW_INX : CStore_rri<0b110, "c.sw", GPRF32C, uimm7_lsb00>, 373 Sched<[WriteSTW, ReadStoreData, ReadMemBase]> { 374 bits<7> imm; 375 let Inst{12-10} = imm{5-3}; 376 let Inst{6} = imm{2}; 377 let Inst{5} = imm{6}; 378} 379 380let DecoderNamespace = "RISCV32Only_", 381 Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in 382def C_FSW : CStore_rri<0b111, "c.fsw", FPR32C, uimm7_lsb00>, 383 Sched<[WriteFST32, ReadFStoreData, ReadFMemBase]> { 384 bits<7> imm; 385 let Inst{12-10} = imm{5-3}; 386 let Inst{6} = imm{2}; 387 let Inst{5} = imm{6}; 388} 389 390let Predicates = [HasStdExtCOrZca, IsRV64] in 391def C_SD : CStore_rri<0b111, "c.sd", GPRC, uimm8_lsb000>, 392 Sched<[WriteSTD, ReadStoreData, ReadMemBase]> { 393 bits<8> imm; 394 let Inst{12-10} = imm{5-3}; 395 let Inst{6-5} = imm{7-6}; 396} 397 398let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 399def C_NOP : RVInst16CI<0b000, 0b01, (outs), (ins), "c.nop", "">, 400 Sched<[WriteNop]> { 401 let rd = 0; 402 let imm = 0; 403} 404 405let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 406def C_ADDI : RVInst16CI<0b000, 0b01, (outs GPRNoX0:$rd_wb), 407 (ins GPRNoX0:$rd, simm6nonzero:$imm), 408 "c.addi", "$rd, $imm">, 409 Sched<[WriteIALU, ReadIALU]> { 410 let Constraints = "$rd = $rd_wb"; 411} 412 413// Alternate syntax for c.nop. Converted to C_NOP by the assembler. 414let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0, 415 isAsmParserOnly = 1 in 416def PseudoC_ADDI_NOP : Pseudo<(outs GPRX0:$rd), (ins GPRX0:$rs1, immzero:$imm), 417 [], "c.addi", "$rd, $imm">; 418 419let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCall = 1, 420 DecoderNamespace = "RISCV32Only_", Defs = [X1], 421 Predicates = [HasStdExtCOrZca, IsRV32] in 422def C_JAL : RVInst16CJ<0b001, 0b01, (outs), (ins simm12_lsb0:$offset), 423 "c.jal", "$offset">, Sched<[WriteJal]>; 424 425let hasSideEffects = 0, mayLoad = 0, mayStore = 0, 426 Predicates = [HasStdExtCOrZca, IsRV64] in 427def C_ADDIW : RVInst16CI<0b001, 0b01, (outs GPRNoX0:$rd_wb), 428 (ins GPRNoX0:$rd, simm6:$imm), 429 "c.addiw", "$rd, $imm">, 430 Sched<[WriteIALU32, ReadIALU32]> { 431 let Constraints = "$rd = $rd_wb"; 432} 433 434let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 435def C_LI : RVInst16CI<0b010, 0b01, (outs GPRNoX0:$rd), (ins simm6:$imm), 436 "c.li", "$rd, $imm">, 437 Sched<[WriteIALU]>; 438 439let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 440def C_ADDI16SP : RVInst16CI<0b011, 0b01, (outs SP:$rd_wb), 441 (ins SP:$rd, simm10_lsb0000nonzero:$imm), 442 "c.addi16sp", "$rd, $imm">, 443 Sched<[WriteIALU, ReadIALU]> { 444 let Constraints = "$rd = $rd_wb"; 445 let Inst{12} = imm{9}; 446 let Inst{11-7} = 2; 447 let Inst{6} = imm{4}; 448 let Inst{5} = imm{6}; 449 let Inst{4-3} = imm{8-7}; 450 let Inst{2} = imm{5}; 451} 452 453let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 454def C_LUI : RVInst16CI<0b011, 0b01, (outs GPRNoX0X2:$rd), 455 (ins c_lui_imm:$imm), 456 "c.lui", "$rd, $imm">, 457 Sched<[WriteIALU]>; 458 459def C_SRLI : Shift_right<0b00, "c.srli">, 460 Sched<[WriteShiftImm, ReadShiftImm]>; 461def C_SRAI : Shift_right<0b01, "c.srai">, 462 Sched<[WriteShiftImm, ReadShiftImm]>; 463 464let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 465def C_ANDI : RVInst16CB<0b100, 0b01, (outs GPRC:$rd), (ins GPRC:$rs1, simm6:$imm), 466 "c.andi", "$rs1, $imm">, 467 Sched<[WriteIALU, ReadIALU]> { 468 let Constraints = "$rs1 = $rd"; 469 let Inst{12} = imm{5}; 470 let Inst{11-10} = 0b10; 471 let Inst{6-2} = imm{4-0}; 472} 473 474def C_SUB : CA_ALU<0b100011, 0b00, "c.sub">, 475 Sched<[WriteIALU, ReadIALU, ReadIALU]>; 476def C_XOR : CA_ALU<0b100011, 0b01, "c.xor">, 477 Sched<[WriteIALU, ReadIALU, ReadIALU]>; 478def C_OR : CA_ALU<0b100011, 0b10, "c.or">, 479 Sched<[WriteIALU, ReadIALU, ReadIALU]>; 480def C_AND : CA_ALU<0b100011, 0b11, "c.and">, 481 Sched<[WriteIALU, ReadIALU, ReadIALU]>; 482 483let Predicates = [HasStdExtCOrZca, IsRV64] in { 484def C_SUBW : CA_ALU<0b100111, 0b00, "c.subw">, 485 Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>; 486def C_ADDW : CA_ALU<0b100111, 0b01, "c.addw">, 487 Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>; 488} 489 490let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 491def C_J : RVInst16CJ<0b101, 0b01, (outs), (ins simm12_lsb0:$offset), 492 "c.j", "$offset">, Sched<[WriteJmp]> { 493 let isBranch = 1; 494 let isTerminator=1; 495 let isBarrier=1; 496} 497 498def C_BEQZ : Bcz<0b110, "c.beqz">, Sched<[WriteJmp, ReadJmp]>; 499def C_BNEZ : Bcz<0b111, "c.bnez">, Sched<[WriteJmp, ReadJmp]>; 500 501let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 502def C_SLLI : RVInst16CI<0b000, 0b10, (outs GPRNoX0:$rd_wb), 503 (ins GPRNoX0:$rd, uimmlog2xlennonzero:$imm), 504 "c.slli", "$rd, $imm">, 505 Sched<[WriteShiftImm, ReadShiftImm]> { 506 let Constraints = "$rd = $rd_wb"; 507} 508 509let Predicates = [HasStdExtCOrZcd, HasStdExtD] in 510def C_FLDSP : CStackLoad<0b001, "c.fldsp", FPR64, uimm9_lsb000>, 511 Sched<[WriteFLD64, ReadFMemBase]> { 512 let Inst{4-2} = imm{8-6}; 513} 514 515def C_LWSP : CStackLoad<0b010, "c.lwsp", GPRNoX0, uimm8_lsb00>, 516 Sched<[WriteLDW, ReadMemBase]> { 517 let Inst{3-2} = imm{7-6}; 518} 519 520let isCodeGenOnly = 1 in 521def C_LWSP_INX : CStackLoad<0b010, "c.lwsp", GPRF32NoX0, uimm8_lsb00>, 522 Sched<[WriteLDW, ReadMemBase]> { 523 let Inst{3-2} = imm{7-6}; 524} 525 526let DecoderNamespace = "RISCV32Only_", 527 Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in 528def C_FLWSP : CStackLoad<0b011, "c.flwsp", FPR32, uimm8_lsb00>, 529 Sched<[WriteFLD32, ReadFMemBase]> { 530 let Inst{3-2} = imm{7-6}; 531} 532 533let Predicates = [HasStdExtCOrZca, IsRV64] in 534def C_LDSP : CStackLoad<0b011, "c.ldsp", GPRNoX0, uimm9_lsb000>, 535 Sched<[WriteLDD, ReadMemBase]> { 536 let Inst{4-2} = imm{8-6}; 537} 538 539let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 540def C_JR : RVInst16CR<0b1000, 0b10, (outs), (ins GPRNoX0:$rs1), 541 "c.jr", "$rs1">, Sched<[WriteJalr, ReadJalr]> { 542 let isBarrier = 1; 543 let isTerminator = 1; 544 let rs2 = 0; 545} 546 547let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isMoveReg = 1, 548 isAsCheapAsAMove = 1 in 549def C_MV : RVInst16CR<0b1000, 0b10, (outs GPRNoX0:$rs1), (ins GPRNoX0:$rs2), 550 "c.mv", "$rs1, $rs2">, 551 Sched<[WriteIALU, ReadIALU]>; 552 553let rs1 = 0, rs2 = 0, hasSideEffects = 1, mayLoad = 0, mayStore = 0 in 554def C_EBREAK : RVInst16CR<0b1001, 0b10, (outs), (ins), "c.ebreak", "">, Sched<[]>; 555 556let hasSideEffects = 0, mayLoad = 0, mayStore = 0, 557 isCall=1, Defs=[X1], rs2 = 0 in 558def C_JALR : RVInst16CR<0b1001, 0b10, (outs), (ins GPRNoX0:$rs1), 559 "c.jalr", "$rs1">, Sched<[WriteJalr, ReadJalr]>; 560 561let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 562def C_ADD : RVInst16CR<0b1001, 0b10, (outs GPRNoX0:$rd), 563 (ins GPRNoX0:$rs1, GPRNoX0:$rs2), 564 "c.add", "$rs1, $rs2">, 565 Sched<[WriteIALU, ReadIALU, ReadIALU]> { 566 let Constraints = "$rs1 = $rd"; 567} 568 569let Predicates = [HasStdExtCOrZcd, HasStdExtD] in 570def C_FSDSP : CStackStore<0b101, "c.fsdsp", FPR64, uimm9_lsb000>, 571 Sched<[WriteFST64, ReadFStoreData, ReadFMemBase]> { 572 let Inst{9-7} = imm{8-6}; 573} 574 575def C_SWSP : CStackStore<0b110, "c.swsp", GPR, uimm8_lsb00>, 576 Sched<[WriteSTW, ReadStoreData, ReadMemBase]> { 577 let Inst{8-7} = imm{7-6}; 578} 579 580let isCodeGenOnly = 1 in 581def C_SWSP_INX : CStackStore<0b110, "c.swsp", GPRF32, uimm8_lsb00>, 582 Sched<[WriteSTW, ReadStoreData, ReadMemBase]> { 583 let Inst{8-7} = imm{7-6}; 584} 585 586let DecoderNamespace = "RISCV32Only_", 587 Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in 588def C_FSWSP : CStackStore<0b111, "c.fswsp", FPR32, uimm8_lsb00>, 589 Sched<[WriteFST32, ReadFStoreData, ReadFMemBase]> { 590 let Inst{8-7} = imm{7-6}; 591} 592 593let Predicates = [HasStdExtCOrZca, IsRV64] in 594def C_SDSP : CStackStore<0b111, "c.sdsp", GPR, uimm9_lsb000>, 595 Sched<[WriteSTD, ReadStoreData, ReadMemBase]> { 596 let Inst{9-7} = imm{8-6}; 597} 598 599// The all zeros pattern isn't a valid RISC-V instruction. It's used by GNU 600// binutils as 16-bit instruction known to be unimplemented (i.e., trapping). 601let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in 602def C_UNIMP : RVInst16<(outs), (ins), "c.unimp", "", [], InstFormatOther>, 603 Sched<[]> { 604 let Inst{15-0} = 0; 605} 606 607} // Predicates = [HasStdExtCOrZca] 608 609//===----------------------------------------------------------------------===// 610// HINT Instructions 611//===----------------------------------------------------------------------===// 612 613let Predicates = [HasStdExtCOrZca, HasRVCHints], hasSideEffects = 0, mayLoad = 0, 614 mayStore = 0 in { 615 616def C_NOP_HINT : RVInst16CI<0b000, 0b01, (outs), (ins simm6nonzero:$imm), 617 "c.nop", "$imm">, Sched<[WriteNop]> { 618 let rd = 0; 619} 620 621def C_ADDI_HINT_IMM_ZERO : RVInst16CI<0b000, 0b01, (outs GPRNoX0:$rd_wb), 622 (ins GPRNoX0:$rd, immzero:$imm), 623 "c.addi", "$rd, $imm">, 624 Sched<[WriteIALU, ReadIALU]> { 625 let Constraints = "$rd = $rd_wb"; 626 let imm = 0; 627 let DecoderMethod = "decodeRVCInstrRdRs1ImmZero"; 628} 629 630def C_LI_HINT : RVInst16CI<0b010, 0b01, (outs GPRX0:$rd), (ins simm6:$imm), 631 "c.li", "$rd, $imm">, 632 Sched<[WriteIALU]> { 633 let Inst{11-7} = 0; 634 let DecoderMethod = "decodeRVCInstrRdSImm"; 635} 636 637def C_LUI_HINT : RVInst16CI<0b011, 0b01, (outs GPRX0:$rd), 638 (ins c_lui_imm:$imm), 639 "c.lui", "$rd, $imm">, 640 Sched<[WriteIALU]> { 641 let Inst{11-7} = 0; 642 let DecoderMethod = "decodeRVCInstrRdSImm"; 643} 644 645def C_MV_HINT : RVInst16CR<0b1000, 0b10, (outs GPRX0:$rs1), (ins GPRNoX0:$rs2), 646 "c.mv", "$rs1, $rs2">, Sched<[WriteIALU, ReadIALU]> { 647 let Inst{11-7} = 0; 648 let DecoderMethod = "decodeRVCInstrRdRs2"; 649} 650 651def C_ADD_HINT : RVInst16CR<0b1001, 0b10, (outs GPRX0:$rd), 652 (ins GPRX0:$rs1, GPRNoX0:$rs2), 653 "c.add", "$rs1, $rs2">, 654 Sched<[WriteIALU, ReadIALU, ReadIALU]> { 655 let Constraints = "$rs1 = $rd"; 656 let Inst{11-7} = 0; 657 let DecoderMethod = "decodeRVCInstrRdRs1Rs2"; 658} 659 660def C_SLLI_HINT : RVInst16CI<0b000, 0b10, (outs GPRX0:$rd_wb), 661 (ins GPRX0:$rd, uimmlog2xlennonzero:$imm), 662 "c.slli", "$rd, $imm">, 663 Sched<[WriteShiftImm, ReadShiftImm]> { 664 let Constraints = "$rd = $rd_wb"; 665 let Inst{11-7} = 0; 666 let DecoderMethod = "decodeRVCInstrRdRs1UImm"; 667} 668 669def C_SLLI64_HINT : RVInst16CI<0b000, 0b10, (outs GPR:$rd_wb), (ins GPR:$rd), 670 "c.slli64", "$rd">, 671 Sched<[WriteShiftImm, ReadShiftImm]> { 672 let Constraints = "$rd = $rd_wb"; 673 let imm = 0; 674} 675 676def C_SRLI64_HINT : RVInst16CB<0b100, 0b01, (outs GPRC:$rd), 677 (ins GPRC:$rs1), 678 "c.srli64", "$rs1">, 679 Sched<[WriteShiftImm, ReadShiftImm]> { 680 let Constraints = "$rs1 = $rd"; 681 let Inst{6-2} = 0; 682 let Inst{11-10} = 0b00; 683 let Inst{12} = 0; 684} 685 686def C_SRAI64_HINT : RVInst16CB<0b100, 0b01, (outs GPRC:$rd), 687 (ins GPRC:$rs1), 688 "c.srai64", "$rs1">, 689 Sched<[WriteShiftImm, ReadShiftImm]> { 690 let Constraints = "$rs1 = $rd"; 691 let Inst{6-2} = 0; 692 let Inst{11-10} = 0b01; 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 873let isCompressOnly = true in 874def : CompressPat<(LW_INX GPRF32C:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm), 875 (C_LW_INX GPRF32C:$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 897let isCompressOnly = true in 898def : CompressPat<(SW_INX GPRF32C:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm), 899 (C_SW_INX GPRF32C:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm)>; 900} // Predicates = [HasStdExtCOrZca] 901 902let Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in { 903def : CompressPat<(FSW FPR32C:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm), 904 (C_FSW FPR32C:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm)>; 905} // Predicates = [HasStdExtC, HasStdExtF, IsRV32] 906 907let Predicates = [HasStdExtCOrZca, IsRV64] in { 908def : CompressPat<(SD GPRC:$rs2, GPRCMem:$rs1, uimm8_lsb000:$imm), 909 (C_SD GPRC:$rs2, GPRCMem:$rs1, uimm8_lsb000:$imm)>; 910} // Predicates = [HasStdExtCOrZca, IsRV64] 911 912// Quadrant 1 913let Predicates = [HasStdExtCOrZca] in { 914def : CompressPat<(ADDI X0, X0, 0), (C_NOP)>; 915def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs1, simm6nonzero:$imm), 916 (C_ADDI GPRNoX0:$rs1, simm6nonzero:$imm)>; 917} // Predicates = [HasStdExtCOrZca] 918 919let Predicates = [HasStdExtCOrZca, IsRV32] in { 920def : CompressPat<(JAL X1, simm12_lsb0:$offset), 921 (C_JAL simm12_lsb0:$offset)>; 922} // Predicates = [HasStdExtCOrZca, IsRV32] 923 924let Predicates = [HasStdExtCOrZca, IsRV64] in { 925def : CompressPat<(ADDIW GPRNoX0:$rs1, GPRNoX0:$rs1, simm6:$imm), 926 (C_ADDIW GPRNoX0:$rs1, simm6:$imm)>; 927} // Predicates = [HasStdExtCOrZca, IsRV64] 928 929let Predicates = [HasStdExtCOrZca] in { 930def : CompressPat<(ADDI GPRNoX0:$rd, X0, simm6:$imm), 931 (C_LI GPRNoX0:$rd, simm6:$imm)>; 932def : CompressPat<(ADDI X2, X2, simm10_lsb0000nonzero:$imm), 933 (C_ADDI16SP X2, simm10_lsb0000nonzero:$imm)>; 934def : CompressPat<(LUI GPRNoX0X2:$rd, c_lui_imm:$imm), 935 (C_LUI GPRNoX0X2:$rd, c_lui_imm:$imm)>; 936def : CompressPat<(SRLI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm), 937 (C_SRLI GPRC:$rs1, uimmlog2xlennonzero:$imm)>; 938def : CompressPat<(SRAI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm), 939 (C_SRAI GPRC:$rs1, uimmlog2xlennonzero:$imm)>; 940def : CompressPat<(ANDI GPRC:$rs1, GPRC:$rs1, simm6:$imm), 941 (C_ANDI GPRC:$rs1, simm6:$imm)>; 942def : CompressPat<(SUB GPRC:$rs1, GPRC:$rs1, GPRC:$rs2), 943 (C_SUB GPRC:$rs1, GPRC:$rs2)>; 944def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2), 945 (C_XOR GPRC:$rs1, GPRC:$rs2)>; 946let isCompressOnly = true in 947def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1), 948 (C_XOR GPRC:$rs1, GPRC:$rs2)>; 949def : CompressPat<(OR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2), 950 (C_OR GPRC:$rs1, GPRC:$rs2)>; 951let isCompressOnly = true in 952def : CompressPat<(OR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1), 953 (C_OR GPRC:$rs1, GPRC:$rs2)>; 954def : CompressPat<(AND GPRC:$rs1, GPRC:$rs1, GPRC:$rs2), 955 (C_AND GPRC:$rs1, GPRC:$rs2)>; 956let isCompressOnly = true in 957def : CompressPat<(AND GPRC:$rs1, GPRC:$rs2, GPRC:$rs1), 958 (C_AND GPRC:$rs1, GPRC:$rs2)>; 959} // Predicates = [HasStdExtCOrZca] 960 961let Predicates = [HasStdExtCOrZca, IsRV64] in { 962let isCompressOnly = true in 963def : CompressPat<(ADDIW GPRNoX0:$rd, X0, simm6:$imm), 964 (C_LI GPRNoX0:$rd, simm6:$imm)>; 965def : CompressPat<(SUBW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2), 966 (C_SUBW GPRC:$rs1, GPRC:$rs2)>; 967def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2), 968 (C_ADDW GPRC:$rs1, GPRC:$rs2)>; 969let isCompressOnly = true in 970def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs2, GPRC:$rs1), 971 (C_ADDW GPRC:$rs1, GPRC:$rs2)>; 972} // Predicates = [HasStdExtCOrZca, IsRV64] 973 974let Predicates = [HasStdExtCOrZca] in { 975def : CompressPat<(JAL X0, simm12_lsb0:$offset), 976 (C_J simm12_lsb0:$offset)>; 977def : CompressPat<(BEQ GPRC:$rs1, X0, simm9_lsb0:$imm), 978 (C_BEQZ GPRC:$rs1, simm9_lsb0:$imm)>; 979let isCompressOnly = true in 980def : CompressPat<(BEQ X0, GPRC:$rs1, simm9_lsb0:$imm), 981 (C_BEQZ GPRC:$rs1, simm9_lsb0:$imm)>; 982def : CompressPat<(BNE GPRC:$rs1, X0, simm9_lsb0:$imm), 983 (C_BNEZ GPRC:$rs1, simm9_lsb0:$imm)>; 984let isCompressOnly = true in 985def : CompressPat<(BNE X0, GPRC:$rs1, simm9_lsb0:$imm), 986 (C_BNEZ GPRC:$rs1, simm9_lsb0:$imm)>; 987} // Predicates = [HasStdExtCOrZca] 988 989// Quadrant 2 990let Predicates = [HasStdExtCOrZca] in { 991def : CompressPat<(SLLI GPRNoX0:$rs1, GPRNoX0:$rs1, uimmlog2xlennonzero:$imm), 992 (C_SLLI GPRNoX0:$rs1, uimmlog2xlennonzero:$imm)>; 993} // Predicates = [HasStdExtCOrZca] 994 995let Predicates = [HasStdExtCOrZcd, HasStdExtD] in { 996def : CompressPat<(FLD FPR64:$rd, SPMem:$rs1, uimm9_lsb000:$imm), 997 (C_FLDSP FPR64:$rd, SPMem:$rs1, uimm9_lsb000:$imm)>; 998} // Predicates = [HasStdExtCOrZcd, HasStdExtD] 999 1000let Predicates = [HasStdExtCOrZca] in { 1001def : CompressPat<(LW GPRNoX0:$rd, SPMem:$rs1, uimm8_lsb00:$imm), 1002 (C_LWSP GPRNoX0:$rd, SPMem:$rs1, uimm8_lsb00:$imm)>; 1003 1004let isCompressOnly = true in 1005def : CompressPat<(LW_INX GPRF32NoX0:$rd, SPMem:$rs1, uimm8_lsb00:$imm), 1006 (C_LWSP_INX GPRF32NoX0:$rd, SPMem:$rs1, uimm8_lsb00:$imm)>; 1007} // Predicates = [HasStdExtCOrZca] 1008 1009let Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in { 1010def : CompressPat<(FLW FPR32:$rd, SPMem:$rs1, uimm8_lsb00:$imm), 1011 (C_FLWSP FPR32:$rd, SPMem:$rs1, uimm8_lsb00:$imm)>; 1012} // Predicates = [HasStdExtC, HasStdExtF, IsRV32] 1013 1014let Predicates = [HasStdExtCOrZca, IsRV64] in { 1015def : CompressPat<(LD GPRNoX0:$rd, SPMem:$rs1, uimm9_lsb000:$imm), 1016 (C_LDSP GPRNoX0:$rd, SPMem:$rs1, uimm9_lsb000:$imm)>; 1017} // Predicates = [HasStdExtCOrZca, IsRV64] 1018 1019let Predicates = [HasStdExtCOrZca] in { 1020def : CompressPat<(JALR X0, GPRNoX0:$rs1, 0), 1021 (C_JR GPRNoX0:$rs1)>; 1022let isCompressOnly = true in { 1023def : CompressPat<(ADD GPRNoX0:$rs1, X0, GPRNoX0:$rs2), 1024 (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>; 1025def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, X0), 1026 (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>; 1027} 1028def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs2, 0), 1029 (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>; 1030def : CompressPat<(EBREAK), (C_EBREAK)>; 1031def : CompressPat<(UNIMP), (C_UNIMP)>; 1032def : CompressPat<(JALR X1, GPRNoX0:$rs1, 0), 1033 (C_JALR GPRNoX0:$rs1)>; 1034def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs1, GPRNoX0:$rs2), 1035 (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>; 1036let isCompressOnly = true in 1037def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, GPRNoX0:$rs1), 1038 (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>; 1039} // Predicates = [HasStdExtCOrZca] 1040 1041let Predicates = [HasStdExtCOrZcd, HasStdExtD] in { 1042def : CompressPat<(FSD FPR64:$rs2, SPMem:$rs1, uimm9_lsb000:$imm), 1043 (C_FSDSP FPR64:$rs2, SPMem:$rs1, uimm9_lsb000:$imm)>; 1044} // Predicates = [HasStdExtCOrZcd, HasStdExtD] 1045 1046let Predicates = [HasStdExtCOrZca] in { 1047def : CompressPat<(SW GPR:$rs2, SPMem:$rs1, uimm8_lsb00:$imm), 1048 (C_SWSP GPR:$rs2, SPMem:$rs1, uimm8_lsb00:$imm)>; 1049 1050let isCompressOnly = true in 1051def : CompressPat<(SW_INX GPRF32:$rs2, SPMem:$rs1, uimm8_lsb00:$imm), 1052 (C_SWSP_INX GPRF32:$rs2, SPMem:$rs1, uimm8_lsb00:$imm)>; 1053} // Predicates = [HasStdExtCOrZca] 1054 1055let Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in { 1056def : CompressPat<(FSW FPR32:$rs2, SPMem:$rs1, uimm8_lsb00:$imm), 1057 (C_FSWSP FPR32:$rs2, SPMem:$rs1, uimm8_lsb00:$imm)>; 1058} // Predicates = [HasStdExtC, HasStdExtF, IsRV32] 1059 1060let Predicates = [HasStdExtCOrZca, IsRV64] in { 1061def : CompressPat<(SD GPR:$rs2, SPMem:$rs1, uimm9_lsb000:$imm), 1062 (C_SDSP GPR:$rs2, SPMem:$rs1, uimm9_lsb000:$imm)>; 1063} // Predicates = [HasStdExtCOrZca, IsRV64] 1064