From 111769832f1d34d783385fc2bac88084b1af6dae Mon Sep 17 00:00:00 2001 From: Alexis Engelke Date: Fri, 8 Jan 2021 10:37:13 +0100 Subject: [PATCH] format: Properly output VSIB encodings --- format.c | 53 +++++++++++++++++++++++++++++++++------------ instrs.txt | 18 ++++++++------- parseinstrs.py | 2 +- tests/test_decode.c | 37 ++++++++++++++++++++++++++++++- 4 files changed, 86 insertions(+), 24 deletions(-) diff --git a/format.c b/format.c index 8aa92ec..a8e5ef0 100644 --- a/format.c +++ b/format.c @@ -263,20 +263,45 @@ fd_format_abs(const FdInstr* instr, uint64_t addr, char* buffer, size_t len) unsigned idx = FD_OP_REG(instr, i); buf = fd_strplcpy(buf, reg_name(type, idx, size), end-buf); } else if (op_type == FD_OT_MEM) { - if (FD_TYPE(instr) == FDI_CMPXCHGD) - size = 2 * FD_OPSIZE(instr); - else if (FD_TYPE(instr) == FDI_BOUND) - size *= 2; - else if (FD_TYPE(instr) == FDI_JMPF || FD_TYPE(instr) == FDI_CALLF - || FD_TYPE(instr) == FDI_LDS || FD_TYPE(instr) == FDI_LES - || FD_TYPE(instr) == FDI_LFS || FD_TYPE(instr) == FDI_LGS - || FD_TYPE(instr) == FDI_LSS) + unsigned idx_rt = FD_RT_GPL; + unsigned idx_sz = FD_ADDRSIZE(instr); + switch (FD_TYPE(instr)) { + case FDI_CMPXCHGD: size = 2 * FD_OPSIZE(instr); break; + case FDI_BOUND: size = 2 * size; break; + case FDI_JMPF: + case FDI_CALLF: + case FDI_LDS: + case FDI_LES: + case FDI_LFS: + case FDI_LGS: + case FDI_LSS: size = 6; - else if (!size && (FD_TYPE(instr) == FDI_FLD || - FD_TYPE(instr) == FDI_FSTP || - FD_TYPE(instr) == FDI_FBLD || - FD_TYPE(instr) == FDI_FBSTP)) - size = 10; + break; + case FDI_FLD: + case FDI_FSTP: + case FDI_FBLD: + case FDI_FBSTP: + size = size != 0 ? size : 10; + break; + case FDI_VPGATHERQD: + case FDI_VGATHERQPS: + idx_rt = FD_RT_VEC; + idx_sz = FD_OP_SIZE(instr, 0) * 2; + break; + case FDI_VPGATHERDQ: + case FDI_VGATHERDPD: + idx_rt = FD_RT_VEC; + idx_sz = FD_OP_SIZE(instr, 0) / 2; + break; + case FDI_VPGATHERDD: + case FDI_VPGATHERQQ: + case FDI_VGATHERDPS: + case FDI_VGATHERQPD: + idx_rt = FD_RT_VEC; + idx_sz = FD_OP_SIZE(instr, 0); + break; + default: break; + } switch (size) { default: break; case 1: buf = fd_strplcpy(buf, "byte ptr ", end-buf); break; @@ -303,7 +328,7 @@ fd_format_abs(const FdInstr* instr, uint64_t addr, char* buffer, size_t len) if (has_base) buf = fd_strplcpy(buf, "+", end-buf); buf = fd_strplcpy(buf, "1*\0002*\0004*\0008*" + 3*FD_OP_SCALE(instr, i), end-buf); - buf = fd_strplcpy(buf, reg_name(FD_RT_GPL, FD_OP_INDEX(instr, i), FD_ADDRSIZE(instr)), end-buf); + buf = fd_strplcpy(buf, reg_name(idx_rt, FD_OP_INDEX(instr, i), idx_sz), end-buf); } uint64_t disp = FD_OP_DISP(instr, i); if (disp && (has_base || has_idx)) { diff --git a/instrs.txt b/instrs.txt index c219a45..7a0f606 100644 --- a/instrs.txt +++ b/instrs.txt @@ -1128,14 +1128,16 @@ VEX.66.W0.0f388c RVM XMM XMM XMM - VPMASKMOVD VEX.66.W1.0f388c RVM XMM XMM XMM - VPMASKMOVQ VEX.66.W0.0f388e MVR XMM XMM XMM - VPMASKMOVD VEX.66.W1.0f388e MVR XMM XMM XMM - VPMASKMOVQ -VEX.66.W0.0f3890/m RMV XMM MEMV XMM - VPGATHERDD VSIB -VEX.66.W1.0f3890/m RMV XMM MEMV XMM - VPGATHERDQ VSIB -VEX.66.W0.0f3891/m RMV XMM MEMV XMM - VPGATHERQD VSIB -VEX.66.W1.0f3891/m RMV XMM MEMV XMM - VPGATHERQQ VSIB -VEX.66.W0.0f3892/m RMV XMM MEMV XMM - VGATHERDPS VSIB -VEX.66.W1.0f3892/m RMV XMM MEMV XMM - VGATHERDPD VSIB -VEX.66.W0.0f3893/m RMV XMM MEMV XMM - VGATHERQPS VSIB -VEX.66.W1.0f3893/m RMV XMM MEMV XMM - VGATHERQPD VSIB +VEX.66.W0.0f3890/m RMV XMM MEM32 XMM - VPGATHERDD VSIB +VEX.66.W1.0f3890/m RMV XMM MEM64 XMM - VPGATHERDQ VSIB +VEX.66.W0.L0.0f3891/m RMV XMM64 MEM32 XMM64 - VPGATHERQD VSIB +VEX.66.W0.L1.0f3891/m RMV XMM128 MEM32 XMM128 - VPGATHERQD VSIB +VEX.66.W1.0f3891/m RMV XMM MEM64 XMM - VPGATHERQQ VSIB +VEX.66.W0.0f3892/m RMV XMM MEM32 XMM - VGATHERDPS VSIB +VEX.66.W1.0f3892/m RMV XMM MEM64 XMM - VGATHERDPD VSIB +VEX.66.W0.L0.0f3893/m RMV XMM64 MEM32 XMM64 - VGATHERQPS VSIB +VEX.66.W0.L1.0f3893/m RMV XMM128 MEM32 XMM128 - VGATHERQPS VSIB +VEX.66.W1.0f3893/m RMV XMM MEM64 XMM - VGATHERQPD VSIB VEX.66.W0.0f3896 RVM XMM XMM XMM - VFMADDSUB132PS VEX.66.W1.0f3896 RVM XMM XMM XMM - VFMADDSUB132PD VEX.66.W0.0f3897 RVM XMM XMM XMM - VFMSUBADD132PS diff --git a/parseinstrs.py b/parseinstrs.py index 6aabafa..8f937fb 100644 --- a/parseinstrs.py +++ b/parseinstrs.py @@ -505,7 +505,7 @@ def encode_table(entries): opsizes -= {32} if "INSTR_WIDTH" not in desc.flags and all(op.size != OpKind.SZ_OP for op in desc.operands): opsizes = {0} - if all(op.size != OpKind.SZ_VEC for op in desc.operands): + if "VSIB" not in desc.flags and all(op.size != OpKind.SZ_VEC for op in desc.operands): vecsizes = {0} # for VEX-encoded general-purpose instructions. if "ENC_NOSZ" in desc.flags: opsizes, vecsizes = {0}, {0} diff --git a/tests/test_decode.c b/tests/test_decode.c index 2a1294d..b15addd 100644 --- a/tests/test_decode.c +++ b/tests/test_decode.c @@ -333,7 +333,6 @@ main(int argc, char** argv) TEST("\xc5\xf2\x2a\xc0", "vcvtsi2ss xmm0, xmm1, eax"); TEST32("\xc4\xe1\xf2\x2a\xc0", "vcvtsi2ss xmm0, xmm1, eax"); TEST64("\xc4\xe1\xf2\x2a\xc0", "vcvtsi2ss xmm0, xmm1, rax"); - TEST64("\xc4\xe2\x75\x90\x04\xe7", "vpgatherdd ymm0, ymmword ptr [rdi+8*rsp], ymm1"); TEST("\xc4\xe3\x79\x14\xc0\x00", "vpextrb al, xmm0, 0x0"); TEST("\xc4\xe3\xf9\x14\xc0\x00", "vpextrb al, xmm0, 0x0"); @@ -363,6 +362,42 @@ main(int argc, char** argv) TEST("\xc4\xe2\xf1\x45\xc2", "vpsrlvq xmm0, xmm1, xmm2"); TEST("\xc4\xe2\xf5\x45\xc2", "vpsrlvq ymm0, ymm1, ymm2"); + TEST("\xc4\xe2\x71\x92\xc0", "UD"); // Must have memory operand + TEST("\xc4\xe2\x71\x92\x00", "UD"); // Must have SIB byte + TEST("\xc4\xe2\x71\x92\x05\x00\x00\x00\x00", "UD"); // Must have SIB byte + TEST32("\xc4\xe2\x71\x92\x04\xe7", "vgatherdps xmm0, dword ptr [edi+8*xmm4], xmm1"); + TEST64("\xc4\xe2\x71\x92\x04\xe7", "vgatherdps xmm0, dword ptr [rdi+8*xmm4], xmm1"); + TEST32("\xc4\xe2\x75\x92\x04\xe7", "vgatherdps ymm0, dword ptr [edi+8*ymm4], ymm1"); + TEST64("\xc4\xe2\x75\x92\x04\xe7", "vgatherdps ymm0, dword ptr [rdi+8*ymm4], ymm1"); + TEST32("\xc4\xe2\x71\x93\x04\xe7", "vgatherqps xmm0, dword ptr [edi+8*xmm4], xmm1"); + TEST64("\xc4\xe2\x71\x93\x04\xe7", "vgatherqps xmm0, dword ptr [rdi+8*xmm4], xmm1"); + TEST32("\xc4\xe2\x75\x93\x04\xe7", "vgatherqps xmm0, dword ptr [edi+8*ymm4], xmm1"); + TEST64("\xc4\xe2\x75\x93\x04\xe7", "vgatherqps xmm0, dword ptr [rdi+8*ymm4], xmm1"); + TEST32("\xc4\xe2\xf1\x92\x04\xe7", "vgatherdpd xmm0, qword ptr [edi+8*xmm4], xmm1"); + TEST64("\xc4\xe2\xf1\x92\x04\xe7", "vgatherdpd xmm0, qword ptr [rdi+8*xmm4], xmm1"); + TEST32("\xc4\xe2\xf5\x92\x04\xe7", "vgatherdpd ymm0, qword ptr [edi+8*xmm4], ymm1"); + TEST64("\xc4\xe2\xf5\x92\x04\xe7", "vgatherdpd ymm0, qword ptr [rdi+8*xmm4], ymm1"); + TEST32("\xc4\xe2\xf1\x93\x04\xe7", "vgatherqpd xmm0, qword ptr [edi+8*xmm4], xmm1"); + TEST64("\xc4\xe2\xf1\x93\x04\xe7", "vgatherqpd xmm0, qword ptr [rdi+8*xmm4], xmm1"); + TEST32("\xc4\xe2\xf5\x93\x04\xe7", "vgatherqpd ymm0, qword ptr [edi+8*ymm4], ymm1"); + TEST64("\xc4\xe2\xf5\x93\x04\xe7", "vgatherqpd ymm0, qword ptr [rdi+8*ymm4], ymm1"); + TEST32("\xc4\xe2\x71\x90\x04\xe7", "vpgatherdd xmm0, dword ptr [edi+8*xmm4], xmm1"); + TEST64("\xc4\xe2\x71\x90\x04\xe7", "vpgatherdd xmm0, dword ptr [rdi+8*xmm4], xmm1"); + TEST32("\xc4\xe2\x75\x90\x04\xe7", "vpgatherdd ymm0, dword ptr [edi+8*ymm4], ymm1"); + TEST64("\xc4\xe2\x75\x90\x04\xe7", "vpgatherdd ymm0, dword ptr [rdi+8*ymm4], ymm1"); + TEST32("\xc4\xe2\x71\x91\x04\xe7", "vpgatherqd xmm0, dword ptr [edi+8*xmm4], xmm1"); + TEST64("\xc4\xe2\x71\x91\x04\xe7", "vpgatherqd xmm0, dword ptr [rdi+8*xmm4], xmm1"); + TEST32("\xc4\xe2\x75\x91\x04\xe7", "vpgatherqd xmm0, dword ptr [edi+8*ymm4], xmm1"); + TEST64("\xc4\xe2\x75\x91\x04\xe7", "vpgatherqd xmm0, dword ptr [rdi+8*ymm4], xmm1"); + TEST32("\xc4\xe2\xf1\x90\x04\xe7", "vpgatherdq xmm0, qword ptr [edi+8*xmm4], xmm1"); + TEST64("\xc4\xe2\xf1\x90\x04\xe7", "vpgatherdq xmm0, qword ptr [rdi+8*xmm4], xmm1"); + TEST32("\xc4\xe2\xf5\x90\x04\xe7", "vpgatherdq ymm0, qword ptr [edi+8*xmm4], ymm1"); + TEST64("\xc4\xe2\xf5\x90\x04\xe7", "vpgatherdq ymm0, qword ptr [rdi+8*xmm4], ymm1"); + TEST32("\xc4\xe2\xf1\x91\x04\xe7", "vpgatherqq xmm0, qword ptr [edi+8*xmm4], xmm1"); + TEST64("\xc4\xe2\xf1\x91\x04\xe7", "vpgatherqq xmm0, qword ptr [rdi+8*xmm4], xmm1"); + TEST32("\xc4\xe2\xf5\x91\x04\xe7", "vpgatherqq ymm0, qword ptr [edi+8*ymm4], ymm1"); + TEST64("\xc4\xe2\xf5\x91\x04\xe7", "vpgatherqq ymm0, qword ptr [rdi+8*ymm4], ymm1"); + TEST32("\xc4\xe2\x7d\x5a\x20", "vbroadcasti128 ymm4, xmmword ptr [eax]"); TEST64("\xc4\xe2\x7d\x5a\x20", "vbroadcasti128 ymm4, xmmword ptr [rax]"); TEST64("\xc4\x62\x7d\x5a\x20", "vbroadcasti128 ymm12, xmmword ptr [rax]");