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 /// TableGen'erated function for getting the binary encoding for an 65 /// instruction. 66 uint64_t getBinaryCodeForInstr(const MCInst &MI, 67 SmallVectorImpl<MCFixup> &Fixups, 68 const MCSubtargetInfo &STI) const; 69 70 /// Return binary encoding of operand. If the machine operand requires 71 /// relocation, record the relocation and return zero. 72 unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, 73 SmallVectorImpl<MCFixup> &Fixups, 74 const MCSubtargetInfo &STI) const; 75 76 unsigned getImmOpValueAsr1(const MCInst &MI, unsigned OpNo, 77 SmallVectorImpl<MCFixup> &Fixups, 78 const MCSubtargetInfo &STI) const; 79 80 unsigned getImmOpValue(const MCInst &MI, unsigned OpNo, 81 SmallVectorImpl<MCFixup> &Fixups, 82 const MCSubtargetInfo &STI) const; 83 }; 84 } // end anonymous namespace 85 86 MCCodeEmitter *llvm::createRISCVMCCodeEmitter(const MCInstrInfo &MCII, 87 const MCRegisterInfo &MRI, 88 MCContext &Ctx) { 89 return new RISCVMCCodeEmitter(Ctx, MCII); 90 } 91 92 // Expand PseudoCALL(Reg), PseudoTAIL and PseudoJump to AUIPC and JALR with 93 // relocation types. We expand those pseudo-instructions while encoding them, 94 // meaning AUIPC and JALR won't go through RISCV MC to MC compressed 95 // instruction transformation. This is acceptable because AUIPC has no 16-bit 96 // form and C_JALR has no immediate operand field. We let linker relaxation 97 // deal with it. When linker relaxation is enabled, AUIPC and JALR have a 98 // chance to relax to JAL. 99 // If the C extension is enabled, JAL has a chance relax to C_JAL. 100 void RISCVMCCodeEmitter::expandFunctionCall(const MCInst &MI, raw_ostream &OS, 101 SmallVectorImpl<MCFixup> &Fixups, 102 const MCSubtargetInfo &STI) const { 103 MCInst TmpInst; 104 MCOperand Func; 105 Register Ra; 106 if (MI.getOpcode() == RISCV::PseudoTAIL) { 107 Func = MI.getOperand(0); 108 Ra = RISCV::X6; 109 } else if (MI.getOpcode() == RISCV::PseudoCALLReg) { 110 Func = MI.getOperand(1); 111 Ra = MI.getOperand(0).getReg(); 112 } else if (MI.getOpcode() == RISCV::PseudoCALL) { 113 Func = MI.getOperand(0); 114 Ra = RISCV::X1; 115 } else if (MI.getOpcode() == RISCV::PseudoJump) { 116 Func = MI.getOperand(1); 117 Ra = MI.getOperand(0).getReg(); 118 } 119 uint32_t Binary; 120 121 assert(Func.isExpr() && "Expected expression"); 122 123 const MCExpr *CallExpr = Func.getExpr(); 124 125 // Emit AUIPC Ra, Func with R_RISCV_CALL relocation type. 126 TmpInst = MCInstBuilder(RISCV::AUIPC) 127 .addReg(Ra) 128 .addOperand(MCOperand::createExpr(CallExpr)); 129 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 130 support::endian::write(OS, Binary, support::little); 131 132 if (MI.getOpcode() == RISCV::PseudoTAIL || 133 MI.getOpcode() == RISCV::PseudoJump) 134 // Emit JALR X0, Ra, 0 135 TmpInst = MCInstBuilder(RISCV::JALR).addReg(RISCV::X0).addReg(Ra).addImm(0); 136 else 137 // Emit JALR Ra, Ra, 0 138 TmpInst = MCInstBuilder(RISCV::JALR).addReg(Ra).addReg(Ra).addImm(0); 139 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 140 support::endian::write(OS, Binary, support::little); 141 } 142 143 // Expand PseudoAddTPRel to a simple ADD with the correct relocation. 144 void RISCVMCCodeEmitter::expandAddTPRel(const MCInst &MI, raw_ostream &OS, 145 SmallVectorImpl<MCFixup> &Fixups, 146 const MCSubtargetInfo &STI) const { 147 MCOperand DestReg = MI.getOperand(0); 148 MCOperand SrcReg = MI.getOperand(1); 149 MCOperand TPReg = MI.getOperand(2); 150 assert(TPReg.isReg() && TPReg.getReg() == RISCV::X4 && 151 "Expected thread pointer as second input to TP-relative add"); 152 153 MCOperand SrcSymbol = MI.getOperand(3); 154 assert(SrcSymbol.isExpr() && 155 "Expected expression as third input to TP-relative add"); 156 157 const RISCVMCExpr *Expr = dyn_cast<RISCVMCExpr>(SrcSymbol.getExpr()); 158 assert(Expr && Expr->getKind() == RISCVMCExpr::VK_RISCV_TPREL_ADD && 159 "Expected tprel_add relocation on TP-relative symbol"); 160 161 // Emit the correct tprel_add relocation for the symbol. 162 Fixups.push_back(MCFixup::create( 163 0, Expr, MCFixupKind(RISCV::fixup_riscv_tprel_add), MI.getLoc())); 164 165 // Emit fixup_riscv_relax for tprel_add where the relax feature is enabled. 166 if (STI.getFeatureBits()[RISCV::FeatureRelax]) { 167 const MCConstantExpr *Dummy = MCConstantExpr::create(0, Ctx); 168 Fixups.push_back(MCFixup::create( 169 0, Dummy, MCFixupKind(RISCV::fixup_riscv_relax), MI.getLoc())); 170 } 171 172 // Emit a normal ADD instruction with the given operands. 173 MCInst TmpInst = MCInstBuilder(RISCV::ADD) 174 .addOperand(DestReg) 175 .addOperand(SrcReg) 176 .addOperand(TPReg); 177 uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 178 support::endian::write(OS, Binary, support::little); 179 } 180 181 void RISCVMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, 182 SmallVectorImpl<MCFixup> &Fixups, 183 const MCSubtargetInfo &STI) const { 184 const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); 185 // Get byte count of instruction. 186 unsigned Size = Desc.getSize(); 187 188 if (MI.getOpcode() == RISCV::PseudoCALLReg || 189 MI.getOpcode() == RISCV::PseudoCALL || 190 MI.getOpcode() == RISCV::PseudoTAIL || 191 MI.getOpcode() == RISCV::PseudoJump) { 192 expandFunctionCall(MI, OS, Fixups, STI); 193 MCNumEmitted += 2; 194 return; 195 } 196 197 if (MI.getOpcode() == RISCV::PseudoAddTPRel) { 198 expandAddTPRel(MI, OS, Fixups, STI); 199 MCNumEmitted += 1; 200 return; 201 } 202 203 switch (Size) { 204 default: 205 llvm_unreachable("Unhandled encodeInstruction length!"); 206 case 2: { 207 uint16_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); 208 support::endian::write<uint16_t>(OS, Bits, support::little); 209 break; 210 } 211 case 4: { 212 uint32_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); 213 support::endian::write(OS, Bits, support::little); 214 break; 215 } 216 } 217 218 ++MCNumEmitted; // Keep track of the # of mi's emitted. 219 } 220 221 unsigned 222 RISCVMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO, 223 SmallVectorImpl<MCFixup> &Fixups, 224 const MCSubtargetInfo &STI) const { 225 226 if (MO.isReg()) 227 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()); 228 229 if (MO.isImm()) 230 return static_cast<unsigned>(MO.getImm()); 231 232 llvm_unreachable("Unhandled expression!"); 233 return 0; 234 } 235 236 unsigned 237 RISCVMCCodeEmitter::getImmOpValueAsr1(const MCInst &MI, unsigned OpNo, 238 SmallVectorImpl<MCFixup> &Fixups, 239 const MCSubtargetInfo &STI) const { 240 const MCOperand &MO = MI.getOperand(OpNo); 241 242 if (MO.isImm()) { 243 unsigned Res = MO.getImm(); 244 assert((Res & 1) == 0 && "LSB is non-zero"); 245 return Res >> 1; 246 } 247 248 return getImmOpValue(MI, OpNo, Fixups, STI); 249 } 250 251 unsigned RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo, 252 SmallVectorImpl<MCFixup> &Fixups, 253 const MCSubtargetInfo &STI) const { 254 bool EnableRelax = STI.getFeatureBits()[RISCV::FeatureRelax]; 255 const MCOperand &MO = MI.getOperand(OpNo); 256 257 MCInstrDesc const &Desc = MCII.get(MI.getOpcode()); 258 unsigned MIFrm = Desc.TSFlags & RISCVII::InstFormatMask; 259 260 // If the destination is an immediate, there is nothing to do. 261 if (MO.isImm()) 262 return MO.getImm(); 263 264 assert(MO.isExpr() && 265 "getImmOpValue expects only expressions or immediates"); 266 const MCExpr *Expr = MO.getExpr(); 267 MCExpr::ExprKind Kind = Expr->getKind(); 268 RISCV::Fixups FixupKind = RISCV::fixup_riscv_invalid; 269 bool RelaxCandidate = false; 270 if (Kind == MCExpr::Target) { 271 const RISCVMCExpr *RVExpr = cast<RISCVMCExpr>(Expr); 272 273 switch (RVExpr->getKind()) { 274 case RISCVMCExpr::VK_RISCV_None: 275 case RISCVMCExpr::VK_RISCV_Invalid: 276 case RISCVMCExpr::VK_RISCV_32_PCREL: 277 llvm_unreachable("Unhandled fixup kind!"); 278 case RISCVMCExpr::VK_RISCV_TPREL_ADD: 279 // tprel_add is only used to indicate that a relocation should be emitted 280 // for an add instruction used in TP-relative addressing. It should not be 281 // expanded as if representing an actual instruction operand and so to 282 // encounter it here is an error. 283 llvm_unreachable( 284 "VK_RISCV_TPREL_ADD should not represent an instruction operand"); 285 case RISCVMCExpr::VK_RISCV_LO: 286 if (MIFrm == RISCVII::InstFormatI) 287 FixupKind = RISCV::fixup_riscv_lo12_i; 288 else if (MIFrm == RISCVII::InstFormatS) 289 FixupKind = RISCV::fixup_riscv_lo12_s; 290 else 291 llvm_unreachable("VK_RISCV_LO used with unexpected instruction format"); 292 RelaxCandidate = true; 293 break; 294 case RISCVMCExpr::VK_RISCV_HI: 295 FixupKind = RISCV::fixup_riscv_hi20; 296 RelaxCandidate = true; 297 break; 298 case RISCVMCExpr::VK_RISCV_PCREL_LO: 299 if (MIFrm == RISCVII::InstFormatI) 300 FixupKind = RISCV::fixup_riscv_pcrel_lo12_i; 301 else if (MIFrm == RISCVII::InstFormatS) 302 FixupKind = RISCV::fixup_riscv_pcrel_lo12_s; 303 else 304 llvm_unreachable( 305 "VK_RISCV_PCREL_LO used with unexpected instruction format"); 306 RelaxCandidate = true; 307 break; 308 case RISCVMCExpr::VK_RISCV_PCREL_HI: 309 FixupKind = RISCV::fixup_riscv_pcrel_hi20; 310 RelaxCandidate = true; 311 break; 312 case RISCVMCExpr::VK_RISCV_GOT_HI: 313 FixupKind = RISCV::fixup_riscv_got_hi20; 314 break; 315 case RISCVMCExpr::VK_RISCV_TPREL_LO: 316 if (MIFrm == RISCVII::InstFormatI) 317 FixupKind = RISCV::fixup_riscv_tprel_lo12_i; 318 else if (MIFrm == RISCVII::InstFormatS) 319 FixupKind = RISCV::fixup_riscv_tprel_lo12_s; 320 else 321 llvm_unreachable( 322 "VK_RISCV_TPREL_LO used with unexpected instruction format"); 323 RelaxCandidate = true; 324 break; 325 case RISCVMCExpr::VK_RISCV_TPREL_HI: 326 FixupKind = RISCV::fixup_riscv_tprel_hi20; 327 RelaxCandidate = true; 328 break; 329 case RISCVMCExpr::VK_RISCV_TLS_GOT_HI: 330 FixupKind = RISCV::fixup_riscv_tls_got_hi20; 331 break; 332 case RISCVMCExpr::VK_RISCV_TLS_GD_HI: 333 FixupKind = RISCV::fixup_riscv_tls_gd_hi20; 334 break; 335 case RISCVMCExpr::VK_RISCV_CALL: 336 FixupKind = RISCV::fixup_riscv_call; 337 RelaxCandidate = true; 338 break; 339 case RISCVMCExpr::VK_RISCV_CALL_PLT: 340 FixupKind = RISCV::fixup_riscv_call_plt; 341 RelaxCandidate = true; 342 break; 343 } 344 } else if (Kind == MCExpr::SymbolRef && 345 cast<MCSymbolRefExpr>(Expr)->getKind() == MCSymbolRefExpr::VK_None) { 346 if (Desc.getOpcode() == RISCV::JAL) { 347 FixupKind = RISCV::fixup_riscv_jal; 348 } else if (MIFrm == RISCVII::InstFormatB) { 349 FixupKind = RISCV::fixup_riscv_branch; 350 } else if (MIFrm == RISCVII::InstFormatCJ) { 351 FixupKind = RISCV::fixup_riscv_rvc_jump; 352 } else if (MIFrm == RISCVII::InstFormatCB) { 353 FixupKind = RISCV::fixup_riscv_rvc_branch; 354 } 355 } 356 357 assert(FixupKind != RISCV::fixup_riscv_invalid && "Unhandled expression!"); 358 359 Fixups.push_back( 360 MCFixup::create(0, Expr, MCFixupKind(FixupKind), MI.getLoc())); 361 ++MCNumFixups; 362 363 // Ensure an R_RISCV_RELAX relocation will be emitted if linker relaxation is 364 // enabled and the current fixup will result in a relocation that may be 365 // relaxed. 366 if (EnableRelax && RelaxCandidate) { 367 const MCConstantExpr *Dummy = MCConstantExpr::create(0, Ctx); 368 Fixups.push_back( 369 MCFixup::create(0, Dummy, MCFixupKind(RISCV::fixup_riscv_relax), 370 MI.getLoc())); 371 ++MCNumFixups; 372 } 373 374 return 0; 375 } 376 377 #include "RISCVGenMCCodeEmitter.inc" 378