• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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