blob: 41b8ad6b96b8db1f353013de5e0c6b3a7572744c [file] [log] [blame]
Jack Carter86ac5c12013-11-18 23:55:27 +00001//===-- 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
Rafael Espindola054234f2014-01-27 03:53:56 +000014#include "InstPrinter/MipsInstPrinter.h"
Jack Carter86ac5c12013-11-18 23:55:27 +000015#include "MipsTargetStreamer.h"
Rafael Espindolacb1953f2014-01-26 06:57:13 +000016#include "MipsMCTargetDesc.h"
Jack Carter86ac5c12013-11-18 23:55:27 +000017#include "llvm/MC/MCELF.h"
18#include "llvm/MC/MCSymbol.h"
Rafael Espindolacb1953f2014-01-26 06:57:13 +000019#include "llvm/MC/MCSubtargetInfo.h"
Jack Carter86ac5c12013-11-18 23:55:27 +000020#include "llvm/Support/CommandLine.h"
Chandler Carruth8a8cd2b2014-01-07 11:48:04 +000021#include "llvm/Support/ELF.h"
Jack Carter86ac5c12013-11-18 23:55:27 +000022#include "llvm/Support/ErrorHandling.h"
23#include "llvm/Support/FormattedStream.h"
24
25using namespace llvm;
26
Jack Carter0cd3c192014-01-06 23:27:31 +000027// Pin vtable to this file.
Jack Carter86ac5c12013-11-18 23:55:27 +000028void MipsTargetStreamer::anchor() {}
29
Rafael Espindola24ea09e2014-01-26 06:06:37 +000030MipsTargetStreamer::MipsTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {}
31
32MipsTargetAsmStreamer::MipsTargetAsmStreamer(MCStreamer &S,
33 formatted_raw_ostream &OS)
34 : MipsTargetStreamer(S), OS(OS) {}
Jack Carter6ef6cc52013-11-19 20:53:28 +000035
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +000036void MipsTargetAsmStreamer::emitDirectiveSetMicroMips() {
37 OS << "\t.set\tmicromips\n";
Jack Carter6ef6cc52013-11-19 20:53:28 +000038}
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +000039
40void MipsTargetAsmStreamer::emitDirectiveSetNoMicroMips() {
41 OS << "\t.set\tnomicromips\n";
42}
43
Rafael Espindola6633d572014-01-14 18:57:12 +000044void MipsTargetAsmStreamer::emitDirectiveSetMips16() {
45 OS << "\t.set\tmips16\n";
46}
47
48void MipsTargetAsmStreamer::emitDirectiveSetNoMips16() {
49 OS << "\t.set\tnomips16\n";
50}
51
Rafael Espindolaeb0a8af2014-01-26 05:06:48 +000052void MipsTargetAsmStreamer::emitDirectiveSetReorder() {
53 OS << "\t.set\treorder\n";
54}
55
56void MipsTargetAsmStreamer::emitDirectiveSetNoReorder() {
57 OS << "\t.set\tnoreorder\n";
58}
59
60void MipsTargetAsmStreamer::emitDirectiveSetMacro() {
61 OS << "\t.set\tmacro\n";
62}
63
64void MipsTargetAsmStreamer::emitDirectiveSetNoMacro() {
65 OS << "\t.set\tnomacro\n";
66}
67
68void MipsTargetAsmStreamer::emitDirectiveSetAt() {
69 OS << "\t.set\tat\n";
70}
71
72void MipsTargetAsmStreamer::emitDirectiveSetNoAt() {
73 OS << "\t.set\tnoat\n";
74}
75
76void MipsTargetAsmStreamer::emitDirectiveEnd(StringRef Name) {
77 OS << "\t.end\t" << Name << '\n';
78}
79
Rafael Espindola6633d572014-01-14 18:57:12 +000080void MipsTargetAsmStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {
81 OS << "\t.ent\t" << Symbol.getName() << '\n';
82}
83
Jack Carter0cd3c192014-01-06 23:27:31 +000084void MipsTargetAsmStreamer::emitDirectiveAbiCalls() { OS << "\t.abicalls\n"; }
85void MipsTargetAsmStreamer::emitDirectiveOptionPic0() {
86 OS << "\t.option\tpic0\n";
87}
88
Rafael Espindola054234f2014-01-27 03:53:56 +000089void MipsTargetAsmStreamer::emitFrame(unsigned StackReg, unsigned StackSize,
90 unsigned ReturnReg) {
91 OS << "\t.frame\t$"
92 << StringRef(MipsInstPrinter::getRegisterName(StackReg)).lower() << ","
93 << StackSize << ",$"
Rafael Espindola25fa2912014-01-27 04:33:11 +000094 << StringRef(MipsInstPrinter::getRegisterName(ReturnReg)).lower() << '\n';
95}
96
97// Print a 32 bit hex number with all numbers.
98static 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
104void MipsTargetAsmStreamer::emitMask(unsigned CPUBitmask,
105 int CPUTopSavedRegOff) {
106 OS << "\t.mask \t";
107 printHex32(CPUBitmask, OS);
108 OS << ',' << CPUTopSavedRegOff << '\n';
109}
110
111void MipsTargetAsmStreamer::emitFMask(unsigned FPUBitmask,
112 int FPUTopSavedRegOff) {
113 OS << "\t.fmask\t";
114 printHex32(FPUBitmask, OS);
115 OS << "," << FPUTopSavedRegOff << '\n';
Rafael Espindola054234f2014-01-27 03:53:56 +0000116}
117
Jack Carter0cd3c192014-01-06 23:27:31 +0000118// This part is for ELF object output.
Rafael Espindolacb1953f2014-01-26 06:57:13 +0000119MipsTargetELFStreamer::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()) {
Matheus Almeida2e03f242014-01-28 19:24:11 +0000140 if (Features & Mips::FeatureN32)
141 EFlags |= ELF::EF_MIPS_ABI2;
142 else if (Features & Mips::FeatureO32) {
143 EFlags |= ELF::EF_MIPS_ABI_O32;
144 EFlags |= ELF::EF_MIPS_32BITMODE; /* Compatibility Mode */
145 }
146 // No need to set any bit for N64 which is the default ABI at the moment
147 // for 64-bit Mips architectures.
Rafael Espindolacb1953f2014-01-26 06:57:13 +0000148 } else {
149 if (Features & Mips::FeatureMips64r2 || Features & Mips::FeatureMips64)
150 EFlags |= ELF::EF_MIPS_32BITMODE;
151
152 // ABI
153 EFlags |= ELF::EF_MIPS_ABI_O32;
154 }
155
156 MCA.setELFHeaderEFlags(EFlags);
157}
Jack Carter86ac5c12013-11-18 23:55:27 +0000158
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +0000159void MipsTargetELFStreamer::emitLabel(MCSymbol *Symbol) {
Rafael Espindola26e917c2014-01-15 03:07:12 +0000160 if (!isMicroMipsEnabled())
161 return;
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +0000162 MCSymbolData &Data = getStreamer().getOrCreateSymbolData(Symbol);
Rafael Espindola26e917c2014-01-15 03:07:12 +0000163 uint8_t Type = MCELF::GetType(Data);
164 if (Type != ELF::STT_FUNC)
165 return;
166
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +0000167 // The "other" values are stored in the last 6 bits of the second byte
168 // The traditional defines for STO values assume the full byte and thus
169 // the shift to pack it.
Rafael Espindola26e917c2014-01-15 03:07:12 +0000170 MCELF::setOther(Data, ELF::STO_MIPS_MICROMIPS >> 2);
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +0000171}
172
Jack Carter86ac5c12013-11-18 23:55:27 +0000173MCELFStreamer &MipsTargetELFStreamer::getStreamer() {
Rafael Espindola24ea09e2014-01-26 06:06:37 +0000174 return static_cast<MCELFStreamer &>(Streamer);
Jack Carter86ac5c12013-11-18 23:55:27 +0000175}
176
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +0000177void MipsTargetELFStreamer::emitDirectiveSetMicroMips() {
178 MicroMipsEnabled = true;
Rafael Espindolacb1953f2014-01-26 06:57:13 +0000179
180 MCAssembler &MCA = getStreamer().getAssembler();
181 unsigned Flags = MCA.getELFHeaderEFlags();
182 Flags |= ELF::EF_MIPS_MICROMIPS;
183 MCA.setELFHeaderEFlags(Flags);
Jack Carter86ac5c12013-11-18 23:55:27 +0000184}
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +0000185
186void MipsTargetELFStreamer::emitDirectiveSetNoMicroMips() {
187 MicroMipsEnabled = false;
188}
189
Rafael Espindola6633d572014-01-14 18:57:12 +0000190void MipsTargetELFStreamer::emitDirectiveSetMips16() {
Rafael Espindolae7583752014-01-24 16:13:20 +0000191 MCAssembler &MCA = getStreamer().getAssembler();
192 unsigned Flags = MCA.getELFHeaderEFlags();
193 Flags |= ELF::EF_MIPS_ARCH_ASE_M16;
194 MCA.setELFHeaderEFlags(Flags);
Rafael Espindola6633d572014-01-14 18:57:12 +0000195}
196
197void MipsTargetELFStreamer::emitDirectiveSetNoMips16() {
198 // FIXME: implement.
199}
200
Rafael Espindolaeb0a8af2014-01-26 05:06:48 +0000201void MipsTargetELFStreamer::emitDirectiveSetReorder() {
202 // FIXME: implement.
203}
204
205void MipsTargetELFStreamer::emitDirectiveSetNoReorder() {
Rafael Espindolacb1953f2014-01-26 06:57:13 +0000206 MCAssembler &MCA = getStreamer().getAssembler();
207 unsigned Flags = MCA.getELFHeaderEFlags();
208 Flags |= ELF::EF_MIPS_NOREORDER;
209 MCA.setELFHeaderEFlags(Flags);
Rafael Espindolaeb0a8af2014-01-26 05:06:48 +0000210}
211
212void MipsTargetELFStreamer::emitDirectiveSetMacro() {
213 // FIXME: implement.
214}
215
216void MipsTargetELFStreamer::emitDirectiveSetNoMacro() {
217 // FIXME: implement.
218}
219
220void MipsTargetELFStreamer::emitDirectiveSetAt() {
221 // FIXME: implement.
222}
223
224void MipsTargetELFStreamer::emitDirectiveSetNoAt() {
225 // FIXME: implement.
226}
227
228void MipsTargetELFStreamer::emitDirectiveEnd(StringRef Name) {
229 // FIXME: implement.
230}
231
Rafael Espindola6633d572014-01-14 18:57:12 +0000232void MipsTargetELFStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {
233 // FIXME: implement.
234}
235
Jack Carter0cd3c192014-01-06 23:27:31 +0000236void MipsTargetELFStreamer::emitDirectiveAbiCalls() {
237 MCAssembler &MCA = getStreamer().getAssembler();
238 unsigned Flags = MCA.getELFHeaderEFlags();
Rafael Espindolacb1953f2014-01-26 06:57:13 +0000239 Flags |= ELF::EF_MIPS_CPIC | ELF::EF_MIPS_PIC;
Jack Carter0cd3c192014-01-06 23:27:31 +0000240 MCA.setELFHeaderEFlags(Flags);
241}
242void MipsTargetELFStreamer::emitDirectiveOptionPic0() {
243 MCAssembler &MCA = getStreamer().getAssembler();
244 unsigned Flags = MCA.getELFHeaderEFlags();
245 Flags &= ~ELF::EF_MIPS_PIC;
246 MCA.setELFHeaderEFlags(Flags);
247}
Rafael Espindola054234f2014-01-27 03:53:56 +0000248
249void MipsTargetELFStreamer::emitFrame(unsigned StackReg, unsigned StackSize,
250 unsigned ReturnReg) {
251 // FIXME: implement.
252}
Rafael Espindola25fa2912014-01-27 04:33:11 +0000253
254void MipsTargetELFStreamer::emitMask(unsigned CPUBitmask,
255 int CPUTopSavedRegOff) {
256 // FIXME: implement.
257}
258
259void MipsTargetELFStreamer::emitFMask(unsigned FPUBitmask,
260 int FPUTopSavedRegOff) {
261 // FIXME: implement.
262}