1 //===- MipsMCInstLower.cpp - Convert Mips MachineInstr to MCInst ----------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file contains code to lower Mips MachineInstrs to their corresponding
12 //===----------------------------------------------------------------------===//
14 #include "MipsMCInstLower.h"
15 #include "MCTargetDesc/MipsBaseInfo.h"
16 #include "MCTargetDesc/MipsMCExpr.h"
17 #include "MipsAsmPrinter.h"
18 #include "llvm/CodeGen/MachineBasicBlock.h"
19 #include "llvm/CodeGen/MachineInstr.h"
20 #include "llvm/CodeGen/MachineOperand.h"
21 #include "llvm/MC/MCExpr.h"
22 #include "llvm/MC/MCInst.h"
23 #include "llvm/Support/ErrorHandling.h"
28 MipsMCInstLower::MipsMCInstLower(MipsAsmPrinter
&asmprinter
)
29 : AsmPrinter(asmprinter
) {}
31 void MipsMCInstLower::Initialize(MCContext
*C
) {
35 MCOperand
MipsMCInstLower::LowerSymbolOperand(const MachineOperand
&MO
,
36 MachineOperandType MOTy
,
37 unsigned Offset
) const {
38 MCSymbolRefExpr::VariantKind Kind
= MCSymbolRefExpr::VK_None
;
39 MipsMCExpr::MipsExprKind TargetKind
= MipsMCExpr::MEK_None
;
41 const MCSymbol
*Symbol
;
43 switch(MO
.getTargetFlags()) {
45 llvm_unreachable("Invalid target flag!");
46 case MipsII::MO_NO_FLAG
:
48 case MipsII::MO_GPREL
:
49 TargetKind
= MipsMCExpr::MEK_GPREL
;
51 case MipsII::MO_GOT_CALL
:
52 TargetKind
= MipsMCExpr::MEK_GOT_CALL
;
55 TargetKind
= MipsMCExpr::MEK_GOT
;
57 case MipsII::MO_ABS_HI
:
58 TargetKind
= MipsMCExpr::MEK_HI
;
60 case MipsII::MO_ABS_LO
:
61 TargetKind
= MipsMCExpr::MEK_LO
;
63 case MipsII::MO_TLSGD
:
64 TargetKind
= MipsMCExpr::MEK_TLSGD
;
66 case MipsII::MO_TLSLDM
:
67 TargetKind
= MipsMCExpr::MEK_TLSLDM
;
69 case MipsII::MO_DTPREL_HI
:
70 TargetKind
= MipsMCExpr::MEK_DTPREL_HI
;
72 case MipsII::MO_DTPREL_LO
:
73 TargetKind
= MipsMCExpr::MEK_DTPREL_LO
;
75 case MipsII::MO_GOTTPREL
:
76 TargetKind
= MipsMCExpr::MEK_GOTTPREL
;
78 case MipsII::MO_TPREL_HI
:
79 TargetKind
= MipsMCExpr::MEK_TPREL_HI
;
81 case MipsII::MO_TPREL_LO
:
82 TargetKind
= MipsMCExpr::MEK_TPREL_LO
;
84 case MipsII::MO_GPOFF_HI
:
85 TargetKind
= MipsMCExpr::MEK_HI
;
88 case MipsII::MO_GPOFF_LO
:
89 TargetKind
= MipsMCExpr::MEK_LO
;
92 case MipsII::MO_GOT_DISP
:
93 TargetKind
= MipsMCExpr::MEK_GOT_DISP
;
95 case MipsII::MO_GOT_HI16
:
96 TargetKind
= MipsMCExpr::MEK_GOT_HI16
;
98 case MipsII::MO_GOT_LO16
:
99 TargetKind
= MipsMCExpr::MEK_GOT_LO16
;
101 case MipsII::MO_GOT_PAGE
:
102 TargetKind
= MipsMCExpr::MEK_GOT_PAGE
;
104 case MipsII::MO_GOT_OFST
:
105 TargetKind
= MipsMCExpr::MEK_GOT_OFST
;
107 case MipsII::MO_HIGHER
:
108 TargetKind
= MipsMCExpr::MEK_HIGHER
;
110 case MipsII::MO_HIGHEST
:
111 TargetKind
= MipsMCExpr::MEK_HIGHEST
;
113 case MipsII::MO_CALL_HI16
:
114 TargetKind
= MipsMCExpr::MEK_CALL_HI16
;
116 case MipsII::MO_CALL_LO16
:
117 TargetKind
= MipsMCExpr::MEK_CALL_LO16
;
119 case MipsII::MO_JALR
:
124 case MachineOperand::MO_MachineBasicBlock
:
125 Symbol
= MO
.getMBB()->getSymbol();
128 case MachineOperand::MO_GlobalAddress
:
129 Symbol
= AsmPrinter
.getSymbol(MO
.getGlobal());
130 Offset
+= MO
.getOffset();
133 case MachineOperand::MO_BlockAddress
:
134 Symbol
= AsmPrinter
.GetBlockAddressSymbol(MO
.getBlockAddress());
135 Offset
+= MO
.getOffset();
138 case MachineOperand::MO_ExternalSymbol
:
139 Symbol
= AsmPrinter
.GetExternalSymbolSymbol(MO
.getSymbolName());
140 Offset
+= MO
.getOffset();
143 case MachineOperand::MO_MCSymbol
:
144 Symbol
= MO
.getMCSymbol();
145 Offset
+= MO
.getOffset();
148 case MachineOperand::MO_JumpTableIndex
:
149 Symbol
= AsmPrinter
.GetJTISymbol(MO
.getIndex());
152 case MachineOperand::MO_ConstantPoolIndex
:
153 Symbol
= AsmPrinter
.GetCPISymbol(MO
.getIndex());
154 Offset
+= MO
.getOffset();
158 llvm_unreachable("<unknown operand type>");
161 const MCExpr
*Expr
= MCSymbolRefExpr::create(Symbol
, Kind
, *Ctx
);
164 // Assume offset is never negative.
167 Expr
= MCBinaryExpr::createAdd(Expr
, MCConstantExpr::create(Offset
, *Ctx
),
172 Expr
= MipsMCExpr::createGpOff(TargetKind
, Expr
, *Ctx
);
173 else if (TargetKind
!= MipsMCExpr::MEK_None
)
174 Expr
= MipsMCExpr::create(TargetKind
, Expr
, *Ctx
);
176 return MCOperand::createExpr(Expr
);
179 MCOperand
MipsMCInstLower::LowerOperand(const MachineOperand
&MO
,
180 unsigned offset
) const {
181 MachineOperandType MOTy
= MO
.getType();
184 default: llvm_unreachable("unknown operand type");
185 case MachineOperand::MO_Register
:
186 // Ignore all implicit register operands.
187 if (MO
.isImplicit()) break;
188 return MCOperand::createReg(MO
.getReg());
189 case MachineOperand::MO_Immediate
:
190 return MCOperand::createImm(MO
.getImm() + offset
);
191 case MachineOperand::MO_MachineBasicBlock
:
192 case MachineOperand::MO_GlobalAddress
:
193 case MachineOperand::MO_ExternalSymbol
:
194 case MachineOperand::MO_MCSymbol
:
195 case MachineOperand::MO_JumpTableIndex
:
196 case MachineOperand::MO_ConstantPoolIndex
:
197 case MachineOperand::MO_BlockAddress
:
198 return LowerSymbolOperand(MO
, MOTy
, offset
);
199 case MachineOperand::MO_RegisterMask
:
206 MCOperand
MipsMCInstLower::createSub(MachineBasicBlock
*BB1
,
207 MachineBasicBlock
*BB2
,
208 MipsMCExpr::MipsExprKind Kind
) const {
209 const MCSymbolRefExpr
*Sym1
= MCSymbolRefExpr::create(BB1
->getSymbol(), *Ctx
);
210 const MCSymbolRefExpr
*Sym2
= MCSymbolRefExpr::create(BB2
->getSymbol(), *Ctx
);
211 const MCBinaryExpr
*Sub
= MCBinaryExpr::createSub(Sym1
, Sym2
, *Ctx
);
213 return MCOperand::createExpr(MipsMCExpr::create(Kind
, Sub
, *Ctx
));
216 void MipsMCInstLower::
217 lowerLongBranchLUi(const MachineInstr
*MI
, MCInst
&OutMI
) const {
218 OutMI
.setOpcode(Mips::LUi
);
220 // Lower register operand.
221 OutMI
.addOperand(LowerOperand(MI
->getOperand(0)));
223 MipsMCExpr::MipsExprKind Kind
;
224 unsigned TargetFlags
= MI
->getOperand(1).getTargetFlags();
225 switch (TargetFlags
) {
226 case MipsII::MO_HIGHEST
:
227 Kind
= MipsMCExpr::MEK_HIGHEST
;
229 case MipsII::MO_HIGHER
:
230 Kind
= MipsMCExpr::MEK_HIGHER
;
232 case MipsII::MO_ABS_HI
:
233 Kind
= MipsMCExpr::MEK_HI
;
235 case MipsII::MO_ABS_LO
:
236 Kind
= MipsMCExpr::MEK_LO
;
239 report_fatal_error("Unexpected flags for lowerLongBranchLUi");
242 if (MI
->getNumOperands() == 2) {
244 MCSymbolRefExpr::create(MI
->getOperand(1).getMBB()->getSymbol(), *Ctx
);
245 const MipsMCExpr
*MipsExpr
= MipsMCExpr::create(Kind
, Expr
, *Ctx
);
246 OutMI
.addOperand(MCOperand::createExpr(MipsExpr
));
247 } else if (MI
->getNumOperands() == 3) {
248 // Create %hi($tgt-$baltgt).
249 OutMI
.addOperand(createSub(MI
->getOperand(1).getMBB(),
250 MI
->getOperand(2).getMBB(), Kind
));
254 void MipsMCInstLower::lowerLongBranchADDiu(const MachineInstr
*MI
,
255 MCInst
&OutMI
, int Opcode
) const {
256 OutMI
.setOpcode(Opcode
);
258 MipsMCExpr::MipsExprKind Kind
;
259 unsigned TargetFlags
= MI
->getOperand(2).getTargetFlags();
260 switch (TargetFlags
) {
261 case MipsII::MO_HIGHEST
:
262 Kind
= MipsMCExpr::MEK_HIGHEST
;
264 case MipsII::MO_HIGHER
:
265 Kind
= MipsMCExpr::MEK_HIGHER
;
267 case MipsII::MO_ABS_HI
:
268 Kind
= MipsMCExpr::MEK_HI
;
270 case MipsII::MO_ABS_LO
:
271 Kind
= MipsMCExpr::MEK_LO
;
274 report_fatal_error("Unexpected flags for lowerLongBranchADDiu");
277 // Lower two register operands.
278 for (unsigned I
= 0, E
= 2; I
!= E
; ++I
) {
279 const MachineOperand
&MO
= MI
->getOperand(I
);
280 OutMI
.addOperand(LowerOperand(MO
));
283 if (MI
->getNumOperands() == 3) {
284 // Lower register operand.
286 MCSymbolRefExpr::create(MI
->getOperand(2).getMBB()->getSymbol(), *Ctx
);
287 const MipsMCExpr
*MipsExpr
= MipsMCExpr::create(Kind
, Expr
, *Ctx
);
288 OutMI
.addOperand(MCOperand::createExpr(MipsExpr
));
289 } else if (MI
->getNumOperands() == 4) {
290 // Create %lo($tgt-$baltgt) or %hi($tgt-$baltgt).
291 OutMI
.addOperand(createSub(MI
->getOperand(2).getMBB(),
292 MI
->getOperand(3).getMBB(), Kind
));
296 bool MipsMCInstLower::lowerLongBranch(const MachineInstr
*MI
,
297 MCInst
&OutMI
) const {
298 switch (MI
->getOpcode()) {
301 case Mips::LONG_BRANCH_LUi
:
302 case Mips::LONG_BRANCH_LUi2Op
:
303 case Mips::LONG_BRANCH_LUi2Op_64
:
304 lowerLongBranchLUi(MI
, OutMI
);
306 case Mips::LONG_BRANCH_ADDiu
:
307 case Mips::LONG_BRANCH_ADDiu2Op
:
308 lowerLongBranchADDiu(MI
, OutMI
, Mips::ADDiu
);
310 case Mips::LONG_BRANCH_DADDiu
:
311 case Mips::LONG_BRANCH_DADDiu2Op
:
312 lowerLongBranchADDiu(MI
, OutMI
, Mips::DADDiu
);
317 void MipsMCInstLower::Lower(const MachineInstr
*MI
, MCInst
&OutMI
) const {
318 if (lowerLongBranch(MI
, OutMI
))
321 OutMI
.setOpcode(MI
->getOpcode());
323 for (unsigned i
= 0, e
= MI
->getNumOperands(); i
!= e
; ++i
) {
324 const MachineOperand
&MO
= MI
->getOperand(i
);
325 MCOperand MCOp
= LowerOperand(MO
);
328 OutMI
.addOperand(MCOp
);