10b57cec5SDimitry Andric //===-- SparcMCCodeEmitter.cpp - Convert Sparc code to machine code -------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements the SparcMCCodeEmitter class. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "MCTargetDesc/SparcFixupKinds.h" 140b57cec5SDimitry Andric #include "SparcMCExpr.h" 150b57cec5SDimitry Andric #include "SparcMCTargetDesc.h" 160b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 170b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h" 180b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h" 190b57cec5SDimitry Andric #include "llvm/MC/MCCodeEmitter.h" 200b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 210b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h" 220b57cec5SDimitry Andric #include "llvm/MC/MCFixup.h" 230b57cec5SDimitry Andric #include "llvm/MC/MCInst.h" 240b57cec5SDimitry Andric #include "llvm/MC/MCInstrInfo.h" 25e8d8bef9SDimitry Andric #include "llvm/MC/MCObjectFileInfo.h" 260b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h" 270b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h" 280b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h" 290b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 300b57cec5SDimitry Andric #include "llvm/Support/Endian.h" 310b57cec5SDimitry Andric #include "llvm/Support/EndianStream.h" 320b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 330b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 3406c3fb27SDimitry Andric #include "llvm/TargetParser/SubtargetFeature.h" 350b57cec5SDimitry Andric #include <cassert> 360b57cec5SDimitry Andric #include <cstdint> 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric using namespace llvm; 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric #define DEBUG_TYPE "mccodeemitter" 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric STATISTIC(MCNumEmitted, "Number of MC instructions emitted"); 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric namespace { 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric class SparcMCCodeEmitter : public MCCodeEmitter { 470b57cec5SDimitry Andric MCContext &Ctx; 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric public: 50753f127fSDimitry Andric SparcMCCodeEmitter(const MCInstrInfo &, MCContext &ctx) 51753f127fSDimitry Andric : Ctx(ctx) {} 520b57cec5SDimitry Andric SparcMCCodeEmitter(const SparcMCCodeEmitter &) = delete; 530b57cec5SDimitry Andric SparcMCCodeEmitter &operator=(const SparcMCCodeEmitter &) = delete; 540b57cec5SDimitry Andric ~SparcMCCodeEmitter() override = default; 550b57cec5SDimitry Andric 5606c3fb27SDimitry Andric void encodeInstruction(const MCInst &MI, SmallVectorImpl<char> &CB, 570b57cec5SDimitry Andric SmallVectorImpl<MCFixup> &Fixups, 580b57cec5SDimitry Andric const MCSubtargetInfo &STI) const override; 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric // getBinaryCodeForInstr - TableGen'erated function for getting the 610b57cec5SDimitry Andric // binary encoding for an instruction. 620b57cec5SDimitry Andric uint64_t getBinaryCodeForInstr(const MCInst &MI, 630b57cec5SDimitry Andric SmallVectorImpl<MCFixup> &Fixups, 640b57cec5SDimitry Andric const MCSubtargetInfo &STI) const; 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric /// getMachineOpValue - Return binary encoding of operand. If the machine 670b57cec5SDimitry Andric /// operand requires relocation, record the relocation and return zero. 680b57cec5SDimitry Andric unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, 690b57cec5SDimitry Andric SmallVectorImpl<MCFixup> &Fixups, 700b57cec5SDimitry Andric const MCSubtargetInfo &STI) const; 710b57cec5SDimitry Andric unsigned getCallTargetOpValue(const MCInst &MI, unsigned OpNo, 720b57cec5SDimitry Andric SmallVectorImpl<MCFixup> &Fixups, 730b57cec5SDimitry Andric const MCSubtargetInfo &STI) const; 740b57cec5SDimitry Andric unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, 750b57cec5SDimitry Andric SmallVectorImpl<MCFixup> &Fixups, 760b57cec5SDimitry Andric const MCSubtargetInfo &STI) const; 77e8d8bef9SDimitry Andric unsigned getSImm13OpValue(const MCInst &MI, unsigned OpNo, 78e8d8bef9SDimitry Andric SmallVectorImpl<MCFixup> &Fixups, 79e8d8bef9SDimitry Andric const MCSubtargetInfo &STI) const; 800b57cec5SDimitry Andric unsigned getBranchPredTargetOpValue(const MCInst &MI, unsigned OpNo, 810b57cec5SDimitry Andric SmallVectorImpl<MCFixup> &Fixups, 820b57cec5SDimitry Andric const MCSubtargetInfo &STI) const; 830b57cec5SDimitry Andric unsigned getBranchOnRegTargetOpValue(const MCInst &MI, unsigned OpNo, 840b57cec5SDimitry Andric SmallVectorImpl<MCFixup> &Fixups, 850b57cec5SDimitry Andric const MCSubtargetInfo &STI) const; 860b57cec5SDimitry Andric }; 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric } // end anonymous namespace 890b57cec5SDimitry Andric 9006c3fb27SDimitry Andric void SparcMCCodeEmitter::encodeInstruction(const MCInst &MI, 9106c3fb27SDimitry Andric SmallVectorImpl<char> &CB, 920b57cec5SDimitry Andric SmallVectorImpl<MCFixup> &Fixups, 930b57cec5SDimitry Andric const MCSubtargetInfo &STI) const { 940b57cec5SDimitry Andric unsigned Bits = getBinaryCodeForInstr(MI, Fixups, STI); 9506c3fb27SDimitry Andric support::endian::write(CB, Bits, 96*5f757f3fSDimitry Andric Ctx.getAsmInfo()->isLittleEndian() 97*5f757f3fSDimitry Andric ? llvm::endianness::little 98*5f757f3fSDimitry Andric : llvm::endianness::big); 9981ad6265SDimitry Andric 10081ad6265SDimitry Andric // Some instructions have phantom operands that only contribute a fixup entry. 10181ad6265SDimitry Andric unsigned SymOpNo = 0; 1020b57cec5SDimitry Andric switch (MI.getOpcode()) { 1030b57cec5SDimitry Andric default: break; 10481ad6265SDimitry Andric case SP::TLS_CALL: SymOpNo = 1; break; 10581ad6265SDimitry Andric case SP::GDOP_LDrr: 10681ad6265SDimitry Andric case SP::GDOP_LDXrr: 1070b57cec5SDimitry Andric case SP::TLS_ADDrr: 1080b57cec5SDimitry Andric case SP::TLS_LDrr: 10981ad6265SDimitry Andric case SP::TLS_LDXrr: SymOpNo = 3; break; 1100b57cec5SDimitry Andric } 11181ad6265SDimitry Andric if (SymOpNo != 0) { 11281ad6265SDimitry Andric const MCOperand &MO = MI.getOperand(SymOpNo); 1130b57cec5SDimitry Andric uint64_t op = getMachineOpValue(MI, MO, Fixups, STI); 1140b57cec5SDimitry Andric assert(op == 0 && "Unexpected operand value!"); 1150b57cec5SDimitry Andric (void)op; // suppress warning. 1160b57cec5SDimitry Andric } 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric ++MCNumEmitted; // Keep track of the # of mi's emitted. 1190b57cec5SDimitry Andric } 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric unsigned SparcMCCodeEmitter:: 1220b57cec5SDimitry Andric getMachineOpValue(const MCInst &MI, const MCOperand &MO, 1230b57cec5SDimitry Andric SmallVectorImpl<MCFixup> &Fixups, 1240b57cec5SDimitry Andric const MCSubtargetInfo &STI) const { 1250b57cec5SDimitry Andric if (MO.isReg()) 1260b57cec5SDimitry Andric return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()); 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric if (MO.isImm()) 1290b57cec5SDimitry Andric return MO.getImm(); 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric assert(MO.isExpr()); 1320b57cec5SDimitry Andric const MCExpr *Expr = MO.getExpr(); 1330b57cec5SDimitry Andric if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Expr)) { 1340b57cec5SDimitry Andric MCFixupKind Kind = (MCFixupKind)SExpr->getFixupKind(); 1350b57cec5SDimitry Andric Fixups.push_back(MCFixup::create(0, Expr, Kind)); 1360b57cec5SDimitry Andric return 0; 1370b57cec5SDimitry Andric } 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric int64_t Res; 1400b57cec5SDimitry Andric if (Expr->evaluateAsAbsolute(Res)) 1410b57cec5SDimitry Andric return Res; 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric llvm_unreachable("Unhandled expression!"); 1440b57cec5SDimitry Andric return 0; 1450b57cec5SDimitry Andric } 1460b57cec5SDimitry Andric 147e8d8bef9SDimitry Andric unsigned 148e8d8bef9SDimitry Andric SparcMCCodeEmitter::getSImm13OpValue(const MCInst &MI, unsigned OpNo, 149e8d8bef9SDimitry Andric SmallVectorImpl<MCFixup> &Fixups, 150e8d8bef9SDimitry Andric const MCSubtargetInfo &STI) const { 151e8d8bef9SDimitry Andric const MCOperand &MO = MI.getOperand(OpNo); 152e8d8bef9SDimitry Andric 153e8d8bef9SDimitry Andric if (MO.isImm()) 154e8d8bef9SDimitry Andric return MO.getImm(); 155e8d8bef9SDimitry Andric 156e8d8bef9SDimitry Andric assert(MO.isExpr() && 157e8d8bef9SDimitry Andric "getSImm13OpValue expects only expressions or an immediate"); 158e8d8bef9SDimitry Andric 159e8d8bef9SDimitry Andric const MCExpr *Expr = MO.getExpr(); 160e8d8bef9SDimitry Andric 161e8d8bef9SDimitry Andric // Constant value, no fixup is needed 162e8d8bef9SDimitry Andric if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 163e8d8bef9SDimitry Andric return CE->getValue(); 164e8d8bef9SDimitry Andric 165e8d8bef9SDimitry Andric MCFixupKind Kind; 166e8d8bef9SDimitry Andric if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Expr)) { 167e8d8bef9SDimitry Andric Kind = MCFixupKind(SExpr->getFixupKind()); 168e8d8bef9SDimitry Andric } else { 169e8d8bef9SDimitry Andric bool IsPic = Ctx.getObjectFileInfo()->isPositionIndependent(); 170e8d8bef9SDimitry Andric Kind = IsPic ? MCFixupKind(Sparc::fixup_sparc_got13) 171e8d8bef9SDimitry Andric : MCFixupKind(Sparc::fixup_sparc_13); 172e8d8bef9SDimitry Andric } 173e8d8bef9SDimitry Andric 174e8d8bef9SDimitry Andric Fixups.push_back(MCFixup::create(0, Expr, Kind)); 175e8d8bef9SDimitry Andric return 0; 176e8d8bef9SDimitry Andric } 177e8d8bef9SDimitry Andric 1780b57cec5SDimitry Andric unsigned SparcMCCodeEmitter:: 1790b57cec5SDimitry Andric getCallTargetOpValue(const MCInst &MI, unsigned OpNo, 1800b57cec5SDimitry Andric SmallVectorImpl<MCFixup> &Fixups, 1810b57cec5SDimitry Andric const MCSubtargetInfo &STI) const { 1820b57cec5SDimitry Andric const MCOperand &MO = MI.getOperand(OpNo); 183e8d8bef9SDimitry Andric const MCExpr *Expr = MO.getExpr(); 184e8d8bef9SDimitry Andric const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Expr); 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andric if (MI.getOpcode() == SP::TLS_CALL) { 1870b57cec5SDimitry Andric // No fixups for __tls_get_addr. Will emit for fixups for tls_symbol in 1880b57cec5SDimitry Andric // encodeInstruction. 1890b57cec5SDimitry Andric #ifndef NDEBUG 1900b57cec5SDimitry Andric // Verify that the callee is actually __tls_get_addr. 1910b57cec5SDimitry Andric assert(SExpr && SExpr->getSubExpr()->getKind() == MCExpr::SymbolRef && 1920b57cec5SDimitry Andric "Unexpected expression in TLS_CALL"); 1930b57cec5SDimitry Andric const MCSymbolRefExpr *SymExpr = cast<MCSymbolRefExpr>(SExpr->getSubExpr()); 1940b57cec5SDimitry Andric assert(SymExpr->getSymbol().getName() == "__tls_get_addr" && 1950b57cec5SDimitry Andric "Unexpected function for TLS_CALL"); 1960b57cec5SDimitry Andric #endif 1970b57cec5SDimitry Andric return 0; 1980b57cec5SDimitry Andric } 1990b57cec5SDimitry Andric 200e8d8bef9SDimitry Andric MCFixupKind Kind = MCFixupKind(SExpr->getFixupKind()); 201e8d8bef9SDimitry Andric Fixups.push_back(MCFixup::create(0, Expr, Kind)); 2020b57cec5SDimitry Andric return 0; 2030b57cec5SDimitry Andric } 2040b57cec5SDimitry Andric 2050b57cec5SDimitry Andric unsigned SparcMCCodeEmitter:: 2060b57cec5SDimitry Andric getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, 2070b57cec5SDimitry Andric SmallVectorImpl<MCFixup> &Fixups, 2080b57cec5SDimitry Andric const MCSubtargetInfo &STI) const { 2090b57cec5SDimitry Andric const MCOperand &MO = MI.getOperand(OpNo); 2100b57cec5SDimitry Andric if (MO.isReg() || MO.isImm()) 2110b57cec5SDimitry Andric return getMachineOpValue(MI, MO, Fixups, STI); 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric Fixups.push_back(MCFixup::create(0, MO.getExpr(), 2140b57cec5SDimitry Andric (MCFixupKind)Sparc::fixup_sparc_br22)); 2150b57cec5SDimitry Andric return 0; 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric unsigned SparcMCCodeEmitter:: 2190b57cec5SDimitry Andric getBranchPredTargetOpValue(const MCInst &MI, unsigned OpNo, 2200b57cec5SDimitry Andric SmallVectorImpl<MCFixup> &Fixups, 2210b57cec5SDimitry Andric const MCSubtargetInfo &STI) const { 2220b57cec5SDimitry Andric const MCOperand &MO = MI.getOperand(OpNo); 2230b57cec5SDimitry Andric if (MO.isReg() || MO.isImm()) 2240b57cec5SDimitry Andric return getMachineOpValue(MI, MO, Fixups, STI); 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric Fixups.push_back(MCFixup::create(0, MO.getExpr(), 2270b57cec5SDimitry Andric (MCFixupKind)Sparc::fixup_sparc_br19)); 2280b57cec5SDimitry Andric return 0; 2290b57cec5SDimitry Andric } 2300b57cec5SDimitry Andric 2310b57cec5SDimitry Andric unsigned SparcMCCodeEmitter:: 2320b57cec5SDimitry Andric getBranchOnRegTargetOpValue(const MCInst &MI, unsigned OpNo, 2330b57cec5SDimitry Andric SmallVectorImpl<MCFixup> &Fixups, 2340b57cec5SDimitry Andric const MCSubtargetInfo &STI) const { 2350b57cec5SDimitry Andric const MCOperand &MO = MI.getOperand(OpNo); 2360b57cec5SDimitry Andric if (MO.isReg() || MO.isImm()) 2370b57cec5SDimitry Andric return getMachineOpValue(MI, MO, Fixups, STI); 2380b57cec5SDimitry Andric 23906c3fb27SDimitry Andric Fixups.push_back( 24006c3fb27SDimitry Andric MCFixup::create(0, MO.getExpr(), (MCFixupKind)Sparc::fixup_sparc_br16)); 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric return 0; 2430b57cec5SDimitry Andric } 2440b57cec5SDimitry Andric 2450b57cec5SDimitry Andric #include "SparcGenMCCodeEmitter.inc" 2460b57cec5SDimitry Andric 2470b57cec5SDimitry Andric MCCodeEmitter *llvm::createSparcMCCodeEmitter(const MCInstrInfo &MCII, 2480b57cec5SDimitry Andric MCContext &Ctx) { 2490b57cec5SDimitry Andric return new SparcMCCodeEmitter(MCII, Ctx); 2500b57cec5SDimitry Andric } 251