1 //===-- MipsMCTargetDesc.cpp - Mips Target Descriptions -------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file provides Mips specific target descriptions. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "MipsMCTargetDesc.h" 15 #include "InstPrinter/MipsInstPrinter.h" 16 #include "MipsAsmBackend.h" 17 #include "MipsELFStreamer.h" 18 #include "MipsMCAsmInfo.h" 19 #include "MipsMCNaCl.h" 20 #include "MipsTargetStreamer.h" 21 #include "llvm/ADT/Triple.h" 22 #include "llvm/MC/MCCodeEmitter.h" 23 #include "llvm/MC/MCELFStreamer.h" 24 #include "llvm/MC/MCInstrAnalysis.h" 25 #include "llvm/MC/MCInstrInfo.h" 26 #include "llvm/MC/MCRegisterInfo.h" 27 #include "llvm/MC/MCSubtargetInfo.h" 28 #include "llvm/MC/MCSymbol.h" 29 #include "llvm/MC/MachineLocation.h" 30 #include "llvm/Support/ErrorHandling.h" 31 #include "llvm/Support/FormattedStream.h" 32 #include "llvm/Support/TargetRegistry.h" 33 34 using namespace llvm; 35 36 #define GET_INSTRINFO_MC_DESC 37 #include "MipsGenInstrInfo.inc" 38 39 #define GET_SUBTARGETINFO_MC_DESC 40 #include "MipsGenSubtargetInfo.inc" 41 42 #define GET_REGINFO_MC_DESC 43 #include "MipsGenRegisterInfo.inc" 44 45 /// Select the Mips CPU for the given triple and cpu name. 46 /// FIXME: Merge with the copy in MipsSubtarget.cpp 47 StringRef MIPS_MC::selectMipsCPU(const Triple &TT, StringRef CPU) { 48 if (CPU.empty() || CPU == "generic") { 49 if (TT.getArch() == Triple::mips || TT.getArch() == Triple::mipsel) 50 CPU = "mips32"; 51 else 52 CPU = "mips64"; 53 } 54 return CPU; 55 } 56 57 static MCInstrInfo *createMipsMCInstrInfo() { 58 MCInstrInfo *X = new MCInstrInfo(); 59 InitMipsMCInstrInfo(X); 60 return X; 61 } 62 63 static MCRegisterInfo *createMipsMCRegisterInfo(const Triple &TT) { 64 MCRegisterInfo *X = new MCRegisterInfo(); 65 InitMipsMCRegisterInfo(X, Mips::RA); 66 return X; 67 } 68 69 static MCSubtargetInfo *createMipsMCSubtargetInfo(const Triple &TT, 70 StringRef CPU, StringRef FS) { 71 CPU = MIPS_MC::selectMipsCPU(TT, CPU); 72 return createMipsMCSubtargetInfoImpl(TT, CPU, FS); 73 } 74 75 static MCAsmInfo *createMipsMCAsmInfo(const MCRegisterInfo &MRI, 76 const Triple &TT) { 77 MCAsmInfo *MAI = new MipsMCAsmInfo(TT); 78 79 unsigned SP = MRI.getDwarfRegNum(Mips::SP, true); 80 MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(nullptr, SP, 0); 81 MAI->addInitialFrameState(Inst); 82 83 return MAI; 84 } 85 86 static MCInstPrinter *createMipsMCInstPrinter(const Triple &T, 87 unsigned SyntaxVariant, 88 const MCAsmInfo &MAI, 89 const MCInstrInfo &MII, 90 const MCRegisterInfo &MRI) { 91 return new MipsInstPrinter(MAI, MII, MRI); 92 } 93 94 static MCStreamer *createMCStreamer(const Triple &T, MCContext &Context, 95 std::unique_ptr<MCAsmBackend> &&MAB, 96 raw_pwrite_stream &OS, 97 std::unique_ptr<MCCodeEmitter> &&Emitter, 98 bool RelaxAll) { 99 MCStreamer *S; 100 if (!T.isOSNaCl()) 101 S = createMipsELFStreamer(Context, std::move(MAB), OS, std::move(Emitter), 102 RelaxAll); 103 else 104 S = createMipsNaClELFStreamer(Context, std::move(MAB), OS, 105 std::move(Emitter), RelaxAll); 106 return S; 107 } 108 109 static MCTargetStreamer *createMipsAsmTargetStreamer(MCStreamer &S, 110 formatted_raw_ostream &OS, 111 MCInstPrinter *InstPrint, 112 bool isVerboseAsm) { 113 return new MipsTargetAsmStreamer(S, OS); 114 } 115 116 static MCTargetStreamer *createMipsNullTargetStreamer(MCStreamer &S) { 117 return new MipsTargetStreamer(S); 118 } 119 120 static MCTargetStreamer * 121 createMipsObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) { 122 return new MipsTargetELFStreamer(S, STI); 123 } 124 125 namespace { 126 127 class MipsMCInstrAnalysis : public MCInstrAnalysis { 128 public: 129 MipsMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {} 130 131 bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size, 132 uint64_t &Target) const override { 133 unsigned NumOps = Inst.getNumOperands(); 134 if (NumOps == 0) 135 return false; 136 switch (Info->get(Inst.getOpcode()).OpInfo[NumOps - 1].OperandType) { 137 case MCOI::OPERAND_UNKNOWN: 138 case MCOI::OPERAND_IMMEDIATE: 139 // jal, bal ... 140 Target = Inst.getOperand(NumOps - 1).getImm(); 141 return true; 142 case MCOI::OPERAND_PCREL: 143 // b, j, beq ... 144 Target = Addr + Inst.getOperand(NumOps - 1).getImm(); 145 return true; 146 default: 147 return false; 148 } 149 } 150 }; 151 } 152 153 static MCInstrAnalysis *createMipsMCInstrAnalysis(const MCInstrInfo *Info) { 154 return new MipsMCInstrAnalysis(Info); 155 } 156 157 extern "C" void LLVMInitializeMipsTargetMC() { 158 for (Target *T : {&getTheMipsTarget(), &getTheMipselTarget(), 159 &getTheMips64Target(), &getTheMips64elTarget()}) { 160 // Register the MC asm info. 161 RegisterMCAsmInfoFn X(*T, createMipsMCAsmInfo); 162 163 // Register the MC instruction info. 164 TargetRegistry::RegisterMCInstrInfo(*T, createMipsMCInstrInfo); 165 166 // Register the MC register info. 167 TargetRegistry::RegisterMCRegInfo(*T, createMipsMCRegisterInfo); 168 169 // Register the elf streamer. 170 TargetRegistry::RegisterELFStreamer(*T, createMCStreamer); 171 172 // Register the asm target streamer. 173 TargetRegistry::RegisterAsmTargetStreamer(*T, createMipsAsmTargetStreamer); 174 175 TargetRegistry::RegisterNullTargetStreamer(*T, 176 createMipsNullTargetStreamer); 177 178 // Register the MC subtarget info. 179 TargetRegistry::RegisterMCSubtargetInfo(*T, createMipsMCSubtargetInfo); 180 181 // Register the MC instruction analyzer. 182 TargetRegistry::RegisterMCInstrAnalysis(*T, createMipsMCInstrAnalysis); 183 184 // Register the MCInstPrinter. 185 TargetRegistry::RegisterMCInstPrinter(*T, createMipsMCInstPrinter); 186 187 TargetRegistry::RegisterObjectTargetStreamer( 188 *T, createMipsObjectTargetStreamer); 189 190 // Register the asm backend. 191 TargetRegistry::RegisterMCAsmBackend(*T, createMipsAsmBackend); 192 } 193 194 // Register the MC Code Emitter 195 for (Target *T : {&getTheMipsTarget(), &getTheMips64Target()}) 196 TargetRegistry::RegisterMCCodeEmitter(*T, createMipsMCCodeEmitterEB); 197 198 for (Target *T : {&getTheMipselTarget(), &getTheMips64elTarget()}) 199 TargetRegistry::RegisterMCCodeEmitter(*T, createMipsMCCodeEmitterEL); 200 } 201