blob: d5bc4e537c37c39f2b2a3fd3f09bfd5267211f62 [file] [log] [blame]
Jia Liu9f610112012-02-17 08:55:11 +00001//===-- MipsMCInstLower.cpp - Convert Mips MachineInstr to MCInst ---------===//
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains code to lower Mips MachineInstrs to their corresponding
11// MCInst records.
12//
13//===----------------------------------------------------------------------===//
Craig Topperb25fda92012-03-17 18:46:09 +000014#include "MipsMCInstLower.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000015#include "MCTargetDesc/MipsBaseInfo.h"
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +000016#include "MipsAsmPrinter.h"
17#include "MipsInstrInfo.h"
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +000018#include "llvm/CodeGen/MachineFunction.h"
19#include "llvm/CodeGen/MachineInstr.h"
20#include "llvm/CodeGen/MachineOperand.h"
Rafael Espindola894843c2014-01-07 21:19:40 +000021#include "llvm/IR/Mangler.h"
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +000022#include "llvm/MC/MCContext.h"
Bruno Cardoso Lopesd5edb382011-11-08 22:26:47 +000023#include "llvm/MC/MCExpr.h"
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +000024#include "llvm/MC/MCInst.h"
Pete Cooperef21bd42015-03-04 01:24:11 +000025#include "llvm/MC/MCStreamer.h"
Akira Hatanaka049e9e42011-11-23 22:19:28 +000026
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +000027using namespace llvm;
28
Akira Hatanaka34ee3ff2012-03-28 00:22:50 +000029MipsMCInstLower::MipsMCInstLower(MipsAsmPrinter &asmprinter)
30 : AsmPrinter(asmprinter) {}
31
Rafael Espindola7d78b2a2013-10-29 16:24:21 +000032void MipsMCInstLower::Initialize(MCContext *C) {
Akira Hatanaka34ee3ff2012-03-28 00:22:50 +000033 Ctx = C;
34}
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +000035
36MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
Akira Hatanaka6520b982011-08-16 02:15:03 +000037 MachineOperandType MOTy,
38 unsigned Offset) const {
Daniel Sandersfe98b2f2016-05-03 13:35:44 +000039 MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
40 MipsMCExpr::MipsExprKind TargetKind = MipsMCExpr::MEK_None;
41 bool IsGpOff = false;
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +000042 const MCSymbol *Symbol;
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +000043
44 switch(MO.getTargetFlags()) {
Daniel Sandersfe98b2f2016-05-03 13:35:44 +000045 default:
46 llvm_unreachable("Invalid target flag!");
47 case MipsII::MO_NO_FLAG:
48 break;
49 case MipsII::MO_GPREL:
50 TargetKind = MipsMCExpr::MEK_GPREL;
51 break;
52 case MipsII::MO_GOT_CALL:
53 TargetKind = MipsMCExpr::MEK_GOT_CALL;
54 break;
55 case MipsII::MO_GOT:
56 TargetKind = MipsMCExpr::MEK_GOT;
57 break;
58 case MipsII::MO_ABS_HI:
59 TargetKind = MipsMCExpr::MEK_HI;
60 break;
61 case MipsII::MO_ABS_LO:
62 TargetKind = MipsMCExpr::MEK_LO;
63 break;
64 case MipsII::MO_TLSGD:
65 TargetKind = MipsMCExpr::MEK_TLSGD;
66 break;
67 case MipsII::MO_TLSLDM:
68 TargetKind = MipsMCExpr::MEK_TLSLDM;
69 break;
70 case MipsII::MO_DTPREL_HI:
71 TargetKind = MipsMCExpr::MEK_DTPREL_HI;
72 break;
73 case MipsII::MO_DTPREL_LO:
74 TargetKind = MipsMCExpr::MEK_DTPREL_LO;
75 break;
76 case MipsII::MO_GOTTPREL:
77 TargetKind = MipsMCExpr::MEK_GOTTPREL;
78 break;
79 case MipsII::MO_TPREL_HI:
80 TargetKind = MipsMCExpr::MEK_TPREL_HI;
81 break;
82 case MipsII::MO_TPREL_LO:
83 TargetKind = MipsMCExpr::MEK_TPREL_LO;
84 break;
85 case MipsII::MO_GPOFF_HI:
86 TargetKind = MipsMCExpr::MEK_HI;
87 IsGpOff = true;
88 break;
89 case MipsII::MO_GPOFF_LO:
90 TargetKind = MipsMCExpr::MEK_LO;
91 IsGpOff = true;
92 break;
93 case MipsII::MO_GOT_DISP:
94 TargetKind = MipsMCExpr::MEK_GOT_DISP;
95 break;
96 case MipsII::MO_GOT_HI16:
97 TargetKind = MipsMCExpr::MEK_GOT_HI16;
98 break;
99 case MipsII::MO_GOT_LO16:
100 TargetKind = MipsMCExpr::MEK_GOT_LO16;
101 break;
102 case MipsII::MO_GOT_PAGE:
103 TargetKind = MipsMCExpr::MEK_GOT_PAGE;
104 break;
105 case MipsII::MO_GOT_OFST:
106 TargetKind = MipsMCExpr::MEK_GOT_OFST;
107 break;
108 case MipsII::MO_HIGHER:
109 TargetKind = MipsMCExpr::MEK_HIGHER;
110 break;
111 case MipsII::MO_HIGHEST:
112 TargetKind = MipsMCExpr::MEK_HIGHEST;
113 break;
114 case MipsII::MO_CALL_HI16:
115 TargetKind = MipsMCExpr::MEK_CALL_HI16;
116 break;
117 case MipsII::MO_CALL_LO16:
118 TargetKind = MipsMCExpr::MEK_CALL_LO16;
119 break;
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000120 }
121
122 switch (MOTy) {
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000123 case MachineOperand::MO_MachineBasicBlock:
124 Symbol = MO.getMBB()->getSymbol();
125 break;
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000126
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000127 case MachineOperand::MO_GlobalAddress:
Rafael Espindola79858aa2013-10-29 17:07:16 +0000128 Symbol = AsmPrinter.getSymbol(MO.getGlobal());
Akira Hatanaka56bf0232012-06-02 00:02:11 +0000129 Offset += MO.getOffset();
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000130 break;
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000131
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000132 case MachineOperand::MO_BlockAddress:
133 Symbol = AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress());
Akira Hatanaka56bf0232012-06-02 00:02:11 +0000134 Offset += MO.getOffset();
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000135 break;
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000136
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000137 case MachineOperand::MO_ExternalSymbol:
138 Symbol = AsmPrinter.GetExternalSymbolSymbol(MO.getSymbolName());
Akira Hatanaka56bf0232012-06-02 00:02:11 +0000139 Offset += MO.getOffset();
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000140 break;
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000141
Rafael Espindolace4c2bc2015-06-23 12:21:54 +0000142 case MachineOperand::MO_MCSymbol:
143 Symbol = MO.getMCSymbol();
144 Offset += MO.getOffset();
145 break;
146
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000147 case MachineOperand::MO_JumpTableIndex:
148 Symbol = AsmPrinter.GetJTISymbol(MO.getIndex());
149 break;
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000150
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000151 case MachineOperand::MO_ConstantPoolIndex:
152 Symbol = AsmPrinter.GetCPISymbol(MO.getIndex());
Akira Hatanaka56bf0232012-06-02 00:02:11 +0000153 Offset += MO.getOffset();
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000154 break;
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000155
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000156 default:
157 llvm_unreachable("<unknown operand type>");
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000158 }
Jia Liuf54f60f2012-02-28 07:46:26 +0000159
Daniel Sandersfe98b2f2016-05-03 13:35:44 +0000160 const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, Kind, *Ctx);
Bruno Cardoso Lopesd5edb382011-11-08 22:26:47 +0000161
Daniel Sandersfe98b2f2016-05-03 13:35:44 +0000162 if (Offset) {
163 // Assume offset is never negative.
164 assert(Offset > 0);
Bruno Cardoso Lopesd5edb382011-11-08 22:26:47 +0000165
Daniel Sandersfe98b2f2016-05-03 13:35:44 +0000166 Expr = MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(Offset, *Ctx),
167 *Ctx);
168 }
Jia Liuf54f60f2012-02-28 07:46:26 +0000169
Daniel Sandersfe98b2f2016-05-03 13:35:44 +0000170 if (IsGpOff)
171 Expr = MipsMCExpr::createGpOff(TargetKind, Expr, *Ctx);
172 else if (TargetKind != MipsMCExpr::MEK_None)
173 Expr = MipsMCExpr::create(TargetKind, Expr, *Ctx);
174
175 return MCOperand::createExpr(Expr);
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000176}
177
Akira Hatanaka5fd22482012-06-14 21:10:56 +0000178MCOperand MipsMCInstLower::LowerOperand(const MachineOperand &MO,
Jia Liuf54f60f2012-02-28 07:46:26 +0000179 unsigned offset) const {
Akira Hatanaka77f1fd52011-08-16 02:21:03 +0000180 MachineOperandType MOTy = MO.getType();
Jia Liuf54f60f2012-02-28 07:46:26 +0000181
Akira Hatanaka77f1fd52011-08-16 02:21:03 +0000182 switch (MOTy) {
Craig Toppere55c5562012-02-07 02:50:20 +0000183 default: llvm_unreachable("unknown operand type");
Akira Hatanaka77f1fd52011-08-16 02:21:03 +0000184 case MachineOperand::MO_Register:
185 // Ignore all implicit register operands.
186 if (MO.isImplicit()) break;
Jim Grosbache9119e42015-05-13 18:37:00 +0000187 return MCOperand::createReg(MO.getReg());
Akira Hatanaka77f1fd52011-08-16 02:21:03 +0000188 case MachineOperand::MO_Immediate:
Jim Grosbache9119e42015-05-13 18:37:00 +0000189 return MCOperand::createImm(MO.getImm() + offset);
Akira Hatanaka77f1fd52011-08-16 02:21:03 +0000190 case MachineOperand::MO_MachineBasicBlock:
191 case MachineOperand::MO_GlobalAddress:
192 case MachineOperand::MO_ExternalSymbol:
Rafael Espindolace4c2bc2015-06-23 12:21:54 +0000193 case MachineOperand::MO_MCSymbol:
Akira Hatanaka77f1fd52011-08-16 02:21:03 +0000194 case MachineOperand::MO_JumpTableIndex:
195 case MachineOperand::MO_ConstantPoolIndex:
196 case MachineOperand::MO_BlockAddress:
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000197 return LowerSymbolOperand(MO, MOTy, offset);
Jakob Stoklund Olesenf1fb1d22012-01-18 23:52:19 +0000198 case MachineOperand::MO_RegisterMask:
199 break;
Akira Hatanaka77f1fd52011-08-16 02:21:03 +0000200 }
201
202 return MCOperand();
203}
204
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000205MCOperand MipsMCInstLower::createSub(MachineBasicBlock *BB1,
206 MachineBasicBlock *BB2,
Daniel Sandersfe98b2f2016-05-03 13:35:44 +0000207 MipsMCExpr::MipsExprKind Kind) const {
Jim Grosbach13760bd2015-05-30 01:25:56 +0000208 const MCSymbolRefExpr *Sym1 = MCSymbolRefExpr::create(BB1->getSymbol(), *Ctx);
209 const MCSymbolRefExpr *Sym2 = MCSymbolRefExpr::create(BB2->getSymbol(), *Ctx);
210 const MCBinaryExpr *Sub = MCBinaryExpr::createSub(Sym1, Sym2, *Ctx);
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000211
Jim Grosbach13760bd2015-05-30 01:25:56 +0000212 return MCOperand::createExpr(MipsMCExpr::create(Kind, Sub, *Ctx));
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000213}
214
215void MipsMCInstLower::
Sasa Stankovice41db2f2014-05-27 18:53:06 +0000216lowerLongBranchLUi(const MachineInstr *MI, MCInst &OutMI) const {
217 OutMI.setOpcode(Mips::LUi);
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000218
219 // Lower register operand.
220 OutMI.addOperand(LowerOperand(MI->getOperand(0)));
221
Sasa Stankovice41db2f2014-05-27 18:53:06 +0000222 // Create %hi($tgt-$baltgt).
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000223 OutMI.addOperand(createSub(MI->getOperand(1).getMBB(),
Sasa Stankovice41db2f2014-05-27 18:53:06 +0000224 MI->getOperand(2).getMBB(),
Daniel Sandersfe98b2f2016-05-03 13:35:44 +0000225 MipsMCExpr::MEK_HI));
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000226}
227
Daniel Sandersfe98b2f2016-05-03 13:35:44 +0000228void MipsMCInstLower::lowerLongBranchADDiu(
229 const MachineInstr *MI, MCInst &OutMI, int Opcode,
230 MipsMCExpr::MipsExprKind Kind) const {
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000231 OutMI.setOpcode(Opcode);
232
233 // Lower two register operands.
234 for (unsigned I = 0, E = 2; I != E; ++I) {
235 const MachineOperand &MO = MI->getOperand(I);
236 OutMI.addOperand(LowerOperand(MO));
237 }
238
Sasa Stankovice41db2f2014-05-27 18:53:06 +0000239 // Create %lo($tgt-$baltgt) or %hi($tgt-$baltgt).
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000240 OutMI.addOperand(createSub(MI->getOperand(2).getMBB(),
241 MI->getOperand(3).getMBB(), Kind));
242}
243
244bool MipsMCInstLower::lowerLongBranch(const MachineInstr *MI,
245 MCInst &OutMI) const {
246 switch (MI->getOpcode()) {
247 default:
248 return false;
249 case Mips::LONG_BRANCH_LUi:
Sasa Stankovice41db2f2014-05-27 18:53:06 +0000250 lowerLongBranchLUi(MI, OutMI);
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000251 return true;
252 case Mips::LONG_BRANCH_ADDiu:
Daniel Sandersfe98b2f2016-05-03 13:35:44 +0000253 lowerLongBranchADDiu(MI, OutMI, Mips::ADDiu, MipsMCExpr::MEK_LO);
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000254 return true;
255 case Mips::LONG_BRANCH_DADDiu:
256 unsigned TargetFlags = MI->getOperand(2).getTargetFlags();
Sasa Stankovice41db2f2014-05-27 18:53:06 +0000257 if (TargetFlags == MipsII::MO_ABS_HI)
Daniel Sandersfe98b2f2016-05-03 13:35:44 +0000258 lowerLongBranchADDiu(MI, OutMI, Mips::DADDiu, MipsMCExpr::MEK_HI);
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000259 else if (TargetFlags == MipsII::MO_ABS_LO)
Daniel Sandersfe98b2f2016-05-03 13:35:44 +0000260 lowerLongBranchADDiu(MI, OutMI, Mips::DADDiu, MipsMCExpr::MEK_LO);
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000261 else
262 report_fatal_error("Unexpected flags for LONG_BRANCH_DADDiu");
263 return true;
264 }
265}
266
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000267void MipsMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000268 if (lowerLongBranch(MI, OutMI))
269 return;
270
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000271 OutMI.setOpcode(MI->getOpcode());
Jia Liuf54f60f2012-02-28 07:46:26 +0000272
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000273 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
274 const MachineOperand &MO = MI->getOperand(i);
Akira Hatanaka77f1fd52011-08-16 02:21:03 +0000275 MCOperand MCOp = LowerOperand(MO);
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000276
Akira Hatanaka77f1fd52011-08-16 02:21:03 +0000277 if (MCOp.isValid())
278 OutMI.addOperand(MCOp);
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000279 }
280}
Jack Carterf6490432012-07-16 15:14:51 +0000281