1311116Sdim//===-- RISCVMCCodeEmitter.cpp - Convert RISCV code to machine code -------===// 2311116Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6311116Sdim// 7311116Sdim//===----------------------------------------------------------------------===// 8311116Sdim// 9311116Sdim// This file implements the RISCVMCCodeEmitter class. 10311116Sdim// 11311116Sdim//===----------------------------------------------------------------------===// 12311116Sdim 13327952Sdim#include "MCTargetDesc/RISCVFixupKinds.h" 14327952Sdim#include "MCTargetDesc/RISCVMCExpr.h" 15311116Sdim#include "MCTargetDesc/RISCVMCTargetDesc.h" 16344779Sdim#include "Utils/RISCVBaseInfo.h" 17311116Sdim#include "llvm/ADT/Statistic.h" 18360784Sdim#include "llvm/CodeGen/Register.h" 19321369Sdim#include "llvm/MC/MCAsmInfo.h" 20311116Sdim#include "llvm/MC/MCCodeEmitter.h" 21311116Sdim#include "llvm/MC/MCContext.h" 22311116Sdim#include "llvm/MC/MCExpr.h" 23311116Sdim#include "llvm/MC/MCInst.h" 24341825Sdim#include "llvm/MC/MCInstBuilder.h" 25327952Sdim#include "llvm/MC/MCInstrInfo.h" 26311116Sdim#include "llvm/MC/MCRegisterInfo.h" 27311116Sdim#include "llvm/MC/MCSymbol.h" 28327952Sdim#include "llvm/Support/Casting.h" 29311116Sdim#include "llvm/Support/EndianStream.h" 30311116Sdim#include "llvm/Support/raw_ostream.h" 31311116Sdim 32311116Sdimusing namespace llvm; 33311116Sdim 34311116Sdim#define DEBUG_TYPE "mccodeemitter" 35311116Sdim 36311116SdimSTATISTIC(MCNumEmitted, "Number of MC instructions emitted"); 37327952SdimSTATISTIC(MCNumFixups, "Number of MC fixups created"); 38311116Sdim 39311116Sdimnamespace { 40311116Sdimclass RISCVMCCodeEmitter : public MCCodeEmitter { 41311116Sdim RISCVMCCodeEmitter(const RISCVMCCodeEmitter &) = delete; 42311116Sdim void operator=(const RISCVMCCodeEmitter &) = delete; 43311116Sdim MCContext &Ctx; 44327952Sdim MCInstrInfo const &MCII; 45311116Sdim 46311116Sdimpublic: 47327952Sdim RISCVMCCodeEmitter(MCContext &ctx, MCInstrInfo const &MCII) 48327952Sdim : Ctx(ctx), MCII(MCII) {} 49311116Sdim 50311116Sdim ~RISCVMCCodeEmitter() override {} 51311116Sdim 52311116Sdim void encodeInstruction(const MCInst &MI, raw_ostream &OS, 53311116Sdim SmallVectorImpl<MCFixup> &Fixups, 54311116Sdim const MCSubtargetInfo &STI) const override; 55311116Sdim 56341825Sdim void expandFunctionCall(const MCInst &MI, raw_ostream &OS, 57341825Sdim SmallVectorImpl<MCFixup> &Fixups, 58341825Sdim const MCSubtargetInfo &STI) const; 59341825Sdim 60353358Sdim void expandAddTPRel(const MCInst &MI, raw_ostream &OS, 61353358Sdim SmallVectorImpl<MCFixup> &Fixups, 62353358Sdim const MCSubtargetInfo &STI) const; 63353358Sdim 64311116Sdim /// TableGen'erated function for getting the binary encoding for an 65311116Sdim /// instruction. 66311116Sdim uint64_t getBinaryCodeForInstr(const MCInst &MI, 67311116Sdim SmallVectorImpl<MCFixup> &Fixups, 68311116Sdim const MCSubtargetInfo &STI) const; 69311116Sdim 70311116Sdim /// Return binary encoding of operand. If the machine operand requires 71311116Sdim /// relocation, record the relocation and return zero. 72311116Sdim unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, 73311116Sdim SmallVectorImpl<MCFixup> &Fixups, 74311116Sdim const MCSubtargetInfo &STI) const; 75327952Sdim 76327952Sdim unsigned getImmOpValueAsr1(const MCInst &MI, unsigned OpNo, 77327952Sdim SmallVectorImpl<MCFixup> &Fixups, 78327952Sdim const MCSubtargetInfo &STI) const; 79327952Sdim 80327952Sdim unsigned getImmOpValue(const MCInst &MI, unsigned OpNo, 81327952Sdim SmallVectorImpl<MCFixup> &Fixups, 82327952Sdim const MCSubtargetInfo &STI) const; 83311116Sdim}; 84311116Sdim} // end anonymous namespace 85311116Sdim 86311116SdimMCCodeEmitter *llvm::createRISCVMCCodeEmitter(const MCInstrInfo &MCII, 87311116Sdim const MCRegisterInfo &MRI, 88311116Sdim MCContext &Ctx) { 89327952Sdim return new RISCVMCCodeEmitter(Ctx, MCII); 90311116Sdim} 91311116Sdim 92353358Sdim// Expand PseudoCALL(Reg) and PseudoTAIL to AUIPC and JALR with relocation 93353358Sdim// types. We expand PseudoCALL(Reg) and PseudoTAIL while encoding, meaning AUIPC 94353358Sdim// and JALR won't go through RISCV MC to MC compressed instruction 95353358Sdim// transformation. This is acceptable because AUIPC has no 16-bit form and 96353358Sdim// C_JALR have no immediate operand field. We let linker relaxation deal with 97353358Sdim// it. When linker relaxation enabled, AUIPC and JALR have chance relax to JAL. 98353358Sdim// If C extension is enabled, JAL has chance relax to C_JAL. 99341825Sdimvoid RISCVMCCodeEmitter::expandFunctionCall(const MCInst &MI, raw_ostream &OS, 100341825Sdim SmallVectorImpl<MCFixup> &Fixups, 101341825Sdim const MCSubtargetInfo &STI) const { 102341825Sdim MCInst TmpInst; 103353358Sdim MCOperand Func; 104360784Sdim Register Ra; 105353358Sdim if (MI.getOpcode() == RISCV::PseudoTAIL) { 106353358Sdim Func = MI.getOperand(0); 107353358Sdim Ra = RISCV::X6; 108353358Sdim } else if (MI.getOpcode() == RISCV::PseudoCALLReg) { 109353358Sdim Func = MI.getOperand(1); 110353358Sdim Ra = MI.getOperand(0).getReg(); 111353358Sdim } else { 112353358Sdim Func = MI.getOperand(0); 113353358Sdim Ra = RISCV::X1; 114353358Sdim } 115341825Sdim uint32_t Binary; 116341825Sdim 117341825Sdim assert(Func.isExpr() && "Expected expression"); 118341825Sdim 119353358Sdim const MCExpr *CallExpr = Func.getExpr(); 120341825Sdim 121341825Sdim // Emit AUIPC Ra, Func with R_RISCV_CALL relocation type. 122341825Sdim TmpInst = MCInstBuilder(RISCV::AUIPC) 123341825Sdim .addReg(Ra) 124341825Sdim .addOperand(MCOperand::createExpr(CallExpr)); 125341825Sdim Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 126341825Sdim support::endian::write(OS, Binary, support::little); 127341825Sdim 128341825Sdim if (MI.getOpcode() == RISCV::PseudoTAIL) 129341825Sdim // Emit JALR X0, X6, 0 130341825Sdim TmpInst = MCInstBuilder(RISCV::JALR).addReg(RISCV::X0).addReg(Ra).addImm(0); 131341825Sdim else 132353358Sdim // Emit JALR Ra, Ra, 0 133341825Sdim TmpInst = MCInstBuilder(RISCV::JALR).addReg(Ra).addReg(Ra).addImm(0); 134341825Sdim Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 135341825Sdim support::endian::write(OS, Binary, support::little); 136341825Sdim} 137341825Sdim 138353358Sdim// Expand PseudoAddTPRel to a simple ADD with the correct relocation. 139353358Sdimvoid RISCVMCCodeEmitter::expandAddTPRel(const MCInst &MI, raw_ostream &OS, 140353358Sdim SmallVectorImpl<MCFixup> &Fixups, 141353358Sdim const MCSubtargetInfo &STI) const { 142353358Sdim MCOperand DestReg = MI.getOperand(0); 143353358Sdim MCOperand SrcReg = MI.getOperand(1); 144353358Sdim MCOperand TPReg = MI.getOperand(2); 145353358Sdim assert(TPReg.isReg() && TPReg.getReg() == RISCV::X4 && 146353358Sdim "Expected thread pointer as second input to TP-relative add"); 147353358Sdim 148353358Sdim MCOperand SrcSymbol = MI.getOperand(3); 149353358Sdim assert(SrcSymbol.isExpr() && 150353358Sdim "Expected expression as third input to TP-relative add"); 151353358Sdim 152353358Sdim const RISCVMCExpr *Expr = dyn_cast<RISCVMCExpr>(SrcSymbol.getExpr()); 153353358Sdim assert(Expr && Expr->getKind() == RISCVMCExpr::VK_RISCV_TPREL_ADD && 154353358Sdim "Expected tprel_add relocation on TP-relative symbol"); 155353358Sdim 156353358Sdim // Emit the correct tprel_add relocation for the symbol. 157353358Sdim Fixups.push_back(MCFixup::create( 158353358Sdim 0, Expr, MCFixupKind(RISCV::fixup_riscv_tprel_add), MI.getLoc())); 159353358Sdim 160353358Sdim // Emit fixup_riscv_relax for tprel_add where the relax feature is enabled. 161353358Sdim if (STI.getFeatureBits()[RISCV::FeatureRelax]) { 162353358Sdim const MCConstantExpr *Dummy = MCConstantExpr::create(0, Ctx); 163353358Sdim Fixups.push_back(MCFixup::create( 164353358Sdim 0, Dummy, MCFixupKind(RISCV::fixup_riscv_relax), MI.getLoc())); 165353358Sdim } 166353358Sdim 167353358Sdim // Emit a normal ADD instruction with the given operands. 168353358Sdim MCInst TmpInst = MCInstBuilder(RISCV::ADD) 169353358Sdim .addOperand(DestReg) 170353358Sdim .addOperand(SrcReg) 171353358Sdim .addOperand(TPReg); 172353358Sdim uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 173353358Sdim support::endian::write(OS, Binary, support::little); 174353358Sdim} 175353358Sdim 176311116Sdimvoid RISCVMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, 177311116Sdim SmallVectorImpl<MCFixup> &Fixups, 178311116Sdim const MCSubtargetInfo &STI) const { 179327952Sdim const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); 180327952Sdim // Get byte count of instruction. 181327952Sdim unsigned Size = Desc.getSize(); 182327952Sdim 183353358Sdim if (MI.getOpcode() == RISCV::PseudoCALLReg || 184353358Sdim MI.getOpcode() == RISCV::PseudoCALL || 185341825Sdim MI.getOpcode() == RISCV::PseudoTAIL) { 186341825Sdim expandFunctionCall(MI, OS, Fixups, STI); 187341825Sdim MCNumEmitted += 2; 188341825Sdim return; 189341825Sdim } 190341825Sdim 191353358Sdim if (MI.getOpcode() == RISCV::PseudoAddTPRel) { 192353358Sdim expandAddTPRel(MI, OS, Fixups, STI); 193353358Sdim MCNumEmitted += 1; 194353358Sdim return; 195353358Sdim } 196353358Sdim 197327952Sdim switch (Size) { 198327952Sdim default: 199327952Sdim llvm_unreachable("Unhandled encodeInstruction length!"); 200327952Sdim case 2: { 201327952Sdim uint16_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); 202341825Sdim support::endian::write<uint16_t>(OS, Bits, support::little); 203327952Sdim break; 204327952Sdim } 205327952Sdim case 4: { 206327952Sdim uint32_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); 207341825Sdim support::endian::write(OS, Bits, support::little); 208327952Sdim break; 209327952Sdim } 210327952Sdim } 211327952Sdim 212311116Sdim ++MCNumEmitted; // Keep track of the # of mi's emitted. 213311116Sdim} 214311116Sdim 215311116Sdimunsigned 216311116SdimRISCVMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO, 217311116Sdim SmallVectorImpl<MCFixup> &Fixups, 218311116Sdim const MCSubtargetInfo &STI) const { 219311116Sdim 220311116Sdim if (MO.isReg()) 221311116Sdim return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()); 222311116Sdim 223311116Sdim if (MO.isImm()) 224311116Sdim return static_cast<unsigned>(MO.getImm()); 225311116Sdim 226311116Sdim llvm_unreachable("Unhandled expression!"); 227311116Sdim return 0; 228311116Sdim} 229311116Sdim 230327952Sdimunsigned 231327952SdimRISCVMCCodeEmitter::getImmOpValueAsr1(const MCInst &MI, unsigned OpNo, 232327952Sdim SmallVectorImpl<MCFixup> &Fixups, 233327952Sdim const MCSubtargetInfo &STI) const { 234327952Sdim const MCOperand &MO = MI.getOperand(OpNo); 235327952Sdim 236327952Sdim if (MO.isImm()) { 237327952Sdim unsigned Res = MO.getImm(); 238327952Sdim assert((Res & 1) == 0 && "LSB is non-zero"); 239327952Sdim return Res >> 1; 240327952Sdim } 241327952Sdim 242327952Sdim return getImmOpValue(MI, OpNo, Fixups, STI); 243327952Sdim} 244327952Sdim 245327952Sdimunsigned RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo, 246327952Sdim SmallVectorImpl<MCFixup> &Fixups, 247327952Sdim const MCSubtargetInfo &STI) const { 248341825Sdim bool EnableRelax = STI.getFeatureBits()[RISCV::FeatureRelax]; 249327952Sdim const MCOperand &MO = MI.getOperand(OpNo); 250327952Sdim 251327952Sdim MCInstrDesc const &Desc = MCII.get(MI.getOpcode()); 252327952Sdim unsigned MIFrm = Desc.TSFlags & RISCVII::InstFormatMask; 253327952Sdim 254344779Sdim // If the destination is an immediate, there is nothing to do. 255327952Sdim if (MO.isImm()) 256327952Sdim return MO.getImm(); 257327952Sdim 258327952Sdim assert(MO.isExpr() && 259327952Sdim "getImmOpValue expects only expressions or immediates"); 260327952Sdim const MCExpr *Expr = MO.getExpr(); 261327952Sdim MCExpr::ExprKind Kind = Expr->getKind(); 262327952Sdim RISCV::Fixups FixupKind = RISCV::fixup_riscv_invalid; 263353358Sdim bool RelaxCandidate = false; 264327952Sdim if (Kind == MCExpr::Target) { 265327952Sdim const RISCVMCExpr *RVExpr = cast<RISCVMCExpr>(Expr); 266327952Sdim 267327952Sdim switch (RVExpr->getKind()) { 268327952Sdim case RISCVMCExpr::VK_RISCV_None: 269327952Sdim case RISCVMCExpr::VK_RISCV_Invalid: 270354469Sdim case RISCVMCExpr::VK_RISCV_32_PCREL: 271327952Sdim llvm_unreachable("Unhandled fixup kind!"); 272353358Sdim case RISCVMCExpr::VK_RISCV_TPREL_ADD: 273353358Sdim // tprel_add is only used to indicate that a relocation should be emitted 274353358Sdim // for an add instruction used in TP-relative addressing. It should not be 275353358Sdim // expanded as if representing an actual instruction operand and so to 276353358Sdim // encounter it here is an error. 277353358Sdim llvm_unreachable( 278353358Sdim "VK_RISCV_TPREL_ADD should not represent an instruction operand"); 279327952Sdim case RISCVMCExpr::VK_RISCV_LO: 280341825Sdim if (MIFrm == RISCVII::InstFormatI) 281341825Sdim FixupKind = RISCV::fixup_riscv_lo12_i; 282341825Sdim else if (MIFrm == RISCVII::InstFormatS) 283341825Sdim FixupKind = RISCV::fixup_riscv_lo12_s; 284341825Sdim else 285341825Sdim llvm_unreachable("VK_RISCV_LO used with unexpected instruction format"); 286353358Sdim RelaxCandidate = true; 287327952Sdim break; 288327952Sdim case RISCVMCExpr::VK_RISCV_HI: 289327952Sdim FixupKind = RISCV::fixup_riscv_hi20; 290353358Sdim RelaxCandidate = true; 291327952Sdim break; 292341825Sdim case RISCVMCExpr::VK_RISCV_PCREL_LO: 293341825Sdim if (MIFrm == RISCVII::InstFormatI) 294341825Sdim FixupKind = RISCV::fixup_riscv_pcrel_lo12_i; 295341825Sdim else if (MIFrm == RISCVII::InstFormatS) 296341825Sdim FixupKind = RISCV::fixup_riscv_pcrel_lo12_s; 297341825Sdim else 298341825Sdim llvm_unreachable( 299341825Sdim "VK_RISCV_PCREL_LO used with unexpected instruction format"); 300353358Sdim RelaxCandidate = true; 301341825Sdim break; 302327952Sdim case RISCVMCExpr::VK_RISCV_PCREL_HI: 303327952Sdim FixupKind = RISCV::fixup_riscv_pcrel_hi20; 304353358Sdim RelaxCandidate = true; 305327952Sdim break; 306353358Sdim case RISCVMCExpr::VK_RISCV_GOT_HI: 307353358Sdim FixupKind = RISCV::fixup_riscv_got_hi20; 308353358Sdim break; 309353358Sdim case RISCVMCExpr::VK_RISCV_TPREL_LO: 310353358Sdim if (MIFrm == RISCVII::InstFormatI) 311353358Sdim FixupKind = RISCV::fixup_riscv_tprel_lo12_i; 312353358Sdim else if (MIFrm == RISCVII::InstFormatS) 313353358Sdim FixupKind = RISCV::fixup_riscv_tprel_lo12_s; 314353358Sdim else 315353358Sdim llvm_unreachable( 316353358Sdim "VK_RISCV_TPREL_LO used with unexpected instruction format"); 317353358Sdim RelaxCandidate = true; 318353358Sdim break; 319353358Sdim case RISCVMCExpr::VK_RISCV_TPREL_HI: 320353358Sdim FixupKind = RISCV::fixup_riscv_tprel_hi20; 321353358Sdim RelaxCandidate = true; 322353358Sdim break; 323353358Sdim case RISCVMCExpr::VK_RISCV_TLS_GOT_HI: 324353358Sdim FixupKind = RISCV::fixup_riscv_tls_got_hi20; 325353358Sdim break; 326353358Sdim case RISCVMCExpr::VK_RISCV_TLS_GD_HI: 327353358Sdim FixupKind = RISCV::fixup_riscv_tls_gd_hi20; 328353358Sdim break; 329341825Sdim case RISCVMCExpr::VK_RISCV_CALL: 330341825Sdim FixupKind = RISCV::fixup_riscv_call; 331353358Sdim RelaxCandidate = true; 332341825Sdim break; 333353358Sdim case RISCVMCExpr::VK_RISCV_CALL_PLT: 334353358Sdim FixupKind = RISCV::fixup_riscv_call_plt; 335353358Sdim RelaxCandidate = true; 336353358Sdim break; 337327952Sdim } 338327952Sdim } else if (Kind == MCExpr::SymbolRef && 339327952Sdim cast<MCSymbolRefExpr>(Expr)->getKind() == MCSymbolRefExpr::VK_None) { 340327952Sdim if (Desc.getOpcode() == RISCV::JAL) { 341327952Sdim FixupKind = RISCV::fixup_riscv_jal; 342327952Sdim } else if (MIFrm == RISCVII::InstFormatB) { 343327952Sdim FixupKind = RISCV::fixup_riscv_branch; 344327952Sdim } else if (MIFrm == RISCVII::InstFormatCJ) { 345327952Sdim FixupKind = RISCV::fixup_riscv_rvc_jump; 346327952Sdim } else if (MIFrm == RISCVII::InstFormatCB) { 347327952Sdim FixupKind = RISCV::fixup_riscv_rvc_branch; 348327952Sdim } 349327952Sdim } 350327952Sdim 351327952Sdim assert(FixupKind != RISCV::fixup_riscv_invalid && "Unhandled expression!"); 352327952Sdim 353327952Sdim Fixups.push_back( 354327952Sdim MCFixup::create(0, Expr, MCFixupKind(FixupKind), MI.getLoc())); 355327952Sdim ++MCNumFixups; 356327952Sdim 357353358Sdim // Ensure an R_RISCV_RELAX relocation will be emitted if linker relaxation is 358353358Sdim // enabled and the current fixup will result in a relocation that may be 359353358Sdim // relaxed. 360353358Sdim if (EnableRelax && RelaxCandidate) { 361353358Sdim const MCConstantExpr *Dummy = MCConstantExpr::create(0, Ctx); 362353358Sdim Fixups.push_back( 363353358Sdim MCFixup::create(0, Dummy, MCFixupKind(RISCV::fixup_riscv_relax), 364353358Sdim MI.getLoc())); 365353358Sdim ++MCNumFixups; 366341825Sdim } 367341825Sdim 368327952Sdim return 0; 369327952Sdim} 370327952Sdim 371311116Sdim#include "RISCVGenMCCodeEmitter.inc" 372