46ae286895a934f3b508add6fe68b879e6973d8f
[oota-llvm.git] / lib / Target / Alpha / AlphaAsmPrinter.cpp
1 //===-- AlphaAsmPrinter.cpp - Alpha 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 Alpha assembly language.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #define DEBUG_TYPE "asm-printer"
16 #include "Alpha.h"
17 #include "AlphaInstrInfo.h"
18 #include "AlphaTargetMachine.h"
19 #include "llvm/Module.h"
20 #include "llvm/Type.h"
21 #include "llvm/Assembly/Writer.h"
22 #include "llvm/CodeGen/AsmPrinter.h"
23 #include "llvm/MC/MCStreamer.h"
24 #include "llvm/MC/MCAsmInfo.h"
25 #include "llvm/MC/MCSymbol.h"
26 #include "llvm/Target/Mangler.h"
27 #include "llvm/Target/TargetLoweringObjectFile.h"
28 #include "llvm/Target/TargetMachine.h"
29 #include "llvm/Target/TargetRegistry.h"
30 #include "llvm/ADT/SmallString.h"
31 #include "llvm/Support/raw_ostream.h"
32 using namespace llvm;
33
34 namespace {
35   struct AlphaAsmPrinter : public AsmPrinter {
36     /// Unique incrementer for label values for referencing Global values.
37     ///
38
39     explicit AlphaAsmPrinter(TargetMachine &tm, MCStreamer &Streamer)
40       : AsmPrinter(tm, Streamer) {}
41
42     virtual const char *getPassName() const {
43       return "Alpha Assembly Printer";
44     }
45     void printInstruction(const MachineInstr *MI, raw_ostream &O);
46     void EmitInstruction(const MachineInstr *MI) {
47       SmallString<128> Str;
48       raw_svector_ostream OS(Str);
49       printInstruction(MI, OS);
50       OutStreamer.EmitRawText(OS.str());
51     }
52     static const char *getRegisterName(unsigned RegNo);
53
54     void printOp(const MachineOperand &MO, raw_ostream &O);
55     void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
56     virtual void EmitFunctionBodyStart();
57     virtual void EmitFunctionBodyEnd(); 
58     void EmitStartOfAsmFile(Module &M);
59
60     bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
61                          unsigned AsmVariant, const char *ExtraCode,
62                          raw_ostream &O);
63     bool PrintAsmMemoryOperand(const MachineInstr *MI,
64                                unsigned OpNo, unsigned AsmVariant,
65                                const char *ExtraCode, raw_ostream &O);
66   };
67 } // end of anonymous namespace
68
69 #include "AlphaGenAsmWriter.inc"
70
71 void AlphaAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
72                                    raw_ostream &O) {
73   const MachineOperand &MO = MI->getOperand(opNum);
74   if (MO.isReg()) {
75     assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
76            "Not physreg??");
77     O << getRegisterName(MO.getReg());
78   } else if (MO.isImm()) {
79     O << MO.getImm();
80     assert(MO.getImm() < (1 << 30));
81   } else {
82     printOp(MO, O);
83   }
84 }
85
86
87 void AlphaAsmPrinter::printOp(const MachineOperand &MO, raw_ostream &O) {
88   switch (MO.getType()) {
89   case MachineOperand::MO_Register:
90     O << getRegisterName(MO.getReg());
91     return;
92
93   case MachineOperand::MO_Immediate:
94     assert(0 && "printOp() does not handle immediate values");
95     return;
96
97   case MachineOperand::MO_MachineBasicBlock:
98     O << *MO.getMBB()->getSymbol();
99     return;
100
101   case MachineOperand::MO_ConstantPoolIndex:
102     O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_"
103       << MO.getIndex();
104     return;
105
106   case MachineOperand::MO_ExternalSymbol:
107     O << MO.getSymbolName();
108     return;
109
110   case MachineOperand::MO_GlobalAddress:
111     O << *Mang->getSymbol(MO.getGlobal());
112     return;
113
114   case MachineOperand::MO_JumpTableIndex:
115     O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
116       << '_' << MO.getIndex();
117     return;
118
119   default:
120     O << "<unknown operand type: " << MO.getType() << ">";
121     return;
122   }
123 }
124
125 /// EmitFunctionBodyStart - Targets can override this to emit stuff before
126 /// the first basic block in the function.
127 void AlphaAsmPrinter::EmitFunctionBodyStart() {
128   OutStreamer.EmitRawText("\t.ent " + Twine(CurrentFnSym->getName()));
129 }
130
131 /// EmitFunctionBodyEnd - Targets can override this to emit stuff after
132 /// the last basic block in the function.
133 void AlphaAsmPrinter::EmitFunctionBodyEnd() {
134   OutStreamer.EmitRawText("\t.end " + Twine(CurrentFnSym->getName()));
135 }
136
137 void AlphaAsmPrinter::EmitStartOfAsmFile(Module &M) {
138   OutStreamer.EmitRawText(StringRef("\t.arch ev6"));
139   OutStreamer.EmitRawText(StringRef("\t.set noat"));
140 }
141
142 /// PrintAsmOperand - Print out an operand for an inline asm expression.
143 ///
144 bool AlphaAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
145                                       unsigned AsmVariant,
146                                       const char *ExtraCode, raw_ostream &O) {
147   printOperand(MI, OpNo, O);
148   return false;
149 }
150
151 bool AlphaAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
152                                             unsigned OpNo, unsigned AsmVariant,
153                                             const char *ExtraCode,
154                                             raw_ostream &O) {
155   if (ExtraCode && ExtraCode[0])
156     return true; // Unknown modifier.
157   O << "0(";
158   printOperand(MI, OpNo, O);
159   O << ")";
160   return false;
161 }
162
163 // Force static initialization.
164 extern "C" void LLVMInitializeAlphaAsmPrinter() { 
165   RegisterAsmPrinter<AlphaAsmPrinter> X(TheAlphaTarget);
166 }