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_CODEGEN_MACHINE_TYPE_H_
6 #define V8_CODEGEN_MACHINE_TYPE_H_
7
8 #include <iosfwd>
9
10 #include "src/base/bits.h"
11 #include "src/common/globals.h"
12 #include "src/flags/flags.h"
13
14 namespace v8 {
15 namespace internal {
16
17 enum class MachineRepresentation : uint8_t {
18 kNone,
19 kBit,
20 kWord8,
21 kWord16,
22 kWord32,
23 kWord64,
24 kTaggedSigned, // (uncompressed) Smi
25 kTaggedPointer, // (uncompressed) HeapObject
26 kTagged, // (uncompressed) Object (Smi or HeapObject)
27 kCompressedPointer, // (compressed) HeapObject
28 kCompressed, // (compressed) Object (Smi or HeapObject)
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 constexpr int ElementSizeLog2Of(MachineRepresentation);
57
58 V8_EXPORT_PRIVATE inline constexpr int ElementSizeInBytes(
59 MachineRepresentation);
60
61 class MachineType {
62 public:
MachineType()63 constexpr MachineType()
64 : representation_(MachineRepresentation::kNone),
65 semantic_(MachineSemantic::kNone) {}
MachineType(MachineRepresentation representation,MachineSemantic semantic)66 constexpr MachineType(MachineRepresentation representation,
67 MachineSemantic semantic)
68 : representation_(representation), semantic_(semantic) {}
69
70 constexpr bool operator==(MachineType other) const {
71 return representation() == other.representation() &&
72 semantic() == other.semantic();
73 }
74
75 constexpr bool operator!=(MachineType other) const {
76 return !(*this == other);
77 }
78
representation()79 constexpr MachineRepresentation representation() const {
80 return representation_;
81 }
semantic()82 constexpr MachineSemantic semantic() const { return semantic_; }
83
IsNone()84 constexpr bool IsNone() const {
85 return representation() == MachineRepresentation::kNone;
86 }
87
IsSigned()88 constexpr bool IsSigned() const {
89 return semantic() == MachineSemantic::kInt32 ||
90 semantic() == MachineSemantic::kInt64;
91 }
IsUnsigned()92 constexpr bool IsUnsigned() const {
93 return semantic() == MachineSemantic::kUint32 ||
94 semantic() == MachineSemantic::kUint64;
95 }
IsTagged()96 constexpr bool IsTagged() const {
97 return representation() == MachineRepresentation::kTaggedPointer ||
98 representation() == MachineRepresentation::kTaggedSigned ||
99 representation() == MachineRepresentation::kTagged;
100 }
IsTaggedSigned()101 constexpr bool IsTaggedSigned() const {
102 return representation() == MachineRepresentation::kTaggedSigned;
103 }
IsTaggedPointer()104 constexpr bool IsTaggedPointer() const {
105 return representation() == MachineRepresentation::kTaggedPointer;
106 }
IsCompressed()107 constexpr bool IsCompressed() const {
108 return representation() == MachineRepresentation::kCompressedPointer ||
109 representation() == MachineRepresentation::kCompressed;
110 }
IsCompressedPointer()111 constexpr bool IsCompressedPointer() const {
112 return representation() == MachineRepresentation::kCompressedPointer;
113 }
TaggedRepresentation()114 constexpr static MachineRepresentation TaggedRepresentation() {
115 return (kTaggedSize == 4) ? MachineRepresentation::kWord32
116 : MachineRepresentation::kWord64;
117 }
PointerRepresentation()118 constexpr static MachineRepresentation PointerRepresentation() {
119 return (kSystemPointerSize == 4) ? MachineRepresentation::kWord32
120 : MachineRepresentation::kWord64;
121 }
UintPtr()122 constexpr static MachineType UintPtr() {
123 return (kSystemPointerSize == 4) ? Uint32() : Uint64();
124 }
IntPtr()125 constexpr static MachineType IntPtr() {
126 return (kSystemPointerSize == 4) ? Int32() : Int64();
127 }
Int8()128 constexpr static MachineType Int8() {
129 return MachineType(MachineRepresentation::kWord8, MachineSemantic::kInt32);
130 }
Uint8()131 constexpr static MachineType Uint8() {
132 return MachineType(MachineRepresentation::kWord8, MachineSemantic::kUint32);
133 }
Int16()134 constexpr static MachineType Int16() {
135 return MachineType(MachineRepresentation::kWord16, MachineSemantic::kInt32);
136 }
Uint16()137 constexpr static MachineType Uint16() {
138 return MachineType(MachineRepresentation::kWord16,
139 MachineSemantic::kUint32);
140 }
Int32()141 constexpr static MachineType Int32() {
142 return MachineType(MachineRepresentation::kWord32, MachineSemantic::kInt32);
143 }
Uint32()144 constexpr static MachineType Uint32() {
145 return MachineType(MachineRepresentation::kWord32,
146 MachineSemantic::kUint32);
147 }
Int64()148 constexpr static MachineType Int64() {
149 return MachineType(MachineRepresentation::kWord64, MachineSemantic::kInt64);
150 }
Uint64()151 constexpr static MachineType Uint64() {
152 return MachineType(MachineRepresentation::kWord64,
153 MachineSemantic::kUint64);
154 }
Float32()155 constexpr static MachineType Float32() {
156 return MachineType(MachineRepresentation::kFloat32,
157 MachineSemantic::kNumber);
158 }
Float64()159 constexpr static MachineType Float64() {
160 return MachineType(MachineRepresentation::kFloat64,
161 MachineSemantic::kNumber);
162 }
Simd128()163 constexpr static MachineType Simd128() {
164 return MachineType(MachineRepresentation::kSimd128, MachineSemantic::kNone);
165 }
Pointer()166 constexpr static MachineType Pointer() {
167 return MachineType(PointerRepresentation(), MachineSemantic::kNone);
168 }
TaggedPointer()169 constexpr static MachineType TaggedPointer() {
170 return MachineType(MachineRepresentation::kTaggedPointer,
171 MachineSemantic::kAny);
172 }
TaggedSigned()173 constexpr static MachineType TaggedSigned() {
174 return MachineType(MachineRepresentation::kTaggedSigned,
175 MachineSemantic::kInt32);
176 }
AnyTagged()177 constexpr static MachineType AnyTagged() {
178 return MachineType(MachineRepresentation::kTagged, MachineSemantic::kAny);
179 }
CompressedPointer()180 constexpr static MachineType CompressedPointer() {
181 return MachineType(MachineRepresentation::kCompressedPointer,
182 MachineSemantic::kAny);
183 }
AnyCompressed()184 constexpr static MachineType AnyCompressed() {
185 return MachineType(MachineRepresentation::kCompressed,
186 MachineSemantic::kAny);
187 }
Bool()188 constexpr static MachineType Bool() {
189 return MachineType(MachineRepresentation::kBit, MachineSemantic::kBool);
190 }
None()191 constexpr static MachineType None() {
192 return MachineType(MachineRepresentation::kNone, MachineSemantic::kNone);
193 }
194
195 static MachineType TypeForRepresentation(const MachineRepresentation& rep,
196 bool isSigned = true) {
197 switch (rep) {
198 case MachineRepresentation::kNone:
199 return MachineType::None();
200 case MachineRepresentation::kBit:
201 return MachineType::Bool();
202 case MachineRepresentation::kWord8:
203 return isSigned ? MachineType::Int8() : MachineType::Uint8();
204 case MachineRepresentation::kWord16:
205 return isSigned ? MachineType::Int16() : MachineType::Uint16();
206 case MachineRepresentation::kWord32:
207 return isSigned ? MachineType::Int32() : MachineType::Uint32();
208 case MachineRepresentation::kWord64:
209 return isSigned ? MachineType::Int64() : MachineType::Uint64();
210 case MachineRepresentation::kFloat32:
211 return MachineType::Float32();
212 case MachineRepresentation::kFloat64:
213 return MachineType::Float64();
214 case MachineRepresentation::kSimd128:
215 return MachineType::Simd128();
216 case MachineRepresentation::kTagged:
217 return MachineType::AnyTagged();
218 case MachineRepresentation::kTaggedSigned:
219 return MachineType::TaggedSigned();
220 case MachineRepresentation::kTaggedPointer:
221 return MachineType::TaggedPointer();
222 case MachineRepresentation::kCompressed:
223 return MachineType::AnyCompressed();
224 case MachineRepresentation::kCompressedPointer:
225 return MachineType::CompressedPointer();
226 default:
227 UNREACHABLE();
228 }
229 }
230
LessThanOrEqualPointerSize()231 constexpr bool LessThanOrEqualPointerSize() const {
232 return ElementSizeLog2Of(this->representation()) <= kSystemPointerSizeLog2;
233 }
234
MemSize()235 constexpr byte MemSize() const {
236 return 1 << i::ElementSizeLog2Of(this->representation());
237 }
238
239 private:
240 MachineRepresentation representation_;
241 MachineSemantic semantic_;
242 };
243
hash_value(MachineRepresentation rep)244 V8_INLINE size_t hash_value(MachineRepresentation rep) {
245 return static_cast<size_t>(rep);
246 }
247
hash_value(MachineType type)248 V8_INLINE size_t hash_value(MachineType type) {
249 return static_cast<size_t>(type.representation()) +
250 static_cast<size_t>(type.semantic()) * 16;
251 }
252
253 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
254 MachineRepresentation rep);
255 std::ostream& operator<<(std::ostream& os, MachineSemantic type);
256 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, MachineType type);
257
IsFloatingPoint(MachineRepresentation rep)258 inline bool IsFloatingPoint(MachineRepresentation rep) {
259 return rep >= MachineRepresentation::kFirstFPRepresentation;
260 }
261
CanBeTaggedPointer(MachineRepresentation rep)262 inline bool CanBeTaggedPointer(MachineRepresentation rep) {
263 return rep == MachineRepresentation::kTagged ||
264 rep == MachineRepresentation::kTaggedPointer;
265 }
266
CanBeTaggedSigned(MachineRepresentation rep)267 inline bool CanBeTaggedSigned(MachineRepresentation rep) {
268 return rep == MachineRepresentation::kTagged ||
269 rep == MachineRepresentation::kTaggedSigned;
270 }
271
IsAnyTagged(MachineRepresentation rep)272 inline bool IsAnyTagged(MachineRepresentation rep) {
273 return CanBeTaggedPointer(rep) || rep == MachineRepresentation::kTaggedSigned;
274 }
275
CanBeCompressedPointer(MachineRepresentation rep)276 inline bool CanBeCompressedPointer(MachineRepresentation rep) {
277 return rep == MachineRepresentation::kCompressed ||
278 rep == MachineRepresentation::kCompressedPointer;
279 }
280
CanBeTaggedOrCompressedPointer(MachineRepresentation rep)281 inline bool CanBeTaggedOrCompressedPointer(MachineRepresentation rep) {
282 return CanBeTaggedPointer(rep) || CanBeCompressedPointer(rep);
283 }
284
IsAnyCompressed(MachineRepresentation rep)285 inline bool IsAnyCompressed(MachineRepresentation rep) {
286 return CanBeCompressedPointer(rep);
287 }
288
289 // Gets the log2 of the element size in bytes of the machine type.
ElementSizeLog2Of(MachineRepresentation rep)290 V8_EXPORT_PRIVATE inline constexpr int ElementSizeLog2Of(
291 MachineRepresentation rep) {
292 switch (rep) {
293 case MachineRepresentation::kBit:
294 case MachineRepresentation::kWord8:
295 return 0;
296 case MachineRepresentation::kWord16:
297 return 1;
298 case MachineRepresentation::kWord32:
299 case MachineRepresentation::kFloat32:
300 return 2;
301 case MachineRepresentation::kWord64:
302 case MachineRepresentation::kFloat64:
303 return 3;
304 case MachineRepresentation::kSimd128:
305 return 4;
306 case MachineRepresentation::kTaggedSigned:
307 case MachineRepresentation::kTaggedPointer:
308 case MachineRepresentation::kTagged:
309 case MachineRepresentation::kCompressedPointer:
310 case MachineRepresentation::kCompressed:
311 return kTaggedSizeLog2;
312 default:
313 #if V8_HAS_CXX14_CONSTEXPR
314 UNREACHABLE();
315 #else
316 // Return something for older compilers.
317 return -1;
318 #endif
319 }
320 }
321
ElementSizeInBytes(MachineRepresentation rep)322 V8_EXPORT_PRIVATE inline constexpr int ElementSizeInBytes(
323 MachineRepresentation rep) {
324 return 1 << ElementSizeLog2Of(rep);
325 }
326
327 // Converts representation to bit for representation masks.
RepresentationBit(MachineRepresentation rep)328 V8_EXPORT_PRIVATE inline constexpr int RepresentationBit(
329 MachineRepresentation rep) {
330 return 1 << static_cast<int>(rep);
331 }
332
333 } // namespace internal
334 } // namespace v8
335
336 #endif // V8_CODEGEN_MACHINE_TYPE_H_
337