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