format: Properly output VSIB encodings

This commit is contained in:
Alexis Engelke
2021-01-08 10:37:13 +01:00
parent 018a954b4c
commit 111769832f
4 changed files with 86 additions and 24 deletions

View File

@@ -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)) {

View File

@@ -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

View File

@@ -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}

View File

@@ -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]");