diff options
author | Robert Mustacchi <rm@joyent.com> | 2012-12-12 01:34:14 +0000 |
---|---|---|
committer | Robert Mustacchi <rm@joyent.com> | 2012-12-12 01:36:45 +0000 |
commit | 910783ff63b1b9faa2038e46306ac3113c491146 (patch) | |
tree | bac7d8c90163b9bb61966b217a8eae392986d8e7 | |
parent | 8847f01c1f02e74ff165f58c4f429feb5fbfeb9f (diff) | |
download | illumos-joyent-910783ff63b1b9faa2038e46306ac3113c491146.tar.gz |
OS-1760 Need disassembler support for rdrand and f16c20121213release-20121213
-rw-r--r-- | usr/src/common/dis/i386/dis_tables.c | 39 |
1 files changed, 34 insertions, 5 deletions
diff --git a/usr/src/common/dis/i386/dis_tables.c b/usr/src/common/dis/i386/dis_tables.c index 87158fa2eb..8258096e43 100644 --- a/usr/src/common/dis/i386/dis_tables.c +++ b/usr/src/common/dis/i386/dis_tables.c @@ -32,7 +32,6 @@ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ - #include "dis_tables.h" /* BEGIN CSTYLED */ @@ -541,6 +540,16 @@ const instable_t dis_op0FC7[8] = { }; /* + * Decode table for 0x0FC7 opcode (group 9) mode 3 + */ + +const instable_t dis_op0FC7m3[8] = { + +/* [0] */ INVALID, INVALID, INVALID, INVALID, +/* [4] */ INVALID, INVALID, TNS("rdrand",MG9), INVALID, +}; + +/* * Decode table for 0x0FC7 opcode with 0x66 prefix */ @@ -1215,7 +1224,7 @@ const instable_t dis_opAVX660F38[256] = { /* [08] */ TNSZ("vpsignb",VEX_RMrX,16),TNSZ("vpsignw",VEX_RMrX,16),TNSZ("vpsignd",VEX_RMrX,16),TNSZ("vpmulhrsw",VEX_RMrX,16), /* [0C] */ TNSZ("vpermilps",VEX_RMrX,8),TNSZ("vpermilpd",VEX_RMrX,16),TNSZ("vtestps",VEX_RRI,8), TNSZ("vtestpd",VEX_RRI,16), -/* [10] */ INVALID, INVALID, INVALID, INVALID, +/* [10] */ INVALID, INVALID, INVALID, TNSZ("vcvtph2ps",VEX_MX,16), /* [14] */ INVALID, INVALID, INVALID, TNSZ("vptest",VEX_RRI,16), /* [18] */ TNSZ("vbroadcastss",VEX_MX,4),TNSZ("vbroadcastsd",VEX_MX,8),TNSZ("vbroadcastf128",VEX_MX,16),INVALID, /* [1C] */ TNSZ("vpabsb",VEX_MX,16),TNSZ("vpabsw",VEX_MX,16),TNSZ("vpabsd",VEX_MX,16),INVALID, @@ -1381,7 +1390,7 @@ const instable_t dis_opAVX660F3A[256] = { /* [10] */ INVALID, INVALID, INVALID, INVALID, /* [14] */ TNSZ("vpextrb",VEX_RRi,8),TNSZ("vpextrw",VEX_RRi,16),TNSZ("vpextrd",VEX_RRi,16),TNSZ("vextractps",VEX_RM,16), /* [18] */ TNSZ("vinsertf128",VEX_RMRX,16),TNSZ("vextractf128",VEX_RX,16),INVALID, INVALID, -/* [1C] */ INVALID, INVALID, INVALID, INVALID, +/* [1C] */ INVALID, TNSZ("vcvtps2ph",VEX_RX,16), INVALID, INVALID, /* [20] */ TNSZ("vpinsrb",VEX_RMRX,8),TNSZ("vinsertps",VEX_RMRX,16),TNSZ("vpinsrd",VEX_RMRX,16),INVALID, /* [24] */ INVALID, INVALID, INVALID, INVALID, @@ -3084,6 +3093,14 @@ dtrace_disx86(dis86_t *x, uint_t cpu_mode) * to the SIMD business described above, but with a different * addressing mode (and an indirect table), so we deal with it * separately (if similarly). + * + * Intel further complicated this with the release of Ivy Bridge + * where they overloaded these instructions based on the ModR/M + * bytes. The VMX instructions have a mode of 0 since they are + * memory instructions but rdrand instructions have a mode of + * 0b11 (REG_ONLY) because they only operate on registers. While + * there are different prefix formats, for now it is sufficient + * to use a single different table. */ /* @@ -3096,6 +3113,15 @@ dtrace_disx86(dis86_t *x, uint_t cpu_mode) sizeof (instable_t); /* + * If we have a mode of 0b11 then we have to rewrite this. + */ + dtrace_get_modrm(x, &mode, ®, &r_m); + if (mode == REG_ONLY) { + dp = (instable_t *)&dis_op0FC7m3[off]; + break; + } + + /* * Rewrite if this instruction used one of the magic prefixes. */ if (rep_prefix) { @@ -4438,7 +4464,8 @@ L_VEX_MX: dtrace_get_operand(x, REG_ONLY, reg, XMM_OPND, 1); dtrace_get_operand(x, mode, r_m, wbit, 0); } else if ((dp == &dis_opAVXF30F[0xE6]) || - (dp == &dis_opAVX0F[0x5][0xA])) { + (dp == &dis_opAVX0F[0x5][0xA]) || + (dp == &dis_opAVX660F38[0x13])) { /* vcvtdq2pd <xmm>, <ymm> */ /* or vcvtps2pd <xmm>, <ymm> */ dtrace_get_operand(x, REG_ONLY, reg, wbit, 1); @@ -4523,7 +4550,9 @@ L_VEX_MX: case VEX_RX: /* ModR/M.rm := op(ModR/M.reg) */ - if (dp == &dis_opAVX660F3A[0x19]) { /* vextractf128 */ + /* vextractf128 || vcvtps2ph */ + if (dp == &dis_opAVX660F3A[0x19] || + dp == &dis_opAVX660F3A[0x1d]) { x->d86_numopnds = 3; dtrace_get_modrm(x, &mode, ®, &r_m); |