1//===-- 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 "InstPrinter/MipsInstPrinter.h"
15#include "MipsMCTargetDesc.h"
16#include "MipsTargetObjectFile.h"
17#include "MipsTargetStreamer.h"
18#include "llvm/MC/MCContext.h"
19#include "llvm/MC/MCELF.h"
20#include "llvm/MC/MCSectionELF.h"
21#include "llvm/MC/MCSubtargetInfo.h"
22#include "llvm/MC/MCSymbol.h"
23#include "llvm/Support/CommandLine.h"
24#include "llvm/Support/ELF.h"
25#include "llvm/Support/ErrorHandling.h"
26#include "llvm/Support/FormattedStream.h"
27
28using namespace llvm;
29
30MipsTargetStreamer::MipsTargetStreamer(MCStreamer &S)
31    : MCTargetStreamer(S), canHaveModuleDirective(true) {}
32void MipsTargetStreamer::emitDirectiveSetMicroMips() {}
33void MipsTargetStreamer::emitDirectiveSetNoMicroMips() {}
34void MipsTargetStreamer::emitDirectiveSetMips16() {}
35void MipsTargetStreamer::emitDirectiveSetNoMips16() {}
36void MipsTargetStreamer::emitDirectiveSetReorder() {}
37void MipsTargetStreamer::emitDirectiveSetNoReorder() {}
38void MipsTargetStreamer::emitDirectiveSetMacro() {}
39void MipsTargetStreamer::emitDirectiveSetNoMacro() {}
40void MipsTargetStreamer::emitDirectiveSetAt() {}
41void MipsTargetStreamer::emitDirectiveSetNoAt() {}
42void MipsTargetStreamer::emitDirectiveEnd(StringRef Name) {}
43void MipsTargetStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {}
44void MipsTargetStreamer::emitDirectiveAbiCalls() {}
45void MipsTargetStreamer::emitDirectiveNaN2008() {}
46void MipsTargetStreamer::emitDirectiveNaNLegacy() {}
47void MipsTargetStreamer::emitDirectiveOptionPic0() {}
48void MipsTargetStreamer::emitDirectiveOptionPic2() {}
49void MipsTargetStreamer::emitFrame(unsigned StackReg, unsigned StackSize,
50                                   unsigned ReturnReg) {}
51void MipsTargetStreamer::emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) {}
52void MipsTargetStreamer::emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) {
53}
54void MipsTargetStreamer::emitDirectiveSetMips32R2() {}
55void MipsTargetStreamer::emitDirectiveSetMips64() {}
56void MipsTargetStreamer::emitDirectiveSetMips64R2() {}
57void MipsTargetStreamer::emitDirectiveSetDsp() {}
58void MipsTargetStreamer::emitDirectiveCpload(unsigned RegNo) {}
59void MipsTargetStreamer::emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
60                                              const MCSymbol &Sym, bool IsReg) {
61}
62void MipsTargetStreamer::emitDirectiveModuleOddSPReg(bool Enabled,
63                                                     bool IsO32ABI) {
64  if (!Enabled && !IsO32ABI)
65    report_fatal_error("+nooddspreg is only valid for O32");
66}
67
68MipsTargetAsmStreamer::MipsTargetAsmStreamer(MCStreamer &S,
69                                             formatted_raw_ostream &OS)
70    : MipsTargetStreamer(S), OS(OS) {}
71
72void MipsTargetAsmStreamer::emitDirectiveSetMicroMips() {
73  OS << "\t.set\tmicromips\n";
74  setCanHaveModuleDir(false);
75}
76
77void MipsTargetAsmStreamer::emitDirectiveSetNoMicroMips() {
78  OS << "\t.set\tnomicromips\n";
79  setCanHaveModuleDir(false);
80}
81
82void MipsTargetAsmStreamer::emitDirectiveSetMips16() {
83  OS << "\t.set\tmips16\n";
84  setCanHaveModuleDir(false);
85}
86
87void MipsTargetAsmStreamer::emitDirectiveSetNoMips16() {
88  OS << "\t.set\tnomips16\n";
89  setCanHaveModuleDir(false);
90}
91
92void MipsTargetAsmStreamer::emitDirectiveSetReorder() {
93  OS << "\t.set\treorder\n";
94  setCanHaveModuleDir(false);
95}
96
97void MipsTargetAsmStreamer::emitDirectiveSetNoReorder() {
98  OS << "\t.set\tnoreorder\n";
99  setCanHaveModuleDir(false);
100}
101
102void MipsTargetAsmStreamer::emitDirectiveSetMacro() {
103  OS << "\t.set\tmacro\n";
104  setCanHaveModuleDir(false);
105}
106
107void MipsTargetAsmStreamer::emitDirectiveSetNoMacro() {
108  OS << "\t.set\tnomacro\n";
109  setCanHaveModuleDir(false);
110}
111
112void MipsTargetAsmStreamer::emitDirectiveSetAt() {
113  OS << "\t.set\tat\n";
114  setCanHaveModuleDir(false);
115}
116
117void MipsTargetAsmStreamer::emitDirectiveSetNoAt() {
118  OS << "\t.set\tnoat\n";
119  setCanHaveModuleDir(false);
120}
121
122void MipsTargetAsmStreamer::emitDirectiveEnd(StringRef Name) {
123  OS << "\t.end\t" << Name << '\n';
124}
125
126void MipsTargetAsmStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {
127  OS << "\t.ent\t" << Symbol.getName() << '\n';
128}
129
130void MipsTargetAsmStreamer::emitDirectiveAbiCalls() { OS << "\t.abicalls\n"; }
131
132void MipsTargetAsmStreamer::emitDirectiveNaN2008() { OS << "\t.nan\t2008\n"; }
133
134void MipsTargetAsmStreamer::emitDirectiveNaNLegacy() {
135  OS << "\t.nan\tlegacy\n";
136}
137
138void MipsTargetAsmStreamer::emitDirectiveOptionPic0() {
139  OS << "\t.option\tpic0\n";
140}
141
142void MipsTargetAsmStreamer::emitDirectiveOptionPic2() {
143  OS << "\t.option\tpic2\n";
144}
145
146void MipsTargetAsmStreamer::emitFrame(unsigned StackReg, unsigned StackSize,
147                                      unsigned ReturnReg) {
148  OS << "\t.frame\t$"
149     << StringRef(MipsInstPrinter::getRegisterName(StackReg)).lower() << ","
150     << StackSize << ",$"
151     << StringRef(MipsInstPrinter::getRegisterName(ReturnReg)).lower() << '\n';
152}
153
154void MipsTargetAsmStreamer::emitDirectiveSetMips32R2() {
155  OS << "\t.set\tmips32r2\n";
156  setCanHaveModuleDir(false);
157}
158
159void MipsTargetAsmStreamer::emitDirectiveSetMips64() {
160  OS << "\t.set\tmips64\n";
161  setCanHaveModuleDir(false);
162}
163
164void MipsTargetAsmStreamer::emitDirectiveSetMips64R2() {
165  OS << "\t.set\tmips64r2\n";
166  setCanHaveModuleDir(false);
167}
168
169void MipsTargetAsmStreamer::emitDirectiveSetDsp() {
170  OS << "\t.set\tdsp\n";
171  setCanHaveModuleDir(false);
172}
173// Print a 32 bit hex number with all numbers.
174static void printHex32(unsigned Value, raw_ostream &OS) {
175  OS << "0x";
176  for (int i = 7; i >= 0; i--)
177    OS.write_hex((Value & (0xF << (i * 4))) >> (i * 4));
178}
179
180void MipsTargetAsmStreamer::emitMask(unsigned CPUBitmask,
181                                     int CPUTopSavedRegOff) {
182  OS << "\t.mask \t";
183  printHex32(CPUBitmask, OS);
184  OS << ',' << CPUTopSavedRegOff << '\n';
185}
186
187void MipsTargetAsmStreamer::emitFMask(unsigned FPUBitmask,
188                                      int FPUTopSavedRegOff) {
189  OS << "\t.fmask\t";
190  printHex32(FPUBitmask, OS);
191  OS << "," << FPUTopSavedRegOff << '\n';
192}
193
194void MipsTargetAsmStreamer::emitDirectiveCpload(unsigned RegNo) {
195  OS << "\t.cpload\t$"
196     << StringRef(MipsInstPrinter::getRegisterName(RegNo)).lower() << "\n";
197  setCanHaveModuleDir(false);
198}
199
200void MipsTargetAsmStreamer::emitDirectiveCpsetup(unsigned RegNo,
201                                                 int RegOrOffset,
202                                                 const MCSymbol &Sym,
203                                                 bool IsReg) {
204  OS << "\t.cpsetup\t$"
205     << StringRef(MipsInstPrinter::getRegisterName(RegNo)).lower() << ", ";
206
207  if (IsReg)
208    OS << "$"
209       << StringRef(MipsInstPrinter::getRegisterName(RegOrOffset)).lower();
210  else
211    OS << RegOrOffset;
212
213  OS << ", ";
214
215  OS << Sym.getName() << "\n";
216  setCanHaveModuleDir(false);
217}
218
219void MipsTargetAsmStreamer::emitDirectiveModuleFP(
220    MipsABIFlagsSection::FpABIKind Value, bool Is32BitABI) {
221  MipsTargetStreamer::emitDirectiveModuleFP(Value, Is32BitABI);
222
223  StringRef ModuleValue;
224  OS << "\t.module\tfp=";
225  OS << ABIFlagsSection.getFpABIString(Value) << "\n";
226}
227
228void MipsTargetAsmStreamer::emitDirectiveSetFp(
229    MipsABIFlagsSection::FpABIKind Value) {
230  StringRef ModuleValue;
231  OS << "\t.set\tfp=";
232  OS << ABIFlagsSection.getFpABIString(Value) << "\n";
233}
234
235void MipsTargetAsmStreamer::emitMipsAbiFlags() {
236  // No action required for text output.
237}
238
239void MipsTargetAsmStreamer::emitDirectiveModuleOddSPReg(bool Enabled,
240                                                        bool IsO32ABI) {
241  MipsTargetStreamer::emitDirectiveModuleOddSPReg(Enabled, IsO32ABI);
242
243  OS << "\t.module\t" << (Enabled ? "" : "no") << "oddspreg\n";
244}
245
246// This part is for ELF object output.
247MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S,
248                                             const MCSubtargetInfo &STI)
249    : MipsTargetStreamer(S), MicroMipsEnabled(false), STI(STI) {
250  MCAssembler &MCA = getStreamer().getAssembler();
251  uint64_t Features = STI.getFeatureBits();
252  Triple T(STI.getTargetTriple());
253  Pic = (MCA.getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_)
254            ? true
255            : false;
256
257  // Update e_header flags
258  unsigned EFlags = 0;
259
260  // Architecture
261  if (Features & Mips::FeatureMips64r6)
262    EFlags |= ELF::EF_MIPS_ARCH_64R6;
263  else if (Features & Mips::FeatureMips64r2)
264    EFlags |= ELF::EF_MIPS_ARCH_64R2;
265  else if (Features & Mips::FeatureMips64)
266    EFlags |= ELF::EF_MIPS_ARCH_64;
267  else if (Features & Mips::FeatureMips5)
268    EFlags |= ELF::EF_MIPS_ARCH_5;
269  else if (Features & Mips::FeatureMips4)
270    EFlags |= ELF::EF_MIPS_ARCH_4;
271  else if (Features & Mips::FeatureMips3)
272    EFlags |= ELF::EF_MIPS_ARCH_3;
273  else if (Features & Mips::FeatureMips32r6)
274    EFlags |= ELF::EF_MIPS_ARCH_32R6;
275  else if (Features & Mips::FeatureMips32r2)
276    EFlags |= ELF::EF_MIPS_ARCH_32R2;
277  else if (Features & Mips::FeatureMips32)
278    EFlags |= ELF::EF_MIPS_ARCH_32;
279  else if (Features & Mips::FeatureMips2)
280    EFlags |= ELF::EF_MIPS_ARCH_2;
281  else
282    EFlags |= ELF::EF_MIPS_ARCH_1;
283
284  if (T.isArch64Bit()) {
285    if (Features & Mips::FeatureN32)
286      EFlags |= ELF::EF_MIPS_ABI2;
287    else if (Features & Mips::FeatureO32) {
288      EFlags |= ELF::EF_MIPS_ABI_O32;
289      EFlags |= ELF::EF_MIPS_32BITMODE; /* Compatibility Mode */
290    }
291    // No need to set any bit for N64 which is the default ABI at the moment
292    // for 64-bit Mips architectures.
293  } else {
294    if (Features & Mips::FeatureMips64r2 || Features & Mips::FeatureMips64)
295      EFlags |= ELF::EF_MIPS_32BITMODE;
296
297    // ABI
298    EFlags |= ELF::EF_MIPS_ABI_O32;
299  }
300
301  // Other options.
302  if (Features & Mips::FeatureNaN2008)
303    EFlags |= ELF::EF_MIPS_NAN2008;
304
305  MCA.setELFHeaderEFlags(EFlags);
306}
307
308void MipsTargetELFStreamer::emitLabel(MCSymbol *Symbol) {
309  if (!isMicroMipsEnabled())
310    return;
311  MCSymbolData &Data = getStreamer().getOrCreateSymbolData(Symbol);
312  uint8_t Type = MCELF::GetType(Data);
313  if (Type != ELF::STT_FUNC)
314    return;
315
316  // The "other" values are stored in the last 6 bits of the second byte
317  // The traditional defines for STO values assume the full byte and thus
318  // the shift to pack it.
319  MCELF::setOther(Data, ELF::STO_MIPS_MICROMIPS >> 2);
320}
321
322void MipsTargetELFStreamer::finish() {
323  MCAssembler &MCA = getStreamer().getAssembler();
324  MCContext &Context = MCA.getContext();
325  MCStreamer &OS = getStreamer();
326  Triple T(STI.getTargetTriple());
327  uint64_t Features = STI.getFeatureBits();
328
329  if (T.isArch64Bit() && (Features & Mips::FeatureN64)) {
330    const MCSectionELF *Sec = Context.getELFSection(
331        ".MIPS.options", ELF::SHT_MIPS_OPTIONS,
332        ELF::SHF_ALLOC | ELF::SHF_MIPS_NOSTRIP, SectionKind::getMetadata());
333    OS.SwitchSection(Sec);
334
335    OS.EmitIntValue(1, 1);  // kind
336    OS.EmitIntValue(40, 1); // size
337    OS.EmitIntValue(0, 2);  // section
338    OS.EmitIntValue(0, 4);  // info
339    OS.EmitIntValue(0, 4);  // ri_gprmask
340    OS.EmitIntValue(0, 4);  // pad
341    OS.EmitIntValue(0, 4);  // ri_cpr[0]mask
342    OS.EmitIntValue(0, 4);  // ri_cpr[1]mask
343    OS.EmitIntValue(0, 4);  // ri_cpr[2]mask
344    OS.EmitIntValue(0, 4);  // ri_cpr[3]mask
345    OS.EmitIntValue(0, 8);  // ri_gp_value
346  } else {
347    const MCSectionELF *Sec =
348        Context.getELFSection(".reginfo", ELF::SHT_MIPS_REGINFO, ELF::SHF_ALLOC,
349                              SectionKind::getMetadata());
350    OS.SwitchSection(Sec);
351
352    OS.EmitIntValue(0, 4); // ri_gprmask
353    OS.EmitIntValue(0, 4); // ri_cpr[0]mask
354    OS.EmitIntValue(0, 4); // ri_cpr[1]mask
355    OS.EmitIntValue(0, 4); // ri_cpr[2]mask
356    OS.EmitIntValue(0, 4); // ri_cpr[3]mask
357    OS.EmitIntValue(0, 4); // ri_gp_value
358  }
359  emitMipsAbiFlags();
360}
361
362void MipsTargetELFStreamer::emitAssignment(MCSymbol *Symbol,
363                                           const MCExpr *Value) {
364  // If on rhs is micromips symbol then mark Symbol as microMips.
365  if (Value->getKind() != MCExpr::SymbolRef)
366    return;
367  const MCSymbol &RhsSym =
368      static_cast<const MCSymbolRefExpr *>(Value)->getSymbol();
369  MCSymbolData &Data = getStreamer().getOrCreateSymbolData(&RhsSym);
370  uint8_t Type = MCELF::GetType(Data);
371  if ((Type != ELF::STT_FUNC) ||
372      !(MCELF::getOther(Data) & (ELF::STO_MIPS_MICROMIPS >> 2)))
373    return;
374
375  MCSymbolData &SymbolData = getStreamer().getOrCreateSymbolData(Symbol);
376  // The "other" values are stored in the last 6 bits of the second byte.
377  // The traditional defines for STO values assume the full byte and thus
378  // the shift to pack it.
379  MCELF::setOther(SymbolData, ELF::STO_MIPS_MICROMIPS >> 2);
380}
381
382MCELFStreamer &MipsTargetELFStreamer::getStreamer() {
383  return static_cast<MCELFStreamer &>(Streamer);
384}
385
386void MipsTargetELFStreamer::emitDirectiveSetMicroMips() {
387  MicroMipsEnabled = true;
388
389  MCAssembler &MCA = getStreamer().getAssembler();
390  unsigned Flags = MCA.getELFHeaderEFlags();
391  Flags |= ELF::EF_MIPS_MICROMIPS;
392  MCA.setELFHeaderEFlags(Flags);
393}
394
395void MipsTargetELFStreamer::emitDirectiveSetNoMicroMips() {
396  MicroMipsEnabled = false;
397  setCanHaveModuleDir(false);
398}
399
400void MipsTargetELFStreamer::emitDirectiveSetMips16() {
401  MCAssembler &MCA = getStreamer().getAssembler();
402  unsigned Flags = MCA.getELFHeaderEFlags();
403  Flags |= ELF::EF_MIPS_ARCH_ASE_M16;
404  MCA.setELFHeaderEFlags(Flags);
405  setCanHaveModuleDir(false);
406}
407
408void MipsTargetELFStreamer::emitDirectiveSetNoMips16() {
409  // FIXME: implement.
410  setCanHaveModuleDir(false);
411}
412
413void MipsTargetELFStreamer::emitDirectiveSetReorder() {
414  // FIXME: implement.
415  setCanHaveModuleDir(false);
416}
417
418void MipsTargetELFStreamer::emitDirectiveSetNoReorder() {
419  MCAssembler &MCA = getStreamer().getAssembler();
420  unsigned Flags = MCA.getELFHeaderEFlags();
421  Flags |= ELF::EF_MIPS_NOREORDER;
422  MCA.setELFHeaderEFlags(Flags);
423  setCanHaveModuleDir(false);
424}
425
426void MipsTargetELFStreamer::emitDirectiveSetMacro() {
427  // FIXME: implement.
428  setCanHaveModuleDir(false);
429}
430
431void MipsTargetELFStreamer::emitDirectiveSetNoMacro() {
432  // FIXME: implement.
433  setCanHaveModuleDir(false);
434}
435
436void MipsTargetELFStreamer::emitDirectiveSetAt() {
437  // FIXME: implement.
438  setCanHaveModuleDir(false);
439}
440
441void MipsTargetELFStreamer::emitDirectiveSetNoAt() {
442  // FIXME: implement.
443  setCanHaveModuleDir(false);
444}
445
446void MipsTargetELFStreamer::emitDirectiveEnd(StringRef Name) {
447  // FIXME: implement.
448}
449
450void MipsTargetELFStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {
451  // FIXME: implement.
452}
453
454void MipsTargetELFStreamer::emitDirectiveAbiCalls() {
455  MCAssembler &MCA = getStreamer().getAssembler();
456  unsigned Flags = MCA.getELFHeaderEFlags();
457  Flags |= ELF::EF_MIPS_CPIC | ELF::EF_MIPS_PIC;
458  MCA.setELFHeaderEFlags(Flags);
459}
460
461void MipsTargetELFStreamer::emitDirectiveNaN2008() {
462  MCAssembler &MCA = getStreamer().getAssembler();
463  unsigned Flags = MCA.getELFHeaderEFlags();
464  Flags |= ELF::EF_MIPS_NAN2008;
465  MCA.setELFHeaderEFlags(Flags);
466}
467
468void MipsTargetELFStreamer::emitDirectiveNaNLegacy() {
469  MCAssembler &MCA = getStreamer().getAssembler();
470  unsigned Flags = MCA.getELFHeaderEFlags();
471  Flags &= ~ELF::EF_MIPS_NAN2008;
472  MCA.setELFHeaderEFlags(Flags);
473}
474
475void MipsTargetELFStreamer::emitDirectiveOptionPic0() {
476  MCAssembler &MCA = getStreamer().getAssembler();
477  unsigned Flags = MCA.getELFHeaderEFlags();
478  // This option overrides other PIC options like -KPIC.
479  Pic = false;
480  Flags &= ~ELF::EF_MIPS_PIC;
481  MCA.setELFHeaderEFlags(Flags);
482}
483
484void MipsTargetELFStreamer::emitDirectiveOptionPic2() {
485  MCAssembler &MCA = getStreamer().getAssembler();
486  unsigned Flags = MCA.getELFHeaderEFlags();
487  Pic = true;
488  // NOTE: We are following the GAS behaviour here which means the directive
489  // 'pic2' also sets the CPIC bit in the ELF header. This is different from
490  // what is stated in the SYSV ABI which consider the bits EF_MIPS_PIC and
491  // EF_MIPS_CPIC to be mutually exclusive.
492  Flags |= ELF::EF_MIPS_PIC | ELF::EF_MIPS_CPIC;
493  MCA.setELFHeaderEFlags(Flags);
494}
495
496void MipsTargetELFStreamer::emitFrame(unsigned StackReg, unsigned StackSize,
497                                      unsigned ReturnReg) {
498  // FIXME: implement.
499}
500
501void MipsTargetELFStreamer::emitMask(unsigned CPUBitmask,
502                                     int CPUTopSavedRegOff) {
503  // FIXME: implement.
504}
505
506void MipsTargetELFStreamer::emitFMask(unsigned FPUBitmask,
507                                      int FPUTopSavedRegOff) {
508  // FIXME: implement.
509}
510
511void MipsTargetELFStreamer::emitDirectiveSetMips32R2() {
512  setCanHaveModuleDir(false);
513}
514
515void MipsTargetELFStreamer::emitDirectiveSetMips64() {
516  setCanHaveModuleDir(false);
517}
518
519void MipsTargetELFStreamer::emitDirectiveSetMips64R2() {
520  setCanHaveModuleDir(false);
521}
522
523void MipsTargetELFStreamer::emitDirectiveSetDsp() {
524  setCanHaveModuleDir(false);
525}
526
527void MipsTargetELFStreamer::emitDirectiveCpload(unsigned RegNo) {
528  // .cpload $reg
529  // This directive expands to:
530  // lui   $gp, %hi(_gp_disp)
531  // addui $gp, $gp, %lo(_gp_disp)
532  // addu  $gp, $gp, $reg
533  // when support for position independent code is enabled.
534  if (!Pic || (isN32() || isN64()))
535    return;
536
537  // There's a GNU extension controlled by -mno-shared that allows
538  // locally-binding symbols to be accessed using absolute addresses.
539  // This is currently not supported. When supported -mno-shared makes
540  // .cpload expand to:
541  //   lui     $gp, %hi(__gnu_local_gp)
542  //   addiu   $gp, $gp, %lo(__gnu_local_gp)
543
544  StringRef SymName("_gp_disp");
545  MCAssembler &MCA = getStreamer().getAssembler();
546  MCSymbol *GP_Disp = MCA.getContext().GetOrCreateSymbol(SymName);
547  MCA.getOrCreateSymbolData(*GP_Disp);
548
549  MCInst TmpInst;
550  TmpInst.setOpcode(Mips::LUi);
551  TmpInst.addOperand(MCOperand::CreateReg(Mips::GP));
552  const MCSymbolRefExpr *HiSym = MCSymbolRefExpr::Create(
553      "_gp_disp", MCSymbolRefExpr::VK_Mips_ABS_HI, MCA.getContext());
554  TmpInst.addOperand(MCOperand::CreateExpr(HiSym));
555  getStreamer().EmitInstruction(TmpInst, STI);
556
557  TmpInst.clear();
558
559  TmpInst.setOpcode(Mips::ADDiu);
560  TmpInst.addOperand(MCOperand::CreateReg(Mips::GP));
561  TmpInst.addOperand(MCOperand::CreateReg(Mips::GP));
562  const MCSymbolRefExpr *LoSym = MCSymbolRefExpr::Create(
563      "_gp_disp", MCSymbolRefExpr::VK_Mips_ABS_LO, MCA.getContext());
564  TmpInst.addOperand(MCOperand::CreateExpr(LoSym));
565  getStreamer().EmitInstruction(TmpInst, STI);
566
567  TmpInst.clear();
568
569  TmpInst.setOpcode(Mips::ADDu);
570  TmpInst.addOperand(MCOperand::CreateReg(Mips::GP));
571  TmpInst.addOperand(MCOperand::CreateReg(Mips::GP));
572  TmpInst.addOperand(MCOperand::CreateReg(RegNo));
573  getStreamer().EmitInstruction(TmpInst, STI);
574
575  setCanHaveModuleDir(false);
576}
577
578void MipsTargetELFStreamer::emitDirectiveCpsetup(unsigned RegNo,
579                                                 int RegOrOffset,
580                                                 const MCSymbol &Sym,
581                                                 bool IsReg) {
582  // Only N32 and N64 emit anything for .cpsetup iff PIC is set.
583  if (!Pic || !(isN32() || isN64()))
584    return;
585
586  MCAssembler &MCA = getStreamer().getAssembler();
587  MCInst Inst;
588
589  // Either store the old $gp in a register or on the stack
590  if (IsReg) {
591    // move $save, $gpreg
592    Inst.setOpcode(Mips::DADDu);
593    Inst.addOperand(MCOperand::CreateReg(RegOrOffset));
594    Inst.addOperand(MCOperand::CreateReg(Mips::GP));
595    Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
596  } else {
597    // sd $gpreg, offset($sp)
598    Inst.setOpcode(Mips::SD);
599    Inst.addOperand(MCOperand::CreateReg(Mips::GP));
600    Inst.addOperand(MCOperand::CreateReg(Mips::SP));
601    Inst.addOperand(MCOperand::CreateImm(RegOrOffset));
602  }
603  getStreamer().EmitInstruction(Inst, STI);
604  Inst.clear();
605
606  const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
607      Sym.getName(), MCSymbolRefExpr::VK_Mips_GPOFF_HI, MCA.getContext());
608  const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
609      Sym.getName(), MCSymbolRefExpr::VK_Mips_GPOFF_LO, MCA.getContext());
610  // lui $gp, %hi(%neg(%gp_rel(funcSym)))
611  Inst.setOpcode(Mips::LUi);
612  Inst.addOperand(MCOperand::CreateReg(Mips::GP));
613  Inst.addOperand(MCOperand::CreateExpr(HiExpr));
614  getStreamer().EmitInstruction(Inst, STI);
615  Inst.clear();
616
617  // addiu  $gp, $gp, %lo(%neg(%gp_rel(funcSym)))
618  Inst.setOpcode(Mips::ADDiu);
619  Inst.addOperand(MCOperand::CreateReg(Mips::GP));
620  Inst.addOperand(MCOperand::CreateReg(Mips::GP));
621  Inst.addOperand(MCOperand::CreateExpr(LoExpr));
622  getStreamer().EmitInstruction(Inst, STI);
623  Inst.clear();
624
625  // daddu  $gp, $gp, $funcreg
626  Inst.setOpcode(Mips::DADDu);
627  Inst.addOperand(MCOperand::CreateReg(Mips::GP));
628  Inst.addOperand(MCOperand::CreateReg(Mips::GP));
629  Inst.addOperand(MCOperand::CreateReg(RegNo));
630  getStreamer().EmitInstruction(Inst, STI);
631
632  setCanHaveModuleDir(false);
633}
634
635void MipsTargetELFStreamer::emitMipsAbiFlags() {
636  MCAssembler &MCA = getStreamer().getAssembler();
637  MCContext &Context = MCA.getContext();
638  MCStreamer &OS = getStreamer();
639  const MCSectionELF *Sec =
640      Context.getELFSection(".MIPS.abiflags", ELF::SHT_MIPS_ABIFLAGS,
641                            ELF::SHF_ALLOC, SectionKind::getMetadata());
642  MCSectionData &ABIShndxSD = MCA.getOrCreateSectionData(*Sec);
643  ABIShndxSD.setAlignment(8);
644  OS.SwitchSection(Sec);
645
646  OS << ABIFlagsSection;
647}
648
649void MipsTargetELFStreamer::emitDirectiveModuleOddSPReg(bool Enabled,
650                                                        bool IsO32ABI) {
651  MipsTargetStreamer::emitDirectiveModuleOddSPReg(Enabled, IsO32ABI);
652
653  ABIFlagsSection.OddSPReg = Enabled;
654}
655