mirror of https://github.com/x64dbg/zydis
Merged internal encoder AVX/REX structs
- It was pretty redundant before - Required unnecessary routing logic - Minor decrease of required stack memory - Added `ZydisEmitMVEX` and generally more MVEX support
This commit is contained in:
parent
9437e89006
commit
c0fd657f15
281
src/Encoder.c
281
src/Encoder.c
|
@ -77,65 +77,28 @@ typedef struct ZydisRawInstruction_
|
||||||
} imms[2];
|
} imms[2];
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
// REX bits
|
||||||
uint8_t W;
|
uint8_t W;
|
||||||
uint8_t R;
|
uint8_t R;
|
||||||
uint8_t X;
|
uint8_t X;
|
||||||
uint8_t B;
|
uint8_t B;
|
||||||
} rex;
|
|
||||||
struct
|
// XOP/VEX bits
|
||||||
{
|
|
||||||
uint8_t R;
|
|
||||||
uint8_t X;
|
|
||||||
uint8_t B;
|
|
||||||
uint8_t m_mmmm;
|
|
||||||
uint8_t W;
|
|
||||||
uint8_t vvvv;
|
|
||||||
uint8_t L;
|
|
||||||
uint8_t pp;
|
|
||||||
} xop;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint8_t R;
|
|
||||||
uint8_t X;
|
|
||||||
uint8_t B;
|
|
||||||
uint8_t m_mmmm;
|
|
||||||
uint8_t W;
|
|
||||||
uint8_t vvvv;
|
|
||||||
uint8_t L;
|
|
||||||
uint8_t pp;
|
|
||||||
} vex;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint8_t R;
|
|
||||||
uint8_t X;
|
|
||||||
uint8_t B;
|
|
||||||
uint8_t R2;
|
|
||||||
uint8_t mm;
|
uint8_t mm;
|
||||||
uint8_t W;
|
|
||||||
uint8_t vvvv;
|
uint8_t vvvv;
|
||||||
|
uint8_t L;
|
||||||
uint8_t pp;
|
uint8_t pp;
|
||||||
|
|
||||||
|
// EVEX/MVEX bits
|
||||||
|
uint8_t R2;
|
||||||
uint8_t z;
|
uint8_t z;
|
||||||
uint8_t L2;
|
uint8_t L2;
|
||||||
uint8_t L;
|
|
||||||
uint8_t b;
|
uint8_t b;
|
||||||
uint8_t V2;
|
uint8_t V2;
|
||||||
uint8_t aaa;
|
uint8_t mask; // `.aaa` / `.kkk`
|
||||||
} evex;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint8_t R;
|
|
||||||
uint8_t X;
|
|
||||||
uint8_t B;
|
|
||||||
uint8_t R2;
|
|
||||||
uint8_t mmmm;
|
|
||||||
uint8_t W;
|
|
||||||
uint8_t vvvv;
|
|
||||||
uint8_t pp;
|
|
||||||
uint8_t E;
|
|
||||||
uint8_t SSS;
|
uint8_t SSS;
|
||||||
uint8_t V2;
|
uint8_t E;
|
||||||
uint8_t kkk;
|
} bits;
|
||||||
} mvex;
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint8_t mod;
|
uint8_t mod;
|
||||||
|
@ -265,10 +228,10 @@ static ZydisStatus ZydisEmitREX(ZydisEncoderContext* ctx)
|
||||||
ZYDIS_CHECK(ZydisEmitByte(
|
ZYDIS_CHECK(ZydisEmitByte(
|
||||||
ctx,
|
ctx,
|
||||||
0x40 |
|
0x40 |
|
||||||
(ctx->raw.rex.W & 0x01) << 3 |
|
(ctx->raw.bits.W & 0x01) << 3 |
|
||||||
(ctx->raw.rex.R & 0x01) << 2 |
|
(ctx->raw.bits.R & 0x01) << 2 |
|
||||||
(ctx->raw.rex.X & 0x01) << 1 |
|
(ctx->raw.bits.X & 0x01) << 1 |
|
||||||
(ctx->raw.rex.B & 0x01) << 0
|
(ctx->raw.bits.B & 0x01) << 0
|
||||||
));
|
));
|
||||||
return ZYDIS_STATUS_SUCCESS;
|
return ZYDIS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -278,18 +241,16 @@ static ZydisStatus ZydisEmitVEX(ZydisEncoderContext* ctx)
|
||||||
ZYDIS_ASSERT(ctx);
|
ZYDIS_ASSERT(ctx);
|
||||||
|
|
||||||
// Can we use short 2-byte VEX encoding?
|
// Can we use short 2-byte VEX encoding?
|
||||||
if (ctx->raw.vex.X == 0 &&
|
if (ctx->raw.bits.X == 0 && ctx->raw.bits.B == 0 &&
|
||||||
ctx->raw.vex.B == 0 &&
|
ctx->raw.bits.W == 0 && ctx->raw.bits.mm == 1)
|
||||||
ctx->raw.vex.W == 0 &&
|
|
||||||
ctx->raw.vex.m_mmmm == 1)
|
|
||||||
{
|
{
|
||||||
ZYDIS_CHECK(ZydisEmitByte(ctx, 0xC5));
|
ZYDIS_CHECK(ZydisEmitByte(ctx, 0xC5));
|
||||||
ZYDIS_CHECK(ZydisEmitByte(
|
ZYDIS_CHECK(ZydisEmitByte(
|
||||||
ctx,
|
ctx,
|
||||||
(~ctx->raw.vex.R & 0x01) << 7 |
|
(~ctx->raw.bits.R & 0x01) << 7 |
|
||||||
(~ctx->raw.vex.vvvv & 0x0F) << 3 |
|
(~ctx->raw.bits.vvvv & 0x0F) << 3 |
|
||||||
( ctx->raw.vex.L & 0x01) << 2 |
|
( ctx->raw.bits.L & 0x01) << 2 |
|
||||||
( ctx->raw.vex.pp & 0x03) << 0
|
( ctx->raw.bits.pp & 0x03) << 0
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
// Nope, use 3-byte VEX.
|
// Nope, use 3-byte VEX.
|
||||||
|
@ -298,17 +259,17 @@ static ZydisStatus ZydisEmitVEX(ZydisEncoderContext* ctx)
|
||||||
ZYDIS_CHECK(ZydisEmitByte(ctx, 0xC4));
|
ZYDIS_CHECK(ZydisEmitByte(ctx, 0xC4));
|
||||||
ZYDIS_CHECK(ZydisEmitByte(
|
ZYDIS_CHECK(ZydisEmitByte(
|
||||||
ctx,
|
ctx,
|
||||||
(~ctx->raw.vex.R & 0x01) << 7 |
|
(~ctx->raw.bits.R & 0x01) << 7 |
|
||||||
(~ctx->raw.vex.X & 0x01) << 6 |
|
(~ctx->raw.bits.X & 0x01) << 6 |
|
||||||
(~ctx->raw.vex.B & 0x01) << 5 |
|
(~ctx->raw.bits.B & 0x01) << 5 |
|
||||||
( ctx->raw.vex.m_mmmm & 0x1F) << 0
|
( ctx->raw.bits.mm & 0x1F) << 0
|
||||||
));
|
));
|
||||||
ZYDIS_CHECK(ZydisEmitByte(
|
ZYDIS_CHECK(ZydisEmitByte(
|
||||||
ctx,
|
ctx,
|
||||||
( ctx->raw.vex.W & 0x01) << 7 |
|
( ctx->raw.bits.W & 0x01) << 7 |
|
||||||
(~ctx->raw.vex.vvvv & 0x0F) << 3 |
|
(~ctx->raw.bits.vvvv & 0x0F) << 3 |
|
||||||
( ctx->raw.vex.L & 0x01) << 2 |
|
( ctx->raw.bits.L & 0x01) << 2 |
|
||||||
( ctx->raw.vex.pp & 0x03) << 0
|
( ctx->raw.bits.pp & 0x03) << 0
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,26 +282,54 @@ static ZydisStatus ZydisEmitEVEX(ZydisEncoderContext* ctx)
|
||||||
ZYDIS_CHECK(ZydisEmitByte(ctx, 0x62));
|
ZYDIS_CHECK(ZydisEmitByte(ctx, 0x62));
|
||||||
ZYDIS_CHECK(ZydisEmitByte(
|
ZYDIS_CHECK(ZydisEmitByte(
|
||||||
ctx,
|
ctx,
|
||||||
(ctx->raw.evex.R & 0x01) << 7 |
|
(ctx->raw.bits.R & 0x01) << 7 |
|
||||||
(ctx->raw.evex.X & 0x01) << 6 |
|
(ctx->raw.bits.X & 0x01) << 6 |
|
||||||
(ctx->raw.evex.B & 0x01) << 5 |
|
(ctx->raw.bits.B & 0x01) << 5 |
|
||||||
(ctx->raw.evex.R2 & 0x01) << 4 |
|
(ctx->raw.bits.R2 & 0x01) << 4 |
|
||||||
(ctx->raw.evex.mm & 0x03) << 0
|
(ctx->raw.bits.mm & 0x03) << 0
|
||||||
));
|
));
|
||||||
ZYDIS_CHECK(ZydisEmitByte(
|
ZYDIS_CHECK(ZydisEmitByte(
|
||||||
ctx,
|
ctx,
|
||||||
(ctx->raw.evex.W & 0x01) << 7 |
|
(ctx->raw.bits.W & 0x01) << 7 |
|
||||||
(ctx->raw.evex.vvvv & 0x0F) << 3 |
|
(ctx->raw.bits.vvvv & 0x0F) << 3 |
|
||||||
(ctx->raw.evex.pp & 0x03) << 0
|
(ctx->raw.bits.pp & 0x03) << 0
|
||||||
));
|
));
|
||||||
ZYDIS_CHECK(ZydisEmitByte(
|
ZYDIS_CHECK(ZydisEmitByte(
|
||||||
ctx,
|
ctx,
|
||||||
(ctx->raw.evex.z & 0x01) << 7 |
|
(ctx->raw.bits.z & 0x01) << 7 |
|
||||||
(ctx->raw.evex.L2 & 0x01) << 6 |
|
(ctx->raw.bits.L2 & 0x01) << 6 |
|
||||||
(ctx->raw.evex.L & 0x01) << 5 |
|
(ctx->raw.bits.L & 0x01) << 5 |
|
||||||
(ctx->raw.evex.b & 0x01) << 4 |
|
(ctx->raw.bits.b & 0x01) << 4 |
|
||||||
(ctx->raw.evex.V2 & 0x01) << 3 |
|
(ctx->raw.bits.V2 & 0x01) << 3 |
|
||||||
(ctx->raw.evex.aaa & 0x07) << 0
|
(ctx->raw.bits.mask & 0x07) << 0
|
||||||
|
));
|
||||||
|
return ZYDIS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ZydisStatus ZydisEmitMVEX(ZydisEncoderContext* ctx)
|
||||||
|
{
|
||||||
|
ZYDIS_ASSERT(ctx);
|
||||||
|
ZYDIS_CHECK(ZydisEmitByte(ctx, 0x62));
|
||||||
|
ZYDIS_CHECK(ZydisEmitByte(
|
||||||
|
ctx,
|
||||||
|
(ctx->raw.bits.R & 0x01) << 7 |
|
||||||
|
(ctx->raw.bits.X & 0x01) << 6 |
|
||||||
|
(ctx->raw.bits.B & 0x01) << 5 |
|
||||||
|
(ctx->raw.bits.R2 & 0x01) << 4 |
|
||||||
|
(ctx->raw.bits.mm & 0x0F) << 0
|
||||||
|
));
|
||||||
|
ZYDIS_CHECK(ZydisEmitByte(
|
||||||
|
ctx,
|
||||||
|
(ctx->raw.bits.W & 0x01) << 7 |
|
||||||
|
(ctx->raw.bits.vvvv & 0x0F) << 3 |
|
||||||
|
(ctx->raw.bits.pp & 0x03) << 0
|
||||||
|
));
|
||||||
|
ZYDIS_CHECK(ZydisEmitByte(
|
||||||
|
ctx,
|
||||||
|
(ctx->raw.bits.E & 0x01) << 7 |
|
||||||
|
(ctx->raw.bits.SSS & 0x07) << 4 |
|
||||||
|
(ctx->raw.bits.V2 & 0x01) << 3 |
|
||||||
|
(ctx->raw.bits.mask & 0x07) << 0
|
||||||
));
|
));
|
||||||
return ZYDIS_STATUS_SUCCESS;
|
return ZYDIS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -351,17 +340,17 @@ static ZydisStatus ZydisEmitXOP(ZydisEncoderContext* ctx)
|
||||||
ZYDIS_CHECK(ZydisEmitByte(ctx, 0x8F));
|
ZYDIS_CHECK(ZydisEmitByte(ctx, 0x8F));
|
||||||
ZYDIS_CHECK(ZydisEmitByte(
|
ZYDIS_CHECK(ZydisEmitByte(
|
||||||
ctx,
|
ctx,
|
||||||
(ctx->raw.xop.R & 0x01) << 7 |
|
(ctx->raw.bits.R & 0x01) << 7 |
|
||||||
(ctx->raw.xop.X & 0x01) << 6 |
|
(ctx->raw.bits.X & 0x01) << 6 |
|
||||||
(ctx->raw.xop.B & 0x01) << 5 |
|
(ctx->raw.bits.B & 0x01) << 5 |
|
||||||
(ctx->raw.xop.m_mmmm & 0x1F) << 0
|
(ctx->raw.bits.mm & 0x1F) << 0
|
||||||
));
|
));
|
||||||
ZYDIS_CHECK(ZydisEmitByte(
|
ZYDIS_CHECK(ZydisEmitByte(
|
||||||
ctx,
|
ctx,
|
||||||
(ctx->raw.xop.W & 0x01) << 7 |
|
(ctx->raw.bits.W & 0x01) << 7 |
|
||||||
(ctx->raw.xop.vvvv & 0x0F) << 3 |
|
(ctx->raw.bits.vvvv & 0x0F) << 3 |
|
||||||
(ctx->raw.xop.L & 0x01) << 2 |
|
(ctx->raw.bits.L & 0x01) << 2 |
|
||||||
(ctx->raw.xop.pp & 0x03) << 0
|
(ctx->raw.bits.pp & 0x03) << 0
|
||||||
));
|
));
|
||||||
return ZYDIS_STATUS_SUCCESS;
|
return ZYDIS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -689,18 +678,19 @@ static ZydisStatus ZydisPrepareOpcode(ZydisEncoderContext* ctx, const ZydisInstr
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ZYDIS_INSTRUCTION_ENCODING_VEX:
|
case ZYDIS_INSTRUCTION_ENCODING_VEX:
|
||||||
ctx->raw.vex.m_mmmm = match->insn->opcodeMap;
|
ctx->raw.bits.mm = match->insn->opcodeMap;
|
||||||
ZYDIS_ASSERT(ctx->raw.vex.m_mmmm <= 0x03);
|
ZYDIS_ASSERT(ctx->raw.bits.mm <= 0x03);
|
||||||
break;
|
break;
|
||||||
case ZYDIS_INSTRUCTION_ENCODING_EVEX:
|
case ZYDIS_INSTRUCTION_ENCODING_EVEX:
|
||||||
ctx->raw.evex.mm = match->insn->opcodeMap;
|
case ZYDIS_INSTRUCTION_ENCODING_MVEX:
|
||||||
ZYDIS_ASSERT(ctx->raw.evex.mm <= 0x03);
|
ctx->raw.bits.mm = match->insn->opcodeMap;
|
||||||
|
ZYDIS_ASSERT(ctx->raw.bits.mm <= 0x03);
|
||||||
break;
|
break;
|
||||||
case ZYDIS_INSTRUCTION_ENCODING_XOP:
|
case ZYDIS_INSTRUCTION_ENCODING_XOP:
|
||||||
ctx->raw.xop.m_mmmm =
|
ctx->raw.bits.mm =
|
||||||
match->insn->opcodeMap - ZYDIS_OPCODE_MAP_XOP8 + 0x08;
|
match->insn->opcodeMap - ZYDIS_OPCODE_MAP_XOP8 + 0x08;
|
||||||
ZYDIS_ASSERT(ctx->raw.xop.m_mmmm >= 0x08);
|
ZYDIS_ASSERT(ctx->raw.bits.mm >= 0x08);
|
||||||
ZYDIS_ASSERT(ctx->raw.xop.m_mmmm <= 0x0B);
|
ZYDIS_ASSERT(ctx->raw.bits.mm <= 0x0B);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ZYDIS_UNREACHABLE;
|
ZYDIS_UNREACHABLE;
|
||||||
|
@ -731,57 +721,18 @@ static ZydisStatus ZydisPrepareRegOperand(ZydisEncoderContext* ctx,
|
||||||
// No top bit? Quick exit.
|
// No top bit? Quick exit.
|
||||||
if (!topBit) return ZYDIS_STATUS_SUCCESS;
|
if (!topBit) return ZYDIS_STATUS_SUCCESS;
|
||||||
|
|
||||||
switch (ctx->req->encoding)
|
if ((ctx->req->encoding == ZYDIS_INSTRUCTION_ENCODING_DEFAULT ||
|
||||||
|
ctx->req->encoding == ZYDIS_INSTRUCTION_ENCODING_3DNOW) && topBit)
|
||||||
{
|
{
|
||||||
case ZYDIS_INSTRUCTION_ENCODING_DEFAULT:
|
ctx->raw.derivedAttrs |= ZYDIS_ATTRIB_HAS_REX;
|
||||||
case ZYDIS_INSTRUCTION_ENCODING_3DNOW:
|
}
|
||||||
switch (topBitDst)
|
|
||||||
{
|
switch (topBitDst)
|
||||||
case 'B': ctx->raw.rex.B = topBit; break;
|
{
|
||||||
case 'R': ctx->raw.rex.R = topBit; break;
|
case 'B': ctx->raw.bits.B = topBit; break;
|
||||||
case 'X': ctx->raw.rex.X = topBit; break;
|
case 'R': ctx->raw.bits.R = topBit; break;
|
||||||
default: ZYDIS_UNREACHABLE;
|
case 'X': ctx->raw.bits.X = topBit; break;
|
||||||
}
|
default: ZYDIS_UNREACHABLE;
|
||||||
if (topBit) ctx->raw.derivedAttrs |= ZYDIS_ATTRIB_HAS_REX;
|
|
||||||
break;
|
|
||||||
case ZYDIS_INSTRUCTION_ENCODING_VEX:
|
|
||||||
switch (topBitDst)
|
|
||||||
{
|
|
||||||
case 'B': ctx->raw.vex.B = topBit; break;
|
|
||||||
case 'R': ctx->raw.vex.R = topBit; break;
|
|
||||||
case 'X': ctx->raw.vex.X = topBit; break;
|
|
||||||
default: ZYDIS_UNREACHABLE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ZYDIS_INSTRUCTION_ENCODING_XOP:
|
|
||||||
switch (topBitDst)
|
|
||||||
{
|
|
||||||
case 'B': ctx->raw.xop.B = topBit; break;
|
|
||||||
case 'R': ctx->raw.xop.R = topBit; break;
|
|
||||||
case 'X': ctx->raw.xop.X = topBit; break;
|
|
||||||
default: ZYDIS_UNREACHABLE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ZYDIS_INSTRUCTION_ENCODING_EVEX:
|
|
||||||
switch (topBitDst)
|
|
||||||
{
|
|
||||||
case 'B': ctx->raw.evex.B = topBit; break;
|
|
||||||
case 'R': ctx->raw.evex.R = topBit; break;
|
|
||||||
case 'X': ctx->raw.evex.X = topBit; break;
|
|
||||||
default: ZYDIS_UNREACHABLE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ZYDIS_INSTRUCTION_ENCODING_MVEX:
|
|
||||||
switch (topBitDst)
|
|
||||||
{
|
|
||||||
case 'B': ctx->raw.mvex.B = topBit; break;
|
|
||||||
case 'R': ctx->raw.mvex.R = topBit; break;
|
|
||||||
case 'X': ctx->raw.mvex.X = topBit; break;
|
|
||||||
default: ZYDIS_UNREACHABLE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return ZYDIS_STATUS_IMPOSSIBLE_INSTRUCTION; // TODO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ZYDIS_STATUS_SUCCESS;
|
return ZYDIS_STATUS_SUCCESS;
|
||||||
|
@ -1008,26 +959,20 @@ static ZydisStatus ZydisPrepareOperand(ZydisEncoderContext* ctx,
|
||||||
int16_t reg = ZydisRegisterGetId(reqOperand->reg);
|
int16_t reg = ZydisRegisterGetId(reqOperand->reg);
|
||||||
if (reg == -1) return ZYDIS_STATUS_INVALID_PARAMETER;
|
if (reg == -1) return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||||
ctx->raw.opcode += reg & 0x07;
|
ctx->raw.opcode += reg & 0x07;
|
||||||
ctx->raw.rex.B = (reg & 0x08) >> 3;
|
ctx->raw.bits.B = (reg & 0x08) >> 3;
|
||||||
if (ctx->raw.rex.B) ctx->raw.derivedAttrs |= ZYDIS_ATTRIB_HAS_REX;
|
if (ctx->raw.bits.B) ctx->raw.derivedAttrs |= ZYDIS_ATTRIB_HAS_REX;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ZYDIS_OPERAND_ENCODING_NDSNDD:
|
case ZYDIS_OPERAND_ENCODING_NDSNDD:
|
||||||
{
|
{
|
||||||
int16_t reg = ZydisRegisterGetId(reqOperand->reg);
|
int16_t reg = ZydisRegisterGetId(reqOperand->reg);
|
||||||
if (reg == -1) return ZYDIS_STATUS_INVALID_PARAMETER;
|
if (reg == -1) return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||||
ctx->raw.vex.vvvv = ctx->raw.xop.vvvv = ctx->raw.evex.vvvv = reg & 0x0F;
|
ctx->raw.bits.vvvv = ctx->raw.bits.vvvv = ctx->raw.bits.vvvv = reg & 0x0F;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ZYDIS_OPERAND_ENCODING_MASK:
|
case ZYDIS_OPERAND_ENCODING_MASK:
|
||||||
{
|
{
|
||||||
uint8_t regId = reqOperand->reg - ZYDIS_REGISTER_K0;
|
ctx->raw.bits.mask = reqOperand->reg - ZYDIS_REGISTER_K0;
|
||||||
switch (match->insn->encoding)
|
|
||||||
{
|
|
||||||
case ZYDIS_INSTRUCTION_ENCODING_EVEX: ctx->raw.evex.aaa = regId; break;
|
|
||||||
case ZYDIS_INSTRUCTION_ENCODING_MVEX: ctx->raw.mvex.kkk = regId; break;
|
|
||||||
default: ZYDIS_UNREACHABLE;
|
|
||||||
}
|
|
||||||
} break;
|
} break;
|
||||||
case ZYDIS_OPERAND_ENCODING_IS4:
|
case ZYDIS_OPERAND_ENCODING_IS4:
|
||||||
{
|
{
|
||||||
|
@ -1085,14 +1030,11 @@ static void ZydisPrepareMandatoryPrefixes(ZydisEncoderContext* ctx,
|
||||||
case ZYDIS_INSTRUCTION_ENCODING_3DNOW:
|
case ZYDIS_INSTRUCTION_ENCODING_3DNOW:
|
||||||
ctx->raw.mandatoryPrefix = prefix;
|
ctx->raw.mandatoryPrefix = prefix;
|
||||||
break;
|
break;
|
||||||
case ZYDIS_INSTRUCTION_ENCODING_VEX:
|
|
||||||
ctx->raw.vex.pp = prefix;
|
|
||||||
break;
|
|
||||||
case ZYDIS_INSTRUCTION_ENCODING_EVEX:
|
|
||||||
ctx->raw.evex.pp = prefix;
|
|
||||||
break;
|
|
||||||
case ZYDIS_INSTRUCTION_ENCODING_XOP:
|
case ZYDIS_INSTRUCTION_ENCODING_XOP:
|
||||||
ctx->raw.xop.pp = prefix;
|
case ZYDIS_INSTRUCTION_ENCODING_VEX:
|
||||||
|
case ZYDIS_INSTRUCTION_ENCODING_EVEX:
|
||||||
|
case ZYDIS_INSTRUCTION_ENCODING_MVEX:
|
||||||
|
ctx->raw.bits.pp = prefix;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ZYDIS_UNREACHABLE;
|
ZYDIS_UNREACHABLE;
|
||||||
|
@ -1481,15 +1423,9 @@ ZydisStatus ZydisEncoderEncodeInstruction(void* buffer, size_t* bufferLen,
|
||||||
// TODO: Check compatibility of requested prefixes to found instruction.
|
// TODO: Check compatibility of requested prefixes to found instruction.
|
||||||
|
|
||||||
// Prepare prefix bits.
|
// Prepare prefix bits.
|
||||||
ctx.raw.evex.B = match.insn->evexB;
|
ctx.raw.bits.B = match.insn->evexB;
|
||||||
ctx.raw.evex.L = match.insn->vectorLength & 0x01;
|
ctx.raw.bits.L = match.insn->vectorLength & 0x01;
|
||||||
ctx.raw.evex.L2 = match.insn->vectorLength & 0x02;
|
ctx.raw.bits.L2 = match.insn->vectorLength & 0x02;
|
||||||
ctx.raw.vex.L = match.insn->vectorLength & 0x01;
|
|
||||||
if (match.insn->rexW)
|
|
||||||
{
|
|
||||||
ctx.raw.rex.W = 1;
|
|
||||||
ctx.raw.derivedAttrs |= ZYDIS_ATTRIB_HAS_REX;
|
|
||||||
}
|
|
||||||
ZydisPrepareMandatoryPrefixes(&ctx, &match);
|
ZydisPrepareMandatoryPrefixes(&ctx, &match);
|
||||||
|
|
||||||
// Prepare opcode.
|
// Prepare opcode.
|
||||||
|
@ -1511,6 +1447,7 @@ ZydisStatus ZydisEncoderEncodeInstruction(void* buffer, size_t* bufferLen,
|
||||||
|
|
||||||
switch (match.insn->encoding)
|
switch (match.insn->encoding)
|
||||||
{
|
{
|
||||||
|
case ZYDIS_INSTRUCTION_ENCODING_MVEX: ZYDIS_CHECK(ZydisEmitMVEX(&ctx)); break;
|
||||||
case ZYDIS_INSTRUCTION_ENCODING_EVEX: ZYDIS_CHECK(ZydisEmitEVEX(&ctx)); break;
|
case ZYDIS_INSTRUCTION_ENCODING_EVEX: ZYDIS_CHECK(ZydisEmitEVEX(&ctx)); break;
|
||||||
case ZYDIS_INSTRUCTION_ENCODING_VEX: ZYDIS_CHECK(ZydisEmitVEX (&ctx)); break;
|
case ZYDIS_INSTRUCTION_ENCODING_VEX: ZYDIS_CHECK(ZydisEmitVEX (&ctx)); break;
|
||||||
case ZYDIS_INSTRUCTION_ENCODING_XOP: ZYDIS_CHECK(ZydisEmitXOP (&ctx)); break;
|
case ZYDIS_INSTRUCTION_ENCODING_XOP: ZYDIS_CHECK(ZydisEmitXOP (&ctx)); break;
|
||||||
|
|
Loading…
Reference in New Issue