xref: /netbsd-src/external/apache2/llvm/dist/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp (revision 82d56013d7b633d116a93943de88e08335357a7c)
17330f729Sjoerg //===-- MipsMCTargetDesc.cpp - Mips Target Descriptions -------------------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // This file provides Mips specific target descriptions.
107330f729Sjoerg //
117330f729Sjoerg //===----------------------------------------------------------------------===//
127330f729Sjoerg 
137330f729Sjoerg #include "MipsMCTargetDesc.h"
147330f729Sjoerg #include "MipsAsmBackend.h"
15*82d56013Sjoerg #include "MipsBaseInfo.h"
167330f729Sjoerg #include "MipsELFStreamer.h"
177330f729Sjoerg #include "MipsInstPrinter.h"
187330f729Sjoerg #include "MipsMCAsmInfo.h"
197330f729Sjoerg #include "MipsMCNaCl.h"
207330f729Sjoerg #include "MipsTargetStreamer.h"
217330f729Sjoerg #include "TargetInfo/MipsTargetInfo.h"
227330f729Sjoerg #include "llvm/ADT/Triple.h"
237330f729Sjoerg #include "llvm/MC/MCCodeEmitter.h"
247330f729Sjoerg #include "llvm/MC/MCELFStreamer.h"
257330f729Sjoerg #include "llvm/MC/MCInstrAnalysis.h"
267330f729Sjoerg #include "llvm/MC/MCInstrInfo.h"
277330f729Sjoerg #include "llvm/MC/MCObjectWriter.h"
287330f729Sjoerg #include "llvm/MC/MCRegisterInfo.h"
297330f729Sjoerg #include "llvm/MC/MCSubtargetInfo.h"
307330f729Sjoerg #include "llvm/MC/MCSymbol.h"
317330f729Sjoerg #include "llvm/MC/MachineLocation.h"
327330f729Sjoerg #include "llvm/Support/ErrorHandling.h"
337330f729Sjoerg #include "llvm/Support/FormattedStream.h"
347330f729Sjoerg #include "llvm/Support/TargetRegistry.h"
357330f729Sjoerg 
367330f729Sjoerg using namespace llvm;
377330f729Sjoerg 
387330f729Sjoerg #define GET_INSTRINFO_MC_DESC
397330f729Sjoerg #include "MipsGenInstrInfo.inc"
407330f729Sjoerg 
417330f729Sjoerg #define GET_SUBTARGETINFO_MC_DESC
427330f729Sjoerg #include "MipsGenSubtargetInfo.inc"
437330f729Sjoerg 
447330f729Sjoerg #define GET_REGINFO_MC_DESC
457330f729Sjoerg #include "MipsGenRegisterInfo.inc"
467330f729Sjoerg 
477330f729Sjoerg /// Select the Mips CPU for the given triple and cpu name.
selectMipsCPU(const Triple & TT,StringRef CPU)487330f729Sjoerg StringRef MIPS_MC::selectMipsCPU(const Triple &TT, StringRef CPU) {
497330f729Sjoerg   if (CPU.empty() || CPU == "generic") {
507330f729Sjoerg     if (TT.getSubArch() == llvm::Triple::MipsSubArch_r6) {
517330f729Sjoerg       if (TT.isMIPS32())
527330f729Sjoerg         CPU = "mips32r6";
537330f729Sjoerg       else
547330f729Sjoerg         CPU = "mips64r6";
557330f729Sjoerg     } else {
567330f729Sjoerg       if (TT.isMIPS32())
577330f729Sjoerg         CPU = "mips32";
587330f729Sjoerg       else
597330f729Sjoerg         CPU = "mips64";
607330f729Sjoerg     }
617330f729Sjoerg   }
627330f729Sjoerg   return CPU;
637330f729Sjoerg }
647330f729Sjoerg 
createMipsMCInstrInfo()657330f729Sjoerg static MCInstrInfo *createMipsMCInstrInfo() {
667330f729Sjoerg   MCInstrInfo *X = new MCInstrInfo();
677330f729Sjoerg   InitMipsMCInstrInfo(X);
687330f729Sjoerg   return X;
697330f729Sjoerg }
707330f729Sjoerg 
createMipsMCRegisterInfo(const Triple & TT)717330f729Sjoerg static MCRegisterInfo *createMipsMCRegisterInfo(const Triple &TT) {
727330f729Sjoerg   MCRegisterInfo *X = new MCRegisterInfo();
737330f729Sjoerg   InitMipsMCRegisterInfo(X, Mips::RA);
747330f729Sjoerg   return X;
757330f729Sjoerg }
767330f729Sjoerg 
createMipsMCSubtargetInfo(const Triple & TT,StringRef CPU,StringRef FS)777330f729Sjoerg static MCSubtargetInfo *createMipsMCSubtargetInfo(const Triple &TT,
787330f729Sjoerg                                                   StringRef CPU, StringRef FS) {
797330f729Sjoerg   CPU = MIPS_MC::selectMipsCPU(TT, CPU);
80*82d56013Sjoerg   return createMipsMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS);
817330f729Sjoerg }
827330f729Sjoerg 
createMipsMCAsmInfo(const MCRegisterInfo & MRI,const Triple & TT,const MCTargetOptions & Options)837330f729Sjoerg static MCAsmInfo *createMipsMCAsmInfo(const MCRegisterInfo &MRI,
847330f729Sjoerg                                       const Triple &TT,
857330f729Sjoerg                                       const MCTargetOptions &Options) {
867330f729Sjoerg   MCAsmInfo *MAI = new MipsMCAsmInfo(TT, Options);
877330f729Sjoerg 
887330f729Sjoerg   unsigned SP = MRI.getDwarfRegNum(Mips::SP, true);
897330f729Sjoerg   MCCFIInstruction Inst = MCCFIInstruction::createDefCfaRegister(nullptr, SP);
907330f729Sjoerg   MAI->addInitialFrameState(Inst);
917330f729Sjoerg 
927330f729Sjoerg   return MAI;
937330f729Sjoerg }
947330f729Sjoerg 
createMipsMCInstPrinter(const Triple & T,unsigned SyntaxVariant,const MCAsmInfo & MAI,const MCInstrInfo & MII,const MCRegisterInfo & MRI)957330f729Sjoerg static MCInstPrinter *createMipsMCInstPrinter(const Triple &T,
967330f729Sjoerg                                               unsigned SyntaxVariant,
977330f729Sjoerg                                               const MCAsmInfo &MAI,
987330f729Sjoerg                                               const MCInstrInfo &MII,
997330f729Sjoerg                                               const MCRegisterInfo &MRI) {
1007330f729Sjoerg   return new MipsInstPrinter(MAI, MII, MRI);
1017330f729Sjoerg }
1027330f729Sjoerg 
createMCStreamer(const Triple & T,MCContext & Context,std::unique_ptr<MCAsmBackend> && MAB,std::unique_ptr<MCObjectWriter> && OW,std::unique_ptr<MCCodeEmitter> && Emitter,bool RelaxAll)1037330f729Sjoerg static MCStreamer *createMCStreamer(const Triple &T, MCContext &Context,
1047330f729Sjoerg                                     std::unique_ptr<MCAsmBackend> &&MAB,
1057330f729Sjoerg                                     std::unique_ptr<MCObjectWriter> &&OW,
1067330f729Sjoerg                                     std::unique_ptr<MCCodeEmitter> &&Emitter,
1077330f729Sjoerg                                     bool RelaxAll) {
1087330f729Sjoerg   MCStreamer *S;
1097330f729Sjoerg   if (!T.isOSNaCl())
1107330f729Sjoerg     S = createMipsELFStreamer(Context, std::move(MAB), std::move(OW),
1117330f729Sjoerg                               std::move(Emitter), RelaxAll);
1127330f729Sjoerg   else
1137330f729Sjoerg     S = createMipsNaClELFStreamer(Context, std::move(MAB), std::move(OW),
1147330f729Sjoerg                                   std::move(Emitter), RelaxAll);
1157330f729Sjoerg   return S;
1167330f729Sjoerg }
1177330f729Sjoerg 
createMipsAsmTargetStreamer(MCStreamer & S,formatted_raw_ostream & OS,MCInstPrinter * InstPrint,bool isVerboseAsm)1187330f729Sjoerg static MCTargetStreamer *createMipsAsmTargetStreamer(MCStreamer &S,
1197330f729Sjoerg                                                      formatted_raw_ostream &OS,
1207330f729Sjoerg                                                      MCInstPrinter *InstPrint,
1217330f729Sjoerg                                                      bool isVerboseAsm) {
1227330f729Sjoerg   return new MipsTargetAsmStreamer(S, OS);
1237330f729Sjoerg }
1247330f729Sjoerg 
createMipsNullTargetStreamer(MCStreamer & S)1257330f729Sjoerg static MCTargetStreamer *createMipsNullTargetStreamer(MCStreamer &S) {
1267330f729Sjoerg   return new MipsTargetStreamer(S);
1277330f729Sjoerg }
1287330f729Sjoerg 
1297330f729Sjoerg static MCTargetStreamer *
createMipsObjectTargetStreamer(MCStreamer & S,const MCSubtargetInfo & STI)1307330f729Sjoerg createMipsObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
1317330f729Sjoerg   return new MipsTargetELFStreamer(S, STI);
1327330f729Sjoerg }
1337330f729Sjoerg 
1347330f729Sjoerg namespace {
1357330f729Sjoerg 
1367330f729Sjoerg class MipsMCInstrAnalysis : public MCInstrAnalysis {
1377330f729Sjoerg public:
MipsMCInstrAnalysis(const MCInstrInfo * Info)1387330f729Sjoerg   MipsMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {}
1397330f729Sjoerg 
evaluateBranch(const MCInst & Inst,uint64_t Addr,uint64_t Size,uint64_t & Target) const1407330f729Sjoerg   bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
1417330f729Sjoerg                       uint64_t &Target) const override {
1427330f729Sjoerg     unsigned NumOps = Inst.getNumOperands();
1437330f729Sjoerg     if (NumOps == 0)
1447330f729Sjoerg       return false;
1457330f729Sjoerg     switch (Info->get(Inst.getOpcode()).OpInfo[NumOps - 1].OperandType) {
1467330f729Sjoerg     case MCOI::OPERAND_UNKNOWN:
1477330f729Sjoerg     case MCOI::OPERAND_IMMEDIATE: {
1487330f729Sjoerg       // j, jal, jalx, jals
1497330f729Sjoerg       // Absolute branch within the current 256 MB-aligned region
1507330f729Sjoerg       uint64_t Region = Addr & ~uint64_t(0xfffffff);
1517330f729Sjoerg       Target = Region + Inst.getOperand(NumOps - 1).getImm();
1527330f729Sjoerg       return true;
1537330f729Sjoerg     }
1547330f729Sjoerg     case MCOI::OPERAND_PCREL:
1557330f729Sjoerg       // b, beq ...
1567330f729Sjoerg       Target = Addr + Inst.getOperand(NumOps - 1).getImm();
1577330f729Sjoerg       return true;
1587330f729Sjoerg     default:
1597330f729Sjoerg       return false;
1607330f729Sjoerg     }
1617330f729Sjoerg   }
1627330f729Sjoerg };
1637330f729Sjoerg }
1647330f729Sjoerg 
createMipsMCInstrAnalysis(const MCInstrInfo * Info)1657330f729Sjoerg static MCInstrAnalysis *createMipsMCInstrAnalysis(const MCInstrInfo *Info) {
1667330f729Sjoerg   return new MipsMCInstrAnalysis(Info);
1677330f729Sjoerg }
1687330f729Sjoerg 
LLVMInitializeMipsTargetMC()169*82d56013Sjoerg extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsTargetMC() {
1707330f729Sjoerg   for (Target *T : {&getTheMipsTarget(), &getTheMipselTarget(),
1717330f729Sjoerg                     &getTheMips64Target(), &getTheMips64elTarget()}) {
1727330f729Sjoerg     // Register the MC asm info.
1737330f729Sjoerg     RegisterMCAsmInfoFn X(*T, createMipsMCAsmInfo);
1747330f729Sjoerg 
1757330f729Sjoerg     // Register the MC instruction info.
1767330f729Sjoerg     TargetRegistry::RegisterMCInstrInfo(*T, createMipsMCInstrInfo);
1777330f729Sjoerg 
1787330f729Sjoerg     // Register the MC register info.
1797330f729Sjoerg     TargetRegistry::RegisterMCRegInfo(*T, createMipsMCRegisterInfo);
1807330f729Sjoerg 
1817330f729Sjoerg     // Register the elf streamer.
1827330f729Sjoerg     TargetRegistry::RegisterELFStreamer(*T, createMCStreamer);
1837330f729Sjoerg 
1847330f729Sjoerg     // Register the asm target streamer.
1857330f729Sjoerg     TargetRegistry::RegisterAsmTargetStreamer(*T, createMipsAsmTargetStreamer);
1867330f729Sjoerg 
1877330f729Sjoerg     TargetRegistry::RegisterNullTargetStreamer(*T,
1887330f729Sjoerg                                                createMipsNullTargetStreamer);
1897330f729Sjoerg 
1907330f729Sjoerg     // Register the MC subtarget info.
1917330f729Sjoerg     TargetRegistry::RegisterMCSubtargetInfo(*T, createMipsMCSubtargetInfo);
1927330f729Sjoerg 
1937330f729Sjoerg     // Register the MC instruction analyzer.
1947330f729Sjoerg     TargetRegistry::RegisterMCInstrAnalysis(*T, createMipsMCInstrAnalysis);
1957330f729Sjoerg 
1967330f729Sjoerg     // Register the MCInstPrinter.
1977330f729Sjoerg     TargetRegistry::RegisterMCInstPrinter(*T, createMipsMCInstPrinter);
1987330f729Sjoerg 
1997330f729Sjoerg     TargetRegistry::RegisterObjectTargetStreamer(
2007330f729Sjoerg         *T, createMipsObjectTargetStreamer);
2017330f729Sjoerg 
2027330f729Sjoerg     // Register the asm backend.
2037330f729Sjoerg     TargetRegistry::RegisterMCAsmBackend(*T, createMipsAsmBackend);
2047330f729Sjoerg   }
2057330f729Sjoerg 
2067330f729Sjoerg   // Register the MC Code Emitter
2077330f729Sjoerg   for (Target *T : {&getTheMipsTarget(), &getTheMips64Target()})
2087330f729Sjoerg     TargetRegistry::RegisterMCCodeEmitter(*T, createMipsMCCodeEmitterEB);
2097330f729Sjoerg 
2107330f729Sjoerg   for (Target *T : {&getTheMipselTarget(), &getTheMips64elTarget()})
2117330f729Sjoerg     TargetRegistry::RegisterMCCodeEmitter(*T, createMipsMCCodeEmitterEL);
2127330f729Sjoerg }
213