blob: fd984058a2bf5d879260a6a568aaefa17a927e86 [file] [log] [blame]
Eugene Zelenko79220eae2017-08-03 22:12:30 +00001//===- MipsMCInstLower.cpp - Convert Mips MachineInstr to MCInst ----------===//
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file contains code to lower Mips MachineInstrs to their corresponding
10// MCInst records.
11//
12//===----------------------------------------------------------------------===//
Eugene Zelenko79220eae2017-08-03 22:12:30 +000013
Craig Topperb25fda92012-03-17 18:46:09 +000014#include "MipsMCInstLower.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000015#include "MCTargetDesc/MipsBaseInfo.h"
Eugene Zelenko79220eae2017-08-03 22:12:30 +000016#include "MCTargetDesc/MipsMCExpr.h"
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +000017#include "MipsAsmPrinter.h"
Eugene Zelenko79220eae2017-08-03 22:12:30 +000018#include "llvm/CodeGen/MachineBasicBlock.h"
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +000019#include "llvm/CodeGen/MachineInstr.h"
20#include "llvm/CodeGen/MachineOperand.h"
Bruno Cardoso Lopesd5edb382011-11-08 22:26:47 +000021#include "llvm/MC/MCExpr.h"
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +000022#include "llvm/MC/MCInst.h"
Eugene Zelenko79220eae2017-08-03 22:12:30 +000023#include "llvm/Support/ErrorHandling.h"
24#include <cassert>
Akira Hatanaka049e9e42011-11-23 22:19:28 +000025
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +000026using namespace llvm;
27
Akira Hatanaka34ee3ff2012-03-28 00:22:50 +000028MipsMCInstLower::MipsMCInstLower(MipsAsmPrinter &asmprinter)
29 : AsmPrinter(asmprinter) {}
30
Rafael Espindola7d78b2a2013-10-29 16:24:21 +000031void MipsMCInstLower::Initialize(MCContext *C) {
Akira Hatanaka34ee3ff2012-03-28 00:22:50 +000032 Ctx = C;
33}
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +000034
35MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
Akira Hatanaka6520b982011-08-16 02:15:03 +000036 MachineOperandType MOTy,
37 unsigned Offset) const {
Daniel Sandersfe98b2f2016-05-03 13:35:44 +000038 MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
39 MipsMCExpr::MipsExprKind TargetKind = MipsMCExpr::MEK_None;
40 bool IsGpOff = false;
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +000041 const MCSymbol *Symbol;
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +000042
43 switch(MO.getTargetFlags()) {
Daniel Sandersfe98b2f2016-05-03 13:35:44 +000044 default:
45 llvm_unreachable("Invalid target flag!");
46 case MipsII::MO_NO_FLAG:
47 break;
48 case MipsII::MO_GPREL:
49 TargetKind = MipsMCExpr::MEK_GPREL;
50 break;
51 case MipsII::MO_GOT_CALL:
52 TargetKind = MipsMCExpr::MEK_GOT_CALL;
53 break;
54 case MipsII::MO_GOT:
55 TargetKind = MipsMCExpr::MEK_GOT;
56 break;
57 case MipsII::MO_ABS_HI:
58 TargetKind = MipsMCExpr::MEK_HI;
59 break;
60 case MipsII::MO_ABS_LO:
61 TargetKind = MipsMCExpr::MEK_LO;
62 break;
63 case MipsII::MO_TLSGD:
64 TargetKind = MipsMCExpr::MEK_TLSGD;
65 break;
66 case MipsII::MO_TLSLDM:
67 TargetKind = MipsMCExpr::MEK_TLSLDM;
68 break;
69 case MipsII::MO_DTPREL_HI:
70 TargetKind = MipsMCExpr::MEK_DTPREL_HI;
71 break;
72 case MipsII::MO_DTPREL_LO:
73 TargetKind = MipsMCExpr::MEK_DTPREL_LO;
74 break;
75 case MipsII::MO_GOTTPREL:
76 TargetKind = MipsMCExpr::MEK_GOTTPREL;
77 break;
78 case MipsII::MO_TPREL_HI:
79 TargetKind = MipsMCExpr::MEK_TPREL_HI;
80 break;
81 case MipsII::MO_TPREL_LO:
82 TargetKind = MipsMCExpr::MEK_TPREL_LO;
83 break;
84 case MipsII::MO_GPOFF_HI:
85 TargetKind = MipsMCExpr::MEK_HI;
86 IsGpOff = true;
87 break;
88 case MipsII::MO_GPOFF_LO:
89 TargetKind = MipsMCExpr::MEK_LO;
90 IsGpOff = true;
91 break;
92 case MipsII::MO_GOT_DISP:
93 TargetKind = MipsMCExpr::MEK_GOT_DISP;
94 break;
95 case MipsII::MO_GOT_HI16:
96 TargetKind = MipsMCExpr::MEK_GOT_HI16;
97 break;
98 case MipsII::MO_GOT_LO16:
99 TargetKind = MipsMCExpr::MEK_GOT_LO16;
100 break;
101 case MipsII::MO_GOT_PAGE:
102 TargetKind = MipsMCExpr::MEK_GOT_PAGE;
103 break;
104 case MipsII::MO_GOT_OFST:
105 TargetKind = MipsMCExpr::MEK_GOT_OFST;
106 break;
107 case MipsII::MO_HIGHER:
108 TargetKind = MipsMCExpr::MEK_HIGHER;
109 break;
110 case MipsII::MO_HIGHEST:
111 TargetKind = MipsMCExpr::MEK_HIGHEST;
112 break;
113 case MipsII::MO_CALL_HI16:
114 TargetKind = MipsMCExpr::MEK_CALL_HI16;
115 break;
116 case MipsII::MO_CALL_LO16:
117 TargetKind = MipsMCExpr::MEK_CALL_LO16;
118 break;
Vladimir Stefanovic3daf8bc2019-01-17 21:50:37 +0000119 case MipsII::MO_JALR:
120 return MCOperand();
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000121 }
122
123 switch (MOTy) {
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000124 case MachineOperand::MO_MachineBasicBlock:
125 Symbol = MO.getMBB()->getSymbol();
126 break;
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000127
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000128 case MachineOperand::MO_GlobalAddress:
Rafael Espindola79858aa2013-10-29 17:07:16 +0000129 Symbol = AsmPrinter.getSymbol(MO.getGlobal());
Akira Hatanaka56bf0232012-06-02 00:02:11 +0000130 Offset += MO.getOffset();
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000131 break;
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000132
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000133 case MachineOperand::MO_BlockAddress:
134 Symbol = AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress());
Akira Hatanaka56bf0232012-06-02 00:02:11 +0000135 Offset += MO.getOffset();
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000136 break;
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000137
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000138 case MachineOperand::MO_ExternalSymbol:
139 Symbol = AsmPrinter.GetExternalSymbolSymbol(MO.getSymbolName());
Akira Hatanaka56bf0232012-06-02 00:02:11 +0000140 Offset += MO.getOffset();
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000141 break;
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000142
Rafael Espindolace4c2bc2015-06-23 12:21:54 +0000143 case MachineOperand::MO_MCSymbol:
144 Symbol = MO.getMCSymbol();
145 Offset += MO.getOffset();
146 break;
147
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000148 case MachineOperand::MO_JumpTableIndex:
149 Symbol = AsmPrinter.GetJTISymbol(MO.getIndex());
150 break;
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000151
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000152 case MachineOperand::MO_ConstantPoolIndex:
153 Symbol = AsmPrinter.GetCPISymbol(MO.getIndex());
Akira Hatanaka56bf0232012-06-02 00:02:11 +0000154 Offset += MO.getOffset();
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000155 break;
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000156
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000157 default:
158 llvm_unreachable("<unknown operand type>");
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000159 }
Jia Liuf54f60f2012-02-28 07:46:26 +0000160
Daniel Sandersfe98b2f2016-05-03 13:35:44 +0000161 const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, Kind, *Ctx);
Bruno Cardoso Lopesd5edb382011-11-08 22:26:47 +0000162
Daniel Sandersfe98b2f2016-05-03 13:35:44 +0000163 if (Offset) {
164 // Assume offset is never negative.
165 assert(Offset > 0);
Bruno Cardoso Lopesd5edb382011-11-08 22:26:47 +0000166
Daniel Sandersfe98b2f2016-05-03 13:35:44 +0000167 Expr = MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(Offset, *Ctx),
168 *Ctx);
169 }
Jia Liuf54f60f2012-02-28 07:46:26 +0000170
Daniel Sandersfe98b2f2016-05-03 13:35:44 +0000171 if (IsGpOff)
172 Expr = MipsMCExpr::createGpOff(TargetKind, Expr, *Ctx);
173 else if (TargetKind != MipsMCExpr::MEK_None)
174 Expr = MipsMCExpr::create(TargetKind, Expr, *Ctx);
175
176 return MCOperand::createExpr(Expr);
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000177}
178
Akira Hatanaka5fd22482012-06-14 21:10:56 +0000179MCOperand MipsMCInstLower::LowerOperand(const MachineOperand &MO,
Jia Liuf54f60f2012-02-28 07:46:26 +0000180 unsigned offset) const {
Akira Hatanaka77f1fd52011-08-16 02:21:03 +0000181 MachineOperandType MOTy = MO.getType();
Jia Liuf54f60f2012-02-28 07:46:26 +0000182
Akira Hatanaka77f1fd52011-08-16 02:21:03 +0000183 switch (MOTy) {
Craig Toppere55c5562012-02-07 02:50:20 +0000184 default: llvm_unreachable("unknown operand type");
Akira Hatanaka77f1fd52011-08-16 02:21:03 +0000185 case MachineOperand::MO_Register:
186 // Ignore all implicit register operands.
187 if (MO.isImplicit()) break;
Jim Grosbache9119e42015-05-13 18:37:00 +0000188 return MCOperand::createReg(MO.getReg());
Akira Hatanaka77f1fd52011-08-16 02:21:03 +0000189 case MachineOperand::MO_Immediate:
Jim Grosbache9119e42015-05-13 18:37:00 +0000190 return MCOperand::createImm(MO.getImm() + offset);
Akira Hatanaka77f1fd52011-08-16 02:21:03 +0000191 case MachineOperand::MO_MachineBasicBlock:
192 case MachineOperand::MO_GlobalAddress:
193 case MachineOperand::MO_ExternalSymbol:
Rafael Espindolace4c2bc2015-06-23 12:21:54 +0000194 case MachineOperand::MO_MCSymbol:
Akira Hatanaka77f1fd52011-08-16 02:21:03 +0000195 case MachineOperand::MO_JumpTableIndex:
196 case MachineOperand::MO_ConstantPoolIndex:
197 case MachineOperand::MO_BlockAddress:
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000198 return LowerSymbolOperand(MO, MOTy, offset);
Jakob Stoklund Olesenf1fb1d22012-01-18 23:52:19 +0000199 case MachineOperand::MO_RegisterMask:
200 break;
Akira Hatanaka77f1fd52011-08-16 02:21:03 +0000201 }
202
203 return MCOperand();
204}
205
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000206MCOperand MipsMCInstLower::createSub(MachineBasicBlock *BB1,
207 MachineBasicBlock *BB2,
Daniel Sandersfe98b2f2016-05-03 13:35:44 +0000208 MipsMCExpr::MipsExprKind Kind) const {
Jim Grosbach13760bd2015-05-30 01:25:56 +0000209 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);
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000212
Jim Grosbach13760bd2015-05-30 01:25:56 +0000213 return MCOperand::createExpr(MipsMCExpr::create(Kind, Sub, *Ctx));
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000214}
215
216void MipsMCInstLower::
Sasa Stankovice41db2f2014-05-27 18:53:06 +0000217lowerLongBranchLUi(const MachineInstr *MI, MCInst &OutMI) const {
218 OutMI.setOpcode(Mips::LUi);
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000219
220 // Lower register operand.
221 OutMI.addOperand(LowerOperand(MI->getOperand(0)));
222
Aleksandar Beserminji8acdc102018-06-12 10:23:49 +0000223 MipsMCExpr::MipsExprKind Kind;
224 unsigned TargetFlags = MI->getOperand(1).getTargetFlags();
225 switch (TargetFlags) {
226 case MipsII::MO_HIGHEST:
227 Kind = MipsMCExpr::MEK_HIGHEST;
228 break;
229 case MipsII::MO_HIGHER:
230 Kind = MipsMCExpr::MEK_HIGHER;
231 break;
232 case MipsII::MO_ABS_HI:
233 Kind = MipsMCExpr::MEK_HI;
234 break;
235 case MipsII::MO_ABS_LO:
236 Kind = MipsMCExpr::MEK_LO;
237 break;
238 default:
239 report_fatal_error("Unexpected flags for lowerLongBranchLUi");
240 }
241
242 if (MI->getNumOperands() == 2) {
243 const MCExpr *Expr =
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));
251 }
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000252}
253
Aleksandar Beserminji8acdc102018-06-12 10:23:49 +0000254void MipsMCInstLower::lowerLongBranchADDiu(const MachineInstr *MI,
255 MCInst &OutMI, int Opcode) const {
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000256 OutMI.setOpcode(Opcode);
257
Aleksandar Beserminji8acdc102018-06-12 10:23:49 +0000258 MipsMCExpr::MipsExprKind Kind;
259 unsigned TargetFlags = MI->getOperand(2).getTargetFlags();
260 switch (TargetFlags) {
261 case MipsII::MO_HIGHEST:
262 Kind = MipsMCExpr::MEK_HIGHEST;
263 break;
264 case MipsII::MO_HIGHER:
265 Kind = MipsMCExpr::MEK_HIGHER;
266 break;
267 case MipsII::MO_ABS_HI:
268 Kind = MipsMCExpr::MEK_HI;
269 break;
270 case MipsII::MO_ABS_LO:
271 Kind = MipsMCExpr::MEK_LO;
272 break;
273 default:
274 report_fatal_error("Unexpected flags for lowerLongBranchADDiu");
275 }
276
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000277 // 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));
281 }
282
Aleksandar Beserminji8acdc102018-06-12 10:23:49 +0000283 if (MI->getNumOperands() == 3) {
284 // Lower register operand.
285 const MCExpr *Expr =
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));
293 }
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000294}
295
296bool MipsMCInstLower::lowerLongBranch(const MachineInstr *MI,
297 MCInst &OutMI) const {
298 switch (MI->getOpcode()) {
299 default:
300 return false;
301 case Mips::LONG_BRANCH_LUi:
Stefan Maksimovic8d7c3512018-11-05 14:37:41 +0000302 case Mips::LONG_BRANCH_LUi2Op:
303 case Mips::LONG_BRANCH_LUi2Op_64:
Sasa Stankovice41db2f2014-05-27 18:53:06 +0000304 lowerLongBranchLUi(MI, OutMI);
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000305 return true;
306 case Mips::LONG_BRANCH_ADDiu:
Stefan Maksimovic8d7c3512018-11-05 14:37:41 +0000307 case Mips::LONG_BRANCH_ADDiu2Op:
Aleksandar Beserminji8acdc102018-06-12 10:23:49 +0000308 lowerLongBranchADDiu(MI, OutMI, Mips::ADDiu);
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000309 return true;
310 case Mips::LONG_BRANCH_DADDiu:
Stefan Maksimovic8d7c3512018-11-05 14:37:41 +0000311 case Mips::LONG_BRANCH_DADDiu2Op:
Aleksandar Beserminji8acdc102018-06-12 10:23:49 +0000312 lowerLongBranchADDiu(MI, OutMI, Mips::DADDiu);
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000313 return true;
314 }
315}
316
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000317void MipsMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000318 if (lowerLongBranch(MI, OutMI))
319 return;
320
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000321 OutMI.setOpcode(MI->getOpcode());
Jia Liuf54f60f2012-02-28 07:46:26 +0000322
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000323 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
324 const MachineOperand &MO = MI->getOperand(i);
Akira Hatanaka77f1fd52011-08-16 02:21:03 +0000325 MCOperand MCOp = LowerOperand(MO);
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000326
Akira Hatanaka77f1fd52011-08-16 02:21:03 +0000327 if (MCOp.isValid())
328 OutMI.addOperand(MCOp);
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000329 }
330}