| //===-- 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<MCAsmBackend> &&MAB, | |
| std::unique_ptr<MCObjectWriter> &&OW, | |
| std::unique_ptr<MCCodeEmitter> &&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); | |
| } |