From fca8b8d7ebbf1cea3c721b4a3438bc3eccb8ee39 Mon Sep 17 00:00:00 2001 From: boykopovar Date: Wed, 5 Aug 2026 12:41:18 +0300 Subject: [PATCH] fix(code): add extrq decoding --- .../codegen/x86/X64OpcodeConstants.hpp | 2 ++ .../codegen/src/x86/X64InstructionDecoder.cpp | 22 +++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/core/codegen/include/codegen/x86/X64OpcodeConstants.hpp b/core/codegen/include/codegen/x86/X64OpcodeConstants.hpp index c88ef7cf9..69bc3598f 100644 --- a/core/codegen/include/codegen/x86/X64OpcodeConstants.hpp +++ b/core/codegen/include/codegen/x86/X64OpcodeConstants.hpp @@ -156,6 +156,8 @@ inline constexpr std::uint8_t TwoBytePextrw = 0xC5; inline constexpr std::uint8_t TwoByteShufpsImm8 = 0xC2; inline constexpr std::uint8_t TwoByteShufpdImm8 = 0xC6; inline constexpr std::uint8_t TwoByteGrp9 = 0xC7; +inline constexpr std::uint8_t TwoByteExtrqInsertqImm8Imm8 = 0x78; +inline constexpr std::uint8_t TwoByteExtrqInsertqModRm = 0x79; inline constexpr std::uint8_t VexNoModRmMin = 0x77; inline constexpr std::uint8_t VexNoModRmMax = 0x77; diff --git a/core/codegen/src/x86/X64InstructionDecoder.cpp b/core/codegen/src/x86/X64InstructionDecoder.cpp index 270513870..68860ec52 100644 --- a/core/codegen/src/x86/X64InstructionDecoder.cpp +++ b/core/codegen/src/x86/X64InstructionDecoder.cpp @@ -11,11 +11,18 @@ std::size_t X64InstructionDecoder::Decode(const std::uint8_t* data, std::size_t bool rexPresent = false; std::uint8_t rex = 0; bool operandSizeOverride = false; + bool repnePrefix = false; while (pos < available) { const std::uint8_t b = data[pos]; - if (b == PrefixLock || b == PrefixRepne || b == PrefixRep || + if (b == PrefixRepne) { + repnePrefix = true; + pos += 1; + continue; + } + + if (b == PrefixLock || b == PrefixRep || b == PrefixSegCs || b == PrefixSegSs || b == PrefixSegDs || b == PrefixSegEs || b == PrefixSegFs || b == PrefixSegGs) { pos += 1; @@ -196,7 +203,18 @@ std::size_t X64InstructionDecoder::Decode(const std::uint8_t* data, std::size_t immediateSize = ImmSize8; } } else { - if (opcode >= TwoByteJccRel32Min && opcode <= TwoByteJccRel32Max) { + if (opcode == TwoByteExtrqInsertqImm8Imm8) { + if (!operandSizeOverride && !repnePrefix) { + throw CodegenException("Unsupported 0F 78 opcode without SSE4A prefix"); + } + hasModRm = true; + immediateSize = ImmSize16; + } else if (opcode == TwoByteExtrqInsertqModRm) { + if (!operandSizeOverride && !repnePrefix) { + throw CodegenException("Unsupported 0F 79 opcode without SSE4A prefix"); + } + hasModRm = true; + } else if (opcode >= TwoByteJccRel32Min && opcode <= TwoByteJccRel32Max) { immediateSize = ImmSize32; } else if (opcode == TwoByteMovImm8ModRm) { hasModRm = true;