blob: 0dec292908ef7c46648a37f0135c22baad569e4d [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()) {
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}
Jack Carter86ac5c12013-11-18 23:55:27 +0000151
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +0000152void MipsTargetELFStreamer::emitLabel(MCSymbol *Symbol) {
Rafael Espindola26e917c2014-01-15 03:07:12 +0000153 if (!isMicroMipsEnabled())
154 return;
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +0000155 MCSymbolData &Data = getStreamer().getOrCreateSymbolData(Symbol);
Rafael Espindola26e917c2014-01-15 03:07:12 +0000156 uint8_t Type = MCELF::GetType(Data);
157 if (Type != ELF::STT_FUNC)
158 return;
159
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +0000160 // 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.
Rafael Espindola26e917c2014-01-15 03:07:12 +0000163 MCELF::setOther(Data, ELF::STO_MIPS_MICROMIPS >> 2);
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +0000164}
165
Jack Carter86ac5c12013-11-18 23:55:27 +0000166MCELFStreamer &MipsTargetELFStreamer::getStreamer() {
Rafael Espindola24ea09e2014-01-26 06:06:37 +0000167 return static_cast<MCELFStreamer &>(Streamer);
Jack Carter86ac5c12013-11-18 23:55:27 +0000168}
169
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +0000170void MipsTargetELFStreamer::emitDirectiveSetMicroMips() {
171 MicroMipsEnabled = true;
Rafael Espindolacb1953f2014-01-26 06:57:13 +0000172
173 MCAssembler &MCA = getStreamer().getAssembler();
174 unsigned Flags = MCA.getELFHeaderEFlags();
175 Flags |= ELF::EF_MIPS_MICROMIPS;
176 MCA.setELFHeaderEFlags(Flags);
Jack Carter86ac5c12013-11-18 23:55:27 +0000177}
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +0000178
179void MipsTargetELFStreamer::emitDirectiveSetNoMicroMips() {
180 MicroMipsEnabled = false;
181}
182
Rafael Espindola6633d572014-01-14 18:57:12 +0000183void MipsTargetELFStreamer::emitDirectiveSetMips16() {
Rafael Espindolae7583752014-01-24 16:13:20 +0000184 MCAssembler &MCA = getStreamer().getAssembler();
185 unsigned Flags = MCA.getELFHeaderEFlags();
186 Flags |= ELF::EF_MIPS_ARCH_ASE_M16;
187 MCA.setELFHeaderEFlags(Flags);
Rafael Espindola6633d572014-01-14 18:57:12 +0000188}
189
190void MipsTargetELFStreamer::emitDirectiveSetNoMips16() {
191 // FIXME: implement.
192}
193
Rafael Espindolaeb0a8af2014-01-26 05:06:48 +0000194void MipsTargetELFStreamer::emitDirectiveSetReorder() {
195 // FIXME: implement.
196}
197
198void MipsTargetELFStreamer::emitDirectiveSetNoReorder() {
Rafael Espindolacb1953f2014-01-26 06:57:13 +0000199 MCAssembler &MCA = getStreamer().getAssembler();
200 unsigned Flags = MCA.getELFHeaderEFlags();
201 Flags |= ELF::EF_MIPS_NOREORDER;
202 MCA.setELFHeaderEFlags(Flags);
Rafael Espindolaeb0a8af2014-01-26 05:06:48 +0000203}
204
205void MipsTargetELFStreamer::emitDirectiveSetMacro() {
206 // FIXME: implement.
207}
208
209void MipsTargetELFStreamer::emitDirectiveSetNoMacro() {
210 // FIXME: implement.
211}
212
213void MipsTargetELFStreamer::emitDirectiveSetAt() {
214 // FIXME: implement.
215}
216
217void MipsTargetELFStreamer::emitDirectiveSetNoAt() {
218 // FIXME: implement.
219}
220
221void MipsTargetELFStreamer::emitDirectiveEnd(StringRef Name) {
222 // FIXME: implement.
223}
224
Rafael Espindola6633d572014-01-14 18:57:12 +0000225void MipsTargetELFStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {
226 // FIXME: implement.
227}
228
Jack Carter0cd3c192014-01-06 23:27:31 +0000229void MipsTargetELFStreamer::emitDirectiveAbiCalls() {
230 MCAssembler &MCA = getStreamer().getAssembler();
231 unsigned Flags = MCA.getELFHeaderEFlags();
Rafael Espindolacb1953f2014-01-26 06:57:13 +0000232 Flags |= ELF::EF_MIPS_CPIC | ELF::EF_MIPS_PIC;
Jack Carter0cd3c192014-01-06 23:27:31 +0000233 MCA.setELFHeaderEFlags(Flags);
234}
235void MipsTargetELFStreamer::emitDirectiveOptionPic0() {
236 MCAssembler &MCA = getStreamer().getAssembler();
237 unsigned Flags = MCA.getELFHeaderEFlags();
238 Flags &= ~ELF::EF_MIPS_PIC;
239 MCA.setELFHeaderEFlags(Flags);
240}
Rafael Espindola054234f2014-01-27 03:53:56 +0000241
242void MipsTargetELFStreamer::emitFrame(unsigned StackReg, unsigned StackSize,
243 unsigned ReturnReg) {
244 // FIXME: implement.
245}
Rafael Espindola25fa2912014-01-27 04:33:11 +0000246
247void MipsTargetELFStreamer::emitMask(unsigned CPUBitmask,
248 int CPUTopSavedRegOff) {
249 // FIXME: implement.
250}
251
252void MipsTargetELFStreamer::emitFMask(unsigned FPUBitmask,
253 int FPUTopSavedRegOff) {
254 // FIXME: implement.
255}