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