LLVM 20.0.0git
MipsTargetStreamer.cpp
Go to the documentation of this file.
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"
15#include "MipsELFStreamer.h"
16#include "MipsInstPrinter.h"
17#include "MipsMCExpr.h"
18#include "MipsMCTargetDesc.h"
20#include "llvm/MC/MCAssembler.h"
21#include "llvm/MC/MCContext.h"
25#include "llvm/MC/MCSymbolELF.h"
30
31using namespace llvm;
32
33namespace {
34static cl::opt<bool> RoundSectionSizes(
35 "mips-round-section-sizes", cl::init(false),
36 cl::desc("Round section sizes up to the section alignment"), cl::Hidden);
37} // end anonymous namespace
38
39static bool isMicroMips(const MCSubtargetInfo *STI) {
40 return STI->hasFeature(Mips::FeatureMicroMips);
41}
42
43static bool isMips32r6(const MCSubtargetInfo *STI) {
44 return STI->hasFeature(Mips::FeatureMips32r6);
45}
46
48 : MCTargetStreamer(S), GPReg(Mips::GP), ModuleDirectiveAllowed(true) {
50}
73}
83void MipsTargetStreamer::emitFrame(unsigned StackReg, unsigned StackSize,
84 unsigned ReturnReg) {}
85void MipsTargetStreamer::emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) {}
86void MipsTargetStreamer::emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) {
87}
90}
111}
114}
123 // .cplocal $reg
124 // This directive forces to use the alternate register for context pointer.
125 // For example
126 // .cplocal $4
127 // jal foo
128 // expands to
129 // ld $25, %call16(foo)($4)
130 // jalr $25
131
132 if (!getABI().IsN32() && !getABI().IsN64())
133 return;
134
135 GPReg = RegNo;
136
138}
140 int Offset, function_ref<unsigned()> GetATReg, SMLoc IDLoc,
141 const MCSubtargetInfo *STI) {
143 return true;
144}
145void MipsTargetStreamer::emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
146 const MCSymbol &Sym, bool IsReg) {
147}
149 bool SaveLocationIsRegister) {}
150
152
155 report_fatal_error("+nooddspreg is only valid for O32");
156}
169}
173}
174
175void MipsTargetStreamer::emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
176 const MCSubtargetInfo *STI) {
177 MCInst TmpInst;
178 TmpInst.setOpcode(Opcode);
179 TmpInst.addOperand(MCOperand::createReg(Reg0));
180 TmpInst.setLoc(IDLoc);
181 getStreamer().emitInstruction(TmpInst, *STI);
182}
183
184void MipsTargetStreamer::emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1,
185 SMLoc IDLoc, const MCSubtargetInfo *STI) {
186 MCInst TmpInst;
187 TmpInst.setOpcode(Opcode);
188 TmpInst.addOperand(MCOperand::createReg(Reg0));
189 TmpInst.addOperand(Op1);
190 TmpInst.setLoc(IDLoc);
191 getStreamer().emitInstruction(TmpInst, *STI);
192}
193
194void MipsTargetStreamer::emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm,
195 SMLoc IDLoc, const MCSubtargetInfo *STI) {
196 emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, STI);
197}
198
199void MipsTargetStreamer::emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1,
200 SMLoc IDLoc, const MCSubtargetInfo *STI) {
201 emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, STI);
202}
203
204void MipsTargetStreamer::emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2,
205 SMLoc IDLoc, const MCSubtargetInfo *STI) {
206 MCInst TmpInst;
207 TmpInst.setOpcode(Opcode);
208 TmpInst.addOperand(MCOperand::createImm(Imm1));
209 TmpInst.addOperand(MCOperand::createImm(Imm2));
210 TmpInst.setLoc(IDLoc);
211 getStreamer().emitInstruction(TmpInst, *STI);
212}
213
214void MipsTargetStreamer::emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1,
215 MCOperand Op2, SMLoc IDLoc,
216 const MCSubtargetInfo *STI) {
217 MCInst TmpInst;
218 TmpInst.setOpcode(Opcode);
219 TmpInst.addOperand(MCOperand::createReg(Reg0));
220 TmpInst.addOperand(MCOperand::createReg(Reg1));
221 TmpInst.addOperand(Op2);
222 TmpInst.setLoc(IDLoc);
223 getStreamer().emitInstruction(TmpInst, *STI);
224}
225
226void MipsTargetStreamer::emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1,
227 unsigned Reg2, SMLoc IDLoc,
228 const MCSubtargetInfo *STI) {
229 emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc, STI);
230}
231
232void MipsTargetStreamer::emitRRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1,
233 unsigned Reg2, MCOperand Op3, SMLoc IDLoc,
234 const MCSubtargetInfo *STI) {
235 MCInst TmpInst;
236 TmpInst.setOpcode(Opcode);
237 TmpInst.addOperand(MCOperand::createReg(Reg0));
238 TmpInst.addOperand(MCOperand::createReg(Reg1));
239 TmpInst.addOperand(MCOperand::createReg(Reg2));
240 TmpInst.addOperand(Op3);
241 TmpInst.setLoc(IDLoc);
242 getStreamer().emitInstruction(TmpInst, *STI);
243}
244
245void MipsTargetStreamer::emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1,
246 int16_t Imm, SMLoc IDLoc,
247 const MCSubtargetInfo *STI) {
248 emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc, STI);
249}
250
251void MipsTargetStreamer::emitRRIII(unsigned Opcode, unsigned Reg0,
252 unsigned Reg1, int16_t Imm0, int16_t Imm1,
253 int16_t Imm2, SMLoc IDLoc,
254 const MCSubtargetInfo *STI) {
255 MCInst TmpInst;
256 TmpInst.setOpcode(Opcode);
257 TmpInst.addOperand(MCOperand::createReg(Reg0));
258 TmpInst.addOperand(MCOperand::createReg(Reg1));
259 TmpInst.addOperand(MCOperand::createImm(Imm0));
260 TmpInst.addOperand(MCOperand::createImm(Imm1));
261 TmpInst.addOperand(MCOperand::createImm(Imm2));
262 TmpInst.setLoc(IDLoc);
263 getStreamer().emitInstruction(TmpInst, *STI);
264}
265
266void MipsTargetStreamer::emitAddu(unsigned DstReg, unsigned SrcReg,
267 unsigned TrgReg, bool Is64Bit,
268 const MCSubtargetInfo *STI) {
269 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
270 STI);
271}
272
273void MipsTargetStreamer::emitDSLL(unsigned DstReg, unsigned SrcReg,
274 int16_t ShiftAmount, SMLoc IDLoc,
275 const MCSubtargetInfo *STI) {
276 if (ShiftAmount >= 32) {
277 emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc, STI);
278 return;
279 }
280
281 emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, STI);
282}
283
285 const MCSubtargetInfo *STI) {
286 // The default case of `nop` is `sll $zero, $zero, 0`.
287 unsigned Opc = Mips::SLL;
288 if (isMicroMips(STI) && hasShortDelaySlot) {
289 Opc = isMips32r6(STI) ? Mips::MOVE16_MMR6 : Mips::MOVE16_MM;
290 emitRR(Opc, Mips::ZERO, Mips::ZERO, IDLoc, STI);
291 return;
292 }
293
294 if (isMicroMips(STI))
295 Opc = isMips32r6(STI) ? Mips::SLL_MMR6 : Mips::SLL_MM;
296
297 emitRRI(Opc, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
298}
299
301 if (isMicroMips(STI))
302 emitRR(Mips::MOVE16_MM, Mips::ZERO, Mips::ZERO, IDLoc, STI);
303 else
304 emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
305}
306
307/// Emit the $gp restore operation for .cprestore.
309 const MCSubtargetInfo *STI) {
310 emitLoadWithImmOffset(Mips::LW, GPReg, Mips::SP, Offset, GPReg, IDLoc, STI);
311}
312
313/// Emit a store instruction with an immediate offset.
315 unsigned Opcode, unsigned SrcReg, unsigned BaseReg, int64_t Offset,
316 function_ref<unsigned()> GetATReg, SMLoc IDLoc,
317 const MCSubtargetInfo *STI) {
318 if (isInt<16>(Offset)) {
319 emitRRI(Opcode, SrcReg, BaseReg, Offset, IDLoc, STI);
320 return;
321 }
322
323 // sw $8, offset($8) => lui $at, %hi(offset)
324 // add $at, $at, $8
325 // sw $8, %lo(offset)($at)
326
327 unsigned ATReg = GetATReg();
328 if (!ATReg)
329 return;
330
331 unsigned LoOffset = Offset & 0x0000ffff;
332 unsigned HiOffset = (Offset & 0xffff0000) >> 16;
333
334 // If msb of LoOffset is 1(negative number) we must increment HiOffset
335 // to account for the sign-extension of the low part.
336 if (LoOffset & 0x8000)
337 HiOffset++;
338
339 // Generate the base address in ATReg.
340 emitRI(Mips::LUi, ATReg, HiOffset, IDLoc, STI);
341 if (BaseReg != Mips::ZERO)
342 emitRRR(Mips::ADDu, ATReg, ATReg, BaseReg, IDLoc, STI);
343 // Emit the store with the adjusted base and offset.
344 emitRRI(Opcode, SrcReg, ATReg, LoOffset, IDLoc, STI);
345}
346
347/// Emit a load instruction with an immediate offset. DstReg and TmpReg are
348/// permitted to be the same register iff DstReg is distinct from BaseReg and
349/// DstReg is a GPR. It is the callers responsibility to identify such cases
350/// and pass the appropriate register in TmpReg.
351void MipsTargetStreamer::emitLoadWithImmOffset(unsigned Opcode, unsigned DstReg,
352 unsigned BaseReg, int64_t Offset,
353 unsigned TmpReg, SMLoc IDLoc,
354 const MCSubtargetInfo *STI) {
355 if (isInt<16>(Offset)) {
356 emitRRI(Opcode, DstReg, BaseReg, Offset, IDLoc, STI);
357 return;
358 }
359
360 // 1) lw $8, offset($9) => lui $8, %hi(offset)
361 // add $8, $8, $9
362 // lw $8, %lo(offset)($9)
363 // 2) lw $8, offset($8) => lui $at, %hi(offset)
364 // add $at, $at, $8
365 // lw $8, %lo(offset)($at)
366
367 unsigned LoOffset = Offset & 0x0000ffff;
368 unsigned HiOffset = (Offset & 0xffff0000) >> 16;
369
370 // If msb of LoOffset is 1(negative number) we must increment HiOffset
371 // to account for the sign-extension of the low part.
372 if (LoOffset & 0x8000)
373 HiOffset++;
374
375 // Generate the base address in TmpReg.
376 emitRI(Mips::LUi, TmpReg, HiOffset, IDLoc, STI);
377 if (BaseReg != Mips::ZERO)
378 emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
379 // Emit the load with the adjusted base and offset.
380 emitRRI(Opcode, DstReg, TmpReg, LoOffset, IDLoc, STI);
381}
382
385 : MipsTargetStreamer(S), OS(OS) {}
386
388 OS << "\t.set\tmicromips\n";
390}
391
393 OS << "\t.set\tnomicromips\n";
395}
396
398 OS << "\t.set\tmips16\n";
400}
401
403 OS << "\t.set\tnomips16\n";
405}
406
408 OS << "\t.set\treorder\n";
410}
411
413 OS << "\t.set\tnoreorder\n";
415}
416
418 OS << "\t.set\tmacro\n";
420}
421
423 OS << "\t.set\tnomacro\n";
425}
426
428 OS << "\t.set\tmsa\n";
430}
431
433 OS << "\t.set\tnomsa\n";
435}
436
438 OS << "\t.set\tmt\n";
440}
441
443 OS << "\t.set\tnomt\n";
445}
446
448 OS << "\t.set\tcrc\n";
450}
451
453 OS << "\t.set\tnocrc\n";
455}
456
458 OS << "\t.set\tvirt\n";
460}
461
463 OS << "\t.set\tnovirt\n";
465}
466
468 OS << "\t.set\tginv\n";
470}
471
473 OS << "\t.set\tnoginv\n";
475}
476
478 OS << "\t.set\tat\n";
480}
481
483 OS << "\t.set\tat=$" << Twine(RegNo) << "\n";
485}
486
488 OS << "\t.set\tnoat\n";
490}
491
493 OS << "\t.end\t" << Name << '\n';
494}
495
497 OS << "\t.ent\t" << Symbol.getName() << '\n';
498}
499
500void MipsTargetAsmStreamer::emitDirectiveAbiCalls() { OS << "\t.abicalls\n"; }
501
502void MipsTargetAsmStreamer::emitDirectiveNaN2008() { OS << "\t.nan\t2008\n"; }
503
505 OS << "\t.nan\tlegacy\n";
506}
507
509 OS << "\t.option\tpic0\n";
510}
511
513 OS << "\t.option\tpic2\n";
514}
515
518 OS << "\t.insn\n";
519}
520
521void MipsTargetAsmStreamer::emitFrame(unsigned StackReg, unsigned StackSize,
522 unsigned ReturnReg) {
523 OS << "\t.frame\t$"
525 << StackSize << ",$"
527}
528
530 OS << "\t.set arch=" << Arch << "\n";
532}
533
535 OS << "\t.set\tmips0\n";
537}
538
540 OS << "\t.set\tmips1\n";
542}
543
545 OS << "\t.set\tmips2\n";
547}
548
550 OS << "\t.set\tmips3\n";
552}
553
555 OS << "\t.set\tmips4\n";
557}
558
560 OS << "\t.set\tmips5\n";
562}
563
565 OS << "\t.set\tmips32\n";
567}
568
570 OS << "\t.set\tmips32r2\n";
572}
573
575 OS << "\t.set\tmips32r3\n";
577}
578
580 OS << "\t.set\tmips32r5\n";
582}
583
585 OS << "\t.set\tmips32r6\n";
587}
588
590 OS << "\t.set\tmips64\n";
592}
593
595 OS << "\t.set\tmips64r2\n";
597}
598
600 OS << "\t.set\tmips64r3\n";
602}
603
605 OS << "\t.set\tmips64r5\n";
607}
608
610 OS << "\t.set\tmips64r6\n";
612}
613
615 OS << "\t.set\tdsp\n";
617}
618
620 OS << "\t.set\tdspr2\n";
622}
623
625 OS << "\t.set\tnodsp\n";
627}
628
630 OS << "\t.set\tmips3d\n";
632}
633
635 OS << "\t.set\tnomips3d\n";
637}
638
640 OS << "\t.set\tpop\n";
642}
643
645 OS << "\t.set\tpush\n";
647}
648
650 OS << "\t.set\tsoftfloat\n";
652}
653
655 OS << "\t.set\thardfloat\n";
657}
658
659// Print a 32 bit hex number with all numbers.
660static void printHex32(unsigned Value, raw_ostream &OS) {
661 OS << "0x";
662 for (int i = 7; i >= 0; i--)
663 OS.write_hex((Value & (0xF << (i * 4))) >> (i * 4));
664}
665
666void MipsTargetAsmStreamer::emitMask(unsigned CPUBitmask,
667 int CPUTopSavedRegOff) {
668 OS << "\t.mask \t";
669 printHex32(CPUBitmask, OS);
670 OS << ',' << CPUTopSavedRegOff << '\n';
671}
672
673void MipsTargetAsmStreamer::emitFMask(unsigned FPUBitmask,
674 int FPUTopSavedRegOff) {
675 OS << "\t.fmask\t";
676 printHex32(FPUBitmask, OS);
677 OS << "," << FPUTopSavedRegOff << '\n';
678}
679
681 OS << "\t.cpadd\t$"
684}
685
687 OS << "\t.cpload\t$"
690}
691
693 OS << "\t.cplocal\t$"
696}
697
699 int Offset, function_ref<unsigned()> GetATReg, SMLoc IDLoc,
700 const MCSubtargetInfo *STI) {
702 OS << "\t.cprestore\t" << Offset << "\n";
703 return true;
704}
705
707 int RegOrOffset,
708 const MCSymbol &Sym,
709 bool IsReg) {
710 OS << "\t.cpsetup\t$"
712
713 if (IsReg)
714 OS << "$"
716 else
717 OS << RegOrOffset;
718
719 OS << ", ";
720
721 OS << Sym.getName();
723}
724
726 bool SaveLocationIsRegister) {
727 OS << "\t.cpreturn";
729}
730
734 OS << "\t.module\tsoftfloat\n";
735 else
736 OS << "\t.module\tfp=" << ABIFlagsSection.getFpABIString(FpABI) << "\n";
737}
738
742
743 OS << "\t.set\tfp=";
744 OS << ABIFlagsSection.getFpABIString(Value) << "\n";
745}
746
749
750 OS << "\t.module\t" << (ABIFlagsSection.OddSPReg ? "" : "no") << "oddspreg\n";
751}
752
755 OS << "\t.set\toddspreg\n";
756}
757
760 OS << "\t.set\tnooddspreg\n";
761}
762
764 OS << "\t.module\tsoftfloat\n";
765}
766
768 OS << "\t.module\thardfloat\n";
769}
770
772 OS << "\t.module\tmt\n";
773}
774
776 OS << "\t.module\tcrc\n";
777}
778
780 OS << "\t.module\tnocrc\n";
781}
782
784 OS << "\t.module\tvirt\n";
785}
786
788 OS << "\t.module\tnovirt\n";
789}
790
792 OS << "\t.module\tginv\n";
793}
794
796 OS << "\t.module\tnoginv\n";
797}
798
799// This part is for ELF object output.
801 const MCSubtargetInfo &STI)
802 : MipsTargetStreamer(S), MicroMipsEnabled(false), STI(STI) {
805
806 // It's possible that MCObjectFileInfo isn't fully initialized at this point
807 // due to an initialization order problem where LLVMTargetMachine creates the
808 // target streamer before TargetLoweringObjectFile calls
809 // InitializeMCObjectFileInfo. There doesn't seem to be a single place that
810 // covers all cases so this statement covers most cases and direct object
811 // emission must call setPic() once MCObjectFileInfo has been initialized. The
812 // cases we don't handle here are covered by MipsAsmPrinter.
814
815 const FeatureBitset &Features = STI.getFeatureBits();
816
817 // Set the header flags that we can in the constructor.
818 // FIXME: This is a fairly terrible hack. We set the rest
819 // of these in the destructor. The problem here is two-fold:
820 //
821 // a: Some of the eflags can be set/reset by directives.
822 // b: There aren't any usage paths that initialize the ABI
823 // pointer until after we initialize either an assembler
824 // or the target machine.
825 // We can fix this by making the target streamer construct
826 // the ABI, but this is fraught with wide ranging dependency
827 // issues as well.
828 unsigned EFlags = W.getELFHeaderEFlags();
829
830 // FIXME: Fix a dependency issue by instantiating the ABI object to some
831 // default based off the triple. The triple doesn't describe the target
832 // fully, but any external user of the API that uses the MCTargetStreamer
833 // would otherwise crash on assertion failure.
834
839 : MipsABIInfo::N64());
840
841 // Architecture
842 if (Features[Mips::FeatureMips64r6])
843 EFlags |= ELF::EF_MIPS_ARCH_64R6;
844 else if (Features[Mips::FeatureMips64r2] ||
845 Features[Mips::FeatureMips64r3] ||
846 Features[Mips::FeatureMips64r5])
847 EFlags |= ELF::EF_MIPS_ARCH_64R2;
848 else if (Features[Mips::FeatureMips64])
849 EFlags |= ELF::EF_MIPS_ARCH_64;
850 else if (Features[Mips::FeatureMips5])
851 EFlags |= ELF::EF_MIPS_ARCH_5;
852 else if (Features[Mips::FeatureMips4])
853 EFlags |= ELF::EF_MIPS_ARCH_4;
854 else if (Features[Mips::FeatureMips3])
855 EFlags |= ELF::EF_MIPS_ARCH_3;
856 else if (Features[Mips::FeatureMips32r6])
857 EFlags |= ELF::EF_MIPS_ARCH_32R6;
858 else if (Features[Mips::FeatureMips32r2] ||
859 Features[Mips::FeatureMips32r3] ||
860 Features[Mips::FeatureMips32r5])
861 EFlags |= ELF::EF_MIPS_ARCH_32R2;
862 else if (Features[Mips::FeatureMips32])
863 EFlags |= ELF::EF_MIPS_ARCH_32;
864 else if (Features[Mips::FeatureMips2])
865 EFlags |= ELF::EF_MIPS_ARCH_2;
866 else
867 EFlags |= ELF::EF_MIPS_ARCH_1;
868
869 // Machine
870 if (Features[Mips::FeatureCnMips])
871 EFlags |= ELF::EF_MIPS_MACH_OCTEON;
872
873 // Other options.
874 if (Features[Mips::FeatureNaN2008])
875 EFlags |= ELF::EF_MIPS_NAN2008;
876
877 W.setELFHeaderEFlags(EFlags);
878}
879
881 auto *Symbol = cast<MCSymbolELF>(S);
883 uint8_t Type = Symbol->getType();
884 if (Type != ELF::STT_FUNC)
885 return;
886
887 if (isMicroMipsEnabled())
888 Symbol->setOther(ELF::STO_MIPS_MICROMIPS);
889}
890
894 const MCObjectFileInfo &OFI = *MCA.getContext().getObjectFileInfo();
896
897 // .bss, .text and .data are always at least 16-byte aligned.
898 MCSection &TextSection = *OFI.getTextSection();
899 S.switchSection(&TextSection);
900 MCSection &DataSection = *OFI.getDataSection();
901 S.switchSection(&DataSection);
902 MCSection &BSSSection = *OFI.getBSSSection();
903 S.switchSection(&BSSSection);
904
905 TextSection.ensureMinAlignment(Align(16));
906 DataSection.ensureMinAlignment(Align(16));
907 BSSSection.ensureMinAlignment(Align(16));
908
909 if (RoundSectionSizes) {
910 // Make sections sizes a multiple of the alignment. This is useful for
911 // verifying the output of IAS against the output of other assemblers but
912 // it's not necessary to produce a correct object and increases section
913 // size.
914 for (MCSection &Sec : MCA) {
915 MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
916
917 Align Alignment = Section.getAlign();
918 S.switchSection(&Section);
919 if (Section.useCodeAlign())
920 S.emitCodeAlignment(Alignment, &STI, Alignment.value());
921 else
922 S.emitValueToAlignment(Alignment, 0, 1, Alignment.value());
923 }
924 }
925
926 const FeatureBitset &Features = STI.getFeatureBits();
927
928 // Update e_header flags. See the FIXME and comment above in
929 // the constructor for a full rundown on this.
930 unsigned EFlags = W.getELFHeaderEFlags();
931
932 // ABI
933 // N64 does not require any ABI bits.
934 if (getABI().IsO32())
935 EFlags |= ELF::EF_MIPS_ABI_O32;
936 else if (getABI().IsN32())
937 EFlags |= ELF::EF_MIPS_ABI2;
938
939 if (Features[Mips::FeatureGP64Bit]) {
940 if (getABI().IsO32())
941 EFlags |= ELF::EF_MIPS_32BITMODE; /* Compatibility Mode */
942 } else if (Features[Mips::FeatureMips64r2] || Features[Mips::FeatureMips64])
943 EFlags |= ELF::EF_MIPS_32BITMODE;
944
945 // -mplt is not implemented but we should act as if it was
946 // given.
947 if (!Features[Mips::FeatureNoABICalls])
948 EFlags |= ELF::EF_MIPS_CPIC;
949
950 if (Pic)
952
953 W.setELFHeaderEFlags(EFlags);
954
955 // Emit all the option records.
956 // At the moment we are only emitting .Mips.options (ODK_REGINFO) and
957 // .reginfo.
958 MipsELFStreamer &MEF = static_cast<MipsELFStreamer &>(Streamer);
960
962}
963
965 auto *Symbol = cast<MCSymbolELF>(S);
966 // If on rhs is micromips symbol then mark Symbol as microMips.
967 if (Value->getKind() != MCExpr::SymbolRef)
968 return;
969 const auto &RhsSym = cast<MCSymbolELF>(
970 static_cast<const MCSymbolRefExpr *>(Value)->getSymbol());
971
972 if (!(RhsSym.getOther() & ELF::STO_MIPS_MICROMIPS))
973 return;
974
975 Symbol->setOther(ELF::STO_MIPS_MICROMIPS);
976}
977
979 return static_cast<MCELFStreamer &>(Streamer);
980}
981
983 MicroMipsEnabled = true;
985}
986
988 MicroMipsEnabled = false;
990}
991
994 unsigned Flags = W.getELFHeaderEFlags();
995 Flags |= ELF::EF_MIPS_MICROMIPS;
996 W.setELFHeaderEFlags(Flags);
997}
998
1001 unsigned Flags = W.getELFHeaderEFlags();
1003 W.setELFHeaderEFlags(Flags);
1005}
1006
1009 unsigned Flags = W.getELFHeaderEFlags();
1010 Flags |= ELF::EF_MIPS_NOREORDER;
1011 W.setELFHeaderEFlags(Flags);
1013}
1014
1017 MCContext &Context = MCA.getContext();
1019
1020 OS.pushSection();
1021 MCSectionELF *Sec = Context.getELFSection(".pdr", ELF::SHT_PROGBITS, 0);
1022 OS.switchSection(Sec);
1023 Sec->setAlignment(Align(4));
1024
1025 MCSymbol *Sym = Context.getOrCreateSymbol(Name);
1026 const MCSymbolRefExpr *ExprRef =
1028
1029 OS.emitValueImpl(ExprRef, 4);
1030
1031 OS.emitIntValue(GPRInfoSet ? GPRBitMask : 0, 4); // reg_mask
1032 OS.emitIntValue(GPRInfoSet ? GPROffset : 0, 4); // reg_offset
1033
1034 OS.emitIntValue(FPRInfoSet ? FPRBitMask : 0, 4); // fpreg_mask
1035 OS.emitIntValue(FPRInfoSet ? FPROffset : 0, 4); // fpreg_offset
1036
1037 OS.emitIntValue(FrameInfoSet ? FrameOffset : 0, 4); // frame_offset
1038 OS.emitIntValue(FrameInfoSet ? FrameReg : 0, 4); // frame_reg
1039 OS.emitIntValue(FrameInfoSet ? ReturnReg : 0, 4); // return_reg
1040
1041 // The .end directive marks the end of a procedure. Invalidate
1042 // the information gathered up until this point.
1044
1045 OS.popSection();
1046
1047 // .end also implicitly sets the size.
1048 MCSymbol *CurPCSym = Context.createTempSymbol();
1049 OS.emitLabel(CurPCSym);
1052 ExprRef, Context);
1053
1054 // The ELFObjectWriter can determine the absolute size as it has access to
1055 // the layout information of the assembly file, so a size expression rather
1056 // than an absolute value is ok here.
1057 static_cast<MCSymbolELF *>(Sym)->setSize(Size);
1058}
1059
1062
1063 // .ent also acts like an implicit '.type symbol, STT_FUNC'
1064 static_cast<const MCSymbolELF &>(Symbol).setType(ELF::STT_FUNC);
1065}
1066
1069 unsigned Flags = W.getELFHeaderEFlags();
1071 W.setELFHeaderEFlags(Flags);
1072}
1073
1076 unsigned Flags = W.getELFHeaderEFlags();
1077 Flags |= ELF::EF_MIPS_NAN2008;
1078 W.setELFHeaderEFlags(Flags);
1079}
1080
1083 unsigned Flags = W.getELFHeaderEFlags();
1084 Flags &= ~ELF::EF_MIPS_NAN2008;
1085 W.setELFHeaderEFlags(Flags);
1086}
1087
1090 unsigned Flags = W.getELFHeaderEFlags();
1091 // This option overrides other PIC options like -KPIC.
1092 Pic = false;
1093 Flags &= ~ELF::EF_MIPS_PIC;
1094 W.setELFHeaderEFlags(Flags);
1095}
1096
1099 unsigned Flags = W.getELFHeaderEFlags();
1100 Pic = true;
1101 // NOTE: We are following the GAS behaviour here which means the directive
1102 // 'pic2' also sets the CPIC bit in the ELF header. This is different from
1103 // what is stated in the SYSV ABI which consider the bits EF_MIPS_PIC and
1104 // EF_MIPS_CPIC to be mutually exclusive.
1106 W.setELFHeaderEFlags(Flags);
1107}
1108
1111 MipsELFStreamer &MEF = static_cast<MipsELFStreamer &>(Streamer);
1113}
1114
1115void MipsTargetELFStreamer::emitFrame(unsigned StackReg, unsigned StackSize,
1116 unsigned ReturnReg_) {
1118 const MCRegisterInfo *RegInfo = Context.getRegisterInfo();
1119
1120 FrameInfoSet = true;
1121 FrameReg = RegInfo->getEncodingValue(StackReg);
1122 FrameOffset = StackSize;
1123 ReturnReg = RegInfo->getEncodingValue(ReturnReg_);
1124}
1125
1126void MipsTargetELFStreamer::emitMask(unsigned CPUBitmask,
1127 int CPUTopSavedRegOff) {
1128 GPRInfoSet = true;
1129 GPRBitMask = CPUBitmask;
1130 GPROffset = CPUTopSavedRegOff;
1131}
1132
1133void MipsTargetELFStreamer::emitFMask(unsigned FPUBitmask,
1134 int FPUTopSavedRegOff) {
1135 FPRInfoSet = true;
1136 FPRBitMask = FPUBitmask;
1137 FPROffset = FPUTopSavedRegOff;
1138}
1139
1141 // .cpadd $reg
1142 // This directive inserts code to add $gp to the argument's register
1143 // when support for position independent code is enabled.
1144 if (!Pic)
1145 return;
1146
1147 emitAddu(RegNo, RegNo, GPReg, getABI().IsN64(), &STI);
1149}
1150
1152 // .cpload $reg
1153 // This directive expands to:
1154 // lui $gp, %hi(_gp_disp)
1155 // addui $gp, $gp, %lo(_gp_disp)
1156 // addu $gp, $gp, $reg
1157 // when support for position independent code is enabled.
1158 if (!Pic || (getABI().IsN32() || getABI().IsN64()))
1159 return;
1160
1161 // There's a GNU extension controlled by -mno-shared that allows
1162 // locally-binding symbols to be accessed using absolute addresses.
1163 // This is currently not supported. When supported -mno-shared makes
1164 // .cpload expand to:
1165 // lui $gp, %hi(__gnu_local_gp)
1166 // addiu $gp, $gp, %lo(__gnu_local_gp)
1167
1168 StringRef SymName("_gp_disp");
1170 MCSymbol *GP_Disp = MCA.getContext().getOrCreateSymbol(SymName);
1171 MCA.registerSymbol(*GP_Disp);
1172
1173 MCInst TmpInst;
1174 TmpInst.setOpcode(Mips::LUi);
1176 const MCExpr *HiSym = MipsMCExpr::create(
1179 MCA.getContext()),
1180 MCA.getContext());
1181 TmpInst.addOperand(MCOperand::createExpr(HiSym));
1182 getStreamer().emitInstruction(TmpInst, STI);
1183
1184 TmpInst.clear();
1185
1186 TmpInst.setOpcode(Mips::ADDiu);
1189 const MCExpr *LoSym = MipsMCExpr::create(
1192 MCA.getContext()),
1193 MCA.getContext());
1194 TmpInst.addOperand(MCOperand::createExpr(LoSym));
1195 getStreamer().emitInstruction(TmpInst, STI);
1196
1197 TmpInst.clear();
1198
1199 TmpInst.setOpcode(Mips::ADDu);
1202 TmpInst.addOperand(MCOperand::createReg(RegNo));
1203 getStreamer().emitInstruction(TmpInst, STI);
1204
1206}
1207
1209 if (Pic)
1211}
1212
1214 int Offset, function_ref<unsigned()> GetATReg, SMLoc IDLoc,
1215 const MCSubtargetInfo *STI) {
1217 // .cprestore offset
1218 // When PIC mode is enabled and the O32 ABI is used, this directive expands
1219 // to:
1220 // sw $gp, offset($sp)
1221 // and adds a corresponding LW after every JAL.
1222
1223 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
1224 // is used in non-PIC mode.
1225 if (!Pic || (getABI().IsN32() || getABI().IsN64()))
1226 return true;
1227
1228 // Store the $gp on the stack.
1229 emitStoreWithImmOffset(Mips::SW, GPReg, Mips::SP, Offset, GetATReg, IDLoc,
1230 STI);
1231 return true;
1232}
1233
1235 int RegOrOffset,
1236 const MCSymbol &Sym,
1237 bool IsReg) {
1238 // Only N32 and N64 emit anything for .cpsetup iff PIC is set.
1239 if (!Pic || !(getABI().IsN32() || getABI().IsN64()))
1240 return;
1241
1243
1245 MCInst Inst;
1246
1247 // Either store the old $gp in a register or on the stack
1248 if (IsReg) {
1249 // move $save, $gpreg
1250 emitRRR(Mips::OR64, RegOrOffset, GPReg, Mips::ZERO, SMLoc(), &STI);
1251 } else {
1252 // sd $gpreg, offset($sp)
1253 emitRRI(Mips::SD, GPReg, Mips::SP, RegOrOffset, SMLoc(), &STI);
1254 }
1255
1256 const MipsMCExpr *HiExpr = MipsMCExpr::createGpOff(
1258 MCA.getContext());
1259 const MipsMCExpr *LoExpr = MipsMCExpr::createGpOff(
1261 MCA.getContext());
1262
1263 // lui $gp, %hi(%neg(%gp_rel(funcSym)))
1264 emitRX(Mips::LUi, GPReg, MCOperand::createExpr(HiExpr), SMLoc(), &STI);
1265
1266 // addiu $gp, $gp, %lo(%neg(%gp_rel(funcSym)))
1267 emitRRX(Mips::ADDiu, GPReg, GPReg, MCOperand::createExpr(LoExpr), SMLoc(),
1268 &STI);
1269
1270 // (d)addu $gp, $gp, $funcreg
1271 if (getABI().IsN32())
1272 emitRRR(Mips::ADDu, GPReg, GPReg, RegNo, SMLoc(), &STI);
1273 else
1274 emitRRR(Mips::DADDu, GPReg, GPReg, RegNo, SMLoc(), &STI);
1275}
1276
1278 bool SaveLocationIsRegister) {
1279 // Only N32 and N64 emit anything for .cpreturn iff PIC is set.
1280 if (!Pic || !(getABI().IsN32() || getABI().IsN64()))
1281 return;
1282
1283 MCInst Inst;
1284 // Either restore the old $gp from a register or on the stack
1285 if (SaveLocationIsRegister) {
1286 Inst.setOpcode(Mips::OR);
1288 Inst.addOperand(MCOperand::createReg(SaveLocation));
1289 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
1290 } else {
1291 Inst.setOpcode(Mips::LD);
1293 Inst.addOperand(MCOperand::createReg(Mips::SP));
1294 Inst.addOperand(MCOperand::createImm(SaveLocation));
1295 }
1296 getStreamer().emitInstruction(Inst, STI);
1297
1299}
1300
1303 MCContext &Context = MCA.getContext();
1305 MCSectionELF *Sec = Context.getELFSection(
1306 ".MIPS.abiflags", ELF::SHT_MIPS_ABIFLAGS, ELF::SHF_ALLOC, 24);
1307 OS.switchSection(Sec);
1308 Sec->setAlignment(Align(8));
1309
1311}
basic Basic Alias true
std::string Name
uint64_t Size
Symbol * Sym
Definition: ELF_riscv.cpp:479
static bool hasShortDelaySlot(MCInst &Inst)
static bool isMicroMips(const MCSubtargetInfo *STI)
static void printHex32(unsigned Value, raw_ostream &OS)
static bool isMips32r6(const MCSubtargetInfo *STI)
raw_pwrite_stream & OS
Container class for subtarget features.
MCContext & getContext() const
Definition: MCAssembler.h:182
bool registerSymbol(const MCSymbol &Symbol)
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:617
Context object for machine code objects.
Definition: MCContext.h:83
const MCObjectFileInfo * getObjectFileInfo() const
Definition: MCContext.h:416
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Definition: MCContext.cpp:346
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
Definition: MCContext.h:551
const MCRegisterInfo * getRegisterInfo() const
Definition: MCContext.h:414
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition: MCContext.cpp:213
void emitValueToAlignment(Align, int64_t, unsigned, unsigned) override
Emit some number of copies of Value until the byte alignment ByteAlignment is reached.
ELFObjectWriter & getWriter()
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:34
@ SymbolRef
References to labels and assigned expressions.
Definition: MCExpr.h:39
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
void setLoc(SMLoc loc)
Definition: MCInst.h:203
void addOperand(const MCOperand Op)
Definition: MCInst.h:210
void setOpcode(unsigned Op)
Definition: MCInst.h:197
void clear()
Definition: MCInst.h:215
MCSection * getBSSSection() const
bool isPositionIndependent() const
MCSection * getTextSection() const
MCSection * getDataSection() const
MCAssembler & getAssembler()
void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override
Emit the given Instruction into the current section.
void emitCodeAlignment(Align ByteAlignment, const MCSubtargetInfo *STI, unsigned MaxBytesToEmit=0) override
Emit nops until the byte alignment ByteAlignment is reached.
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:134
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:162
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:141
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
uint16_t getEncodingValue(MCRegister RegNo) const
Returns the encoding for RegNo.
This represents a section on linux, lots of unix variants and some bare metal systems.
Definition: MCSectionELF.h:27
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition: MCSection.h:36
void setAlignment(Align Value)
Definition: MCSection.h:145
void ensureMinAlignment(Align MinAlignment)
Makes sure that Alignment is at least MinAlignment.
Definition: MCSection.h:148
Streaming machine code generation interface.
Definition: MCStreamer.h:213
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
virtual void switchSection(MCSection *Section, uint32_t Subsec=0)
Set the current section where code is being emitted to Section.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
const Triple & getTargetTriple() const
const FeatureBitset & getFeatureBits() const
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:188
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:393
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
Target specific streamer interface.
Definition: MCStreamer.h:94
MCStreamer & getStreamer()
Definition: MCStreamer.h:102
MCStreamer & Streamer
Definition: MCStreamer.h:96
static MipsABIInfo O32()
Definition: MipsABIInfo.h:33
static MipsABIInfo N64()
Definition: MipsABIInfo.h:35
bool IsN32() const
Definition: MipsABIInfo.h:41
bool IsO32() const
Definition: MipsABIInfo.h:40
void EmitMipsOptionRecords()
Emits all the option records stored up until the point it's called.
void createPendingLabelRelocs()
Mark labels as microMIPS, if necessary for the subtarget.
static const char * getRegisterName(MCRegister Reg)
static const MipsMCExpr * create(MipsExprKind Kind, const MCExpr *Expr, MCContext &Ctx)
Definition: MipsMCExpr.cpp:27
static const MipsMCExpr * createGpOff(MipsExprKind Kind, const MCExpr *Expr, MCContext &Ctx)
Definition: MipsMCExpr.cpp:32
void emitDirectiveSetFp(MipsABIFlagsSection::FpABIKind Value) override
void emitDirectiveSetArch(StringRef Arch) override
bool emitDirectiveCpRestore(int Offset, function_ref< unsigned()> GetATReg, SMLoc IDLoc, const MCSubtargetInfo *STI) override
Emit a .cprestore directive.
MipsTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS)
void emitDirectiveCpLoad(unsigned RegNo) override
void emitDirectiveSetNoOddSPReg() override
void emitDirectiveEnt(const MCSymbol &Symbol) override
void emitDirectiveModuleSoftFloat() override
void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset, const MCSymbol &Sym, bool IsReg) override
void emitDirectiveCpLocal(unsigned RegNo) override
void emitDirectiveModuleHardFloat() override
void emitDirectiveEnd(StringRef Name) override
void emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) override
void emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) override
void emitFrame(unsigned StackReg, unsigned StackSize, unsigned ReturnReg) override
void emitDirectiveCpreturn(unsigned SaveLocation, bool SaveLocationIsRegister) override
void emitDirectiveCpAdd(unsigned RegNo) override
void emitDirectiveSetAtWithArg(unsigned RegNo) override
void emitDirectiveSetNoMicroMips() override
void emitDirectiveModuleOddSPReg() override
void emitDirectiveCpAdd(unsigned RegNo) override
void emitDirectiveCpLoad(unsigned RegNo) override
MipsTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI)
void emitDirectiveSetNoMicroMips() override
void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset, const MCSymbol &Sym, bool IsReg) override
void emitDirectiveEnd(StringRef Name) override
bool emitDirectiveCpRestore(int Offset, function_ref< unsigned()> GetATReg, SMLoc IDLoc, const MCSubtargetInfo *STI) override
void emitLabel(MCSymbol *Symbol) override
void emitDirectiveCpLocal(unsigned RegNo) override
void emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) override
void emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) override
void emitFrame(unsigned StackReg, unsigned StackSize, unsigned ReturnReg) override
void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override
void emitDirectiveCpreturn(unsigned SaveLocation, bool SaveLocationIsRegister) override
void emitDirectiveEnt(const MCSymbol &Symbol) override
std::optional< MipsABIInfo > ABI
virtual void emitDirectiveSetMips64R5()
virtual void emitDirectiveModuleNoVirt()
virtual void emitDirectiveSetReorder()
void emitRRIII(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm0, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetNoCRC()
virtual void emitDirectiveModuleNoGINV()
void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetSoftFloat()
virtual void emitDirectiveCpreturn(unsigned SaveLocation, bool SaveLocationIsRegister)
virtual void emitDirectiveSetNoMicroMips()
void emitStoreWithImmOffset(unsigned Opcode, unsigned SrcReg, unsigned BaseReg, int64_t Offset, function_ref< unsigned()> GetATReg, SMLoc IDLoc, const MCSubtargetInfo *STI)
Emit a store instruction with an offset.
void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetMips64R2()
virtual void emitDirectiveEnd(StringRef Name)
virtual void emitDirectiveSetFp(MipsABIFlagsSection::FpABIKind Value)
virtual void emitDirectiveSetMips64R3()
void emitAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg, bool Is64Bit, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetNoVirt()
virtual void emitDirectiveSetMacro()
virtual void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset, const MCSymbol &Sym, bool IsReg)
void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetMips3()
virtual void emitDirectiveSetNoGINV()
virtual void emitDirectiveSetMips32R3()
virtual void emitDirectiveSetMips32R2()
virtual void emitDirectiveEnt(const MCSymbol &Symbol)
virtual void emitDirectiveSetMips1()
virtual void emitDirectiveSetNoMips3D()
virtual void emitDirectiveCpLocal(unsigned RegNo)
virtual void emitDirectiveCpLoad(unsigned RegNo)
virtual void emitDirectiveSetHardFloat()
void emitEmptyDelaySlot(bool hasShortDelaySlot, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetNoMips16()
virtual void emitDirectiveSetMips5()
virtual void emitDirectiveSetMips2()
virtual void emitFrame(unsigned StackReg, unsigned StackSize, unsigned ReturnReg)
virtual void emitDirectiveSetNoOddSPReg()
void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetOddSPReg()
virtual void emitDirectiveModuleGINV()
void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveNaNLegacy()
virtual void emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff)
void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetMicroMips()
void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetMips0()
void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveModuleSoftFloat()
virtual void emitDirectiveSetArch(StringRef Arch)
virtual void emitDirectiveSetAtWithArg(unsigned RegNo)
void emitRRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2, MCOperand Op3, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual bool emitDirectiveCpRestore(int Offset, function_ref< unsigned()> GetATReg, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitLoadWithImmOffset(unsigned Opcode, unsigned DstReg, unsigned BaseReg, int64_t Offset, unsigned TmpReg, SMLoc IDLoc, const MCSubtargetInfo *STI)
Emit a load instruction with an immediate offset.
virtual void emitDirectiveModuleNoCRC()
virtual void emitDirectiveSetNoMacro()
const MipsABIInfo & getABI() const
virtual void emitDirectiveModuleOddSPReg()
virtual void emitDirectiveCpAdd(unsigned RegNo)
virtual void emitDirectiveSetMips64R6()
virtual void emitDirectiveSetNoMsa()
void emitGPRestore(int Offset, SMLoc IDLoc, const MCSubtargetInfo *STI)
Emit the $gp restore operation for .cprestore.
virtual void emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff)
virtual void emitDirectiveModuleVirt()
void emitNop(SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetNoReorder()
void emitDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetMips32()
virtual void emitDirectiveOptionPic0()
virtual void emitDirectiveModuleHardFloat()
virtual void emitDirectiveSetMips32R5()
virtual void emitDirectiveSetMips32R6()
virtual void emitDirectiveSetMips4()
virtual void emitDirectiveOptionPic2()
virtual void emitDirectiveSetMips16()
virtual void emitDirectiveAbiCalls()
MipsABIFlagsSection ABIFlagsSection
Represents a location in source code.
Definition: SMLoc.h:23
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
std::string lower() const
Definition: StringRef.cpp:111
ArchType getArch() const
Get the parsed architecture type of this triple.
Definition: Triple.h:375
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVM Value Representation.
Definition: Value.h:74
formatted_raw_ostream - A raw_ostream that wraps another one and keeps track of line and column posit...
An efficient, type-erasing, non-owning reference to a callable.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
raw_ostream & write_hex(unsigned long long N)
Output N in hexadecimal, without any prefix or padding.
@ STO_MIPS_MICROMIPS
Definition: ELF.h:591
@ STT_FUNC
Definition: ELF.h:1332
@ EF_MIPS_MICROMIPS
Definition: ELF.h:552
@ EF_MIPS_ARCH_32R6
Definition: ELF.h:567
@ EF_MIPS_ABI_O32
Definition: ELF.h:523
@ EF_MIPS_ARCH_64
Definition: ELF.h:564
@ EF_MIPS_ARCH_32
Definition: ELF.h:563
@ EF_MIPS_MACH_OCTEON
Definition: ELF.h:538
@ EF_MIPS_ARCH_4
Definition: ELF.h:561
@ EF_MIPS_ARCH_5
Definition: ELF.h:562
@ EF_MIPS_NAN2008
Definition: ELF.h:520
@ EF_MIPS_PIC
Definition: ELF.h:513
@ EF_MIPS_ARCH_2
Definition: ELF.h:559
@ EF_MIPS_32BITMODE
Definition: ELF.h:516
@ EF_MIPS_ARCH_32R2
Definition: ELF.h:565
@ EF_MIPS_ARCH_64R2
Definition: ELF.h:566
@ EF_MIPS_ARCH_ASE_M16
Definition: ELF.h:553
@ EF_MIPS_NOREORDER
Definition: ELF.h:512
@ EF_MIPS_ARCH_1
Definition: ELF.h:558
@ EF_MIPS_CPIC
Definition: ELF.h:514
@ EF_MIPS_ARCH_64R6
Definition: ELF.h:568
@ EF_MIPS_ABI2
Definition: ELF.h:515
@ EF_MIPS_ARCH_3
Definition: ELF.h:560
@ SHT_PROGBITS
Definition: ELF.h:1068
@ SHT_MIPS_ABIFLAGS
Definition: ELF.h:1144
@ SHF_ALLOC
Definition: ELF.h:1165
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
StringRef getFpABIString(FpABIKind Value)