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