109467b48Spatrick //===-- MipsMCTargetDesc.cpp - Mips Target Descriptions -------------------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // This file provides Mips specific target descriptions.
1009467b48Spatrick //
1109467b48Spatrick //===----------------------------------------------------------------------===//
1209467b48Spatrick 
1309467b48Spatrick #include "MipsMCTargetDesc.h"
1409467b48Spatrick #include "MipsAsmBackend.h"
1509467b48Spatrick #include "MipsBaseInfo.h"
1609467b48Spatrick #include "MipsELFStreamer.h"
1709467b48Spatrick #include "MipsInstPrinter.h"
1809467b48Spatrick #include "MipsMCAsmInfo.h"
1909467b48Spatrick #include "MipsMCNaCl.h"
2009467b48Spatrick #include "MipsTargetStreamer.h"
2109467b48Spatrick #include "TargetInfo/MipsTargetInfo.h"
2209467b48Spatrick #include "llvm/ADT/Triple.h"
2309467b48Spatrick #include "llvm/MC/MCCodeEmitter.h"
2409467b48Spatrick #include "llvm/MC/MCELFStreamer.h"
2509467b48Spatrick #include "llvm/MC/MCInstrAnalysis.h"
2609467b48Spatrick #include "llvm/MC/MCInstrInfo.h"
2709467b48Spatrick #include "llvm/MC/MCObjectWriter.h"
2809467b48Spatrick #include "llvm/MC/MCRegisterInfo.h"
2909467b48Spatrick #include "llvm/MC/MCSubtargetInfo.h"
3009467b48Spatrick #include "llvm/MC/MCSymbol.h"
3109467b48Spatrick #include "llvm/MC/MachineLocation.h"
32*d415bd75Srobert #include "llvm/MC/TargetRegistry.h"
3309467b48Spatrick #include "llvm/Support/ErrorHandling.h"
3409467b48Spatrick #include "llvm/Support/FormattedStream.h"
3509467b48Spatrick 
3609467b48Spatrick using namespace llvm;
3709467b48Spatrick 
3809467b48Spatrick #define GET_INSTRINFO_MC_DESC
39*d415bd75Srobert #define ENABLE_INSTR_PREDICATE_VERIFIER
4009467b48Spatrick #include "MipsGenInstrInfo.inc"
4109467b48Spatrick 
4209467b48Spatrick #define GET_SUBTARGETINFO_MC_DESC
4309467b48Spatrick #include "MipsGenSubtargetInfo.inc"
4409467b48Spatrick 
4509467b48Spatrick #define GET_REGINFO_MC_DESC
4609467b48Spatrick #include "MipsGenRegisterInfo.inc"
4709467b48Spatrick 
4809467b48Spatrick /// Select the Mips CPU for the given triple and cpu name.
selectMipsCPU(const Triple & TT,StringRef CPU)4909467b48Spatrick StringRef MIPS_MC::selectMipsCPU(const Triple &TT, StringRef CPU) {
5009467b48Spatrick   if (CPU.empty() || CPU == "generic") {
5109467b48Spatrick     if (TT.getSubArch() == llvm::Triple::MipsSubArch_r6) {
5209467b48Spatrick       if (TT.isMIPS32())
5309467b48Spatrick         CPU = "mips32r6";
5409467b48Spatrick       else
5509467b48Spatrick         CPU = "mips64r6";
5609467b48Spatrick     } else {
5709467b48Spatrick       if (TT.isMIPS32())
5809467b48Spatrick         CPU = "mips32";
5909467b48Spatrick       else
6009467b48Spatrick         CPU = "mips64";
6109467b48Spatrick     }
6209467b48Spatrick   }
6309467b48Spatrick   return CPU;
6409467b48Spatrick }
6509467b48Spatrick 
createMipsMCInstrInfo()6609467b48Spatrick static MCInstrInfo *createMipsMCInstrInfo() {
6709467b48Spatrick   MCInstrInfo *X = new MCInstrInfo();
6809467b48Spatrick   InitMipsMCInstrInfo(X);
6909467b48Spatrick   return X;
7009467b48Spatrick }
7109467b48Spatrick 
createMipsMCRegisterInfo(const Triple & TT)7209467b48Spatrick static MCRegisterInfo *createMipsMCRegisterInfo(const Triple &TT) {
7309467b48Spatrick   MCRegisterInfo *X = new MCRegisterInfo();
7409467b48Spatrick   InitMipsMCRegisterInfo(X, Mips::RA);
7509467b48Spatrick   return X;
7609467b48Spatrick }
7709467b48Spatrick 
createMipsMCSubtargetInfo(const Triple & TT,StringRef CPU,StringRef FS)7809467b48Spatrick static MCSubtargetInfo *createMipsMCSubtargetInfo(const Triple &TT,
7909467b48Spatrick                                                   StringRef CPU, StringRef FS) {
8009467b48Spatrick   CPU = MIPS_MC::selectMipsCPU(TT, CPU);
8173471bf0Spatrick   return createMipsMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS);
8209467b48Spatrick }
8309467b48Spatrick 
createMipsMCAsmInfo(const MCRegisterInfo & MRI,const Triple & TT,const MCTargetOptions & Options)8409467b48Spatrick static MCAsmInfo *createMipsMCAsmInfo(const MCRegisterInfo &MRI,
8509467b48Spatrick                                       const Triple &TT,
8609467b48Spatrick                                       const MCTargetOptions &Options) {
8709467b48Spatrick   MCAsmInfo *MAI = new MipsMCAsmInfo(TT, Options);
8809467b48Spatrick 
8909467b48Spatrick   unsigned SP = MRI.getDwarfRegNum(Mips::SP, true);
9009467b48Spatrick   MCCFIInstruction Inst = MCCFIInstruction::createDefCfaRegister(nullptr, SP);
9109467b48Spatrick   MAI->addInitialFrameState(Inst);
9209467b48Spatrick 
9309467b48Spatrick   return MAI;
9409467b48Spatrick }
9509467b48Spatrick 
createMipsMCInstPrinter(const Triple & T,unsigned SyntaxVariant,const MCAsmInfo & MAI,const MCInstrInfo & MII,const MCRegisterInfo & MRI)9609467b48Spatrick static MCInstPrinter *createMipsMCInstPrinter(const Triple &T,
9709467b48Spatrick                                               unsigned SyntaxVariant,
9809467b48Spatrick                                               const MCAsmInfo &MAI,
9909467b48Spatrick                                               const MCInstrInfo &MII,
10009467b48Spatrick                                               const MCRegisterInfo &MRI) {
10109467b48Spatrick   return new MipsInstPrinter(MAI, MII, MRI);
10209467b48Spatrick }
10309467b48Spatrick 
createMCStreamer(const Triple & T,MCContext & Context,std::unique_ptr<MCAsmBackend> && MAB,std::unique_ptr<MCObjectWriter> && OW,std::unique_ptr<MCCodeEmitter> && Emitter,bool RelaxAll)10409467b48Spatrick static MCStreamer *createMCStreamer(const Triple &T, MCContext &Context,
10509467b48Spatrick                                     std::unique_ptr<MCAsmBackend> &&MAB,
10609467b48Spatrick                                     std::unique_ptr<MCObjectWriter> &&OW,
10709467b48Spatrick                                     std::unique_ptr<MCCodeEmitter> &&Emitter,
10809467b48Spatrick                                     bool RelaxAll) {
10909467b48Spatrick   MCStreamer *S;
11009467b48Spatrick   if (!T.isOSNaCl())
11109467b48Spatrick     S = createMipsELFStreamer(Context, std::move(MAB), std::move(OW),
11209467b48Spatrick                               std::move(Emitter), RelaxAll);
11309467b48Spatrick   else
11409467b48Spatrick     S = createMipsNaClELFStreamer(Context, std::move(MAB), std::move(OW),
11509467b48Spatrick                                   std::move(Emitter), RelaxAll);
11609467b48Spatrick   return S;
11709467b48Spatrick }
11809467b48Spatrick 
createMipsAsmTargetStreamer(MCStreamer & S,formatted_raw_ostream & OS,MCInstPrinter * InstPrint,bool isVerboseAsm)11909467b48Spatrick static MCTargetStreamer *createMipsAsmTargetStreamer(MCStreamer &S,
12009467b48Spatrick                                                      formatted_raw_ostream &OS,
12109467b48Spatrick                                                      MCInstPrinter *InstPrint,
12209467b48Spatrick                                                      bool isVerboseAsm) {
12309467b48Spatrick   return new MipsTargetAsmStreamer(S, OS);
12409467b48Spatrick }
12509467b48Spatrick 
createMipsNullTargetStreamer(MCStreamer & S)12609467b48Spatrick static MCTargetStreamer *createMipsNullTargetStreamer(MCStreamer &S) {
12709467b48Spatrick   return new MipsTargetStreamer(S);
12809467b48Spatrick }
12909467b48Spatrick 
13009467b48Spatrick static MCTargetStreamer *
createMipsObjectTargetStreamer(MCStreamer & S,const MCSubtargetInfo & STI)13109467b48Spatrick createMipsObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
13209467b48Spatrick   return new MipsTargetELFStreamer(S, STI);
13309467b48Spatrick }
13409467b48Spatrick 
13509467b48Spatrick namespace {
13609467b48Spatrick 
13709467b48Spatrick class MipsMCInstrAnalysis : public MCInstrAnalysis {
13809467b48Spatrick public:
MipsMCInstrAnalysis(const MCInstrInfo * Info)13909467b48Spatrick   MipsMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {}
14009467b48Spatrick 
evaluateBranch(const MCInst & Inst,uint64_t Addr,uint64_t Size,uint64_t & Target) const14109467b48Spatrick   bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
14209467b48Spatrick                       uint64_t &Target) const override {
14309467b48Spatrick     unsigned NumOps = Inst.getNumOperands();
14409467b48Spatrick     if (NumOps == 0)
14509467b48Spatrick       return false;
146*d415bd75Srobert     switch (Info->get(Inst.getOpcode()).operands()[NumOps - 1].OperandType) {
14709467b48Spatrick     case MCOI::OPERAND_UNKNOWN:
14809467b48Spatrick     case MCOI::OPERAND_IMMEDIATE: {
14909467b48Spatrick       // j, jal, jalx, jals
15009467b48Spatrick       // Absolute branch within the current 256 MB-aligned region
15109467b48Spatrick       uint64_t Region = Addr & ~uint64_t(0xfffffff);
15209467b48Spatrick       Target = Region + Inst.getOperand(NumOps - 1).getImm();
15309467b48Spatrick       return true;
15409467b48Spatrick     }
15509467b48Spatrick     case MCOI::OPERAND_PCREL:
15609467b48Spatrick       // b, beq ...
15709467b48Spatrick       Target = Addr + Inst.getOperand(NumOps - 1).getImm();
15809467b48Spatrick       return true;
15909467b48Spatrick     default:
16009467b48Spatrick       return false;
16109467b48Spatrick     }
16209467b48Spatrick   }
16309467b48Spatrick };
16409467b48Spatrick }
16509467b48Spatrick 
createMipsMCInstrAnalysis(const MCInstrInfo * Info)16609467b48Spatrick static MCInstrAnalysis *createMipsMCInstrAnalysis(const MCInstrInfo *Info) {
16709467b48Spatrick   return new MipsMCInstrAnalysis(Info);
16809467b48Spatrick }
16909467b48Spatrick 
LLVMInitializeMipsTargetMC()17009467b48Spatrick extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsTargetMC() {
17109467b48Spatrick   for (Target *T : {&getTheMipsTarget(), &getTheMipselTarget(),
17209467b48Spatrick                     &getTheMips64Target(), &getTheMips64elTarget()}) {
17309467b48Spatrick     // Register the MC asm info.
17409467b48Spatrick     RegisterMCAsmInfoFn X(*T, createMipsMCAsmInfo);
17509467b48Spatrick 
17609467b48Spatrick     // Register the MC instruction info.
17709467b48Spatrick     TargetRegistry::RegisterMCInstrInfo(*T, createMipsMCInstrInfo);
17809467b48Spatrick 
17909467b48Spatrick     // Register the MC register info.
18009467b48Spatrick     TargetRegistry::RegisterMCRegInfo(*T, createMipsMCRegisterInfo);
18109467b48Spatrick 
18209467b48Spatrick     // Register the elf streamer.
18309467b48Spatrick     TargetRegistry::RegisterELFStreamer(*T, createMCStreamer);
18409467b48Spatrick 
18509467b48Spatrick     // Register the asm target streamer.
18609467b48Spatrick     TargetRegistry::RegisterAsmTargetStreamer(*T, createMipsAsmTargetStreamer);
18709467b48Spatrick 
18809467b48Spatrick     TargetRegistry::RegisterNullTargetStreamer(*T,
18909467b48Spatrick                                                createMipsNullTargetStreamer);
19009467b48Spatrick 
19109467b48Spatrick     // Register the MC subtarget info.
19209467b48Spatrick     TargetRegistry::RegisterMCSubtargetInfo(*T, createMipsMCSubtargetInfo);
19309467b48Spatrick 
19409467b48Spatrick     // Register the MC instruction analyzer.
19509467b48Spatrick     TargetRegistry::RegisterMCInstrAnalysis(*T, createMipsMCInstrAnalysis);
19609467b48Spatrick 
19709467b48Spatrick     // Register the MCInstPrinter.
19809467b48Spatrick     TargetRegistry::RegisterMCInstPrinter(*T, createMipsMCInstPrinter);
19909467b48Spatrick 
20009467b48Spatrick     TargetRegistry::RegisterObjectTargetStreamer(
20109467b48Spatrick         *T, createMipsObjectTargetStreamer);
20209467b48Spatrick 
20309467b48Spatrick     // Register the asm backend.
20409467b48Spatrick     TargetRegistry::RegisterMCAsmBackend(*T, createMipsAsmBackend);
20509467b48Spatrick   }
20609467b48Spatrick 
20709467b48Spatrick   // Register the MC Code Emitter
20809467b48Spatrick   for (Target *T : {&getTheMipsTarget(), &getTheMips64Target()})
20909467b48Spatrick     TargetRegistry::RegisterMCCodeEmitter(*T, createMipsMCCodeEmitterEB);
21009467b48Spatrick 
21109467b48Spatrick   for (Target *T : {&getTheMipselTarget(), &getTheMips64elTarget()})
21209467b48Spatrick     TargetRegistry::RegisterMCCodeEmitter(*T, createMipsMCCodeEmitterEL);
21309467b48Spatrick }
214