LLVM 18.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#include <cassert>
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;
42
43 switch(MO.getTargetFlags()) {
44 default:
45 llvm_unreachable("Invalid target flag!");
47 break;
49 TargetKind = MipsMCExpr::MEK_GPREL;
50 break;
52 TargetKind = MipsMCExpr::MEK_GOT_CALL;
53 break;
54 case MipsII::MO_GOT:
55 TargetKind = MipsMCExpr::MEK_GOT;
56 break;
58 TargetKind = MipsMCExpr::MEK_HI;
59 break;
61 TargetKind = MipsMCExpr::MEK_LO;
62 break;
64 TargetKind = MipsMCExpr::MEK_TLSGD;
65 break;
67 TargetKind = MipsMCExpr::MEK_TLSLDM;
68 break;
70 TargetKind = MipsMCExpr::MEK_DTPREL_HI;
71 break;
73 TargetKind = MipsMCExpr::MEK_DTPREL_LO;
74 break;
76 TargetKind = MipsMCExpr::MEK_GOTTPREL;
77 break;
79 TargetKind = MipsMCExpr::MEK_TPREL_HI;
80 break;
82 TargetKind = MipsMCExpr::MEK_TPREL_LO;
83 break;
85 TargetKind = MipsMCExpr::MEK_HI;
86 IsGpOff = true;
87 break;
89 TargetKind = MipsMCExpr::MEK_LO;
90 IsGpOff = true;
91 break;
93 TargetKind = MipsMCExpr::MEK_GOT_DISP;
94 break;
96 TargetKind = MipsMCExpr::MEK_GOT_HI16;
97 break;
99 TargetKind = MipsMCExpr::MEK_GOT_LO16;
100 break;
102 TargetKind = MipsMCExpr::MEK_GOT_PAGE;
103 break;
105 TargetKind = MipsMCExpr::MEK_GOT_OFST;
106 break;
108 TargetKind = MipsMCExpr::MEK_HIGHER;
109 break;
111 TargetKind = MipsMCExpr::MEK_HIGHEST;
112 break;
114 TargetKind = MipsMCExpr::MEK_CALL_HI16;
115 break;
117 TargetKind = MipsMCExpr::MEK_CALL_LO16;
118 break;
119 case MipsII::MO_JALR:
120 return MCOperand();
121 }
122
123 switch (MOTy) {
125 Symbol = MO.getMBB()->getSymbol();
126 break;
127
129 Symbol = AsmPrinter.getSymbol(MO.getGlobal());
130 Offset += MO.getOffset();
131 break;
132
135 Offset += MO.getOffset();
136 break;
137
140 Offset += MO.getOffset();
141 break;
142
144 Symbol = MO.getMCSymbol();
145 Offset += MO.getOffset();
146 break;
147
149 Symbol = AsmPrinter.GetJTISymbol(MO.getIndex());
150 break;
151
153 Symbol = AsmPrinter.GetCPISymbol(MO.getIndex());
154 Offset += MO.getOffset();
155 break;
156
157 default:
158 llvm_unreachable("<unknown operand type>");
159 }
160
161 const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, Kind, *Ctx);
162
163 if (Offset) {
164 // Note: Offset can also be negative
166 *Ctx);
167 }
168
169 if (IsGpOff)
170 Expr = MipsMCExpr::createGpOff(TargetKind, Expr, *Ctx);
171 else if (TargetKind != MipsMCExpr::MEK_None)
172 Expr = MipsMCExpr::create(TargetKind, Expr, *Ctx);
173
174 return MCOperand::createExpr(Expr);
175}
176
178 int64_t offset) const {
179 MachineOperandType MOTy = MO.getType();
180
181 switch (MOTy) {
182 default: llvm_unreachable("unknown operand type");
184 // Ignore all implicit register operands.
185 if (MO.isImplicit()) break;
186 return MCOperand::createReg(MO.getReg());
188 return MCOperand::createImm(MO.getImm() + offset);
196 return LowerSymbolOperand(MO, MOTy, offset);
198 break;
199 }
200
201 return MCOperand();
202}
203
204MCOperand MipsMCInstLower::createSub(MachineBasicBlock *BB1,
206 MipsMCExpr::MipsExprKind Kind) const {
207 const MCSymbolRefExpr *Sym1 = MCSymbolRefExpr::create(BB1->getSymbol(), *Ctx);
208 const MCSymbolRefExpr *Sym2 = MCSymbolRefExpr::create(BB2->getSymbol(), *Ctx);
209 const MCBinaryExpr *Sub = MCBinaryExpr::createSub(Sym1, Sym2, *Ctx);
210
211 return MCOperand::createExpr(MipsMCExpr::create(Kind, Sub, *Ctx));
212}
213
214void MipsMCInstLower::
215lowerLongBranchLUi(const MachineInstr *MI, MCInst &OutMI) const {
216 OutMI.setOpcode(Mips::LUi);
217
218 // Lower register operand.
219 OutMI.addOperand(LowerOperand(MI->getOperand(0)));
220
222 unsigned TargetFlags = MI->getOperand(1).getTargetFlags();
223 switch (TargetFlags) {
226 break;
229 break;
231 Kind = MipsMCExpr::MEK_HI;
232 break;
234 Kind = MipsMCExpr::MEK_LO;
235 break;
236 default:
237 report_fatal_error("Unexpected flags for lowerLongBranchLUi");
238 }
239
240 if (MI->getNumOperands() == 2) {
241 const MCExpr *Expr =
242 MCSymbolRefExpr::create(MI->getOperand(1).getMBB()->getSymbol(), *Ctx);
243 const MipsMCExpr *MipsExpr = MipsMCExpr::create(Kind, Expr, *Ctx);
244 OutMI.addOperand(MCOperand::createExpr(MipsExpr));
245 } else if (MI->getNumOperands() == 3) {
246 // Create %hi($tgt-$baltgt).
247 OutMI.addOperand(createSub(MI->getOperand(1).getMBB(),
248 MI->getOperand(2).getMBB(), Kind));
249 }
250}
251
252void MipsMCInstLower::lowerLongBranchADDiu(const MachineInstr *MI,
253 MCInst &OutMI, int Opcode) const {
254 OutMI.setOpcode(Opcode);
255
257 unsigned TargetFlags = MI->getOperand(2).getTargetFlags();
258 switch (TargetFlags) {
261 break;
264 break;
267 break;
270 break;
271 default:
272 report_fatal_error("Unexpected flags for lowerLongBranchADDiu");
273 }
274
275 // Lower two register operands.
276 for (unsigned I = 0, E = 2; I != E; ++I) {
277 const MachineOperand &MO = MI->getOperand(I);
278 OutMI.addOperand(LowerOperand(MO));
279 }
280
281 if (MI->getNumOperands() == 3) {
282 // Lower register operand.
283 const MCExpr *Expr =
284 MCSymbolRefExpr::create(MI->getOperand(2).getMBB()->getSymbol(), *Ctx);
285 const MipsMCExpr *MipsExpr = MipsMCExpr::create(Kind, Expr, *Ctx);
286 OutMI.addOperand(MCOperand::createExpr(MipsExpr));
287 } else if (MI->getNumOperands() == 4) {
288 // Create %lo($tgt-$baltgt) or %hi($tgt-$baltgt).
289 OutMI.addOperand(createSub(MI->getOperand(2).getMBB(),
290 MI->getOperand(3).getMBB(), Kind));
291 }
292}
293
294bool MipsMCInstLower::lowerLongBranch(const MachineInstr *MI,
295 MCInst &OutMI) const {
296 switch (MI->getOpcode()) {
297 default:
298 return false;
299 case Mips::LONG_BRANCH_LUi:
300 case Mips::LONG_BRANCH_LUi2Op:
301 case Mips::LONG_BRANCH_LUi2Op_64:
302 lowerLongBranchLUi(MI, OutMI);
303 return true;
304 case Mips::LONG_BRANCH_ADDiu:
305 case Mips::LONG_BRANCH_ADDiu2Op:
306 lowerLongBranchADDiu(MI, OutMI, Mips::ADDiu);
307 return true;
308 case Mips::LONG_BRANCH_DADDiu:
309 case Mips::LONG_BRANCH_DADDiu2Op:
310 lowerLongBranchADDiu(MI, OutMI, Mips::DADDiu);
311 return true;
312 }
313}
314
315void MipsMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
316 if (lowerLongBranch(MI, OutMI))
317 return;
318
319 OutMI.setOpcode(MI->getOpcode());
320
321 for (const MachineOperand &MO : MI->operands()) {
322 MCOperand MCOp = LowerOperand(MO);
323
324 if (MCOp.isValid())
325 OutMI.addOperand(MCOp);
326 }
327}
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
static constexpr uint32_t Opcode
Definition: aarch32.h:200
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:679
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(StringRef 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:484
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:528
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:613
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:76
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:389
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:68
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:440
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:156