llvm.org GIT mirror llvm / 8fea32f
split MachineInstr -> MCInst lowering into its own class (not being embedded into X86ATTAsmPrinter). This still depends heavily on X86ATTAsmPrinter, but this is a step in the right direction. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@81627 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 11 years ago
3 changed file(s) with 227 addition(s) and 163 deletion(s). Raw diff Collapse all Expand all
4444 virtual const char *getPassName() const {
4545 return "X86 AT&T-Style Assembly Printer";
4646 }
47
48 const X86Subtarget &getSubtarget() const { return *Subtarget; }
4749
4850 void getAnalysisUsage(AnalysisUsage &AU) const {
4951 AU.setPreservesAll();
6365
6466 // New MCInst printing stuff.
6567 void printInstruction(const MCInst *MI);
66 MCSymbol *GetPICBaseSymbol();
67 MCSymbol *GetGlobalAddressSymbol(const MachineOperand &MO);
68 MCSymbol *GetExternalSymbolSymbol(const MachineOperand &MO);
69 MCSymbol *GetJumpTableSymbol(const MachineOperand &MO);
70 MCSymbol *GetConstantPoolIndexSymbol(const MachineOperand &MO);
71 MCOperand LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym);
7268
7369
7470 virtual void printMCInst(const MCInst *MI) { printInstruction(MI); }
1111 //
1212 //===----------------------------------------------------------------------===//
1313
14
14 #include "X86MCInstLower.h"
1515 #include "X86ATTAsmPrinter.h"
1616 #include "X86MCAsmInfo.h"
1717 #include "llvm/MC/MCContext.h"
2323 #include "llvm/ADT/SmallString.h"
2424 using namespace llvm;
2525
26 MCSymbol *X86ATTAsmPrinter::GetPICBaseSymbol() {
26
27 const X86Subtarget &X86MCInstLower::getSubtarget() const {
28 return AsmPrinter.getSubtarget();
29 }
30
31
32 MCSymbol *X86MCInstLower::GetPICBaseSymbol() const {
2733 // FIXME: the actual label generated doesn't matter here! Just mangle in
2834 // something unique (the function number) with Private prefix.
2935 SmallString<60> Name;
3036
31 if (Subtarget->isTargetDarwin()) {
32 raw_svector_ostream(Name) << 'L' << getFunctionNumber() << "$pb";
37 if (getSubtarget().isTargetDarwin()) {
38 raw_svector_ostream(Name) << 'L' << AsmPrinter.getFunctionNumber() << "$pb";
3339 } else {
34 assert(Subtarget->isTargetELF() && "Don't know how to print PIC label!");
35 raw_svector_ostream(Name) << ".Lllvm$" << getFunctionNumber()<<".$piclabel";
36 }
37 return OutContext.GetOrCreateSymbol(Name.str());
40 assert(getSubtarget().isTargetELF() && "Don't know how to print PIC label!");
41 raw_svector_ostream(Name) << ".Lllvm$" << AsmPrinter.getFunctionNumber()
42 << ".$piclabel";
43 }
44 return Ctx.GetOrCreateSymbol(Name.str());
3845 }
3946
4047
4148 /// LowerGlobalAddressOperand - Lower an MO_GlobalAddress operand to an
4249 /// MCOperand.
43 MCSymbol *X86ATTAsmPrinter::GetGlobalAddressSymbol(const MachineOperand &MO) {
50 MCSymbol *X86MCInstLower::
51 GetGlobalAddressSymbol(const MachineOperand &MO) const {
4452 const GlobalValue *GV = MO.getGlobal();
4553
4654 bool isImplicitlyPrivate = false;
5361 SmallString<128> Name;
5462 Mang->getNameWithPrefix(Name, GV, isImplicitlyPrivate);
5563
56 if (Subtarget->isTargetCygMing())
57 DecorateCygMingName(Name, GV);
64 if (getSubtarget().isTargetCygMing())
65 AsmPrinter.DecorateCygMingName(Name, GV);
5866
5967 switch (MO.getTargetFlags()) {
6068 default: llvm_unreachable("Unknown target flag on GV operand");
7179 case X86II::MO_DARWIN_NONLAZY:
7280 case X86II::MO_DARWIN_NONLAZY_PIC_BASE: {
7381 Name += "$non_lazy_ptr";
74 MCSymbol *Sym = OutContext.GetOrCreateSymbol(Name.str());
75 MCSymbol *&StubSym = GVStubs[Sym];
82 MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
83 MCSymbol *&StubSym = AsmPrinter.GVStubs[Sym];
7684 if (StubSym == 0) {
7785 Name.clear();
7886 Mang->getNameWithPrefix(Name, GV, false);
79 StubSym = OutContext.GetOrCreateSymbol(Name.str());
87 StubSym = Ctx.GetOrCreateSymbol(Name.str());
8088 }
8189 return Sym;
82
8390 }
8491 case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: {
8592 Name += "$non_lazy_ptr";
86 MCSymbol *Sym = OutContext.GetOrCreateSymbol(Name.str());
87 MCSymbol *&StubSym = HiddenGVStubs[Sym];
93 MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
94 MCSymbol *&StubSym = AsmPrinter.HiddenGVStubs[Sym];
8895 if (StubSym == 0) {
8996 Name.clear();
9097 Mang->getNameWithPrefix(Name, GV, false);
91 StubSym = OutContext.GetOrCreateSymbol(Name.str());
98 StubSym = Ctx.GetOrCreateSymbol(Name.str());
9299 }
93100 return Sym;
94101 }
95102 case X86II::MO_DARWIN_STUB: {
96103 Name += "$stub";
97 MCSymbol *Sym = OutContext.GetOrCreateSymbol(Name.str());
98 MCSymbol *&StubSym = FnStubs[Sym];
104 MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
105 MCSymbol *&StubSym = AsmPrinter.FnStubs[Sym];
99106 if (StubSym == 0) {
100107 Name.clear();
101108 Mang->getNameWithPrefix(Name, GV, false);
102 StubSym = OutContext.GetOrCreateSymbol(Name.str());
109 StubSym = Ctx.GetOrCreateSymbol(Name.str());
103110 }
104111 return Sym;
105112 }
115122 case X86II::MO_PLT: Name += "@PLT"; break;
116123 }
117124
118 return OutContext.GetOrCreateSymbol(Name.str());
119 }
120
121 MCSymbol *X86ATTAsmPrinter::GetExternalSymbolSymbol(const MachineOperand &MO) {
125 return Ctx.GetOrCreateSymbol(Name.str());
126 }
127
128 MCSymbol *X86MCInstLower::
129 GetExternalSymbolSymbol(const MachineOperand &MO) const {
122130 SmallString<128> Name;
123 Name += MAI->getGlobalPrefix();
131 Name += AsmPrinter.MAI->getGlobalPrefix();
124132 Name += MO.getSymbolName();
125133
126134 switch (MO.getTargetFlags()) {
137145 }
138146 case X86II::MO_DARWIN_STUB: {
139147 Name += "$stub";
140 MCSymbol *Sym = OutContext.GetOrCreateSymbol(Name.str());
141 MCSymbol *&StubSym = FnStubs[Sym];
148 MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
149 MCSymbol *&StubSym = AsmPrinter.FnStubs[Sym];
142150 if (StubSym == 0) {
143151 Name.erase(Name.end()-5, Name.end());
144 StubSym = OutContext.GetOrCreateSymbol(Name.str());
152 StubSym = Ctx.GetOrCreateSymbol(Name.str());
145153 }
146154 return Sym;
147155 }
157165 case X86II::MO_PLT: Name += "@PLT"; break;
158166 }
159167
160 return OutContext.GetOrCreateSymbol(Name.str());
161 }
162
163 MCSymbol *X86ATTAsmPrinter::GetJumpTableSymbol(const MachineOperand &MO) {
168 return Ctx.GetOrCreateSymbol(Name.str());
169 }
170
171 MCSymbol *X86MCInstLower::GetJumpTableSymbol(const MachineOperand &MO) const {
164172 SmallString<256> Name;
165 raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI"
166 << getFunctionNumber() << '_' << MO.getIndex();
173 raw_svector_ostream(Name) << AsmPrinter.MAI->getPrivateGlobalPrefix() << "JTI"
174 << AsmPrinter.getFunctionNumber() << '_' << MO.getIndex();
167175
168176 switch (MO.getTargetFlags()) {
169177 default:
186194 }
187195
188196 // Create a symbol for the name.
189 return OutContext.GetOrCreateSymbol(Name.str());
190 }
191
192
193 MCSymbol *X86ATTAsmPrinter::
194 GetConstantPoolIndexSymbol(const MachineOperand &MO) {
197 return Ctx.GetOrCreateSymbol(Name.str());
198 }
199
200
201 MCSymbol *X86MCInstLower::
202 GetConstantPoolIndexSymbol(const MachineOperand &MO) const {
195203 SmallString<256> Name;
196 raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "CPI"
197 << getFunctionNumber() << '_' << MO.getIndex();
204 raw_svector_ostream(Name) << AsmPrinter.MAI->getPrivateGlobalPrefix() << "CPI"
205 << AsmPrinter.getFunctionNumber() << '_' << MO.getIndex();
198206
199207 switch (MO.getTargetFlags()) {
200208 default:
217225 }
218226
219227 // Create a symbol for the name.
220 return OutContext.GetOrCreateSymbol(Name.str());
221 }
222
223 MCOperand X86ATTAsmPrinter::LowerSymbolOperand(const MachineOperand &MO,
224 MCSymbol *Sym) {
228 return Ctx.GetOrCreateSymbol(Name.str());
229 }
230
231 MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO,
232 MCSymbol *Sym) const {
225233 // FIXME: We would like an efficient form for this, so we don't have to do a
226234 // lot of extra uniquing.
227 const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, OutContext);
235 const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, Ctx);
228236
229237 switch (MO.getTargetFlags()) {
230238 default: llvm_unreachable("Unknown target flag on GV operand");
250258 // Subtract the pic base.
251259 Expr = MCBinaryExpr::CreateSub(Expr,
252260 MCSymbolRefExpr::Create(GetPICBaseSymbol(),
253 OutContext),
254 OutContext);
261 Ctx),
262 Ctx);
255263 break;
256264 case X86II::MO_GOT_ABSOLUTE_ADDRESS: {
257265 // For this, we want to print something like:
259267 // However, we can't generate a ".", so just emit a new label here and refer
260268 // to it. We know that this operand flag occurs at most once per function.
261269 SmallString<64> Name;
262 raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "picbaseref"
263 << getFunctionNumber();
264 MCSymbol *DotSym = OutContext.GetOrCreateSymbol(Name.str());
265 OutStreamer.EmitLabel(DotSym);
266
267 const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext);
270 raw_svector_ostream(Name) << AsmPrinter.MAI->getPrivateGlobalPrefix()
271 << "picbaseref" << AsmPrinter.getFunctionNumber();
272 MCSymbol *DotSym = Ctx.GetOrCreateSymbol(Name.str());
273 // FIXME: This instruction should be lowered before we get here...
274 AsmPrinter.OutStreamer.EmitLabel(DotSym);
275
276 const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, Ctx);
268277 const MCExpr *PICBase = MCSymbolRefExpr::Create(GetPICBaseSymbol(),
269 OutContext);
270 DotExpr = MCBinaryExpr::CreateSub(DotExpr, PICBase, OutContext);
271 Expr = MCBinaryExpr::CreateAdd(Expr, DotExpr, OutContext);
278 Ctx);
279 DotExpr = MCBinaryExpr::CreateSub(DotExpr, PICBase, Ctx);
280 Expr = MCBinaryExpr::CreateAdd(Expr, DotExpr, Ctx);
272281 break;
273282 }
274283 }
275284
276285 if (!MO.isJTI() && MO.getOffset())
277 Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(MO.getOffset(),
278 OutContext),
279 OutContext);
286 Expr = MCBinaryExpr::CreateAdd(Expr,
287 MCConstantExpr::Create(MO.getOffset(), Ctx),
288 Ctx);
280289 return MCOperand::CreateExpr(Expr);
281290 }
282291
302311 }
303312
304313
314
315 void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
316 OutMI.setOpcode(MI->getOpcode());
317
318 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
319 const MachineOperand &MO = MI->getOperand(i);
320
321 MCOperand MCOp;
322 switch (MO.getType()) {
323 default:
324 MI->dump();
325 llvm_unreachable("unknown operand type");
326 case MachineOperand::MO_Register:
327 MCOp = MCOperand::CreateReg(MO.getReg());
328 break;
329 case MachineOperand::MO_Immediate:
330 MCOp = MCOperand::CreateImm(MO.getImm());
331 break;
332 case MachineOperand::MO_MachineBasicBlock:
333 // FIXME: Kill MBBLabel operand type!
334 MCOp = MCOperand::CreateMBBLabel(AsmPrinter.getFunctionNumber(),
335 MO.getMBB()->getNumber());
336 break;
337 case MachineOperand::MO_GlobalAddress:
338 MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO));
339 break;
340 case MachineOperand::MO_ExternalSymbol:
341 MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO));
342 break;
343 case MachineOperand::MO_JumpTableIndex:
344 MCOp = LowerSymbolOperand(MO, GetJumpTableSymbol(MO));
345 break;
346 case MachineOperand::MO_ConstantPoolIndex:
347 MCOp = LowerSymbolOperand(MO, GetConstantPoolIndexSymbol(MO));
348 break;
349 }
350
351 OutMI.addOperand(MCOp);
352 }
353
354 // Handle a few special cases to eliminate operand modifiers.
355 switch (OutMI.getOpcode()) {
356 case X86::LEA64_32r: // Handle 'subreg rewriting' for the lea64_32mem operand.
357 lower_lea64_32mem(&OutMI, 1);
358 break;
359 case X86::MOV16r0:
360 OutMI.setOpcode(X86::MOV32r0);
361 lower_subreg32(&OutMI, 0);
362 break;
363 case X86::MOVZX16rr8:
364 OutMI.setOpcode(X86::MOVZX32rr8);
365 lower_subreg32(&OutMI, 0);
366 break;
367 case X86::MOVZX16rm8:
368 OutMI.setOpcode(X86::MOVZX32rm8);
369 lower_subreg32(&OutMI, 0);
370 break;
371 case X86::MOVSX16rr8:
372 OutMI.setOpcode(X86::MOVSX32rr8);
373 lower_subreg32(&OutMI, 0);
374 break;
375 case X86::MOVSX16rm8:
376 OutMI.setOpcode(X86::MOVSX32rm8);
377 lower_subreg32(&OutMI, 0);
378 break;
379 case X86::MOVZX64rr32:
380 OutMI.setOpcode(X86::MOV32rr);
381 lower_subreg32(&OutMI, 0);
382 break;
383 case X86::MOVZX64rm32:
384 OutMI.setOpcode(X86::MOV32rm);
385 lower_subreg32(&OutMI, 0);
386 break;
387 case X86::MOV64ri64i32:
388 OutMI.setOpcode(X86::MOV32ri);
389 lower_subreg32(&OutMI, 0);
390 break;
391 case X86::MOVZX64rr8:
392 OutMI.setOpcode(X86::MOVZX32rr8);
393 lower_subreg32(&OutMI, 0);
394 break;
395 case X86::MOVZX64rm8:
396 OutMI.setOpcode(X86::MOVZX32rm8);
397 lower_subreg32(&OutMI, 0);
398 break;
399 case X86::MOVZX64rr16:
400 OutMI.setOpcode(X86::MOVZX32rr16);
401 lower_subreg32(&OutMI, 0);
402 break;
403 case X86::MOVZX64rm16:
404 OutMI.setOpcode(X86::MOVZX32rm16);
405 lower_subreg32(&OutMI, 0);
406 break;
407 }
408 }
409
410
411
305412 void X86ATTAsmPrinter::
306413 printInstructionThroughMCStreamer(const MachineInstr *MI) {
307 MCInst TmpInst;
414 X86MCInstLower MCInstLowering(OutContext, Mang, *this);
308415 switch (MI->getOpcode()) {
309416 case TargetInstrInfo::DBG_LABEL:
310417 case TargetInstrInfo::EH_LABEL:
319426 printImplicitDef(MI);
320427 return;
321428 case X86::MOVPC32r: {
429 MCInst TmpInst;
322430 // This is a pseudo op for a two instruction sequence with a label, which
323431 // looks like:
324432 // call "L1$pb"
326434 // popl %esi
327435
328436 // Emit the call.
329 MCSymbol *PICBase = GetPICBaseSymbol();
437 MCSymbol *PICBase = MCInstLowering.GetPICBaseSymbol();
330438 TmpInst.setOpcode(X86::CALLpcrel32);
331439 // FIXME: We would like an efficient form for this, so we don't have to do a
332440 // lot of extra uniquing.
346454 }
347455 }
348456
349 TmpInst.setOpcode(MI->getOpcode());
350
351 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
352 const MachineOperand &MO = MI->getOperand(i);
353
354 MCOperand MCOp;
355 switch (MO.getType()) {
356 default:
357 O.flush();
358 errs() << "Cannot lower operand #" << i << " of :" << *MI;
359 llvm_unreachable("Unimp");
360 case MachineOperand::MO_Register:
361 MCOp = MCOperand::CreateReg(MO.getReg());
362 break;
363 case MachineOperand::MO_Immediate:
364 MCOp = MCOperand::CreateImm(MO.getImm());
365 break;
366 case MachineOperand::MO_MachineBasicBlock:
367 MCOp = MCOperand::CreateMBBLabel(getFunctionNumber(),
368 MO.getMBB()->getNumber());
369 break;
370 case MachineOperand::MO_GlobalAddress:
371 MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO));
372 break;
373 case MachineOperand::MO_ExternalSymbol:
374 MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO));
375 break;
376 case MachineOperand::MO_JumpTableIndex:
377 MCOp = LowerSymbolOperand(MO, GetJumpTableSymbol(MO));
378 break;
379 case MachineOperand::MO_ConstantPoolIndex:
380 MCOp = LowerSymbolOperand(MO, GetConstantPoolIndexSymbol(MO));
381 break;
382 }
383
384 TmpInst.addOperand(MCOp);
385 }
386
387 // Handle a few special cases to eliminate operand modifiers.
388 switch (TmpInst.getOpcode()) {
389 case X86::LEA64_32r: // Handle 'subreg rewriting' for the lea64_32mem operand.
390 lower_lea64_32mem(&TmpInst, 1);
391 break;
392 case X86::MOV16r0:
393 TmpInst.setOpcode(X86::MOV32r0);
394 lower_subreg32(&TmpInst, 0);
395 break;
396 case X86::MOVZX16rr8:
397 TmpInst.setOpcode(X86::MOVZX32rr8);
398 lower_subreg32(&TmpInst, 0);
399 break;
400 case X86::MOVZX16rm8:
401 TmpInst.setOpcode(X86::MOVZX32rm8);
402 lower_subreg32(&TmpInst, 0);
403 break;
404 case X86::MOVSX16rr8:
405 TmpInst.setOpcode(X86::MOVSX32rr8);
406 lower_subreg32(&TmpInst, 0);
407 break;
408 case X86::MOVSX16rm8:
409 TmpInst.setOpcode(X86::MOVSX32rm8);
410 lower_subreg32(&TmpInst, 0);
411 break;
412 case X86::MOVZX64rr32:
413 TmpInst.setOpcode(X86::MOV32rr);
414 lower_subreg32(&TmpInst, 0);
415 break;
416 case X86::MOVZX64rm32:
417 TmpInst.setOpcode(X86::MOV32rm);
418 lower_subreg32(&TmpInst, 0);
419 break;
420 case X86::MOV64ri64i32:
421 TmpInst.setOpcode(X86::MOV32ri);
422 lower_subreg32(&TmpInst, 0);
423 break;
424 case X86::MOVZX64rr8:
425 TmpInst.setOpcode(X86::MOVZX32rr8);
426 lower_subreg32(&TmpInst, 0);
427 break;
428 case X86::MOVZX64rm8:
429 TmpInst.setOpcode(X86::MOVZX32rm8);
430 lower_subreg32(&TmpInst, 0);
431 break;
432 case X86::MOVZX64rr16:
433 TmpInst.setOpcode(X86::MOVZX32rr16);
434 lower_subreg32(&TmpInst, 0);
435 break;
436 case X86::MOVZX64rm16:
437 TmpInst.setOpcode(X86::MOVZX32rm16);
438 lower_subreg32(&TmpInst, 0);
439 break;
440 }
457 MCInst TmpInst;
458 MCInstLowering.Lower(MI, TmpInst);
459
441460
442461 printInstruction(&TmpInst);
443462 }
0 //===-- X86MCInstLower.h - Lower MachineInstr to MCInst -------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef X86_MCINSTLOWER_H
10 #define X86_MCINSTLOWER_H
11
12
13 namespace llvm {
14 class MCContext;
15 class MCInst;
16 class MCOperand;
17 class MCSymbol;
18 class MachineInstr;
19 class MachineOperand;
20 class Mangler;
21 class X86ATTAsmPrinter;
22 class X86Subtarget;
23
24 class X86MCInstLower {
25 MCContext &Ctx;
26 Mangler *Mang;
27 X86ATTAsmPrinter &AsmPrinter;
28 public:
29 X86MCInstLower(MCContext &ctx, Mangler *mang, X86ATTAsmPrinter &asmprinter)
30 : Ctx(ctx), Mang(mang), AsmPrinter(asmprinter) {}
31
32 void Lower(const MachineInstr *MI, MCInst &OutMI) const;
33
34 MCSymbol *GetPICBaseSymbol() const;
35
36 private:
37 const X86Subtarget &getSubtarget() const;
38
39 MCSymbol *GetGlobalAddressSymbol(const MachineOperand &MO) const;
40 MCSymbol *GetExternalSymbolSymbol(const MachineOperand &MO) const;
41 MCSymbol *GetJumpTableSymbol(const MachineOperand &MO) const;
42 MCSymbol *GetConstantPoolIndexSymbol(const MachineOperand &MO) const;
43 MCOperand LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const;
44 };
45
46 }
47
48 #endif