LLVM 19.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/MCExpr.h"
22#include "llvm/MC/MCInst.h"
24
25using namespace llvm;
26
28 : AsmPrinter(asmprinter) {}
29
31 Ctx = C;
32}
33
34MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
35 MachineOperandType MOTy,
36 int64_t Offset) const {
39 bool IsGpOff = false;
40 const MCSymbol *Symbol;
41
42 switch(MO.getTargetFlags()) {
43 default:
44 llvm_unreachable("Invalid target flag!");
46 break;
48 TargetKind = MipsMCExpr::MEK_GPREL;
49 break;
51 TargetKind = MipsMCExpr::MEK_GOT_CALL;
52 break;
53 case MipsII::MO_GOT:
54 TargetKind = MipsMCExpr::MEK_GOT;
55 break;
57 TargetKind = MipsMCExpr::MEK_HI;
58 break;
60 TargetKind = MipsMCExpr::MEK_LO;
61 break;
63 TargetKind = MipsMCExpr::MEK_TLSGD;
64 break;
66 TargetKind = MipsMCExpr::MEK_TLSLDM;
67 break;
69 TargetKind = MipsMCExpr::MEK_DTPREL_HI;
70 break;
72 TargetKind = MipsMCExpr::MEK_DTPREL_LO;
73 break;
75 TargetKind = MipsMCExpr::MEK_GOTTPREL;
76 break;
78 TargetKind = MipsMCExpr::MEK_TPREL_HI;
79 break;
81 TargetKind = MipsMCExpr::MEK_TPREL_LO;
82 break;
84 TargetKind = MipsMCExpr::MEK_HI;
85 IsGpOff = true;
86 break;
88 TargetKind = MipsMCExpr::MEK_LO;
89 IsGpOff = true;
90 break;
92 TargetKind = MipsMCExpr::MEK_GOT_DISP;
93 break;
95 TargetKind = MipsMCExpr::MEK_GOT_HI16;
96 break;
98 TargetKind = MipsMCExpr::MEK_GOT_LO16;
99 break;
101 TargetKind = MipsMCExpr::MEK_GOT_PAGE;
102 break;
104 TargetKind = MipsMCExpr::MEK_GOT_OFST;
105 break;
107 TargetKind = MipsMCExpr::MEK_HIGHER;
108 break;
110 TargetKind = MipsMCExpr::MEK_HIGHEST;
111 break;
113 TargetKind = MipsMCExpr::MEK_CALL_HI16;
114 break;
116 TargetKind = MipsMCExpr::MEK_CALL_LO16;
117 break;
118 case MipsII::MO_JALR:
119 return MCOperand();
120 }
121
122 switch (MOTy) {
124 Symbol = MO.getMBB()->getSymbol();
125 break;
126
128 Symbol = AsmPrinter.getSymbol(MO.getGlobal());
129 Offset += MO.getOffset();
130 break;
131
134 Offset += MO.getOffset();
135 break;
136
139 Offset += MO.getOffset();
140 break;
141
143 Symbol = MO.getMCSymbol();
144 Offset += MO.getOffset();
145 break;
146
148 Symbol = AsmPrinter.GetJTISymbol(MO.getIndex());
149 break;
150
152 Symbol = AsmPrinter.GetCPISymbol(MO.getIndex());
153 Offset += MO.getOffset();
154 break;
155
156 default:
157 llvm_unreachable("<unknown operand type>");
158 }
159
160 const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, Kind, *Ctx);
161
162 if (Offset) {
163 // Note: Offset can also be negative
165 *Ctx);
166 }
167
168 if (IsGpOff)
169 Expr = MipsMCExpr::createGpOff(TargetKind, Expr, *Ctx);
170 else if (TargetKind != MipsMCExpr::MEK_None)
171 Expr = MipsMCExpr::create(TargetKind, Expr, *Ctx);
172
173 return MCOperand::createExpr(Expr);
174}
175
177 int64_t offset) const {
178 MachineOperandType MOTy = MO.getType();
179
180 switch (MOTy) {
181 default: llvm_unreachable("unknown operand type");
183 // Ignore all implicit register operands.
184 if (MO.isImplicit()) break;
185 return MCOperand::createReg(MO.getReg());
187 return MCOperand::createImm(MO.getImm() + offset);
195 return LowerSymbolOperand(MO, MOTy, offset);
197 break;
198 }
199
200 return MCOperand();
201}
202
203MCOperand MipsMCInstLower::createSub(MachineBasicBlock *BB1,
205 MipsMCExpr::MipsExprKind Kind) const {
206 const MCSymbolRefExpr *Sym1 = MCSymbolRefExpr::create(BB1->getSymbol(), *Ctx);
207 const MCSymbolRefExpr *Sym2 = MCSymbolRefExpr::create(BB2->getSymbol(), *Ctx);
208 const MCBinaryExpr *Sub = MCBinaryExpr::createSub(Sym1, Sym2, *Ctx);
209
210 return MCOperand::createExpr(MipsMCExpr::create(Kind, Sub, *Ctx));
211}
212
213void MipsMCInstLower::
214lowerLongBranchLUi(const MachineInstr *MI, MCInst &OutMI) const {
215 OutMI.setOpcode(Mips::LUi);
216
217 // Lower register operand.
218 OutMI.addOperand(LowerOperand(MI->getOperand(0)));
219
221 unsigned TargetFlags = MI->getOperand(1).getTargetFlags();
222 switch (TargetFlags) {
225 break;
228 break;
230 Kind = MipsMCExpr::MEK_HI;
231 break;
233 Kind = MipsMCExpr::MEK_LO;
234 break;
235 default:
236 report_fatal_error("Unexpected flags for lowerLongBranchLUi");
237 }
238
239 if (MI->getNumOperands() == 2) {
240 const MCExpr *Expr =
241 MCSymbolRefExpr::create(MI->getOperand(1).getMBB()->getSymbol(), *Ctx);
242 const MipsMCExpr *MipsExpr = MipsMCExpr::create(Kind, Expr, *Ctx);
243 OutMI.addOperand(MCOperand::createExpr(MipsExpr));
244 } else if (MI->getNumOperands() == 3) {
245 // Create %hi($tgt-$baltgt).
246 OutMI.addOperand(createSub(MI->getOperand(1).getMBB(),
247 MI->getOperand(2).getMBB(), Kind));
248 }
249}
250
251void MipsMCInstLower::lowerLongBranchADDiu(const MachineInstr *MI,
252 MCInst &OutMI, int Opcode) const {
253 OutMI.setOpcode(Opcode);
254
256 unsigned TargetFlags = MI->getOperand(2).getTargetFlags();
257 switch (TargetFlags) {
260 break;
263 break;
266 break;
269 break;
270 default:
271 report_fatal_error("Unexpected flags for lowerLongBranchADDiu");
272 }
273
274 // Lower two register operands.
275 for (unsigned I = 0, E = 2; I != E; ++I) {
276 const MachineOperand &MO = MI->getOperand(I);
277 OutMI.addOperand(LowerOperand(MO));
278 }
279
280 if (MI->getNumOperands() == 3) {
281 // Lower register operand.
282 const MCExpr *Expr =
283 MCSymbolRefExpr::create(MI->getOperand(2).getMBB()->getSymbol(), *Ctx);
284 const MipsMCExpr *MipsExpr = MipsMCExpr::create(Kind, Expr, *Ctx);
285 OutMI.addOperand(MCOperand::createExpr(MipsExpr));
286 } else if (MI->getNumOperands() == 4) {
287 // Create %lo($tgt-$baltgt) or %hi($tgt-$baltgt).
288 OutMI.addOperand(createSub(MI->getOperand(2).getMBB(),
289 MI->getOperand(3).getMBB(), Kind));
290 }
291}
292
293bool MipsMCInstLower::lowerLongBranch(const MachineInstr *MI,
294 MCInst &OutMI) const {
295 switch (MI->getOpcode()) {
296 default:
297 return false;
298 case Mips::LONG_BRANCH_LUi:
299 case Mips::LONG_BRANCH_LUi2Op:
300 case Mips::LONG_BRANCH_LUi2Op_64:
301 lowerLongBranchLUi(MI, OutMI);
302 return true;
303 case Mips::LONG_BRANCH_ADDiu:
304 case Mips::LONG_BRANCH_ADDiu2Op:
305 lowerLongBranchADDiu(MI, OutMI, Mips::ADDiu);
306 return true;
307 case Mips::LONG_BRANCH_DADDiu:
308 case Mips::LONG_BRANCH_DADDiu2Op:
309 lowerLongBranchADDiu(MI, OutMI, Mips::DADDiu);
310 return true;
311 }
312}
313
314void MipsMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
315 if (lowerLongBranch(MI, OutMI))
316 return;
317
318 OutMI.setOpcode(MI->getOpcode());
319
320 for (const MachineOperand &MO : MI->operands()) {
321 MCOperand MCOp = LowerOperand(MO);
322
323 if (MCOp.isValid())
324 OutMI.addOperand(MCOp);
325 }
326}
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:84
MCSymbol * getSymbol(const GlobalValue *GV) const
Definition: AsmPrinter.cpp:700
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.
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:492
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:536
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:621
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition: MCExpr.cpp:194
Context object for machine code objects.
Definition: MCContext.h:81
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
void addOperand(const MCOperand Op)
Definition: MCInst.h:210
void setOpcode(unsigned Op)
Definition: MCInst.h:197
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:134
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:162
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:141
bool isValid() const
Definition: MCInst.h:60
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:397
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:40
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)
#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_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:456
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:156