blob: 68bf3829aab51bfce2ae01e3a5c1387cf7ae3e8d [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//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Benjamin Kramera7c40ef2014-08-13 16:26:38 +000010#ifndef LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSABIFLAGSSECTION_H
11#define LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSABIFLAGSSECTION_H
Daniel Sandersc7dbc632014-07-08 10:11:38 +000012
Eugene Zelenko926883e2017-02-01 01:22:51 +000013#include "llvm/ADT/StringRef.h"
Pete Cooper81902a32015-05-15 22:19:42 +000014#include "llvm/Support/ErrorHandling.h"
Simon Atanasyanfee03b12015-05-07 14:57:04 +000015#include "llvm/Support/MipsABIFlags.h"
Eugene Zelenko926883e2017-02-01 01:22:51 +000016#include <cstdint>
Daniel Sandersc7dbc632014-07-08 10:11:38 +000017
18namespace llvm {
19
20class MCStreamer;
21
22struct MipsABIFlagsSection {
Toma Tabacu506cfd02015-05-07 10:29:52 +000023 // Internal representation of the fp_abi related values used in .module.
24 enum class FpABIKind { ANY, XX, S32, S64, SOFT };
Daniel Sanders7e527422014-07-10 13:38:23 +000025
Daniel Sandersc7dbc632014-07-08 10:11:38 +000026 // Version of flags structure.
Eugene Zelenko926883e2017-02-01 01:22:51 +000027 uint16_t Version = 0;
Daniel Sandersc7dbc632014-07-08 10:11:38 +000028 // The level of the ISA: 1-5, 32, 64.
Eugene Zelenko926883e2017-02-01 01:22:51 +000029 uint8_t ISALevel = 0;
Daniel Sandersc7dbc632014-07-08 10:11:38 +000030 // The revision of ISA: 0 for MIPS V and below, 1-n otherwise.
Eugene Zelenko926883e2017-02-01 01:22:51 +000031 uint8_t ISARevision = 0;
Daniel Sandersc7dbc632014-07-08 10:11:38 +000032 // The size of general purpose registers.
Eugene Zelenko926883e2017-02-01 01:22:51 +000033 Mips::AFL_REG GPRSize = Mips::AFL_REG_NONE;
Daniel Sandersc7dbc632014-07-08 10:11:38 +000034 // The size of co-processor 1 registers.
Eugene Zelenko926883e2017-02-01 01:22:51 +000035 Mips::AFL_REG CPR1Size = Mips::AFL_REG_NONE;
Daniel Sandersc7dbc632014-07-08 10:11:38 +000036 // The size of co-processor 2 registers.
Eugene Zelenko926883e2017-02-01 01:22:51 +000037 Mips::AFL_REG CPR2Size = Mips::AFL_REG_NONE;
Daniel Sandersc7dbc632014-07-08 10:11:38 +000038 // Processor-specific extension.
Eugene Zelenko926883e2017-02-01 01:22:51 +000039 Mips::AFL_EXT ISAExtension = Mips::AFL_EXT_NONE;
Daniel Sandersc7dbc632014-07-08 10:11:38 +000040 // Mask of ASEs used.
Eugene Zelenko926883e2017-02-01 01:22:51 +000041 uint32_t ASESet = 0;
Daniel Sandersc7dbc632014-07-08 10:11:38 +000042
Eugene Zelenko926883e2017-02-01 01:22:51 +000043 bool OddSPReg = false;
Daniel Sanders7e527422014-07-10 13:38:23 +000044
Eugene Zelenko926883e2017-02-01 01:22:51 +000045 bool Is32BitABI = false;
Daniel Sanders7e527422014-07-10 13:38:23 +000046
47protected:
48 // The floating-point ABI.
Eugene Zelenko926883e2017-02-01 01:22:51 +000049 FpABIKind FpABI = FpABIKind::ANY;
Daniel Sanders7e527422014-07-10 13:38:23 +000050
51public:
Eugene Zelenko926883e2017-02-01 01:22:51 +000052 MipsABIFlagsSection() = default;
Daniel Sandersc7dbc632014-07-08 10:11:38 +000053
Daniel Sanders7e527422014-07-10 13:38:23 +000054 uint16_t getVersionValue() { return (uint16_t)Version; }
55 uint8_t getISALevelValue() { return (uint8_t)ISALevel; }
56 uint8_t getISARevisionValue() { return (uint8_t)ISARevision; }
57 uint8_t getGPRSizeValue() { return (uint8_t)GPRSize; }
Daniel Sanders185f23a2014-07-17 09:57:23 +000058 uint8_t getCPR1SizeValue();
Daniel Sanders7e527422014-07-10 13:38:23 +000059 uint8_t getCPR2SizeValue() { return (uint8_t)CPR2Size; }
60 uint8_t getFpABIValue();
Daniel Sanders415c1592016-05-12 11:31:19 +000061 uint32_t getISAExtensionValue() { return (uint32_t)ISAExtension; }
Daniel Sanders7e527422014-07-10 13:38:23 +000062 uint32_t getASESetValue() { return (uint32_t)ASESet; }
Daniel Sandersc7dbc632014-07-08 10:11:38 +000063
Daniel Sanders7e527422014-07-10 13:38:23 +000064 uint32_t getFlags1Value() {
65 uint32_t Value = 0;
66
67 if (OddSPReg)
Simon Atanasyanfee03b12015-05-07 14:57:04 +000068 Value |= (uint32_t)Mips::AFL_FLAGS1_ODDSPREG;
Daniel Sanders7e527422014-07-10 13:38:23 +000069
70 return Value;
71 }
72
73 uint32_t getFlags2Value() { return 0; }
74
75 FpABIKind getFpABI() { return FpABI; }
76 void setFpABI(FpABIKind Value, bool IsABI32Bit) {
77 FpABI = Value;
78 Is32BitABI = IsABI32Bit;
79 }
Eugene Zelenko926883e2017-02-01 01:22:51 +000080
Daniel Sanders7e527422014-07-10 13:38:23 +000081 StringRef getFpABIString(FpABIKind Value);
Daniel Sandersc7dbc632014-07-08 10:11:38 +000082
83 template <class PredicateLibrary>
84 void setISALevelAndRevisionFromPredicates(const PredicateLibrary &P) {
85 if (P.hasMips64()) {
86 ISALevel = 64;
87 if (P.hasMips64r6())
88 ISARevision = 6;
Daniel Sanders17793142015-02-18 16:24:50 +000089 else if (P.hasMips64r5())
90 ISARevision = 5;
91 else if (P.hasMips64r3())
92 ISARevision = 3;
Daniel Sandersc7dbc632014-07-08 10:11:38 +000093 else if (P.hasMips64r2())
94 ISARevision = 2;
95 else
96 ISARevision = 1;
97 } else if (P.hasMips32()) {
98 ISALevel = 32;
99 if (P.hasMips32r6())
100 ISARevision = 6;
Daniel Sanders17793142015-02-18 16:24:50 +0000101 else if (P.hasMips32r5())
102 ISARevision = 5;
103 else if (P.hasMips32r3())
104 ISARevision = 3;
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000105 else if (P.hasMips32r2())
106 ISARevision = 2;
107 else
108 ISARevision = 1;
109 } else {
110 ISARevision = 0;
111 if (P.hasMips5())
112 ISALevel = 5;
113 else if (P.hasMips4())
114 ISALevel = 4;
115 else if (P.hasMips3())
116 ISALevel = 3;
117 else if (P.hasMips2())
118 ISALevel = 2;
119 else if (P.hasMips1())
120 ISALevel = 1;
121 else
122 llvm_unreachable("Unknown ISA level!");
123 }
124 }
125
126 template <class PredicateLibrary>
127 void setGPRSizeFromPredicates(const PredicateLibrary &P) {
Simon Atanasyanfee03b12015-05-07 14:57:04 +0000128 GPRSize = P.isGP64bit() ? Mips::AFL_REG_64 : Mips::AFL_REG_32;
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000129 }
130
131 template <class PredicateLibrary>
132 void setCPR1SizeFromPredicates(const PredicateLibrary &P) {
Eric Christophere8ae3e32015-05-07 23:10:21 +0000133 if (P.useSoftFloat())
Simon Atanasyanfee03b12015-05-07 14:57:04 +0000134 CPR1Size = Mips::AFL_REG_NONE;
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000135 else if (P.hasMSA())
Simon Atanasyanfee03b12015-05-07 14:57:04 +0000136 CPR1Size = Mips::AFL_REG_128;
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000137 else
Simon Atanasyanfee03b12015-05-07 14:57:04 +0000138 CPR1Size = P.isFP64bit() ? Mips::AFL_REG_64 : Mips::AFL_REG_32;
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000139 }
140
141 template <class PredicateLibrary>
Daniel Sanders415c1592016-05-12 11:31:19 +0000142 void setISAExtensionFromPredicates(const PredicateLibrary &P) {
143 if (P.hasCnMips())
144 ISAExtension = Mips::AFL_EXT_OCTEON;
145 else
146 ISAExtension = Mips::AFL_EXT_NONE;
147 }
148
149 template <class PredicateLibrary>
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000150 void setASESetFromPredicates(const PredicateLibrary &P) {
151 ASESet = 0;
152 if (P.hasDSP())
Simon Atanasyanfee03b12015-05-07 14:57:04 +0000153 ASESet |= Mips::AFL_ASE_DSP;
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000154 if (P.hasDSPR2())
Simon Atanasyanfee03b12015-05-07 14:57:04 +0000155 ASESet |= Mips::AFL_ASE_DSPR2;
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000156 if (P.hasMSA())
Simon Atanasyanfee03b12015-05-07 14:57:04 +0000157 ASESet |= Mips::AFL_ASE_MSA;
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000158 if (P.inMicroMipsMode())
Simon Atanasyanfee03b12015-05-07 14:57:04 +0000159 ASESet |= Mips::AFL_ASE_MICROMIPS;
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000160 if (P.inMips16Mode())
Simon Atanasyanfee03b12015-05-07 14:57:04 +0000161 ASESet |= Mips::AFL_ASE_MIPS16;
Simon Dardisae719c52017-07-11 18:03:20 +0000162 if (P.hasMT())
163 ASESet |= Mips::AFL_ASE_MT;
Petar Jovanovic3408caf2018-03-14 14:13:31 +0000164 if (P.hasCRC())
165 ASESet |= Mips::AFL_ASE_CRC;
Petar Jovanovicd4349f32018-04-27 09:12:08 +0000166 if (P.hasVirt())
167 ASESet |= Mips::AFL_ASE_VIRT;
Petar Jovanovicdaf51692018-05-17 16:30:32 +0000168 if (P.hasGINV())
169 ASESet |= Mips::AFL_ASE_GINV;
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000170 }
171
172 template <class PredicateLibrary>
173 void setFpAbiFromPredicates(const PredicateLibrary &P) {
Daniel Sanders7e527422014-07-10 13:38:23 +0000174 Is32BitABI = P.isABI_O32();
175
176 FpABI = FpABIKind::ANY;
Eric Christophere8ae3e32015-05-07 23:10:21 +0000177 if (P.useSoftFloat())
Toma Tabacu506cfd02015-05-07 10:29:52 +0000178 FpABI = FpABIKind::SOFT;
179 else if (P.isABI_N32() || P.isABI_N64())
Daniel Sanders7e527422014-07-10 13:38:23 +0000180 FpABI = FpABIKind::S64;
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000181 else if (P.isABI_O32()) {
Daniel Sanders185f23a2014-07-17 09:57:23 +0000182 if (P.isABI_FPXX())
Daniel Sanders7e527422014-07-10 13:38:23 +0000183 FpABI = FpABIKind::XX;
Daniel Sanders185f23a2014-07-17 09:57:23 +0000184 else if (P.isFP64bit())
185 FpABI = FpABIKind::S64;
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000186 else
Daniel Sanders7e527422014-07-10 13:38:23 +0000187 FpABI = FpABIKind::S32;
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000188 }
189 }
190
191 template <class PredicateLibrary>
192 void setAllFromPredicates(const PredicateLibrary &P) {
193 setISALevelAndRevisionFromPredicates(P);
194 setGPRSizeFromPredicates(P);
195 setCPR1SizeFromPredicates(P);
Daniel Sanders415c1592016-05-12 11:31:19 +0000196 setISAExtensionFromPredicates(P);
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000197 setASESetFromPredicates(P);
198 setFpAbiFromPredicates(P);
Daniel Sanders9ee2aee2014-07-14 10:26:15 +0000199 OddSPReg = P.useOddSPReg();
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000200 }
201};
202
203MCStreamer &operator<<(MCStreamer &OS, MipsABIFlagsSection &ABIFlagsSection);
Daniel Sandersc7dbc632014-07-08 10:11:38 +0000204
Eugene Zelenko926883e2017-02-01 01:22:51 +0000205} // end namespace llvm
206
207#endif // LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSABIFLAGSSECTION_H