blob: 786edf5d35f9e87a98a40c40938c1644654167d0 [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
14#include "MipsTargetStreamer.h"
15#include "llvm/MC/MCELF.h"
16#include "llvm/MC/MCSymbol.h"
17#include "llvm/Support/CommandLine.h"
Chandler Carruth8a8cd2b2014-01-07 11:48:04 +000018#include "llvm/Support/ELF.h"
Jack Carter86ac5c12013-11-18 23:55:27 +000019#include "llvm/Support/ErrorHandling.h"
20#include "llvm/Support/FormattedStream.h"
21
22using namespace llvm;
23
Jack Carter6ef6cc52013-11-19 20:53:28 +000024static cl::opt<bool> PrintHackDirectives("print-hack-directives",
25 cl::init(false), cl::Hidden);
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
Jack Carter6ef6cc52013-11-19 20:53:28 +000030MipsTargetAsmStreamer::MipsTargetAsmStreamer(formatted_raw_ostream &OS)
31 : OS(OS) {}
32
33void MipsTargetAsmStreamer::emitMipsHackELFFlags(unsigned Flags) {
34 if (!PrintHackDirectives)
35 return;
36
37 OS << "\t.mips_hack_elf_flags 0x";
38 OS.write_hex(Flags);
39 OS << '\n';
40}
Jack Carter6ef6cc52013-11-19 20:53:28 +000041
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +000042void MipsTargetAsmStreamer::emitDirectiveSetMicroMips() {
43 OS << "\t.set\tmicromips\n";
Jack Carter6ef6cc52013-11-19 20:53:28 +000044}
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +000045
46void MipsTargetAsmStreamer::emitDirectiveSetNoMicroMips() {
47 OS << "\t.set\tnomicromips\n";
48}
49
Rafael Espindola6633d572014-01-14 18:57:12 +000050void MipsTargetAsmStreamer::emitDirectiveSetMips16() {
51 OS << "\t.set\tmips16\n";
52}
53
54void MipsTargetAsmStreamer::emitDirectiveSetNoMips16() {
55 OS << "\t.set\tnomips16\n";
56}
57
58void MipsTargetAsmStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {
59 OS << "\t.ent\t" << Symbol.getName() << '\n';
60}
61
Jack Carter0cd3c192014-01-06 23:27:31 +000062void MipsTargetAsmStreamer::emitDirectiveAbiCalls() { OS << "\t.abicalls\n"; }
63void MipsTargetAsmStreamer::emitDirectiveOptionPic0() {
64 OS << "\t.option\tpic0\n";
65}
Jack Carter39536722014-01-22 23:08:42 +000066void MipsTargetAsmStreamer::emitDirectiveSetMips16(bool IsMips16) {
67 if (IsMips16)
68 OS << "\t.set\tmips16\n";
69 else
70 OS << "\t.set\tnomips16\n";
71}
Jack Carter0cd3c192014-01-06 23:27:31 +000072
73// This part is for ELF object output.
Rafael Espindola9d795ca2014-01-15 03:27:26 +000074MipsTargetELFStreamer::MipsTargetELFStreamer() : MicroMipsEnabled(false) {}
Jack Carter86ac5c12013-11-18 23:55:27 +000075
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +000076void MipsTargetELFStreamer::emitLabel(MCSymbol *Symbol) {
Rafael Espindola26e917c2014-01-15 03:07:12 +000077 if (!isMicroMipsEnabled())
78 return;
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +000079 MCSymbolData &Data = getStreamer().getOrCreateSymbolData(Symbol);
Rafael Espindola26e917c2014-01-15 03:07:12 +000080 uint8_t Type = MCELF::GetType(Data);
81 if (Type != ELF::STT_FUNC)
82 return;
83
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +000084 // The "other" values are stored in the last 6 bits of the second byte
85 // The traditional defines for STO values assume the full byte and thus
86 // the shift to pack it.
Rafael Espindola26e917c2014-01-15 03:07:12 +000087 MCELF::setOther(Data, ELF::STO_MIPS_MICROMIPS >> 2);
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +000088}
89
Jack Carter86ac5c12013-11-18 23:55:27 +000090MCELFStreamer &MipsTargetELFStreamer::getStreamer() {
91 return static_cast<MCELFStreamer &>(*Streamer);
92}
93
94void MipsTargetELFStreamer::emitMipsHackELFFlags(unsigned Flags) {
95 MCAssembler &MCA = getStreamer().getAssembler();
96 MCA.setELFHeaderEFlags(Flags);
97}
98
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +000099void MipsTargetELFStreamer::emitDirectiveSetMicroMips() {
100 MicroMipsEnabled = true;
Jack Carter86ac5c12013-11-18 23:55:27 +0000101}
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +0000102
103void MipsTargetELFStreamer::emitDirectiveSetNoMicroMips() {
104 MicroMipsEnabled = false;
105}
106
Rafael Espindola6633d572014-01-14 18:57:12 +0000107void MipsTargetELFStreamer::emitDirectiveSetMips16() {
108 // FIXME: implement.
109}
110
111void MipsTargetELFStreamer::emitDirectiveSetNoMips16() {
112 // FIXME: implement.
113}
114
115void MipsTargetELFStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {
116 // FIXME: implement.
117}
118
Jack Carter0cd3c192014-01-06 23:27:31 +0000119void MipsTargetELFStreamer::emitDirectiveAbiCalls() {
120 MCAssembler &MCA = getStreamer().getAssembler();
121 unsigned Flags = MCA.getELFHeaderEFlags();
122 Flags |= ELF::EF_MIPS_CPIC;
123 MCA.setELFHeaderEFlags(Flags);
124}
125void MipsTargetELFStreamer::emitDirectiveOptionPic0() {
126 MCAssembler &MCA = getStreamer().getAssembler();
127 unsigned Flags = MCA.getELFHeaderEFlags();
128 Flags &= ~ELF::EF_MIPS_PIC;
129 MCA.setELFHeaderEFlags(Flags);
130}
Jack Carter39536722014-01-22 23:08:42 +0000131void MipsTargetELFStreamer::emitDirectiveSetMips16(bool IsMips16) {
132 // Don't do anything for .set nomips16
133 if (!IsMips16)
134 return;
135
136 MCAssembler &MCA = getStreamer().getAssembler();
137 unsigned Flags = MCA.getELFHeaderEFlags();
138 Flags |= ELF::EF_MIPS_ARCH_ASE_M16;
139 MCA.setELFHeaderEFlags(Flags);
140}