1 //===-- RISCVMCCodeEmitter.cpp - Convert RISC-V code to machine code ------===// 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 // 9 // This file implements the RISCVMCCodeEmitter class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "MCTargetDesc/RISCVBaseInfo.h" 14 #include "MCTargetDesc/RISCVFixupKinds.h" 15 #include "MCTargetDesc/RISCVMCAsmInfo.h" 16 #include "MCTargetDesc/RISCVMCTargetDesc.h" 17 #include "llvm/ADT/Statistic.h" 18 #include "llvm/MC/MCAsmInfo.h" 19 #include "llvm/MC/MCCodeEmitter.h" 20 #include "llvm/MC/MCContext.h" 21 #include "llvm/MC/MCExpr.h" 22 #include "llvm/MC/MCInst.h" 23 #include "llvm/MC/MCInstBuilder.h" 24 #include "llvm/MC/MCInstrInfo.h" 25 #include "llvm/MC/MCRegisterInfo.h" 26 #include "llvm/MC/MCSubtargetInfo.h" 27 #include "llvm/MC/MCSymbol.h" 28 #include "llvm/Support/Casting.h" 29 #include "llvm/Support/EndianStream.h" 30 31 using namespace llvm; 32 33 #define DEBUG_TYPE "mccodeemitter" 34 35 STATISTIC(MCNumEmitted, "Number of MC instructions emitted"); 36 STATISTIC(MCNumFixups, "Number of MC fixups created"); 37 38 namespace { 39 class RISCVMCCodeEmitter : public MCCodeEmitter { 40 RISCVMCCodeEmitter(const RISCVMCCodeEmitter &) = delete; 41 void operator=(const RISCVMCCodeEmitter &) = delete; 42 MCContext &Ctx; 43 MCInstrInfo const &MCII; 44 45 public: 46 RISCVMCCodeEmitter(MCContext &ctx, MCInstrInfo const &MCII) 47 : Ctx(ctx), MCII(MCII) {} 48 49 ~RISCVMCCodeEmitter() override = default; 50 51 void encodeInstruction(const MCInst &MI, SmallVectorImpl<char> &CB, 52 SmallVectorImpl<MCFixup> &Fixups, 53 const MCSubtargetInfo &STI) const override; 54 55 void expandFunctionCall(const MCInst &MI, SmallVectorImpl<char> &CB, 56 SmallVectorImpl<MCFixup> &Fixups, 57 const MCSubtargetInfo &STI) const; 58 59 void expandTLSDESCCall(const MCInst &MI, SmallVectorImpl<char> &CB, 60 SmallVectorImpl<MCFixup> &Fixups, 61 const MCSubtargetInfo &STI) const; 62 63 void expandAddTPRel(const MCInst &MI, SmallVectorImpl<char> &CB, 64 SmallVectorImpl<MCFixup> &Fixups, 65 const MCSubtargetInfo &STI) const; 66 67 void expandLongCondBr(const MCInst &MI, SmallVectorImpl<char> &CB, 68 SmallVectorImpl<MCFixup> &Fixups, 69 const MCSubtargetInfo &STI) const; 70 71 void expandQCLongCondBrImm(const MCInst &MI, SmallVectorImpl<char> &CB, 72 SmallVectorImpl<MCFixup> &Fixups, 73 const MCSubtargetInfo &STI, unsigned Size) const; 74 75 /// TableGen'erated function for getting the binary encoding for an 76 /// instruction. 77 uint64_t getBinaryCodeForInstr(const MCInst &MI, 78 SmallVectorImpl<MCFixup> &Fixups, 79 const MCSubtargetInfo &STI) const; 80 81 /// Return binary encoding of operand. If the machine operand requires 82 /// relocation, record the relocation and return zero. 83 uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO, 84 SmallVectorImpl<MCFixup> &Fixups, 85 const MCSubtargetInfo &STI) const; 86 87 uint64_t getImmOpValueMinus1(const MCInst &MI, unsigned OpNo, 88 SmallVectorImpl<MCFixup> &Fixups, 89 const MCSubtargetInfo &STI) const; 90 91 uint64_t getImmOpValueSlist(const MCInst &MI, unsigned OpNo, 92 SmallVectorImpl<MCFixup> &Fixups, 93 const MCSubtargetInfo &STI) const; 94 95 template <unsigned N> 96 unsigned getImmOpValueAsrN(const MCInst &MI, unsigned OpNo, 97 SmallVectorImpl<MCFixup> &Fixups, 98 const MCSubtargetInfo &STI) const; 99 100 uint64_t getImmOpValue(const MCInst &MI, unsigned OpNo, 101 SmallVectorImpl<MCFixup> &Fixups, 102 const MCSubtargetInfo &STI) const; 103 104 unsigned getVMaskReg(const MCInst &MI, unsigned OpNo, 105 SmallVectorImpl<MCFixup> &Fixups, 106 const MCSubtargetInfo &STI) const; 107 108 unsigned getRlistOpValue(const MCInst &MI, unsigned OpNo, 109 SmallVectorImpl<MCFixup> &Fixups, 110 const MCSubtargetInfo &STI) const; 111 112 unsigned getRlistS0OpValue(const MCInst &MI, unsigned OpNo, 113 SmallVectorImpl<MCFixup> &Fixups, 114 const MCSubtargetInfo &STI) const; 115 }; 116 } // end anonymous namespace 117 118 MCCodeEmitter *llvm::createRISCVMCCodeEmitter(const MCInstrInfo &MCII, 119 MCContext &Ctx) { 120 return new RISCVMCCodeEmitter(Ctx, MCII); 121 } 122 123 static void addFixup(SmallVectorImpl<MCFixup> &Fixups, uint32_t Offset, 124 const MCExpr *Value, uint16_t Kind) { 125 bool PCRel = false; 126 switch (Kind) { 127 case ELF::R_RISCV_CALL_PLT: 128 case RISCV::fixup_riscv_pcrel_hi20: 129 case RISCV::fixup_riscv_pcrel_lo12_i: 130 case RISCV::fixup_riscv_pcrel_lo12_s: 131 case RISCV::fixup_riscv_jal: 132 case RISCV::fixup_riscv_branch: 133 case RISCV::fixup_riscv_rvc_jump: 134 case RISCV::fixup_riscv_rvc_branch: 135 case RISCV::fixup_riscv_call: 136 case RISCV::fixup_riscv_call_plt: 137 case RISCV::fixup_riscv_qc_e_branch: 138 case RISCV::fixup_riscv_qc_e_call_plt: 139 case RISCV::fixup_riscv_nds_branch_10: 140 PCRel = true; 141 } 142 Fixups.push_back(MCFixup::create(Offset, Value, Kind, PCRel)); 143 } 144 145 // Expand PseudoCALL(Reg), PseudoTAIL and PseudoJump to AUIPC and JALR with 146 // relocation types. We expand those pseudo-instructions while encoding them, 147 // meaning AUIPC and JALR won't go through RISC-V MC to MC compressed 148 // instruction transformation. This is acceptable because AUIPC has no 16-bit 149 // form and C_JALR has no immediate operand field. We let linker relaxation 150 // deal with it. When linker relaxation is enabled, AUIPC and JALR have a 151 // chance to relax to JAL. 152 // If the C extension is enabled, JAL has a chance relax to C_JAL. 153 void RISCVMCCodeEmitter::expandFunctionCall(const MCInst &MI, 154 SmallVectorImpl<char> &CB, 155 SmallVectorImpl<MCFixup> &Fixups, 156 const MCSubtargetInfo &STI) const { 157 MCInst TmpInst; 158 MCOperand Func; 159 MCRegister Ra; 160 if (MI.getOpcode() == RISCV::PseudoTAIL) { 161 Func = MI.getOperand(0); 162 Ra = RISCVII::getTailExpandUseRegNo(STI.getFeatureBits()); 163 } else if (MI.getOpcode() == RISCV::PseudoCALLReg) { 164 Func = MI.getOperand(1); 165 Ra = MI.getOperand(0).getReg(); 166 } else if (MI.getOpcode() == RISCV::PseudoCALL) { 167 Func = MI.getOperand(0); 168 Ra = RISCV::X1; 169 } else if (MI.getOpcode() == RISCV::PseudoJump) { 170 Func = MI.getOperand(1); 171 Ra = MI.getOperand(0).getReg(); 172 } 173 uint32_t Binary; 174 175 assert(Func.isExpr() && "Expected expression"); 176 177 const MCExpr *CallExpr = Func.getExpr(); 178 179 // Emit AUIPC Ra, Func with R_RISCV_CALL relocation type. 180 TmpInst = MCInstBuilder(RISCV::AUIPC).addReg(Ra).addExpr(CallExpr); 181 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 182 support::endian::write(CB, Binary, llvm::endianness::little); 183 184 if (MI.getOpcode() == RISCV::PseudoTAIL || 185 MI.getOpcode() == RISCV::PseudoJump) 186 // Emit JALR X0, Ra, 0 187 TmpInst = MCInstBuilder(RISCV::JALR).addReg(RISCV::X0).addReg(Ra).addImm(0); 188 else 189 // Emit JALR Ra, Ra, 0 190 TmpInst = MCInstBuilder(RISCV::JALR).addReg(Ra).addReg(Ra).addImm(0); 191 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 192 support::endian::write(CB, Binary, llvm::endianness::little); 193 } 194 195 void RISCVMCCodeEmitter::expandTLSDESCCall(const MCInst &MI, 196 SmallVectorImpl<char> &CB, 197 SmallVectorImpl<MCFixup> &Fixups, 198 const MCSubtargetInfo &STI) const { 199 MCOperand SrcSymbol = MI.getOperand(3); 200 assert(SrcSymbol.isExpr() && 201 "Expected expression as first input to TLSDESCCALL"); 202 const auto *Expr = dyn_cast<MCSpecifierExpr>(SrcSymbol.getExpr()); 203 MCRegister Link = MI.getOperand(0).getReg(); 204 MCRegister Dest = MI.getOperand(1).getReg(); 205 int64_t Imm = MI.getOperand(2).getImm(); 206 addFixup(Fixups, 0, Expr, ELF::R_RISCV_TLSDESC_CALL); 207 MCInst Call = 208 MCInstBuilder(RISCV::JALR).addReg(Link).addReg(Dest).addImm(Imm); 209 210 uint32_t Binary = getBinaryCodeForInstr(Call, Fixups, STI); 211 support::endian::write(CB, Binary, llvm::endianness::little); 212 } 213 214 // Expand PseudoAddTPRel to a simple ADD with the correct relocation. 215 void RISCVMCCodeEmitter::expandAddTPRel(const MCInst &MI, 216 SmallVectorImpl<char> &CB, 217 SmallVectorImpl<MCFixup> &Fixups, 218 const MCSubtargetInfo &STI) const { 219 MCOperand DestReg = MI.getOperand(0); 220 MCOperand SrcReg = MI.getOperand(1); 221 MCOperand TPReg = MI.getOperand(2); 222 assert(TPReg.isReg() && TPReg.getReg() == RISCV::X4 && 223 "Expected thread pointer as second input to TP-relative add"); 224 225 MCOperand SrcSymbol = MI.getOperand(3); 226 assert(SrcSymbol.isExpr() && 227 "Expected expression as third input to TP-relative add"); 228 229 const auto *Expr = dyn_cast<MCSpecifierExpr>(SrcSymbol.getExpr()); 230 assert(Expr && Expr->getSpecifier() == ELF::R_RISCV_TPREL_ADD && 231 "Expected tprel_add relocation on TP-relative symbol"); 232 233 addFixup(Fixups, 0, Expr, ELF::R_RISCV_TPREL_ADD); 234 if (STI.hasFeature(RISCV::FeatureRelax)) 235 Fixups.back().setLinkerRelaxable(); 236 237 // Emit a normal ADD instruction with the given operands. 238 MCInst TmpInst = MCInstBuilder(RISCV::ADD) 239 .addOperand(DestReg) 240 .addOperand(SrcReg) 241 .addOperand(TPReg); 242 uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 243 support::endian::write(CB, Binary, llvm::endianness::little); 244 } 245 246 static unsigned getInvertedBranchOp(unsigned BrOp) { 247 switch (BrOp) { 248 default: 249 llvm_unreachable("Unexpected branch opcode!"); 250 case RISCV::PseudoLongBEQ: 251 return RISCV::BNE; 252 case RISCV::PseudoLongBNE: 253 return RISCV::BEQ; 254 case RISCV::PseudoLongBLT: 255 return RISCV::BGE; 256 case RISCV::PseudoLongBGE: 257 return RISCV::BLT; 258 case RISCV::PseudoLongBLTU: 259 return RISCV::BGEU; 260 case RISCV::PseudoLongBGEU: 261 return RISCV::BLTU; 262 case RISCV::PseudoLongQC_BEQI: 263 return RISCV::QC_BNEI; 264 case RISCV::PseudoLongQC_BNEI: 265 return RISCV::QC_BEQI; 266 case RISCV::PseudoLongQC_BLTI: 267 return RISCV::QC_BGEI; 268 case RISCV::PseudoLongQC_BGEI: 269 return RISCV::QC_BLTI; 270 case RISCV::PseudoLongQC_BLTUI: 271 return RISCV::QC_BGEUI; 272 case RISCV::PseudoLongQC_BGEUI: 273 return RISCV::QC_BLTUI; 274 case RISCV::PseudoLongQC_E_BEQI: 275 return RISCV::QC_E_BNEI; 276 case RISCV::PseudoLongQC_E_BNEI: 277 return RISCV::QC_E_BEQI; 278 case RISCV::PseudoLongQC_E_BLTI: 279 return RISCV::QC_E_BGEI; 280 case RISCV::PseudoLongQC_E_BGEI: 281 return RISCV::QC_E_BLTI; 282 case RISCV::PseudoLongQC_E_BLTUI: 283 return RISCV::QC_E_BGEUI; 284 case RISCV::PseudoLongQC_E_BGEUI: 285 return RISCV::QC_E_BLTUI; 286 } 287 } 288 289 // Expand PseudoLongBxx to an inverted conditional branch and an unconditional 290 // jump. 291 void RISCVMCCodeEmitter::expandLongCondBr(const MCInst &MI, 292 SmallVectorImpl<char> &CB, 293 SmallVectorImpl<MCFixup> &Fixups, 294 const MCSubtargetInfo &STI) const { 295 MCRegister SrcReg1 = MI.getOperand(0).getReg(); 296 MCRegister SrcReg2 = MI.getOperand(1).getReg(); 297 MCOperand SrcSymbol = MI.getOperand(2); 298 unsigned Opcode = MI.getOpcode(); 299 bool IsEqTest = 300 Opcode == RISCV::PseudoLongBNE || Opcode == RISCV::PseudoLongBEQ; 301 302 bool UseCompressedBr = false; 303 if (IsEqTest && STI.hasFeature(RISCV::FeatureStdExtZca)) { 304 if (RISCV::X8 <= SrcReg1.id() && SrcReg1.id() <= RISCV::X15 && 305 SrcReg2.id() == RISCV::X0) { 306 UseCompressedBr = true; 307 } else if (RISCV::X8 <= SrcReg2.id() && SrcReg2.id() <= RISCV::X15 && 308 SrcReg1.id() == RISCV::X0) { 309 std::swap(SrcReg1, SrcReg2); 310 UseCompressedBr = true; 311 } 312 } 313 314 uint32_t Offset; 315 if (UseCompressedBr) { 316 unsigned InvOpc = 317 Opcode == RISCV::PseudoLongBNE ? RISCV::C_BEQZ : RISCV::C_BNEZ; 318 MCInst TmpInst = MCInstBuilder(InvOpc).addReg(SrcReg1).addImm(6); 319 uint16_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 320 support::endian::write<uint16_t>(CB, Binary, llvm::endianness::little); 321 Offset = 2; 322 } else { 323 unsigned InvOpc = getInvertedBranchOp(Opcode); 324 MCInst TmpInst = 325 MCInstBuilder(InvOpc).addReg(SrcReg1).addReg(SrcReg2).addImm(8); 326 uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 327 support::endian::write(CB, Binary, llvm::endianness::little); 328 Offset = 4; 329 } 330 331 // Save the number fixups. 332 size_t FixupStartIndex = Fixups.size(); 333 334 // Emit an unconditional jump to the destination. 335 MCInst TmpInst = 336 MCInstBuilder(RISCV::JAL).addReg(RISCV::X0).addOperand(SrcSymbol); 337 uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 338 support::endian::write(CB, Binary, llvm::endianness::little); 339 340 // Drop any fixup added so we can add the correct one. 341 Fixups.resize(FixupStartIndex); 342 343 if (SrcSymbol.isExpr()) 344 addFixup(Fixups, Offset, SrcSymbol.getExpr(), RISCV::fixup_riscv_jal); 345 } 346 347 // Expand PseudoLongQC_(E_)Bxxx to an inverted conditional branch and an 348 // unconditional jump. 349 void RISCVMCCodeEmitter::expandQCLongCondBrImm(const MCInst &MI, 350 SmallVectorImpl<char> &CB, 351 SmallVectorImpl<MCFixup> &Fixups, 352 const MCSubtargetInfo &STI, 353 unsigned Size) const { 354 MCRegister SrcReg1 = MI.getOperand(0).getReg(); 355 auto BrImm = MI.getOperand(1).getImm(); 356 MCOperand SrcSymbol = MI.getOperand(2); 357 unsigned Opcode = MI.getOpcode(); 358 uint32_t Offset; 359 unsigned InvOpc = getInvertedBranchOp(Opcode); 360 // Emit inverted conditional branch with offset: 361 // 8 (QC.BXXX(4) + JAL(4)) 362 // or 363 // 10 (QC.E.BXXX(6) + JAL(4)). 364 if (Size == 4) { 365 MCInst TmpBr = 366 MCInstBuilder(InvOpc).addReg(SrcReg1).addImm(BrImm).addImm(8); 367 uint32_t BrBinary = getBinaryCodeForInstr(TmpBr, Fixups, STI); 368 support::endian::write(CB, BrBinary, llvm::endianness::little); 369 } else { 370 MCInst TmpBr = 371 MCInstBuilder(InvOpc).addReg(SrcReg1).addImm(BrImm).addImm(10); 372 uint64_t BrBinary = 373 getBinaryCodeForInstr(TmpBr, Fixups, STI) & 0xffff'ffff'ffffu; 374 SmallVector<char, 8> Encoding; 375 support::endian::write(Encoding, BrBinary, llvm::endianness::little); 376 assert(Encoding[6] == 0 && Encoding[7] == 0 && 377 "Unexpected encoding for 48-bit instruction"); 378 Encoding.truncate(6); 379 CB.append(Encoding); 380 } 381 Offset = Size; 382 // Save the number fixups. 383 size_t FixupStartIndex = Fixups.size(); 384 // Emit an unconditional jump to the destination. 385 MCInst TmpJ = 386 MCInstBuilder(RISCV::JAL).addReg(RISCV::X0).addOperand(SrcSymbol); 387 uint32_t JBinary = getBinaryCodeForInstr(TmpJ, Fixups, STI); 388 support::endian::write(CB, JBinary, llvm::endianness::little); 389 // Drop any fixup added so we can add the correct one. 390 Fixups.resize(FixupStartIndex); 391 if (SrcSymbol.isExpr()) 392 addFixup(Fixups, Offset, SrcSymbol.getExpr(), RISCV::fixup_riscv_jal); 393 } 394 395 void RISCVMCCodeEmitter::encodeInstruction(const MCInst &MI, 396 SmallVectorImpl<char> &CB, 397 SmallVectorImpl<MCFixup> &Fixups, 398 const MCSubtargetInfo &STI) const { 399 const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); 400 // Get byte count of instruction. 401 unsigned Size = Desc.getSize(); 402 403 // RISCVInstrInfo::getInstSizeInBytes expects that the total size of the 404 // expanded instructions for each pseudo is correct in the Size field of the 405 // tablegen definition for the pseudo. 406 switch (MI.getOpcode()) { 407 default: 408 break; 409 case RISCV::PseudoCALLReg: 410 case RISCV::PseudoCALL: 411 case RISCV::PseudoTAIL: 412 case RISCV::PseudoJump: 413 expandFunctionCall(MI, CB, Fixups, STI); 414 MCNumEmitted += 2; 415 return; 416 case RISCV::PseudoAddTPRel: 417 expandAddTPRel(MI, CB, Fixups, STI); 418 MCNumEmitted += 1; 419 return; 420 case RISCV::PseudoLongBEQ: 421 case RISCV::PseudoLongBNE: 422 case RISCV::PseudoLongBLT: 423 case RISCV::PseudoLongBGE: 424 case RISCV::PseudoLongBLTU: 425 case RISCV::PseudoLongBGEU: 426 expandLongCondBr(MI, CB, Fixups, STI); 427 MCNumEmitted += 2; 428 return; 429 case RISCV::PseudoLongQC_BEQI: 430 case RISCV::PseudoLongQC_BNEI: 431 case RISCV::PseudoLongQC_BLTI: 432 case RISCV::PseudoLongQC_BGEI: 433 case RISCV::PseudoLongQC_BLTUI: 434 case RISCV::PseudoLongQC_BGEUI: 435 expandQCLongCondBrImm(MI, CB, Fixups, STI, 4); 436 MCNumEmitted += 2; 437 return; 438 case RISCV::PseudoLongQC_E_BEQI: 439 case RISCV::PseudoLongQC_E_BNEI: 440 case RISCV::PseudoLongQC_E_BLTI: 441 case RISCV::PseudoLongQC_E_BGEI: 442 case RISCV::PseudoLongQC_E_BLTUI: 443 case RISCV::PseudoLongQC_E_BGEUI: 444 expandQCLongCondBrImm(MI, CB, Fixups, STI, 6); 445 MCNumEmitted += 2; 446 return; 447 case RISCV::PseudoTLSDESCCall: 448 expandTLSDESCCall(MI, CB, Fixups, STI); 449 MCNumEmitted += 1; 450 return; 451 } 452 453 switch (Size) { 454 default: 455 llvm_unreachable("Unhandled encodeInstruction length!"); 456 case 2: { 457 uint16_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); 458 support::endian::write<uint16_t>(CB, Bits, llvm::endianness::little); 459 break; 460 } 461 case 4: { 462 uint32_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); 463 support::endian::write(CB, Bits, llvm::endianness::little); 464 break; 465 } 466 case 6: { 467 uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI) & 0xffff'ffff'ffffu; 468 SmallVector<char, 8> Encoding; 469 support::endian::write(Encoding, Bits, llvm::endianness::little); 470 assert(Encoding[6] == 0 && Encoding[7] == 0 && 471 "Unexpected encoding for 48-bit instruction"); 472 Encoding.truncate(6); 473 CB.append(Encoding); 474 break; 475 } 476 case 8: { 477 uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); 478 support::endian::write(CB, Bits, llvm::endianness::little); 479 break; 480 } 481 } 482 483 ++MCNumEmitted; // Keep track of the # of mi's emitted. 484 } 485 486 uint64_t 487 RISCVMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO, 488 SmallVectorImpl<MCFixup> &Fixups, 489 const MCSubtargetInfo &STI) const { 490 491 if (MO.isReg()) 492 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()); 493 494 if (MO.isImm()) 495 return MO.getImm(); 496 497 llvm_unreachable("Unhandled expression!"); 498 return 0; 499 } 500 501 uint64_t 502 RISCVMCCodeEmitter::getImmOpValueMinus1(const MCInst &MI, unsigned OpNo, 503 SmallVectorImpl<MCFixup> &Fixups, 504 const MCSubtargetInfo &STI) const { 505 const MCOperand &MO = MI.getOperand(OpNo); 506 507 if (MO.isImm()) { 508 uint64_t Res = MO.getImm(); 509 return (Res - 1); 510 } 511 512 llvm_unreachable("Unhandled expression!"); 513 return 0; 514 } 515 516 uint64_t 517 RISCVMCCodeEmitter::getImmOpValueSlist(const MCInst &MI, unsigned OpNo, 518 SmallVectorImpl<MCFixup> &Fixups, 519 const MCSubtargetInfo &STI) const { 520 const MCOperand &MO = MI.getOperand(OpNo); 521 assert(MO.isImm() && "Slist operand must be immediate"); 522 523 uint64_t Res = MO.getImm(); 524 switch (Res) { 525 case 0: 526 return 0; 527 case 1: 528 return 1; 529 case 2: 530 return 2; 531 case 4: 532 return 3; 533 case 8: 534 return 4; 535 case 16: 536 return 5; 537 case 15: 538 return 6; 539 case 31: 540 return 7; 541 default: 542 llvm_unreachable("Unhandled Slist value!"); 543 } 544 } 545 546 template <unsigned N> 547 unsigned 548 RISCVMCCodeEmitter::getImmOpValueAsrN(const MCInst &MI, unsigned OpNo, 549 SmallVectorImpl<MCFixup> &Fixups, 550 const MCSubtargetInfo &STI) const { 551 const MCOperand &MO = MI.getOperand(OpNo); 552 553 if (MO.isImm()) { 554 uint64_t Res = MO.getImm(); 555 assert((Res & ((1 << N) - 1)) == 0 && "LSB is non-zero"); 556 return Res >> N; 557 } 558 559 return getImmOpValue(MI, OpNo, Fixups, STI); 560 } 561 562 uint64_t RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo, 563 SmallVectorImpl<MCFixup> &Fixups, 564 const MCSubtargetInfo &STI) const { 565 bool EnableRelax = STI.hasFeature(RISCV::FeatureRelax); 566 const MCOperand &MO = MI.getOperand(OpNo); 567 568 MCInstrDesc const &Desc = MCII.get(MI.getOpcode()); 569 unsigned MIFrm = RISCVII::getFormat(Desc.TSFlags); 570 571 // If the destination is an immediate, there is nothing to do. 572 if (MO.isImm()) 573 return MO.getImm(); 574 575 assert(MO.isExpr() && 576 "getImmOpValue expects only expressions or immediates"); 577 const MCExpr *Expr = MO.getExpr(); 578 MCExpr::ExprKind Kind = Expr->getKind(); 579 580 // `RelaxCandidate` must be set to `true` in two cases: 581 // - The fixup's relocation gets a R_RISCV_RELAX relocation 582 // - The underlying instruction may be relaxed to an instruction that gets a 583 // `R_RISCV_RELAX` relocation. 584 // 585 // The actual emission of `R_RISCV_RELAX` will be handled in 586 // `RISCVAsmBackend::applyFixup`. 587 bool RelaxCandidate = false; 588 auto AsmRelaxToLinkerRelaxableWithFeature = [&](unsigned Feature) -> void { 589 if (!STI.hasFeature(RISCV::FeatureExactAssembly) && STI.hasFeature(Feature)) 590 RelaxCandidate = true; 591 }; 592 593 unsigned FixupKind = RISCV::fixup_riscv_invalid; 594 if (Kind == MCExpr::Specifier) { 595 const auto *RVExpr = cast<MCSpecifierExpr>(Expr); 596 FixupKind = RVExpr->getSpecifier(); 597 switch (RVExpr->getSpecifier()) { 598 default: 599 assert(FixupKind && FixupKind < FirstTargetFixupKind && 600 "invalid specifier"); 601 break; 602 case ELF::R_RISCV_TPREL_ADD: 603 // tprel_add is only used to indicate that a relocation should be emitted 604 // for an add instruction used in TP-relative addressing. It should not be 605 // expanded as if representing an actual instruction operand and so to 606 // encounter it here is an error. 607 llvm_unreachable( 608 "ELF::R_RISCV_TPREL_ADD should not represent an instruction operand"); 609 case RISCV::S_LO: 610 if (MIFrm == RISCVII::InstFormatI) 611 FixupKind = RISCV::fixup_riscv_lo12_i; 612 else if (MIFrm == RISCVII::InstFormatS) 613 FixupKind = RISCV::fixup_riscv_lo12_s; 614 else 615 llvm_unreachable("VK_LO used with unexpected instruction format"); 616 RelaxCandidate = true; 617 break; 618 case ELF::R_RISCV_HI20: 619 FixupKind = RISCV::fixup_riscv_hi20; 620 RelaxCandidate = true; 621 break; 622 case RISCV::S_PCREL_LO: 623 if (MIFrm == RISCVII::InstFormatI) 624 FixupKind = RISCV::fixup_riscv_pcrel_lo12_i; 625 else if (MIFrm == RISCVII::InstFormatS) 626 FixupKind = RISCV::fixup_riscv_pcrel_lo12_s; 627 else 628 llvm_unreachable("VK_PCREL_LO used with unexpected instruction format"); 629 RelaxCandidate = true; 630 break; 631 case ELF::R_RISCV_PCREL_HI20: 632 FixupKind = RISCV::fixup_riscv_pcrel_hi20; 633 RelaxCandidate = true; 634 break; 635 case RISCV::S_TPREL_LO: 636 if (MIFrm == RISCVII::InstFormatI) 637 FixupKind = ELF::R_RISCV_TPREL_LO12_I; 638 else if (MIFrm == RISCVII::InstFormatS) 639 FixupKind = ELF::R_RISCV_TPREL_LO12_S; 640 else 641 llvm_unreachable("VK_TPREL_LO used with unexpected instruction format"); 642 RelaxCandidate = true; 643 break; 644 case ELF::R_RISCV_TPREL_HI20: 645 RelaxCandidate = true; 646 break; 647 case ELF::R_RISCV_CALL_PLT: 648 FixupKind = RISCV::fixup_riscv_call_plt; 649 RelaxCandidate = true; 650 break; 651 case RISCV::S_QC_ABS20: 652 FixupKind = RISCV::fixup_riscv_qc_abs20_u; 653 RelaxCandidate = true; 654 break; 655 } 656 } else if (Kind == MCExpr::SymbolRef || Kind == MCExpr::Binary) { 657 // FIXME: Sub kind binary exprs have chance of underflow. 658 if (MIFrm == RISCVII::InstFormatJ) { 659 FixupKind = RISCV::fixup_riscv_jal; 660 AsmRelaxToLinkerRelaxableWithFeature(RISCV::FeatureVendorXqcilb); 661 } else if (MIFrm == RISCVII::InstFormatB) { 662 FixupKind = RISCV::fixup_riscv_branch; 663 // This might be assembler relaxed to `b<cc>; jal` but we cannot relax 664 // the `jal` again in the assembler. 665 } else if (MIFrm == RISCVII::InstFormatCJ) { 666 FixupKind = RISCV::fixup_riscv_rvc_jump; 667 AsmRelaxToLinkerRelaxableWithFeature(RISCV::FeatureVendorXqcilb); 668 } else if (MIFrm == RISCVII::InstFormatCB) { 669 FixupKind = RISCV::fixup_riscv_rvc_branch; 670 // This might be assembler relaxed to `b<cc>; jal` but we cannot relax 671 // the `jal` again in the assembler. 672 } else if (MIFrm == RISCVII::InstFormatCI) { 673 FixupKind = RISCV::fixup_riscv_rvc_imm; 674 } else if (MIFrm == RISCVII::InstFormatI) { 675 FixupKind = RISCV::fixup_riscv_12_i; 676 } else if (MIFrm == RISCVII::InstFormatQC_EB) { 677 FixupKind = RISCV::fixup_riscv_qc_e_branch; 678 // This might be assembler relaxed to `qc.e.b<cc>; jal` but we cannot 679 // relax the `jal` again in the assembler. 680 } else if (MIFrm == RISCVII::InstFormatQC_EAI) { 681 FixupKind = RISCV::fixup_riscv_qc_e_32; 682 RelaxCandidate = true; 683 } else if (MIFrm == RISCVII::InstFormatQC_EJ) { 684 FixupKind = RISCV::fixup_riscv_qc_e_call_plt; 685 RelaxCandidate = true; 686 } else if (MIFrm == RISCVII::InstFormatNDS_BRANCH_10) { 687 FixupKind = RISCV::fixup_riscv_nds_branch_10; 688 } 689 } 690 691 assert(FixupKind != RISCV::fixup_riscv_invalid && "Unhandled expression!"); 692 693 addFixup(Fixups, 0, Expr, FixupKind); 694 // If linker relaxation is enabled and supported by this relocation, set a bit 695 // so that the assembler knows the size of the instruction is not fixed/known, 696 // and the relocation will need a R_RISCV_RELAX relocation. 697 if (EnableRelax && RelaxCandidate) 698 Fixups.back().setLinkerRelaxable(); 699 ++MCNumFixups; 700 701 return 0; 702 } 703 704 unsigned RISCVMCCodeEmitter::getVMaskReg(const MCInst &MI, unsigned OpNo, 705 SmallVectorImpl<MCFixup> &Fixups, 706 const MCSubtargetInfo &STI) const { 707 MCOperand MO = MI.getOperand(OpNo); 708 assert(MO.isReg() && "Expected a register."); 709 710 switch (MO.getReg()) { 711 default: 712 llvm_unreachable("Invalid mask register."); 713 case RISCV::V0: 714 return 0; 715 case RISCV::NoRegister: 716 return 1; 717 } 718 } 719 720 unsigned RISCVMCCodeEmitter::getRlistOpValue(const MCInst &MI, unsigned OpNo, 721 SmallVectorImpl<MCFixup> &Fixups, 722 const MCSubtargetInfo &STI) const { 723 const MCOperand &MO = MI.getOperand(OpNo); 724 assert(MO.isImm() && "Rlist operand must be immediate"); 725 auto Imm = MO.getImm(); 726 assert(Imm >= 4 && "EABI is currently not implemented"); 727 return Imm; 728 } 729 unsigned 730 RISCVMCCodeEmitter::getRlistS0OpValue(const MCInst &MI, unsigned OpNo, 731 SmallVectorImpl<MCFixup> &Fixups, 732 const MCSubtargetInfo &STI) const { 733 const MCOperand &MO = MI.getOperand(OpNo); 734 assert(MO.isImm() && "Rlist operand must be immediate"); 735 auto Imm = MO.getImm(); 736 assert(Imm >= 4 && "EABI is currently not implemented"); 737 assert(Imm != RISCVZC::RA && "Rlist operand must include s0"); 738 return Imm; 739 } 740 741 #include "RISCVGenMCCodeEmitter.inc" 742