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