diff --git a/CMakeLists.txt b/CMakeLists.txt index b6082ca..1e9dd44 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -179,9 +179,15 @@ if (NOT ASMJIT_NO_CUSTOM_FLAGS) -Oi) # [+] Generate intrinsic functions. elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "^(GNU|Clang|AppleClang)$") list(APPEND ASMJIT_PRIVATE_CFLAGS -Wall -Wextra) - list(APPEND ASMJIT_PRIVATE_CFLAGS -fno-math-errno -fno-threadsafe-statics) + list(APPEND ASMJIT_PRIVATE_CFLAGS -fno-math-errno) list(APPEND ASMJIT_PRIVATE_CFLAGS_REL -O2) - asmjit_detect_cflags(ASMJIT_PRIVATE_CFLAGS_REL -fmerge-all-constants) + + asmjit_detect_cflags(ASMJIT_PRIVATE_CFLAGS + -fno-threadsafe-statics + -fno-semantic-interposition) + + asmjit_detect_cflags(ASMJIT_PRIVATE_CFLAGS_REL + -fmerge-all-constants) endif() endif() diff --git a/src/asmjit/x86/x86assembler.cpp b/src/asmjit/x86/x86assembler.cpp index 468bca6..89c2b52 100644 --- a/src/asmjit/x86/x86assembler.cpp +++ b/src/asmjit/x86/x86assembler.cpp @@ -473,6 +473,49 @@ public: #define ENC_OPS3(OP0, OP1, OP2) ((Operand::kOp##OP0) + ((Operand::kOp##OP1) << 3) + ((Operand::kOp##OP2) << 6)) #define ENC_OPS4(OP0, OP1, OP2, OP3) ((Operand::kOp##OP0) + ((Operand::kOp##OP1) << 3) + ((Operand::kOp##OP2) << 6) + ((Operand::kOp##OP3) << 9)) +// ============================================================================ +// [asmjit::x86::Assembler - Movabs Heuristics] +// ============================================================================ + +static ASMJIT_INLINE bool x86GetMovAbsInstSize64Bit(uint32_t regSize, uint32_t options, const Mem& rmRel) noexcept { + uint32_t segmentPrefixSize = rmRel.segmentId() != 0; + uint32_t _66hPrefixSize = regSize == 2; + uint32_t rexPrefixSize = (regSize == 8) || ((options & Inst::kOptionRex) != 0); + uint32_t opCodeByteSize = 1; + uint32_t immediateSize = 8; + + return segmentPrefixSize + _66hPrefixSize + rexPrefixSize + opCodeByteSize + immediateSize; +} + +static ASMJIT_INLINE uint32_t x86GetMovAbsAddrType(Assembler* self, X86BufferWriter& writer, uint32_t regSize, uint32_t options, const Mem& rmRel) noexcept { + uint32_t addrType = rmRel.addrType(); + int64_t addrValue = rmRel.offset(); + + if (addrType == BaseMem::kAddrTypeDefault && !(options & Inst::kOptionModMR)) { + if (self->is64Bit()) { + uint64_t baseAddress = self->codeInfo().baseAddress(); + if (baseAddress != Globals::kNoBaseAddress && !rmRel.hasSegment()) { + uint32_t instructionSize = x86GetMovAbsInstSize64Bit(regSize, options, rmRel); + uint64_t virtualOffset = uint64_t(writer.offsetFrom(self->_bufferData)); + uint64_t rip64 = baseAddress + self->_section->offset() + virtualOffset + instructionSize; + uint64_t rel64 = uint64_t(addrValue) - rip64; + + if (!Support::isInt32(int64_t(rel64))) + addrType = BaseMem::kAddrTypeAbs; + } + else { + if (!Support::isInt32(addrValue)) + addrType = BaseMem::kAddrTypeAbs; + } + } + else { + addrType = BaseMem::kAddrTypeAbs; + } + } + + return addrType; +} + // ============================================================================ // [asmjit::x86::Assembler - Construction / Destruction] // ============================================================================ @@ -1536,10 +1579,10 @@ CaseX86M_GPB_MulDiv: if (o0.size() == 1) FIXUP_GPB(o0, opReg); - // Handle a special form `mov al|ax|eax|rax, [ptr64]` that doesn't use MOD. - if (o0.id() == Gp::kIdAx && !rmRel->as().hasBaseOrIndex() && !rmRel->as().isRel()) { + // Handle a special form of `mov al|ax|eax|rax, [ptr64]` that doesn't use MOD. + if (opReg == Gp::kIdAx && !rmRel->as().hasBaseOrIndex()) { immValue = rmRel->as().offset(); - if (!is64Bit() || (is64Bit() && ((options & Inst::kOptionLongForm) || !Support::isInt32(immValue)))) { + if (x86GetMovAbsAddrType(this, writer, o0.size(), options, rmRel->as()) == BaseMem::kAddrTypeAbs) { opcode += 0xA0; goto EmitX86OpMovAbs; } @@ -1569,10 +1612,10 @@ CaseX86M_GPB_MulDiv: if (o1.size() == 1) FIXUP_GPB(o1, opReg); - // Handle a special form `mov [ptr64], al|ax|eax|rax` that doesn't use MOD. - if (o1.id() == Gp::kIdAx && !rmRel->as().hasBaseOrIndex() && !rmRel->as().isRel()) { + // Handle a special form of `mov [ptr64], al|ax|eax|rax` that doesn't use MOD. + if (opReg == Gp::kIdAx && !rmRel->as().hasBaseOrIndex()) { immValue = rmRel->as().offset(); - if (!is64Bit() || (is64Bit() && ((options & Inst::kOptionLongForm) || !Support::isInt32(immValue)))) { + if (x86GetMovAbsAddrType(this, writer, o1.size(), options, rmRel->as()) == BaseMem::kAddrTypeAbs) { opcode += 0xA2; goto EmitX86OpMovAbs; }