mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-17 04:24:37 +03:00
[ABI] Moved vector operand from arm to a64 namespace
This is unfortunately API/ABI break, which cannot be deprecated instead of removed as arm::Vec would collide with a64::Vec if present. This is a preparetion for ARM32 tooling.
This commit is contained in:
@@ -16,6 +16,12 @@ ASMJIT_BEGIN_SUB_NAMESPACE(a64)
|
||||
class GpW;
|
||||
class GpX;
|
||||
|
||||
class VecB;
|
||||
class VecH;
|
||||
class VecS;
|
||||
class VecD;
|
||||
class VecV;
|
||||
|
||||
//! General purpose register (AArch64).
|
||||
class Gp : public Reg {
|
||||
public:
|
||||
@@ -25,9 +31,9 @@ public:
|
||||
enum Id : uint32_t {
|
||||
//! Register that depends on OS, could be used as TLS offset.
|
||||
kIdOs = 18,
|
||||
//! Frame pointer.
|
||||
//! Frame pointer register id.
|
||||
kIdFp = 29,
|
||||
//! Link register.
|
||||
//! Link register id.
|
||||
kIdLr = 30,
|
||||
//! Stack register id.
|
||||
kIdSp = 31,
|
||||
@@ -63,18 +69,211 @@ ASMJIT_INLINE_NODEBUG GpW Gp::w() const noexcept { return GpW(id()); }
|
||||
ASMJIT_INLINE_NODEBUG GpX Gp::x() const noexcept { return GpX(id()); }
|
||||
#endif
|
||||
|
||||
//! Vector register (AArch64).
|
||||
class Vec : public BaseVec {
|
||||
public:
|
||||
ASMJIT_DEFINE_ABSTRACT_REG(Vec, BaseVec)
|
||||
|
||||
//! Element type (AArch64 only).
|
||||
enum ElementType : uint32_t {
|
||||
//! No element type specified.
|
||||
kElementTypeNone = 0,
|
||||
//! Byte elements (B8 or B16).
|
||||
kElementTypeB,
|
||||
//! Halfword elements (H4 or H8).
|
||||
kElementTypeH,
|
||||
//! Singleword elements (S2 or S4).
|
||||
kElementTypeS,
|
||||
//! Doubleword elements (D2).
|
||||
kElementTypeD,
|
||||
//! Byte elements grouped by 4 bytes (B4).
|
||||
//!
|
||||
//! \note This element-type is only used by few instructions.
|
||||
kElementTypeB4,
|
||||
//! Halfword elements grouped by 2 halfwords (H2).
|
||||
//!
|
||||
//! \note This element-type is only used by few instructions.
|
||||
kElementTypeH2,
|
||||
|
||||
//! Count of element types.
|
||||
kElementTypeCount
|
||||
};
|
||||
|
||||
//! \cond
|
||||
//! Shortcuts.
|
||||
enum SignatureReg : uint32_t {
|
||||
kSignatureElementB = kElementTypeB << kSignatureRegElementTypeShift,
|
||||
kSignatureElementH = kElementTypeH << kSignatureRegElementTypeShift,
|
||||
kSignatureElementS = kElementTypeS << kSignatureRegElementTypeShift,
|
||||
kSignatureElementD = kElementTypeD << kSignatureRegElementTypeShift,
|
||||
kSignatureElementB4 = kElementTypeB4 << kSignatureRegElementTypeShift,
|
||||
kSignatureElementH2 = kElementTypeH2 << kSignatureRegElementTypeShift
|
||||
};
|
||||
//! \endcond
|
||||
|
||||
//! Returns whether the register has associated an element type.
|
||||
ASMJIT_INLINE_NODEBUG constexpr bool hasElementType() const noexcept { return _signature.hasField<kSignatureRegElementTypeMask>(); }
|
||||
//! Returns whether the register has element index (it's an element index access).
|
||||
ASMJIT_INLINE_NODEBUG constexpr bool hasElementIndex() const noexcept { return _signature.hasField<kSignatureRegElementFlagMask>(); }
|
||||
//! Returns whether the register has element type or element index (or both).
|
||||
ASMJIT_INLINE_NODEBUG constexpr bool hasElementTypeOrIndex() const noexcept { return _signature.hasField<kSignatureRegElementTypeMask | kSignatureRegElementFlagMask>(); }
|
||||
|
||||
//! Returns element type of the register.
|
||||
ASMJIT_INLINE_NODEBUG constexpr uint32_t elementType() const noexcept { return _signature.getField<kSignatureRegElementTypeMask>(); }
|
||||
//! Sets element type of the register to `elementType`.
|
||||
ASMJIT_INLINE_NODEBUG void setElementType(uint32_t elementType) noexcept { _signature.setField<kSignatureRegElementTypeMask>(elementType); }
|
||||
//! Resets element type to none.
|
||||
ASMJIT_INLINE_NODEBUG void resetElementType() noexcept { _signature.setField<kSignatureRegElementTypeMask>(0); }
|
||||
|
||||
//! Returns element index of the register.
|
||||
ASMJIT_INLINE_NODEBUG constexpr uint32_t elementIndex() const noexcept { return _signature.getField<kSignatureRegElementIndexMask>(); }
|
||||
//! Sets element index of the register to `elementType`.
|
||||
ASMJIT_INLINE_NODEBUG void setElementIndex(uint32_t elementIndex) noexcept {
|
||||
_signature |= kSignatureRegElementFlagMask;
|
||||
_signature.setField<kSignatureRegElementIndexMask>(elementIndex);
|
||||
}
|
||||
//! Resets element index of the register.
|
||||
ASMJIT_INLINE_NODEBUG void resetElementIndex() noexcept {
|
||||
_signature &= ~(kSignatureRegElementFlagMask | kSignatureRegElementIndexMask);
|
||||
}
|
||||
|
||||
ASMJIT_INLINE_NODEBUG constexpr bool isVecB8() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecD>::kSignature | kSignatureElementB); }
|
||||
ASMJIT_INLINE_NODEBUG constexpr bool isVecH4() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecD>::kSignature | kSignatureElementH); }
|
||||
ASMJIT_INLINE_NODEBUG constexpr bool isVecS2() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecD>::kSignature | kSignatureElementS); }
|
||||
ASMJIT_INLINE_NODEBUG constexpr bool isVecD1() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecD>::kSignature); }
|
||||
|
||||
ASMJIT_INLINE_NODEBUG constexpr bool isVecB16() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementB); }
|
||||
ASMJIT_INLINE_NODEBUG constexpr bool isVecH8() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementH); }
|
||||
ASMJIT_INLINE_NODEBUG constexpr bool isVecS4() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementS); }
|
||||
ASMJIT_INLINE_NODEBUG constexpr bool isVecD2() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementD); }
|
||||
ASMJIT_INLINE_NODEBUG constexpr bool isVecB4x4() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementB4); }
|
||||
ASMJIT_INLINE_NODEBUG constexpr bool isVecH2x4() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementH2); }
|
||||
|
||||
//! Creates a cloned register with element access.
|
||||
ASMJIT_INLINE_NODEBUG Vec at(uint32_t elementIndex) const noexcept {
|
||||
return Vec((signature() & ~kSignatureRegElementIndexMask) | (elementIndex << kSignatureRegElementIndexShift) | kSignatureRegElementFlagMask, id());
|
||||
}
|
||||
|
||||
//! Cast this register to an 8-bit B register (AArch64 only).
|
||||
ASMJIT_INLINE_NODEBUG VecB b() const noexcept;
|
||||
//! Cast this register to a 16-bit H register (AArch64 only).
|
||||
ASMJIT_INLINE_NODEBUG VecH h() const noexcept;
|
||||
//! Cast this register to a 32-bit S register.
|
||||
ASMJIT_INLINE_NODEBUG VecS s() const noexcept;
|
||||
//! Cast this register to a 64-bit D register.
|
||||
ASMJIT_INLINE_NODEBUG VecD d() const noexcept;
|
||||
//! Cast this register to a 128-bit Q register.
|
||||
ASMJIT_INLINE_NODEBUG VecV q() const noexcept;
|
||||
//! Cast this register to a 128-bit V register.
|
||||
ASMJIT_INLINE_NODEBUG VecV v() const noexcept;
|
||||
|
||||
//! Cast this register to a 128-bit V.B[elementIndex] register.
|
||||
ASMJIT_INLINE_NODEBUG VecV b(uint32_t elementIndex) const noexcept;
|
||||
//! Cast this register to a 128-bit V.H[elementIndex] register.
|
||||
ASMJIT_INLINE_NODEBUG VecV h(uint32_t elementIndex) const noexcept;
|
||||
//! Cast this register to a 128-bit V.S[elementIndex] register.
|
||||
ASMJIT_INLINE_NODEBUG VecV s(uint32_t elementIndex) const noexcept;
|
||||
//! Cast this register to a 128-bit V.D[elementIndex] register.
|
||||
ASMJIT_INLINE_NODEBUG VecV d(uint32_t elementIndex) const noexcept;
|
||||
//! Cast this register to a 128-bit V.H2[elementIndex] register.
|
||||
ASMJIT_INLINE_NODEBUG VecV h2(uint32_t elementIndex) const noexcept;
|
||||
//! Cast this register to a 128-bit V.B4[elementIndex] register.
|
||||
ASMJIT_INLINE_NODEBUG VecV b4(uint32_t elementIndex) const noexcept;
|
||||
|
||||
//! Cast this register to V.8B.
|
||||
ASMJIT_INLINE_NODEBUG VecD b8() const noexcept;
|
||||
//! Cast this register to V.16B.
|
||||
ASMJIT_INLINE_NODEBUG VecV b16() const noexcept;
|
||||
//! Cast this register to V.2H.
|
||||
ASMJIT_INLINE_NODEBUG VecS h2() const noexcept;
|
||||
//! Cast this register to V.4H.
|
||||
ASMJIT_INLINE_NODEBUG VecD h4() const noexcept;
|
||||
//! Cast this register to V.8H.
|
||||
ASMJIT_INLINE_NODEBUG VecV h8() const noexcept;
|
||||
//! Cast this register to V.2S.
|
||||
ASMJIT_INLINE_NODEBUG VecD s2() const noexcept;
|
||||
//! Cast this register to V.4S.
|
||||
ASMJIT_INLINE_NODEBUG VecV s4() const noexcept;
|
||||
//! Cast this register to V.2D.
|
||||
ASMJIT_INLINE_NODEBUG VecV d2() const noexcept;
|
||||
|
||||
static ASMJIT_INLINE_NODEBUG constexpr OperandSignature _makeElementAccessSignature(uint32_t elementType, uint32_t elementIndex) noexcept {
|
||||
return OperandSignature{
|
||||
uint32_t(RegTraits<RegType::kARM_VecV>::kSignature) |
|
||||
uint32_t(kSignatureRegElementFlagMask) |
|
||||
uint32_t(elementType << kSignatureRegElementTypeShift) |
|
||||
uint32_t(elementIndex << kSignatureRegElementIndexShift)};
|
||||
}
|
||||
};
|
||||
|
||||
//! 8-bit view (S) of VFP/SIMD register.
|
||||
class VecB : public Vec {
|
||||
public:
|
||||
ASMJIT_DEFINE_FINAL_REG(VecB, Vec, RegTraits<RegType::kARM_VecB>)
|
||||
};
|
||||
|
||||
//! 16-bit view (S) of VFP/SIMD register.
|
||||
class VecH : public Vec {
|
||||
public:
|
||||
ASMJIT_DEFINE_FINAL_REG(VecH, Vec, RegTraits<RegType::kARM_VecH>)
|
||||
};
|
||||
|
||||
//! 32-bit view (S) of VFP/SIMD register.
|
||||
class VecS : public Vec {
|
||||
public:
|
||||
ASMJIT_DEFINE_FINAL_REG(VecS, Vec, RegTraits<RegType::kARM_VecS>)
|
||||
};
|
||||
|
||||
//! 64-bit view (D) of VFP/SIMD register.
|
||||
class VecD : public Vec {
|
||||
public:
|
||||
ASMJIT_DEFINE_FINAL_REG(VecD, Vec, RegTraits<RegType::kARM_VecD>)
|
||||
};
|
||||
|
||||
//! 128-bit vector register (Q or V).
|
||||
class VecV : public Vec {
|
||||
public:
|
||||
ASMJIT_DEFINE_FINAL_REG(VecV, Vec, RegTraits<RegType::kARM_VecV>)
|
||||
};
|
||||
|
||||
ASMJIT_INLINE_NODEBUG VecB Vec::b() const noexcept { return VecB(id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecH Vec::h() const noexcept { return VecH(id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecS Vec::s() const noexcept { return VecS(id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecD Vec::d() const noexcept { return VecD(id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecV Vec::q() const noexcept { return VecV(id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecV Vec::v() const noexcept { return VecV(id()); }
|
||||
|
||||
ASMJIT_INLINE_NODEBUG VecV Vec::b(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(kElementTypeB, elementIndex), id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecV Vec::h(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(kElementTypeH, elementIndex), id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecV Vec::s(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(kElementTypeS, elementIndex), id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecV Vec::d(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(kElementTypeD, elementIndex), id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecV Vec::h2(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(kElementTypeH2, elementIndex), id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecV Vec::b4(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(kElementTypeB4, elementIndex), id()); }
|
||||
|
||||
ASMJIT_INLINE_NODEBUG VecD Vec::b8() const noexcept { return VecD(OperandSignature{VecD::kSignature | kSignatureElementB}, id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecS Vec::h2() const noexcept { return VecS(OperandSignature{VecS::kSignature | kSignatureElementH}, id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecD Vec::h4() const noexcept { return VecD(OperandSignature{VecD::kSignature | kSignatureElementH}, id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecD Vec::s2() const noexcept { return VecD(OperandSignature{VecD::kSignature | kSignatureElementS}, id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecV Vec::b16() const noexcept { return VecV(OperandSignature{VecV::kSignature | kSignatureElementB}, id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecV Vec::h8() const noexcept { return VecV(OperandSignature{VecV::kSignature | kSignatureElementH}, id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecV Vec::s4() const noexcept { return VecV(OperandSignature{VecV::kSignature | kSignatureElementS}, id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecV Vec::d2() const noexcept { return VecV(OperandSignature{VecV::kSignature | kSignatureElementD}, id()); }
|
||||
|
||||
#ifndef _DOXYGEN
|
||||
namespace regs {
|
||||
#endif
|
||||
|
||||
//! Creates a 32-bit W register operand (ARM/AArch64).
|
||||
//! Creates a 32-bit W register operand.
|
||||
static ASMJIT_INLINE_NODEBUG constexpr GpW w(uint32_t id) noexcept { return GpW(id); }
|
||||
//! Creates a 64-bit X register operand (AArch64).
|
||||
//! Creates a 64-bit X register operand.
|
||||
static ASMJIT_INLINE_NODEBUG constexpr GpX x(uint32_t id) noexcept { return GpX(id); }
|
||||
|
||||
using ::asmjit::arm::regs::s;
|
||||
using ::asmjit::arm::regs::d;
|
||||
using ::asmjit::arm::regs::v;
|
||||
//! Creates a 32-bit S register operand.
|
||||
static ASMJIT_INLINE_NODEBUG constexpr VecS s(uint32_t id) noexcept { return VecS(id); }
|
||||
//! Creates a 64-bit D register operand.
|
||||
static ASMJIT_INLINE_NODEBUG constexpr VecD d(uint32_t id) noexcept { return VecD(id); }
|
||||
//! Creates a 1282-bit V register operand.
|
||||
static ASMJIT_INLINE_NODEBUG constexpr VecV v(uint32_t id) noexcept { return VecV(id); }
|
||||
|
||||
static constexpr GpW w0 = GpW(0);
|
||||
static constexpr GpW w1 = GpW(1);
|
||||
@@ -433,6 +632,9 @@ ASMJIT_END_SUB_NAMESPACE
|
||||
ASMJIT_BEGIN_NAMESPACE
|
||||
ASMJIT_DEFINE_TYPE_ID(a64::GpW, TypeId::kInt32);
|
||||
ASMJIT_DEFINE_TYPE_ID(a64::GpX, TypeId::kInt64);
|
||||
ASMJIT_DEFINE_TYPE_ID(a64::VecS, TypeId::kFloat32x1);
|
||||
ASMJIT_DEFINE_TYPE_ID(a64::VecD, TypeId::kFloat64x1);
|
||||
ASMJIT_DEFINE_TYPE_ID(a64::VecV, TypeId::kInt32x4);
|
||||
ASMJIT_END_NAMESPACE
|
||||
//! \endcond
|
||||
|
||||
|
||||
@@ -394,10 +394,10 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatOperand(
|
||||
if (op.isReg()) {
|
||||
const BaseReg& reg = op.as<BaseReg>();
|
||||
|
||||
uint32_t elementType = op.as<Vec>().elementType();
|
||||
uint32_t elementIndex = op.as<Vec>().elementIndex();
|
||||
uint32_t elementType = op._signature.getField<BaseVec::kSignatureRegElementTypeMask>();
|
||||
uint32_t elementIndex = op.as<BaseVec>().elementIndex();
|
||||
|
||||
if (!op.as<Vec>().hasElementIndex())
|
||||
if (!op.as<BaseVec>().hasElementIndex())
|
||||
elementIndex = 0xFFFFFFFFu;
|
||||
|
||||
return formatRegister(sb, flags, emitter, arch, reg.type(), reg.id(), elementType, elementIndex);
|
||||
|
||||
@@ -19,13 +19,6 @@ ASMJIT_BEGIN_SUB_NAMESPACE(arm)
|
||||
class Reg;
|
||||
class Mem;
|
||||
|
||||
class Vec;
|
||||
class VecB;
|
||||
class VecH;
|
||||
class VecS;
|
||||
class VecD;
|
||||
class VecV;
|
||||
|
||||
//! Register traits (AArch32/AArch64).
|
||||
//!
|
||||
//! Register traits contains information about a particular register type. It's used by asmjit to setup register
|
||||
@@ -44,7 +37,7 @@ ASMJIT_DEFINE_REG_TRAITS(RegType::kARM_VecB , RegGroup::kVec , 1 ,
|
||||
ASMJIT_DEFINE_REG_TRAITS(RegType::kARM_VecH , RegGroup::kVec , 2 , TypeId::kVoid ); // AArch64
|
||||
ASMJIT_DEFINE_REG_TRAITS(RegType::kARM_VecS , RegGroup::kVec , 4 , TypeId::kInt32x1 ); // AArch32 & AArch64
|
||||
ASMJIT_DEFINE_REG_TRAITS(RegType::kARM_VecD , RegGroup::kVec , 8 , TypeId::kInt32x2 ); // AArch32 & AArch64
|
||||
ASMJIT_DEFINE_REG_TRAITS(RegType::kARM_VecV , RegGroup::kVec , 16, TypeId::kInt32x4 ); // AArch32 & AArch64
|
||||
ASMJIT_DEFINE_REG_TRAITS(RegType::kARM_VecQ , RegGroup::kVec , 16, TypeId::kInt32x4 ); // AArch32 & AArch64
|
||||
ASMJIT_DEFINE_REG_TRAITS(RegType::kARM_PC , RegGroup::kPC , 8 , TypeId::kInt64 ); // AArch64
|
||||
//! \endcond
|
||||
|
||||
@@ -122,14 +115,8 @@ public:
|
||||
class BaseVec : public Reg {
|
||||
public:
|
||||
ASMJIT_DEFINE_ABSTRACT_REG(BaseVec, Reg)
|
||||
};
|
||||
|
||||
//! Vector register (ARM).
|
||||
class Vec : public BaseVec {
|
||||
public:
|
||||
ASMJIT_DEFINE_ABSTRACT_REG(Vec, BaseVec)
|
||||
|
||||
//! Additional signature bits used by arm::Vec.
|
||||
//! Additional signature bits used by a vector register.
|
||||
enum AdditionalBits : uint32_t {
|
||||
// Register element type (3 bits).
|
||||
// |........|........|.XXX....|........|
|
||||
@@ -147,57 +134,8 @@ public:
|
||||
kSignatureRegElementIndexMask = 0x0F << kSignatureRegElementIndexShift
|
||||
};
|
||||
|
||||
//! Element type (AArch64 only).
|
||||
enum ElementType : uint32_t {
|
||||
//! No element type specified.
|
||||
kElementTypeNone = 0,
|
||||
//! Byte elements (B8 or B16).
|
||||
kElementTypeB,
|
||||
//! Halfword elements (H4 or H8).
|
||||
kElementTypeH,
|
||||
//! Singleword elements (S2 or S4).
|
||||
kElementTypeS,
|
||||
//! Doubleword elements (D2).
|
||||
kElementTypeD,
|
||||
//! Byte elements grouped by 4 bytes (B4).
|
||||
//!
|
||||
//! \note This element-type is only used by few instructions.
|
||||
kElementTypeB4,
|
||||
//! Halfword elements grouped by 2 halfwords (H2).
|
||||
//!
|
||||
//! \note This element-type is only used by few instructions.
|
||||
kElementTypeH2,
|
||||
|
||||
//! Count of element types.
|
||||
kElementTypeCount
|
||||
};
|
||||
|
||||
//! \cond
|
||||
//! Shortcuts.
|
||||
enum SignatureReg : uint32_t {
|
||||
kSignatureElementB = kElementTypeB << kSignatureRegElementTypeShift,
|
||||
kSignatureElementH = kElementTypeH << kSignatureRegElementTypeShift,
|
||||
kSignatureElementS = kElementTypeS << kSignatureRegElementTypeShift,
|
||||
kSignatureElementD = kElementTypeD << kSignatureRegElementTypeShift,
|
||||
kSignatureElementB4 = kElementTypeB4 << kSignatureRegElementTypeShift,
|
||||
kSignatureElementH2 = kElementTypeH2 << kSignatureRegElementTypeShift
|
||||
};
|
||||
//! \endcond
|
||||
|
||||
//! Returns whether the register has associated an element type.
|
||||
ASMJIT_INLINE_NODEBUG constexpr bool hasElementType() const noexcept { return _signature.hasField<kSignatureRegElementTypeMask>(); }
|
||||
//! Returns whether the register has element index (it's an element index access).
|
||||
ASMJIT_INLINE_NODEBUG constexpr bool hasElementIndex() const noexcept { return _signature.hasField<kSignatureRegElementFlagMask>(); }
|
||||
//! Returns whether the register has element type or element index (or both).
|
||||
ASMJIT_INLINE_NODEBUG constexpr bool hasElementTypeOrIndex() const noexcept { return _signature.hasField<kSignatureRegElementTypeMask | kSignatureRegElementFlagMask>(); }
|
||||
|
||||
//! Returns element type of the register.
|
||||
ASMJIT_INLINE_NODEBUG constexpr uint32_t elementType() const noexcept { return _signature.getField<kSignatureRegElementTypeMask>(); }
|
||||
//! Sets element type of the register to `elementType`.
|
||||
ASMJIT_INLINE_NODEBUG void setElementType(uint32_t elementType) noexcept { _signature.setField<kSignatureRegElementTypeMask>(elementType); }
|
||||
//! Resets element type to none.
|
||||
ASMJIT_INLINE_NODEBUG void resetElementType() noexcept { _signature.setField<kSignatureRegElementTypeMask>(0); }
|
||||
|
||||
//! Returns element index of the register.
|
||||
ASMJIT_INLINE_NODEBUG constexpr uint32_t elementIndex() const noexcept { return _signature.getField<kSignatureRegElementIndexMask>(); }
|
||||
//! Sets element index of the register to `elementType`.
|
||||
@@ -209,128 +147,8 @@ public:
|
||||
ASMJIT_INLINE_NODEBUG void resetElementIndex() noexcept {
|
||||
_signature &= ~(kSignatureRegElementFlagMask | kSignatureRegElementIndexMask);
|
||||
}
|
||||
|
||||
ASMJIT_INLINE_NODEBUG constexpr bool isVecB8() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecD>::kSignature | kSignatureElementB); }
|
||||
ASMJIT_INLINE_NODEBUG constexpr bool isVecH4() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecD>::kSignature | kSignatureElementH); }
|
||||
ASMJIT_INLINE_NODEBUG constexpr bool isVecS2() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecD>::kSignature | kSignatureElementS); }
|
||||
ASMJIT_INLINE_NODEBUG constexpr bool isVecD1() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecD>::kSignature); }
|
||||
|
||||
ASMJIT_INLINE_NODEBUG constexpr bool isVecB16() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementB); }
|
||||
ASMJIT_INLINE_NODEBUG constexpr bool isVecH8() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementH); }
|
||||
ASMJIT_INLINE_NODEBUG constexpr bool isVecS4() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementS); }
|
||||
ASMJIT_INLINE_NODEBUG constexpr bool isVecD2() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementD); }
|
||||
ASMJIT_INLINE_NODEBUG constexpr bool isVecB4x4() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementB4); }
|
||||
ASMJIT_INLINE_NODEBUG constexpr bool isVecH2x4() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementH2); }
|
||||
|
||||
//! Creates a cloned register with element access.
|
||||
ASMJIT_INLINE_NODEBUG Vec at(uint32_t elementIndex) const noexcept {
|
||||
return Vec((signature() & ~kSignatureRegElementIndexMask) | (elementIndex << kSignatureRegElementIndexShift) | kSignatureRegElementFlagMask, id());
|
||||
}
|
||||
|
||||
//! Cast this register to an 8-bit B register (AArch64 only).
|
||||
ASMJIT_INLINE_NODEBUG VecB b() const noexcept;
|
||||
//! Cast this register to a 16-bit H register (AArch64 only).
|
||||
ASMJIT_INLINE_NODEBUG VecH h() const noexcept;
|
||||
//! Cast this register to a 32-bit S register.
|
||||
ASMJIT_INLINE_NODEBUG VecS s() const noexcept;
|
||||
//! Cast this register to a 64-bit D register.
|
||||
ASMJIT_INLINE_NODEBUG VecD d() const noexcept;
|
||||
//! Cast this register to a 128-bit Q register.
|
||||
ASMJIT_INLINE_NODEBUG VecV q() const noexcept;
|
||||
//! Cast this register to a 128-bit V register.
|
||||
ASMJIT_INLINE_NODEBUG VecV v() const noexcept;
|
||||
|
||||
//! Cast this register to a 128-bit V.B[elementIndex] register.
|
||||
ASMJIT_INLINE_NODEBUG VecV b(uint32_t elementIndex) const noexcept;
|
||||
//! Cast this register to a 128-bit V.H[elementIndex] register.
|
||||
ASMJIT_INLINE_NODEBUG VecV h(uint32_t elementIndex) const noexcept;
|
||||
//! Cast this register to a 128-bit V.S[elementIndex] register.
|
||||
ASMJIT_INLINE_NODEBUG VecV s(uint32_t elementIndex) const noexcept;
|
||||
//! Cast this register to a 128-bit V.D[elementIndex] register.
|
||||
ASMJIT_INLINE_NODEBUG VecV d(uint32_t elementIndex) const noexcept;
|
||||
//! Cast this register to a 128-bit V.H2[elementIndex] register.
|
||||
ASMJIT_INLINE_NODEBUG VecV h2(uint32_t elementIndex) const noexcept;
|
||||
//! Cast this register to a 128-bit V.B4[elementIndex] register.
|
||||
ASMJIT_INLINE_NODEBUG VecV b4(uint32_t elementIndex) const noexcept;
|
||||
|
||||
//! Cast this register to V.8B.
|
||||
ASMJIT_INLINE_NODEBUG VecD b8() const noexcept;
|
||||
//! Cast this register to V.16B.
|
||||
ASMJIT_INLINE_NODEBUG VecV b16() const noexcept;
|
||||
//! Cast this register to V.2H.
|
||||
ASMJIT_INLINE_NODEBUG VecS h2() const noexcept;
|
||||
//! Cast this register to V.4H.
|
||||
ASMJIT_INLINE_NODEBUG VecD h4() const noexcept;
|
||||
//! Cast this register to V.8H.
|
||||
ASMJIT_INLINE_NODEBUG VecV h8() const noexcept;
|
||||
//! Cast this register to V.2S.
|
||||
ASMJIT_INLINE_NODEBUG VecD s2() const noexcept;
|
||||
//! Cast this register to V.4S.
|
||||
ASMJIT_INLINE_NODEBUG VecV s4() const noexcept;
|
||||
//! Cast this register to V.2D.
|
||||
ASMJIT_INLINE_NODEBUG VecV d2() const noexcept;
|
||||
|
||||
static ASMJIT_INLINE_NODEBUG constexpr OperandSignature _makeElementAccessSignature(uint32_t elementType, uint32_t elementIndex) noexcept {
|
||||
return OperandSignature{
|
||||
uint32_t(RegTraits<RegType::kARM_VecV>::kSignature) |
|
||||
uint32_t(kSignatureRegElementFlagMask) |
|
||||
uint32_t(elementType << kSignatureRegElementTypeShift) |
|
||||
uint32_t(elementIndex << kSignatureRegElementIndexShift)};
|
||||
}
|
||||
};
|
||||
|
||||
//! 8-bit view (S) of VFP/SIMD register.
|
||||
class VecB : public Vec { ASMJIT_DEFINE_FINAL_REG(VecB, Vec, RegTraits<RegType::kARM_VecB>) };
|
||||
//! 16-bit view (S) of VFP/SIMD register.
|
||||
class VecH : public Vec { ASMJIT_DEFINE_FINAL_REG(VecH, Vec, RegTraits<RegType::kARM_VecH>) };
|
||||
//! 32-bit view (S) of VFP/SIMD register.
|
||||
class VecS : public Vec { ASMJIT_DEFINE_FINAL_REG(VecS, Vec, RegTraits<RegType::kARM_VecS>) };
|
||||
//! 64-bit view (D) of VFP/SIMD register.
|
||||
class VecD : public Vec { ASMJIT_DEFINE_FINAL_REG(VecD, Vec, RegTraits<RegType::kARM_VecD>) };
|
||||
//! 128-bit vector register (Q or V).
|
||||
class VecV : public Vec { ASMJIT_DEFINE_FINAL_REG(VecV, Vec, RegTraits<RegType::kARM_VecV>) };
|
||||
|
||||
ASMJIT_INLINE_NODEBUG VecB Vec::b() const noexcept { return VecB(id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecH Vec::h() const noexcept { return VecH(id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecS Vec::s() const noexcept { return VecS(id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecD Vec::d() const noexcept { return VecD(id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecV Vec::q() const noexcept { return VecV(id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecV Vec::v() const noexcept { return VecV(id()); }
|
||||
|
||||
ASMJIT_INLINE_NODEBUG VecV Vec::b(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(kElementTypeB, elementIndex), id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecV Vec::h(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(kElementTypeH, elementIndex), id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecV Vec::s(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(kElementTypeS, elementIndex), id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecV Vec::d(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(kElementTypeD, elementIndex), id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecV Vec::h2(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(kElementTypeH2, elementIndex), id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecV Vec::b4(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(kElementTypeB4, elementIndex), id()); }
|
||||
|
||||
ASMJIT_INLINE_NODEBUG VecD Vec::b8() const noexcept { return VecD(OperandSignature{VecD::kSignature | kSignatureElementB}, id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecS Vec::h2() const noexcept { return VecS(OperandSignature{VecS::kSignature | kSignatureElementH}, id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecD Vec::h4() const noexcept { return VecD(OperandSignature{VecD::kSignature | kSignatureElementH}, id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecD Vec::s2() const noexcept { return VecD(OperandSignature{VecD::kSignature | kSignatureElementS}, id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecV Vec::b16() const noexcept { return VecV(OperandSignature{VecV::kSignature | kSignatureElementB}, id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecV Vec::h8() const noexcept { return VecV(OperandSignature{VecV::kSignature | kSignatureElementH}, id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecV Vec::s4() const noexcept { return VecV(OperandSignature{VecV::kSignature | kSignatureElementS}, id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecV Vec::d2() const noexcept { return VecV(OperandSignature{VecV::kSignature | kSignatureElementD}, id()); }
|
||||
|
||||
#ifndef _DOXYGEN
|
||||
namespace regs {
|
||||
#endif
|
||||
|
||||
//! Creates a 32-bit S register operand (ARM/AArch64).
|
||||
static ASMJIT_INLINE_NODEBUG constexpr VecS s(uint32_t id) noexcept { return VecS(id); }
|
||||
//! Creates a 64-bit D register operand (ARM/AArch64).
|
||||
static ASMJIT_INLINE_NODEBUG constexpr VecD d(uint32_t id) noexcept { return VecD(id); }
|
||||
//! Creates a 1282-bit V register operand (ARM/AArch64).
|
||||
static ASMJIT_INLINE_NODEBUG constexpr VecV v(uint32_t id) noexcept { return VecV(id); }
|
||||
|
||||
#ifndef _DOXYGEN
|
||||
} // {regs}
|
||||
|
||||
// Make `arm::regs` accessible through `arm` namespace as well.
|
||||
using namespace regs;
|
||||
#endif
|
||||
|
||||
//! Memory operand (ARM).
|
||||
class Mem : public BaseMem {
|
||||
public:
|
||||
@@ -564,12 +382,4 @@ static ASMJIT_INLINE_NODEBUG constexpr Mem ptr(uint64_t base) noexcept { return
|
||||
|
||||
ASMJIT_END_SUB_NAMESPACE
|
||||
|
||||
//! \cond INTERNAL
|
||||
ASMJIT_BEGIN_NAMESPACE
|
||||
ASMJIT_DEFINE_TYPE_ID(arm::VecS, TypeId::kFloat32x1);
|
||||
ASMJIT_DEFINE_TYPE_ID(arm::VecD, TypeId::kFloat64x1);
|
||||
ASMJIT_DEFINE_TYPE_ID(arm::VecV, TypeId::kInt32x4);
|
||||
ASMJIT_END_NAMESPACE
|
||||
//! \endcond
|
||||
|
||||
#endif // ASMJIT_ARM_ARMOPERAND_H_INCLUDED
|
||||
|
||||
@@ -239,6 +239,22 @@ namespace asmjit {
|
||||
//! because some compilers would warn about that. If your project compiles fine with `ASMJIT_NO_DEPRECATED`
|
||||
//! it's not using anything, which was deprecated.
|
||||
//!
|
||||
//! ### Changes committed at 2023-12-26
|
||||
//!
|
||||
//! Core changes:
|
||||
//!
|
||||
//! - Reworked InstNode and InstExNode to be friendlier to static analysis and to not cause undefined behavior.
|
||||
//! InstNode has no operands visually embedded within the struct so there is no _opArray (which was internal).
|
||||
//! This means that sizeof(InstNode) changed, but since it's allocated by AsmJit this should be fine. Moreover,
|
||||
//! there is no longer InstExNode as that was more a hack, instead there is now InstNodeWithOperands, which is
|
||||
//! a template and specifies the number of operands embedded (InstNode accesses these). All nodes that inherited
|
||||
//! InstExNode now just inherit InstNodeWithOperands<InstNode::kBaseOpCapacity>, which would provide the same
|
||||
//! number of nodes as InstNode.
|
||||
//!
|
||||
//! - Moved GP and Vec registers from asmjit::arm namespace to asmjit::a64 namespace. At this time there was
|
||||
//! no prior deprecation as having arm::Vec would collide with a64::Vec as arm namespace is used within a64
|
||||
//! namespace. Just change `arm::Gp` to `a64::Gp` and `arm::Vec` to `a64::Vec`.
|
||||
//!
|
||||
//! ### Changes committed at 2023-09-10
|
||||
//!
|
||||
//! Core changes:
|
||||
|
||||
@@ -152,7 +152,9 @@ enum class RegType : uint8_t {
|
||||
kARM_VecS = kVec32,
|
||||
//! 64-bit view of VFP/ASIMD register (D).
|
||||
kARM_VecD = kVec64,
|
||||
//! 128-bit view of VFP/ASIMD register (Q|V).
|
||||
//! 128-bit view of VFP/ASIMD register (Q).
|
||||
kARM_VecQ = kVec128,
|
||||
//! 128-bit view of VFP/ASIMD register (V).
|
||||
kARM_VecV = kVec128,
|
||||
|
||||
//! Maximum value of `RegType`.
|
||||
|
||||
@@ -211,9 +211,9 @@ public:
|
||||
funcNode->setArg(1, src1);
|
||||
funcNode->setArg(2, src2);
|
||||
|
||||
arm::Vec v1 = cc.newVecQ("vec1");
|
||||
arm::Vec v2 = cc.newVecQ("vec2");
|
||||
arm::Vec v3 = cc.newVecQ("vec3");
|
||||
a64::Vec v1 = cc.newVecQ("vec1");
|
||||
a64::Vec v2 = cc.newVecQ("vec2");
|
||||
a64::Vec v3 = cc.newVecQ("vec3");
|
||||
|
||||
cc.ldr(v2, a64::ptr(src1));
|
||||
cc.ldr(v3, a64::ptr(src2));
|
||||
@@ -465,9 +465,9 @@ public:
|
||||
virtual void compile(a64::Compiler& cc) {
|
||||
FuncNode* funcNode = cc.addFunc(FuncSignatureT<double, double, double>());
|
||||
|
||||
arm::Vec x = cc.newVecD("x");
|
||||
arm::Vec y = cc.newVecD("y");
|
||||
arm::Vec r = cc.newVecD("r");
|
||||
a64::Vec x = cc.newVecD("x");
|
||||
a64::Vec y = cc.newVecD("y");
|
||||
a64::Vec r = cc.newVecD("r");
|
||||
a64::Gp fn = cc.newUIntPtr("fn");
|
||||
|
||||
funcNode->setArg(0, x);
|
||||
@@ -517,9 +517,9 @@ public:
|
||||
virtual void compile(a64::Compiler& cc) {
|
||||
FuncNode* funcNode = cc.addFunc(FuncSignatureT<double, double, double>());
|
||||
|
||||
arm::Vec x = cc.newVecD("x");
|
||||
arm::Vec y = cc.newVecD("y");
|
||||
arm::Vec r = cc.newVecD("r");
|
||||
a64::Vec x = cc.newVecD("x");
|
||||
a64::Vec y = cc.newVecD("y");
|
||||
a64::Vec r = cc.newVecD("r");
|
||||
a64::Gp fn = cc.newUIntPtr("fn");
|
||||
|
||||
funcNode->setArg(0, x);
|
||||
@@ -582,8 +582,8 @@ public:
|
||||
virtual void compile(a64::Compiler& cc) {
|
||||
FuncNode* funcNode = cc.addFunc(FuncSignatureT<float, float, float, uint32_t>());
|
||||
|
||||
arm::Vec a = cc.newVecS("a");
|
||||
arm::Vec b = cc.newVecS("b");
|
||||
a64::Vec a = cc.newVecS("a");
|
||||
a64::Vec b = cc.newVecS("b");
|
||||
a64::Gp op = cc.newUInt32("op");
|
||||
|
||||
a64::Gp target = cc.newIntPtr("target");
|
||||
|
||||
Reference in New Issue
Block a user