mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-17 04:24:37 +03:00
[ABI] Renamed a64::Vec::ElementType to a64::VecElementType
This commit is contained in:
@@ -47,7 +47,6 @@ TODO
|
||||
|
||||
* [ ] Ports:
|
||||
* [ ] 32-bit ARM/Thumb port.
|
||||
* [ ] 64-bit ARM (AArch64) port.
|
||||
* [ ] RISC-V port.
|
||||
|
||||
Support
|
||||
|
||||
@@ -21,12 +21,16 @@
|
||||
|
||||
ASMJIT_BEGIN_SUB_NAMESPACE(a64)
|
||||
|
||||
// a64::Assembler - Utils
|
||||
// ======================
|
||||
|
||||
static ASMJIT_FORCE_INLINE constexpr uint32_t diff(RegType a, RegType b) noexcept { return uint32_t(a) - uint32_t(b); }
|
||||
static ASMJIT_FORCE_INLINE constexpr uint32_t diff(VecElementType elementType, VecElementType baseType) noexcept { return uint32_t(elementType) - uint32_t(baseType); }
|
||||
|
||||
// a64::Assembler - Cond
|
||||
// =====================
|
||||
|
||||
static inline uint32_t condCodeToOpcodeCond(uint32_t cond) noexcept {
|
||||
return (uint32_t(cond) - 2u) & 0xFu;
|
||||
}
|
||||
static inline uint32_t condCodeToOpcodeCond(uint32_t cond) noexcept { return (uint32_t(cond) - 2u) & 0xFu; }
|
||||
|
||||
// a64::Assembler - Bits
|
||||
// =====================
|
||||
@@ -49,10 +53,6 @@ static constexpr uint32_t kWX = InstDB::kWX;
|
||||
static const uint8_t armShiftOpToLdStOptMap[] = { ASMJIT_LOOKUP_TABLE_16(VALUE, 0) };
|
||||
#undef VALUE
|
||||
|
||||
static inline constexpr uint32_t diff(RegType a, RegType b) noexcept {
|
||||
return uint32_t(a) - uint32_t(b);
|
||||
}
|
||||
|
||||
// asmjit::a64::Assembler - SizeOp
|
||||
// ===============================
|
||||
|
||||
@@ -118,25 +118,25 @@ struct SizeOpTable {
|
||||
};
|
||||
|
||||
#define VALUE_BIN(x) { \
|
||||
x == (((uint32_t(RegType::kARM_VecD) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeNone)) ? SizeOp::k00 : \
|
||||
x == (((uint32_t(RegType::kARM_VecV) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeNone)) ? SizeOp::k00Q : \
|
||||
x == (((uint32_t(RegType::kARM_VecD) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeB )) ? SizeOp::k00 : \
|
||||
x == (((uint32_t(RegType::kARM_VecV) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeB )) ? SizeOp::k00Q : SizeOp::kInvalid \
|
||||
x == (((uint32_t(RegType::kARM_VecD) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kNone)) ? SizeOp::k00 : \
|
||||
x == (((uint32_t(RegType::kARM_VecV) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kNone)) ? SizeOp::k00Q : \
|
||||
x == (((uint32_t(RegType::kARM_VecD) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kB )) ? SizeOp::k00 : \
|
||||
x == (((uint32_t(RegType::kARM_VecV) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kB )) ? SizeOp::k00Q : SizeOp::kInvalid \
|
||||
}
|
||||
|
||||
#define VALUE_ANY(x) { \
|
||||
x == (((uint32_t(RegType::kARM_VecB) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeNone)) ? SizeOp::k00S : \
|
||||
x == (((uint32_t(RegType::kARM_VecH) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeNone)) ? SizeOp::k01S : \
|
||||
x == (((uint32_t(RegType::kARM_VecS) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeNone)) ? SizeOp::k10S : \
|
||||
x == (((uint32_t(RegType::kARM_VecD) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeNone)) ? SizeOp::k11S : \
|
||||
x == (((uint32_t(RegType::kARM_VecD) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeB )) ? SizeOp::k00 : \
|
||||
x == (((uint32_t(RegType::kARM_VecV) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeB )) ? SizeOp::k00Q : \
|
||||
x == (((uint32_t(RegType::kARM_VecD) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeH )) ? SizeOp::k01 : \
|
||||
x == (((uint32_t(RegType::kARM_VecV) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeH )) ? SizeOp::k01Q : \
|
||||
x == (((uint32_t(RegType::kARM_VecD) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeS )) ? SizeOp::k10 : \
|
||||
x == (((uint32_t(RegType::kARM_VecV) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeS )) ? SizeOp::k10Q : \
|
||||
x == (((uint32_t(RegType::kARM_VecD) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeD )) ? SizeOp::k11S : \
|
||||
x == (((uint32_t(RegType::kARM_VecV) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeD )) ? SizeOp::k11Q : SizeOp::kInvalid \
|
||||
x == (((uint32_t(RegType::kARM_VecB) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kNone)) ? SizeOp::k00S : \
|
||||
x == (((uint32_t(RegType::kARM_VecH) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kNone)) ? SizeOp::k01S : \
|
||||
x == (((uint32_t(RegType::kARM_VecS) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kNone)) ? SizeOp::k10S : \
|
||||
x == (((uint32_t(RegType::kARM_VecD) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kNone)) ? SizeOp::k11S : \
|
||||
x == (((uint32_t(RegType::kARM_VecD) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kB )) ? SizeOp::k00 : \
|
||||
x == (((uint32_t(RegType::kARM_VecV) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kB )) ? SizeOp::k00Q : \
|
||||
x == (((uint32_t(RegType::kARM_VecD) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kH )) ? SizeOp::k01 : \
|
||||
x == (((uint32_t(RegType::kARM_VecV) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kH )) ? SizeOp::k01Q : \
|
||||
x == (((uint32_t(RegType::kARM_VecD) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kS )) ? SizeOp::k10 : \
|
||||
x == (((uint32_t(RegType::kARM_VecV) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kS )) ? SizeOp::k10Q : \
|
||||
x == (((uint32_t(RegType::kARM_VecD) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kD )) ? SizeOp::k11S : \
|
||||
x == (((uint32_t(RegType::kARM_VecV) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kD )) ? SizeOp::k11Q : SizeOp::kInvalid \
|
||||
}
|
||||
|
||||
static const SizeOpTable sizeOpTable[SizeOpTable::kCount] = {
|
||||
@@ -254,16 +254,16 @@ static const Operand_& significantSimdOp(const Operand_& o0, const Operand_& o1,
|
||||
return !(instFlags & InstDB::kInstFlagLong) ? o0 : o1;
|
||||
}
|
||||
|
||||
static inline SizeOp armElementTypeToSizeOp(uint32_t vecOpType, RegType regType, uint32_t elementType) noexcept {
|
||||
static inline SizeOp armElementTypeToSizeOp(uint32_t vecOpType, RegType regType, VecElementType elementType) noexcept {
|
||||
// Instruction data or Assembler is wrong if this triggers an assertion failure.
|
||||
ASMJIT_ASSERT(vecOpType < InstDB::kVO_Count);
|
||||
// ElementType uses 3 bits in the operand signature, it should never overflow.
|
||||
ASMJIT_ASSERT(elementType <= 0x7u);
|
||||
ASMJIT_ASSERT(uint32_t(elementType) <= 0x7u);
|
||||
|
||||
const SizeOpMap& map = sizeOpMap[vecOpType];
|
||||
const SizeOpTable& table = sizeOpTable[map.tableId];
|
||||
|
||||
size_t index = (Support::min<uint32_t>(diff(regType, RegType::kARM_VecB), diff(RegType::kARM_VecV, RegType::kARM_VecB) + 1) << 3) | elementType;
|
||||
size_t index = (Support::min<uint32_t>(diff(regType, RegType::kARM_VecB), diff(RegType::kARM_VecV, RegType::kARM_VecB) + 1) << 3) | uint32_t(elementType);
|
||||
SizeOp op = table.array[index];
|
||||
SizeOp modifiedOp { uint8_t(op.value & map.sizeOpMask) };
|
||||
|
||||
@@ -537,7 +537,7 @@ static inline bool pickFpOpcode(const Vec& reg, uint32_t sOp, uint32_t sHf, uint
|
||||
else {
|
||||
// Vector operation [HSD].
|
||||
uint32_t q = diff(reg.type(), RegType::kARM_VecD);
|
||||
uint32_t sz = reg.elementType() - Vec::kElementTypeH;
|
||||
uint32_t sz = diff(reg.elementType(), VecElementType::kH);
|
||||
|
||||
if (q > 1u || sz > 2u || !Support::bitTest(szBits[vHf].sizeMask, sz))
|
||||
return false;
|
||||
@@ -2768,7 +2768,7 @@ Case_BaseLdurStur:
|
||||
// hD, vS.{4|8}h (16-bit)
|
||||
// sD, vS.4s (32-bit)
|
||||
uint32_t sz = diff(o0.as<Reg>().type(), RegType::kARM_VecH);
|
||||
uint32_t elementSz = o1.as<Vec>().elementType() - Vec::kElementTypeH;
|
||||
uint32_t elementSz = diff(o1.as<Vec>().elementType(), VecElementType::kH);
|
||||
|
||||
// Size greater than 1 means 64-bit elements, not supported.
|
||||
if ((sz | elementSz) > 1 || sz != elementSz)
|
||||
@@ -2890,7 +2890,7 @@ Case_BaseLdurStur:
|
||||
if (q > 1)
|
||||
goto InvalidInstruction;
|
||||
|
||||
uint32_t sz = o0.as<Vec>().elementType() - Vec::kElementTypeB;
|
||||
uint32_t sz = diff(o0.as<Vec>().elementType(), VecElementType::kB);
|
||||
if (sz == 0 || sz > 3)
|
||||
goto InvalidInstruction;
|
||||
|
||||
@@ -2982,7 +2982,7 @@ Case_BaseLdurStur:
|
||||
if (q > 1)
|
||||
goto InvalidInstruction;
|
||||
|
||||
uint32_t sz = o0.as<Vec>().elementType() - Vec::kElementTypeB;
|
||||
uint32_t sz = diff(o0.as<Vec>().elementType(), VecElementType::kB);
|
||||
if (sz == 0 || sz > 3)
|
||||
goto InvalidInstruction;
|
||||
|
||||
@@ -3164,11 +3164,11 @@ Case_BaseLdurStur:
|
||||
if (uint32_t(opcode.hasQ()) != q)
|
||||
goto InvalidInstruction;
|
||||
|
||||
if (rL.isVecS4() && rN.elementType() == Vec::kElementTypeH && !opData.isCvtxn()) {
|
||||
if (rL.isVecS4() && rN.elementType() == VecElementType::kH && !opData.isCvtxn()) {
|
||||
goto EmitOp_Rd0_Rn5;
|
||||
}
|
||||
|
||||
if (rL.isVecD2() && rN.elementType() == Vec::kElementTypeS) {
|
||||
if (rL.isVecD2() && rN.elementType() == VecElementType::kS) {
|
||||
opcode |= B(22);
|
||||
goto EmitOp_Rd0_Rn5;
|
||||
}
|
||||
@@ -3279,8 +3279,8 @@ Case_BaseLdurStur:
|
||||
}
|
||||
|
||||
if (uint32_t(o0.as<Reg>().type()) != uint32_t(o1.as<Reg>().type()) + qIsOptional ||
|
||||
o0.as<Vec>().elementType() != opData.tA ||
|
||||
o1.as<Vec>().elementType() != opData.tB)
|
||||
uint32_t(o0.as<Vec>().elementType()) != opData.tA ||
|
||||
uint32_t(o1.as<Vec>().elementType()) != opData.tB)
|
||||
goto InvalidInstruction;
|
||||
|
||||
if (!o2.as<Vec>().hasElementIndex()) {
|
||||
@@ -3292,7 +3292,7 @@ Case_BaseLdurStur:
|
||||
goto EmitOp_Rd0_Rn5_Rm16;
|
||||
}
|
||||
else {
|
||||
if (o2.as<Vec>().elementType() != opData.tElement)
|
||||
if (uint32_t(o2.as<Vec>().elementType()) != opData.tElement)
|
||||
goto InvalidInstruction;
|
||||
|
||||
if (o2.as<Reg>().id() > 15)
|
||||
@@ -3442,7 +3442,7 @@ Case_BaseLdurStur:
|
||||
}
|
||||
else {
|
||||
uint32_t q = diff(o0.as<Vec>().type(), RegType::kARM_VecD);
|
||||
uint32_t sz = o0.as<Vec>().elementType() - Vec::kElementTypeH;
|
||||
uint32_t sz = diff(o0.as<Vec>().elementType(), VecElementType::kH);
|
||||
|
||||
if (q > 1 || sz > 2)
|
||||
goto InvalidInstruction;
|
||||
@@ -3496,7 +3496,7 @@ Case_BaseLdurStur:
|
||||
if (q > 1)
|
||||
goto InvalidInstruction;
|
||||
|
||||
uint32_t sz = o0.as<Vec>().elementType() - Vec::kElementTypeH;
|
||||
uint32_t sz = diff(o0.as<Vec>().elementType(), VecElementType::kH);
|
||||
if (sz > 2)
|
||||
goto InvalidInstruction;
|
||||
|
||||
@@ -3520,7 +3520,7 @@ Case_BaseLdurStur:
|
||||
if (isign4 == ENC_OPS2(Reg, Reg)) {
|
||||
// The first destination operand is scalar, which matches element-type of source vectors.
|
||||
uint32_t L = (instFlags & InstDB::kInstFlagLong) != 0;
|
||||
if (diff(o0.as<Vec>().type(), RegType::kARM_VecB) != o1.as<Vec>().elementType() - Vec::kElementTypeB + L)
|
||||
if (diff(o0.as<Vec>().type(), RegType::kARM_VecB) != diff(o1.as<Vec>().elementType(), VecElementType::kB) + L)
|
||||
goto InvalidInstruction;
|
||||
|
||||
SizeOp sizeOp = armElementTypeToSizeOp(opData.vecOpType, o1.as<Reg>().type(), o1.as<Vec>().elementType());
|
||||
@@ -3620,7 +3620,7 @@ Case_BaseLdurStur:
|
||||
if (!sizeOp.isValid())
|
||||
goto InvalidInstruction;
|
||||
|
||||
if (!checkSignature(o0, o1) || !o0.as<Reg>().isVecV() || o0.as<Vec>().elementType() != o2.as<Vec>().elementType() + 1)
|
||||
if (!checkSignature(o0, o1) || !o0.as<Reg>().isVecV() || uint32_t(o0.as<Vec>().elementType()) != uint32_t(o2.as<Vec>().elementType()) + 1u)
|
||||
goto InvalidInstruction;
|
||||
|
||||
opcode.reset(opData.opcode());
|
||||
@@ -3905,9 +3905,9 @@ Case_BaseLdurStur:
|
||||
if (o0.as<Reg>().type() != o1.as<Reg>().type() || o1.as<Reg>().type() != o2.as<Reg>().type())
|
||||
goto InvalidInstruction;
|
||||
|
||||
if (o0.as<Vec>().elementType() != opData.tA ||
|
||||
o1.as<Vec>().elementType() != opData.tB ||
|
||||
o2.as<Vec>().elementType() != opData.tB)
|
||||
if (uint32_t(o0.as<Vec>().elementType()) != opData.tA ||
|
||||
uint32_t(o1.as<Vec>().elementType()) != opData.tB ||
|
||||
uint32_t(o2.as<Vec>().elementType()) != opData.tB)
|
||||
goto InvalidInstruction;
|
||||
|
||||
opcode.reset(uint32_t(opData.vectorOp) << 10);
|
||||
@@ -3921,9 +3921,9 @@ Case_BaseLdurStur:
|
||||
if (o0.as<Reg>().type() != o1.as<Reg>().type() || !o2.as<Reg>().isVecV())
|
||||
goto InvalidInstruction;
|
||||
|
||||
if (o0.as<Vec>().elementType() != opData.tA ||
|
||||
o1.as<Vec>().elementType() != opData.tB ||
|
||||
o2.as<Vec>().elementType() != opData.tElement)
|
||||
if (uint32_t(o0.as<Vec>().elementType()) != opData.tA ||
|
||||
uint32_t(o1.as<Vec>().elementType()) != opData.tB ||
|
||||
uint32_t(o2.as<Vec>().elementType()) != opData.tElement)
|
||||
goto InvalidInstruction;
|
||||
|
||||
uint32_t elementIndex = o2.as<Vec>().elementIndex();
|
||||
@@ -3949,13 +3949,13 @@ Case_BaseLdurStur:
|
||||
case InstDB::kEncodingSimdDup: SimdDup: {
|
||||
if (isign4 == ENC_OPS2(Reg, Reg)) {
|
||||
// Truth table of valid encodings of `Q:1|ElementType:3`
|
||||
uint32_t kValidEncodings = B(Vec::kElementTypeB + 0) |
|
||||
B(Vec::kElementTypeH + 0) |
|
||||
B(Vec::kElementTypeS + 0) |
|
||||
B(Vec::kElementTypeB + 8) |
|
||||
B(Vec::kElementTypeH + 8) |
|
||||
B(Vec::kElementTypeS + 8) |
|
||||
B(Vec::kElementTypeD + 8) ;
|
||||
uint32_t kValidEncodings = B(uint32_t(VecElementType::kB) + 0) |
|
||||
B(uint32_t(VecElementType::kH) + 0) |
|
||||
B(uint32_t(VecElementType::kS) + 0) |
|
||||
B(uint32_t(VecElementType::kB) + 8) |
|
||||
B(uint32_t(VecElementType::kH) + 8) |
|
||||
B(uint32_t(VecElementType::kS) + 8) |
|
||||
B(uint32_t(VecElementType::kD) + 8) ;
|
||||
|
||||
uint32_t q = diff(o0.as<Reg>().type(), RegType::kARM_VecD);
|
||||
|
||||
@@ -3964,7 +3964,7 @@ Case_BaseLdurStur:
|
||||
//
|
||||
// NOTE: This is only scalar for `dup d, x` case, otherwise the value
|
||||
// would be duplicated across all vector elements (1, 2, 4, 8, or 16).
|
||||
uint32_t elementType = o0.as<Vec>().elementType();
|
||||
uint32_t elementType = uint32_t(o0.as<Vec>().elementType());
|
||||
if (q > 1 || !Support::bitTest(kValidEncodings, (q << 3) | elementType))
|
||||
goto InvalidInstruction;
|
||||
|
||||
@@ -3985,7 +3985,7 @@ Case_BaseLdurStur:
|
||||
// DUP - Vec (scalar) <- Vec[N].
|
||||
uint32_t lsbIndex = diff(o0.as<Reg>().type(), RegType::kARM_VecB);
|
||||
|
||||
if (lsbIndex != o1.as<Vec>().elementType() - Vec::kElementTypeB || lsbIndex > 3)
|
||||
if (lsbIndex != diff(o1.as<Vec>().elementType(), VecElementType::kB) || lsbIndex > 3)
|
||||
goto InvalidInstruction;
|
||||
|
||||
uint32_t imm5 = ((dstIndex << 1) | 1u) << lsbIndex;
|
||||
@@ -3998,7 +3998,7 @@ Case_BaseLdurStur:
|
||||
}
|
||||
else {
|
||||
// DUP - Vec (all) <- Vec[N].
|
||||
uint32_t elementType = o0.as<Vec>().elementType();
|
||||
uint32_t elementType = uint32_t(o0.as<Vec>().elementType());
|
||||
if (q > 1 || !Support::bitTest(kValidEncodings, (q << 3) | elementType))
|
||||
goto InvalidInstruction;
|
||||
|
||||
@@ -4023,7 +4023,7 @@ Case_BaseLdurStur:
|
||||
if (!o0.as<Vec>().hasElementIndex())
|
||||
goto InvalidInstruction;
|
||||
|
||||
uint32_t elementType = o0.as<Vec>().elementType();
|
||||
uint32_t elementType = uint32_t(o0.as<Vec>().elementType());
|
||||
uint32_t dstIndex = o0.as<Vec>().elementIndex();
|
||||
uint32_t lsbIndex = elementType - 1u;
|
||||
|
||||
@@ -4735,7 +4735,7 @@ Case_SimdLdurStur:
|
||||
uint32_t q = 0;
|
||||
uint32_t rm = 0;
|
||||
uint32_t rn = m.baseId();
|
||||
uint32_t sz = v.elementType() - Vec::kElementTypeB;
|
||||
uint32_t sz = diff(v.elementType(), VecElementType::kB);
|
||||
uint32_t opcSsize = sz;
|
||||
uint32_t offsetPossibility = 0;
|
||||
|
||||
|
||||
@@ -31,14 +31,6 @@ public:
|
||||
|
||||
//! \}
|
||||
|
||||
//! \name Accessors
|
||||
//! \{
|
||||
|
||||
//! Gets whether the current ARM mode is THUMB (alternative to 32-bit ARM encoding).
|
||||
ASMJIT_INLINE_NODEBUG bool isInThumbMode() const noexcept { return _environment.isArchThumb(); }
|
||||
|
||||
//! \}
|
||||
|
||||
//! \name Emit
|
||||
//! \{
|
||||
|
||||
|
||||
@@ -174,10 +174,10 @@ Error queryRWInfo(const BaseInst& inst, const Operand_* operands, size_t opCount
|
||||
if (srcOp.isReg()) {
|
||||
if (srcOp.as<Vec>().hasElementIndex()) {
|
||||
// Only part of the vector is accessed if element index [] is used.
|
||||
uint32_t elementType = srcOp.as<Vec>().elementType();
|
||||
VecElementType elementType = srcOp.as<Vec>().elementType();
|
||||
uint32_t elementIndex = srcOp.as<Vec>().elementIndex();
|
||||
|
||||
uint32_t elementSize = elementTypeSize[elementType];
|
||||
uint32_t elementSize = elementTypeSize[size_t(elementType)];
|
||||
uint64_t accessMask = uint64_t(Support::lsbMask<uint32_t>(elementSize)) << (elementIndex * elementSize);
|
||||
|
||||
op._readByteMask &= accessMask;
|
||||
|
||||
@@ -59,14 +59,14 @@ enum RWInfoType : uint32_t {
|
||||
// a64::InstDB - ElementType
|
||||
// =========================
|
||||
|
||||
enum ElementType : uint8_t {
|
||||
kET_None = Vec::kElementTypeNone,
|
||||
kET_B = Vec::kElementTypeB,
|
||||
kET_H = Vec::kElementTypeH,
|
||||
kET_S = Vec::kElementTypeS,
|
||||
kET_D = Vec::kElementTypeD,
|
||||
kET_2H = Vec::kElementTypeH2,
|
||||
kET_4B = Vec::kElementTypeB4
|
||||
enum InstElementType : uint8_t {
|
||||
kET_None = uint8_t(VecElementType::kNone),
|
||||
kET_B = uint8_t(VecElementType::kB),
|
||||
kET_H = uint8_t(VecElementType::kH),
|
||||
kET_S = uint8_t(VecElementType::kS),
|
||||
kET_D = uint8_t(VecElementType::kD),
|
||||
kET_2H = uint8_t(VecElementType::kH2),
|
||||
kET_4B = uint8_t(VecElementType::kB4)
|
||||
};
|
||||
|
||||
// a64::InstDB - GpType
|
||||
|
||||
@@ -56,7 +56,7 @@ UNIT(a64_operand) {
|
||||
EXPECT_EQ(vd_1.group(), RegGroup::kVec);
|
||||
EXPECT_EQ(vd_1.id(), 15u);
|
||||
EXPECT_TRUE(vd_1.isVecD2());
|
||||
EXPECT_EQ(vd_1.elementType(), Vec::kElementTypeD);
|
||||
EXPECT_EQ(vd_1.elementType(), VecElementType::kD);
|
||||
EXPECT_TRUE(vd_1.hasElementIndex());
|
||||
EXPECT_EQ(vd_1.elementIndex(), 1u);
|
||||
|
||||
@@ -65,7 +65,7 @@ UNIT(a64_operand) {
|
||||
EXPECT_EQ(vs_3.group(), RegGroup::kVec);
|
||||
EXPECT_EQ(vs_3.id(), 15u);
|
||||
EXPECT_TRUE(vs_3.isVecS4());
|
||||
EXPECT_EQ(vs_3.elementType(), Vec::kElementTypeS);
|
||||
EXPECT_EQ(vs_3.elementType(), VecElementType::kS);
|
||||
EXPECT_TRUE(vs_3.hasElementIndex());
|
||||
EXPECT_EQ(vs_3.elementIndex(), 3u);
|
||||
|
||||
@@ -74,7 +74,7 @@ UNIT(a64_operand) {
|
||||
EXPECT_EQ(vb_4.group(), RegGroup::kVec);
|
||||
EXPECT_EQ(vb_4.id(), 15u);
|
||||
EXPECT_TRUE(vb_4.isVecB4x4());
|
||||
EXPECT_EQ(vb_4.elementType(), Vec::kElementTypeB4);
|
||||
EXPECT_EQ(vb_4.elementType(), VecElementType::kB4);
|
||||
EXPECT_TRUE(vb_4.hasElementIndex());
|
||||
EXPECT_EQ(vb_4.elementIndex(), 3u);
|
||||
}
|
||||
|
||||
@@ -69,74 +69,60 @@ ASMJIT_INLINE_NODEBUG GpW Gp::w() const noexcept { return GpW(id()); }
|
||||
ASMJIT_INLINE_NODEBUG GpX Gp::x() const noexcept { return GpX(id()); }
|
||||
#endif
|
||||
|
||||
//! Vector element type (AArch64).
|
||||
enum class VecElementType : uint32_t {
|
||||
//! No element type specified.
|
||||
kNone = 0,
|
||||
//! Byte elements (B8 or B16).
|
||||
kB,
|
||||
//! Halfword elements (H4 or H8).
|
||||
kH,
|
||||
//! Singleword elements (S2 or S4).
|
||||
kS,
|
||||
//! Doubleword elements (D2).
|
||||
kD,
|
||||
//! Byte elements grouped by 4 bytes (B4).
|
||||
//!
|
||||
//! \note This element-type is only used by few instructions.
|
||||
kB4,
|
||||
//! Halfword elements grouped by 2 halfwords (H2).
|
||||
//!
|
||||
//! \note This element-type is only used by few instructions.
|
||||
kH2,
|
||||
|
||||
//! Maximum value of \ref VecElementType
|
||||
kMaxValue = kH2
|
||||
};
|
||||
|
||||
//! 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
|
||||
kSignatureElementB = uint32_t(VecElementType::kB) << kSignatureRegElementTypeShift,
|
||||
kSignatureElementH = uint32_t(VecElementType::kH) << kSignatureRegElementTypeShift,
|
||||
kSignatureElementS = uint32_t(VecElementType::kS) << kSignatureRegElementTypeShift,
|
||||
kSignatureElementD = uint32_t(VecElementType::kD) << kSignatureRegElementTypeShift,
|
||||
kSignatureElementB4 = uint32_t(VecElementType::kB4) << kSignatureRegElementTypeShift,
|
||||
kSignatureElementH2 = uint32_t(VecElementType::kH2) << 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.
|
||||
//! Returns whether the vector register has associated a vector element type.
|
||||
ASMJIT_INLINE_NODEBUG constexpr bool hasElementType() const noexcept { return _signature.hasField<kSignatureRegElementTypeMask>(); }
|
||||
//! Returns vector element type of the register.
|
||||
ASMJIT_INLINE_NODEBUG constexpr VecElementType elementType() const noexcept { return VecElementType(_signature.getField<kSignatureRegElementTypeMask>()); }
|
||||
//! Sets vector element type of the register to `elementType`.
|
||||
ASMJIT_INLINE_NODEBUG void setElementType(VecElementType elementType) noexcept { _signature.setField<kSignatureRegElementTypeMask>(uint32_t(elementType)); }
|
||||
//! Resets vector 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); }
|
||||
@@ -197,12 +183,12 @@ public:
|
||||
//! 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 {
|
||||
static ASMJIT_INLINE_NODEBUG constexpr OperandSignature _makeElementAccessSignature(VecElementType 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)};
|
||||
(uint32_t(elementType) << kSignatureRegElementTypeShift) |
|
||||
(uint32_t(elementIndex << kSignatureRegElementIndexShift))};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -243,12 +229,12 @@ 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 VecV Vec::b(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(VecElementType::kB, elementIndex), id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecV Vec::h(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(VecElementType::kH, elementIndex), id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecV Vec::s(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(VecElementType::kS, elementIndex), id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecV Vec::d(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(VecElementType::kD, elementIndex), id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecV Vec::h2(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(VecElementType::kH2, elementIndex), id()); }
|
||||
ASMJIT_INLINE_NODEBUG VecV Vec::b4(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(VecElementType::kB4, 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()); }
|
||||
|
||||
@@ -230,7 +230,7 @@ Error RACFGBuilder::onInst(InstNode* inst, InstControlFlow& controlType, RAInstB
|
||||
if (reg.as<Vec>().hasElementIndex()) {
|
||||
// Only the first 0..15 registers can be used if the register uses
|
||||
// element accessor that accesses half-words (h[0..7] elements).
|
||||
if (instInfo.hasFlag(InstDB::kInstFlagVH0_15) && reg.as<Vec>().elementType() == Vec::kElementTypeH) {
|
||||
if (instInfo.hasFlag(InstDB::kInstFlagVH0_15) && reg.as<Vec>().elementType() == VecElementType::kH) {
|
||||
if (Support::test(flags, RATiedFlags::kUse))
|
||||
useId &= 0x0000FFFFu;
|
||||
else
|
||||
|
||||
@@ -318,9 +318,9 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatRegister(
|
||||
ASMJIT_PROPAGATE(sb.appendFormat("%c%u", letter, rId));
|
||||
}
|
||||
|
||||
constexpr uint32_t kElementTypeCount = uint32_t(a64::VecElementType::kMaxValue) + 1;
|
||||
if (elementType) {
|
||||
if (elementType > a64::Vec::kElementTypeCount)
|
||||
elementType = a64::Vec::kElementTypeCount;
|
||||
elementType = Support::min(elementType, kElementTypeCount);
|
||||
|
||||
FormatElementData elementData = formatElementDataTable[elementType];
|
||||
uint32_t elementCount = elementData.elementCount;
|
||||
|
||||
@@ -239,6 +239,13 @@ 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-27
|
||||
//!
|
||||
//! Core changes:
|
||||
//!
|
||||
//! - Renamed `a64::Vec::ElementType` to `a64::VecElementType` and made it a typed enum. This enum was used mostly
|
||||
//! internally, but there is a public API using it, so it's a breaking change.
|
||||
//!
|
||||
//! ### Changes committed at 2023-12-26
|
||||
//!
|
||||
//! Core changes:
|
||||
@@ -1045,7 +1052,7 @@ namespace asmjit {
|
||||
//!
|
||||
//! // Type-unsafe, but possible.
|
||||
//! a.emit(x86::Inst::kIdMov, dst, m);
|
||||
//! // Also possible, `emit()` is typeless and can be used with raw Operand.
|
||||
//! // Also possible, `emit()` is type-less and can be used with raw Operand.
|
||||
//! a.emit(x86::Inst::kIdMov, dst, op);
|
||||
//! }
|
||||
//! ```
|
||||
@@ -1139,7 +1146,7 @@ namespace asmjit {
|
||||
//! mem.size(); // 4.
|
||||
//! mem.offset(); // 12.
|
||||
//!
|
||||
//! mem.setSize(0); // Sets the size to 0 (makes it sizeless).
|
||||
//! mem.setSize(0); // Sets the size to 0 (makes it size-less).
|
||||
//! mem.addOffset(-1); // Adds -1 to the offset and makes it 11.
|
||||
//! mem.setOffset(0); // Sets the offset to 0.
|
||||
//! mem.setBase(rcx); // Changes BASE to RCX.
|
||||
|
||||
Reference in New Issue
Block a user