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