disasm for AVX2 gather

This commit is contained in:
Stanislav Shwartsman 2011-08-28 21:38:53 +00:00
parent 6bdfbeeffa
commit 1dc8f56f06
6 changed files with 108 additions and 36 deletions

View File

@ -543,6 +543,15 @@ void disassembler::Mpd(const x86_insn *insn) { OP_M(insn, XMM_SIZE + insn->vex_l
void disassembler::Mss(const x86_insn *insn) { OP_M(insn, D_SIZE); }
void disassembler::Msd(const x86_insn *insn) { OP_M(insn, Q_SIZE); }
// gather VSib
void disassembler::VSib(const x86_insn *insn)
{
if(insn->mod == 3)
dis_sprintf("(bad)");
else
(this->*resolve_modrm)(insn, (XMM_SIZE + insn->vex_l) | VSIB_Index);
}
// string instructions
void disassembler::OP_X(const x86_insn *insn, unsigned size)
{

View File

@ -177,6 +177,8 @@
#define Mss &disassembler::Mss
#define Msd &disassembler::Msd
#define VSib &disassembler::VSib
#define Xb &disassembler::Xb
#define Xw &disassembler::Xw
#define Xd &disassembler::Xd

View File

@ -447,6 +447,26 @@ static BxDisasmOpcodeTable_t BxDisasmGrpVexW_0f388e[2] = {
/* 1 */ { GRPSSE66(Ia_vmaskmovq_Mdq_Hdq_Vdq) }
};
static BxDisasmOpcodeTable_t BxDisasmGrpVexW_0f3890[2] = {
/* 0 */ { GRPSSE66(Ia_vgatherdd_Vdq_VSib_Hdq) },
/* 1 */ { GRPSSE66(Ia_vgatherdq_Vdq_VSib_Hdq) }
};
static BxDisasmOpcodeTable_t BxDisasmGrpVexW_0f3891[2] = {
/* 0 */ { GRPSSE66(Ia_vgatherqd_Vdq_VSib_Hdq) },
/* 1 */ { GRPSSE66(Ia_vgatherqq_Vdq_VSib_Hdq) }
};
static BxDisasmOpcodeTable_t BxDisasmGrpVexW_0f3892[2] = {
/* 0 */ { GRPSSE66(Ia_vgatherdps_Vps_VSib_Hps) },
/* 1 */ { GRPSSE66(Ia_vgatherdpd_Vpd_VSib_Hpd) }
};
static BxDisasmOpcodeTable_t BxDisasmGrpVexW_0f3893[2] = {
/* 0 */ { GRPSSE66(Ia_vgatherqps_Vps_VSib_Hps) },
/* 1 */ { GRPSSE66(Ia_vgatherqpd_Vpd_VSib_Hpd) }
};
static BxDisasmOpcodeTable_t BxDisasmGroupAVX_0f38f5[4] = {
/* -- */ { 0, &Ia_bzhi_Gy_Ey_By },
/* 66 */ { 0, &Ia_Invalid },
@ -877,10 +897,10 @@ static BxDisasmOpcodeTable_t BxDisasmOpcodesAVX[256*3] = {
/* 8D */ { 0, &Ia_Invalid },
/* 8E */ { GRPVEXW(0f388e) },
/* 8F */ { 0, &Ia_Invalid },
/* 90 */ { 0, &Ia_Invalid },
/* 91 */ { 0, &Ia_Invalid },
/* 92 */ { 0, &Ia_Invalid },
/* 93 */ { 0, &Ia_Invalid },
/* 90 */ { GRPVEXW(0f3890) },
/* 91 */ { GRPVEXW(0f3891) },
/* 92 */ { GRPVEXW(0f3892) },
/* 93 */ { GRPVEXW(0f3893) },
/* 94 */ { 0, &Ia_Invalid },
/* 95 */ { 0, &Ia_Invalid },
/* 96 */ { 0, &Ia_Invalid },

View File

@ -132,6 +132,8 @@ struct BxDisasmOpcodeTable_t
#define XMM_SIZE 0x07 /* double quad word (XMM) */
#define YMM_SIZE 0x08 /* quadruple quad word (YMM) */
#define VSIB_Index 0x80
// branch hint attribute
#define BRANCH_HINT 0x1000
@ -563,6 +565,9 @@ public:
void Mss(const x86_insn *insn);
void Msd(const x86_insn *insn);
// gather VSib
void VSib(const x86_insn *insn);
// string instructions
void OP_X(const x86_insn *insn, unsigned size);
void Xb(const x86_insn *insn);

View File

@ -1361,6 +1361,14 @@ Ia_verw = { "verw", "verw", Ew, XX, XX, XX, 0 },
Ia_vextractf128_Wdq_Vdq_Ib = { "vextractf128", "vextractf128", Wdq, Vdq, Ib, XX, IA_AVX },
Ia_vextracti128_Wdq_Vdq_Ib = { "vextracti128", "vextracti128", Wdq, Vdq, Ib, XX, IA_AVX2 },
Ia_vextractps_Ed_Vdq_Ib = { "vextractps", "vextractps", Ed, Vdq, Ib, XX, IA_AVX },
Ia_vgatherdd_Vdq_VSib_Hdq = { "vgatherdd", "vgatherdd", Vdq, VSib, Hdq, XX, IA_AVX2 },
Ia_vgatherdps_Vps_VSib_Hps = { "vgatherdps", "vgatherdps", Vps, VSib, Hps, XX, IA_AVX2 },
Ia_vgatherdpd_Vpd_VSib_Hpd = { "vgatherdpd", "vgatherdpd", Vpd, VSib, Hpd, XX, IA_AVX2 },
Ia_vgatherdq_Vdq_VSib_Hdq = { "vgatherdq", "vgatherdq", Vdq, VSib, Hdq, XX, IA_AVX2 },
Ia_vgatherqd_Vdq_VSib_Hdq = { "vgatherqd", "vgatherqd", Vdq, VSib, Hdq, XX, IA_AVX2 },
Ia_vgatherqps_Vps_VSib_Hps = { "vgatherqps", "vgatherqps", Vps, VSib, Hps, XX, IA_AVX2 },
Ia_vgatherqpd_Vpd_VSib_Hpd = { "vgatherqpd", "vgatherqpd", Vpd, VSib, Hpd, XX, IA_AVX2 },
Ia_vgatherqq_Vdq_VSib_Hdq = { "vgatherqq", "vgatherqq", Vdq, VSib, Hdq, XX, IA_AVX2 },
Ia_vhaddpd_Vpd_Hpd_Wpd = { "vhaddpd", "vhaddpd", Vpd, Hpd, Wpd, XX, IA_AVX },
Ia_vhaddps_Vps_Hps_Wps = { "vhaddps", "vhaddps", Vps, Hps, Wps, XX, IA_AVX },
Ia_vhsubpd_Vpd_Hpd_Wpd = { "vhsubpd", "vhsubpd", Vpd, Hpd, Wpd, XX, IA_AVX },

View File

@ -155,7 +155,7 @@ void disassembler::decode_modrm(x86_insn *insn)
}
}
void disassembler::resolve16_mod0(const x86_insn *insn, unsigned mode)
void disassembler::resolve16_mod0(const x86_insn *insn, unsigned datasize)
{
const char *seg;
@ -165,12 +165,12 @@ void disassembler::resolve16_mod0(const x86_insn *insn, unsigned mode)
seg = sreg_mod00_rm16[insn->rm];
if(insn->rm == 6)
print_memory_access16(mode, seg, NULL, insn->displacement.displ16);
print_memory_access16(datasize, seg, NULL, insn->displacement.displ16);
else
print_memory_access16(mode, seg, index16[insn->rm], 0);
print_memory_access16(datasize, seg, index16[insn->rm], 0);
}
void disassembler::resolve16_mod1or2(const x86_insn *insn, unsigned mode)
void disassembler::resolve16_mod1or2(const x86_insn *insn, unsigned datasize)
{
const char *seg;
@ -179,10 +179,10 @@ void disassembler::resolve16_mod1or2(const x86_insn *insn, unsigned mode)
else
seg = sreg_mod01or10_rm16[insn->rm];
print_memory_access16(mode, seg, index16[insn->rm], insn->displacement.displ16);
print_memory_access16(datasize, seg, index16[insn->rm], insn->displacement.displ16);
}
void disassembler::resolve32_mod0(const x86_insn *insn, unsigned mode)
void disassembler::resolve32_mod0(const x86_insn *insn, unsigned datasize)
{
const char *seg, *eip_regname = NULL;
@ -197,12 +197,12 @@ void disassembler::resolve32_mod0(const x86_insn *insn, unsigned mode)
}
if ((insn->rm & 7) == 5) /* no reg, 32-bit displacement */
print_memory_access32(mode, seg, eip_regname, NULL, 0, insn->displacement.displ32);
print_memory_access32(datasize, seg, eip_regname, NULL, 0, insn->displacement.displ32);
else
print_memory_access32(mode, seg, general_32bit_regname[insn->rm], NULL, 0, 0);
print_memory_access32(datasize, seg, general_32bit_regname[insn->rm], NULL, 0, 0);
}
void disassembler::resolve32_mod1or2(const x86_insn *insn, unsigned mode)
void disassembler::resolve32_mod1or2(const x86_insn *insn, unsigned datasize)
{
const char *seg;
@ -211,12 +211,13 @@ void disassembler::resolve32_mod1or2(const x86_insn *insn, unsigned mode)
else
seg = sreg_mod01or10_base32[insn->rm];
print_memory_access32(mode, seg,
print_memory_access32(datasize, seg,
general_32bit_regname[insn->rm], NULL, 0, insn->displacement.displ32);
}
void disassembler::resolve32_mod0_rm4(const x86_insn *insn, unsigned mode)
void disassembler::resolve32_mod0_rm4(const x86_insn *insn, unsigned datasize)
{
char vsib_index[8];
const char *seg, *base = NULL, *index = NULL;
Bit32u disp32 = 0;
@ -230,14 +231,21 @@ void disassembler::resolve32_mod0_rm4(const x86_insn *insn, unsigned mode)
else
disp32 = insn->displacement.displ32;
if (insn->index != 4)
index = general_32bit_regname[insn->index];
if (datasize & VSIB_Index) {
sprintf(vsib_index, "%s%d", vector_reg_name[insn->vex_l], insn->index);
index = vsib_index;
}
else {
if (insn->index != 4)
index = general_32bit_regname[insn->index];
}
print_memory_access32(mode, seg, base, index, insn->scale, disp32);
print_memory_access32(datasize, seg, base, index, insn->scale, disp32);
}
void disassembler::resolve32_mod1or2_rm4(const x86_insn *insn, unsigned mode)
void disassembler::resolve32_mod1or2_rm4(const x86_insn *insn, unsigned datasize)
{
char vsib_index[8];
const char *seg, *index = NULL;
if (insn->is_seg_override())
@ -245,14 +253,20 @@ void disassembler::resolve32_mod1or2_rm4(const x86_insn *insn, unsigned mode)
else
seg = sreg_mod01or10_base32[insn->base];
if (insn->index != 4)
index = general_32bit_regname[insn->index];
if (datasize & VSIB_Index) {
sprintf(vsib_index, "%s%d", vector_reg_name[insn->vex_l], insn->index);
index = vsib_index;
}
else {
if (insn->index != 4)
index = general_32bit_regname[insn->index];
}
print_memory_access32(mode, seg,
print_memory_access32(datasize, seg,
general_32bit_regname[insn->base], index, insn->scale, insn->displacement.displ32);
}
void disassembler::resolve64_mod0(const x86_insn *insn, unsigned mode)
void disassembler::resolve64_mod0(const x86_insn *insn, unsigned datasize)
{
const char *seg, *rip_regname;
@ -265,12 +279,12 @@ void disassembler::resolve64_mod0(const x86_insn *insn, unsigned mode)
else rip_regname = "%rip";
if ((insn->rm & 7) == 5) /* no reg, 32-bit displacement */
print_memory_access64(mode, seg, rip_regname, NULL, 0, (Bit32s) insn->displacement.displ32);
print_memory_access64(datasize, seg, rip_regname, NULL, 0, (Bit32s) insn->displacement.displ32);
else
print_memory_access64(mode, seg, general_64bit_regname[insn->rm], NULL, 0, 0);
print_memory_access64(datasize, seg, general_64bit_regname[insn->rm], NULL, 0, 0);
}
void disassembler::resolve64_mod1or2(const x86_insn *insn, unsigned mode)
void disassembler::resolve64_mod1or2(const x86_insn *insn, unsigned datasize)
{
const char *seg;
@ -279,12 +293,13 @@ void disassembler::resolve64_mod1or2(const x86_insn *insn, unsigned mode)
else
seg = sreg_mod01or10_base32[insn->rm];
print_memory_access64(mode, seg,
print_memory_access64(datasize, seg,
general_64bit_regname[insn->rm], NULL, 0, (Bit32s) insn->displacement.displ32);
}
void disassembler::resolve64_mod0_rm4(const x86_insn *insn, unsigned mode)
void disassembler::resolve64_mod0_rm4(const x86_insn *insn, unsigned datasize)
{
char vsib_index[8];
const char *seg, *base = NULL, *index = NULL;
Bit32s disp32 = 0;
@ -298,14 +313,21 @@ void disassembler::resolve64_mod0_rm4(const x86_insn *insn, unsigned mode)
else
disp32 = (Bit32s) insn->displacement.displ32;
if (insn->index != 4)
index = general_64bit_regname[insn->index];
if (datasize & VSIB_Index) {
sprintf(vsib_index, "%s%d", vector_reg_name[insn->vex_l], insn->index);
index = vsib_index;
}
else {
if (insn->index != 4)
index = general_64bit_regname[insn->index];
}
print_memory_access64(mode, seg, base, index, insn->scale, disp32);
print_memory_access64(datasize, seg, base, index, insn->scale, disp32);
}
void disassembler::resolve64_mod1or2_rm4(const x86_insn *insn, unsigned mode)
void disassembler::resolve64_mod1or2_rm4(const x86_insn *insn, unsigned datasize)
{
char vsib_index[8];
const char *seg, *index = NULL;
if (insn->is_seg_override())
@ -313,10 +335,16 @@ void disassembler::resolve64_mod1or2_rm4(const x86_insn *insn, unsigned mode)
else
seg = sreg_mod01or10_base32[insn->base];
if (insn->index != 4)
index = general_64bit_regname[insn->index];
if (datasize & VSIB_Index) {
sprintf(vsib_index, "%s%d", vector_reg_name[insn->vex_l], insn->index);
index = vsib_index;
}
else {
if (insn->index != 4)
index = general_64bit_regname[insn->index];
}
print_memory_access64(mode, seg,
print_memory_access64(datasize, seg,
general_64bit_regname[insn->base], index, insn->scale, (Bit32s) insn->displacement.displ32);
}
@ -324,7 +352,7 @@ void disassembler::print_datasize(unsigned size)
{
if (!intel_mode) return;
switch(size)
switch(size & 0xff)
{
case B_SIZE:
dis_sprintf("byte ptr ");