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 "Support/Statistic.h"
33 #include "Support/StringExtras.h"
34 #include "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 O << "\t.align " << (unsigned)TD.getTypeAlignment(CP[i]->getType())
154 O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t#"
156 emitGlobalConstant(CP[i]);
160 /// runOnMachineFunction - This uses the printMachineInstruction()
161 /// method to print assembly for each instruction.
163 bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
164 setupMachineFunction(MF);
167 // Print out constants referenced by the function
168 printConstantPool(MF.getConstantPool());
170 // Print out labels for the function.
172 O << "\t.align 16\n";
173 O << "\t.globl\t" << CurrentFnName << "\n";
174 O << "\t.type\t" << CurrentFnName << ", @function\n";
175 O << CurrentFnName << ":\n";
177 // Print out code for the function.
178 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
180 // Print a label for the basic block.
181 O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t# "
182 << I->getBasicBlock()->getName() << "\n";
183 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
185 // Print the assembly for the instruction.
187 printMachineInstruction(II);
191 // We didn't modify anything.
195 static bool isScale(const MachineOperand &MO) {
196 return MO.isImmediate() &&
197 (MO.getImmedValue() == 1 || MO.getImmedValue() == 2 ||
198 MO.getImmedValue() == 4 || MO.getImmedValue() == 8);
201 static bool isMem(const MachineInstr *MI, unsigned Op) {
202 if (MI->getOperand(Op).isFrameIndex()) return true;
203 if (MI->getOperand(Op).isConstantPoolIndex()) return true;
204 return Op+4 <= MI->getNumOperands() &&
205 MI->getOperand(Op ).isRegister() && isScale(MI->getOperand(Op+1)) &&
206 MI->getOperand(Op+2).isRegister() && MI->getOperand(Op+3).isImmediate();
211 void X86AsmPrinter::printOp(const MachineOperand &MO,
212 bool elideOffsetKeyword /* = false */) {
213 const MRegisterInfo &RI = *TM.getRegisterInfo();
214 switch (MO.getType()) {
215 case MachineOperand::MO_VirtualRegister:
216 if (Value *V = MO.getVRegValueOrNull()) {
217 O << "<" << V->getName() << ">";
221 case MachineOperand::MO_MachineRegister:
222 if (MRegisterInfo::isPhysicalRegister(MO.getReg()))
223 // Bug Workaround: See note in Printer::doInitialization about %.
224 O << "%" << RI.get(MO.getReg()).Name;
226 O << "%reg" << MO.getReg();
229 case MachineOperand::MO_SignExtendedImmed:
230 case MachineOperand::MO_UnextendedImmed:
231 O << (int)MO.getImmedValue();
233 case MachineOperand::MO_MachineBasicBlock: {
234 MachineBasicBlock *MBBOp = MO.getMachineBasicBlock();
235 O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction())
236 << "_" << MBBOp->getNumber () << "\t# "
237 << MBBOp->getBasicBlock ()->getName ();
240 case MachineOperand::MO_PCRelativeDisp:
241 std::cerr << "Shouldn't use addPCDisp() when building X86 MachineInstrs";
244 case MachineOperand::MO_GlobalAddress:
245 if (!elideOffsetKeyword)
247 O << Mang->getValueName(MO.getGlobal());
249 case MachineOperand::MO_ExternalSymbol:
250 O << MO.getSymbolName();
253 O << "<unknown operand type>"; return;
257 void X86AsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op) {
258 assert(isMem(MI, Op) && "Invalid memory reference!");
260 if (MI->getOperand(Op).isFrameIndex()) {
261 O << "[frame slot #" << MI->getOperand(Op).getFrameIndex();
262 if (MI->getOperand(Op+3).getImmedValue())
263 O << " + " << MI->getOperand(Op+3).getImmedValue();
266 } else if (MI->getOperand(Op).isConstantPoolIndex()) {
267 O << "[.CPI" << CurrentFnName << "_"
268 << MI->getOperand(Op).getConstantPoolIndex();
269 if (MI->getOperand(Op+3).getImmedValue())
270 O << " + " << MI->getOperand(Op+3).getImmedValue();
275 const MachineOperand &BaseReg = MI->getOperand(Op);
276 int ScaleVal = MI->getOperand(Op+1).getImmedValue();
277 const MachineOperand &IndexReg = MI->getOperand(Op+2);
278 int DispVal = MI->getOperand(Op+3).getImmedValue();
281 bool NeedPlus = false;
282 if (BaseReg.getReg()) {
287 if (IndexReg.getReg()) {
288 if (NeedPlus) O << " + ";
290 O << ScaleVal << "*";
309 /// printMachineInstruction -- Print out a single X86 LLVM instruction
310 /// MI in Intel syntax to the current output stream.
312 void X86AsmPrinter::printMachineInstruction(const MachineInstr *MI) {
317 // The 80-bit FP store-pop instruction "fstp XWORD PTR [...]" is misassembled
318 // by gas in intel_syntax mode as its 32-bit equivalent "fstp DWORD PTR
319 // [...]". Workaround: Output the raw opcode bytes instead of the instruction.
321 // The 80-bit FP load instruction "fld XWORD PTR [...]" is misassembled by gas
322 // in intel_syntax mode as its 32-bit equivalent "fld DWORD PTR
323 // [...]". Workaround: Output the raw opcode bytes instead of the instruction.
325 // gas intel_syntax mode treats "fild QWORD PTR [...]" as an invalid opcode,
326 // saying "64 bit operations are only supported in 64 bit modes." libopcodes
327 // disassembles it as "fild DWORD PTR [...]", which is wrong. Workaround:
328 // Output the raw opcode bytes instead of the instruction.
330 // gas intel_syntax mode treats "fistp QWORD PTR [...]" as an invalid opcode,
331 // saying "64 bit operations are only supported in 64 bit modes." libopcodes
332 // disassembles it as "fistpll DWORD PTR [...]", which is wrong. Workaround:
333 // Output the raw opcode bytes instead of the instruction.
334 switch (MI->getOpcode()) {
339 GasBugWorkaroundEmitter gwe(O);
340 X86::emitInstruction(gwe, (X86InstrInfo&)*TM.getInstrInfo(), *MI);
344 // Call the autogenerated instruction printer routines.
345 bool Handled = printInstruction(MI);
348 assert(0 && "Do not know how to print this instruction!");
353 bool X86AsmPrinter::doInitialization(Module &M) {
354 AsmPrinter::doInitialization(M);
355 // Tell gas we are outputting Intel syntax (not AT&T syntax) assembly.
357 // Bug: gas in `intel_syntax noprefix' mode interprets the symbol `Sp' in an
358 // instruction as a reference to the register named sp, and if you try to
359 // reference a symbol `Sp' (e.g. `mov ECX, OFFSET Sp') then it gets lowercased
360 // before being looked up in the symbol table. This creates spurious
361 // `undefined symbol' errors when linking. Workaround: Do not use `noprefix'
362 // mode, and decorate all register names with percent signs.
363 O << "\t.intel_syntax\n";
367 // SwitchSection - Switch to the specified section of the executable if we are
368 // not already in it!
370 static void SwitchSection(std::ostream &OS, std::string &CurSection,
371 const char *NewSection) {
372 if (CurSection != NewSection) {
373 CurSection = NewSection;
374 if (!CurSection.empty())
375 OS << "\t" << NewSection << "\n";
379 bool X86AsmPrinter::doFinalization(Module &M) {
380 const TargetData &TD = TM.getTargetData();
381 std::string CurSection;
383 // Print out module-level global variables here.
384 for (Module::const_giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
385 if (I->hasInitializer()) { // External global require no code
387 std::string name = Mang->getValueName(I);
388 Constant *C = I->getInitializer();
389 unsigned Size = TD.getTypeSize(C->getType());
390 unsigned Align = TD.getTypeAlignment(C->getType());
392 if (C->isNullValue() &&
393 (I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
394 I->hasWeakLinkage() /* FIXME: Verify correct */)) {
395 SwitchSection(O, CurSection, ".data");
396 if (I->hasInternalLinkage())
397 O << "\t.local " << name << "\n";
399 O << "\t.comm " << name << "," << TD.getTypeSize(C->getType())
400 << "," << (unsigned)TD.getTypeAlignment(C->getType());
402 WriteAsOperand(O, I, true, true, &M);
405 switch (I->getLinkage()) {
406 case GlobalValue::LinkOnceLinkage:
407 case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak.
408 // Nonnull linkonce -> weak
409 O << "\t.weak " << name << "\n";
410 SwitchSection(O, CurSection, "");
411 O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n";
414 case GlobalValue::AppendingLinkage:
415 // FIXME: appending linkage variables should go into a section of
416 // their name or something. For now, just emit them as external.
417 case GlobalValue::ExternalLinkage:
418 // If external or appending, declare as a global symbol
419 O << "\t.globl " << name << "\n";
421 case GlobalValue::InternalLinkage:
422 if (C->isNullValue())
423 SwitchSection(O, CurSection, ".bss");
425 SwitchSection(O, CurSection, ".data");
429 O << "\t.align " << Align << "\n";
430 O << "\t.type " << name << ",@object\n";
431 O << "\t.size " << name << "," << Size << "\n";
432 O << name << ":\t\t\t\t# ";
433 WriteAsOperand(O, I, true, true, &M);
435 WriteAsOperand(O, C, false, false, &M);
437 emitGlobalConstant(C);
441 AsmPrinter::doFinalization(M);
442 return false; // success