14c1625b3cb23745dba38e205b20e7b63954d8067Jack Carter//===-- MipsTargetStreamer.cpp - Mips Target Streamer Methods -------------===//
24c1625b3cb23745dba38e205b20e7b63954d8067Jack Carter//
34c1625b3cb23745dba38e205b20e7b63954d8067Jack Carter//                     The LLVM Compiler Infrastructure
44c1625b3cb23745dba38e205b20e7b63954d8067Jack Carter//
54c1625b3cb23745dba38e205b20e7b63954d8067Jack Carter// This file is distributed under the University of Illinois Open Source
64c1625b3cb23745dba38e205b20e7b63954d8067Jack Carter// License. See LICENSE.TXT for details.
74c1625b3cb23745dba38e205b20e7b63954d8067Jack Carter//
84c1625b3cb23745dba38e205b20e7b63954d8067Jack Carter//===----------------------------------------------------------------------===//
94c1625b3cb23745dba38e205b20e7b63954d8067Jack Carter//
104c1625b3cb23745dba38e205b20e7b63954d8067Jack Carter// This file provides Mips specific target streamer methods.
114c1625b3cb23745dba38e205b20e7b63954d8067Jack Carter//
124c1625b3cb23745dba38e205b20e7b63954d8067Jack Carter//===----------------------------------------------------------------------===//
134c1625b3cb23745dba38e205b20e7b63954d8067Jack Carter
1436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "InstPrinter/MipsInstPrinter.h"
1536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "MipsMCTargetDesc.h"
1636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "MipsTargetObjectFile.h"
174c1625b3cb23745dba38e205b20e7b63954d8067Jack Carter#include "MipsTargetStreamer.h"
1836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCContext.h"
194c1625b3cb23745dba38e205b20e7b63954d8067Jack Carter#include "llvm/MC/MCELF.h"
2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCSectionELF.h"
2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCSubtargetInfo.h"
224c1625b3cb23745dba38e205b20e7b63954d8067Jack Carter#include "llvm/MC/MCSymbol.h"
234c1625b3cb23745dba38e205b20e7b63954d8067Jack Carter#include "llvm/Support/CommandLine.h"
2436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/ELF.h"
254c1625b3cb23745dba38e205b20e7b63954d8067Jack Carter#include "llvm/Support/ErrorHandling.h"
264c1625b3cb23745dba38e205b20e7b63954d8067Jack Carter#include "llvm/Support/FormattedStream.h"
274c1625b3cb23745dba38e205b20e7b63954d8067Jack Carter
284c1625b3cb23745dba38e205b20e7b63954d8067Jack Carterusing namespace llvm;
294c1625b3cb23745dba38e205b20e7b63954d8067Jack Carter
30cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMipsTargetStreamer::MipsTargetStreamer(MCStreamer &S)
31cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    : MCTargetStreamer(S), canHaveModuleDirective(true) {}
32cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetStreamer::emitDirectiveSetMicroMips() {}
33cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetStreamer::emitDirectiveSetNoMicroMips() {}
34cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetStreamer::emitDirectiveSetMips16() {}
35cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetStreamer::emitDirectiveSetNoMips16() {}
36cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetStreamer::emitDirectiveSetReorder() {}
37cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetStreamer::emitDirectiveSetNoReorder() {}
38cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetStreamer::emitDirectiveSetMacro() {}
39cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetStreamer::emitDirectiveSetNoMacro() {}
40cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetStreamer::emitDirectiveSetAt() {}
41cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetStreamer::emitDirectiveSetNoAt() {}
42cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetStreamer::emitDirectiveEnd(StringRef Name) {}
43cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {}
44cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetStreamer::emitDirectiveAbiCalls() {}
45cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetStreamer::emitDirectiveNaN2008() {}
46cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetStreamer::emitDirectiveNaNLegacy() {}
47cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetStreamer::emitDirectiveOptionPic0() {}
48cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetStreamer::emitDirectiveOptionPic2() {}
49cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetStreamer::emitFrame(unsigned StackReg, unsigned StackSize,
50cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                   unsigned ReturnReg) {}
51cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetStreamer::emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) {}
52cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetStreamer::emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) {
53cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
54cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetStreamer::emitDirectiveSetMips32R2() {}
55cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetStreamer::emitDirectiveSetMips64() {}
56cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetStreamer::emitDirectiveSetMips64R2() {}
57cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetStreamer::emitDirectiveSetDsp() {}
58cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetStreamer::emitDirectiveCpload(unsigned RegNo) {}
59cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetStreamer::emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
60cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                              const MCSymbol &Sym, bool IsReg) {
61cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
62cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetStreamer::emitDirectiveModuleOddSPReg(bool Enabled,
63cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                                     bool IsO32ABI) {
64cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (!Enabled && !IsO32ABI)
65cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    report_fatal_error("+nooddspreg is only valid for O32");
66cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesMipsTargetAsmStreamer::MipsTargetAsmStreamer(MCStreamer &S,
6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                             formatted_raw_ostream &OS)
7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    : MipsTargetStreamer(S), OS(OS) {}
7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetAsmStreamer::emitDirectiveSetMicroMips() {
7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\t.set\tmicromips\n";
74cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetAsmStreamer::emitDirectiveSetNoMicroMips() {
7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\t.set\tnomicromips\n";
79cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetAsmStreamer::emitDirectiveSetMips16() {
8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\t.set\tmips16\n";
84cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetAsmStreamer::emitDirectiveSetNoMips16() {
8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\t.set\tnomips16\n";
89cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
9136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetAsmStreamer::emitDirectiveSetReorder() {
9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\t.set\treorder\n";
94cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetAsmStreamer::emitDirectiveSetNoReorder() {
9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\t.set\tnoreorder\n";
99cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
10136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetAsmStreamer::emitDirectiveSetMacro() {
10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\t.set\tmacro\n";
104cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
10636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
10736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetAsmStreamer::emitDirectiveSetNoMacro() {
10836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\t.set\tnomacro\n";
109cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetAsmStreamer::emitDirectiveSetAt() {
11336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\t.set\tat\n";
114cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
11536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
11636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetAsmStreamer::emitDirectiveSetNoAt() {
11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\t.set\tnoat\n";
119cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
12036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
12236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetAsmStreamer::emitDirectiveEnd(StringRef Name) {
12336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\t.end\t" << Name << '\n';
12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetAsmStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {
12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\t.ent\t" << Symbol.getName() << '\n';
12836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetAsmStreamer::emitDirectiveAbiCalls() { OS << "\t.abicalls\n"; }
131dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
132dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid MipsTargetAsmStreamer::emitDirectiveNaN2008() { OS << "\t.nan\t2008\n"; }
133dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
134dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid MipsTargetAsmStreamer::emitDirectiveNaNLegacy() {
135dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  OS << "\t.nan\tlegacy\n";
136dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
137dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
13836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetAsmStreamer::emitDirectiveOptionPic0() {
13936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\t.option\tpic0\n";
14036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
14136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
14236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetAsmStreamer::emitDirectiveOptionPic2() {
14336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\t.option\tpic2\n";
14436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
14536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
14636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetAsmStreamer::emitFrame(unsigned StackReg, unsigned StackSize,
14736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                      unsigned ReturnReg) {
14836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\t.frame\t$"
14936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     << StringRef(MipsInstPrinter::getRegisterName(StackReg)).lower() << ","
15036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     << StackSize << ",$"
15136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     << StringRef(MipsInstPrinter::getRegisterName(ReturnReg)).lower() << '\n';
15236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
15336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
15436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetAsmStreamer::emitDirectiveSetMips32R2() {
15536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\t.set\tmips32r2\n";
156cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
15736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
15836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
15936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetAsmStreamer::emitDirectiveSetMips64() {
16036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\t.set\tmips64\n";
161cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
16236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
16336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
16436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetAsmStreamer::emitDirectiveSetMips64R2() {
16536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\t.set\tmips64r2\n";
166cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
16736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
16836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetAsmStreamer::emitDirectiveSetDsp() {
17036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\t.set\tdsp\n";
171cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
17236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
17336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Print a 32 bit hex number with all numbers.
17436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic void printHex32(unsigned Value, raw_ostream &OS) {
17536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "0x";
17636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (int i = 7; i >= 0; i--)
177cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    OS.write_hex((Value & (0xF << (i * 4))) >> (i * 4));
17836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
17936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
18036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetAsmStreamer::emitMask(unsigned CPUBitmask,
18136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                     int CPUTopSavedRegOff) {
18236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\t.mask \t";
18336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  printHex32(CPUBitmask, OS);
18436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << ',' << CPUTopSavedRegOff << '\n';
18536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
18636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
18736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetAsmStreamer::emitFMask(unsigned FPUBitmask,
18836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                      int FPUTopSavedRegOff) {
18936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\t.fmask\t";
19036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  printHex32(FPUBitmask, OS);
19136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "," << FPUTopSavedRegOff << '\n';
19236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
19336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
194dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid MipsTargetAsmStreamer::emitDirectiveCpload(unsigned RegNo) {
195dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  OS << "\t.cpload\t$"
196dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines     << StringRef(MipsInstPrinter::getRegisterName(RegNo)).lower() << "\n";
197cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
198dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
199dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
200dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid MipsTargetAsmStreamer::emitDirectiveCpsetup(unsigned RegNo,
201dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                 int RegOrOffset,
202dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                 const MCSymbol &Sym,
203dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                 bool IsReg) {
204dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  OS << "\t.cpsetup\t$"
205dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines     << StringRef(MipsInstPrinter::getRegisterName(RegNo)).lower() << ", ";
206dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
207dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (IsReg)
208dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    OS << "$"
209dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines       << StringRef(MipsInstPrinter::getRegisterName(RegOrOffset)).lower();
210dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  else
211dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    OS << RegOrOffset;
212dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
213dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  OS << ", ";
214dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
215dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  OS << Sym.getName() << "\n";
216cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
217cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
218cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
219cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetAsmStreamer::emitDirectiveModuleFP(
220cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    MipsABIFlagsSection::FpABIKind Value, bool Is32BitABI) {
221cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MipsTargetStreamer::emitDirectiveModuleFP(Value, Is32BitABI);
222cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
223cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  StringRef ModuleValue;
224cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  OS << "\t.module\tfp=";
225cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  OS << ABIFlagsSection.getFpABIString(Value) << "\n";
226cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
227cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
228cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetAsmStreamer::emitDirectiveSetFp(
229cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    MipsABIFlagsSection::FpABIKind Value) {
230cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  StringRef ModuleValue;
231cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  OS << "\t.set\tfp=";
232cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  OS << ABIFlagsSection.getFpABIString(Value) << "\n";
233cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
234cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
235cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetAsmStreamer::emitMipsAbiFlags() {
236cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // No action required for text output.
237cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
238cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
239cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetAsmStreamer::emitDirectiveModuleOddSPReg(bool Enabled,
240cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                                        bool IsO32ABI) {
241cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MipsTargetStreamer::emitDirectiveModuleOddSPReg(Enabled, IsO32ABI);
242cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
243cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  OS << "\t.module\t" << (Enabled ? "" : "no") << "oddspreg\n";
244dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
245dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
24636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// This part is for ELF object output.
24736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesMipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S,
24836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                             const MCSubtargetInfo &STI)
24936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    : MipsTargetStreamer(S), MicroMipsEnabled(false), STI(STI) {
25036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCAssembler &MCA = getStreamer().getAssembler();
25136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t Features = STI.getFeatureBits();
25236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Triple T(STI.getTargetTriple());
253cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  Pic = (MCA.getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_)
25436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            ? true
25536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            : false;
25636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
25736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Update e_header flags
25836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned EFlags = 0;
25936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
26036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Architecture
261cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (Features & Mips::FeatureMips64r6)
262cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    EFlags |= ELF::EF_MIPS_ARCH_64R6;
263cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  else if (Features & Mips::FeatureMips64r2)
26436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    EFlags |= ELF::EF_MIPS_ARCH_64R2;
26536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  else if (Features & Mips::FeatureMips64)
26636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    EFlags |= ELF::EF_MIPS_ARCH_64;
267cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  else if (Features & Mips::FeatureMips5)
268cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    EFlags |= ELF::EF_MIPS_ARCH_5;
26936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  else if (Features & Mips::FeatureMips4)
27036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    EFlags |= ELF::EF_MIPS_ARCH_4;
271cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  else if (Features & Mips::FeatureMips3)
272cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    EFlags |= ELF::EF_MIPS_ARCH_3;
273cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  else if (Features & Mips::FeatureMips32r6)
274cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    EFlags |= ELF::EF_MIPS_ARCH_32R6;
27536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  else if (Features & Mips::FeatureMips32r2)
27636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    EFlags |= ELF::EF_MIPS_ARCH_32R2;
27736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  else if (Features & Mips::FeatureMips32)
27836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    EFlags |= ELF::EF_MIPS_ARCH_32;
279cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  else if (Features & Mips::FeatureMips2)
280cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    EFlags |= ELF::EF_MIPS_ARCH_2;
281cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  else
282cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    EFlags |= ELF::EF_MIPS_ARCH_1;
28336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
28436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (T.isArch64Bit()) {
28536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Features & Mips::FeatureN32)
28636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      EFlags |= ELF::EF_MIPS_ABI2;
28736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else if (Features & Mips::FeatureO32) {
28836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      EFlags |= ELF::EF_MIPS_ABI_O32;
28936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      EFlags |= ELF::EF_MIPS_32BITMODE; /* Compatibility Mode */
29036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
29136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // No need to set any bit for N64 which is the default ABI at the moment
29236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // for 64-bit Mips architectures.
29336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else {
29436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Features & Mips::FeatureMips64r2 || Features & Mips::FeatureMips64)
29536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      EFlags |= ELF::EF_MIPS_32BITMODE;
29636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
29736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // ABI
29836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    EFlags |= ELF::EF_MIPS_ABI_O32;
29936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
30036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
301dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Other options.
302dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Features & Mips::FeatureNaN2008)
303dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    EFlags |= ELF::EF_MIPS_NAN2008;
304dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
30536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCA.setELFHeaderEFlags(EFlags);
30636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
307a87a147ee7bb9adb4caea631ff0ba7e66bb9b0b5Bill Wendling
30836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetELFStreamer::emitLabel(MCSymbol *Symbol) {
30936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!isMicroMipsEnabled())
310a87a147ee7bb9adb4caea631ff0ba7e66bb9b0b5Bill Wendling    return;
31136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCSymbolData &Data = getStreamer().getOrCreateSymbolData(Symbol);
31236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t Type = MCELF::GetType(Data);
31336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Type != ELF::STT_FUNC)
31436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return;
31536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
31636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // The "other" values are stored in the last 6 bits of the second byte
31736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // The traditional defines for STO values assume the full byte and thus
31836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // the shift to pack it.
31936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCELF::setOther(Data, ELF::STO_MIPS_MICROMIPS >> 2);
32036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
32136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
32236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetELFStreamer::finish() {
32336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCAssembler &MCA = getStreamer().getAssembler();
32436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCContext &Context = MCA.getContext();
32536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCStreamer &OS = getStreamer();
32636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Triple T(STI.getTargetTriple());
32736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t Features = STI.getFeatureBits();
32836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
32936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (T.isArch64Bit() && (Features & Mips::FeatureN64)) {
33036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const MCSectionELF *Sec = Context.getELFSection(
33136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        ".MIPS.options", ELF::SHT_MIPS_OPTIONS,
33236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        ELF::SHF_ALLOC | ELF::SHF_MIPS_NOSTRIP, SectionKind::getMetadata());
33336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS.SwitchSection(Sec);
334a87a147ee7bb9adb4caea631ff0ba7e66bb9b0b5Bill Wendling
335cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    OS.EmitIntValue(1, 1);  // kind
33636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS.EmitIntValue(40, 1); // size
337cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    OS.EmitIntValue(0, 2);  // section
338cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    OS.EmitIntValue(0, 4);  // info
339cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    OS.EmitIntValue(0, 4);  // ri_gprmask
340cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    OS.EmitIntValue(0, 4);  // pad
341cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    OS.EmitIntValue(0, 4);  // ri_cpr[0]mask
342cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    OS.EmitIntValue(0, 4);  // ri_cpr[1]mask
343cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    OS.EmitIntValue(0, 4);  // ri_cpr[2]mask
344cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    OS.EmitIntValue(0, 4);  // ri_cpr[3]mask
345cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    OS.EmitIntValue(0, 8);  // ri_gp_value
34636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else {
34736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const MCSectionELF *Sec =
34836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Context.getELFSection(".reginfo", ELF::SHT_MIPS_REGINFO, ELF::SHF_ALLOC,
34936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                              SectionKind::getMetadata());
35036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS.SwitchSection(Sec);
35136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
35236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS.EmitIntValue(0, 4); // ri_gprmask
35336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS.EmitIntValue(0, 4); // ri_cpr[0]mask
35436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS.EmitIntValue(0, 4); // ri_cpr[1]mask
35536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS.EmitIntValue(0, 4); // ri_cpr[2]mask
35636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS.EmitIntValue(0, 4); // ri_cpr[3]mask
35736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS.EmitIntValue(0, 4); // ri_gp_value
35836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
359cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  emitMipsAbiFlags();
360a87a147ee7bb9adb4caea631ff0ba7e66bb9b0b5Bill Wendling}
36136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
36236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetELFStreamer::emitAssignment(MCSymbol *Symbol,
36336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                           const MCExpr *Value) {
36436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // If on rhs is micromips symbol then mark Symbol as microMips.
36536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Value->getKind() != MCExpr::SymbolRef)
36636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return;
36736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const MCSymbol &RhsSym =
368cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      static_cast<const MCSymbolRefExpr *>(Value)->getSymbol();
36936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCSymbolData &Data = getStreamer().getOrCreateSymbolData(&RhsSym);
37036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t Type = MCELF::GetType(Data);
371cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if ((Type != ELF::STT_FUNC) ||
372cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      !(MCELF::getOther(Data) & (ELF::STO_MIPS_MICROMIPS >> 2)))
373a87a147ee7bb9adb4caea631ff0ba7e66bb9b0b5Bill Wendling    return;
374a87a147ee7bb9adb4caea631ff0ba7e66bb9b0b5Bill Wendling
37536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCSymbolData &SymbolData = getStreamer().getOrCreateSymbolData(Symbol);
37636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // The "other" values are stored in the last 6 bits of the second byte.
37736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // The traditional defines for STO values assume the full byte and thus
37836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // the shift to pack it.
37936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCELF::setOther(SymbolData, ELF::STO_MIPS_MICROMIPS >> 2);
380a87a147ee7bb9adb4caea631ff0ba7e66bb9b0b5Bill Wendling}
3814c1625b3cb23745dba38e205b20e7b63954d8067Jack Carter
3824c1625b3cb23745dba38e205b20e7b63954d8067Jack CarterMCELFStreamer &MipsTargetELFStreamer::getStreamer() {
38336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return static_cast<MCELFStreamer &>(Streamer);
3844c1625b3cb23745dba38e205b20e7b63954d8067Jack Carter}
3854c1625b3cb23745dba38e205b20e7b63954d8067Jack Carter
38636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetELFStreamer::emitDirectiveSetMicroMips() {
38736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MicroMipsEnabled = true;
38836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
3894c1625b3cb23745dba38e205b20e7b63954d8067Jack Carter  MCAssembler &MCA = getStreamer().getAssembler();
39036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Flags = MCA.getELFHeaderEFlags();
39136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Flags |= ELF::EF_MIPS_MICROMIPS;
3924c1625b3cb23745dba38e205b20e7b63954d8067Jack Carter  MCA.setELFHeaderEFlags(Flags);
3934c1625b3cb23745dba38e205b20e7b63954d8067Jack Carter}
3944c1625b3cb23745dba38e205b20e7b63954d8067Jack Carter
39536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetELFStreamer::emitDirectiveSetNoMicroMips() {
39636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MicroMipsEnabled = false;
397cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
39836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
39936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
40036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetELFStreamer::emitDirectiveSetMips16() {
40136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCAssembler &MCA = getStreamer().getAssembler();
40236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Flags = MCA.getELFHeaderEFlags();
40336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Flags |= ELF::EF_MIPS_ARCH_ASE_M16;
40436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCA.setELFHeaderEFlags(Flags);
405cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
40636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
40736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
40836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetELFStreamer::emitDirectiveSetNoMips16() {
40936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // FIXME: implement.
410cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
41136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
41236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
41336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetELFStreamer::emitDirectiveSetReorder() {
41436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // FIXME: implement.
415cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
41636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
41736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
41836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetELFStreamer::emitDirectiveSetNoReorder() {
41936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCAssembler &MCA = getStreamer().getAssembler();
42036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Flags = MCA.getELFHeaderEFlags();
42136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Flags |= ELF::EF_MIPS_NOREORDER;
42236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCA.setELFHeaderEFlags(Flags);
423cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
42436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
42536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
42636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetELFStreamer::emitDirectiveSetMacro() {
42736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // FIXME: implement.
428cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
42936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
43036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
43136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetELFStreamer::emitDirectiveSetNoMacro() {
43236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // FIXME: implement.
433cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
43436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
43536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
43636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetELFStreamer::emitDirectiveSetAt() {
43736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // FIXME: implement.
438cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
43936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
44036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
44136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetELFStreamer::emitDirectiveSetNoAt() {
44236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // FIXME: implement.
443cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
44436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
44536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
44636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetELFStreamer::emitDirectiveEnd(StringRef Name) {
44736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // FIXME: implement.
44836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
44936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
45036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetELFStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {
45136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // FIXME: implement.
45236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
45336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
45436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetELFStreamer::emitDirectiveAbiCalls() {
45536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCAssembler &MCA = getStreamer().getAssembler();
45636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Flags = MCA.getELFHeaderEFlags();
45736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Flags |= ELF::EF_MIPS_CPIC | ELF::EF_MIPS_PIC;
45836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCA.setELFHeaderEFlags(Flags);
45936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
460dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
461dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid MipsTargetELFStreamer::emitDirectiveNaN2008() {
462dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MCAssembler &MCA = getStreamer().getAssembler();
463dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Flags = MCA.getELFHeaderEFlags();
464dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Flags |= ELF::EF_MIPS_NAN2008;
465dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MCA.setELFHeaderEFlags(Flags);
466dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
467dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
468dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid MipsTargetELFStreamer::emitDirectiveNaNLegacy() {
469dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MCAssembler &MCA = getStreamer().getAssembler();
470dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Flags = MCA.getELFHeaderEFlags();
471dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Flags &= ~ELF::EF_MIPS_NAN2008;
472dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MCA.setELFHeaderEFlags(Flags);
473dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
474dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
47536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetELFStreamer::emitDirectiveOptionPic0() {
47636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCAssembler &MCA = getStreamer().getAssembler();
47736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Flags = MCA.getELFHeaderEFlags();
47836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // This option overrides other PIC options like -KPIC.
47936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Pic = false;
48036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Flags &= ~ELF::EF_MIPS_PIC;
48136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCA.setELFHeaderEFlags(Flags);
48236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
48336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
48436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetELFStreamer::emitDirectiveOptionPic2() {
48536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCAssembler &MCA = getStreamer().getAssembler();
48636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Flags = MCA.getELFHeaderEFlags();
48736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Pic = true;
48836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // NOTE: We are following the GAS behaviour here which means the directive
48936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // 'pic2' also sets the CPIC bit in the ELF header. This is different from
49036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // what is stated in the SYSV ABI which consider the bits EF_MIPS_PIC and
49136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // EF_MIPS_CPIC to be mutually exclusive.
49236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Flags |= ELF::EF_MIPS_PIC | ELF::EF_MIPS_CPIC;
49336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCA.setELFHeaderEFlags(Flags);
49436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
49536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
49636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetELFStreamer::emitFrame(unsigned StackReg, unsigned StackSize,
49736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                      unsigned ReturnReg) {
49836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // FIXME: implement.
49936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
50036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
50136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetELFStreamer::emitMask(unsigned CPUBitmask,
50236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                     int CPUTopSavedRegOff) {
50336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // FIXME: implement.
50436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
50536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
50636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetELFStreamer::emitFMask(unsigned FPUBitmask,
50736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                      int FPUTopSavedRegOff) {
50836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // FIXME: implement.
50936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
51036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
51136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetELFStreamer::emitDirectiveSetMips32R2() {
512cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
51336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
51436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
51536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetELFStreamer::emitDirectiveSetMips64() {
516cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
51736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
51836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
51936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetELFStreamer::emitDirectiveSetMips64R2() {
520cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
52136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
52236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
52336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsTargetELFStreamer::emitDirectiveSetDsp() {
524cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
5254c1625b3cb23745dba38e205b20e7b63954d8067Jack Carter}
526dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
527dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid MipsTargetELFStreamer::emitDirectiveCpload(unsigned RegNo) {
528dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // .cpload $reg
529dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // This directive expands to:
530dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // lui   $gp, %hi(_gp_disp)
531dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // addui $gp, $gp, %lo(_gp_disp)
532dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // addu  $gp, $gp, $reg
533dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // when support for position independent code is enabled.
534dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!Pic || (isN32() || isN64()))
535dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
536dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
537dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // There's a GNU extension controlled by -mno-shared that allows
538dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // locally-binding symbols to be accessed using absolute addresses.
539dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // This is currently not supported. When supported -mno-shared makes
540dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // .cpload expand to:
541dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //   lui     $gp, %hi(__gnu_local_gp)
542dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //   addiu   $gp, $gp, %lo(__gnu_local_gp)
543dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
544dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  StringRef SymName("_gp_disp");
545dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MCAssembler &MCA = getStreamer().getAssembler();
546dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MCSymbol *GP_Disp = MCA.getContext().GetOrCreateSymbol(SymName);
547dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MCA.getOrCreateSymbolData(*GP_Disp);
548dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
549dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MCInst TmpInst;
550dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  TmpInst.setOpcode(Mips::LUi);
551dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  TmpInst.addOperand(MCOperand::CreateReg(Mips::GP));
552dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MCSymbolRefExpr *HiSym = MCSymbolRefExpr::Create(
553dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      "_gp_disp", MCSymbolRefExpr::VK_Mips_ABS_HI, MCA.getContext());
554dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  TmpInst.addOperand(MCOperand::CreateExpr(HiSym));
555dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  getStreamer().EmitInstruction(TmpInst, STI);
556dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
557dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  TmpInst.clear();
558dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
559dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  TmpInst.setOpcode(Mips::ADDiu);
560dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  TmpInst.addOperand(MCOperand::CreateReg(Mips::GP));
561dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  TmpInst.addOperand(MCOperand::CreateReg(Mips::GP));
562dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MCSymbolRefExpr *LoSym = MCSymbolRefExpr::Create(
563dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      "_gp_disp", MCSymbolRefExpr::VK_Mips_ABS_LO, MCA.getContext());
564dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  TmpInst.addOperand(MCOperand::CreateExpr(LoSym));
565dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  getStreamer().EmitInstruction(TmpInst, STI);
566dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
567dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  TmpInst.clear();
568dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
569dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  TmpInst.setOpcode(Mips::ADDu);
570dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  TmpInst.addOperand(MCOperand::CreateReg(Mips::GP));
571dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  TmpInst.addOperand(MCOperand::CreateReg(Mips::GP));
572dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  TmpInst.addOperand(MCOperand::CreateReg(RegNo));
573dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  getStreamer().EmitInstruction(TmpInst, STI);
574cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
575cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
576dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
577dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
578dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid MipsTargetELFStreamer::emitDirectiveCpsetup(unsigned RegNo,
579dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                 int RegOrOffset,
580dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                 const MCSymbol &Sym,
581dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                 bool IsReg) {
582dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Only N32 and N64 emit anything for .cpsetup iff PIC is set.
583dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!Pic || !(isN32() || isN64()))
584dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
585dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
586dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MCAssembler &MCA = getStreamer().getAssembler();
587dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MCInst Inst;
588dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
589dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Either store the old $gp in a register or on the stack
590dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (IsReg) {
591dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // move $save, $gpreg
592dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.setOpcode(Mips::DADDu);
593dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateReg(RegOrOffset));
594dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateReg(Mips::GP));
595dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
596dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  } else {
597dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // sd $gpreg, offset($sp)
598dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.setOpcode(Mips::SD);
599dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateReg(Mips::GP));
600dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateReg(Mips::SP));
601dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(RegOrOffset));
602dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
603dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  getStreamer().EmitInstruction(Inst, STI);
604dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Inst.clear();
605dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
606dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
607dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Sym.getName(), MCSymbolRefExpr::VK_Mips_GPOFF_HI, MCA.getContext());
608dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
609dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Sym.getName(), MCSymbolRefExpr::VK_Mips_GPOFF_LO, MCA.getContext());
610dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // lui $gp, %hi(%neg(%gp_rel(funcSym)))
611dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Inst.setOpcode(Mips::LUi);
612dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Inst.addOperand(MCOperand::CreateReg(Mips::GP));
613dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Inst.addOperand(MCOperand::CreateExpr(HiExpr));
614dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  getStreamer().EmitInstruction(Inst, STI);
615dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Inst.clear();
616dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
617dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // addiu  $gp, $gp, %lo(%neg(%gp_rel(funcSym)))
618dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Inst.setOpcode(Mips::ADDiu);
619dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Inst.addOperand(MCOperand::CreateReg(Mips::GP));
620dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Inst.addOperand(MCOperand::CreateReg(Mips::GP));
621dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Inst.addOperand(MCOperand::CreateExpr(LoExpr));
622dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  getStreamer().EmitInstruction(Inst, STI);
623dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Inst.clear();
624dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
625dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // daddu  $gp, $gp, $funcreg
626dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Inst.setOpcode(Mips::DADDu);
627dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Inst.addOperand(MCOperand::CreateReg(Mips::GP));
628dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Inst.addOperand(MCOperand::CreateReg(Mips::GP));
629dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Inst.addOperand(MCOperand::CreateReg(RegNo));
630dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  getStreamer().EmitInstruction(Inst, STI);
631cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
632cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  setCanHaveModuleDir(false);
633cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
634cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
635cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetELFStreamer::emitMipsAbiFlags() {
636cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MCAssembler &MCA = getStreamer().getAssembler();
637cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MCContext &Context = MCA.getContext();
638cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MCStreamer &OS = getStreamer();
639cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  const MCSectionELF *Sec =
640cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      Context.getELFSection(".MIPS.abiflags", ELF::SHT_MIPS_ABIFLAGS,
641cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                            ELF::SHF_ALLOC, SectionKind::getMetadata());
642cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MCSectionData &ABIShndxSD = MCA.getOrCreateSectionData(*Sec);
643cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  ABIShndxSD.setAlignment(8);
644cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  OS.SwitchSection(Sec);
645cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
646cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  OS << ABIFlagsSection;
647cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
648cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
649cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsTargetELFStreamer::emitDirectiveModuleOddSPReg(bool Enabled,
650cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                                        bool IsO32ABI) {
651cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MipsTargetStreamer::emitDirectiveModuleOddSPReg(Enabled, IsO32ABI);
652cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
653cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  ABIFlagsSection.OddSPReg = Enabled;
654dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
655