170 lines · cpp
1//===-- CSKYMCTargetDesc.cpp - CSKY 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 CSKY specific target descriptions.10///11//===----------------------------------------------------------------------===//12 13#include "CSKYMCTargetDesc.h"14#include "CSKYAsmBackend.h"15#include "CSKYELFStreamer.h"16#include "CSKYInstPrinter.h"17#include "CSKYMCAsmInfo.h"18#include "CSKYTargetStreamer.h"19#include "TargetInfo/CSKYTargetInfo.h"20#include "llvm/MC/MCAssembler.h"21#include "llvm/MC/MCInstrAnalysis.h"22#include "llvm/MC/MCInstrInfo.h"23#include "llvm/MC/MCRegisterInfo.h"24#include "llvm/MC/MCSubtargetInfo.h"25#include "llvm/MC/TargetRegistry.h"26 27#define GET_INSTRINFO_MC_DESC28#define ENABLE_INSTR_PREDICATE_VERIFIER29#include "CSKYGenInstrInfo.inc"30 31#define GET_REGINFO_MC_DESC32#include "CSKYGenRegisterInfo.inc"33 34#define GET_SUBTARGETINFO_MC_DESC35#include "CSKYGenSubtargetInfo.inc"36 37using namespace llvm;38 39static MCAsmInfo *createCSKYMCAsmInfo(const MCRegisterInfo &MRI,40 const Triple &TT,41 const MCTargetOptions &Options) {42 MCAsmInfo *MAI = new CSKYMCAsmInfo(TT);43 44 // Initial state of the frame pointer is SP.45 unsigned Reg = MRI.getDwarfRegNum(CSKY::R14, true);46 MCCFIInstruction Inst = MCCFIInstruction::cfiDefCfa(nullptr, Reg, 0);47 MAI->addInitialFrameState(Inst);48 return MAI;49}50 51static MCInstrInfo *createCSKYMCInstrInfo() {52 MCInstrInfo *Info = new MCInstrInfo();53 InitCSKYMCInstrInfo(Info);54 return Info;55}56 57static MCInstPrinter *createCSKYMCInstPrinter(const Triple &T,58 unsigned SyntaxVariant,59 const MCAsmInfo &MAI,60 const MCInstrInfo &MII,61 const MCRegisterInfo &MRI) {62 return new CSKYInstPrinter(MAI, MII, MRI);63}64 65static MCRegisterInfo *createCSKYMCRegisterInfo(const Triple &TT) {66 MCRegisterInfo *Info = new MCRegisterInfo();67 InitCSKYMCRegisterInfo(Info, CSKY::R15);68 return Info;69}70 71static MCSubtargetInfo *createCSKYMCSubtargetInfo(const Triple &TT,72 StringRef CPU, StringRef FS) {73 std::string CPUName = std::string(CPU);74 if (CPUName.empty())75 CPUName = "generic";76 return createCSKYMCSubtargetInfoImpl(TT, CPUName, /*TuneCPU=*/CPUName, FS);77}78 79static MCTargetStreamer *80createCSKYObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {81 const Triple &TT = STI.getTargetTriple();82 if (TT.isOSBinFormatELF())83 return new CSKYTargetELFStreamer(S, STI);84 return nullptr;85}86 87static MCStreamer *createELFStreamer(const Triple &T, MCContext &Ctx,88 std::unique_ptr<MCAsmBackend> &&MAB,89 std::unique_ptr<MCObjectWriter> &&OW,90 std::unique_ptr<MCCodeEmitter> &&Emitter) {91 CSKYELFStreamer *S = new CSKYELFStreamer(Ctx, std::move(MAB), std::move(OW),92 std::move(Emitter));93 94 return S;95}96 97static MCTargetStreamer *98createCSKYAsmTargetStreamer(MCStreamer &S, formatted_raw_ostream &OS,99 MCInstPrinter *InstPrinter) {100 return new CSKYTargetAsmStreamer(S, OS);101}102 103static MCTargetStreamer *createCSKYNullTargetStreamer(MCStreamer &S) {104 return new CSKYTargetStreamer(S);105}106 107namespace {108 109class CSKYMCInstrAnalysis : public MCInstrAnalysis {110public:111 explicit CSKYMCInstrAnalysis(const MCInstrInfo *Info)112 : MCInstrAnalysis(Info) {}113 114 bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,115 uint64_t &Target) const override {116 if (isConditionalBranch(Inst) || isUnconditionalBranch(Inst)) {117 int64_t Imm;118 Imm = Inst.getOperand(Inst.getNumOperands() - 1).getImm();119 Target = Addr + Imm;120 return true;121 }122 123 if (Inst.getOpcode() == CSKY::BSR32) {124 Target = Addr + Inst.getOperand(0).getImm();125 return true;126 }127 128 switch (Inst.getOpcode()) {129 default:130 return false;131 case CSKY::LRW16:132 case CSKY::LRW32:133 case CSKY::JSRI32:134 case CSKY::JMPI32:135 int64_t Imm = Inst.getOperand(Inst.getNumOperands() - 1).getImm();136 Target = ((Addr + Imm) & 0xFFFFFFFC);137 return true;138 }139 140 return false;141 }142};143 144} // end anonymous namespace145 146static MCInstrAnalysis *createCSKYInstrAnalysis(const MCInstrInfo *Info) {147 return new CSKYMCInstrAnalysis(Info);148}149 150extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYTargetMC() {151 auto &CSKYTarget = getTheCSKYTarget();152 TargetRegistry::RegisterMCAsmBackend(CSKYTarget, createCSKYAsmBackend);153 TargetRegistry::RegisterMCAsmInfo(CSKYTarget, createCSKYMCAsmInfo);154 TargetRegistry::RegisterMCInstrInfo(CSKYTarget, createCSKYMCInstrInfo);155 TargetRegistry::RegisterMCRegInfo(CSKYTarget, createCSKYMCRegisterInfo);156 TargetRegistry::RegisterMCCodeEmitter(CSKYTarget, createCSKYMCCodeEmitter);157 TargetRegistry::RegisterMCInstPrinter(CSKYTarget, createCSKYMCInstPrinter);158 TargetRegistry::RegisterMCSubtargetInfo(CSKYTarget,159 createCSKYMCSubtargetInfo);160 TargetRegistry::RegisterELFStreamer(CSKYTarget, createELFStreamer);161 TargetRegistry::RegisterObjectTargetStreamer(CSKYTarget,162 createCSKYObjectTargetStreamer);163 TargetRegistry::RegisterAsmTargetStreamer(CSKYTarget,164 createCSKYAsmTargetStreamer);165 // Register the null target streamer.166 TargetRegistry::RegisterNullTargetStreamer(CSKYTarget,167 createCSKYNullTargetStreamer);168 TargetRegistry::RegisterMCInstrAnalysis(CSKYTarget, createCSKYInstrAnalysis);169}170