1 //===- RISCVInstrInfoC.td - Compressed RISCV instructions -*- tblgen-*-----===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 include "RISCVInstrFormatsC.td" 11 12 //===----------------------------------------------------------------------===// 13 // Operand definitions. 14 //===----------------------------------------------------------------------===// 15 16 def UImmLog2XLenNonZeroAsmOperand : AsmOperandClass { 17 let Name = "UImmLog2XLenNonZero"; 18 let RenderMethod = "addImmOperands"; 19 let DiagnosticType = "InvalidUImmLog2XLenNonZero"; 20 } 21 22 def uimmlog2xlennonzero : Operand<XLenVT>, ImmLeaf<XLenVT, [{ 23 if (Subtarget->is64Bit()) 24 return isUInt<6>(Imm) && (Imm != 0); 25 return isUInt<5>(Imm) && (Imm != 0); 26 }]> { 27 let ParserMatchClass = UImmLog2XLenNonZeroAsmOperand; 28 // TODO: should ensure invalid shamt is rejected when decoding. 29 let DecoderMethod = "decodeUImmOperand<6>"; 30 let MCOperandPredicate = [{ 31 int64_t Imm; 32 if (!MCOp.evaluateAsConstantImm(Imm)) 33 return false; 34 if (STI.getTargetTriple().isArch64Bit()) 35 return isUInt<6>(Imm) && (Imm != 0); 36 return isUInt<5>(Imm) && (Imm != 0); 37 }]; 38 } 39 40 def simm6 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isInt<6>(Imm);}]> { 41 let ParserMatchClass = SImmAsmOperand<6>; 42 let EncoderMethod = "getImmOpValue"; 43 let DecoderMethod = "decodeSImmOperand<6>"; 44 let MCOperandPredicate = [{ 45 int64_t Imm; 46 if (MCOp.evaluateAsConstantImm(Imm)) 47 return isInt<6>(Imm); 48 return MCOp.isBareSymbolRef(); 49 }]; 50 } 51 52 def simm6nonzero : Operand<XLenVT>, 53 ImmLeaf<XLenVT, [{return (Imm != 0) && isInt<6>(Imm);}]> { 54 let ParserMatchClass = SImmAsmOperand<6, "NonZero">; 55 let EncoderMethod = "getImmOpValue"; 56 let DecoderMethod = "decodeSImmOperand<6>"; 57 let MCOperandPredicate = [{ 58 int64_t Imm; 59 if (MCOp.evaluateAsConstantImm(Imm)) 60 return (Imm != 0) && isInt<6>(Imm); 61 return MCOp.isBareSymbolRef(); 62 }]; 63 } 64 65 def CLUIImmAsmOperand : AsmOperandClass { 66 let Name = "CLUIImm"; 67 let RenderMethod = "addImmOperands"; 68 let DiagnosticType = !strconcat("Invalid", Name); 69 } 70 71 72 // c_lui_imm checks the immediate range is in [1, 31] or [0xfffe0, 0xfffff]. 73 // The RISC-V ISA describes the constraint as [1, 63], with that value being 74 // loaded in to bits 17-12 of the destination register and sign extended from 75 // bit 17. Therefore, this 6-bit immediate can represent values in the ranges 76 // [1, 31] and [0xfffe0, 0xfffff]. 77 def c_lui_imm : Operand<XLenVT>, 78 ImmLeaf<XLenVT, [{return (Imm != 0) && 79 (isUInt<5>(Imm) || 80 (Imm >= 0xfffe0 && Imm <= 0xfffff));}]> { 81 let ParserMatchClass = CLUIImmAsmOperand; 82 let EncoderMethod = "getImmOpValue"; 83 let DecoderMethod = "decodeCLUIImmOperand"; 84 let MCOperandPredicate = [{ 85 int64_t Imm; 86 if (MCOp.evaluateAsConstantImm(Imm)) 87 return (Imm != 0) && (isUInt<5>(Imm) || 88 (Imm >= 0xfffe0 && Imm <= 0xfffff)); 89 return MCOp.isBareSymbolRef(); 90 }]; 91 } 92 93 // A 7-bit unsigned immediate where the least significant two bits are zero. 94 def uimm7_lsb00 : Operand<XLenVT>, 95 ImmLeaf<XLenVT, [{return isShiftedUInt<5, 2>(Imm);}]> { 96 let ParserMatchClass = UImmAsmOperand<7, "Lsb00">; 97 let EncoderMethod = "getImmOpValue"; 98 let DecoderMethod = "decodeUImmOperand<7>"; 99 let MCOperandPredicate = [{ 100 int64_t Imm; 101 if (!MCOp.evaluateAsConstantImm(Imm)) 102 return false; 103 return isShiftedUInt<5, 2>(Imm); 104 }]; 105 } 106 107 // A 8-bit unsigned immediate where the least significant two bits are zero. 108 def uimm8_lsb00 : Operand<XLenVT>, 109 ImmLeaf<XLenVT, [{return isShiftedUInt<6, 2>(Imm);}]> { 110 let ParserMatchClass = UImmAsmOperand<8, "Lsb00">; 111 let EncoderMethod = "getImmOpValue"; 112 let DecoderMethod = "decodeUImmOperand<8>"; 113 let MCOperandPredicate = [{ 114 int64_t Imm; 115 if (!MCOp.evaluateAsConstantImm(Imm)) 116 return false; 117 return isShiftedUInt<6, 2>(Imm); 118 }]; 119 } 120 121 // A 8-bit unsigned immediate where the least significant three bits are zero. 122 def uimm8_lsb000 : Operand<XLenVT>, 123 ImmLeaf<XLenVT, [{return isShiftedUInt<5, 3>(Imm);}]> { 124 let ParserMatchClass = UImmAsmOperand<8, "Lsb000">; 125 let EncoderMethod = "getImmOpValue"; 126 let DecoderMethod = "decodeUImmOperand<8>"; 127 let MCOperandPredicate = [{ 128 int64_t Imm; 129 if (!MCOp.evaluateAsConstantImm(Imm)) 130 return false; 131 return isShiftedUInt<5, 3>(Imm); 132 }]; 133 } 134 135 // A 9-bit signed immediate where the least significant bit is zero. 136 def simm9_lsb0 : Operand<OtherVT> { 137 let ParserMatchClass = SImmAsmOperand<9, "Lsb0">; 138 let EncoderMethod = "getImmOpValueAsr1"; 139 let DecoderMethod = "decodeSImmOperandAndLsl1<9>"; 140 let MCOperandPredicate = [{ 141 int64_t Imm; 142 if (MCOp.evaluateAsConstantImm(Imm)) 143 return isShiftedInt<8, 1>(Imm); 144 return MCOp.isBareSymbolRef(); 145 146 }]; 147 } 148 149 // A 9-bit unsigned immediate where the least significant three bits are zero. 150 def uimm9_lsb000 : Operand<XLenVT>, 151 ImmLeaf<XLenVT, [{return isShiftedUInt<6, 3>(Imm);}]> { 152 let ParserMatchClass = UImmAsmOperand<9, "Lsb000">; 153 let EncoderMethod = "getImmOpValue"; 154 let DecoderMethod = "decodeUImmOperand<9>"; 155 let MCOperandPredicate = [{ 156 int64_t Imm; 157 if (!MCOp.evaluateAsConstantImm(Imm)) 158 return false; 159 return isShiftedUInt<6, 3>(Imm); 160 }]; 161 } 162 163 // A 10-bit unsigned immediate where the least significant two bits are zero 164 // and the immediate can't be zero. 165 def uimm10_lsb00nonzero : Operand<XLenVT>, 166 ImmLeaf<XLenVT, 167 [{return isShiftedUInt<8, 2>(Imm) && (Imm != 0);}]> { 168 let ParserMatchClass = UImmAsmOperand<10, "Lsb00NonZero">; 169 let EncoderMethod = "getImmOpValue"; 170 let DecoderMethod = "decodeUImmOperand<10>"; 171 let MCOperandPredicate = [{ 172 int64_t Imm; 173 if (!MCOp.evaluateAsConstantImm(Imm)) 174 return false; 175 return isShiftedUInt<8, 2>(Imm) && (Imm != 0); 176 }]; 177 } 178 179 // A 10-bit signed immediate where the least significant four bits are zero. 180 def simm10_lsb0000nonzero : Operand<XLenVT>, 181 ImmLeaf<XLenVT, 182 [{return (Imm != 0) && isShiftedInt<6, 4>(Imm);}]> { 183 let ParserMatchClass = SImmAsmOperand<10, "Lsb0000NonZero">; 184 let EncoderMethod = "getImmOpValue"; 185 let DecoderMethod = "decodeSImmOperand<10>"; 186 let MCOperandPredicate = [{ 187 int64_t Imm; 188 if (!MCOp.evaluateAsConstantImm(Imm)) 189 return false; 190 return isShiftedInt<6, 4>(Imm); 191 }]; 192 } 193 194 // A 12-bit signed immediate where the least significant bit is zero. 195 def simm12_lsb0 : Operand<XLenVT> { 196 let ParserMatchClass = SImmAsmOperand<12, "Lsb0">; 197 let EncoderMethod = "getImmOpValueAsr1"; 198 let DecoderMethod = "decodeSImmOperandAndLsl1<12>"; 199 let MCOperandPredicate = [{ 200 int64_t Imm; 201 if (MCOp.evaluateAsConstantImm(Imm)) 202 return isShiftedInt<11, 1>(Imm); 203 return MCOp.isBareSymbolRef(); 204 }]; 205 } 206 207 //===----------------------------------------------------------------------===// 208 // Instruction Class Templates 209 //===----------------------------------------------------------------------===// 210 211 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in 212 class CStackLoad<bits<3> funct3, string OpcodeStr, 213 RegisterClass cls, DAGOperand opnd> 214 : RVInst16CI<funct3, 0b10, (outs cls:$rd), (ins SP:$rs1, opnd:$imm), 215 OpcodeStr, "$rd, ${imm}(${rs1})">; 216 217 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 218 class CStackStore<bits<3> funct3, string OpcodeStr, 219 RegisterClass cls, DAGOperand opnd> 220 : RVInst16CSS<funct3, 0b10, (outs), (ins cls:$rs2, SP:$rs1, opnd:$imm), 221 OpcodeStr, "$rs2, ${imm}(${rs1})">; 222 223 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in 224 class CLoad_ri<bits<3> funct3, string OpcodeStr, 225 RegisterClass cls, DAGOperand opnd> 226 : RVInst16CL<funct3, 0b00, (outs cls:$rd), (ins GPRC:$rs1, opnd:$imm), 227 OpcodeStr, "$rd, ${imm}(${rs1})">; 228 229 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 230 class CStore_rri<bits<3> funct3, string OpcodeStr, 231 RegisterClass cls, DAGOperand opnd> 232 : RVInst16CS<funct3, 0b00, (outs), (ins cls:$rs2, GPRC:$rs1, opnd:$imm), 233 OpcodeStr, "$rs2, ${imm}(${rs1})">; 234 235 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 236 class Bcz<bits<3> funct3, string OpcodeStr, PatFrag CondOp, 237 RegisterClass cls> 238 : RVInst16CB<funct3, 0b01, (outs), (ins cls:$rs1, simm9_lsb0:$imm), 239 OpcodeStr, "$rs1, $imm"> { 240 let isBranch = 1; 241 let isTerminator = 1; 242 let Inst{12} = imm{7}; 243 let Inst{11-10} = imm{3-2}; 244 let Inst{6-5} = imm{6-5}; 245 let Inst{4-3} = imm{1-0}; 246 let Inst{2} = imm{4}; 247 } 248 249 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 250 class Shift_right<bits<2> funct2, string OpcodeStr, RegisterClass cls, 251 Operand ImmOpnd> 252 : RVInst16CB<0b100, 0b01, (outs cls:$rs1_wb), (ins cls:$rs1, ImmOpnd:$imm), 253 OpcodeStr, "$rs1, $imm"> { 254 let Constraints = "$rs1 = $rs1_wb"; 255 let Inst{12} = imm{5}; 256 let Inst{11-10} = funct2; 257 let Inst{6-2} = imm{4-0}; 258 } 259 260 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 261 class CS_ALU<bits<2> funct2, string OpcodeStr, RegisterClass cls, 262 bit RV64only> 263 : RVInst16CS<0b100, 0b01, (outs cls:$rd_wb), (ins cls:$rd, cls:$rs2), 264 OpcodeStr, "$rd, $rs2"> { 265 bits<3> rd; 266 let Constraints = "$rd = $rd_wb"; 267 let Inst{12} = RV64only; 268 let Inst{11-10} = 0b11; 269 let Inst{9-7} = rd; 270 let Inst{6-5} = funct2; 271 } 272 273 //===----------------------------------------------------------------------===// 274 // Instructions 275 //===----------------------------------------------------------------------===// 276 277 let Predicates = [HasStdExtC] in { 278 279 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Uses = [X2] in 280 def C_ADDI4SPN : RVInst16CIW<0b000, 0b00, (outs GPRC:$rd), 281 (ins SP:$rs1, uimm10_lsb00nonzero:$imm), 282 "c.addi4spn", "$rd, $rs1, $imm"> { 283 bits<5> rs1; 284 let Inst{12-11} = imm{5-4}; 285 let Inst{10-7} = imm{9-6}; 286 let Inst{6} = imm{2}; 287 let Inst{5} = imm{3}; 288 } 289 290 let Predicates = [HasStdExtC, HasStdExtD] in 291 def C_FLD : CLoad_ri<0b001, "c.fld", FPR64C, uimm8_lsb000> { 292 bits<8> imm; 293 let Inst{12-10} = imm{5-3}; 294 let Inst{6-5} = imm{7-6}; 295 } 296 297 def C_LW : CLoad_ri<0b010, "c.lw", GPRC, uimm7_lsb00> { 298 bits<7> imm; 299 let Inst{12-10} = imm{5-3}; 300 let Inst{6} = imm{2}; 301 let Inst{5} = imm{6}; 302 } 303 304 let DecoderNamespace = "RISCV32Only_", 305 Predicates = [HasStdExtC, HasStdExtF, IsRV32] in 306 def C_FLW : CLoad_ri<0b011, "c.flw", FPR32C, uimm7_lsb00> { 307 bits<7> imm; 308 let Inst{12-10} = imm{5-3}; 309 let Inst{6} = imm{2}; 310 let Inst{5} = imm{6}; 311 } 312 313 let Predicates = [HasStdExtC, IsRV64] in 314 def C_LD : CLoad_ri<0b011, "c.ld", GPRC, uimm8_lsb000> { 315 bits<8> imm; 316 let Inst{12-10} = imm{5-3}; 317 let Inst{6-5} = imm{7-6}; 318 } 319 320 let Predicates = [HasStdExtC, HasStdExtD] in 321 def C_FSD : CStore_rri<0b101, "c.fsd", FPR64C, uimm8_lsb000> { 322 bits<8> imm; 323 let Inst{12-10} = imm{5-3}; 324 let Inst{6-5} = imm{7-6}; 325 } 326 327 def C_SW : CStore_rri<0b110, "c.sw", GPRC, uimm7_lsb00> { 328 bits<7> imm; 329 let Inst{12-10} = imm{5-3}; 330 let Inst{6} = imm{2}; 331 let Inst{5} = imm{6}; 332 } 333 334 let DecoderNamespace = "RISCV32Only_", 335 Predicates = [HasStdExtC, HasStdExtF, IsRV32] in 336 def C_FSW : CStore_rri<0b111, "c.fsw", FPR32C, uimm7_lsb00> { 337 bits<7> imm; 338 let Inst{12-10} = imm{5-3}; 339 let Inst{6} = imm{2}; 340 let Inst{5} = imm{6}; 341 } 342 343 let Predicates = [HasStdExtC, IsRV64] in 344 def C_SD : CStore_rri<0b111, "c.sd", GPRC, uimm8_lsb000> { 345 bits<8> imm; 346 let Inst{12-10} = imm{5-3}; 347 let Inst{6-5} = imm{7-6}; 348 } 349 350 let rd = 0, imm = 0, hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 351 def C_NOP : RVInst16CI<0b000, 0b01, (outs), (ins), "c.nop", "">; 352 353 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 354 def C_ADDI : RVInst16CI<0b000, 0b01, (outs GPRNoX0:$rd_wb), 355 (ins GPRNoX0:$rd, simm6nonzero:$imm), 356 "c.addi", "$rd, $imm"> { 357 let Constraints = "$rd = $rd_wb"; 358 let Inst{6-2} = imm{4-0}; 359 } 360 361 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCall = 1, 362 DecoderNamespace = "RISCV32Only_", Defs = [X1], 363 Predicates = [HasStdExtC, IsRV32] in 364 def C_JAL : RVInst16CJ<0b001, 0b01, (outs), (ins simm12_lsb0:$offset), 365 "c.jal", "$offset">; 366 367 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, 368 Predicates = [HasStdExtC, IsRV64] in 369 def C_ADDIW : RVInst16CI<0b001, 0b01, (outs GPRNoX0:$rd_wb), 370 (ins GPRNoX0:$rd, simm6:$imm), 371 "c.addiw", "$rd, $imm"> { 372 let Constraints = "$rd = $rd_wb"; 373 let Inst{6-2} = imm{4-0}; 374 } 375 376 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 377 def C_LI : RVInst16CI<0b010, 0b01, (outs GPRNoX0:$rd), (ins simm6:$imm), 378 "c.li", "$rd, $imm"> { 379 let Inst{6-2} = imm{4-0}; 380 } 381 382 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 383 def C_ADDI16SP : RVInst16CI<0b011, 0b01, (outs SP:$rd_wb), 384 (ins SP:$rd, simm10_lsb0000nonzero:$imm), 385 "c.addi16sp", "$rd, $imm"> { 386 let Constraints = "$rd = $rd_wb"; 387 let Inst{12} = imm{9}; 388 let Inst{11-7} = 2; 389 let Inst{6} = imm{4}; 390 let Inst{5} = imm{6}; 391 let Inst{4-3} = imm{8-7}; 392 let Inst{2} = imm{5}; 393 } 394 395 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 396 def C_LUI : RVInst16CI<0b011, 0b01, (outs GPRNoX0X2:$rd), 397 (ins c_lui_imm:$imm), 398 "c.lui", "$rd, $imm"> { 399 let Inst{6-2} = imm{4-0}; 400 } 401 402 def C_SRLI : Shift_right<0b00, "c.srli", GPRC, uimmlog2xlennonzero>; 403 def C_SRAI : Shift_right<0b01, "c.srai", GPRC, uimmlog2xlennonzero>; 404 405 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 406 def C_ANDI : RVInst16CB<0b100, 0b01, (outs GPRC:$rs1_wb), (ins GPRC:$rs1, simm6:$imm), 407 "c.andi", "$rs1, $imm"> { 408 let Constraints = "$rs1 = $rs1_wb"; 409 let Inst{12} = imm{5}; 410 let Inst{11-10} = 0b10; 411 let Inst{6-2} = imm{4-0}; 412 } 413 414 def C_SUB : CS_ALU<0b00, "c.sub", GPRC, 0>; 415 def C_XOR : CS_ALU<0b01, "c.xor", GPRC, 0>; 416 def C_OR : CS_ALU<0b10, "c.or" , GPRC, 0>; 417 def C_AND : CS_ALU<0b11, "c.and", GPRC, 0>; 418 419 let Predicates = [HasStdExtC, IsRV64] in { 420 def C_SUBW : CS_ALU<0b00, "c.subw", GPRC, 1>; 421 def C_ADDW : CS_ALU<0b01, "c.addw", GPRC, 1>; 422 } 423 424 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 425 def C_J : RVInst16CJ<0b101, 0b01, (outs), (ins simm12_lsb0:$offset), 426 "c.j", "$offset"> { 427 let isBranch = 1; 428 let isTerminator=1; 429 let isBarrier=1; 430 } 431 432 def C_BEQZ : Bcz<0b110, "c.beqz", seteq, GPRC>; 433 def C_BNEZ : Bcz<0b111, "c.bnez", setne, GPRC>; 434 435 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 436 def C_SLLI : RVInst16CI<0b000, 0b10, (outs GPRNoX0:$rd_wb), 437 (ins GPRNoX0:$rd, uimmlog2xlennonzero:$imm), 438 "c.slli" ,"$rd, $imm"> { 439 let Constraints = "$rd = $rd_wb"; 440 let Inst{6-2} = imm{4-0}; 441 } 442 443 let Predicates = [HasStdExtC, HasStdExtD] in 444 def C_FLDSP : CStackLoad<0b001, "c.fldsp", FPR64, uimm9_lsb000> { 445 let Inst{6-5} = imm{4-3}; 446 let Inst{4-2} = imm{8-6}; 447 } 448 449 def C_LWSP : CStackLoad<0b010, "c.lwsp", GPRNoX0, uimm8_lsb00> { 450 let Inst{6-4} = imm{4-2}; 451 let Inst{3-2} = imm{7-6}; 452 } 453 454 let DecoderNamespace = "RISCV32Only_", 455 Predicates = [HasStdExtC, HasStdExtF, IsRV32] in 456 def C_FLWSP : CStackLoad<0b011, "c.flwsp", FPR32, uimm8_lsb00> { 457 let Inst{6-4} = imm{4-2}; 458 let Inst{3-2} = imm{7-6}; 459 } 460 461 let Predicates = [HasStdExtC, IsRV64] in 462 def C_LDSP : CStackLoad<0b011, "c.ldsp", GPRNoX0, uimm9_lsb000> { 463 let Inst{6-5} = imm{4-3}; 464 let Inst{4-2} = imm{8-6}; 465 } 466 467 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 468 def C_JR : RVInst16CR<0b1000, 0b10, (outs), (ins GPRNoX0:$rs1), 469 "c.jr", "$rs1"> { 470 let isBranch = 1; 471 let isBarrier = 1; 472 let isTerminator = 1; 473 let isIndirectBranch = 1; 474 let rs2 = 0; 475 } 476 477 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 478 def C_MV : RVInst16CR<0b1000, 0b10, (outs GPRNoX0:$rs1), (ins GPRNoX0:$rs2), 479 "c.mv", "$rs1, $rs2">; 480 481 let rs1 = 0, rs2 = 0, hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 482 def C_EBREAK : RVInst16CR<0b1001, 0b10, (outs), (ins), "c.ebreak", "">; 483 484 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, 485 isCall=1, Defs=[X1], rs2 = 0 in 486 def C_JALR : RVInst16CR<0b1001, 0b10, (outs), (ins GPRNoX0:$rs1), 487 "c.jalr", "$rs1">; 488 489 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 490 def C_ADD : RVInst16CR<0b1001, 0b10, (outs GPRNoX0:$rs1_wb), 491 (ins GPRNoX0:$rs1, GPRNoX0:$rs2), 492 "c.add", "$rs1, $rs2"> { 493 let Constraints = "$rs1 = $rs1_wb"; 494 } 495 496 let Predicates = [HasStdExtC, HasStdExtD] in 497 def C_FSDSP : CStackStore<0b101, "c.fsdsp", FPR64, uimm9_lsb000> { 498 let Inst{12-10} = imm{5-3}; 499 let Inst{9-7} = imm{8-6}; 500 } 501 502 def C_SWSP : CStackStore<0b110, "c.swsp", GPR, uimm8_lsb00> { 503 let Inst{12-9} = imm{5-2}; 504 let Inst{8-7} = imm{7-6}; 505 } 506 507 let DecoderNamespace = "RISCV32Only_", 508 Predicates = [HasStdExtC, HasStdExtF, IsRV32] in 509 def C_FSWSP : CStackStore<0b111, "c.fswsp", FPR32, uimm8_lsb00> { 510 let Inst{12-9} = imm{5-2}; 511 let Inst{8-7} = imm{7-6}; 512 } 513 514 let Predicates = [HasStdExtC, IsRV64] in 515 def C_SDSP : CStackStore<0b111, "c.sdsp", GPR, uimm9_lsb000> { 516 let Inst{12-10} = imm{5-3}; 517 let Inst{9-7} = imm{8-6}; 518 } 519 520 } // Predicates = [HasStdExtC] 521 522 //===----------------------------------------------------------------------===// 523 // Compress Instruction tablegen backend. 524 //===----------------------------------------------------------------------===// 525 526 class CompressPat<dag input, dag output> { 527 dag Input = input; 528 dag Output = output; 529 list<Predicate> Predicates = []; 530 } 531 532 // Patterns are defined in the same order the compressed instructions appear 533 // on page 82 of the ISA manual. 534 535 // Quadrant 0 536 let Predicates = [HasStdExtC] in { 537 def : CompressPat<(ADDI GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm), 538 (C_ADDI4SPN GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm)>; 539 } // Predicates = [HasStdExtC] 540 541 let Predicates = [HasStdExtC, HasStdExtD] in { 542 def : CompressPat<(FLD FPR64C:$rd, GPRC:$rs1, uimm8_lsb000:$imm), 543 (C_FLD FPR64C:$rd, GPRC:$rs1, uimm8_lsb000:$imm)>; 544 } // Predicates = [HasStdExtC, HasStdExtD] 545 546 let Predicates = [HasStdExtC] in { 547 def : CompressPat<(LW GPRC:$rd, GPRC:$rs1, uimm7_lsb00:$imm), 548 (C_LW GPRC:$rd, GPRC:$rs1, uimm7_lsb00:$imm)>; 549 } // Predicates = [HasStdExtC] 550 551 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in { 552 def : CompressPat<(FLW FPR32C:$rd, GPRC:$rs1, uimm7_lsb00:$imm), 553 (C_FLW FPR32C:$rd, GPRC:$rs1, uimm7_lsb00:$imm)>; 554 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32] 555 556 let Predicates = [HasStdExtC, IsRV64] in { 557 def : CompressPat<(LD GPRC:$rd, GPRC:$rs1, uimm8_lsb000:$imm), 558 (C_LD GPRC:$rd, GPRC:$rs1, uimm8_lsb000:$imm)>; 559 } // Predicates = [HasStdExtC, IsRV64] 560 561 let Predicates = [HasStdExtC, HasStdExtD] in { 562 def : CompressPat<(FSD FPR64C:$rs2, GPRC:$rs1, uimm8_lsb000:$imm), 563 (C_FSD FPR64C:$rs2, GPRC:$rs1, uimm8_lsb000:$imm)>; 564 } // Predicates = [HasStdExtC, HasStdExtD] 565 566 let Predicates = [HasStdExtC] in { 567 def : CompressPat<(SW GPRC:$rs2, GPRC:$rs1, uimm7_lsb00:$imm), 568 (C_SW GPRC:$rs2, GPRC:$rs1, uimm7_lsb00:$imm)>; 569 } // Predicates = [HasStdExtC] 570 571 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in { 572 def : CompressPat<(FSW FPR32C:$rs2, GPRC:$rs1,uimm7_lsb00:$imm), 573 (C_FSW FPR32C:$rs2, GPRC:$rs1, uimm7_lsb00:$imm)>; 574 } // Predicate = [HasStdExtC, HasStdExtF, IsRV32] 575 576 let Predicates = [HasStdExtC, IsRV64] in { 577 def : CompressPat<(SD GPRC:$rs2, GPRC:$rs1, uimm8_lsb000:$imm), 578 (C_SD GPRC:$rs2, GPRC:$rs1, uimm8_lsb000:$imm)>; 579 } // Predicates = [HasStdExtC, IsRV64] 580 581 // Quadrant 1 582 let Predicates = [HasStdExtC] in { 583 def : CompressPat<(ADDI X0, X0, 0), (C_NOP)>; 584 def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs1, simm6nonzero:$imm), 585 (C_ADDI GPRNoX0:$rs1, simm6nonzero:$imm)>; 586 } // Predicates = [HasStdExtC] 587 588 let Predicates = [HasStdExtC, IsRV32] in { 589 def : CompressPat<(JAL X1, simm12_lsb0:$offset), 590 (C_JAL simm12_lsb0:$offset)>; 591 } // Predicates = [HasStdExtC, IsRV32] 592 593 let Predicates = [HasStdExtC, IsRV64] in { 594 def : CompressPat<(ADDIW GPRNoX0:$rs1, GPRNoX0:$rs1, simm6:$imm), 595 (C_ADDIW GPRNoX0:$rs1, simm6:$imm)>; 596 } // Predicates = [HasStdExtC, IsRV64] 597 598 let Predicates = [HasStdExtC] in { 599 def : CompressPat<(ADDI GPRNoX0:$rd, X0, simm6:$imm), 600 (C_LI GPRNoX0:$rd, simm6:$imm)>; 601 def : CompressPat<(ADDI X2, X2, simm10_lsb0000nonzero:$imm), 602 (C_ADDI16SP X2, simm10_lsb0000nonzero:$imm)>; 603 def : CompressPat<(LUI GPRNoX0X2:$rd, c_lui_imm:$imm), 604 (C_LUI GPRNoX0X2:$rd, c_lui_imm:$imm)>; 605 def : CompressPat<(SRLI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm), 606 (C_SRLI GPRC:$rs1, uimmlog2xlennonzero:$imm)>; 607 def : CompressPat<(SRAI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm), 608 (C_SRAI GPRC:$rs1, uimmlog2xlennonzero:$imm)>; 609 def : CompressPat<(ANDI GPRC:$rs1, GPRC:$rs1, simm6:$imm), 610 (C_ANDI GPRC:$rs1, simm6:$imm)>; 611 def : CompressPat<(SUB GPRC:$rs1, GPRC:$rs1, GPRC:$rs2), 612 (C_SUB GPRC:$rs1, GPRC:$rs2)>; 613 def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2), 614 (C_XOR GPRC:$rs1, GPRC:$rs2)>; 615 def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1), 616 (C_XOR GPRC:$rs1, GPRC:$rs2)>; 617 def : CompressPat<(OR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2), 618 (C_OR GPRC:$rs1, GPRC:$rs2)>; 619 def : CompressPat<(OR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1), 620 (C_OR GPRC:$rs1, GPRC:$rs2)>; 621 def : CompressPat<(AND GPRC:$rs1, GPRC:$rs1, GPRC:$rs2), 622 (C_AND GPRC:$rs1, GPRC:$rs2)>; 623 def : CompressPat<(AND GPRC:$rs1, GPRC:$rs2, GPRC:$rs1), 624 (C_AND GPRC:$rs1, GPRC:$rs2)>; 625 } // Predicates = [HasStdExtC] 626 627 let Predicates = [HasStdExtC, IsRV64] in { 628 def : CompressPat<(SUBW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2), 629 (C_SUBW GPRC:$rs1, GPRC:$rs2)>; 630 def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2), 631 (C_ADDW GPRC:$rs1, GPRC:$rs2)>; 632 def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs2, GPRC:$rs1), 633 (C_ADDW GPRC:$rs1, GPRC:$rs2)>; 634 } // Predicates = [HasStdExtC, IsRV64] 635 636 let Predicates = [HasStdExtC] in { 637 def : CompressPat<(JAL X0, simm12_lsb0:$offset), 638 (C_J simm12_lsb0:$offset)>; 639 def : CompressPat<(BEQ GPRC:$rs1, X0, simm9_lsb0:$imm), 640 (C_BEQZ GPRC:$rs1, simm9_lsb0:$imm)>; 641 def : CompressPat<(BNE GPRC:$rs1, X0, simm9_lsb0:$imm), 642 (C_BNEZ GPRC:$rs1, simm9_lsb0:$imm)>; 643 } // Predicates = [HasStdExtC] 644 645 // Quadrant 2 646 let Predicates = [HasStdExtC] in { 647 def : CompressPat<(SLLI GPRNoX0:$rs1, GPRNoX0:$rs1, uimmlog2xlennonzero:$imm), 648 (C_SLLI GPRNoX0:$rs1, uimmlog2xlennonzero:$imm)>; 649 } // Predicates = [HasStdExtC] 650 651 let Predicates = [HasStdExtC, HasStdExtD] in { 652 def : CompressPat<(FLD FPR64:$rd, SP:$rs1, uimm9_lsb000:$imm), 653 (C_FLDSP FPR64:$rd, SP:$rs1, uimm9_lsb000:$imm)>; 654 } // Predicates = [HasStdExtC, HasStdExtD] 655 656 let Predicates = [HasStdExtC] in { 657 def : CompressPat<(LW GPRNoX0:$rd, SP:$rs1, uimm8_lsb00:$imm), 658 (C_LWSP GPRNoX0:$rd, SP:$rs1, uimm8_lsb00:$imm)>; 659 } // Predicates = [HasStdExtC] 660 661 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in { 662 def : CompressPat<(FLW FPR32:$rd, SP:$rs1, uimm8_lsb00:$imm), 663 (C_FLWSP FPR32:$rd, SP:$rs1, uimm8_lsb00:$imm)>; 664 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32] 665 666 let Predicates = [HasStdExtC, IsRV64] in { 667 def : CompressPat<(LD GPRNoX0:$rd, SP:$rs1, uimm9_lsb000:$imm), 668 (C_LDSP GPRNoX0:$rd, SP:$rs1, uimm9_lsb000:$imm)>; 669 } // Predicates = [HasStdExtC, IsRV64] 670 671 let Predicates = [HasStdExtC] in { 672 def : CompressPat<(JALR X0, GPRNoX0:$rs1, 0), 673 (C_JR GPRNoX0:$rs1)>; 674 def : CompressPat<(ADD GPRNoX0:$rs1, X0, GPRNoX0:$rs2), 675 (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>; 676 def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, X0), 677 (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>; 678 def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs2, 0), 679 (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>; 680 def : CompressPat<(EBREAK), (C_EBREAK)>; 681 def : CompressPat<(JALR X1, GPRNoX0:$rs1, 0), 682 (C_JALR GPRNoX0:$rs1)>; 683 def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs1, GPRNoX0:$rs2), 684 (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>; 685 def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, GPRNoX0:$rs1), 686 (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>; 687 } // Predicates = [HasStdExtC] 688 689 let Predicates = [HasStdExtC, HasStdExtD] in { 690 def : CompressPat<(FSD FPR64:$rs2, SP:$rs1, uimm9_lsb000:$imm), 691 (C_FSDSP FPR64:$rs2, SP:$rs1, uimm9_lsb000:$imm)>; 692 } // Predicates = [HasStdExtC, HasStdExtD] 693 694 let Predicates = [HasStdExtC] in { 695 def : CompressPat<(SW GPR:$rs2, SP:$rs1, uimm8_lsb00:$imm), 696 (C_SWSP GPR:$rs2, SP:$rs1, uimm8_lsb00:$imm)>; 697 } // Predicates = [HasStdExtC] 698 699 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in { 700 def : CompressPat<(FSW FPR32:$rs2, SP:$rs1, uimm8_lsb00:$imm), 701 (C_FSWSP FPR32:$rs2, SP:$rs1, uimm8_lsb00:$imm)>; 702 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32] 703 704 let Predicates = [HasStdExtC, IsRV64] in { 705 def : CompressPat<(SD GPR:$rs2, SP:$rs1, uimm9_lsb000:$imm), 706 (C_SDSP GPR:$rs2, SP:$rs1, uimm9_lsb000:$imm)>; 707 } // Predicates = [HasStdExtC, IsRV64] 708