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