1 //===-- LanaiMCTargetDesc.cpp - Lanai 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 Lanai specific target descriptions. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "LanaiMCTargetDesc.h" 14 #include "LanaiInstPrinter.h" 15 #include "LanaiMCAsmInfo.h" 16 #include "TargetInfo/LanaiTargetInfo.h" 17 #include "llvm/ADT/StringRef.h" 18 #include "llvm/ADT/Triple.h" 19 #include "llvm/MC/MCInst.h" 20 #include "llvm/MC/MCInstrAnalysis.h" 21 #include "llvm/MC/MCInstrInfo.h" 22 #include "llvm/MC/MCRegisterInfo.h" 23 #include "llvm/MC/MCStreamer.h" 24 #include "llvm/MC/MCSubtargetInfo.h" 25 #include "llvm/MC/TargetRegistry.h" 26 #include "llvm/Support/ErrorHandling.h" 27 #include <cstdint> 28 #include <string> 29 30 #define GET_INSTRINFO_MC_DESC 31 #define ENABLE_INSTR_PREDICATE_VERIFIER 32 #include "LanaiGenInstrInfo.inc" 33 34 #define GET_SUBTARGETINFO_MC_DESC 35 #include "LanaiGenSubtargetInfo.inc" 36 37 #define GET_REGINFO_MC_DESC 38 #include "LanaiGenRegisterInfo.inc" 39 40 using namespace llvm; 41 42 static MCInstrInfo *createLanaiMCInstrInfo() { 43 MCInstrInfo *X = new MCInstrInfo(); 44 InitLanaiMCInstrInfo(X); 45 return X; 46 } 47 48 static MCRegisterInfo *createLanaiMCRegisterInfo(const Triple & /*TT*/) { 49 MCRegisterInfo *X = new MCRegisterInfo(); 50 InitLanaiMCRegisterInfo(X, Lanai::RCA, 0, 0, Lanai::PC); 51 return X; 52 } 53 54 static MCSubtargetInfo * 55 createLanaiMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) { 56 std::string CPUName = std::string(CPU); 57 if (CPUName.empty()) 58 CPUName = "generic"; 59 60 return createLanaiMCSubtargetInfoImpl(TT, CPUName, /*TuneCPU*/ CPUName, FS); 61 } 62 63 static MCStreamer *createMCStreamer(const Triple &T, MCContext &Context, 64 std::unique_ptr<MCAsmBackend> &&MAB, 65 std::unique_ptr<MCObjectWriter> &&OW, 66 std::unique_ptr<MCCodeEmitter> &&Emitter, 67 bool RelaxAll) { 68 if (!T.isOSBinFormatELF()) 69 llvm_unreachable("OS not supported"); 70 71 return createELFStreamer(Context, std::move(MAB), std::move(OW), 72 std::move(Emitter), RelaxAll); 73 } 74 75 static MCInstPrinter *createLanaiMCInstPrinter(const Triple & /*T*/, 76 unsigned SyntaxVariant, 77 const MCAsmInfo &MAI, 78 const MCInstrInfo &MII, 79 const MCRegisterInfo &MRI) { 80 if (SyntaxVariant == 0) 81 return new LanaiInstPrinter(MAI, MII, MRI); 82 return nullptr; 83 } 84 85 static MCRelocationInfo *createLanaiElfRelocation(const Triple &TheTriple, 86 MCContext &Ctx) { 87 return createMCRelocationInfo(TheTriple, Ctx); 88 } 89 90 namespace { 91 92 class LanaiMCInstrAnalysis : public MCInstrAnalysis { 93 public: 94 explicit LanaiMCInstrAnalysis(const MCInstrInfo *Info) 95 : MCInstrAnalysis(Info) {} 96 97 bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size, 98 uint64_t &Target) const override { 99 if (Inst.getNumOperands() == 0) 100 return false; 101 if (!isConditionalBranch(Inst) && !isUnconditionalBranch(Inst) && 102 !isCall(Inst)) 103 return false; 104 105 if (Info->get(Inst.getOpcode()).operands()[0].OperandType == 106 MCOI::OPERAND_PCREL) { 107 int64_t Imm = Inst.getOperand(0).getImm(); 108 Target = Addr + Size + Imm; 109 return true; 110 } else { 111 int64_t Imm = Inst.getOperand(0).getImm(); 112 113 // Skip case where immediate is 0 as that occurs in file that isn't linked 114 // and the branch target inferred would be wrong. 115 if (Imm == 0) 116 return false; 117 118 Target = Imm; 119 return true; 120 } 121 } 122 }; 123 124 } // end anonymous namespace 125 126 static MCInstrAnalysis *createLanaiInstrAnalysis(const MCInstrInfo *Info) { 127 return new LanaiMCInstrAnalysis(Info); 128 } 129 130 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLanaiTargetMC() { 131 // Register the MC asm info. 132 RegisterMCAsmInfo<LanaiMCAsmInfo> X(getTheLanaiTarget()); 133 134 // Register the MC instruction info. 135 TargetRegistry::RegisterMCInstrInfo(getTheLanaiTarget(), 136 createLanaiMCInstrInfo); 137 138 // Register the MC register info. 139 TargetRegistry::RegisterMCRegInfo(getTheLanaiTarget(), 140 createLanaiMCRegisterInfo); 141 142 // Register the MC subtarget info. 143 TargetRegistry::RegisterMCSubtargetInfo(getTheLanaiTarget(), 144 createLanaiMCSubtargetInfo); 145 146 // Register the MC code emitter 147 TargetRegistry::RegisterMCCodeEmitter(getTheLanaiTarget(), 148 createLanaiMCCodeEmitter); 149 150 // Register the ASM Backend 151 TargetRegistry::RegisterMCAsmBackend(getTheLanaiTarget(), 152 createLanaiAsmBackend); 153 154 // Register the MCInstPrinter. 155 TargetRegistry::RegisterMCInstPrinter(getTheLanaiTarget(), 156 createLanaiMCInstPrinter); 157 158 // Register the ELF streamer. 159 TargetRegistry::RegisterELFStreamer(getTheLanaiTarget(), createMCStreamer); 160 161 // Register the MC relocation info. 162 TargetRegistry::RegisterMCRelocationInfo(getTheLanaiTarget(), 163 createLanaiElfRelocation); 164 165 // Register the MC instruction analyzer. 166 TargetRegistry::RegisterMCInstrAnalysis(getTheLanaiTarget(), 167 createLanaiInstrAnalysis); 168 } 169