170 lines · cpp
1//===-- LanaiMCTargetDesc.cpp - Lanai Target Descriptions -----------------===//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 provides Lanai specific target descriptions.10//11//===----------------------------------------------------------------------===//12 13#include "LanaiMCTargetDesc.h"14#include "LanaiInstPrinter.h"15#include "LanaiMCAsmInfo.h"16#include "TargetInfo/LanaiTargetInfo.h"17#include "llvm/ADT/StringRef.h"18#include "llvm/MC/MCInst.h"19#include "llvm/MC/MCInstrAnalysis.h"20#include "llvm/MC/MCInstrInfo.h"21#include "llvm/MC/MCRegisterInfo.h"22#include "llvm/MC/MCStreamer.h"23#include "llvm/MC/MCSubtargetInfo.h"24#include "llvm/MC/TargetRegistry.h"25#include "llvm/Support/Compiler.h"26#include "llvm/Support/ErrorHandling.h"27#include "llvm/TargetParser/Triple.h"28#include <cstdint>29#include <string>30 31#define GET_INSTRINFO_MC_DESC32#define ENABLE_INSTR_PREDICATE_VERIFIER33#include "LanaiGenInstrInfo.inc"34 35#define GET_SUBTARGETINFO_MC_DESC36#include "LanaiGenSubtargetInfo.inc"37 38#define GET_REGINFO_MC_DESC39#include "LanaiGenRegisterInfo.inc"40 41using namespace llvm;42 43static MCInstrInfo *createLanaiMCInstrInfo() {44 MCInstrInfo *X = new MCInstrInfo();45 InitLanaiMCInstrInfo(X);46 return X;47}48 49static MCRegisterInfo *createLanaiMCRegisterInfo(const Triple & /*TT*/) {50 MCRegisterInfo *X = new MCRegisterInfo();51 InitLanaiMCRegisterInfo(X, Lanai::RCA, 0, 0, Lanai::PC);52 return X;53}54 55static MCSubtargetInfo *56createLanaiMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {57 std::string CPUName = std::string(CPU);58 if (CPUName.empty())59 CPUName = "generic";60 61 return createLanaiMCSubtargetInfoImpl(TT, CPUName, /*TuneCPU*/ CPUName, FS);62}63 64static MCStreamer *createMCStreamer(const Triple &T, MCContext &Context,65 std::unique_ptr<MCAsmBackend> &&MAB,66 std::unique_ptr<MCObjectWriter> &&OW,67 std::unique_ptr<MCCodeEmitter> &&Emitter) {68 if (!T.isOSBinFormatELF())69 llvm_unreachable("OS not supported");70 71 return createELFStreamer(Context, std::move(MAB), std::move(OW),72 std::move(Emitter));73}74 75static MCInstPrinter *createLanaiMCInstPrinter(const Triple & /*T*/,76 unsigned SyntaxVariant,77 const MCAsmInfo &MAI,78 const MCInstrInfo &MII,79 const MCRegisterInfo &MRI) {80 if (SyntaxVariant == 0)81 return new LanaiInstPrinter(MAI, MII, MRI);82 return nullptr;83}84 85static MCRelocationInfo *createLanaiElfRelocation(const Triple &TheTriple,86 MCContext &Ctx) {87 return createMCRelocationInfo(TheTriple, Ctx);88}89 90namespace {91 92class LanaiMCInstrAnalysis : public MCInstrAnalysis {93public:94 explicit LanaiMCInstrAnalysis(const MCInstrInfo *Info)95 : MCInstrAnalysis(Info) {}96 97 bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,98 uint64_t &Target) const override {99 if (Inst.getNumOperands() == 0)100 return false;101 if (!isConditionalBranch(Inst) && !isUnconditionalBranch(Inst) &&102 !isCall(Inst))103 return false;104 105 if (Info->get(Inst.getOpcode()).operands()[0].OperandType ==106 MCOI::OPERAND_PCREL) {107 int64_t Imm = Inst.getOperand(0).getImm();108 Target = Addr + Size + Imm;109 return true;110 } else {111 int64_t Imm = Inst.getOperand(0).getImm();112 113 // Skip case where immediate is 0 as that occurs in file that isn't linked114 // and the branch target inferred would be wrong.115 if (Imm == 0)116 return false;117 118 Target = Imm;119 return true;120 }121 }122};123 124} // end anonymous namespace125 126static MCInstrAnalysis *createLanaiInstrAnalysis(const MCInstrInfo *Info) {127 return new LanaiMCInstrAnalysis(Info);128}129 130extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void131LLVMInitializeLanaiTargetMC() {132 // Register the MC asm info.133 RegisterMCAsmInfo<LanaiMCAsmInfo> X(getTheLanaiTarget());134 135 // Register the MC instruction info.136 TargetRegistry::RegisterMCInstrInfo(getTheLanaiTarget(),137 createLanaiMCInstrInfo);138 139 // Register the MC register info.140 TargetRegistry::RegisterMCRegInfo(getTheLanaiTarget(),141 createLanaiMCRegisterInfo);142 143 // Register the MC subtarget info.144 TargetRegistry::RegisterMCSubtargetInfo(getTheLanaiTarget(),145 createLanaiMCSubtargetInfo);146 147 // Register the MC code emitter148 TargetRegistry::RegisterMCCodeEmitter(getTheLanaiTarget(),149 createLanaiMCCodeEmitter);150 151 // Register the ASM Backend152 TargetRegistry::RegisterMCAsmBackend(getTheLanaiTarget(),153 createLanaiAsmBackend);154 155 // Register the MCInstPrinter.156 TargetRegistry::RegisterMCInstPrinter(getTheLanaiTarget(),157 createLanaiMCInstPrinter);158 159 // Register the ELF streamer.160 TargetRegistry::RegisterELFStreamer(getTheLanaiTarget(), createMCStreamer);161 162 // Register the MC relocation info.163 TargetRegistry::RegisterMCRelocationInfo(getTheLanaiTarget(),164 createLanaiElfRelocation);165 166 // Register the MC instruction analyzer.167 TargetRegistry::RegisterMCInstrAnalysis(getTheLanaiTarget(),168 createLanaiInstrAnalysis);169}170