LLVM 19.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) {
804
805 // It's possible that MCObjectFileInfo isn't fully initialized at this point
806 // due to an initialization order problem where LLVMTargetMachine creates the
807 // target streamer before TargetLoweringObjectFile calls
808 // InitializeMCObjectFileInfo. There doesn't seem to be a single place that
809 // covers all cases so this statement covers most cases and direct object
810 // emission must call setPic() once MCObjectFileInfo has been initialized. The
811 // cases we don't handle here are covered by MipsAsmPrinter.
813
814 const FeatureBitset &Features = STI.getFeatureBits();
815
816 // Set the header flags that we can in the constructor.
817 // FIXME: This is a fairly terrible hack. We set the rest
818 // of these in the destructor. The problem here is two-fold:
819 //
820 // a: Some of the eflags can be set/reset by directives.
821 // b: There aren't any usage paths that initialize the ABI
822 // pointer until after we initialize either an assembler
823 // or the target machine.
824 // We can fix this by making the target streamer construct
825 // the ABI, but this is fraught with wide ranging dependency
826 // issues as well.
827 unsigned EFlags = MCA.getELFHeaderEFlags();
828
829 // FIXME: Fix a dependency issue by instantiating the ABI object to some
830 // default based off the triple. The triple doesn't describe the target
831 // fully, but any external user of the API that uses the MCTargetStreamer
832 // would otherwise crash on assertion failure.
833
838 : MipsABIInfo::N64());
839
840 // Architecture
841 if (Features[Mips::FeatureMips64r6])
842 EFlags |= ELF::EF_MIPS_ARCH_64R6;
843 else if (Features[Mips::FeatureMips64r2] ||
844 Features[Mips::FeatureMips64r3] ||
845 Features[Mips::FeatureMips64r5])
846 EFlags |= ELF::EF_MIPS_ARCH_64R2;
847 else if (Features[Mips::FeatureMips64])
848 EFlags |= ELF::EF_MIPS_ARCH_64;
849 else if (Features[Mips::FeatureMips5])
850 EFlags |= ELF::EF_MIPS_ARCH_5;
851 else if (Features[Mips::FeatureMips4])
852 EFlags |= ELF::EF_MIPS_ARCH_4;
853 else if (Features[Mips::FeatureMips3])
854 EFlags |= ELF::EF_MIPS_ARCH_3;
855 else if (Features[Mips::FeatureMips32r6])
856 EFlags |= ELF::EF_MIPS_ARCH_32R6;
857 else if (Features[Mips::FeatureMips32r2] ||
858 Features[Mips::FeatureMips32r3] ||
859 Features[Mips::FeatureMips32r5])
860 EFlags |= ELF::EF_MIPS_ARCH_32R2;
861 else if (Features[Mips::FeatureMips32])
862 EFlags |= ELF::EF_MIPS_ARCH_32;
863 else if (Features[Mips::FeatureMips2])
864 EFlags |= ELF::EF_MIPS_ARCH_2;
865 else
866 EFlags |= ELF::EF_MIPS_ARCH_1;
867
868 // Machine
869 if (Features[Mips::FeatureCnMips])
870 EFlags |= ELF::EF_MIPS_MACH_OCTEON;
871
872 // Other options.
873 if (Features[Mips::FeatureNaN2008])
874 EFlags |= ELF::EF_MIPS_NAN2008;
875
876 MCA.setELFHeaderEFlags(EFlags);
877}
878
880 auto *Symbol = cast<MCSymbolELF>(S);
882 uint8_t Type = Symbol->getType();
883 if (Type != ELF::STT_FUNC)
884 return;
885
886 if (isMicroMipsEnabled())
887 Symbol->setOther(ELF::STO_MIPS_MICROMIPS);
888}
889
892 const MCObjectFileInfo &OFI = *MCA.getContext().getObjectFileInfo();
894
895 // .bss, .text and .data are always at least 16-byte aligned.
896 MCSection &TextSection = *OFI.getTextSection();
897 S.switchSection(&TextSection);
898 MCSection &DataSection = *OFI.getDataSection();
899 S.switchSection(&DataSection);
900 MCSection &BSSSection = *OFI.getBSSSection();
901 S.switchSection(&BSSSection);
902
903 TextSection.ensureMinAlignment(Align(16));
904 DataSection.ensureMinAlignment(Align(16));
905 BSSSection.ensureMinAlignment(Align(16));
906
907 if (RoundSectionSizes) {
908 // Make sections sizes a multiple of the alignment. This is useful for
909 // verifying the output of IAS against the output of other assemblers but
910 // it's not necessary to produce a correct object and increases section
911 // size.
912 for (MCSection &Sec : MCA) {
913 MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
914
915 Align Alignment = Section.getAlign();
916 S.switchSection(&Section);
917 if (Section.useCodeAlign())
918 S.emitCodeAlignment(Alignment, &STI, Alignment.value());
919 else
920 S.emitValueToAlignment(Alignment, 0, 1, Alignment.value());
921 }
922 }
923
924 const FeatureBitset &Features = STI.getFeatureBits();
925
926 // Update e_header flags. See the FIXME and comment above in
927 // the constructor for a full rundown on this.
928 unsigned EFlags = MCA.getELFHeaderEFlags();
929
930 // ABI
931 // N64 does not require any ABI bits.
932 if (getABI().IsO32())
933 EFlags |= ELF::EF_MIPS_ABI_O32;
934 else if (getABI().IsN32())
935 EFlags |= ELF::EF_MIPS_ABI2;
936
937 if (Features[Mips::FeatureGP64Bit]) {
938 if (getABI().IsO32())
939 EFlags |= ELF::EF_MIPS_32BITMODE; /* Compatibility Mode */
940 } else if (Features[Mips::FeatureMips64r2] || Features[Mips::FeatureMips64])
941 EFlags |= ELF::EF_MIPS_32BITMODE;
942
943 // -mplt is not implemented but we should act as if it was
944 // given.
945 if (!Features[Mips::FeatureNoABICalls])
946 EFlags |= ELF::EF_MIPS_CPIC;
947
948 if (Pic)
950
951 MCA.setELFHeaderEFlags(EFlags);
952
953 // Emit all the option records.
954 // At the moment we are only emitting .Mips.options (ODK_REGINFO) and
955 // .reginfo.
956 MipsELFStreamer &MEF = static_cast<MipsELFStreamer &>(Streamer);
958
960}
961
963 auto *Symbol = cast<MCSymbolELF>(S);
964 // If on rhs is micromips symbol then mark Symbol as microMips.
965 if (Value->getKind() != MCExpr::SymbolRef)
966 return;
967 const auto &RhsSym = cast<MCSymbolELF>(
968 static_cast<const MCSymbolRefExpr *>(Value)->getSymbol());
969
970 if (!(RhsSym.getOther() & ELF::STO_MIPS_MICROMIPS))
971 return;
972
973 Symbol->setOther(ELF::STO_MIPS_MICROMIPS);
974}
975
977 return static_cast<MCELFStreamer &>(Streamer);
978}
979
981 MicroMipsEnabled = true;
983}
984
986 MicroMipsEnabled = false;
988}
989
992 unsigned Flags = MCA.getELFHeaderEFlags();
993 Flags |= ELF::EF_MIPS_MICROMIPS;
994 MCA.setELFHeaderEFlags(Flags);
995}
996
999 unsigned Flags = MCA.getELFHeaderEFlags();
1001 MCA.setELFHeaderEFlags(Flags);
1003}
1004
1007 unsigned Flags = MCA.getELFHeaderEFlags();
1008 Flags |= ELF::EF_MIPS_NOREORDER;
1009 MCA.setELFHeaderEFlags(Flags);
1011}
1012
1015 MCContext &Context = MCA.getContext();
1017
1018 OS.pushSection();
1019 MCSectionELF *Sec = Context.getELFSection(".pdr", ELF::SHT_PROGBITS, 0);
1020 OS.switchSection(Sec);
1021 Sec->setAlignment(Align(4));
1022
1023 MCSymbol *Sym = Context.getOrCreateSymbol(Name);
1024 const MCSymbolRefExpr *ExprRef =
1026
1027 OS.emitValueImpl(ExprRef, 4);
1028
1029 OS.emitIntValue(GPRInfoSet ? GPRBitMask : 0, 4); // reg_mask
1030 OS.emitIntValue(GPRInfoSet ? GPROffset : 0, 4); // reg_offset
1031
1032 OS.emitIntValue(FPRInfoSet ? FPRBitMask : 0, 4); // fpreg_mask
1033 OS.emitIntValue(FPRInfoSet ? FPROffset : 0, 4); // fpreg_offset
1034
1035 OS.emitIntValue(FrameInfoSet ? FrameOffset : 0, 4); // frame_offset
1036 OS.emitIntValue(FrameInfoSet ? FrameReg : 0, 4); // frame_reg
1037 OS.emitIntValue(FrameInfoSet ? ReturnReg : 0, 4); // return_reg
1038
1039 // The .end directive marks the end of a procedure. Invalidate
1040 // the information gathered up until this point.
1042
1043 OS.popSection();
1044
1045 // .end also implicitly sets the size.
1046 MCSymbol *CurPCSym = Context.createTempSymbol();
1047 OS.emitLabel(CurPCSym);
1050 ExprRef, Context);
1051
1052 // The ELFObjectWriter can determine the absolute size as it has access to
1053 // the layout information of the assembly file, so a size expression rather
1054 // than an absolute value is ok here.
1055 static_cast<MCSymbolELF *>(Sym)->setSize(Size);
1056}
1057
1060
1061 // .ent also acts like an implicit '.type symbol, STT_FUNC'
1062 static_cast<const MCSymbolELF &>(Symbol).setType(ELF::STT_FUNC);
1063}
1064
1067 unsigned Flags = MCA.getELFHeaderEFlags();
1069 MCA.setELFHeaderEFlags(Flags);
1070}
1071
1074 unsigned Flags = MCA.getELFHeaderEFlags();
1075 Flags |= ELF::EF_MIPS_NAN2008;
1076 MCA.setELFHeaderEFlags(Flags);
1077}
1078
1081 unsigned Flags = MCA.getELFHeaderEFlags();
1082 Flags &= ~ELF::EF_MIPS_NAN2008;
1083 MCA.setELFHeaderEFlags(Flags);
1084}
1085
1088 unsigned Flags = MCA.getELFHeaderEFlags();
1089 // This option overrides other PIC options like -KPIC.
1090 Pic = false;
1091 Flags &= ~ELF::EF_MIPS_PIC;
1092 MCA.setELFHeaderEFlags(Flags);
1093}
1094
1097 unsigned Flags = MCA.getELFHeaderEFlags();
1098 Pic = true;
1099 // NOTE: We are following the GAS behaviour here which means the directive
1100 // 'pic2' also sets the CPIC bit in the ELF header. This is different from
1101 // what is stated in the SYSV ABI which consider the bits EF_MIPS_PIC and
1102 // EF_MIPS_CPIC to be mutually exclusive.
1104 MCA.setELFHeaderEFlags(Flags);
1105}
1106
1109 MipsELFStreamer &MEF = static_cast<MipsELFStreamer &>(Streamer);
1111}
1112
1113void MipsTargetELFStreamer::emitFrame(unsigned StackReg, unsigned StackSize,
1114 unsigned ReturnReg_) {
1116 const MCRegisterInfo *RegInfo = Context.getRegisterInfo();
1117
1118 FrameInfoSet = true;
1119 FrameReg = RegInfo->getEncodingValue(StackReg);
1120 FrameOffset = StackSize;
1121 ReturnReg = RegInfo->getEncodingValue(ReturnReg_);
1122}
1123
1124void MipsTargetELFStreamer::emitMask(unsigned CPUBitmask,
1125 int CPUTopSavedRegOff) {
1126 GPRInfoSet = true;
1127 GPRBitMask = CPUBitmask;
1128 GPROffset = CPUTopSavedRegOff;
1129}
1130
1131void MipsTargetELFStreamer::emitFMask(unsigned FPUBitmask,
1132 int FPUTopSavedRegOff) {
1133 FPRInfoSet = true;
1134 FPRBitMask = FPUBitmask;
1135 FPROffset = FPUTopSavedRegOff;
1136}
1137
1139 // .cpadd $reg
1140 // This directive inserts code to add $gp to the argument's register
1141 // when support for position independent code is enabled.
1142 if (!Pic)
1143 return;
1144
1145 emitAddu(RegNo, RegNo, GPReg, getABI().IsN64(), &STI);
1147}
1148
1150 // .cpload $reg
1151 // This directive expands to:
1152 // lui $gp, %hi(_gp_disp)
1153 // addui $gp, $gp, %lo(_gp_disp)
1154 // addu $gp, $gp, $reg
1155 // when support for position independent code is enabled.
1156 if (!Pic || (getABI().IsN32() || getABI().IsN64()))
1157 return;
1158
1159 // There's a GNU extension controlled by -mno-shared that allows
1160 // locally-binding symbols to be accessed using absolute addresses.
1161 // This is currently not supported. When supported -mno-shared makes
1162 // .cpload expand to:
1163 // lui $gp, %hi(__gnu_local_gp)
1164 // addiu $gp, $gp, %lo(__gnu_local_gp)
1165
1166 StringRef SymName("_gp_disp");
1168 MCSymbol *GP_Disp = MCA.getContext().getOrCreateSymbol(SymName);
1169 MCA.registerSymbol(*GP_Disp);
1170
1171 MCInst TmpInst;
1172 TmpInst.setOpcode(Mips::LUi);
1174 const MCExpr *HiSym = MipsMCExpr::create(
1177 MCA.getContext()),
1178 MCA.getContext());
1179 TmpInst.addOperand(MCOperand::createExpr(HiSym));
1180 getStreamer().emitInstruction(TmpInst, STI);
1181
1182 TmpInst.clear();
1183
1184 TmpInst.setOpcode(Mips::ADDiu);
1187 const MCExpr *LoSym = MipsMCExpr::create(
1190 MCA.getContext()),
1191 MCA.getContext());
1192 TmpInst.addOperand(MCOperand::createExpr(LoSym));
1193 getStreamer().emitInstruction(TmpInst, STI);
1194
1195 TmpInst.clear();
1196
1197 TmpInst.setOpcode(Mips::ADDu);
1200 TmpInst.addOperand(MCOperand::createReg(RegNo));
1201 getStreamer().emitInstruction(TmpInst, STI);
1202
1204}
1205
1207 if (Pic)
1209}
1210
1212 int Offset, function_ref<unsigned()> GetATReg, SMLoc IDLoc,
1213 const MCSubtargetInfo *STI) {
1215 // .cprestore offset
1216 // When PIC mode is enabled and the O32 ABI is used, this directive expands
1217 // to:
1218 // sw $gp, offset($sp)
1219 // and adds a corresponding LW after every JAL.
1220
1221 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
1222 // is used in non-PIC mode.
1223 if (!Pic || (getABI().IsN32() || getABI().IsN64()))
1224 return true;
1225
1226 // Store the $gp on the stack.
1227 emitStoreWithImmOffset(Mips::SW, GPReg, Mips::SP, Offset, GetATReg, IDLoc,
1228 STI);
1229 return true;
1230}
1231
1233 int RegOrOffset,
1234 const MCSymbol &Sym,
1235 bool IsReg) {
1236 // Only N32 and N64 emit anything for .cpsetup iff PIC is set.
1237 if (!Pic || !(getABI().IsN32() || getABI().IsN64()))
1238 return;
1239
1241
1243 MCInst Inst;
1244
1245 // Either store the old $gp in a register or on the stack
1246 if (IsReg) {
1247 // move $save, $gpreg
1248 emitRRR(Mips::OR64, RegOrOffset, GPReg, Mips::ZERO, SMLoc(), &STI);
1249 } else {
1250 // sd $gpreg, offset($sp)
1251 emitRRI(Mips::SD, GPReg, Mips::SP, RegOrOffset, SMLoc(), &STI);
1252 }
1253
1254 const MipsMCExpr *HiExpr = MipsMCExpr::createGpOff(
1256 MCA.getContext());
1257 const MipsMCExpr *LoExpr = MipsMCExpr::createGpOff(
1259 MCA.getContext());
1260
1261 // lui $gp, %hi(%neg(%gp_rel(funcSym)))
1262 emitRX(Mips::LUi, GPReg, MCOperand::createExpr(HiExpr), SMLoc(), &STI);
1263
1264 // addiu $gp, $gp, %lo(%neg(%gp_rel(funcSym)))
1265 emitRRX(Mips::ADDiu, GPReg, GPReg, MCOperand::createExpr(LoExpr), SMLoc(),
1266 &STI);
1267
1268 // (d)addu $gp, $gp, $funcreg
1269 if (getABI().IsN32())
1270 emitRRR(Mips::ADDu, GPReg, GPReg, RegNo, SMLoc(), &STI);
1271 else
1272 emitRRR(Mips::DADDu, GPReg, GPReg, RegNo, SMLoc(), &STI);
1273}
1274
1276 bool SaveLocationIsRegister) {
1277 // Only N32 and N64 emit anything for .cpreturn iff PIC is set.
1278 if (!Pic || !(getABI().IsN32() || getABI().IsN64()))
1279 return;
1280
1281 MCInst Inst;
1282 // Either restore the old $gp from a register or on the stack
1283 if (SaveLocationIsRegister) {
1284 Inst.setOpcode(Mips::OR);
1286 Inst.addOperand(MCOperand::createReg(SaveLocation));
1287 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
1288 } else {
1289 Inst.setOpcode(Mips::LD);
1291 Inst.addOperand(MCOperand::createReg(Mips::SP));
1292 Inst.addOperand(MCOperand::createImm(SaveLocation));
1293 }
1294 getStreamer().emitInstruction(Inst, STI);
1295
1297}
1298
1301 MCContext &Context = MCA.getContext();
1303 MCSectionELF *Sec = Context.getELFSection(
1304 ".MIPS.abiflags", ELF::SHT_MIPS_ABIFLAGS, ELF::SHF_ALLOC, 24);
1305 OS.switchSection(Sec);
1306 Sec->setAlignment(Align(8));
1307
1309}
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:322
unsigned getELFHeaderEFlags() const
ELF e_header flags.
Definition: MCAssembler.h:277
void setELFHeaderEFlags(unsigned Flags)
Definition: MCAssembler.h:278
bool registerSymbol(const MCSymbol &Symbol)
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:621
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:345
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
Definition: MCContext.h:547
const MCRegisterInfo * getRegisterInfo() const
Definition: MCContext.h:414
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition: MCContext.cpp:212
void emitValueToAlignment(Align, int64_t, unsigned, unsigned) override
Emit some number of copies of Value until the byte alignment ByteAlignment is reached.
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
@ SymbolRef
References to labels and assigned expressions.
Definition: MCExpr.h:40
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:159
void ensureMinAlignment(Align MinAlignment)
Makes sure that Alignment is at least MinAlignment.
Definition: MCSection.h:162
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:192
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:397
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:373
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:590
@ SHT_PROGBITS
Definition: ELF.h:1067
@ SHT_MIPS_ABIFLAGS
Definition: ELF.h:1140
@ SHF_ALLOC
Definition: ELF.h:1161
@ STT_FUNC
Definition: ELF.h:1328
@ EF_MIPS_MICROMIPS
Definition: ELF.h:551
@ EF_MIPS_ARCH_32R6
Definition: ELF.h:566
@ EF_MIPS_ABI_O32
Definition: ELF.h:522
@ EF_MIPS_ARCH_64
Definition: ELF.h:563
@ EF_MIPS_ARCH_32
Definition: ELF.h:562
@ EF_MIPS_MACH_OCTEON
Definition: ELF.h:537
@ EF_MIPS_ARCH_4
Definition: ELF.h:560
@ EF_MIPS_ARCH_5
Definition: ELF.h:561
@ EF_MIPS_NAN2008
Definition: ELF.h:519
@ EF_MIPS_PIC
Definition: ELF.h:512
@ EF_MIPS_ARCH_2
Definition: ELF.h:558
@ EF_MIPS_32BITMODE
Definition: ELF.h:515
@ EF_MIPS_ARCH_32R2
Definition: ELF.h:564
@ EF_MIPS_ARCH_64R2
Definition: ELF.h:565
@ EF_MIPS_ARCH_ASE_M16
Definition: ELF.h:552
@ EF_MIPS_NOREORDER
Definition: ELF.h:511
@ EF_MIPS_ARCH_1
Definition: ELF.h:557
@ EF_MIPS_CPIC
Definition: ELF.h:513
@ EF_MIPS_ARCH_64R6
Definition: ELF.h:567
@ EF_MIPS_ABI2
Definition: ELF.h:514
@ EF_MIPS_ARCH_3
Definition: ELF.h:559
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)