blob: 3cdb83f6527add61efea90ef9e2fbafd2452fdb3 [file] [log] [blame]
Chris Lattnerb16f72e2009-09-02 17:35:12 +00001//===-- X86MCInstLower.cpp - Convert X86 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 X86 MachineInstrs to their corresponding
11// MCInst records.
12//
13//===----------------------------------------------------------------------===//
14
15
16#include "X86ATTAsmPrinter.h"
17#include "X86MCAsmInfo.h"
18#include "llvm/MC/MCContext.h"
19#include "llvm/MC/MCExpr.h"
20#include "llvm/MC/MCInst.h"
21#include "llvm/MC/MCStreamer.h"
22#include "llvm/Support/FormattedStream.h"
23#include "llvm/Support/Mangler.h"
24#include "llvm/ADT/SmallString.h"
Chris Lattnerb16f72e2009-09-02 17:35:12 +000025using namespace llvm;
26
27MCSymbol *X86ATTAsmPrinter::GetPICBaseSymbol() {
28 // FIXME: the actual label generated doesn't matter here! Just mangle in
29 // something unique (the function number) with Private prefix.
Chris Lattnerb8f1df32009-09-02 17:37:38 +000030 SmallString<60> Name;
Chris Lattnerb16f72e2009-09-02 17:35:12 +000031
32 if (Subtarget->isTargetDarwin()) {
Chris Lattnerb8f1df32009-09-02 17:37:38 +000033 raw_svector_ostream(Name) << 'L' << getFunctionNumber() << "$pb";
Chris Lattnerb16f72e2009-09-02 17:35:12 +000034 } else {
35 assert(Subtarget->isTargetELF() && "Don't know how to print PIC label!");
Chris Lattnerb8f1df32009-09-02 17:37:38 +000036 raw_svector_ostream(Name) << ".Lllvm$" << getFunctionNumber()<<".$piclabel";
37 }
Chris Lattner86216492009-09-03 03:54:02 +000038 return OutContext.GetOrCreateSymbol(Name.str());
Chris Lattnerb16f72e2009-09-02 17:35:12 +000039}
40
41
Chris Lattnerb16f72e2009-09-02 17:35:12 +000042/// LowerGlobalAddressOperand - Lower an MO_GlobalAddress operand to an
43/// MCOperand.
Chris Lattner3dccf612009-09-03 05:06:07 +000044MCSymbol *X86ATTAsmPrinter::GetGlobalAddressSymbol(const MachineOperand &MO) {
Chris Lattnerb16f72e2009-09-02 17:35:12 +000045 const GlobalValue *GV = MO.getGlobal();
46
Chris Lattner2eaccff2009-09-11 05:58:44 +000047 bool isImplicitlyPrivate = false;
48 if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB ||
49 MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
50 MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE ||
51 MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
52 isImplicitlyPrivate = true;
Chris Lattnerb16f72e2009-09-02 17:35:12 +000053
Chris Lattner2eaccff2009-09-11 05:58:44 +000054 SmallString<128> Name;
55 Mang->getNameWithPrefix(Name, GV, isImplicitlyPrivate);
56
Chris Lattnerb16f72e2009-09-02 17:35:12 +000057 if (Subtarget->isTargetCygMing())
58 DecorateCygMingName(Name, GV);
59
Chris Lattnerb16f72e2009-09-02 17:35:12 +000060 switch (MO.getTargetFlags()) {
Chris Lattner3dccf612009-09-03 05:06:07 +000061 default: llvm_unreachable("Unknown target flag on GV operand");
62 case X86II::MO_NO_FLAG: // No flag.
63 case X86II::MO_GOT_ABSOLUTE_ADDRESS: // Doesn't modify symbol name.
64 case X86II::MO_PIC_BASE_OFFSET: // Doesn't modify symbol name.
65 break;
Chris Lattner2eaccff2009-09-11 05:58:44 +000066 case X86II::MO_DLLIMPORT: {
Chris Lattner3dccf612009-09-03 05:06:07 +000067 // Handle dllimport linkage.
Chris Lattner2eaccff2009-09-11 05:58:44 +000068 const char *Prefix = "__imp_";
69 Name.insert(Name.begin(), Prefix, Prefix+strlen(Prefix));
Chris Lattner3dccf612009-09-03 05:06:07 +000070 break;
Chris Lattner2eaccff2009-09-11 05:58:44 +000071 }
Chris Lattner3dccf612009-09-03 05:06:07 +000072 case X86II::MO_DARWIN_NONLAZY:
Chris Lattnerd17abca2009-09-11 06:59:18 +000073 case X86II::MO_DARWIN_NONLAZY_PIC_BASE: {
Chris Lattner2eaccff2009-09-11 05:58:44 +000074 Name += "$non_lazy_ptr";
Chris Lattnerd17abca2009-09-11 06:59:18 +000075 MCSymbol *Sym = OutContext.GetOrCreateSymbol(Name.str());
76 MCSymbol *&StubSym = GVStubs[Sym];
77 if (StubSym == 0) {
78 Name.clear();
79 Mang->getNameWithPrefix(Name, GV, false);
80 StubSym = OutContext.GetOrCreateSymbol(Name.str());
81 }
82 return Sym;
83
84 }
Chris Lattner67e71742009-09-11 07:03:20 +000085 case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: {
Chris Lattner2eaccff2009-09-11 05:58:44 +000086 Name += "$non_lazy_ptr";
Chris Lattner67e71742009-09-11 07:03:20 +000087 MCSymbol *Sym = OutContext.GetOrCreateSymbol(Name.str());
88 MCSymbol *&StubSym = HiddenGVStubs[Sym];
89 if (StubSym == 0) {
90 Name.clear();
91 Mang->getNameWithPrefix(Name, GV, false);
92 StubSym = OutContext.GetOrCreateSymbol(Name.str());
93 }
Chris Lattner3dccf612009-09-03 05:06:07 +000094 break;
Chris Lattner67e71742009-09-11 07:03:20 +000095 }
Chris Lattner25c61742009-09-11 06:36:33 +000096 case X86II::MO_DARWIN_STUB: {
Chris Lattner2eaccff2009-09-11 05:58:44 +000097 Name += "$stub";
Chris Lattner25c61742009-09-11 06:36:33 +000098 MCSymbol *Sym = OutContext.GetOrCreateSymbol(Name.str());
Chris Lattnerd17abca2009-09-11 06:59:18 +000099 MCSymbol *&StubSym = FnStubs[Sym];
100 if (StubSym == 0) {
101 Name.clear();
102 Mang->getNameWithPrefix(Name, GV, false);
103 StubSym = OutContext.GetOrCreateSymbol(Name.str());
104 }
Chris Lattner25c61742009-09-11 06:36:33 +0000105 return Sym;
106 }
Chris Lattner3dccf612009-09-03 05:06:07 +0000107 // FIXME: These probably should be a modifier on the symbol or something??
108 case X86II::MO_TLSGD: Name += "@TLSGD"; break;
109 case X86II::MO_GOTTPOFF: Name += "@GOTTPOFF"; break;
110 case X86II::MO_INDNTPOFF: Name += "@INDNTPOFF"; break;
111 case X86II::MO_TPOFF: Name += "@TPOFF"; break;
112 case X86II::MO_NTPOFF: Name += "@NTPOFF"; break;
113 case X86II::MO_GOTPCREL: Name += "@GOTPCREL"; break;
114 case X86II::MO_GOT: Name += "@GOT"; break;
115 case X86II::MO_GOTOFF: Name += "@GOTOFF"; break;
116 case X86II::MO_PLT: Name += "@PLT"; break;
Chris Lattnerb16f72e2009-09-02 17:35:12 +0000117 }
118
Chris Lattner2eaccff2009-09-11 05:58:44 +0000119 return OutContext.GetOrCreateSymbol(Name.str());
Chris Lattnerb16f72e2009-09-02 17:35:12 +0000120}
121
Chris Lattner5750f442009-09-03 04:56:20 +0000122MCSymbol *X86ATTAsmPrinter::GetExternalSymbolSymbol(const MachineOperand &MO) {
Chris Lattner2eaccff2009-09-11 05:58:44 +0000123 SmallString<128> Name;
Chris Lattner2fe752e2009-09-11 04:36:43 +0000124 Name += MAI->getGlobalPrefix();
125 Name += MO.getSymbolName();
Chris Lattner50470b52009-09-09 00:10:14 +0000126
127 switch (MO.getTargetFlags()) {
128 default: llvm_unreachable("Unknown target flag on GV operand");
129 case X86II::MO_NO_FLAG: // No flag.
130 case X86II::MO_GOT_ABSOLUTE_ADDRESS: // Doesn't modify symbol name.
131 case X86II::MO_PIC_BASE_OFFSET: // Doesn't modify symbol name.
132 break;
Chris Lattner2fe752e2009-09-11 04:36:43 +0000133 case X86II::MO_DLLIMPORT: {
Chris Lattner50470b52009-09-09 00:10:14 +0000134 // Handle dllimport linkage.
Chris Lattner2fe752e2009-09-11 04:36:43 +0000135 const char *Prefix = "__imp_";
136 Name.insert(Name.begin(), Prefix, Prefix+strlen(Prefix));
Chris Lattner50470b52009-09-09 00:10:14 +0000137 break;
Chris Lattner2fe752e2009-09-11 04:36:43 +0000138 }
Chris Lattner25c61742009-09-11 06:36:33 +0000139 case X86II::MO_DARWIN_STUB: {
Chris Lattner2fe752e2009-09-11 04:36:43 +0000140 Name += "$stub";
Chris Lattner25c61742009-09-11 06:36:33 +0000141 MCSymbol *Sym = OutContext.GetOrCreateSymbol(Name.str());
Chris Lattnerd17abca2009-09-11 06:59:18 +0000142 MCSymbol *&StubSym = FnStubs[Sym];
143 if (StubSym == 0) {
144 Name.erase(Name.end()-5, Name.end());
145 StubSym = OutContext.GetOrCreateSymbol(Name.str());
146 }
Chris Lattner25c61742009-09-11 06:36:33 +0000147 return Sym;
148 }
149 // FIXME: These probably should be a modifier on the symbol or something??
Chris Lattner50470b52009-09-09 00:10:14 +0000150 case X86II::MO_TLSGD: Name += "@TLSGD"; break;
151 case X86II::MO_GOTTPOFF: Name += "@GOTTPOFF"; break;
152 case X86II::MO_INDNTPOFF: Name += "@INDNTPOFF"; break;
153 case X86II::MO_TPOFF: Name += "@TPOFF"; break;
154 case X86II::MO_NTPOFF: Name += "@NTPOFF"; break;
155 case X86II::MO_GOTPCREL: Name += "@GOTPCREL"; break;
156 case X86II::MO_GOT: Name += "@GOT"; break;
157 case X86II::MO_GOTOFF: Name += "@GOTOFF"; break;
158 case X86II::MO_PLT: Name += "@PLT"; break;
159 }
160
Chris Lattner2fe752e2009-09-11 04:36:43 +0000161 return OutContext.GetOrCreateSymbol(Name.str());
Chris Lattnerb16f72e2009-09-02 17:35:12 +0000162}
163
Chris Lattner5750f442009-09-03 04:56:20 +0000164MCSymbol *X86ATTAsmPrinter::GetJumpTableSymbol(const MachineOperand &MO) {
Chris Lattnerb16f72e2009-09-02 17:35:12 +0000165 SmallString<256> Name;
166 raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI"
Chris Lattner9fb70d62009-09-03 04:44:53 +0000167 << getFunctionNumber() << '_' << MO.getIndex();
Chris Lattnerb16f72e2009-09-02 17:35:12 +0000168
Chris Lattnerb16f72e2009-09-02 17:35:12 +0000169 switch (MO.getTargetFlags()) {
Chris Lattner9fb70d62009-09-03 04:44:53 +0000170 default:
171 llvm_unreachable("Unknown target flag on GV operand");
172 case X86II::MO_NO_FLAG: // No flag.
Chris Lattner9fb70d62009-09-03 04:44:53 +0000173 case X86II::MO_PIC_BASE_OFFSET:
174 case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
175 case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE:
Chris Lattner5750f442009-09-03 04:56:20 +0000176 break;
Chris Lattner420109d2009-09-08 06:25:12 +0000177 // FIXME: These probably should be a modifier on the symbol or something??
178 case X86II::MO_TLSGD: Name += "@TLSGD"; break;
179 case X86II::MO_GOTTPOFF: Name += "@GOTTPOFF"; break;
180 case X86II::MO_INDNTPOFF: Name += "@INDNTPOFF"; break;
181 case X86II::MO_TPOFF: Name += "@TPOFF"; break;
182 case X86II::MO_NTPOFF: Name += "@NTPOFF"; break;
183 case X86II::MO_GOTPCREL: Name += "@GOTPCREL"; break;
184 case X86II::MO_GOT: Name += "@GOT"; break;
185 case X86II::MO_GOTOFF: Name += "@GOTOFF"; break;
186 case X86II::MO_PLT: Name += "@PLT"; break;
Chris Lattnerb16f72e2009-09-02 17:35:12 +0000187 }
188
189 // Create a symbol for the name.
Chris Lattner5750f442009-09-03 04:56:20 +0000190 return OutContext.GetOrCreateSymbol(Name.str());
Chris Lattnerb16f72e2009-09-02 17:35:12 +0000191}
192
193
Chris Lattner5750f442009-09-03 04:56:20 +0000194MCSymbol *X86ATTAsmPrinter::
195GetConstantPoolIndexSymbol(const MachineOperand &MO) {
Chris Lattner9fb70d62009-09-03 04:44:53 +0000196 SmallString<256> Name;
197 raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "CPI"
198 << getFunctionNumber() << '_' << MO.getIndex();
199
Chris Lattner9fb70d62009-09-03 04:44:53 +0000200 switch (MO.getTargetFlags()) {
201 default:
202 llvm_unreachable("Unknown target flag on GV operand");
203 case X86II::MO_NO_FLAG: // No flag.
Chris Lattner9fb70d62009-09-03 04:44:53 +0000204 case X86II::MO_PIC_BASE_OFFSET:
205 case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
206 case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE:
Chris Lattner9fb70d62009-09-03 04:44:53 +0000207 break;
Chris Lattner420109d2009-09-08 06:25:12 +0000208 // FIXME: These probably should be a modifier on the symbol or something??
209 case X86II::MO_TLSGD: Name += "@TLSGD"; break;
210 case X86II::MO_GOTTPOFF: Name += "@GOTTPOFF"; break;
211 case X86II::MO_INDNTPOFF: Name += "@INDNTPOFF"; break;
212 case X86II::MO_TPOFF: Name += "@TPOFF"; break;
213 case X86II::MO_NTPOFF: Name += "@NTPOFF"; break;
214 case X86II::MO_GOTPCREL: Name += "@GOTPCREL"; break;
215 case X86II::MO_GOT: Name += "@GOT"; break;
216 case X86II::MO_GOTOFF: Name += "@GOTOFF"; break;
217 case X86II::MO_PLT: Name += "@PLT"; break;
Chris Lattner9fb70d62009-09-03 04:44:53 +0000218 }
219
220 // Create a symbol for the name.
Chris Lattner5750f442009-09-03 04:56:20 +0000221 return OutContext.GetOrCreateSymbol(Name.str());
222}
223
224MCOperand X86ATTAsmPrinter::LowerSymbolOperand(const MachineOperand &MO,
225 MCSymbol *Sym) {
Chris Lattner02c96d72009-09-03 07:30:56 +0000226 // FIXME: We would like an efficient form for this, so we don't have to do a
227 // lot of extra uniquing.
228 const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, OutContext);
229
Chris Lattner5750f442009-09-03 04:56:20 +0000230 switch (MO.getTargetFlags()) {
Chris Lattner3dccf612009-09-03 05:06:07 +0000231 default: llvm_unreachable("Unknown target flag on GV operand");
232 case X86II::MO_NO_FLAG: // No flag.
233
234 // These affect the name of the symbol, not any suffix.
235 case X86II::MO_DARWIN_NONLAZY:
Chris Lattner3dccf612009-09-03 05:06:07 +0000236 case X86II::MO_DLLIMPORT:
237 case X86II::MO_DARWIN_STUB:
238 case X86II::MO_TLSGD:
239 case X86II::MO_GOTTPOFF:
240 case X86II::MO_INDNTPOFF:
241 case X86II::MO_TPOFF:
242 case X86II::MO_NTPOFF:
243 case X86II::MO_GOTPCREL:
244 case X86II::MO_GOT:
245 case X86II::MO_GOTOFF:
246 case X86II::MO_PLT:
247 break;
248 case X86II::MO_PIC_BASE_OFFSET:
249 case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
250 case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE:
251 // Subtract the pic base.
Chris Lattner02c96d72009-09-03 07:30:56 +0000252 Expr = MCBinaryExpr::CreateSub(Expr,
253 MCSymbolRefExpr::Create(GetPICBaseSymbol(),
254 OutContext),
255 OutContext);
Chris Lattner3dccf612009-09-03 05:06:07 +0000256 break;
Chris Lattner02c96d72009-09-03 07:30:56 +0000257 case X86II::MO_GOT_ABSOLUTE_ADDRESS: {
258 // For this, we want to print something like:
259 // MYSYMBOL + (. - PICBASE)
260 // However, we can't generate a ".", so just emit a new label here and refer
261 // to it. We know that this operand flag occurs at most once per function.
262 SmallString<64> Name;
263 raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "picbaseref"
264 << getFunctionNumber();
265 MCSymbol *DotSym = OutContext.GetOrCreateSymbol(Name.str());
266 OutStreamer.EmitLabel(DotSym);
267
268 const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext);
269 const MCExpr *PICBase = MCSymbolRefExpr::Create(GetPICBaseSymbol(),
270 OutContext);
271 DotExpr = MCBinaryExpr::CreateSub(DotExpr, PICBase, OutContext);
272 Expr = MCBinaryExpr::CreateAdd(Expr, DotExpr, OutContext);
Chris Lattner3dccf612009-09-03 05:06:07 +0000273 break;
Chris Lattner5750f442009-09-03 04:56:20 +0000274 }
Chris Lattner02c96d72009-09-03 07:30:56 +0000275 }
Chris Lattner5750f442009-09-03 04:56:20 +0000276
Chris Lattnerb55972f2009-09-03 07:36:42 +0000277 if (!MO.isJTI() && MO.getOffset())
Chris Lattner3dccf612009-09-03 05:06:07 +0000278 Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(MO.getOffset(),
279 OutContext),
280 OutContext);
Chris Lattner9fb70d62009-09-03 04:44:53 +0000281 return MCOperand::CreateExpr(Expr);
282}
283
Chris Lattnere6fe9452009-09-11 04:28:13 +0000284
285
286static void lower_subreg32(MCInst *MI, unsigned OpNo) {
287 // Convert registers in the addr mode according to subreg32.
288 unsigned Reg = MI->getOperand(OpNo).getReg();
289 if (Reg != 0)
290 MI->getOperand(OpNo).setReg(getX86SubSuperRegister(Reg, MVT::i32));
291}
292
293static void lower_lea64_32mem(MCInst *MI, unsigned OpNo) {
294 // Convert registers in the addr mode according to subreg64.
295 for (unsigned i = 0; i != 4; ++i) {
296 if (!MI->getOperand(OpNo+i).isReg()) continue;
297
298 unsigned Reg = MI->getOperand(OpNo+i).getReg();
299 if (Reg == 0) continue;
300
301 MI->getOperand(OpNo+i).setReg(getX86SubSuperRegister(Reg, MVT::i64));
302 }
303}
304
305
Chris Lattnerb16f72e2009-09-02 17:35:12 +0000306void X86ATTAsmPrinter::
307printInstructionThroughMCStreamer(const MachineInstr *MI) {
Chris Lattnerb16f72e2009-09-02 17:35:12 +0000308 MCInst TmpInst;
Chris Lattnerb16f72e2009-09-02 17:35:12 +0000309 switch (MI->getOpcode()) {
310 case TargetInstrInfo::DBG_LABEL:
311 case TargetInstrInfo::EH_LABEL:
312 case TargetInstrInfo::GC_LABEL:
313 printLabel(MI);
314 return;
315 case TargetInstrInfo::INLINEASM:
316 O << '\t';
317 printInlineAsm(MI);
318 return;
319 case TargetInstrInfo::IMPLICIT_DEF:
320 printImplicitDef(MI);
321 return;
322 case X86::MOVPC32r: {
323 // This is a pseudo op for a two instruction sequence with a label, which
324 // looks like:
325 // call "L1$pb"
326 // "L1$pb":
327 // popl %esi
328
329 // Emit the call.
330 MCSymbol *PICBase = GetPICBaseSymbol();
331 TmpInst.setOpcode(X86::CALLpcrel32);
332 // FIXME: We would like an efficient form for this, so we don't have to do a
333 // lot of extra uniquing.
334 TmpInst.addOperand(MCOperand::CreateExpr(MCSymbolRefExpr::Create(PICBase,
335 OutContext)));
336 printInstruction(&TmpInst);
Chris Lattner2fdf82d2009-09-11 05:59:55 +0000337 O << '\n';
Chris Lattnerb16f72e2009-09-02 17:35:12 +0000338
339 // Emit the label.
340 OutStreamer.EmitLabel(PICBase);
341
342 // popl $reg
343 TmpInst.setOpcode(X86::POP32r);
344 TmpInst.getOperand(0) = MCOperand::CreateReg(MI->getOperand(0).getReg());
345 printInstruction(&TmpInst);
346 return;
347 }
348 }
349
350 TmpInst.setOpcode(MI->getOpcode());
351
352 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
353 const MachineOperand &MO = MI->getOperand(i);
354
355 MCOperand MCOp;
356 switch (MO.getType()) {
357 default:
358 O.flush();
359 errs() << "Cannot lower operand #" << i << " of :" << *MI;
360 llvm_unreachable("Unimp");
Chris Lattnerb16f72e2009-09-02 17:35:12 +0000361 case MachineOperand::MO_Register:
362 MCOp = MCOperand::CreateReg(MO.getReg());
363 break;
364 case MachineOperand::MO_Immediate:
365 MCOp = MCOperand::CreateImm(MO.getImm());
366 break;
367 case MachineOperand::MO_MachineBasicBlock:
368 MCOp = MCOperand::CreateMBBLabel(getFunctionNumber(),
369 MO.getMBB()->getNumber());
370 break;
371 case MachineOperand::MO_GlobalAddress:
Chris Lattner3dccf612009-09-03 05:06:07 +0000372 MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO));
Chris Lattnerb16f72e2009-09-02 17:35:12 +0000373 break;
374 case MachineOperand::MO_ExternalSymbol:
Chris Lattner5750f442009-09-03 04:56:20 +0000375 MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO));
Chris Lattnerb16f72e2009-09-02 17:35:12 +0000376 break;
Chris Lattner9fb70d62009-09-03 04:44:53 +0000377 case MachineOperand::MO_JumpTableIndex:
Chris Lattner5750f442009-09-03 04:56:20 +0000378 MCOp = LowerSymbolOperand(MO, GetJumpTableSymbol(MO));
Chris Lattner9fb70d62009-09-03 04:44:53 +0000379 break;
380 case MachineOperand::MO_ConstantPoolIndex:
Chris Lattner5750f442009-09-03 04:56:20 +0000381 MCOp = LowerSymbolOperand(MO, GetConstantPoolIndexSymbol(MO));
Chris Lattner9fb70d62009-09-03 04:44:53 +0000382 break;
Chris Lattnerb16f72e2009-09-02 17:35:12 +0000383 }
384
385 TmpInst.addOperand(MCOp);
386 }
387
Chris Lattnere6fe9452009-09-11 04:28:13 +0000388 // Handle a few special cases to eliminate operand modifiers.
Chris Lattnerb16f72e2009-09-02 17:35:12 +0000389 switch (TmpInst.getOpcode()) {
Chris Lattnere6fe9452009-09-11 04:28:13 +0000390 case X86::LEA64_32r: // Handle 'subreg rewriting' for the lea64_32mem operand.
Chris Lattnerb16f72e2009-09-02 17:35:12 +0000391 lower_lea64_32mem(&TmpInst, 1);
392 break;
Chris Lattnera2683c92009-09-08 05:49:25 +0000393 case X86::MOV16r0:
394 TmpInst.setOpcode(X86::MOV32r0);
395 lower_subreg32(&TmpInst, 0);
396 break;
Chris Lattner06418122009-09-08 06:03:07 +0000397 case X86::MOVZX16rr8:
398 TmpInst.setOpcode(X86::MOVZX32rr8);
399 lower_subreg32(&TmpInst, 0);
400 break;
401 case X86::MOVZX16rm8:
402 TmpInst.setOpcode(X86::MOVZX32rm8);
403 lower_subreg32(&TmpInst, 0);
404 break;
Chris Lattnerc638baf2009-09-08 06:19:15 +0000405 case X86::MOVSX16rr8:
406 TmpInst.setOpcode(X86::MOVSX32rr8);
407 lower_subreg32(&TmpInst, 0);
408 break;
409 case X86::MOVSX16rm8:
410 TmpInst.setOpcode(X86::MOVSX32rm8);
411 lower_subreg32(&TmpInst, 0);
412 break;
413 case X86::MOVZX64rr32:
414 TmpInst.setOpcode(X86::MOV32rr);
415 lower_subreg32(&TmpInst, 0);
416 break;
417 case X86::MOVZX64rm32:
418 TmpInst.setOpcode(X86::MOV32rm);
419 lower_subreg32(&TmpInst, 0);
420 break;
421 case X86::MOV64ri64i32:
422 TmpInst.setOpcode(X86::MOV32ri);
423 lower_subreg32(&TmpInst, 0);
424 break;
425 case X86::MOVZX64rr8:
426 TmpInst.setOpcode(X86::MOVZX32rr8);
427 lower_subreg32(&TmpInst, 0);
428 break;
429 case X86::MOVZX64rm8:
430 TmpInst.setOpcode(X86::MOVZX32rm8);
431 lower_subreg32(&TmpInst, 0);
432 break;
433 case X86::MOVZX64rr16:
434 TmpInst.setOpcode(X86::MOVZX32rr16);
435 lower_subreg32(&TmpInst, 0);
436 break;
437 case X86::MOVZX64rm16:
438 TmpInst.setOpcode(X86::MOVZX32rm16);
439 lower_subreg32(&TmpInst, 0);
440 break;
Chris Lattnerb16f72e2009-09-02 17:35:12 +0000441 }
442
443 printInstruction(&TmpInst);
444}