Path: blob/main/contrib/llvm-project/llvm/lib/Target/VE/MCTargetDesc/VEMCCodeEmitter.cpp
35294 views
//===-- VEMCCodeEmitter.cpp - Convert VE 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 VEMCCodeEmitter class.9//10//===----------------------------------------------------------------------===//1112#include "MCTargetDesc/VEFixupKinds.h"13#include "VE.h"14#include "VEMCExpr.h"15#include "llvm/ADT/SmallVector.h"16#include "llvm/ADT/Statistic.h"17#include "llvm/MC/MCCodeEmitter.h"18#include "llvm/MC/MCContext.h"19#include "llvm/MC/MCExpr.h"20#include "llvm/MC/MCFixup.h"21#include "llvm/MC/MCInst.h"22#include "llvm/MC/MCInstrInfo.h"23#include "llvm/MC/MCRegisterInfo.h"24#include "llvm/MC/MCSubtargetInfo.h"25#include "llvm/MC/MCSymbol.h"26#include "llvm/Support/EndianStream.h"27#include "llvm/Support/ErrorHandling.h"28#include "llvm/Support/raw_ostream.h"29#include <cassert>30#include <cstdint>3132using namespace llvm;3334#define DEBUG_TYPE "mccodeemitter"3536STATISTIC(MCNumEmitted, "Number of MC instructions emitted");3738namespace {3940class VEMCCodeEmitter : public MCCodeEmitter {41MCContext &Ctx;4243public:44VEMCCodeEmitter(const MCInstrInfo &, MCContext &ctx)45: Ctx(ctx) {}46VEMCCodeEmitter(const VEMCCodeEmitter &) = delete;47VEMCCodeEmitter &operator=(const VEMCCodeEmitter &) = delete;48~VEMCCodeEmitter() override = default;4950void encodeInstruction(const MCInst &MI, SmallVectorImpl<char> &CB,51SmallVectorImpl<MCFixup> &Fixups,52const MCSubtargetInfo &STI) const override;5354// getBinaryCodeForInstr - TableGen'erated function for getting the55// binary encoding for an instruction.56uint64_t getBinaryCodeForInstr(const MCInst &MI,57SmallVectorImpl<MCFixup> &Fixups,58const MCSubtargetInfo &STI) const;5960/// getMachineOpValue - Return binary encoding of operand. If the machine61/// operand requires relocation, record the relocation and return zero.62unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,63SmallVectorImpl<MCFixup> &Fixups,64const MCSubtargetInfo &STI) const;6566uint64_t getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,67SmallVectorImpl<MCFixup> &Fixups,68const MCSubtargetInfo &STI) const;69uint64_t getCCOpValue(const MCInst &MI, unsigned OpNo,70SmallVectorImpl<MCFixup> &Fixups,71const MCSubtargetInfo &STI) const;72uint64_t getRDOpValue(const MCInst &MI, unsigned OpNo,73SmallVectorImpl<MCFixup> &Fixups,74const MCSubtargetInfo &STI) const;75};7677} // end anonymous namespace7879void VEMCCodeEmitter::encodeInstruction(const MCInst &MI,80SmallVectorImpl<char> &CB,81SmallVectorImpl<MCFixup> &Fixups,82const MCSubtargetInfo &STI) const {83uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);84support::endian::write<uint64_t>(CB, Bits, llvm::endianness::little);8586++MCNumEmitted; // Keep track of the # of mi's emitted.87}8889unsigned VEMCCodeEmitter::getMachineOpValue(const MCInst &MI,90const MCOperand &MO,91SmallVectorImpl<MCFixup> &Fixups,92const MCSubtargetInfo &STI) const {93if (MO.isReg())94return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());95if (MO.isImm())96return static_cast<unsigned>(MO.getImm());9798assert(MO.isExpr());99100const MCExpr *Expr = MO.getExpr();101if (const VEMCExpr *SExpr = dyn_cast<VEMCExpr>(Expr)) {102MCFixupKind Kind = (MCFixupKind)SExpr->getFixupKind();103Fixups.push_back(MCFixup::create(0, Expr, Kind));104return 0;105}106107int64_t Res;108if (Expr->evaluateAsAbsolute(Res))109return Res;110111llvm_unreachable("Unhandled expression!");112return 0;113}114115uint64_t116VEMCCodeEmitter::getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,117SmallVectorImpl<MCFixup> &Fixups,118const MCSubtargetInfo &STI) const {119const MCOperand &MO = MI.getOperand(OpNo);120if (MO.isReg() || MO.isImm())121return getMachineOpValue(MI, MO, Fixups, STI);122123Fixups.push_back(124MCFixup::create(0, MO.getExpr(), (MCFixupKind)VE::fixup_ve_srel32));125return 0;126}127128uint64_t VEMCCodeEmitter::getCCOpValue(const MCInst &MI, unsigned OpNo,129SmallVectorImpl<MCFixup> &Fixups,130const MCSubtargetInfo &STI) const {131const MCOperand &MO = MI.getOperand(OpNo);132if (MO.isImm())133return VECondCodeToVal(134static_cast<VECC::CondCode>(getMachineOpValue(MI, MO, Fixups, STI)));135return 0;136}137138uint64_t VEMCCodeEmitter::getRDOpValue(const MCInst &MI, unsigned OpNo,139SmallVectorImpl<MCFixup> &Fixups,140const MCSubtargetInfo &STI) const {141const MCOperand &MO = MI.getOperand(OpNo);142if (MO.isImm())143return VERDToVal(static_cast<VERD::RoundingMode>(144getMachineOpValue(MI, MO, Fixups, STI)));145return 0;146}147148#include "VEGenMCCodeEmitter.inc"149150MCCodeEmitter *llvm::createVEMCCodeEmitter(const MCInstrInfo &MCII,151MCContext &Ctx) {152return new VEMCCodeEmitter(MCII, Ctx);153}154155156