a7e6729141dd50896798da7497107cf2ac155cf8
[oota-llvm.git] / lib / Target / X86 / X86ATTAsmPrinter.cpp
1 //===-- X86ATTAsmPrinter.cpp - Convert X86 LLVM code to Intel assembly ----===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
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.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains a printer that converts from our internal representation
11 // of machine-dependent LLVM code to AT&T format assembly
12 // language. This printer is the output mechanism used by `llc'.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #include "X86ATTAsmPrinter.h"
17 #include "X86.h"
18 #include "X86TargetMachine.h"
19 #include "llvm/Module.h"
20 #include "llvm/Support/Mangler.h"
21 using namespace llvm;
22 using namespace x86;
23
24 /// runOnMachineFunction - This uses the printMachineInstruction()
25 /// method to print assembly for each instruction.
26 ///
27 bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
28   setupMachineFunction(MF);
29   O << "\n\n";
30
31   // Print out constants referenced by the function
32   printConstantPool(MF.getConstantPool());
33
34   // Print out labels for the function.
35   O << "\t.text\n";
36   emitAlignment(4);
37   O << "\t.globl\t" << CurrentFnName << "\n";
38   if (!forCygwin && !forDarwin)
39     O << "\t.type\t" << CurrentFnName << ", @function\n";
40   O << CurrentFnName << ":\n";
41
42   // Print out code for the function.
43   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
44        I != E; ++I) {
45     // Print a label for the basic block.
46     if (I->pred_begin() != I->pred_end())
47       O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t"
48         << CommentString << " " << I->getBasicBlock()->getName() << "\n";
49     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
50          II != E; ++II) {
51       // Print the assembly for the instruction.
52       O << "\t";
53       printMachineInstruction(II);
54     }
55   }
56
57   // We didn't modify anything.
58   return false;
59 }
60
61 void X86ATTAsmPrinter::printOp(const MachineOperand &MO, bool isCallOp) {
62   const MRegisterInfo &RI = *TM.getRegisterInfo();
63   switch (MO.getType()) {
64   case MachineOperand::MO_VirtualRegister:
65   case MachineOperand::MO_MachineRegister:
66     assert(MRegisterInfo::isPhysicalRegister(MO.getReg()) &&
67            "Virtual registers should not make it this far!");
68     O << '%';
69     for (const char *Name = RI.get(MO.getReg()).Name; *Name; ++Name)
70       O << (char)tolower(*Name);
71     return;
72
73   case MachineOperand::MO_SignExtendedImmed:
74   case MachineOperand::MO_UnextendedImmed:
75     O << '$' << (int)MO.getImmedValue();
76     return;
77   case MachineOperand::MO_MachineBasicBlock: {
78     MachineBasicBlock *MBBOp = MO.getMachineBasicBlock();
79     O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction())
80       << "_" << MBBOp->getNumber () << "\t# "
81       << MBBOp->getBasicBlock ()->getName ();
82     return;
83   }
84   case MachineOperand::MO_PCRelativeDisp:
85     std::cerr << "Shouldn't use addPCDisp() when building X86 MachineInstrs";
86     abort ();
87     return;
88   case MachineOperand::MO_GlobalAddress: {
89     if (!isCallOp) O << '$';
90     O << Mang->getValueName(MO.getGlobal());
91     int Offset = MO.getOffset();
92     if (Offset > 0)
93       O << "+" << Offset;
94     else if (Offset < 0)
95       O << Offset;
96     return;
97   }
98   case MachineOperand::MO_ExternalSymbol:
99     if (!isCallOp) O << '$';
100     O << GlobalPrefix << MO.getSymbolName();
101     return;
102   default:
103     O << "<unknown operand type>"; return;
104   }
105 }
106
107 void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){
108   assert(isMem(MI, Op) && "Invalid memory reference!");
109
110   const MachineOperand &BaseReg  = MI->getOperand(Op);
111   int ScaleVal                   = MI->getOperand(Op+1).getImmedValue();
112   const MachineOperand &IndexReg = MI->getOperand(Op+2);
113   const MachineOperand &DispSpec = MI->getOperand(Op+3);
114
115   if (BaseReg.isFrameIndex()) {
116     O << "[frame slot #" << BaseReg.getFrameIndex();
117     if (DispSpec.getImmedValue())
118       O << " + " << DispSpec.getImmedValue();
119     O << "]";
120     return;
121   } else if (BaseReg.isConstantPoolIndex()) {
122     O << ".CPI" << CurrentFnName << "_"
123       << BaseReg.getConstantPoolIndex();
124     if (DispSpec.getImmedValue())
125       O << "+" << DispSpec.getImmedValue();
126     if (IndexReg.getReg()) {
127       O << "(,";
128       printOp(IndexReg);
129       if (ScaleVal != 1)
130         O << "," << ScaleVal;
131       O << ")";
132     }
133     return;
134   }
135
136   if (DispSpec.isGlobalAddress()) {
137     printOp(DispSpec, true);
138   } else {
139     int DispVal = DispSpec.getImmedValue();
140     if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg()))
141       O << DispVal;
142   }
143
144   if (IndexReg.getReg() || BaseReg.getReg()) {
145     O << "(";
146     if (BaseReg.getReg())
147       printOp(BaseReg);
148
149     if (IndexReg.getReg()) {
150       O << ",";
151       printOp(IndexReg);
152       if (ScaleVal != 1)
153         O << "," << ScaleVal;
154     }
155
156     O << ")";
157   }
158 }
159
160 /// printMachineInstruction -- Print out a single X86 LLVM instruction
161 /// MI in Intel syntax to the current output stream.
162 ///
163 void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
164   ++EmittedInsts;
165   // Call the autogenerated instruction printer routines.
166   printInstruction(MI);
167 }
168
169 // Include the auto-generated portion of the assembly writer.
170 #include "X86GenAsmWriter.inc"
171