xref: /llvm-project/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp (revision eec21ccee0950d52926a79685573db1996e3ba5b)
1 //===-- MipsTargetStreamer.cpp - Mips Target Streamer Methods -------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file provides Mips specific target streamer methods.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "MipsTargetStreamer.h"
14 #include "MCTargetDesc/MipsABIInfo.h"
15 #include "MipsELFStreamer.h"
16 #include "MipsInstPrinter.h"
17 #include "MipsMCExpr.h"
18 #include "MipsMCTargetDesc.h"
19 #include "llvm/BinaryFormat/ELF.h"
20 #include "llvm/MC/MCAssembler.h"
21 #include "llvm/MC/MCContext.h"
22 #include "llvm/MC/MCELFObjectWriter.h"
23 #include "llvm/MC/MCObjectFileInfo.h"
24 #include "llvm/MC/MCSectionELF.h"
25 #include "llvm/MC/MCSubtargetInfo.h"
26 #include "llvm/MC/MCSymbolELF.h"
27 #include "llvm/Support/Casting.h"
28 #include "llvm/Support/CommandLine.h"
29 #include "llvm/Support/ErrorHandling.h"
30 #include "llvm/Support/FormattedStream.h"
31 
32 using namespace llvm;
33 
34 namespace {
35 static cl::opt<bool> RoundSectionSizes(
36     "mips-round-section-sizes", cl::init(false),
37     cl::desc("Round section sizes up to the section alignment"), cl::Hidden);
38 } // end anonymous namespace
39 
40 static bool isMicroMips(const MCSubtargetInfo *STI) {
41   return STI->hasFeature(Mips::FeatureMicroMips);
42 }
43 
44 static bool isMips32r6(const MCSubtargetInfo *STI) {
45   return STI->hasFeature(Mips::FeatureMips32r6);
46 }
47 
48 MipsTargetStreamer::MipsTargetStreamer(MCStreamer &S)
49     : MCTargetStreamer(S), GPReg(Mips::GP), ModuleDirectiveAllowed(true) {
50   GPRInfoSet = FPRInfoSet = FrameInfoSet = false;
51 }
52 void MipsTargetStreamer::emitDirectiveSetMicroMips() {}
53 void MipsTargetStreamer::emitDirectiveSetNoMicroMips() {}
54 void MipsTargetStreamer::setUsesMicroMips() {}
55 void MipsTargetStreamer::emitDirectiveSetMips16() {}
56 void MipsTargetStreamer::emitDirectiveSetNoMips16() { forbidModuleDirective(); }
57 void MipsTargetStreamer::emitDirectiveSetReorder() { forbidModuleDirective(); }
58 void MipsTargetStreamer::emitDirectiveSetNoReorder() {}
59 void MipsTargetStreamer::emitDirectiveSetMacro() { forbidModuleDirective(); }
60 void MipsTargetStreamer::emitDirectiveSetNoMacro() { forbidModuleDirective(); }
61 void MipsTargetStreamer::emitDirectiveSetMsa() { forbidModuleDirective(); }
62 void MipsTargetStreamer::emitDirectiveSetNoMsa() { forbidModuleDirective(); }
63 void MipsTargetStreamer::emitDirectiveSetMt() {}
64 void MipsTargetStreamer::emitDirectiveSetNoMt() { forbidModuleDirective(); }
65 void MipsTargetStreamer::emitDirectiveSetCRC() {}
66 void MipsTargetStreamer::emitDirectiveSetNoCRC() {}
67 void MipsTargetStreamer::emitDirectiveSetVirt() {}
68 void MipsTargetStreamer::emitDirectiveSetNoVirt() {}
69 void MipsTargetStreamer::emitDirectiveSetGINV() {}
70 void MipsTargetStreamer::emitDirectiveSetNoGINV() {}
71 void MipsTargetStreamer::emitDirectiveSetAt() { forbidModuleDirective(); }
72 void MipsTargetStreamer::emitDirectiveSetAtWithArg(unsigned RegNo) {
73   forbidModuleDirective();
74 }
75 void MipsTargetStreamer::emitDirectiveSetNoAt() { forbidModuleDirective(); }
76 void MipsTargetStreamer::emitDirectiveEnd(StringRef Name) {}
77 void MipsTargetStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {}
78 void MipsTargetStreamer::emitDirectiveAbiCalls() {}
79 void MipsTargetStreamer::emitDirectiveNaN2008() {}
80 void MipsTargetStreamer::emitDirectiveNaNLegacy() {}
81 void MipsTargetStreamer::emitDirectiveOptionPic0() {}
82 void MipsTargetStreamer::emitDirectiveOptionPic2() {}
83 void MipsTargetStreamer::emitDirectiveInsn() { forbidModuleDirective(); }
84 void MipsTargetStreamer::emitFrame(unsigned StackReg, unsigned StackSize,
85                                    unsigned ReturnReg) {}
86 void MipsTargetStreamer::emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) {}
87 void MipsTargetStreamer::emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) {
88 }
89 void MipsTargetStreamer::emitDirectiveSetArch(StringRef Arch) {
90   forbidModuleDirective();
91 }
92 void MipsTargetStreamer::emitDirectiveSetMips0() { forbidModuleDirective(); }
93 void MipsTargetStreamer::emitDirectiveSetMips1() { forbidModuleDirective(); }
94 void MipsTargetStreamer::emitDirectiveSetMips2() { forbidModuleDirective(); }
95 void MipsTargetStreamer::emitDirectiveSetMips3() { forbidModuleDirective(); }
96 void MipsTargetStreamer::emitDirectiveSetMips4() { forbidModuleDirective(); }
97 void MipsTargetStreamer::emitDirectiveSetMips5() { forbidModuleDirective(); }
98 void MipsTargetStreamer::emitDirectiveSetMips32() { forbidModuleDirective(); }
99 void MipsTargetStreamer::emitDirectiveSetMips32R2() { forbidModuleDirective(); }
100 void MipsTargetStreamer::emitDirectiveSetMips32R3() { forbidModuleDirective(); }
101 void MipsTargetStreamer::emitDirectiveSetMips32R5() { forbidModuleDirective(); }
102 void MipsTargetStreamer::emitDirectiveSetMips32R6() { forbidModuleDirective(); }
103 void MipsTargetStreamer::emitDirectiveSetMips64() { forbidModuleDirective(); }
104 void MipsTargetStreamer::emitDirectiveSetMips64R2() { forbidModuleDirective(); }
105 void MipsTargetStreamer::emitDirectiveSetMips64R3() { forbidModuleDirective(); }
106 void MipsTargetStreamer::emitDirectiveSetMips64R5() { forbidModuleDirective(); }
107 void MipsTargetStreamer::emitDirectiveSetMips64R6() { forbidModuleDirective(); }
108 void MipsTargetStreamer::emitDirectiveSetPop() { forbidModuleDirective(); }
109 void MipsTargetStreamer::emitDirectiveSetPush() { forbidModuleDirective(); }
110 void MipsTargetStreamer::emitDirectiveSetSoftFloat() {
111   forbidModuleDirective();
112 }
113 void MipsTargetStreamer::emitDirectiveSetHardFloat() {
114   forbidModuleDirective();
115 }
116 void MipsTargetStreamer::emitDirectiveSetDsp() { forbidModuleDirective(); }
117 void MipsTargetStreamer::emitDirectiveSetDspr2() { forbidModuleDirective(); }
118 void MipsTargetStreamer::emitDirectiveSetNoDsp() { forbidModuleDirective(); }
119 void MipsTargetStreamer::emitDirectiveSetMips3D() { forbidModuleDirective(); }
120 void MipsTargetStreamer::emitDirectiveSetNoMips3D() { forbidModuleDirective(); }
121 void MipsTargetStreamer::emitDirectiveCpAdd(unsigned RegNo) {}
122 void MipsTargetStreamer::emitDirectiveCpLoad(unsigned RegNo) {}
123 void MipsTargetStreamer::emitDirectiveCpLocal(unsigned RegNo) {
124   // .cplocal $reg
125   // This directive forces to use the alternate register for context pointer.
126   // For example
127   //   .cplocal $4
128   //   jal foo
129   // expands to
130   //   ld    $25, %call16(foo)($4)
131   //   jalr  $25
132 
133   if (!getABI().IsN32() && !getABI().IsN64())
134     return;
135 
136   GPReg = RegNo;
137 
138   forbidModuleDirective();
139 }
140 bool MipsTargetStreamer::emitDirectiveCpRestore(
141     int Offset, function_ref<unsigned()> GetATReg, SMLoc IDLoc,
142     const MCSubtargetInfo *STI) {
143   forbidModuleDirective();
144   return true;
145 }
146 void MipsTargetStreamer::emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
147                                               const MCSymbol &Sym, bool IsReg) {
148 }
149 void MipsTargetStreamer::emitDirectiveCpreturn(unsigned SaveLocation,
150                                                bool SaveLocationIsRegister) {}
151 
152 void MipsTargetStreamer::emitDirectiveModuleFP() {}
153 
154 void MipsTargetStreamer::emitDirectiveModuleOddSPReg() {
155   if (!ABIFlagsSection.OddSPReg && !ABIFlagsSection.Is32BitABI)
156     report_fatal_error("+nooddspreg is only valid for O32");
157 }
158 void MipsTargetStreamer::emitDirectiveModuleSoftFloat() {}
159 void MipsTargetStreamer::emitDirectiveModuleHardFloat() {}
160 void MipsTargetStreamer::emitDirectiveModuleMT() {}
161 void MipsTargetStreamer::emitDirectiveModuleCRC() {}
162 void MipsTargetStreamer::emitDirectiveModuleNoCRC() {}
163 void MipsTargetStreamer::emitDirectiveModuleVirt() {}
164 void MipsTargetStreamer::emitDirectiveModuleNoVirt() {}
165 void MipsTargetStreamer::emitDirectiveModuleGINV() {}
166 void MipsTargetStreamer::emitDirectiveModuleNoGINV() {}
167 void MipsTargetStreamer::emitDirectiveSetFp(
168     MipsABIFlagsSection::FpABIKind Value) {
169   forbidModuleDirective();
170 }
171 void MipsTargetStreamer::emitDirectiveSetOddSPReg() { forbidModuleDirective(); }
172 void MipsTargetStreamer::emitDirectiveSetNoOddSPReg() {
173   forbidModuleDirective();
174 }
175 
176 void MipsTargetStreamer::emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
177                                const MCSubtargetInfo *STI) {
178   MCInst TmpInst;
179   TmpInst.setOpcode(Opcode);
180   TmpInst.addOperand(MCOperand::createReg(Reg0));
181   TmpInst.setLoc(IDLoc);
182   getStreamer().emitInstruction(TmpInst, *STI);
183 }
184 
185 void MipsTargetStreamer::emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1,
186                                 SMLoc IDLoc, const MCSubtargetInfo *STI) {
187   MCInst TmpInst;
188   TmpInst.setOpcode(Opcode);
189   TmpInst.addOperand(MCOperand::createReg(Reg0));
190   TmpInst.addOperand(Op1);
191   TmpInst.setLoc(IDLoc);
192   getStreamer().emitInstruction(TmpInst, *STI);
193 }
194 
195 void MipsTargetStreamer::emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm,
196                                 SMLoc IDLoc, const MCSubtargetInfo *STI) {
197   emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, STI);
198 }
199 
200 void MipsTargetStreamer::emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1,
201                                 SMLoc IDLoc, const MCSubtargetInfo *STI) {
202   emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, STI);
203 }
204 
205 void MipsTargetStreamer::emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2,
206                                 SMLoc IDLoc, const MCSubtargetInfo *STI) {
207   MCInst TmpInst;
208   TmpInst.setOpcode(Opcode);
209   TmpInst.addOperand(MCOperand::createImm(Imm1));
210   TmpInst.addOperand(MCOperand::createImm(Imm2));
211   TmpInst.setLoc(IDLoc);
212   getStreamer().emitInstruction(TmpInst, *STI);
213 }
214 
215 void MipsTargetStreamer::emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1,
216                                  MCOperand Op2, SMLoc IDLoc,
217                                  const MCSubtargetInfo *STI) {
218   MCInst TmpInst;
219   TmpInst.setOpcode(Opcode);
220   TmpInst.addOperand(MCOperand::createReg(Reg0));
221   TmpInst.addOperand(MCOperand::createReg(Reg1));
222   TmpInst.addOperand(Op2);
223   TmpInst.setLoc(IDLoc);
224   getStreamer().emitInstruction(TmpInst, *STI);
225 }
226 
227 void MipsTargetStreamer::emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1,
228                                  unsigned Reg2, SMLoc IDLoc,
229                                  const MCSubtargetInfo *STI) {
230   emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc, STI);
231 }
232 
233 void MipsTargetStreamer::emitRRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1,
234                                   unsigned Reg2, MCOperand Op3, SMLoc IDLoc,
235                                   const MCSubtargetInfo *STI) {
236   MCInst TmpInst;
237   TmpInst.setOpcode(Opcode);
238   TmpInst.addOperand(MCOperand::createReg(Reg0));
239   TmpInst.addOperand(MCOperand::createReg(Reg1));
240   TmpInst.addOperand(MCOperand::createReg(Reg2));
241   TmpInst.addOperand(Op3);
242   TmpInst.setLoc(IDLoc);
243   getStreamer().emitInstruction(TmpInst, *STI);
244 }
245 
246 void MipsTargetStreamer::emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1,
247                                  int16_t Imm, SMLoc IDLoc,
248                                  const MCSubtargetInfo *STI) {
249   emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc, STI);
250 }
251 
252 void MipsTargetStreamer::emitRRIII(unsigned Opcode, unsigned Reg0,
253                                    unsigned Reg1, int16_t Imm0, int16_t Imm1,
254                                    int16_t Imm2, SMLoc IDLoc,
255                                    const MCSubtargetInfo *STI) {
256   MCInst TmpInst;
257   TmpInst.setOpcode(Opcode);
258   TmpInst.addOperand(MCOperand::createReg(Reg0));
259   TmpInst.addOperand(MCOperand::createReg(Reg1));
260   TmpInst.addOperand(MCOperand::createImm(Imm0));
261   TmpInst.addOperand(MCOperand::createImm(Imm1));
262   TmpInst.addOperand(MCOperand::createImm(Imm2));
263   TmpInst.setLoc(IDLoc);
264   getStreamer().emitInstruction(TmpInst, *STI);
265 }
266 
267 void MipsTargetStreamer::emitAddu(unsigned DstReg, unsigned SrcReg,
268                                   unsigned TrgReg, bool Is64Bit,
269                                   const MCSubtargetInfo *STI) {
270   emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
271           STI);
272 }
273 
274 void MipsTargetStreamer::emitDSLL(unsigned DstReg, unsigned SrcReg,
275                                   int16_t ShiftAmount, SMLoc IDLoc,
276                                   const MCSubtargetInfo *STI) {
277   if (ShiftAmount >= 32) {
278     emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc, STI);
279     return;
280   }
281 
282   emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, STI);
283 }
284 
285 void MipsTargetStreamer::emitEmptyDelaySlot(bool hasShortDelaySlot, SMLoc IDLoc,
286                                             const MCSubtargetInfo *STI) {
287   // The default case of `nop` is `sll $zero, $zero, 0`.
288   unsigned Opc = Mips::SLL;
289   if (isMicroMips(STI) && hasShortDelaySlot) {
290     Opc = isMips32r6(STI) ? Mips::MOVE16_MMR6 : Mips::MOVE16_MM;
291     emitRR(Opc, Mips::ZERO, Mips::ZERO, IDLoc, STI);
292     return;
293   }
294 
295   if (isMicroMips(STI))
296     Opc = isMips32r6(STI) ? Mips::SLL_MMR6 : Mips::SLL_MM;
297 
298   emitRRI(Opc, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
299 }
300 
301 void MipsTargetStreamer::emitNop(SMLoc IDLoc, const MCSubtargetInfo *STI) {
302   if (isMicroMips(STI))
303     emitRR(Mips::MOVE16_MM, Mips::ZERO, Mips::ZERO, IDLoc, STI);
304   else
305     emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
306 }
307 
308 /// Emit the $gp restore operation for .cprestore.
309 void MipsTargetStreamer::emitGPRestore(int Offset, SMLoc IDLoc,
310                                        const MCSubtargetInfo *STI) {
311   emitLoadWithImmOffset(Mips::LW, GPReg, Mips::SP, Offset, GPReg, IDLoc, STI);
312 }
313 
314 /// Emit a store instruction with an immediate offset.
315 void MipsTargetStreamer::emitStoreWithImmOffset(
316     unsigned Opcode, unsigned SrcReg, unsigned BaseReg, int64_t Offset,
317     function_ref<unsigned()> GetATReg, SMLoc IDLoc,
318     const MCSubtargetInfo *STI) {
319   if (isInt<16>(Offset)) {
320     emitRRI(Opcode, SrcReg, BaseReg, Offset, IDLoc, STI);
321     return;
322   }
323 
324   // sw $8, offset($8) => lui $at, %hi(offset)
325   //                      add $at, $at, $8
326   //                      sw $8, %lo(offset)($at)
327 
328   unsigned ATReg = GetATReg();
329   if (!ATReg)
330     return;
331 
332   unsigned LoOffset = Offset & 0x0000ffff;
333   unsigned HiOffset = (Offset & 0xffff0000) >> 16;
334 
335   // If msb of LoOffset is 1(negative number) we must increment HiOffset
336   // to account for the sign-extension of the low part.
337   if (LoOffset & 0x8000)
338     HiOffset++;
339 
340   // Generate the base address in ATReg.
341   emitRI(Mips::LUi, ATReg, HiOffset, IDLoc, STI);
342   if (BaseReg != Mips::ZERO)
343     emitRRR(Mips::ADDu, ATReg, ATReg, BaseReg, IDLoc, STI);
344   // Emit the store with the adjusted base and offset.
345   emitRRI(Opcode, SrcReg, ATReg, LoOffset, IDLoc, STI);
346 }
347 
348 /// Emit a load instruction with an immediate offset. DstReg and TmpReg are
349 /// permitted to be the same register iff DstReg is distinct from BaseReg and
350 /// DstReg is a GPR. It is the callers responsibility to identify such cases
351 /// and pass the appropriate register in TmpReg.
352 void MipsTargetStreamer::emitLoadWithImmOffset(unsigned Opcode, unsigned DstReg,
353                                                unsigned BaseReg, int64_t Offset,
354                                                unsigned TmpReg, SMLoc IDLoc,
355                                                const MCSubtargetInfo *STI) {
356   if (isInt<16>(Offset)) {
357     emitRRI(Opcode, DstReg, BaseReg, Offset, IDLoc, STI);
358     return;
359   }
360 
361   // 1) lw $8, offset($9) => lui $8, %hi(offset)
362   //                         add $8, $8, $9
363   //                         lw $8, %lo(offset)($9)
364   // 2) lw $8, offset($8) => lui $at, %hi(offset)
365   //                         add $at, $at, $8
366   //                         lw $8, %lo(offset)($at)
367 
368   unsigned LoOffset = Offset & 0x0000ffff;
369   unsigned HiOffset = (Offset & 0xffff0000) >> 16;
370 
371   // If msb of LoOffset is 1(negative number) we must increment HiOffset
372   // to account for the sign-extension of the low part.
373   if (LoOffset & 0x8000)
374     HiOffset++;
375 
376   // Generate the base address in TmpReg.
377   emitRI(Mips::LUi, TmpReg, HiOffset, IDLoc, STI);
378   if (BaseReg != Mips::ZERO)
379     emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
380   // Emit the load with the adjusted base and offset.
381   emitRRI(Opcode, DstReg, TmpReg, LoOffset, IDLoc, STI);
382 }
383 
384 MipsTargetAsmStreamer::MipsTargetAsmStreamer(MCStreamer &S,
385                                              formatted_raw_ostream &OS)
386     : MipsTargetStreamer(S), OS(OS) {}
387 
388 void MipsTargetAsmStreamer::emitDirectiveSetMicroMips() {
389   OS << "\t.set\tmicromips\n";
390   forbidModuleDirective();
391 }
392 
393 void MipsTargetAsmStreamer::emitDirectiveSetNoMicroMips() {
394   OS << "\t.set\tnomicromips\n";
395   forbidModuleDirective();
396 }
397 
398 void MipsTargetAsmStreamer::emitDirectiveSetMips16() {
399   OS << "\t.set\tmips16\n";
400   forbidModuleDirective();
401 }
402 
403 void MipsTargetAsmStreamer::emitDirectiveSetNoMips16() {
404   OS << "\t.set\tnomips16\n";
405   MipsTargetStreamer::emitDirectiveSetNoMips16();
406 }
407 
408 void MipsTargetAsmStreamer::emitDirectiveSetReorder() {
409   OS << "\t.set\treorder\n";
410   MipsTargetStreamer::emitDirectiveSetReorder();
411 }
412 
413 void MipsTargetAsmStreamer::emitDirectiveSetNoReorder() {
414   OS << "\t.set\tnoreorder\n";
415   forbidModuleDirective();
416 }
417 
418 void MipsTargetAsmStreamer::emitDirectiveSetMacro() {
419   OS << "\t.set\tmacro\n";
420   MipsTargetStreamer::emitDirectiveSetMacro();
421 }
422 
423 void MipsTargetAsmStreamer::emitDirectiveSetNoMacro() {
424   OS << "\t.set\tnomacro\n";
425   MipsTargetStreamer::emitDirectiveSetNoMacro();
426 }
427 
428 void MipsTargetAsmStreamer::emitDirectiveSetMsa() {
429   OS << "\t.set\tmsa\n";
430   MipsTargetStreamer::emitDirectiveSetMsa();
431 }
432 
433 void MipsTargetAsmStreamer::emitDirectiveSetNoMsa() {
434   OS << "\t.set\tnomsa\n";
435   MipsTargetStreamer::emitDirectiveSetNoMsa();
436 }
437 
438 void MipsTargetAsmStreamer::emitDirectiveSetMt() {
439   OS << "\t.set\tmt\n";
440   MipsTargetStreamer::emitDirectiveSetMt();
441 }
442 
443 void MipsTargetAsmStreamer::emitDirectiveSetNoMt() {
444   OS << "\t.set\tnomt\n";
445   MipsTargetStreamer::emitDirectiveSetNoMt();
446 }
447 
448 void MipsTargetAsmStreamer::emitDirectiveSetCRC() {
449   OS << "\t.set\tcrc\n";
450   MipsTargetStreamer::emitDirectiveSetCRC();
451 }
452 
453 void MipsTargetAsmStreamer::emitDirectiveSetNoCRC() {
454   OS << "\t.set\tnocrc\n";
455   MipsTargetStreamer::emitDirectiveSetNoCRC();
456 }
457 
458 void MipsTargetAsmStreamer::emitDirectiveSetVirt() {
459   OS << "\t.set\tvirt\n";
460   MipsTargetStreamer::emitDirectiveSetVirt();
461 }
462 
463 void MipsTargetAsmStreamer::emitDirectiveSetNoVirt() {
464   OS << "\t.set\tnovirt\n";
465   MipsTargetStreamer::emitDirectiveSetNoVirt();
466 }
467 
468 void MipsTargetAsmStreamer::emitDirectiveSetGINV() {
469   OS << "\t.set\tginv\n";
470   MipsTargetStreamer::emitDirectiveSetGINV();
471 }
472 
473 void MipsTargetAsmStreamer::emitDirectiveSetNoGINV() {
474   OS << "\t.set\tnoginv\n";
475   MipsTargetStreamer::emitDirectiveSetNoGINV();
476 }
477 
478 void MipsTargetAsmStreamer::emitDirectiveSetAt() {
479   OS << "\t.set\tat\n";
480   MipsTargetStreamer::emitDirectiveSetAt();
481 }
482 
483 void MipsTargetAsmStreamer::emitDirectiveSetAtWithArg(unsigned RegNo) {
484   OS << "\t.set\tat=$" << Twine(RegNo) << "\n";
485   MipsTargetStreamer::emitDirectiveSetAtWithArg(RegNo);
486 }
487 
488 void MipsTargetAsmStreamer::emitDirectiveSetNoAt() {
489   OS << "\t.set\tnoat\n";
490   MipsTargetStreamer::emitDirectiveSetNoAt();
491 }
492 
493 void MipsTargetAsmStreamer::emitDirectiveEnd(StringRef Name) {
494   OS << "\t.end\t" << Name << '\n';
495 }
496 
497 void MipsTargetAsmStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {
498   OS << "\t.ent\t" << Symbol.getName() << '\n';
499 }
500 
501 void MipsTargetAsmStreamer::emitDirectiveAbiCalls() { OS << "\t.abicalls\n"; }
502 
503 void MipsTargetAsmStreamer::emitDirectiveNaN2008() { OS << "\t.nan\t2008\n"; }
504 
505 void MipsTargetAsmStreamer::emitDirectiveNaNLegacy() {
506   OS << "\t.nan\tlegacy\n";
507 }
508 
509 void MipsTargetAsmStreamer::emitDirectiveOptionPic0() {
510   OS << "\t.option\tpic0\n";
511 }
512 
513 void MipsTargetAsmStreamer::emitDirectiveOptionPic2() {
514   OS << "\t.option\tpic2\n";
515 }
516 
517 void MipsTargetAsmStreamer::emitDirectiveInsn() {
518   MipsTargetStreamer::emitDirectiveInsn();
519   OS << "\t.insn\n";
520 }
521 
522 void MipsTargetAsmStreamer::emitFrame(unsigned StackReg, unsigned StackSize,
523                                       unsigned ReturnReg) {
524   OS << "\t.frame\t$"
525      << StringRef(MipsInstPrinter::getRegisterName(StackReg)).lower() << ","
526      << StackSize << ",$"
527      << StringRef(MipsInstPrinter::getRegisterName(ReturnReg)).lower() << '\n';
528 }
529 
530 void MipsTargetAsmStreamer::emitDirectiveSetArch(StringRef Arch) {
531   OS << "\t.set arch=" << Arch << "\n";
532   MipsTargetStreamer::emitDirectiveSetArch(Arch);
533 }
534 
535 void MipsTargetAsmStreamer::emitDirectiveSetMips0() {
536   OS << "\t.set\tmips0\n";
537   MipsTargetStreamer::emitDirectiveSetMips0();
538 }
539 
540 void MipsTargetAsmStreamer::emitDirectiveSetMips1() {
541   OS << "\t.set\tmips1\n";
542   MipsTargetStreamer::emitDirectiveSetMips1();
543 }
544 
545 void MipsTargetAsmStreamer::emitDirectiveSetMips2() {
546   OS << "\t.set\tmips2\n";
547   MipsTargetStreamer::emitDirectiveSetMips2();
548 }
549 
550 void MipsTargetAsmStreamer::emitDirectiveSetMips3() {
551   OS << "\t.set\tmips3\n";
552   MipsTargetStreamer::emitDirectiveSetMips3();
553 }
554 
555 void MipsTargetAsmStreamer::emitDirectiveSetMips4() {
556   OS << "\t.set\tmips4\n";
557   MipsTargetStreamer::emitDirectiveSetMips4();
558 }
559 
560 void MipsTargetAsmStreamer::emitDirectiveSetMips5() {
561   OS << "\t.set\tmips5\n";
562   MipsTargetStreamer::emitDirectiveSetMips5();
563 }
564 
565 void MipsTargetAsmStreamer::emitDirectiveSetMips32() {
566   OS << "\t.set\tmips32\n";
567   MipsTargetStreamer::emitDirectiveSetMips32();
568 }
569 
570 void MipsTargetAsmStreamer::emitDirectiveSetMips32R2() {
571   OS << "\t.set\tmips32r2\n";
572   MipsTargetStreamer::emitDirectiveSetMips32R2();
573 }
574 
575 void MipsTargetAsmStreamer::emitDirectiveSetMips32R3() {
576   OS << "\t.set\tmips32r3\n";
577   MipsTargetStreamer::emitDirectiveSetMips32R3();
578 }
579 
580 void MipsTargetAsmStreamer::emitDirectiveSetMips32R5() {
581   OS << "\t.set\tmips32r5\n";
582   MipsTargetStreamer::emitDirectiveSetMips32R5();
583 }
584 
585 void MipsTargetAsmStreamer::emitDirectiveSetMips32R6() {
586   OS << "\t.set\tmips32r6\n";
587   MipsTargetStreamer::emitDirectiveSetMips32R6();
588 }
589 
590 void MipsTargetAsmStreamer::emitDirectiveSetMips64() {
591   OS << "\t.set\tmips64\n";
592   MipsTargetStreamer::emitDirectiveSetMips64();
593 }
594 
595 void MipsTargetAsmStreamer::emitDirectiveSetMips64R2() {
596   OS << "\t.set\tmips64r2\n";
597   MipsTargetStreamer::emitDirectiveSetMips64R2();
598 }
599 
600 void MipsTargetAsmStreamer::emitDirectiveSetMips64R3() {
601   OS << "\t.set\tmips64r3\n";
602   MipsTargetStreamer::emitDirectiveSetMips64R3();
603 }
604 
605 void MipsTargetAsmStreamer::emitDirectiveSetMips64R5() {
606   OS << "\t.set\tmips64r5\n";
607   MipsTargetStreamer::emitDirectiveSetMips64R5();
608 }
609 
610 void MipsTargetAsmStreamer::emitDirectiveSetMips64R6() {
611   OS << "\t.set\tmips64r6\n";
612   MipsTargetStreamer::emitDirectiveSetMips64R6();
613 }
614 
615 void MipsTargetAsmStreamer::emitDirectiveSetDsp() {
616   OS << "\t.set\tdsp\n";
617   MipsTargetStreamer::emitDirectiveSetDsp();
618 }
619 
620 void MipsTargetAsmStreamer::emitDirectiveSetDspr2() {
621   OS << "\t.set\tdspr2\n";
622   MipsTargetStreamer::emitDirectiveSetDspr2();
623 }
624 
625 void MipsTargetAsmStreamer::emitDirectiveSetNoDsp() {
626   OS << "\t.set\tnodsp\n";
627   MipsTargetStreamer::emitDirectiveSetNoDsp();
628 }
629 
630 void MipsTargetAsmStreamer::emitDirectiveSetMips3D() {
631   OS << "\t.set\tmips3d\n";
632   MipsTargetStreamer::emitDirectiveSetMips3D();
633 }
634 
635 void MipsTargetAsmStreamer::emitDirectiveSetNoMips3D() {
636   OS << "\t.set\tnomips3d\n";
637   MipsTargetStreamer::emitDirectiveSetNoMips3D();
638 }
639 
640 void MipsTargetAsmStreamer::emitDirectiveSetPop() {
641   OS << "\t.set\tpop\n";
642   MipsTargetStreamer::emitDirectiveSetPop();
643 }
644 
645 void MipsTargetAsmStreamer::emitDirectiveSetPush() {
646  OS << "\t.set\tpush\n";
647  MipsTargetStreamer::emitDirectiveSetPush();
648 }
649 
650 void MipsTargetAsmStreamer::emitDirectiveSetSoftFloat() {
651   OS << "\t.set\tsoftfloat\n";
652   MipsTargetStreamer::emitDirectiveSetSoftFloat();
653 }
654 
655 void MipsTargetAsmStreamer::emitDirectiveSetHardFloat() {
656   OS << "\t.set\thardfloat\n";
657   MipsTargetStreamer::emitDirectiveSetHardFloat();
658 }
659 
660 // Print a 32 bit hex number with all numbers.
661 static void printHex32(unsigned Value, raw_ostream &OS) {
662   OS << "0x";
663   for (int i = 7; i >= 0; i--)
664     OS.write_hex((Value & (0xF << (i * 4))) >> (i * 4));
665 }
666 
667 void MipsTargetAsmStreamer::emitMask(unsigned CPUBitmask,
668                                      int CPUTopSavedRegOff) {
669   OS << "\t.mask \t";
670   printHex32(CPUBitmask, OS);
671   OS << ',' << CPUTopSavedRegOff << '\n';
672 }
673 
674 void MipsTargetAsmStreamer::emitFMask(unsigned FPUBitmask,
675                                       int FPUTopSavedRegOff) {
676   OS << "\t.fmask\t";
677   printHex32(FPUBitmask, OS);
678   OS << "," << FPUTopSavedRegOff << '\n';
679 }
680 
681 void MipsTargetAsmStreamer::emitDirectiveCpAdd(unsigned RegNo) {
682   OS << "\t.cpadd\t$"
683      << StringRef(MipsInstPrinter::getRegisterName(RegNo)).lower() << "\n";
684   forbidModuleDirective();
685 }
686 
687 void MipsTargetAsmStreamer::emitDirectiveCpLoad(unsigned RegNo) {
688   OS << "\t.cpload\t$"
689      << StringRef(MipsInstPrinter::getRegisterName(RegNo)).lower() << "\n";
690   forbidModuleDirective();
691 }
692 
693 void MipsTargetAsmStreamer::emitDirectiveCpLocal(unsigned RegNo) {
694   OS << "\t.cplocal\t$"
695      << StringRef(MipsInstPrinter::getRegisterName(RegNo)).lower() << "\n";
696   MipsTargetStreamer::emitDirectiveCpLocal(RegNo);
697 }
698 
699 bool MipsTargetAsmStreamer::emitDirectiveCpRestore(
700     int Offset, function_ref<unsigned()> GetATReg, SMLoc IDLoc,
701     const MCSubtargetInfo *STI) {
702   MipsTargetStreamer::emitDirectiveCpRestore(Offset, GetATReg, IDLoc, STI);
703   OS << "\t.cprestore\t" << Offset << "\n";
704   return true;
705 }
706 
707 void MipsTargetAsmStreamer::emitDirectiveCpsetup(unsigned RegNo,
708                                                  int RegOrOffset,
709                                                  const MCSymbol &Sym,
710                                                  bool IsReg) {
711   OS << "\t.cpsetup\t$"
712      << StringRef(MipsInstPrinter::getRegisterName(RegNo)).lower() << ", ";
713 
714   if (IsReg)
715     OS << "$"
716        << StringRef(MipsInstPrinter::getRegisterName(RegOrOffset)).lower();
717   else
718     OS << RegOrOffset;
719 
720   OS << ", ";
721 
722   OS << Sym.getName();
723   forbidModuleDirective();
724 }
725 
726 void MipsTargetAsmStreamer::emitDirectiveCpreturn(unsigned SaveLocation,
727                                                   bool SaveLocationIsRegister) {
728   OS << "\t.cpreturn";
729   forbidModuleDirective();
730 }
731 
732 void MipsTargetAsmStreamer::emitDirectiveModuleFP() {
733   MipsABIFlagsSection::FpABIKind FpABI = ABIFlagsSection.getFpABI();
734   if (FpABI == MipsABIFlagsSection::FpABIKind::SOFT)
735     OS << "\t.module\tsoftfloat\n";
736   else
737     OS << "\t.module\tfp=" << ABIFlagsSection.getFpABIString(FpABI) << "\n";
738 }
739 
740 void MipsTargetAsmStreamer::emitDirectiveSetFp(
741     MipsABIFlagsSection::FpABIKind Value) {
742   MipsTargetStreamer::emitDirectiveSetFp(Value);
743 
744   OS << "\t.set\tfp=";
745   OS << ABIFlagsSection.getFpABIString(Value) << "\n";
746 }
747 
748 void MipsTargetAsmStreamer::emitDirectiveModuleOddSPReg() {
749   MipsTargetStreamer::emitDirectiveModuleOddSPReg();
750 
751   OS << "\t.module\t" << (ABIFlagsSection.OddSPReg ? "" : "no") << "oddspreg\n";
752 }
753 
754 void MipsTargetAsmStreamer::emitDirectiveSetOddSPReg() {
755   MipsTargetStreamer::emitDirectiveSetOddSPReg();
756   OS << "\t.set\toddspreg\n";
757 }
758 
759 void MipsTargetAsmStreamer::emitDirectiveSetNoOddSPReg() {
760   MipsTargetStreamer::emitDirectiveSetNoOddSPReg();
761   OS << "\t.set\tnooddspreg\n";
762 }
763 
764 void MipsTargetAsmStreamer::emitDirectiveModuleSoftFloat() {
765   OS << "\t.module\tsoftfloat\n";
766 }
767 
768 void MipsTargetAsmStreamer::emitDirectiveModuleHardFloat() {
769   OS << "\t.module\thardfloat\n";
770 }
771 
772 void MipsTargetAsmStreamer::emitDirectiveModuleMT() {
773   OS << "\t.module\tmt\n";
774 }
775 
776 void MipsTargetAsmStreamer::emitDirectiveModuleCRC() {
777   OS << "\t.module\tcrc\n";
778 }
779 
780 void MipsTargetAsmStreamer::emitDirectiveModuleNoCRC() {
781   OS << "\t.module\tnocrc\n";
782 }
783 
784 void MipsTargetAsmStreamer::emitDirectiveModuleVirt() {
785   OS << "\t.module\tvirt\n";
786 }
787 
788 void MipsTargetAsmStreamer::emitDirectiveModuleNoVirt() {
789   OS << "\t.module\tnovirt\n";
790 }
791 
792 void MipsTargetAsmStreamer::emitDirectiveModuleGINV() {
793   OS << "\t.module\tginv\n";
794 }
795 
796 void MipsTargetAsmStreamer::emitDirectiveModuleNoGINV() {
797   OS << "\t.module\tnoginv\n";
798 }
799 
800 // This part is for ELF object output.
801 MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S,
802                                              const MCSubtargetInfo &STI)
803     : MipsTargetStreamer(S), MicroMipsEnabled(false), STI(STI) {
804   MCAssembler &MCA = getStreamer().getAssembler();
805   ELFObjectWriter &W = getStreamer().getWriter();
806 
807   // It's possible that MCObjectFileInfo isn't fully initialized at this point
808   // due to an initialization order problem where CodeGenTargetMachineImpl
809   // creates the target streamer before TargetLoweringObjectFile calls
810   // InitializeMCObjectFileInfo. There doesn't seem to be a single place that
811   // covers all cases so this statement covers most cases and direct object
812   // emission must call setPic() once MCObjectFileInfo has been initialized. The
813   // cases we don't handle here are covered by MipsAsmPrinter.
814   Pic = MCA.getContext().getObjectFileInfo()->isPositionIndependent();
815 
816   const FeatureBitset &Features = STI.getFeatureBits();
817 
818   // Set the header flags that we can in the constructor.
819   // FIXME: This is a fairly terrible hack. We set the rest
820   // of these in the destructor. The problem here is two-fold:
821   //
822   // a: Some of the eflags can be set/reset by directives.
823   // b: There aren't any usage paths that initialize the ABI
824   //    pointer until after we initialize either an assembler
825   //    or the target machine.
826   // We can fix this by making the target streamer construct
827   // the ABI, but this is fraught with wide ranging dependency
828   // issues as well.
829   unsigned EFlags = W.getELFHeaderEFlags();
830 
831   // FIXME: Fix a dependency issue by instantiating the ABI object to some
832   // default based off the triple. The triple doesn't describe the target
833   // fully, but any external user of the API that uses the MCTargetStreamer
834   // would otherwise crash on assertion failure.
835 
836   ABI = MipsABIInfo(
837       STI.getTargetTriple().getArch() == Triple::ArchType::mipsel ||
838               STI.getTargetTriple().getArch() == Triple::ArchType::mips
839           ? MipsABIInfo::O32()
840           : MipsABIInfo::N64());
841 
842   // Architecture
843   if (Features[Mips::FeatureMips64r6])
844     EFlags |= ELF::EF_MIPS_ARCH_64R6;
845   else if (Features[Mips::FeatureMips64r2] ||
846            Features[Mips::FeatureMips64r3] ||
847            Features[Mips::FeatureMips64r5])
848     EFlags |= ELF::EF_MIPS_ARCH_64R2;
849   else if (Features[Mips::FeatureMips64])
850     EFlags |= ELF::EF_MIPS_ARCH_64;
851   else if (Features[Mips::FeatureMips5])
852     EFlags |= ELF::EF_MIPS_ARCH_5;
853   else if (Features[Mips::FeatureMips4])
854     EFlags |= ELF::EF_MIPS_ARCH_4;
855   else if (Features[Mips::FeatureMips3])
856     EFlags |= ELF::EF_MIPS_ARCH_3;
857   else if (Features[Mips::FeatureMips32r6])
858     EFlags |= ELF::EF_MIPS_ARCH_32R6;
859   else if (Features[Mips::FeatureMips32r2] ||
860            Features[Mips::FeatureMips32r3] ||
861            Features[Mips::FeatureMips32r5])
862     EFlags |= ELF::EF_MIPS_ARCH_32R2;
863   else if (Features[Mips::FeatureMips32])
864     EFlags |= ELF::EF_MIPS_ARCH_32;
865   else if (Features[Mips::FeatureMips2])
866     EFlags |= ELF::EF_MIPS_ARCH_2;
867   else
868     EFlags |= ELF::EF_MIPS_ARCH_1;
869 
870   // Machine
871   if (Features[Mips::FeatureCnMips])
872     EFlags |= ELF::EF_MIPS_MACH_OCTEON;
873 
874   // Other options.
875   if (Features[Mips::FeatureNaN2008])
876     EFlags |= ELF::EF_MIPS_NAN2008;
877 
878   W.setELFHeaderEFlags(EFlags);
879 }
880 
881 void MipsTargetELFStreamer::emitLabel(MCSymbol *S) {
882   auto *Symbol = cast<MCSymbolELF>(S);
883   getStreamer().getAssembler().registerSymbol(*Symbol);
884   uint8_t Type = Symbol->getType();
885   if (Type != ELF::STT_FUNC)
886     return;
887 
888   if (isMicroMipsEnabled())
889     Symbol->setOther(ELF::STO_MIPS_MICROMIPS);
890 }
891 
892 void MipsTargetELFStreamer::finish() {
893   MCAssembler &MCA = getStreamer().getAssembler();
894   ELFObjectWriter &W = getStreamer().getWriter();
895   const MCObjectFileInfo &OFI = *MCA.getContext().getObjectFileInfo();
896   MCELFStreamer &S = getStreamer();
897 
898   // .bss, .text and .data are always at least 16-byte aligned.
899   MCSection &TextSection = *OFI.getTextSection();
900   S.switchSection(&TextSection);
901   MCSection &DataSection = *OFI.getDataSection();
902   S.switchSection(&DataSection);
903   MCSection &BSSSection = *OFI.getBSSSection();
904   S.switchSection(&BSSSection);
905 
906   TextSection.ensureMinAlignment(Align(16));
907   DataSection.ensureMinAlignment(Align(16));
908   BSSSection.ensureMinAlignment(Align(16));
909 
910   if (RoundSectionSizes) {
911     // Make sections sizes a multiple of the alignment. This is useful for
912     // verifying the output of IAS against the output of other assemblers but
913     // it's not necessary to produce a correct object and increases section
914     // size.
915     for (MCSection &Sec : MCA) {
916       MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
917 
918       Align Alignment = Section.getAlign();
919       S.switchSection(&Section);
920       if (Section.useCodeAlign())
921         S.emitCodeAlignment(Alignment, &STI, Alignment.value());
922       else
923         S.emitValueToAlignment(Alignment, 0, 1, Alignment.value());
924     }
925   }
926 
927   const FeatureBitset &Features = STI.getFeatureBits();
928 
929   // Update e_header flags. See the FIXME and comment above in
930   // the constructor for a full rundown on this.
931   unsigned EFlags = W.getELFHeaderEFlags();
932 
933   // ABI
934   // N64 does not require any ABI bits.
935   if (getABI().IsO32())
936     EFlags |= ELF::EF_MIPS_ABI_O32;
937   else if (getABI().IsN32())
938     EFlags |= ELF::EF_MIPS_ABI2;
939 
940   if (Features[Mips::FeatureGP64Bit]) {
941     if (getABI().IsO32())
942       EFlags |= ELF::EF_MIPS_32BITMODE; /* Compatibility Mode */
943   } else if (Features[Mips::FeatureMips64r2] || Features[Mips::FeatureMips64])
944     EFlags |= ELF::EF_MIPS_32BITMODE;
945 
946   // -mplt is not implemented but we should act as if it was
947   // given.
948   if (!Features[Mips::FeatureNoABICalls])
949     EFlags |= ELF::EF_MIPS_CPIC;
950 
951   if (Pic)
952     EFlags |= ELF::EF_MIPS_PIC | ELF::EF_MIPS_CPIC;
953 
954   W.setELFHeaderEFlags(EFlags);
955 
956   // Emit all the option records.
957   // At the moment we are only emitting .Mips.options (ODK_REGINFO) and
958   // .reginfo.
959   MipsELFStreamer &MEF = static_cast<MipsELFStreamer &>(Streamer);
960   MEF.EmitMipsOptionRecords();
961 
962   emitMipsAbiFlags();
963 }
964 
965 void MipsTargetELFStreamer::emitAssignment(MCSymbol *S, const MCExpr *Value) {
966   auto *Symbol = cast<MCSymbolELF>(S);
967   // If on rhs is micromips symbol then mark Symbol as microMips.
968   if (Value->getKind() != MCExpr::SymbolRef)
969     return;
970   const auto &RhsSym = cast<MCSymbolELF>(
971       static_cast<const MCSymbolRefExpr *>(Value)->getSymbol());
972 
973   if (!(RhsSym.getOther() & ELF::STO_MIPS_MICROMIPS))
974     return;
975 
976   Symbol->setOther(ELF::STO_MIPS_MICROMIPS);
977 }
978 
979 MCELFStreamer &MipsTargetELFStreamer::getStreamer() {
980   return static_cast<MCELFStreamer &>(Streamer);
981 }
982 
983 void MipsTargetELFStreamer::emitDirectiveSetMicroMips() {
984   MicroMipsEnabled = true;
985   forbidModuleDirective();
986 }
987 
988 void MipsTargetELFStreamer::emitDirectiveSetNoMicroMips() {
989   MicroMipsEnabled = false;
990   forbidModuleDirective();
991 }
992 
993 void MipsTargetELFStreamer::setUsesMicroMips() {
994   ELFObjectWriter &W = getStreamer().getWriter();
995   unsigned Flags = W.getELFHeaderEFlags();
996   Flags |= ELF::EF_MIPS_MICROMIPS;
997   W.setELFHeaderEFlags(Flags);
998 }
999 
1000 void MipsTargetELFStreamer::emitDirectiveSetMips16() {
1001   ELFObjectWriter &W = getStreamer().getWriter();
1002   unsigned Flags = W.getELFHeaderEFlags();
1003   Flags |= ELF::EF_MIPS_ARCH_ASE_M16;
1004   W.setELFHeaderEFlags(Flags);
1005   forbidModuleDirective();
1006 }
1007 
1008 void MipsTargetELFStreamer::emitDirectiveSetNoReorder() {
1009   ELFObjectWriter &W = getStreamer().getWriter();
1010   unsigned Flags = W.getELFHeaderEFlags();
1011   Flags |= ELF::EF_MIPS_NOREORDER;
1012   W.setELFHeaderEFlags(Flags);
1013   forbidModuleDirective();
1014 }
1015 
1016 void MipsTargetELFStreamer::emitDirectiveEnd(StringRef Name) {
1017   MCAssembler &MCA = getStreamer().getAssembler();
1018   MCContext &Context = MCA.getContext();
1019   MCStreamer &OS = getStreamer();
1020 
1021   OS.pushSection();
1022   MCSectionELF *Sec = Context.getELFSection(".pdr", ELF::SHT_PROGBITS, 0);
1023   OS.switchSection(Sec);
1024   Sec->setAlignment(Align(4));
1025 
1026   MCSymbol *Sym = Context.getOrCreateSymbol(Name);
1027   const MCSymbolRefExpr *ExprRef =
1028       MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Context);
1029 
1030   OS.emitValueImpl(ExprRef, 4);
1031 
1032   OS.emitIntValue(GPRInfoSet ? GPRBitMask : 0, 4); // reg_mask
1033   OS.emitIntValue(GPRInfoSet ? GPROffset : 0, 4);  // reg_offset
1034 
1035   OS.emitIntValue(FPRInfoSet ? FPRBitMask : 0, 4); // fpreg_mask
1036   OS.emitIntValue(FPRInfoSet ? FPROffset : 0, 4);  // fpreg_offset
1037 
1038   OS.emitIntValue(FrameInfoSet ? FrameOffset : 0, 4); // frame_offset
1039   OS.emitIntValue(FrameInfoSet ? FrameReg : 0, 4);    // frame_reg
1040   OS.emitIntValue(FrameInfoSet ? ReturnReg : 0, 4);   // return_reg
1041 
1042   // The .end directive marks the end of a procedure. Invalidate
1043   // the information gathered up until this point.
1044   GPRInfoSet = FPRInfoSet = FrameInfoSet = false;
1045 
1046   OS.popSection();
1047 
1048   // .end also implicitly sets the size.
1049   MCSymbol *CurPCSym = Context.createTempSymbol();
1050   OS.emitLabel(CurPCSym);
1051   const MCExpr *Size = MCBinaryExpr::createSub(
1052       MCSymbolRefExpr::create(CurPCSym, MCSymbolRefExpr::VK_None, Context),
1053       ExprRef, Context);
1054 
1055   // The ELFObjectWriter can determine the absolute size as it has access to
1056   // the layout information of the assembly file, so a size expression rather
1057   // than an absolute value is ok here.
1058   static_cast<MCSymbolELF *>(Sym)->setSize(Size);
1059 }
1060 
1061 void MipsTargetELFStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {
1062   GPRInfoSet = FPRInfoSet = FrameInfoSet = false;
1063 
1064   // .ent also acts like an implicit '.type symbol, STT_FUNC'
1065   static_cast<const MCSymbolELF &>(Symbol).setType(ELF::STT_FUNC);
1066 }
1067 
1068 void MipsTargetELFStreamer::emitDirectiveAbiCalls() {
1069   ELFObjectWriter &W = getStreamer().getWriter();
1070   unsigned Flags = W.getELFHeaderEFlags();
1071   Flags |= ELF::EF_MIPS_CPIC | ELF::EF_MIPS_PIC;
1072   W.setELFHeaderEFlags(Flags);
1073 }
1074 
1075 void MipsTargetELFStreamer::emitDirectiveNaN2008() {
1076   ELFObjectWriter &W = getStreamer().getWriter();
1077   unsigned Flags = W.getELFHeaderEFlags();
1078   Flags |= ELF::EF_MIPS_NAN2008;
1079   W.setELFHeaderEFlags(Flags);
1080 }
1081 
1082 void MipsTargetELFStreamer::emitDirectiveNaNLegacy() {
1083   ELFObjectWriter &W = getStreamer().getWriter();
1084   unsigned Flags = W.getELFHeaderEFlags();
1085   Flags &= ~ELF::EF_MIPS_NAN2008;
1086   W.setELFHeaderEFlags(Flags);
1087 }
1088 
1089 void MipsTargetELFStreamer::emitDirectiveOptionPic0() {
1090   ELFObjectWriter &W = getStreamer().getWriter();
1091   unsigned Flags = W.getELFHeaderEFlags();
1092   // This option overrides other PIC options like -KPIC.
1093   Pic = false;
1094   Flags &= ~ELF::EF_MIPS_PIC;
1095   W.setELFHeaderEFlags(Flags);
1096 }
1097 
1098 void MipsTargetELFStreamer::emitDirectiveOptionPic2() {
1099   ELFObjectWriter &W = getStreamer().getWriter();
1100   unsigned Flags = W.getELFHeaderEFlags();
1101   Pic = true;
1102   // NOTE: We are following the GAS behaviour here which means the directive
1103   // 'pic2' also sets the CPIC bit in the ELF header. This is different from
1104   // what is stated in the SYSV ABI which consider the bits EF_MIPS_PIC and
1105   // EF_MIPS_CPIC to be mutually exclusive.
1106   Flags |= ELF::EF_MIPS_PIC | ELF::EF_MIPS_CPIC;
1107   W.setELFHeaderEFlags(Flags);
1108 }
1109 
1110 void MipsTargetELFStreamer::emitDirectiveInsn() {
1111   MipsTargetStreamer::emitDirectiveInsn();
1112   MipsELFStreamer &MEF = static_cast<MipsELFStreamer &>(Streamer);
1113   MEF.createPendingLabelRelocs();
1114 }
1115 
1116 void MipsTargetELFStreamer::emitFrame(unsigned StackReg, unsigned StackSize,
1117                                       unsigned ReturnReg_) {
1118   MCContext &Context = getStreamer().getAssembler().getContext();
1119   const MCRegisterInfo *RegInfo = Context.getRegisterInfo();
1120 
1121   FrameInfoSet = true;
1122   FrameReg = RegInfo->getEncodingValue(StackReg);
1123   FrameOffset = StackSize;
1124   ReturnReg = RegInfo->getEncodingValue(ReturnReg_);
1125 }
1126 
1127 void MipsTargetELFStreamer::emitMask(unsigned CPUBitmask,
1128                                      int CPUTopSavedRegOff) {
1129   GPRInfoSet = true;
1130   GPRBitMask = CPUBitmask;
1131   GPROffset = CPUTopSavedRegOff;
1132 }
1133 
1134 void MipsTargetELFStreamer::emitFMask(unsigned FPUBitmask,
1135                                       int FPUTopSavedRegOff) {
1136   FPRInfoSet = true;
1137   FPRBitMask = FPUBitmask;
1138   FPROffset = FPUTopSavedRegOff;
1139 }
1140 
1141 void MipsTargetELFStreamer::emitDirectiveCpAdd(unsigned RegNo) {
1142   // .cpadd $reg
1143   // This directive inserts code to add $gp to the argument's register
1144   // when support for position independent code is enabled.
1145   if (!Pic)
1146     return;
1147 
1148   emitAddu(RegNo, RegNo, GPReg, getABI().IsN64(), &STI);
1149   forbidModuleDirective();
1150 }
1151 
1152 void MipsTargetELFStreamer::emitDirectiveCpLoad(unsigned RegNo) {
1153   // .cpload $reg
1154   // This directive expands to:
1155   // lui   $gp, %hi(_gp_disp)
1156   // addui $gp, $gp, %lo(_gp_disp)
1157   // addu  $gp, $gp, $reg
1158   // when support for position independent code is enabled.
1159   if (!Pic || (getABI().IsN32() || getABI().IsN64()))
1160     return;
1161 
1162   // There's a GNU extension controlled by -mno-shared that allows
1163   // locally-binding symbols to be accessed using absolute addresses.
1164   // This is currently not supported. When supported -mno-shared makes
1165   // .cpload expand to:
1166   //   lui     $gp, %hi(__gnu_local_gp)
1167   //   addiu   $gp, $gp, %lo(__gnu_local_gp)
1168 
1169   StringRef SymName("_gp_disp");
1170   MCAssembler &MCA = getStreamer().getAssembler();
1171   MCSymbol *GP_Disp = MCA.getContext().getOrCreateSymbol(SymName);
1172   MCA.registerSymbol(*GP_Disp);
1173 
1174   MCInst TmpInst;
1175   TmpInst.setOpcode(Mips::LUi);
1176   TmpInst.addOperand(MCOperand::createReg(GPReg));
1177   const MCExpr *HiSym = MipsMCExpr::create(
1178       MipsMCExpr::MEK_HI,
1179       MCSymbolRefExpr::create("_gp_disp", MCSymbolRefExpr::VK_None,
1180                               MCA.getContext()),
1181       MCA.getContext());
1182   TmpInst.addOperand(MCOperand::createExpr(HiSym));
1183   getStreamer().emitInstruction(TmpInst, STI);
1184 
1185   TmpInst.clear();
1186 
1187   TmpInst.setOpcode(Mips::ADDiu);
1188   TmpInst.addOperand(MCOperand::createReg(GPReg));
1189   TmpInst.addOperand(MCOperand::createReg(GPReg));
1190   const MCExpr *LoSym = MipsMCExpr::create(
1191       MipsMCExpr::MEK_LO,
1192       MCSymbolRefExpr::create("_gp_disp", MCSymbolRefExpr::VK_None,
1193                               MCA.getContext()),
1194       MCA.getContext());
1195   TmpInst.addOperand(MCOperand::createExpr(LoSym));
1196   getStreamer().emitInstruction(TmpInst, STI);
1197 
1198   TmpInst.clear();
1199 
1200   TmpInst.setOpcode(Mips::ADDu);
1201   TmpInst.addOperand(MCOperand::createReg(GPReg));
1202   TmpInst.addOperand(MCOperand::createReg(GPReg));
1203   TmpInst.addOperand(MCOperand::createReg(RegNo));
1204   getStreamer().emitInstruction(TmpInst, STI);
1205 
1206   forbidModuleDirective();
1207 }
1208 
1209 void MipsTargetELFStreamer::emitDirectiveCpLocal(unsigned RegNo) {
1210   if (Pic)
1211     MipsTargetStreamer::emitDirectiveCpLocal(RegNo);
1212 }
1213 
1214 bool MipsTargetELFStreamer::emitDirectiveCpRestore(
1215     int Offset, function_ref<unsigned()> GetATReg, SMLoc IDLoc,
1216     const MCSubtargetInfo *STI) {
1217   MipsTargetStreamer::emitDirectiveCpRestore(Offset, GetATReg, IDLoc, STI);
1218   // .cprestore offset
1219   // When PIC mode is enabled and the O32 ABI is used, this directive expands
1220   // to:
1221   //    sw $gp, offset($sp)
1222   // and adds a corresponding LW after every JAL.
1223 
1224   // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
1225   // is used in non-PIC mode.
1226   if (!Pic || (getABI().IsN32() || getABI().IsN64()))
1227     return true;
1228 
1229   // Store the $gp on the stack.
1230   emitStoreWithImmOffset(Mips::SW, GPReg, Mips::SP, Offset, GetATReg, IDLoc,
1231                          STI);
1232   return true;
1233 }
1234 
1235 void MipsTargetELFStreamer::emitDirectiveCpsetup(unsigned RegNo,
1236                                                  int RegOrOffset,
1237                                                  const MCSymbol &Sym,
1238                                                  bool IsReg) {
1239   // Only N32 and N64 emit anything for .cpsetup iff PIC is set.
1240   if (!Pic || !(getABI().IsN32() || getABI().IsN64()))
1241     return;
1242 
1243   forbidModuleDirective();
1244 
1245   MCAssembler &MCA = getStreamer().getAssembler();
1246   MCInst Inst;
1247 
1248   // Either store the old $gp in a register or on the stack
1249   if (IsReg) {
1250     // move $save, $gpreg
1251     emitRRR(Mips::OR64, RegOrOffset, GPReg, Mips::ZERO, SMLoc(), &STI);
1252   } else {
1253     // sd $gpreg, offset($sp)
1254     emitRRI(Mips::SD, GPReg, Mips::SP, RegOrOffset, SMLoc(), &STI);
1255   }
1256 
1257   const MipsMCExpr *HiExpr = MipsMCExpr::createGpOff(
1258       MipsMCExpr::MEK_HI, MCSymbolRefExpr::create(&Sym, MCA.getContext()),
1259       MCA.getContext());
1260   const MipsMCExpr *LoExpr = MipsMCExpr::createGpOff(
1261       MipsMCExpr::MEK_LO, MCSymbolRefExpr::create(&Sym, MCA.getContext()),
1262       MCA.getContext());
1263 
1264   // lui $gp, %hi(%neg(%gp_rel(funcSym)))
1265   emitRX(Mips::LUi, GPReg, MCOperand::createExpr(HiExpr), SMLoc(), &STI);
1266 
1267   // addiu  $gp, $gp, %lo(%neg(%gp_rel(funcSym)))
1268   emitRRX(Mips::ADDiu, GPReg, GPReg, MCOperand::createExpr(LoExpr), SMLoc(),
1269           &STI);
1270 
1271   // (d)addu  $gp, $gp, $funcreg
1272   if (getABI().IsN32())
1273     emitRRR(Mips::ADDu, GPReg, GPReg, RegNo, SMLoc(), &STI);
1274   else
1275     emitRRR(Mips::DADDu, GPReg, GPReg, RegNo, SMLoc(), &STI);
1276 }
1277 
1278 void MipsTargetELFStreamer::emitDirectiveCpreturn(unsigned SaveLocation,
1279                                                   bool SaveLocationIsRegister) {
1280   // Only N32 and N64 emit anything for .cpreturn iff PIC is set.
1281   if (!Pic || !(getABI().IsN32() || getABI().IsN64()))
1282     return;
1283 
1284   MCInst Inst;
1285   // Either restore the old $gp from a register or on the stack
1286   if (SaveLocationIsRegister) {
1287     Inst.setOpcode(Mips::OR);
1288     Inst.addOperand(MCOperand::createReg(GPReg));
1289     Inst.addOperand(MCOperand::createReg(SaveLocation));
1290     Inst.addOperand(MCOperand::createReg(Mips::ZERO));
1291   } else {
1292     Inst.setOpcode(Mips::LD);
1293     Inst.addOperand(MCOperand::createReg(GPReg));
1294     Inst.addOperand(MCOperand::createReg(Mips::SP));
1295     Inst.addOperand(MCOperand::createImm(SaveLocation));
1296   }
1297   getStreamer().emitInstruction(Inst, STI);
1298 
1299   forbidModuleDirective();
1300 }
1301 
1302 void MipsTargetELFStreamer::emitMipsAbiFlags() {
1303   MCAssembler &MCA = getStreamer().getAssembler();
1304   MCContext &Context = MCA.getContext();
1305   MCStreamer &OS = getStreamer();
1306   MCSectionELF *Sec = Context.getELFSection(
1307       ".MIPS.abiflags", ELF::SHT_MIPS_ABIFLAGS, ELF::SHF_ALLOC, 24);
1308   OS.switchSection(Sec);
1309   Sec->setAlignment(Align(8));
1310 
1311   OS << ABIFlagsSection;
1312 }
1313