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/Type.h"
21 #include "llvm/Assembly/Writer.h"
22 #include "llvm/CodeGen/AsmPrinter.h"
23 #include "llvm/CodeGen/MachineConstantPool.h"
24 #include "llvm/CodeGen/MachineFunctionPass.h"
25 #include "llvm/CodeGen/ValueTypes.h"
26 #include "llvm/Target/TargetMachine.h"
27 #include "llvm/Support/Mangler.h"
28 #include "llvm/ADT/Statistic.h"
29 #include "llvm/Support/CommandLine.h"
33 Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
34 enum AsmWriterFlavor { att, intel };
36 cl::opt<AsmWriterFlavor>
37 AsmWriterFlavor("x86-asm-syntax",
38 cl::desc("Choose style of code to emit from X86 backend:"),
40 clEnumVal(att, " Emit AT&T-style assembly"),
41 clEnumVal(intel, " Emit Intel-style assembly"),
45 struct X86SharedAsmPrinter : public AsmPrinter {
46 X86SharedAsmPrinter(std::ostream &O, TargetMachine &TM)
47 : AsmPrinter(O, TM), forCygwin(false), forDarwin(false) { }
49 bool doInitialization(Module &M);
50 void printConstantPool(MachineConstantPool *MCP);
51 bool doFinalization(Module &M);
57 static bool isScale(const MachineOperand &MO) {
58 return MO.isImmediate() &&
59 (MO.getImmedValue() == 1 || MO.getImmedValue() == 2 ||
60 MO.getImmedValue() == 4 || MO.getImmedValue() == 8);
63 static bool isMem(const MachineInstr *MI, unsigned Op) {
64 if (MI->getOperand(Op).isFrameIndex()) return true;
65 if (MI->getOperand(Op).isConstantPoolIndex()) return true;
66 return Op+4 <= MI->getNumOperands() &&
67 MI->getOperand(Op ).isRegister() && isScale(MI->getOperand(Op+1)) &&
68 MI->getOperand(Op+2).isRegister() && (MI->getOperand(Op+3).isImmediate() ||
69 MI->getOperand(Op+3).isGlobalAddress());
72 // SwitchSection - Switch to the specified section of the executable if we are
75 static void SwitchSection(std::ostream &OS, std::string &CurSection,
76 const char *NewSection) {
77 if (CurSection != NewSection) {
78 CurSection = NewSection;
79 if (!CurSection.empty())
80 OS << "\t" << NewSection << "\n";
84 /// doInitialization - determine
85 bool X86SharedAsmPrinter::doInitialization(Module& M) {
86 const std::string& TT = M.getTargetTriple();
87 if (TT.length() > 5) {
88 forCygwin = TT.find("cygwin") != std::string::npos ||
89 TT.find("mingw") != std::string::npos;
90 forDarwin = TT.find("darwin") != std::string::npos;
91 } else if (TT.empty()) {
92 #if defined(__CYGWIN__) || defined(__MINGW32__)
94 #elif defined(__MACOSX__)
98 if (forCygwin || forDarwin)
101 AlignmentIsInBytes = false;
102 return AsmPrinter::doInitialization(M);
105 /// printConstantPool - Print to the current output stream assembly
106 /// representations of the constants in the constant pool MCP. This is
107 /// used to print out constants which have been "spilled to memory" by
108 /// the code generator.
110 void X86SharedAsmPrinter::printConstantPool(MachineConstantPool *MCP) {
111 const std::vector<Constant*> &CP = MCP->getConstants();
112 const TargetData &TD = TM.getTargetData();
114 if (CP.empty()) return;
116 for (unsigned i = 0, e = CP.size(); i != e; ++i) {
117 O << "\t.section .rodata\n";
118 emitAlignment(TD.getTypeAlignmentShift(CP[i]->getType()));
119 O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t" << CommentString
121 emitGlobalConstant(CP[i]);
125 bool X86SharedAsmPrinter::doFinalization(Module &M) {
126 const TargetData &TD = TM.getTargetData();
127 std::string CurSection;
129 // Print out module-level global variables here.
130 for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
131 if (I->hasInitializer()) { // External global require no code
133 std::string name = Mang->getValueName(I);
134 Constant *C = I->getInitializer();
135 unsigned Size = TD.getTypeSize(C->getType());
136 unsigned Align = TD.getTypeAlignmentShift(C->getType());
138 if (C->isNullValue() &&
139 (I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
140 I->hasWeakLinkage() /* FIXME: Verify correct */)) {
141 SwitchSection(O, CurSection, ".data");
142 if (!forCygwin && I->hasInternalLinkage())
143 O << "\t.local " << name << "\n";
145 O << "\t.comm " << name << "," << TD.getTypeSize(C->getType());
147 O << "," << (1 << Align);
149 WriteAsOperand(O, I, true, true, &M);
152 switch (I->getLinkage()) {
153 case GlobalValue::LinkOnceLinkage:
154 case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak.
155 // Nonnull linkonce -> weak
156 O << "\t.weak " << name << "\n";
157 SwitchSection(O, CurSection, "");
158 O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n";
160 case GlobalValue::AppendingLinkage:
161 // FIXME: appending linkage variables should go into a section of
162 // their name or something. For now, just emit them as external.
163 case GlobalValue::ExternalLinkage:
164 // If external or appending, declare as a global symbol
165 O << "\t.globl " << name << "\n";
167 case GlobalValue::InternalLinkage:
168 if (C->isNullValue())
169 SwitchSection(O, CurSection, ".bss");
171 SwitchSection(O, CurSection, ".data");
173 case GlobalValue::GhostLinkage:
174 std::cerr << "GhostLinkage cannot appear in X86AsmPrinter!\n";
178 emitAlignment(Align);
179 if (!forCygwin && !forDarwin) {
180 O << "\t.type " << name << ",@object\n";
181 O << "\t.size " << name << "," << Size << "\n";
183 O << name << ":\t\t\t\t# ";
184 WriteAsOperand(O, I, true, true, &M);
186 WriteAsOperand(O, C, false, false, &M);
188 emitGlobalConstant(C);
192 AsmPrinter::doFinalization(M);
193 return false; // success
197 struct X86IntelAsmPrinter : public X86SharedAsmPrinter {
198 X86IntelAsmPrinter(std::ostream &O, TargetMachine &TM)
199 : X86SharedAsmPrinter(O, TM) { }
201 virtual const char *getPassName() const {
202 return "X86 Intel-Style Assembly Printer";
205 /// printInstruction - This method is automatically generated by tablegen
206 /// from the instruction set description. This method returns true if the
207 /// machine instruction was sufficiently described to print it, otherwise it
209 bool printInstruction(const MachineInstr *MI);
211 // This method is used by the tablegen'erated instruction printer.
212 void printOperand(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT){
213 const MachineOperand &MO = MI->getOperand(OpNo);
214 if (MO.getType() == MachineOperand::MO_MachineRegister) {
215 assert(MRegisterInfo::isPhysicalRegister(MO.getReg())&&"Not physref??");
216 // Bug Workaround: See note in Printer::doInitialization about %.
217 O << "%" << TM.getRegisterInfo()->get(MO.getReg()).Name;
223 void printCallOperand(const MachineInstr *MI, unsigned OpNo,
225 printOp(MI->getOperand(OpNo), true); // Don't print "OFFSET".
228 void printMemoryOperand(const MachineInstr *MI, unsigned OpNo,
231 default: assert(0 && "Unknown arg size!");
232 case MVT::i8: O << "BYTE PTR "; break;
233 case MVT::i16: O << "WORD PTR "; break;
235 case MVT::f32: O << "DWORD PTR "; break;
237 case MVT::f64: O << "QWORD PTR "; break;
238 case MVT::f80: O << "XWORD PTR "; break;
240 printMemReference(MI, OpNo);
243 void printMachineInstruction(const MachineInstr *MI);
244 void printOp(const MachineOperand &MO, bool elideOffsetKeyword = false);
245 void printMemReference(const MachineInstr *MI, unsigned Op);
246 bool runOnMachineFunction(MachineFunction &F);
247 bool doInitialization(Module &M);
249 } // end of anonymous namespace
252 // Include the auto-generated portion of the assembly writer.
253 #include "X86GenAsmWriter1.inc"
256 /// runOnMachineFunction - This uses the printMachineInstruction()
257 /// method to print assembly for each instruction.
259 bool X86IntelAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
260 setupMachineFunction(MF);
263 // Print out constants referenced by the function
264 printConstantPool(MF.getConstantPool());
266 // Print out labels for the function.
269 O << "\t.globl\t" << CurrentFnName << "\n";
270 if (!forCygwin && !forDarwin)
271 O << "\t.type\t" << CurrentFnName << ", @function\n";
272 O << CurrentFnName << ":\n";
274 // Print out code for the function.
275 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
277 // Print a label for the basic block if there are any predecessors.
278 if (I->pred_begin() != I->pred_end())
279 O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t"
280 << CommentString << " " << I->getBasicBlock()->getName() << "\n";
281 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
283 // Print the assembly for the instruction.
285 printMachineInstruction(II);
289 // We didn't modify anything.
293 void X86IntelAsmPrinter::printOp(const MachineOperand &MO,
294 bool elideOffsetKeyword /* = false */) {
295 const MRegisterInfo &RI = *TM.getRegisterInfo();
296 switch (MO.getType()) {
297 case MachineOperand::MO_VirtualRegister:
298 if (Value *V = MO.getVRegValueOrNull()) {
299 O << "<" << V->getName() << ">";
303 case MachineOperand::MO_MachineRegister:
304 if (MRegisterInfo::isPhysicalRegister(MO.getReg()))
305 // Bug Workaround: See note in Printer::doInitialization about %.
306 O << "%" << RI.get(MO.getReg()).Name;
308 O << "%reg" << MO.getReg();
311 case MachineOperand::MO_SignExtendedImmed:
312 case MachineOperand::MO_UnextendedImmed:
313 O << (int)MO.getImmedValue();
315 case MachineOperand::MO_MachineBasicBlock: {
316 MachineBasicBlock *MBBOp = MO.getMachineBasicBlock();
317 O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction())
318 << "_" << MBBOp->getNumber () << '\t' << CommentString
319 << MBBOp->getBasicBlock ()->getName ();
322 case MachineOperand::MO_PCRelativeDisp:
323 std::cerr << "Shouldn't use addPCDisp() when building X86 MachineInstrs";
326 case MachineOperand::MO_GlobalAddress: {
327 if (!elideOffsetKeyword)
329 O << Mang->getValueName(MO.getGlobal());
330 int Offset = MO.getOffset();
332 O << " + " << Offset;
334 O << " - " << -Offset;
337 case MachineOperand::MO_ExternalSymbol:
338 O << GlobalPrefix << MO.getSymbolName();
341 O << "<unknown operand type>"; return;
345 void X86IntelAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){
346 assert(isMem(MI, Op) && "Invalid memory reference!");
348 const MachineOperand &BaseReg = MI->getOperand(Op);
349 int ScaleVal = MI->getOperand(Op+1).getImmedValue();
350 const MachineOperand &IndexReg = MI->getOperand(Op+2);
351 const MachineOperand &DispSpec = MI->getOperand(Op+3);
353 if (BaseReg.isFrameIndex()) {
354 O << "[frame slot #" << BaseReg.getFrameIndex();
355 if (DispSpec.getImmedValue())
356 O << " + " << DispSpec.getImmedValue();
359 } else if (BaseReg.isConstantPoolIndex()) {
360 O << "[.CPI" << CurrentFnName << "_"
361 << BaseReg.getConstantPoolIndex();
363 if (IndexReg.getReg()) {
366 O << ScaleVal << "*";
370 if (DispSpec.getImmedValue())
371 O << " + " << DispSpec.getImmedValue();
377 bool NeedPlus = false;
378 if (BaseReg.getReg()) {
379 printOp(BaseReg, true);
383 if (IndexReg.getReg()) {
384 if (NeedPlus) O << " + ";
386 O << ScaleVal << "*";
391 if (DispSpec.isGlobalAddress()) {
394 printOp(DispSpec, true);
396 int DispVal = DispSpec.getImmedValue();
397 if (DispVal || (!BaseReg.getReg() && !IndexReg.getReg())) {
412 /// printMachineInstruction -- Print out a single X86 LLVM instruction
413 /// MI in Intel syntax to the current output stream.
415 void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
418 // Call the autogenerated instruction printer routines.
419 printInstruction(MI);
422 bool X86IntelAsmPrinter::doInitialization(Module &M) {
423 AsmPrinter::doInitialization(M);
424 // Tell gas we are outputting Intel syntax (not AT&T syntax) assembly.
426 // Bug: gas in `intel_syntax noprefix' mode interprets the symbol `Sp' in an
427 // instruction as a reference to the register named sp, and if you try to
428 // reference a symbol `Sp' (e.g. `mov ECX, OFFSET Sp') then it gets lowercased
429 // before being looked up in the symbol table. This creates spurious
430 // `undefined symbol' errors when linking. Workaround: Do not use `noprefix'
431 // mode, and decorate all register names with percent signs.
432 O << "\t.intel_syntax\n";
439 struct X86ATTAsmPrinter : public X86SharedAsmPrinter {
440 X86ATTAsmPrinter(std::ostream &O, TargetMachine &TM)
441 : X86SharedAsmPrinter(O, TM) { }
443 virtual const char *getPassName() const {
444 return "X86 AT&T-Style Assembly Printer";
447 /// printInstruction - This method is automatically generated by tablegen
448 /// from the instruction set description. This method returns true if the
449 /// machine instruction was sufficiently described to print it, otherwise it
451 bool printInstruction(const MachineInstr *MI);
453 // This method is used by the tablegen'erated instruction printer.
454 void printOperand(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT){
455 printOp(MI->getOperand(OpNo));
458 void printCallOperand(const MachineInstr *MI, unsigned OpNo,
460 printOp(MI->getOperand(OpNo), true); // Don't print '$' prefix.
463 void printMemoryOperand(const MachineInstr *MI, unsigned OpNo,
465 printMemReference(MI, OpNo);
468 void printMachineInstruction(const MachineInstr *MI);
469 void printOp(const MachineOperand &MO, bool isCallOperand = false);
470 void printMemReference(const MachineInstr *MI, unsigned Op);
471 bool runOnMachineFunction(MachineFunction &F);
473 } // end of anonymous namespace
476 // Include the auto-generated portion of the assembly writer.
477 #include "X86GenAsmWriter.inc"
480 /// runOnMachineFunction - This uses the printMachineInstruction()
481 /// method to print assembly for each instruction.
483 bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
484 setupMachineFunction(MF);
487 // Print out constants referenced by the function
488 printConstantPool(MF.getConstantPool());
490 // Print out labels for the function.
493 O << "\t.globl\t" << CurrentFnName << "\n";
494 if (!forCygwin && !forDarwin)
495 O << "\t.type\t" << CurrentFnName << ", @function\n";
496 O << CurrentFnName << ":\n";
498 // Print out code for the function.
499 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
501 // Print a label for the basic block.
502 if (I->pred_begin() != I->pred_end())
503 O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t"
504 << CommentString << " " << I->getBasicBlock()->getName() << "\n";
505 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
507 // Print the assembly for the instruction.
509 printMachineInstruction(II);
513 // We didn't modify anything.
517 void X86ATTAsmPrinter::printOp(const MachineOperand &MO, bool isCallOp) {
518 const MRegisterInfo &RI = *TM.getRegisterInfo();
519 switch (MO.getType()) {
520 case MachineOperand::MO_VirtualRegister:
521 case MachineOperand::MO_MachineRegister:
522 assert(MRegisterInfo::isPhysicalRegister(MO.getReg()) &&
523 "Virtual registers should not make it this far!");
525 for (const char *Name = RI.get(MO.getReg()).Name; *Name; ++Name)
526 O << (char)tolower(*Name);
529 case MachineOperand::MO_SignExtendedImmed:
530 case MachineOperand::MO_UnextendedImmed:
531 O << '$' << (int)MO.getImmedValue();
533 case MachineOperand::MO_MachineBasicBlock: {
534 MachineBasicBlock *MBBOp = MO.getMachineBasicBlock();
535 O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction())
536 << "_" << MBBOp->getNumber () << '\t' << CommentString
537 << MBBOp->getBasicBlock ()->getName ();
540 case MachineOperand::MO_PCRelativeDisp:
541 std::cerr << "Shouldn't use addPCDisp() when building X86 MachineInstrs";
544 case MachineOperand::MO_GlobalAddress: {
545 if (!isCallOp) O << '$';
546 O << Mang->getValueName(MO.getGlobal());
547 int Offset = MO.getOffset();
554 case MachineOperand::MO_ExternalSymbol:
555 if (!isCallOp) O << '$';
556 O << GlobalPrefix << MO.getSymbolName();
559 O << "<unknown operand type>"; return;
563 void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){
564 assert(isMem(MI, Op) && "Invalid memory reference!");
566 const MachineOperand &BaseReg = MI->getOperand(Op);
567 int ScaleVal = MI->getOperand(Op+1).getImmedValue();
568 const MachineOperand &IndexReg = MI->getOperand(Op+2);
569 const MachineOperand &DispSpec = MI->getOperand(Op+3);
571 if (BaseReg.isFrameIndex()) {
572 O << "[frame slot #" << BaseReg.getFrameIndex();
573 if (DispSpec.getImmedValue())
574 O << " + " << DispSpec.getImmedValue();
577 } else if (BaseReg.isConstantPoolIndex()) {
578 O << ".CPI" << CurrentFnName << "_"
579 << BaseReg.getConstantPoolIndex();
580 if (DispSpec.getImmedValue())
581 O << "+" << DispSpec.getImmedValue();
582 if (IndexReg.getReg()) {
586 O << "," << ScaleVal;
592 if (DispSpec.isGlobalAddress()) {
593 printOp(DispSpec, true);
595 int DispVal = DispSpec.getImmedValue();
596 if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg()))
600 if (IndexReg.getReg() || BaseReg.getReg()) {
602 if (BaseReg.getReg())
605 if (IndexReg.getReg()) {
609 O << "," << ScaleVal;
617 /// printMachineInstruction -- Print out a single X86 LLVM instruction
618 /// MI in Intel syntax to the current output stream.
620 void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
622 // Call the autogenerated instruction printer routines.
623 printInstruction(MI);
627 /// createX86CodePrinterPass - Returns a pass that prints the X86 assembly code
628 /// for a MachineFunction to the given output stream, using the given target
629 /// machine description.
631 FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o,TargetMachine &tm){
632 switch (AsmWriterFlavor) {
634 assert(0 && "Unknown asm flavor!");
636 return new X86IntelAsmPrinter(o, tm);
638 return new X86ATTAsmPrinter(o, tm);