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