diff options
author | kobalicek <kobalicek.petr@gmail.com> | 2017-02-27 19:12:28 +0300 |
---|---|---|
committer | kobalicek <kobalicek.petr@gmail.com> | 2017-02-27 19:12:28 +0300 |
commit | 90c26db7096ac868e507b448186d80b5ed16ff38 (patch) | |
tree | f71973ed64d595e5319e398b65bde5cbfa1b6188 | |
parent | a808b44359f0423219e029c69910d0decc91ebdb (diff) |
Added more memory addressing types to Mem operand
-rw-r--r-- | src/asmjit/base/operand.h | 89 | ||||
-rw-r--r-- | src/asmjit/x86/x86emitter.h | 10 | ||||
-rw-r--r-- | src/asmjit/x86/x86operand.h | 11 |
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) |