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_MACHINE_TYPE_H_ 6 #define V8_MACHINE_TYPE_H_ 7 8 #include <iosfwd> 9 10 #include "src/base/bits.h" 11 #include "src/globals.h" 12 13 namespace v8 { 14 namespace internal { 15 16 enum class MachineRepresentation : uint8_t { 17 kNone, 18 kBit, 19 kWord8, 20 kWord16, 21 kWord32, 22 kWord64, 23 kTaggedSigned, 24 kTaggedPointer, 25 kTagged, 26 // FP representations must be last, and in order of increasing size. 27 kFloat32, 28 kFloat64, 29 kSimd128, 30 kFirstFPRepresentation = kFloat32, 31 kLastRepresentation = kSimd128 32 }; 33 34 bool IsSubtype(MachineRepresentation rep1, MachineRepresentation rep2); 35 36 static_assert(static_cast<int>(MachineRepresentation::kLastRepresentation) < 37 kIntSize * kBitsPerByte, 38 "Bit masks of MachineRepresentation should fit in an int"); 39 40 V8_EXPORT_PRIVATE const char* MachineReprToString(MachineRepresentation); 41 42 enum class MachineSemantic : uint8_t { 43 kNone, 44 kBool, 45 kInt32, 46 kUint32, 47 kInt64, 48 kUint64, 49 kNumber, 50 kAny 51 }; 52 53 V8_EXPORT_PRIVATE inline int ElementSizeLog2Of(MachineRepresentation rep); 54 55 V8_EXPORT_PRIVATE inline int ElementSizeInBytes(MachineRepresentation rep); 56 57 class MachineType { 58 public: 59 constexpr MachineType() 60 : representation_(MachineRepresentation::kNone), 61 semantic_(MachineSemantic::kNone) {} 62 constexpr MachineType(MachineRepresentation representation, 63 MachineSemantic semantic) 64 : representation_(representation), semantic_(semantic) {} 65 66 constexpr bool operator==(MachineType other) const { 67 return representation() == other.representation() && 68 semantic() == other.semantic(); 69 } 70 71 constexpr bool operator!=(MachineType other) const { 72 return !(*this == other); 73 } 74 75 constexpr MachineRepresentation representation() const { 76 return representation_; 77 } 78 constexpr MachineSemantic semantic() const { return semantic_; } 79 80 constexpr bool IsNone() const { 81 return representation() == MachineRepresentation::kNone; 82 } 83 84 constexpr bool IsSigned() const { 85 return semantic() == MachineSemantic::kInt32 || 86 semantic() == MachineSemantic::kInt64; 87 } 88 constexpr bool IsUnsigned() const { 89 return semantic() == MachineSemantic::kUint32 || 90 semantic() == MachineSemantic::kUint64; 91 } 92 constexpr bool IsTagged() const { 93 return representation() == MachineRepresentation::kTaggedPointer || 94 representation() == MachineRepresentation::kTaggedSigned || 95 representation() == MachineRepresentation::kTagged; 96 } 97 constexpr static MachineRepresentation PointerRepresentation() { 98 return (kPointerSize == 4) ? MachineRepresentation::kWord32 99 : MachineRepresentation::kWord64; 100 } 101 constexpr static MachineType UintPtr() { 102 return (kPointerSize == 4) ? Uint32() : Uint64(); 103 } 104 constexpr static MachineType IntPtr() { 105 return (kPointerSize == 4) ? Int32() : Int64(); 106 } 107 constexpr static MachineType Int8() { 108 return MachineType(MachineRepresentation::kWord8, MachineSemantic::kInt32); 109 } 110 constexpr static MachineType Uint8() { 111 return MachineType(MachineRepresentation::kWord8, MachineSemantic::kUint32); 112 } 113 constexpr static MachineType Int16() { 114 return MachineType(MachineRepresentation::kWord16, MachineSemantic::kInt32); 115 } 116 constexpr static MachineType Uint16() { 117 return MachineType(MachineRepresentation::kWord16, 118 MachineSemantic::kUint32); 119 } 120 constexpr static MachineType Int32() { 121 return MachineType(MachineRepresentation::kWord32, MachineSemantic::kInt32); 122 } 123 constexpr static MachineType Uint32() { 124 return MachineType(MachineRepresentation::kWord32, 125 MachineSemantic::kUint32); 126 } 127 constexpr static MachineType Int64() { 128 return MachineType(MachineRepresentation::kWord64, MachineSemantic::kInt64); 129 } 130 constexpr static MachineType Uint64() { 131 return MachineType(MachineRepresentation::kWord64, 132 MachineSemantic::kUint64); 133 } 134 constexpr static MachineType Float32() { 135 return MachineType(MachineRepresentation::kFloat32, 136 MachineSemantic::kNumber); 137 } 138 constexpr static MachineType Float64() { 139 return MachineType(MachineRepresentation::kFloat64, 140 MachineSemantic::kNumber); 141 } 142 constexpr static MachineType Simd128() { 143 return MachineType(MachineRepresentation::kSimd128, MachineSemantic::kNone); 144 } 145 constexpr static MachineType Pointer() { 146 return MachineType(PointerRepresentation(), MachineSemantic::kNone); 147 } 148 constexpr static MachineType TaggedPointer() { 149 return MachineType(MachineRepresentation::kTaggedPointer, 150 MachineSemantic::kAny); 151 } 152 constexpr static MachineType TaggedSigned() { 153 return MachineType(MachineRepresentation::kTaggedSigned, 154 MachineSemantic::kInt32); 155 } 156 constexpr static MachineType AnyTagged() { 157 return MachineType(MachineRepresentation::kTagged, MachineSemantic::kAny); 158 } 159 constexpr static MachineType Bool() { 160 return MachineType(MachineRepresentation::kBit, MachineSemantic::kBool); 161 } 162 constexpr static MachineType TaggedBool() { 163 return MachineType(MachineRepresentation::kTagged, MachineSemantic::kBool); 164 } 165 constexpr static MachineType None() { 166 return MachineType(MachineRepresentation::kNone, MachineSemantic::kNone); 167 } 168 169 // These naked representations should eventually go away. 170 constexpr static MachineType RepWord8() { 171 return MachineType(MachineRepresentation::kWord8, MachineSemantic::kNone); 172 } 173 constexpr static MachineType RepWord16() { 174 return MachineType(MachineRepresentation::kWord16, MachineSemantic::kNone); 175 } 176 constexpr static MachineType RepWord32() { 177 return MachineType(MachineRepresentation::kWord32, MachineSemantic::kNone); 178 } 179 constexpr static MachineType RepWord64() { 180 return MachineType(MachineRepresentation::kWord64, MachineSemantic::kNone); 181 } 182 constexpr static MachineType RepFloat32() { 183 return MachineType(MachineRepresentation::kFloat32, MachineSemantic::kNone); 184 } 185 constexpr static MachineType RepFloat64() { 186 return MachineType(MachineRepresentation::kFloat64, MachineSemantic::kNone); 187 } 188 constexpr static MachineType RepSimd128() { 189 return MachineType(MachineRepresentation::kSimd128, MachineSemantic::kNone); 190 } 191 constexpr static MachineType RepTagged() { 192 return MachineType(MachineRepresentation::kTagged, MachineSemantic::kNone); 193 } 194 constexpr static MachineType RepBit() { 195 return MachineType(MachineRepresentation::kBit, MachineSemantic::kNone); 196 } 197 198 static MachineType TypeForRepresentation(const MachineRepresentation& rep, 199 bool isSigned = true) { 200 switch (rep) { 201 case MachineRepresentation::kNone: 202 return MachineType::None(); 203 case MachineRepresentation::kBit: 204 return MachineType::Bool(); 205 case MachineRepresentation::kWord8: 206 return isSigned ? MachineType::Int8() : MachineType::Uint8(); 207 case MachineRepresentation::kWord16: 208 return isSigned ? MachineType::Int16() : MachineType::Uint16(); 209 case MachineRepresentation::kWord32: 210 return isSigned ? MachineType::Int32() : MachineType::Uint32(); 211 case MachineRepresentation::kWord64: 212 return isSigned ? MachineType::Int64() : MachineType::Uint64(); 213 case MachineRepresentation::kFloat32: 214 return MachineType::Float32(); 215 case MachineRepresentation::kFloat64: 216 return MachineType::Float64(); 217 case MachineRepresentation::kSimd128: 218 return MachineType::Simd128(); 219 case MachineRepresentation::kTagged: 220 return MachineType::AnyTagged(); 221 case MachineRepresentation::kTaggedSigned: 222 return MachineType::TaggedSigned(); 223 case MachineRepresentation::kTaggedPointer: 224 return MachineType::TaggedPointer(); 225 default: 226 UNREACHABLE(); 227 } 228 } 229 230 bool LessThanOrEqualPointerSize() { 231 return ElementSizeLog2Of(this->representation()) <= kPointerSizeLog2; 232 } 233 234 private: 235 MachineRepresentation representation_; 236 MachineSemantic semantic_; 237 }; 238 239 V8_INLINE size_t hash_value(MachineRepresentation rep) { 240 return static_cast<size_t>(rep); 241 } 242 243 V8_INLINE size_t hash_value(MachineType type) { 244 return static_cast<size_t>(type.representation()) + 245 static_cast<size_t>(type.semantic()) * 16; 246 } 247 248 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, 249 MachineRepresentation rep); 250 std::ostream& operator<<(std::ostream& os, MachineSemantic type); 251 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, MachineType type); 252 253 inline bool IsFloatingPoint(MachineRepresentation rep) { 254 return rep >= MachineRepresentation::kFirstFPRepresentation; 255 } 256 257 inline bool CanBeTaggedPointer(MachineRepresentation rep) { 258 return rep == MachineRepresentation::kTagged || 259 rep == MachineRepresentation::kTaggedPointer; 260 } 261 262 inline bool CanBeTaggedSigned(MachineRepresentation rep) { 263 return rep == MachineRepresentation::kTagged || 264 rep == MachineRepresentation::kTaggedSigned; 265 } 266 267 inline bool IsAnyTagged(MachineRepresentation rep) { 268 return CanBeTaggedPointer(rep) || rep == MachineRepresentation::kTaggedSigned; 269 } 270 271 // Gets the log2 of the element size in bytes of the machine type. 272 V8_EXPORT_PRIVATE inline int ElementSizeLog2Of(MachineRepresentation rep) { 273 switch (rep) { 274 case MachineRepresentation::kBit: 275 case MachineRepresentation::kWord8: 276 return 0; 277 case MachineRepresentation::kWord16: 278 return 1; 279 case MachineRepresentation::kWord32: 280 case MachineRepresentation::kFloat32: 281 return 2; 282 case MachineRepresentation::kWord64: 283 case MachineRepresentation::kFloat64: 284 return 3; 285 case MachineRepresentation::kSimd128: 286 return 4; 287 case MachineRepresentation::kTaggedSigned: 288 case MachineRepresentation::kTaggedPointer: 289 case MachineRepresentation::kTagged: 290 return kPointerSizeLog2; 291 default: 292 break; 293 } 294 UNREACHABLE(); 295 } 296 297 V8_EXPORT_PRIVATE inline int ElementSizeInBytes(MachineRepresentation rep) { 298 return 1 << ElementSizeLog2Of(rep); 299 } 300 301 } // namespace internal 302 } // namespace v8 303 304 #endif // V8_MACHINE_TYPE_H_ 305