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