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_COMPILER_MACHINE_TYPE_H_
6 #define V8_COMPILER_MACHINE_TYPE_H_
7
8 #include "src/base/bits.h"
9 #include "src/globals.h"
10 #include "src/zone.h"
11
12 namespace v8 {
13 namespace internal {
14
15 class OStream;
16
17 namespace compiler {
18
19 // Machine-level types and representations.
20 // TODO(titzer): Use the real type system instead of MachineType.
21 enum MachineType {
22 // Representations.
23 kRepBit = 1 << 0,
24 kRepWord8 = 1 << 1,
25 kRepWord16 = 1 << 2,
26 kRepWord32 = 1 << 3,
27 kRepWord64 = 1 << 4,
28 kRepFloat32 = 1 << 5,
29 kRepFloat64 = 1 << 6,
30 kRepTagged = 1 << 7,
31
32 // Types.
33 kTypeBool = 1 << 8,
34 kTypeInt32 = 1 << 9,
35 kTypeUint32 = 1 << 10,
36 kTypeInt64 = 1 << 11,
37 kTypeUint64 = 1 << 12,
38 kTypeNumber = 1 << 13,
39 kTypeAny = 1 << 14,
40
41 // Machine types.
42 kMachNone = 0,
43 kMachFloat32 = kRepFloat32 | kTypeNumber,
44 kMachFloat64 = kRepFloat64 | kTypeNumber,
45 kMachInt8 = kRepWord8 | kTypeInt32,
46 kMachUint8 = kRepWord8 | kTypeUint32,
47 kMachInt16 = kRepWord16 | kTypeInt32,
48 kMachUint16 = kRepWord16 | kTypeUint32,
49 kMachInt32 = kRepWord32 | kTypeInt32,
50 kMachUint32 = kRepWord32 | kTypeUint32,
51 kMachInt64 = kRepWord64 | kTypeInt64,
52 kMachUint64 = kRepWord64 | kTypeUint64,
53 kMachPtr = (kPointerSize == 4) ? kRepWord32 : kRepWord64,
54 kMachAnyTagged = kRepTagged | kTypeAny
55 };
56
57 OStream& operator<<(OStream& os, const MachineType& type);
58
59 typedef uint16_t MachineTypeUnion;
60
61 // Globally useful machine types and constants.
62 const MachineTypeUnion kRepMask = kRepBit | kRepWord8 | kRepWord16 |
63 kRepWord32 | kRepWord64 | kRepFloat32 |
64 kRepFloat64 | kRepTagged;
65 const MachineTypeUnion kTypeMask = kTypeBool | kTypeInt32 | kTypeUint32 |
66 kTypeInt64 | kTypeUint64 | kTypeNumber |
67 kTypeAny;
68
69 // Gets only the type of the given type.
TypeOf(MachineType machine_type)70 inline MachineType TypeOf(MachineType machine_type) {
71 int result = machine_type & kTypeMask;
72 return static_cast<MachineType>(result);
73 }
74
75 // Gets only the representation of the given type.
RepresentationOf(MachineType machine_type)76 inline MachineType RepresentationOf(MachineType machine_type) {
77 int result = machine_type & kRepMask;
78 CHECK(base::bits::IsPowerOfTwo32(result));
79 return static_cast<MachineType>(result);
80 }
81
82 // Gets the element size in bytes of the machine type.
ElementSizeOf(MachineType machine_type)83 inline int ElementSizeOf(MachineType machine_type) {
84 switch (RepresentationOf(machine_type)) {
85 case kRepBit:
86 case kRepWord8:
87 return 1;
88 case kRepWord16:
89 return 2;
90 case kRepWord32:
91 case kRepFloat32:
92 return 4;
93 case kRepWord64:
94 case kRepFloat64:
95 return 8;
96 case kRepTagged:
97 return kPointerSize;
98 default:
99 UNREACHABLE();
100 return kPointerSize;
101 }
102 }
103
104 // Describes the inputs and outputs of a function or call.
105 template <typename T>
106 class Signature : public ZoneObject {
107 public:
Signature(size_t return_count,size_t parameter_count,T * reps)108 Signature(size_t return_count, size_t parameter_count, T* reps)
109 : return_count_(return_count),
110 parameter_count_(parameter_count),
111 reps_(reps) {}
112
return_count()113 size_t return_count() const { return return_count_; }
parameter_count()114 size_t parameter_count() const { return parameter_count_; }
115
GetParam(size_t index)116 T GetParam(size_t index) const {
117 DCHECK(index < parameter_count_);
118 return reps_[return_count_ + index];
119 }
120
121 T GetReturn(size_t index = 0) const {
122 DCHECK(index < return_count_);
123 return reps_[index];
124 }
125
126 // For incrementally building signatures.
127 class Builder {
128 public:
Builder(Zone * zone,size_t return_count,size_t parameter_count)129 Builder(Zone* zone, size_t return_count, size_t parameter_count)
130 : return_count_(return_count),
131 parameter_count_(parameter_count),
132 zone_(zone),
133 rcursor_(0),
134 pcursor_(0),
135 buffer_(zone->NewArray<T>(
136 static_cast<int>(return_count + parameter_count))) {}
137
138 const size_t return_count_;
139 const size_t parameter_count_;
140
AddReturn(T val)141 void AddReturn(T val) {
142 DCHECK(rcursor_ < return_count_);
143 buffer_[rcursor_++] = val;
144 }
AddParam(T val)145 void AddParam(T val) {
146 DCHECK(pcursor_ < parameter_count_);
147 buffer_[return_count_ + pcursor_++] = val;
148 }
Build()149 Signature<T>* Build() {
150 DCHECK(rcursor_ == return_count_);
151 DCHECK(pcursor_ == parameter_count_);
152 return new (zone_) Signature<T>(return_count_, parameter_count_, buffer_);
153 }
154
155 private:
156 Zone* zone_;
157 size_t rcursor_;
158 size_t pcursor_;
159 T* buffer_;
160 };
161
162 protected:
163 size_t return_count_;
164 size_t parameter_count_;
165 T* reps_;
166 };
167
168 typedef Signature<MachineType> MachineSignature;
169 } // namespace compiler
170 } // namespace internal
171 } // namespace v8
172
173 #endif // V8_COMPILER_MACHINE_TYPE_H_
174