blob: 6091ee24b04de6501cdfe1a6ee0134872f07051d [file] [log] [blame]
Eugene Zelenko926883e2017-02-01 01:22:51 +00001//===- MipsABIFlagsSection.h - Mips ELF ABI Flags Section -------*- C++ -*-===//
Daniel Sandersc7dbc632014-07-08 10:11:38 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Daniel Sandersc7dbc632014-07-08 10:11:38 +00006//
7//===----------------------------------------------------------------------===//
8
Benjamin Kramera7c40ef2014-08-13 16:26:38 +00009#ifndef LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSABIFLAGSSECTION_H
10#define LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSABIFLAGSSECTION_H
Daniel Sandersc7dbc632014-07-08 10:11:38 +000011
Eugene Zelenko926883e2017-02-01 01:22:51 +000012#include "llvm/ADT/StringRef.h"
Pete Cooper81902a32015-05-15 22:19:42 +000013#include "llvm/Support/ErrorHandling.h"
Simon Atanasyanfee03b12015-05-07 14:57:04 +000014#include "llvm/Support/MipsABIFlags.h"
Eugene Zelenko926883e2017-02-01 01:22:51 +000015#include <cstdint>
Daniel Sandersc7dbc632014-07-08 10:11:38 +000016
17namespace llvm {
18
19class MCStreamer;
20
21struct MipsABIFlagsSection {
Toma Tabacu506cfd02015-05-07 10:29:52 +000022 // Internal representation of the fp_abi related values used in .module.
23 enum class FpABIKind { ANY, XX, S32, S64, SOFT };
Daniel Sanders7e527422014-07-10 13:38:23 +000024
Daniel Sandersc7dbc632014-07-08 10:11:38 +000025 // Version of flags structure.
Eugene Zelenko926883e2017-02-01 01:22:51 +000026 uint16_t Version = 0;
Daniel Sandersc7dbc632014-07-08 10:11:38 +000027 // The level of the ISA: 1-5, 32, 64.
Eugene Zelenko926883e2017-02-01 01:22:51 +000028 uint8_t ISALevel = 0;
Daniel Sandersc7dbc632014-07-08 10:11:38 +000029 // The revision of ISA: 0 for MIPS V and below, 1-n otherwise.
Eugene Zelenko926883e2017-02-01 01:22:51 +000030 uint8_t ISARevision = 0;
Daniel Sandersc7dbc632014-07-08 10:11:38 +000031 // The size of general purpose registers.
Eugene Zelenko926883e2017-02-01 01:22:51 +000032 Mips::AFL_REG GPRSize = Mips::AFL_REG_NONE;
Daniel Sandersc7dbc632014-07-08 10:11:38 +000033 // The size of co-processor 1 registers.
Eugene Zelenko926883e2017-02-01 01:22:51 +000034 Mips::AFL_REG CPR1Size = Mips::AFL_REG_NONE;
Daniel Sandersc7dbc632014-07-08 10:11:38 +000035 // The size of co-processor 2 registers.
Eugene Zelenko926883e2017-02-01 01:22:51 +000036 Mips::AFL_REG CPR2Size = Mips::AFL_REG_NONE;
Daniel Sandersc7dbc632014-07-08 10:11:38 +000037 // Processor-specific extension.
Eugene Zelenko926883e2017-02-01 01:22:51 +000038 Mips::AFL_EXT ISAExtension = Mips::AFL_EXT_NONE;
Daniel Sandersc7dbc632014-07-08 10:11:38 +000039 // Mask of ASEs used.
Eugene Zelenko926883e2017-02-01 01:22:51 +000040 uint32_t ASESet = 0;
Daniel Sandersc7dbc632014-07-08 10:11:38 +000041
Eugene Zelenko926883e2017-02-01 01:22:51 +000042 bool OddSPReg = false;
Daniel Sanders7e527422014-07-10 13:38:23 +000043
Eugene Zelenko926883e2017-02-01 01:22:51 +000044 bool Is32BitABI = false;
Daniel Sanders7e527422014-07-10 13:38:23 +000045
46protected:
47 // The floating-point ABI.
Eugene Zelenko926883e2017-02-01 01:22:51 +000048 FpABIKind FpABI = FpABIKind::ANY;
Daniel Sanders7e527422014-07-10 13:38:23 +000049
50public:
Eugene Zelenko926883e2017-02-01 01:22:51 +000051 MipsABIFlagsSection() = default;
Daniel Sandersc7dbc632014-07-08 10:11:38 +000052
Daniel Sanders7e527422014-07-10 13:38:23 +000053 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; }
Daniel Sanders185f23a2014-07-17 09:57:23 +000057 uint8_t getCPR1SizeValue();
Daniel Sanders7e527422014-07-10 13:38:23 +000058 uint8_t getCPR2SizeValue() { return (uint8_t)CPR2Size; }
59 uint8_t getFpABIValue();
Daniel Sanders415c1592016-05-12 11:31:19 +000060 uint32_t getISAExtensionValue() { return (uint32_t)ISAExtension; }
Daniel Sanders7e527422014-07-10 13:38:23 +000061 uint32_t getASESetValue() { return (uint32_t)ASESet; }
Daniel Sandersc7dbc632014-07-08 10:11:38 +000062
Daniel Sanders7e527422014-07-10 13:38:23 +000063 uint32_t getFlags1Value() {
64 uint32_t Value = 0;
65
66 if (OddSPReg)
Simon Atanasyanfee03b12015-05-07 14:57:04 +000067 Value |= (uint32_t)Mips::AFL_FLAGS1_ODDSPREG;
Daniel Sanders7e527422014-07-10 13:38:23 +000068
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 }
Eugene Zelenko926883e2017-02-01 01:22:51 +000079
Daniel Sanders7e527422014-07-10 13:38:23 +000080 StringRef getFpABIString(FpABIKind Value);
Daniel Sandersc7dbc632014-07-08 10:11:38 +000081
82 template <class PredicateLibrary>
83 void setISALevelAndRevisionFromPredicates(const PredicateLibrary &P) {
84 if (P.hasMips64()) {
85 ISALevel = 64;
86 if (P.hasMips64r6())
87 ISARevision = 6;
Daniel Sanders17793142015-02-18 16:24:50 +000088 else if (P.hasMips64r5())
89 ISARevision = 5;
90 else if (P.hasMips64r3())
91 ISARevision = 3;
Daniel Sandersc7dbc632014-07-08 10:11:38 +000092 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;
Daniel Sanders17793142015-02-18 16:24:50 +0000100 else if (P.hasMips32r5())
101 ISARevision = 5;
102 else if (P.hasMips32r3())
103 ISARevision = 3;
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000104 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) {
Simon Atanasyanfee03b12015-05-07 14:57:04 +0000127 GPRSize = P.isGP64bit() ? Mips::AFL_REG_64 : Mips::AFL_REG_32;
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000128 }
129
130 template <class PredicateLibrary>
131 void setCPR1SizeFromPredicates(const PredicateLibrary &P) {
Eric Christophere8ae3e32015-05-07 23:10:21 +0000132 if (P.useSoftFloat())
Simon Atanasyanfee03b12015-05-07 14:57:04 +0000133 CPR1Size = Mips::AFL_REG_NONE;
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000134 else if (P.hasMSA())
Simon Atanasyanfee03b12015-05-07 14:57:04 +0000135 CPR1Size = Mips::AFL_REG_128;
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000136 else
Simon Atanasyanfee03b12015-05-07 14:57:04 +0000137 CPR1Size = P.isFP64bit() ? Mips::AFL_REG_64 : Mips::AFL_REG_32;
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000138 }
139
140 template <class PredicateLibrary>
Daniel Sanders415c1592016-05-12 11:31:19 +0000141 void setISAExtensionFromPredicates(const PredicateLibrary &P) {
Simon Atanasyanbf996f72019-11-05 01:26:24 +0300142 if (P.hasCnMipsP())
143 ISAExtension = Mips::AFL_EXT_OCTEONP;
144 else if (P.hasCnMips())
Daniel Sanders415c1592016-05-12 11:31:19 +0000145 ISAExtension = Mips::AFL_EXT_OCTEON;
146 else
147 ISAExtension = Mips::AFL_EXT_NONE;
148 }
149
150 template <class PredicateLibrary>
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000151 void setASESetFromPredicates(const PredicateLibrary &P) {
152 ASESet = 0;
153 if (P.hasDSP())
Simon Atanasyanfee03b12015-05-07 14:57:04 +0000154 ASESet |= Mips::AFL_ASE_DSP;
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000155 if (P.hasDSPR2())
Simon Atanasyanfee03b12015-05-07 14:57:04 +0000156 ASESet |= Mips::AFL_ASE_DSPR2;
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000157 if (P.hasMSA())
Simon Atanasyanfee03b12015-05-07 14:57:04 +0000158 ASESet |= Mips::AFL_ASE_MSA;
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000159 if (P.inMicroMipsMode())
Simon Atanasyanfee03b12015-05-07 14:57:04 +0000160 ASESet |= Mips::AFL_ASE_MICROMIPS;
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000161 if (P.inMips16Mode())
Simon Atanasyanfee03b12015-05-07 14:57:04 +0000162 ASESet |= Mips::AFL_ASE_MIPS16;
Simon Dardisae719c52017-07-11 18:03:20 +0000163 if (P.hasMT())
164 ASESet |= Mips::AFL_ASE_MT;
Petar Jovanovic3408caf2018-03-14 14:13:31 +0000165 if (P.hasCRC())
166 ASESet |= Mips::AFL_ASE_CRC;
Petar Jovanovicd4349f32018-04-27 09:12:08 +0000167 if (P.hasVirt())
168 ASESet |= Mips::AFL_ASE_VIRT;
Petar Jovanovicdaf51692018-05-17 16:30:32 +0000169 if (P.hasGINV())
170 ASESet |= Mips::AFL_ASE_GINV;
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000171 }
172
173 template <class PredicateLibrary>
174 void setFpAbiFromPredicates(const PredicateLibrary &P) {
Daniel Sanders7e527422014-07-10 13:38:23 +0000175 Is32BitABI = P.isABI_O32();
176
177 FpABI = FpABIKind::ANY;
Eric Christophere8ae3e32015-05-07 23:10:21 +0000178 if (P.useSoftFloat())
Toma Tabacu506cfd02015-05-07 10:29:52 +0000179 FpABI = FpABIKind::SOFT;
180 else if (P.isABI_N32() || P.isABI_N64())
Daniel Sanders7e527422014-07-10 13:38:23 +0000181 FpABI = FpABIKind::S64;
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000182 else if (P.isABI_O32()) {
Daniel Sanders185f23a2014-07-17 09:57:23 +0000183 if (P.isABI_FPXX())
Daniel Sanders7e527422014-07-10 13:38:23 +0000184 FpABI = FpABIKind::XX;
Daniel Sanders185f23a2014-07-17 09:57:23 +0000185 else if (P.isFP64bit())
186 FpABI = FpABIKind::S64;
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000187 else
Daniel Sanders7e527422014-07-10 13:38:23 +0000188 FpABI = FpABIKind::S32;
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000189 }
190 }
191
192 template <class PredicateLibrary>
193 void setAllFromPredicates(const PredicateLibrary &P) {
194 setISALevelAndRevisionFromPredicates(P);
195 setGPRSizeFromPredicates(P);
196 setCPR1SizeFromPredicates(P);
Daniel Sanders415c1592016-05-12 11:31:19 +0000197 setISAExtensionFromPredicates(P);
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000198 setASESetFromPredicates(P);
199 setFpAbiFromPredicates(P);
Daniel Sanders9ee2aee2014-07-14 10:26:15 +0000200 OddSPReg = P.useOddSPReg();
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000201 }
202};
203
204MCStreamer &operator<<(MCStreamer &OS, MipsABIFlagsSection &ABIFlagsSection);
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000205
Eugene Zelenko926883e2017-02-01 01:22:51 +0000206} // end namespace llvm
207
208#endif // LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSABIFLAGSSECTION_H