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 *Expr = Func.getExpr(); 105 106 // Create function call expression CallExpr for AUIPC. 107 const MCExpr *CallExpr = 108 RISCVMCExpr::create(Expr, RISCVMCExpr::VK_RISCV_CALL, Ctx); 109 110 // Emit AUIPC Ra, Func with R_RISCV_CALL relocation type. 111 TmpInst = MCInstBuilder(RISCV::AUIPC) 112 .addReg(Ra) 113 .addOperand(MCOperand::createExpr(CallExpr)); 114 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 115 support::endian::write(OS, Binary, support::little); 116 117 if (MI.getOpcode() == RISCV::PseudoTAIL) 118 // Emit JALR X0, X6, 0 119 TmpInst = MCInstBuilder(RISCV::JALR).addReg(RISCV::X0).addReg(Ra).addImm(0); 120 else 121 // Emit JALR X1, X1, 0 122 TmpInst = MCInstBuilder(RISCV::JALR).addReg(Ra).addReg(Ra).addImm(0); 123 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 124 support::endian::write(OS, Binary, support::little); 125 } 126 127 void RISCVMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, 128 SmallVectorImpl<MCFixup> &Fixups, 129 const MCSubtargetInfo &STI) const { 130 const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); 131 // Get byte count of instruction. 132 unsigned Size = Desc.getSize(); 133 134 if (MI.getOpcode() == RISCV::PseudoCALL || 135 MI.getOpcode() == RISCV::PseudoTAIL) { 136 expandFunctionCall(MI, OS, Fixups, STI); 137 MCNumEmitted += 2; 138 return; 139 } 140 141 switch (Size) { 142 default: 143 llvm_unreachable("Unhandled encodeInstruction length!"); 144 case 2: { 145 uint16_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); 146 support::endian::write<uint16_t>(OS, Bits, support::little); 147 break; 148 } 149 case 4: { 150 uint32_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); 151 support::endian::write(OS, Bits, support::little); 152 break; 153 } 154 } 155 156 ++MCNumEmitted; // Keep track of the # of mi's emitted. 157 } 158 159 unsigned 160 RISCVMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO, 161 SmallVectorImpl<MCFixup> &Fixups, 162 const MCSubtargetInfo &STI) const { 163 164 if (MO.isReg()) 165 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()); 166 167 if (MO.isImm()) 168 return static_cast<unsigned>(MO.getImm()); 169 170 llvm_unreachable("Unhandled expression!"); 171 return 0; 172 } 173 174 unsigned 175 RISCVMCCodeEmitter::getImmOpValueAsr1(const MCInst &MI, unsigned OpNo, 176 SmallVectorImpl<MCFixup> &Fixups, 177 const MCSubtargetInfo &STI) const { 178 const MCOperand &MO = MI.getOperand(OpNo); 179 180 if (MO.isImm()) { 181 unsigned Res = MO.getImm(); 182 assert((Res & 1) == 0 && "LSB is non-zero"); 183 return Res >> 1; 184 } 185 186 return getImmOpValue(MI, OpNo, Fixups, STI); 187 } 188 189 unsigned RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo, 190 SmallVectorImpl<MCFixup> &Fixups, 191 const MCSubtargetInfo &STI) const { 192 bool EnableRelax = STI.getFeatureBits()[RISCV::FeatureRelax]; 193 const MCOperand &MO = MI.getOperand(OpNo); 194 195 MCInstrDesc const &Desc = MCII.get(MI.getOpcode()); 196 unsigned MIFrm = Desc.TSFlags & RISCVII::InstFormatMask; 197 198 // If the destination is an immediate, there is nothing to do. 199 if (MO.isImm()) 200 return MO.getImm(); 201 202 assert(MO.isExpr() && 203 "getImmOpValue expects only expressions or immediates"); 204 const MCExpr *Expr = MO.getExpr(); 205 MCExpr::ExprKind Kind = Expr->getKind(); 206 RISCV::Fixups FixupKind = RISCV::fixup_riscv_invalid; 207 bool RelaxCandidate = false; 208 if (Kind == MCExpr::Target) { 209 const RISCVMCExpr *RVExpr = cast<RISCVMCExpr>(Expr); 210 211 switch (RVExpr->getKind()) { 212 case RISCVMCExpr::VK_RISCV_None: 213 case RISCVMCExpr::VK_RISCV_Invalid: 214 llvm_unreachable("Unhandled fixup kind!"); 215 case RISCVMCExpr::VK_RISCV_LO: 216 if (MIFrm == RISCVII::InstFormatI) 217 FixupKind = RISCV::fixup_riscv_lo12_i; 218 else if (MIFrm == RISCVII::InstFormatS) 219 FixupKind = RISCV::fixup_riscv_lo12_s; 220 else 221 llvm_unreachable("VK_RISCV_LO used with unexpected instruction format"); 222 RelaxCandidate = true; 223 break; 224 case RISCVMCExpr::VK_RISCV_HI: 225 FixupKind = RISCV::fixup_riscv_hi20; 226 RelaxCandidate = true; 227 break; 228 case RISCVMCExpr::VK_RISCV_PCREL_LO: 229 if (MIFrm == RISCVII::InstFormatI) 230 FixupKind = RISCV::fixup_riscv_pcrel_lo12_i; 231 else if (MIFrm == RISCVII::InstFormatS) 232 FixupKind = RISCV::fixup_riscv_pcrel_lo12_s; 233 else 234 llvm_unreachable( 235 "VK_RISCV_PCREL_LO used with unexpected instruction format"); 236 RelaxCandidate = true; 237 break; 238 case RISCVMCExpr::VK_RISCV_PCREL_HI: 239 FixupKind = RISCV::fixup_riscv_pcrel_hi20; 240 RelaxCandidate = true; 241 break; 242 case RISCVMCExpr::VK_RISCV_GOT_HI: 243 FixupKind = RISCV::fixup_riscv_got_hi20; 244 break; 245 case RISCVMCExpr::VK_RISCV_CALL: 246 FixupKind = RISCV::fixup_riscv_call; 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