Home | History | Annotate | Download | only in wasm
      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