1 //===- MipsMCInstLower.cpp - Convert Mips MachineInstr to MCInst ----------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains code to lower Mips MachineInstrs to their corresponding
13 //===----------------------------------------------------------------------===//
15 #include "MipsMCInstLower.h"
16 #include "MCTargetDesc/MipsBaseInfo.h"
17 #include "MCTargetDesc/MipsMCExpr.h"
18 #include "MipsAsmPrinter.h"
19 #include "llvm/CodeGen/MachineBasicBlock.h"
20 #include "llvm/CodeGen/MachineInstr.h"
21 #include "llvm/CodeGen/MachineOperand.h"
22 #include "llvm/MC/MCExpr.h"
23 #include "llvm/MC/MCInst.h"
24 #include "llvm/Support/ErrorHandling.h"
29 MipsMCInstLower::MipsMCInstLower(MipsAsmPrinter
&asmprinter
)
30 : AsmPrinter(asmprinter
) {}
32 void MipsMCInstLower::Initialize(MCContext
*C
) {
36 MCOperand
MipsMCInstLower::LowerSymbolOperand(const MachineOperand
&MO
,
37 MachineOperandType MOTy
,
38 unsigned Offset
) const {
39 MCSymbolRefExpr::VariantKind Kind
= MCSymbolRefExpr::VK_None
;
40 MipsMCExpr::MipsExprKind TargetKind
= MipsMCExpr::MEK_None
;
42 const MCSymbol
*Symbol
;
44 switch(MO
.getTargetFlags()) {
46 llvm_unreachable("Invalid target flag!");
47 case MipsII::MO_NO_FLAG
:
49 case MipsII::MO_GPREL
:
50 TargetKind
= MipsMCExpr::MEK_GPREL
;
52 case MipsII::MO_GOT_CALL
:
53 TargetKind
= MipsMCExpr::MEK_GOT_CALL
;
56 TargetKind
= MipsMCExpr::MEK_GOT
;
58 case MipsII::MO_ABS_HI
:
59 TargetKind
= MipsMCExpr::MEK_HI
;
61 case MipsII::MO_ABS_LO
:
62 TargetKind
= MipsMCExpr::MEK_LO
;
64 case MipsII::MO_TLSGD
:
65 TargetKind
= MipsMCExpr::MEK_TLSGD
;
67 case MipsII::MO_TLSLDM
:
68 TargetKind
= MipsMCExpr::MEK_TLSLDM
;
70 case MipsII::MO_DTPREL_HI
:
71 TargetKind
= MipsMCExpr::MEK_DTPREL_HI
;
73 case MipsII::MO_DTPREL_LO
:
74 TargetKind
= MipsMCExpr::MEK_DTPREL_LO
;
76 case MipsII::MO_GOTTPREL
:
77 TargetKind
= MipsMCExpr::MEK_GOTTPREL
;
79 case MipsII::MO_TPREL_HI
:
80 TargetKind
= MipsMCExpr::MEK_TPREL_HI
;
82 case MipsII::MO_TPREL_LO
:
83 TargetKind
= MipsMCExpr::MEK_TPREL_LO
;
85 case MipsII::MO_GPOFF_HI
:
86 TargetKind
= MipsMCExpr::MEK_HI
;
89 case MipsII::MO_GPOFF_LO
:
90 TargetKind
= MipsMCExpr::MEK_LO
;
93 case MipsII::MO_GOT_DISP
:
94 TargetKind
= MipsMCExpr::MEK_GOT_DISP
;
96 case MipsII::MO_GOT_HI16
:
97 TargetKind
= MipsMCExpr::MEK_GOT_HI16
;
99 case MipsII::MO_GOT_LO16
:
100 TargetKind
= MipsMCExpr::MEK_GOT_LO16
;
102 case MipsII::MO_GOT_PAGE
:
103 TargetKind
= MipsMCExpr::MEK_GOT_PAGE
;
105 case MipsII::MO_GOT_OFST
:
106 TargetKind
= MipsMCExpr::MEK_GOT_OFST
;
108 case MipsII::MO_HIGHER
:
109 TargetKind
= MipsMCExpr::MEK_HIGHER
;
111 case MipsII::MO_HIGHEST
:
112 TargetKind
= MipsMCExpr::MEK_HIGHEST
;
114 case MipsII::MO_CALL_HI16
:
115 TargetKind
= MipsMCExpr::MEK_CALL_HI16
;
117 case MipsII::MO_CALL_LO16
:
118 TargetKind
= MipsMCExpr::MEK_CALL_LO16
;
123 case MachineOperand::MO_MachineBasicBlock
:
124 Symbol
= MO
.getMBB()->getSymbol();
127 case MachineOperand::MO_GlobalAddress
:
128 Symbol
= AsmPrinter
.getSymbol(MO
.getGlobal());
129 Offset
+= MO
.getOffset();
132 case MachineOperand::MO_BlockAddress
:
133 Symbol
= AsmPrinter
.GetBlockAddressSymbol(MO
.getBlockAddress());
134 Offset
+= MO
.getOffset();
137 case MachineOperand::MO_ExternalSymbol
:
138 Symbol
= AsmPrinter
.GetExternalSymbolSymbol(MO
.getSymbolName());
139 Offset
+= MO
.getOffset();
142 case MachineOperand::MO_MCSymbol
:
143 Symbol
= MO
.getMCSymbol();
144 Offset
+= MO
.getOffset();
147 case MachineOperand::MO_JumpTableIndex
:
148 Symbol
= AsmPrinter
.GetJTISymbol(MO
.getIndex());
151 case MachineOperand::MO_ConstantPoolIndex
:
152 Symbol
= AsmPrinter
.GetCPISymbol(MO
.getIndex());
153 Offset
+= MO
.getOffset();
157 llvm_unreachable("<unknown operand type>");
160 const MCExpr
*Expr
= MCSymbolRefExpr::create(Symbol
, Kind
, *Ctx
);
163 // Assume offset is never negative.
166 Expr
= MCBinaryExpr::createAdd(Expr
, MCConstantExpr::create(Offset
, *Ctx
),
171 Expr
= MipsMCExpr::createGpOff(TargetKind
, Expr
, *Ctx
);
172 else if (TargetKind
!= MipsMCExpr::MEK_None
)
173 Expr
= MipsMCExpr::create(TargetKind
, Expr
, *Ctx
);
175 return MCOperand::createExpr(Expr
);
178 MCOperand
MipsMCInstLower::LowerOperand(const MachineOperand
&MO
,
179 unsigned offset
) const {
180 MachineOperandType MOTy
= MO
.getType();
183 default: llvm_unreachable("unknown operand type");
184 case MachineOperand::MO_Register
:
185 // Ignore all implicit register operands.
186 if (MO
.isImplicit()) break;
187 return MCOperand::createReg(MO
.getReg());
188 case MachineOperand::MO_Immediate
:
189 return MCOperand::createImm(MO
.getImm() + offset
);
190 case MachineOperand::MO_MachineBasicBlock
:
191 case MachineOperand::MO_GlobalAddress
:
192 case MachineOperand::MO_ExternalSymbol
:
193 case MachineOperand::MO_MCSymbol
:
194 case MachineOperand::MO_JumpTableIndex
:
195 case MachineOperand::MO_ConstantPoolIndex
:
196 case MachineOperand::MO_BlockAddress
:
197 return LowerSymbolOperand(MO
, MOTy
, offset
);
198 case MachineOperand::MO_RegisterMask
:
205 MCOperand
MipsMCInstLower::createSub(MachineBasicBlock
*BB1
,
206 MachineBasicBlock
*BB2
,
207 MipsMCExpr::MipsExprKind Kind
) const {
208 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
);
212 return MCOperand::createExpr(MipsMCExpr::create(Kind
, Sub
, *Ctx
));
215 void MipsMCInstLower::
216 lowerLongBranchLUi(const MachineInstr
*MI
, MCInst
&OutMI
) const {
217 OutMI
.setOpcode(Mips::LUi
);
219 // Lower register operand.
220 OutMI
.addOperand(LowerOperand(MI
->getOperand(0)));
222 MipsMCExpr::MipsExprKind Kind
;
223 unsigned TargetFlags
= MI
->getOperand(1).getTargetFlags();
224 switch (TargetFlags
) {
225 case MipsII::MO_HIGHEST
:
226 Kind
= MipsMCExpr::MEK_HIGHEST
;
228 case MipsII::MO_HIGHER
:
229 Kind
= MipsMCExpr::MEK_HIGHER
;
231 case MipsII::MO_ABS_HI
:
232 Kind
= MipsMCExpr::MEK_HI
;
234 case MipsII::MO_ABS_LO
:
235 Kind
= MipsMCExpr::MEK_LO
;
238 report_fatal_error("Unexpected flags for lowerLongBranchLUi");
241 if (MI
->getNumOperands() == 2) {
243 MCSymbolRefExpr::create(MI
->getOperand(1).getMBB()->getSymbol(), *Ctx
);
244 const MipsMCExpr
*MipsExpr
= MipsMCExpr::create(Kind
, Expr
, *Ctx
);
245 OutMI
.addOperand(MCOperand::createExpr(MipsExpr
));
246 } else if (MI
->getNumOperands() == 3) {
247 // Create %hi($tgt-$baltgt).
248 OutMI
.addOperand(createSub(MI
->getOperand(1).getMBB(),
249 MI
->getOperand(2).getMBB(), Kind
));
253 void MipsMCInstLower::lowerLongBranchADDiu(const MachineInstr
*MI
,
254 MCInst
&OutMI
, int Opcode
) const {
255 OutMI
.setOpcode(Opcode
);
257 MipsMCExpr::MipsExprKind Kind
;
258 unsigned TargetFlags
= MI
->getOperand(2).getTargetFlags();
259 switch (TargetFlags
) {
260 case MipsII::MO_HIGHEST
:
261 Kind
= MipsMCExpr::MEK_HIGHEST
;
263 case MipsII::MO_HIGHER
:
264 Kind
= MipsMCExpr::MEK_HIGHER
;
266 case MipsII::MO_ABS_HI
:
267 Kind
= MipsMCExpr::MEK_HI
;
269 case MipsII::MO_ABS_LO
:
270 Kind
= MipsMCExpr::MEK_LO
;
273 report_fatal_error("Unexpected flags for lowerLongBranchADDiu");
276 // Lower two register operands.
277 for (unsigned I
= 0, E
= 2; I
!= E
; ++I
) {
278 const MachineOperand
&MO
= MI
->getOperand(I
);
279 OutMI
.addOperand(LowerOperand(MO
));
282 if (MI
->getNumOperands() == 3) {
283 // Lower register operand.
285 MCSymbolRefExpr::create(MI
->getOperand(2).getMBB()->getSymbol(), *Ctx
);
286 const MipsMCExpr
*MipsExpr
= MipsMCExpr::create(Kind
, Expr
, *Ctx
);
287 OutMI
.addOperand(MCOperand::createExpr(MipsExpr
));
288 } else if (MI
->getNumOperands() == 4) {
289 // Create %lo($tgt-$baltgt) or %hi($tgt-$baltgt).
290 OutMI
.addOperand(createSub(MI
->getOperand(2).getMBB(),
291 MI
->getOperand(3).getMBB(), Kind
));
295 bool MipsMCInstLower::lowerLongBranch(const MachineInstr
*MI
,
296 MCInst
&OutMI
) const {
297 switch (MI
->getOpcode()) {
300 case Mips::LONG_BRANCH_LUi
:
301 lowerLongBranchLUi(MI
, OutMI
);
303 case Mips::LONG_BRANCH_ADDiu
:
304 lowerLongBranchADDiu(MI
, OutMI
, Mips::ADDiu
);
306 case Mips::LONG_BRANCH_DADDiu
:
307 lowerLongBranchADDiu(MI
, OutMI
, Mips::DADDiu
);
312 void MipsMCInstLower::Lower(const MachineInstr
*MI
, MCInst
&OutMI
) const {
313 if (lowerLongBranch(MI
, OutMI
))
316 OutMI
.setOpcode(MI
->getOpcode());
318 for (unsigned i
= 0, e
= MI
->getNumOperands(); i
!= e
; ++i
) {
319 const MachineOperand
&MO
= MI
->getOperand(i
);
320 MCOperand MCOp
= LowerOperand(MO
);
323 OutMI
.addOperand(MCOp
);