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
15namespace v8 {
16namespace internal {
17
18enum class MachineRepresentation : uint8_t {
19  kNone,
20  kBit,
21  kWord8,
22  kWord16,
23  kWord32,
24  kWord64,
25  kFloat32,
26  kFloat64,
27  kTagged
28};
29
30enum class MachineSemantic : uint8_t {
31  kNone,
32  kBool,
33  kInt32,
34  kUint32,
35  kInt64,
36  kUint64,
37  kNumber,
38  kAny
39};
40
41class MachineType {
42 public:
43  MachineType()
44      : representation_(MachineRepresentation::kNone),
45        semantic_(MachineSemantic::kNone) {}
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
57  MachineRepresentation representation() const { return representation_; }
58  MachineSemantic semantic() const { return semantic_; }
59
60  bool IsSigned() {
61    return semantic() == MachineSemantic::kInt32 ||
62           semantic() == MachineSemantic::kInt64;
63  }
64  bool IsUnsigned() {
65    return semantic() == MachineSemantic::kUint32 ||
66           semantic() == MachineSemantic::kUint64;
67  }
68
69  static MachineRepresentation PointerRepresentation() {
70    return (kPointerSize == 4) ? MachineRepresentation::kWord32
71                               : MachineRepresentation::kWord64;
72  }
73  static MachineType Pointer() {
74    return MachineType(PointerRepresentation(), MachineSemantic::kNone);
75  }
76  static MachineType IntPtr() {
77    return (kPointerSize == 4) ? Int32() : Int64();
78  }
79  static MachineType Float32() {
80    return MachineType(MachineRepresentation::kFloat32,
81                       MachineSemantic::kNumber);
82  }
83  static MachineType Float64() {
84    return MachineType(MachineRepresentation::kFloat64,
85                       MachineSemantic::kNumber);
86  }
87  static MachineType Int8() {
88    return MachineType(MachineRepresentation::kWord8, MachineSemantic::kInt32);
89  }
90  static MachineType Uint8() {
91    return MachineType(MachineRepresentation::kWord8, MachineSemantic::kUint32);
92  }
93  static MachineType Int16() {
94    return MachineType(MachineRepresentation::kWord16, MachineSemantic::kInt32);
95  }
96  static MachineType Uint16() {
97    return MachineType(MachineRepresentation::kWord16,
98                       MachineSemantic::kUint32);
99  }
100  static MachineType Int32() {
101    return MachineType(MachineRepresentation::kWord32, MachineSemantic::kInt32);
102  }
103  static MachineType Uint32() {
104    return MachineType(MachineRepresentation::kWord32,
105                       MachineSemantic::kUint32);
106  }
107  static MachineType Int64() {
108    return MachineType(MachineRepresentation::kWord64, MachineSemantic::kInt64);
109  }
110  static MachineType Uint64() {
111    return MachineType(MachineRepresentation::kWord64,
112                       MachineSemantic::kUint64);
113  }
114  static MachineType AnyTagged() {
115    return MachineType(MachineRepresentation::kTagged, MachineSemantic::kAny);
116  }
117  static MachineType Bool() {
118    return MachineType(MachineRepresentation::kBit, MachineSemantic::kBool);
119  }
120  static MachineType TaggedBool() {
121    return MachineType(MachineRepresentation::kTagged, MachineSemantic::kBool);
122  }
123  static MachineType None() {
124    return MachineType(MachineRepresentation::kNone, MachineSemantic::kNone);
125  }
126
127  // These naked representations should eventually go away.
128  static MachineType RepWord8() {
129    return MachineType(MachineRepresentation::kWord8, MachineSemantic::kNone);
130  }
131  static MachineType RepWord16() {
132    return MachineType(MachineRepresentation::kWord16, MachineSemantic::kNone);
133  }
134  static MachineType RepWord32() {
135    return MachineType(MachineRepresentation::kWord32, MachineSemantic::kNone);
136  }
137  static MachineType RepWord64() {
138    return MachineType(MachineRepresentation::kWord64, MachineSemantic::kNone);
139  }
140  static MachineType RepFloat32() {
141    return MachineType(MachineRepresentation::kFloat32, MachineSemantic::kNone);
142  }
143  static MachineType RepFloat64() {
144    return MachineType(MachineRepresentation::kFloat64, MachineSemantic::kNone);
145  }
146  static MachineType RepTagged() {
147    return MachineType(MachineRepresentation::kTagged, MachineSemantic::kNone);
148  }
149  static MachineType RepBit() {
150    return MachineType(MachineRepresentation::kBit, MachineSemantic::kNone);
151  }
152
153 private:
154  MachineRepresentation representation_;
155  MachineSemantic semantic_;
156};
157
158V8_INLINE size_t hash_value(MachineRepresentation rep) {
159  return static_cast<size_t>(rep);
160}
161
162V8_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
167std::ostream& operator<<(std::ostream& os, MachineRepresentation rep);
168std::ostream& operator<<(std::ostream& os, MachineSemantic type);
169std::ostream& operator<<(std::ostream& os, MachineType type);
170
171inline 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.
177inline 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
199typedef Signature<MachineType> MachineSignature;
200
201}  // namespace internal
202}  // namespace v8
203
204#endif  // V8_MACHINE_TYPE_H_
205