Path: blob/main/contrib/llvm-project/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
35294 views
//===-- MipsMCTargetDesc.cpp - Mips Target Descriptions -------------------===//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 provides Mips specific target descriptions.9//10//===----------------------------------------------------------------------===//1112#include "MipsMCTargetDesc.h"13#include "MipsAsmBackend.h"14#include "MipsBaseInfo.h"15#include "MipsELFStreamer.h"16#include "MipsInstPrinter.h"17#include "MipsMCAsmInfo.h"18#include "MipsMCNaCl.h"19#include "MipsTargetStreamer.h"20#include "TargetInfo/MipsTargetInfo.h"21#include "llvm/MC/MCCodeEmitter.h"22#include "llvm/MC/MCELFStreamer.h"23#include "llvm/MC/MCInstrAnalysis.h"24#include "llvm/MC/MCInstrInfo.h"25#include "llvm/MC/MCObjectWriter.h"26#include "llvm/MC/MCRegisterInfo.h"27#include "llvm/MC/MCSubtargetInfo.h"28#include "llvm/MC/MCSymbol.h"29#include "llvm/MC/MachineLocation.h"30#include "llvm/MC/TargetRegistry.h"31#include "llvm/Support/ErrorHandling.h"32#include "llvm/Support/FormattedStream.h"33#include "llvm/TargetParser/Triple.h"3435using namespace llvm;3637#define GET_INSTRINFO_MC_DESC38#define ENABLE_INSTR_PREDICATE_VERIFIER39#include "MipsGenInstrInfo.inc"4041#define GET_SUBTARGETINFO_MC_DESC42#include "MipsGenSubtargetInfo.inc"4344#define GET_REGINFO_MC_DESC45#include "MipsGenRegisterInfo.inc"4647/// Select the Mips CPU for the given triple and cpu name.48StringRef MIPS_MC::selectMipsCPU(const Triple &TT, StringRef CPU) {49if (CPU.empty() || CPU == "generic") {50if (TT.getSubArch() == llvm::Triple::MipsSubArch_r6) {51if (TT.isMIPS32())52CPU = "mips32r6";53else54CPU = "mips64r6";55} else {56if (TT.isMIPS32())57CPU = "mips32";58else59CPU = "mips64";60}61}62return CPU;63}6465static MCInstrInfo *createMipsMCInstrInfo() {66MCInstrInfo *X = new MCInstrInfo();67InitMipsMCInstrInfo(X);68return X;69}7071static MCRegisterInfo *createMipsMCRegisterInfo(const Triple &TT) {72MCRegisterInfo *X = new MCRegisterInfo();73InitMipsMCRegisterInfo(X, Mips::RA);74return X;75}7677static MCSubtargetInfo *createMipsMCSubtargetInfo(const Triple &TT,78StringRef CPU, StringRef FS) {79CPU = MIPS_MC::selectMipsCPU(TT, CPU);80return createMipsMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS);81}8283static MCAsmInfo *createMipsMCAsmInfo(const MCRegisterInfo &MRI,84const Triple &TT,85const MCTargetOptions &Options) {86MCAsmInfo *MAI = new MipsMCAsmInfo(TT, Options);8788unsigned SP = MRI.getDwarfRegNum(Mips::SP, true);89MCCFIInstruction Inst = MCCFIInstruction::createDefCfaRegister(nullptr, SP);90MAI->addInitialFrameState(Inst);9192return MAI;93}9495static MCInstPrinter *createMipsMCInstPrinter(const Triple &T,96unsigned SyntaxVariant,97const MCAsmInfo &MAI,98const MCInstrInfo &MII,99const MCRegisterInfo &MRI) {100return new MipsInstPrinter(MAI, MII, MRI);101}102103static MCStreamer *createMCStreamer(const Triple &T, MCContext &Context,104std::unique_ptr<MCAsmBackend> &&MAB,105std::unique_ptr<MCObjectWriter> &&OW,106std::unique_ptr<MCCodeEmitter> &&Emitter) {107MCStreamer *S;108if (!T.isOSNaCl())109S = createMipsELFStreamer(Context, std::move(MAB), std::move(OW),110std::move(Emitter));111else112S = createMipsNaClELFStreamer(Context, std::move(MAB), std::move(OW),113std::move(Emitter));114return S;115}116117static MCTargetStreamer *createMipsAsmTargetStreamer(MCStreamer &S,118formatted_raw_ostream &OS,119MCInstPrinter *InstPrint) {120return new MipsTargetAsmStreamer(S, OS);121}122123static MCTargetStreamer *createMipsNullTargetStreamer(MCStreamer &S) {124return new MipsTargetStreamer(S);125}126127static MCTargetStreamer *128createMipsObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {129return new MipsTargetELFStreamer(S, STI);130}131132namespace {133134class MipsMCInstrAnalysis : public MCInstrAnalysis {135public:136MipsMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {}137138bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,139uint64_t &Target) const override {140unsigned NumOps = Inst.getNumOperands();141if (NumOps == 0)142return false;143switch (Info->get(Inst.getOpcode()).operands()[NumOps - 1].OperandType) {144case MCOI::OPERAND_UNKNOWN:145case MCOI::OPERAND_IMMEDIATE: {146// j, jal, jalx, jals147// Absolute branch within the current 256 MB-aligned region148uint64_t Region = Addr & ~uint64_t(0xfffffff);149Target = Region + Inst.getOperand(NumOps - 1).getImm();150return true;151}152case MCOI::OPERAND_PCREL:153// b, beq ...154Target = Addr + Inst.getOperand(NumOps - 1).getImm();155return true;156default:157return false;158}159}160};161}162163static MCInstrAnalysis *createMipsMCInstrAnalysis(const MCInstrInfo *Info) {164return new MipsMCInstrAnalysis(Info);165}166167extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsTargetMC() {168for (Target *T : {&getTheMipsTarget(), &getTheMipselTarget(),169&getTheMips64Target(), &getTheMips64elTarget()}) {170// Register the MC asm info.171RegisterMCAsmInfoFn X(*T, createMipsMCAsmInfo);172173// Register the MC instruction info.174TargetRegistry::RegisterMCInstrInfo(*T, createMipsMCInstrInfo);175176// Register the MC register info.177TargetRegistry::RegisterMCRegInfo(*T, createMipsMCRegisterInfo);178179// Register the elf streamer.180TargetRegistry::RegisterELFStreamer(*T, createMCStreamer);181182// Register the asm target streamer.183TargetRegistry::RegisterAsmTargetStreamer(*T, createMipsAsmTargetStreamer);184185TargetRegistry::RegisterNullTargetStreamer(*T,186createMipsNullTargetStreamer);187188// Register the MC subtarget info.189TargetRegistry::RegisterMCSubtargetInfo(*T, createMipsMCSubtargetInfo);190191// Register the MC instruction analyzer.192TargetRegistry::RegisterMCInstrAnalysis(*T, createMipsMCInstrAnalysis);193194// Register the MCInstPrinter.195TargetRegistry::RegisterMCInstPrinter(*T, createMipsMCInstPrinter);196197TargetRegistry::RegisterObjectTargetStreamer(198*T, createMipsObjectTargetStreamer);199200// Register the asm backend.201TargetRegistry::RegisterMCAsmBackend(*T, createMipsAsmBackend);202}203204// Register the MC Code Emitter205for (Target *T : {&getTheMipsTarget(), &getTheMips64Target()})206TargetRegistry::RegisterMCCodeEmitter(*T, createMipsMCCodeEmitterEB);207208for (Target *T : {&getTheMipselTarget(), &getTheMips64elTarget()})209TargetRegistry::RegisterMCCodeEmitter(*T, createMipsMCCodeEmitterEL);210}211212213