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");
149 emitAlignment(Align);
150 O << "\t.type " << name << ",@object\n";
151 O << "\t.size " << name << "," << Size << "\n";
152 O << name << ":\t\t\t\t# ";
153 WriteAsOperand(O, I, true, true, &M);
155 WriteAsOperand(O, C, false, false, &M);
157 emitGlobalConstant(C);
161 AsmPrinter::doFinalization(M);
162 return false; // success
166 struct X86IntelAsmPrinter : public X86SharedAsmPrinter {
167 X86IntelAsmPrinter(std::ostream &O, TargetMachine &TM)
168 : X86SharedAsmPrinter(O, TM) { }
170 virtual const char *getPassName() const {
171 return "X86 Intel-Style Assembly Printer";
174 /// printInstruction - This method is automatically generated by tablegen
175 /// from the instruction set description. This method returns true if the
176 /// machine instruction was sufficiently described to print it, otherwise it
178 bool printInstruction(const MachineInstr *MI);
180 // This method is used by the tablegen'erated instruction printer.
181 void printOperand(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT){
182 const MachineOperand &MO = MI->getOperand(OpNo);
183 if (MO.getType() == MachineOperand::MO_MachineRegister) {
184 assert(MRegisterInfo::isPhysicalRegister(MO.getReg())&&"Not physref??");
185 // Bug Workaround: See note in Printer::doInitialization about %.
186 O << "%" << TM.getRegisterInfo()->get(MO.getReg()).Name;
192 void printCallOperand(const MachineInstr *MI, unsigned OpNo,
194 printOp(MI->getOperand(OpNo), true); // Don't print "OFFSET".
197 void printMemoryOperand(const MachineInstr *MI, unsigned OpNo,
200 default: assert(0 && "Unknown arg size!");
201 case MVT::i8: O << "BYTE PTR "; break;
202 case MVT::i16: O << "WORD PTR "; break;
204 case MVT::f32: O << "DWORD PTR "; break;
206 case MVT::f64: O << "QWORD PTR "; break;
207 case MVT::f80: O << "XWORD PTR "; break;
209 printMemReference(MI, OpNo);
212 void printMachineInstruction(const MachineInstr *MI);
213 void printOp(const MachineOperand &MO, bool elideOffsetKeyword = false);
214 void printMemReference(const MachineInstr *MI, unsigned Op);
215 bool runOnMachineFunction(MachineFunction &F);
216 bool doInitialization(Module &M);
218 } // end of anonymous namespace
221 // Include the auto-generated portion of the assembly writer.
222 #include "X86GenIntelAsmWriter.inc"
225 /// runOnMachineFunction - This uses the printMachineInstruction()
226 /// method to print assembly for each instruction.
228 bool X86IntelAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
229 setupMachineFunction(MF);
232 // Print out constants referenced by the function
233 printConstantPool(MF.getConstantPool());
235 // Print out labels for the function.
238 O << "\t.globl\t" << CurrentFnName << "\n";
239 O << "\t.type\t" << CurrentFnName << ", @function\n";
240 O << CurrentFnName << ":\n";
242 // Print out code for the function.
243 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
245 // Print a label for the basic block.
246 O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t"
247 << CommentString << " " << I->getBasicBlock()->getName() << "\n";
248 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
250 // Print the assembly for the instruction.
252 printMachineInstruction(II);
256 // We didn't modify anything.
260 void X86IntelAsmPrinter::printOp(const MachineOperand &MO,
261 bool elideOffsetKeyword /* = false */) {
262 const MRegisterInfo &RI = *TM.getRegisterInfo();
263 switch (MO.getType()) {
264 case MachineOperand::MO_VirtualRegister:
265 if (Value *V = MO.getVRegValueOrNull()) {
266 O << "<" << V->getName() << ">";
270 case MachineOperand::MO_MachineRegister:
271 if (MRegisterInfo::isPhysicalRegister(MO.getReg()))
272 // Bug Workaround: See note in Printer::doInitialization about %.
273 O << "%" << RI.get(MO.getReg()).Name;
275 O << "%reg" << MO.getReg();
278 case MachineOperand::MO_SignExtendedImmed:
279 case MachineOperand::MO_UnextendedImmed:
280 O << (int)MO.getImmedValue();
282 case MachineOperand::MO_MachineBasicBlock: {
283 MachineBasicBlock *MBBOp = MO.getMachineBasicBlock();
284 O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction())
285 << "_" << MBBOp->getNumber () << "\t# "
286 << MBBOp->getBasicBlock ()->getName ();
289 case MachineOperand::MO_PCRelativeDisp:
290 std::cerr << "Shouldn't use addPCDisp() when building X86 MachineInstrs";
293 case MachineOperand::MO_GlobalAddress: {
294 if (!elideOffsetKeyword)
296 O << Mang->getValueName(MO.getGlobal());
297 int Offset = MO.getOffset();
299 O << " + " << Offset;
301 O << " - " << -Offset;
304 case MachineOperand::MO_ExternalSymbol:
305 O << MO.getSymbolName();
308 O << "<unknown operand type>"; return;
312 void X86IntelAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){
313 assert(isMem(MI, Op) && "Invalid memory reference!");
315 const MachineOperand &BaseReg = MI->getOperand(Op);
316 int ScaleVal = MI->getOperand(Op+1).getImmedValue();
317 const MachineOperand &IndexReg = MI->getOperand(Op+2);
318 const MachineOperand &DispSpec = MI->getOperand(Op+3);
320 if (BaseReg.isFrameIndex()) {
321 O << "[frame slot #" << BaseReg.getFrameIndex();
322 if (DispSpec.getImmedValue())
323 O << " + " << DispSpec.getImmedValue();
326 } else if (BaseReg.isConstantPoolIndex()) {
327 O << "[.CPI" << CurrentFnName << "_"
328 << BaseReg.getConstantPoolIndex();
330 if (IndexReg.getReg()) {
333 O << ScaleVal << "*";
337 if (DispSpec.getImmedValue())
338 O << " + " << DispSpec.getImmedValue();
344 bool NeedPlus = false;
345 if (BaseReg.getReg()) {
346 printOp(BaseReg, true);
350 if (IndexReg.getReg()) {
351 if (NeedPlus) O << " + ";
353 O << ScaleVal << "*";
358 if (DispSpec.isGlobalAddress()) {
361 printOp(DispSpec, true);
363 int DispVal = DispSpec.getImmedValue();
379 /// printMachineInstruction -- Print out a single X86 LLVM instruction
380 /// MI in Intel syntax to the current output stream.
382 void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
385 // Call the autogenerated instruction printer routines.
386 printInstruction(MI);
389 bool X86IntelAsmPrinter::doInitialization(Module &M) {
390 AsmPrinter::doInitialization(M);
391 // Tell gas we are outputting Intel syntax (not AT&T syntax) assembly.
393 // Bug: gas in `intel_syntax noprefix' mode interprets the symbol `Sp' in an
394 // instruction as a reference to the register named sp, and if you try to
395 // reference a symbol `Sp' (e.g. `mov ECX, OFFSET Sp') then it gets lowercased
396 // before being looked up in the symbol table. This creates spurious
397 // `undefined symbol' errors when linking. Workaround: Do not use `noprefix'
398 // mode, and decorate all register names with percent signs.
399 O << "\t.intel_syntax\n";
406 struct X86ATTAsmPrinter : public X86SharedAsmPrinter {
407 X86ATTAsmPrinter(std::ostream &O, TargetMachine &TM)
408 : X86SharedAsmPrinter(O, TM) { }
410 virtual const char *getPassName() const {
411 return "X86 AT&T-Style Assembly Printer";
414 /// printInstruction - This method is automatically generated by tablegen
415 /// from the instruction set description. This method returns true if the
416 /// machine instruction was sufficiently described to print it, otherwise it
418 bool printInstruction(const MachineInstr *MI);
420 // This method is used by the tablegen'erated instruction printer.
421 void printOperand(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT){
422 printOp(MI->getOperand(OpNo));
425 void printCallOperand(const MachineInstr *MI, unsigned OpNo,
427 printOp(MI->getOperand(OpNo), true); // Don't print '$' prefix.
430 void printMemoryOperand(const MachineInstr *MI, unsigned OpNo,
432 printMemReference(MI, OpNo);
435 void printMachineInstruction(const MachineInstr *MI);
436 void printOp(const MachineOperand &MO, bool isCallOperand = false);
437 void printMemReference(const MachineInstr *MI, unsigned Op);
438 bool runOnMachineFunction(MachineFunction &F);
440 } // end of anonymous namespace
443 // Include the auto-generated portion of the assembly writer.
444 #include "X86GenATTAsmWriter.inc"
447 /// runOnMachineFunction - This uses the printMachineInstruction()
448 /// method to print assembly for each instruction.
450 bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
451 setupMachineFunction(MF);
454 // Print out constants referenced by the function
455 printConstantPool(MF.getConstantPool());
457 // Print out labels for the function.
460 O << "\t.globl\t" << CurrentFnName << "\n";
461 O << "\t.type\t" << CurrentFnName << ", @function\n";
462 O << CurrentFnName << ":\n";
464 // Print out code for the function.
465 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
467 // Print a label for the basic block.
468 O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t"
469 << CommentString << " " << I->getBasicBlock()->getName() << "\n";
470 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
472 // Print the assembly for the instruction.
474 printMachineInstruction(II);
478 // We didn't modify anything.
482 void X86ATTAsmPrinter::printOp(const MachineOperand &MO, bool isCallOp) {
483 const MRegisterInfo &RI = *TM.getRegisterInfo();
484 switch (MO.getType()) {
485 case MachineOperand::MO_VirtualRegister:
486 case MachineOperand::MO_MachineRegister:
487 assert(MRegisterInfo::isPhysicalRegister(MO.getReg()) &&
488 "Virtual registers should not make it this far!");
490 for (const char *Name = RI.get(MO.getReg()).Name; *Name; ++Name)
491 O << (char)tolower(*Name);
494 case MachineOperand::MO_SignExtendedImmed:
495 case MachineOperand::MO_UnextendedImmed:
496 O << '$' << (int)MO.getImmedValue();
498 case MachineOperand::MO_MachineBasicBlock: {
499 MachineBasicBlock *MBBOp = MO.getMachineBasicBlock();
500 O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction())
501 << "_" << MBBOp->getNumber () << "\t# "
502 << MBBOp->getBasicBlock ()->getName ();
505 case MachineOperand::MO_PCRelativeDisp:
506 std::cerr << "Shouldn't use addPCDisp() when building X86 MachineInstrs";
509 case MachineOperand::MO_GlobalAddress: {
510 if (!isCallOp) O << '$';
511 O << Mang->getValueName(MO.getGlobal());
512 int Offset = MO.getOffset();
519 case MachineOperand::MO_ExternalSymbol:
520 if (!isCallOp) O << '$';
521 O << MO.getSymbolName();
524 O << "<unknown operand type>"; return;
528 void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){
529 assert(isMem(MI, Op) && "Invalid memory reference!");
531 const MachineOperand &BaseReg = MI->getOperand(Op);
532 int ScaleVal = MI->getOperand(Op+1).getImmedValue();
533 const MachineOperand &IndexReg = MI->getOperand(Op+2);
534 const MachineOperand &DispSpec = MI->getOperand(Op+3);
536 if (BaseReg.isFrameIndex()) {
537 O << "[frame slot #" << BaseReg.getFrameIndex();
538 if (DispSpec.getImmedValue())
539 O << " + " << DispSpec.getImmedValue();
542 } else if (BaseReg.isConstantPoolIndex()) {
543 O << ".CPI" << CurrentFnName << "_"
544 << BaseReg.getConstantPoolIndex();
545 if (DispSpec.getImmedValue())
546 O << "+" << DispSpec.getImmedValue();
547 if (IndexReg.getReg()) {
551 O << "," << ScaleVal;
557 if (DispSpec.isGlobalAddress()) {
558 printOp(DispSpec, true);
560 int DispVal = DispSpec.getImmedValue();
565 if (IndexReg.getReg() || BaseReg.getReg()) {
567 if (BaseReg.getReg())
570 if (IndexReg.getReg()) {
574 O << "," << ScaleVal;
582 /// printMachineInstruction -- Print out a single X86 LLVM instruction
583 /// MI in Intel syntax to the current output stream.
585 void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
587 // Call the autogenerated instruction printer routines.
588 printInstruction(MI);
592 /// createX86CodePrinterPass - Returns a pass that prints the X86 assembly code
593 /// for a MachineFunction to the given output stream, using the given target
594 /// machine description.
596 FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o,TargetMachine &tm){
597 switch (AsmWriterFlavor) {
598 default: assert(0 && "Unknown asm flavor!");
600 return new X86IntelAsmPrinter(o, tm);
602 return new X86ATTAsmPrinter(o, tm);