blob: 6b57dff2c83d8c1b74bc3d701418f801a50ce61d [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}
66
67// This part is for ELF object output.
Rafael Espindola9d795ca2014-01-15 03:27:26 +000068MipsTargetELFStreamer::MipsTargetELFStreamer() : MicroMipsEnabled(false) {}
Jack Carter86ac5c12013-11-18 23:55:27 +000069
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +000070void MipsTargetELFStreamer::emitLabel(MCSymbol *Symbol) {
Rafael Espindola26e917c2014-01-15 03:07:12 +000071 if (!isMicroMipsEnabled())
72 return;
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +000073 MCSymbolData &Data = getStreamer().getOrCreateSymbolData(Symbol);
Rafael Espindola26e917c2014-01-15 03:07:12 +000074 uint8_t Type = MCELF::GetType(Data);
75 if (Type != ELF::STT_FUNC)
76 return;
77
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +000078 // The "other" values are stored in the last 6 bits of the second byte
79 // The traditional defines for STO values assume the full byte and thus
80 // the shift to pack it.
Rafael Espindola26e917c2014-01-15 03:07:12 +000081 MCELF::setOther(Data, ELF::STO_MIPS_MICROMIPS >> 2);
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +000082}
83
Jack Carter86ac5c12013-11-18 23:55:27 +000084MCELFStreamer &MipsTargetELFStreamer::getStreamer() {
85 return static_cast<MCELFStreamer &>(*Streamer);
86}
87
88void MipsTargetELFStreamer::emitMipsHackELFFlags(unsigned Flags) {
89 MCAssembler &MCA = getStreamer().getAssembler();
90 MCA.setELFHeaderEFlags(Flags);
91}
92
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +000093void MipsTargetELFStreamer::emitDirectiveSetMicroMips() {
94 MicroMipsEnabled = true;
Jack Carter86ac5c12013-11-18 23:55:27 +000095}
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +000096
97void MipsTargetELFStreamer::emitDirectiveSetNoMicroMips() {
98 MicroMipsEnabled = false;
99}
100
Rafael Espindola6633d572014-01-14 18:57:12 +0000101void MipsTargetELFStreamer::emitDirectiveSetMips16() {
Rafael Espindolae7583752014-01-24 16:13:20 +0000102 MCAssembler &MCA = getStreamer().getAssembler();
103 unsigned Flags = MCA.getELFHeaderEFlags();
104 Flags |= ELF::EF_MIPS_ARCH_ASE_M16;
105 MCA.setELFHeaderEFlags(Flags);
Rafael Espindola6633d572014-01-14 18:57:12 +0000106}
107
108void MipsTargetELFStreamer::emitDirectiveSetNoMips16() {
109 // FIXME: implement.
110}
111
112void MipsTargetELFStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {
113 // FIXME: implement.
114}
115
Jack Carter0cd3c192014-01-06 23:27:31 +0000116void MipsTargetELFStreamer::emitDirectiveAbiCalls() {
117 MCAssembler &MCA = getStreamer().getAssembler();
118 unsigned Flags = MCA.getELFHeaderEFlags();
119 Flags |= ELF::EF_MIPS_CPIC;
120 MCA.setELFHeaderEFlags(Flags);
121}
122void MipsTargetELFStreamer::emitDirectiveOptionPic0() {
123 MCAssembler &MCA = getStreamer().getAssembler();
124 unsigned Flags = MCA.getELFHeaderEFlags();
125 Flags &= ~ELF::EF_MIPS_PIC;
126 MCA.setELFHeaderEFlags(Flags);
127}