mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-18 13:04:36 +03:00
Added more memory addressing types to Mem operand
This commit is contained in:
@@ -90,20 +90,20 @@ struct Operand_ {
|
|||||||
kSignatureMemBaseIndexMask = kSignatureMemBaseIndexBits << kSignatureMemBaseIndexShift,
|
kSignatureMemBaseIndexMask = kSignatureMemBaseIndexBits << kSignatureMemBaseIndexShift,
|
||||||
|
|
||||||
// Memory should be encoded as absolute immediate (X86|X64).
|
// Memory should be encoded as absolute immediate (X86|X64).
|
||||||
// |........|........|..X.....|........|
|
// |........|........|.XX.....|........|
|
||||||
kSignatureMemAbsoluteShift = 13,
|
kSignatureMemAddrTypeShift = 13,
|
||||||
kSignatureMemAbsoluteBits = 0x01U,
|
kSignatureMemAddrTypeBits = 0x03U,
|
||||||
kSignatureMemAbsoluteFlag = kSignatureMemAbsoluteBits << kSignatureMemAbsoluteShift,
|
kSignatureMemAddrTypeMask = kSignatureMemAddrTypeBits << kSignatureMemAddrTypeShift,
|
||||||
|
|
||||||
// This memory operand represents a function argument's stack location (CodeCompiler)
|
// This memory operand represents a function argument's stack location (CodeCompiler)
|
||||||
// |........|........|.X......|........|
|
// |........|........|.X......|........|
|
||||||
kSignatureMemArgHomeShift = 14,
|
kSignatureMemArgHomeShift = 15,
|
||||||
kSignatureMemArgHomeBits = 0x01U,
|
kSignatureMemArgHomeBits = 0x01U,
|
||||||
kSignatureMemArgHomeFlag = kSignatureMemArgHomeBits << kSignatureMemArgHomeShift,
|
kSignatureMemArgHomeFlag = kSignatureMemArgHomeBits << kSignatureMemArgHomeShift,
|
||||||
|
|
||||||
// This memory operand represents a virtual register's home-slot (CodeCompiler).
|
// This memory operand represents a virtual register's home-slot (CodeCompiler).
|
||||||
// |........|........|X.......|........|
|
// |........|........|X.......|........|
|
||||||
kSignatureMemRegHomeShift = 15,
|
kSignatureMemRegHomeShift = 16,
|
||||||
kSignatureMemRegHomeBits = 0x01U,
|
kSignatureMemRegHomeBits = 0x01U,
|
||||||
kSignatureMemRegHomeFlag = kSignatureMemRegHomeBits << kSignatureMemRegHomeShift
|
kSignatureMemRegHomeFlag = kSignatureMemRegHomeBits << kSignatureMemRegHomeShift
|
||||||
};
|
};
|
||||||
@@ -243,16 +243,12 @@ struct Operand_ {
|
|||||||
//! Improper use of `setSignature()` can lead to hard-to-debug errors.
|
//! Improper use of `setSignature()` can lead to hard-to-debug errors.
|
||||||
ASMJIT_INLINE void setSignature(uint32_t signature) noexcept { _signature = signature; }
|
ASMJIT_INLINE void setSignature(uint32_t signature) noexcept { _signature = signature; }
|
||||||
|
|
||||||
ASMJIT_INLINE bool _hasSignatureData(uint32_t bits) const noexcept {
|
ASMJIT_INLINE bool _hasSignatureData(uint32_t bits) const noexcept { return (_signature & bits) != 0; }
|
||||||
return (_signature & bits) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \internal
|
//! \internal
|
||||||
//!
|
//!
|
||||||
//! Unpacks information from operand's signature.
|
//! Unpacks information from operand's signature.
|
||||||
ASMJIT_INLINE uint32_t _getSignatureData(uint32_t bits, uint32_t shift) const noexcept {
|
ASMJIT_INLINE uint32_t _getSignatureData(uint32_t bits, uint32_t shift) const noexcept { return (_signature >> shift) & bits; }
|
||||||
return (_signature >> shift) & bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \internal
|
//! \internal
|
||||||
//!
|
//!
|
||||||
@@ -264,6 +260,9 @@ struct Operand_ {
|
|||||||
|
|
||||||
ASMJIT_INLINE void _addSignatureData(uint32_t data) noexcept { _signature |= data; }
|
ASMJIT_INLINE void _addSignatureData(uint32_t data) noexcept { _signature |= data; }
|
||||||
|
|
||||||
|
//! Clears specified bits in operand's signature.
|
||||||
|
ASMJIT_INLINE void _clearSignatureData(uint32_t bits, uint32_t shift) noexcept { _signature &= ~(bits << shift); }
|
||||||
|
|
||||||
//! Get type of the operand, see \ref OpType.
|
//! Get type of the operand, see \ref OpType.
|
||||||
ASMJIT_INLINE uint32_t getOp() const noexcept { return _getSignatureData(kSignatureOpBits, kSignatureOpShift); }
|
ASMJIT_INLINE uint32_t getOp() const noexcept { return _getSignatureData(kSignatureOpBits, kSignatureOpShift); }
|
||||||
//! Get if the operand is none (\ref kOpNone).
|
//! Get if the operand is none (\ref kOpNone).
|
||||||
@@ -818,6 +817,20 @@ public:
|
|||||||
//! prefix and index shift (scale).
|
//! prefix and index shift (scale).
|
||||||
class Mem : public Operand {
|
class Mem : public Operand {
|
||||||
public:
|
public:
|
||||||
|
enum AddrType {
|
||||||
|
kAddrTypeDefault = 0,
|
||||||
|
kAddrTypeAbs = 1,
|
||||||
|
kAddrTypeRel = 2,
|
||||||
|
kAddrTypeWrt = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
// Shortcuts.
|
||||||
|
enum SignatureMem {
|
||||||
|
kSignatureMemAbs = kAddrTypeAbs << kSignatureMemAddrTypeShift,
|
||||||
|
kSignatureMemRel = kAddrTypeRel << kSignatureMemAddrTypeShift,
|
||||||
|
kSignatureMemWrt = kAddrTypeWrt << kSignatureMemAddrTypeShift
|
||||||
|
};
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// [Construction / Destruction]
|
// [Construction / Destruction]
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
@@ -854,15 +867,25 @@ public:
|
|||||||
_init_packed_d2_d3(0, 0);
|
_init_packed_d2_d3(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASMJIT_INLINE bool isAbs() const noexcept { return _hasSignatureData(kSignatureMemAbsoluteFlag); }
|
ASMJIT_INLINE bool hasAddrType() const noexcept { return _hasSignatureData(kSignatureMemAddrTypeMask); }
|
||||||
|
ASMJIT_INLINE uint32_t getAddrType() const noexcept { return _getSignatureData(kSignatureMemAddrTypeBits, kSignatureMemAddrTypeShift); }
|
||||||
|
ASMJIT_INLINE void setAddrType(uint32_t addrType) noexcept { return _setSignatureData(addrType, kSignatureMemAddrTypeBits, kSignatureMemAddrTypeShift); }
|
||||||
|
ASMJIT_INLINE void resetAddrType() noexcept { return _clearSignatureData(kSignatureMemAddrTypeBits, kSignatureMemAddrTypeShift); }
|
||||||
|
|
||||||
|
ASMJIT_INLINE bool isAbs() const noexcept { return getAddrType() == kAddrTypeAbs; }
|
||||||
|
ASMJIT_INLINE bool isRel() const noexcept { return getAddrType() == kAddrTypeRel; }
|
||||||
|
ASMJIT_INLINE bool isWrt() const noexcept { return getAddrType() == kAddrTypeWrt; }
|
||||||
|
|
||||||
|
ASMJIT_INLINE void setAbs() noexcept { setAddrType(kAddrTypeAbs); }
|
||||||
|
ASMJIT_INLINE void setRel() noexcept { setAddrType(kAddrTypeRel); }
|
||||||
|
ASMJIT_INLINE void setWrt() noexcept { setAddrType(kAddrTypeWrt); }
|
||||||
|
|
||||||
ASMJIT_INLINE bool isArgHome() const noexcept { return _hasSignatureData(kSignatureMemArgHomeFlag); }
|
ASMJIT_INLINE bool isArgHome() const noexcept { return _hasSignatureData(kSignatureMemArgHomeFlag); }
|
||||||
ASMJIT_INLINE bool isRegHome() const noexcept { return _hasSignatureData(kSignatureMemRegHomeFlag); }
|
ASMJIT_INLINE bool isRegHome() const noexcept { return _hasSignatureData(kSignatureMemRegHomeFlag); }
|
||||||
|
|
||||||
ASMJIT_INLINE void setAbs() noexcept { _signature |= kSignatureMemAbsoluteFlag; }
|
|
||||||
ASMJIT_INLINE void setArgHome() noexcept { _signature |= kSignatureMemArgHomeFlag; }
|
ASMJIT_INLINE void setArgHome() noexcept { _signature |= kSignatureMemArgHomeFlag; }
|
||||||
ASMJIT_INLINE void setRegHome() noexcept { _signature |= kSignatureMemRegHomeFlag; }
|
ASMJIT_INLINE void setRegHome() noexcept { _signature |= kSignatureMemRegHomeFlag; }
|
||||||
|
|
||||||
ASMJIT_INLINE void clearAbs() noexcept { _signature &= ~kSignatureMemAbsoluteFlag; }
|
|
||||||
ASMJIT_INLINE void clearArgHome() noexcept { _signature &= ~kSignatureMemArgHomeFlag; }
|
ASMJIT_INLINE void clearArgHome() noexcept { _signature &= ~kSignatureMemArgHomeFlag; }
|
||||||
ASMJIT_INLINE void clearRegHome() noexcept { _signature &= ~kSignatureMemRegHomeFlag; }
|
ASMJIT_INLINE void clearRegHome() noexcept { _signature &= ~kSignatureMemRegHomeFlag; }
|
||||||
|
|
||||||
@@ -873,46 +896,28 @@ public:
|
|||||||
//! Get whether the memory operand has BASE and INDEX register.
|
//! Get whether the memory operand has BASE and INDEX register.
|
||||||
ASMJIT_INLINE bool hasBaseOrIndex() const noexcept { return (_signature & kSignatureMemBaseIndexMask) != 0; }
|
ASMJIT_INLINE bool hasBaseOrIndex() const noexcept { return (_signature & kSignatureMemBaseIndexMask) != 0; }
|
||||||
//! Get whether the memory operand has BASE and INDEX register.
|
//! Get whether the memory operand has BASE and INDEX register.
|
||||||
ASMJIT_INLINE bool hasBaseAndIndex() const noexcept {
|
ASMJIT_INLINE bool hasBaseAndIndex() const noexcept { return (_signature & kSignatureMemBaseTypeMask) != 0 && (_signature & kSignatureMemIndexTypeMask) != 0; }
|
||||||
return (_signature & kSignatureMemBaseTypeMask) != 0 &&
|
|
||||||
(_signature & kSignatureMemIndexTypeMask) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Get if the BASE operand is a register.
|
//! Get if the BASE operand is a register (registers start after `kLabelTag`).
|
||||||
ASMJIT_INLINE bool hasBaseReg() const noexcept {
|
ASMJIT_INLINE bool hasBaseReg() const noexcept { return (_signature & kSignatureMemBaseTypeMask) > (Label::kLabelTag << kSignatureMemBaseTypeShift); }
|
||||||
// Registers start after kLabelTag.
|
|
||||||
return (_signature & kSignatureMemBaseTypeMask) > (Label::kLabelTag << kSignatureMemBaseTypeShift);
|
|
||||||
}
|
|
||||||
//! Get if the BASE operand is a label.
|
//! Get if the BASE operand is a label.
|
||||||
ASMJIT_INLINE bool hasBaseLabel() const noexcept {
|
ASMJIT_INLINE bool hasBaseLabel() const noexcept { return (_signature & kSignatureMemBaseTypeMask) == (Label::kLabelTag << kSignatureMemBaseTypeShift); }
|
||||||
return (_signature & kSignatureMemBaseTypeMask) == (Label::kLabelTag << kSignatureMemBaseTypeShift);
|
//! Get if the INDEX operand is a register (registers start after `kLabelTag`).
|
||||||
}
|
ASMJIT_INLINE bool hasIndexReg() const noexcept { return (_signature & kSignatureMemIndexTypeMask) > (Label::kLabelTag << kSignatureMemIndexTypeShift); }
|
||||||
|
|
||||||
//! Get if the INDEX operand is a register.
|
|
||||||
ASMJIT_INLINE bool hasIndexReg() const noexcept {
|
|
||||||
// Registers start after kLabelTag.
|
|
||||||
return (_signature & kSignatureMemIndexTypeMask) > (Label::kLabelTag << kSignatureMemIndexTypeShift);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Get type of a BASE register (0 if this memory operand doesn't use the BASE register).
|
//! Get type of a BASE register (0 if this memory operand doesn't use the BASE register).
|
||||||
//!
|
//!
|
||||||
//! NOTE: If the returned type is one (a value never associated to a register
|
//! NOTE: If the returned type is one (a value never associated to a register
|
||||||
//! type) the BASE is not register, but it's a label. One equals to `kLabelTag`.
|
//! type) the BASE is not register, but it's a label. One equals to `kLabelTag`.
|
||||||
//! You should always check `hasBaseLabel()` before using `getBaseId()` result.
|
//! You should always check `hasBaseLabel()` before using `getBaseId()` result.
|
||||||
ASMJIT_INLINE uint32_t getBaseType() const noexcept {
|
ASMJIT_INLINE uint32_t getBaseType() const noexcept { return _getSignatureData(kSignatureMemBaseTypeBits, kSignatureMemBaseTypeShift); }
|
||||||
return _getSignatureData(kSignatureMemBaseTypeBits, kSignatureMemBaseTypeShift);
|
|
||||||
}
|
|
||||||
//! Get type of an INDEX register (0 if this memory operand doesn't use the INDEX register).
|
//! Get type of an INDEX register (0 if this memory operand doesn't use the INDEX register).
|
||||||
ASMJIT_INLINE uint32_t getIndexType() const noexcept {
|
ASMJIT_INLINE uint32_t getIndexType() const noexcept { return _getSignatureData(kSignatureMemIndexTypeBits, kSignatureMemIndexTypeShift); }
|
||||||
return _getSignatureData(kSignatureMemIndexTypeBits, kSignatureMemIndexTypeShift);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Get both BASE (4:0 bits) and INDEX (9:5 bits) types combined into a single integer.
|
//! Get both BASE (4:0 bits) and INDEX (9:5 bits) types combined into a single integer.
|
||||||
//!
|
//!
|
||||||
//! This is used internally for BASE+INDEX validation.
|
//! This is used internally for BASE+INDEX validation.
|
||||||
ASMJIT_INLINE uint32_t getBaseIndexType() const noexcept {
|
ASMJIT_INLINE uint32_t getBaseIndexType() const noexcept { return _getSignatureData(kSignatureMemBaseIndexBits, kSignatureMemBaseIndexShift); }
|
||||||
return _getSignatureData(kSignatureMemBaseIndexBits, kSignatureMemBaseIndexShift);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Get id of the BASE register or label (if the BASE was specified as label).
|
//! Get id of the BASE register or label (if the BASE was specified as label).
|
||||||
ASMJIT_INLINE uint32_t getBaseId() const noexcept { return _mem.base; }
|
ASMJIT_INLINE uint32_t getBaseId() const noexcept { return _mem.base; }
|
||||||
|
|||||||
@@ -161,8 +161,6 @@ namespace asmjit {
|
|||||||
|
|
||||||
template<typename This>
|
template<typename This>
|
||||||
struct X86EmitterExplicitT {
|
struct X86EmitterExplicitT {
|
||||||
ASMJIT_INLINE X86EmitterExplicitT() noexcept {}
|
|
||||||
|
|
||||||
// These typedefs are used to describe implicit operands passed explicitly.
|
// These typedefs are used to describe implicit operands passed explicitly.
|
||||||
typedef X86Gp AL;
|
typedef X86Gp AL;
|
||||||
typedef X86Gp AH;
|
typedef X86Gp AH;
|
||||||
@@ -279,12 +277,12 @@ struct X86EmitterExplicitT {
|
|||||||
//! \overload
|
//! \overload
|
||||||
ASMJIT_INLINE X86Mem intptr_ptr_abs(uint64_t base) const noexcept {
|
ASMJIT_INLINE X86Mem intptr_ptr_abs(uint64_t base) const noexcept {
|
||||||
uint32_t nativeGpSize = static_cast<const This*>(this)->getGpSize();
|
uint32_t nativeGpSize = static_cast<const This*>(this)->getGpSize();
|
||||||
return X86Mem(base, nativeGpSize, Mem::kSignatureMemAbsoluteFlag);
|
return X86Mem(base, nativeGpSize, Mem::kSignatureMemAbs);
|
||||||
}
|
}
|
||||||
//! \overload
|
//! \overload
|
||||||
ASMJIT_INLINE X86Mem intptr_ptr_abs(uint64_t base, const X86Gp& index, uint32_t shift = 0) const noexcept {
|
ASMJIT_INLINE X86Mem intptr_ptr_abs(uint64_t base, const X86Gp& index, uint32_t shift = 0) const noexcept {
|
||||||
uint32_t nativeGpSize = static_cast<const This*>(this)->getGpSize();
|
uint32_t nativeGpSize = static_cast<const This*>(this)->getGpSize();
|
||||||
return X86Mem(base, index, shift, nativeGpSize, Mem::kSignatureMemAbsoluteFlag);
|
return X86Mem(base, index, shift, nativeGpSize, Mem::kSignatureMemAbs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
@@ -5097,9 +5095,7 @@ struct X86EmitterImplicitT : public X86EmitterExplicitT<This> {
|
|||||||
//! NOTE: This class cannot be created, you can only cast to it and use it as
|
//! NOTE: This class cannot be created, you can only cast to it and use it as
|
||||||
//! emitter that emits to either X86Assembler, X86Builder, or X86Compiler (use
|
//! emitter that emits to either X86Assembler, X86Builder, or X86Compiler (use
|
||||||
//! with caution with X86Compiler as it expects virtual registers to be used).
|
//! with caution with X86Compiler as it expects virtual registers to be used).
|
||||||
class X86Emitter
|
class X86Emitter : public CodeEmitter, public X86EmitterImplicitT<X86Emitter> {
|
||||||
: public CodeEmitter,
|
|
||||||
public X86EmitterImplicitT<X86Emitter> {
|
|
||||||
ASMJIT_NONCONSTRUCTIBLE(X86Emitter)
|
ASMJIT_NONCONSTRUCTIBLE(X86Emitter)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -58,11 +58,11 @@ class X86Mem : public Mem {
|
|||||||
public:
|
public:
|
||||||
//! Additional bits of operand's signature used by `X86Mem`.
|
//! Additional bits of operand's signature used by `X86Mem`.
|
||||||
ASMJIT_ENUM(AdditionalBits) {
|
ASMJIT_ENUM(AdditionalBits) {
|
||||||
kSignatureMemShiftShift = 16,
|
kSignatureMemShiftShift = 19,
|
||||||
kSignatureMemShiftBits = 0x03U,
|
kSignatureMemShiftBits = 0x03U,
|
||||||
kSignatureMemShiftMask = kSignatureMemShiftBits << kSignatureMemShiftShift,
|
kSignatureMemShiftMask = kSignatureMemShiftBits << kSignatureMemShiftShift,
|
||||||
|
|
||||||
kSignatureMemSegmentShift = 18,
|
kSignatureMemSegmentShift = 21,
|
||||||
kSignatureMemSegmentBits = 0x07U,
|
kSignatureMemSegmentBits = 0x07U,
|
||||||
kSignatureMemSegmentMask = kSignatureMemSegmentBits << kSignatureMemSegmentShift
|
kSignatureMemSegmentMask = kSignatureMemSegmentBits << kSignatureMemSegmentShift
|
||||||
};
|
};
|
||||||
@@ -1052,7 +1052,7 @@ static ASMJIT_INLINE X86Mem ptr(uint64_t base, const X86Vec& index, uint32_t shi
|
|||||||
} \
|
} \
|
||||||
/*! Create a `[base + (vec_index << shift) + offset]` memory operand. */ \
|
/*! Create a `[base + (vec_index << shift) + offset]` memory operand. */ \
|
||||||
static ASMJIT_INLINE X86Mem FUNC(uint64_t base, const X86Vec& index, uint32_t shift = 0) noexcept { \
|
static ASMJIT_INLINE X86Mem FUNC(uint64_t base, const X86Vec& index, uint32_t shift = 0) noexcept { \
|
||||||
return X86Mem(base, index, shift, SIZE, Mem::kSignatureMemAbsoluteFlag); \
|
return X86Mem(base, index, shift, SIZE, Mem::kSignatureMemAbs); \
|
||||||
} \
|
} \
|
||||||
/*! Create a `[base + offset]` memory operand. */ \
|
/*! Create a `[base + offset]` memory operand. */ \
|
||||||
static ASMJIT_INLINE X86Mem FUNC##_abs(uint64_t base) noexcept { \
|
static ASMJIT_INLINE X86Mem FUNC##_abs(uint64_t base) noexcept { \
|
||||||
@@ -1060,17 +1060,18 @@ static ASMJIT_INLINE X86Mem ptr(uint64_t base, const X86Vec& index, uint32_t shi
|
|||||||
} \
|
} \
|
||||||
/*! Create a `[base + (index << shift) + offset]` memory operand. */ \
|
/*! Create a `[base + (index << shift) + offset]` memory operand. */ \
|
||||||
static ASMJIT_INLINE X86Mem FUNC##_abs(uint64_t base, const X86Gp& index, uint32_t shift = 0) noexcept { \
|
static ASMJIT_INLINE X86Mem FUNC##_abs(uint64_t base, const X86Gp& index, uint32_t shift = 0) noexcept { \
|
||||||
return X86Mem(base, index, shift, SIZE, Mem::kSignatureMemAbsoluteFlag); \
|
return X86Mem(base, index, shift, SIZE, Mem::kSignatureMemAbs); \
|
||||||
} \
|
} \
|
||||||
/*! Create a `[base + (vec_index << shift) + offset]` memory operand. */ \
|
/*! Create a `[base + (vec_index << shift) + offset]` memory operand. */ \
|
||||||
static ASMJIT_INLINE X86Mem FUNC##_abs(uint64_t base, const X86Vec& index, uint32_t shift = 0) noexcept { \
|
static ASMJIT_INLINE X86Mem FUNC##_abs(uint64_t base, const X86Vec& index, uint32_t shift = 0) noexcept { \
|
||||||
return X86Mem(base, index, shift, SIZE, Mem::kSignatureMemAbsoluteFlag); \
|
return X86Mem(base, index, shift, SIZE, Mem::kSignatureMemAbs); \
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define memory operand constructors that use platform independent naming.
|
// Define memory operand constructors that use platform independent naming.
|
||||||
ASMJIT_X86_PTR_FN(ptr_8, 1)
|
ASMJIT_X86_PTR_FN(ptr_8, 1)
|
||||||
ASMJIT_X86_PTR_FN(ptr_16, 2)
|
ASMJIT_X86_PTR_FN(ptr_16, 2)
|
||||||
ASMJIT_X86_PTR_FN(ptr_32, 4)
|
ASMJIT_X86_PTR_FN(ptr_32, 4)
|
||||||
|
ASMJIT_X86_PTR_FN(ptr_48, 6)
|
||||||
ASMJIT_X86_PTR_FN(ptr_64, 8)
|
ASMJIT_X86_PTR_FN(ptr_64, 8)
|
||||||
ASMJIT_X86_PTR_FN(ptr_80, 10)
|
ASMJIT_X86_PTR_FN(ptr_80, 10)
|
||||||
ASMJIT_X86_PTR_FN(ptr_128, 16)
|
ASMJIT_X86_PTR_FN(ptr_128, 16)
|
||||||
|
|||||||
Reference in New Issue
Block a user