| // Copyright 2014 the V8 project authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef V8_MACHINE_TYPE_H_ |
| #define V8_MACHINE_TYPE_H_ |
| |
| #include <iosfwd> |
| |
| #include "src/base/bits.h" |
| #include "src/globals.h" |
| #include "src/signature.h" |
| #include "src/zone/zone.h" |
| |
| namespace v8 { |
| namespace internal { |
| |
| enum class MachineRepresentation : uint8_t { |
| kNone, |
| kBit, |
| kWord8, |
| kWord16, |
| kWord32, |
| kWord64, |
| kTaggedSigned, |
| kTaggedPointer, |
| kTagged, |
| // FP representations must be last, and in order of increasing size. |
| kFloat32, |
| kFloat64, |
| kSimd128, |
| kFirstFPRepresentation = kFloat32, |
| kLastRepresentation = kSimd128 |
| }; |
| |
| bool IsSubtype(MachineRepresentation rep1, MachineRepresentation rep2); |
| |
| static_assert(static_cast<int>(MachineRepresentation::kLastRepresentation) < |
| kIntSize * kBitsPerByte, |
| "Bit masks of MachineRepresentation should fit in an int"); |
| |
| V8_EXPORT_PRIVATE const char* MachineReprToString(MachineRepresentation); |
| |
| enum class MachineSemantic : uint8_t { |
| kNone, |
| kBool, |
| kInt32, |
| kUint32, |
| kInt64, |
| kUint64, |
| kNumber, |
| kAny |
| }; |
| |
| V8_EXPORT_PRIVATE inline int ElementSizeLog2Of(MachineRepresentation rep); |
| |
| class MachineType { |
| public: |
| constexpr MachineType() |
| : representation_(MachineRepresentation::kNone), |
| semantic_(MachineSemantic::kNone) {} |
| constexpr MachineType(MachineRepresentation representation, |
| MachineSemantic semantic) |
| : representation_(representation), semantic_(semantic) {} |
| |
| constexpr bool operator==(MachineType other) const { |
| return representation() == other.representation() && |
| semantic() == other.semantic(); |
| } |
| |
| constexpr bool operator!=(MachineType other) const { |
| return !(*this == other); |
| } |
| |
| constexpr MachineRepresentation representation() const { |
| return representation_; |
| } |
| constexpr MachineSemantic semantic() const { return semantic_; } |
| |
| constexpr bool IsNone() const { |
| return representation() == MachineRepresentation::kNone; |
| } |
| |
| constexpr bool IsSigned() const { |
| return semantic() == MachineSemantic::kInt32 || |
| semantic() == MachineSemantic::kInt64; |
| } |
| constexpr bool IsUnsigned() const { |
| return semantic() == MachineSemantic::kUint32 || |
| semantic() == MachineSemantic::kUint64; |
| } |
| constexpr bool IsTagged() const { |
| return representation() == MachineRepresentation::kTaggedPointer || |
| representation() == MachineRepresentation::kTaggedSigned || |
| representation() == MachineRepresentation::kTagged; |
| } |
| constexpr static MachineRepresentation PointerRepresentation() { |
| return (kPointerSize == 4) ? MachineRepresentation::kWord32 |
| : MachineRepresentation::kWord64; |
| } |
| constexpr static MachineType UintPtr() { |
| return (kPointerSize == 4) ? Uint32() : Uint64(); |
| } |
| constexpr static MachineType IntPtr() { |
| return (kPointerSize == 4) ? Int32() : Int64(); |
| } |
| constexpr static MachineType Int8() { |
| return MachineType(MachineRepresentation::kWord8, MachineSemantic::kInt32); |
| } |
| constexpr static MachineType Uint8() { |
| return MachineType(MachineRepresentation::kWord8, MachineSemantic::kUint32); |
| } |
| constexpr static MachineType Int16() { |
| return MachineType(MachineRepresentation::kWord16, MachineSemantic::kInt32); |
| } |
| constexpr static MachineType Uint16() { |
| return MachineType(MachineRepresentation::kWord16, |
| MachineSemantic::kUint32); |
| } |
| constexpr static MachineType Int32() { |
| return MachineType(MachineRepresentation::kWord32, MachineSemantic::kInt32); |
| } |
| constexpr static MachineType Uint32() { |
| return MachineType(MachineRepresentation::kWord32, |
| MachineSemantic::kUint32); |
| } |
| constexpr static MachineType Int64() { |
| return MachineType(MachineRepresentation::kWord64, MachineSemantic::kInt64); |
| } |
| constexpr static MachineType Uint64() { |
| return MachineType(MachineRepresentation::kWord64, |
| MachineSemantic::kUint64); |
| } |
| constexpr static MachineType Float32() { |
| return MachineType(MachineRepresentation::kFloat32, |
| MachineSemantic::kNumber); |
| } |
| constexpr static MachineType Float64() { |
| return MachineType(MachineRepresentation::kFloat64, |
| MachineSemantic::kNumber); |
| } |
| constexpr static MachineType Simd128() { |
| return MachineType(MachineRepresentation::kSimd128, MachineSemantic::kNone); |
| } |
| constexpr static MachineType Pointer() { |
| return MachineType(PointerRepresentation(), MachineSemantic::kNone); |
| } |
| constexpr static MachineType TaggedPointer() { |
| return MachineType(MachineRepresentation::kTaggedPointer, |
| MachineSemantic::kAny); |
| } |
| constexpr static MachineType TaggedSigned() { |
| return MachineType(MachineRepresentation::kTaggedSigned, |
| MachineSemantic::kInt32); |
| } |
| constexpr static MachineType AnyTagged() { |
| return MachineType(MachineRepresentation::kTagged, MachineSemantic::kAny); |
| } |
| constexpr static MachineType Bool() { |
| return MachineType(MachineRepresentation::kBit, MachineSemantic::kBool); |
| } |
| constexpr static MachineType TaggedBool() { |
| return MachineType(MachineRepresentation::kTagged, MachineSemantic::kBool); |
| } |
| constexpr static MachineType None() { |
| return MachineType(MachineRepresentation::kNone, MachineSemantic::kNone); |
| } |
| |
| // These naked representations should eventually go away. |
| constexpr static MachineType RepWord8() { |
| return MachineType(MachineRepresentation::kWord8, MachineSemantic::kNone); |
| } |
| constexpr static MachineType RepWord16() { |
| return MachineType(MachineRepresentation::kWord16, MachineSemantic::kNone); |
| } |
| constexpr static MachineType RepWord32() { |
| return MachineType(MachineRepresentation::kWord32, MachineSemantic::kNone); |
| } |
| constexpr static MachineType RepWord64() { |
| return MachineType(MachineRepresentation::kWord64, MachineSemantic::kNone); |
| } |
| constexpr static MachineType RepFloat32() { |
| return MachineType(MachineRepresentation::kFloat32, MachineSemantic::kNone); |
| } |
| constexpr static MachineType RepFloat64() { |
| return MachineType(MachineRepresentation::kFloat64, MachineSemantic::kNone); |
| } |
| constexpr static MachineType RepSimd128() { |
| return MachineType(MachineRepresentation::kSimd128, MachineSemantic::kNone); |
| } |
| constexpr static MachineType RepTagged() { |
| return MachineType(MachineRepresentation::kTagged, MachineSemantic::kNone); |
| } |
| constexpr static MachineType RepBit() { |
| return MachineType(MachineRepresentation::kBit, MachineSemantic::kNone); |
| } |
| |
| static MachineType TypeForRepresentation(const MachineRepresentation& rep, |
| bool isSigned = true) { |
| switch (rep) { |
| case MachineRepresentation::kNone: |
| return MachineType::None(); |
| case MachineRepresentation::kBit: |
| return MachineType::Bool(); |
| case MachineRepresentation::kWord8: |
| return isSigned ? MachineType::Int8() : MachineType::Uint8(); |
| case MachineRepresentation::kWord16: |
| return isSigned ? MachineType::Int16() : MachineType::Uint16(); |
| case MachineRepresentation::kWord32: |
| return isSigned ? MachineType::Int32() : MachineType::Uint32(); |
| case MachineRepresentation::kWord64: |
| return isSigned ? MachineType::Int64() : MachineType::Uint64(); |
| case MachineRepresentation::kFloat32: |
| return MachineType::Float32(); |
| case MachineRepresentation::kFloat64: |
| return MachineType::Float64(); |
| case MachineRepresentation::kSimd128: |
| return MachineType::Simd128(); |
| case MachineRepresentation::kTagged: |
| return MachineType::AnyTagged(); |
| case MachineRepresentation::kTaggedSigned: |
| return MachineType::TaggedSigned(); |
| case MachineRepresentation::kTaggedPointer: |
| return MachineType::TaggedPointer(); |
| default: |
| UNREACHABLE(); |
| } |
| } |
| |
| bool LessThanOrEqualPointerSize() { |
| return ElementSizeLog2Of(this->representation()) <= kPointerSizeLog2; |
| } |
| |
| private: |
| MachineRepresentation representation_; |
| MachineSemantic semantic_; |
| }; |
| |
| V8_INLINE size_t hash_value(MachineRepresentation rep) { |
| return static_cast<size_t>(rep); |
| } |
| |
| V8_INLINE size_t hash_value(MachineType type) { |
| return static_cast<size_t>(type.representation()) + |
| static_cast<size_t>(type.semantic()) * 16; |
| } |
| |
| V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, |
| MachineRepresentation rep); |
| std::ostream& operator<<(std::ostream& os, MachineSemantic type); |
| V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, MachineType type); |
| |
| inline bool IsFloatingPoint(MachineRepresentation rep) { |
| return rep >= MachineRepresentation::kFirstFPRepresentation; |
| } |
| |
| inline bool CanBeTaggedPointer(MachineRepresentation rep) { |
| return rep == MachineRepresentation::kTagged || |
| rep == MachineRepresentation::kTaggedPointer; |
| } |
| |
| inline bool CanBeTaggedSigned(MachineRepresentation rep) { |
| return rep == MachineRepresentation::kTagged || |
| rep == MachineRepresentation::kTaggedSigned; |
| } |
| |
| inline bool IsAnyTagged(MachineRepresentation rep) { |
| return CanBeTaggedPointer(rep) || rep == MachineRepresentation::kTaggedSigned; |
| } |
| |
| // Gets the log2 of the element size in bytes of the machine type. |
| V8_EXPORT_PRIVATE inline int ElementSizeLog2Of(MachineRepresentation rep) { |
| switch (rep) { |
| case MachineRepresentation::kBit: |
| case MachineRepresentation::kWord8: |
| return 0; |
| case MachineRepresentation::kWord16: |
| return 1; |
| case MachineRepresentation::kWord32: |
| case MachineRepresentation::kFloat32: |
| return 2; |
| case MachineRepresentation::kWord64: |
| case MachineRepresentation::kFloat64: |
| return 3; |
| case MachineRepresentation::kSimd128: |
| return 4; |
| case MachineRepresentation::kTaggedSigned: |
| case MachineRepresentation::kTaggedPointer: |
| case MachineRepresentation::kTagged: |
| return kPointerSizeLog2; |
| default: |
| break; |
| } |
| UNREACHABLE(); |
| } |
| |
| typedef Signature<MachineType> MachineSignature; |
| |
| } // namespace internal |
| } // namespace v8 |
| |
| #endif // V8_MACHINE_TYPE_H_ |