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
15namespace v8 {
16namespace internal {
17
18enum 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
39static_assert(static_cast<int>(MachineRepresentation::kLastRepresentation) <
40                  kIntSize * kBitsPerByte,
41              "Bit masks of MachineRepresentation should fit in an int");
42
43const char* MachineReprToString(MachineRepresentation);
44
45enum class MachineSemantic {
46  kNone,
47  kBool,
48  kInt32,
49  kUint32,
50  kInt64,
51  kUint64,
52  kNumber,
53  kAny
54};
55
56class MachineType {
57 public:
58  MachineType()
59      : representation_(MachineRepresentation::kNone),
60        semantic_(MachineSemantic::kNone) {}
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
72  MachineRepresentation representation() const { return representation_; }
73  MachineSemantic semantic() const { return semantic_; }
74
75  bool IsNone() { return representation() == MachineRepresentation::kNone; }
76
77  bool IsSigned() {
78    return semantic() == MachineSemantic::kInt32 ||
79           semantic() == MachineSemantic::kInt64;
80  }
81  bool IsUnsigned() {
82    return semantic() == MachineSemantic::kUint32 ||
83           semantic() == MachineSemantic::kUint64;
84  }
85  static MachineRepresentation PointerRepresentation() {
86    return (kPointerSize == 4) ? MachineRepresentation::kWord32
87                               : MachineRepresentation::kWord64;
88  }
89  static MachineType UintPtr() {
90    return (kPointerSize == 4) ? Uint32() : Uint64();
91  }
92  static MachineType IntPtr() {
93    return (kPointerSize == 4) ? Int32() : Int64();
94  }
95  static MachineType Int8() {
96    return MachineType(MachineRepresentation::kWord8, MachineSemantic::kInt32);
97  }
98  static MachineType Uint8() {
99    return MachineType(MachineRepresentation::kWord8, MachineSemantic::kUint32);
100  }
101  static MachineType Int16() {
102    return MachineType(MachineRepresentation::kWord16, MachineSemantic::kInt32);
103  }
104  static MachineType Uint16() {
105    return MachineType(MachineRepresentation::kWord16,
106                       MachineSemantic::kUint32);
107  }
108  static MachineType Int32() {
109    return MachineType(MachineRepresentation::kWord32, MachineSemantic::kInt32);
110  }
111  static MachineType Uint32() {
112    return MachineType(MachineRepresentation::kWord32,
113                       MachineSemantic::kUint32);
114  }
115  static MachineType Int64() {
116    return MachineType(MachineRepresentation::kWord64, MachineSemantic::kInt64);
117  }
118  static MachineType Uint64() {
119    return MachineType(MachineRepresentation::kWord64,
120                       MachineSemantic::kUint64);
121  }
122  static MachineType Float32() {
123    return MachineType(MachineRepresentation::kFloat32,
124                       MachineSemantic::kNumber);
125  }
126  static MachineType Float64() {
127    return MachineType(MachineRepresentation::kFloat64,
128                       MachineSemantic::kNumber);
129  }
130  static MachineType Simd128() {
131    return MachineType(MachineRepresentation::kSimd128, MachineSemantic::kNone);
132  }
133  static MachineType Simd1x4() {
134    return MachineType(MachineRepresentation::kSimd1x4, MachineSemantic::kNone);
135  }
136  static MachineType Simd1x8() {
137    return MachineType(MachineRepresentation::kSimd1x8, MachineSemantic::kNone);
138  }
139  static MachineType Simd1x16() {
140    return MachineType(MachineRepresentation::kSimd1x16,
141                       MachineSemantic::kNone);
142  }
143  static MachineType Pointer() {
144    return MachineType(PointerRepresentation(), MachineSemantic::kNone);
145  }
146  static MachineType TaggedPointer() {
147    return MachineType(MachineRepresentation::kTaggedPointer,
148                       MachineSemantic::kAny);
149  }
150  static MachineType TaggedSigned() {
151    return MachineType(MachineRepresentation::kTaggedSigned,
152                       MachineSemantic::kInt32);
153  }
154  static MachineType AnyTagged() {
155    return MachineType(MachineRepresentation::kTagged, MachineSemantic::kAny);
156  }
157  static MachineType Bool() {
158    return MachineType(MachineRepresentation::kBit, MachineSemantic::kBool);
159  }
160  static MachineType TaggedBool() {
161    return MachineType(MachineRepresentation::kTagged, MachineSemantic::kBool);
162  }
163  static MachineType None() {
164    return MachineType(MachineRepresentation::kNone, MachineSemantic::kNone);
165  }
166
167  // These naked representations should eventually go away.
168  static MachineType RepWord8() {
169    return MachineType(MachineRepresentation::kWord8, MachineSemantic::kNone);
170  }
171  static MachineType RepWord16() {
172    return MachineType(MachineRepresentation::kWord16, MachineSemantic::kNone);
173  }
174  static MachineType RepWord32() {
175    return MachineType(MachineRepresentation::kWord32, MachineSemantic::kNone);
176  }
177  static MachineType RepWord64() {
178    return MachineType(MachineRepresentation::kWord64, MachineSemantic::kNone);
179  }
180  static MachineType RepFloat32() {
181    return MachineType(MachineRepresentation::kFloat32, MachineSemantic::kNone);
182  }
183  static MachineType RepFloat64() {
184    return MachineType(MachineRepresentation::kFloat64, MachineSemantic::kNone);
185  }
186  static MachineType RepSimd128() {
187    return MachineType(MachineRepresentation::kSimd128, MachineSemantic::kNone);
188  }
189  static MachineType RepSimd1x4() {
190    return MachineType(MachineRepresentation::kSimd1x4, MachineSemantic::kNone);
191  }
192  static MachineType RepSimd1x8() {
193    return MachineType(MachineRepresentation::kSimd1x8, MachineSemantic::kNone);
194  }
195  static MachineType RepSimd1x16() {
196    return MachineType(MachineRepresentation::kSimd1x16,
197                       MachineSemantic::kNone);
198  }
199  static MachineType RepTagged() {
200    return MachineType(MachineRepresentation::kTagged, MachineSemantic::kNone);
201  }
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
250V8_INLINE size_t hash_value(MachineRepresentation rep) {
251  return static_cast<size_t>(rep);
252}
253
254V8_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
259V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
260                                           MachineRepresentation rep);
261std::ostream& operator<<(std::ostream& os, MachineSemantic type);
262V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, MachineType type);
263
264inline bool IsFloatingPoint(MachineRepresentation rep) {
265  return rep >= MachineRepresentation::kFirstFPRepresentation;
266}
267
268inline bool CanBeTaggedPointer(MachineRepresentation rep) {
269  return rep == MachineRepresentation::kTagged ||
270         rep == MachineRepresentation::kTaggedPointer;
271}
272
273inline bool CanBeTaggedSigned(MachineRepresentation rep) {
274  return rep == MachineRepresentation::kTagged ||
275         rep == MachineRepresentation::kTaggedSigned;
276}
277
278inline 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.
283V8_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
309typedef Signature<MachineType> MachineSignature;
310
311}  // namespace internal
312}  // namespace v8
313
314#endif  // V8_MACHINE_TYPE_H_
315