Path: blob/main/contrib/llvm-project/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
35294 views
//===-- SparcMCCodeEmitter.cpp - Convert Sparc code to machine code -------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements the SparcMCCodeEmitter class.9//10//===----------------------------------------------------------------------===//1112#include "MCTargetDesc/SparcFixupKinds.h"13#include "SparcMCExpr.h"14#include "SparcMCTargetDesc.h"15#include "llvm/ADT/SmallVector.h"16#include "llvm/ADT/Statistic.h"17#include "llvm/MC/MCAsmInfo.h"18#include "llvm/MC/MCCodeEmitter.h"19#include "llvm/MC/MCContext.h"20#include "llvm/MC/MCExpr.h"21#include "llvm/MC/MCFixup.h"22#include "llvm/MC/MCInst.h"23#include "llvm/MC/MCInstrInfo.h"24#include "llvm/MC/MCObjectFileInfo.h"25#include "llvm/MC/MCRegisterInfo.h"26#include "llvm/MC/MCSubtargetInfo.h"27#include "llvm/MC/MCSymbol.h"28#include "llvm/Support/Casting.h"29#include "llvm/Support/Endian.h"30#include "llvm/Support/EndianStream.h"31#include "llvm/Support/ErrorHandling.h"32#include "llvm/Support/raw_ostream.h"33#include "llvm/TargetParser/SubtargetFeature.h"34#include <cassert>35#include <cstdint>3637using namespace llvm;3839#define DEBUG_TYPE "mccodeemitter"4041STATISTIC(MCNumEmitted, "Number of MC instructions emitted");4243namespace {4445class SparcMCCodeEmitter : public MCCodeEmitter {46MCContext &Ctx;4748public:49SparcMCCodeEmitter(const MCInstrInfo &, MCContext &ctx)50: Ctx(ctx) {}51SparcMCCodeEmitter(const SparcMCCodeEmitter &) = delete;52SparcMCCodeEmitter &operator=(const SparcMCCodeEmitter &) = delete;53~SparcMCCodeEmitter() override = default;5455void encodeInstruction(const MCInst &MI, SmallVectorImpl<char> &CB,56SmallVectorImpl<MCFixup> &Fixups,57const MCSubtargetInfo &STI) const override;5859// getBinaryCodeForInstr - TableGen'erated function for getting the60// binary encoding for an instruction.61uint64_t getBinaryCodeForInstr(const MCInst &MI,62SmallVectorImpl<MCFixup> &Fixups,63const MCSubtargetInfo &STI) const;6465/// getMachineOpValue - Return binary encoding of operand. If the machine66/// operand requires relocation, record the relocation and return zero.67unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,68SmallVectorImpl<MCFixup> &Fixups,69const MCSubtargetInfo &STI) const;70unsigned getCallTargetOpValue(const MCInst &MI, unsigned OpNo,71SmallVectorImpl<MCFixup> &Fixups,72const MCSubtargetInfo &STI) const;73unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,74SmallVectorImpl<MCFixup> &Fixups,75const MCSubtargetInfo &STI) const;76unsigned getSImm13OpValue(const MCInst &MI, unsigned OpNo,77SmallVectorImpl<MCFixup> &Fixups,78const MCSubtargetInfo &STI) const;79unsigned getBranchPredTargetOpValue(const MCInst &MI, unsigned OpNo,80SmallVectorImpl<MCFixup> &Fixups,81const MCSubtargetInfo &STI) const;82unsigned getBranchOnRegTargetOpValue(const MCInst &MI, unsigned OpNo,83SmallVectorImpl<MCFixup> &Fixups,84const MCSubtargetInfo &STI) const;85};8687} // end anonymous namespace8889void SparcMCCodeEmitter::encodeInstruction(const MCInst &MI,90SmallVectorImpl<char> &CB,91SmallVectorImpl<MCFixup> &Fixups,92const MCSubtargetInfo &STI) const {93unsigned Bits = getBinaryCodeForInstr(MI, Fixups, STI);94support::endian::write(CB, Bits,95Ctx.getAsmInfo()->isLittleEndian()96? llvm::endianness::little97: llvm::endianness::big);9899// Some instructions have phantom operands that only contribute a fixup entry.100unsigned SymOpNo = 0;101switch (MI.getOpcode()) {102default: break;103case SP::TLS_CALL: SymOpNo = 1; break;104case SP::GDOP_LDrr:105case SP::GDOP_LDXrr:106case SP::TLS_ADDrr:107case SP::TLS_LDrr:108case SP::TLS_LDXrr: SymOpNo = 3; break;109}110if (SymOpNo != 0) {111const MCOperand &MO = MI.getOperand(SymOpNo);112uint64_t op = getMachineOpValue(MI, MO, Fixups, STI);113assert(op == 0 && "Unexpected operand value!");114(void)op; // suppress warning.115}116117++MCNumEmitted; // Keep track of the # of mi's emitted.118}119120unsigned SparcMCCodeEmitter::121getMachineOpValue(const MCInst &MI, const MCOperand &MO,122SmallVectorImpl<MCFixup> &Fixups,123const MCSubtargetInfo &STI) const {124if (MO.isReg())125return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());126127if (MO.isImm())128return MO.getImm();129130assert(MO.isExpr());131const MCExpr *Expr = MO.getExpr();132if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Expr)) {133MCFixupKind Kind = (MCFixupKind)SExpr->getFixupKind();134Fixups.push_back(MCFixup::create(0, Expr, Kind));135return 0;136}137138int64_t Res;139if (Expr->evaluateAsAbsolute(Res))140return Res;141142llvm_unreachable("Unhandled expression!");143return 0;144}145146unsigned147SparcMCCodeEmitter::getSImm13OpValue(const MCInst &MI, unsigned OpNo,148SmallVectorImpl<MCFixup> &Fixups,149const MCSubtargetInfo &STI) const {150const MCOperand &MO = MI.getOperand(OpNo);151152if (MO.isImm())153return MO.getImm();154155assert(MO.isExpr() &&156"getSImm13OpValue expects only expressions or an immediate");157158const MCExpr *Expr = MO.getExpr();159160// Constant value, no fixup is needed161if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))162return CE->getValue();163164MCFixupKind Kind;165if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Expr)) {166Kind = MCFixupKind(SExpr->getFixupKind());167} else {168bool IsPic = Ctx.getObjectFileInfo()->isPositionIndependent();169Kind = IsPic ? MCFixupKind(Sparc::fixup_sparc_got13)170: MCFixupKind(Sparc::fixup_sparc_13);171}172173Fixups.push_back(MCFixup::create(0, Expr, Kind));174return 0;175}176177unsigned SparcMCCodeEmitter::178getCallTargetOpValue(const MCInst &MI, unsigned OpNo,179SmallVectorImpl<MCFixup> &Fixups,180const MCSubtargetInfo &STI) const {181const MCOperand &MO = MI.getOperand(OpNo);182const MCExpr *Expr = MO.getExpr();183const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Expr);184185if (MI.getOpcode() == SP::TLS_CALL) {186// No fixups for __tls_get_addr. Will emit for fixups for tls_symbol in187// encodeInstruction.188#ifndef NDEBUG189// Verify that the callee is actually __tls_get_addr.190assert(SExpr && SExpr->getSubExpr()->getKind() == MCExpr::SymbolRef &&191"Unexpected expression in TLS_CALL");192const MCSymbolRefExpr *SymExpr = cast<MCSymbolRefExpr>(SExpr->getSubExpr());193assert(SymExpr->getSymbol().getName() == "__tls_get_addr" &&194"Unexpected function for TLS_CALL");195#endif196return 0;197}198199MCFixupKind Kind = MCFixupKind(SExpr->getFixupKind());200Fixups.push_back(MCFixup::create(0, Expr, Kind));201return 0;202}203204unsigned SparcMCCodeEmitter::205getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,206SmallVectorImpl<MCFixup> &Fixups,207const MCSubtargetInfo &STI) const {208const MCOperand &MO = MI.getOperand(OpNo);209if (MO.isReg() || MO.isImm())210return getMachineOpValue(MI, MO, Fixups, STI);211212Fixups.push_back(MCFixup::create(0, MO.getExpr(),213(MCFixupKind)Sparc::fixup_sparc_br22));214return 0;215}216217unsigned SparcMCCodeEmitter::218getBranchPredTargetOpValue(const MCInst &MI, unsigned OpNo,219SmallVectorImpl<MCFixup> &Fixups,220const MCSubtargetInfo &STI) const {221const MCOperand &MO = MI.getOperand(OpNo);222if (MO.isReg() || MO.isImm())223return getMachineOpValue(MI, MO, Fixups, STI);224225Fixups.push_back(MCFixup::create(0, MO.getExpr(),226(MCFixupKind)Sparc::fixup_sparc_br19));227return 0;228}229230unsigned SparcMCCodeEmitter::231getBranchOnRegTargetOpValue(const MCInst &MI, unsigned OpNo,232SmallVectorImpl<MCFixup> &Fixups,233const MCSubtargetInfo &STI) const {234const MCOperand &MO = MI.getOperand(OpNo);235if (MO.isReg() || MO.isImm())236return getMachineOpValue(MI, MO, Fixups, STI);237238Fixups.push_back(239MCFixup::create(0, MO.getExpr(), (MCFixupKind)Sparc::fixup_sparc_br16));240241return 0;242}243244#include "SparcGenMCCodeEmitter.inc"245246MCCodeEmitter *llvm::createSparcMCCodeEmitter(const MCInstrInfo &MCII,247MCContext &Ctx) {248return new SparcMCCodeEmitter(MCII, Ctx);249}250251252