LLVM 24.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
94void MipsTargetStreamer::emitFrame(MCRegister StackReg, unsigned StackSize,
96void MipsTargetStreamer::emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) {}
97void MipsTargetStreamer::emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) {
98}
134 // .cplocal $reg
135 // This directive forces to use the alternate register for context pointer.
136 // For example
137 // .cplocal $4
138 // jal foo
139 // expands to
140 // ld $25, %call16(foo)($4)
141 // jalr $25
142
143 if (!getABI().IsN32() && !getABI().IsN64())
144 return;
145
146 GPReg = Reg;
147
149}
151 int Offset, function_ref<MCRegister()> GetATReg, SMLoc IDLoc,
152 const MCSubtargetInfo *STI) {
154 return true;
155}
157 const MCSymbol &Sym, bool IsReg) {
158}
160 bool SaveLocationIsRegister) {}
161
163
165 if (!ABIFlagsSection.OddSPReg && !ABIFlagsSection.Is32BitABI)
166 report_fatal_error("+nooddspreg is only valid for O32");
167}
185
186void MipsTargetStreamer::emitR(unsigned Opcode, MCRegister Reg0, SMLoc IDLoc,
187 const MCSubtargetInfo *STI) {
188 MCInst TmpInst;
189 TmpInst.setOpcode(Opcode);
190 TmpInst.addOperand(MCOperand::createReg(Reg0));
191 TmpInst.setLoc(IDLoc);
192 getStreamer().emitInstruction(TmpInst, *STI);
193}
194
195void MipsTargetStreamer::emitRX(unsigned Opcode, MCRegister Reg0, MCOperand Op1,
196 SMLoc IDLoc, const MCSubtargetInfo *STI) {
197 MCInst TmpInst;
198 TmpInst.setOpcode(Opcode);
199 TmpInst.addOperand(MCOperand::createReg(Reg0));
200 TmpInst.addOperand(Op1);
201 TmpInst.setLoc(IDLoc);
202 getStreamer().emitInstruction(TmpInst, *STI);
203}
204
205void MipsTargetStreamer::emitRI(unsigned Opcode, MCRegister Reg0, int32_t Imm,
206 SMLoc IDLoc, const MCSubtargetInfo *STI) {
207 emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, STI);
208}
209
210void MipsTargetStreamer::emitRR(unsigned Opcode, MCRegister Reg0,
211 MCRegister Reg1, SMLoc IDLoc,
212 const MCSubtargetInfo *STI) {
213 emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, STI);
214}
215
216void MipsTargetStreamer::emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2,
217 SMLoc IDLoc, const MCSubtargetInfo *STI) {
218 MCInst TmpInst;
219 TmpInst.setOpcode(Opcode);
220 TmpInst.addOperand(MCOperand::createImm(Imm1));
221 TmpInst.addOperand(MCOperand::createImm(Imm2));
222 TmpInst.setLoc(IDLoc);
223 getStreamer().emitInstruction(TmpInst, *STI);
224}
225
226void MipsTargetStreamer::emitRRX(unsigned Opcode, MCRegister Reg0,
227 MCRegister Reg1, MCOperand Op2, SMLoc IDLoc,
228 const MCSubtargetInfo *STI) {
229 MCInst TmpInst;
230 TmpInst.setOpcode(Opcode);
231 TmpInst.addOperand(MCOperand::createReg(Reg0));
232 TmpInst.addOperand(MCOperand::createReg(Reg1));
233 TmpInst.addOperand(Op2);
234 TmpInst.setLoc(IDLoc);
235 getStreamer().emitInstruction(TmpInst, *STI);
236}
237
238void MipsTargetStreamer::emitRRR(unsigned Opcode, MCRegister Reg0,
239 MCRegister Reg1, MCRegister Reg2, SMLoc IDLoc,
240 const MCSubtargetInfo *STI) {
241 emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc, STI);
242}
243
244void MipsTargetStreamer::emitRRRX(unsigned Opcode, MCRegister Reg0,
245 MCRegister Reg1, MCRegister Reg2,
246 MCOperand Op3, SMLoc IDLoc,
247 const MCSubtargetInfo *STI) {
248 MCInst TmpInst;
249 TmpInst.setOpcode(Opcode);
250 TmpInst.addOperand(MCOperand::createReg(Reg0));
251 TmpInst.addOperand(MCOperand::createReg(Reg1));
252 TmpInst.addOperand(MCOperand::createReg(Reg2));
253 TmpInst.addOperand(Op3);
254 TmpInst.setLoc(IDLoc);
255 getStreamer().emitInstruction(TmpInst, *STI);
256}
257
258void MipsTargetStreamer::emitRRI(unsigned Opcode, MCRegister Reg0,
259 MCRegister Reg1, int16_t Imm, SMLoc IDLoc,
260 const MCSubtargetInfo *STI) {
261 emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc, STI);
262}
263
264void MipsTargetStreamer::emitRRIII(unsigned Opcode, MCRegister Reg0,
265 MCRegister Reg1, int16_t Imm0, int16_t Imm1,
266 int16_t Imm2, SMLoc IDLoc,
267 const MCSubtargetInfo *STI) {
268 MCInst TmpInst;
269 TmpInst.setOpcode(Opcode);
270 TmpInst.addOperand(MCOperand::createReg(Reg0));
271 TmpInst.addOperand(MCOperand::createReg(Reg1));
272 TmpInst.addOperand(MCOperand::createImm(Imm0));
273 TmpInst.addOperand(MCOperand::createImm(Imm1));
274 TmpInst.addOperand(MCOperand::createImm(Imm2));
275 TmpInst.setLoc(IDLoc);
276 getStreamer().emitInstruction(TmpInst, *STI);
277}
278
280 MCRegister TrgReg, bool Is64Bit,
281 const MCSubtargetInfo *STI) {
282 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
283 STI);
284}
285
287 int16_t ShiftAmount, SMLoc IDLoc,
288 const MCSubtargetInfo *STI) {
289 if (ShiftAmount >= 32) {
290 emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc, STI);
291 return;
292 }
293
294 emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, STI);
295}
296
298 const MCSubtargetInfo *STI) {
299 // The default case of `nop` is `sll $zero, $zero, 0`.
300 unsigned Opc = Mips::SLL;
301 if (isMicroMips(STI) && hasShortDelaySlot) {
302 Opc = isMips32r6(STI) ? Mips::MOVE16_MMR6 : Mips::MOVE16_MM;
303 emitRR(Opc, Mips::ZERO, Mips::ZERO, IDLoc, STI);
304 return;
305 }
306
307 if (isMicroMips(STI))
308 Opc = isMips32r6(STI) ? Mips::SLL_MMR6 : Mips::SLL_MM;
309
310 emitRRI(Opc, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
311}
312
314 if (isMicroMips(STI))
315 emitRR(Mips::MOVE16_MM, Mips::ZERO, Mips::ZERO, IDLoc, STI);
316 else
317 emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
318}
319
320/// Emit the $gp restore operation for .cprestore.
322 const MCSubtargetInfo *STI) {
323 emitLoadWithImmOffset(Mips::LW, GPReg, Mips::SP, Offset, GPReg, IDLoc, STI);
324}
325
326/// Emit a store instruction with an immediate offset.
328 unsigned Opcode, MCRegister SrcReg, MCRegister BaseReg, int64_t Offset,
329 function_ref<MCRegister()> GetATReg, SMLoc IDLoc,
330 const MCSubtargetInfo *STI) {
331 if (isInt<16>(Offset)) {
332 emitRRI(Opcode, SrcReg, BaseReg, Offset, IDLoc, STI);
333 return;
334 }
335
336 // sw $8, offset($8) => lui $at, %hi(offset)
337 // add $at, $at, $8
338 // sw $8, %lo(offset)($at)
339
340 MCRegister ATReg = GetATReg();
341 if (!ATReg)
342 return;
343
344 unsigned LoOffset = Offset & 0x0000ffff;
345 unsigned HiOffset = (Offset & 0xffff0000) >> 16;
346
347 // If msb of LoOffset is 1(negative number) we must increment HiOffset
348 // to account for the sign-extension of the low part.
349 if (LoOffset & 0x8000)
350 HiOffset++;
351
352 // Generate the base address in ATReg.
353 emitRI(Mips::LUi, ATReg, HiOffset, IDLoc, STI);
354 if (BaseReg != Mips::ZERO)
355 emitRRR(Mips::ADDu, ATReg, ATReg, BaseReg, IDLoc, STI);
356 // Emit the store with the adjusted base and offset.
357 emitRRI(Opcode, SrcReg, ATReg, LoOffset, IDLoc, STI);
358}
359
360/// Emit a load instruction with an immediate offset. DstReg and TmpReg are
361/// permitted to be the same register iff DstReg is distinct from BaseReg and
362/// DstReg is a GPR. It is the callers responsibility to identify such cases
363/// and pass the appropriate register in TmpReg.
365 unsigned Opcode, MCRegister DstReg, MCRegister BaseReg, int64_t Offset,
366 MCRegister TmpReg, SMLoc IDLoc, const MCSubtargetInfo *STI) {
367 if (isInt<16>(Offset)) {
368 emitRRI(Opcode, DstReg, BaseReg, Offset, IDLoc, STI);
369 return;
370 }
371
372 // 1) lw $8, offset($9) => lui $8, %hi(offset)
373 // add $8, $8, $9
374 // lw $8, %lo(offset)($9)
375 // 2) lw $8, offset($8) => lui $at, %hi(offset)
376 // add $at, $at, $8
377 // lw $8, %lo(offset)($at)
378
379 unsigned LoOffset = Offset & 0x0000ffff;
380 unsigned HiOffset = (Offset & 0xffff0000) >> 16;
381
382 // If msb of LoOffset is 1(negative number) we must increment HiOffset
383 // to account for the sign-extension of the low part.
384 if (LoOffset & 0x8000)
385 HiOffset++;
386
387 // Generate the base address in TmpReg.
388 emitRI(Mips::LUi, TmpReg, HiOffset, IDLoc, STI);
389 if (BaseReg != Mips::ZERO)
390 emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
391 // Emit the load with the adjusted base and offset.
392 emitRRI(Opcode, DstReg, TmpReg, LoOffset, IDLoc, STI);
393}
394
398
400 auto &MAI = getStreamer().getContext().getAsmInfo();
401 OS << "\t.dtprelword\t";
402 MAI.printExpr(OS, *Value);
403 OS << '\n';
404}
405
407 auto &MAI = getStreamer().getContext().getAsmInfo();
408 OS << "\t.dtpreldword\t";
409 MAI.printExpr(OS, *Value);
410 OS << '\n';
411}
412
414 auto &MAI = getStreamer().getContext().getAsmInfo();
415 OS << "\t.tprelword\t";
416 MAI.printExpr(OS, *Value);
417 OS << '\n';
418}
419
421 auto &MAI = getStreamer().getContext().getAsmInfo();
422 OS << "\t.tpreldword\t";
423 MAI.printExpr(OS, *Value);
424 OS << '\n';
425}
426
428 auto &MAI = getStreamer().getContext().getAsmInfo();
429 OS << "\t.gpword\t";
430 MAI.printExpr(OS, *Value);
431 OS << '\n';
432}
433
435 auto &MAI = getStreamer().getContext().getAsmInfo();
436 OS << "\t.gpdword\t";
437 MAI.printExpr(OS, *Value);
438 OS << '\n';
439}
440
442 OS << "\t.set\tmicromips\n";
444}
445
447 OS << "\t.set\tnomicromips\n";
449}
450
452 OS << "\t.set\tmips16\n";
454}
455
460
465
467 OS << "\t.set\tnoreorder\n";
469}
470
475
480
485
490
495
500
505
510
515
520
525
530
535
540
545
547 OS << "\t.set\tat=$" << Twine(RegNo) << "\n";
549}
550
555
557 OS << "\t.end\t" << Name << '\n';
558}
559
561 OS << "\t.ent\t" << Symbol.getName() << '\n';
562}
563
564void MipsTargetAsmStreamer::emitDirectiveAbiCalls() { OS << "\t.abicalls\n"; }
565
566void MipsTargetAsmStreamer::emitDirectiveNaN2008() { OS << "\t.nan\t2008\n"; }
567
569 OS << "\t.nan\tlegacy\n";
570}
571
573 OS << "\t.option\tpic0\n";
574}
575
577 OS << "\t.option\tpic2\n";
578}
579
584
585void MipsTargetAsmStreamer::emitFrame(MCRegister StackReg, unsigned StackSize,
587 OS << "\t.frame\t$"
589 << StackSize << ",$"
591}
592
594 OS << "\t.set arch=" << Arch << "\n";
596}
597
602
607
612
617
622
627
632
637
642
647
652
657
662
667
672
677
682
687
692
697
702
707
712
717
722
723// Print a 32 bit hex number with all numbers.
724static void printHex32(unsigned Value, raw_ostream &OS) {
725 OS << "0x";
726 for (int i = 7; i >= 0; i--)
727 OS.write_hex((Value & (0xF << (i * 4))) >> (i * 4));
728}
729
730void MipsTargetAsmStreamer::emitMask(unsigned CPUBitmask,
731 int CPUTopSavedRegOff) {
732 OS << "\t.mask \t";
733 printHex32(CPUBitmask, OS);
734 OS << ',' << CPUTopSavedRegOff << '\n';
735}
736
737void MipsTargetAsmStreamer::emitFMask(unsigned FPUBitmask,
738 int FPUTopSavedRegOff) {
739 OS << "\t.fmask\t";
740 printHex32(FPUBitmask, OS);
741 OS << "," << FPUTopSavedRegOff << '\n';
742}
743
749
755
761
763 int Offset, function_ref<MCRegister()> GetATReg, SMLoc IDLoc,
764 const MCSubtargetInfo *STI) {
766 OS << "\t.cprestore\t" << Offset << "\n";
767 return true;
768}
769
771 int RegOrOffset,
772 const MCSymbol &Sym,
773 bool IsReg) {
774 OS << "\t.cpsetup\t$"
776
777 if (IsReg)
778 OS << "$"
780 else
781 OS << RegOrOffset;
782
783 OS << ", ";
784
785 OS << Sym.getName();
787}
788
790 bool SaveLocationIsRegister) {
791 OS << "\t.cpreturn";
793}
794
798 OS << "\t.module\tsoftfloat\n";
799 else
800 OS << "\t.module\tfp=" << ABIFlagsSection.getFpABIString(FpABI) << "\n";
801}
802
810
813
814 OS << "\t.module\t" << (ABIFlagsSection.OddSPReg ? "" : "no") << "oddspreg\n";
815}
816
821
826
828 OS << "\t.module\tsoftfloat\n";
829}
830
832 OS << "\t.module\thardfloat\n";
833}
834
836 OS << "\t.module\tmt\n";
837}
838
840 OS << "\t.module\tcrc\n";
841}
842
844 OS << "\t.module\tnocrc\n";
845}
846
848 OS << "\t.module\tvirt\n";
849}
850
852 OS << "\t.module\tnovirt\n";
853}
854
856 OS << "\t.module\tginv\n";
857}
858
860 OS << "\t.module\tnoginv\n";
861}
862
863// This part is for ELF object output.
865 const MCSubtargetInfo &STI)
866 : MipsTargetStreamer(S), MicroMipsEnabled(false), STI(STI) {
869
870 // It's possible that MCObjectFileInfo isn't fully initialized at this point
871 // due to an initialization order problem where CodeGenTargetMachineImpl
872 // creates the target streamer before TargetLoweringObjectFile calls
873 // InitializeMCObjectFileInfo. There doesn't seem to be a single place that
874 // covers all cases so this statement covers most cases and direct object
875 // emission must call setPic() once MCObjectFileInfo has been initialized. The
876 // cases we don't handle here are covered by MipsAsmPrinter.
878
879 const FeatureBitset &Features = STI.getFeatureBits();
880
881 // Set the header flags that we can in the constructor.
882 // FIXME: This is a fairly terrible hack. We set the rest
883 // of these in the destructor. The problem here is two-fold:
884 //
885 // a: Some of the eflags can be set/reset by directives.
886 // b: There aren't any usage paths that initialize the ABI
887 // pointer until after we initialize either an assembler
888 // or the target machine.
889 // We can fix this by making the target streamer construct
890 // the ABI, but this is fraught with wide ranging dependency
891 // issues as well.
892 unsigned EFlags = W.getELFHeaderEFlags();
893
894 // FIXME: Fix a dependency issue by instantiating the ABI object to some
895 // default based off the triple. The triple doesn't describe the target
896 // fully, but any external user of the API that uses the MCTargetStreamer
897 // would otherwise crash on assertion failure.
898
900 STI.getTargetTriple().getArch() == Triple::ArchType::mipsel ||
901 STI.getTargetTriple().getArch() == Triple::ArchType::mips
903 : MipsABIInfo::N64());
904
905 // Architecture
906 if (Features[Mips::FeatureMips64r6])
907 EFlags |= ELF::EF_MIPS_ARCH_64R6;
908 else if (Features[Mips::FeatureMips64r2] ||
909 Features[Mips::FeatureMips64r3] ||
910 Features[Mips::FeatureMips64r5])
911 EFlags |= ELF::EF_MIPS_ARCH_64R2;
912 else if (Features[Mips::FeatureMips64])
913 EFlags |= ELF::EF_MIPS_ARCH_64;
914 else if (Features[Mips::FeatureMips5])
915 EFlags |= ELF::EF_MIPS_ARCH_5;
916 else if (Features[Mips::FeatureMips4])
917 EFlags |= ELF::EF_MIPS_ARCH_4;
918 else if (Features[Mips::FeatureMips3])
919 EFlags |= ELF::EF_MIPS_ARCH_3;
920 else if (Features[Mips::FeatureMips32r6])
921 EFlags |= ELF::EF_MIPS_ARCH_32R6;
922 else if (Features[Mips::FeatureMips32r2] ||
923 Features[Mips::FeatureMips32r3] ||
924 Features[Mips::FeatureMips32r5])
925 EFlags |= ELF::EF_MIPS_ARCH_32R2;
926 else if (Features[Mips::FeatureMips32])
927 EFlags |= ELF::EF_MIPS_ARCH_32;
928 else if (Features[Mips::FeatureMips2])
929 EFlags |= ELF::EF_MIPS_ARCH_2;
930 else
931 EFlags |= ELF::EF_MIPS_ARCH_1;
932
933 // Machine
934 if (Features[Mips::FeatureCnMips])
935 EFlags |= ELF::EF_MIPS_MACH_OCTEON;
936 else if (Features[Mips::FeatureR5900])
937 EFlags |= ELF::EF_MIPS_MACH_5900;
938
939 // Other options.
940 if (Features[Mips::FeatureNaN2008])
941 EFlags |= ELF::EF_MIPS_NAN2008;
942
943 W.setELFHeaderEFlags(EFlags);
944}
945
947 auto *Symbol = static_cast<MCSymbolELF *>(S);
949 uint8_t Type = Symbol->getType();
950 if (Type != ELF::STT_FUNC)
951 return;
952
953 if (isMicroMipsEnabled())
954 Symbol->setOther(ELF::STO_MIPS_MICROMIPS);
955}
956
960 const MCObjectFileInfo &OFI = *MCA.getContext().getObjectFileInfo();
962
963 // .bss, .text and .data are always at least 16-byte aligned.
964 MCSection &TextSection = *OFI.getTextSection();
965 S.switchSection(&TextSection);
966 MCSection &DataSection = *OFI.getDataSection();
967 S.switchSection(&DataSection);
968 MCSection &BSSSection = *OFI.getBSSSection();
969 S.switchSection(&BSSSection);
970
971 TextSection.ensureMinAlignment(Align(16));
972 DataSection.ensureMinAlignment(Align(16));
973 BSSSection.ensureMinAlignment(Align(16));
974
975 if (RoundSectionSizes) {
976 // Make sections sizes a multiple of the alignment. This is useful for
977 // verifying the output of IAS against the output of other assemblers but
978 // it's not necessary to produce a correct object and increases section
979 // size.
980 for (MCSection &Sec : MCA) {
981 MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
982
983 Align Alignment = Section.getAlign();
984 S.switchSection(&Section);
985 if (getContext().getAsmInfo().useCodeAlign(Section))
986 S.emitCodeAlignment(Alignment, STI, Alignment.value());
987 else
988 S.emitValueToAlignment(Alignment, 0, 1, Alignment.value());
989 }
990 }
991
992 const FeatureBitset &Features = STI.getFeatureBits();
993
994 // Update e_header flags. See the FIXME and comment above in
995 // the constructor for a full rundown on this.
996 unsigned EFlags = W.getELFHeaderEFlags();
997
998 // ABI
999 // N64 does not require any ABI bits.
1000 if (getABI().IsO32())
1001 EFlags |= ELF::EF_MIPS_ABI_O32;
1002 else if (getABI().IsN32())
1003 EFlags |= ELF::EF_MIPS_ABI2;
1004
1005 if (Features[Mips::FeatureGP64Bit]) {
1006 if (getABI().IsO32())
1007 EFlags |= ELF::EF_MIPS_32BITMODE; /* Compatibility Mode */
1008 } else if (Features[Mips::FeatureMips64r2] || Features[Mips::FeatureMips64])
1009 EFlags |= ELF::EF_MIPS_32BITMODE;
1010
1011 // -mplt is not implemented but we should act as if it was
1012 // given.
1013 if (!Features[Mips::FeatureNoABICalls])
1014 EFlags |= ELF::EF_MIPS_CPIC;
1015
1016 if (Pic)
1018
1019 W.setELFHeaderEFlags(EFlags);
1020
1021 // Emit all the option records.
1022 // At the moment we are only emitting .Mips.options (ODK_REGINFO) and
1023 // .reginfo.
1024 MipsELFStreamer &MEF = static_cast<MipsELFStreamer &>(Streamer);
1026
1028}
1029
1031 auto *Symbol = static_cast<MCSymbolELF *>(S);
1032 // If on rhs is micromips symbol then mark Symbol as microMips.
1033 if (Value->getKind() != MCExpr::SymbolRef)
1034 return;
1035 auto &RhsSym = static_cast<const MCSymbolELF &>(
1036 static_cast<const MCSymbolRefExpr *>(Value)->getSymbol());
1037
1038 if (!(RhsSym.getOther() & ELF::STO_MIPS_MICROMIPS))
1039 return;
1040
1042}
1043
1047
1049 auto &S = getStreamer();
1050 S.ensureHeadroom(4);
1051 S.addFixup(Value, Mips::fixup_Mips_GPREL32);
1052 S.appendContents(4, 0);
1053}
1054
1056 auto &S = getStreamer();
1057 S.ensureHeadroom(8);
1058 // fixup_Mips_GPREL32 desginates R_MIPS_GPREL32+R_MIPS_64 on MIPS64.
1059 S.addFixup(Value, Mips::fixup_Mips_GPREL32);
1060 S.appendContents(8, 0);
1061}
1062
1064 auto &S = getStreamer();
1065 S.ensureHeadroom(4);
1066 S.addFixup(Value, Mips::fixup_Mips_DTPREL32);
1067 S.appendContents(4, 0);
1068}
1069
1071 auto &S = getStreamer();
1072 S.ensureHeadroom(8);
1073 S.addFixup(Value, Mips::fixup_Mips_DTPREL64);
1074 S.appendContents(8, 0);
1075}
1076
1078 auto &S = getStreamer();
1079 S.ensureHeadroom(4);
1080 S.addFixup(Value, Mips::fixup_Mips_TPREL32);
1081 S.appendContents(4, 0);
1082}
1083
1085 auto &S = getStreamer();
1086 S.ensureHeadroom(8);
1087 S.addFixup(Value, Mips::fixup_Mips_TPREL64);
1088 S.appendContents(8, 0);
1089}
1090
1092 MicroMipsEnabled = true;
1094}
1095
1097 MicroMipsEnabled = false;
1099}
1100
1103 unsigned Flags = W.getELFHeaderEFlags();
1104 Flags |= ELF::EF_MIPS_MICROMIPS;
1105 W.setELFHeaderEFlags(Flags);
1106}
1107
1110 unsigned Flags = W.getELFHeaderEFlags();
1112 W.setELFHeaderEFlags(Flags);
1114}
1115
1118 unsigned Flags = W.getELFHeaderEFlags();
1119 Flags |= ELF::EF_MIPS_NOREORDER;
1120 W.setELFHeaderEFlags(Flags);
1122}
1123
1126 MCContext &Context = MCA.getContext();
1127 MCStreamer &OS = getStreamer();
1128
1129 OS.pushSection();
1130 MCSectionELF *Sec = Context.getELFSection(".pdr", ELF::SHT_PROGBITS, 0);
1131 OS.switchSection(Sec);
1132 Sec->setAlignment(Align(4));
1133
1134 MCSymbol *Sym = Context.getOrCreateSymbol(Name);
1135 const auto *ExprRef = MCSymbolRefExpr::create(Sym, Context);
1136 OS.emitValueImpl(ExprRef, 4);
1137
1138 OS.emitIntValue(GPRInfoSet ? GPRBitMask : 0, 4); // reg_mask
1139 OS.emitIntValue(GPRInfoSet ? GPROffset : 0, 4); // reg_offset
1140
1141 OS.emitIntValue(FPRInfoSet ? FPRBitMask : 0, 4); // fpreg_mask
1142 OS.emitIntValue(FPRInfoSet ? FPROffset : 0, 4); // fpreg_offset
1143
1144 OS.emitIntValue(FrameInfoSet ? FrameOffset : 0, 4); // frame_offset
1145 OS.emitIntValue(FrameInfoSet ? FrameReg : 0, 4); // frame_reg
1146 OS.emitIntValue(FrameInfoSet ? ReturnReg : 0, 4); // return_reg
1147
1148 // The .end directive marks the end of a procedure. Invalidate
1149 // the information gathered up until this point.
1151
1152 OS.popSection();
1153
1154 // .end also implicitly sets the size.
1155 MCSymbol *CurPCSym = Context.createTempSymbol();
1156 OS.emitLabel(CurPCSym);
1158 MCSymbolRefExpr::create(CurPCSym, Context), ExprRef, Context);
1159
1160 // The ELFObjectWriter can determine the absolute size as it has access to
1161 // the layout information of the assembly file, so a size expression rather
1162 // than an absolute value is ok here.
1163 static_cast<MCSymbolELF *>(Sym)->setSize(Size);
1164}
1165
1168
1169 // .ent also acts like an implicit '.type symbol, STT_FUNC'
1170 static_cast<const MCSymbolELF &>(Symbol).setType(ELF::STT_FUNC);
1171}
1172
1175 unsigned Flags = W.getELFHeaderEFlags();
1177 W.setELFHeaderEFlags(Flags);
1178}
1179
1182 unsigned Flags = W.getELFHeaderEFlags();
1183 Flags |= ELF::EF_MIPS_NAN2008;
1184 W.setELFHeaderEFlags(Flags);
1185}
1186
1189 unsigned Flags = W.getELFHeaderEFlags();
1190 Flags &= ~ELF::EF_MIPS_NAN2008;
1191 W.setELFHeaderEFlags(Flags);
1192}
1193
1196 unsigned Flags = W.getELFHeaderEFlags();
1197 // This option overrides other PIC options like -KPIC.
1198 Pic = false;
1199 Flags &= ~ELF::EF_MIPS_PIC;
1200 W.setELFHeaderEFlags(Flags);
1201}
1202
1205 unsigned Flags = W.getELFHeaderEFlags();
1206 Pic = true;
1207 // NOTE: We are following the GAS behaviour here which means the directive
1208 // 'pic2' also sets the CPIC bit in the ELF header. This is different from
1209 // what is stated in the SYSV ABI which consider the bits EF_MIPS_PIC and
1210 // EF_MIPS_CPIC to be mutually exclusive.
1212 W.setELFHeaderEFlags(Flags);
1213}
1214
1220
1221void MipsTargetELFStreamer::emitFrame(MCRegister StackReg, unsigned StackSize,
1222 MCRegister ReturnReg_) {
1224 const MCRegisterInfo *RegInfo = Context.getRegisterInfo();
1225
1226 FrameInfoSet = true;
1227 FrameReg = RegInfo->getEncodingValue(StackReg);
1228 FrameOffset = StackSize;
1229 ReturnReg = RegInfo->getEncodingValue(ReturnReg_);
1230}
1231
1232void MipsTargetELFStreamer::emitMask(unsigned CPUBitmask,
1233 int CPUTopSavedRegOff) {
1234 GPRInfoSet = true;
1235 GPRBitMask = CPUBitmask;
1236 GPROffset = CPUTopSavedRegOff;
1237}
1238
1239void MipsTargetELFStreamer::emitFMask(unsigned FPUBitmask,
1240 int FPUTopSavedRegOff) {
1241 FPRInfoSet = true;
1242 FPRBitMask = FPUBitmask;
1243 FPROffset = FPUTopSavedRegOff;
1244}
1245
1247 // .cpadd $reg
1248 // This directive inserts code to add $gp to the argument's register
1249 // when support for position independent code is enabled.
1250 if (!Pic)
1251 return;
1252
1253 emitAddu(Reg, Reg, GPReg, getABI().IsN64(), &STI);
1255}
1256
1258 // .cpload $reg
1259 // This directive expands to:
1260 // lui $gp, %hi(_gp_disp)
1261 // addui $gp, $gp, %lo(_gp_disp)
1262 // addu $gp, $gp, $reg
1263 // when support for position independent code is enabled.
1264 if (!Pic || (getABI().IsN32() || getABI().IsN64()))
1265 return;
1266
1267 // There's a GNU extension controlled by -mno-shared that allows
1268 // locally-binding symbols to be accessed using absolute addresses.
1269 // This is currently not supported. When supported -mno-shared makes
1270 // .cpload expand to:
1271 // lui $gp, %hi(__gnu_local_gp)
1272 // addiu $gp, $gp, %lo(__gnu_local_gp)
1273
1274 StringRef SymName("_gp_disp");
1276 MCSymbol *GP_Disp = MCA.getContext().getOrCreateSymbol(SymName);
1277 MCA.registerSymbol(*GP_Disp);
1278
1279 MCInst TmpInst;
1280 TmpInst.setOpcode(Mips::LUi);
1282 auto *HiSym = MCSpecifierExpr::create(GP_Disp, Mips::S_HI, MCA.getContext());
1283 TmpInst.addOperand(MCOperand::createExpr(HiSym));
1284 getStreamer().emitInstruction(TmpInst, STI);
1285
1286 TmpInst.clear();
1287
1288 TmpInst.setOpcode(Mips::ADDiu);
1291 auto *LoSym = MCSpecifierExpr::create(GP_Disp, Mips::S_LO, MCA.getContext());
1292 TmpInst.addOperand(MCOperand::createExpr(LoSym));
1293 getStreamer().emitInstruction(TmpInst, STI);
1294
1295 TmpInst.clear();
1296
1297 TmpInst.setOpcode(Mips::ADDu);
1300 TmpInst.addOperand(MCOperand::createReg(Reg));
1301 getStreamer().emitInstruction(TmpInst, STI);
1302
1304}
1305
1310
1312 int Offset, function_ref<MCRegister()> GetATReg, SMLoc IDLoc,
1313 const MCSubtargetInfo *STI) {
1315 // .cprestore offset
1316 // When PIC mode is enabled and the O32 ABI is used, this directive expands
1317 // to:
1318 // sw $gp, offset($sp)
1319 // and adds a corresponding LW after every JAL.
1320
1321 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
1322 // is used in non-PIC mode.
1323 if (!Pic || (getABI().IsN32() || getABI().IsN64()))
1324 return true;
1325
1326 // Store the $gp on the stack.
1327 emitStoreWithImmOffset(Mips::SW, GPReg, Mips::SP, Offset, GetATReg, IDLoc,
1328 STI);
1329 return true;
1330}
1331
1333 int RegOrOffset,
1334 const MCSymbol &Sym,
1335 bool IsReg) {
1336 // Only N32 and N64 emit anything for .cpsetup iff PIC is set.
1337 if (!Pic || !(getABI().IsN32() || getABI().IsN64()))
1338 return;
1339
1341
1343 MCInst Inst;
1344
1345 // Either store the old $gp in a register or on the stack
1346 if (IsReg) {
1347 // move $save, $gpreg
1348 emitRRR(Mips::OR64, RegOrOffset, GPReg, Mips::ZERO, SMLoc(), &STI);
1349 } else {
1350 // sd $gpreg, offset($sp)
1351 emitRRI(Mips::SD, GPReg, Mips::SP, RegOrOffset, SMLoc(), &STI);
1352 }
1353
1354 auto *HiExpr =
1356 Mips::S_HI, MCA.getContext());
1357 auto *LoExpr =
1359 Mips::S_LO, MCA.getContext());
1360
1361 // lui $gp, %hi(%neg(%gp_rel(funcSym)))
1362 emitRX(Mips::LUi, GPReg, MCOperand::createExpr(HiExpr), SMLoc(), &STI);
1363
1364 // addiu $gp, $gp, %lo(%neg(%gp_rel(funcSym)))
1365 emitRRX(Mips::ADDiu, GPReg, GPReg, MCOperand::createExpr(LoExpr), SMLoc(),
1366 &STI);
1367
1368 // (d)addu $gp, $gp, $funcreg
1369 if (getABI().IsN32())
1370 emitRRR(Mips::ADDu, GPReg, GPReg, Reg, SMLoc(), &STI);
1371 else
1372 emitRRR(Mips::DADDu, GPReg, GPReg, Reg, SMLoc(), &STI);
1373}
1374
1376 bool SaveLocationIsRegister) {
1377 // Only N32 and N64 emit anything for .cpreturn iff PIC is set.
1378 if (!Pic || !(getABI().IsN32() || getABI().IsN64()))
1379 return;
1380
1381 MCInst Inst;
1382 // Either restore the old $gp from a register or on the stack
1383 if (SaveLocationIsRegister) {
1384 Inst.setOpcode(Mips::OR);
1386 Inst.addOperand(MCOperand::createReg(SaveLocation));
1387 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
1388 } else {
1389 Inst.setOpcode(Mips::LD);
1391 Inst.addOperand(MCOperand::createReg(Mips::SP));
1392 Inst.addOperand(MCOperand::createImm(SaveLocation));
1393 }
1394 getStreamer().emitInstruction(Inst, STI);
1395
1397}
1398
1401 MCContext &Context = MCA.getContext();
1402 MCStreamer &OS = getStreamer();
1403 MCSectionELF *Sec = Context.getELFSection(
1404 ".MIPS.abiflags", ELF::SHT_MIPS_ABIFLAGS, ELF::SHF_ALLOC, 24);
1405 OS.switchSection(Sec);
1406 Sec->setAlignment(Align(8));
1407
1408 OS << ABIFlagsSection;
1409}
unsigned Imm
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:427
Context object for machine code objects.
Definition MCContext.h:83
const MCObjectFileInfo * getObjectFileInfo() const
Definition MCContext.h:413
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
const MCAsmInfo & getAsmInfo() const
Definition MCContext.h:409
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 emitCodeAlignment(Align ByteAlignment, const MCSubtargetInfo &STI, unsigned MaxBytesToEmit=0) override
Emit nops until the byte alignment ByteAlignment is reached.
void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override
Emit the given Instruction into the current section.
Instances of this class represent operands of the MCInst class.
Definition MCInst.h: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:580
void setAlignment(Align Value)
Definition MCSection.h:665
void ensureMinAlignment(Align MinAlignment)
Makes sure that Alignment is at least MinAlignment.
Definition MCSection.h:668
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:222
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:326
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:460
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
LLVM_ABI 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:226
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:213
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:103
MCContext & getContext()
MCStreamer & Streamer
Definition MCStreamer.h:97
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, unsigned AltIdx=Mips::NoRegAltName)
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
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
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:46
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:1259
@ STO_MIPS_MICROMIPS
Definition ELF.h:602
@ SHT_PROGBITS
Definition ELF.h:1157
@ SHT_MIPS_ABIFLAGS
Definition ELF.h:1238
@ 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:1435
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.
@ Offset
Definition DWP.cpp:577
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:166
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