//===-- CSKYMCTargetDesc.cpp - CSKY Target Descriptions -------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// /// This file provides CSKY specific target descriptions. /// //===----------------------------------------------------------------------===// #include "CSKYMCTargetDesc.h" #include "CSKYAsmBackend.h" #include "CSKYELFStreamer.h" #include "CSKYInstPrinter.h" #include "CSKYMCAsmInfo.h" #include "CSKYMCCodeEmitter.h" #include "CSKYTargetStreamer.h" #include "TargetInfo/CSKYTargetInfo.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCInstrAnalysis.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/TargetRegistry.h" #define GET_INSTRINFO_MC_DESC #define ENABLE_INSTR_PREDICATE_VERIFIER #include "CSKYGenInstrInfo.inc" #define GET_REGINFO_MC_DESC #include "CSKYGenRegisterInfo.inc" #define GET_SUBTARGETINFO_MC_DESC #include "CSKYGenSubtargetInfo.inc" using namespace llvm; static MCAsmInfo *createCSKYMCAsmInfo(const MCRegisterInfo &MRI, const Triple &TT, const MCTargetOptions &Options) { MCAsmInfo *MAI = new CSKYMCAsmInfo(TT); // Initial state of the frame pointer is SP. unsigned Reg = MRI.getDwarfRegNum(CSKY::R14, true); MCCFIInstruction Inst = MCCFIInstruction::cfiDefCfa(nullptr, Reg, 0); MAI->addInitialFrameState(Inst); return MAI; } static MCInstrInfo *createCSKYMCInstrInfo() { MCInstrInfo *Info = new MCInstrInfo(); InitCSKYMCInstrInfo(Info); return Info; } static MCInstPrinter *createCSKYMCInstPrinter(const Triple &T, unsigned SyntaxVariant, const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI) { return new CSKYInstPrinter(MAI, MII, MRI); } static MCRegisterInfo *createCSKYMCRegisterInfo(const Triple &TT) { MCRegisterInfo *Info = new MCRegisterInfo(); InitCSKYMCRegisterInfo(Info, CSKY::R15); return Info; } static MCSubtargetInfo *createCSKYMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) { std::string CPUName = std::string(CPU); if (CPUName.empty()) CPUName = "generic"; return createCSKYMCSubtargetInfoImpl(TT, CPUName, /*TuneCPU=*/CPUName, FS); } static MCTargetStreamer * createCSKYObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) { const Triple &TT = STI.getTargetTriple(); if (TT.isOSBinFormatELF()) return new CSKYTargetELFStreamer(S, STI); return nullptr; } static MCStreamer *createELFStreamer(const Triple &T, MCContext &Ctx, std::unique_ptr &&MAB, std::unique_ptr &&OW, std::unique_ptr &&Emitter, bool RelaxAll) { CSKYELFStreamer *S = new CSKYELFStreamer(Ctx, std::move(MAB), std::move(OW), std::move(Emitter)); if (RelaxAll) S->getAssembler().setRelaxAll(true); return S; } static MCTargetStreamer *createCSKYAsmTargetStreamer(MCStreamer &S, formatted_raw_ostream &OS, MCInstPrinter *InstPrinter, bool isVerboseAsm) { return new CSKYTargetAsmStreamer(S, OS); } static MCTargetStreamer *createCSKYNullTargetStreamer(MCStreamer &S) { return new CSKYTargetStreamer(S); } namespace { class CSKYMCInstrAnalysis : public MCInstrAnalysis { public: explicit CSKYMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {} bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size, uint64_t &Target) const override { if (isConditionalBranch(Inst) || isUnconditionalBranch(Inst)) { int64_t Imm; Imm = Inst.getOperand(Inst.getNumOperands() - 1).getImm(); Target = Addr + Imm; return true; } if (Inst.getOpcode() == CSKY::BSR32) { Target = Addr + Inst.getOperand(0).getImm(); return true; } switch (Inst.getOpcode()) { default: return false; case CSKY::LRW16: case CSKY::LRW32: case CSKY::JSRI32: case CSKY::JMPI32: int64_t Imm = Inst.getOperand(Inst.getNumOperands() - 1).getImm(); Target = ((Addr + Imm) & 0xFFFFFFFC); return true; } return false; } }; } // end anonymous namespace static MCInstrAnalysis *createCSKYInstrAnalysis(const MCInstrInfo *Info) { return new CSKYMCInstrAnalysis(Info); } extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYTargetMC() { auto &CSKYTarget = getTheCSKYTarget(); TargetRegistry::RegisterMCAsmBackend(CSKYTarget, createCSKYAsmBackend); TargetRegistry::RegisterMCAsmInfo(CSKYTarget, createCSKYMCAsmInfo); TargetRegistry::RegisterMCInstrInfo(CSKYTarget, createCSKYMCInstrInfo); TargetRegistry::RegisterMCRegInfo(CSKYTarget, createCSKYMCRegisterInfo); TargetRegistry::RegisterMCCodeEmitter(CSKYTarget, createCSKYMCCodeEmitter); TargetRegistry::RegisterMCInstPrinter(CSKYTarget, createCSKYMCInstPrinter); TargetRegistry::RegisterMCSubtargetInfo(CSKYTarget, createCSKYMCSubtargetInfo); TargetRegistry::RegisterELFStreamer(CSKYTarget, createELFStreamer); TargetRegistry::RegisterObjectTargetStreamer(CSKYTarget, createCSKYObjectTargetStreamer); TargetRegistry::RegisterAsmTargetStreamer(CSKYTarget, createCSKYAsmTargetStreamer); // Register the null target streamer. TargetRegistry::RegisterNullTargetStreamer(CSKYTarget, createCSKYNullTargetStreamer); TargetRegistry::RegisterMCInstrAnalysis(CSKYTarget, createCSKYInstrAnalysis); }