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