Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/asmjit/asmjit.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkobalicek <kobalicek.petr@gmail.com>2017-02-27 19:12:28 +0300
committerkobalicek <kobalicek.petr@gmail.com>2017-02-27 19:12:28 +0300
commit90c26db7096ac868e507b448186d80b5ed16ff38 (patch)
treef71973ed64d595e5319e398b65bde5cbfa1b6188
parenta808b44359f0423219e029c69910d0decc91ebdb (diff)
Added more memory addressing types to Mem operand
-rw-r--r--src/asmjit/base/operand.h89
-rw-r--r--src/asmjit/x86/x86emitter.h10
-rw-r--r--src/asmjit/x86/x86operand.h11
3 files changed, 56 insertions, 54 deletions
diff --git a/src/asmjit/base/operand.h b/src/asmjit/base/operand.h
index 2874053..623663f 100644
--- a/src/asmjit/base/operand.h
+++ b/src/asmjit/base/operand.h
@@ -90,20 +90,20 @@ struct Operand_ {
kSignatureMemBaseIndexMask = kSignatureMemBaseIndexBits << kSignatureMemBaseIndexShift,
// Memory should be encoded as absolute immediate (X86|X64).
- // |........|........|..X.....|........|
- kSignatureMemAbsoluteShift = 13,
- kSignatureMemAbsoluteBits = 0x01U,
- kSignatureMemAbsoluteFlag = kSignatureMemAbsoluteBits << kSignatureMemAbsoluteShift,
+ // |........|........|.XX.....|........|
+ kSignatureMemAddrTypeShift = 13,
+ kSignatureMemAddrTypeBits = 0x03U,
+ kSignatureMemAddrTypeMask = kSignatureMemAddrTypeBits << kSignatureMemAddrTypeShift,
// This memory operand represents a function argument's stack location (CodeCompiler)
// |........|........|.X......|........|
- kSignatureMemArgHomeShift = 14,
+ kSignatureMemArgHomeShift = 15,
kSignatureMemArgHomeBits = 0x01U,
kSignatureMemArgHomeFlag = kSignatureMemArgHomeBits << kSignatureMemArgHomeShift,
// This memory operand represents a virtual register's home-slot (CodeCompiler).
// |........|........|X.......|........|
- kSignatureMemRegHomeShift = 15,
+ kSignatureMemRegHomeShift = 16,
kSignatureMemRegHomeBits = 0x01U,
kSignatureMemRegHomeFlag = kSignatureMemRegHomeBits << kSignatureMemRegHomeShift
};
@@ -243,16 +243,12 @@ struct Operand_ {
//! Improper use of `setSignature()` can lead to hard-to-debug errors.
ASMJIT_INLINE void setSignature(uint32_t signature) noexcept { _signature = signature; }
- ASMJIT_INLINE bool _hasSignatureData(uint32_t bits) const noexcept {
- return (_signature & bits) != 0;
- }
+ ASMJIT_INLINE bool _hasSignatureData(uint32_t bits) const noexcept { return (_signature & bits) != 0; }
//! \internal
//!
//! Unpacks information from operand's signature.
- ASMJIT_INLINE uint32_t _getSignatureData(uint32_t bits, uint32_t shift) const noexcept {
- return (_signature >> shift) & bits;
- }
+ ASMJIT_INLINE uint32_t _getSignatureData(uint32_t bits, uint32_t shift) const noexcept { return (_signature >> shift) & bits; }
//! \internal
//!
@@ -264,6 +260,9 @@ struct Operand_ {
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.
ASMJIT_INLINE uint32_t getOp() const noexcept { return _getSignatureData(kSignatureOpBits, kSignatureOpShift); }
//! Get if the operand is none (\ref kOpNone).
@@ -818,6 +817,20 @@ public:
//! prefix and index shift (scale).
class Mem : public Operand {
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]
// --------------------------------------------------------------------------
@@ -854,15 +867,25 @@ public:
_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 isRegHome() const noexcept { return _hasSignatureData(kSignatureMemRegHomeFlag); }
- ASMJIT_INLINE void setAbs() noexcept { _signature |= kSignatureMemAbsoluteFlag; }
ASMJIT_INLINE void setArgHome() noexcept { _signature |= kSignatureMemArgHomeFlag; }
ASMJIT_INLINE void setRegHome() noexcept { _signature |= kSignatureMemRegHomeFlag; }
- ASMJIT_INLINE void clearAbs() noexcept { _signature &= ~kSignatureMemAbsoluteFlag; }
ASMJIT_INLINE void clearArgHome() noexcept { _signature &= ~kSignatureMemArgHomeFlag; }
ASMJIT_INLINE void clearRegHome() noexcept { _signature &= ~kSignatureMemRegHomeFlag; }
@@ -873,46 +896,28 @@ public:
//! Get whether the memory operand has BASE and INDEX register.
ASMJIT_INLINE bool hasBaseOrIndex() const noexcept { return (_signature & kSignatureMemBaseIndexMask) != 0; }
//! Get whether the memory operand has BASE and INDEX register.
- ASMJIT_INLINE bool hasBaseAndIndex() const noexcept {
- return (_signature & kSignatureMemBaseTypeMask) != 0 &&
- (_signature & kSignatureMemIndexTypeMask) != 0;
- }
+ ASMJIT_INLINE bool hasBaseAndIndex() const noexcept { return (_signature & kSignatureMemBaseTypeMask) != 0 && (_signature & kSignatureMemIndexTypeMask) != 0; }
- //! Get if the BASE operand is a register.
- ASMJIT_INLINE bool hasBaseReg() const noexcept {
- // Registers start after kLabelTag.
- return (_signature & kSignatureMemBaseTypeMask) > (Label::kLabelTag << kSignatureMemBaseTypeShift);
- }
+ //! Get if the BASE operand is a register (registers start after `kLabelTag`).
+ ASMJIT_INLINE bool hasBaseReg() const noexcept { return (_signature & kSignatureMemBaseTypeMask) > (Label::kLabelTag << kSignatureMemBaseTypeShift); }
//! Get if the BASE operand is a label.
- ASMJIT_INLINE bool hasBaseLabel() const noexcept {
- return (_signature & kSignatureMemBaseTypeMask) == (Label::kLabelTag << kSignatureMemBaseTypeShift);
- }
-
- //! Get if the INDEX operand is a register.
- ASMJIT_INLINE bool hasIndexReg() const noexcept {
- // Registers start after kLabelTag.
- return (_signature & kSignatureMemIndexTypeMask) > (Label::kLabelTag << kSignatureMemIndexTypeShift);
- }
+ ASMJIT_INLINE bool hasBaseLabel() const noexcept { 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 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
//! type) the BASE is not register, but it's a label. One equals to `kLabelTag`.
//! You should always check `hasBaseLabel()` before using `getBaseId()` result.
- ASMJIT_INLINE uint32_t getBaseType() const noexcept {
- return _getSignatureData(kSignatureMemBaseTypeBits, kSignatureMemBaseTypeShift);
- }
+ ASMJIT_INLINE uint32_t getBaseType() const noexcept { return _getSignatureData(kSignatureMemBaseTypeBits, kSignatureMemBaseTypeShift); }
//! Get type of an INDEX register (0 if this memory operand doesn't use the INDEX register).
- ASMJIT_INLINE uint32_t getIndexType() const noexcept {
- return _getSignatureData(kSignatureMemIndexTypeBits, kSignatureMemIndexTypeShift);
- }
+ ASMJIT_INLINE uint32_t getIndexType() const noexcept { return _getSignatureData(kSignatureMemIndexTypeBits, kSignatureMemIndexTypeShift); }
//! 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.
- ASMJIT_INLINE uint32_t getBaseIndexType() const noexcept {
- return _getSignatureData(kSignatureMemBaseIndexBits, kSignatureMemBaseIndexShift);
- }
+ ASMJIT_INLINE uint32_t getBaseIndexType() const noexcept { return _getSignatureData(kSignatureMemBaseIndexBits, kSignatureMemBaseIndexShift); }
//! 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; }
diff --git a/src/asmjit/x86/x86emitter.h b/src/asmjit/x86/x86emitter.h
index eabcd4b..04fb3a0 100644
--- a/src/asmjit/x86/x86emitter.h
+++ b/src/asmjit/x86/x86emitter.h
@@ -161,8 +161,6 @@ namespace asmjit {
template<typename This>
struct X86EmitterExplicitT {
- ASMJIT_INLINE X86EmitterExplicitT() noexcept {}
-
// These typedefs are used to describe implicit operands passed explicitly.
typedef X86Gp AL;
typedef X86Gp AH;
@@ -279,12 +277,12 @@ struct X86EmitterExplicitT {
//! \overload
ASMJIT_INLINE X86Mem intptr_ptr_abs(uint64_t base) const noexcept {
uint32_t nativeGpSize = static_cast<const This*>(this)->getGpSize();
- return X86Mem(base, nativeGpSize, Mem::kSignatureMemAbsoluteFlag);
+ return X86Mem(base, nativeGpSize, Mem::kSignatureMemAbs);
}
//! \overload
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();
- 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
//! emitter that emits to either X86Assembler, X86Builder, or X86Compiler (use
//! with caution with X86Compiler as it expects virtual registers to be used).
-class X86Emitter
- : public CodeEmitter,
- public X86EmitterImplicitT<X86Emitter> {
+class X86Emitter : public CodeEmitter, public X86EmitterImplicitT<X86Emitter> {
ASMJIT_NONCONSTRUCTIBLE(X86Emitter)
};
diff --git a/src/asmjit/x86/x86operand.h b/src/asmjit/x86/x86operand.h
index 0e1bce2..ffe9392 100644
--- a/src/asmjit/x86/x86operand.h
+++ b/src/asmjit/x86/x86operand.h
@@ -58,11 +58,11 @@ class X86Mem : public Mem {
public:
//! Additional bits of operand's signature used by `X86Mem`.
ASMJIT_ENUM(AdditionalBits) {
- kSignatureMemShiftShift = 16,
+ kSignatureMemShiftShift = 19,
kSignatureMemShiftBits = 0x03U,
kSignatureMemShiftMask = kSignatureMemShiftBits << kSignatureMemShiftShift,
- kSignatureMemSegmentShift = 18,
+ kSignatureMemSegmentShift = 21,
kSignatureMemSegmentBits = 0x07U,
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. */ \
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. */ \
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. */ \
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. */ \
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.
ASMJIT_X86_PTR_FN(ptr_8, 1)
ASMJIT_X86_PTR_FN(ptr_16, 2)
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_80, 10)
ASMJIT_X86_PTR_FN(ptr_128, 16)