aboutsummaryrefslogtreecommitdiff
path: root/opcodes
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@novell.com>2015-04-23 16:42:40 +0200
committerJan Beulich <jbeulich@suse.com>2015-04-23 16:42:40 +0200
commit04d824a468650c632d228b977006139f17d646a4 (patch)
tree1fc66e25aab33ba9ef1109ec3d6a0ad7001539b2 /opcodes
parentaf508cb92f8fa7eed6c7f2bd3a49d42701db5900 (diff)
downloadgdb-04d824a468650c632d228b977006139f17d646a4.zip
gdb-04d824a468650c632d228b977006139f17d646a4.tar.gz
gdb-04d824a468650c632d228b977006139f17d646a4.tar.bz2
x86: disambiguate disassembly of certain AVX512 insns
Certain conversion operations as well as vfpclassp{d,s} are ambiguous when the input operand is in memory and no broadcast is being used. While in Intel mode this gets resolved by printing suitable operand size modifiers, AT&T mode need mnemonic suffixes to be added. gas/testsuite/ 2015-04-23 Jan Beulich <jbeulich@suse.com> * gas/i386/avx512dq.d: Add 'z' suffix to vfpclassp{d,s} non- register, non-broadcast cases. * gas/i386/x86-64-avx512dq.d: Likewise. * gas/i386/avx512dq_vl.d: Add 'x' and 'y' suffixes to vcvt{,u}qq2ps and vfpclassp{d,s} non-register, non-broadcast cases. * gas/i386/x86-64-avx512dq_vl.d: Likewise. * gas/i386/avx512f_vl.d: Add 'x' and 'y' suffixes to vcvt{,t}pd2{,u}dq and vcvtpd2ps non-register, non-broadcast cases. * gas/i386/x86-64-avx512f_vl.d: Likewise. opcodes/ 2015-04-23 Jan Beulich <jbeulich@suse.com> * i386-dis.c (putop): Extend "XY" handling to AVX512. Handle "XZ". * i386-dis-evex.h.c (vcvtpd2ps, vcvtqq2ps, vcvttpd2udq, vcvtpd2udq, vcvtuqq2ps, vcvttpd2dq, vcvtpd2dq): Add %XY. (vfpclasspd, vfpclassps): Add %XZ.
Diffstat (limited to 'opcodes')
-rw-r--r--opcodes/ChangeLog7
-rw-r--r--opcodes/i386-dis-evex.h18
-rw-r--r--opcodes/i386-dis.c40
3 files changed, 52 insertions, 13 deletions
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index b0089d0..26eb961 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,10 @@
+2015-04-23 Jan Beulich <jbeulich@suse.com>
+
+ * i386-dis.c (putop): Extend "XY" handling to AVX512. Handle "XZ".
+ * i386-dis-evex.h.c (vcvtpd2ps, vcvtqq2ps, vcvttpd2udq,
+ vcvtpd2udq, vcvtuqq2ps, vcvttpd2dq, vcvtpd2dq): Add %XY.
+ (vfpclasspd, vfpclassps): Add %XZ.
+
2015-04-15 H.J. Lu <hongjiu.lu@intel.com>
* i386-dis.c (PREFIX_UD_SHIFT): Removed.
diff --git a/opcodes/i386-dis-evex.h b/opcodes/i386-dis-evex.h
index 14426b0..551ecdf 100644
--- a/opcodes/i386-dis-evex.h
+++ b/opcodes/i386-dis-evex.h
@@ -3025,7 +3025,7 @@ static const struct dis386 evex_table[][256] = {
/* EVEX_W_0F5A_P_2 */
{
{ Bad_Opcode },
- { "vcvtpd2ps", { XMxmmq, EXx, EXxEVexR }, 0 },
+ { "vcvtpd2ps%XY", { XMxmmq, EXx, EXxEVexR }, 0 },
},
/* EVEX_W_0F5A_P_3 */
{
@@ -3035,7 +3035,7 @@ static const struct dis386 evex_table[][256] = {
/* EVEX_W_0F5B_P_0 */
{
{ "vcvtdq2ps", { XM, EXx, EXxEVexR }, 0 },
- { "vcvtqq2ps", { XMxmmq, EXx, EXxEVexR }, 0 },
+ { "vcvtqq2ps%XY", { XMxmmq, EXx, EXxEVexR }, 0 },
},
/* EVEX_W_0F5B_P_1 */
{
@@ -3192,7 +3192,7 @@ static const struct dis386 evex_table[][256] = {
/* EVEX_W_0F78_P_0 */
{
{ "vcvttps2udq", { XM, EXx, EXxEVexS }, 0 },
- { "vcvttpd2udq", { XMxmmq, EXx, EXxEVexS }, 0 },
+ { "vcvttpd2udq%XY", { XMxmmq, EXx, EXxEVexS }, 0 },
},
/* EVEX_W_0F78_P_2 */
{
@@ -3202,7 +3202,7 @@ static const struct dis386 evex_table[][256] = {
/* EVEX_W_0F79_P_0 */
{
{ "vcvtps2udq", { XM, EXx, EXxEVexR }, 0 },
- { "vcvtpd2udq", { XMxmmq, EXx, EXxEVexR }, 0 },
+ { "vcvtpd2udq%XY", { XMxmmq, EXx, EXxEVexR }, 0 },
},
/* EVEX_W_0F79_P_2 */
{
@@ -3222,7 +3222,7 @@ static const struct dis386 evex_table[][256] = {
/* EVEX_W_0F7A_P_3 */
{
{ "vcvtudq2ps", { XM, EXx, EXxEVexR }, 0 },
- { "vcvtuqq2ps", { XMxmmq, EXx, EXxEVexR }, 0 },
+ { "vcvtuqq2ps%XY", { XMxmmq, EXx, EXxEVexR }, 0 },
},
/* EVEX_W_0F7B_P_1 */
{
@@ -3318,12 +3318,12 @@ static const struct dis386 evex_table[][256] = {
/* EVEX_W_0FE6_P_2 */
{
{ Bad_Opcode },
- { "vcvttpd2dq", { XMxmmq, EXx, EXxEVexS }, 0 },
+ { "vcvttpd2dq%XY", { XMxmmq, EXx, EXxEVexS }, 0 },
},
/* EVEX_W_0FE6_P_3 */
{
{ Bad_Opcode },
- { "vcvtpd2dq", { XMxmmq, EXx, EXxEVexR }, 0 },
+ { "vcvtpd2dq%XY", { XMxmmq, EXx, EXxEVexR }, 0 },
},
/* EVEX_W_0FE7_P_2 */
{
@@ -3800,8 +3800,8 @@ static const struct dis386 evex_table[][256] = {
},
/* EVEX_W_0F3A66_P_2 */
{
- { "vfpclassps", { XMask, EXx, Ib }, 0 },
- { "vfpclasspd", { XMask, EXx, Ib }, 0 },
+ { "vfpclassps%XZ", { XMask, EXx, Ib }, 0 },
+ { "vfpclasspd%XZ", { XMask, EXx, Ib }, 0 },
},
/* EVEX_W_0F3A67_P_2 */
{
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index a25acc6..88c1758 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -2413,8 +2413,10 @@ struct dis386 {
'%' => add 1 upper case letter to the macro.
2 upper case letter macros:
- "XY" => print 'x' or 'y' if no register operands or suffix_always
- is true.
+ "XY" => print 'x' or 'y' if suffix_always is true or no register
+ operands and no broadcast.
+ "XZ" => print 'x', 'y', or 'z' if suffix_always is true or no
+ register operands and no broadcast.
"XW" => print 's', 'd' depending on the VEX.W bit (for FMA)
"LQ" => print 'l' ('d' in Intel mode) or 'q' for memory operand
or suffix_always is true
@@ -13795,6 +13797,34 @@ case_B:
*obufp++ = 'd';
break;
case 'Z':
+ if (l != 0 || len != 1)
+ {
+ if (l != 1 || len != 2 || last[0] != 'X')
+ {
+ SAVE_LAST (*p);
+ break;
+ }
+ if (!need_vex || !vex.evex)
+ abort ();
+ if (intel_syntax
+ || ((modrm.mod == 3 || vex.b) && !(sizeflag & SUFFIX_ALWAYS)))
+ break;
+ switch (vex.length)
+ {
+ case 128:
+ *obufp++ = 'x';
+ break;
+ case 256:
+ *obufp++ = 'y';
+ break;
+ case 512:
+ *obufp++ = 'z';
+ break;
+ default:
+ abort ();
+ }
+ break;
+ }
if (intel_syntax)
break;
if (address_mode == mode_64bit && (sizeflag & SUFFIX_ALWAYS))
@@ -14093,7 +14123,7 @@ case_S:
if (!need_vex)
abort ();
if (intel_syntax
- || (modrm.mod == 3 && !(sizeflag & SUFFIX_ALWAYS)))
+ || ((modrm.mod == 3 || vex.b) && !(sizeflag & SUFFIX_ALWAYS)))
break;
switch (vex.length)
{
@@ -14103,8 +14133,10 @@ case_S:
case 256:
*obufp++ = 'y';
break;
+ case 512:
+ if (!vex.evex)
default:
- abort ();
+ abort ();
}
}
break;