blob: 03c382594f69cd36f184daf53a374b33f47175ea [file] [log] [blame]
Chris Lattner9cf0eb52009-10-19 20:21:05 +00001//===-- ARMMCInstLower.cpp - Convert ARM MachineInstr to an MCInst --------===//
2//
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 ARM MachineInstrs to their corresponding
11// MCInst records.
12//
13//===----------------------------------------------------------------------===//
14
Jim Grosbach1685caf2010-09-14 20:41:27 +000015#include "ARM.h"
Chris Lattner9cf0eb52009-10-19 20:21:05 +000016#include "ARMMCInstLower.h"
Chris Lattner9cf0eb52009-10-19 20:21:05 +000017//#include "llvm/CodeGen/MachineModuleInfoImpls.h"
Chris Lattner96bc2172009-10-20 00:52:47 +000018#include "llvm/CodeGen/AsmPrinter.h"
Jim Grosbach26edbcb2010-09-15 18:47:08 +000019#include "llvm/Constants.h"
Chris Lattner96bc2172009-10-20 00:52:47 +000020#include "llvm/CodeGen/MachineBasicBlock.h"
Chris Lattner6f997762009-10-19 21:53:00 +000021#include "llvm/MC/MCAsmInfo.h"
22#include "llvm/MC/MCContext.h"
23#include "llvm/MC/MCExpr.h"
Chris Lattner9cf0eb52009-10-19 20:21:05 +000024#include "llvm/MC/MCInst.h"
25//#include "llvm/MC/MCStreamer.h"
Chris Lattnerd62f1b42010-03-12 21:19:23 +000026#include "llvm/Target/Mangler.h"
Chris Lattner6f997762009-10-19 21:53:00 +000027#include "llvm/Support/raw_ostream.h"
Chris Lattner6f997762009-10-19 21:53:00 +000028#include "llvm/ADT/SmallString.h"
Chris Lattner9cf0eb52009-10-19 20:21:05 +000029using namespace llvm;
30
31
32#if 0
33const ARMSubtarget &ARMMCInstLower::getSubtarget() const {
34 return AsmPrinter.getSubtarget();
35}
36
37MachineModuleInfoMachO &ARMMCInstLower::getMachOMMI() const {
38 assert(getSubtarget().isTargetDarwin() &&"Can only get MachO info on darwin");
Jim Grosbachfc16a892010-09-13 18:25:42 +000039 return AsmPrinter.MMI->getObjFileInfo<MachineModuleInfoMachO>();
Chris Lattner9cf0eb52009-10-19 20:21:05 +000040}
41#endif
42
Jim Grosbachc686e332010-09-17 18:25:25 +000043MCSymbol *ARMMCInstLower::GetGlobalAddressSymbol(const GlobalValue *GV) const {
44 return Printer.Mang->getSymbol(GV);
45}
46
47const MCSymbolRefExpr *ARMMCInstLower::
48GetSymbolRef(const MachineOperand &MO) const {
49 assert(MO.isGlobal() && "Isn't a global address reference?");
Chris Lattner6f997762009-10-19 21:53:00 +000050 // FIXME: HANDLE PLT references how??
Jim Grosbachc686e332010-09-17 18:25:25 +000051
52 const MCSymbolRefExpr *SymRef;
53 const MCSymbol *Symbol = GetGlobalAddressSymbol(MO.getGlobal());
54
Chris Lattner6f997762009-10-19 21:53:00 +000055 switch (MO.getTargetFlags()) {
56 default: assert(0 && "Unknown target flag on GV operand");
Jim Grosbachc686e332010-09-17 18:25:25 +000057 case 0:
58 SymRef = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, Ctx);
59 break;
60 case ARMII::MO_LO16:
61 SymRef = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_LO16, Ctx);
62 break;
63 case ARMII::MO_HI16:
64 SymRef = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_HI16, Ctx);
65 break;
Chris Lattner6f997762009-10-19 21:53:00 +000066 }
Jim Grosbachfc16a892010-09-13 18:25:42 +000067
Jim Grosbachc686e332010-09-17 18:25:25 +000068 return SymRef;
Chris Lattner6f997762009-10-19 21:53:00 +000069}
70
Chris Lattner292df8e2009-10-20 00:56:16 +000071MCSymbol *ARMMCInstLower::
72GetExternalSymbolSymbol(const MachineOperand &MO) const {
Chris Lattner292df8e2009-10-20 00:56:16 +000073 // FIXME: HANDLE PLT references how??
Jim Grosbachc686e332010-09-17 18:25:25 +000074 // FIXME: This probably needs to be merged with the above SymbolRef stuff
75 // to handle :lower16: and :upper16: (?)
Chris Lattner292df8e2009-10-20 00:56:16 +000076 switch (MO.getTargetFlags()) {
77 default: assert(0 && "Unknown target flag on GV operand");
78 case 0: break;
79 }
Jim Grosbachfc16a892010-09-13 18:25:42 +000080
Chris Lattner9ab19f22010-01-16 01:40:07 +000081 return Printer.GetExternalSymbolSymbol(MO.getSymbolName());
Chris Lattner292df8e2009-10-20 00:56:16 +000082}
83
84
Chris Lattner6f997762009-10-19 21:53:00 +000085
86MCSymbol *ARMMCInstLower::
87GetJumpTableSymbol(const MachineOperand &MO) const {
88 SmallString<256> Name;
Chris Lattner96bc2172009-10-20 00:52:47 +000089 raw_svector_ostream(Name) << Printer.MAI->getPrivateGlobalPrefix() << "JTI"
90 << Printer.getFunctionNumber() << '_' << MO.getIndex();
Jim Grosbachfc16a892010-09-13 18:25:42 +000091
Chris Lattner6f997762009-10-19 21:53:00 +000092#if 0
93 switch (MO.getTargetFlags()) {
94 default: llvm_unreachable("Unknown target flag on GV operand");
95 }
96#endif
Jim Grosbachfc16a892010-09-13 18:25:42 +000097
Chris Lattner6f997762009-10-19 21:53:00 +000098 // Create a symbol for the name.
Chris Lattner9b97a732010-03-30 18:10:53 +000099 return Ctx.GetOrCreateSymbol(Name.str());
Chris Lattner6f997762009-10-19 21:53:00 +0000100}
101
102MCSymbol *ARMMCInstLower::
103GetConstantPoolIndexSymbol(const MachineOperand &MO) const {
104 SmallString<256> Name;
Chris Lattner96bc2172009-10-20 00:52:47 +0000105 raw_svector_ostream(Name) << Printer.MAI->getPrivateGlobalPrefix() << "CPI"
106 << Printer.getFunctionNumber() << '_' << MO.getIndex();
Jim Grosbachfc16a892010-09-13 18:25:42 +0000107
Chris Lattner6f997762009-10-19 21:53:00 +0000108#if 0
109 switch (MO.getTargetFlags()) {
110 default: llvm_unreachable("Unknown target flag on GV operand");
111 }
112#endif
Jim Grosbachfc16a892010-09-13 18:25:42 +0000113
Chris Lattner6f997762009-10-19 21:53:00 +0000114 // Create a symbol for the name.
Chris Lattner9b97a732010-03-30 18:10:53 +0000115 return Ctx.GetOrCreateSymbol(Name.str());
Chris Lattner6f997762009-10-19 21:53:00 +0000116}
Jim Grosbachfc16a892010-09-13 18:25:42 +0000117
Chris Lattner6f997762009-10-19 21:53:00 +0000118MCOperand ARMMCInstLower::
119LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const {
120 // FIXME: We would like an efficient form for this, so we don't have to do a
121 // lot of extra uniquing.
122 const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, Ctx);
Jim Grosbachfc16a892010-09-13 18:25:42 +0000123
Chris Lattner6f997762009-10-19 21:53:00 +0000124#if 0
125 switch (MO.getTargetFlags()) {
126 default: llvm_unreachable("Unknown target flag on GV operand");
127 }
128#endif
Jim Grosbachfc16a892010-09-13 18:25:42 +0000129
Chris Lattner6f997762009-10-19 21:53:00 +0000130 if (!MO.isJTI() && MO.getOffset())
131 Expr = MCBinaryExpr::CreateAdd(Expr,
132 MCConstantExpr::Create(MO.getOffset(), Ctx),
133 Ctx);
134 return MCOperand::CreateExpr(Expr);
135}
136
Jim Grosbachc686e332010-09-17 18:25:25 +0000137MCOperand ARMMCInstLower::
138LowerSymbolRefOperand(const MachineOperand &MO,
139 const MCSymbolRefExpr *Sym) const {
140 const MCExpr *Expr = Sym;
141 if (!MO.isJTI() && MO.getOffset())
142 Expr = MCBinaryExpr::CreateAdd(Expr,
143 MCConstantExpr::Create(MO.getOffset(), Ctx),
144 Ctx);
145 return MCOperand::CreateExpr(Expr);
146}
147
Chris Lattner9cf0eb52009-10-19 20:21:05 +0000148
149void ARMMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
150 OutMI.setOpcode(MI->getOpcode());
Jim Grosbachfc16a892010-09-13 18:25:42 +0000151
Chris Lattner9cf0eb52009-10-19 20:21:05 +0000152 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
153 const MachineOperand &MO = MI->getOperand(i);
Jim Grosbachfc16a892010-09-13 18:25:42 +0000154
Chris Lattner9cf0eb52009-10-19 20:21:05 +0000155 MCOperand MCOp;
156 switch (MO.getType()) {
157 default:
158 MI->dump();
159 assert(0 && "unknown operand type");
160 case MachineOperand::MO_Register:
Jim Grosbach1685caf2010-09-14 20:41:27 +0000161 // Ignore all non-CPSR implicit register operands.
162 if (MO.isImplicit() && MO.getReg() != ARM::CPSR) continue;
Anton Korobeynikove8ea0112009-11-07 15:20:32 +0000163 assert(!MO.getSubReg() && "Subregs should be eliminated!");
Chris Lattner9cf0eb52009-10-19 20:21:05 +0000164 MCOp = MCOperand::CreateReg(MO.getReg());
165 break;
166 case MachineOperand::MO_Immediate:
167 MCOp = MCOperand::CreateImm(MO.getImm());
168 break;
Chris Lattner9cf0eb52009-10-19 20:21:05 +0000169 case MachineOperand::MO_MachineBasicBlock:
170 MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
Chris Lattner1b2eb0e2010-03-13 21:04:28 +0000171 MO.getMBB()->getSymbol(), Ctx));
Chris Lattner9cf0eb52009-10-19 20:21:05 +0000172 break;
173 case MachineOperand::MO_GlobalAddress:
Jim Grosbachc686e332010-09-17 18:25:25 +0000174 MCOp = LowerSymbolRefOperand(MO, GetSymbolRef(MO));
Chris Lattner9cf0eb52009-10-19 20:21:05 +0000175 break;
176 case MachineOperand::MO_ExternalSymbol:
177 MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO));
178 break;
179 case MachineOperand::MO_JumpTableIndex:
180 MCOp = LowerSymbolOperand(MO, GetJumpTableSymbol(MO));
181 break;
182 case MachineOperand::MO_ConstantPoolIndex:
183 MCOp = LowerSymbolOperand(MO, GetConstantPoolIndexSymbol(MO));
184 break;
Bob Wilsonddb16df2009-10-30 05:45:42 +0000185 case MachineOperand::MO_BlockAddress:
186 MCOp = LowerSymbolOperand(MO, Printer.GetBlockAddressSymbol(
187 MO.getBlockAddress()));
188 break;
Jim Grosbach26edbcb2010-09-15 18:47:08 +0000189 case MachineOperand::MO_FPImmediate:
Jim Grosbach1d51c412010-09-16 17:37:30 +0000190 APFloat Val = MO.getFPImm()->getValueAPF();
191 bool ignored;
192 Val.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &ignored);
193 MCOp = MCOperand::CreateFPImm(Val.convertToDouble());
Jim Grosbach26edbcb2010-09-15 18:47:08 +0000194 break;
Chris Lattner9cf0eb52009-10-19 20:21:05 +0000195 }
Jim Grosbachfc16a892010-09-13 18:25:42 +0000196
Chris Lattner9cf0eb52009-10-19 20:21:05 +0000197 OutMI.addOperand(MCOp);
198 }
Jim Grosbachfc16a892010-09-13 18:25:42 +0000199
Chris Lattner9cf0eb52009-10-19 20:21:05 +0000200}