LLVM 24.0.0git
MipsMCTargetDesc.cpp
Go to the documentation of this file.
1//===-- MipsMCTargetDesc.cpp - Mips 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 Mips specific target descriptions.
10//
11//===----------------------------------------------------------------------===//
12
13#include "MipsMCTargetDesc.h"
14#include "MipsAsmBackend.h"
15#include "MipsBaseInfo.h"
16#include "MipsELFStreamer.h"
17#include "MipsInstPrinter.h"
18#include "MipsMCAsmInfo.h"
19#include "MipsMCOptions.h"
20#include "MipsTargetStreamer.h"
26#include "llvm/MC/MCInstrInfo.h"
30#include "llvm/MC/MCSymbol.h"
37
38using namespace llvm;
39
40#define GET_INSTRINFO_MC_DESC
41#define ENABLE_INSTR_PREDICATE_VERIFIER
42#include "MipsGenInstrInfo.inc"
43
44#define GET_SUBTARGETINFO_MC_DESC
45#include "MipsGenSubtargetInfo.inc"
46
47#define GET_REGINFO_MC_DESC
48#include "MipsGenRegisterInfo.inc"
49
50#define GET_REGISTER_MATCHER
51#include "MipsGenAsmMatcher.inc"
52
53#define OPTIONS_STRUCT_DEFS
54#include "MipsMCOptions.inc"
55
57 unsigned RegClassID, unsigned AltIdx) {
58 MCRegister Reg = MatchRegisterAltName(Name, AltIdx);
59 if (!Reg)
60 Reg = MatchRegisterName(Name);
61 if (!Reg)
62 return MCRegister();
63
64 const MCRegisterClass &RC = MRI.getRegClass(RegClassID);
65 // GPR32 and GPR64 share names; select the requested width.
66 if (!RC.contains(Reg)) {
67 if (RegClassID == Mips::GPR32RegClassID &&
68 MRI.getRegClass(Mips::GPR64RegClassID).contains(Reg))
69 Reg = MRI.getSubReg(Reg, Mips::sub_32);
70 else if (RegClassID == Mips::GPR64RegClassID &&
71 MRI.getRegClass(Mips::GPR32RegClassID).contains(Reg))
72 Reg = MRI.getMatchingSuperReg(Reg, Mips::sub_32, &RC);
73 }
74 return RC.contains(Reg) ? Reg : MCRegister();
75}
76
78 unsigned AltIdx, bool *IsDeprecated) {
79 if (IsDeprecated)
80 *IsDeprecated = false;
81
82 if (MCRegister Reg =
83 matchRegisterName(Name, MRI, Mips::GPR32RegClassID, AltIdx))
84 return MRI.getEncodingValue(Reg);
85
86 static const struct {
87 StringLiteral Name;
88 MCPhysReg Reg;
89 // NoRegAltName applies to all ABIs.
90 unsigned AltIdx;
91 } Aliases[] = {
92 {"AT", Mips::AT, Mips::NoRegAltName},
93 {"s8", Mips::FP, Mips::NoRegAltName},
94 {"kt0", Mips::K0, Mips::NABIRegAltName},
95 {"kt1", Mips::K1, Mips::NABIRegAltName},
96 };
97 for (const auto &Alias : Aliases)
98 if (Name == Alias.Name &&
99 (Alias.AltIdx == Mips::NoRegAltName || Alias.AltIdx == AltIdx))
100 return MRI.getEncodingValue(Alias.Reg);
101
102 // GNU also accepts t4-t7 for NABI's t0-t3.
103 if (AltIdx == Mips::NABIRegAltName) {
104 static const struct {
105 StringLiteral Name;
106 MCPhysReg Reg;
107 } Deprecated[] = {
108 {"t4", Mips::T4},
109 {"t5", Mips::T5},
110 {"t6", Mips::T6},
111 {"t7", Mips::T7},
112 };
113 for (const auto &Alias : Deprecated) {
114 if (Name == Alias.Name) {
115 if (IsDeprecated)
116 *IsDeprecated = true;
117 return MRI.getEncodingValue(Alias.Reg);
118 }
119 }
120 }
121 return -1;
122}
123
125 // Mapping from CodeView to MC register id.
126 static const struct {
128 MCPhysReg Reg;
129 } RegMap[] = {
130 {codeview::RegisterId::MIPS_ZERO, Mips::ZERO},
131 {codeview::RegisterId::MIPS_AT, Mips::AT},
132 {codeview::RegisterId::MIPS_V0, Mips::V0},
133 {codeview::RegisterId::MIPS_V1, Mips::V1},
134 {codeview::RegisterId::MIPS_A0, Mips::A0},
135 {codeview::RegisterId::MIPS_A1, Mips::A1},
136 {codeview::RegisterId::MIPS_A2, Mips::A2},
137 {codeview::RegisterId::MIPS_A3, Mips::A3},
138 {codeview::RegisterId::MIPS_T0, Mips::T0},
139 {codeview::RegisterId::MIPS_T1, Mips::T1},
140 {codeview::RegisterId::MIPS_T2, Mips::T2},
141 {codeview::RegisterId::MIPS_T3, Mips::T3},
142 {codeview::RegisterId::MIPS_T4, Mips::T4},
143 {codeview::RegisterId::MIPS_T5, Mips::T5},
144 {codeview::RegisterId::MIPS_T6, Mips::T6},
145 {codeview::RegisterId::MIPS_T7, Mips::T7},
146 {codeview::RegisterId::MIPS_S0, Mips::S0},
147 {codeview::RegisterId::MIPS_S1, Mips::S1},
148 {codeview::RegisterId::MIPS_S2, Mips::S2},
149 {codeview::RegisterId::MIPS_S3, Mips::S3},
150 {codeview::RegisterId::MIPS_S4, Mips::S4},
151 {codeview::RegisterId::MIPS_S5, Mips::S5},
152 {codeview::RegisterId::MIPS_S6, Mips::S6},
153 {codeview::RegisterId::MIPS_S7, Mips::S7},
154 {codeview::RegisterId::MIPS_T8, Mips::T8},
155 {codeview::RegisterId::MIPS_T9, Mips::T9},
156 {codeview::RegisterId::MIPS_K0, Mips::K0},
157 {codeview::RegisterId::MIPS_K1, Mips::K1},
158 {codeview::RegisterId::MIPS_GP, Mips::GP},
159 {codeview::RegisterId::MIPS_SP, Mips::SP},
160 {codeview::RegisterId::MIPS_S8, Mips::FP},
161 {codeview::RegisterId::MIPS_RA, Mips::RA},
162 {codeview::RegisterId::MIPS_LO, Mips::HI0},
163 {codeview::RegisterId::MIPS_HI, Mips::LO0},
164 {codeview::RegisterId::MIPS_Fir, Mips::FCR0},
165 {codeview::RegisterId::MIPS_Psr, Mips::COP012}, // CP0.Status
166 {codeview::RegisterId::MIPS_F0, Mips::F0},
167 {codeview::RegisterId::MIPS_F1, Mips::F1},
168 {codeview::RegisterId::MIPS_F2, Mips::F2},
169 {codeview::RegisterId::MIPS_F3, Mips::F3},
170 {codeview::RegisterId::MIPS_F4, Mips::F4},
171 {codeview::RegisterId::MIPS_F5, Mips::F5},
172 {codeview::RegisterId::MIPS_F6, Mips::F6},
173 {codeview::RegisterId::MIPS_F7, Mips::F7},
174 {codeview::RegisterId::MIPS_F8, Mips::F8},
175 {codeview::RegisterId::MIPS_F9, Mips::F9},
176 {codeview::RegisterId::MIPS_F10, Mips::F10},
177 {codeview::RegisterId::MIPS_F11, Mips::F11},
178 {codeview::RegisterId::MIPS_F12, Mips::F12},
179 {codeview::RegisterId::MIPS_F13, Mips::F13},
180 {codeview::RegisterId::MIPS_F14, Mips::F14},
181 {codeview::RegisterId::MIPS_F15, Mips::F15},
182 {codeview::RegisterId::MIPS_F16, Mips::F16},
183 {codeview::RegisterId::MIPS_F17, Mips::F17},
184 {codeview::RegisterId::MIPS_F18, Mips::F18},
185 {codeview::RegisterId::MIPS_F19, Mips::F19},
186 {codeview::RegisterId::MIPS_F20, Mips::F20},
187 {codeview::RegisterId::MIPS_F21, Mips::F21},
188 {codeview::RegisterId::MIPS_F22, Mips::F22},
189 {codeview::RegisterId::MIPS_F23, Mips::F23},
190 {codeview::RegisterId::MIPS_F24, Mips::F24},
191 {codeview::RegisterId::MIPS_F25, Mips::F25},
192 {codeview::RegisterId::MIPS_F26, Mips::F26},
193 {codeview::RegisterId::MIPS_F27, Mips::F27},
194 {codeview::RegisterId::MIPS_F28, Mips::F28},
195 {codeview::RegisterId::MIPS_F29, Mips::F29},
196 {codeview::RegisterId::MIPS_F30, Mips::F30},
197 {codeview::RegisterId::MIPS_F31, Mips::F31},
198 {codeview::RegisterId::MIPS_Fsr, Mips::FCR31},
199 };
200 for (const auto &I : RegMap)
201 MRI->mapLLVMRegToCVReg(I.Reg, static_cast<int>(I.CVReg));
202}
203
204namespace {
205class MipsWinCOFFTargetStreamer : public MipsTargetStreamer {
206public:
207 MipsWinCOFFTargetStreamer(MCStreamer &S) : MipsTargetStreamer(S) {}
208};
209} // end namespace
210
211/// Select the Mips CPU for the given triple and cpu name.
213 if (CPU.empty() || CPU == "generic") {
214 if (TT.getSubArch() == llvm::Triple::MipsSubArch_r6) {
215 if (TT.isMIPS32())
216 CPU = "mips32r6";
217 else
218 CPU = "mips64r6";
219 } else {
220 if (TT.isMIPS32())
221 CPU = "mips32";
222 else
223 CPU = "mips64";
224 }
225 }
226 return CPU;
227}
228
230 MCInstrInfo *X = new MCInstrInfo();
231 InitMipsMCInstrInfo(X);
232 return X;
233}
234
237 InitMipsMCRegisterInfo(X, Mips::RA);
238 return X;
239}
240
242 StringRef CPU, StringRef FS) {
243 CPU = MIPS_MC::selectMipsCPU(TT, CPU);
244 return createMipsMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS);
245}
246
248 const Triple &TT,
249 const MCTargetOptions &Options) {
250 MCAsmInfo *MAI;
251
252 if (TT.isOSBinFormatCOFF())
253 MAI = new MipsCOFFMCAsmInfo(Options);
254 else
255 MAI = new MipsELFMCAsmInfo(TT, Options);
256
257 unsigned SP = MRI.getDwarfRegNum(Mips::SP, true);
259 MAI->addInitialFrameState(Inst);
260
261 return MAI;
262}
263
265 unsigned SyntaxVariant,
266 const MCAsmInfo &MAI,
267 const MCInstrInfo &MII,
268 const MCRegisterInfo &MRI) {
269 return new MipsInstPrinter(MAI, MII, MRI);
270}
271
273 std::unique_ptr<MCAsmBackend> &&MAB,
274 std::unique_ptr<MCObjectWriter> &&OW,
275 std::unique_ptr<MCCodeEmitter> &&Emitter) {
276 MCStreamer *S;
277 S = createMipsELFStreamer(Context, std::move(MAB), std::move(OW),
278 std::move(Emitter));
279 return S;
280}
281
287
291
292static MCTargetStreamer *
295 return new MipsWinCOFFTargetStreamer(S);
296 return new MipsTargetELFStreamer(S, STI);
297}
298
299namespace {
300
301class MipsMCInstrAnalysis : public MCInstrAnalysis {
302public:
303 MipsMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {}
304
305 bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
306 uint64_t &Target) const override {
307 unsigned NumOps = Inst.getNumOperands();
308 if (NumOps == 0)
309 return false;
310 switch (Info->get(Inst.getOpcode()).operands()[NumOps - 1].OperandType) {
313 // j, jal, jalx, jals
314 // Absolute branch within the current 256 MB-aligned region
315 uint64_t Region = Addr & ~uint64_t(0xfffffff);
316 Target = Region + Inst.getOperand(NumOps - 1).getImm();
317 return true;
318 }
320 // b, beq ...
321 Target = Addr + Inst.getOperand(NumOps - 1).getImm();
322 return true;
323 default:
324 return false;
325 }
326 }
327};
328}
329
331 return new MipsMCInstrAnalysis(Info);
332}
333
338 // Register the MC asm info.
340
341 // Register the MC instruction info.
343
344 // Register the MC register info.
346
347 // Register the elf streamer.
349
350 // Register the asm target streamer.
352
355
357
358 // Register the MC subtarget info.
360
361 // Register the MC instruction analyzer.
363
364 // Register the MCInstPrinter.
366
369
370 // Register the asm backend.
372 }
373
374 // Register the MC Code Emitter
377
380}
static MCRegister MatchRegisterName(StringRef Name)
unsigned uint64_t
static MCStreamer * createMCStreamer(const Triple &T, MCContext &Context, std::unique_ptr< MCAsmBackend > &&MAB, std::unique_ptr< MCObjectWriter > &&OW, std::unique_ptr< MCCodeEmitter > &&Emitter)
static MCRegister MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
#define X(NUM, ENUM, NAME)
Definition ELF.h:857
#define LLVM_ABI
Definition Compiler.h:215
#define LLVM_EXTERNAL_VISIBILITY
Definition Compiler.h:132
dxil DXContainer Global Emitter
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
static LVOptions Options
Definition LVOptions.cpp:25
#define I(x, y, z)
Definition MD5.cpp:57
#define T
static MCRegisterInfo * createMipsMCRegisterInfo(const Triple &TT)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsTargetMC()
static MCTargetStreamer * createMipsObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI)
static MCTargetStreamer * createMipsAsmTargetStreamer(MCStreamer &S, formatted_raw_ostream &OS, MCInstPrinter *InstPrint)
static MCStreamer * createMCStreamer(const Triple &T, MCContext &Context, std::unique_ptr< MCAsmBackend > &&MAB, std::unique_ptr< MCObjectWriter > &&OW, std::unique_ptr< MCCodeEmitter > &&Emitter)
static MCSubtargetInfo * createMipsMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS)
static MCInstrInfo * createMipsMCInstrInfo()
static MCInstPrinter * createMipsMCInstPrinter(const Triple &T, unsigned SyntaxVariant, const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI)
static MCTargetStreamer * createMipsNullTargetStreamer(MCStreamer &S)
static MCAsmInfo * createMipsMCAsmInfo(const MCRegisterInfo &MRI, const Triple &TT, const MCTargetOptions &Options)
static MCInstrAnalysis * createMipsMCInstrAnalysis(const MCInstrInfo *Info)
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition MCAsmInfo.h:67
void addInitialFrameState(const MCCFIInstruction &Inst)
Definition MCAsmInfo.cpp:39
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register, SMLoc Loc={})
.cfi_def_cfa_register modifies a rule for computing CFA.
Definition MCDwarf.h:635
Context object for machine code objects.
Definition MCContext.h:83
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
unsigned getNumOperands() const
Definition MCInst.h:212
unsigned getOpcode() const
Definition MCInst.h:202
const MCOperand & getOperand(unsigned i) const
Definition MCInst.h:210
Interface to description of machine instruction set.
Definition MCInstrInfo.h:27
int64_t getImm() const
Definition MCInst.h:84
MCRegisterClass - Base class of TargetRegisterClass.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx, const MCRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg.
void mapLLVMRegToCVReg(MCRegister LLVMReg, int CVReg)
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
virtual int64_t getDwarfRegNum(MCRegister Reg, bool isEH) const
Map a target register to an equivalent dwarf register number.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
Streaming machine code generation interface.
Definition MCStreamer.h:222
Generic base class for all target subtargets.
const Triple & getTargetTriple() const
Target specific streamer interface.
Definition MCStreamer.h:95
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Definition StringRef.h:888
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
bool isOSBinFormatCOFF() const
Tests whether the OS uses the COFF binary format.
Definition Triple.h:870
@ MipsSubArch_r6
Definition Triple.h:171
formatted_raw_ostream - A raw_ostream that wraps another one and keeps track of line and column posit...
Registers T::Global with cl::ParseCommandLineOptions.
@ OPERAND_IMMEDIATE
Definition MCInstrDesc.h:61
StringRef selectMipsCPU(const Triple &TT, StringRef CPU)
Select the Mips CPU for the given triple and cpu name.
MCRegister matchRegisterName(StringRef Name, const MCRegisterInfo &MRI, unsigned RegClassID, unsigned AltIdx)
Match a symbolic name in RegClassID, or return an invalid register.
void initLLVMToCVRegMapping(MCRegisterInfo *MRI)
int getCPURegisterIndex(StringRef Name, const MCRegisterInfo &MRI, unsigned AltIdx, bool *IsDeprecated=nullptr)
Return a GPR name's hardware index, or -1 if unknown.
This is an optimization pass for GlobalISel generic memory operations.
MCCodeEmitter * createMipsMCCodeEmitterEL(const MCInstrInfo &MCII, MCContext &Ctx)
MCCodeEmitter * createMipsMCCodeEmitterEB(const MCInstrInfo &MCII, MCContext &Ctx)
MCELFStreamer * createMipsELFStreamer(MCContext &Context, std::unique_ptr< MCAsmBackend > MAB, std::unique_ptr< MCObjectWriter > OW, std::unique_ptr< MCCodeEmitter > Emitter)
Target & getTheMips64Target()
MCStreamer * createMipsWinCOFFStreamer(MCContext &C, std::unique_ptr< MCAsmBackend > &&AB, std::unique_ptr< MCObjectWriter > &&OW, std::unique_ptr< MCCodeEmitter > &&CE)
Construct an MIPS Windows COFF machine code streamer which will generate PE/COFF format object files.
Target & getTheMips64elTarget()
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
Target & getTheMipselTarget()
Target & getTheMipsTarget()
MCAsmBackend * createMipsAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
RegisterMCAsmInfoFn - Helper template for registering a target assembly info implementation.
static void RegisterMCRegInfo(Target &T, Target::MCRegInfoCtorFnTy Fn)
RegisterMCRegInfo - Register a MCRegisterInfo implementation for the given target.
static void RegisterMCAsmBackend(Target &T, Target::MCAsmBackendCtorTy Fn)
RegisterMCAsmBackend - Register a MCAsmBackend implementation for the given target.
static void RegisterMCCodeEmitter(Target &T, Target::MCCodeEmitterCtorTy Fn)
RegisterMCCodeEmitter - Register a MCCodeEmitter implementation for the given target.
static void RegisterMCSubtargetInfo(Target &T, Target::MCSubtargetInfoCtorFnTy Fn)
RegisterMCSubtargetInfo - Register a MCSubtargetInfo implementation for the given target.
static void RegisterObjectTargetStreamer(Target &T, Target::ObjectTargetStreamerCtorTy Fn)
static void RegisterMCInstrAnalysis(Target &T, Target::MCInstrAnalysisCtorFnTy Fn)
RegisterMCInstrAnalysis - Register a MCInstrAnalysis implementation for the given target.
static void RegisterELFStreamer(Target &T, Target::ELFStreamerCtorTy Fn)
static void RegisterNullTargetStreamer(Target &T, Target::NullTargetStreamerCtorTy Fn)
static void RegisterMCInstPrinter(Target &T, Target::MCInstPrinterCtorTy Fn)
RegisterMCInstPrinter - Register a MCInstPrinter implementation for the given target.
static void RegisterCOFFStreamer(Target &T, Target::COFFStreamerCtorTy Fn)
static void RegisterMCInstrInfo(Target &T, Target::MCInstrInfoCtorFnTy Fn)
RegisterMCInstrInfo - Register a MCInstrInfo implementation for the given target.
static void RegisterAsmTargetStreamer(Target &T, Target::AsmTargetStreamerCtorTy Fn)