fix PrintAsmOperand and PrintAsmMemoryOperand to pass down
[oota-llvm.git] / lib / Target / Mips / AsmPrinter / MipsAsmPrinter.cpp
1 //===-- MipsAsmPrinter.cpp - Mips LLVM assembly writer --------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // 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 GAS-format MIPS assembly language.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #define DEBUG_TYPE "mips-asm-printer"
16
17 #include "Mips.h"
18 #include "MipsSubtarget.h"
19 #include "MipsInstrInfo.h"
20 #include "MipsTargetMachine.h"
21 #include "MipsMachineFunction.h"
22 #include "llvm/Constants.h"
23 #include "llvm/DerivedTypes.h"
24 #include "llvm/Module.h"
25 #include "llvm/CodeGen/AsmPrinter.h"
26 #include "llvm/CodeGen/DwarfWriter.h"
27 #include "llvm/CodeGen/MachineFunctionPass.h"
28 #include "llvm/CodeGen/MachineConstantPool.h"
29 #include "llvm/CodeGen/MachineFrameInfo.h"
30 #include "llvm/CodeGen/MachineInstr.h"
31 #include "llvm/MC/MCStreamer.h"
32 #include "llvm/MC/MCAsmInfo.h"
33 #include "llvm/MC/MCSymbol.h"
34 #include "llvm/Target/Mangler.h"
35 #include "llvm/Target/TargetData.h"
36 #include "llvm/Target/TargetLoweringObjectFile.h" 
37 #include "llvm/Target/TargetMachine.h"
38 #include "llvm/Target/TargetOptions.h"
39 #include "llvm/Target/TargetRegistry.h"
40 #include "llvm/Support/ErrorHandling.h"
41 #include "llvm/ADT/StringExtras.h"
42 #include "llvm/Support/Debug.h"
43 #include "llvm/Support/CommandLine.h"
44 #include "llvm/Support/FormattedStream.h"
45 #include "llvm/Support/MathExtras.h"
46 #include <cctype>
47 using namespace llvm;
48
49 namespace {
50   class MipsAsmPrinter : public AsmPrinter {
51     const MipsSubtarget *Subtarget;
52   public:
53     explicit MipsAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM, 
54                             MCStreamer &Streamer)
55       : AsmPrinter(O, TM, Streamer) {
56       Subtarget = &TM.getSubtarget<MipsSubtarget>();
57     }
58
59     virtual const char *getPassName() const {
60       return "Mips Assembly Printer";
61     }
62
63     bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 
64                          unsigned AsmVariant, const char *ExtraCode,
65                          raw_ostream &O);
66     void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
67     void printUnsignedImm(const MachineInstr *MI, int opNum, raw_ostream &O);
68     void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O, 
69                          const char *Modifier = 0);
70     void printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O, 
71                          const char *Modifier = 0);
72     void printSavedRegsBitmask(raw_ostream &O);
73     void printHex32(unsigned int Value, raw_ostream &O);
74
75     const char *emitCurrentABIString();
76     void emitFrameDirective(raw_ostream &O);
77
78     void printInstruction(const MachineInstr *MI, raw_ostream &O); // autogen'd.
79     void EmitInstruction(const MachineInstr *MI) {
80       printInstruction(MI, O);
81       OutStreamer.AddBlankLine();
82     }
83     virtual void EmitFunctionBodyStart();
84     virtual void EmitFunctionBodyEnd();
85     static const char *getRegisterName(unsigned RegNo);
86
87     virtual void EmitFunctionEntryLabel();
88     void EmitStartOfAsmFile(Module &M);
89   };
90 } // end of anonymous namespace
91
92 #include "MipsGenAsmWriter.inc"
93
94 //===----------------------------------------------------------------------===//
95 //
96 //  Mips Asm Directives
97 //
98 //  -- Frame directive "frame Stackpointer, Stacksize, RARegister"
99 //  Describe the stack frame.
100 //
101 //  -- Mask directives "(f)mask  bitmask, offset" 
102 //  Tells the assembler which registers are saved and where.
103 //  bitmask - contain a little endian bitset indicating which registers are 
104 //            saved on function prologue (e.g. with a 0x80000000 mask, the 
105 //            assembler knows the register 31 (RA) is saved at prologue.
106 //  offset  - the position before stack pointer subtraction indicating where 
107 //            the first saved register on prologue is located. (e.g. with a
108 //
109 //  Consider the following function prologue:
110 //
111 //    .frame  $fp,48,$ra
112 //    .mask   0xc0000000,-8
113 //       addiu $sp, $sp, -48
114 //       sw $ra, 40($sp)
115 //       sw $fp, 36($sp)
116 //
117 //    With a 0xc0000000 mask, the assembler knows the register 31 (RA) and 
118 //    30 (FP) are saved at prologue. As the save order on prologue is from 
119 //    left to right, RA is saved first. A -8 offset means that after the 
120 //    stack pointer subtration, the first register in the mask (RA) will be
121 //    saved at address 48-8=40.
122 //
123 //===----------------------------------------------------------------------===//
124
125 //===----------------------------------------------------------------------===//
126 // Mask directives
127 //===----------------------------------------------------------------------===//
128
129 // Create a bitmask with all callee saved registers for CPU or Floating Point 
130 // registers. For CPU registers consider RA, GP and FP for saving if necessary.
131 void MipsAsmPrinter::printSavedRegsBitmask(raw_ostream &O) {
132   const TargetRegisterInfo &RI = *TM.getRegisterInfo();
133   const MipsFunctionInfo *MipsFI = MF->getInfo<MipsFunctionInfo>();
134              
135   // CPU and FPU Saved Registers Bitmasks
136   unsigned int CPUBitmask = 0;
137   unsigned int FPUBitmask = 0;
138
139   // Set the CPU and FPU Bitmasks
140   const MachineFrameInfo *MFI = MF->getFrameInfo();
141   const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
142   for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
143     unsigned RegNum = MipsRegisterInfo::getRegisterNumbering(CSI[i].getReg());
144     if (CSI[i].getRegClass() == Mips::CPURegsRegisterClass)
145       CPUBitmask |= (1 << RegNum);
146     else
147       FPUBitmask |= (1 << RegNum);
148   }
149
150   // Return Address and Frame registers must also be set in CPUBitmask.
151   if (RI.hasFP(*MF)) 
152     CPUBitmask |= (1 << MipsRegisterInfo::
153                 getRegisterNumbering(RI.getFrameRegister(*MF)));
154   
155   if (MFI->hasCalls()) 
156     CPUBitmask |= (1 << MipsRegisterInfo::
157                 getRegisterNumbering(RI.getRARegister()));
158
159   // Print CPUBitmask
160   O << "\t.mask \t"; printHex32(CPUBitmask, O);
161   O << ',' << MipsFI->getCPUTopSavedRegOff() << '\n';
162
163   // Print FPUBitmask
164   O << "\t.fmask\t"; printHex32(FPUBitmask, O); O << ","
165     << MipsFI->getFPUTopSavedRegOff() << '\n';
166 }
167
168 // Print a 32 bit hex number with all numbers.
169 void MipsAsmPrinter::printHex32(unsigned Value, raw_ostream &O) {
170   O << "0x";
171   for (int i = 7; i >= 0; i--) 
172     O << utohexstr((Value & (0xF << (i*4))) >> (i*4));
173 }
174
175 //===----------------------------------------------------------------------===//
176 // Frame and Set directives
177 //===----------------------------------------------------------------------===//
178
179 /// Frame Directive
180 void MipsAsmPrinter::emitFrameDirective(raw_ostream &O) {
181   const TargetRegisterInfo &RI = *TM.getRegisterInfo();
182
183   unsigned stackReg  = RI.getFrameRegister(*MF);
184   unsigned returnReg = RI.getRARegister();
185   unsigned stackSize = MF->getFrameInfo()->getStackSize();
186
187
188   O << "\t.frame\t" << '$' << LowercaseString(getRegisterName(stackReg))
189                     << ',' << stackSize << ','
190                     << '$' << LowercaseString(getRegisterName(returnReg))
191                     << '\n';
192 }
193
194 /// Emit Set directives.
195 const char *MipsAsmPrinter::emitCurrentABIString() {  
196   switch(Subtarget->getTargetABI()) {
197     case MipsSubtarget::O32:  return "abi32";  
198     case MipsSubtarget::O64:  return "abiO64";
199     case MipsSubtarget::N32:  return "abiN32";
200     case MipsSubtarget::N64:  return "abi64";
201     case MipsSubtarget::EABI: return "eabi32"; // TODO: handle eabi64
202     default: break;
203   }
204
205   llvm_unreachable("Unknown Mips ABI");
206   return NULL;
207 }  
208
209 void MipsAsmPrinter::EmitFunctionEntryLabel() {
210   O << "\t.ent\t" << *CurrentFnSym << '\n';
211   OutStreamer.EmitLabel(CurrentFnSym);
212 }
213
214 /// EmitFunctionBodyStart - Targets can override this to emit stuff before
215 /// the first basic block in the function.
216 void MipsAsmPrinter::EmitFunctionBodyStart() {
217   emitFrameDirective(O);
218   printSavedRegsBitmask(O);
219 }
220
221 /// EmitFunctionBodyEnd - Targets can override this to emit stuff after
222 /// the last basic block in the function.
223 void MipsAsmPrinter::EmitFunctionBodyEnd() {
224   // There are instruction for this macros, but they must
225   // always be at the function end, and we can't emit and
226   // break with BB logic. 
227   O << "\t.set\tmacro\n"; 
228   O << "\t.set\treorder\n"; 
229   
230   O << "\t.end\t" << *CurrentFnSym << '\n';
231 }
232
233
234 // Print out an operand for an inline asm expression.
235 bool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 
236                                      unsigned AsmVariant,const char *ExtraCode,
237                                      raw_ostream &O) {
238   // Does this asm operand have a single letter operand modifier?
239   if (ExtraCode && ExtraCode[0]) 
240     return true; // Unknown modifier.
241
242   printOperand(MI, OpNo, O);
243   return false;
244 }
245
246 void MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
247                                   raw_ostream &O) {
248   const MachineOperand &MO = MI->getOperand(opNum);
249   bool closeP = false;
250
251   if (MO.getTargetFlags())
252     closeP = true;
253
254   switch(MO.getTargetFlags()) {
255   case MipsII::MO_GPREL:    O << "%gp_rel("; break;
256   case MipsII::MO_GOT_CALL: O << "%call16("; break;
257   case MipsII::MO_GOT:
258     if (MI->getOpcode() == Mips::LW)
259       O << "%got(";
260     else
261       O << "%lo(";
262     break;
263   case MipsII::MO_ABS_HILO:
264     if (MI->getOpcode() == Mips::LUi)
265       O << "%hi(";
266     else
267       O << "%lo(";     
268     break;
269   }
270
271   switch (MO.getType()) {
272     case MachineOperand::MO_Register:
273       O << '$' << LowercaseString(getRegisterName(MO.getReg()));
274       break;
275
276     case MachineOperand::MO_Immediate:
277       O << (short int)MO.getImm();
278       break;
279
280     case MachineOperand::MO_MachineBasicBlock:
281       O << *MO.getMBB()->getSymbol();
282       return;
283
284     case MachineOperand::MO_GlobalAddress:
285       O << *Mang->getSymbol(MO.getGlobal());
286       break;
287
288     case MachineOperand::MO_ExternalSymbol:
289       O << *GetExternalSymbolSymbol(MO.getSymbolName());
290       break;
291
292     case MachineOperand::MO_JumpTableIndex:
293       O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
294         << '_' << MO.getIndex();
295       break;
296
297     case MachineOperand::MO_ConstantPoolIndex:
298       O << MAI->getPrivateGlobalPrefix() << "CPI"
299         << getFunctionNumber() << "_" << MO.getIndex();
300       if (MO.getOffset())
301         O << "+" << MO.getOffset();
302       break;
303   
304     default:
305       llvm_unreachable("<unknown operand type>");
306   }
307
308   if (closeP) O << ")";
309 }
310
311 void MipsAsmPrinter::printUnsignedImm(const MachineInstr *MI, int opNum,
312                                       raw_ostream &O) {
313   const MachineOperand &MO = MI->getOperand(opNum);
314   if (MO.getType() == MachineOperand::MO_Immediate)
315     O << (unsigned short int)MO.getImm();
316   else 
317     printOperand(MI, opNum, O);
318 }
319
320 void MipsAsmPrinter::
321 printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
322                 const char *Modifier) {
323   // when using stack locations for not load/store instructions
324   // print the same way as all normal 3 operand instructions.
325   if (Modifier && !strcmp(Modifier, "stackloc")) {
326     printOperand(MI, opNum+1, O);
327     O << ", ";
328     printOperand(MI, opNum, O);
329     return;
330   }
331
332   // Load/Store memory operands -- imm($reg) 
333   // If PIC target the target is loaded as the 
334   // pattern lw $25,%call16($28)
335   printOperand(MI, opNum, O);
336   O << "(";
337   printOperand(MI, opNum+1, O);
338   O << ")";
339 }
340
341 void MipsAsmPrinter::
342 printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
343                 const char *Modifier) {
344   const MachineOperand& MO = MI->getOperand(opNum);
345   O << Mips::MipsFCCToString((Mips::CondCode)MO.getImm()); 
346 }
347
348 void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) {
349   // FIXME: Use SwitchSection.
350   
351   // Tell the assembler which ABI we are using
352   O << "\t.section .mdebug." << emitCurrentABIString() << '\n';
353
354   // TODO: handle O64 ABI
355   if (Subtarget->isABI_EABI())
356     O << "\t.section .gcc_compiled_long" << 
357       (Subtarget->isGP32bit() ? "32" : "64") << '\n';
358
359   // return to previous section
360   O << "\t.previous" << '\n'; 
361 }
362
363 // Force static initialization.
364 extern "C" void LLVMInitializeMipsAsmPrinter() { 
365   RegisterAsmPrinter<MipsAsmPrinter> X(TheMipsTarget);
366   RegisterAsmPrinter<MipsAsmPrinter> Y(TheMipselTarget);
367 }