1 //===-- SparcMCCodeEmitter.cpp - Convert Sparc 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 SparcMCCodeEmitter class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "MCTargetDesc/SparcFixupKinds.h" 14 #include "SparcMCExpr.h" 15 #include "SparcMCTargetDesc.h" 16 #include "llvm/ADT/SmallVector.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/MCFixup.h" 23 #include "llvm/MC/MCInst.h" 24 #include "llvm/MC/MCInstrInfo.h" 25 #include "llvm/MC/MCObjectFileInfo.h" 26 #include "llvm/MC/MCRegisterInfo.h" 27 #include "llvm/MC/MCSubtargetInfo.h" 28 #include "llvm/MC/MCSymbol.h" 29 #include "llvm/Support/Casting.h" 30 #include "llvm/Support/EndianStream.h" 31 #include "llvm/Support/ErrorHandling.h" 32 #include <cassert> 33 #include <cstdint> 34 35 using namespace llvm; 36 37 #define DEBUG_TYPE "mccodeemitter" 38 39 STATISTIC(MCNumEmitted, "Number of MC instructions emitted"); 40 41 namespace { 42 43 class SparcMCCodeEmitter : public MCCodeEmitter { 44 MCContext &Ctx; 45 46 public: 47 SparcMCCodeEmitter(const MCInstrInfo &, MCContext &ctx) 48 : Ctx(ctx) {} 49 SparcMCCodeEmitter(const SparcMCCodeEmitter &) = delete; 50 SparcMCCodeEmitter &operator=(const SparcMCCodeEmitter &) = delete; 51 ~SparcMCCodeEmitter() override = default; 52 53 void encodeInstruction(const MCInst &MI, SmallVectorImpl<char> &CB, 54 SmallVectorImpl<MCFixup> &Fixups, 55 const MCSubtargetInfo &STI) const override; 56 57 // getBinaryCodeForInstr - TableGen'erated function for getting the 58 // binary encoding for an instruction. 59 uint64_t getBinaryCodeForInstr(const MCInst &MI, 60 SmallVectorImpl<MCFixup> &Fixups, 61 const MCSubtargetInfo &STI) const; 62 63 /// getMachineOpValue - Return binary encoding of operand. If the machine 64 /// operand requires relocation, record the relocation and return zero. 65 unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, 66 SmallVectorImpl<MCFixup> &Fixups, 67 const MCSubtargetInfo &STI) const; 68 unsigned getCallTargetOpValue(const MCInst &MI, unsigned OpNo, 69 SmallVectorImpl<MCFixup> &Fixups, 70 const MCSubtargetInfo &STI) const; 71 unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, 72 SmallVectorImpl<MCFixup> &Fixups, 73 const MCSubtargetInfo &STI) const; 74 unsigned getSImm13OpValue(const MCInst &MI, unsigned OpNo, 75 SmallVectorImpl<MCFixup> &Fixups, 76 const MCSubtargetInfo &STI) const; 77 unsigned getBranchPredTargetOpValue(const MCInst &MI, unsigned OpNo, 78 SmallVectorImpl<MCFixup> &Fixups, 79 const MCSubtargetInfo &STI) const; 80 unsigned getBranchOnRegTargetOpValue(const MCInst &MI, unsigned OpNo, 81 SmallVectorImpl<MCFixup> &Fixups, 82 const MCSubtargetInfo &STI) const; 83 }; 84 85 } // end anonymous namespace 86 87 void SparcMCCodeEmitter::encodeInstruction(const MCInst &MI, 88 SmallVectorImpl<char> &CB, 89 SmallVectorImpl<MCFixup> &Fixups, 90 const MCSubtargetInfo &STI) const { 91 unsigned Bits = getBinaryCodeForInstr(MI, Fixups, STI); 92 support::endian::write(CB, Bits, 93 Ctx.getAsmInfo()->isLittleEndian() 94 ? llvm::endianness::little 95 : llvm::endianness::big); 96 97 // Some instructions have phantom operands that only contribute a fixup entry. 98 unsigned SymOpNo = 0; 99 switch (MI.getOpcode()) { 100 default: break; 101 case SP::TLS_CALL: SymOpNo = 1; break; 102 case SP::GDOP_LDrr: 103 case SP::GDOP_LDXrr: 104 case SP::TLS_ADDrr: 105 case SP::TLS_LDrr: 106 case SP::TLS_LDXrr: SymOpNo = 3; break; 107 } 108 if (SymOpNo != 0) { 109 const MCOperand &MO = MI.getOperand(SymOpNo); 110 uint64_t op = getMachineOpValue(MI, MO, Fixups, STI); 111 assert(op == 0 && "Unexpected operand value!"); 112 (void)op; // suppress warning. 113 } 114 115 ++MCNumEmitted; // Keep track of the # of mi's emitted. 116 } 117 118 unsigned SparcMCCodeEmitter:: 119 getMachineOpValue(const MCInst &MI, const MCOperand &MO, 120 SmallVectorImpl<MCFixup> &Fixups, 121 const MCSubtargetInfo &STI) const { 122 if (MO.isReg()) 123 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()); 124 125 if (MO.isImm()) 126 return MO.getImm(); 127 128 assert(MO.isExpr()); 129 const MCExpr *Expr = MO.getExpr(); 130 if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Expr)) { 131 MCFixupKind Kind = (MCFixupKind)SExpr->getFixupKind(); 132 Fixups.push_back(MCFixup::create(0, Expr, Kind)); 133 return 0; 134 } 135 136 int64_t Res; 137 if (Expr->evaluateAsAbsolute(Res)) 138 return Res; 139 140 llvm_unreachable("Unhandled expression!"); 141 return 0; 142 } 143 144 unsigned 145 SparcMCCodeEmitter::getSImm13OpValue(const MCInst &MI, unsigned OpNo, 146 SmallVectorImpl<MCFixup> &Fixups, 147 const MCSubtargetInfo &STI) const { 148 const MCOperand &MO = MI.getOperand(OpNo); 149 150 if (MO.isImm()) 151 return MO.getImm(); 152 153 assert(MO.isExpr() && 154 "getSImm13OpValue expects only expressions or an immediate"); 155 156 const MCExpr *Expr = MO.getExpr(); 157 158 // Constant value, no fixup is needed 159 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 160 return CE->getValue(); 161 162 MCFixupKind Kind; 163 if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Expr)) { 164 Kind = MCFixupKind(SExpr->getFixupKind()); 165 } else { 166 bool IsPic = Ctx.getObjectFileInfo()->isPositionIndependent(); 167 Kind = IsPic ? MCFixupKind(Sparc::fixup_sparc_got13) 168 : MCFixupKind(Sparc::fixup_sparc_13); 169 } 170 171 Fixups.push_back(MCFixup::create(0, Expr, Kind)); 172 return 0; 173 } 174 175 unsigned SparcMCCodeEmitter:: 176 getCallTargetOpValue(const MCInst &MI, unsigned OpNo, 177 SmallVectorImpl<MCFixup> &Fixups, 178 const MCSubtargetInfo &STI) const { 179 const MCOperand &MO = MI.getOperand(OpNo); 180 const MCExpr *Expr = MO.getExpr(); 181 const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Expr); 182 183 if (MI.getOpcode() == SP::TLS_CALL) { 184 // No fixups for __tls_get_addr. Will emit for fixups for tls_symbol in 185 // encodeInstruction. 186 #ifndef NDEBUG 187 // Verify that the callee is actually __tls_get_addr. 188 assert(SExpr && SExpr->getSubExpr()->getKind() == MCExpr::SymbolRef && 189 "Unexpected expression in TLS_CALL"); 190 const MCSymbolRefExpr *SymExpr = cast<MCSymbolRefExpr>(SExpr->getSubExpr()); 191 assert(SymExpr->getSymbol().getName() == "__tls_get_addr" && 192 "Unexpected function for TLS_CALL"); 193 #endif 194 return 0; 195 } 196 197 MCFixupKind Kind = MCFixupKind(SExpr->getFixupKind()); 198 Fixups.push_back(MCFixup::create(0, Expr, Kind)); 199 return 0; 200 } 201 202 unsigned SparcMCCodeEmitter:: 203 getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, 204 SmallVectorImpl<MCFixup> &Fixups, 205 const MCSubtargetInfo &STI) const { 206 const MCOperand &MO = MI.getOperand(OpNo); 207 if (MO.isReg() || MO.isImm()) 208 return getMachineOpValue(MI, MO, Fixups, STI); 209 210 Fixups.push_back(MCFixup::create(0, MO.getExpr(), 211 (MCFixupKind)Sparc::fixup_sparc_br22)); 212 return 0; 213 } 214 215 unsigned SparcMCCodeEmitter:: 216 getBranchPredTargetOpValue(const MCInst &MI, unsigned OpNo, 217 SmallVectorImpl<MCFixup> &Fixups, 218 const MCSubtargetInfo &STI) const { 219 const MCOperand &MO = MI.getOperand(OpNo); 220 if (MO.isReg() || MO.isImm()) 221 return getMachineOpValue(MI, MO, Fixups, STI); 222 223 Fixups.push_back(MCFixup::create(0, MO.getExpr(), 224 (MCFixupKind)Sparc::fixup_sparc_br19)); 225 return 0; 226 } 227 228 unsigned SparcMCCodeEmitter:: 229 getBranchOnRegTargetOpValue(const MCInst &MI, unsigned OpNo, 230 SmallVectorImpl<MCFixup> &Fixups, 231 const MCSubtargetInfo &STI) const { 232 const MCOperand &MO = MI.getOperand(OpNo); 233 if (MO.isReg() || MO.isImm()) 234 return getMachineOpValue(MI, MO, Fixups, STI); 235 236 Fixups.push_back( 237 MCFixup::create(0, MO.getExpr(), (MCFixupKind)Sparc::fixup_sparc_br16)); 238 239 return 0; 240 } 241 242 #include "SparcGenMCCodeEmitter.inc" 243 244 MCCodeEmitter *llvm::createSparcMCCodeEmitter(const MCInstrInfo &MCII, 245 MCContext &Ctx) { 246 return new SparcMCCodeEmitter(MCII, Ctx); 247 } 248