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