X86AsmPrinter.cpp revision e11a9a93a88d937e1f1d55be968cf2b3f8e0bd47
1//===-- X86AsmPrinter.cpp - Convert X86 LLVM code to Intel assembly -------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains a printer that converts from our internal representation
11// of machine-dependent LLVM code to Intel and AT&T format assembly
12// language. This printer is the output mechanism used by `llc' and `lli
13// -print-machineinstrs' on X86.
14//
15//===----------------------------------------------------------------------===//
16
17#include "X86.h"
18#include "X86TargetMachine.h"
19#include "llvm/Module.h"
20#include "llvm/Assembly/Writer.h"
21#include "llvm/CodeGen/AsmPrinter.h"
22#include "llvm/CodeGen/MachineConstantPool.h"
23#include "llvm/CodeGen/MachineFunctionPass.h"
24#include "llvm/CodeGen/ValueTypes.h"
25#include "llvm/Target/TargetMachine.h"
26#include "llvm/Support/Mangler.h"
27#include "llvm/ADT/Statistic.h"
28#include "llvm/Support/CommandLine.h"
29using namespace llvm;
30
31namespace {
32  Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
33  enum AsmWriterFlavor { att, intel };
34
35  cl::opt<AsmWriterFlavor>
36  AsmWriterFlavor("x86-asm-syntax",
37                  cl::desc("Choose style of code to emit from X86 backend:"),
38                  cl::values(
39                             clEnumVal(att,   "  Emit AT&T-style assembly"),
40                             clEnumVal(intel, "  Emit Intel-style assembly"),
41                             clEnumValEnd),
42                  cl::init(att));
43
44  struct X86SharedAsmPrinter : public AsmPrinter {
45    X86SharedAsmPrinter(std::ostream &O, TargetMachine &TM)
46      : AsmPrinter(O, TM) { }
47
48    void printConstantPool(MachineConstantPool *MCP);
49    bool doFinalization(Module &M);
50  };
51}
52
53static bool isScale(const MachineOperand &MO) {
54  return MO.isImmediate() &&
55    (MO.getImmedValue() == 1 || MO.getImmedValue() == 2 ||
56     MO.getImmedValue() == 4 || MO.getImmedValue() == 8);
57}
58
59static bool isMem(const MachineInstr *MI, unsigned Op) {
60  if (MI->getOperand(Op).isFrameIndex()) return true;
61  if (MI->getOperand(Op).isConstantPoolIndex()) return true;
62  return Op+4 <= MI->getNumOperands() &&
63    MI->getOperand(Op  ).isRegister() && isScale(MI->getOperand(Op+1)) &&
64    MI->getOperand(Op+2).isRegister() && (MI->getOperand(Op+3).isImmediate() ||
65        MI->getOperand(Op+3).isGlobalAddress());
66}
67
68// SwitchSection - Switch to the specified section of the executable if we are
69// not already in it!
70//
71static void SwitchSection(std::ostream &OS, std::string &CurSection,
72                          const char *NewSection) {
73  if (CurSection != NewSection) {
74    CurSection = NewSection;
75    if (!CurSection.empty())
76      OS << "\t" << NewSection << "\n";
77  }
78}
79
80/// printConstantPool - Print to the current output stream assembly
81/// representations of the constants in the constant pool MCP. This is
82/// used to print out constants which have been "spilled to memory" by
83/// the code generator.
84///
85void X86SharedAsmPrinter::printConstantPool(MachineConstantPool *MCP) {
86  const std::vector<Constant*> &CP = MCP->getConstants();
87  const TargetData &TD = TM.getTargetData();
88
89  if (CP.empty()) return;
90
91  for (unsigned i = 0, e = CP.size(); i != e; ++i) {
92    O << "\t.section .rodata\n";
93    emitAlignment(TD.getTypeAlignmentShift(CP[i]->getType()));
94    O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t" << CommentString
95      << *CP[i] << "\n";
96    emitGlobalConstant(CP[i]);
97  }
98}
99
100bool X86SharedAsmPrinter::doFinalization(Module &M) {
101  const TargetData &TD = TM.getTargetData();
102  std::string CurSection;
103
104  // Print out module-level global variables here.
105  for (Module::const_giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
106    if (I->hasInitializer()) {   // External global require no code
107      O << "\n\n";
108      std::string name = Mang->getValueName(I);
109      Constant *C = I->getInitializer();
110      unsigned Size = TD.getTypeSize(C->getType());
111      unsigned Align = TD.getTypeAlignmentShift(C->getType());
112
113      if (C->isNullValue() &&
114          (I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
115           I->hasWeakLinkage() /* FIXME: Verify correct */)) {
116        SwitchSection(O, CurSection, ".data");
117        if (I->hasInternalLinkage())
118          O << "\t.local " << name << "\n";
119
120        O << "\t.comm " << name << "," << TD.getTypeSize(C->getType())
121          << "," << (1 << Align);
122        O << "\t\t# ";
123        WriteAsOperand(O, I, true, true, &M);
124        O << "\n";
125      } else {
126        switch (I->getLinkage()) {
127        case GlobalValue::LinkOnceLinkage:
128        case GlobalValue::WeakLinkage:   // FIXME: Verify correct for weak.
129          // Nonnull linkonce -> weak
130          O << "\t.weak " << name << "\n";
131          SwitchSection(O, CurSection, "");
132          O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n";
133          break;
134        case GlobalValue::AppendingLinkage:
135          // FIXME: appending linkage variables should go into a section of
136          // their name or something.  For now, just emit them as external.
137        case GlobalValue::ExternalLinkage:
138          // If external or appending, declare as a global symbol
139          O << "\t.globl " << name << "\n";
140          // FALL THROUGH
141        case GlobalValue::InternalLinkage:
142          if (C->isNullValue())
143            SwitchSection(O, CurSection, ".bss");
144          else
145            SwitchSection(O, CurSection, ".data");
146          break;
147        case GlobalValue::GhostLinkage:
148          std::cerr << "GhostLinkage cannot appear in X86AsmPrinter!\n";
149          abort();
150        }
151
152        emitAlignment(Align);
153        O << "\t.type " << name << ",@object\n";
154        O << "\t.size " << name << "," << Size << "\n";
155        O << name << ":\t\t\t\t# ";
156        WriteAsOperand(O, I, true, true, &M);
157        O << " = ";
158        WriteAsOperand(O, C, false, false, &M);
159        O << "\n";
160        emitGlobalConstant(C);
161      }
162    }
163
164  AsmPrinter::doFinalization(M);
165  return false; // success
166}
167
168namespace {
169  struct X86IntelAsmPrinter : public X86SharedAsmPrinter {
170    X86IntelAsmPrinter(std::ostream &O, TargetMachine &TM)
171      : X86SharedAsmPrinter(O, TM) { }
172
173    virtual const char *getPassName() const {
174      return "X86 Intel-Style Assembly Printer";
175    }
176
177    /// printInstruction - This method is automatically generated by tablegen
178    /// from the instruction set description.  This method returns true if the
179    /// machine instruction was sufficiently described to print it, otherwise it
180    /// returns false.
181    bool printInstruction(const MachineInstr *MI);
182
183    // This method is used by the tablegen'erated instruction printer.
184    void printOperand(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT){
185      const MachineOperand &MO = MI->getOperand(OpNo);
186      if (MO.getType() == MachineOperand::MO_MachineRegister) {
187        assert(MRegisterInfo::isPhysicalRegister(MO.getReg())&&"Not physref??");
188        // Bug Workaround: See note in Printer::doInitialization about %.
189        O << "%" << TM.getRegisterInfo()->get(MO.getReg()).Name;
190      } else {
191        printOp(MO);
192      }
193    }
194
195    void printCallOperand(const MachineInstr *MI, unsigned OpNo,
196                          MVT::ValueType VT) {
197      printOp(MI->getOperand(OpNo), true); // Don't print "OFFSET".
198    }
199
200    void printMemoryOperand(const MachineInstr *MI, unsigned OpNo,
201                            MVT::ValueType VT) {
202      switch (VT) {
203      default: assert(0 && "Unknown arg size!");
204      case MVT::i8:   O << "BYTE PTR "; break;
205      case MVT::i16:  O << "WORD PTR "; break;
206      case MVT::i32:
207      case MVT::f32:  O << "DWORD PTR "; break;
208      case MVT::i64:
209      case MVT::f64:  O << "QWORD PTR "; break;
210      case MVT::f80:  O << "XWORD PTR "; break;
211      }
212      printMemReference(MI, OpNo);
213    }
214
215    void printMachineInstruction(const MachineInstr *MI);
216    void printOp(const MachineOperand &MO, bool elideOffsetKeyword = false);
217    void printMemReference(const MachineInstr *MI, unsigned Op);
218    bool runOnMachineFunction(MachineFunction &F);
219    bool doInitialization(Module &M);
220  };
221} // end of anonymous namespace
222
223
224// Include the auto-generated portion of the assembly writer.
225#include "X86GenAsmWriter1.inc"
226
227
228/// runOnMachineFunction - This uses the printMachineInstruction()
229/// method to print assembly for each instruction.
230///
231bool X86IntelAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
232  setupMachineFunction(MF);
233  O << "\n\n";
234
235  // Print out constants referenced by the function
236  printConstantPool(MF.getConstantPool());
237
238  // Print out labels for the function.
239  O << "\t.text\n";
240  emitAlignment(4);
241  O << "\t.globl\t" << CurrentFnName << "\n";
242  O << "\t.type\t" << CurrentFnName << ", @function\n";
243  O << CurrentFnName << ":\n";
244
245  // Print out code for the function.
246  for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
247       I != E; ++I) {
248    // Print a label for the basic block if there are any predecessors.
249    if (I->pred_begin() != I->pred_end())
250      O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t"
251        << CommentString << " " << I->getBasicBlock()->getName() << "\n";
252    for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
253         II != E; ++II) {
254      // Print the assembly for the instruction.
255      O << "\t";
256      printMachineInstruction(II);
257    }
258  }
259
260  // We didn't modify anything.
261  return false;
262}
263
264void X86IntelAsmPrinter::printOp(const MachineOperand &MO,
265                                 bool elideOffsetKeyword /* = false */) {
266  const MRegisterInfo &RI = *TM.getRegisterInfo();
267  switch (MO.getType()) {
268  case MachineOperand::MO_VirtualRegister:
269    if (Value *V = MO.getVRegValueOrNull()) {
270      O << "<" << V->getName() << ">";
271      return;
272    }
273    // FALLTHROUGH
274  case MachineOperand::MO_MachineRegister:
275    if (MRegisterInfo::isPhysicalRegister(MO.getReg()))
276      // Bug Workaround: See note in Printer::doInitialization about %.
277      O << "%" << RI.get(MO.getReg()).Name;
278    else
279      O << "%reg" << MO.getReg();
280    return;
281
282  case MachineOperand::MO_SignExtendedImmed:
283  case MachineOperand::MO_UnextendedImmed:
284    O << (int)MO.getImmedValue();
285    return;
286  case MachineOperand::MO_MachineBasicBlock: {
287    MachineBasicBlock *MBBOp = MO.getMachineBasicBlock();
288    O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction())
289      << "_" << MBBOp->getNumber () << "\t# "
290      << MBBOp->getBasicBlock ()->getName ();
291    return;
292  }
293  case MachineOperand::MO_PCRelativeDisp:
294    std::cerr << "Shouldn't use addPCDisp() when building X86 MachineInstrs";
295    abort ();
296    return;
297  case MachineOperand::MO_GlobalAddress: {
298    if (!elideOffsetKeyword)
299      O << "OFFSET ";
300    O << Mang->getValueName(MO.getGlobal());
301    int Offset = MO.getOffset();
302    if (Offset > 0)
303      O << " + " << Offset;
304    else if (Offset < 0)
305      O << " - " << -Offset;
306    return;
307  }
308  case MachineOperand::MO_ExternalSymbol:
309    O << MO.getSymbolName();
310    return;
311  default:
312    O << "<unknown operand type>"; return;
313  }
314}
315
316void X86IntelAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){
317  assert(isMem(MI, Op) && "Invalid memory reference!");
318
319  const MachineOperand &BaseReg  = MI->getOperand(Op);
320  int ScaleVal                   = MI->getOperand(Op+1).getImmedValue();
321  const MachineOperand &IndexReg = MI->getOperand(Op+2);
322  const MachineOperand &DispSpec = MI->getOperand(Op+3);
323
324  if (BaseReg.isFrameIndex()) {
325    O << "[frame slot #" << BaseReg.getFrameIndex();
326    if (DispSpec.getImmedValue())
327      O << " + " << DispSpec.getImmedValue();
328    O << "]";
329    return;
330  } else if (BaseReg.isConstantPoolIndex()) {
331    O << "[.CPI" << CurrentFnName << "_"
332      << BaseReg.getConstantPoolIndex();
333
334    if (IndexReg.getReg()) {
335      O << " + ";
336      if (ScaleVal != 1)
337        O << ScaleVal << "*";
338      printOp(IndexReg);
339    }
340
341    if (DispSpec.getImmedValue())
342      O << " + " << DispSpec.getImmedValue();
343    O << "]";
344    return;
345  }
346
347  O << "[";
348  bool NeedPlus = false;
349  if (BaseReg.getReg()) {
350    printOp(BaseReg, true);
351    NeedPlus = true;
352  }
353
354  if (IndexReg.getReg()) {
355    if (NeedPlus) O << " + ";
356    if (ScaleVal != 1)
357      O << ScaleVal << "*";
358    printOp(IndexReg);
359    NeedPlus = true;
360  }
361
362  if (DispSpec.isGlobalAddress()) {
363    if (NeedPlus)
364      O << " + ";
365    printOp(DispSpec, true);
366  } else {
367    int DispVal = DispSpec.getImmedValue();
368    if (DispVal || (!BaseReg.getReg() && !IndexReg.getReg())) {
369      if (NeedPlus)
370        if (DispVal > 0)
371          O << " + ";
372        else {
373          O << " - ";
374          DispVal = -DispVal;
375        }
376      O << DispVal;
377    }
378  }
379  O << "]";
380}
381
382
383/// printMachineInstruction -- Print out a single X86 LLVM instruction
384/// MI in Intel syntax to the current output stream.
385///
386void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
387  ++EmittedInsts;
388
389  // Call the autogenerated instruction printer routines.
390  printInstruction(MI);
391}
392
393bool X86IntelAsmPrinter::doInitialization(Module &M) {
394  AsmPrinter::doInitialization(M);
395  // Tell gas we are outputting Intel syntax (not AT&T syntax) assembly.
396  //
397  // Bug: gas in `intel_syntax noprefix' mode interprets the symbol `Sp' in an
398  // instruction as a reference to the register named sp, and if you try to
399  // reference a symbol `Sp' (e.g. `mov ECX, OFFSET Sp') then it gets lowercased
400  // before being looked up in the symbol table. This creates spurious
401  // `undefined symbol' errors when linking. Workaround: Do not use `noprefix'
402  // mode, and decorate all register names with percent signs.
403  O << "\t.intel_syntax\n";
404  return false;
405}
406
407
408
409namespace {
410  struct X86ATTAsmPrinter : public X86SharedAsmPrinter {
411    X86ATTAsmPrinter(std::ostream &O, TargetMachine &TM)
412      : X86SharedAsmPrinter(O, TM) { }
413
414    virtual const char *getPassName() const {
415      return "X86 AT&T-Style Assembly Printer";
416    }
417
418    /// printInstruction - This method is automatically generated by tablegen
419    /// from the instruction set description.  This method returns true if the
420    /// machine instruction was sufficiently described to print it, otherwise it
421    /// returns false.
422    bool printInstruction(const MachineInstr *MI);
423
424    // This method is used by the tablegen'erated instruction printer.
425    void printOperand(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT){
426      printOp(MI->getOperand(OpNo));
427    }
428
429    void printCallOperand(const MachineInstr *MI, unsigned OpNo,
430                          MVT::ValueType VT) {
431      printOp(MI->getOperand(OpNo), true); // Don't print '$' prefix.
432    }
433
434    void printMemoryOperand(const MachineInstr *MI, unsigned OpNo,
435                            MVT::ValueType VT) {
436      printMemReference(MI, OpNo);
437    }
438
439    void printMachineInstruction(const MachineInstr *MI);
440    void printOp(const MachineOperand &MO, bool isCallOperand = false);
441    void printMemReference(const MachineInstr *MI, unsigned Op);
442    bool runOnMachineFunction(MachineFunction &F);
443  };
444} // end of anonymous namespace
445
446
447// Include the auto-generated portion of the assembly writer.
448#include "X86GenAsmWriter.inc"
449
450
451/// runOnMachineFunction - This uses the printMachineInstruction()
452/// method to print assembly for each instruction.
453///
454bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
455  setupMachineFunction(MF);
456  O << "\n\n";
457
458  // Print out constants referenced by the function
459  printConstantPool(MF.getConstantPool());
460
461  // Print out labels for the function.
462  O << "\t.text\n";
463  emitAlignment(4);
464  O << "\t.globl\t" << CurrentFnName << "\n";
465  O << "\t.type\t" << CurrentFnName << ", @function\n";
466  O << CurrentFnName << ":\n";
467
468  // Print out code for the function.
469  for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
470       I != E; ++I) {
471    // Print a label for the basic block.
472    if (I->pred_begin() != I->pred_end())
473      O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t"
474        << CommentString << " " << I->getBasicBlock()->getName() << "\n";
475    for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
476         II != E; ++II) {
477      // Print the assembly for the instruction.
478      O << "\t";
479      printMachineInstruction(II);
480    }
481  }
482
483  // We didn't modify anything.
484  return false;
485}
486
487void X86ATTAsmPrinter::printOp(const MachineOperand &MO, bool isCallOp) {
488  const MRegisterInfo &RI = *TM.getRegisterInfo();
489  switch (MO.getType()) {
490  case MachineOperand::MO_VirtualRegister:
491  case MachineOperand::MO_MachineRegister:
492    assert(MRegisterInfo::isPhysicalRegister(MO.getReg()) &&
493           "Virtual registers should not make it this far!");
494    O << '%';
495    for (const char *Name = RI.get(MO.getReg()).Name; *Name; ++Name)
496      O << (char)tolower(*Name);
497    return;
498
499  case MachineOperand::MO_SignExtendedImmed:
500  case MachineOperand::MO_UnextendedImmed:
501    O << '$' << (int)MO.getImmedValue();
502    return;
503  case MachineOperand::MO_MachineBasicBlock: {
504    MachineBasicBlock *MBBOp = MO.getMachineBasicBlock();
505    O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction())
506      << "_" << MBBOp->getNumber () << "\t# "
507      << MBBOp->getBasicBlock ()->getName ();
508    return;
509  }
510  case MachineOperand::MO_PCRelativeDisp:
511    std::cerr << "Shouldn't use addPCDisp() when building X86 MachineInstrs";
512    abort ();
513    return;
514  case MachineOperand::MO_GlobalAddress: {
515    if (!isCallOp) O << '$';
516    O << Mang->getValueName(MO.getGlobal());
517    int Offset = MO.getOffset();
518    if (Offset > 0)
519      O << "+" << Offset;
520    else if (Offset < 0)
521      O << Offset;
522    return;
523  }
524  case MachineOperand::MO_ExternalSymbol:
525    if (!isCallOp) O << '$';
526    O << MO.getSymbolName();
527    return;
528  default:
529    O << "<unknown operand type>"; return;
530  }
531}
532
533void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){
534  assert(isMem(MI, Op) && "Invalid memory reference!");
535
536  const MachineOperand &BaseReg  = MI->getOperand(Op);
537  int ScaleVal                   = MI->getOperand(Op+1).getImmedValue();
538  const MachineOperand &IndexReg = MI->getOperand(Op+2);
539  const MachineOperand &DispSpec = MI->getOperand(Op+3);
540
541  if (BaseReg.isFrameIndex()) {
542    O << "[frame slot #" << BaseReg.getFrameIndex();
543    if (DispSpec.getImmedValue())
544      O << " + " << DispSpec.getImmedValue();
545    O << "]";
546    return;
547  } else if (BaseReg.isConstantPoolIndex()) {
548    O << ".CPI" << CurrentFnName << "_"
549      << BaseReg.getConstantPoolIndex();
550    if (DispSpec.getImmedValue())
551      O << "+" << DispSpec.getImmedValue();
552    if (IndexReg.getReg()) {
553      O << "(,";
554      printOp(IndexReg);
555      if (ScaleVal != 1)
556        O << "," << ScaleVal;
557      O << ")";
558    }
559    return;
560  }
561
562  if (DispSpec.isGlobalAddress()) {
563    printOp(DispSpec, true);
564  } else {
565    int DispVal = DispSpec.getImmedValue();
566    if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg()))
567      O << DispVal;
568  }
569
570  if (IndexReg.getReg() || BaseReg.getReg()) {
571    O << "(";
572    if (BaseReg.getReg())
573      printOp(BaseReg);
574
575    if (IndexReg.getReg()) {
576      O << ",";
577      printOp(IndexReg);
578      if (ScaleVal != 1)
579        O << "," << ScaleVal;
580    }
581
582    O << ")";
583  }
584}
585
586
587/// printMachineInstruction -- Print out a single X86 LLVM instruction
588/// MI in Intel syntax to the current output stream.
589///
590void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
591  ++EmittedInsts;
592  // Call the autogenerated instruction printer routines.
593  printInstruction(MI);
594}
595
596
597/// createX86CodePrinterPass - Returns a pass that prints the X86 assembly code
598/// for a MachineFunction to the given output stream, using the given target
599/// machine description.
600///
601FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o,TargetMachine &tm){
602  switch (AsmWriterFlavor) {
603  default: assert(0 && "Unknown asm flavor!");
604  case intel:
605    return new X86IntelAsmPrinter(o, tm);
606  case att:
607    return new X86ATTAsmPrinter(o, tm);
608  }
609}
610