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-format assembly language. This
12 // printer is the output mechanism used by `llc' and `lli -print-machineinstrs'
15 //===----------------------------------------------------------------------===//
18 #include "X86InstrInfo.h"
19 #include "X86TargetMachine.h"
20 #include "llvm/Constants.h"
21 #include "llvm/DerivedTypes.h"
22 #include "llvm/Module.h"
23 #include "llvm/Assembly/Writer.h"
24 #include "llvm/CodeGen/AsmPrinter.h"
25 #include "llvm/CodeGen/MachineCodeEmitter.h"
26 #include "llvm/CodeGen/MachineConstantPool.h"
27 #include "llvm/CodeGen/MachineFunctionPass.h"
28 #include "llvm/CodeGen/MachineInstr.h"
29 #include "llvm/CodeGen/ValueTypes.h"
30 #include "llvm/Target/TargetMachine.h"
31 #include "llvm/Support/Mangler.h"
32 #include "llvm/ADT/Statistic.h"
33 #include "llvm/ADT/StringExtras.h"
34 #include "llvm/Support/CommandLine.h"
38 Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
40 struct GasBugWorkaroundEmitter : public MachineCodeEmitter {
41 GasBugWorkaroundEmitter(std::ostream& o)
42 : O(o), OldFlags(O.flags()), firstByte(true) {
46 ~GasBugWorkaroundEmitter() {
50 virtual void emitByte(unsigned char B) {
51 if (!firstByte) O << "\n\t";
53 O << ".byte 0x" << (unsigned) B;
56 // These should never be called
57 virtual void emitWord(unsigned W) { assert(0); }
58 virtual uint64_t getGlobalValueAddress(GlobalValue *V) { abort(); }
59 virtual uint64_t getGlobalValueAddress(const std::string &Name) { abort(); }
60 virtual uint64_t getConstantPoolEntryAddress(unsigned Index) { abort(); }
61 virtual uint64_t getCurrentPCValue() { abort(); }
62 virtual uint64_t forceCompilationOf(Function *F) { abort(); }
66 std::ios::fmtflags OldFlags;
70 struct X86AsmPrinter : public AsmPrinter {
71 X86AsmPrinter(std::ostream &O, TargetMachine &TM) : AsmPrinter(O, TM) { }
73 virtual const char *getPassName() const {
74 return "X86 Assembly Printer";
77 /// printInstruction - This method is automatically generated by tablegen
78 /// from the instruction set description. This method returns true if the
79 /// machine instruction was sufficiently described to print it, otherwise it
81 bool printInstruction(const MachineInstr *MI);
83 // This method is used by the tablegen'erated instruction printer.
84 void printOperand(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT){
85 const MachineOperand &MO = MI->getOperand(OpNo);
86 if (MO.getType() == MachineOperand::MO_MachineRegister) {
87 assert(MRegisterInfo::isPhysicalRegister(MO.getReg())&&"Not physref??");
88 // Bug Workaround: See note in Printer::doInitialization about %.
89 O << "%" << TM.getRegisterInfo()->get(MO.getReg()).Name;
95 void printCallOperand(const MachineInstr *MI, unsigned OpNo,
97 printOp(MI->getOperand(OpNo), true); // Don't print "OFFSET".
100 void printMemoryOperand(const MachineInstr *MI, unsigned OpNo,
103 default: assert(0 && "Unknown arg size!");
104 case MVT::i8: O << "BYTE PTR "; break;
105 case MVT::i16: O << "WORD PTR "; break;
107 case MVT::f32: O << "DWORD PTR "; break;
109 case MVT::f64: O << "QWORD PTR "; break;
110 case MVT::f80: O << "XWORD PTR "; break;
112 printMemReference(MI, OpNo);
115 void printMachineInstruction(const MachineInstr *MI);
116 void printOp(const MachineOperand &MO, bool elideOffsetKeyword = false);
117 void printMemReference(const MachineInstr *MI, unsigned Op);
118 void printConstantPool(MachineConstantPool *MCP);
119 bool runOnMachineFunction(MachineFunction &F);
120 bool doInitialization(Module &M);
121 bool doFinalization(Module &M);
123 } // end of anonymous namespace
125 /// createX86CodePrinterPass - Returns a pass that prints the X86
126 /// assembly code for a MachineFunction to the given output stream,
127 /// using the given target machine description. This should work
128 /// regardless of whether the function is in SSA form.
130 FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o,TargetMachine &tm){
131 return new X86AsmPrinter(o, tm);
135 // Include the auto-generated portion of the assembly writer.
136 #include "X86GenAsmWriter.inc"
139 /// printConstantPool - Print to the current output stream assembly
140 /// representations of the constants in the constant pool MCP. This is
141 /// used to print out constants which have been "spilled to memory" by
142 /// the code generator.
144 void X86AsmPrinter::printConstantPool(MachineConstantPool *MCP) {
145 const std::vector<Constant*> &CP = MCP->getConstants();
146 const TargetData &TD = TM.getTargetData();
148 if (CP.empty()) return;
150 for (unsigned i = 0, e = CP.size(); i != e; ++i) {
151 O << "\t.section .rodata\n";
152 emitAlignment(TD.getTypeAlignmentShift(CP[i]->getType()));
153 O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t" << CommentString
155 emitGlobalConstant(CP[i]);
159 /// runOnMachineFunction - This uses the printMachineInstruction()
160 /// method to print assembly for each instruction.
162 bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
163 setupMachineFunction(MF);
166 // Print out constants referenced by the function
167 printConstantPool(MF.getConstantPool());
169 // Print out labels for the function.
172 O << "\t.globl\t" << CurrentFnName << "\n";
173 O << "\t.type\t" << CurrentFnName << ", @function\n";
174 O << CurrentFnName << ":\n";
176 // Print out code for the function.
177 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
179 // Print a label for the basic block.
180 O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t"
181 << CommentString << " " << I->getBasicBlock()->getName() << "\n";
182 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
184 // Print the assembly for the instruction.
186 printMachineInstruction(II);
190 // We didn't modify anything.
194 static bool isScale(const MachineOperand &MO) {
195 return MO.isImmediate() &&
196 (MO.getImmedValue() == 1 || MO.getImmedValue() == 2 ||
197 MO.getImmedValue() == 4 || MO.getImmedValue() == 8);
200 static bool isMem(const MachineInstr *MI, unsigned Op) {
201 if (MI->getOperand(Op).isFrameIndex()) return true;
202 if (MI->getOperand(Op).isConstantPoolIndex()) return true;
203 return Op+4 <= MI->getNumOperands() &&
204 MI->getOperand(Op ).isRegister() && isScale(MI->getOperand(Op+1)) &&
205 MI->getOperand(Op+2).isRegister() && MI->getOperand(Op+3).isImmediate();
210 void X86AsmPrinter::printOp(const MachineOperand &MO,
211 bool elideOffsetKeyword /* = false */) {
212 const MRegisterInfo &RI = *TM.getRegisterInfo();
213 switch (MO.getType()) {
214 case MachineOperand::MO_VirtualRegister:
215 if (Value *V = MO.getVRegValueOrNull()) {
216 O << "<" << V->getName() << ">";
220 case MachineOperand::MO_MachineRegister:
221 if (MRegisterInfo::isPhysicalRegister(MO.getReg()))
222 // Bug Workaround: See note in Printer::doInitialization about %.
223 O << "%" << RI.get(MO.getReg()).Name;
225 O << "%reg" << MO.getReg();
228 case MachineOperand::MO_SignExtendedImmed:
229 case MachineOperand::MO_UnextendedImmed:
230 O << (int)MO.getImmedValue();
232 case MachineOperand::MO_MachineBasicBlock: {
233 MachineBasicBlock *MBBOp = MO.getMachineBasicBlock();
234 O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction())
235 << "_" << MBBOp->getNumber () << "\t# "
236 << MBBOp->getBasicBlock ()->getName ();
239 case MachineOperand::MO_PCRelativeDisp:
240 std::cerr << "Shouldn't use addPCDisp() when building X86 MachineInstrs";
243 case MachineOperand::MO_GlobalAddress:
244 if (!elideOffsetKeyword)
246 O << Mang->getValueName(MO.getGlobal());
248 case MachineOperand::MO_ExternalSymbol:
249 O << MO.getSymbolName();
252 O << "<unknown operand type>"; return;
256 void X86AsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op) {
257 assert(isMem(MI, Op) && "Invalid memory reference!");
259 if (MI->getOperand(Op).isFrameIndex()) {
260 O << "[frame slot #" << MI->getOperand(Op).getFrameIndex();
261 if (MI->getOperand(Op+3).getImmedValue())
262 O << " + " << MI->getOperand(Op+3).getImmedValue();
265 } else if (MI->getOperand(Op).isConstantPoolIndex()) {
266 O << "[.CPI" << CurrentFnName << "_"
267 << MI->getOperand(Op).getConstantPoolIndex();
268 if (MI->getOperand(Op+3).getImmedValue())
269 O << " + " << MI->getOperand(Op+3).getImmedValue();
274 const MachineOperand &BaseReg = MI->getOperand(Op);
275 int ScaleVal = MI->getOperand(Op+1).getImmedValue();
276 const MachineOperand &IndexReg = MI->getOperand(Op+2);
277 int DispVal = MI->getOperand(Op+3).getImmedValue();
280 bool NeedPlus = false;
281 if (BaseReg.getReg()) {
286 if (IndexReg.getReg()) {
287 if (NeedPlus) O << " + ";
289 O << ScaleVal << "*";
308 /// printMachineInstruction -- Print out a single X86 LLVM instruction
309 /// MI in Intel syntax to the current output stream.
311 void X86AsmPrinter::printMachineInstruction(const MachineInstr *MI) {
316 // The 80-bit FP store-pop instruction "fstp XWORD PTR [...]" is misassembled
317 // by gas in intel_syntax mode as its 32-bit equivalent "fstp DWORD PTR
318 // [...]". Workaround: Output the raw opcode bytes instead of the instruction.
320 // The 80-bit FP load instruction "fld XWORD PTR [...]" is misassembled by gas
321 // in intel_syntax mode as its 32-bit equivalent "fld DWORD PTR
322 // [...]". Workaround: Output the raw opcode bytes instead of the instruction.
324 // gas intel_syntax mode treats "fild QWORD PTR [...]" as an invalid opcode,
325 // saying "64 bit operations are only supported in 64 bit modes." libopcodes
326 // disassembles it as "fild DWORD PTR [...]", which is wrong. Workaround:
327 // Output the raw opcode bytes instead of the instruction.
329 // gas intel_syntax mode treats "fistp QWORD PTR [...]" as an invalid opcode,
330 // saying "64 bit operations are only supported in 64 bit modes." libopcodes
331 // disassembles it as "fistpll DWORD PTR [...]", which is wrong. Workaround:
332 // Output the raw opcode bytes instead of the instruction.
333 switch (MI->getOpcode()) {
338 GasBugWorkaroundEmitter gwe(O);
339 X86::emitInstruction(gwe, (X86InstrInfo&)*TM.getInstrInfo(), *MI);
343 // Call the autogenerated instruction printer routines.
344 bool Handled = printInstruction(MI);
347 assert(0 && "Do not know how to print this instruction!");
352 bool X86AsmPrinter::doInitialization(Module &M) {
353 AsmPrinter::doInitialization(M);
354 // Tell gas we are outputting Intel syntax (not AT&T syntax) assembly.
356 // Bug: gas in `intel_syntax noprefix' mode interprets the symbol `Sp' in an
357 // instruction as a reference to the register named sp, and if you try to
358 // reference a symbol `Sp' (e.g. `mov ECX, OFFSET Sp') then it gets lowercased
359 // before being looked up in the symbol table. This creates spurious
360 // `undefined symbol' errors when linking. Workaround: Do not use `noprefix'
361 // mode, and decorate all register names with percent signs.
362 O << "\t.intel_syntax\n";
366 // SwitchSection - Switch to the specified section of the executable if we are
367 // not already in it!
369 static void SwitchSection(std::ostream &OS, std::string &CurSection,
370 const char *NewSection) {
371 if (CurSection != NewSection) {
372 CurSection = NewSection;
373 if (!CurSection.empty())
374 OS << "\t" << NewSection << "\n";
378 bool X86AsmPrinter::doFinalization(Module &M) {
379 const TargetData &TD = TM.getTargetData();
380 std::string CurSection;
382 // Print out module-level global variables here.
383 for (Module::const_giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
384 if (I->hasInitializer()) { // External global require no code
386 std::string name = Mang->getValueName(I);
387 Constant *C = I->getInitializer();
388 unsigned Size = TD.getTypeSize(C->getType());
389 unsigned Align = TD.getTypeAlignmentShift(C->getType());
391 if (C->isNullValue() &&
392 (I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
393 I->hasWeakLinkage() /* FIXME: Verify correct */)) {
394 SwitchSection(O, CurSection, ".data");
395 if (I->hasInternalLinkage())
396 O << "\t.local " << name << "\n";
398 O << "\t.comm " << name << "," << TD.getTypeSize(C->getType())
399 << "," << (1 << Align);
401 WriteAsOperand(O, I, true, true, &M);
404 switch (I->getLinkage()) {
405 case GlobalValue::LinkOnceLinkage:
406 case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak.
407 // Nonnull linkonce -> weak
408 O << "\t.weak " << name << "\n";
409 SwitchSection(O, CurSection, "");
410 O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n";
412 case GlobalValue::AppendingLinkage:
413 // FIXME: appending linkage variables should go into a section of
414 // their name or something. For now, just emit them as external.
415 case GlobalValue::ExternalLinkage:
416 // If external or appending, declare as a global symbol
417 O << "\t.globl " << name << "\n";
419 case GlobalValue::InternalLinkage:
420 if (C->isNullValue())
421 SwitchSection(O, CurSection, ".bss");
423 SwitchSection(O, CurSection, ".data");
427 emitAlignment(Align);
428 O << "\t.type " << name << ",@object\n";
429 O << "\t.size " << name << "," << Size << "\n";
430 O << name << ":\t\t\t\t# ";
431 WriteAsOperand(O, I, true, true, &M);
433 WriteAsOperand(O, C, false, false, &M);
435 emitGlobalConstant(C);
439 AsmPrinter::doFinalization(M);
440 return false; // success