• 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_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