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