machine-type.h 4.71 KB
Newer Older
1 2 3 4 5 6 7
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_COMPILER_MACHINE_TYPE_H_
#define V8_COMPILER_MACHINE_TYPE_H_

8 9
#include <iosfwd>

10
#include "src/base/bits.h"
11
#include "src/globals.h"
12
#include "src/zone.h"
13

14 15 16 17
namespace v8 {
namespace internal {
namespace compiler {

18 19
// Machine-level types and representations.
// TODO(titzer): Use the real type system instead of MachineType.
20
enum MachineType {
21 22 23 24 25 26
  // Representations.
  kRepBit = 1 << 0,
  kRepWord8 = 1 << 1,
  kRepWord16 = 1 << 2,
  kRepWord32 = 1 << 3,
  kRepWord64 = 1 << 4,
27 28 29
  kRepFloat32 = 1 << 5,
  kRepFloat64 = 1 << 6,
  kRepTagged = 1 << 7,
30 31

  // Types.
32 33 34 35 36 37
  kTypeBool = 1 << 8,
  kTypeInt32 = 1 << 9,
  kTypeUint32 = 1 << 10,
  kTypeInt64 = 1 << 11,
  kTypeUint64 = 1 << 12,
  kTypeNumber = 1 << 13,
38 39 40 41
  kTypeAny = 1 << 14,

  // Machine types.
  kMachNone = 0,
42
  kMachBool = kRepBit | kTypeBool,
43 44 45 46 47 48 49 50 51 52 53 54
  kMachFloat32 = kRepFloat32 | kTypeNumber,
  kMachFloat64 = kRepFloat64 | kTypeNumber,
  kMachInt8 = kRepWord8 | kTypeInt32,
  kMachUint8 = kRepWord8 | kTypeUint32,
  kMachInt16 = kRepWord16 | kTypeInt32,
  kMachUint16 = kRepWord16 | kTypeUint32,
  kMachInt32 = kRepWord32 | kTypeInt32,
  kMachUint32 = kRepWord32 | kTypeUint32,
  kMachInt64 = kRepWord64 | kTypeInt64,
  kMachUint64 = kRepWord64 | kTypeUint64,
  kMachPtr = (kPointerSize == 4) ? kRepWord32 : kRepWord64,
  kMachAnyTagged = kRepTagged | kTypeAny
55
};
56

57
std::ostream& operator<<(std::ostream& os, const MachineType& type);
58 59 60 61 62

typedef uint16_t MachineTypeUnion;

// Globally useful machine types and constants.
const MachineTypeUnion kRepMask = kRepBit | kRepWord8 | kRepWord16 |
63 64
                                  kRepWord32 | kRepWord64 | kRepFloat32 |
                                  kRepFloat64 | kRepTagged;
65 66 67 68
const MachineTypeUnion kTypeMask = kTypeBool | kTypeInt32 | kTypeUint32 |
                                   kTypeInt64 | kTypeUint64 | kTypeNumber |
                                   kTypeAny;

69 70 71 72 73 74
// Gets only the type of the given type.
inline MachineType TypeOf(MachineType machine_type) {
  int result = machine_type & kTypeMask;
  return static_cast<MachineType>(result);
}

75 76 77
// Gets only the representation of the given type.
inline MachineType RepresentationOf(MachineType machine_type) {
  int result = machine_type & kRepMask;
78
  CHECK(base::bits::IsPowerOfTwo32(result));
79 80 81 82 83 84 85 86 87 88 89 90
  return static_cast<MachineType>(result);
}

// Gets the element size in bytes of the machine type.
inline int ElementSizeOf(MachineType machine_type) {
  switch (RepresentationOf(machine_type)) {
    case kRepBit:
    case kRepWord8:
      return 1;
    case kRepWord16:
      return 2;
    case kRepWord32:
91
    case kRepFloat32:
92 93 94 95 96 97 98 99 100 101 102
      return 4;
    case kRepWord64:
    case kRepFloat64:
      return 8;
    case kRepTagged:
      return kPointerSize;
    default:
      UNREACHABLE();
      return kPointerSize;
  }
}
103

104 105 106
// Describes the inputs and outputs of a function or call.
template <typename T>
class Signature : public ZoneObject {
107
 public:
108 109 110 111
  Signature(size_t return_count, size_t parameter_count, T* reps)
      : return_count_(return_count),
        parameter_count_(parameter_count),
        reps_(reps) {}
112

113 114
  size_t return_count() const { return return_count_; }
  size_t parameter_count() const { return parameter_count_; }
115

116 117
  T GetParam(size_t index) const {
    DCHECK(index < parameter_count_);
118 119 120
    return reps_[return_count_ + index];
  }

121 122
  T GetReturn(size_t index = 0) const {
    DCHECK(index < return_count_);
123 124 125
    return reps_[index];
  }

126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
  // For incrementally building signatures.
  class Builder {
   public:
    Builder(Zone* zone, size_t return_count, size_t parameter_count)
        : return_count_(return_count),
          parameter_count_(parameter_count),
          zone_(zone),
          rcursor_(0),
          pcursor_(0),
          buffer_(zone->NewArray<T>(
              static_cast<int>(return_count + parameter_count))) {}

    const size_t return_count_;
    const size_t parameter_count_;

    void AddReturn(T val) {
      DCHECK(rcursor_ < return_count_);
      buffer_[rcursor_++] = val;
    }
    void AddParam(T val) {
      DCHECK(pcursor_ < parameter_count_);
      buffer_[return_count_ + pcursor_++] = val;
    }
    Signature<T>* Build() {
      DCHECK(rcursor_ == return_count_);
      DCHECK(pcursor_ == parameter_count_);
      return new (zone_) Signature<T>(return_count_, parameter_count_, buffer_);
    }

   private:
    Zone* zone_;
    size_t rcursor_;
    size_t pcursor_;
    T* buffer_;
  };

162
 protected:
163 164 165
  size_t return_count_;
  size_t parameter_count_;
  T* reps_;
166
};
167 168

typedef Signature<MachineType> MachineSignature;
169 170 171
}  // namespace compiler
}  // namespace internal
}  // namespace v8
172 173

#endif  // V8_COMPILER_MACHINE_TYPE_H_