Construct the MCStreamer before constructing the MCTargetStreamer.
[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 "MipsTargetStreamer.h"
15 #include "llvm/MC/MCELF.h"
16 #include "llvm/MC/MCSymbol.h"
17 #include "llvm/Support/CommandLine.h"
18 #include "llvm/Support/ELF.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "llvm/Support/FormattedStream.h"
21
22 using namespace llvm;
23
24 static cl::opt<bool> PrintHackDirectives("print-hack-directives",
25                                          cl::init(false), cl::Hidden);
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::emitMipsHackELFFlags(unsigned Flags) {
37   if (!PrintHackDirectives)
38     return;
39
40   OS << "\t.mips_hack_elf_flags 0x";
41   OS.write_hex(Flags);
42   OS << '\n';
43 }
44
45 void MipsTargetAsmStreamer::emitDirectiveSetMicroMips() {
46   OS << "\t.set\tmicromips\n";
47 }
48
49 void MipsTargetAsmStreamer::emitDirectiveSetNoMicroMips() {
50   OS << "\t.set\tnomicromips\n";
51 }
52
53 void MipsTargetAsmStreamer::emitDirectiveSetMips16() {
54   OS << "\t.set\tmips16\n";
55 }
56
57 void MipsTargetAsmStreamer::emitDirectiveSetNoMips16() {
58   OS << "\t.set\tnomips16\n";
59 }
60
61 void MipsTargetAsmStreamer::emitDirectiveSetReorder() {
62   OS << "\t.set\treorder\n";
63 }
64
65 void MipsTargetAsmStreamer::emitDirectiveSetNoReorder() {
66   OS << "\t.set\tnoreorder\n";
67 }
68
69 void MipsTargetAsmStreamer::emitDirectiveSetMacro() {
70   OS << "\t.set\tmacro\n";
71 }
72
73 void MipsTargetAsmStreamer::emitDirectiveSetNoMacro() {
74   OS << "\t.set\tnomacro\n";
75 }
76
77 void MipsTargetAsmStreamer::emitDirectiveSetAt() {
78   OS << "\t.set\tat\n";
79 }
80
81 void MipsTargetAsmStreamer::emitDirectiveSetNoAt() {
82   OS << "\t.set\tnoat\n";
83 }
84
85 void MipsTargetAsmStreamer::emitDirectiveEnd(StringRef Name) {
86   OS << "\t.end\t" << Name << '\n';
87 }
88
89 void MipsTargetAsmStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {
90   OS << "\t.ent\t" << Symbol.getName() << '\n';
91 }
92
93 void MipsTargetAsmStreamer::emitDirectiveAbiCalls() { OS << "\t.abicalls\n"; }
94 void MipsTargetAsmStreamer::emitDirectiveOptionPic0() {
95   OS << "\t.option\tpic0\n";
96 }
97
98 // This part is for ELF object output.
99 MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S)
100     : MipsTargetStreamer(S), MicroMipsEnabled(false) {}
101
102 void MipsTargetELFStreamer::emitLabel(MCSymbol *Symbol) {
103   if (!isMicroMipsEnabled())
104     return;
105   MCSymbolData &Data = getStreamer().getOrCreateSymbolData(Symbol);
106   uint8_t Type = MCELF::GetType(Data);
107   if (Type != ELF::STT_FUNC)
108     return;
109
110   // The "other" values are stored in the last 6 bits of the second byte
111   // The traditional defines for STO values assume the full byte and thus
112   // the shift to pack it.
113   MCELF::setOther(Data, ELF::STO_MIPS_MICROMIPS >> 2);
114 }
115
116 MCELFStreamer &MipsTargetELFStreamer::getStreamer() {
117   return static_cast<MCELFStreamer &>(Streamer);
118 }
119
120 void MipsTargetELFStreamer::emitMipsHackELFFlags(unsigned Flags) {
121   MCAssembler &MCA = getStreamer().getAssembler();
122   MCA.setELFHeaderEFlags(Flags);
123 }
124
125 void MipsTargetELFStreamer::emitDirectiveSetMicroMips() {
126   MicroMipsEnabled = true;
127 }
128
129 void MipsTargetELFStreamer::emitDirectiveSetNoMicroMips() {
130   MicroMipsEnabled = false;
131 }
132
133 void MipsTargetELFStreamer::emitDirectiveSetMips16() {
134   MCAssembler &MCA = getStreamer().getAssembler();
135   unsigned Flags = MCA.getELFHeaderEFlags();
136   Flags |= ELF::EF_MIPS_ARCH_ASE_M16;
137   MCA.setELFHeaderEFlags(Flags);
138 }
139
140 void MipsTargetELFStreamer::emitDirectiveSetNoMips16() {
141   // FIXME: implement.
142 }
143
144 void MipsTargetELFStreamer::emitDirectiveSetReorder() {
145   // FIXME: implement.
146 }
147
148 void MipsTargetELFStreamer::emitDirectiveSetNoReorder() {
149   // FIXME: implement.
150 }
151
152 void MipsTargetELFStreamer::emitDirectiveSetMacro() {
153   // FIXME: implement.
154 }
155
156 void MipsTargetELFStreamer::emitDirectiveSetNoMacro() {
157   // FIXME: implement.
158 }
159
160 void MipsTargetELFStreamer::emitDirectiveSetAt() {
161   // FIXME: implement.
162 }
163
164 void MipsTargetELFStreamer::emitDirectiveSetNoAt() {
165   // FIXME: implement.
166 }
167
168 void MipsTargetELFStreamer::emitDirectiveEnd(StringRef Name) {
169   // FIXME: implement.
170 }
171
172 void MipsTargetELFStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {
173   // FIXME: implement.
174 }
175
176 void MipsTargetELFStreamer::emitDirectiveAbiCalls() {
177   MCAssembler &MCA = getStreamer().getAssembler();
178   unsigned Flags = MCA.getELFHeaderEFlags();
179   Flags |= ELF::EF_MIPS_CPIC;
180   MCA.setELFHeaderEFlags(Flags);
181 }
182 void MipsTargetELFStreamer::emitDirectiveOptionPic0() {
183   MCAssembler &MCA = getStreamer().getAssembler();
184   unsigned Flags = MCA.getELFHeaderEFlags();
185   Flags &= ~ELF::EF_MIPS_PIC;
186   MCA.setELFHeaderEFlags(Flags);
187 }