1//===- RISCVInstrInfoC.td - Compressed RISCV 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 = "decodeUImmOperand<6>"; 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 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isInt<6>(Imm);}]> { 40 let ParserMatchClass = SImmAsmOperand<6>; 41 let EncoderMethod = "getImmOpValue"; 42 let DecoderMethod = "decodeSImmOperand<6>"; 43 let MCOperandPredicate = [{ 44 int64_t Imm; 45 if (MCOp.evaluateAsConstantImm(Imm)) 46 return isInt<6>(Imm); 47 return MCOp.isBareSymbolRef(); 48 }]; 49} 50 51def simm6nonzero : Operand<XLenVT>, 52 ImmLeaf<XLenVT, [{return (Imm != 0) && isInt<6>(Imm);}]> { 53 let ParserMatchClass = SImmAsmOperand<6, "NonZero">; 54 let EncoderMethod = "getImmOpValue"; 55 let DecoderMethod = "decodeSImmOperand<6>"; 56 let MCOperandPredicate = [{ 57 int64_t Imm; 58 if (MCOp.evaluateAsConstantImm(Imm)) 59 return (Imm != 0) && isInt<6>(Imm); 60 return MCOp.isBareSymbolRef(); 61 }]; 62} 63 64def immzero : Operand<XLenVT>, 65 ImmLeaf<XLenVT, [{return (Imm == 0);}]> { 66 let ParserMatchClass = ImmZeroAsmOperand; 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 : Operand<XLenVT>, 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 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 : Operand<XLenVT>, 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 MCOperandPredicate = [{ 104 int64_t Imm; 105 if (!MCOp.evaluateAsConstantImm(Imm)) 106 return false; 107 return isShiftedUInt<5, 2>(Imm); 108 }]; 109} 110 111// A 8-bit unsigned immediate where the least significant two bits are zero. 112def uimm8_lsb00 : Operand<XLenVT>, 113 ImmLeaf<XLenVT, [{return isShiftedUInt<6, 2>(Imm);}]> { 114 let ParserMatchClass = UImmAsmOperand<8, "Lsb00">; 115 let EncoderMethod = "getImmOpValue"; 116 let DecoderMethod = "decodeUImmOperand<8>"; 117 let MCOperandPredicate = [{ 118 int64_t Imm; 119 if (!MCOp.evaluateAsConstantImm(Imm)) 120 return false; 121 return isShiftedUInt<6, 2>(Imm); 122 }]; 123} 124 125// A 8-bit unsigned immediate where the least significant three bits are zero. 126def uimm8_lsb000 : Operand<XLenVT>, 127 ImmLeaf<XLenVT, [{return isShiftedUInt<5, 3>(Imm);}]> { 128 let ParserMatchClass = UImmAsmOperand<8, "Lsb000">; 129 let EncoderMethod = "getImmOpValue"; 130 let DecoderMethod = "decodeUImmOperand<8>"; 131 let MCOperandPredicate = [{ 132 int64_t Imm; 133 if (!MCOp.evaluateAsConstantImm(Imm)) 134 return false; 135 return isShiftedUInt<5, 3>(Imm); 136 }]; 137} 138 139// A 9-bit signed immediate where the least significant bit is zero. 140def simm9_lsb0 : Operand<OtherVT>, 141 ImmLeaf<XLenVT, [{return isShiftedInt<8, 1>(Imm);}]> { 142 let ParserMatchClass = SImmAsmOperand<9, "Lsb0">; 143 let PrintMethod = "printBranchOperand"; 144 let EncoderMethod = "getImmOpValueAsr1"; 145 let DecoderMethod = "decodeSImmOperandAndLsl1<9>"; 146 let MCOperandPredicate = [{ 147 int64_t Imm; 148 if (MCOp.evaluateAsConstantImm(Imm)) 149 return isShiftedInt<8, 1>(Imm); 150 return MCOp.isBareSymbolRef(); 151 152 }]; 153 let OperandType = "OPERAND_PCREL"; 154} 155 156// A 9-bit unsigned immediate where the least significant three bits are zero. 157def uimm9_lsb000 : Operand<XLenVT>, 158 ImmLeaf<XLenVT, [{return isShiftedUInt<6, 3>(Imm);}]> { 159 let ParserMatchClass = UImmAsmOperand<9, "Lsb000">; 160 let EncoderMethod = "getImmOpValue"; 161 let DecoderMethod = "decodeUImmOperand<9>"; 162 let MCOperandPredicate = [{ 163 int64_t Imm; 164 if (!MCOp.evaluateAsConstantImm(Imm)) 165 return false; 166 return isShiftedUInt<6, 3>(Imm); 167 }]; 168} 169 170// A 10-bit unsigned immediate where the least significant two bits are zero 171// and the immediate can't be zero. 172def uimm10_lsb00nonzero : Operand<XLenVT>, 173 ImmLeaf<XLenVT, 174 [{return isShiftedUInt<8, 2>(Imm) && (Imm != 0);}]> { 175 let ParserMatchClass = UImmAsmOperand<10, "Lsb00NonZero">; 176 let EncoderMethod = "getImmOpValue"; 177 let DecoderMethod = "decodeUImmNonZeroOperand<10>"; 178 let MCOperandPredicate = [{ 179 int64_t Imm; 180 if (!MCOp.evaluateAsConstantImm(Imm)) 181 return false; 182 return isShiftedUInt<8, 2>(Imm) && (Imm != 0); 183 }]; 184} 185 186// A 10-bit signed immediate where the least significant four bits are zero. 187def simm10_lsb0000nonzero : Operand<XLenVT>, 188 ImmLeaf<XLenVT, 189 [{return (Imm != 0) && isShiftedInt<6, 4>(Imm);}]> { 190 let ParserMatchClass = SImmAsmOperand<10, "Lsb0000NonZero">; 191 let EncoderMethod = "getImmOpValue"; 192 let DecoderMethod = "decodeSImmNonZeroOperand<10>"; 193 let MCOperandPredicate = [{ 194 int64_t Imm; 195 if (!MCOp.evaluateAsConstantImm(Imm)) 196 return false; 197 return isShiftedInt<6, 4>(Imm) && (Imm != 0); 198 }]; 199} 200 201// A 12-bit signed immediate where the least significant bit is zero. 202def simm12_lsb0 : Operand<XLenVT>, 203 ImmLeaf<XLenVT, [{return isShiftedInt<11, 1>(Imm);}]> { 204 let ParserMatchClass = SImmAsmOperand<12, "Lsb0">; 205 let PrintMethod = "printBranchOperand"; 206 let EncoderMethod = "getImmOpValueAsr1"; 207 let DecoderMethod = "decodeSImmOperandAndLsl1<12>"; 208 let MCOperandPredicate = [{ 209 int64_t Imm; 210 if (MCOp.evaluateAsConstantImm(Imm)) 211 return isShiftedInt<11, 1>(Imm); 212 return MCOp.isBareSymbolRef(); 213 }]; 214 let OperandType = "OPERAND_PCREL"; 215} 216 217//===----------------------------------------------------------------------===// 218// Instruction Class Templates 219//===----------------------------------------------------------------------===// 220 221let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in 222class CStackLoad<bits<3> funct3, string OpcodeStr, 223 RegisterClass cls, DAGOperand opnd> 224 : RVInst16CI<funct3, 0b10, (outs cls:$rd), (ins SP:$rs1, opnd:$imm), 225 OpcodeStr, "$rd, ${imm}(${rs1})">; 226 227let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 228class CStackStore<bits<3> funct3, string OpcodeStr, 229 RegisterClass cls, DAGOperand opnd> 230 : RVInst16CSS<funct3, 0b10, (outs), (ins cls:$rs2, SP:$rs1, opnd:$imm), 231 OpcodeStr, "$rs2, ${imm}(${rs1})">; 232 233let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in 234class CLoad_ri<bits<3> funct3, string OpcodeStr, 235 RegisterClass cls, DAGOperand opnd> 236 : RVInst16CL<funct3, 0b00, (outs cls:$rd), (ins GPRC:$rs1, opnd:$imm), 237 OpcodeStr, "$rd, ${imm}(${rs1})">; 238 239let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 240class CStore_rri<bits<3> funct3, string OpcodeStr, 241 RegisterClass cls, DAGOperand opnd> 242 : RVInst16CS<funct3, 0b00, (outs), (ins cls:$rs2, GPRC:$rs1, opnd:$imm), 243 OpcodeStr, "$rs2, ${imm}(${rs1})">; 244 245let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 246class Bcz<bits<3> funct3, string OpcodeStr, 247 RegisterClass cls> 248 : RVInst16CB<funct3, 0b01, (outs), (ins cls:$rs1, simm9_lsb0:$imm), 249 OpcodeStr, "$rs1, $imm"> { 250 let isBranch = 1; 251 let isTerminator = 1; 252 let Inst{12} = imm{7}; 253 let Inst{11-10} = imm{3-2}; 254 let Inst{6-5} = imm{6-5}; 255 let Inst{4-3} = imm{1-0}; 256 let Inst{2} = imm{4}; 257} 258 259let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 260class Shift_right<bits<2> funct2, string OpcodeStr, RegisterClass cls, 261 Operand ImmOpnd> 262 : RVInst16CB<0b100, 0b01, (outs cls:$rs1_wb), (ins cls:$rs1, ImmOpnd:$imm), 263 OpcodeStr, "$rs1, $imm"> { 264 let Constraints = "$rs1 = $rs1_wb"; 265 let Inst{12} = imm{5}; 266 let Inst{11-10} = funct2; 267 let Inst{6-2} = imm{4-0}; 268} 269 270let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 271class CS_ALU<bits<6> funct6, bits<2> funct2, string OpcodeStr, 272 RegisterClass cls> 273 : RVInst16CA<funct6, funct2, 0b01, (outs cls:$rd_wb), (ins cls:$rd, cls:$rs2), 274 OpcodeStr, "$rd, $rs2"> { 275 bits<3> rd; 276 let Constraints = "$rd = $rd_wb"; 277 let Inst{9-7} = rd; 278} 279 280//===----------------------------------------------------------------------===// 281// Instructions 282//===----------------------------------------------------------------------===// 283 284let Predicates = [HasStdExtC] in { 285 286let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Uses = [X2] in 287def C_ADDI4SPN : RVInst16CIW<0b000, 0b00, (outs GPRC:$rd), 288 (ins SP:$rs1, uimm10_lsb00nonzero:$imm), 289 "c.addi4spn", "$rd, $rs1, $imm">, 290 Sched<[WriteIALU, ReadIALU]> { 291 bits<5> rs1; 292 let Inst{12-11} = imm{5-4}; 293 let Inst{10-7} = imm{9-6}; 294 let Inst{6} = imm{2}; 295 let Inst{5} = imm{3}; 296} 297 298let Predicates = [HasStdExtC, HasStdExtD] in 299def C_FLD : CLoad_ri<0b001, "c.fld", FPR64C, uimm8_lsb000>, 300 Sched<[WriteFLD64, ReadMemBase]> { 301 bits<8> imm; 302 let Inst{12-10} = imm{5-3}; 303 let Inst{6-5} = imm{7-6}; 304} 305 306def C_LW : CLoad_ri<0b010, "c.lw", GPRC, uimm7_lsb00>, 307 Sched<[WriteLDW, ReadMemBase]> { 308 bits<7> imm; 309 let Inst{12-10} = imm{5-3}; 310 let Inst{6} = imm{2}; 311 let Inst{5} = imm{6}; 312} 313 314let DecoderNamespace = "RISCV32Only_", 315 Predicates = [HasStdExtC, HasStdExtF, IsRV32] in 316def C_FLW : CLoad_ri<0b011, "c.flw", FPR32C, uimm7_lsb00>, 317 Sched<[WriteFLD32, ReadMemBase]> { 318 bits<7> imm; 319 let Inst{12-10} = imm{5-3}; 320 let Inst{6} = imm{2}; 321 let Inst{5} = imm{6}; 322} 323 324let Predicates = [HasStdExtC, IsRV64] in 325def C_LD : CLoad_ri<0b011, "c.ld", GPRC, uimm8_lsb000>, 326 Sched<[WriteLDD, ReadMemBase]> { 327 bits<8> imm; 328 let Inst{12-10} = imm{5-3}; 329 let Inst{6-5} = imm{7-6}; 330} 331 332let Predicates = [HasStdExtC, HasStdExtD] in 333def C_FSD : CStore_rri<0b101, "c.fsd", FPR64C, uimm8_lsb000>, 334 Sched<[WriteFST64, ReadStoreData, ReadMemBase]> { 335 bits<8> imm; 336 let Inst{12-10} = imm{5-3}; 337 let Inst{6-5} = imm{7-6}; 338} 339 340def C_SW : CStore_rri<0b110, "c.sw", GPRC, uimm7_lsb00>, 341 Sched<[WriteSTW, ReadStoreData, ReadMemBase]> { 342 bits<7> imm; 343 let Inst{12-10} = imm{5-3}; 344 let Inst{6} = imm{2}; 345 let Inst{5} = imm{6}; 346} 347 348let DecoderNamespace = "RISCV32Only_", 349 Predicates = [HasStdExtC, HasStdExtF, IsRV32] in 350def C_FSW : CStore_rri<0b111, "c.fsw", FPR32C, uimm7_lsb00>, 351 Sched<[WriteFST32, ReadStoreData, ReadMemBase]> { 352 bits<7> imm; 353 let Inst{12-10} = imm{5-3}; 354 let Inst{6} = imm{2}; 355 let Inst{5} = imm{6}; 356} 357 358let Predicates = [HasStdExtC, IsRV64] in 359def C_SD : CStore_rri<0b111, "c.sd", GPRC, uimm8_lsb000>, 360 Sched<[WriteSTD, ReadStoreData, ReadMemBase]> { 361 bits<8> imm; 362 let Inst{12-10} = imm{5-3}; 363 let Inst{6-5} = imm{7-6}; 364} 365 366let rd = 0, imm = 0, hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 367def C_NOP : RVInst16CI<0b000, 0b01, (outs), (ins), "c.nop", "">, 368 Sched<[WriteNop]> 369{ 370 let Inst{6-2} = 0; 371} 372 373let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 374def C_ADDI : RVInst16CI<0b000, 0b01, (outs GPRNoX0:$rd_wb), 375 (ins GPRNoX0:$rd, simm6nonzero:$imm), 376 "c.addi", "$rd, $imm">, 377 Sched<[WriteIALU, ReadIALU]> { 378 let Constraints = "$rd = $rd_wb"; 379 let Inst{6-2} = imm{4-0}; 380} 381 382let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 383def C_ADDI_NOP : RVInst16CI<0b000, 0b01, (outs GPRX0:$rd_wb), 384 (ins GPRX0:$rd, immzero:$imm), 385 "c.addi", "$rd, $imm">, 386 Sched<[WriteIALU, ReadIALU]> { 387 let Constraints = "$rd = $rd_wb"; 388 let Inst{6-2} = 0; 389 let isAsmParserOnly = 1; 390} 391 392let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCall = 1, 393 DecoderNamespace = "RISCV32Only_", Defs = [X1], 394 Predicates = [HasStdExtC, IsRV32] in 395def C_JAL : RVInst16CJ<0b001, 0b01, (outs), (ins simm12_lsb0:$offset), 396 "c.jal", "$offset">, Sched<[WriteJal]>; 397 398let hasSideEffects = 0, mayLoad = 0, mayStore = 0, 399 Predicates = [HasStdExtC, IsRV64] in 400def C_ADDIW : RVInst16CI<0b001, 0b01, (outs GPRNoX0:$rd_wb), 401 (ins GPRNoX0:$rd, simm6:$imm), 402 "c.addiw", "$rd, $imm">, 403 Sched<[WriteIALU32, ReadIALU32]> { 404 let Constraints = "$rd = $rd_wb"; 405 let Inst{6-2} = imm{4-0}; 406} 407 408let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 409def C_LI : RVInst16CI<0b010, 0b01, (outs GPRNoX0:$rd), (ins simm6:$imm), 410 "c.li", "$rd, $imm">, 411 Sched<[WriteIALU]> { 412 let Inst{6-2} = imm{4-0}; 413} 414 415let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 416def C_ADDI16SP : RVInst16CI<0b011, 0b01, (outs SP:$rd_wb), 417 (ins SP:$rd, simm10_lsb0000nonzero:$imm), 418 "c.addi16sp", "$rd, $imm">, 419 Sched<[WriteIALU, ReadIALU]> { 420 let Constraints = "$rd = $rd_wb"; 421 let Inst{12} = imm{9}; 422 let Inst{11-7} = 2; 423 let Inst{6} = imm{4}; 424 let Inst{5} = imm{6}; 425 let Inst{4-3} = imm{8-7}; 426 let Inst{2} = imm{5}; 427} 428 429let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 430def C_LUI : RVInst16CI<0b011, 0b01, (outs GPRNoX0X2:$rd), 431 (ins c_lui_imm:$imm), 432 "c.lui", "$rd, $imm">, 433 Sched<[WriteIALU]> { 434 let Inst{6-2} = imm{4-0}; 435} 436 437def C_SRLI : Shift_right<0b00, "c.srli", GPRC, uimmlog2xlennonzero>, 438 Sched<[WriteShiftImm, ReadShiftImm]>; 439def C_SRAI : Shift_right<0b01, "c.srai", GPRC, uimmlog2xlennonzero>, 440 Sched<[WriteShiftImm, ReadShiftImm]>; 441 442let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 443def C_ANDI : RVInst16CB<0b100, 0b01, (outs GPRC:$rs1_wb), (ins GPRC:$rs1, simm6:$imm), 444 "c.andi", "$rs1, $imm">, 445 Sched<[WriteIALU, ReadIALU]> { 446 let Constraints = "$rs1 = $rs1_wb"; 447 let Inst{12} = imm{5}; 448 let Inst{11-10} = 0b10; 449 let Inst{6-2} = imm{4-0}; 450} 451 452def C_SUB : CS_ALU<0b100011, 0b00, "c.sub", GPRC>, 453 Sched<[WriteIALU, ReadIALU, ReadIALU]>; 454def C_XOR : CS_ALU<0b100011, 0b01, "c.xor", GPRC>, 455 Sched<[WriteIALU, ReadIALU, ReadIALU]>; 456def C_OR : CS_ALU<0b100011, 0b10, "c.or" , GPRC>, 457 Sched<[WriteIALU, ReadIALU, ReadIALU]>; 458def C_AND : CS_ALU<0b100011, 0b11, "c.and", GPRC>, 459 Sched<[WriteIALU, ReadIALU, ReadIALU]>; 460 461let Predicates = [HasStdExtC, IsRV64] in { 462def C_SUBW : CS_ALU<0b100111, 0b00, "c.subw", GPRC>, 463 Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>; 464def C_ADDW : CS_ALU<0b100111, 0b01, "c.addw", GPRC>, 465 Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>; 466} 467 468let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 469def C_J : RVInst16CJ<0b101, 0b01, (outs), (ins simm12_lsb0:$offset), 470 "c.j", "$offset">, Sched<[WriteJmp]> { 471 let isBranch = 1; 472 let isTerminator=1; 473 let isBarrier=1; 474} 475 476def C_BEQZ : Bcz<0b110, "c.beqz", GPRC>, Sched<[WriteJmp]>; 477def C_BNEZ : Bcz<0b111, "c.bnez", GPRC>, Sched<[WriteJmp]>; 478 479let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 480def C_SLLI : RVInst16CI<0b000, 0b10, (outs GPRNoX0:$rd_wb), 481 (ins GPRNoX0:$rd, uimmlog2xlennonzero:$imm), 482 "c.slli", "$rd, $imm">, 483 Sched<[WriteShiftImm, ReadShiftImm]> { 484 let Constraints = "$rd = $rd_wb"; 485 let Inst{6-2} = imm{4-0}; 486} 487 488let Predicates = [HasStdExtC, HasStdExtD] in 489def C_FLDSP : CStackLoad<0b001, "c.fldsp", FPR64, uimm9_lsb000>, 490 Sched<[WriteFLD64, ReadMemBase]> { 491 let Inst{6-5} = imm{4-3}; 492 let Inst{4-2} = imm{8-6}; 493} 494 495def C_LWSP : CStackLoad<0b010, "c.lwsp", GPRNoX0, uimm8_lsb00>, 496 Sched<[WriteLDW, ReadMemBase]> { 497 let Inst{6-4} = imm{4-2}; 498 let Inst{3-2} = imm{7-6}; 499} 500 501let DecoderNamespace = "RISCV32Only_", 502 Predicates = [HasStdExtC, HasStdExtF, IsRV32] in 503def C_FLWSP : CStackLoad<0b011, "c.flwsp", FPR32, uimm8_lsb00>, 504 Sched<[WriteFLD32, ReadMemBase]> { 505 let Inst{6-4} = imm{4-2}; 506 let Inst{3-2} = imm{7-6}; 507} 508 509let Predicates = [HasStdExtC, IsRV64] in 510def C_LDSP : CStackLoad<0b011, "c.ldsp", GPRNoX0, uimm9_lsb000>, 511 Sched<[WriteLDD, ReadMemBase]> { 512 let Inst{6-5} = imm{4-3}; 513 let Inst{4-2} = imm{8-6}; 514} 515 516let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 517def C_JR : RVInst16CR<0b1000, 0b10, (outs), (ins GPRNoX0:$rs1), 518 "c.jr", "$rs1">, Sched<[WriteJmpReg]> { 519 let isBranch = 1; 520 let isBarrier = 1; 521 let isTerminator = 1; 522 let isIndirectBranch = 1; 523 let rs2 = 0; 524} 525 526let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isMoveReg = 1, 527 isAsCheapAsAMove = 1 in 528def C_MV : RVInst16CR<0b1000, 0b10, (outs GPRNoX0:$rs1), (ins GPRNoX0:$rs2), 529 "c.mv", "$rs1, $rs2">, 530 Sched<[WriteIALU, ReadIALU]>; 531 532let rs1 = 0, rs2 = 0, hasSideEffects = 1, mayLoad = 0, mayStore = 0 in 533def C_EBREAK : RVInst16CR<0b1001, 0b10, (outs), (ins), "c.ebreak", "">, Sched<[]>; 534 535let hasSideEffects = 0, mayLoad = 0, mayStore = 0, 536 isCall=1, Defs=[X1], rs2 = 0 in 537def C_JALR : RVInst16CR<0b1001, 0b10, (outs), (ins GPRNoX0:$rs1), 538 "c.jalr", "$rs1">, Sched<[WriteJalr, ReadJalr]>; 539 540let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 541def C_ADD : RVInst16CR<0b1001, 0b10, (outs GPRNoX0:$rs1_wb), 542 (ins GPRNoX0:$rs1, GPRNoX0:$rs2), 543 "c.add", "$rs1, $rs2">, 544 Sched<[WriteIALU, ReadIALU, ReadIALU]> { 545 let Constraints = "$rs1 = $rs1_wb"; 546} 547 548let Predicates = [HasStdExtC, HasStdExtD] in 549def C_FSDSP : CStackStore<0b101, "c.fsdsp", FPR64, uimm9_lsb000>, 550 Sched<[WriteFST64, ReadStoreData, ReadMemBase]> { 551 let Inst{12-10} = imm{5-3}; 552 let Inst{9-7} = imm{8-6}; 553} 554 555def C_SWSP : CStackStore<0b110, "c.swsp", GPR, uimm8_lsb00>, 556 Sched<[WriteSTW, ReadStoreData, ReadMemBase]> { 557 let Inst{12-9} = imm{5-2}; 558 let Inst{8-7} = imm{7-6}; 559} 560 561let DecoderNamespace = "RISCV32Only_", 562 Predicates = [HasStdExtC, HasStdExtF, IsRV32] in 563def C_FSWSP : CStackStore<0b111, "c.fswsp", FPR32, uimm8_lsb00>, 564 Sched<[WriteFST32, ReadStoreData, ReadMemBase]> { 565 let Inst{12-9} = imm{5-2}; 566 let Inst{8-7} = imm{7-6}; 567} 568 569let Predicates = [HasStdExtC, IsRV64] in 570def C_SDSP : CStackStore<0b111, "c.sdsp", GPR, uimm9_lsb000>, 571 Sched<[WriteSTD, ReadStoreData, ReadMemBase]> { 572 let Inst{12-10} = imm{5-3}; 573 let Inst{9-7} = imm{8-6}; 574} 575 576// The all zeros pattern isn't a valid RISC-V instruction. It's used by GNU 577// binutils as 16-bit instruction known to be unimplemented (i.e., trapping). 578let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in 579def C_UNIMP : RVInst16<(outs), (ins), "c.unimp", "", [], InstFormatOther>, 580 Sched<[]> { 581 let Inst{15-0} = 0; 582} 583 584} // Predicates = [HasStdExtC] 585 586//===----------------------------------------------------------------------===// 587// HINT Instructions 588//===----------------------------------------------------------------------===// 589 590let Predicates = [HasStdExtC, HasRVCHints], hasSideEffects = 0, mayLoad = 0, 591 mayStore = 0 in 592{ 593 594let rd = 0 in 595def C_NOP_HINT : RVInst16CI<0b000, 0b01, (outs), (ins simm6nonzero:$imm), 596 "c.nop", "$imm">, Sched<[WriteNop]> { 597 let Inst{6-2} = imm{4-0}; 598 let DecoderMethod = "decodeRVCInstrSImm"; 599} 600 601// Just a different syntax for the c.nop hint: c.addi x0, simm6 vs c.nop simm6. 602def C_ADDI_HINT_X0 : RVInst16CI<0b000, 0b01, (outs GPRX0:$rd_wb), 603 (ins GPRX0:$rd, simm6nonzero:$imm), 604 "c.addi", "$rd, $imm">, 605 Sched<[WriteIALU, ReadIALU]> { 606 let Constraints = "$rd = $rd_wb"; 607 let Inst{6-2} = imm{4-0}; 608 let isAsmParserOnly = 1; 609} 610 611def C_ADDI_HINT_IMM_ZERO : RVInst16CI<0b000, 0b01, (outs GPRNoX0:$rd_wb), 612 (ins GPRNoX0:$rd, immzero:$imm), 613 "c.addi", "$rd, $imm">, 614 Sched<[WriteIALU, ReadIALU]> { 615 let Constraints = "$rd = $rd_wb"; 616 let Inst{6-2} = 0; 617 let isAsmParserOnly = 1; 618} 619 620def C_LI_HINT : RVInst16CI<0b010, 0b01, (outs GPRX0:$rd), (ins simm6:$imm), 621 "c.li", "$rd, $imm">, 622 Sched<[WriteIALU]> { 623 let Inst{6-2} = imm{4-0}; 624 let Inst{11-7} = 0; 625 let DecoderMethod = "decodeRVCInstrRdSImm"; 626} 627 628def C_LUI_HINT : RVInst16CI<0b011, 0b01, (outs GPRX0:$rd), 629 (ins c_lui_imm:$imm), 630 "c.lui", "$rd, $imm">, 631 Sched<[WriteIALU]> { 632 let Inst{6-2} = imm{4-0}; 633 let Inst{11-7} = 0; 634 let DecoderMethod = "decodeRVCInstrRdSImm"; 635} 636 637def C_MV_HINT : RVInst16CR<0b1000, 0b10, (outs GPRX0:$rs1), (ins GPRNoX0:$rs2), 638 "c.mv", "$rs1, $rs2">, Sched<[WriteIALU, ReadIALU]> 639{ 640 let Inst{11-7} = 0; 641 let DecoderMethod = "decodeRVCInstrRdRs2"; 642} 643 644def C_ADD_HINT : RVInst16CR<0b1001, 0b10, (outs GPRX0:$rs1_wb), 645 (ins GPRX0:$rs1, GPRNoX0:$rs2), 646 "c.add", "$rs1, $rs2">, 647 Sched<[WriteIALU, ReadIALU, ReadIALU]> { 648 let Constraints = "$rs1 = $rs1_wb"; 649 let Inst{11-7} = 0; 650 let DecoderMethod = "decodeRVCInstrRdRs1Rs2"; 651} 652 653def C_SLLI_HINT : RVInst16CI<0b000, 0b10, (outs GPRX0:$rd_wb), 654 (ins GPRX0:$rd, uimmlog2xlennonzero:$imm), 655 "c.slli", "$rd, $imm">, 656 Sched<[WriteShiftImm, ReadShiftImm]> { 657 let Constraints = "$rd = $rd_wb"; 658 let Inst{6-2} = imm{4-0}; 659 let Inst{11-7} = 0; 660 let DecoderMethod = "decodeRVCInstrRdRs1UImm"; 661} 662 663def C_SLLI64_HINT : RVInst16CI<0b000, 0b10, (outs GPR:$rd_wb), (ins GPR:$rd), 664 "c.slli64", "$rd">, 665 Sched<[WriteShiftImm, ReadShiftImm]> { 666 let Constraints = "$rd = $rd_wb"; 667 let Inst{6-2} = 0; 668 let Inst{12} = 0; 669} 670 671def C_SRLI64_HINT : RVInst16CI<0b100, 0b01, (outs GPRC:$rd_wb), 672 (ins GPRC:$rd), 673 "c.srli64", "$rd">, 674 Sched<[WriteShiftImm, ReadShiftImm]> { 675 let Constraints = "$rd = $rd_wb"; 676 let Inst{6-2} = 0; 677 let Inst{11-10} = 0; 678 let Inst{12} = 0; 679} 680 681def C_SRAI64_HINT : RVInst16CI<0b100, 0b01, (outs GPRC:$rd_wb), 682 (ins GPRC:$rd), 683 "c.srai64", "$rd">, 684 Sched<[WriteShiftImm, ReadShiftImm]> { 685 let Constraints = "$rd = $rd_wb"; 686 let Inst{6-2} = 0; 687 let Inst{11-10} = 1; 688 let Inst{12} = 0; 689} 690 691} // Predicates = [HasStdExtC, HasRVCHints], hasSideEffects = 0, mayLoad = 0, 692 // mayStore = 0 693 694//===----------------------------------------------------------------------===// 695// Assembler Pseudo Instructions 696//===----------------------------------------------------------------------===// 697 698let EmitPriority = 0 in { 699let Predicates = [HasStdExtC] in { 700def : InstAlias<"c.lw $rd, (${rs1})", (C_LW GPRC:$rd, GPRC:$rs1, 0)>; 701def : InstAlias<"c.sw $rs2, (${rs1})", (C_SW GPRC:$rs2, GPRC:$rs1, 0)>; 702def : InstAlias<"c.lwsp $rd, (${rs1})", (C_LWSP GPRC:$rd, SP:$rs1, 0)>; 703def : InstAlias<"c.swsp $rs2, (${rs1})", (C_SWSP GPRC:$rs2, SP:$rs1, 0)>; 704} 705 706let Predicates = [HasStdExtC, IsRV64] in { 707def : InstAlias<"c.ld $rd, (${rs1})", (C_LD GPRC:$rd, GPRC:$rs1, 0)>; 708def : InstAlias<"c.sd $rs2, (${rs1})", (C_SD GPRC:$rs2, GPRC:$rs1, 0)>; 709def : InstAlias<"c.ldsp $rd, (${rs1})", (C_LDSP GPRC:$rd, SP:$rs1, 0)>; 710def : InstAlias<"c.sdsp $rs2, (${rs1})", (C_SDSP GPRC:$rs2, SP:$rs1, 0)>; 711} 712 713let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in { 714def : InstAlias<"c.flw $rd, (${rs1})", (C_FLW FPR32C:$rd, GPRC:$rs1, 0)>; 715def : InstAlias<"c.fsw $rs2, (${rs1})", (C_FSW FPR32C:$rs2, GPRC:$rs1, 0)>; 716def : InstAlias<"c.flwsp $rd, (${rs1})", (C_FLWSP FPR32C:$rd, SP:$rs1, 0)>; 717def : InstAlias<"c.fswsp $rs2, (${rs1})", (C_FSWSP FPR32C:$rs2, SP:$rs1, 0)>; 718} 719 720let Predicates = [HasStdExtC, HasStdExtD] in { 721def : InstAlias<"c.fld $rd, (${rs1})", (C_FLD FPR64C:$rd, GPRC:$rs1, 0)>; 722def : InstAlias<"c.fsd $rs2, (${rs1})", (C_FSD FPR64C:$rs2, GPRC:$rs1, 0)>; 723def : InstAlias<"c.fldsp $rd, (${rs1})", (C_FLDSP FPR64C:$rd, SP:$rs1, 0)>; 724def : InstAlias<"c.fsdsp $rs2, (${rs1})", (C_FSDSP FPR64C:$rs2, SP:$rs1, 0)>; 725} 726} // EmitPriority = 0 727 728//===----------------------------------------------------------------------===/i 729// Compress Instruction tablegen backend. 730//===----------------------------------------------------------------------===// 731 732// Patterns are defined in the same order the compressed instructions appear 733// on page 82 of the ISA manual. 734 735// Quadrant 0 736let Predicates = [HasStdExtC] in { 737def : CompressPat<(ADDI GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm), 738 (C_ADDI4SPN GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm)>; 739} // Predicates = [HasStdExtC] 740 741let Predicates = [HasStdExtC, HasStdExtD] in { 742def : CompressPat<(FLD FPR64C:$rd, GPRC:$rs1, uimm8_lsb000:$imm), 743 (C_FLD FPR64C:$rd, GPRC:$rs1, uimm8_lsb000:$imm)>; 744} // Predicates = [HasStdExtC, HasStdExtD] 745 746let Predicates = [HasStdExtC] in { 747def : CompressPat<(LW GPRC:$rd, GPRC:$rs1, uimm7_lsb00:$imm), 748 (C_LW GPRC:$rd, GPRC:$rs1, uimm7_lsb00:$imm)>; 749} // Predicates = [HasStdExtC] 750 751let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in { 752def : CompressPat<(FLW FPR32C:$rd, GPRC:$rs1, uimm7_lsb00:$imm), 753 (C_FLW FPR32C:$rd, GPRC:$rs1, uimm7_lsb00:$imm)>; 754} // Predicates = [HasStdExtC, HasStdExtF, IsRV32] 755 756let Predicates = [HasStdExtC, IsRV64] in { 757def : CompressPat<(LD GPRC:$rd, GPRC:$rs1, uimm8_lsb000:$imm), 758 (C_LD GPRC:$rd, GPRC:$rs1, uimm8_lsb000:$imm)>; 759} // Predicates = [HasStdExtC, IsRV64] 760 761let Predicates = [HasStdExtC, HasStdExtD] in { 762def : CompressPat<(FSD FPR64C:$rs2, GPRC:$rs1, uimm8_lsb000:$imm), 763 (C_FSD FPR64C:$rs2, GPRC:$rs1, uimm8_lsb000:$imm)>; 764} // Predicates = [HasStdExtC, HasStdExtD] 765 766let Predicates = [HasStdExtC] in { 767def : CompressPat<(SW GPRC:$rs2, GPRC:$rs1, uimm7_lsb00:$imm), 768 (C_SW GPRC:$rs2, GPRC:$rs1, uimm7_lsb00:$imm)>; 769} // Predicates = [HasStdExtC] 770 771let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in { 772def : CompressPat<(FSW FPR32C:$rs2, GPRC:$rs1, uimm7_lsb00:$imm), 773 (C_FSW FPR32C:$rs2, GPRC:$rs1, uimm7_lsb00:$imm)>; 774} // Predicates = [HasStdExtC, HasStdExtF, IsRV32] 775 776let Predicates = [HasStdExtC, IsRV64] in { 777def : CompressPat<(SD GPRC:$rs2, GPRC:$rs1, uimm8_lsb000:$imm), 778 (C_SD GPRC:$rs2, GPRC:$rs1, uimm8_lsb000:$imm)>; 779} // Predicates = [HasStdExtC, IsRV64] 780 781// Quadrant 1 782let Predicates = [HasStdExtC] in { 783def : CompressPat<(ADDI X0, X0, 0), (C_NOP)>; 784def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs1, simm6nonzero:$imm), 785 (C_ADDI GPRNoX0:$rs1, simm6nonzero:$imm)>; 786} // Predicates = [HasStdExtC] 787 788let Predicates = [HasStdExtC, IsRV32] in { 789def : CompressPat<(JAL X1, simm12_lsb0:$offset), 790 (C_JAL simm12_lsb0:$offset)>; 791} // Predicates = [HasStdExtC, IsRV32] 792 793let Predicates = [HasStdExtC, IsRV64] in { 794def : CompressPat<(ADDIW GPRNoX0:$rs1, GPRNoX0:$rs1, simm6:$imm), 795 (C_ADDIW GPRNoX0:$rs1, simm6:$imm)>; 796} // Predicates = [HasStdExtC, IsRV64] 797 798let Predicates = [HasStdExtC] in { 799def : CompressPat<(ADDI GPRNoX0:$rd, X0, simm6:$imm), 800 (C_LI GPRNoX0:$rd, simm6:$imm)>; 801def : CompressPat<(ADDI X2, X2, simm10_lsb0000nonzero:$imm), 802 (C_ADDI16SP X2, simm10_lsb0000nonzero:$imm)>; 803def : CompressPat<(LUI GPRNoX0X2:$rd, c_lui_imm:$imm), 804 (C_LUI GPRNoX0X2:$rd, c_lui_imm:$imm)>; 805def : CompressPat<(SRLI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm), 806 (C_SRLI GPRC:$rs1, uimmlog2xlennonzero:$imm)>; 807def : CompressPat<(SRAI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm), 808 (C_SRAI GPRC:$rs1, uimmlog2xlennonzero:$imm)>; 809def : CompressPat<(ANDI GPRC:$rs1, GPRC:$rs1, simm6:$imm), 810 (C_ANDI GPRC:$rs1, simm6:$imm)>; 811def : CompressPat<(SUB GPRC:$rs1, GPRC:$rs1, GPRC:$rs2), 812 (C_SUB GPRC:$rs1, GPRC:$rs2)>; 813def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2), 814 (C_XOR GPRC:$rs1, GPRC:$rs2)>; 815let isCompressOnly = true in 816def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1), 817 (C_XOR GPRC:$rs1, GPRC:$rs2)>; 818def : CompressPat<(OR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2), 819 (C_OR GPRC:$rs1, GPRC:$rs2)>; 820let isCompressOnly = true in 821def : CompressPat<(OR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1), 822 (C_OR GPRC:$rs1, GPRC:$rs2)>; 823def : CompressPat<(AND GPRC:$rs1, GPRC:$rs1, GPRC:$rs2), 824 (C_AND GPRC:$rs1, GPRC:$rs2)>; 825let isCompressOnly = true in 826def : CompressPat<(AND GPRC:$rs1, GPRC:$rs2, GPRC:$rs1), 827 (C_AND GPRC:$rs1, GPRC:$rs2)>; 828} // Predicates = [HasStdExtC] 829 830let Predicates = [HasStdExtC, IsRV64] in { 831let isCompressOnly = true in 832def : CompressPat<(ADDIW GPRNoX0:$rd, X0, simm6:$imm), 833 (C_LI GPRNoX0:$rd, simm6:$imm)>; 834def : CompressPat<(SUBW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2), 835 (C_SUBW GPRC:$rs1, GPRC:$rs2)>; 836def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2), 837 (C_ADDW GPRC:$rs1, GPRC:$rs2)>; 838let isCompressOnly = true in 839def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs2, GPRC:$rs1), 840 (C_ADDW GPRC:$rs1, GPRC:$rs2)>; 841} // Predicates = [HasStdExtC, IsRV64] 842 843let Predicates = [HasStdExtC] in { 844def : CompressPat<(JAL X0, simm12_lsb0:$offset), 845 (C_J simm12_lsb0:$offset)>; 846def : CompressPat<(BEQ GPRC:$rs1, X0, simm9_lsb0:$imm), 847 (C_BEQZ GPRC:$rs1, simm9_lsb0:$imm)>; 848def : CompressPat<(BNE GPRC:$rs1, X0, simm9_lsb0:$imm), 849 (C_BNEZ GPRC:$rs1, simm9_lsb0:$imm)>; 850} // Predicates = [HasStdExtC] 851 852// Quadrant 2 853let Predicates = [HasStdExtC] in { 854def : CompressPat<(SLLI GPRNoX0:$rs1, GPRNoX0:$rs1, uimmlog2xlennonzero:$imm), 855 (C_SLLI GPRNoX0:$rs1, uimmlog2xlennonzero:$imm)>; 856} // Predicates = [HasStdExtC] 857 858let Predicates = [HasStdExtC, HasStdExtD] in { 859def : CompressPat<(FLD FPR64:$rd, SP:$rs1, uimm9_lsb000:$imm), 860 (C_FLDSP FPR64:$rd, SP:$rs1, uimm9_lsb000:$imm)>; 861} // Predicates = [HasStdExtC, HasStdExtD] 862 863let Predicates = [HasStdExtC] in { 864def : CompressPat<(LW GPRNoX0:$rd, SP:$rs1, uimm8_lsb00:$imm), 865 (C_LWSP GPRNoX0:$rd, SP:$rs1, uimm8_lsb00:$imm)>; 866} // Predicates = [HasStdExtC] 867 868let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in { 869def : CompressPat<(FLW FPR32:$rd, SP:$rs1, uimm8_lsb00:$imm), 870 (C_FLWSP FPR32:$rd, SP:$rs1, uimm8_lsb00:$imm)>; 871} // Predicates = [HasStdExtC, HasStdExtF, IsRV32] 872 873let Predicates = [HasStdExtC, IsRV64] in { 874def : CompressPat<(LD GPRNoX0:$rd, SP:$rs1, uimm9_lsb000:$imm), 875 (C_LDSP GPRNoX0:$rd, SP:$rs1, uimm9_lsb000:$imm)>; 876} // Predicates = [HasStdExtC, IsRV64] 877 878let Predicates = [HasStdExtC] in { 879def : CompressPat<(JALR X0, GPRNoX0:$rs1, 0), 880 (C_JR GPRNoX0:$rs1)>; 881let isCompressOnly = true in { 882def : CompressPat<(ADD GPRNoX0:$rs1, X0, GPRNoX0:$rs2), 883 (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>; 884def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, X0), 885 (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>; 886} 887def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs2, 0), 888 (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>; 889def : CompressPat<(EBREAK), (C_EBREAK)>; 890def : CompressPat<(UNIMP), (C_UNIMP)>; 891def : CompressPat<(JALR X1, GPRNoX0:$rs1, 0), 892 (C_JALR GPRNoX0:$rs1)>; 893def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs1, GPRNoX0:$rs2), 894 (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>; 895let isCompressOnly = true in 896def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, GPRNoX0:$rs1), 897 (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>; 898} // Predicates = [HasStdExtC] 899 900let Predicates = [HasStdExtC, HasStdExtD] in { 901def : CompressPat<(FSD FPR64:$rs2, SP:$rs1, uimm9_lsb000:$imm), 902 (C_FSDSP FPR64:$rs2, SP:$rs1, uimm9_lsb000:$imm)>; 903} // Predicates = [HasStdExtC, HasStdExtD] 904 905let Predicates = [HasStdExtC] in { 906def : CompressPat<(SW GPR:$rs2, SP:$rs1, uimm8_lsb00:$imm), 907 (C_SWSP GPR:$rs2, SP:$rs1, uimm8_lsb00:$imm)>; 908} // Predicates = [HasStdExtC] 909 910let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in { 911def : CompressPat<(FSW FPR32:$rs2, SP:$rs1, uimm8_lsb00:$imm), 912 (C_FSWSP FPR32:$rs2, SP:$rs1, uimm8_lsb00:$imm)>; 913} // Predicates = [HasStdExtC, HasStdExtF, IsRV32] 914 915let Predicates = [HasStdExtC, IsRV64] in { 916def : CompressPat<(SD GPR:$rs2, SP:$rs1, uimm9_lsb000:$imm), 917 (C_SDSP GPR:$rs2, SP:$rs1, uimm9_lsb000:$imm)>; 918} // Predicates = [HasStdExtC, IsRV64] 919