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 // Emit JALR Ra, Ra, 0 119 TmpInst = MCInstBuilder(RISCV::JALR).addReg(Ra).addReg(Ra).addImm(0); 120 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 121 support::endian::write(OS, Binary, support::little); 122 } 123 124 void RISCVMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, 125 SmallVectorImpl<MCFixup> &Fixups, 126 const MCSubtargetInfo &STI) const { 127 const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); 128 // Get byte count of instruction. 129 unsigned Size = Desc.getSize(); 130 131 if (MI.getOpcode() == RISCV::PseudoCALL || 132 MI.getOpcode() == RISCV::PseudoTAIL) { 133 expandFunctionCall(MI, OS, Fixups, STI); 134 MCNumEmitted += 2; 135 return; 136 } 137 138 switch (Size) { 139 default: 140 llvm_unreachable("Unhandled encodeInstruction length!"); 141 case 2: { 142 uint16_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); 143 support::endian::write<uint16_t>(OS, Bits, support::little); 144 break; 145 } 146 case 4: { 147 uint32_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); 148 support::endian::write(OS, Bits, support::little); 149 break; 150 } 151 } 152 153 ++MCNumEmitted; // Keep track of the # of mi's emitted. 154 } 155 156 unsigned 157 RISCVMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO, 158 SmallVectorImpl<MCFixup> &Fixups, 159 const MCSubtargetInfo &STI) const { 160 161 if (MO.isReg()) 162 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()); 163 164 if (MO.isImm()) 165 return static_cast<unsigned>(MO.getImm()); 166 167 llvm_unreachable("Unhandled expression!"); 168 return 0; 169 } 170 171 unsigned 172 RISCVMCCodeEmitter::getImmOpValueAsr1(const MCInst &MI, unsigned OpNo, 173 SmallVectorImpl<MCFixup> &Fixups, 174 const MCSubtargetInfo &STI) const { 175 const MCOperand &MO = MI.getOperand(OpNo); 176 177 if (MO.isImm()) { 178 unsigned Res = MO.getImm(); 179 assert((Res & 1) == 0 && "LSB is non-zero"); 180 return Res >> 1; 181 } 182 183 return getImmOpValue(MI, OpNo, Fixups, STI); 184 } 185 186 unsigned RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo, 187 SmallVectorImpl<MCFixup> &Fixups, 188 const MCSubtargetInfo &STI) const { 189 bool EnableRelax = STI.getFeatureBits()[RISCV::FeatureRelax]; 190 const MCOperand &MO = MI.getOperand(OpNo); 191 192 MCInstrDesc const &Desc = MCII.get(MI.getOpcode()); 193 unsigned MIFrm = Desc.TSFlags & RISCVII::InstFormatMask; 194 195 // If the destination is an immediate, there is nothing to do 196 if (MO.isImm()) 197 return MO.getImm(); 198 199 assert(MO.isExpr() && 200 "getImmOpValue expects only expressions or immediates"); 201 const MCExpr *Expr = MO.getExpr(); 202 MCExpr::ExprKind Kind = Expr->getKind(); 203 RISCV::Fixups FixupKind = RISCV::fixup_riscv_invalid; 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 break; 219 case RISCVMCExpr::VK_RISCV_HI: 220 FixupKind = RISCV::fixup_riscv_hi20; 221 break; 222 case RISCVMCExpr::VK_RISCV_PCREL_LO: 223 if (MIFrm == RISCVII::InstFormatI) 224 FixupKind = RISCV::fixup_riscv_pcrel_lo12_i; 225 else if (MIFrm == RISCVII::InstFormatS) 226 FixupKind = RISCV::fixup_riscv_pcrel_lo12_s; 227 else 228 llvm_unreachable( 229 "VK_RISCV_PCREL_LO used with unexpected instruction format"); 230 break; 231 case RISCVMCExpr::VK_RISCV_PCREL_HI: 232 FixupKind = RISCV::fixup_riscv_pcrel_hi20; 233 break; 234 case RISCVMCExpr::VK_RISCV_CALL: 235 FixupKind = RISCV::fixup_riscv_call; 236 break; 237 } 238 } else if (Kind == MCExpr::SymbolRef && 239 cast<MCSymbolRefExpr>(Expr)->getKind() == MCSymbolRefExpr::VK_None) { 240 if (Desc.getOpcode() == RISCV::JAL) { 241 FixupKind = RISCV::fixup_riscv_jal; 242 } else if (MIFrm == RISCVII::InstFormatB) { 243 FixupKind = RISCV::fixup_riscv_branch; 244 } else if (MIFrm == RISCVII::InstFormatCJ) { 245 FixupKind = RISCV::fixup_riscv_rvc_jump; 246 } else if (MIFrm == RISCVII::InstFormatCB) { 247 FixupKind = RISCV::fixup_riscv_rvc_branch; 248 } 249 } 250 251 assert(FixupKind != RISCV::fixup_riscv_invalid && "Unhandled expression!"); 252 253 Fixups.push_back( 254 MCFixup::create(0, Expr, MCFixupKind(FixupKind), MI.getLoc())); 255 ++MCNumFixups; 256 257 if (EnableRelax) { 258 if (FixupKind == RISCV::fixup_riscv_call) { 259 Fixups.push_back( 260 MCFixup::create(0, Expr, MCFixupKind(RISCV::fixup_riscv_relax), 261 MI.getLoc())); 262 ++MCNumFixups; 263 } 264 } 265 266 return 0; 267 } 268 269 #include "RISCVGenMCCodeEmitter.inc" 270