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