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
13namespace v8 {
14namespace internal {
15
16enum 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
37bool IsSubtype(MachineRepresentation rep1, MachineRepresentation rep2);
38
39static_assert(static_cast<int>(MachineRepresentation::kLastRepresentation) <
40 kIntSize * kBitsPerByte,
41 "Bit masks of MachineRepresentation should fit in an int");
42
43V8_EXPORT_PRIVATE const char* MachineReprToString(MachineRepresentation);
44
45enum class MachineSemantic : uint8_t {
46 kNone,
47 kBool,
48 kInt32,
49 kUint32,
50 kInt64,
51 kUint64,
52 kNumber,
53 kAny
54};
55
56V8_EXPORT_PRIVATE inline int ElementSizeLog2Of(MachineRepresentation rep);
57
58V8_EXPORT_PRIVATE inline int ElementSizeInBytes(MachineRepresentation rep);
59
60class MachineType {
61 public:
62 constexpr MachineType()
63 : representation_(MachineRepresentation::kNone),
64 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 return representation() == other.representation() &&
71 semantic() == other.semantic();
72 }
73
74 constexpr bool operator!=(MachineType other) const {
75 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 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 return representation() == MachineRepresentation::kTaggedPointer ||
97 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 static MachineType TypeForRepresentation(const MachineRepresentation& rep,
239 bool isSigned = true) {
240 switch (rep) {
241 case MachineRepresentation::kNone:
242 return MachineType::None();
243 case MachineRepresentation::kBit:
244 return MachineType::Bool();
245 case MachineRepresentation::kWord8:
246 return isSigned ? MachineType::Int8() : MachineType::Uint8();
247 case MachineRepresentation::kWord16:
248 return isSigned ? MachineType::Int16() : MachineType::Uint16();
249 case MachineRepresentation::kWord32:
250 return isSigned ? MachineType::Int32() : MachineType::Uint32();
251 case MachineRepresentation::kWord64:
252 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 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
285V8_INLINE size_t hash_value(MachineRepresentation rep) {
286 return static_cast<size_t>(rep);
287}
288
289V8_INLINE size_t hash_value(MachineType type) {
290 return static_cast<size_t>(type.representation()) +
291 static_cast<size_t>(type.semantic()) * 16;
292}
293
294V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
295 MachineRepresentation rep);
296std::ostream& operator<<(std::ostream& os, MachineSemantic type);
297V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, MachineType type);
298
299inline bool IsFloatingPoint(MachineRepresentation rep) {
300 return rep >= MachineRepresentation::kFirstFPRepresentation;
301}
302
303inline bool CanBeTaggedPointer(MachineRepresentation rep) {
304 return rep == MachineRepresentation::kTagged ||
305 rep == MachineRepresentation::kTaggedPointer;
306}
307
308inline bool CanBeTaggedSigned(MachineRepresentation rep) {
309 return rep == MachineRepresentation::kTagged ||
310 rep == MachineRepresentation::kTaggedSigned;
311}
312
313inline bool IsAnyTagged(MachineRepresentation rep) {
314 return CanBeTaggedPointer(rep) || rep == MachineRepresentation::kTaggedSigned;
315}
316
317inline bool CanBeCompressedPointer(MachineRepresentation rep) {
318 return rep == MachineRepresentation::kCompressed ||
319 rep == MachineRepresentation::kCompressedPointer;
320}
321
322inline bool CanBeTaggedOrCompressedPointer(MachineRepresentation rep) {
323 return CanBeTaggedPointer(rep) || CanBeCompressedPointer(rep);
324}
325
326inline bool CanBeCompressedSigned(MachineRepresentation rep) {
327 return rep == MachineRepresentation::kCompressed ||
328 rep == MachineRepresentation::kCompressedSigned;
329}
330
331inline bool IsAnyCompressed(MachineRepresentation rep) {
332 return CanBeCompressedPointer(rep) ||
333 rep == MachineRepresentation::kCompressedSigned;
334}
335
336// Gets the log2 of the element size in bytes of the machine type.
337V8_EXPORT_PRIVATE inline int ElementSizeLog2Of(MachineRepresentation rep) {
338 switch (rep) {
339 case MachineRepresentation::kBit:
340 case MachineRepresentation::kWord8:
341 return 0;
342 case MachineRepresentation::kWord16:
343 return 1;
344 case MachineRepresentation::kWord32:
345 case MachineRepresentation::kFloat32:
346 return 2;
347 case MachineRepresentation::kWord64:
348 case MachineRepresentation::kFloat64:
349 return 3;
350 case MachineRepresentation::kSimd128:
351 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 return kTaggedSizeLog2;
359 default:
360 break;
361 }
362 UNREACHABLE();
363}
364
365V8_EXPORT_PRIVATE inline int ElementSizeInBytes(MachineRepresentation rep) {
366 return 1 << ElementSizeLog2Of(rep);
367}
368
369// Converts representation to bit for representation masks.
370V8_EXPORT_PRIVATE inline constexpr int RepresentationBit(
371 MachineRepresentation rep) {
372 return 1 << static_cast<int>(rep);
373}
374
375} // namespace internal
376} // namespace v8
377
378#endif // V8_MACHINE_TYPE_H_
379