Add support for 3rd source operand in avx insns

This commit is contained in:
Vivek Thampi
2013-06-29 14:46:32 -07:00
parent 4642ba1b75
commit cb356500db
5 changed files with 57 additions and 16 deletions
+15 -12
View File
@@ -9063,21 +9063,13 @@
</def>
</instruction>
<instruction>
<mnemonic>pblendw</mnemonic>
<def>
<pfx>aso rexr rexx rexb</pfx>
<opc>/sse=66 0f 3a 0e</opc>
<opr>V W Ib</opr>
</def>
</instruction>
<instruction>
<mnemonic>blendps</mnemonic>
<def>
<pfx>aso rexr rexx rexb</pfx>
<opc>/sse=66 0f 3a 0c</opc>
<opr>V W Ib</opr>
<opr>V H W Ib</opr>
<cpuid>sse4.1 avx</cpuid>
</def>
</instruction>
@@ -9085,8 +9077,9 @@
<mnemonic>blendvpd</mnemonic>
<def>
<pfx>aso rexr rexx rexb</pfx>
<opc>/sse=66 0f 38 15</opc>
<opr>V W</opr>
<opc>/sse=66 0f 38 15 /vexw=0</opc>
<opr>V H W L</opr>
<cpuid>sse4.1 avx</cpuid>
</def>
</instruction>
@@ -9099,6 +9092,16 @@
</def>
</instruction>
<instruction>
<mnemonic>pblendw</mnemonic>
<def>
<pfx>aso rexr rexx rexb</pfx>
<opc>/sse=66 0f 3a 0e</opc>
<opr>V W Ib</opr>
</def>
</instruction>
<instruction>
<mnemonic>dpps</mnemonic>
<def>
+32 -2
View File
@@ -247,8 +247,8 @@ decode_prefixes(struct ud *u)
/*
* vex_l
* Returns the vex.L bit
* vex_l, vex_w
* Return the vex.L and vex.W bits
*/
static inline uint8_t
vex_l(const struct ud *u)
@@ -257,6 +257,13 @@ vex_l(const struct ud *u)
return ((u->vex_op == 0xc4 ? u->vex_b2 : u->vex_b1) >> 2) & 1;
}
static inline uint8_t
vex_w(const struct ud *u)
{
UD_ASSERT(u->vex_op != 0);
return u->vex_op == 0xc4 ? ((u->vex_b2 >> 7) & 1) : 0;
}
static inline uint8_t
modrm(struct ud * u)
@@ -649,6 +656,22 @@ decode_vex_vvvv(struct ud *u, struct ud_operand *opr, unsigned size)
}
/*
* decode_vex_immreg
* Decode source operand encoded in immediate byte [7:4]
*/
static int
decode_vex_immreg(struct ud *u, struct ud_operand *opr, unsigned size)
{
uint8_t imm = ud_inp_next(u);
uint8_t mask = u->dis_mode == 64 ? 0xf : 0x7;
UD_RETURN_ON_ERROR(u);
UD_ASSERT(u->vex_op != 0);
decode_reg(u, opr, REGCLASS_XMM, mask & (imm >> 4), size);
return 0;
}
/*
* decode_operand
*
@@ -806,6 +829,9 @@ decode_operand(struct ud *u,
operand->base = (type - OP_ST0) + UD_R_ST0;
operand->size = 80;
break;
case OP_L:
decode_vex_immreg(u, operand, size);
break;
default :
operand->type = UD_NONE;
break;
@@ -871,6 +897,7 @@ clear_insn(register struct ud* u)
u->operand[0].type = UD_NONE;
u->operand[1].type = UD_NONE;
u->operand[2].type = UD_NONE;
u->operand[3].type = UD_NONE;
}
@@ -1120,6 +1147,9 @@ decode_ext(struct ud *u, uint16_t ptr)
return decode_ssepfx(u);
case UD_TAB__OPC_VEX:
return decode_vex(u);
case UD_TAB__OPC_VEX_W:
idx = vex_w(u);
break;
case UD_TAB__OPC_TABLE:
return decode_opcode(u);
default:
+1
View File
@@ -93,6 +93,7 @@ enum ud_operand_code {
OP_V, OP_W, OP_Q, OP_P,
OP_U, OP_N, OP_MU, OP_H,
OP_L,
OP_R, OP_C, OP_D,
+1
View File
@@ -85,6 +85,7 @@ class UdItabGenerator:
"U" : [ "OP_U" , "SZ_O" ],
"V" : [ "OP_V" , "SZ_O" ],
"H" : [ "OP_H" , "SZ_O" ],
"L" : [ "OP_L" , "SZ_O" ],
"MwU" : [ "OP_MU" , "SZ_WO" ],
"MdU" : [ "OP_MU" , "SZ_DO" ],
"MqU" : [ "OP_MU" , "SZ_QO" ],
+8 -2
View File
@@ -134,6 +134,7 @@ class UdOpcodeTable:
else (((int(v, 16) & 0xf) + 1) / 2)),
# AVX
'/vex' : lambda v: UdOpcodeTable.vex2idx(v),
'/vexw' : lambda v: 0 if v == '0' else 1,
# Vendor
'/vendor': lambda v: UdOpcodeTable.vendor2idx(v)
}
@@ -152,6 +153,7 @@ class UdOpcodeTable:
'/3dnow' : { 'label' : 'UD_TAB__OPC_3DNOW', 'size' : 256 },
'/vendor' : { 'label' : 'UD_TAB__OPC_VENDOR', 'size' : 3 },
'/vex' : { 'label' : 'UD_TAB__OPC_VEX', 'size' : 16 },
'/vexw' : { 'label' : 'UD_TAB__OPC_VEX_W', 'size' : 2 },
}
@@ -426,13 +428,17 @@ class UdOpcodeTables(object):
if 'avx' in insnDef['cpuid'] and '/sse' in opcexts:
sseoprs = []
for opr in insnDef['operands']:
if opr not in ( 'H', ):
if opr not in ( 'H', 'L'):
sseoprs.append(opr)
sseopcexts = {}
for e, v in opcexts.iteritems():
if e not in ( 'vexw', ):
sseopcexts[e] = v
self.addInsn(mnemonic=insnDef['mnemonic'],
prefixes=insnDef['prefixes'],
opcodes=opcodes,
opcexts=opcexts,
opcexts=sseopcexts,
operands=sseoprs,
cpuid=insnDef['cpuid'])