1 //===-- X86AsmPrinter.cpp - Convert X86 LLVM code to Intel assembly -------===//
3 // The LLVM Compiler Infrastructure
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.
8 //===----------------------------------------------------------------------===//
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.
15 //===----------------------------------------------------------------------===//
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"
32 Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
33 enum AsmWriterFlavor { att, intel };
35 cl::opt<AsmWriterFlavor>
36 AsmWriterFlavor("x86-asm-syntax",
37 cl::desc("Choose style of code to emit from X86 backend:"),
39 clEnumVal(att, " Emit AT&T-style assembly"),
40 clEnumVal(intel, " Emit Intel-style assembly"),
44 struct X86SharedAsmPrinter : public AsmPrinter {
45 X86SharedAsmPrinter(std::ostream &O, TargetMachine &TM)
46 : AsmPrinter(O, TM) { }
48 void printConstantPool(MachineConstantPool *MCP);
49 bool doFinalization(Module &M);
53 static bool isScale(const MachineOperand &MO) {
54 return MO.isImmediate() &&
55 (MO.getImmedValue() == 1 || MO.getImmedValue() == 2 ||
56 MO.getImmedValue() == 4 || MO.getImmedValue() == 8);
59 static 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());
68 // SwitchSection - Switch to the specified section of the executable if we are
71 static 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";
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.
85 void X86SharedAsmPrinter::printConstantPool(MachineConstantPool *MCP) {
86 const std::vector<Constant*> &CP = MCP->getConstants();
87 const TargetData &TD = TM.getTargetData();
89 if (CP.empty()) return;
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
96 emitGlobalConstant(CP[i]);
100 bool X86SharedAsmPrinter::doFinalization(Module &M) {
101 const TargetData &TD = TM.getTargetData();
102 std::string CurSection;
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
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());
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";
120 O << "\t.comm " << name << "," << TD.getTypeSize(C->getType())
121 << "," << (1 << Align);
123 WriteAsOperand(O, I, true, true, &M);
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";
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";
141 case GlobalValue::InternalLinkage:
142 if (C->isNullValue())
143 SwitchSection(O, CurSection, ".bss");
145 SwitchSection(O, CurSection, ".data");
147 case GlobalValue::GhostLinkage:
148 std::cerr << "GhostLinkage cannot appear in X86AsmPrinter!\n";
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);
158 WriteAsOperand(O, C, false, false, &M);
160 emitGlobalConstant(C);
164 AsmPrinter::doFinalization(M);
165 return false; // success
169 struct X86IntelAsmPrinter : public X86SharedAsmPrinter {
170 X86IntelAsmPrinter(std::ostream &O, TargetMachine &TM)
171 : X86SharedAsmPrinter(O, TM) { }
173 virtual const char *getPassName() const {
174 return "X86 Intel-Style Assembly Printer";
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
181 bool printInstruction(const MachineInstr *MI);
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;
195 void printCallOperand(const MachineInstr *MI, unsigned OpNo,
197 printOp(MI->getOperand(OpNo), true); // Don't print "OFFSET".
200 void printMemoryOperand(const MachineInstr *MI, unsigned OpNo,
203 default: assert(0 && "Unknown arg size!");
204 case MVT::i8: O << "BYTE PTR "; break;
205 case MVT::i16: O << "WORD PTR "; break;
207 case MVT::f32: O << "DWORD PTR "; break;
209 case MVT::f64: O << "QWORD PTR "; break;
210 case MVT::f80: O << "XWORD PTR "; break;
212 printMemReference(MI, OpNo);
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);
221 } // end of anonymous namespace
224 // Include the auto-generated portion of the assembly writer.
225 #include "X86GenAsmWriter1.inc"
228 /// runOnMachineFunction - This uses the printMachineInstruction()
229 /// method to print assembly for each instruction.
231 bool X86IntelAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
232 setupMachineFunction(MF);
235 // Print out constants referenced by the function
236 printConstantPool(MF.getConstantPool());
238 // Print out labels for the function.
241 O << "\t.globl\t" << CurrentFnName << "\n";
242 O << "\t.type\t" << CurrentFnName << ", @function\n";
243 O << CurrentFnName << ":\n";
245 // Print out code for the function.
246 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
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();
254 // Print the assembly for the instruction.
256 printMachineInstruction(II);
260 // We didn't modify anything.
264 void 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() << ">";
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;
279 O << "%reg" << MO.getReg();
282 case MachineOperand::MO_SignExtendedImmed:
283 case MachineOperand::MO_UnextendedImmed:
284 O << (int)MO.getImmedValue();
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 ();
293 case MachineOperand::MO_PCRelativeDisp:
294 std::cerr << "Shouldn't use addPCDisp() when building X86 MachineInstrs";
297 case MachineOperand::MO_GlobalAddress: {
298 if (!elideOffsetKeyword)
300 O << Mang->getValueName(MO.getGlobal());
301 int Offset = MO.getOffset();
303 O << " + " << Offset;
305 O << " - " << -Offset;
308 case MachineOperand::MO_ExternalSymbol:
309 O << MO.getSymbolName();
312 O << "<unknown operand type>"; return;
316 void X86IntelAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){
317 assert(isMem(MI, Op) && "Invalid memory reference!");
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);
324 if (BaseReg.isFrameIndex()) {
325 O << "[frame slot #" << BaseReg.getFrameIndex();
326 if (DispSpec.getImmedValue())
327 O << " + " << DispSpec.getImmedValue();
330 } else if (BaseReg.isConstantPoolIndex()) {
331 O << "[.CPI" << CurrentFnName << "_"
332 << BaseReg.getConstantPoolIndex();
334 if (IndexReg.getReg()) {
337 O << ScaleVal << "*";
341 if (DispSpec.getImmedValue())
342 O << " + " << DispSpec.getImmedValue();
348 bool NeedPlus = false;
349 if (BaseReg.getReg()) {
350 printOp(BaseReg, true);
354 if (IndexReg.getReg()) {
355 if (NeedPlus) O << " + ";
357 O << ScaleVal << "*";
362 if (DispSpec.isGlobalAddress()) {
365 printOp(DispSpec, true);
367 int DispVal = DispSpec.getImmedValue();
383 /// printMachineInstruction -- Print out a single X86 LLVM instruction
384 /// MI in Intel syntax to the current output stream.
386 void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
389 // Call the autogenerated instruction printer routines.
390 printInstruction(MI);
393 bool X86IntelAsmPrinter::doInitialization(Module &M) {
394 AsmPrinter::doInitialization(M);
395 // Tell gas we are outputting Intel syntax (not AT&T syntax) assembly.
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";
410 struct X86ATTAsmPrinter : public X86SharedAsmPrinter {
411 X86ATTAsmPrinter(std::ostream &O, TargetMachine &TM)
412 : X86SharedAsmPrinter(O, TM) { }
414 virtual const char *getPassName() const {
415 return "X86 AT&T-Style Assembly Printer";
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
422 bool printInstruction(const MachineInstr *MI);
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));
429 void printCallOperand(const MachineInstr *MI, unsigned OpNo,
431 printOp(MI->getOperand(OpNo), true); // Don't print '$' prefix.
434 void printMemoryOperand(const MachineInstr *MI, unsigned OpNo,
436 printMemReference(MI, OpNo);
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);
444 } // end of anonymous namespace
447 // Include the auto-generated portion of the assembly writer.
448 #include "X86GenAsmWriter.inc"
451 /// runOnMachineFunction - This uses the printMachineInstruction()
452 /// method to print assembly for each instruction.
454 bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
455 setupMachineFunction(MF);
458 // Print out constants referenced by the function
459 printConstantPool(MF.getConstantPool());
461 // Print out labels for the function.
464 O << "\t.globl\t" << CurrentFnName << "\n";
465 O << "\t.type\t" << CurrentFnName << ", @function\n";
466 O << CurrentFnName << ":\n";
468 // Print out code for the function.
469 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
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();
477 // Print the assembly for the instruction.
479 printMachineInstruction(II);
483 // We didn't modify anything.
487 void 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!");
495 for (const char *Name = RI.get(MO.getReg()).Name; *Name; ++Name)
496 O << (char)tolower(*Name);
499 case MachineOperand::MO_SignExtendedImmed:
500 case MachineOperand::MO_UnextendedImmed:
501 O << '$' << (int)MO.getImmedValue();
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 ();
510 case MachineOperand::MO_PCRelativeDisp:
511 std::cerr << "Shouldn't use addPCDisp() when building X86 MachineInstrs";
514 case MachineOperand::MO_GlobalAddress: {
515 if (!isCallOp) O << '$';
516 O << Mang->getValueName(MO.getGlobal());
517 int Offset = MO.getOffset();
524 case MachineOperand::MO_ExternalSymbol:
525 if (!isCallOp) O << '$';
526 O << MO.getSymbolName();
529 O << "<unknown operand type>"; return;
533 void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){
534 assert(isMem(MI, Op) && "Invalid memory reference!");
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);
541 if (BaseReg.isFrameIndex()) {
542 O << "[frame slot #" << BaseReg.getFrameIndex();
543 if (DispSpec.getImmedValue())
544 O << " + " << DispSpec.getImmedValue();
547 } else if (BaseReg.isConstantPoolIndex()) {
548 O << ".CPI" << CurrentFnName << "_"
549 << BaseReg.getConstantPoolIndex();
550 if (DispSpec.getImmedValue())
551 O << "+" << DispSpec.getImmedValue();
552 if (IndexReg.getReg()) {
556 O << "," << ScaleVal;
562 if (DispSpec.isGlobalAddress()) {
563 printOp(DispSpec, true);
565 int DispVal = DispSpec.getImmedValue();
566 if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg()))
570 if (IndexReg.getReg() || BaseReg.getReg()) {
572 if (BaseReg.getReg())
575 if (IndexReg.getReg()) {
579 O << "," << ScaleVal;
587 /// printMachineInstruction -- Print out a single X86 LLVM instruction
588 /// MI in Intel syntax to the current output stream.
590 void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
592 // Call the autogenerated instruction printer routines.
593 printInstruction(MI);
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.
601 FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o,TargetMachine &tm){
602 switch (AsmWriterFlavor) {
603 default: assert(0 && "Unknown asm flavor!");
605 return new X86IntelAsmPrinter(o, tm);
607 return new X86ATTAsmPrinter(o, tm);