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
12namespace v8 {
13namespace internal {
14
15class OStream;
16
17namespace compiler {
18
19// Machine-level types and representations.
20// TODO(titzer): Use the real type system instead of MachineType.
21enum 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
57OStream& operator<<(OStream& os, const MachineType& type);
58
59typedef uint16_t MachineTypeUnion;
60
61// Globally useful machine types and constants.
62const MachineTypeUnion kRepMask = kRepBit | kRepWord8 | kRepWord16 |
63                                  kRepWord32 | kRepWord64 | kRepFloat32 |
64                                  kRepFloat64 | kRepTagged;
65const MachineTypeUnion kTypeMask = kTypeBool | kTypeInt32 | kTypeUint32 |
66                                   kTypeInt64 | kTypeUint64 | kTypeNumber |
67                                   kTypeAny;
68
69// Gets only the type of the given type.
70inline 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.
76inline 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.
83inline 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.
105template <typename T>
106class Signature : public ZoneObject {
107 public:
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
113  size_t return_count() const { return return_count_; }
114  size_t parameter_count() const { return parameter_count_; }
115
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:
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
141    void AddReturn(T val) {
142      DCHECK(rcursor_ < return_count_);
143      buffer_[rcursor_++] = val;
144    }
145    void AddParam(T val) {
146      DCHECK(pcursor_ < parameter_count_);
147      buffer_[return_count_ + pcursor_++] = val;
148    }
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
168typedef Signature<MachineType> MachineSignature;
169}  // namespace compiler
170}  // namespace internal
171}  // namespace v8
172
173#endif  // V8_COMPILER_MACHINE_TYPE_H_
174