// 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"
|
|
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);
|
|
V8_EXPORT_PRIVATE inline int ElementSizeInBytes(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();
|
}
|
|
V8_EXPORT_PRIVATE inline int ElementSizeInBytes(MachineRepresentation rep) {
|
return 1 << ElementSizeLog2Of(rep);
|
}
|
|
} // namespace internal
|
} // namespace v8
|
|
#endif // V8_MACHINE_TYPE_H_
|