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 #include "CSKYGenInstrInfo.inc" 30 31 #define GET_REGINFO_MC_DESC 32 #include "CSKYGenRegisterInfo.inc" 33 34 #define GET_SUBTARGETINFO_MC_DESC 35 #include "CSKYGenSubtargetInfo.inc" 36 37 using namespace llvm; 38 39 static 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 51 static MCInstrInfo *createCSKYMCInstrInfo() { 52 MCInstrInfo *Info = new MCInstrInfo(); 53 InitCSKYMCInstrInfo(Info); 54 return Info; 55 } 56 57 static 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 65 static MCRegisterInfo *createCSKYMCRegisterInfo(const Triple &TT) { 66 MCRegisterInfo *Info = new MCRegisterInfo(); 67 InitCSKYMCRegisterInfo(Info, CSKY::R15); 68 return Info; 69 } 70 71 static 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 79 static MCTargetStreamer * 80 createCSKYObjectTargetStreamer(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 87 static 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 bool RelaxAll) { 92 CSKYELFStreamer *S = new CSKYELFStreamer(Ctx, std::move(MAB), std::move(OW), 93 std::move(Emitter)); 94 95 if (RelaxAll) 96 S->getAssembler().setRelaxAll(true); 97 return S; 98 } 99 100 static MCTargetStreamer *createCSKYAsmTargetStreamer(MCStreamer &S, 101 formatted_raw_ostream &OS, 102 MCInstPrinter *InstPrinter, 103 bool isVerboseAsm) { 104 return new CSKYTargetAsmStreamer(S, OS); 105 } 106 107 static MCTargetStreamer *createCSKYNullTargetStreamer(MCStreamer &S) { 108 return new CSKYTargetStreamer(S); 109 } 110 111 namespace { 112 113 class CSKYMCInstrAnalysis : public MCInstrAnalysis { 114 public: 115 explicit CSKYMCInstrAnalysis(const MCInstrInfo *Info) 116 : MCInstrAnalysis(Info) {} 117 118 bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size, 119 uint64_t &Target) const override { 120 if (isConditionalBranch(Inst) || isUnconditionalBranch(Inst)) { 121 int64_t Imm; 122 Imm = Inst.getOperand(Inst.getNumOperands() - 1).getImm(); 123 Target = Addr + Imm; 124 return true; 125 } 126 127 if (Inst.getOpcode() == CSKY::BSR32) { 128 Target = Addr + Inst.getOperand(0).getImm(); 129 return true; 130 } 131 132 switch (Inst.getOpcode()) { 133 default: 134 return false; 135 case CSKY::LRW16: 136 case CSKY::LRW32: 137 case CSKY::JSRI32: 138 case CSKY::JMPI32: 139 int64_t Imm = Inst.getOperand(Inst.getNumOperands() - 1).getImm(); 140 Target = ((Addr + Imm) & 0xFFFFFFFC); 141 return true; 142 } 143 144 return false; 145 } 146 }; 147 148 } // end anonymous namespace 149 150 static MCInstrAnalysis *createCSKYInstrAnalysis(const MCInstrInfo *Info) { 151 return new CSKYMCInstrAnalysis(Info); 152 } 153 154 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYTargetMC() { 155 auto &CSKYTarget = getTheCSKYTarget(); 156 TargetRegistry::RegisterMCAsmBackend(CSKYTarget, createCSKYAsmBackend); 157 TargetRegistry::RegisterMCAsmInfo(CSKYTarget, createCSKYMCAsmInfo); 158 TargetRegistry::RegisterMCInstrInfo(CSKYTarget, createCSKYMCInstrInfo); 159 TargetRegistry::RegisterMCRegInfo(CSKYTarget, createCSKYMCRegisterInfo); 160 TargetRegistry::RegisterMCCodeEmitter(CSKYTarget, createCSKYMCCodeEmitter); 161 TargetRegistry::RegisterMCInstPrinter(CSKYTarget, createCSKYMCInstPrinter); 162 TargetRegistry::RegisterMCSubtargetInfo(CSKYTarget, 163 createCSKYMCSubtargetInfo); 164 TargetRegistry::RegisterELFStreamer(CSKYTarget, createELFStreamer); 165 TargetRegistry::RegisterObjectTargetStreamer(CSKYTarget, 166 createCSKYObjectTargetStreamer); 167 TargetRegistry::RegisterAsmTargetStreamer(CSKYTarget, 168 createCSKYAsmTargetStreamer); 169 // Register the null target streamer. 170 TargetRegistry::RegisterNullTargetStreamer(CSKYTarget, 171 createCSKYNullTargetStreamer); 172 TargetRegistry::RegisterMCInstrAnalysis(CSKYTarget, createCSKYInstrAnalysis); 173 } 174