brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.8 KiB · ab71939 Raw
164 lines · cpp
1//===-- VEMCCodeEmitter.cpp - Convert VE 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-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the VEMCCodeEmitter class.10//11//===----------------------------------------------------------------------===//12 13#include "MCTargetDesc/VEFixupKinds.h"14#include "VE.h"15#include "VEMCAsmInfo.h"16#include "llvm/ADT/SmallVector.h"17#include "llvm/ADT/Statistic.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/MCRegisterInfo.h"25#include "llvm/MC/MCSubtargetInfo.h"26#include "llvm/MC/MCSymbol.h"27#include "llvm/Support/EndianStream.h"28#include <cassert>29#include <cstdint>30 31using namespace llvm;32 33#define DEBUG_TYPE "mccodeemitter"34 35STATISTIC(MCNumEmitted, "Number of MC instructions emitted");36 37namespace {38 39class VEMCCodeEmitter : public MCCodeEmitter {40  MCContext &Ctx;41 42public:43  VEMCCodeEmitter(const MCInstrInfo &, MCContext &ctx)44      : Ctx(ctx) {}45  VEMCCodeEmitter(const VEMCCodeEmitter &) = delete;46  VEMCCodeEmitter &operator=(const VEMCCodeEmitter &) = delete;47  ~VEMCCodeEmitter() override = default;48 49  void encodeInstruction(const MCInst &MI, SmallVectorImpl<char> &CB,50                         SmallVectorImpl<MCFixup> &Fixups,51                         const MCSubtargetInfo &STI) const override;52 53  // getBinaryCodeForInstr - TableGen'erated function for getting the54  // binary encoding for an instruction.55  uint64_t getBinaryCodeForInstr(const MCInst &MI,56                                 SmallVectorImpl<MCFixup> &Fixups,57                                 const MCSubtargetInfo &STI) const;58 59  /// getMachineOpValue - Return binary encoding of operand. If the machine60  /// operand requires relocation, record the relocation and return zero.61  unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,62                             SmallVectorImpl<MCFixup> &Fixups,63                             const MCSubtargetInfo &STI) const;64 65  uint64_t getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,66                                  SmallVectorImpl<MCFixup> &Fixups,67                                  const MCSubtargetInfo &STI) const;68  uint64_t getCCOpValue(const MCInst &MI, unsigned OpNo,69                        SmallVectorImpl<MCFixup> &Fixups,70                        const MCSubtargetInfo &STI) const;71  uint64_t getRDOpValue(const MCInst &MI, unsigned OpNo,72                        SmallVectorImpl<MCFixup> &Fixups,73                        const MCSubtargetInfo &STI) const;74};75 76} // end anonymous namespace77 78static void addFixup(SmallVectorImpl<MCFixup> &Fixups, uint32_t Offset,79                     const MCExpr *Value, uint16_t Kind) {80  bool PCRel = false;81  switch (Kind) {82  case VE::fixup_ve_srel32:83  case VE::fixup_ve_pc_hi32:84  case VE::fixup_ve_pc_lo32:85    PCRel = true;86  }87  Fixups.push_back(MCFixup::create(Offset, Value, Kind, PCRel));88}89 90void VEMCCodeEmitter::encodeInstruction(const MCInst &MI,91                                        SmallVectorImpl<char> &CB,92                                        SmallVectorImpl<MCFixup> &Fixups,93                                        const MCSubtargetInfo &STI) const {94  uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);95  support::endian::write<uint64_t>(CB, Bits, llvm::endianness::little);96 97  ++MCNumEmitted; // Keep track of the # of mi's emitted.98}99 100unsigned VEMCCodeEmitter::getMachineOpValue(const MCInst &MI,101                                            const MCOperand &MO,102                                            SmallVectorImpl<MCFixup> &Fixups,103                                            const MCSubtargetInfo &STI) const {104  if (MO.isReg())105    return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());106  if (MO.isImm())107    return static_cast<unsigned>(MO.getImm());108 109  assert(MO.isExpr());110 111  const MCExpr *Expr = MO.getExpr();112  if (const auto *SExpr = dyn_cast<MCSpecifierExpr>(Expr)) {113    auto Kind = VE::getFixupKind(SExpr->getSpecifier());114    addFixup(Fixups, 0, Expr, Kind);115    return 0;116  }117 118  int64_t Res;119  if (Expr->evaluateAsAbsolute(Res))120    return Res;121 122  llvm_unreachable("Unhandled expression!");123  return 0;124}125 126uint64_t127VEMCCodeEmitter::getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,128                                        SmallVectorImpl<MCFixup> &Fixups,129                                        const MCSubtargetInfo &STI) const {130  const MCOperand &MO = MI.getOperand(OpNo);131  if (MO.isReg() || MO.isImm())132    return getMachineOpValue(MI, MO, Fixups, STI);133 134  addFixup(Fixups, 0, MO.getExpr(), VE::fixup_ve_srel32);135  return 0;136}137 138uint64_t VEMCCodeEmitter::getCCOpValue(const MCInst &MI, unsigned OpNo,139                                       SmallVectorImpl<MCFixup> &Fixups,140                                       const MCSubtargetInfo &STI) const {141  const MCOperand &MO = MI.getOperand(OpNo);142  if (MO.isImm())143    return VECondCodeToVal(144        static_cast<VECC::CondCode>(getMachineOpValue(MI, MO, Fixups, STI)));145  return 0;146}147 148uint64_t VEMCCodeEmitter::getRDOpValue(const MCInst &MI, unsigned OpNo,149                                       SmallVectorImpl<MCFixup> &Fixups,150                                       const MCSubtargetInfo &STI) const {151  const MCOperand &MO = MI.getOperand(OpNo);152  if (MO.isImm())153    return VERDToVal(static_cast<VERD::RoundingMode>(154        getMachineOpValue(MI, MO, Fixups, STI)));155  return 0;156}157 158#include "VEGenMCCodeEmitter.inc"159 160MCCodeEmitter *llvm::createVEMCCodeEmitter(const MCInstrInfo &MCII,161                                           MCContext &Ctx) {162  return new VEMCCodeEmitter(MCII, Ctx);163}164