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. 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. 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. 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: 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 168 typedef Signature<MachineType> MachineSignature; 169 } // namespace compiler 170 } // namespace internal 171 } // namespace v8 172 173 #endif // V8_COMPILER_MACHINE_TYPE_H_ 174