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