1 //===- MipsOptionRecord.cpp - Abstraction for storing information ---------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "MipsOptionRecord.h"
10 #include "MipsABIInfo.h"
11 #include "MipsELFStreamer.h"
12 #include "MipsTargetStreamer.h"
13 #include "llvm/BinaryFormat/ELF.h"
14 #include "llvm/MC/MCAssembler.h"
15 #include "llvm/MC/MCContext.h"
16 #include "llvm/MC/MCRegisterInfo.h"
17 #include "llvm/MC/MCSectionELF.h"
22 void MipsRegInfoRecord::EmitMipsOptionRecord() {
23 MipsTargetStreamer
*MTS
=
24 static_cast<MipsTargetStreamer
*>(Streamer
->getTargetStreamer());
26 Streamer
->pushSection();
28 // We need to distinguish between N64 and the rest because at the moment
29 // we don't emit .Mips.options for other ELFs other than N64.
30 // Since .reginfo has the same information as .Mips.options (ODK_REGINFO),
31 // we can use the same abstraction (MipsRegInfoRecord class) to handle both.
32 if (MTS
->getABI().IsN64()) {
33 // The EntrySize value of 1 seems strange since the records are neither
34 // 1-byte long nor fixed length but it matches the value GAS emits.
36 Context
.getELFSection(".MIPS.options", ELF::SHT_MIPS_OPTIONS
,
37 ELF::SHF_ALLOC
| ELF::SHF_MIPS_NOSTRIP
, 1);
38 Sec
->setAlignment(Align(8));
39 Streamer
->switchSection(Sec
);
41 Streamer
->emitInt8(ELF::ODK_REGINFO
); // kind
42 Streamer
->emitInt8(40); // size
43 Streamer
->emitInt16(0); // section
44 Streamer
->emitInt32(0); // info
45 Streamer
->emitInt32(ri_gprmask
);
46 Streamer
->emitInt32(0); // pad
47 Streamer
->emitInt32(ri_cprmask
[0]);
48 Streamer
->emitInt32(ri_cprmask
[1]);
49 Streamer
->emitInt32(ri_cprmask
[2]);
50 Streamer
->emitInt32(ri_cprmask
[3]);
51 Streamer
->emitIntValue(ri_gp_value
, 8);
53 MCSectionELF
*Sec
= Context
.getELFSection(".reginfo", ELF::SHT_MIPS_REGINFO
,
55 Sec
->setAlignment(MTS
->getABI().IsN32() ? Align(8) : Align(4));
56 Streamer
->switchSection(Sec
);
58 Streamer
->emitInt32(ri_gprmask
);
59 Streamer
->emitInt32(ri_cprmask
[0]);
60 Streamer
->emitInt32(ri_cprmask
[1]);
61 Streamer
->emitInt32(ri_cprmask
[2]);
62 Streamer
->emitInt32(ri_cprmask
[3]);
63 assert((ri_gp_value
& 0xffffffff) == ri_gp_value
);
64 Streamer
->emitInt32(ri_gp_value
);
67 Streamer
->popSection();
70 void MipsRegInfoRecord::SetPhysRegUsed(unsigned Reg
,
71 const MCRegisterInfo
*MCRegInfo
) {
74 for (const MCPhysReg
&SubReg
: MCRegInfo
->subregs_inclusive(Reg
)) {
75 unsigned EncVal
= MCRegInfo
->getEncodingValue(SubReg
);
78 if (GPR32RegClass
->contains(SubReg
) || GPR64RegClass
->contains(SubReg
))
80 else if (COP0RegClass
->contains(SubReg
))
81 ri_cprmask
[0] |= Value
;
82 // MIPS COP1 is the FPU.
83 else if (FGR32RegClass
->contains(SubReg
) ||
84 FGR64RegClass
->contains(SubReg
) ||
85 AFGR64RegClass
->contains(SubReg
) ||
86 MSA128BRegClass
->contains(SubReg
))
87 ri_cprmask
[1] |= Value
;
88 else if (COP2RegClass
->contains(SubReg
))
89 ri_cprmask
[2] |= Value
;
90 else if (COP3RegClass
->contains(SubReg
))
91 ri_cprmask
[3] |= Value
;