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 : kCompressedSigned,
27 : kCompressedPointer,
28 : kCompressed,
29 : // FP representations must be last, and in order of increasing size.
30 : kFloat32,
31 : kFloat64,
32 : kSimd128,
33 : kFirstFPRepresentation = kFloat32,
34 : kLastRepresentation = kSimd128
35 : };
36 :
37 : bool IsSubtype(MachineRepresentation rep1, MachineRepresentation rep2);
38 :
39 : static_assert(static_cast<int>(MachineRepresentation::kLastRepresentation) <
40 : kIntSize * kBitsPerByte,
41 : "Bit masks of MachineRepresentation should fit in an int");
42 :
43 : V8_EXPORT_PRIVATE const char* MachineReprToString(MachineRepresentation);
44 :
45 : enum class MachineSemantic : uint8_t {
46 : kNone,
47 : kBool,
48 : kInt32,
49 : kUint32,
50 : kInt64,
51 : kUint64,
52 : kNumber,
53 : kAny
54 : };
55 :
56 : V8_EXPORT_PRIVATE inline int ElementSizeLog2Of(MachineRepresentation rep);
57 :
58 : V8_EXPORT_PRIVATE inline int ElementSizeInBytes(MachineRepresentation rep);
59 :
60 : class MachineType {
61 : public:
62 : constexpr MachineType()
63 : : representation_(MachineRepresentation::kNone),
64 19839927 : semantic_(MachineSemantic::kNone) {}
65 : constexpr MachineType(MachineRepresentation representation,
66 : MachineSemantic semantic)
67 : : representation_(representation), semantic_(semantic) {}
68 :
69 : constexpr bool operator==(MachineType other) const {
70 376928385 : return representation() == other.representation() &&
71 : semantic() == other.semantic();
72 : }
73 :
74 : constexpr bool operator!=(MachineType other) const {
75 345556 : return !(*this == other);
76 : }
77 :
78 : constexpr MachineRepresentation representation() const {
79 : return representation_;
80 : }
81 : constexpr MachineSemantic semantic() const { return semantic_; }
82 :
83 : constexpr bool IsNone() const {
84 : return representation() == MachineRepresentation::kNone;
85 : }
86 :
87 : constexpr bool IsSigned() const {
88 554077 : return semantic() == MachineSemantic::kInt32 ||
89 : semantic() == MachineSemantic::kInt64;
90 : }
91 : constexpr bool IsUnsigned() const {
92 : return semantic() == MachineSemantic::kUint32 ||
93 : semantic() == MachineSemantic::kUint64;
94 : }
95 : constexpr bool IsTagged() const {
96 78528 : return representation() == MachineRepresentation::kTaggedPointer ||
97 160126 : representation() == MachineRepresentation::kTaggedSigned ||
98 : representation() == MachineRepresentation::kTagged;
99 : }
100 : constexpr bool IsTaggedSigned() const {
101 : return representation() == MachineRepresentation::kTaggedSigned;
102 : }
103 : constexpr bool IsTaggedPointer() const {
104 : return representation() == MachineRepresentation::kTaggedPointer;
105 : }
106 : constexpr bool IsCompressed() const {
107 : return representation() == MachineRepresentation::kCompressedPointer ||
108 : representation() == MachineRepresentation::kCompressedSigned ||
109 : representation() == MachineRepresentation::kCompressed;
110 : }
111 : constexpr bool IsCompressedSigned() const {
112 : return representation() == MachineRepresentation::kCompressedSigned;
113 : }
114 : constexpr bool IsCompressedPointer() const {
115 : return representation() == MachineRepresentation::kCompressedPointer;
116 : }
117 : constexpr static MachineRepresentation PointerRepresentation() {
118 : return (kSystemPointerSize == 4) ? MachineRepresentation::kWord32
119 : : MachineRepresentation::kWord64;
120 : }
121 : constexpr static MachineType UintPtr() {
122 : return (kSystemPointerSize == 4) ? Uint32() : Uint64();
123 : }
124 : constexpr static MachineType IntPtr() {
125 : return (kSystemPointerSize == 4) ? Int32() : Int64();
126 : }
127 : constexpr static MachineType Int8() {
128 : return MachineType(MachineRepresentation::kWord8, MachineSemantic::kInt32);
129 : }
130 : constexpr static MachineType Uint8() {
131 : return MachineType(MachineRepresentation::kWord8, MachineSemantic::kUint32);
132 : }
133 : constexpr static MachineType Int16() {
134 : return MachineType(MachineRepresentation::kWord16, MachineSemantic::kInt32);
135 : }
136 : constexpr static MachineType Uint16() {
137 : return MachineType(MachineRepresentation::kWord16,
138 : MachineSemantic::kUint32);
139 : }
140 : constexpr static MachineType Int32() {
141 : return MachineType(MachineRepresentation::kWord32, MachineSemantic::kInt32);
142 : }
143 : constexpr static MachineType Uint32() {
144 : return MachineType(MachineRepresentation::kWord32,
145 : MachineSemantic::kUint32);
146 : }
147 : constexpr static MachineType Int64() {
148 : return MachineType(MachineRepresentation::kWord64, MachineSemantic::kInt64);
149 : }
150 : constexpr static MachineType Uint64() {
151 : return MachineType(MachineRepresentation::kWord64,
152 : MachineSemantic::kUint64);
153 : }
154 : constexpr static MachineType Float32() {
155 : return MachineType(MachineRepresentation::kFloat32,
156 : MachineSemantic::kNumber);
157 : }
158 : constexpr static MachineType Float64() {
159 : return MachineType(MachineRepresentation::kFloat64,
160 : MachineSemantic::kNumber);
161 : }
162 : constexpr static MachineType Simd128() {
163 : return MachineType(MachineRepresentation::kSimd128, MachineSemantic::kNone);
164 : }
165 : constexpr static MachineType Pointer() {
166 : return MachineType(PointerRepresentation(), MachineSemantic::kNone);
167 : }
168 : constexpr static MachineType TaggedPointer() {
169 : return MachineType(MachineRepresentation::kTaggedPointer,
170 : MachineSemantic::kAny);
171 : }
172 : constexpr static MachineType TaggedSigned() {
173 : return MachineType(MachineRepresentation::kTaggedSigned,
174 : MachineSemantic::kInt32);
175 : }
176 : constexpr static MachineType AnyTagged() {
177 : return MachineType(MachineRepresentation::kTagged, MachineSemantic::kAny);
178 : }
179 : constexpr static MachineType CompressedSigned() {
180 : return MachineType(MachineRepresentation::kCompressedSigned,
181 : MachineSemantic::kInt32);
182 : }
183 : constexpr static MachineType CompressedPointer() {
184 : return MachineType(MachineRepresentation::kCompressedPointer,
185 : MachineSemantic::kAny);
186 : }
187 : constexpr static MachineType AnyCompressed() {
188 : return MachineType(MachineRepresentation::kCompressed,
189 : MachineSemantic::kAny);
190 : }
191 : constexpr static MachineType Bool() {
192 : return MachineType(MachineRepresentation::kBit, MachineSemantic::kBool);
193 : }
194 : constexpr static MachineType TaggedBool() {
195 : return MachineType(MachineRepresentation::kTagged, MachineSemantic::kBool);
196 : }
197 : constexpr static MachineType CompressedBool() {
198 : return MachineType(MachineRepresentation::kCompressed,
199 : MachineSemantic::kBool);
200 : }
201 : constexpr static MachineType None() {
202 : return MachineType(MachineRepresentation::kNone, MachineSemantic::kNone);
203 : }
204 :
205 : // These naked representations should eventually go away.
206 : constexpr static MachineType RepWord8() {
207 : return MachineType(MachineRepresentation::kWord8, MachineSemantic::kNone);
208 : }
209 : constexpr static MachineType RepWord16() {
210 : return MachineType(MachineRepresentation::kWord16, MachineSemantic::kNone);
211 : }
212 : constexpr static MachineType RepWord32() {
213 : return MachineType(MachineRepresentation::kWord32, MachineSemantic::kNone);
214 : }
215 : constexpr static MachineType RepWord64() {
216 : return MachineType(MachineRepresentation::kWord64, MachineSemantic::kNone);
217 : }
218 : constexpr static MachineType RepFloat32() {
219 : return MachineType(MachineRepresentation::kFloat32, MachineSemantic::kNone);
220 : }
221 : constexpr static MachineType RepFloat64() {
222 : return MachineType(MachineRepresentation::kFloat64, MachineSemantic::kNone);
223 : }
224 : constexpr static MachineType RepSimd128() {
225 : return MachineType(MachineRepresentation::kSimd128, MachineSemantic::kNone);
226 : }
227 : constexpr static MachineType RepTagged() {
228 : return MachineType(MachineRepresentation::kTagged, MachineSemantic::kNone);
229 : }
230 : constexpr static MachineType RepCompressed() {
231 : return MachineType(MachineRepresentation::kCompressed,
232 : MachineSemantic::kNone);
233 : }
234 : constexpr static MachineType RepBit() {
235 : return MachineType(MachineRepresentation::kBit, MachineSemantic::kNone);
236 : }
237 :
238 6023493 : static MachineType TypeForRepresentation(const MachineRepresentation& rep,
239 : bool isSigned = true) {
240 6023493 : switch (rep) {
241 : case MachineRepresentation::kNone:
242 : return MachineType::None();
243 : case MachineRepresentation::kBit:
244 : return MachineType::Bool();
245 : case MachineRepresentation::kWord8:
246 0 : return isSigned ? MachineType::Int8() : MachineType::Uint8();
247 : case MachineRepresentation::kWord16:
248 0 : return isSigned ? MachineType::Int16() : MachineType::Uint16();
249 : case MachineRepresentation::kWord32:
250 2492744 : return isSigned ? MachineType::Int32() : MachineType::Uint32();
251 : case MachineRepresentation::kWord64:
252 81687 : return isSigned ? MachineType::Int64() : MachineType::Uint64();
253 : case MachineRepresentation::kFloat32:
254 : return MachineType::Float32();
255 : case MachineRepresentation::kFloat64:
256 : return MachineType::Float64();
257 : case MachineRepresentation::kSimd128:
258 : return MachineType::Simd128();
259 : case MachineRepresentation::kTagged:
260 : return MachineType::AnyTagged();
261 : case MachineRepresentation::kTaggedSigned:
262 : return MachineType::TaggedSigned();
263 : case MachineRepresentation::kTaggedPointer:
264 : return MachineType::TaggedPointer();
265 : case MachineRepresentation::kCompressed:
266 : return MachineType::AnyCompressed();
267 : case MachineRepresentation::kCompressedPointer:
268 : return MachineType::CompressedPointer();
269 : case MachineRepresentation::kCompressedSigned:
270 : return MachineType::CompressedSigned();
271 : default:
272 0 : UNREACHABLE();
273 : }
274 : }
275 :
276 : bool LessThanOrEqualPointerSize() {
277 : return ElementSizeLog2Of(this->representation()) <= kSystemPointerSizeLog2;
278 : }
279 :
280 : private:
281 : MachineRepresentation representation_;
282 : MachineSemantic semantic_;
283 : };
284 :
285 : V8_INLINE size_t hash_value(MachineRepresentation rep) {
286 15572457 : return static_cast<size_t>(rep);
287 : }
288 :
289 : V8_INLINE size_t hash_value(MachineType type) {
290 0 : return static_cast<size_t>(type.representation()) +
291 0 : static_cast<size_t>(type.semantic()) * 16;
292 : }
293 :
294 : V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
295 : MachineRepresentation rep);
296 : std::ostream& operator<<(std::ostream& os, MachineSemantic type);
297 : V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, MachineType type);
298 :
299 : inline bool IsFloatingPoint(MachineRepresentation rep) {
300 : return rep >= MachineRepresentation::kFirstFPRepresentation;
301 : }
302 :
303 : inline bool CanBeTaggedPointer(MachineRepresentation rep) {
304 103318986 : return rep == MachineRepresentation::kTagged ||
305 : rep == MachineRepresentation::kTaggedPointer;
306 : }
307 :
308 : inline bool CanBeTaggedSigned(MachineRepresentation rep) {
309 35089 : return rep == MachineRepresentation::kTagged ||
310 35089 : rep == MachineRepresentation::kTaggedSigned;
311 : }
312 :
313 : inline bool IsAnyTagged(MachineRepresentation rep) {
314 14048330 : return CanBeTaggedPointer(rep) || rep == MachineRepresentation::kTaggedSigned;
315 : }
316 :
317 : inline bool CanBeCompressedPointer(MachineRepresentation rep) {
318 41604075 : return rep == MachineRepresentation::kCompressed ||
319 : rep == MachineRepresentation::kCompressedPointer;
320 : }
321 :
322 : inline bool CanBeTaggedOrCompressedPointer(MachineRepresentation rep) {
323 124674020 : return CanBeTaggedPointer(rep) || CanBeCompressedPointer(rep);
324 : }
325 :
326 : inline bool CanBeCompressedSigned(MachineRepresentation rep) {
327 0 : return rep == MachineRepresentation::kCompressed ||
328 0 : rep == MachineRepresentation::kCompressedSigned;
329 : }
330 :
331 : inline bool IsAnyCompressed(MachineRepresentation rep) {
332 533610 : return CanBeCompressedPointer(rep) ||
333 : rep == MachineRepresentation::kCompressedSigned;
334 : }
335 :
336 : // Gets the log2 of the element size in bytes of the machine type.
337 10962189 : V8_EXPORT_PRIVATE inline int ElementSizeLog2Of(MachineRepresentation rep) {
338 10962189 : switch (rep) {
339 : case MachineRepresentation::kBit:
340 : case MachineRepresentation::kWord8:
341 : return 0;
342 : case MachineRepresentation::kWord16:
343 44755 : return 1;
344 : case MachineRepresentation::kWord32:
345 : case MachineRepresentation::kFloat32:
346 2751976 : return 2;
347 : case MachineRepresentation::kWord64:
348 : case MachineRepresentation::kFloat64:
349 977218 : return 3;
350 : case MachineRepresentation::kSimd128:
351 26028 : return 4;
352 : case MachineRepresentation::kTaggedSigned:
353 : case MachineRepresentation::kTaggedPointer:
354 : case MachineRepresentation::kTagged:
355 : case MachineRepresentation::kCompressedSigned:
356 : case MachineRepresentation::kCompressedPointer:
357 : case MachineRepresentation::kCompressed:
358 7043553 : return kTaggedSizeLog2;
359 : default:
360 : break;
361 : }
362 0 : UNREACHABLE();
363 : }
364 :
365 : V8_EXPORT_PRIVATE inline int ElementSizeInBytes(MachineRepresentation rep) {
366 361257 : return 1 << ElementSizeLog2Of(rep);
367 : }
368 :
369 : // Converts representation to bit for representation masks.
370 : V8_EXPORT_PRIVATE inline constexpr int RepresentationBit(
371 : MachineRepresentation rep) {
372 33290561 : return 1 << static_cast<int>(rep);
373 : }
374 :
375 : } // namespace internal
376 : } // namespace v8
377 :
378 : #endif // V8_MACHINE_TYPE_H_
|