Add support for assembling .s files on mac os x for intel
[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     // Darwin block shameless ripped from PowerPCAsmPrinter.cpp
90     if (forDarwin) {
91       if (!isCallOp) O << '$';
92       GlobalValue *GV = MO.getGlobal();
93       std::string Name = Mang->getValueName(GV);
94
95       // Dynamically-resolved functions need a stub for the function.  Be
96       // wary however not to output $stub for external functions whose addresses
97       // are taken.  Those should be emitted as $non_lazy_ptr below.
98       Function *F = dyn_cast<Function>(GV);
99       if (F && isCallOp && F->isExternal()) {
100         FnStubs.insert(Name);
101         O << "L" << Name << "$stub";
102         return;
103       }
104
105       // Link-once, External, or Weakly-linked global variables need 
106       // non-lazily-resolved stubs
107       if (GV->hasLinkOnceLinkage()) {
108         LinkOnceStubs.insert(Name);
109         O << "L" << Name << "$non_lazy_ptr";
110         return;
111       }
112       if (GV->isExternal() || GV->hasWeakLinkage()) {
113         GVStubs.insert(Name);
114         O << "L" << Name << "$non_lazy_ptr";
115         return;
116       }
117       O << Mang->getValueName(GV);
118       return;
119     }
120     if (!isCallOp) O << '$';
121     O << Mang->getValueName(MO.getGlobal());
122     int Offset = MO.getOffset();
123     if (Offset > 0)
124       O << "+" << Offset;
125     else if (Offset < 0)
126       O << Offset;
127     return;
128   }
129   case MachineOperand::MO_ExternalSymbol:
130     if (isCallOp && forDarwin) {
131       std::string Name(GlobalPrefix); Name += MO.getSymbolName();
132       FnStubs.insert(Name);
133       O << "L" << Name << "$stub";
134       return;
135     }
136     if (!isCallOp) O << '$';
137     O << GlobalPrefix << MO.getSymbolName();
138     return;
139   default:
140     O << "<unknown operand type>"; return;
141   }
142 }
143
144 void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){
145   assert(isMem(MI, Op) && "Invalid memory reference!");
146
147   const MachineOperand &BaseReg  = MI->getOperand(Op);
148   int ScaleVal                   = MI->getOperand(Op+1).getImmedValue();
149   const MachineOperand &IndexReg = MI->getOperand(Op+2);
150   const MachineOperand &DispSpec = MI->getOperand(Op+3);
151
152   if (BaseReg.isFrameIndex()) {
153     O << "[frame slot #" << BaseReg.getFrameIndex();
154     if (DispSpec.getImmedValue())
155       O << " + " << DispSpec.getImmedValue();
156     O << "]";
157     return;
158   } else if (BaseReg.isConstantPoolIndex()) {
159     O << ".CPI" << CurrentFnName << "_"
160       << BaseReg.getConstantPoolIndex();
161     if (DispSpec.getImmedValue())
162       O << "+" << DispSpec.getImmedValue();
163     if (IndexReg.getReg()) {
164       O << "(,";
165       printOp(IndexReg);
166       if (ScaleVal != 1)
167         O << "," << ScaleVal;
168       O << ")";
169     }
170     return;
171   }
172
173   if (DispSpec.isGlobalAddress()) {
174     printOp(DispSpec, true);
175   } else {
176     int DispVal = DispSpec.getImmedValue();
177     if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg()))
178       O << DispVal;
179   }
180
181   if (IndexReg.getReg() || BaseReg.getReg()) {
182     O << "(";
183     if (BaseReg.getReg())
184       printOp(BaseReg);
185
186     if (IndexReg.getReg()) {
187       O << ",";
188       printOp(IndexReg);
189       if (ScaleVal != 1)
190         O << "," << ScaleVal;
191     }
192
193     O << ")";
194   }
195 }
196
197 /// printMachineInstruction -- Print out a single X86 LLVM instruction
198 /// MI in Intel syntax to the current output stream.
199 ///
200 void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
201   ++EmittedInsts;
202   // Call the autogenerated instruction printer routines.
203   printInstruction(MI);
204 }
205
206 // Include the auto-generated portion of the assembly writer.
207 #include "X86GenAsmWriter.inc"
208