Print .mask and .fmask with the target streamer.
[oota-llvm.git] / lib / Target / Mips / MCTargetDesc / MipsTargetStreamer.cpp
1 //===-- MipsTargetStreamer.cpp - Mips Target Streamer Methods -------------===//
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 provides Mips specific target streamer methods.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "InstPrinter/MipsInstPrinter.h"
15 #include "MipsTargetStreamer.h"
16 #include "MipsMCTargetDesc.h"
17 #include "llvm/MC/MCELF.h"
18 #include "llvm/MC/MCSymbol.h"
19 #include "llvm/MC/MCSubtargetInfo.h"
20 #include "llvm/Support/CommandLine.h"
21 #include "llvm/Support/ELF.h"
22 #include "llvm/Support/ErrorHandling.h"
23 #include "llvm/Support/FormattedStream.h"
24
25 using namespace llvm;
26
27 // Pin vtable to this file.
28 void MipsTargetStreamer::anchor() {}
29
30 MipsTargetStreamer::MipsTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {}
31
32 MipsTargetAsmStreamer::MipsTargetAsmStreamer(MCStreamer &S,
33                                              formatted_raw_ostream &OS)
34     : MipsTargetStreamer(S), OS(OS) {}
35
36 void MipsTargetAsmStreamer::emitDirectiveSetMicroMips() {
37   OS << "\t.set\tmicromips\n";
38 }
39
40 void MipsTargetAsmStreamer::emitDirectiveSetNoMicroMips() {
41   OS << "\t.set\tnomicromips\n";
42 }
43
44 void MipsTargetAsmStreamer::emitDirectiveSetMips16() {
45   OS << "\t.set\tmips16\n";
46 }
47
48 void MipsTargetAsmStreamer::emitDirectiveSetNoMips16() {
49   OS << "\t.set\tnomips16\n";
50 }
51
52 void MipsTargetAsmStreamer::emitDirectiveSetReorder() {
53   OS << "\t.set\treorder\n";
54 }
55
56 void MipsTargetAsmStreamer::emitDirectiveSetNoReorder() {
57   OS << "\t.set\tnoreorder\n";
58 }
59
60 void MipsTargetAsmStreamer::emitDirectiveSetMacro() {
61   OS << "\t.set\tmacro\n";
62 }
63
64 void MipsTargetAsmStreamer::emitDirectiveSetNoMacro() {
65   OS << "\t.set\tnomacro\n";
66 }
67
68 void MipsTargetAsmStreamer::emitDirectiveSetAt() {
69   OS << "\t.set\tat\n";
70 }
71
72 void MipsTargetAsmStreamer::emitDirectiveSetNoAt() {
73   OS << "\t.set\tnoat\n";
74 }
75
76 void MipsTargetAsmStreamer::emitDirectiveEnd(StringRef Name) {
77   OS << "\t.end\t" << Name << '\n';
78 }
79
80 void MipsTargetAsmStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {
81   OS << "\t.ent\t" << Symbol.getName() << '\n';
82 }
83
84 void MipsTargetAsmStreamer::emitDirectiveAbiCalls() { OS << "\t.abicalls\n"; }
85 void MipsTargetAsmStreamer::emitDirectiveOptionPic0() {
86   OS << "\t.option\tpic0\n";
87 }
88
89 void MipsTargetAsmStreamer::emitFrame(unsigned StackReg, unsigned StackSize,
90                                       unsigned ReturnReg) {
91   OS << "\t.frame\t$"
92      << StringRef(MipsInstPrinter::getRegisterName(StackReg)).lower() << ","
93      << StackSize << ",$"
94      << StringRef(MipsInstPrinter::getRegisterName(ReturnReg)).lower() << '\n';
95 }
96
97 // Print a 32 bit hex number with all numbers.
98 static void printHex32(unsigned Value, raw_ostream &OS) {
99   OS << "0x";
100   for (int i = 7; i >= 0; i--)
101     OS.write_hex((Value & (0xF << (i*4))) >> (i*4));
102 }
103
104 void MipsTargetAsmStreamer::emitMask(unsigned CPUBitmask,
105                                      int CPUTopSavedRegOff) {
106   OS << "\t.mask \t";
107   printHex32(CPUBitmask, OS);
108   OS << ',' << CPUTopSavedRegOff << '\n';
109 }
110
111 void MipsTargetAsmStreamer::emitFMask(unsigned FPUBitmask,
112                                       int FPUTopSavedRegOff) {
113   OS << "\t.fmask\t";
114   printHex32(FPUBitmask, OS);
115   OS << "," << FPUTopSavedRegOff << '\n';
116 }
117
118 // This part is for ELF object output.
119 MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S,
120                                              const MCSubtargetInfo &STI)
121     : MipsTargetStreamer(S), MicroMipsEnabled(false) {
122   MCAssembler &MCA = getStreamer().getAssembler();
123   uint64_t Features = STI.getFeatureBits();
124   Triple T(STI.getTargetTriple());
125
126   // Update e_header flags
127   unsigned EFlags = 0;
128
129   // Architecture
130   if (Features & Mips::FeatureMips64r2)
131     EFlags |= ELF::EF_MIPS_ARCH_64R2;
132   else if (Features & Mips::FeatureMips64)
133     EFlags |= ELF::EF_MIPS_ARCH_64;
134   else if (Features & Mips::FeatureMips32r2)
135     EFlags |= ELF::EF_MIPS_ARCH_32R2;
136   else if (Features & Mips::FeatureMips32)
137     EFlags |= ELF::EF_MIPS_ARCH_32;
138
139   if (T.isArch64Bit()) {
140     EFlags |= ELF::EF_MIPS_ABI2;
141   } else {
142     if (Features & Mips::FeatureMips64r2 || Features & Mips::FeatureMips64)
143       EFlags |= ELF::EF_MIPS_32BITMODE;
144
145     // ABI
146     EFlags |= ELF::EF_MIPS_ABI_O32;
147   }
148
149   MCA.setELFHeaderEFlags(EFlags);
150 }
151
152 void MipsTargetELFStreamer::emitLabel(MCSymbol *Symbol) {
153   if (!isMicroMipsEnabled())
154     return;
155   MCSymbolData &Data = getStreamer().getOrCreateSymbolData(Symbol);
156   uint8_t Type = MCELF::GetType(Data);
157   if (Type != ELF::STT_FUNC)
158     return;
159
160   // The "other" values are stored in the last 6 bits of the second byte
161   // The traditional defines for STO values assume the full byte and thus
162   // the shift to pack it.
163   MCELF::setOther(Data, ELF::STO_MIPS_MICROMIPS >> 2);
164 }
165
166 MCELFStreamer &MipsTargetELFStreamer::getStreamer() {
167   return static_cast<MCELFStreamer &>(Streamer);
168 }
169
170 void MipsTargetELFStreamer::emitDirectiveSetMicroMips() {
171   MicroMipsEnabled = true;
172
173   MCAssembler &MCA = getStreamer().getAssembler();
174   unsigned Flags = MCA.getELFHeaderEFlags();
175   Flags |= ELF::EF_MIPS_MICROMIPS;
176   MCA.setELFHeaderEFlags(Flags);
177 }
178
179 void MipsTargetELFStreamer::emitDirectiveSetNoMicroMips() {
180   MicroMipsEnabled = false;
181 }
182
183 void MipsTargetELFStreamer::emitDirectiveSetMips16() {
184   MCAssembler &MCA = getStreamer().getAssembler();
185   unsigned Flags = MCA.getELFHeaderEFlags();
186   Flags |= ELF::EF_MIPS_ARCH_ASE_M16;
187   MCA.setELFHeaderEFlags(Flags);
188 }
189
190 void MipsTargetELFStreamer::emitDirectiveSetNoMips16() {
191   // FIXME: implement.
192 }
193
194 void MipsTargetELFStreamer::emitDirectiveSetReorder() {
195   // FIXME: implement.
196 }
197
198 void MipsTargetELFStreamer::emitDirectiveSetNoReorder() {
199   MCAssembler &MCA = getStreamer().getAssembler();
200   unsigned Flags = MCA.getELFHeaderEFlags();
201   Flags |= ELF::EF_MIPS_NOREORDER;
202   MCA.setELFHeaderEFlags(Flags);
203 }
204
205 void MipsTargetELFStreamer::emitDirectiveSetMacro() {
206   // FIXME: implement.
207 }
208
209 void MipsTargetELFStreamer::emitDirectiveSetNoMacro() {
210   // FIXME: implement.
211 }
212
213 void MipsTargetELFStreamer::emitDirectiveSetAt() {
214   // FIXME: implement.
215 }
216
217 void MipsTargetELFStreamer::emitDirectiveSetNoAt() {
218   // FIXME: implement.
219 }
220
221 void MipsTargetELFStreamer::emitDirectiveEnd(StringRef Name) {
222   // FIXME: implement.
223 }
224
225 void MipsTargetELFStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {
226   // FIXME: implement.
227 }
228
229 void MipsTargetELFStreamer::emitDirectiveAbiCalls() {
230   MCAssembler &MCA = getStreamer().getAssembler();
231   unsigned Flags = MCA.getELFHeaderEFlags();
232   Flags |= ELF::EF_MIPS_CPIC | ELF::EF_MIPS_PIC;
233   MCA.setELFHeaderEFlags(Flags);
234 }
235 void MipsTargetELFStreamer::emitDirectiveOptionPic0() {
236   MCAssembler &MCA = getStreamer().getAssembler();
237   unsigned Flags = MCA.getELFHeaderEFlags();
238   Flags &= ~ELF::EF_MIPS_PIC;
239   MCA.setELFHeaderEFlags(Flags);
240 }
241
242 void MipsTargetELFStreamer::emitFrame(unsigned StackReg, unsigned StackSize,
243                                       unsigned ReturnReg) {
244   // FIXME: implement.
245 }
246
247 void MipsTargetELFStreamer::emitMask(unsigned CPUBitmask,
248                                      int CPUTopSavedRegOff) {
249   // FIXME: implement.
250 }
251
252 void MipsTargetELFStreamer::emitFMask(unsigned FPUBitmask,
253                                       int FPUTopSavedRegOff) {
254   // FIXME: implement.
255 }