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.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   kFloat32,
26   kFloat64,
27   kTagged
28 };
29 
30 enum class MachineSemantic : uint8_t {
31   kNone,
32   kBool,
33   kInt32,
34   kUint32,
35   kInt64,
36   kUint64,
37   kNumber,
38   kAny
39 };
40 
41 class MachineType {
42  public:
MachineType()43   MachineType()
44       : representation_(MachineRepresentation::kNone),
45         semantic_(MachineSemantic::kNone) {}
MachineType(MachineRepresentation representation,MachineSemantic semantic)46   MachineType(MachineRepresentation representation, MachineSemantic semantic)
47       : representation_(representation), semantic_(semantic) {}
48 
49   bool operator==(MachineType other) const {
50     return representation() == other.representation() &&
51            semantic() == other.semantic();
52   }
53 
54   bool operator!=(MachineType other) const { return !(*this == other); }
55 
56 
representation()57   MachineRepresentation representation() const { return representation_; }
semantic()58   MachineSemantic semantic() const { return semantic_; }
59 
IsSigned()60   bool IsSigned() {
61     return semantic() == MachineSemantic::kInt32 ||
62            semantic() == MachineSemantic::kInt64;
63   }
IsUnsigned()64   bool IsUnsigned() {
65     return semantic() == MachineSemantic::kUint32 ||
66            semantic() == MachineSemantic::kUint64;
67   }
68 
PointerRepresentation()69   static MachineRepresentation PointerRepresentation() {
70     return (kPointerSize == 4) ? MachineRepresentation::kWord32
71                                : MachineRepresentation::kWord64;
72   }
Pointer()73   static MachineType Pointer() {
74     return MachineType(PointerRepresentation(), MachineSemantic::kNone);
75   }
IntPtr()76   static MachineType IntPtr() {
77     return (kPointerSize == 4) ? Int32() : Int64();
78   }
Float32()79   static MachineType Float32() {
80     return MachineType(MachineRepresentation::kFloat32,
81                        MachineSemantic::kNumber);
82   }
Float64()83   static MachineType Float64() {
84     return MachineType(MachineRepresentation::kFloat64,
85                        MachineSemantic::kNumber);
86   }
Int8()87   static MachineType Int8() {
88     return MachineType(MachineRepresentation::kWord8, MachineSemantic::kInt32);
89   }
Uint8()90   static MachineType Uint8() {
91     return MachineType(MachineRepresentation::kWord8, MachineSemantic::kUint32);
92   }
Int16()93   static MachineType Int16() {
94     return MachineType(MachineRepresentation::kWord16, MachineSemantic::kInt32);
95   }
Uint16()96   static MachineType Uint16() {
97     return MachineType(MachineRepresentation::kWord16,
98                        MachineSemantic::kUint32);
99   }
Int32()100   static MachineType Int32() {
101     return MachineType(MachineRepresentation::kWord32, MachineSemantic::kInt32);
102   }
Uint32()103   static MachineType Uint32() {
104     return MachineType(MachineRepresentation::kWord32,
105                        MachineSemantic::kUint32);
106   }
Int64()107   static MachineType Int64() {
108     return MachineType(MachineRepresentation::kWord64, MachineSemantic::kInt64);
109   }
Uint64()110   static MachineType Uint64() {
111     return MachineType(MachineRepresentation::kWord64,
112                        MachineSemantic::kUint64);
113   }
AnyTagged()114   static MachineType AnyTagged() {
115     return MachineType(MachineRepresentation::kTagged, MachineSemantic::kAny);
116   }
Bool()117   static MachineType Bool() {
118     return MachineType(MachineRepresentation::kBit, MachineSemantic::kBool);
119   }
TaggedBool()120   static MachineType TaggedBool() {
121     return MachineType(MachineRepresentation::kTagged, MachineSemantic::kBool);
122   }
None()123   static MachineType None() {
124     return MachineType(MachineRepresentation::kNone, MachineSemantic::kNone);
125   }
126 
127   // These naked representations should eventually go away.
RepWord8()128   static MachineType RepWord8() {
129     return MachineType(MachineRepresentation::kWord8, MachineSemantic::kNone);
130   }
RepWord16()131   static MachineType RepWord16() {
132     return MachineType(MachineRepresentation::kWord16, MachineSemantic::kNone);
133   }
RepWord32()134   static MachineType RepWord32() {
135     return MachineType(MachineRepresentation::kWord32, MachineSemantic::kNone);
136   }
RepWord64()137   static MachineType RepWord64() {
138     return MachineType(MachineRepresentation::kWord64, MachineSemantic::kNone);
139   }
RepFloat32()140   static MachineType RepFloat32() {
141     return MachineType(MachineRepresentation::kFloat32, MachineSemantic::kNone);
142   }
RepFloat64()143   static MachineType RepFloat64() {
144     return MachineType(MachineRepresentation::kFloat64, MachineSemantic::kNone);
145   }
RepTagged()146   static MachineType RepTagged() {
147     return MachineType(MachineRepresentation::kTagged, MachineSemantic::kNone);
148   }
RepBit()149   static MachineType RepBit() {
150     return MachineType(MachineRepresentation::kBit, MachineSemantic::kNone);
151   }
152 
153  private:
154   MachineRepresentation representation_;
155   MachineSemantic semantic_;
156 };
157 
hash_value(MachineRepresentation rep)158 V8_INLINE size_t hash_value(MachineRepresentation rep) {
159   return static_cast<size_t>(rep);
160 }
161 
hash_value(MachineType type)162 V8_INLINE size_t hash_value(MachineType type) {
163   return static_cast<size_t>(type.representation()) +
164          static_cast<size_t>(type.semantic()) * 16;
165 }
166 
167 std::ostream& operator<<(std::ostream& os, MachineRepresentation rep);
168 std::ostream& operator<<(std::ostream& os, MachineSemantic type);
169 std::ostream& operator<<(std::ostream& os, MachineType type);
170 
IsFloatingPoint(MachineRepresentation rep)171 inline bool IsFloatingPoint(MachineRepresentation rep) {
172   return rep == MachineRepresentation::kFloat32 ||
173          rep == MachineRepresentation::kFloat64;
174 }
175 
176 // Gets the log2 of the element size in bytes of the machine type.
ElementSizeLog2Of(MachineRepresentation rep)177 inline int ElementSizeLog2Of(MachineRepresentation rep) {
178   switch (rep) {
179     case MachineRepresentation::kBit:
180     case MachineRepresentation::kWord8:
181       return 0;
182     case MachineRepresentation::kWord16:
183       return 1;
184     case MachineRepresentation::kWord32:
185     case MachineRepresentation::kFloat32:
186       return 2;
187     case MachineRepresentation::kWord64:
188     case MachineRepresentation::kFloat64:
189       return 3;
190     case MachineRepresentation::kTagged:
191       return kPointerSizeLog2;
192     default:
193       break;
194   }
195   UNREACHABLE();
196   return -1;
197 }
198 
199 typedef Signature<MachineType> MachineSignature;
200 
201 }  // namespace internal
202 }  // namespace v8
203 
204 #endif  // V8_MACHINE_TYPE_H_
205