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