Compare commits
10 Commits
0a36604c81
...
9263c3d6b2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9263c3d6b2 | ||
|
|
e2480e9f85 | ||
|
|
6abc971576 | ||
|
|
48f886e130 | ||
|
|
1290e9f094 | ||
|
|
bbc1b0b648 | ||
|
|
8dad665751 | ||
|
|
247acd6221 | ||
|
|
239be46d4a | ||
|
|
0297f66de6 |
@@ -1449,6 +1449,9 @@ main(int argc, char** argv)
|
||||
TEST("\xc5\xf9\x6e\xc8", "vmovd xmm1, eax");
|
||||
TEST64("\xc4\xe1\xf9\x6e\xc8", "vmovq xmm1, rax");
|
||||
TEST32("\xc4\xe1\xf9\x6e\xc8", "vmovd xmm1, eax");
|
||||
TEST("\xc5\xf9\x7e\xc8", "vmovd eax, xmm1");
|
||||
TEST64("\xc4\xe1\xf9\x7e\xc8", "vmovq rax, xmm1");
|
||||
TEST32("\xc4\xe1\xf9\x7e\xc8", "vmovd eax, xmm1");
|
||||
TEST("\xc5\xf2\x10\xc2", "vmovss xmm0, xmm1, xmm2");
|
||||
TEST("\xc5\xf6\x10\xc2", "vmovss xmm0, xmm1, xmm2"); // VEX.L=1
|
||||
TEST("\xc5\xfa\x10\x04\x25\x34\x12\x00\x00", "vmovss xmm0, dword ptr [0x1234]");
|
||||
@@ -1547,6 +1550,7 @@ main(int argc, char** argv)
|
||||
|
||||
TEST("\xc4\xe3\x71\x20\xc0\x00", "vpinsrb xmm0, xmm1, al, 0x0");
|
||||
TEST("\xc4\xe3\xf1\x20\xc0\x00", "vpinsrb xmm0, xmm1, al, 0x0");
|
||||
TEST("\xc4\xe3\x71\x20\xc6\x00", "vpinsrb xmm0, xmm1, sil, 0x0");
|
||||
TEST("\xc4\xe1\x71\xc4\xc0\x00", "vpinsrw xmm0, xmm1, ax, 0x0");
|
||||
TEST("\xc4\xe1\xf1\xc4\xc0\x00", "vpinsrw xmm0, xmm1, ax, 0x0");
|
||||
TEST("\xc4\xe3\x71\x22\xc0\x00", "vpinsrd xmm0, xmm1, eax, 0x0");
|
||||
|
||||
91
decode.c
91
decode.c
@@ -91,6 +91,10 @@ struct InstrDesc
|
||||
#define DESC_LOCK(desc) (((desc)->operand_indices >> 11) & 1)
|
||||
#define DESC_VSIB(desc) (((desc)->operand_indices >> 15) & 1)
|
||||
#define DESC_OPSIZE(desc) (((desc)->reg_types >> 11) & 7)
|
||||
#define DESC_MODRM_SIZE(desc) (((desc)->operand_sizes >> 0) & 3)
|
||||
#define DESC_MODREG_SIZE(desc) (((desc)->operand_sizes >> 2) & 3)
|
||||
#define DESC_VEXREG_SIZE(desc) (((desc)->operand_sizes >> 4) & 3)
|
||||
#define DESC_IMM_SIZE(desc) (((desc)->operand_sizes >> 6) & 3)
|
||||
#define DESC_LEGACY(desc) (((desc)->operand_sizes >> 8) & 1)
|
||||
#define DESC_SIZE_FIX1(desc) (((desc)->operand_sizes >> 10) & 7)
|
||||
#define DESC_SIZE_FIX2(desc) (((desc)->operand_sizes >> 13) & 3)
|
||||
@@ -245,18 +249,17 @@ fd_decode(const uint8_t* buffer, size_t len_sz, int mode_int, uintptr_t address,
|
||||
{
|
||||
if (byte & 0x08) // Bit 3 of opcode_escape must be clear.
|
||||
return FD_ERR_UD;
|
||||
opcode_escape = (byte & 0x07);
|
||||
_Static_assert(PREFIX_REXRR == 0x10, "wrong REXRR value");
|
||||
if (mode == DECODE_64)
|
||||
prefix_rex |= (byte & PREFIX_REXRR) ^ PREFIX_REXRR;
|
||||
}
|
||||
else // 3-byte VEX
|
||||
{
|
||||
if (byte & 0x1c) // Bits 4:2 of opcode_escape must be clear.
|
||||
if (byte & 0x18) // Bits 4:3 of opcode_escape must be clear.
|
||||
return FD_ERR_UD;
|
||||
opcode_escape = (byte & 0x03); // 4 is table index with VEX
|
||||
}
|
||||
|
||||
opcode_escape = (byte & 0x07);
|
||||
if (UNLIKELY(opcode_escape == 0)) {
|
||||
int prefix_len = vex_prefix == 0x62 ? 4 : 3;
|
||||
// Pretend to decode the prefix plus one opcode byte.
|
||||
@@ -451,14 +454,14 @@ direct:
|
||||
else if (UNLIKELY(prefix_rex & PREFIX_REXRR))
|
||||
return FD_ERR_UD;
|
||||
op_modreg->type = FD_OT_REG;
|
||||
op_modreg->size = operand_sizes[(desc->operand_sizes >> 2) & 3];
|
||||
op_modreg->size = operand_sizes[DESC_MODREG_SIZE(desc)];
|
||||
op_modreg->reg = reg_idx;
|
||||
}
|
||||
|
||||
if (DESC_HAS_MODRM(desc))
|
||||
{
|
||||
FdOp* op_modrm = &instr->operands[DESC_MODRM_IDX(desc)];
|
||||
op_modrm->size = operand_sizes[(desc->operand_sizes >> 0) & 3];
|
||||
op_modrm->size = operand_sizes[DESC_MODRM_SIZE(desc)];
|
||||
|
||||
unsigned rm = op_byte & 0x07;
|
||||
if (op_byte >= 0xc0)
|
||||
@@ -475,33 +478,35 @@ direct:
|
||||
}
|
||||
else
|
||||
{
|
||||
bool vsib = UNLIKELY(DESC_VSIB(desc));
|
||||
|
||||
// EVEX.z for memory destination operand is UD.
|
||||
if (UNLIKELY(prefix_evex & 0x80) && DESC_MODRM_IDX(desc) == 0)
|
||||
return FD_ERR_UD;
|
||||
|
||||
// EVEX.b for memory-operand without broadcast support is UD.
|
||||
unsigned dispscale = 0;
|
||||
if (UNLIKELY(prefix_evex & 0x10)) {
|
||||
if (UNLIKELY(!DESC_EVEX_BCST(desc)))
|
||||
|
||||
if (UNLIKELY(prefix_evex)) {
|
||||
// EVEX.z for memory destination operand is UD.
|
||||
if (UNLIKELY(prefix_evex & 0x80) && DESC_MODRM_IDX(desc) == 0)
|
||||
return FD_ERR_UD;
|
||||
if (UNLIKELY(DESC_EVEX_BCST16(desc)))
|
||||
dispscale = 1;
|
||||
else
|
||||
dispscale = prefix_rex & PREFIX_REXW ? 3 : 2;
|
||||
instr->segment |= dispscale << 6; // Store broadcast size
|
||||
op_modrm->type = FD_OT_MEMBCST;
|
||||
} else {
|
||||
if (UNLIKELY(prefix_evex))
|
||||
|
||||
// EVEX.b for memory-operand without broadcast support is UD.
|
||||
if (UNLIKELY(prefix_evex & 0x10)) {
|
||||
if (UNLIKELY(!DESC_EVEX_BCST(desc)))
|
||||
return FD_ERR_UD;
|
||||
if (UNLIKELY(DESC_EVEX_BCST16(desc)))
|
||||
dispscale = 1;
|
||||
else
|
||||
dispscale = prefix_rex & PREFIX_REXW ? 3 : 2;
|
||||
instr->segment |= dispscale << 6; // Store broadcast size
|
||||
op_modrm->type = FD_OT_MEMBCST;
|
||||
} else {
|
||||
dispscale = op_modrm->size - 1;
|
||||
op_modrm->type = FD_OT_MEM;
|
||||
}
|
||||
} else {
|
||||
op_modrm->type = FD_OT_MEM;
|
||||
}
|
||||
|
||||
// 16-bit address size implies different ModRM encoding
|
||||
if (UNLIKELY(addr_size == 1)) {
|
||||
ASSUME(mode == DECODE_32);
|
||||
if (vsib) // 16-bit address size + VSIB is UD
|
||||
if (UNLIKELY(DESC_VSIB(desc))) // 16-bit addr size + VSIB is UD
|
||||
return FD_ERR_UD;
|
||||
if (rm < 6)
|
||||
op_modrm->misc = rm & 1 ? FD_REG_DI : FD_REG_SI;
|
||||
@@ -532,8 +537,7 @@ direct:
|
||||
|
||||
// SIB byte
|
||||
uint8_t base = rm;
|
||||
if (rm == 4)
|
||||
{
|
||||
if (rm == 4) {
|
||||
if (UNLIKELY(off >= len))
|
||||
return FD_ERR_PARTIAL;
|
||||
uint8_t sib = buffer[off++];
|
||||
@@ -541,22 +545,25 @@ direct:
|
||||
unsigned idx = (sib & 0x38) >> 3;
|
||||
idx += prefix_rex & PREFIX_REXX ? 8 : 0;
|
||||
base = sib & 0x07;
|
||||
if (!vsib && idx == 4)
|
||||
if (idx == 4)
|
||||
idx = FD_REG_NONE;
|
||||
if (vsib && prefix_evex) {
|
||||
// EVEX.V':EVEX.X:SIB.idx
|
||||
idx |= prefix_evex & 0x8 ? 0 : 0x10;
|
||||
}
|
||||
op_modrm->misc = scale | idx;
|
||||
}
|
||||
else
|
||||
{
|
||||
// VSIB must have a memory operand with SIB byte.
|
||||
if (vsib)
|
||||
return FD_ERR_UD;
|
||||
} else {
|
||||
op_modrm->misc = FD_REG_NONE;
|
||||
}
|
||||
|
||||
if (UNLIKELY(DESC_VSIB(desc))) {
|
||||
// VSIB must have a memory operand with SIB byte.
|
||||
if (rm != 4)
|
||||
return FD_ERR_UD;
|
||||
_Static_assert(FD_REG_NONE == 0x3f, "unexpected FD_REG_NONE");
|
||||
// idx 4 is valid for VSIB
|
||||
if ((op_modrm->misc & 0x3f) == FD_REG_NONE)
|
||||
op_modrm->misc &= 0xc4;
|
||||
if (prefix_evex) // EVEX.V':EVEX.X:SIB.idx
|
||||
op_modrm->misc |= prefix_evex & 0x8 ? 0 : 0x10;
|
||||
}
|
||||
|
||||
// RIP-relative addressing only if SIB-byte is absent
|
||||
if (op_byte < 0x40 && rm == 5 && mode == DECODE_64)
|
||||
op_modrm->reg = FD_REG_IP;
|
||||
@@ -592,7 +599,7 @@ direct:
|
||||
} else {
|
||||
operand->type = FD_OT_REG;
|
||||
// Without VEX prefix, this encodes an implicit register
|
||||
operand->size = operand_sizes[(desc->operand_sizes >> 4) & 3];
|
||||
operand->size = operand_sizes[DESC_VEXREG_SIZE(desc)];
|
||||
if (mode == DECODE_32)
|
||||
vex_operand &= 0x7;
|
||||
// Note: 32-bit will never UD here. EVEX.V' is caught above already.
|
||||
@@ -628,7 +635,7 @@ direct:
|
||||
// 2 = memory, address-sized, used for mov with moffs operand
|
||||
FdOp* operand = &instr->operands[DESC_IMM_IDX(desc)];
|
||||
operand->type = FD_OT_MEM;
|
||||
operand->size = operand_sizes[(desc->operand_sizes >> 6) & 3];
|
||||
operand->size = operand_sizes[DESC_IMM_SIZE(desc)];
|
||||
operand->reg = FD_REG_NONE;
|
||||
operand->misc = FD_REG_NONE;
|
||||
|
||||
@@ -675,9 +682,9 @@ direct:
|
||||
if (UNLIKELY(off + 1 > len))
|
||||
return FD_ERR_PARTIAL;
|
||||
instr->imm = (int8_t) LOAD_LE_1(&buffer[off++]);
|
||||
operand->size = desc->operand_sizes & 0x40 ? 1 : op_size;
|
||||
operand->size = DESC_IMM_SIZE(desc) & 1 ? 1 : op_size;
|
||||
} else {
|
||||
operand->size = operand_sizes[(desc->operand_sizes >> 6) & 3];
|
||||
operand->size = operand_sizes[DESC_IMM_SIZE(desc)];
|
||||
|
||||
uint8_t imm_size;
|
||||
if (UNLIKELY(instr->type == FDI_RET || instr->type == FDI_RETF ||
|
||||
@@ -760,9 +767,9 @@ skip_modrm:
|
||||
return FD_ERR_UD;
|
||||
}
|
||||
|
||||
instr->operandsz = 0;
|
||||
} else {
|
||||
instr->operandsz = UNLIKELY(DESC_INSTR_WIDTH(desc)) ? op_size - 1 : 0;
|
||||
} else {
|
||||
instr->operandsz = 0;
|
||||
}
|
||||
|
||||
instr->size = off;
|
||||
|
||||
54
encode.c
54
encode.c
@@ -274,36 +274,36 @@ struct EncodingInfo {
|
||||
const struct EncodingInfo encoding_infos[ENC_MAX] = {
|
||||
[ENC_INVALID] = { 0 },
|
||||
[ENC_NP] = { 0 },
|
||||
[ENC_M] = { .modrm = 0^3 },
|
||||
[ENC_M1] = { .modrm = 0^3, .immctl = 1, .immidx = 1 },
|
||||
[ENC_MI] = { .modrm = 0^3, .immctl = 4, .immidx = 1 },
|
||||
[ENC_MC] = { .modrm = 0^3, .zregidx = 1^3, .zregval = 1 },
|
||||
[ENC_MR] = { .modrm = 0^3, .modreg = 1^3 },
|
||||
[ENC_RM] = { .modrm = 1^3, .modreg = 0^3 },
|
||||
[ENC_RMA] = { .modrm = 1^3, .modreg = 0^3, .zregidx = 2^3, .zregval = 0 },
|
||||
[ENC_MRI] = { .modrm = 0^3, .modreg = 1^3, .immctl = 4, .immidx = 2 },
|
||||
[ENC_RMI] = { .modrm = 1^3, .modreg = 0^3, .immctl = 4, .immidx = 2 },
|
||||
[ENC_MRC] = { .modrm = 0^3, .modreg = 1^3, .zregidx = 2^3, .zregval = 1 },
|
||||
[ENC_AM] = { .modrm = 1^3, .zregidx = 0^3, .zregval = 0 },
|
||||
[ENC_MA] = { .modrm = 0^3, .zregidx = 1^3, .zregval = 0 },
|
||||
[ENC_M] = { .modrm = 0x0^3 },
|
||||
[ENC_M1] = { .modrm = 0x0^3, .immctl = 1, .immidx = 1 },
|
||||
[ENC_MI] = { .modrm = 0x0^3, .immctl = 4, .immidx = 1 },
|
||||
[ENC_MC] = { .modrm = 0x0^3, .zregidx = 0x1^3, .zregval = 1 },
|
||||
[ENC_MR] = { .modrm = 0x0^3, .modreg = 0x1^3 },
|
||||
[ENC_RM] = { .modrm = 0x1^3, .modreg = 0x0^3 },
|
||||
[ENC_RMA] = { .modrm = 0x1^3, .modreg = 0x0^3, .zregidx = 0x2^3, .zregval = 0 },
|
||||
[ENC_MRI] = { .modrm = 0x0^3, .modreg = 0x1^3, .immctl = 4, .immidx = 2 },
|
||||
[ENC_RMI] = { .modrm = 0x1^3, .modreg = 0x0^3, .immctl = 4, .immidx = 2 },
|
||||
[ENC_MRC] = { .modrm = 0x0^3, .modreg = 0x1^3, .zregidx = 0x2^3, .zregval = 1 },
|
||||
[ENC_AM] = { .modrm = 0x1^3, .zregidx = 0x0^3, .zregval = 0 },
|
||||
[ENC_MA] = { .modrm = 0x0^3, .zregidx = 0x1^3, .zregval = 0 },
|
||||
[ENC_I] = { .immctl = 4, .immidx = 0 },
|
||||
[ENC_IA] = { .zregidx = 0^3, .zregval = 0, .immctl = 4, .immidx = 1 },
|
||||
[ENC_O] = { .modreg = 0^3 },
|
||||
[ENC_OI] = { .modreg = 0^3, .immctl = 4, .immidx = 1 },
|
||||
[ENC_OA] = { .modreg = 0^3, .zregidx = 1^3, .zregval = 0 },
|
||||
[ENC_IA] = { .zregidx = 0x0^3, .zregval = 0, .immctl = 4, .immidx = 1 },
|
||||
[ENC_O] = { .modreg = 0x0^3 },
|
||||
[ENC_OI] = { .modreg = 0x0^3, .immctl = 4, .immidx = 1 },
|
||||
[ENC_OA] = { .modreg = 0x0^3, .zregidx = 0x1^3, .zregval = 0 },
|
||||
[ENC_S] = { 0 },
|
||||
[ENC_A] = { .zregidx = 0^3, .zregval = 0 },
|
||||
[ENC_A] = { .zregidx = 0x0^3, .zregval = 0 },
|
||||
[ENC_D] = { .immctl = 6, .immidx = 0 },
|
||||
[ENC_FD] = { .zregidx = 0^3, .zregval = 0, .immctl = 2, .immidx = 1 },
|
||||
[ENC_TD] = { .zregidx = 1^3, .zregval = 0, .immctl = 2, .immidx = 0 },
|
||||
[ENC_RVM] = { .modrm = 2^3, .modreg = 0^3, .vexreg = 1^3 },
|
||||
[ENC_RVMI] = { .modrm = 2^3, .modreg = 0^3, .vexreg = 1^3, .immctl = 4, .immidx = 3 },
|
||||
[ENC_RVMR] = { .modrm = 2^3, .modreg = 0^3, .vexreg = 1^3, .immctl = 3, .immidx = 3 },
|
||||
[ENC_RMV] = { .modrm = 1^3, .modreg = 0^3, .vexreg = 2^3 },
|
||||
[ENC_VM] = { .modrm = 1^3, .vexreg = 0^3 },
|
||||
[ENC_VMI] = { .modrm = 1^3, .vexreg = 0^3, .immctl = 4, .immidx = 2 },
|
||||
[ENC_MVR] = { .modrm = 0^3, .modreg = 2^3, .vexreg = 1^3 },
|
||||
[ENC_MRV] = { .modrm = 0^3, .modreg = 1^3, .vexreg = 2^3 },
|
||||
[ENC_FD] = { .zregidx = 0x0^3, .zregval = 0, .immctl = 2, .immidx = 1 },
|
||||
[ENC_TD] = { .zregidx = 0x1^3, .zregval = 0, .immctl = 2, .immidx = 0 },
|
||||
[ENC_RVM] = { .modrm = 0x2^3, .modreg = 0x0^3, .vexreg = 0x1^3 },
|
||||
[ENC_RVMI] = { .modrm = 0x2^3, .modreg = 0x0^3, .vexreg = 0x1^3, .immctl = 4, .immidx = 3 },
|
||||
[ENC_RVMR] = { .modrm = 0x2^3, .modreg = 0x0^3, .vexreg = 0x1^3, .immctl = 3, .immidx = 3 },
|
||||
[ENC_RMV] = { .modrm = 0x1^3, .modreg = 0x0^3, .vexreg = 0x2^3 },
|
||||
[ENC_VM] = { .modrm = 0x1^3, .vexreg = 0x0^3 },
|
||||
[ENC_VMI] = { .modrm = 0x1^3, .vexreg = 0x0^3, .immctl = 4, .immidx = 2 },
|
||||
[ENC_MVR] = { .modrm = 0x0^3, .modreg = 0x2^3, .vexreg = 0x1^3 },
|
||||
[ENC_MRV] = { .modrm = 0x0^3, .modreg = 0x1^3, .vexreg = 0x2^3 },
|
||||
};
|
||||
|
||||
static const uint64_t alt_tab[] = {
|
||||
|
||||
2
format.c
2
format.c
@@ -26,7 +26,7 @@ struct FdStr {
|
||||
unsigned sz;
|
||||
};
|
||||
|
||||
#define fd_stre(s) ((struct FdStr) { (s "\0\0\0\0\0\0\0\0\0\0"), sizeof (s)-1 })
|
||||
#define fd_stre(s) ((struct FdStr) { (s "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"), sizeof (s)-1 })
|
||||
|
||||
static char*
|
||||
fd_strpcat(char* restrict dst, struct FdStr src) {
|
||||
|
||||
@@ -1026,7 +1026,7 @@ VEX.F2.0f7c RVM Vx Hx Wx - VHADDPS F=AVX
|
||||
VEX.66.0f7d RVM Vx Hx Wx - VHSUBPD F=AVX
|
||||
VEX.F2.0f7d RVM Vx Hx Wx - VHSUBPS F=AVX
|
||||
VEX.66.W0.L0.0f7e MR Ey Vy - - VMOVD_X2G F=AVX ENC_NOSZ
|
||||
VEX.66.W1.L0.0f7e MR Ey Vy - - VMOVQ_X2G I64 F=AVX ENC_NOSZ
|
||||
VEX.66.W1.L0.0f7e MR Ey Vy - - VMOVD_X2G I64 F=AVX ENC_NOSZ
|
||||
VEX.66.W1.L0.0f7e MR Ey Vy - - VMOVQ_X2G O64 F=AVX ENC_NOSZ
|
||||
VEX.F3.L0.0f7e RM Vq Wq - - VMOVQ F=AVX ENC_NOSZ
|
||||
VEX.66.0f7f MR Wx Vx - - VMOVDQA F=AVX
|
||||
|
||||
18
meson.build
18
meson.build
@@ -11,6 +11,12 @@ if not py_version.version_compare('>=3.6')
|
||||
endif
|
||||
|
||||
cc = meson.get_compiler('c')
|
||||
if get_option('wasm_build')
|
||||
add_project_arguments('--target=wasm32', language: 'c')
|
||||
add_project_arguments(['-nostdlib', '-fvisibility=default'], language: 'c')
|
||||
|
||||
endif
|
||||
|
||||
if cc.has_argument('-fstrict-aliasing')
|
||||
add_project_arguments('-fstrict-aliasing', language: 'c')
|
||||
endif
|
||||
@@ -99,11 +105,13 @@ fadec = declare_dependency(link_with: libfadec,
|
||||
sources: tables)
|
||||
install_headers(headers)
|
||||
|
||||
foreach component : components
|
||||
test(component, executable('@0@-test'.format(component),
|
||||
'@0@-test.c'.format(component),
|
||||
dependencies: fadec))
|
||||
endforeach
|
||||
if get_option('wasm_build') == false
|
||||
foreach component : components
|
||||
test(component, executable('@0@-test'.format(component),
|
||||
'@0@-test.c'.format(component),
|
||||
dependencies: fadec))
|
||||
endforeach
|
||||
endif
|
||||
|
||||
if meson.version().version_compare('>=0.54.0')
|
||||
meson.override_dependency('fadec', fadec)
|
||||
|
||||
@@ -4,3 +4,4 @@ option('with_decode', type: 'boolean', value: true)
|
||||
option('with_encode', type: 'boolean', value: true)
|
||||
# encode2 is off-by-default to reduce size and compile-time
|
||||
option('with_encode2', type: 'boolean', value: false)
|
||||
option('wasm_build', type: 'boolean', value: false)
|
||||
@@ -276,17 +276,17 @@ class InstrDesc(NamedTuple):
|
||||
else: # either empty or GP operand size
|
||||
dynsizes = [OpKind.SZ_OP]
|
||||
if "SZ8" in self.flags:
|
||||
extraflags["opsize"] = 1
|
||||
dynsizes = []
|
||||
if "D64" in self.flags: extraflags["opsize"] = 2
|
||||
if "F64" in self.flags: extraflags["opsize"] = 3
|
||||
extraflags["instr_width"] = "INSTR_WIDTH" in self.flags
|
||||
extraflags["lock"] = "LOCK" in self.flags
|
||||
|
||||
if "SZ8" in self.flags or mnem in ("MOVSX", "MOVZX", "XCHG_NOP", "3DNOW"):
|
||||
if "SZ8" not in self.flags and "INSTR_WIDTH" in self.flags:
|
||||
raise Exception("legacy instr with +w without SZ8")
|
||||
if (self.flags & {"SZ8", "INSTR_WIDTH"} or
|
||||
mnem in ("MOVSX", "MOVZX", "XCHG_NOP", "3DNOW")):
|
||||
extraflags["legacy"] = 1
|
||||
# INSTR_WIDTH defaults to zero, so only enable when SZ8 is unset
|
||||
if "INSTR_WIDTH" in self.flags and "SZ8" not in self.flags:
|
||||
extraflags["instr_width"] = 1
|
||||
|
||||
imm_byte = self.imm_size(4) == 1
|
||||
extraflags["imm_control"] = flags.imm_control | imm_byte
|
||||
|
||||
Reference in New Issue
Block a user