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