Line data Source code
1 : // Copyright 2014 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_MACHINE_TYPE_H_
6 : #define V8_MACHINE_TYPE_H_
7 :
8 : #include <iosfwd>
9 :
10 : #include "src/base/bits.h"
11 : #include "src/globals.h"
12 :
13 : namespace v8 {
14 : namespace internal {
15 :
16 : enum class MachineRepresentation : uint8_t {
17 : kNone,
18 : kBit,
19 : kWord8,
20 : kWord16,
21 : kWord32,
22 : kWord64,
23 : kTaggedSigned,
24 : kTaggedPointer,
25 : kTagged,
26 : // FP representations must be last, and in order of increasing size.
27 : kFloat32,
28 : kFloat64,
29 : kSimd128,
30 : kFirstFPRepresentation = kFloat32,
31 : kLastRepresentation = kSimd128
32 : };
33 :
34 : bool IsSubtype(MachineRepresentation rep1, MachineRepresentation rep2);
35 :
36 : static_assert(static_cast<int>(MachineRepresentation::kLastRepresentation) <
37 : kIntSize * kBitsPerByte,
38 : "Bit masks of MachineRepresentation should fit in an int");
39 :
40 : V8_EXPORT_PRIVATE const char* MachineReprToString(MachineRepresentation);
41 :
42 : enum class MachineSemantic : uint8_t {
43 : kNone,
44 : kBool,
45 : kInt32,
46 : kUint32,
47 : kInt64,
48 : kUint64,
49 : kNumber,
50 : kAny
51 : };
52 :
53 : V8_EXPORT_PRIVATE inline int ElementSizeLog2Of(MachineRepresentation rep);
54 :
55 : V8_EXPORT_PRIVATE inline int ElementSizeInBytes(MachineRepresentation rep);
56 :
57 : class MachineType {
58 : public:
59 : constexpr MachineType()
60 : : representation_(MachineRepresentation::kNone),
61 18457592 : semantic_(MachineSemantic::kNone) {}
62 : constexpr MachineType(MachineRepresentation representation,
63 : MachineSemantic semantic)
64 : : representation_(representation), semantic_(semantic) {}
65 :
66 385683349 : constexpr bool operator==(MachineType other) const {
67 586602905 : return representation() == other.representation() &&
68 385278520 : semantic() == other.semantic();
69 : }
70 :
71 255250 : constexpr bool operator!=(MachineType other) const {
72 255250 : return !(*this == other);
73 : }
74 :
75 0 : constexpr MachineRepresentation representation() const {
76 0 : return representation_;
77 : }
78 0 : constexpr MachineSemantic semantic() const { return semantic_; }
79 :
80 5676 : constexpr bool IsNone() const {
81 : return representation() == MachineRepresentation::kNone;
82 : }
83 :
84 807 : constexpr bool IsSigned() const {
85 459908 : return semantic() == MachineSemantic::kInt32 ||
86 : semantic() == MachineSemantic::kInt64;
87 : }
88 : constexpr bool IsUnsigned() const {
89 : return semantic() == MachineSemantic::kUint32 ||
90 : semantic() == MachineSemantic::kUint64;
91 : }
92 : constexpr bool IsTagged() const {
93 495 : return representation() == MachineRepresentation::kTaggedPointer ||
94 1230 : representation() == MachineRepresentation::kTaggedSigned ||
95 : representation() == MachineRepresentation::kTagged;
96 : }
97 : constexpr bool IsTaggedSigned() const {
98 : return representation() == MachineRepresentation::kTaggedSigned;
99 : }
100 : constexpr bool IsTaggedPointer() const {
101 : return representation() == MachineRepresentation::kTaggedPointer;
102 : }
103 : constexpr static MachineRepresentation PointerRepresentation() {
104 : return (kSystemPointerSize == 4) ? MachineRepresentation::kWord32
105 : : MachineRepresentation::kWord64;
106 : }
107 : constexpr static MachineType UintPtr() {
108 : return (kSystemPointerSize == 4) ? Uint32() : Uint64();
109 : }
110 : constexpr static MachineType IntPtr() {
111 : return (kSystemPointerSize == 4) ? Int32() : Int64();
112 : }
113 : constexpr static MachineType Int8() {
114 : return MachineType(MachineRepresentation::kWord8, MachineSemantic::kInt32);
115 : }
116 : constexpr static MachineType Uint8() {
117 : return MachineType(MachineRepresentation::kWord8, MachineSemantic::kUint32);
118 : }
119 : constexpr static MachineType Int16() {
120 : return MachineType(MachineRepresentation::kWord16, MachineSemantic::kInt32);
121 : }
122 : constexpr static MachineType Uint16() {
123 : return MachineType(MachineRepresentation::kWord16,
124 : MachineSemantic::kUint32);
125 : }
126 : constexpr static MachineType Int32() {
127 : return MachineType(MachineRepresentation::kWord32, MachineSemantic::kInt32);
128 : }
129 : constexpr static MachineType Uint32() {
130 : return MachineType(MachineRepresentation::kWord32,
131 : MachineSemantic::kUint32);
132 : }
133 : constexpr static MachineType Int64() {
134 : return MachineType(MachineRepresentation::kWord64, MachineSemantic::kInt64);
135 : }
136 : constexpr static MachineType Uint64() {
137 : return MachineType(MachineRepresentation::kWord64,
138 : MachineSemantic::kUint64);
139 : }
140 : constexpr static MachineType Float32() {
141 : return MachineType(MachineRepresentation::kFloat32,
142 : MachineSemantic::kNumber);
143 : }
144 : constexpr static MachineType Float64() {
145 : return MachineType(MachineRepresentation::kFloat64,
146 : MachineSemantic::kNumber);
147 : }
148 : constexpr static MachineType Simd128() {
149 : return MachineType(MachineRepresentation::kSimd128, MachineSemantic::kNone);
150 : }
151 : constexpr static MachineType Pointer() {
152 : return MachineType(PointerRepresentation(), MachineSemantic::kNone);
153 : }
154 : constexpr static MachineType TaggedPointer() {
155 : return MachineType(MachineRepresentation::kTaggedPointer,
156 : MachineSemantic::kAny);
157 : }
158 : constexpr static MachineType TaggedSigned() {
159 : return MachineType(MachineRepresentation::kTaggedSigned,
160 : MachineSemantic::kInt32);
161 : }
162 : constexpr static MachineType AnyTagged() {
163 : return MachineType(MachineRepresentation::kTagged, MachineSemantic::kAny);
164 : }
165 : constexpr static MachineType Bool() {
166 : return MachineType(MachineRepresentation::kBit, MachineSemantic::kBool);
167 : }
168 : constexpr static MachineType TaggedBool() {
169 : return MachineType(MachineRepresentation::kTagged, MachineSemantic::kBool);
170 : }
171 : constexpr static MachineType None() {
172 : return MachineType(MachineRepresentation::kNone, MachineSemantic::kNone);
173 : }
174 :
175 : // These naked representations should eventually go away.
176 : constexpr static MachineType RepWord8() {
177 : return MachineType(MachineRepresentation::kWord8, MachineSemantic::kNone);
178 : }
179 : constexpr static MachineType RepWord16() {
180 : return MachineType(MachineRepresentation::kWord16, MachineSemantic::kNone);
181 : }
182 : constexpr static MachineType RepWord32() {
183 : return MachineType(MachineRepresentation::kWord32, MachineSemantic::kNone);
184 : }
185 : constexpr static MachineType RepWord64() {
186 : return MachineType(MachineRepresentation::kWord64, MachineSemantic::kNone);
187 : }
188 : constexpr static MachineType RepFloat32() {
189 : return MachineType(MachineRepresentation::kFloat32, MachineSemantic::kNone);
190 : }
191 : constexpr static MachineType RepFloat64() {
192 : return MachineType(MachineRepresentation::kFloat64, MachineSemantic::kNone);
193 : }
194 : constexpr static MachineType RepSimd128() {
195 : return MachineType(MachineRepresentation::kSimd128, MachineSemantic::kNone);
196 : }
197 : constexpr static MachineType RepTagged() {
198 : return MachineType(MachineRepresentation::kTagged, MachineSemantic::kNone);
199 : }
200 : constexpr static MachineType RepBit() {
201 : return MachineType(MachineRepresentation::kBit, MachineSemantic::kNone);
202 : }
203 :
204 7146317 : static MachineType TypeForRepresentation(const MachineRepresentation& rep,
205 : bool isSigned = true) {
206 7146317 : switch (rep) {
207 : case MachineRepresentation::kNone:
208 : return MachineType::None();
209 : case MachineRepresentation::kBit:
210 : return MachineType::Bool();
211 : case MachineRepresentation::kWord8:
212 0 : return isSigned ? MachineType::Int8() : MachineType::Uint8();
213 : case MachineRepresentation::kWord16:
214 0 : return isSigned ? MachineType::Int16() : MachineType::Uint16();
215 : case MachineRepresentation::kWord32:
216 3062220 : return isSigned ? MachineType::Int32() : MachineType::Uint32();
217 : case MachineRepresentation::kWord64:
218 102865 : return isSigned ? MachineType::Int64() : MachineType::Uint64();
219 : case MachineRepresentation::kFloat32:
220 : return MachineType::Float32();
221 : case MachineRepresentation::kFloat64:
222 : return MachineType::Float64();
223 : case MachineRepresentation::kSimd128:
224 : return MachineType::Simd128();
225 : case MachineRepresentation::kTagged:
226 : return MachineType::AnyTagged();
227 : case MachineRepresentation::kTaggedSigned:
228 : return MachineType::TaggedSigned();
229 : case MachineRepresentation::kTaggedPointer:
230 : return MachineType::TaggedPointer();
231 : default:
232 0 : UNREACHABLE();
233 : }
234 : }
235 :
236 : bool LessThanOrEqualPointerSize() {
237 : return ElementSizeLog2Of(this->representation()) <= kSystemPointerSizeLog2;
238 : }
239 :
240 : private:
241 : MachineRepresentation representation_;
242 : MachineSemantic semantic_;
243 : };
244 :
245 : V8_INLINE size_t hash_value(MachineRepresentation rep) {
246 15144808 : return static_cast<size_t>(rep);
247 : }
248 :
249 : V8_INLINE size_t hash_value(MachineType type) {
250 0 : return static_cast<size_t>(type.representation()) +
251 0 : static_cast<size_t>(type.semantic()) * 16;
252 : }
253 :
254 : V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
255 : MachineRepresentation rep);
256 : std::ostream& operator<<(std::ostream& os, MachineSemantic type);
257 : V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, MachineType type);
258 :
259 : inline bool IsFloatingPoint(MachineRepresentation rep) {
260 : return rep >= MachineRepresentation::kFirstFPRepresentation;
261 : }
262 :
263 : inline bool CanBeTaggedPointer(MachineRepresentation rep) {
264 94586379 : return rep == MachineRepresentation::kTagged ||
265 27429599 : rep == MachineRepresentation::kTaggedPointer;
266 : }
267 :
268 : inline bool CanBeTaggedSigned(MachineRepresentation rep) {
269 36496 : return rep == MachineRepresentation::kTagged ||
270 36496 : rep == MachineRepresentation::kTaggedSigned;
271 : }
272 :
273 : inline bool IsAnyTagged(MachineRepresentation rep) {
274 12878039 : return CanBeTaggedPointer(rep) || rep == MachineRepresentation::kTaggedSigned;
275 : }
276 :
277 : // Gets the log2 of the element size in bytes of the machine type.
278 9302938 : V8_EXPORT_PRIVATE inline int ElementSizeLog2Of(MachineRepresentation rep) {
279 9302938 : switch (rep) {
280 : case MachineRepresentation::kBit:
281 : case MachineRepresentation::kWord8:
282 : return 0;
283 : case MachineRepresentation::kWord16:
284 42244 : return 1;
285 : case MachineRepresentation::kWord32:
286 : case MachineRepresentation::kFloat32:
287 3127484 : return 2;
288 : case MachineRepresentation::kWord64:
289 : case MachineRepresentation::kFloat64:
290 1090042 : return 3;
291 : case MachineRepresentation::kSimd128:
292 31550 : return 4;
293 : case MachineRepresentation::kTaggedSigned:
294 : case MachineRepresentation::kTaggedPointer:
295 : case MachineRepresentation::kTagged:
296 4880935 : return kTaggedSizeLog2;
297 : default:
298 : break;
299 : }
300 0 : UNREACHABLE();
301 : }
302 :
303 : V8_EXPORT_PRIVATE inline int ElementSizeInBytes(MachineRepresentation rep) {
304 536839 : return 1 << ElementSizeLog2Of(rep);
305 : }
306 :
307 : // Converts representation to bit for representation masks.
308 : V8_EXPORT_PRIVATE inline constexpr int RepresentationBit(
309 : MachineRepresentation rep) {
310 31164449 : return 1 << static_cast<int>(rep);
311 : }
312 :
313 : } // namespace internal
314 : } // namespace v8
315 :
316 : #endif // V8_MACHINE_TYPE_H_
|