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