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