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();
893
894 // .bss, .text and .data are always at least 16-byte aligned.
895 MCSection &TextSection = *OFI.getTextSection();
896 MCA.registerSection(TextSection);
897 MCSection &DataSection = *OFI.getDataSection();
898 MCA.registerSection(DataSection);
899 MCSection &BSSSection = *OFI.getBSSSection();
900 MCA.registerSection(BSSSection);
901
902 TextSection.ensureMinAlignment(Align(16));
903 DataSection.ensureMinAlignment(Align(16));
904 BSSSection.ensureMinAlignment(Align(16));
905
906 if (RoundSectionSizes) {
907 // Make sections sizes a multiple of the alignment. This is useful for
908 // verifying the output of IAS against the output of other assemblers but
909 // it's not necessary to produce a correct object and increases section
910 // size.
912 for (MCSection &S : MCA) {
913 MCSectionELF &Section = static_cast<MCSectionELF &>(S);
914
915 Align Alignment = Section.getAlign();
916 OS.switchSection(&Section);
917 if (Section.useCodeAlign())
918 OS.emitCodeAlignment(Alignment, &STI, Alignment.value());
919 else
920 OS.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 MCSectionELF *Sec = Context.getELFSection(".pdr", ELF::SHT_PROGBITS, 0);
1019
1020 MCSymbol *Sym = Context.getOrCreateSymbol(Name);
1021 const MCSymbolRefExpr *ExprRef =
1023
1024 MCA.registerSection(*Sec);
1025 Sec->setAlignment(Align(4));
1026
1027 OS.pushSection();
1028
1029 OS.switchSection(Sec);
1030
1031 OS.emitValueImpl(ExprRef, 4);
1032
1033 OS.emitIntValue(GPRInfoSet ? GPRBitMask : 0, 4); // reg_mask
1034 OS.emitIntValue(GPRInfoSet ? GPROffset : 0, 4); // reg_offset
1035
1036 OS.emitIntValue(FPRInfoSet ? FPRBitMask : 0, 4); // fpreg_mask
1037 OS.emitIntValue(FPRInfoSet ? FPROffset : 0, 4); // fpreg_offset
1038
1039 OS.emitIntValue(FrameInfoSet ? FrameOffset : 0, 4); // frame_offset
1040 OS.emitIntValue(FrameInfoSet ? FrameReg : 0, 4); // frame_reg
1041 OS.emitIntValue(FrameInfoSet ? ReturnReg : 0, 4); // return_reg
1042
1043 // The .end directive marks the end of a procedure. Invalidate
1044 // the information gathered up until this point.
1046
1047 OS.popSection();
1048
1049 // .end also implicitly sets the size.
1050 MCSymbol *CurPCSym = Context.createTempSymbol();
1051 OS.emitLabel(CurPCSym);
1054 ExprRef, Context);
1055
1056 // The ELFObjectWriter can determine the absolute size as it has access to
1057 // the layout information of the assembly file, so a size expression rather
1058 // than an absolute value is ok here.
1059 static_cast<MCSymbolELF *>(Sym)->setSize(Size);
1060}
1061
1064
1065 // .ent also acts like an implicit '.type symbol, STT_FUNC'
1066 static_cast<const MCSymbolELF &>(Symbol).setType(ELF::STT_FUNC);
1067}
1068
1071 unsigned Flags = MCA.getELFHeaderEFlags();
1073 MCA.setELFHeaderEFlags(Flags);
1074}
1075
1078 unsigned Flags = MCA.getELFHeaderEFlags();
1079 Flags |= ELF::EF_MIPS_NAN2008;
1080 MCA.setELFHeaderEFlags(Flags);
1081}
1082
1085 unsigned Flags = MCA.getELFHeaderEFlags();
1086 Flags &= ~ELF::EF_MIPS_NAN2008;
1087 MCA.setELFHeaderEFlags(Flags);
1088}
1089
1092 unsigned Flags = MCA.getELFHeaderEFlags();
1093 // This option overrides other PIC options like -KPIC.
1094 Pic = false;
1095 Flags &= ~ELF::EF_MIPS_PIC;
1096 MCA.setELFHeaderEFlags(Flags);
1097}
1098
1101 unsigned Flags = MCA.getELFHeaderEFlags();
1102 Pic = true;
1103 // NOTE: We are following the GAS behaviour here which means the directive
1104 // 'pic2' also sets the CPIC bit in the ELF header. This is different from
1105 // what is stated in the SYSV ABI which consider the bits EF_MIPS_PIC and
1106 // EF_MIPS_CPIC to be mutually exclusive.
1108 MCA.setELFHeaderEFlags(Flags);
1109}
1110
1113 MipsELFStreamer &MEF = static_cast<MipsELFStreamer &>(Streamer);
1115}
1116
1117void MipsTargetELFStreamer::emitFrame(unsigned StackReg, unsigned StackSize,
1118 unsigned ReturnReg_) {
1120 const MCRegisterInfo *RegInfo = Context.getRegisterInfo();
1121
1122 FrameInfoSet = true;
1123 FrameReg = RegInfo->getEncodingValue(StackReg);
1124 FrameOffset = StackSize;
1125 ReturnReg = RegInfo->getEncodingValue(ReturnReg_);
1126}
1127
1128void MipsTargetELFStreamer::emitMask(unsigned CPUBitmask,
1129 int CPUTopSavedRegOff) {
1130 GPRInfoSet = true;
1131 GPRBitMask = CPUBitmask;
1132 GPROffset = CPUTopSavedRegOff;
1133}
1134
1135void MipsTargetELFStreamer::emitFMask(unsigned FPUBitmask,
1136 int FPUTopSavedRegOff) {
1137 FPRInfoSet = true;
1138 FPRBitMask = FPUBitmask;
1139 FPROffset = FPUTopSavedRegOff;
1140}
1141
1143 // .cpadd $reg
1144 // This directive inserts code to add $gp to the argument's register
1145 // when support for position independent code is enabled.
1146 if (!Pic)
1147 return;
1148
1149 emitAddu(RegNo, RegNo, GPReg, getABI().IsN64(), &STI);
1151}
1152
1154 // .cpload $reg
1155 // This directive expands to:
1156 // lui $gp, %hi(_gp_disp)
1157 // addui $gp, $gp, %lo(_gp_disp)
1158 // addu $gp, $gp, $reg
1159 // when support for position independent code is enabled.
1160 if (!Pic || (getABI().IsN32() || getABI().IsN64()))
1161 return;
1162
1163 // There's a GNU extension controlled by -mno-shared that allows
1164 // locally-binding symbols to be accessed using absolute addresses.
1165 // This is currently not supported. When supported -mno-shared makes
1166 // .cpload expand to:
1167 // lui $gp, %hi(__gnu_local_gp)
1168 // addiu $gp, $gp, %lo(__gnu_local_gp)
1169
1170 StringRef SymName("_gp_disp");
1172 MCSymbol *GP_Disp = MCA.getContext().getOrCreateSymbol(SymName);
1173 MCA.registerSymbol(*GP_Disp);
1174
1175 MCInst TmpInst;
1176 TmpInst.setOpcode(Mips::LUi);
1178 const MCExpr *HiSym = MipsMCExpr::create(
1181 MCA.getContext()),
1182 MCA.getContext());
1183 TmpInst.addOperand(MCOperand::createExpr(HiSym));
1184 getStreamer().emitInstruction(TmpInst, STI);
1185
1186 TmpInst.clear();
1187
1188 TmpInst.setOpcode(Mips::ADDiu);
1191 const MCExpr *LoSym = MipsMCExpr::create(
1194 MCA.getContext()),
1195 MCA.getContext());
1196 TmpInst.addOperand(MCOperand::createExpr(LoSym));
1197 getStreamer().emitInstruction(TmpInst, STI);
1198
1199 TmpInst.clear();
1200
1201 TmpInst.setOpcode(Mips::ADDu);
1204 TmpInst.addOperand(MCOperand::createReg(RegNo));
1205 getStreamer().emitInstruction(TmpInst, STI);
1206
1208}
1209
1211 if (Pic)
1213}
1214
1216 int Offset, function_ref<unsigned()> GetATReg, SMLoc IDLoc,
1217 const MCSubtargetInfo *STI) {
1219 // .cprestore offset
1220 // When PIC mode is enabled and the O32 ABI is used, this directive expands
1221 // to:
1222 // sw $gp, offset($sp)
1223 // and adds a corresponding LW after every JAL.
1224
1225 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
1226 // is used in non-PIC mode.
1227 if (!Pic || (getABI().IsN32() || getABI().IsN64()))
1228 return true;
1229
1230 // Store the $gp on the stack.
1231 emitStoreWithImmOffset(Mips::SW, GPReg, Mips::SP, Offset, GetATReg, IDLoc,
1232 STI);
1233 return true;
1234}
1235
1237 int RegOrOffset,
1238 const MCSymbol &Sym,
1239 bool IsReg) {
1240 // Only N32 and N64 emit anything for .cpsetup iff PIC is set.
1241 if (!Pic || !(getABI().IsN32() || getABI().IsN64()))
1242 return;
1243
1245
1247 MCInst Inst;
1248
1249 // Either store the old $gp in a register or on the stack
1250 if (IsReg) {
1251 // move $save, $gpreg
1252 emitRRR(Mips::OR64, RegOrOffset, GPReg, Mips::ZERO, SMLoc(), &STI);
1253 } else {
1254 // sd $gpreg, offset($sp)
1255 emitRRI(Mips::SD, GPReg, Mips::SP, RegOrOffset, SMLoc(), &STI);
1256 }
1257
1258 const MipsMCExpr *HiExpr = MipsMCExpr::createGpOff(
1260 MCA.getContext());
1261 const MipsMCExpr *LoExpr = MipsMCExpr::createGpOff(
1263 MCA.getContext());
1264
1265 // lui $gp, %hi(%neg(%gp_rel(funcSym)))
1266 emitRX(Mips::LUi, GPReg, MCOperand::createExpr(HiExpr), SMLoc(), &STI);
1267
1268 // addiu $gp, $gp, %lo(%neg(%gp_rel(funcSym)))
1269 emitRRX(Mips::ADDiu, GPReg, GPReg, MCOperand::createExpr(LoExpr), SMLoc(),
1270 &STI);
1271
1272 // (d)addu $gp, $gp, $funcreg
1273 if (getABI().IsN32())
1274 emitRRR(Mips::ADDu, GPReg, GPReg, RegNo, SMLoc(), &STI);
1275 else
1276 emitRRR(Mips::DADDu, GPReg, GPReg, RegNo, SMLoc(), &STI);
1277}
1278
1280 bool SaveLocationIsRegister) {
1281 // Only N32 and N64 emit anything for .cpreturn iff PIC is set.
1282 if (!Pic || !(getABI().IsN32() || getABI().IsN64()))
1283 return;
1284
1285 MCInst Inst;
1286 // Either restore the old $gp from a register or on the stack
1287 if (SaveLocationIsRegister) {
1288 Inst.setOpcode(Mips::OR);
1290 Inst.addOperand(MCOperand::createReg(SaveLocation));
1291 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
1292 } else {
1293 Inst.setOpcode(Mips::LD);
1295 Inst.addOperand(MCOperand::createReg(Mips::SP));
1296 Inst.addOperand(MCOperand::createImm(SaveLocation));
1297 }
1298 getStreamer().emitInstruction(Inst, STI);
1299
1301}
1302
1305 MCContext &Context = MCA.getContext();
1307 MCSectionELF *Sec = Context.getELFSection(
1308 ".MIPS.abiflags", ELF::SHT_MIPS_ABIFLAGS, ELF::SHF_ALLOC, 24);
1309 MCA.registerSection(*Sec);
1310 Sec->setAlignment(Align(8));
1311 OS.switchSection(Sec);
1312
1314}
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)
LLVMContext & Context
raw_pwrite_stream & OS
Container class for subtarget features.
MCContext & getContext() const
Definition: MCAssembler.h:326
unsigned getELFHeaderEFlags() const
ELF e_header flags.
Definition: MCAssembler.h:281
bool registerSection(MCSection &Section)
void setELFHeaderEFlags(unsigned Flags)
Definition: MCAssembler.h:282
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:76
const MCObjectFileInfo * getObjectFileInfo() const
Definition: MCContext.h:450
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition: MCContext.cpp:200
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.
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:26
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition: MCSection.h:39
void setAlignment(Align Value)
Definition: MCSection.h:141
void ensureMinAlignment(Align MinAlignment)
Makes sure that Alignment is at least MinAlignment.
Definition: MCSection.h:144
Streaming machine code generation interface.
Definition: MCStreamer.h:212
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current 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:40
Target specific streamer interface.
Definition: MCStreamer.h:93
MCStreamer & getStreamer()
Definition: MCStreamer.h:101
MCStreamer & Streamer
Definition: MCStreamer.h:95
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:361
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.
@ SHF_ALLOC
Definition: ELF.h:1155
@ STO_MIPS_MICROMIPS
Definition: ELF.h:590
@ 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
@ SHT_PROGBITS
Definition: ELF.h:1063
@ SHT_MIPS_ABIFLAGS
Definition: ELF.h:1136
@ STT_FUNC
Definition: ELF.h:1322
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:450
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:456
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:156
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)