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"
26#include "llvm/MC/MCSymbolELF.h"
31
32using namespace llvm;
33
34namespace {
35static cl::opt<bool> RoundSectionSizes(
36 "mips-round-section-sizes", cl::init(false),
37 cl::desc("Round section sizes up to the section alignment"), cl::Hidden);
38} // end anonymous namespace
39
40static bool isMicroMips(const MCSubtargetInfo *STI) {
41 return STI->hasFeature(Mips::FeatureMicroMips);
42}
43
44static bool isMips32r6(const MCSubtargetInfo *STI) {
45 return STI->hasFeature(Mips::FeatureMips32r6);
46}
47
49 : MCTargetStreamer(S), GPReg(Mips::GP), ModuleDirectiveAllowed(true) {
51}
74}
84void MipsTargetStreamer::emitFrame(unsigned StackReg, unsigned StackSize,
85 unsigned ReturnReg) {}
86void MipsTargetStreamer::emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) {}
87void MipsTargetStreamer::emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) {
88}
91}
112}
115}
124 // .cplocal $reg
125 // This directive forces to use the alternate register for context pointer.
126 // For example
127 // .cplocal $4
128 // jal foo
129 // expands to
130 // ld $25, %call16(foo)($4)
131 // jalr $25
132
133 if (!getABI().IsN32() && !getABI().IsN64())
134 return;
135
136 GPReg = RegNo;
137
139}
141 int Offset, function_ref<unsigned()> GetATReg, SMLoc IDLoc,
142 const MCSubtargetInfo *STI) {
144 return true;
145}
146void MipsTargetStreamer::emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
147 const MCSymbol &Sym, bool IsReg) {
148}
150 bool SaveLocationIsRegister) {}
151
153
156 report_fatal_error("+nooddspreg is only valid for O32");
157}
170}
174}
175
176void MipsTargetStreamer::emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
177 const MCSubtargetInfo *STI) {
178 MCInst TmpInst;
179 TmpInst.setOpcode(Opcode);
180 TmpInst.addOperand(MCOperand::createReg(Reg0));
181 TmpInst.setLoc(IDLoc);
182 getStreamer().emitInstruction(TmpInst, *STI);
183}
184
185void MipsTargetStreamer::emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1,
186 SMLoc IDLoc, const MCSubtargetInfo *STI) {
187 MCInst TmpInst;
188 TmpInst.setOpcode(Opcode);
189 TmpInst.addOperand(MCOperand::createReg(Reg0));
190 TmpInst.addOperand(Op1);
191 TmpInst.setLoc(IDLoc);
192 getStreamer().emitInstruction(TmpInst, *STI);
193}
194
195void MipsTargetStreamer::emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm,
196 SMLoc IDLoc, const MCSubtargetInfo *STI) {
197 emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, STI);
198}
199
200void MipsTargetStreamer::emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1,
201 SMLoc IDLoc, const MCSubtargetInfo *STI) {
202 emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, STI);
203}
204
205void MipsTargetStreamer::emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2,
206 SMLoc IDLoc, const MCSubtargetInfo *STI) {
207 MCInst TmpInst;
208 TmpInst.setOpcode(Opcode);
209 TmpInst.addOperand(MCOperand::createImm(Imm1));
210 TmpInst.addOperand(MCOperand::createImm(Imm2));
211 TmpInst.setLoc(IDLoc);
212 getStreamer().emitInstruction(TmpInst, *STI);
213}
214
215void MipsTargetStreamer::emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1,
216 MCOperand Op2, SMLoc IDLoc,
217 const MCSubtargetInfo *STI) {
218 MCInst TmpInst;
219 TmpInst.setOpcode(Opcode);
220 TmpInst.addOperand(MCOperand::createReg(Reg0));
221 TmpInst.addOperand(MCOperand::createReg(Reg1));
222 TmpInst.addOperand(Op2);
223 TmpInst.setLoc(IDLoc);
224 getStreamer().emitInstruction(TmpInst, *STI);
225}
226
227void MipsTargetStreamer::emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1,
228 unsigned Reg2, SMLoc IDLoc,
229 const MCSubtargetInfo *STI) {
230 emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc, STI);
231}
232
233void MipsTargetStreamer::emitRRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1,
234 unsigned Reg2, MCOperand Op3, SMLoc IDLoc,
235 const MCSubtargetInfo *STI) {
236 MCInst TmpInst;
237 TmpInst.setOpcode(Opcode);
238 TmpInst.addOperand(MCOperand::createReg(Reg0));
239 TmpInst.addOperand(MCOperand::createReg(Reg1));
240 TmpInst.addOperand(MCOperand::createReg(Reg2));
241 TmpInst.addOperand(Op3);
242 TmpInst.setLoc(IDLoc);
243 getStreamer().emitInstruction(TmpInst, *STI);
244}
245
246void MipsTargetStreamer::emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1,
247 int16_t Imm, SMLoc IDLoc,
248 const MCSubtargetInfo *STI) {
249 emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc, STI);
250}
251
252void MipsTargetStreamer::emitRRIII(unsigned Opcode, unsigned Reg0,
253 unsigned Reg1, int16_t Imm0, int16_t Imm1,
254 int16_t Imm2, SMLoc IDLoc,
255 const MCSubtargetInfo *STI) {
256 MCInst TmpInst;
257 TmpInst.setOpcode(Opcode);
258 TmpInst.addOperand(MCOperand::createReg(Reg0));
259 TmpInst.addOperand(MCOperand::createReg(Reg1));
260 TmpInst.addOperand(MCOperand::createImm(Imm0));
261 TmpInst.addOperand(MCOperand::createImm(Imm1));
262 TmpInst.addOperand(MCOperand::createImm(Imm2));
263 TmpInst.setLoc(IDLoc);
264 getStreamer().emitInstruction(TmpInst, *STI);
265}
266
267void MipsTargetStreamer::emitAddu(unsigned DstReg, unsigned SrcReg,
268 unsigned TrgReg, bool Is64Bit,
269 const MCSubtargetInfo *STI) {
270 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
271 STI);
272}
273
274void MipsTargetStreamer::emitDSLL(unsigned DstReg, unsigned SrcReg,
275 int16_t ShiftAmount, SMLoc IDLoc,
276 const MCSubtargetInfo *STI) {
277 if (ShiftAmount >= 32) {
278 emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc, STI);
279 return;
280 }
281
282 emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, STI);
283}
284
286 const MCSubtargetInfo *STI) {
287 // The default case of `nop` is `sll $zero, $zero, 0`.
288 unsigned Opc = Mips::SLL;
289 if (isMicroMips(STI) && hasShortDelaySlot) {
290 Opc = isMips32r6(STI) ? Mips::MOVE16_MMR6 : Mips::MOVE16_MM;
291 emitRR(Opc, Mips::ZERO, Mips::ZERO, IDLoc, STI);
292 return;
293 }
294
295 if (isMicroMips(STI))
296 Opc = isMips32r6(STI) ? Mips::SLL_MMR6 : Mips::SLL_MM;
297
298 emitRRI(Opc, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
299}
300
302 if (isMicroMips(STI))
303 emitRR(Mips::MOVE16_MM, Mips::ZERO, Mips::ZERO, IDLoc, STI);
304 else
305 emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
306}
307
308/// Emit the $gp restore operation for .cprestore.
310 const MCSubtargetInfo *STI) {
311 emitLoadWithImmOffset(Mips::LW, GPReg, Mips::SP, Offset, GPReg, IDLoc, STI);
312}
313
314/// Emit a store instruction with an immediate offset.
316 unsigned Opcode, unsigned SrcReg, unsigned BaseReg, int64_t Offset,
317 function_ref<unsigned()> GetATReg, SMLoc IDLoc,
318 const MCSubtargetInfo *STI) {
319 if (isInt<16>(Offset)) {
320 emitRRI(Opcode, SrcReg, BaseReg, Offset, IDLoc, STI);
321 return;
322 }
323
324 // sw $8, offset($8) => lui $at, %hi(offset)
325 // add $at, $at, $8
326 // sw $8, %lo(offset)($at)
327
328 unsigned ATReg = GetATReg();
329 if (!ATReg)
330 return;
331
332 unsigned LoOffset = Offset & 0x0000ffff;
333 unsigned HiOffset = (Offset & 0xffff0000) >> 16;
334
335 // If msb of LoOffset is 1(negative number) we must increment HiOffset
336 // to account for the sign-extension of the low part.
337 if (LoOffset & 0x8000)
338 HiOffset++;
339
340 // Generate the base address in ATReg.
341 emitRI(Mips::LUi, ATReg, HiOffset, IDLoc, STI);
342 if (BaseReg != Mips::ZERO)
343 emitRRR(Mips::ADDu, ATReg, ATReg, BaseReg, IDLoc, STI);
344 // Emit the store with the adjusted base and offset.
345 emitRRI(Opcode, SrcReg, ATReg, LoOffset, IDLoc, STI);
346}
347
348/// Emit a load instruction with an immediate offset. DstReg and TmpReg are
349/// permitted to be the same register iff DstReg is distinct from BaseReg and
350/// DstReg is a GPR. It is the callers responsibility to identify such cases
351/// and pass the appropriate register in TmpReg.
352void MipsTargetStreamer::emitLoadWithImmOffset(unsigned Opcode, unsigned DstReg,
353 unsigned BaseReg, int64_t Offset,
354 unsigned TmpReg, SMLoc IDLoc,
355 const MCSubtargetInfo *STI) {
356 if (isInt<16>(Offset)) {
357 emitRRI(Opcode, DstReg, BaseReg, Offset, IDLoc, STI);
358 return;
359 }
360
361 // 1) lw $8, offset($9) => lui $8, %hi(offset)
362 // add $8, $8, $9
363 // lw $8, %lo(offset)($9)
364 // 2) lw $8, offset($8) => lui $at, %hi(offset)
365 // add $at, $at, $8
366 // lw $8, %lo(offset)($at)
367
368 unsigned LoOffset = Offset & 0x0000ffff;
369 unsigned HiOffset = (Offset & 0xffff0000) >> 16;
370
371 // If msb of LoOffset is 1(negative number) we must increment HiOffset
372 // to account for the sign-extension of the low part.
373 if (LoOffset & 0x8000)
374 HiOffset++;
375
376 // Generate the base address in TmpReg.
377 emitRI(Mips::LUi, TmpReg, HiOffset, IDLoc, STI);
378 if (BaseReg != Mips::ZERO)
379 emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
380 // Emit the load with the adjusted base and offset.
381 emitRRI(Opcode, DstReg, TmpReg, LoOffset, IDLoc, STI);
382}
383
386 : MipsTargetStreamer(S), OS(OS) {}
387
389 OS << "\t.set\tmicromips\n";
391}
392
394 OS << "\t.set\tnomicromips\n";
396}
397
399 OS << "\t.set\tmips16\n";
401}
402
404 OS << "\t.set\tnomips16\n";
406}
407
409 OS << "\t.set\treorder\n";
411}
412
414 OS << "\t.set\tnoreorder\n";
416}
417
419 OS << "\t.set\tmacro\n";
421}
422
424 OS << "\t.set\tnomacro\n";
426}
427
429 OS << "\t.set\tmsa\n";
431}
432
434 OS << "\t.set\tnomsa\n";
436}
437
439 OS << "\t.set\tmt\n";
441}
442
444 OS << "\t.set\tnomt\n";
446}
447
449 OS << "\t.set\tcrc\n";
451}
452
454 OS << "\t.set\tnocrc\n";
456}
457
459 OS << "\t.set\tvirt\n";
461}
462
464 OS << "\t.set\tnovirt\n";
466}
467
469 OS << "\t.set\tginv\n";
471}
472
474 OS << "\t.set\tnoginv\n";
476}
477
479 OS << "\t.set\tat\n";
481}
482
484 OS << "\t.set\tat=$" << Twine(RegNo) << "\n";
486}
487
489 OS << "\t.set\tnoat\n";
491}
492
494 OS << "\t.end\t" << Name << '\n';
495}
496
498 OS << "\t.ent\t" << Symbol.getName() << '\n';
499}
500
501void MipsTargetAsmStreamer::emitDirectiveAbiCalls() { OS << "\t.abicalls\n"; }
502
503void MipsTargetAsmStreamer::emitDirectiveNaN2008() { OS << "\t.nan\t2008\n"; }
504
506 OS << "\t.nan\tlegacy\n";
507}
508
510 OS << "\t.option\tpic0\n";
511}
512
514 OS << "\t.option\tpic2\n";
515}
516
519 OS << "\t.insn\n";
520}
521
522void MipsTargetAsmStreamer::emitFrame(unsigned StackReg, unsigned StackSize,
523 unsigned ReturnReg) {
524 OS << "\t.frame\t$"
526 << StackSize << ",$"
528}
529
531 OS << "\t.set arch=" << Arch << "\n";
533}
534
536 OS << "\t.set\tmips0\n";
538}
539
541 OS << "\t.set\tmips1\n";
543}
544
546 OS << "\t.set\tmips2\n";
548}
549
551 OS << "\t.set\tmips3\n";
553}
554
556 OS << "\t.set\tmips4\n";
558}
559
561 OS << "\t.set\tmips5\n";
563}
564
566 OS << "\t.set\tmips32\n";
568}
569
571 OS << "\t.set\tmips32r2\n";
573}
574
576 OS << "\t.set\tmips32r3\n";
578}
579
581 OS << "\t.set\tmips32r5\n";
583}
584
586 OS << "\t.set\tmips32r6\n";
588}
589
591 OS << "\t.set\tmips64\n";
593}
594
596 OS << "\t.set\tmips64r2\n";
598}
599
601 OS << "\t.set\tmips64r3\n";
603}
604
606 OS << "\t.set\tmips64r5\n";
608}
609
611 OS << "\t.set\tmips64r6\n";
613}
614
616 OS << "\t.set\tdsp\n";
618}
619
621 OS << "\t.set\tdspr2\n";
623}
624
626 OS << "\t.set\tnodsp\n";
628}
629
631 OS << "\t.set\tmips3d\n";
633}
634
636 OS << "\t.set\tnomips3d\n";
638}
639
641 OS << "\t.set\tpop\n";
643}
644
646 OS << "\t.set\tpush\n";
648}
649
651 OS << "\t.set\tsoftfloat\n";
653}
654
656 OS << "\t.set\thardfloat\n";
658}
659
660// Print a 32 bit hex number with all numbers.
661static void printHex32(unsigned Value, raw_ostream &OS) {
662 OS << "0x";
663 for (int i = 7; i >= 0; i--)
664 OS.write_hex((Value & (0xF << (i * 4))) >> (i * 4));
665}
666
667void MipsTargetAsmStreamer::emitMask(unsigned CPUBitmask,
668 int CPUTopSavedRegOff) {
669 OS << "\t.mask \t";
670 printHex32(CPUBitmask, OS);
671 OS << ',' << CPUTopSavedRegOff << '\n';
672}
673
674void MipsTargetAsmStreamer::emitFMask(unsigned FPUBitmask,
675 int FPUTopSavedRegOff) {
676 OS << "\t.fmask\t";
677 printHex32(FPUBitmask, OS);
678 OS << "," << FPUTopSavedRegOff << '\n';
679}
680
682 OS << "\t.cpadd\t$"
685}
686
688 OS << "\t.cpload\t$"
691}
692
694 OS << "\t.cplocal\t$"
697}
698
700 int Offset, function_ref<unsigned()> GetATReg, SMLoc IDLoc,
701 const MCSubtargetInfo *STI) {
703 OS << "\t.cprestore\t" << Offset << "\n";
704 return true;
705}
706
708 int RegOrOffset,
709 const MCSymbol &Sym,
710 bool IsReg) {
711 OS << "\t.cpsetup\t$"
713
714 if (IsReg)
715 OS << "$"
717 else
718 OS << RegOrOffset;
719
720 OS << ", ";
721
722 OS << Sym.getName();
724}
725
727 bool SaveLocationIsRegister) {
728 OS << "\t.cpreturn";
730}
731
735 OS << "\t.module\tsoftfloat\n";
736 else
737 OS << "\t.module\tfp=" << ABIFlagsSection.getFpABIString(FpABI) << "\n";
738}
739
743
744 OS << "\t.set\tfp=";
745 OS << ABIFlagsSection.getFpABIString(Value) << "\n";
746}
747
750
751 OS << "\t.module\t" << (ABIFlagsSection.OddSPReg ? "" : "no") << "oddspreg\n";
752}
753
756 OS << "\t.set\toddspreg\n";
757}
758
761 OS << "\t.set\tnooddspreg\n";
762}
763
765 OS << "\t.module\tsoftfloat\n";
766}
767
769 OS << "\t.module\thardfloat\n";
770}
771
773 OS << "\t.module\tmt\n";
774}
775
777 OS << "\t.module\tcrc\n";
778}
779
781 OS << "\t.module\tnocrc\n";
782}
783
785 OS << "\t.module\tvirt\n";
786}
787
789 OS << "\t.module\tnovirt\n";
790}
791
793 OS << "\t.module\tginv\n";
794}
795
797 OS << "\t.module\tnoginv\n";
798}
799
800// This part is for ELF object output.
802 const MCSubtargetInfo &STI)
803 : MipsTargetStreamer(S), MicroMipsEnabled(false), STI(STI) {
806
807 // It's possible that MCObjectFileInfo isn't fully initialized at this point
808 // due to an initialization order problem where LLVMTargetMachine creates the
809 // target streamer before TargetLoweringObjectFile calls
810 // InitializeMCObjectFileInfo. There doesn't seem to be a single place that
811 // covers all cases so this statement covers most cases and direct object
812 // emission must call setPic() once MCObjectFileInfo has been initialized. The
813 // cases we don't handle here are covered by MipsAsmPrinter.
815
816 const FeatureBitset &Features = STI.getFeatureBits();
817
818 // Set the header flags that we can in the constructor.
819 // FIXME: This is a fairly terrible hack. We set the rest
820 // of these in the destructor. The problem here is two-fold:
821 //
822 // a: Some of the eflags can be set/reset by directives.
823 // b: There aren't any usage paths that initialize the ABI
824 // pointer until after we initialize either an assembler
825 // or the target machine.
826 // We can fix this by making the target streamer construct
827 // the ABI, but this is fraught with wide ranging dependency
828 // issues as well.
829 unsigned EFlags = W.getELFHeaderEFlags();
830
831 // FIXME: Fix a dependency issue by instantiating the ABI object to some
832 // default based off the triple. The triple doesn't describe the target
833 // fully, but any external user of the API that uses the MCTargetStreamer
834 // would otherwise crash on assertion failure.
835
840 : MipsABIInfo::N64());
841
842 // Architecture
843 if (Features[Mips::FeatureMips64r6])
844 EFlags |= ELF::EF_MIPS_ARCH_64R6;
845 else if (Features[Mips::FeatureMips64r2] ||
846 Features[Mips::FeatureMips64r3] ||
847 Features[Mips::FeatureMips64r5])
848 EFlags |= ELF::EF_MIPS_ARCH_64R2;
849 else if (Features[Mips::FeatureMips64])
850 EFlags |= ELF::EF_MIPS_ARCH_64;
851 else if (Features[Mips::FeatureMips5])
852 EFlags |= ELF::EF_MIPS_ARCH_5;
853 else if (Features[Mips::FeatureMips4])
854 EFlags |= ELF::EF_MIPS_ARCH_4;
855 else if (Features[Mips::FeatureMips3])
856 EFlags |= ELF::EF_MIPS_ARCH_3;
857 else if (Features[Mips::FeatureMips32r6])
858 EFlags |= ELF::EF_MIPS_ARCH_32R6;
859 else if (Features[Mips::FeatureMips32r2] ||
860 Features[Mips::FeatureMips32r3] ||
861 Features[Mips::FeatureMips32r5])
862 EFlags |= ELF::EF_MIPS_ARCH_32R2;
863 else if (Features[Mips::FeatureMips32])
864 EFlags |= ELF::EF_MIPS_ARCH_32;
865 else if (Features[Mips::FeatureMips2])
866 EFlags |= ELF::EF_MIPS_ARCH_2;
867 else
868 EFlags |= ELF::EF_MIPS_ARCH_1;
869
870 // Machine
871 if (Features[Mips::FeatureCnMips])
872 EFlags |= ELF::EF_MIPS_MACH_OCTEON;
873
874 // Other options.
875 if (Features[Mips::FeatureNaN2008])
876 EFlags |= ELF::EF_MIPS_NAN2008;
877
878 W.setELFHeaderEFlags(EFlags);
879}
880
882 auto *Symbol = cast<MCSymbolELF>(S);
884 uint8_t Type = Symbol->getType();
885 if (Type != ELF::STT_FUNC)
886 return;
887
888 if (isMicroMipsEnabled())
889 Symbol->setOther(ELF::STO_MIPS_MICROMIPS);
890}
891
895 const MCObjectFileInfo &OFI = *MCA.getContext().getObjectFileInfo();
897
898 // .bss, .text and .data are always at least 16-byte aligned.
899 MCSection &TextSection = *OFI.getTextSection();
900 S.switchSection(&TextSection);
901 MCSection &DataSection = *OFI.getDataSection();
902 S.switchSection(&DataSection);
903 MCSection &BSSSection = *OFI.getBSSSection();
904 S.switchSection(&BSSSection);
905
906 TextSection.ensureMinAlignment(Align(16));
907 DataSection.ensureMinAlignment(Align(16));
908 BSSSection.ensureMinAlignment(Align(16));
909
910 if (RoundSectionSizes) {
911 // Make sections sizes a multiple of the alignment. This is useful for
912 // verifying the output of IAS against the output of other assemblers but
913 // it's not necessary to produce a correct object and increases section
914 // size.
915 for (MCSection &Sec : MCA) {
916 MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
917
918 Align Alignment = Section.getAlign();
919 S.switchSection(&Section);
920 if (Section.useCodeAlign())
921 S.emitCodeAlignment(Alignment, &STI, Alignment.value());
922 else
923 S.emitValueToAlignment(Alignment, 0, 1, Alignment.value());
924 }
925 }
926
927 const FeatureBitset &Features = STI.getFeatureBits();
928
929 // Update e_header flags. See the FIXME and comment above in
930 // the constructor for a full rundown on this.
931 unsigned EFlags = W.getELFHeaderEFlags();
932
933 // ABI
934 // N64 does not require any ABI bits.
935 if (getABI().IsO32())
936 EFlags |= ELF::EF_MIPS_ABI_O32;
937 else if (getABI().IsN32())
938 EFlags |= ELF::EF_MIPS_ABI2;
939
940 if (Features[Mips::FeatureGP64Bit]) {
941 if (getABI().IsO32())
942 EFlags |= ELF::EF_MIPS_32BITMODE; /* Compatibility Mode */
943 } else if (Features[Mips::FeatureMips64r2] || Features[Mips::FeatureMips64])
944 EFlags |= ELF::EF_MIPS_32BITMODE;
945
946 // -mplt is not implemented but we should act as if it was
947 // given.
948 if (!Features[Mips::FeatureNoABICalls])
949 EFlags |= ELF::EF_MIPS_CPIC;
950
951 if (Pic)
953
954 W.setELFHeaderEFlags(EFlags);
955
956 // Emit all the option records.
957 // At the moment we are only emitting .Mips.options (ODK_REGINFO) and
958 // .reginfo.
959 MipsELFStreamer &MEF = static_cast<MipsELFStreamer &>(Streamer);
961
963}
964
966 auto *Symbol = cast<MCSymbolELF>(S);
967 // If on rhs is micromips symbol then mark Symbol as microMips.
968 if (Value->getKind() != MCExpr::SymbolRef)
969 return;
970 const auto &RhsSym = cast<MCSymbolELF>(
971 static_cast<const MCSymbolRefExpr *>(Value)->getSymbol());
972
973 if (!(RhsSym.getOther() & ELF::STO_MIPS_MICROMIPS))
974 return;
975
976 Symbol->setOther(ELF::STO_MIPS_MICROMIPS);
977}
978
980 return static_cast<MCELFStreamer &>(Streamer);
981}
982
984 MicroMipsEnabled = true;
986}
987
989 MicroMipsEnabled = false;
991}
992
995 unsigned Flags = W.getELFHeaderEFlags();
996 Flags |= ELF::EF_MIPS_MICROMIPS;
997 W.setELFHeaderEFlags(Flags);
998}
999
1002 unsigned Flags = W.getELFHeaderEFlags();
1004 W.setELFHeaderEFlags(Flags);
1006}
1007
1010 unsigned Flags = W.getELFHeaderEFlags();
1011 Flags |= ELF::EF_MIPS_NOREORDER;
1012 W.setELFHeaderEFlags(Flags);
1014}
1015
1018 MCContext &Context = MCA.getContext();
1020
1021 OS.pushSection();
1022 MCSectionELF *Sec = Context.getELFSection(".pdr", ELF::SHT_PROGBITS, 0);
1023 OS.switchSection(Sec);
1024 Sec->setAlignment(Align(4));
1025
1026 MCSymbol *Sym = Context.getOrCreateSymbol(Name);
1027 const MCSymbolRefExpr *ExprRef =
1029
1030 OS.emitValueImpl(ExprRef, 4);
1031
1032 OS.emitIntValue(GPRInfoSet ? GPRBitMask : 0, 4); // reg_mask
1033 OS.emitIntValue(GPRInfoSet ? GPROffset : 0, 4); // reg_offset
1034
1035 OS.emitIntValue(FPRInfoSet ? FPRBitMask : 0, 4); // fpreg_mask
1036 OS.emitIntValue(FPRInfoSet ? FPROffset : 0, 4); // fpreg_offset
1037
1038 OS.emitIntValue(FrameInfoSet ? FrameOffset : 0, 4); // frame_offset
1039 OS.emitIntValue(FrameInfoSet ? FrameReg : 0, 4); // frame_reg
1040 OS.emitIntValue(FrameInfoSet ? ReturnReg : 0, 4); // return_reg
1041
1042 // The .end directive marks the end of a procedure. Invalidate
1043 // the information gathered up until this point.
1045
1046 OS.popSection();
1047
1048 // .end also implicitly sets the size.
1049 MCSymbol *CurPCSym = Context.createTempSymbol();
1050 OS.emitLabel(CurPCSym);
1053 ExprRef, Context);
1054
1055 // The ELFObjectWriter can determine the absolute size as it has access to
1056 // the layout information of the assembly file, so a size expression rather
1057 // than an absolute value is ok here.
1058 static_cast<MCSymbolELF *>(Sym)->setSize(Size);
1059}
1060
1063
1064 // .ent also acts like an implicit '.type symbol, STT_FUNC'
1065 static_cast<const MCSymbolELF &>(Symbol).setType(ELF::STT_FUNC);
1066}
1067
1070 unsigned Flags = W.getELFHeaderEFlags();
1072 W.setELFHeaderEFlags(Flags);
1073}
1074
1077 unsigned Flags = W.getELFHeaderEFlags();
1078 Flags |= ELF::EF_MIPS_NAN2008;
1079 W.setELFHeaderEFlags(Flags);
1080}
1081
1084 unsigned Flags = W.getELFHeaderEFlags();
1085 Flags &= ~ELF::EF_MIPS_NAN2008;
1086 W.setELFHeaderEFlags(Flags);
1087}
1088
1091 unsigned Flags = W.getELFHeaderEFlags();
1092 // This option overrides other PIC options like -KPIC.
1093 Pic = false;
1094 Flags &= ~ELF::EF_MIPS_PIC;
1095 W.setELFHeaderEFlags(Flags);
1096}
1097
1100 unsigned Flags = W.getELFHeaderEFlags();
1101 Pic = true;
1102 // NOTE: We are following the GAS behaviour here which means the directive
1103 // 'pic2' also sets the CPIC bit in the ELF header. This is different from
1104 // what is stated in the SYSV ABI which consider the bits EF_MIPS_PIC and
1105 // EF_MIPS_CPIC to be mutually exclusive.
1107 W.setELFHeaderEFlags(Flags);
1108}
1109
1112 MipsELFStreamer &MEF = static_cast<MipsELFStreamer &>(Streamer);
1114}
1115
1116void MipsTargetELFStreamer::emitFrame(unsigned StackReg, unsigned StackSize,
1117 unsigned ReturnReg_) {
1119 const MCRegisterInfo *RegInfo = Context.getRegisterInfo();
1120
1121 FrameInfoSet = true;
1122 FrameReg = RegInfo->getEncodingValue(StackReg);
1123 FrameOffset = StackSize;
1124 ReturnReg = RegInfo->getEncodingValue(ReturnReg_);
1125}
1126
1127void MipsTargetELFStreamer::emitMask(unsigned CPUBitmask,
1128 int CPUTopSavedRegOff) {
1129 GPRInfoSet = true;
1130 GPRBitMask = CPUBitmask;
1131 GPROffset = CPUTopSavedRegOff;
1132}
1133
1134void MipsTargetELFStreamer::emitFMask(unsigned FPUBitmask,
1135 int FPUTopSavedRegOff) {
1136 FPRInfoSet = true;
1137 FPRBitMask = FPUBitmask;
1138 FPROffset = FPUTopSavedRegOff;
1139}
1140
1142 // .cpadd $reg
1143 // This directive inserts code to add $gp to the argument's register
1144 // when support for position independent code is enabled.
1145 if (!Pic)
1146 return;
1147
1148 emitAddu(RegNo, RegNo, GPReg, getABI().IsN64(), &STI);
1150}
1151
1153 // .cpload $reg
1154 // This directive expands to:
1155 // lui $gp, %hi(_gp_disp)
1156 // addui $gp, $gp, %lo(_gp_disp)
1157 // addu $gp, $gp, $reg
1158 // when support for position independent code is enabled.
1159 if (!Pic || (getABI().IsN32() || getABI().IsN64()))
1160 return;
1161
1162 // There's a GNU extension controlled by -mno-shared that allows
1163 // locally-binding symbols to be accessed using absolute addresses.
1164 // This is currently not supported. When supported -mno-shared makes
1165 // .cpload expand to:
1166 // lui $gp, %hi(__gnu_local_gp)
1167 // addiu $gp, $gp, %lo(__gnu_local_gp)
1168
1169 StringRef SymName("_gp_disp");
1171 MCSymbol *GP_Disp = MCA.getContext().getOrCreateSymbol(SymName);
1172 MCA.registerSymbol(*GP_Disp);
1173
1174 MCInst TmpInst;
1175 TmpInst.setOpcode(Mips::LUi);
1177 const MCExpr *HiSym = MipsMCExpr::create(
1180 MCA.getContext()),
1181 MCA.getContext());
1182 TmpInst.addOperand(MCOperand::createExpr(HiSym));
1183 getStreamer().emitInstruction(TmpInst, STI);
1184
1185 TmpInst.clear();
1186
1187 TmpInst.setOpcode(Mips::ADDiu);
1190 const MCExpr *LoSym = MipsMCExpr::create(
1193 MCA.getContext()),
1194 MCA.getContext());
1195 TmpInst.addOperand(MCOperand::createExpr(LoSym));
1196 getStreamer().emitInstruction(TmpInst, STI);
1197
1198 TmpInst.clear();
1199
1200 TmpInst.setOpcode(Mips::ADDu);
1203 TmpInst.addOperand(MCOperand::createReg(RegNo));
1204 getStreamer().emitInstruction(TmpInst, STI);
1205
1207}
1208
1210 if (Pic)
1212}
1213
1215 int Offset, function_ref<unsigned()> GetATReg, SMLoc IDLoc,
1216 const MCSubtargetInfo *STI) {
1218 // .cprestore offset
1219 // When PIC mode is enabled and the O32 ABI is used, this directive expands
1220 // to:
1221 // sw $gp, offset($sp)
1222 // and adds a corresponding LW after every JAL.
1223
1224 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
1225 // is used in non-PIC mode.
1226 if (!Pic || (getABI().IsN32() || getABI().IsN64()))
1227 return true;
1228
1229 // Store the $gp on the stack.
1230 emitStoreWithImmOffset(Mips::SW, GPReg, Mips::SP, Offset, GetATReg, IDLoc,
1231 STI);
1232 return true;
1233}
1234
1236 int RegOrOffset,
1237 const MCSymbol &Sym,
1238 bool IsReg) {
1239 // Only N32 and N64 emit anything for .cpsetup iff PIC is set.
1240 if (!Pic || !(getABI().IsN32() || getABI().IsN64()))
1241 return;
1242
1244
1246 MCInst Inst;
1247
1248 // Either store the old $gp in a register or on the stack
1249 if (IsReg) {
1250 // move $save, $gpreg
1251 emitRRR(Mips::OR64, RegOrOffset, GPReg, Mips::ZERO, SMLoc(), &STI);
1252 } else {
1253 // sd $gpreg, offset($sp)
1254 emitRRI(Mips::SD, GPReg, Mips::SP, RegOrOffset, SMLoc(), &STI);
1255 }
1256
1257 const MipsMCExpr *HiExpr = MipsMCExpr::createGpOff(
1259 MCA.getContext());
1260 const MipsMCExpr *LoExpr = MipsMCExpr::createGpOff(
1262 MCA.getContext());
1263
1264 // lui $gp, %hi(%neg(%gp_rel(funcSym)))
1265 emitRX(Mips::LUi, GPReg, MCOperand::createExpr(HiExpr), SMLoc(), &STI);
1266
1267 // addiu $gp, $gp, %lo(%neg(%gp_rel(funcSym)))
1268 emitRRX(Mips::ADDiu, GPReg, GPReg, MCOperand::createExpr(LoExpr), SMLoc(),
1269 &STI);
1270
1271 // (d)addu $gp, $gp, $funcreg
1272 if (getABI().IsN32())
1273 emitRRR(Mips::ADDu, GPReg, GPReg, RegNo, SMLoc(), &STI);
1274 else
1275 emitRRR(Mips::DADDu, GPReg, GPReg, RegNo, SMLoc(), &STI);
1276}
1277
1279 bool SaveLocationIsRegister) {
1280 // Only N32 and N64 emit anything for .cpreturn iff PIC is set.
1281 if (!Pic || !(getABI().IsN32() || getABI().IsN64()))
1282 return;
1283
1284 MCInst Inst;
1285 // Either restore the old $gp from a register or on the stack
1286 if (SaveLocationIsRegister) {
1287 Inst.setOpcode(Mips::OR);
1289 Inst.addOperand(MCOperand::createReg(SaveLocation));
1290 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
1291 } else {
1292 Inst.setOpcode(Mips::LD);
1294 Inst.addOperand(MCOperand::createReg(Mips::SP));
1295 Inst.addOperand(MCOperand::createImm(SaveLocation));
1296 }
1297 getStreamer().emitInstruction(Inst, STI);
1298
1300}
1301
1304 MCContext &Context = MCA.getContext();
1306 MCSectionELF *Sec = Context.getELFSection(
1307 ".MIPS.abiflags", ELF::SHT_MIPS_ABIFLAGS, ELF::SHF_ALLOC, 24);
1308 OS.switchSection(Sec);
1309 Sec->setAlignment(Align(8));
1310
1312}
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:147
void ensureMinAlignment(Align MinAlignment)
Makes sure that Alignment is at least MinAlignment.
Definition: MCSection.h:150
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: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:591
@ 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:1089
@ SHT_MIPS_ABIFLAGS
Definition: ELF.h:1165
@ SHF_ALLOC
Definition: ELF.h:1186
@ STT_FUNC
Definition: ELF.h:1353
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)