1//===- MipsABIFlagsSection.h - Mips ELF ABI Flags Section -------*- C++ -*-===//
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#ifndef LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSABIFLAGSSECTION_H
10#define LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSABIFLAGSSECTION_H
11
12#include "llvm/Support/ErrorHandling.h"
13#include "llvm/Support/MipsABIFlags.h"
14#include <cstdint>
15
16namespace llvm {
17
18class MCStreamer;
19class StringRef;
20
21struct MipsABIFlagsSection {
22 // Internal representation of the fp_abi related values used in .module.
23 enum class FpABIKind { ANY, XX, S32, S64, SOFT, SINGLE };
24
25 // Version of flags structure.
26 uint16_t Version = 0;
27 // The level of the ISA: 1-5, 32, 64.
28 uint8_t ISALevel = 0;
29 // The revision of ISA: 0 for MIPS V and below, 1-n otherwise.
30 uint8_t ISARevision = 0;
31 // The size of general purpose registers.
32 Mips::AFL_REG GPRSize = Mips::AFL_REG_NONE;
33 // The size of co-processor 1 registers.
34 Mips::AFL_REG CPR1Size = Mips::AFL_REG_NONE;
35 // The size of co-processor 2 registers.
36 Mips::AFL_REG CPR2Size = Mips::AFL_REG_NONE;
37 // Processor-specific extension.
38 Mips::AFL_EXT ISAExtension = Mips::AFL_EXT_NONE;
39 // Mask of ASEs used.
40 uint32_t ASESet = 0;
41
42 bool OddSPReg = false;
43
44 bool Is32BitABI = false;
45
46protected:
47 // The floating-point ABI.
48 FpABIKind FpABI = FpABIKind::ANY;
49
50public:
51 MipsABIFlagsSection() = default;
52
53 uint16_t getVersionValue() { return (uint16_t)Version; }
54 uint8_t getISALevelValue() { return (uint8_t)ISALevel; }
55 uint8_t getISARevisionValue() { return (uint8_t)ISARevision; }
56 uint8_t getGPRSizeValue() { return (uint8_t)GPRSize; }
57 uint8_t getCPR1SizeValue();
58 uint8_t getCPR2SizeValue() { return (uint8_t)CPR2Size; }
59 uint8_t getFpABIValue();
60 uint32_t getISAExtensionValue() { return (uint32_t)ISAExtension; }
61 uint32_t getASESetValue() { return (uint32_t)ASESet; }
62
63 uint32_t getFlags1Value() {
64 uint32_t Value = 0;
65
66 if (OddSPReg)
67 Value |= (uint32_t)Mips::AFL_FLAGS1_ODDSPREG;
68
69 return Value;
70 }
71
72 uint32_t getFlags2Value() { return 0; }
73
74 FpABIKind getFpABI() { return FpABI; }
75 void setFpABI(FpABIKind Value, bool IsABI32Bit) {
76 FpABI = Value;
77 Is32BitABI = IsABI32Bit;
78 }
79
80 StringRef getFpABIString(FpABIKind Value);
81
82 template <class PredicateLibrary>
83 void setISALevelAndRevisionFromPredicates(const PredicateLibrary &P) {
84 if (P.hasMips64()) {
85 ISALevel = 64;
86 if (P.hasMips64r6())
87 ISARevision = 6;
88 else if (P.hasMips64r5())
89 ISARevision = 5;
90 else if (P.hasMips64r3())
91 ISARevision = 3;
92 else if (P.hasMips64r2())
93 ISARevision = 2;
94 else
95 ISARevision = 1;
96 } else if (P.hasMips32()) {
97 ISALevel = 32;
98 if (P.hasMips32r6())
99 ISARevision = 6;
100 else if (P.hasMips32r5())
101 ISARevision = 5;
102 else if (P.hasMips32r3())
103 ISARevision = 3;
104 else if (P.hasMips32r2())
105 ISARevision = 2;
106 else
107 ISARevision = 1;
108 } else {
109 ISARevision = 0;
110 if (P.hasMips5())
111 ISALevel = 5;
112 else if (P.hasMips4())
113 ISALevel = 4;
114 else if (P.hasMips3())
115 ISALevel = 3;
116 else if (P.hasMips2())
117 ISALevel = 2;
118 else if (P.hasMips1())
119 ISALevel = 1;
120 else
121 llvm_unreachable("Unknown ISA level!");
122 }
123 }
124
125 template <class PredicateLibrary>
126 void setGPRSizeFromPredicates(const PredicateLibrary &P) {
127 GPRSize = P.isGP64bit() ? Mips::AFL_REG_64 : Mips::AFL_REG_32;
128 }
129
130 template <class PredicateLibrary>
131 void setCPR1SizeFromPredicates(const PredicateLibrary &P) {
132 if (P.useSoftFloat())
133 CPR1Size = Mips::AFL_REG_NONE;
134 else if (P.hasMSA())
135 CPR1Size = Mips::AFL_REG_128;
136 else if (P.isSingleFloat())
137 CPR1Size = Mips::AFL_REG_32;
138 else
139 CPR1Size = P.isFP64bit() ? Mips::AFL_REG_64 : Mips::AFL_REG_32;
140 }
141
142 template <class PredicateLibrary>
143 void setISAExtensionFromPredicates(const PredicateLibrary &P) {
144 if (P.hasCnMipsP())
145 ISAExtension = Mips::AFL_EXT_OCTEONP;
146 else if (P.hasCnMips())
147 ISAExtension = Mips::AFL_EXT_OCTEON;
148 else if (P.isR5900())
149 ISAExtension = Mips::AFL_EXT_5900;
150 else
151 ISAExtension = Mips::AFL_EXT_NONE;
152 }
153
154 template <class PredicateLibrary>
155 void setASESetFromPredicates(const PredicateLibrary &P) {
156 ASESet = 0;
157 if (P.hasDSP())
158 ASESet |= Mips::AFL_ASE_DSP;
159 if (P.hasDSPR2())
160 ASESet |= Mips::AFL_ASE_DSPR2;
161 if (P.hasMSA())
162 ASESet |= Mips::AFL_ASE_MSA;
163 if (P.inMicroMipsMode())
164 ASESet |= Mips::AFL_ASE_MICROMIPS;
165 if (P.inMips16Mode())
166 ASESet |= Mips::AFL_ASE_MIPS16;
167 if (P.hasMT())
168 ASESet |= Mips::AFL_ASE_MT;
169 if (P.hasCRC())
170 ASESet |= Mips::AFL_ASE_CRC;
171 if (P.hasVirt())
172 ASESet |= Mips::AFL_ASE_VIRT;
173 if (P.hasGINV())
174 ASESet |= Mips::AFL_ASE_GINV;
175 }
176
177 template <class PredicateLibrary>
178 void setFpAbiFromPredicates(const PredicateLibrary &P) {
179 Is32BitABI = P.isABI_O32();
180
181 FpABI = FpABIKind::ANY;
182 if (P.useSoftFloat())
183 FpABI = FpABIKind::SOFT;
184 else if (P.isSingleFloat())
185 FpABI = FpABIKind::SINGLE;
186 else if (P.isABI_N32() || P.isABI_N64())
187 FpABI = FpABIKind::S64;
188 else if (P.isABI_O32()) {
189 if (P.isABI_FPXX())
190 FpABI = FpABIKind::XX;
191 else if (P.isFP64bit())
192 FpABI = FpABIKind::S64;
193 else
194 FpABI = FpABIKind::S32;
195 }
196 }
197
198 template <class PredicateLibrary>
199 void setAllFromPredicates(const PredicateLibrary &P) {
200 setISALevelAndRevisionFromPredicates(P);
201 setGPRSizeFromPredicates(P);
202 setCPR1SizeFromPredicates(P);
203 setISAExtensionFromPredicates(P);
204 setASESetFromPredicates(P);
205 setFpAbiFromPredicates(P);
206 OddSPReg = P.useOddSPReg();
207 }
208};
209
210MCStreamer &operator<<(MCStreamer &OS, MipsABIFlagsSection &ABIFlagsSection);
211
212} // end namespace llvm
213
214#endif // LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSABIFLAGSSECTION_H
215