LLVM 22.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"
16#include "MipsBaseInfo.h"
17#include "MipsELFStreamer.h"
18#include "MipsInstPrinter.h"
19#include "MipsMCTargetDesc.h"
21#include "llvm/MC/MCAsmInfo.h"
22#include "llvm/MC/MCAssembler.h"
23#include "llvm/MC/MCContext.h"
28#include "llvm/MC/MCSymbolELF.h"
32
33using namespace llvm;
34
35namespace {
36static cl::opt<bool> RoundSectionSizes(
37 "mips-round-section-sizes", cl::init(false),
38 cl::desc("Round section sizes up to the section alignment"), cl::Hidden);
39} // end anonymous namespace
40
41static bool isMicroMips(const MCSubtargetInfo *STI) {
42 return STI->hasFeature(Mips::FeatureMicroMips);
43}
44
45static bool isMips32r6(const MCSubtargetInfo *STI) {
46 return STI->hasFeature(Mips::FeatureMips32r6);
47}
48
50 : MCTargetStreamer(S), GPReg(Mips::GP), ModuleDirectiveAllowed(true) {
52}
53
82}
92void MipsTargetStreamer::emitFrame(MCRegister StackReg, unsigned StackSize,
93 MCRegister ReturnReg) {}
94void MipsTargetStreamer::emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) {}
95void MipsTargetStreamer::emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) {
96}
99}
120}
123}
132 // .cplocal $reg
133 // This directive forces to use the alternate register for context pointer.
134 // For example
135 // .cplocal $4
136 // jal foo
137 // expands to
138 // ld $25, %call16(foo)($4)
139 // jalr $25
140
141 if (!getABI().IsN32() && !getABI().IsN64())
142 return;
143
144 GPReg = RegNo;
145
147}
149 int Offset, function_ref<unsigned()> GetATReg, SMLoc IDLoc,
150 const MCSubtargetInfo *STI) {
152 return true;
153}
154void MipsTargetStreamer::emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
155 const MCSymbol &Sym, bool IsReg) {
156}
158 bool SaveLocationIsRegister) {}
159
161
164 report_fatal_error("+nooddspreg is only valid for O32");
165}
178}
182}
183
184void MipsTargetStreamer::emitR(unsigned Opcode, MCRegister Reg0, SMLoc IDLoc,
185 const MCSubtargetInfo *STI) {
186 MCInst TmpInst;
187 TmpInst.setOpcode(Opcode);
188 TmpInst.addOperand(MCOperand::createReg(Reg0));
189 TmpInst.setLoc(IDLoc);
190 getStreamer().emitInstruction(TmpInst, *STI);
191}
192
193void MipsTargetStreamer::emitRX(unsigned Opcode, MCRegister Reg0, MCOperand Op1,
194 SMLoc IDLoc, const MCSubtargetInfo *STI) {
195 MCInst TmpInst;
196 TmpInst.setOpcode(Opcode);
197 TmpInst.addOperand(MCOperand::createReg(Reg0));
198 TmpInst.addOperand(Op1);
199 TmpInst.setLoc(IDLoc);
200 getStreamer().emitInstruction(TmpInst, *STI);
201}
202
203void MipsTargetStreamer::emitRI(unsigned Opcode, MCRegister Reg0, int32_t Imm,
204 SMLoc IDLoc, const MCSubtargetInfo *STI) {
205 emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, STI);
206}
207
208void MipsTargetStreamer::emitRR(unsigned Opcode, MCRegister Reg0,
209 MCRegister Reg1, SMLoc IDLoc,
210 const MCSubtargetInfo *STI) {
211 emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, STI);
212}
213
214void MipsTargetStreamer::emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2,
215 SMLoc IDLoc, const MCSubtargetInfo *STI) {
216 MCInst TmpInst;
217 TmpInst.setOpcode(Opcode);
218 TmpInst.addOperand(MCOperand::createImm(Imm1));
219 TmpInst.addOperand(MCOperand::createImm(Imm2));
220 TmpInst.setLoc(IDLoc);
221 getStreamer().emitInstruction(TmpInst, *STI);
222}
223
224void MipsTargetStreamer::emitRRX(unsigned Opcode, MCRegister Reg0,
225 MCRegister Reg1, MCOperand Op2, SMLoc IDLoc,
226 const MCSubtargetInfo *STI) {
227 MCInst TmpInst;
228 TmpInst.setOpcode(Opcode);
229 TmpInst.addOperand(MCOperand::createReg(Reg0));
230 TmpInst.addOperand(MCOperand::createReg(Reg1));
231 TmpInst.addOperand(Op2);
232 TmpInst.setLoc(IDLoc);
233 getStreamer().emitInstruction(TmpInst, *STI);
234}
235
236void MipsTargetStreamer::emitRRR(unsigned Opcode, MCRegister Reg0,
237 MCRegister Reg1, MCRegister Reg2, SMLoc IDLoc,
238 const MCSubtargetInfo *STI) {
239 emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc, STI);
240}
241
242void MipsTargetStreamer::emitRRRX(unsigned Opcode, MCRegister Reg0,
243 MCRegister Reg1, MCRegister Reg2,
244 MCOperand Op3, SMLoc IDLoc,
245 const MCSubtargetInfo *STI) {
246 MCInst TmpInst;
247 TmpInst.setOpcode(Opcode);
248 TmpInst.addOperand(MCOperand::createReg(Reg0));
249 TmpInst.addOperand(MCOperand::createReg(Reg1));
250 TmpInst.addOperand(MCOperand::createReg(Reg2));
251 TmpInst.addOperand(Op3);
252 TmpInst.setLoc(IDLoc);
253 getStreamer().emitInstruction(TmpInst, *STI);
254}
255
256void MipsTargetStreamer::emitRRI(unsigned Opcode, MCRegister Reg0,
257 MCRegister Reg1, int16_t Imm, SMLoc IDLoc,
258 const MCSubtargetInfo *STI) {
259 emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc, STI);
260}
261
262void MipsTargetStreamer::emitRRIII(unsigned Opcode, MCRegister Reg0,
263 MCRegister Reg1, int16_t Imm0, int16_t Imm1,
264 int16_t Imm2, SMLoc IDLoc,
265 const MCSubtargetInfo *STI) {
266 MCInst TmpInst;
267 TmpInst.setOpcode(Opcode);
268 TmpInst.addOperand(MCOperand::createReg(Reg0));
269 TmpInst.addOperand(MCOperand::createReg(Reg1));
270 TmpInst.addOperand(MCOperand::createImm(Imm0));
271 TmpInst.addOperand(MCOperand::createImm(Imm1));
272 TmpInst.addOperand(MCOperand::createImm(Imm2));
273 TmpInst.setLoc(IDLoc);
274 getStreamer().emitInstruction(TmpInst, *STI);
275}
276
278 MCRegister TrgReg, bool Is64Bit,
279 const MCSubtargetInfo *STI) {
280 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
281 STI);
282}
283
285 int16_t ShiftAmount, SMLoc IDLoc,
286 const MCSubtargetInfo *STI) {
287 if (ShiftAmount >= 32) {
288 emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc, STI);
289 return;
290 }
291
292 emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, STI);
293}
294
296 const MCSubtargetInfo *STI) {
297 // The default case of `nop` is `sll $zero, $zero, 0`.
298 unsigned Opc = Mips::SLL;
299 if (isMicroMips(STI) && hasShortDelaySlot) {
300 Opc = isMips32r6(STI) ? Mips::MOVE16_MMR6 : Mips::MOVE16_MM;
301 emitRR(Opc, Mips::ZERO, Mips::ZERO, IDLoc, STI);
302 return;
303 }
304
305 if (isMicroMips(STI))
306 Opc = isMips32r6(STI) ? Mips::SLL_MMR6 : Mips::SLL_MM;
307
308 emitRRI(Opc, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
309}
310
312 if (isMicroMips(STI))
313 emitRR(Mips::MOVE16_MM, Mips::ZERO, Mips::ZERO, IDLoc, STI);
314 else
315 emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
316}
317
318/// Emit the $gp restore operation for .cprestore.
320 const MCSubtargetInfo *STI) {
321 emitLoadWithImmOffset(Mips::LW, GPReg, Mips::SP, Offset, GPReg, IDLoc, STI);
322}
323
324/// Emit a store instruction with an immediate offset.
326 unsigned Opcode, MCRegister SrcReg, MCRegister BaseReg, int64_t Offset,
327 function_ref<unsigned()> GetATReg, SMLoc IDLoc,
328 const MCSubtargetInfo *STI) {
329 if (isInt<16>(Offset)) {
330 emitRRI(Opcode, SrcReg, BaseReg, Offset, IDLoc, STI);
331 return;
332 }
333
334 // sw $8, offset($8) => lui $at, %hi(offset)
335 // add $at, $at, $8
336 // sw $8, %lo(offset)($at)
337
338 MCRegister ATReg = GetATReg();
339 if (!ATReg)
340 return;
341
342 unsigned LoOffset = Offset & 0x0000ffff;
343 unsigned HiOffset = (Offset & 0xffff0000) >> 16;
344
345 // If msb of LoOffset is 1(negative number) we must increment HiOffset
346 // to account for the sign-extension of the low part.
347 if (LoOffset & 0x8000)
348 HiOffset++;
349
350 // Generate the base address in ATReg.
351 emitRI(Mips::LUi, ATReg, HiOffset, IDLoc, STI);
352 if (BaseReg != Mips::ZERO)
353 emitRRR(Mips::ADDu, ATReg, ATReg, BaseReg, IDLoc, STI);
354 // Emit the store with the adjusted base and offset.
355 emitRRI(Opcode, SrcReg, ATReg, LoOffset, IDLoc, STI);
356}
357
358/// Emit a load instruction with an immediate offset. DstReg and TmpReg are
359/// permitted to be the same register iff DstReg is distinct from BaseReg and
360/// DstReg is a GPR. It is the callers responsibility to identify such cases
361/// and pass the appropriate register in TmpReg.
363 unsigned Opcode, MCRegister DstReg, MCRegister BaseReg, int64_t Offset,
364 MCRegister TmpReg, SMLoc IDLoc, const MCSubtargetInfo *STI) {
365 if (isInt<16>(Offset)) {
366 emitRRI(Opcode, DstReg, BaseReg, Offset, IDLoc, STI);
367 return;
368 }
369
370 // 1) lw $8, offset($9) => lui $8, %hi(offset)
371 // add $8, $8, $9
372 // lw $8, %lo(offset)($9)
373 // 2) lw $8, offset($8) => lui $at, %hi(offset)
374 // add $at, $at, $8
375 // lw $8, %lo(offset)($at)
376
377 unsigned LoOffset = Offset & 0x0000ffff;
378 unsigned HiOffset = (Offset & 0xffff0000) >> 16;
379
380 // If msb of LoOffset is 1(negative number) we must increment HiOffset
381 // to account for the sign-extension of the low part.
382 if (LoOffset & 0x8000)
383 HiOffset++;
384
385 // Generate the base address in TmpReg.
386 emitRI(Mips::LUi, TmpReg, HiOffset, IDLoc, STI);
387 if (BaseReg != Mips::ZERO)
388 emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
389 // Emit the load with the adjusted base and offset.
390 emitRRI(Opcode, DstReg, TmpReg, LoOffset, IDLoc, STI);
391}
392
395 : MipsTargetStreamer(S), OS(OS) {}
396
398 auto *MAI = getStreamer().getContext().getAsmInfo();
399 OS << "\t.dtprelword\t";
400 MAI->printExpr(OS, *Value);
401 OS << '\n';
402}
403
405 auto *MAI = getStreamer().getContext().getAsmInfo();
406 OS << "\t.dtpreldword\t";
407 MAI->printExpr(OS, *Value);
408 OS << '\n';
409}
410
412 auto *MAI = getStreamer().getContext().getAsmInfo();
413 OS << "\t.tprelword\t";
414 MAI->printExpr(OS, *Value);
415 OS << '\n';
416}
417
419 auto *MAI = getStreamer().getContext().getAsmInfo();
420 OS << "\t.tpreldword\t";
421 MAI->printExpr(OS, *Value);
422 OS << '\n';
423}
424
426 auto *MAI = getStreamer().getContext().getAsmInfo();
427 OS << "\t.gpword\t";
428 MAI->printExpr(OS, *Value);
429 OS << '\n';
430}
431
433 auto *MAI = getStreamer().getContext().getAsmInfo();
434 OS << "\t.gpdword\t";
435 MAI->printExpr(OS, *Value);
436 OS << '\n';
437}
438
440 OS << "\t.set\tmicromips\n";
442}
443
445 OS << "\t.set\tnomicromips\n";
447}
448
450 OS << "\t.set\tmips16\n";
452}
453
455 OS << "\t.set\tnomips16\n";
457}
458
460 OS << "\t.set\treorder\n";
462}
463
465 OS << "\t.set\tnoreorder\n";
467}
468
470 OS << "\t.set\tmacro\n";
472}
473
475 OS << "\t.set\tnomacro\n";
477}
478
480 OS << "\t.set\tmsa\n";
482}
483
485 OS << "\t.set\tnomsa\n";
487}
488
490 OS << "\t.set\tmt\n";
492}
493
495 OS << "\t.set\tnomt\n";
497}
498
500 OS << "\t.set\tcrc\n";
502}
503
505 OS << "\t.set\tnocrc\n";
507}
508
510 OS << "\t.set\tvirt\n";
512}
513
515 OS << "\t.set\tnovirt\n";
517}
518
520 OS << "\t.set\tginv\n";
522}
523
525 OS << "\t.set\tnoginv\n";
527}
528
530 OS << "\t.set\tat\n";
532}
533
535 OS << "\t.set\tat=$" << Twine(RegNo) << "\n";
537}
538
540 OS << "\t.set\tnoat\n";
542}
543
545 OS << "\t.end\t" << Name << '\n';
546}
547
549 OS << "\t.ent\t" << Symbol.getName() << '\n';
550}
551
552void MipsTargetAsmStreamer::emitDirectiveAbiCalls() { OS << "\t.abicalls\n"; }
553
554void MipsTargetAsmStreamer::emitDirectiveNaN2008() { OS << "\t.nan\t2008\n"; }
555
557 OS << "\t.nan\tlegacy\n";
558}
559
561 OS << "\t.option\tpic0\n";
562}
563
565 OS << "\t.option\tpic2\n";
566}
567
570 OS << "\t.insn\n";
571}
572
573void MipsTargetAsmStreamer::emitFrame(MCRegister StackReg, unsigned StackSize,
574 MCRegister ReturnReg) {
575 OS << "\t.frame\t$"
577 << StackSize << ",$"
579}
580
582 OS << "\t.set arch=" << Arch << "\n";
584}
585
587 OS << "\t.set\tmips0\n";
589}
590
592 OS << "\t.set\tmips1\n";
594}
595
597 OS << "\t.set\tmips2\n";
599}
600
602 OS << "\t.set\tmips3\n";
604}
605
607 OS << "\t.set\tmips4\n";
609}
610
612 OS << "\t.set\tmips5\n";
614}
615
617 OS << "\t.set\tmips32\n";
619}
620
622 OS << "\t.set\tmips32r2\n";
624}
625
627 OS << "\t.set\tmips32r3\n";
629}
630
632 OS << "\t.set\tmips32r5\n";
634}
635
637 OS << "\t.set\tmips32r6\n";
639}
640
642 OS << "\t.set\tmips64\n";
644}
645
647 OS << "\t.set\tmips64r2\n";
649}
650
652 OS << "\t.set\tmips64r3\n";
654}
655
657 OS << "\t.set\tmips64r5\n";
659}
660
662 OS << "\t.set\tmips64r6\n";
664}
665
667 OS << "\t.set\tdsp\n";
669}
670
672 OS << "\t.set\tdspr2\n";
674}
675
677 OS << "\t.set\tnodsp\n";
679}
680
682 OS << "\t.set\tmips3d\n";
684}
685
687 OS << "\t.set\tnomips3d\n";
689}
690
692 OS << "\t.set\tpop\n";
694}
695
697 OS << "\t.set\tpush\n";
699}
700
702 OS << "\t.set\tsoftfloat\n";
704}
705
707 OS << "\t.set\thardfloat\n";
709}
710
711// Print a 32 bit hex number with all numbers.
712static void printHex32(unsigned Value, raw_ostream &OS) {
713 OS << "0x";
714 for (int i = 7; i >= 0; i--)
715 OS.write_hex((Value & (0xF << (i * 4))) >> (i * 4));
716}
717
718void MipsTargetAsmStreamer::emitMask(unsigned CPUBitmask,
719 int CPUTopSavedRegOff) {
720 OS << "\t.mask \t";
721 printHex32(CPUBitmask, OS);
722 OS << ',' << CPUTopSavedRegOff << '\n';
723}
724
725void MipsTargetAsmStreamer::emitFMask(unsigned FPUBitmask,
726 int FPUTopSavedRegOff) {
727 OS << "\t.fmask\t";
728 printHex32(FPUBitmask, OS);
729 OS << "," << FPUTopSavedRegOff << '\n';
730}
731
733 OS << "\t.cpadd\t$"
736}
737
739 OS << "\t.cpload\t$"
742}
743
745 OS << "\t.cplocal\t$"
748}
749
751 int Offset, function_ref<unsigned()> GetATReg, SMLoc IDLoc,
752 const MCSubtargetInfo *STI) {
754 OS << "\t.cprestore\t" << Offset << "\n";
755 return true;
756}
757
759 int RegOrOffset,
760 const MCSymbol &Sym,
761 bool IsReg) {
762 OS << "\t.cpsetup\t$"
764
765 if (IsReg)
766 OS << "$"
768 else
769 OS << RegOrOffset;
770
771 OS << ", ";
772
773 OS << Sym.getName();
775}
776
778 bool SaveLocationIsRegister) {
779 OS << "\t.cpreturn";
781}
782
786 OS << "\t.module\tsoftfloat\n";
787 else
788 OS << "\t.module\tfp=" << ABIFlagsSection.getFpABIString(FpABI) << "\n";
789}
790
794
795 OS << "\t.set\tfp=";
796 OS << ABIFlagsSection.getFpABIString(Value) << "\n";
797}
798
801
802 OS << "\t.module\t" << (ABIFlagsSection.OddSPReg ? "" : "no") << "oddspreg\n";
803}
804
807 OS << "\t.set\toddspreg\n";
808}
809
812 OS << "\t.set\tnooddspreg\n";
813}
814
816 OS << "\t.module\tsoftfloat\n";
817}
818
820 OS << "\t.module\thardfloat\n";
821}
822
824 OS << "\t.module\tmt\n";
825}
826
828 OS << "\t.module\tcrc\n";
829}
830
832 OS << "\t.module\tnocrc\n";
833}
834
836 OS << "\t.module\tvirt\n";
837}
838
840 OS << "\t.module\tnovirt\n";
841}
842
844 OS << "\t.module\tginv\n";
845}
846
848 OS << "\t.module\tnoginv\n";
849}
850
851// This part is for ELF object output.
853 const MCSubtargetInfo &STI)
854 : MipsTargetStreamer(S), MicroMipsEnabled(false), STI(STI) {
857
858 // It's possible that MCObjectFileInfo isn't fully initialized at this point
859 // due to an initialization order problem where CodeGenTargetMachineImpl
860 // creates the target streamer before TargetLoweringObjectFile calls
861 // InitializeMCObjectFileInfo. There doesn't seem to be a single place that
862 // covers all cases so this statement covers most cases and direct object
863 // emission must call setPic() once MCObjectFileInfo has been initialized. The
864 // cases we don't handle here are covered by MipsAsmPrinter.
866
867 const FeatureBitset &Features = STI.getFeatureBits();
868
869 // Set the header flags that we can in the constructor.
870 // FIXME: This is a fairly terrible hack. We set the rest
871 // of these in the destructor. The problem here is two-fold:
872 //
873 // a: Some of the eflags can be set/reset by directives.
874 // b: There aren't any usage paths that initialize the ABI
875 // pointer until after we initialize either an assembler
876 // or the target machine.
877 // We can fix this by making the target streamer construct
878 // the ABI, but this is fraught with wide ranging dependency
879 // issues as well.
880 unsigned EFlags = W.getELFHeaderEFlags();
881
882 // FIXME: Fix a dependency issue by instantiating the ABI object to some
883 // default based off the triple. The triple doesn't describe the target
884 // fully, but any external user of the API that uses the MCTargetStreamer
885 // would otherwise crash on assertion failure.
886
891 : MipsABIInfo::N64());
892
893 // Architecture
894 if (Features[Mips::FeatureMips64r6])
895 EFlags |= ELF::EF_MIPS_ARCH_64R6;
896 else if (Features[Mips::FeatureMips64r2] ||
897 Features[Mips::FeatureMips64r3] ||
898 Features[Mips::FeatureMips64r5])
899 EFlags |= ELF::EF_MIPS_ARCH_64R2;
900 else if (Features[Mips::FeatureMips64])
901 EFlags |= ELF::EF_MIPS_ARCH_64;
902 else if (Features[Mips::FeatureMips5])
903 EFlags |= ELF::EF_MIPS_ARCH_5;
904 else if (Features[Mips::FeatureMips4])
905 EFlags |= ELF::EF_MIPS_ARCH_4;
906 else if (Features[Mips::FeatureMips3])
907 EFlags |= ELF::EF_MIPS_ARCH_3;
908 else if (Features[Mips::FeatureMips32r6])
909 EFlags |= ELF::EF_MIPS_ARCH_32R6;
910 else if (Features[Mips::FeatureMips32r2] ||
911 Features[Mips::FeatureMips32r3] ||
912 Features[Mips::FeatureMips32r5])
913 EFlags |= ELF::EF_MIPS_ARCH_32R2;
914 else if (Features[Mips::FeatureMips32])
915 EFlags |= ELF::EF_MIPS_ARCH_32;
916 else if (Features[Mips::FeatureMips2])
917 EFlags |= ELF::EF_MIPS_ARCH_2;
918 else
919 EFlags |= ELF::EF_MIPS_ARCH_1;
920
921 // Machine
922 if (Features[Mips::FeatureCnMips])
923 EFlags |= ELF::EF_MIPS_MACH_OCTEON;
924
925 // Other options.
926 if (Features[Mips::FeatureNaN2008])
927 EFlags |= ELF::EF_MIPS_NAN2008;
928
929 W.setELFHeaderEFlags(EFlags);
930}
931
933 auto *Symbol = static_cast<MCSymbolELF *>(S);
935 uint8_t Type = Symbol->getType();
936 if (Type != ELF::STT_FUNC)
937 return;
938
939 if (isMicroMipsEnabled())
940 Symbol->setOther(ELF::STO_MIPS_MICROMIPS);
941}
942
946 const MCObjectFileInfo &OFI = *MCA.getContext().getObjectFileInfo();
948
949 // .bss, .text and .data are always at least 16-byte aligned.
950 MCSection &TextSection = *OFI.getTextSection();
951 S.switchSection(&TextSection);
952 MCSection &DataSection = *OFI.getDataSection();
953 S.switchSection(&DataSection);
954 MCSection &BSSSection = *OFI.getBSSSection();
955 S.switchSection(&BSSSection);
956
957 TextSection.ensureMinAlignment(Align(16));
958 DataSection.ensureMinAlignment(Align(16));
959 BSSSection.ensureMinAlignment(Align(16));
960
961 if (RoundSectionSizes) {
962 // Make sections sizes a multiple of the alignment. This is useful for
963 // verifying the output of IAS against the output of other assemblers but
964 // it's not necessary to produce a correct object and increases section
965 // size.
966 for (MCSection &Sec : MCA) {
967 MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
968
969 Align Alignment = Section.getAlign();
970 S.switchSection(&Section);
971 if (getContext().getAsmInfo()->useCodeAlign(Section))
972 S.emitCodeAlignment(Alignment, &STI, Alignment.value());
973 else
974 S.emitValueToAlignment(Alignment, 0, 1, Alignment.value());
975 }
976 }
977
978 const FeatureBitset &Features = STI.getFeatureBits();
979
980 // Update e_header flags. See the FIXME and comment above in
981 // the constructor for a full rundown on this.
982 unsigned EFlags = W.getELFHeaderEFlags();
983
984 // ABI
985 // N64 does not require any ABI bits.
986 if (getABI().IsO32())
987 EFlags |= ELF::EF_MIPS_ABI_O32;
988 else if (getABI().IsN32())
989 EFlags |= ELF::EF_MIPS_ABI2;
990
991 if (Features[Mips::FeatureGP64Bit]) {
992 if (getABI().IsO32())
993 EFlags |= ELF::EF_MIPS_32BITMODE; /* Compatibility Mode */
994 } else if (Features[Mips::FeatureMips64r2] || Features[Mips::FeatureMips64])
995 EFlags |= ELF::EF_MIPS_32BITMODE;
996
997 // -mplt is not implemented but we should act as if it was
998 // given.
999 if (!Features[Mips::FeatureNoABICalls])
1000 EFlags |= ELF::EF_MIPS_CPIC;
1001
1002 if (Pic)
1004
1005 W.setELFHeaderEFlags(EFlags);
1006
1007 // Emit all the option records.
1008 // At the moment we are only emitting .Mips.options (ODK_REGINFO) and
1009 // .reginfo.
1010 MipsELFStreamer &MEF = static_cast<MipsELFStreamer &>(Streamer);
1012
1014}
1015
1017 auto *Symbol = static_cast<MCSymbolELF *>(S);
1018 // If on rhs is micromips symbol then mark Symbol as microMips.
1019 if (Value->getKind() != MCExpr::SymbolRef)
1020 return;
1021 auto &RhsSym = static_cast<const MCSymbolELF &>(
1022 static_cast<const MCSymbolRefExpr *>(Value)->getSymbol());
1023
1024 if (!(RhsSym.getOther() & ELF::STO_MIPS_MICROMIPS))
1025 return;
1026
1027 Symbol->setOther(ELF::STO_MIPS_MICROMIPS);
1028}
1029
1031 return static_cast<MCELFStreamer &>(Streamer);
1032}
1033
1035 auto &S = getStreamer();
1036 S.ensureHeadroom(4);
1037 S.addFixup(Value, Mips::fixup_Mips_GPREL32);
1038 S.appendContents(4, 0);
1039}
1040
1042 auto &S = getStreamer();
1043 S.ensureHeadroom(8);
1044 // fixup_Mips_GPREL32 desginates R_MIPS_GPREL32+R_MIPS_64 on MIPS64.
1045 S.addFixup(Value, Mips::fixup_Mips_GPREL32);
1046 S.appendContents(8, 0);
1047}
1048
1050 auto &S = getStreamer();
1051 S.ensureHeadroom(4);
1052 S.addFixup(Value, Mips::fixup_Mips_DTPREL32);
1053 S.appendContents(4, 0);
1054}
1055
1057 auto &S = getStreamer();
1058 S.ensureHeadroom(8);
1059 S.addFixup(Value, Mips::fixup_Mips_DTPREL64);
1060 S.appendContents(8, 0);
1061}
1062
1064 auto &S = getStreamer();
1065 S.ensureHeadroom(4);
1066 S.addFixup(Value, Mips::fixup_Mips_TPREL32);
1067 S.appendContents(4, 0);
1068}
1069
1071 auto &S = getStreamer();
1072 S.ensureHeadroom(8);
1073 S.addFixup(Value, Mips::fixup_Mips_TPREL64);
1074 S.appendContents(8, 0);
1075}
1076
1078 MicroMipsEnabled = true;
1080}
1081
1083 MicroMipsEnabled = false;
1085}
1086
1089 unsigned Flags = W.getELFHeaderEFlags();
1090 Flags |= ELF::EF_MIPS_MICROMIPS;
1091 W.setELFHeaderEFlags(Flags);
1092}
1093
1096 unsigned Flags = W.getELFHeaderEFlags();
1098 W.setELFHeaderEFlags(Flags);
1100}
1101
1104 unsigned Flags = W.getELFHeaderEFlags();
1105 Flags |= ELF::EF_MIPS_NOREORDER;
1106 W.setELFHeaderEFlags(Flags);
1108}
1109
1112 MCContext &Context = MCA.getContext();
1114
1115 OS.pushSection();
1116 MCSectionELF *Sec = Context.getELFSection(".pdr", ELF::SHT_PROGBITS, 0);
1117 OS.switchSection(Sec);
1118 Sec->setAlignment(Align(4));
1119
1120 MCSymbol *Sym = Context.getOrCreateSymbol(Name);
1121 const auto *ExprRef = MCSymbolRefExpr::create(Sym, Context);
1122 OS.emitValueImpl(ExprRef, 4);
1123
1124 OS.emitIntValue(GPRInfoSet ? GPRBitMask : 0, 4); // reg_mask
1125 OS.emitIntValue(GPRInfoSet ? GPROffset : 0, 4); // reg_offset
1126
1127 OS.emitIntValue(FPRInfoSet ? FPRBitMask : 0, 4); // fpreg_mask
1128 OS.emitIntValue(FPRInfoSet ? FPROffset : 0, 4); // fpreg_offset
1129
1130 OS.emitIntValue(FrameInfoSet ? FrameOffset : 0, 4); // frame_offset
1131 OS.emitIntValue(FrameInfoSet ? FrameReg : 0, 4); // frame_reg
1132 OS.emitIntValue(FrameInfoSet ? ReturnReg : 0, 4); // return_reg
1133
1134 // The .end directive marks the end of a procedure. Invalidate
1135 // the information gathered up until this point.
1137
1138 OS.popSection();
1139
1140 // .end also implicitly sets the size.
1141 MCSymbol *CurPCSym = Context.createTempSymbol();
1142 OS.emitLabel(CurPCSym);
1144 MCSymbolRefExpr::create(CurPCSym, Context), ExprRef, Context);
1145
1146 // The ELFObjectWriter can determine the absolute size as it has access to
1147 // the layout information of the assembly file, so a size expression rather
1148 // than an absolute value is ok here.
1149 static_cast<MCSymbolELF *>(Sym)->setSize(Size);
1150}
1151
1154
1155 // .ent also acts like an implicit '.type symbol, STT_FUNC'
1156 static_cast<const MCSymbolELF &>(Symbol).setType(ELF::STT_FUNC);
1157}
1158
1161 unsigned Flags = W.getELFHeaderEFlags();
1163 W.setELFHeaderEFlags(Flags);
1164}
1165
1168 unsigned Flags = W.getELFHeaderEFlags();
1169 Flags |= ELF::EF_MIPS_NAN2008;
1170 W.setELFHeaderEFlags(Flags);
1171}
1172
1175 unsigned Flags = W.getELFHeaderEFlags();
1176 Flags &= ~ELF::EF_MIPS_NAN2008;
1177 W.setELFHeaderEFlags(Flags);
1178}
1179
1182 unsigned Flags = W.getELFHeaderEFlags();
1183 // This option overrides other PIC options like -KPIC.
1184 Pic = false;
1185 Flags &= ~ELF::EF_MIPS_PIC;
1186 W.setELFHeaderEFlags(Flags);
1187}
1188
1191 unsigned Flags = W.getELFHeaderEFlags();
1192 Pic = true;
1193 // NOTE: We are following the GAS behaviour here which means the directive
1194 // 'pic2' also sets the CPIC bit in the ELF header. This is different from
1195 // what is stated in the SYSV ABI which consider the bits EF_MIPS_PIC and
1196 // EF_MIPS_CPIC to be mutually exclusive.
1198 W.setELFHeaderEFlags(Flags);
1199}
1200
1203 MipsELFStreamer &MEF = static_cast<MipsELFStreamer &>(Streamer);
1205}
1206
1207void MipsTargetELFStreamer::emitFrame(MCRegister StackReg, unsigned StackSize,
1208 MCRegister ReturnReg_) {
1210 const MCRegisterInfo *RegInfo = Context.getRegisterInfo();
1211
1212 FrameInfoSet = true;
1213 FrameReg = RegInfo->getEncodingValue(StackReg);
1214 FrameOffset = StackSize;
1215 ReturnReg = RegInfo->getEncodingValue(ReturnReg_);
1216}
1217
1218void MipsTargetELFStreamer::emitMask(unsigned CPUBitmask,
1219 int CPUTopSavedRegOff) {
1220 GPRInfoSet = true;
1221 GPRBitMask = CPUBitmask;
1222 GPROffset = CPUTopSavedRegOff;
1223}
1224
1225void MipsTargetELFStreamer::emitFMask(unsigned FPUBitmask,
1226 int FPUTopSavedRegOff) {
1227 FPRInfoSet = true;
1228 FPRBitMask = FPUBitmask;
1229 FPROffset = FPUTopSavedRegOff;
1230}
1231
1233 // .cpadd $reg
1234 // This directive inserts code to add $gp to the argument's register
1235 // when support for position independent code is enabled.
1236 if (!Pic)
1237 return;
1238
1239 emitAddu(RegNo, RegNo, GPReg, getABI().IsN64(), &STI);
1241}
1242
1244 // .cpload $reg
1245 // This directive expands to:
1246 // lui $gp, %hi(_gp_disp)
1247 // addui $gp, $gp, %lo(_gp_disp)
1248 // addu $gp, $gp, $reg
1249 // when support for position independent code is enabled.
1250 if (!Pic || (getABI().IsN32() || getABI().IsN64()))
1251 return;
1252
1253 // There's a GNU extension controlled by -mno-shared that allows
1254 // locally-binding symbols to be accessed using absolute addresses.
1255 // This is currently not supported. When supported -mno-shared makes
1256 // .cpload expand to:
1257 // lui $gp, %hi(__gnu_local_gp)
1258 // addiu $gp, $gp, %lo(__gnu_local_gp)
1259
1260 StringRef SymName("_gp_disp");
1262 MCSymbol *GP_Disp = MCA.getContext().getOrCreateSymbol(SymName);
1263 MCA.registerSymbol(*GP_Disp);
1264
1265 MCInst TmpInst;
1266 TmpInst.setOpcode(Mips::LUi);
1268 auto *HiSym = MCSpecifierExpr::create(GP_Disp, Mips::S_HI, MCA.getContext());
1269 TmpInst.addOperand(MCOperand::createExpr(HiSym));
1270 getStreamer().emitInstruction(TmpInst, STI);
1271
1272 TmpInst.clear();
1273
1274 TmpInst.setOpcode(Mips::ADDiu);
1277 auto *LoSym = MCSpecifierExpr::create(GP_Disp, Mips::S_LO, MCA.getContext());
1278 TmpInst.addOperand(MCOperand::createExpr(LoSym));
1279 getStreamer().emitInstruction(TmpInst, STI);
1280
1281 TmpInst.clear();
1282
1283 TmpInst.setOpcode(Mips::ADDu);
1286 TmpInst.addOperand(MCOperand::createReg(RegNo));
1287 getStreamer().emitInstruction(TmpInst, STI);
1288
1290}
1291
1293 if (Pic)
1295}
1296
1298 int Offset, function_ref<unsigned()> GetATReg, SMLoc IDLoc,
1299 const MCSubtargetInfo *STI) {
1301 // .cprestore offset
1302 // When PIC mode is enabled and the O32 ABI is used, this directive expands
1303 // to:
1304 // sw $gp, offset($sp)
1305 // and adds a corresponding LW after every JAL.
1306
1307 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
1308 // is used in non-PIC mode.
1309 if (!Pic || (getABI().IsN32() || getABI().IsN64()))
1310 return true;
1311
1312 // Store the $gp on the stack.
1313 emitStoreWithImmOffset(Mips::SW, GPReg, Mips::SP, Offset, GetATReg, IDLoc,
1314 STI);
1315 return true;
1316}
1317
1319 int RegOrOffset,
1320 const MCSymbol &Sym,
1321 bool IsReg) {
1322 // Only N32 and N64 emit anything for .cpsetup iff PIC is set.
1323 if (!Pic || !(getABI().IsN32() || getABI().IsN64()))
1324 return;
1325
1327
1329 MCInst Inst;
1330
1331 // Either store the old $gp in a register or on the stack
1332 if (IsReg) {
1333 // move $save, $gpreg
1334 emitRRR(Mips::OR64, RegOrOffset, GPReg, Mips::ZERO, SMLoc(), &STI);
1335 } else {
1336 // sd $gpreg, offset($sp)
1337 emitRRI(Mips::SD, GPReg, Mips::SP, RegOrOffset, SMLoc(), &STI);
1338 }
1339
1340 auto *HiExpr =
1342 Mips::S_HI, MCA.getContext());
1343 auto *LoExpr =
1345 Mips::S_LO, MCA.getContext());
1346
1347 // lui $gp, %hi(%neg(%gp_rel(funcSym)))
1348 emitRX(Mips::LUi, GPReg, MCOperand::createExpr(HiExpr), SMLoc(), &STI);
1349
1350 // addiu $gp, $gp, %lo(%neg(%gp_rel(funcSym)))
1351 emitRRX(Mips::ADDiu, GPReg, GPReg, MCOperand::createExpr(LoExpr), SMLoc(),
1352 &STI);
1353
1354 // (d)addu $gp, $gp, $funcreg
1355 if (getABI().IsN32())
1356 emitRRR(Mips::ADDu, GPReg, GPReg, RegNo, SMLoc(), &STI);
1357 else
1358 emitRRR(Mips::DADDu, GPReg, GPReg, RegNo, SMLoc(), &STI);
1359}
1360
1362 bool SaveLocationIsRegister) {
1363 // Only N32 and N64 emit anything for .cpreturn iff PIC is set.
1364 if (!Pic || !(getABI().IsN32() || getABI().IsN64()))
1365 return;
1366
1367 MCInst Inst;
1368 // Either restore the old $gp from a register or on the stack
1369 if (SaveLocationIsRegister) {
1370 Inst.setOpcode(Mips::OR);
1372 Inst.addOperand(MCOperand::createReg(SaveLocation));
1373 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
1374 } else {
1375 Inst.setOpcode(Mips::LD);
1377 Inst.addOperand(MCOperand::createReg(Mips::SP));
1378 Inst.addOperand(MCOperand::createImm(SaveLocation));
1379 }
1380 getStreamer().emitInstruction(Inst, STI);
1381
1383}
1384
1387 MCContext &Context = MCA.getContext();
1389 MCSectionELF *Sec = Context.getELFSection(
1390 ".MIPS.abiflags", ELF::SHT_MIPS_ABIFLAGS, ELF::SHF_ALLOC, 24);
1391 OS.switchSection(Sec);
1392 Sec->setAlignment(Align(8));
1393
1395}
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.
virtual bool useCodeAlign(const MCSection &Sec) const
Definition: MCAsmInfo.h:503
MCContext & getContext() const
Definition: MCAssembler.h:169
LLVM_ABI bool registerSymbol(const MCSymbol &Symbol)
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:428
Context object for machine code objects.
Definition: MCContext.h:83
const MCObjectFileInfo * getObjectFileInfo() const
Definition: MCContext.h:416
const MCAsmInfo * getAsmInfo() const
Definition: MCContext.h:412
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition: MCContext.cpp:203
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:43
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:188
void setLoc(SMLoc loc)
Definition: MCInst.h:207
void addOperand(const MCOperand Op)
Definition: MCInst.h:215
void setOpcode(unsigned Op)
Definition: MCInst.h:201
void clear()
Definition: MCInst.h:223
MCSection * getBSSSection() const
bool isPositionIndependent() const
MCSection * getTextSection() const
MCSection * getDataSection() const
void emitValueToAlignment(Align Alignment, int64_t Fill=0, uint8_t FillLen=1, unsigned MaxBytesToEmit=0) override
Emit some number of copies of Value until the byte alignment ByteAlignment is reached.
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:40
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:166
static MCOperand createReg(MCRegister Reg)
Definition: MCInst.h:138
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:145
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
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:496
void setAlignment(Align Value)
Definition: MCSection.h:580
void ensureMinAlignment(Align MinAlignment)
Makes sure that Alignment is at least MinAlignment.
Definition: MCSection.h:583
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition: MCExpr.cpp:743
Streaming machine code generation interface.
Definition: MCStreamer.h:220
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
MCContext & getContext() const
Definition: MCStreamer.h:314
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:190
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition: MCExpr.h:214
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:42
Target specific streamer interface.
Definition: MCStreamer.h:93
MCStreamer & getStreamer()
Definition: MCStreamer.h:101
MCContext & getContext()
Definition: MCStreamer.h:1117
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)
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 emitDTPRel64Value(const MCExpr *) override
void emitTPRel64Value(const MCExpr *) override
void emitDirectiveCpLocal(unsigned RegNo) override
void emitFrame(MCRegister StackReg, unsigned StackSize, MCRegister ReturnReg) override
void emitDirectiveModuleHardFloat() override
void emitDirectiveEnd(StringRef Name) override
void emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) override
void emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) override
void emitDirectiveCpreturn(unsigned SaveLocation, bool SaveLocationIsRegister) override
void emitDirectiveCpAdd(unsigned RegNo) override
void emitDTPRel32Value(const MCExpr *) override
void emitTPRel32Value(const MCExpr *) override
void emitDirectiveSetAtWithArg(unsigned RegNo) override
void emitGPRel64Value(const MCExpr *) override
void emitDirectiveSetNoMicroMips() override
void emitGPRel32Value(const MCExpr *) override
void emitDirectiveModuleOddSPReg() override
void emitDTPRel32Value(const MCExpr *) override
void emitDirectiveCpAdd(unsigned RegNo) override
void emitDirectiveCpLoad(unsigned RegNo) override
MipsTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI)
void emitGPRel64Value(const MCExpr *) override
void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset, const MCSymbol &Sym, bool IsReg) override
void emitGPRel32Value(const MCExpr *) override
void emitDirectiveEnd(StringRef Name) override
void emitFrame(MCRegister StackReg, unsigned StackSize, MCRegister ReturnReg) override
bool emitDirectiveCpRestore(int Offset, function_ref< unsigned()> GetATReg, SMLoc IDLoc, const MCSubtargetInfo *STI) override
void emitTPRel64Value(const MCExpr *) override
void emitLabel(MCSymbol *Symbol) override
void emitTPRel32Value(const MCExpr *) override
void emitDTPRel64Value(const MCExpr *) override
void emitDirectiveCpLocal(unsigned RegNo) override
void emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) override
void emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) 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()
void emitRRX(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCOperand Op2, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetReorder()
virtual void emitDirectiveSetNoCRC()
virtual void emitFrame(MCRegister StackReg, unsigned StackSize, MCRegister ReturnReg)
void emitRRRX(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCRegister Reg2, MCOperand Op3, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveModuleNoGINV()
virtual void emitDirectiveSetSoftFloat()
virtual void emitDirectiveCpreturn(unsigned SaveLocation, bool SaveLocationIsRegister)
virtual void emitGPRel32Value(const MCExpr *)
virtual void emitDirectiveSetNoMicroMips()
void emitRX(unsigned Opcode, MCRegister Reg0, MCOperand Op1, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetMips64R2()
virtual void emitDirectiveEnd(StringRef Name)
virtual void emitDirectiveSetFp(MipsABIFlagsSection::FpABIKind Value)
virtual void emitTPRel64Value(const MCExpr *)
virtual void emitDirectiveSetMips64R3()
virtual void emitDirectiveSetNoVirt()
virtual void emitDirectiveSetMacro()
virtual void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset, const MCSymbol &Sym, bool IsReg)
void emitR(unsigned Opcode, MCRegister Reg0, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetNoGINV()
virtual void emitDirectiveSetMips32R3()
virtual void emitDirectiveSetMips32R2()
void emitRRI(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, int16_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveEnt(const MCSymbol &Symbol)
virtual void emitDirectiveSetNoMips3D()
void emitLoadWithImmOffset(unsigned Opcode, MCRegister DstReg, MCRegister BaseReg, int64_t Offset, MCRegister TmpReg, SMLoc IDLoc, const MCSubtargetInfo *STI)
Emit a load instruction with an immediate offset.
virtual void emitDirectiveCpLocal(unsigned RegNo)
virtual void emitDirectiveCpLoad(unsigned RegNo)
virtual void emitDirectiveSetHardFloat()
void emitEmptyDelaySlot(bool hasShortDelaySlot, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitAddu(MCRegister DstReg, MCRegister SrcReg, MCRegister TrgReg, bool Is64Bit, const MCSubtargetInfo *STI)
void emitRI(unsigned Opcode, MCRegister Reg0, int32_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitTPRel32Value(const MCExpr *)
virtual void emitDirectiveSetNoMips16()
virtual void emitDirectiveSetNoOddSPReg()
virtual void emitGPRel64Value(const MCExpr *)
void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRR(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetOddSPReg()
virtual void emitDirectiveModuleGINV()
virtual void emitDirectiveNaNLegacy()
virtual void emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff)
void emitRRIII(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, int16_t Imm0, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetMicroMips()
virtual void emitDTPRel64Value(const MCExpr *)
virtual void emitDirectiveModuleSoftFloat()
virtual void emitDirectiveSetArch(StringRef Arch)
virtual void emitDTPRel32Value(const MCExpr *)
virtual void emitDirectiveSetAtWithArg(unsigned RegNo)
virtual bool emitDirectiveCpRestore(int Offset, function_ref< unsigned()> GetATReg, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveModuleNoCRC()
virtual void emitDirectiveSetNoMacro()
void emitDSLL(MCRegister DstReg, MCRegister SrcReg, int16_t ShiftAmount, SMLoc IDLoc, const MCSubtargetInfo *STI)
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)
void emitRRR(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCRegister Reg2, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetNoReorder()
virtual void emitDirectiveOptionPic0()
virtual void emitDirectiveModuleHardFloat()
virtual void emitDirectiveSetMips32R5()
virtual void emitDirectiveSetMips32R6()
virtual void emitDirectiveOptionPic2()
virtual void emitDirectiveSetMips16()
virtual void emitDirectiveAbiCalls()
void emitStoreWithImmOffset(unsigned Opcode, MCRegister SrcReg, MCRegister BaseReg, int64_t Offset, function_ref< unsigned()> GetATReg, SMLoc IDLoc, const MCSubtargetInfo *STI)
Emit a store instruction with an offset.
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:55
LLVM_ABI std::string lower() const
Definition: StringRef.cpp:112
ArchType getArch() const
Get the parsed architecture type of this triple.
Definition: Triple.h:408
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:82
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:75
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:53
raw_ostream & write_hex(unsigned long long N)
Output N in hexadecimal, without any prefix or padding.
@ STO_MIPS_MICROMIPS
Definition: ELF.h:602
@ EF_MIPS_MICROMIPS
Definition: ELF.h:563
@ EF_MIPS_ARCH_32R6
Definition: ELF.h:578
@ EF_MIPS_ABI_O32
Definition: ELF.h:534
@ EF_MIPS_ARCH_64
Definition: ELF.h:575
@ EF_MIPS_ARCH_32
Definition: ELF.h:574
@ EF_MIPS_MACH_OCTEON
Definition: ELF.h:549
@ EF_MIPS_ARCH_4
Definition: ELF.h:572
@ EF_MIPS_ARCH_5
Definition: ELF.h:573
@ EF_MIPS_NAN2008
Definition: ELF.h:531
@ EF_MIPS_PIC
Definition: ELF.h:524
@ EF_MIPS_ARCH_2
Definition: ELF.h:570
@ EF_MIPS_32BITMODE
Definition: ELF.h:527
@ EF_MIPS_ARCH_32R2
Definition: ELF.h:576
@ EF_MIPS_ARCH_64R2
Definition: ELF.h:577
@ EF_MIPS_ARCH_ASE_M16
Definition: ELF.h:564
@ EF_MIPS_NOREORDER
Definition: ELF.h:523
@ EF_MIPS_ARCH_1
Definition: ELF.h:569
@ EF_MIPS_CPIC
Definition: ELF.h:525
@ EF_MIPS_ARCH_64R6
Definition: ELF.h:579
@ EF_MIPS_ABI2
Definition: ELF.h:526
@ EF_MIPS_ARCH_3
Definition: ELF.h:571
@ SHT_PROGBITS
Definition: ELF.h:1140
@ SHT_MIPS_ABIFLAGS
Definition: ELF.h:1219
@ SHF_ALLOC
Definition: ELF.h:1240
@ STT_FUNC
Definition: ELF.h:1410
const MCSpecifierExpr * createGpOff(const MCExpr *Expr, Specifier S, MCContext &Ctx)
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:444
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:477
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
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)