1 // Copyright 2018 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_WASM_VALUE_TYPE_H_ 6 #define V8_WASM_VALUE_TYPE_H_ 7 8 #include "src/machine-type.h" 9 #include "src/wasm/wasm-constants.h" 10 11 namespace v8 { 12 namespace internal { 13 namespace wasm { 14 15 enum ValueType : uint8_t { 16 kWasmStmt, 17 kWasmI32, 18 kWasmI64, 19 kWasmF32, 20 kWasmF64, 21 kWasmS128, 22 kWasmAnyRef, 23 kWasmAnyFunc, 24 kWasmVar, 25 }; 26 27 inline size_t hash_value(ValueType type) { return static_cast<size_t>(type); } 28 29 // TODO(clemensh): Compute memtype and size from ValueType once we have c++14 30 // constexpr support. 31 #define FOREACH_LOAD_TYPE(V) \ 32 V(I32, , Int32, 2) \ 33 V(I32, 8S, Int8, 0) \ 34 V(I32, 8U, Uint8, 0) \ 35 V(I32, 16S, Int16, 1) \ 36 V(I32, 16U, Uint16, 1) \ 37 V(I64, , Int64, 3) \ 38 V(I64, 8S, Int8, 0) \ 39 V(I64, 8U, Uint8, 0) \ 40 V(I64, 16S, Int16, 1) \ 41 V(I64, 16U, Uint16, 1) \ 42 V(I64, 32S, Int32, 2) \ 43 V(I64, 32U, Uint32, 2) \ 44 V(F32, , Float32, 2) \ 45 V(F64, , Float64, 3) \ 46 V(S128, , Simd128, 4) 47 48 class LoadType { 49 public: 50 enum LoadTypeValue : uint8_t { 51 #define DEF_ENUM(type, suffix, ...) k##type##Load##suffix, 52 FOREACH_LOAD_TYPE(DEF_ENUM) 53 #undef DEF_ENUM 54 }; 55 56 // Allow implicit convertion of the enum value to this wrapper. 57 constexpr LoadType(LoadTypeValue val) // NOLINT(runtime/explicit) 58 : val_(val) {} 59 60 constexpr LoadTypeValue value() const { return val_; } 61 constexpr unsigned size_log_2() const { return kLoadSizeLog2[val_]; } 62 constexpr unsigned size() const { return 1 << size_log_2(); } 63 constexpr ValueType value_type() const { return kValueType[val_]; } 64 constexpr MachineType mem_type() const { return kMemType[val_]; } 65 66 static LoadType ForValueType(ValueType type) { 67 switch (type) { 68 case kWasmI32: 69 return kI32Load; 70 case kWasmI64: 71 return kI64Load; 72 case kWasmF32: 73 return kF32Load; 74 case kWasmF64: 75 return kF64Load; 76 default: 77 UNREACHABLE(); 78 } 79 } 80 81 private: 82 const LoadTypeValue val_; 83 84 static constexpr uint8_t kLoadSizeLog2[] = { 85 #define LOAD_SIZE(_, __, ___, size) size, 86 FOREACH_LOAD_TYPE(LOAD_SIZE) 87 #undef LOAD_SIZE 88 }; 89 90 static constexpr ValueType kValueType[] = { 91 #define VALUE_TYPE(type, ...) kWasm##type, 92 FOREACH_LOAD_TYPE(VALUE_TYPE) 93 #undef VALUE_TYPE 94 }; 95 96 static constexpr MachineType kMemType[] = { 97 #define MEMTYPE(_, __, memtype, ___) MachineType::memtype(), 98 FOREACH_LOAD_TYPE(MEMTYPE) 99 #undef MEMTYPE 100 }; 101 }; 102 103 #define FOREACH_STORE_TYPE(V) \ 104 V(I32, , Word32, 2) \ 105 V(I32, 8, Word8, 0) \ 106 V(I32, 16, Word16, 1) \ 107 V(I64, , Word64, 3) \ 108 V(I64, 8, Word8, 0) \ 109 V(I64, 16, Word16, 1) \ 110 V(I64, 32, Word32, 2) \ 111 V(F32, , Float32, 2) \ 112 V(F64, , Float64, 3) \ 113 V(S128, , Simd128, 4) 114 115 class StoreType { 116 public: 117 enum StoreTypeValue : uint8_t { 118 #define DEF_ENUM(type, suffix, ...) k##type##Store##suffix, 119 FOREACH_STORE_TYPE(DEF_ENUM) 120 #undef DEF_ENUM 121 }; 122 123 // Allow implicit convertion of the enum value to this wrapper. 124 constexpr StoreType(StoreTypeValue val) // NOLINT(runtime/explicit) 125 : val_(val) {} 126 127 constexpr StoreTypeValue value() const { return val_; } 128 constexpr unsigned size_log_2() const { return kStoreSizeLog2[val_]; } 129 constexpr unsigned size() const { return 1 << size_log_2(); } 130 constexpr ValueType value_type() const { return kValueType[val_]; } 131 constexpr MachineRepresentation mem_rep() const { return kMemRep[val_]; } 132 133 static StoreType ForValueType(ValueType type) { 134 switch (type) { 135 case kWasmI32: 136 return kI32Store; 137 case kWasmI64: 138 return kI64Store; 139 case kWasmF32: 140 return kF32Store; 141 case kWasmF64: 142 return kF64Store; 143 default: 144 UNREACHABLE(); 145 } 146 } 147 148 private: 149 const StoreTypeValue val_; 150 151 static constexpr uint8_t kStoreSizeLog2[] = { 152 #define STORE_SIZE(_, __, ___, size) size, 153 FOREACH_STORE_TYPE(STORE_SIZE) 154 #undef STORE_SIZE 155 }; 156 157 static constexpr ValueType kValueType[] = { 158 #define VALUE_TYPE(type, ...) kWasm##type, 159 FOREACH_STORE_TYPE(VALUE_TYPE) 160 #undef VALUE_TYPE 161 }; 162 163 static constexpr MachineRepresentation kMemRep[] = { 164 #define MEMREP(_, __, memrep, ___) MachineRepresentation::k##memrep, 165 FOREACH_STORE_TYPE(MEMREP) 166 #undef MEMREP 167 }; 168 }; 169 170 // A collection of ValueType-related static methods. 171 class V8_EXPORT_PRIVATE ValueTypes { 172 public: 173 static byte MemSize(MachineType type) { 174 return 1 << i::ElementSizeLog2Of(type.representation()); 175 } 176 177 static int ElementSizeInBytes(ValueType type) { 178 switch (type) { 179 case kWasmI32: 180 case kWasmF32: 181 return 4; 182 case kWasmI64: 183 case kWasmF64: 184 return 8; 185 case kWasmS128: 186 return 16; 187 default: 188 UNREACHABLE(); 189 } 190 } 191 192 static int ElementSizeLog2Of(ValueType type) { 193 switch (type) { 194 case kWasmI32: 195 case kWasmF32: 196 return 2; 197 case kWasmI64: 198 case kWasmF64: 199 return 3; 200 case kWasmS128: 201 return 4; 202 default: 203 UNREACHABLE(); 204 } 205 } 206 207 static byte MemSize(ValueType type) { return 1 << ElementSizeLog2Of(type); } 208 209 static ValueTypeCode ValueTypeCodeFor(ValueType type) { 210 switch (type) { 211 case kWasmI32: 212 return kLocalI32; 213 case kWasmI64: 214 return kLocalI64; 215 case kWasmF32: 216 return kLocalF32; 217 case kWasmF64: 218 return kLocalF64; 219 case kWasmS128: 220 return kLocalS128; 221 case kWasmAnyRef: 222 return kLocalAnyRef; 223 case kWasmStmt: 224 return kLocalVoid; 225 default: 226 UNREACHABLE(); 227 } 228 } 229 230 static MachineType MachineTypeFor(ValueType type) { 231 switch (type) { 232 case kWasmI32: 233 return MachineType::Int32(); 234 case kWasmI64: 235 return MachineType::Int64(); 236 case kWasmF32: 237 return MachineType::Float32(); 238 case kWasmF64: 239 return MachineType::Float64(); 240 case kWasmAnyFunc: 241 case kWasmAnyRef: 242 return MachineType::TaggedPointer(); 243 case kWasmS128: 244 return MachineType::Simd128(); 245 case kWasmStmt: 246 return MachineType::None(); 247 default: 248 UNREACHABLE(); 249 } 250 } 251 252 static MachineRepresentation MachineRepresentationFor(ValueType type) { 253 switch (type) { 254 case kWasmI32: 255 return MachineRepresentation::kWord32; 256 case kWasmI64: 257 return MachineRepresentation::kWord64; 258 case kWasmF32: 259 return MachineRepresentation::kFloat32; 260 case kWasmF64: 261 return MachineRepresentation::kFloat64; 262 case kWasmAnyRef: 263 return MachineRepresentation::kTaggedPointer; 264 case kWasmS128: 265 return MachineRepresentation::kSimd128; 266 case kWasmStmt: 267 return MachineRepresentation::kNone; 268 default: 269 UNREACHABLE(); 270 } 271 } 272 273 static ValueType ValueTypeFor(MachineType type) { 274 switch (type.representation()) { 275 case MachineRepresentation::kWord8: 276 case MachineRepresentation::kWord16: 277 case MachineRepresentation::kWord32: 278 return kWasmI32; 279 case MachineRepresentation::kWord64: 280 return kWasmI64; 281 case MachineRepresentation::kFloat32: 282 return kWasmF32; 283 case MachineRepresentation::kFloat64: 284 return kWasmF64; 285 case MachineRepresentation::kTaggedPointer: 286 return kWasmAnyRef; 287 case MachineRepresentation::kSimd128: 288 return kWasmS128; 289 default: 290 UNREACHABLE(); 291 } 292 } 293 294 static char ShortNameOf(ValueType type) { 295 switch (type) { 296 case kWasmI32: 297 return 'i'; 298 case kWasmI64: 299 return 'l'; 300 case kWasmF32: 301 return 'f'; 302 case kWasmF64: 303 return 'd'; 304 case kWasmAnyRef: 305 return 'r'; 306 case kWasmS128: 307 return 's'; 308 case kWasmStmt: 309 return 'v'; 310 case kWasmVar: 311 return '*'; 312 default: 313 return '?'; 314 } 315 } 316 317 static const char* TypeName(ValueType type) { 318 switch (type) { 319 case kWasmI32: 320 return "i32"; 321 case kWasmI64: 322 return "i64"; 323 case kWasmF32: 324 return "f32"; 325 case kWasmF64: 326 return "f64"; 327 case kWasmAnyRef: 328 return "ref"; 329 case kWasmS128: 330 return "s128"; 331 case kWasmStmt: 332 return "<stmt>"; 333 case kWasmVar: 334 return "<var>"; 335 default: 336 return "<unknown>"; 337 } 338 } 339 340 private: 341 DISALLOW_IMPLICIT_CONSTRUCTORS(ValueTypes); 342 }; 343 344 } // namespace wasm 345 } // namespace internal 346 } // namespace v8 347 348 #endif // V8_WASM_VALUE_TYPE_H_ 349