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.
864MipsTargetELFStreamer::ISAMode
865MipsTargetELFStreamer::getISAMode(const MCSubtargetInfo &STI) {
866 if (STI.hasFeature(Mips::FeatureMips16))
867 return ISAMode::Mips16;
868 if (STI.hasFeature(Mips::FeatureMicroMips))
869 return ISAMode::MicroMips;
870 return ISAMode::Standard;
871}
872
874 const MCSubtargetInfo &STI)
875 : MipsTargetStreamer(S), Mode(getISAMode(STI)), STI(STI) {
878
879 // It's possible that MCObjectFileInfo isn't fully initialized at this point
880 // due to an initialization order problem where CodeGenTargetMachineImpl
881 // creates the target streamer before TargetLoweringObjectFile calls
882 // InitializeMCObjectFileInfo. There doesn't seem to be a single place that
883 // covers all cases so this statement covers most cases and direct object
884 // emission must call setPic() once MCObjectFileInfo has been initialized. The
885 // cases we don't handle here are covered by MipsAsmPrinter.
887
888 const FeatureBitset &Features = STI.getFeatureBits();
889
890 // Set the header flags that we can in the constructor.
891 // FIXME: This is a fairly terrible hack. We set the rest
892 // of these in the destructor. The problem here is two-fold:
893 //
894 // a: Some of the eflags can be set/reset by directives.
895 // b: There aren't any usage paths that initialize the ABI
896 // pointer until after we initialize either an assembler
897 // or the target machine.
898 // We can fix this by making the target streamer construct
899 // the ABI, but this is fraught with wide ranging dependency
900 // issues as well.
901 unsigned EFlags = W.getELFHeaderEFlags();
902
903 // FIXME: Fix a dependency issue by instantiating the ABI object to some
904 // default based off the triple. The triple doesn't describe the target
905 // fully, but any external user of the API that uses the MCTargetStreamer
906 // would otherwise crash on assertion failure.
907
908 ABI = MipsABIInfo(STI.getTargetTriple().isMIPS32() ? MipsABIInfo::O32()
909 : MipsABIInfo::N64());
910
911 // Architecture
912 if (Features[Mips::FeatureMips64r6])
913 EFlags |= ELF::EF_MIPS_ARCH_64R6;
914 else if (Features[Mips::FeatureMips64r2] ||
915 Features[Mips::FeatureMips64r3] ||
916 Features[Mips::FeatureMips64r5])
917 EFlags |= ELF::EF_MIPS_ARCH_64R2;
918 else if (Features[Mips::FeatureMips64])
919 EFlags |= ELF::EF_MIPS_ARCH_64;
920 else if (Features[Mips::FeatureMips5])
921 EFlags |= ELF::EF_MIPS_ARCH_5;
922 else if (Features[Mips::FeatureMips4])
923 EFlags |= ELF::EF_MIPS_ARCH_4;
924 else if (Features[Mips::FeatureMips3])
925 EFlags |= ELF::EF_MIPS_ARCH_3;
926 else if (Features[Mips::FeatureMips32r6])
927 EFlags |= ELF::EF_MIPS_ARCH_32R6;
928 else if (Features[Mips::FeatureMips32r2] ||
929 Features[Mips::FeatureMips32r3] ||
930 Features[Mips::FeatureMips32r5])
931 EFlags |= ELF::EF_MIPS_ARCH_32R2;
932 else if (Features[Mips::FeatureMips32])
933 EFlags |= ELF::EF_MIPS_ARCH_32;
934 else if (Features[Mips::FeatureMips2])
935 EFlags |= ELF::EF_MIPS_ARCH_2;
936 else
937 EFlags |= ELF::EF_MIPS_ARCH_1;
938
939 // Machine
940 if (Features[Mips::FeatureCnMips])
941 EFlags |= ELF::EF_MIPS_MACH_OCTEON;
942 else if (Features[Mips::FeatureR5900])
943 EFlags |= ELF::EF_MIPS_MACH_5900;
944
945 // Other options.
946 if (isMips16Enabled())
948 if (Features[Mips::FeatureNaN2008])
949 EFlags |= ELF::EF_MIPS_NAN2008;
950
951 W.setELFHeaderEFlags(EFlags);
952}
953
955 auto *Symbol = static_cast<MCSymbolELF *>(S);
957 uint8_t Type = Symbol->getType();
958 if (Type != ELF::STT_FUNC)
959 return;
960
961 if (isMicroMipsEnabled())
962 Symbol->setOther(ELF::STO_MIPS_MICROMIPS);
963 else if (isMips16Enabled())
964 Symbol->setOther(ELF::STO_MIPS_MIPS16);
965}
966
970 const MCObjectFileInfo &OFI = *MCA.getContext().getObjectFileInfo();
972
973 // .bss, .text and .data are always at least 16-byte aligned.
974 MCSection &TextSection = *OFI.getTextSection();
975 S.switchSection(&TextSection);
976 MCSection &DataSection = *OFI.getDataSection();
977 S.switchSection(&DataSection);
978 MCSection &BSSSection = *OFI.getBSSSection();
979 S.switchSection(&BSSSection);
980
981 TextSection.ensureMinAlignment(Align(16));
982 DataSection.ensureMinAlignment(Align(16));
983 BSSSection.ensureMinAlignment(Align(16));
984
985 if (RoundSectionSizes) {
986 // Make sections sizes a multiple of the alignment. This is useful for
987 // verifying the output of IAS against the output of other assemblers but
988 // it's not necessary to produce a correct object and increases section
989 // size.
990 for (MCSection &Sec : MCA) {
991 MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
992
993 Align Alignment = Section.getAlign();
994 S.switchSection(&Section);
995 if (getContext().getAsmInfo().useCodeAlign(Section))
996 S.emitCodeAlignment(Alignment, STI, Alignment.value());
997 else
998 S.emitValueToAlignment(Alignment, 0, 1, Alignment.value());
999 }
1000 }
1001
1002 const FeatureBitset &Features = STI.getFeatureBits();
1003
1004 // Update e_header flags. See the FIXME and comment above in
1005 // the constructor for a full rundown on this.
1006 unsigned EFlags = W.getELFHeaderEFlags();
1007
1008 // ABI
1009 // N64 does not require any ABI bits.
1010 if (getABI().IsO32())
1011 EFlags |= ELF::EF_MIPS_ABI_O32;
1012 else if (getABI().IsN32())
1013 EFlags |= ELF::EF_MIPS_ABI2;
1014
1015 if (Features[Mips::FeatureGP64Bit]) {
1016 if (getABI().IsO32())
1017 EFlags |= ELF::EF_MIPS_32BITMODE; /* Compatibility Mode */
1018 } else if (Features[Mips::FeatureMips64r2] || Features[Mips::FeatureMips64])
1019 EFlags |= ELF::EF_MIPS_32BITMODE;
1020
1021 // -mplt is not implemented but we should act as if it was
1022 // given.
1023 if (!Features[Mips::FeatureNoABICalls])
1024 EFlags |= ELF::EF_MIPS_CPIC;
1025
1026 if (Pic)
1028
1029 W.setELFHeaderEFlags(EFlags);
1030
1031 // Emit all the option records.
1032 // At the moment we are only emitting .Mips.options (ODK_REGINFO) and
1033 // .reginfo.
1034 MipsELFStreamer &MEF = static_cast<MipsELFStreamer &>(Streamer);
1036
1038}
1039
1041 auto *Symbol = static_cast<MCSymbolELF *>(S);
1042 // Propagate the ISA mode of a symbol to its alias.
1043 if (Value->getKind() != MCExpr::SymbolRef)
1044 return;
1045 auto &RhsSym = static_cast<const MCSymbolELF &>(
1046 static_cast<const MCSymbolRefExpr *>(Value)->getSymbol());
1047
1048 // Copy the target-specific flags directly; visibility is stored separately.
1049 Symbol->setOther(RhsSym.getOther());
1050}
1051
1055
1057 auto &S = getStreamer();
1058 S.ensureHeadroom(4);
1059 S.addFixup(Value, Mips::fixup_Mips_GPREL32);
1060 S.appendContents(4, 0);
1061}
1062
1064 auto &S = getStreamer();
1065 S.ensureHeadroom(8);
1066 // fixup_Mips_GPREL32 desginates R_MIPS_GPREL32+R_MIPS_64 on MIPS64.
1067 S.addFixup(Value, Mips::fixup_Mips_GPREL32);
1068 S.appendContents(8, 0);
1069}
1070
1072 auto &S = getStreamer();
1073 S.ensureHeadroom(4);
1074 S.addFixup(Value, Mips::fixup_Mips_DTPREL32);
1075 S.appendContents(4, 0);
1076}
1077
1079 auto &S = getStreamer();
1080 S.ensureHeadroom(8);
1081 S.addFixup(Value, Mips::fixup_Mips_DTPREL64);
1082 S.appendContents(8, 0);
1083}
1084
1086 auto &S = getStreamer();
1087 S.ensureHeadroom(4);
1088 S.addFixup(Value, Mips::fixup_Mips_TPREL32);
1089 S.appendContents(4, 0);
1090}
1091
1093 auto &S = getStreamer();
1094 S.ensureHeadroom(8);
1095 S.addFixup(Value, Mips::fixup_Mips_TPREL64);
1096 S.appendContents(8, 0);
1097}
1098
1100 Mode = ISAMode::MicroMips;
1102}
1103
1105 if (isMicroMipsEnabled())
1106 Mode = ISAMode::Standard;
1108}
1109
1114
1116 assert(!ModeStack.empty() && "unmatched .set pop");
1117 Mode = ModeStack.pop_back_val();
1119}
1120
1125
1128 unsigned Flags = W.getELFHeaderEFlags();
1129 Flags |= ELF::EF_MIPS_MICROMIPS;
1130 W.setELFHeaderEFlags(Flags);
1131}
1132
1134 Mode = ISAMode::Mips16;
1136 unsigned Flags = W.getELFHeaderEFlags();
1138 W.setELFHeaderEFlags(Flags);
1140}
1141
1147
1150 unsigned Flags = W.getELFHeaderEFlags();
1151 Flags |= ELF::EF_MIPS_NOREORDER;
1152 W.setELFHeaderEFlags(Flags);
1154}
1155
1158 MCContext &Context = MCA.getContext();
1159 MCStreamer &OS = getStreamer();
1160
1161 OS.pushSection();
1162 MCSectionELF *Sec = Context.getELFSection(".pdr", ELF::SHT_PROGBITS, 0);
1163 OS.switchSection(Sec);
1164 Sec->setAlignment(Align(4));
1165
1166 MCSymbol *Sym = Context.getOrCreateSymbol(Name);
1167 const auto *ExprRef = MCSymbolRefExpr::create(Sym, Context);
1168 OS.emitValueImpl(ExprRef, 4);
1169
1170 OS.emitIntValue(GPRInfoSet ? GPRBitMask : 0, 4); // reg_mask
1171 OS.emitIntValue(GPRInfoSet ? GPROffset : 0, 4); // reg_offset
1172
1173 OS.emitIntValue(FPRInfoSet ? FPRBitMask : 0, 4); // fpreg_mask
1174 OS.emitIntValue(FPRInfoSet ? FPROffset : 0, 4); // fpreg_offset
1175
1176 OS.emitIntValue(FrameInfoSet ? FrameOffset : 0, 4); // frame_offset
1177 OS.emitIntValue(FrameInfoSet ? FrameReg : 0, 4); // frame_reg
1178 OS.emitIntValue(FrameInfoSet ? ReturnReg : 0, 4); // return_reg
1179
1180 // The .end directive marks the end of a procedure. Invalidate
1181 // the information gathered up until this point.
1183
1184 OS.popSection();
1185
1186 // .end also implicitly sets the size.
1187 MCSymbol *CurPCSym = Context.createTempSymbol();
1188 OS.emitLabel(CurPCSym);
1190 MCSymbolRefExpr::create(CurPCSym, Context), ExprRef, Context);
1191
1192 // The ELFObjectWriter can determine the absolute size as it has access to
1193 // the layout information of the assembly file, so a size expression rather
1194 // than an absolute value is ok here.
1195 static_cast<MCSymbolELF *>(Sym)->setSize(Size);
1196}
1197
1200
1201 // .ent also acts like an implicit '.type symbol, STT_FUNC'
1202 static_cast<const MCSymbolELF &>(Symbol).setType(ELF::STT_FUNC);
1203}
1204
1207 unsigned Flags = W.getELFHeaderEFlags();
1209 W.setELFHeaderEFlags(Flags);
1210}
1211
1214 unsigned Flags = W.getELFHeaderEFlags();
1215 Flags |= ELF::EF_MIPS_NAN2008;
1216 W.setELFHeaderEFlags(Flags);
1217}
1218
1221 unsigned Flags = W.getELFHeaderEFlags();
1222 Flags &= ~ELF::EF_MIPS_NAN2008;
1223 W.setELFHeaderEFlags(Flags);
1224}
1225
1228 unsigned Flags = W.getELFHeaderEFlags();
1229 // This option overrides other PIC options like -KPIC.
1230 Pic = false;
1231 Flags &= ~ELF::EF_MIPS_PIC;
1232 W.setELFHeaderEFlags(Flags);
1233}
1234
1237 unsigned Flags = W.getELFHeaderEFlags();
1238 Pic = true;
1239 // NOTE: We are following the GAS behaviour here which means the directive
1240 // 'pic2' also sets the CPIC bit in the ELF header. This is different from
1241 // what is stated in the SYSV ABI which consider the bits EF_MIPS_PIC and
1242 // EF_MIPS_CPIC to be mutually exclusive.
1244 W.setELFHeaderEFlags(Flags);
1245}
1246
1252
1253void MipsTargetELFStreamer::emitFrame(MCRegister StackReg, unsigned StackSize,
1254 MCRegister ReturnReg_) {
1256 const MCRegisterInfo *RegInfo = Context.getRegisterInfo();
1257
1258 FrameInfoSet = true;
1259 FrameReg = RegInfo->getEncodingValue(StackReg);
1260 FrameOffset = StackSize;
1261 ReturnReg = RegInfo->getEncodingValue(ReturnReg_);
1262}
1263
1264void MipsTargetELFStreamer::emitMask(unsigned CPUBitmask,
1265 int CPUTopSavedRegOff) {
1266 GPRInfoSet = true;
1267 GPRBitMask = CPUBitmask;
1268 GPROffset = CPUTopSavedRegOff;
1269}
1270
1271void MipsTargetELFStreamer::emitFMask(unsigned FPUBitmask,
1272 int FPUTopSavedRegOff) {
1273 FPRInfoSet = true;
1274 FPRBitMask = FPUBitmask;
1275 FPROffset = FPUTopSavedRegOff;
1276}
1277
1279 // .cpadd $reg
1280 // This directive inserts code to add $gp to the argument's register
1281 // when support for position independent code is enabled.
1282 if (!Pic)
1283 return;
1284
1285 emitAddu(Reg, Reg, GPReg, getABI().IsN64(), &STI);
1287}
1288
1290 // .cpload $reg
1291 // This directive expands to:
1292 // lui $gp, %hi(_gp_disp)
1293 // addui $gp, $gp, %lo(_gp_disp)
1294 // addu $gp, $gp, $reg
1295 // when support for position independent code is enabled.
1296 if (!Pic || (getABI().IsN32() || getABI().IsN64()))
1297 return;
1298
1299 // There's a GNU extension controlled by -mno-shared that allows
1300 // locally-binding symbols to be accessed using absolute addresses.
1301 // This is currently not supported. When supported -mno-shared makes
1302 // .cpload expand to:
1303 // lui $gp, %hi(__gnu_local_gp)
1304 // addiu $gp, $gp, %lo(__gnu_local_gp)
1305
1306 StringRef SymName("_gp_disp");
1308 MCSymbol *GP_Disp = MCA.getContext().getOrCreateSymbol(SymName);
1309 MCA.registerSymbol(*GP_Disp);
1310
1311 MCInst TmpInst;
1312 TmpInst.setOpcode(Mips::LUi);
1314 auto *HiSym = MCSpecifierExpr::create(GP_Disp, Mips::S_HI, MCA.getContext());
1315 TmpInst.addOperand(MCOperand::createExpr(HiSym));
1316 getStreamer().emitInstruction(TmpInst, STI);
1317
1318 TmpInst.clear();
1319
1320 TmpInst.setOpcode(Mips::ADDiu);
1323 auto *LoSym = MCSpecifierExpr::create(GP_Disp, Mips::S_LO, MCA.getContext());
1324 TmpInst.addOperand(MCOperand::createExpr(LoSym));
1325 getStreamer().emitInstruction(TmpInst, STI);
1326
1327 TmpInst.clear();
1328
1329 TmpInst.setOpcode(Mips::ADDu);
1332 TmpInst.addOperand(MCOperand::createReg(Reg));
1333 getStreamer().emitInstruction(TmpInst, STI);
1334
1336}
1337
1342
1344 int Offset, function_ref<MCRegister()> GetATReg, SMLoc IDLoc,
1345 const MCSubtargetInfo *STI) {
1347 // .cprestore offset
1348 // When PIC mode is enabled and the O32 ABI is used, this directive expands
1349 // to:
1350 // sw $gp, offset($sp)
1351 // and adds a corresponding LW after every JAL.
1352
1353 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
1354 // is used in non-PIC mode.
1355 if (!Pic || (getABI().IsN32() || getABI().IsN64()))
1356 return true;
1357
1358 // Store the $gp on the stack.
1359 emitStoreWithImmOffset(Mips::SW, GPReg, Mips::SP, Offset, GetATReg, IDLoc,
1360 STI);
1361 return true;
1362}
1363
1365 int RegOrOffset,
1366 const MCSymbol &Sym,
1367 bool IsReg) {
1368 // Only N32 and N64 emit anything for .cpsetup iff PIC is set.
1369 if (!Pic || !(getABI().IsN32() || getABI().IsN64()))
1370 return;
1371
1373
1375 MCInst Inst;
1376
1377 // Either store the old $gp in a register or on the stack
1378 if (IsReg) {
1379 // move $save, $gpreg
1380 emitRRR(Mips::OR64, RegOrOffset, GPReg, Mips::ZERO, SMLoc(), &STI);
1381 } else {
1382 // sd $gpreg, offset($sp)
1383 emitRRI(Mips::SD, GPReg, Mips::SP, RegOrOffset, SMLoc(), &STI);
1384 }
1385
1386 auto *HiExpr =
1388 Mips::S_HI, MCA.getContext());
1389 auto *LoExpr =
1391 Mips::S_LO, MCA.getContext());
1392
1393 // lui $gp, %hi(%neg(%gp_rel(funcSym)))
1394 emitRX(Mips::LUi, GPReg, MCOperand::createExpr(HiExpr), SMLoc(), &STI);
1395
1396 // addiu $gp, $gp, %lo(%neg(%gp_rel(funcSym)))
1397 emitRRX(Mips::ADDiu, GPReg, GPReg, MCOperand::createExpr(LoExpr), SMLoc(),
1398 &STI);
1399
1400 // (d)addu $gp, $gp, $funcreg
1401 if (getABI().IsN32())
1402 emitRRR(Mips::ADDu, GPReg, GPReg, Reg, SMLoc(), &STI);
1403 else
1404 emitRRR(Mips::DADDu, GPReg, GPReg, Reg, SMLoc(), &STI);
1405}
1406
1408 bool SaveLocationIsRegister) {
1409 // Only N32 and N64 emit anything for .cpreturn iff PIC is set.
1410 if (!Pic || !(getABI().IsN32() || getABI().IsN64()))
1411 return;
1412
1413 MCInst Inst;
1414 // Either restore the old $gp from a register or on the stack
1415 if (SaveLocationIsRegister) {
1416 Inst.setOpcode(Mips::OR);
1418 Inst.addOperand(MCOperand::createReg(SaveLocation));
1419 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
1420 } else {
1421 Inst.setOpcode(Mips::LD);
1423 Inst.addOperand(MCOperand::createReg(Mips::SP));
1424 Inst.addOperand(MCOperand::createImm(SaveLocation));
1425 }
1426 getStreamer().emitInstruction(Inst, STI);
1427
1429}
1430
1433 MCContext &Context = MCA.getContext();
1434 MCStreamer &OS = getStreamer();
1435 MCSectionELF *Sec = Context.getELFSection(
1436 ".MIPS.abiflags", ELF::SHT_MIPS_ABIFLAGS, ELF::SHF_ALLOC, 24);
1437 OS.switchSection(Sec);
1438 Sec->setAlignment(Align(8));
1439
1440 OS << ABIFlagsSection;
1441}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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
@ STO_MIPS_MIPS16
Definition ELF.h:603
@ 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