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 Encoding) {
58 unsigned Reg = getCOP0RegNum(Encoding);
59 unsigned Sel = getCOP0Sel(Encoding);
60 assert(Reg < 32 && Sel < 8 && "Invalid COP0 register encoding");
61 // COP0's register class is ordered by selector, then register number.
62 return MRI.getRegClass(Mips::COP0RegClassID).getRegister(Sel * 32 + Reg);
63}
64
66 unsigned RegClassID, unsigned AltIdx) {
67 MCRegister Reg = MatchRegisterAltName(Name, AltIdx);
68 if (!Reg)
69 Reg = MatchRegisterName(Name);
70 if (!Reg)
71 return MCRegister();
72
73 const MCRegisterClass &RC = MRI.getRegClass(RegClassID);
74 // GPR32 and GPR64 share names; select the requested width.
75 if (!RC.contains(Reg)) {
76 if (RegClassID == Mips::GPR32RegClassID &&
77 MRI.getRegClass(Mips::GPR64RegClassID).contains(Reg))
78 Reg = MRI.getSubReg(Reg, Mips::sub_32);
79 else if (RegClassID == Mips::GPR64RegClassID &&
80 MRI.getRegClass(Mips::GPR32RegClassID).contains(Reg))
81 Reg = MRI.getMatchingSuperReg(Reg, Mips::sub_32, &RC);
82 }
83 return RC.contains(Reg) ? Reg : MCRegister();
84}
85
87 unsigned AltIdx, bool *IsDeprecated) {
88 if (IsDeprecated)
89 *IsDeprecated = false;
90
91 if (MCRegister Reg =
92 matchRegisterName(Name, MRI, Mips::GPR32RegClassID, AltIdx))
93 return MRI.getEncodingValue(Reg);
94
95 static const struct {
96 StringLiteral Name;
97 MCPhysReg Reg;
98 // NoRegAltName applies to all ABIs.
99 unsigned AltIdx;
100 } Aliases[] = {
101 {"AT", Mips::R1, Mips::NoRegAltName},
102 {"s8", Mips::FP, Mips::NoRegAltName},
103 {"kt0", Mips::R26, Mips::NABIRegAltName},
104 {"kt1", Mips::R27, Mips::NABIRegAltName},
105 };
106 for (const auto &Alias : Aliases)
107 if (Name == Alias.Name &&
108 (Alias.AltIdx == Mips::NoRegAltName || Alias.AltIdx == AltIdx))
109 return MRI.getEncodingValue(Alias.Reg);
110
111 // GNU also accepts t4-t7 for NABI's t0-t3.
112 if (AltIdx == Mips::NABIRegAltName) {
113 static const struct {
114 StringLiteral Name;
115 MCPhysReg Reg;
116 } Deprecated[] = {
117 {"t4", Mips::R12},
118 {"t5", Mips::R13},
119 {"t6", Mips::R14},
120 {"t7", Mips::R15},
121 };
122 for (const auto &Alias : Deprecated) {
123 if (Name == Alias.Name) {
124 if (IsDeprecated)
125 *IsDeprecated = true;
126 return MRI.getEncodingValue(Alias.Reg);
127 }
128 }
129 }
130 return -1;
131}
132
134 // Mapping from CodeView to MC register id.
135 static const struct {
137 MCPhysReg Reg;
138 } RegMap[] = {
139 {codeview::RegisterId::MIPS_ZERO, Mips::R0},
140 {codeview::RegisterId::MIPS_AT, Mips::R1},
141 {codeview::RegisterId::MIPS_V0, Mips::R2},
142 {codeview::RegisterId::MIPS_V1, Mips::R3},
143 {codeview::RegisterId::MIPS_A0, Mips::R4},
144 {codeview::RegisterId::MIPS_A1, Mips::R5},
145 {codeview::RegisterId::MIPS_A2, Mips::R6},
146 {codeview::RegisterId::MIPS_A3, Mips::R7},
147 {codeview::RegisterId::MIPS_T0, Mips::R8},
148 {codeview::RegisterId::MIPS_T1, Mips::R9},
149 {codeview::RegisterId::MIPS_T2, Mips::R10},
150 {codeview::RegisterId::MIPS_T3, Mips::R11},
151 {codeview::RegisterId::MIPS_T4, Mips::R12},
152 {codeview::RegisterId::MIPS_T5, Mips::R13},
153 {codeview::RegisterId::MIPS_T6, Mips::R14},
154 {codeview::RegisterId::MIPS_T7, Mips::R15},
155 {codeview::RegisterId::MIPS_S0, Mips::R16},
156 {codeview::RegisterId::MIPS_S1, Mips::R17},
157 {codeview::RegisterId::MIPS_S2, Mips::R18},
158 {codeview::RegisterId::MIPS_S3, Mips::R19},
159 {codeview::RegisterId::MIPS_S4, Mips::R20},
160 {codeview::RegisterId::MIPS_S5, Mips::R21},
161 {codeview::RegisterId::MIPS_S6, Mips::R22},
162 {codeview::RegisterId::MIPS_S7, Mips::R23},
163 {codeview::RegisterId::MIPS_T8, Mips::R24},
164 {codeview::RegisterId::MIPS_T9, Mips::R25},
165 {codeview::RegisterId::MIPS_K0, Mips::R26},
166 {codeview::RegisterId::MIPS_K1, Mips::R27},
167 {codeview::RegisterId::MIPS_GP, Mips::GP},
168 {codeview::RegisterId::MIPS_SP, Mips::SP},
169 {codeview::RegisterId::MIPS_S8, Mips::FP},
170 {codeview::RegisterId::MIPS_RA, Mips::RA},
171 {codeview::RegisterId::MIPS_LO, Mips::HI0},
172 {codeview::RegisterId::MIPS_HI, Mips::LO0},
173 {codeview::RegisterId::MIPS_Fir, Mips::FCR0},
174 {codeview::RegisterId::MIPS_Psr, Mips::COP012}, // CP0.Status
175 {codeview::RegisterId::MIPS_F0, Mips::F0},
176 {codeview::RegisterId::MIPS_F1, Mips::F1},
177 {codeview::RegisterId::MIPS_F2, Mips::F2},
178 {codeview::RegisterId::MIPS_F3, Mips::F3},
179 {codeview::RegisterId::MIPS_F4, Mips::F4},
180 {codeview::RegisterId::MIPS_F5, Mips::F5},
181 {codeview::RegisterId::MIPS_F6, Mips::F6},
182 {codeview::RegisterId::MIPS_F7, Mips::F7},
183 {codeview::RegisterId::MIPS_F8, Mips::F8},
184 {codeview::RegisterId::MIPS_F9, Mips::F9},
185 {codeview::RegisterId::MIPS_F10, Mips::F10},
186 {codeview::RegisterId::MIPS_F11, Mips::F11},
187 {codeview::RegisterId::MIPS_F12, Mips::F12},
188 {codeview::RegisterId::MIPS_F13, Mips::F13},
189 {codeview::RegisterId::MIPS_F14, Mips::F14},
190 {codeview::RegisterId::MIPS_F15, Mips::F15},
191 {codeview::RegisterId::MIPS_F16, Mips::F16},
192 {codeview::RegisterId::MIPS_F17, Mips::F17},
193 {codeview::RegisterId::MIPS_F18, Mips::F18},
194 {codeview::RegisterId::MIPS_F19, Mips::F19},
195 {codeview::RegisterId::MIPS_F20, Mips::F20},
196 {codeview::RegisterId::MIPS_F21, Mips::F21},
197 {codeview::RegisterId::MIPS_F22, Mips::F22},
198 {codeview::RegisterId::MIPS_F23, Mips::F23},
199 {codeview::RegisterId::MIPS_F24, Mips::F24},
200 {codeview::RegisterId::MIPS_F25, Mips::F25},
201 {codeview::RegisterId::MIPS_F26, Mips::F26},
202 {codeview::RegisterId::MIPS_F27, Mips::F27},
203 {codeview::RegisterId::MIPS_F28, Mips::F28},
204 {codeview::RegisterId::MIPS_F29, Mips::F29},
205 {codeview::RegisterId::MIPS_F30, Mips::F30},
206 {codeview::RegisterId::MIPS_F31, Mips::F31},
207 {codeview::RegisterId::MIPS_Fsr, Mips::FCR31},
208 };
209 for (const auto &I : RegMap)
210 MRI->mapLLVMRegToCVReg(I.Reg, static_cast<int>(I.CVReg));
211}
212
213namespace {
214class MipsWinCOFFTargetStreamer : public MipsTargetStreamer {
215public:
216 MipsWinCOFFTargetStreamer(MCStreamer &S) : MipsTargetStreamer(S) {}
217};
218} // end namespace
219
220/// Select the Mips CPU for the given triple and cpu name.
222 if (CPU.empty() || CPU == "generic") {
223 if (TT.getSubArch() == llvm::Triple::MipsSubArch_r6) {
224 if (TT.isMIPS32())
225 CPU = "mips32r6";
226 else
227 CPU = "mips64r6";
228 } else {
229 if (TT.isMIPS32())
230 CPU = "mips32";
231 else
232 CPU = "mips64";
233 }
234 }
235 return CPU;
236}
237
239 MCInstrInfo *X = new MCInstrInfo();
240 InitMipsMCInstrInfo(X);
241 return X;
242}
243
246 InitMipsMCRegisterInfo(X, Mips::RA);
247 return X;
248}
249
251 StringRef CPU, StringRef FS) {
252 CPU = MIPS_MC::selectMipsCPU(TT, CPU);
253 return createMipsMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS);
254}
255
257 const Triple &TT,
258 const MCTargetOptions &Options) {
259 MCAsmInfo *MAI;
260
261 if (TT.isOSBinFormatCOFF())
262 MAI = new MipsCOFFMCAsmInfo(Options);
263 else
264 MAI = new MipsELFMCAsmInfo(TT, Options);
265
266 unsigned SP = MRI.getDwarfRegNum(Mips::SP, true);
268 MAI->addInitialFrameState(Inst);
269
270 return MAI;
271}
272
274 unsigned SyntaxVariant,
275 const MCAsmInfo &MAI,
276 const MCInstrInfo &MII,
277 const MCRegisterInfo &MRI) {
278 return new MipsInstPrinter(MAI, MII, MRI);
279}
280
282 std::unique_ptr<MCAsmBackend> &&MAB,
283 std::unique_ptr<MCObjectWriter> &&OW,
284 std::unique_ptr<MCCodeEmitter> &&Emitter) {
285 MCStreamer *S;
286 S = createMipsELFStreamer(Context, std::move(MAB), std::move(OW),
287 std::move(Emitter));
288 return S;
289}
290
296
300
301static MCTargetStreamer *
304 return new MipsWinCOFFTargetStreamer(S);
305 return new MipsTargetELFStreamer(S, STI);
306}
307
308namespace {
309
310class MipsMCInstrAnalysis : public MCInstrAnalysis {
311public:
312 MipsMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {}
313
314 bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
315 uint64_t &Target) const override {
316 unsigned NumOps = Inst.getNumOperands();
317 // Register-list transfers have more MC operands than descriptor entries.
318 if (NumOps == 0 || NumOps > Info->get(Inst.getOpcode()).getNumOperands())
319 return false;
320 switch (Info->get(Inst.getOpcode()).operands()[NumOps - 1].OperandType) {
322 // Absolute branch within the current 256 MB-aligned region
323 uint64_t Region = Addr & ~uint64_t(0xfffffff);
324 Target = Region + Inst.getOperand(NumOps - 1).getImm();
325 return true;
326 }
328 // Absolute branch within the current 128 MB-aligned region
329 uint64_t Region = Addr & ~uint64_t(0x7ffffff);
330 Target = Region + Inst.getOperand(NumOps - 1).getImm();
331 return true;
332 }
334 // b, beq ...
335 Target = Addr + Inst.getOperand(NumOps - 1).getImm();
336 return true;
337 default:
338 return false;
339 }
340 }
341};
342} // anonymous namespace
343
345 return new MipsMCInstrAnalysis(Info);
346}
347
352 // Register the MC asm info.
354
355 // Register the MC instruction info.
357
358 // Register the MC register info.
360
361 // Register the elf streamer.
363
364 // Register the asm target streamer.
366
369
371
372 // Register the MC subtarget info.
374
375 // Register the MC instruction analyzer.
377
378 // Register the MCInstPrinter.
380
383
384 // Register the asm backend.
386 }
387
388 // Register the MC Code Emitter
391
394}
static MCRegister MatchRegisterName(StringRef Name)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t 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:665
#define LLVM_ABI
Definition Compiler.h:211
#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)
MachineRegisterInfo & MRI
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...
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.
MCRegister getCOP0Register(const MCRegisterInfo &MRI, unsigned Encoding)
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)
constexpr unsigned getCOP0RegNum(unsigned Encoding)
int getCPURegisterIndex(StringRef Name, const MCRegisterInfo &MRI, unsigned AltIdx, bool *IsDeprecated=nullptr)
Return a GPR name's hardware index, or -1 if unknown.
constexpr unsigned getCOP0Sel(unsigned Encoding)
constexpr MCPhysReg FP
constexpr MCPhysReg GP
constexpr MCPhysReg SP
constexpr MCPhysReg RA
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)