1 //===-- RISCVMCCodeEmitter.cpp - Convert RISCV 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/RISCVFixupKinds.h" 14 #include "MCTargetDesc/RISCVMCExpr.h" 15 #include "MCTargetDesc/RISCVMCTargetDesc.h" 16 #include "Utils/RISCVBaseInfo.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/MCSymbol.h" 27 #include "llvm/Support/Casting.h" 28 #include "llvm/Support/EndianStream.h" 29 #include "llvm/Support/raw_ostream.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 {} 50 51 void encodeInstruction(const MCInst &MI, raw_ostream &OS, 52 SmallVectorImpl<MCFixup> &Fixups, 53 const MCSubtargetInfo &STI) const override; 54 55 void expandFunctionCall(const MCInst &MI, raw_ostream &OS, 56 SmallVectorImpl<MCFixup> &Fixups, 57 const MCSubtargetInfo &STI) const; 58 59 void expandAddTPRel(const MCInst &MI, raw_ostream &OS, 60 SmallVectorImpl<MCFixup> &Fixups, 61 const MCSubtargetInfo &STI) const; 62 63 void expandVMSGE(const MCInst &MI, raw_ostream &OS, 64 SmallVectorImpl<MCFixup> &Fixups, 65 const MCSubtargetInfo &STI) const; 66 67 /// TableGen'erated function for getting the binary encoding for an 68 /// instruction. 69 uint64_t getBinaryCodeForInstr(const MCInst &MI, 70 SmallVectorImpl<MCFixup> &Fixups, 71 const MCSubtargetInfo &STI) const; 72 73 /// Return binary encoding of operand. If the machine operand requires 74 /// relocation, record the relocation and return zero. 75 unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, 76 SmallVectorImpl<MCFixup> &Fixups, 77 const MCSubtargetInfo &STI) const; 78 79 unsigned getImmOpValueAsr1(const MCInst &MI, unsigned OpNo, 80 SmallVectorImpl<MCFixup> &Fixups, 81 const MCSubtargetInfo &STI) const; 82 83 unsigned getImmOpValue(const MCInst &MI, unsigned OpNo, 84 SmallVectorImpl<MCFixup> &Fixups, 85 const MCSubtargetInfo &STI) const; 86 87 unsigned getVMaskReg(const MCInst &MI, unsigned OpNo, 88 SmallVectorImpl<MCFixup> &Fixups, 89 const MCSubtargetInfo &STI) const; 90 91 private: 92 FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const; 93 void 94 verifyInstructionPredicates(const MCInst &MI, 95 const FeatureBitset &AvailableFeatures) const; 96 }; 97 } // end anonymous namespace 98 99 MCCodeEmitter *llvm::createRISCVMCCodeEmitter(const MCInstrInfo &MCII, 100 const MCRegisterInfo &MRI, 101 MCContext &Ctx) { 102 return new RISCVMCCodeEmitter(Ctx, MCII); 103 } 104 105 // Expand PseudoCALL(Reg), PseudoTAIL and PseudoJump to AUIPC and JALR with 106 // relocation types. We expand those pseudo-instructions while encoding them, 107 // meaning AUIPC and JALR won't go through RISCV MC to MC compressed 108 // instruction transformation. This is acceptable because AUIPC has no 16-bit 109 // form and C_JALR has no immediate operand field. We let linker relaxation 110 // deal with it. When linker relaxation is enabled, AUIPC and JALR have a 111 // chance to relax to JAL. 112 // If the C extension is enabled, JAL has a chance relax to C_JAL. 113 void RISCVMCCodeEmitter::expandFunctionCall(const MCInst &MI, raw_ostream &OS, 114 SmallVectorImpl<MCFixup> &Fixups, 115 const MCSubtargetInfo &STI) const { 116 MCInst TmpInst; 117 MCOperand Func; 118 MCRegister Ra; 119 if (MI.getOpcode() == RISCV::PseudoTAIL) { 120 Func = MI.getOperand(0); 121 Ra = RISCV::X6; 122 } else if (MI.getOpcode() == RISCV::PseudoCALLReg) { 123 Func = MI.getOperand(1); 124 Ra = MI.getOperand(0).getReg(); 125 } else if (MI.getOpcode() == RISCV::PseudoCALL) { 126 Func = MI.getOperand(0); 127 Ra = RISCV::X1; 128 } else if (MI.getOpcode() == RISCV::PseudoJump) { 129 Func = MI.getOperand(1); 130 Ra = MI.getOperand(0).getReg(); 131 } 132 uint32_t Binary; 133 134 assert(Func.isExpr() && "Expected expression"); 135 136 const MCExpr *CallExpr = Func.getExpr(); 137 138 // Emit AUIPC Ra, Func with R_RISCV_CALL relocation type. 139 TmpInst = MCInstBuilder(RISCV::AUIPC) 140 .addReg(Ra) 141 .addOperand(MCOperand::createExpr(CallExpr)); 142 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 143 support::endian::write(OS, Binary, support::little); 144 145 if (MI.getOpcode() == RISCV::PseudoTAIL || 146 MI.getOpcode() == RISCV::PseudoJump) 147 // Emit JALR X0, Ra, 0 148 TmpInst = MCInstBuilder(RISCV::JALR).addReg(RISCV::X0).addReg(Ra).addImm(0); 149 else 150 // Emit JALR Ra, Ra, 0 151 TmpInst = MCInstBuilder(RISCV::JALR).addReg(Ra).addReg(Ra).addImm(0); 152 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 153 support::endian::write(OS, Binary, support::little); 154 } 155 156 // Expand PseudoAddTPRel to a simple ADD with the correct relocation. 157 void RISCVMCCodeEmitter::expandAddTPRel(const MCInst &MI, raw_ostream &OS, 158 SmallVectorImpl<MCFixup> &Fixups, 159 const MCSubtargetInfo &STI) const { 160 MCOperand DestReg = MI.getOperand(0); 161 MCOperand SrcReg = MI.getOperand(1); 162 MCOperand TPReg = MI.getOperand(2); 163 assert(TPReg.isReg() && TPReg.getReg() == RISCV::X4 && 164 "Expected thread pointer as second input to TP-relative add"); 165 166 MCOperand SrcSymbol = MI.getOperand(3); 167 assert(SrcSymbol.isExpr() && 168 "Expected expression as third input to TP-relative add"); 169 170 const RISCVMCExpr *Expr = dyn_cast<RISCVMCExpr>(SrcSymbol.getExpr()); 171 assert(Expr && Expr->getKind() == RISCVMCExpr::VK_RISCV_TPREL_ADD && 172 "Expected tprel_add relocation on TP-relative symbol"); 173 174 // Emit the correct tprel_add relocation for the symbol. 175 Fixups.push_back(MCFixup::create( 176 0, Expr, MCFixupKind(RISCV::fixup_riscv_tprel_add), MI.getLoc())); 177 178 // Emit fixup_riscv_relax for tprel_add where the relax feature is enabled. 179 if (STI.getFeatureBits()[RISCV::FeatureRelax]) { 180 const MCConstantExpr *Dummy = MCConstantExpr::create(0, Ctx); 181 Fixups.push_back(MCFixup::create( 182 0, Dummy, MCFixupKind(RISCV::fixup_riscv_relax), MI.getLoc())); 183 } 184 185 // Emit a normal ADD instruction with the given operands. 186 MCInst TmpInst = MCInstBuilder(RISCV::ADD) 187 .addOperand(DestReg) 188 .addOperand(SrcReg) 189 .addOperand(TPReg); 190 uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 191 support::endian::write(OS, Binary, support::little); 192 } 193 194 void RISCVMCCodeEmitter::expandVMSGE(const MCInst &MI, raw_ostream &OS, 195 SmallVectorImpl<MCFixup> &Fixups, 196 const MCSubtargetInfo &STI) const { 197 MCInst TmpInst; 198 uint32_t Binary; 199 unsigned Opcode; 200 switch (MI.getOpcode()) { 201 default: 202 llvm_unreachable("Unexpacted opcode. It should be vmsgeu.vx or vmsge.vx."); 203 case RISCV::PseudoVMSGEU_VX: 204 case RISCV::PseudoVMSGEU_VX_M: 205 case RISCV::PseudoVMSGEU_VX_M_T: 206 Opcode = RISCV::VMSLTU_VX; 207 break; 208 case RISCV::PseudoVMSGE_VX: 209 case RISCV::PseudoVMSGE_VX_M: 210 case RISCV::PseudoVMSGE_VX_M_T: 211 Opcode = RISCV::VMSLT_VX; 212 break; 213 } 214 if (MI.getNumOperands() == 3) { 215 // unmasked va >= x 216 // 217 // pseudoinstruction: vmsge{u}.vx vd, va, x 218 // expansion: vmslt{u}.vx vd, va, x; vmnand.mm vd, vd, vd 219 TmpInst = MCInstBuilder(Opcode) 220 .addOperand(MI.getOperand(0)) 221 .addOperand(MI.getOperand(1)) 222 .addOperand(MI.getOperand(2)) 223 .addReg(RISCV::NoRegister); 224 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 225 support::endian::write(OS, Binary, support::little); 226 227 TmpInst = MCInstBuilder(RISCV::VMNAND_MM) 228 .addOperand(MI.getOperand(0)) 229 .addOperand(MI.getOperand(0)) 230 .addOperand(MI.getOperand(0)); 231 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 232 support::endian::write(OS, Binary, support::little); 233 } else if (MI.getNumOperands() == 4) { 234 // masked va >= x, vd != v0 235 // 236 // pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t 237 // expansion: vmslt{u}.vx vd, va, x, v0.t; vmxor.mm vd, vd, v0 238 assert(MI.getOperand(0).getReg() != RISCV::V0 && 239 "The destination register should not be V0."); 240 TmpInst = MCInstBuilder(Opcode) 241 .addOperand(MI.getOperand(0)) 242 .addOperand(MI.getOperand(1)) 243 .addOperand(MI.getOperand(2)) 244 .addOperand(MI.getOperand(3)); 245 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 246 support::endian::write(OS, Binary, support::little); 247 248 TmpInst = MCInstBuilder(RISCV::VMXOR_MM) 249 .addOperand(MI.getOperand(0)) 250 .addOperand(MI.getOperand(0)) 251 .addReg(RISCV::V0); 252 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 253 support::endian::write(OS, Binary, support::little); 254 } else if (MI.getNumOperands() == 5) { 255 // masked va >= x, vd == v0 256 // 257 // pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t, vt 258 // expansion: vmslt{u}.vx vt, va, x; vmandnot.mm vd, vd, vt 259 assert(MI.getOperand(0).getReg() == RISCV::V0 && 260 "The destination register should be V0."); 261 assert(MI.getOperand(1).getReg() != RISCV::V0 && 262 "The temporary vector register should not be V0."); 263 TmpInst = MCInstBuilder(Opcode) 264 .addOperand(MI.getOperand(1)) 265 .addOperand(MI.getOperand(2)) 266 .addOperand(MI.getOperand(3)) 267 .addOperand(MI.getOperand(4)); 268 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 269 support::endian::write(OS, Binary, support::little); 270 271 TmpInst = MCInstBuilder(RISCV::VMANDNOT_MM) 272 .addOperand(MI.getOperand(0)) 273 .addOperand(MI.getOperand(0)) 274 .addOperand(MI.getOperand(1)); 275 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 276 support::endian::write(OS, Binary, support::little); 277 } 278 } 279 280 void RISCVMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, 281 SmallVectorImpl<MCFixup> &Fixups, 282 const MCSubtargetInfo &STI) const { 283 verifyInstructionPredicates(MI, 284 computeAvailableFeatures(STI.getFeatureBits())); 285 286 const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); 287 // Get byte count of instruction. 288 unsigned Size = Desc.getSize(); 289 290 // RISCVInstrInfo::getInstSizeInBytes hard-codes the number of expanded 291 // instructions for each pseudo, and must be updated when adding new pseudos 292 // or changing existing ones. 293 if (MI.getOpcode() == RISCV::PseudoCALLReg || 294 MI.getOpcode() == RISCV::PseudoCALL || 295 MI.getOpcode() == RISCV::PseudoTAIL || 296 MI.getOpcode() == RISCV::PseudoJump) { 297 expandFunctionCall(MI, OS, Fixups, STI); 298 MCNumEmitted += 2; 299 return; 300 } 301 302 if (MI.getOpcode() == RISCV::PseudoAddTPRel) { 303 expandAddTPRel(MI, OS, Fixups, STI); 304 MCNumEmitted += 1; 305 return; 306 } 307 308 if (MI.getOpcode() == RISCV::PseudoVMSGEU_VX || 309 MI.getOpcode() == RISCV::PseudoVMSGE_VX || 310 MI.getOpcode() == RISCV::PseudoVMSGEU_VX_M || 311 MI.getOpcode() == RISCV::PseudoVMSGE_VX_M || 312 MI.getOpcode() == RISCV::PseudoVMSGEU_VX_M_T || 313 MI.getOpcode() == RISCV::PseudoVMSGE_VX_M_T) { 314 expandVMSGE(MI, OS, Fixups, STI); 315 return; 316 } 317 318 switch (Size) { 319 default: 320 llvm_unreachable("Unhandled encodeInstruction length!"); 321 case 2: { 322 uint16_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); 323 support::endian::write<uint16_t>(OS, Bits, support::little); 324 break; 325 } 326 case 4: { 327 uint32_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); 328 support::endian::write(OS, Bits, support::little); 329 break; 330 } 331 } 332 333 ++MCNumEmitted; // Keep track of the # of mi's emitted. 334 } 335 336 unsigned 337 RISCVMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO, 338 SmallVectorImpl<MCFixup> &Fixups, 339 const MCSubtargetInfo &STI) const { 340 341 if (MO.isReg()) 342 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()); 343 344 if (MO.isImm()) 345 return static_cast<unsigned>(MO.getImm()); 346 347 llvm_unreachable("Unhandled expression!"); 348 return 0; 349 } 350 351 unsigned 352 RISCVMCCodeEmitter::getImmOpValueAsr1(const MCInst &MI, unsigned OpNo, 353 SmallVectorImpl<MCFixup> &Fixups, 354 const MCSubtargetInfo &STI) const { 355 const MCOperand &MO = MI.getOperand(OpNo); 356 357 if (MO.isImm()) { 358 unsigned Res = MO.getImm(); 359 assert((Res & 1) == 0 && "LSB is non-zero"); 360 return Res >> 1; 361 } 362 363 return getImmOpValue(MI, OpNo, Fixups, STI); 364 } 365 366 unsigned RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo, 367 SmallVectorImpl<MCFixup> &Fixups, 368 const MCSubtargetInfo &STI) const { 369 bool EnableRelax = STI.getFeatureBits()[RISCV::FeatureRelax]; 370 const MCOperand &MO = MI.getOperand(OpNo); 371 372 MCInstrDesc const &Desc = MCII.get(MI.getOpcode()); 373 unsigned MIFrm = Desc.TSFlags & RISCVII::InstFormatMask; 374 375 // If the destination is an immediate, there is nothing to do. 376 if (MO.isImm()) 377 return MO.getImm(); 378 379 assert(MO.isExpr() && 380 "getImmOpValue expects only expressions or immediates"); 381 const MCExpr *Expr = MO.getExpr(); 382 MCExpr::ExprKind Kind = Expr->getKind(); 383 RISCV::Fixups FixupKind = RISCV::fixup_riscv_invalid; 384 bool RelaxCandidate = false; 385 if (Kind == MCExpr::Target) { 386 const RISCVMCExpr *RVExpr = cast<RISCVMCExpr>(Expr); 387 388 switch (RVExpr->getKind()) { 389 case RISCVMCExpr::VK_RISCV_None: 390 case RISCVMCExpr::VK_RISCV_Invalid: 391 case RISCVMCExpr::VK_RISCV_32_PCREL: 392 llvm_unreachable("Unhandled fixup kind!"); 393 case RISCVMCExpr::VK_RISCV_TPREL_ADD: 394 // tprel_add is only used to indicate that a relocation should be emitted 395 // for an add instruction used in TP-relative addressing. It should not be 396 // expanded as if representing an actual instruction operand and so to 397 // encounter it here is an error. 398 llvm_unreachable( 399 "VK_RISCV_TPREL_ADD should not represent an instruction operand"); 400 case RISCVMCExpr::VK_RISCV_LO: 401 if (MIFrm == RISCVII::InstFormatI) 402 FixupKind = RISCV::fixup_riscv_lo12_i; 403 else if (MIFrm == RISCVII::InstFormatS) 404 FixupKind = RISCV::fixup_riscv_lo12_s; 405 else 406 llvm_unreachable("VK_RISCV_LO used with unexpected instruction format"); 407 RelaxCandidate = true; 408 break; 409 case RISCVMCExpr::VK_RISCV_HI: 410 FixupKind = RISCV::fixup_riscv_hi20; 411 RelaxCandidate = true; 412 break; 413 case RISCVMCExpr::VK_RISCV_PCREL_LO: 414 if (MIFrm == RISCVII::InstFormatI) 415 FixupKind = RISCV::fixup_riscv_pcrel_lo12_i; 416 else if (MIFrm == RISCVII::InstFormatS) 417 FixupKind = RISCV::fixup_riscv_pcrel_lo12_s; 418 else 419 llvm_unreachable( 420 "VK_RISCV_PCREL_LO used with unexpected instruction format"); 421 RelaxCandidate = true; 422 break; 423 case RISCVMCExpr::VK_RISCV_PCREL_HI: 424 FixupKind = RISCV::fixup_riscv_pcrel_hi20; 425 RelaxCandidate = true; 426 break; 427 case RISCVMCExpr::VK_RISCV_GOT_HI: 428 FixupKind = RISCV::fixup_riscv_got_hi20; 429 break; 430 case RISCVMCExpr::VK_RISCV_TPREL_LO: 431 if (MIFrm == RISCVII::InstFormatI) 432 FixupKind = RISCV::fixup_riscv_tprel_lo12_i; 433 else if (MIFrm == RISCVII::InstFormatS) 434 FixupKind = RISCV::fixup_riscv_tprel_lo12_s; 435 else 436 llvm_unreachable( 437 "VK_RISCV_TPREL_LO used with unexpected instruction format"); 438 RelaxCandidate = true; 439 break; 440 case RISCVMCExpr::VK_RISCV_TPREL_HI: 441 FixupKind = RISCV::fixup_riscv_tprel_hi20; 442 RelaxCandidate = true; 443 break; 444 case RISCVMCExpr::VK_RISCV_TLS_GOT_HI: 445 FixupKind = RISCV::fixup_riscv_tls_got_hi20; 446 break; 447 case RISCVMCExpr::VK_RISCV_TLS_GD_HI: 448 FixupKind = RISCV::fixup_riscv_tls_gd_hi20; 449 break; 450 case RISCVMCExpr::VK_RISCV_CALL: 451 FixupKind = RISCV::fixup_riscv_call; 452 RelaxCandidate = true; 453 break; 454 case RISCVMCExpr::VK_RISCV_CALL_PLT: 455 FixupKind = RISCV::fixup_riscv_call_plt; 456 RelaxCandidate = true; 457 break; 458 } 459 } else if (Kind == MCExpr::SymbolRef && 460 cast<MCSymbolRefExpr>(Expr)->getKind() == MCSymbolRefExpr::VK_None) { 461 if (Desc.getOpcode() == RISCV::JAL) { 462 FixupKind = RISCV::fixup_riscv_jal; 463 } else if (MIFrm == RISCVII::InstFormatB) { 464 FixupKind = RISCV::fixup_riscv_branch; 465 } else if (MIFrm == RISCVII::InstFormatCJ) { 466 FixupKind = RISCV::fixup_riscv_rvc_jump; 467 } else if (MIFrm == RISCVII::InstFormatCB) { 468 FixupKind = RISCV::fixup_riscv_rvc_branch; 469 } 470 } 471 472 assert(FixupKind != RISCV::fixup_riscv_invalid && "Unhandled expression!"); 473 474 Fixups.push_back( 475 MCFixup::create(0, Expr, MCFixupKind(FixupKind), MI.getLoc())); 476 ++MCNumFixups; 477 478 // Ensure an R_RISCV_RELAX relocation will be emitted if linker relaxation is 479 // enabled and the current fixup will result in a relocation that may be 480 // relaxed. 481 if (EnableRelax && RelaxCandidate) { 482 const MCConstantExpr *Dummy = MCConstantExpr::create(0, Ctx); 483 Fixups.push_back( 484 MCFixup::create(0, Dummy, MCFixupKind(RISCV::fixup_riscv_relax), 485 MI.getLoc())); 486 ++MCNumFixups; 487 } 488 489 return 0; 490 } 491 492 unsigned RISCVMCCodeEmitter::getVMaskReg(const MCInst &MI, unsigned OpNo, 493 SmallVectorImpl<MCFixup> &Fixups, 494 const MCSubtargetInfo &STI) const { 495 MCOperand MO = MI.getOperand(OpNo); 496 assert(MO.isReg() && "Expected a register."); 497 498 switch (MO.getReg()) { 499 default: 500 llvm_unreachable("Invalid mask register."); 501 case RISCV::V0: 502 return 0; 503 case RISCV::NoRegister: 504 return 1; 505 } 506 } 507 508 #define ENABLE_INSTR_PREDICATE_VERIFIER 509 #include "RISCVGenMCCodeEmitter.inc" 510