LLVM 23.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
53
92void MipsTargetStreamer::emitFrame(MCRegister StackReg, unsigned StackSize,
94void MipsTargetStreamer::emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) {}
95void MipsTargetStreamer::emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) {
96}
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 = Reg;
145
147}
149 int Offset, function_ref<MCRegister()> GetATReg, SMLoc IDLoc,
150 const MCSubtargetInfo *STI) {
152 return true;
153}
155 const MCSymbol &Sym, bool IsReg) {
156}
158 bool SaveLocationIsRegister) {}
159
161
163 if (!ABIFlagsSection.OddSPReg && !ABIFlagsSection.Is32BitABI)
164 report_fatal_error("+nooddspreg is only valid for O32");
165}
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<MCRegister()> 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
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
458
463
465 OS << "\t.set\tnoreorder\n";
467}
468
473
478
483
488
493
498
503
508
513
518
523
528
533
535 OS << "\t.set\tat=$" << Twine(RegNo) << "\n";
537}
538
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
572
573void MipsTargetAsmStreamer::emitFrame(MCRegister StackReg, unsigned StackSize,
575 OS << "\t.frame\t$"
577 << StackSize << ",$"
579}
580
582 OS << "\t.set arch=" << Arch << "\n";
584}
585
590
595
600
605
610
615
620
625
630
635
640
645
650
655
660
665
670
675
680
685
690
695
700
705
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
737
743
749
751 int Offset, function_ref<MCRegister()> 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
798
801
802 OS << "\t.module\t" << (ABIFlagsSection.OddSPReg ? "" : "no") << "oddspreg\n";
803}
804
809
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
888 STI.getTargetTriple().getArch() == Triple::ArchType::mipsel ||
889 STI.getTargetTriple().getArch() == Triple::ArchType::mips
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 else if (Features[Mips::FeatureR5900])
925 EFlags |= ELF::EF_MIPS_MACH_5900;
926
927 // Other options.
928 if (Features[Mips::FeatureNaN2008])
929 EFlags |= ELF::EF_MIPS_NAN2008;
930
931 W.setELFHeaderEFlags(EFlags);
932}
933
935 auto *Symbol = static_cast<MCSymbolELF *>(S);
937 uint8_t Type = Symbol->getType();
938 if (Type != ELF::STT_FUNC)
939 return;
940
941 if (isMicroMipsEnabled())
942 Symbol->setOther(ELF::STO_MIPS_MICROMIPS);
943}
944
948 const MCObjectFileInfo &OFI = *MCA.getContext().getObjectFileInfo();
950
951 // .bss, .text and .data are always at least 16-byte aligned.
952 MCSection &TextSection = *OFI.getTextSection();
953 S.switchSection(&TextSection);
954 MCSection &DataSection = *OFI.getDataSection();
955 S.switchSection(&DataSection);
956 MCSection &BSSSection = *OFI.getBSSSection();
957 S.switchSection(&BSSSection);
958
959 TextSection.ensureMinAlignment(Align(16));
960 DataSection.ensureMinAlignment(Align(16));
961 BSSSection.ensureMinAlignment(Align(16));
962
963 if (RoundSectionSizes) {
964 // Make sections sizes a multiple of the alignment. This is useful for
965 // verifying the output of IAS against the output of other assemblers but
966 // it's not necessary to produce a correct object and increases section
967 // size.
968 for (MCSection &Sec : MCA) {
969 MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
970
971 Align Alignment = Section.getAlign();
972 S.switchSection(&Section);
973 if (getContext().getAsmInfo()->useCodeAlign(Section))
974 S.emitCodeAlignment(Alignment, &STI, Alignment.value());
975 else
976 S.emitValueToAlignment(Alignment, 0, 1, Alignment.value());
977 }
978 }
979
980 const FeatureBitset &Features = STI.getFeatureBits();
981
982 // Update e_header flags. See the FIXME and comment above in
983 // the constructor for a full rundown on this.
984 unsigned EFlags = W.getELFHeaderEFlags();
985
986 // ABI
987 // N64 does not require any ABI bits.
988 if (getABI().IsO32())
989 EFlags |= ELF::EF_MIPS_ABI_O32;
990 else if (getABI().IsN32())
991 EFlags |= ELF::EF_MIPS_ABI2;
992
993 if (Features[Mips::FeatureGP64Bit]) {
994 if (getABI().IsO32())
995 EFlags |= ELF::EF_MIPS_32BITMODE; /* Compatibility Mode */
996 } else if (Features[Mips::FeatureMips64r2] || Features[Mips::FeatureMips64])
997 EFlags |= ELF::EF_MIPS_32BITMODE;
998
999 // -mplt is not implemented but we should act as if it was
1000 // given.
1001 if (!Features[Mips::FeatureNoABICalls])
1002 EFlags |= ELF::EF_MIPS_CPIC;
1003
1004 if (Pic)
1006
1007 W.setELFHeaderEFlags(EFlags);
1008
1009 // Emit all the option records.
1010 // At the moment we are only emitting .Mips.options (ODK_REGINFO) and
1011 // .reginfo.
1012 MipsELFStreamer &MEF = static_cast<MipsELFStreamer &>(Streamer);
1014
1016}
1017
1019 auto *Symbol = static_cast<MCSymbolELF *>(S);
1020 // If on rhs is micromips symbol then mark Symbol as microMips.
1021 if (Value->getKind() != MCExpr::SymbolRef)
1022 return;
1023 auto &RhsSym = static_cast<const MCSymbolELF &>(
1024 static_cast<const MCSymbolRefExpr *>(Value)->getSymbol());
1025
1026 if (!(RhsSym.getOther() & ELF::STO_MIPS_MICROMIPS))
1027 return;
1028
1030}
1031
1035
1037 auto &S = getStreamer();
1038 S.ensureHeadroom(4);
1039 S.addFixup(Value, Mips::fixup_Mips_GPREL32);
1040 S.appendContents(4, 0);
1041}
1042
1044 auto &S = getStreamer();
1045 S.ensureHeadroom(8);
1046 // fixup_Mips_GPREL32 desginates R_MIPS_GPREL32+R_MIPS_64 on MIPS64.
1047 S.addFixup(Value, Mips::fixup_Mips_GPREL32);
1048 S.appendContents(8, 0);
1049}
1050
1052 auto &S = getStreamer();
1053 S.ensureHeadroom(4);
1054 S.addFixup(Value, Mips::fixup_Mips_DTPREL32);
1055 S.appendContents(4, 0);
1056}
1057
1059 auto &S = getStreamer();
1060 S.ensureHeadroom(8);
1061 S.addFixup(Value, Mips::fixup_Mips_DTPREL64);
1062 S.appendContents(8, 0);
1063}
1064
1066 auto &S = getStreamer();
1067 S.ensureHeadroom(4);
1068 S.addFixup(Value, Mips::fixup_Mips_TPREL32);
1069 S.appendContents(4, 0);
1070}
1071
1073 auto &S = getStreamer();
1074 S.ensureHeadroom(8);
1075 S.addFixup(Value, Mips::fixup_Mips_TPREL64);
1076 S.appendContents(8, 0);
1077}
1078
1080 MicroMipsEnabled = true;
1082}
1083
1085 MicroMipsEnabled = false;
1087}
1088
1091 unsigned Flags = W.getELFHeaderEFlags();
1092 Flags |= ELF::EF_MIPS_MICROMIPS;
1093 W.setELFHeaderEFlags(Flags);
1094}
1095
1098 unsigned Flags = W.getELFHeaderEFlags();
1100 W.setELFHeaderEFlags(Flags);
1102}
1103
1106 unsigned Flags = W.getELFHeaderEFlags();
1107 Flags |= ELF::EF_MIPS_NOREORDER;
1108 W.setELFHeaderEFlags(Flags);
1110}
1111
1114 MCContext &Context = MCA.getContext();
1115 MCStreamer &OS = getStreamer();
1116
1117 OS.pushSection();
1118 MCSectionELF *Sec = Context.getELFSection(".pdr", ELF::SHT_PROGBITS, 0);
1119 OS.switchSection(Sec);
1120 Sec->setAlignment(Align(4));
1121
1122 MCSymbol *Sym = Context.getOrCreateSymbol(Name);
1123 const auto *ExprRef = MCSymbolRefExpr::create(Sym, Context);
1124 OS.emitValueImpl(ExprRef, 4);
1125
1126 OS.emitIntValue(GPRInfoSet ? GPRBitMask : 0, 4); // reg_mask
1127 OS.emitIntValue(GPRInfoSet ? GPROffset : 0, 4); // reg_offset
1128
1129 OS.emitIntValue(FPRInfoSet ? FPRBitMask : 0, 4); // fpreg_mask
1130 OS.emitIntValue(FPRInfoSet ? FPROffset : 0, 4); // fpreg_offset
1131
1132 OS.emitIntValue(FrameInfoSet ? FrameOffset : 0, 4); // frame_offset
1133 OS.emitIntValue(FrameInfoSet ? FrameReg : 0, 4); // frame_reg
1134 OS.emitIntValue(FrameInfoSet ? ReturnReg : 0, 4); // return_reg
1135
1136 // The .end directive marks the end of a procedure. Invalidate
1137 // the information gathered up until this point.
1139
1140 OS.popSection();
1141
1142 // .end also implicitly sets the size.
1143 MCSymbol *CurPCSym = Context.createTempSymbol();
1144 OS.emitLabel(CurPCSym);
1146 MCSymbolRefExpr::create(CurPCSym, Context), ExprRef, Context);
1147
1148 // The ELFObjectWriter can determine the absolute size as it has access to
1149 // the layout information of the assembly file, so a size expression rather
1150 // than an absolute value is ok here.
1151 static_cast<MCSymbolELF *>(Sym)->setSize(Size);
1152}
1153
1156
1157 // .ent also acts like an implicit '.type symbol, STT_FUNC'
1158 static_cast<const MCSymbolELF &>(Symbol).setType(ELF::STT_FUNC);
1159}
1160
1163 unsigned Flags = W.getELFHeaderEFlags();
1165 W.setELFHeaderEFlags(Flags);
1166}
1167
1170 unsigned Flags = W.getELFHeaderEFlags();
1171 Flags |= ELF::EF_MIPS_NAN2008;
1172 W.setELFHeaderEFlags(Flags);
1173}
1174
1177 unsigned Flags = W.getELFHeaderEFlags();
1178 Flags &= ~ELF::EF_MIPS_NAN2008;
1179 W.setELFHeaderEFlags(Flags);
1180}
1181
1184 unsigned Flags = W.getELFHeaderEFlags();
1185 // This option overrides other PIC options like -KPIC.
1186 Pic = false;
1187 Flags &= ~ELF::EF_MIPS_PIC;
1188 W.setELFHeaderEFlags(Flags);
1189}
1190
1193 unsigned Flags = W.getELFHeaderEFlags();
1194 Pic = true;
1195 // NOTE: We are following the GAS behaviour here which means the directive
1196 // 'pic2' also sets the CPIC bit in the ELF header. This is different from
1197 // what is stated in the SYSV ABI which consider the bits EF_MIPS_PIC and
1198 // EF_MIPS_CPIC to be mutually exclusive.
1200 W.setELFHeaderEFlags(Flags);
1201}
1202
1208
1209void MipsTargetELFStreamer::emitFrame(MCRegister StackReg, unsigned StackSize,
1210 MCRegister ReturnReg_) {
1212 const MCRegisterInfo *RegInfo = Context.getRegisterInfo();
1213
1214 FrameInfoSet = true;
1215 FrameReg = RegInfo->getEncodingValue(StackReg);
1216 FrameOffset = StackSize;
1217 ReturnReg = RegInfo->getEncodingValue(ReturnReg_);
1218}
1219
1220void MipsTargetELFStreamer::emitMask(unsigned CPUBitmask,
1221 int CPUTopSavedRegOff) {
1222 GPRInfoSet = true;
1223 GPRBitMask = CPUBitmask;
1224 GPROffset = CPUTopSavedRegOff;
1225}
1226
1227void MipsTargetELFStreamer::emitFMask(unsigned FPUBitmask,
1228 int FPUTopSavedRegOff) {
1229 FPRInfoSet = true;
1230 FPRBitMask = FPUBitmask;
1231 FPROffset = FPUTopSavedRegOff;
1232}
1233
1235 // .cpadd $reg
1236 // This directive inserts code to add $gp to the argument's register
1237 // when support for position independent code is enabled.
1238 if (!Pic)
1239 return;
1240
1241 emitAddu(Reg, Reg, GPReg, getABI().IsN64(), &STI);
1243}
1244
1246 // .cpload $reg
1247 // This directive expands to:
1248 // lui $gp, %hi(_gp_disp)
1249 // addui $gp, $gp, %lo(_gp_disp)
1250 // addu $gp, $gp, $reg
1251 // when support for position independent code is enabled.
1252 if (!Pic || (getABI().IsN32() || getABI().IsN64()))
1253 return;
1254
1255 // There's a GNU extension controlled by -mno-shared that allows
1256 // locally-binding symbols to be accessed using absolute addresses.
1257 // This is currently not supported. When supported -mno-shared makes
1258 // .cpload expand to:
1259 // lui $gp, %hi(__gnu_local_gp)
1260 // addiu $gp, $gp, %lo(__gnu_local_gp)
1261
1262 StringRef SymName("_gp_disp");
1264 MCSymbol *GP_Disp = MCA.getContext().getOrCreateSymbol(SymName);
1265 MCA.registerSymbol(*GP_Disp);
1266
1267 MCInst TmpInst;
1268 TmpInst.setOpcode(Mips::LUi);
1270 auto *HiSym = MCSpecifierExpr::create(GP_Disp, Mips::S_HI, MCA.getContext());
1271 TmpInst.addOperand(MCOperand::createExpr(HiSym));
1272 getStreamer().emitInstruction(TmpInst, STI);
1273
1274 TmpInst.clear();
1275
1276 TmpInst.setOpcode(Mips::ADDiu);
1279 auto *LoSym = MCSpecifierExpr::create(GP_Disp, Mips::S_LO, MCA.getContext());
1280 TmpInst.addOperand(MCOperand::createExpr(LoSym));
1281 getStreamer().emitInstruction(TmpInst, STI);
1282
1283 TmpInst.clear();
1284
1285 TmpInst.setOpcode(Mips::ADDu);
1288 TmpInst.addOperand(MCOperand::createReg(Reg));
1289 getStreamer().emitInstruction(TmpInst, STI);
1290
1292}
1293
1298
1300 int Offset, function_ref<MCRegister()> GetATReg, SMLoc IDLoc,
1301 const MCSubtargetInfo *STI) {
1303 // .cprestore offset
1304 // When PIC mode is enabled and the O32 ABI is used, this directive expands
1305 // to:
1306 // sw $gp, offset($sp)
1307 // and adds a corresponding LW after every JAL.
1308
1309 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
1310 // is used in non-PIC mode.
1311 if (!Pic || (getABI().IsN32() || getABI().IsN64()))
1312 return true;
1313
1314 // Store the $gp on the stack.
1315 emitStoreWithImmOffset(Mips::SW, GPReg, Mips::SP, Offset, GetATReg, IDLoc,
1316 STI);
1317 return true;
1318}
1319
1321 int RegOrOffset,
1322 const MCSymbol &Sym,
1323 bool IsReg) {
1324 // Only N32 and N64 emit anything for .cpsetup iff PIC is set.
1325 if (!Pic || !(getABI().IsN32() || getABI().IsN64()))
1326 return;
1327
1329
1331 MCInst Inst;
1332
1333 // Either store the old $gp in a register or on the stack
1334 if (IsReg) {
1335 // move $save, $gpreg
1336 emitRRR(Mips::OR64, RegOrOffset, GPReg, Mips::ZERO, SMLoc(), &STI);
1337 } else {
1338 // sd $gpreg, offset($sp)
1339 emitRRI(Mips::SD, GPReg, Mips::SP, RegOrOffset, SMLoc(), &STI);
1340 }
1341
1342 auto *HiExpr =
1344 Mips::S_HI, MCA.getContext());
1345 auto *LoExpr =
1347 Mips::S_LO, MCA.getContext());
1348
1349 // lui $gp, %hi(%neg(%gp_rel(funcSym)))
1350 emitRX(Mips::LUi, GPReg, MCOperand::createExpr(HiExpr), SMLoc(), &STI);
1351
1352 // addiu $gp, $gp, %lo(%neg(%gp_rel(funcSym)))
1353 emitRRX(Mips::ADDiu, GPReg, GPReg, MCOperand::createExpr(LoExpr), SMLoc(),
1354 &STI);
1355
1356 // (d)addu $gp, $gp, $funcreg
1357 if (getABI().IsN32())
1358 emitRRR(Mips::ADDu, GPReg, GPReg, Reg, SMLoc(), &STI);
1359 else
1360 emitRRR(Mips::DADDu, GPReg, GPReg, Reg, SMLoc(), &STI);
1361}
1362
1364 bool SaveLocationIsRegister) {
1365 // Only N32 and N64 emit anything for .cpreturn iff PIC is set.
1366 if (!Pic || !(getABI().IsN32() || getABI().IsN64()))
1367 return;
1368
1369 MCInst Inst;
1370 // Either restore the old $gp from a register or on the stack
1371 if (SaveLocationIsRegister) {
1372 Inst.setOpcode(Mips::OR);
1374 Inst.addOperand(MCOperand::createReg(SaveLocation));
1375 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
1376 } else {
1377 Inst.setOpcode(Mips::LD);
1379 Inst.addOperand(MCOperand::createReg(Mips::SP));
1380 Inst.addOperand(MCOperand::createImm(SaveLocation));
1381 }
1382 getStreamer().emitInstruction(Inst, STI);
1383
1385}
1386
1389 MCContext &Context = MCA.getContext();
1390 MCStreamer &OS = getStreamer();
1391 MCSectionELF *Sec = Context.getELFSection(
1392 ".MIPS.abiflags", ELF::SHT_MIPS_ABIFLAGS, ELF::SHF_ALLOC, 24);
1393 OS.switchSection(Sec);
1394 Sec->setAlignment(Align(8));
1395
1396 OS << ABIFlagsSection;
1397}
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)
Container class for subtarget features.
void printExpr(raw_ostream &, const MCExpr &) const
MCContext & getContext() const
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.
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...
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
This represents a section on linux, lots of unix variants and some bare metal systems.
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition MCSection.h:517
void setAlignment(Align Value)
Definition MCSection.h:602
void ensureMinAlignment(Align MinAlignment)
Makes sure that Alignment is at least MinAlignment.
Definition MCSection.h:605
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 bool popSection()
Restore the current and previous section from the section stack.
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 emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
virtual void emitIntValue(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers.
void pushSection()
Save the current and previous section on the section stack.
Definition MCStreamer.h:443
virtual void switchSection(MCSection *Section, uint32_t Subsec=0)
Set the current section where code is being emitted to Section.
virtual void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
Emit the expression Value into the output as a native integer of the given Size bytes.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
void setOther(unsigned Other)
Represent a reference to a symbol from inside an expression.
Definition MCExpr.h:190
const MCSymbol & getSymbol() const
Definition MCExpr.h:227
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
StringRef getName() const
getName - Get the symbol name.
Definition MCSymbol.h:188
MCStreamer & getStreamer()
Definition MCStreamer.h:101
MCContext & getContext()
MCStreamer & Streamer
Definition MCStreamer.h:95
MCTargetStreamer(MCStreamer &S)
static MipsABIInfo O32()
Definition MipsABIInfo.h:33
static MipsABIInfo N64()
Definition MipsABIInfo.h:35
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
void emitDirectiveCpsetup(MCRegister Reg, int RegOrOffset, const MCSymbol &Sym, bool IsReg) override
MipsTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS)
void emitDirectiveCpLocal(MCRegister Reg) override
void emitDirectiveEnt(const MCSymbol &Symbol) override
void emitDTPRel64Value(const MCExpr *) override
void emitTPRel64Value(const MCExpr *) override
bool emitDirectiveCpRestore(int Offset, function_ref< MCRegister()> GetATReg, SMLoc IDLoc, const MCSubtargetInfo *STI) override
Emit a .cprestore directive.
void emitDirectiveCpAdd(MCRegister Reg) override
void emitDirectiveCpLoad(MCRegister Reg) override
void emitFrame(MCRegister StackReg, unsigned StackSize, MCRegister ReturnReg) 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 emitDTPRel32Value(const MCExpr *) override
void emitTPRel32Value(const MCExpr *) override
void emitDirectiveSetAtWithArg(unsigned RegNo) override
void emitGPRel64Value(const MCExpr *) override
void emitGPRel32Value(const MCExpr *) override
bool emitDirectiveCpRestore(int Offset, function_ref< MCRegister()> GetATReg, SMLoc IDLoc, const MCSubtargetInfo *STI) override
void emitDTPRel32Value(const MCExpr *) override
MipsTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI)
void emitGPRel64Value(const MCExpr *) override
void emitGPRel32Value(const MCExpr *) override
void emitDirectiveEnd(StringRef Name) override
void emitFrame(MCRegister StackReg, unsigned StackSize, MCRegister ReturnReg) override
void emitDirectiveCpsetup(MCRegister Reg, int RegOrOffset, const MCSymbol &Sym, bool IsReg) override
void emitDirectiveCpAdd(MCRegister Reg) override
void emitDirectiveCpLocal(MCRegister Reg) override
void emitTPRel64Value(const MCExpr *) override
void emitLabel(MCSymbol *Symbol) override
void emitTPRel32Value(const MCExpr *) override
void emitDTPRel64Value(const MCExpr *) override
void emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) override
void emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) override
void emitDirectiveCpLoad(MCRegister Reg) 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
void emitRRX(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCOperand Op2, SMLoc IDLoc, const MCSubtargetInfo *STI)
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 emitDirectiveCpLoad(MCRegister Reg)
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 emitDirectiveEnd(StringRef Name)
virtual void emitDirectiveSetFp(MipsABIFlagsSection::FpABIKind Value)
virtual void emitTPRel64Value(const MCExpr *)
void emitR(unsigned Opcode, MCRegister Reg0, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRRI(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, int16_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveEnt(const MCSymbol &Symbol)
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.
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 bool emitDirectiveCpRestore(int Offset, function_ref< MCRegister()> GetATReg, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff)
virtual void emitDirectiveCpsetup(MCRegister Reg, int RegOrOffset, const MCSymbol &Sym, bool IsReg)
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 emitDirectiveCpAdd(MCRegister Reg)
virtual void emitDirectiveSetAtWithArg(unsigned RegNo)
void emitDSLL(MCRegister DstReg, MCRegister SrcReg, int16_t ShiftAmount, SMLoc IDLoc, const MCSubtargetInfo *STI)
const MipsABIInfo & getABI() const
virtual void emitDirectiveModuleOddSPReg()
void emitGPRestore(int Offset, SMLoc IDLoc, const MCSubtargetInfo *STI)
Emit the $gp restore operation for .cprestore.
virtual void emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff)
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()
void emitStoreWithImmOffset(unsigned Opcode, MCRegister SrcReg, MCRegister BaseReg, int64_t Offset, function_ref< MCRegister()> GetATReg, SMLoc IDLoc, const MCSubtargetInfo *STI)
Emit a store instruction with an offset.
virtual void emitDirectiveModuleHardFloat()
virtual void emitDirectiveCpLocal(MCRegister Reg)
MipsABIFlagsSection ABIFlagsSection
Represents a location in source code.
Definition SMLoc.h:22
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
LLVM_ABI std::string lower() const
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.
@ SHF_ALLOC
Definition ELF.h:1248
@ STO_MIPS_MICROMIPS
Definition ELF.h:602
@ SHT_PROGBITS
Definition ELF.h:1147
@ SHT_MIPS_ABIFLAGS
Definition ELF.h:1227
@ EF_MIPS_MACH_5900
Definition ELF.h:554
@ 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
@ STT_FUNC
Definition ELF.h:1418
const MCSpecifierExpr * createGpOff(const MCExpr *Expr, Specifier S, MCContext &Ctx)
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
@ Offset
Definition DWP.cpp:532
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:165
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:77