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 /// TableGen'erated function for getting the binary encoding for an 60 /// instruction. 61 uint64_t getBinaryCodeForInstr(const MCInst &MI, 62 SmallVectorImpl<MCFixup> &Fixups, 63 const MCSubtargetInfo &STI) const; 64 65 /// Return binary encoding of operand. If the machine operand requires 66 /// relocation, record the relocation and return zero. 67 unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, 68 SmallVectorImpl<MCFixup> &Fixups, 69 const MCSubtargetInfo &STI) const; 70 71 unsigned getImmOpValueAsr1(const MCInst &MI, unsigned OpNo, 72 SmallVectorImpl<MCFixup> &Fixups, 73 const MCSubtargetInfo &STI) const; 74 75 unsigned getImmOpValue(const MCInst &MI, unsigned OpNo, 76 SmallVectorImpl<MCFixup> &Fixups, 77 const MCSubtargetInfo &STI) const; 78 }; 79 } // end anonymous namespace 80 81 MCCodeEmitter *llvm::createRISCVMCCodeEmitter(const MCInstrInfo &MCII, 82 const MCRegisterInfo &MRI, 83 MCContext &Ctx) { 84 return new RISCVMCCodeEmitter(Ctx, MCII); 85 } 86 87 // Expand PseudoCALL and PseudoTAIL to AUIPC and JALR with relocation types. 88 // We expand PseudoCALL and PseudoTAIL while encoding, meaning AUIPC and JALR 89 // won't go through RISCV MC to MC compressed instruction transformation. This 90 // is acceptable because AUIPC has no 16-bit form and C_JALR have no immediate 91 // operand field. We let linker relaxation deal with it. When linker 92 // relaxation enabled, AUIPC and JALR have chance relax to JAL. If C extension 93 // is enabled, JAL has chance relax to C_JAL. 94 void RISCVMCCodeEmitter::expandFunctionCall(const MCInst &MI, raw_ostream &OS, 95 SmallVectorImpl<MCFixup> &Fixups, 96 const MCSubtargetInfo &STI) const { 97 MCInst TmpInst; 98 MCOperand Func = MI.getOperand(0); 99 unsigned Ra = (MI.getOpcode() == RISCV::PseudoTAIL) ? RISCV::X6 : RISCV::X1; 100 uint32_t Binary; 101 102 assert(Func.isExpr() && "Expected expression"); 103 104 const MCExpr *CallExpr = Func.getExpr(); 105 106 // Emit AUIPC Ra, Func with R_RISCV_CALL relocation type. 107 TmpInst = MCInstBuilder(RISCV::AUIPC) 108 .addReg(Ra) 109 .addOperand(MCOperand::createExpr(CallExpr)); 110 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 111 support::endian::write(OS, Binary, support::little); 112 113 if (MI.getOpcode() == RISCV::PseudoTAIL) 114 // Emit JALR X0, X6, 0 115 TmpInst = MCInstBuilder(RISCV::JALR).addReg(RISCV::X0).addReg(Ra).addImm(0); 116 else 117 // Emit JALR X1, X1, 0 118 TmpInst = MCInstBuilder(RISCV::JALR).addReg(Ra).addReg(Ra).addImm(0); 119 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 120 support::endian::write(OS, Binary, support::little); 121 } 122 123 void RISCVMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, 124 SmallVectorImpl<MCFixup> &Fixups, 125 const MCSubtargetInfo &STI) const { 126 const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); 127 // Get byte count of instruction. 128 unsigned Size = Desc.getSize(); 129 130 if (MI.getOpcode() == RISCV::PseudoCALL || 131 MI.getOpcode() == RISCV::PseudoTAIL) { 132 expandFunctionCall(MI, OS, Fixups, STI); 133 MCNumEmitted += 2; 134 return; 135 } 136 137 switch (Size) { 138 default: 139 llvm_unreachable("Unhandled encodeInstruction length!"); 140 case 2: { 141 uint16_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); 142 support::endian::write<uint16_t>(OS, Bits, support::little); 143 break; 144 } 145 case 4: { 146 uint32_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); 147 support::endian::write(OS, Bits, support::little); 148 break; 149 } 150 } 151 152 ++MCNumEmitted; // Keep track of the # of mi's emitted. 153 } 154 155 unsigned 156 RISCVMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO, 157 SmallVectorImpl<MCFixup> &Fixups, 158 const MCSubtargetInfo &STI) const { 159 160 if (MO.isReg()) 161 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()); 162 163 if (MO.isImm()) 164 return static_cast<unsigned>(MO.getImm()); 165 166 llvm_unreachable("Unhandled expression!"); 167 return 0; 168 } 169 170 unsigned 171 RISCVMCCodeEmitter::getImmOpValueAsr1(const MCInst &MI, unsigned OpNo, 172 SmallVectorImpl<MCFixup> &Fixups, 173 const MCSubtargetInfo &STI) const { 174 const MCOperand &MO = MI.getOperand(OpNo); 175 176 if (MO.isImm()) { 177 unsigned Res = MO.getImm(); 178 assert((Res & 1) == 0 && "LSB is non-zero"); 179 return Res >> 1; 180 } 181 182 return getImmOpValue(MI, OpNo, Fixups, STI); 183 } 184 185 unsigned RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo, 186 SmallVectorImpl<MCFixup> &Fixups, 187 const MCSubtargetInfo &STI) const { 188 bool EnableRelax = STI.getFeatureBits()[RISCV::FeatureRelax]; 189 const MCOperand &MO = MI.getOperand(OpNo); 190 191 MCInstrDesc const &Desc = MCII.get(MI.getOpcode()); 192 unsigned MIFrm = Desc.TSFlags & RISCVII::InstFormatMask; 193 194 // If the destination is an immediate, there is nothing to do. 195 if (MO.isImm()) 196 return MO.getImm(); 197 198 assert(MO.isExpr() && 199 "getImmOpValue expects only expressions or immediates"); 200 const MCExpr *Expr = MO.getExpr(); 201 MCExpr::ExprKind Kind = Expr->getKind(); 202 RISCV::Fixups FixupKind = RISCV::fixup_riscv_invalid; 203 bool RelaxCandidate = false; 204 if (Kind == MCExpr::Target) { 205 const RISCVMCExpr *RVExpr = cast<RISCVMCExpr>(Expr); 206 207 switch (RVExpr->getKind()) { 208 case RISCVMCExpr::VK_RISCV_None: 209 case RISCVMCExpr::VK_RISCV_Invalid: 210 llvm_unreachable("Unhandled fixup kind!"); 211 case RISCVMCExpr::VK_RISCV_LO: 212 if (MIFrm == RISCVII::InstFormatI) 213 FixupKind = RISCV::fixup_riscv_lo12_i; 214 else if (MIFrm == RISCVII::InstFormatS) 215 FixupKind = RISCV::fixup_riscv_lo12_s; 216 else 217 llvm_unreachable("VK_RISCV_LO used with unexpected instruction format"); 218 RelaxCandidate = true; 219 break; 220 case RISCVMCExpr::VK_RISCV_HI: 221 FixupKind = RISCV::fixup_riscv_hi20; 222 RelaxCandidate = true; 223 break; 224 case RISCVMCExpr::VK_RISCV_PCREL_LO: 225 if (MIFrm == RISCVII::InstFormatI) 226 FixupKind = RISCV::fixup_riscv_pcrel_lo12_i; 227 else if (MIFrm == RISCVII::InstFormatS) 228 FixupKind = RISCV::fixup_riscv_pcrel_lo12_s; 229 else 230 llvm_unreachable( 231 "VK_RISCV_PCREL_LO used with unexpected instruction format"); 232 RelaxCandidate = true; 233 break; 234 case RISCVMCExpr::VK_RISCV_PCREL_HI: 235 FixupKind = RISCV::fixup_riscv_pcrel_hi20; 236 RelaxCandidate = true; 237 break; 238 case RISCVMCExpr::VK_RISCV_GOT_HI: 239 FixupKind = RISCV::fixup_riscv_got_hi20; 240 break; 241 case RISCVMCExpr::VK_RISCV_CALL: 242 FixupKind = RISCV::fixup_riscv_call; 243 RelaxCandidate = true; 244 break; 245 case RISCVMCExpr::VK_RISCV_CALL_PLT: 246 FixupKind = RISCV::fixup_riscv_call_plt; 247 RelaxCandidate = true; 248 break; 249 } 250 } else if (Kind == MCExpr::SymbolRef && 251 cast<MCSymbolRefExpr>(Expr)->getKind() == MCSymbolRefExpr::VK_None) { 252 if (Desc.getOpcode() == RISCV::JAL) { 253 FixupKind = RISCV::fixup_riscv_jal; 254 } else if (MIFrm == RISCVII::InstFormatB) { 255 FixupKind = RISCV::fixup_riscv_branch; 256 } else if (MIFrm == RISCVII::InstFormatCJ) { 257 FixupKind = RISCV::fixup_riscv_rvc_jump; 258 } else if (MIFrm == RISCVII::InstFormatCB) { 259 FixupKind = RISCV::fixup_riscv_rvc_branch; 260 } 261 } 262 263 assert(FixupKind != RISCV::fixup_riscv_invalid && "Unhandled expression!"); 264 265 Fixups.push_back( 266 MCFixup::create(0, Expr, MCFixupKind(FixupKind), MI.getLoc())); 267 ++MCNumFixups; 268 269 // Ensure an R_RISCV_RELAX relocation will be emitted if linker relaxation is 270 // enabled and the current fixup will result in a relocation that may be 271 // relaxed. 272 if (EnableRelax && RelaxCandidate) { 273 const MCConstantExpr *Dummy = MCConstantExpr::create(0, Ctx); 274 Fixups.push_back( 275 MCFixup::create(0, Dummy, MCFixupKind(RISCV::fixup_riscv_relax), 276 MI.getLoc())); 277 ++MCNumFixups; 278 } 279 280 return 0; 281 } 282 283 #include "RISCVGenMCCodeEmitter.inc" 284