LLVM 20.0.0git
MipsMCInstLower.cpp
Go to the documentation of this file.
1//===- MipsMCInstLower.cpp - Convert Mips MachineInstr to MCInst ----------===//
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 contains code to lower Mips MachineInstrs to their corresponding
10// MCInst records.
11//
12//===----------------------------------------------------------------------===//
13
14#include "MipsMCInstLower.h"
17#include "MipsAsmPrinter.h"
21#include "llvm/MC/MCContext.h"
22#include "llvm/MC/MCExpr.h"
23#include "llvm/MC/MCInst.h"
25
26using namespace llvm;
27
29 : AsmPrinter(asmprinter) {}
30
32 Ctx = C;
33}
34
35MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
36 MachineOperandType MOTy,
37 int64_t Offset) const {
40 bool IsGpOff = false;
41 const MCSymbol *Symbol;
43 unsigned TargetFlags = MO.getTargetFlags();
44
45 if (TargetFlags & MipsII::MO_DLLIMPORT) {
46 // Handle dllimport linkage
47 Name += "__imp_";
48 TargetFlags &= ~MipsII::MO_DLLIMPORT;
49 }
50
51 switch (TargetFlags) {
52 default:
53 llvm_unreachable("Invalid target flag!");
55 break;
57 TargetKind = MipsMCExpr::MEK_GPREL;
58 break;
60 TargetKind = MipsMCExpr::MEK_GOT_CALL;
61 break;
62 case MipsII::MO_GOT:
63 TargetKind = MipsMCExpr::MEK_GOT;
64 break;
66 TargetKind = MipsMCExpr::MEK_HI;
67 break;
69 TargetKind = MipsMCExpr::MEK_LO;
70 break;
72 TargetKind = MipsMCExpr::MEK_TLSGD;
73 break;
75 TargetKind = MipsMCExpr::MEK_TLSLDM;
76 break;
78 TargetKind = MipsMCExpr::MEK_DTPREL_HI;
79 break;
81 TargetKind = MipsMCExpr::MEK_DTPREL_LO;
82 break;
84 TargetKind = MipsMCExpr::MEK_GOTTPREL;
85 break;
87 TargetKind = MipsMCExpr::MEK_TPREL_HI;
88 break;
90 TargetKind = MipsMCExpr::MEK_TPREL_LO;
91 break;
93 TargetKind = MipsMCExpr::MEK_HI;
94 IsGpOff = true;
95 break;
97 TargetKind = MipsMCExpr::MEK_LO;
98 IsGpOff = true;
99 break;
101 TargetKind = MipsMCExpr::MEK_GOT_DISP;
102 break;
104 TargetKind = MipsMCExpr::MEK_GOT_HI16;
105 break;
107 TargetKind = MipsMCExpr::MEK_GOT_LO16;
108 break;
110 TargetKind = MipsMCExpr::MEK_GOT_PAGE;
111 break;
113 TargetKind = MipsMCExpr::MEK_GOT_OFST;
114 break;
116 TargetKind = MipsMCExpr::MEK_HIGHER;
117 break;
119 TargetKind = MipsMCExpr::MEK_HIGHEST;
120 break;
122 TargetKind = MipsMCExpr::MEK_CALL_HI16;
123 break;
125 TargetKind = MipsMCExpr::MEK_CALL_LO16;
126 break;
127 case MipsII::MO_JALR:
128 return MCOperand();
129 }
130
131 switch (MOTy) {
133 Symbol = MO.getMBB()->getSymbol();
134 break;
135
139 Offset += MO.getOffset();
140 break;
141
144 Offset += MO.getOffset();
145 break;
146
149 Offset += MO.getOffset();
150 break;
151
153 Symbol = MO.getMCSymbol();
154 Offset += MO.getOffset();
155 break;
156
159 break;
160
163 Offset += MO.getOffset();
164 break;
165
166 default:
167 llvm_unreachable("<unknown operand type>");
168 }
169
170 const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, Kind, *Ctx);
171
172 if (Offset) {
173 // Note: Offset can also be negative
175 *Ctx);
176 }
177
178 if (IsGpOff)
179 Expr = MipsMCExpr::createGpOff(TargetKind, Expr, *Ctx);
180 else if (TargetKind != MipsMCExpr::MEK_None)
181 Expr = MipsMCExpr::create(TargetKind, Expr, *Ctx);
182
183 return MCOperand::createExpr(Expr);
184}
185
187 int64_t offset) const {
188 MachineOperandType MOTy = MO.getType();
189
190 switch (MOTy) {
191 default: llvm_unreachable("unknown operand type");
193 // Ignore all implicit register operands.
194 if (MO.isImplicit()) break;
195 return MCOperand::createReg(MO.getReg());
197 return MCOperand::createImm(MO.getImm() + offset);
205 return LowerSymbolOperand(MO, MOTy, offset);
207 break;
208 }
209
210 return MCOperand();
211}
212
213MCOperand MipsMCInstLower::createSub(MachineBasicBlock *BB1,
215 MipsMCExpr::MipsExprKind Kind) const {
216 const MCSymbolRefExpr *Sym1 = MCSymbolRefExpr::create(BB1->getSymbol(), *Ctx);
217 const MCSymbolRefExpr *Sym2 = MCSymbolRefExpr::create(BB2->getSymbol(), *Ctx);
218 const MCBinaryExpr *Sub = MCBinaryExpr::createSub(Sym1, Sym2, *Ctx);
219
220 return MCOperand::createExpr(MipsMCExpr::create(Kind, Sub, *Ctx));
221}
222
223void MipsMCInstLower::
224lowerLongBranchLUi(const MachineInstr *MI, MCInst &OutMI) const {
225 OutMI.setOpcode(Mips::LUi);
226
227 // Lower register operand.
228 OutMI.addOperand(LowerOperand(MI->getOperand(0)));
229
231 unsigned TargetFlags = MI->getOperand(1).getTargetFlags();
232 switch (TargetFlags) {
235 break;
238 break;
240 Kind = MipsMCExpr::MEK_HI;
241 break;
243 Kind = MipsMCExpr::MEK_LO;
244 break;
245 default:
246 report_fatal_error("Unexpected flags for lowerLongBranchLUi");
247 }
248
249 if (MI->getNumOperands() == 2) {
250 const MCExpr *Expr =
251 MCSymbolRefExpr::create(MI->getOperand(1).getMBB()->getSymbol(), *Ctx);
252 const MipsMCExpr *MipsExpr = MipsMCExpr::create(Kind, Expr, *Ctx);
253 OutMI.addOperand(MCOperand::createExpr(MipsExpr));
254 } else if (MI->getNumOperands() == 3) {
255 // Create %hi($tgt-$baltgt).
256 OutMI.addOperand(createSub(MI->getOperand(1).getMBB(),
257 MI->getOperand(2).getMBB(), Kind));
258 }
259}
260
261void MipsMCInstLower::lowerLongBranchADDiu(const MachineInstr *MI,
262 MCInst &OutMI, int Opcode) const {
263 OutMI.setOpcode(Opcode);
264
266 unsigned TargetFlags = MI->getOperand(2).getTargetFlags();
267 switch (TargetFlags) {
270 break;
273 break;
276 break;
279 break;
280 default:
281 report_fatal_error("Unexpected flags for lowerLongBranchADDiu");
282 }
283
284 // Lower two register operands.
285 for (unsigned I = 0, E = 2; I != E; ++I) {
286 const MachineOperand &MO = MI->getOperand(I);
287 OutMI.addOperand(LowerOperand(MO));
288 }
289
290 if (MI->getNumOperands() == 3) {
291 // Lower register operand.
292 const MCExpr *Expr =
293 MCSymbolRefExpr::create(MI->getOperand(2).getMBB()->getSymbol(), *Ctx);
294 const MipsMCExpr *MipsExpr = MipsMCExpr::create(Kind, Expr, *Ctx);
295 OutMI.addOperand(MCOperand::createExpr(MipsExpr));
296 } else if (MI->getNumOperands() == 4) {
297 // Create %lo($tgt-$baltgt) or %hi($tgt-$baltgt).
298 OutMI.addOperand(createSub(MI->getOperand(2).getMBB(),
299 MI->getOperand(3).getMBB(), Kind));
300 }
301}
302
303bool MipsMCInstLower::lowerLongBranch(const MachineInstr *MI,
304 MCInst &OutMI) const {
305 switch (MI->getOpcode()) {
306 default:
307 return false;
308 case Mips::LONG_BRANCH_LUi:
309 case Mips::LONG_BRANCH_LUi2Op:
310 case Mips::LONG_BRANCH_LUi2Op_64:
311 lowerLongBranchLUi(MI, OutMI);
312 return true;
313 case Mips::LONG_BRANCH_ADDiu:
314 case Mips::LONG_BRANCH_ADDiu2Op:
315 lowerLongBranchADDiu(MI, OutMI, Mips::ADDiu);
316 return true;
317 case Mips::LONG_BRANCH_DADDiu:
318 case Mips::LONG_BRANCH_DADDiu2Op:
319 lowerLongBranchADDiu(MI, OutMI, Mips::DADDiu);
320 return true;
321 }
322}
323
324void MipsMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
325 if (lowerLongBranch(MI, OutMI))
326 return;
327
328 OutMI.setOpcode(MI->getOpcode());
329
330 for (const MachineOperand &MO : MI->operands()) {
331 MCOperand MCOp = LowerOperand(MO);
332
333 if (MCOp.isValid())
334 OutMI.addOperand(MCOp);
335 }
336}
std::string Name
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:87
virtual MCSymbol * GetCPISymbol(unsigned CPID) const
Return the symbol for the specified constant pool entry.
MCSymbol * GetJTISymbol(unsigned JTID, bool isLinkerPrivate=false) const
Return the symbol for the specified jump table entry.
MCSymbol * GetExternalSymbolSymbol(Twine Sym) const
Return the MCSymbol for the specified ExternalSymbol.
void getNameWithPrefix(SmallVectorImpl< char > &Name, const GlobalValue *GV) const
Definition: AsmPrinter.cpp:692
MCSymbol * GetBlockAddressSymbol(const BlockAddress *BA) const
Return the MCSymbol used to satisfy BlockAddress uses of the specified basic block.
Binary assembler expressions.
Definition: MCExpr.h:493
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:537
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:622
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition: MCExpr.cpp:222
Context object for machine code objects.
Definition: MCContext.h:83
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition: MCContext.cpp:212
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:34
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:185
void addOperand(const MCOperand Op)
Definition: MCInst.h:211
void setOpcode(unsigned Op)
Definition: MCInst.h:198
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:37
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:163
static MCOperand createReg(MCRegister Reg)
Definition: MCInst.h:135
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:142
bool isValid() const
Definition: MCInst.h:61
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:192
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:398
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
Representation of each machine instruction.
Definition: MachineInstr.h:69
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
int64_t getImm() const
bool isImplicit() const
MachineBasicBlock * getMBB() const
const BlockAddress * getBlockAddress() const
unsigned getTargetFlags() const
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
const char * getSymbolName() const
Register getReg() const
getReg - Returns the register number.
MCSymbol * getMCSymbol() const
@ MO_Immediate
Immediate operand.
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.
@ MO_MCSymbol
MCSymbol reference (for debug/eh info)
@ MO_GlobalAddress
Address of a global value.
@ MO_RegisterMask
Mask of preserved registers.
@ MO_BlockAddress
Address of a basic block.
@ MO_MachineBasicBlock
MachineBasicBlock reference.
@ MO_Register
Register operand.
@ MO_ExternalSymbol
Name of external global symbol.
@ MO_JumpTableIndex
Address of indexed Jump Table for switch.
int64_t getOffset() const
Return the offset from the symbol in this operand.
static const MipsMCExpr * create(MipsExprKind Kind, const MCExpr *Expr, MCContext &Ctx)
Definition: MipsMCExpr.cpp:27
static const MipsMCExpr * createGpOff(MipsExprKind Kind, const MCExpr *Expr, MCContext &Ctx)
Definition: MipsMCExpr.cpp:32
void Lower(const MachineInstr *MI, MCInst &OutMI) const
MCOperand LowerOperand(const MachineOperand &MO, int64_t offset=0) const
void Initialize(MCContext *C)
MipsMCInstLower(MipsAsmPrinter &asmprinter)
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ MO_GOT_CALL
MO_GOT_CALL - Represents the offset into the global offset table at which the address of a call site ...
Definition: MipsBaseInfo.h:44
@ MO_TPREL_HI
MO_TPREL_HI/LO - Represents the hi and low part of the offset from.
Definition: MipsBaseInfo.h:73
@ MO_GOT
MO_GOT - Represents the offset into the global offset table at which the address the relocation entry...
Definition: MipsBaseInfo.h:38
@ MO_JALR
Helper operand used to generate R_MIPS_JALR.
Definition: MipsBaseInfo.h:95
@ MO_GOTTPREL
MO_GOTTPREL - Represents the offset from the thread pointer (Initial.
Definition: MipsBaseInfo.h:69
@ MO_ABS_HI
MO_ABS_HI/LO - Represents the hi or low part of an absolute symbol address.
Definition: MipsBaseInfo.h:52
@ MO_GOT_HI16
MO_GOT_HI16/LO16, MO_CALL_HI16/LO16 - Relocations used for large GOTs.
Definition: MipsBaseInfo.h:89
@ MO_TLSLDM
MO_TLSLDM - Represents the offset into the global offset table at which.
Definition: MipsBaseInfo.h:63
@ MO_DLLIMPORT
MO_DLLIMPORT - On a symbol operand "FOO", this indicates that the reference is actually to the "__imp...
Definition: MipsBaseInfo.h:100
@ MO_TLSGD
MO_TLSGD - Represents the offset into the global offset table at which.
Definition: MipsBaseInfo.h:58
@ MO_GPREL
MO_GPREL - Represents the offset from the current gp value to be used for the relocatable object file...
Definition: MipsBaseInfo.h:48
@ MO_HIGHER
MO_HIGHER/HIGHEST - Represents the highest or higher half word of a 64-bit symbol address.
Definition: MipsBaseInfo.h:85
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167