Move TargetRegistry and TargetSelect from Target to Support where they belong.
[oota-llvm.git] / lib / Target / SystemZ / SystemZAsmPrinter.cpp
1 //===-- SystemZAsmPrinter.cpp - SystemZ 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 the SystemZ assembly language.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #define DEBUG_TYPE "asm-printer"
16 #include "SystemZ.h"
17 #include "SystemZInstrInfo.h"
18 #include "SystemZTargetMachine.h"
19 #include "llvm/Constants.h"
20 #include "llvm/DerivedTypes.h"
21 #include "llvm/Module.h"
22 #include "llvm/Assembly/Writer.h"
23 #include "llvm/CodeGen/AsmPrinter.h"
24 #include "llvm/CodeGen/MachineModuleInfo.h"
25 #include "llvm/CodeGen/MachineFunctionPass.h"
26 #include "llvm/CodeGen/MachineConstantPool.h"
27 #include "llvm/MC/MCStreamer.h"
28 #include "llvm/MC/MCAsmInfo.h"
29 #include "llvm/MC/MCSymbol.h"
30 #include "llvm/Target/Mangler.h"
31 #include "llvm/ADT/SmallString.h"
32 #include "llvm/Support/TargetRegistry.h"
33 #include "llvm/Support/raw_ostream.h"
34 using namespace llvm;
35
36 namespace {
37   class SystemZAsmPrinter : public AsmPrinter {
38   public:
39     SystemZAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
40       : AsmPrinter(TM, Streamer) {}
41
42     virtual const char *getPassName() const {
43       return "SystemZ Assembly Printer";
44     }
45
46     void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
47                       const char* Modifier = 0);
48     void printPCRelImmOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
49     void printRIAddrOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
50                             const char* Modifier = 0);
51     void printRRIAddrOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
52                              const char* Modifier = 0);
53     void printS16ImmOperand(const MachineInstr *MI, int OpNum, raw_ostream &O) {
54       O << (int16_t)MI->getOperand(OpNum).getImm();
55     }
56     void printU16ImmOperand(const MachineInstr *MI, int OpNum, raw_ostream &O) {
57       O << (uint16_t)MI->getOperand(OpNum).getImm();
58     }
59     void printS32ImmOperand(const MachineInstr *MI, int OpNum, raw_ostream &O) {
60       O << (int32_t)MI->getOperand(OpNum).getImm();
61     }
62     void printU32ImmOperand(const MachineInstr *MI, int OpNum, raw_ostream &O) {
63       O << (uint32_t)MI->getOperand(OpNum).getImm();
64     }
65
66     void printInstruction(const MachineInstr *MI, raw_ostream &O);
67     static const char *getRegisterName(unsigned RegNo);
68
69     void EmitInstruction(const MachineInstr *MI);
70   };
71 } // end of anonymous namespace
72
73 #include "SystemZGenAsmWriter.inc"
74
75 void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) {
76   SmallString<128> Str;
77   raw_svector_ostream OS(Str);
78   printInstruction(MI, OS);
79   OutStreamer.EmitRawText(OS.str());
80 }
81
82 void SystemZAsmPrinter::printPCRelImmOperand(const MachineInstr *MI, int OpNum,
83                                              raw_ostream &O) {
84   const MachineOperand &MO = MI->getOperand(OpNum);
85   switch (MO.getType()) {
86   case MachineOperand::MO_Immediate:
87     O << MO.getImm();
88     return;
89   case MachineOperand::MO_MachineBasicBlock:
90     O << *MO.getMBB()->getSymbol();
91     return;
92   case MachineOperand::MO_GlobalAddress: {
93     const GlobalValue *GV = MO.getGlobal();
94     O << *Mang->getSymbol(GV);
95
96     // Assemble calls via PLT for externally visible symbols if PIC.
97     if (TM.getRelocationModel() == Reloc::PIC_ &&
98         !GV->hasHiddenVisibility() && !GV->hasProtectedVisibility() &&
99         !GV->hasLocalLinkage())
100       O << "@PLT";
101
102     printOffset(MO.getOffset(), O);
103     return;
104   }
105   case MachineOperand::MO_ExternalSymbol: {
106     std::string Name(MAI->getGlobalPrefix());
107     Name += MO.getSymbolName();
108     O << Name;
109
110     if (TM.getRelocationModel() == Reloc::PIC_)
111       O << "@PLT";
112
113     return;
114   }
115   default:
116     assert(0 && "Not implemented yet!");
117   }
118 }
119
120
121 void SystemZAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
122                                      raw_ostream &O, const char *Modifier) {
123   const MachineOperand &MO = MI->getOperand(OpNum);
124   switch (MO.getType()) {
125   case MachineOperand::MO_Register: {
126     assert (TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
127             "Virtual registers should be already mapped!");
128     unsigned Reg = MO.getReg();
129     if (Modifier && strncmp(Modifier, "subreg", 6) == 0) {
130       if (strncmp(Modifier + 7, "even", 4) == 0)
131         Reg = TM.getRegisterInfo()->getSubReg(Reg, SystemZ::subreg_32bit);
132       else if (strncmp(Modifier + 7, "odd", 3) == 0)
133         Reg = TM.getRegisterInfo()->getSubReg(Reg, SystemZ::subreg_odd32);
134       else
135         assert(0 && "Invalid subreg modifier");
136     }
137
138     O << '%' << getRegisterName(Reg);
139     return;
140   }
141   case MachineOperand::MO_Immediate:
142     O << MO.getImm();
143     return;
144   case MachineOperand::MO_MachineBasicBlock:
145     O << *MO.getMBB()->getSymbol();
146     return;
147   case MachineOperand::MO_JumpTableIndex:
148     O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_'
149       << MO.getIndex();
150
151     return;
152   case MachineOperand::MO_ConstantPoolIndex:
153     O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
154       << MO.getIndex();
155
156     printOffset(MO.getOffset(), O);
157     break;
158   case MachineOperand::MO_GlobalAddress:
159     O << *Mang->getSymbol(MO.getGlobal());
160     break;
161   case MachineOperand::MO_ExternalSymbol: {
162     O << *GetExternalSymbolSymbol(MO.getSymbolName());
163     break;
164   }
165   default:
166     assert(0 && "Not implemented yet!");
167   }
168
169   switch (MO.getTargetFlags()) {
170   default: assert(0 && "Unknown target flag on GV operand");
171   case SystemZII::MO_NO_FLAG:
172     break;
173   case SystemZII::MO_GOTENT:    O << "@GOTENT";    break;
174   case SystemZII::MO_PLT:       O << "@PLT";       break;
175   }
176
177   printOffset(MO.getOffset(), O);
178 }
179
180 void SystemZAsmPrinter::printRIAddrOperand(const MachineInstr *MI, int OpNum,
181                                            raw_ostream &O,
182                                            const char *Modifier) {
183   const MachineOperand &Base = MI->getOperand(OpNum);
184
185   // Print displacement operand.
186   printOperand(MI, OpNum+1, O);
187
188   // Print base operand (if any)
189   if (Base.getReg()) {
190     O << '(';
191     printOperand(MI, OpNum, O);
192     O << ')';
193   }
194 }
195
196 void SystemZAsmPrinter::printRRIAddrOperand(const MachineInstr *MI, int OpNum,
197                                             raw_ostream &O,
198                                             const char *Modifier) {
199   const MachineOperand &Base = MI->getOperand(OpNum);
200   const MachineOperand &Index = MI->getOperand(OpNum+2);
201
202   // Print displacement operand.
203   printOperand(MI, OpNum+1, O);
204
205   // Print base operand (if any)
206   if (Base.getReg()) {
207     O << '(';
208     printOperand(MI, OpNum, O);
209     if (Index.getReg()) {
210       O << ',';
211       printOperand(MI, OpNum+2, O);
212     }
213     O << ')';
214   } else
215     assert(!Index.getReg() && "Should allocate base register first!");
216 }
217
218 // Force static initialization.
219 extern "C" void LLVMInitializeSystemZAsmPrinter() {
220   RegisterAsmPrinter<SystemZAsmPrinter> X(TheSystemZTarget);
221 }