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