diff options
author | kobalicek <kobalicek.petr@gmail.com> | 2022-06-05 23:45:15 +0300 |
---|---|---|
committer | kobalicek <kobalicek.petr@gmail.com> | 2022-06-05 23:45:15 +0300 |
commit | d198ca4cfdb64180b1f961ca6cc9ceab98696d10 (patch) | |
tree | 72dd0a18728825757bc7b6e100e8b888a756666a | |
parent | a4cb51b532af0f8137c4182914244c3b05d7745f (diff) |
[Bug] Fixed queryFeatures() to properly return AVX-512 requirements of shift instructions that use memory operandsimprovements
[Bug] Fixed queryFeatures() to properly return AVX-512 requirements of some floating-point conversion instructions
[Opt] Slightly improved the performance of BitWordIterator and friends possibly taking advantage of BMI extensions
[API] Removed BitWordFlipIterator that was never used by the library
[Enh] Log the whole instruction if the validation fails in asmjit::Builder
-rw-r--r-- | src/asmjit/core/builder.cpp | 4 | ||||
-rw-r--r-- | src/asmjit/core/emitterutils.cpp | 4 | ||||
-rw-r--r-- | src/asmjit/core/emitterutils_p.h | 2 | ||||
-rw-r--r-- | src/asmjit/core/formatter.h | 4 | ||||
-rw-r--r-- | src/asmjit/core/support.h | 29 | ||||
-rw-r--r-- | src/asmjit/x86/x86formatter.cpp | 5 | ||||
-rw-r--r-- | src/asmjit/x86/x86instapi.cpp | 31 |
7 files changed, 40 insertions, 39 deletions
diff --git a/src/asmjit/core/builder.cpp b/src/asmjit/core/builder.cpp index 5df243e..ad2cf7a 100644 --- a/src/asmjit/core/builder.cpp +++ b/src/asmjit/core/builder.cpp @@ -594,10 +594,14 @@ Error BaseBuilder::_emit(InstId instId, const Operand_& o0, const Operand_& o1, Error err = _funcs.validate(arch(), BaseInst(instId, options, _extraReg), opArray, opCount, validationFlags); if (ASMJIT_UNLIKELY(err)) { +#ifndef ASMJIT_NO_LOGGING + return EmitterUtils::logInstructionFailed(this, err, instId, options, o0, o1, o2, opExt); +#else resetInstOptions(); resetExtraReg(); resetInlineComment(); return reportError(err); +#endif } } #endif diff --git a/src/asmjit/core/emitterutils.cpp b/src/asmjit/core/emitterutils.cpp index f36a1b3..da12217 100644 --- a/src/asmjit/core/emitterutils.cpp +++ b/src/asmjit/core/emitterutils.cpp @@ -96,7 +96,7 @@ void logInstructionEmitted( } Error logInstructionFailed( - BaseAssembler* self, + BaseEmitter* self, Error err, InstId instId, InstOptions options, @@ -109,7 +109,7 @@ Error logInstructionFailed( Operand_ opArray[Globals::kMaxOpCount]; opArrayFromEmitArgs(opArray, o0, o1, o2, opExt); - self->_funcs.formatInstruction(sb, FormatFlags::kNone, self, self->arch(), BaseInst(instId, options, self->extraReg()), opArray, Globals::kMaxOpCount); + self->_funcs.formatInstruction(sb, FormatFlags::kRegType, self, self->arch(), BaseInst(instId, options, self->extraReg()), opArray, Globals::kMaxOpCount); if (self->inlineComment()) { sb.append(" ; "); diff --git a/src/asmjit/core/emitterutils_p.h b/src/asmjit/core/emitterutils_p.h index b7610e7..2f7370a 100644 --- a/src/asmjit/core/emitterutils_p.h +++ b/src/asmjit/core/emitterutils_p.h @@ -71,7 +71,7 @@ void logInstructionEmitted( uint32_t relSize, uint32_t immSize, uint8_t* afterCursor); Error logInstructionFailed( - BaseAssembler* self, + BaseEmitter* self, Error err, InstId instId, InstOptions options, diff --git a/src/asmjit/core/formatter.h b/src/asmjit/core/formatter.h index d7a4b93..0ee6bde 100644 --- a/src/asmjit/core/formatter.h +++ b/src/asmjit/core/formatter.h @@ -37,7 +37,9 @@ enum class FormatFlags : uint32_t { //! Show casts between virtual register types (Compiler output). kRegCasts = 0x00000010u, //! Show positions associated with nodes (Compiler output). - kPositions = 0x00000020u + kPositions = 0x00000020u, + //! Always format a register type (Compiler output). + kRegType = 0x00000040u }; ASMJIT_DEFINE_ENUM_FLAGS(FormatFlags) diff --git a/src/asmjit/core/support.h b/src/asmjit/core/support.h index e55b808..1bc1b58 100644 --- a/src/asmjit/core/support.h +++ b/src/asmjit/core/support.h @@ -1227,36 +1227,13 @@ public: ASMJIT_FORCE_INLINE uint32_t next() noexcept { ASMJIT_ASSERT(_bitWord != 0); uint32_t index = ctz(_bitWord); - _bitWord ^= T(1u) << index; + _bitWord &= T(_bitWord - 1); return index; } T _bitWord; }; -// Support - BitWordFlipIterator -// ============================= - -template<typename T> -class BitWordFlipIterator { -public: - ASMJIT_FORCE_INLINE explicit BitWordFlipIterator(T bitWord) noexcept - : _bitWord(bitWord) {} - - ASMJIT_FORCE_INLINE void init(T bitWord) noexcept { _bitWord = bitWord; } - ASMJIT_FORCE_INLINE bool hasNext() const noexcept { return _bitWord != 0; } - - ASMJIT_FORCE_INLINE uint32_t nextAndFlip() noexcept { - ASMJIT_ASSERT(_bitWord != 0); - uint32_t index = ctz(_bitWord); - _bitWord ^= T(1u) << index; - return index; - } - - T _bitWord; - T _xorMask; -}; - // Support - BitVectorOps // ====================== @@ -1406,7 +1383,7 @@ public: ASMJIT_ASSERT(bitWord != T(0)); uint32_t bit = ctz(bitWord); - bitWord ^= T(1u) << bit; + bitWord &= T(bitWord - 1u); size_t n = _idx + bit; while (!bitWord && (_idx += bitSizeOf<T>()) < _end) @@ -1471,7 +1448,7 @@ public: ASMJIT_ASSERT(bitWord != T(0)); uint32_t bit = ctz(bitWord); - bitWord ^= T(1u) << bit; + bitWord &= T(bitWord - 1u); size_t n = _idx + bit; while (!bitWord && (_idx += kTSizeInBits) < _end) diff --git a/src/asmjit/x86/x86formatter.cpp b/src/asmjit/x86/x86formatter.cpp index d62dd18..9d52e96 100644 --- a/src/asmjit/x86/x86formatter.cpp +++ b/src/asmjit/x86/x86formatter.cpp @@ -344,7 +344,10 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatRegister(String& sb, FormatFlag else ASMJIT_PROPAGATE(sb.appendFormat("%%%u", unsigned(Operand::virtIdToIndex(id)))); - if (vReg->type() != type && uint32_t(type) <= uint32_t(RegType::kMaxValue) && Support::test(formatFlags, FormatFlags::kRegCasts)) { + bool formatType = (Support::test(formatFlags, FormatFlags::kRegType)) || + (Support::test(formatFlags, FormatFlags::kRegCasts) && vReg->type() != type); + + if (formatType && uint32_t(type) <= uint32_t(RegType::kMaxValue)) { const RegFormatInfo::TypeEntry& typeEntry = info.typeEntries[size_t(type)]; if (typeEntry.index) ASMJIT_PROPAGATE(sb.appendFormat("@%s", info.typeStrings + typeEntry.index)); diff --git a/src/asmjit/x86/x86instapi.cpp b/src/asmjit/x86/x86instapi.cpp index 3857cc1..0bf7b89 100644 --- a/src/asmjit/x86/x86instapi.cpp +++ b/src/asmjit/x86/x86instapi.cpp @@ -1588,14 +1588,6 @@ Error InstInternal::queryFeatures(Arch arch, const BaseInst& inst, const Operand uint32_t mustUseEvex = 0; switch (instId) { - // Special case: VPSLLDQ and VPSRLDQ instructions only allow `reg, reg. imm` combination in AVX|AVX2 mode, - // then AVX-512 introduced `reg, reg/mem, imm` combination that uses EVEX prefix. This means that if the - // second operand is memory then this is AVX-512_BW instruction and not AVX/AVX2 instruction. - case Inst::kIdVpslldq: - case Inst::kIdVpsrldq: - mustUseEvex = opCount >= 2 && operands[1].isMem(); - break; - // Special case: VPBROADCAST[B|D|Q|W] only supports r32/r64 with EVEX prefix. case Inst::kIdVpbroadcastb: case Inst::kIdVpbroadcastd: @@ -1604,6 +1596,29 @@ Error InstInternal::queryFeatures(Arch arch, const BaseInst& inst, const Operand mustUseEvex = opCount >= 2 && x86::Reg::isGp(operands[1]); break; + case Inst::kIdVcvtpd2dq: + case Inst::kIdVcvtpd2ps: + case Inst::kIdVcvttpd2dq: + mustUseEvex = opCount >= 2 && Reg::isYmm(operands[0]); + break; + + // Special case: These instructions only allow `reg, reg. imm` combination in AVX|AVX2 mode, then + // AVX-512 introduced `reg, reg/mem, imm` combination that uses EVEX prefix. This means that if + // the second operand is memory then this is AVX-512_BW instruction and not AVX/AVX2 instruction. + case Inst::kIdVpslldq: + case Inst::kIdVpslld: + case Inst::kIdVpsllq: + case Inst::kIdVpsllw: + case Inst::kIdVpsrad: + case Inst::kIdVpsraq: + case Inst::kIdVpsraw: + case Inst::kIdVpsrld: + case Inst::kIdVpsrldq: + case Inst::kIdVpsrlq: + case Inst::kIdVpsrlw: + mustUseEvex = opCount >= 2 && operands[1].isMem(); + break; + // Special case: VPERMPD - AVX2 vs AVX512-F case. case Inst::kIdVpermpd: mustUseEvex = opCount >= 3 && !operands[2].isImm(); |