summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/asmjit/src/asmjit/core/type.h
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/asmjit/src/asmjit/core/type.h')
-rw-r--r--3rdparty/asmjit/src/asmjit/core/type.h616
1 files changed, 342 insertions, 274 deletions
diff --git a/3rdparty/asmjit/src/asmjit/core/type.h b/3rdparty/asmjit/src/asmjit/core/type.h
index ef03ecb8360..415fe0a421d 100644
--- a/3rdparty/asmjit/src/asmjit/core/type.h
+++ b/3rdparty/asmjit/src/asmjit/core/type.h
@@ -1,210 +1,261 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_TYPE_H_INCLUDED
#define ASMJIT_CORE_TYPE_H_INCLUDED
#include "../core/globals.h"
+#include "../core/support.h"
ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_core
//! \{
-// ============================================================================
-// [asmjit::Type]
-// ============================================================================
-
-//! Provides a minimalist type-system that is used by Asmjit library.
-namespace Type {
-
-//! TypeId.
+//! Type identifier provides a minimalist type system used across AsmJit library.
//!
-//! This is an additional information that can be used to describe a value-type
-//! of physical or virtual register. it's used mostly by BaseCompiler to describe
-//! register representation (the group of data stored in the register and the
-//! width used) and it's also used by APIs that allow to describe and work with
-//! function signatures.
-enum Id : uint32_t {
- kIdVoid = 0, //!< Void type.
-
- _kIdBaseStart = 32,
- _kIdBaseEnd = 44,
-
- _kIdIntStart = 32,
- _kIdIntEnd = 41,
-
- kIdIntPtr = 32, //!< Abstract signed integer type that has a native size.
- kIdUIntPtr = 33, //!< Abstract unsigned integer type that has a native size.
-
- kIdI8 = 34, //!< 8-bit signed integer type.
- kIdU8 = 35, //!< 8-bit unsigned integer type.
- kIdI16 = 36, //!< 16-bit signed integer type.
- kIdU16 = 37, //!< 16-bit unsigned integer type.
- kIdI32 = 38, //!< 32-bit signed integer type.
- kIdU32 = 39, //!< 32-bit unsigned integer type.
- kIdI64 = 40, //!< 64-bit signed integer type.
- kIdU64 = 41, //!< 64-bit unsigned integer type.
-
- _kIdFloatStart = 42,
- _kIdFloatEnd = 44,
-
- kIdF32 = 42, //!< 32-bit floating point type.
- kIdF64 = 43, //!< 64-bit floating point type.
- kIdF80 = 44, //!< 80-bit floating point type.
-
- _kIdMaskStart = 45,
- _kIdMaskEnd = 48,
-
- kIdMask8 = 45, //!< 8-bit opmask register (K).
- kIdMask16 = 46, //!< 16-bit opmask register (K).
- kIdMask32 = 47, //!< 32-bit opmask register (K).
- kIdMask64 = 48, //!< 64-bit opmask register (K).
-
- _kIdMmxStart = 49,
- _kIdMmxEnd = 50,
-
- kIdMmx32 = 49, //!< 64-bit MMX register only used for 32 bits.
- kIdMmx64 = 50, //!< 64-bit MMX register.
-
- _kIdVec32Start = 51,
- _kIdVec32End = 60,
-
- kIdI8x4 = 51,
- kIdU8x4 = 52,
- kIdI16x2 = 53,
- kIdU16x2 = 54,
- kIdI32x1 = 55,
- kIdU32x1 = 56,
- kIdF32x1 = 59,
-
- _kIdVec64Start = 61,
- _kIdVec64End = 70,
-
- kIdI8x8 = 61,
- kIdU8x8 = 62,
- kIdI16x4 = 63,
- kIdU16x4 = 64,
- kIdI32x2 = 65,
- kIdU32x2 = 66,
- kIdI64x1 = 67,
- kIdU64x1 = 68,
- kIdF32x2 = 69,
- kIdF64x1 = 70,
-
- _kIdVec128Start = 71,
- _kIdVec128End = 80,
-
- kIdI8x16 = 71,
- kIdU8x16 = 72,
- kIdI16x8 = 73,
- kIdU16x8 = 74,
- kIdI32x4 = 75,
- kIdU32x4 = 76,
- kIdI64x2 = 77,
- kIdU64x2 = 78,
- kIdF32x4 = 79,
- kIdF64x2 = 80,
-
- _kIdVec256Start = 81,
- _kIdVec256End = 90,
-
- kIdI8x32 = 81,
- kIdU8x32 = 82,
- kIdI16x16 = 83,
- kIdU16x16 = 84,
- kIdI32x8 = 85,
- kIdU32x8 = 86,
- kIdI64x4 = 87,
- kIdU64x4 = 88,
- kIdF32x8 = 89,
- kIdF64x4 = 90,
-
- _kIdVec512Start = 91,
- _kIdVec512End = 100,
-
- kIdI8x64 = 91,
- kIdU8x64 = 92,
- kIdI16x32 = 93,
- kIdU16x32 = 94,
- kIdI32x16 = 95,
- kIdU32x16 = 96,
- kIdI64x8 = 97,
- kIdU64x8 = 98,
- kIdF32x16 = 99,
- kIdF64x8 = 100,
-
- kIdCount = 101,
- kIdMax = 255
+//! This is an additional information that can be used to describe a value-type of physical or virtual register. It's
+//! used mostly by BaseCompiler to describe register representation (the group of data stored in the register and the
+//! width used) and it's also used by APIs that allow to describe and work with function signatures.
+enum class TypeId : uint8_t {
+ //! Void type.
+ kVoid = 0,
+
+ _kBaseStart = 32,
+ _kBaseEnd = 44,
+
+ _kIntStart = 32,
+ _kIntEnd = 41,
+
+ //! Abstract signed integer type that has a native size.
+ kIntPtr = 32,
+ //! Abstract unsigned integer type that has a native size.
+ kUIntPtr = 33,
+
+ //! 8-bit signed integer type.
+ kInt8 = 34,
+ //! 8-bit unsigned integer type.
+ kUInt8 = 35,
+ //! 16-bit signed integer type.
+ kInt16 = 36,
+ //! 16-bit unsigned integer type.
+ kUInt16 = 37,
+ //! 32-bit signed integer type.
+ kInt32 = 38,
+ //! 32-bit unsigned integer type.
+ kUInt32 = 39,
+ //! 64-bit signed integer type.
+ kInt64 = 40,
+ //! 64-bit unsigned integer type.
+ kUInt64 = 41,
+
+ _kFloatStart = 42,
+ _kFloatEnd = 44,
+
+ //! 32-bit floating point type.
+ kFloat32 = 42,
+ //! 64-bit floating point type.
+ kFloat64 = 43,
+ //! 80-bit floating point type.
+ kFloat80 = 44,
+
+ _kMaskStart = 45,
+ _kMaskEnd = 48,
+
+ //! 8-bit opmask register (K).
+ kMask8 = 45,
+ //! 16-bit opmask register (K).
+ kMask16 = 46,
+ //! 32-bit opmask register (K).
+ kMask32 = 47,
+ //! 64-bit opmask register (K).
+ kMask64 = 48,
+
+ _kMmxStart = 49,
+ _kMmxEnd = 50,
+
+ //! 64-bit MMX register only used for 32 bits.
+ kMmx32 = 49,
+ //! 64-bit MMX register.
+ kMmx64 = 50,
+
+ _kVec32Start = 51,
+ _kVec32End = 60,
+
+ kInt8x4 = 51,
+ kUInt8x4 = 52,
+ kInt16x2 = 53,
+ kUInt16x2 = 54,
+ kInt32x1 = 55,
+ kUInt32x1 = 56,
+ kFloat32x1 = 59,
+
+ _kVec64Start = 61,
+ _kVec64End = 70,
+
+ kInt8x8 = 61,
+ kUInt8x8 = 62,
+ kInt16x4 = 63,
+ kUInt16x4 = 64,
+ kInt32x2 = 65,
+ kUInt32x2 = 66,
+ kInt64x1 = 67,
+ kUInt64x1 = 68,
+ kFloat32x2 = 69,
+ kFloat64x1 = 70,
+
+ _kVec128Start = 71,
+ _kVec128End = 80,
+
+ kInt8x16 = 71,
+ kUInt8x16 = 72,
+ kInt16x8 = 73,
+ kUInt16x8 = 74,
+ kInt32x4 = 75,
+ kUInt32x4 = 76,
+ kInt64x2 = 77,
+ kUInt64x2 = 78,
+ kFloat32x4 = 79,
+ kFloat64x2 = 80,
+
+ _kVec256Start = 81,
+ _kVec256End = 90,
+
+ kInt8x32 = 81,
+ kUInt8x32 = 82,
+ kInt16x16 = 83,
+ kUInt16x16 = 84,
+ kInt32x8 = 85,
+ kUInt32x8 = 86,
+ kInt64x4 = 87,
+ kUInt64x4 = 88,
+ kFloat32x8 = 89,
+ kFloat64x4 = 90,
+
+ _kVec512Start = 91,
+ _kVec512End = 100,
+
+ kInt8x64 = 91,
+ kUInt8x64 = 92,
+ kInt16x32 = 93,
+ kUInt16x32 = 94,
+ kInt32x16 = 95,
+ kUInt32x16 = 96,
+ kInt64x8 = 97,
+ kUInt64x8 = 98,
+ kFloat32x16 = 99,
+ kFloat64x8 = 100,
+
+ kLastAssigned = kFloat64x8,
+
+ kMaxValue = 255
};
+ASMJIT_DEFINE_ENUM_COMPARE(TypeId)
+
+//! Type identifier utilities.
+namespace TypeUtils {
struct TypeData {
- uint8_t baseOf[kIdMax + 1];
- uint8_t sizeOf[kIdMax + 1];
+ TypeId scalarOf[uint32_t(TypeId::kMaxValue) + 1];
+ uint8_t sizeOf[uint32_t(TypeId::kMaxValue) + 1];
};
ASMJIT_VARAPI const TypeData _typeData;
-static constexpr bool isVoid(uint32_t typeId) noexcept { return typeId == 0; }
-static constexpr bool isValid(uint32_t typeId) noexcept { return typeId >= _kIdIntStart && typeId <= _kIdVec512End; }
-static constexpr bool isBase(uint32_t typeId) noexcept { return typeId >= _kIdBaseStart && typeId <= _kIdBaseEnd; }
-static constexpr bool isAbstract(uint32_t typeId) noexcept { return typeId >= kIdIntPtr && typeId <= kIdUIntPtr; }
-
-static constexpr bool isInt(uint32_t typeId) noexcept { return typeId >= _kIdIntStart && typeId <= _kIdIntEnd; }
-static constexpr bool isInt8(uint32_t typeId) noexcept { return typeId == kIdI8; }
-static constexpr bool isUInt8(uint32_t typeId) noexcept { return typeId == kIdU8; }
-static constexpr bool isInt16(uint32_t typeId) noexcept { return typeId == kIdI16; }
-static constexpr bool isUInt16(uint32_t typeId) noexcept { return typeId == kIdU16; }
-static constexpr bool isInt32(uint32_t typeId) noexcept { return typeId == kIdI32; }
-static constexpr bool isUInt32(uint32_t typeId) noexcept { return typeId == kIdU32; }
-static constexpr bool isInt64(uint32_t typeId) noexcept { return typeId == kIdI64; }
-static constexpr bool isUInt64(uint32_t typeId) noexcept { return typeId == kIdU64; }
-
-static constexpr bool isGp8(uint32_t typeId) noexcept { return typeId >= kIdI8 && typeId <= kIdU8; }
-static constexpr bool isGp16(uint32_t typeId) noexcept { return typeId >= kIdI16 && typeId <= kIdU16; }
-static constexpr bool isGp32(uint32_t typeId) noexcept { return typeId >= kIdI32 && typeId <= kIdU32; }
-static constexpr bool isGp64(uint32_t typeId) noexcept { return typeId >= kIdI64 && typeId <= kIdU64; }
-
-static constexpr bool isFloat(uint32_t typeId) noexcept { return typeId >= _kIdFloatStart && typeId <= _kIdFloatEnd; }
-static constexpr bool isFloat32(uint32_t typeId) noexcept { return typeId == kIdF32; }
-static constexpr bool isFloat64(uint32_t typeId) noexcept { return typeId == kIdF64; }
-static constexpr bool isFloat80(uint32_t typeId) noexcept { return typeId == kIdF80; }
-
-static constexpr bool isMask(uint32_t typeId) noexcept { return typeId >= _kIdMaskStart && typeId <= _kIdMaskEnd; }
-static constexpr bool isMask8(uint32_t typeId) noexcept { return typeId == kIdMask8; }
-static constexpr bool isMask16(uint32_t typeId) noexcept { return typeId == kIdMask16; }
-static constexpr bool isMask32(uint32_t typeId) noexcept { return typeId == kIdMask32; }
-static constexpr bool isMask64(uint32_t typeId) noexcept { return typeId == kIdMask64; }
-
-static constexpr bool isMmx(uint32_t typeId) noexcept { return typeId >= _kIdMmxStart && typeId <= _kIdMmxEnd; }
-static constexpr bool isMmx32(uint32_t typeId) noexcept { return typeId == kIdMmx32; }
-static constexpr bool isMmx64(uint32_t typeId) noexcept { return typeId == kIdMmx64; }
-
-static constexpr bool isVec(uint32_t typeId) noexcept { return typeId >= _kIdVec32Start && typeId <= _kIdVec512End; }
-static constexpr bool isVec32(uint32_t typeId) noexcept { return typeId >= _kIdVec32Start && typeId <= _kIdVec32End; }
-static constexpr bool isVec64(uint32_t typeId) noexcept { return typeId >= _kIdVec64Start && typeId <= _kIdVec64End; }
-static constexpr bool isVec128(uint32_t typeId) noexcept { return typeId >= _kIdVec128Start && typeId <= _kIdVec128End; }
-static constexpr bool isVec256(uint32_t typeId) noexcept { return typeId >= _kIdVec256Start && typeId <= _kIdVec256End; }
-static constexpr bool isVec512(uint32_t typeId) noexcept { return typeId >= _kIdVec512Start && typeId <= _kIdVec512End; }
+//! Returns the scalar type of `typeId`.
+static ASMJIT_INLINE_NODEBUG TypeId scalarOf(TypeId typeId) noexcept { return _typeData.scalarOf[uint32_t(typeId)]; }
+
+//! Returns the size [in bytes] of `typeId`.
+static ASMJIT_INLINE_NODEBUG uint32_t sizeOf(TypeId typeId) noexcept { return _typeData.sizeOf[uint32_t(typeId)]; }
+
+//! Tests whether a given type `typeId` is between `a` and `b`.
+static ASMJIT_INLINE_NODEBUG constexpr bool isBetween(TypeId typeId, TypeId a, TypeId b) noexcept {
+ return Support::isBetween(uint32_t(typeId), uint32_t(a), uint32_t(b));
+}
+
+//! Tests whether a given type `typeId` is \ref TypeId::kVoid.
+static ASMJIT_INLINE_NODEBUG constexpr bool isVoid(TypeId typeId) noexcept { return typeId == TypeId::kVoid; }
+//! Tests whether a given type `typeId` is a valid non-void type.
+static ASMJIT_INLINE_NODEBUG constexpr bool isValid(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kIntStart, TypeId::_kVec512End); }
+//! Tests whether a given type `typeId` is scalar (has no vector part).
+static ASMJIT_INLINE_NODEBUG constexpr bool isScalar(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kBaseStart, TypeId::_kBaseEnd); }
+//! Tests whether a given type `typeId` is abstract, which means that its size depends on register size.
+static ASMJIT_INLINE_NODEBUG constexpr bool isAbstract(TypeId typeId) noexcept { return isBetween(typeId, TypeId::kIntPtr, TypeId::kUIntPtr); }
+
+//! Tests whether a given type is a scalar integer (signed or unsigned) of any size.
+static ASMJIT_INLINE_NODEBUG constexpr bool isInt(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kIntStart, TypeId::_kIntEnd); }
+//! Tests whether a given type is a scalar 8-bit integer (signed).
+static ASMJIT_INLINE_NODEBUG constexpr bool isInt8(TypeId typeId) noexcept { return typeId == TypeId::kInt8; }
+//! Tests whether a given type is a scalar 8-bit integer (unsigned).
+static ASMJIT_INLINE_NODEBUG constexpr bool isUInt8(TypeId typeId) noexcept { return typeId == TypeId::kUInt8; }
+//! Tests whether a given type is a scalar 16-bit integer (signed).
+static ASMJIT_INLINE_NODEBUG constexpr bool isInt16(TypeId typeId) noexcept { return typeId == TypeId::kInt16; }
+//! Tests whether a given type is a scalar 16-bit integer (unsigned).
+static ASMJIT_INLINE_NODEBUG constexpr bool isUInt16(TypeId typeId) noexcept { return typeId == TypeId::kUInt16; }
+//! Tests whether a given type is a scalar 32-bit integer (signed).
+static ASMJIT_INLINE_NODEBUG constexpr bool isInt32(TypeId typeId) noexcept { return typeId == TypeId::kInt32; }
+//! Tests whether a given type is a scalar 32-bit integer (unsigned).
+static ASMJIT_INLINE_NODEBUG constexpr bool isUInt32(TypeId typeId) noexcept { return typeId == TypeId::kUInt32; }
+//! Tests whether a given type is a scalar 64-bit integer (signed).
+static ASMJIT_INLINE_NODEBUG constexpr bool isInt64(TypeId typeId) noexcept { return typeId == TypeId::kInt64; }
+//! Tests whether a given type is a scalar 64-bit integer (unsigned).
+static ASMJIT_INLINE_NODEBUG constexpr bool isUInt64(TypeId typeId) noexcept { return typeId == TypeId::kUInt64; }
+
+//! Tests whether a given type is an 8-bit general purpose register representing either signed or unsigned 8-bit integer.
+static ASMJIT_INLINE_NODEBUG constexpr bool isGp8(TypeId typeId) noexcept { return isBetween(typeId, TypeId::kInt8, TypeId::kUInt8); }
+//! Tests whether a given type is a 16-bit general purpose register representing either signed or unsigned 16-bit integer
+static ASMJIT_INLINE_NODEBUG constexpr bool isGp16(TypeId typeId) noexcept { return isBetween(typeId, TypeId::kInt16, TypeId::kUInt16); }
+//! Tests whether a given type is a 32-bit general purpose register representing either signed or unsigned 32-bit integer
+static ASMJIT_INLINE_NODEBUG constexpr bool isGp32(TypeId typeId) noexcept { return isBetween(typeId, TypeId::kInt32, TypeId::kUInt32); }
+//! Tests whether a given type is a 64-bit general purpose register representing either signed or unsigned 64-bit integer
+static ASMJIT_INLINE_NODEBUG constexpr bool isGp64(TypeId typeId) noexcept { return isBetween(typeId, TypeId::kInt64, TypeId::kUInt64); }
+
+//! Tests whether a given type is a scalar floating point of any size.
+static ASMJIT_INLINE_NODEBUG constexpr bool isFloat(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kFloatStart, TypeId::_kFloatEnd); }
+//! Tests whether a given type is a scalar 32-bit float.
+static ASMJIT_INLINE_NODEBUG constexpr bool isFloat32(TypeId typeId) noexcept { return typeId == TypeId::kFloat32; }
+//! Tests whether a given type is a scalar 64-bit float.
+static ASMJIT_INLINE_NODEBUG constexpr bool isFloat64(TypeId typeId) noexcept { return typeId == TypeId::kFloat64; }
+//! Tests whether a given type is a scalar 80-bit float.
+static ASMJIT_INLINE_NODEBUG constexpr bool isFloat80(TypeId typeId) noexcept { return typeId == TypeId::kFloat80; }
+
+//! Tests whether a given type is a mask register of any size.
+static ASMJIT_INLINE_NODEBUG constexpr bool isMask(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kMaskStart, TypeId::_kMaskEnd); }
+//! Tests whether a given type is an 8-bit mask register.
+static ASMJIT_INLINE_NODEBUG constexpr bool isMask8(TypeId typeId) noexcept { return typeId == TypeId::kMask8; }
+//! Tests whether a given type is an 16-bit mask register.
+static ASMJIT_INLINE_NODEBUG constexpr bool isMask16(TypeId typeId) noexcept { return typeId == TypeId::kMask16; }
+//! Tests whether a given type is an 32-bit mask register.
+static ASMJIT_INLINE_NODEBUG constexpr bool isMask32(TypeId typeId) noexcept { return typeId == TypeId::kMask32; }
+//! Tests whether a given type is an 64-bit mask register.
+static ASMJIT_INLINE_NODEBUG constexpr bool isMask64(TypeId typeId) noexcept { return typeId == TypeId::kMask64; }
+
+//! Tests whether a given type is an MMX register.
+//!
+//! \note MMX functionality is in general deprecated on X86 architecture. AsmJit provides it just for completeness.
+static ASMJIT_INLINE_NODEBUG constexpr bool isMmx(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kMmxStart, TypeId::_kMmxEnd); }
+//! Tests whether a given type is an MMX register, which only uses the low 32 bits of data (only specific cases).
+//!
+//! \note MMX functionality is in general deprecated on X86 architecture. AsmJit provides it just for completeness.
+static ASMJIT_INLINE_NODEBUG constexpr bool isMmx32(TypeId typeId) noexcept { return typeId == TypeId::kMmx32; }
+//! Tests whether a given type is an MMX register, which uses 64 bits of data (default).
+//!
+//! \note MMX functionality is in general deprecated on X86 architecture. AsmJit provides it just for completeness.
+static ASMJIT_INLINE_NODEBUG constexpr bool isMmx64(TypeId typeId) noexcept { return typeId == TypeId::kMmx64; }
+
+//! Tests whether a given type is a vector register of any size.
+static ASMJIT_INLINE_NODEBUG constexpr bool isVec(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kVec32Start, TypeId::_kVec512End); }
+//! Tests whether a given type is a 32-bit or 32-bit view of a vector register.
+static ASMJIT_INLINE_NODEBUG constexpr bool isVec32(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kVec32Start, TypeId::_kVec32End); }
+//! Tests whether a given type is a 64-bit or 64-bit view of a vector register.
+static ASMJIT_INLINE_NODEBUG constexpr bool isVec64(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kVec64Start, TypeId::_kVec64End); }
+//! Tests whether a given type is a 128-bit or 128-bit view of a vector register.
+static ASMJIT_INLINE_NODEBUG constexpr bool isVec128(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kVec128Start, TypeId::_kVec128End); }
+//! Tests whether a given type is a 256-bit or 256-bit view of a vector register.
+static ASMJIT_INLINE_NODEBUG constexpr bool isVec256(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kVec256Start, TypeId::_kVec256End); }
+//! Tests whether a given type is a 512-bit or 512-bit view of a vector register.
+static ASMJIT_INLINE_NODEBUG constexpr bool isVec512(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kVec512Start, TypeId::_kVec512End); }
//! \cond
enum TypeCategory : uint32_t {
@@ -215,157 +266,174 @@ enum TypeCategory : uint32_t {
kTypeCategoryFunction = 4
};
-template<typename T, uint32_t Category>
-struct IdOfT_ByCategory {}; // Fails if not specialized.
+template<typename T, TypeCategory kCategory>
+struct TypeIdOfT_ByCategory {}; // Fails if not specialized.
template<typename T>
-struct IdOfT_ByCategory<T, kTypeCategoryIntegral> {
+struct TypeIdOfT_ByCategory<T, kTypeCategoryIntegral> {
enum : uint32_t {
- kTypeId = (sizeof(T) == 1 && std::is_signed<T>::value) ? kIdI8 :
- (sizeof(T) == 1 && !std::is_signed<T>::value) ? kIdU8 :
- (sizeof(T) == 2 && std::is_signed<T>::value) ? kIdI16 :
- (sizeof(T) == 2 && !std::is_signed<T>::value) ? kIdU16 :
- (sizeof(T) == 4 && std::is_signed<T>::value) ? kIdI32 :
- (sizeof(T) == 4 && !std::is_signed<T>::value) ? kIdU32 :
- (sizeof(T) == 8 && std::is_signed<T>::value) ? kIdI64 :
- (sizeof(T) == 8 && !std::is_signed<T>::value) ? kIdU64 : kIdVoid
+ kTypeId = uint32_t(
+ (sizeof(T) == 1 && std::is_signed<T>::value) ? TypeId::kInt8 :
+ (sizeof(T) == 1 && !std::is_signed<T>::value) ? TypeId::kUInt8 :
+ (sizeof(T) == 2 && std::is_signed<T>::value) ? TypeId::kInt16 :
+ (sizeof(T) == 2 && !std::is_signed<T>::value) ? TypeId::kUInt16 :
+ (sizeof(T) == 4 && std::is_signed<T>::value) ? TypeId::kInt32 :
+ (sizeof(T) == 4 && !std::is_signed<T>::value) ? TypeId::kUInt32 :
+ (sizeof(T) == 8 && std::is_signed<T>::value) ? TypeId::kInt64 :
+ (sizeof(T) == 8 && !std::is_signed<T>::value) ? TypeId::kUInt64 : TypeId::kVoid)
};
};
template<typename T>
-struct IdOfT_ByCategory<T, kTypeCategoryFloatingPoint> {
+struct TypeIdOfT_ByCategory<T, kTypeCategoryFloatingPoint> {
enum : uint32_t {
- kTypeId = (sizeof(T) == 4 ) ? kIdF32 :
- (sizeof(T) == 8 ) ? kIdF64 :
- (sizeof(T) >= 10) ? kIdF80 : kIdVoid
+ kTypeId = uint32_t(
+ (sizeof(T) == 4 ) ? TypeId::kFloat32 :
+ (sizeof(T) == 8 ) ? TypeId::kFloat64 :
+ (sizeof(T) >= 10) ? TypeId::kFloat80 : TypeId::kVoid)
};
};
template<typename T>
-struct IdOfT_ByCategory<T, kTypeCategoryEnum>
- : public IdOfT_ByCategory<typename std::underlying_type<T>::type, kTypeCategoryIntegral> {};
+struct TypeIdOfT_ByCategory<T, kTypeCategoryEnum>
+ : public TypeIdOfT_ByCategory<typename std::underlying_type<T>::type, kTypeCategoryIntegral> {};
template<typename T>
-struct IdOfT_ByCategory<T, kTypeCategoryFunction> {
- enum: uint32_t { kTypeId = kIdUIntPtr };
+struct TypeIdOfT_ByCategory<T, kTypeCategoryFunction> {
+ enum : uint32_t {
+ kTypeId = uint32_t(TypeId::kUIntPtr)
+ };
};
//! \endcond
-//! IdOfT<> template allows to get a TypeId from a C++ type `T`.
-template<typename T>
-struct IdOfT
+//! TypeIdOfT<> template allows to get a TypeId from a C++ type `T`.
#ifdef _DOXYGEN
+template<typename T>
+struct TypeIdOfT {
//! TypeId of C++ type `T`.
- static constexpr uint32_t kTypeId = _TypeIdDeducedAtCompileTime_;
+ static constexpr TypeId kTypeId = _TypeIdDeducedAtCompileTime_;
+};
#else
- : public IdOfT_ByCategory<T,
+template<typename T>
+struct TypeIdOfT
+ : public TypeIdOfT_ByCategory<T,
std::is_enum<T>::value ? kTypeCategoryEnum :
std::is_integral<T>::value ? kTypeCategoryIntegral :
std::is_floating_point<T>::value ? kTypeCategoryFloatingPoint :
- std::is_function<T>::value ? kTypeCategoryFunction : kTypeCategoryUnknown>
+ std::is_function<T>::value ? kTypeCategoryFunction : kTypeCategoryUnknown> {};
#endif
-{};
//! \cond
template<typename T>
-struct IdOfT<T*> { enum : uint32_t { kTypeId = kIdUIntPtr }; };
+struct TypeIdOfT<T*> {
+ enum : uint32_t {
+ kTypeId = uint32_t(TypeId::kUIntPtr)
+ };
+};
template<typename T>
-struct IdOfT<T&> { enum : uint32_t { kTypeId = kIdUIntPtr }; };
+struct TypeIdOfT<T&> {
+ enum : uint32_t {
+ kTypeId = uint32_t(TypeId::kUIntPtr)
+ };
+};
//! \endcond
-static inline uint32_t baseOf(uint32_t typeId) noexcept {
- ASMJIT_ASSERT(typeId <= kIdMax);
- return _typeData.baseOf[typeId];
-}
-
-static inline uint32_t sizeOf(uint32_t typeId) noexcept {
- ASMJIT_ASSERT(typeId <= kIdMax);
- return _typeData.sizeOf[typeId];
-}
+//! Returns a corresponding \ref TypeId of `T` type.
+template<typename T>
+static ASMJIT_INLINE_NODEBUG constexpr TypeId typeIdOfT() noexcept { return TypeId(TypeIdOfT<T>::kTypeId); }
-//! Returns offset needed to convert a `kIntPtr` and `kUIntPtr` TypeId
-//! into a type that matches `registerSize` (general-purpose register size).
-//! If you find such TypeId it's then only about adding the offset to it.
+//! Returns offset needed to convert a `kIntPtr` and `kUIntPtr` TypeId into a type that matches `registerSize`
+//! (general-purpose register size). If you find such TypeId it's then only about adding the offset to it.
//!
//! For example:
//!
//! ```
-//! uint32_t registerSize = '4' or '8';
-//! uint32_t deabstractDelta = Type::deabstractDeltaOfSize(registerSize);
+//! uint32_t registerSize = /* 4 or 8 */;
+//! uint32_t deabstractDelta = TypeUtils::deabstractDeltaOfSize(registerSize);
//!
-//! uint32_t typeId = 'some type-id';
+//! TypeId typeId = 'some type-id';
//!
//! // Normalize some typeId into a non-abstract typeId.
-//! if (Type::isAbstract(typeId)) typeId += deabstractDelta;
+//! if (TypeUtils::isAbstract(typeId)) typeId += deabstractDelta;
//!
-//! // The same, but by using Type::deabstract() function.
-//! typeId = Type::deabstract(typeId, deabstractDelta);
+//! // The same, but by using TypeUtils::deabstract() function.
+//! typeId = TypeUtils::deabstract(typeId, deabstractDelta);
//! ```
-static constexpr uint32_t deabstractDeltaOfSize(uint32_t registerSize) noexcept {
- return registerSize >= 8 ? kIdI64 - kIdIntPtr : kIdI32 - kIdIntPtr;
+static ASMJIT_INLINE_NODEBUG constexpr uint32_t deabstractDeltaOfSize(uint32_t registerSize) noexcept {
+ return registerSize >= 8 ? uint32_t(TypeId::kInt64) - uint32_t(TypeId::kIntPtr)
+ : uint32_t(TypeId::kInt32) - uint32_t(TypeId::kIntPtr);
+}
+
+//! Deabstracts a given `typeId` into a native type by using `deabstractDelta`, which was previously
+//! calculated by calling \ref deabstractDeltaOfSize() with a target native register size.
+static ASMJIT_INLINE_NODEBUG constexpr TypeId deabstract(TypeId typeId, uint32_t deabstractDelta) noexcept {
+ return isAbstract(typeId) ? TypeId(uint32_t(typeId) + deabstractDelta) : typeId;
}
-static constexpr uint32_t deabstract(uint32_t typeId, uint32_t deabstractDelta) noexcept {
- return isAbstract(typeId) ? typeId + deabstractDelta : typeId;
+static ASMJIT_INLINE_NODEBUG constexpr TypeId scalarToVector(TypeId scalarTypeId, TypeId vecStartId) noexcept {
+ return TypeId(uint32_t(vecStartId) + uint32_t(scalarTypeId) - uint32_t(TypeId::kInt8));
}
+} // {TypeUtils}
+
+//! Provides type identifiers that can be used in templates instead of native types.
+namespace Type {
+
//! bool as C++ type-name.
struct Bool {};
//! int8_t as C++ type-name.
-struct I8 {};
+struct Int8 {};
//! uint8_t as C++ type-name.
-struct U8 {};
+struct UInt8 {};
//! int16_t as C++ type-name.
-struct I16 {};
+struct Int16 {};
//! uint16_t as C++ type-name.
-struct U16 {};
+struct UInt16 {};
//! int32_t as C++ type-name.
-struct I32 {};
+struct Int32 {};
//! uint32_t as C++ type-name.
-struct U32 {};
+struct UInt32 {};
//! int64_t as C++ type-name.
-struct I64 {};
+struct Int64 {};
//! uint64_t as C++ type-name.
-struct U64 {};
+struct UInt64 {};
//! intptr_t as C++ type-name.
-struct IPtr {};
+struct IntPtr {};
//! uintptr_t as C++ type-name.
-struct UPtr {};
+struct UIntPtr {};
//! float as C++ type-name.
-struct F32 {};
+struct Float32 {};
//! double as C++ type-name.
-struct F64 {};
+struct Float64 {};
} // {Type}
-// ============================================================================
-// [ASMJIT_DEFINE_TYPE_ID]
-// ============================================================================
-
//! \cond
-#define ASMJIT_DEFINE_TYPE_ID(T, TYPE_ID) \
-namespace Type { \
- template<> \
- struct IdOfT<T> { \
- enum : uint32_t { kTypeId = TYPE_ID }; \
- }; \
+#define ASMJIT_DEFINE_TYPE_ID(T, TYPE_ID) \
+namespace TypeUtils { \
+ template<> \
+ struct TypeIdOfT<T> { \
+ enum : uint32_t { \
+ kTypeId = uint32_t(TYPE_ID) \
+ }; \
+ }; \
}
-ASMJIT_DEFINE_TYPE_ID(void, kIdVoid);
-ASMJIT_DEFINE_TYPE_ID(Bool, kIdU8);
-ASMJIT_DEFINE_TYPE_ID(I8 , kIdI8);
-ASMJIT_DEFINE_TYPE_ID(U8 , kIdU8);
-ASMJIT_DEFINE_TYPE_ID(I16 , kIdI16);
-ASMJIT_DEFINE_TYPE_ID(U16 , kIdU16);
-ASMJIT_DEFINE_TYPE_ID(I32 , kIdI32);
-ASMJIT_DEFINE_TYPE_ID(U32 , kIdU32);
-ASMJIT_DEFINE_TYPE_ID(I64 , kIdI64);
-ASMJIT_DEFINE_TYPE_ID(U64 , kIdU64);
-ASMJIT_DEFINE_TYPE_ID(IPtr, kIdIntPtr);
-ASMJIT_DEFINE_TYPE_ID(UPtr, kIdUIntPtr);
-ASMJIT_DEFINE_TYPE_ID(F32 , kIdF32);
-ASMJIT_DEFINE_TYPE_ID(F64 , kIdF64);
+ASMJIT_DEFINE_TYPE_ID(void , TypeId::kVoid);
+ASMJIT_DEFINE_TYPE_ID(Type::Bool , TypeId::kUInt8);
+ASMJIT_DEFINE_TYPE_ID(Type::Int8 , TypeId::kInt8);
+ASMJIT_DEFINE_TYPE_ID(Type::UInt8 , TypeId::kUInt8);
+ASMJIT_DEFINE_TYPE_ID(Type::Int16 , TypeId::kInt16);
+ASMJIT_DEFINE_TYPE_ID(Type::UInt16 , TypeId::kUInt16);
+ASMJIT_DEFINE_TYPE_ID(Type::Int32 , TypeId::kInt32);
+ASMJIT_DEFINE_TYPE_ID(Type::UInt32 , TypeId::kUInt32);
+ASMJIT_DEFINE_TYPE_ID(Type::Int64 , TypeId::kInt64);
+ASMJIT_DEFINE_TYPE_ID(Type::UInt64 , TypeId::kUInt64);
+ASMJIT_DEFINE_TYPE_ID(Type::IntPtr , TypeId::kIntPtr);
+ASMJIT_DEFINE_TYPE_ID(Type::UIntPtr, TypeId::kUIntPtr);
+ASMJIT_DEFINE_TYPE_ID(Type::Float32, TypeId::kFloat32);
+ASMJIT_DEFINE_TYPE_ID(Type::Float64, TypeId::kFloat64);
//! \endcond
//! \}