424 lines
12 KiB
Diff
424 lines
12 KiB
Diff
From 2235ecb8afebeb56baf29eb98de34cfa1b95f697 Mon Sep 17 00:00:00 2001
|
|
From: Jan Beulich <jbeulich@suse.com>
|
|
Date: Fri, 14 Jan 2022 10:54:21 +0100
|
|
Subject: [PATCH] x86: reduce AVX512-FP16 set of insns decoded through
|
|
vex_w_table[]
|
|
|
|
Like already indicated during review of the original submission, there's
|
|
really only very few insns where going through this table is easier /
|
|
cheaper than using suitable macros. Utilize %XH more and introduce
|
|
similar %XS and %XD (which subsequently can be used for further table
|
|
size reduction).
|
|
|
|
While there also switch to using oappend() in 'XH' macro processing.
|
|
|
|
diff --git a/opcodes/i386-dis-evex-prefix.h b/opcodes/i386-dis-evex-prefix.h
|
|
index 9c8156ac11e..64a43ce02a1 100644
|
|
--- a/opcodes/i386-dis-evex-prefix.h
|
|
+++ b/opcodes/i386-dis-evex-prefix.h
|
|
@@ -375,17 +375,17 @@
|
|
{ "vfmsub213s%XW", { XMScalar, VexScalar, EXdq, EXxEVexR }, 0 },
|
|
{ "v4fnmaddss", { XMScalar, VexScalar, Mxmm }, 0 },
|
|
},
|
|
- /* PREFIX_EVEX_0F3A08_W_0 */
|
|
+ /* PREFIX_EVEX_0F3A08 */
|
|
{
|
|
- { "vrndscaleph", { XM, EXxh, EXxEVexS, Ib }, 0 },
|
|
+ { "vrndscalep%XH", { XM, EXxh, EXxEVexS, Ib }, 0 },
|
|
{ Bad_Opcode },
|
|
- { "vrndscaleps", { XM, EXx, EXxEVexS, Ib }, 0 },
|
|
+ { "vrndscalep%XS", { XM, EXx, EXxEVexS, Ib }, 0 },
|
|
},
|
|
- /* PREFIX_EVEX_0F3A0A_W_0 */
|
|
+ /* PREFIX_EVEX_0F3A0A */
|
|
{
|
|
- { "vrndscalesh", { XMScalar, VexScalar, EXw, EXxEVexS, Ib }, 0 },
|
|
+ { "vrndscales%XH", { XMScalar, VexScalar, EXw, EXxEVexS, Ib }, 0 },
|
|
{ Bad_Opcode },
|
|
- { "vrndscaless", { XMScalar, VexScalar, EXd, EXxEVexS, Ib }, 0 },
|
|
+ { "vrndscales%XS", { XMScalar, VexScalar, EXd, EXxEVexS, Ib }, 0 },
|
|
},
|
|
/* PREFIX_EVEX_0F3A26 */
|
|
{
|
|
@@ -482,27 +482,18 @@
|
|
{ "vmulp%XH", { XM, Vex, EXxh, EXxEVexR }, 0 },
|
|
{ "vmuls%XH", { XMM, VexScalar, EXw, EXxEVexR }, 0 },
|
|
},
|
|
- /* PREFIX_EVEX_MAP5_5A_W_0 */
|
|
+ /* PREFIX_EVEX_MAP5_5A */
|
|
{
|
|
- { "vcvtph2pd", { XM, EXxmmqdh, EXxEVexS }, 0 },
|
|
- { "vcvtsh2sd", { XMM, VexScalar, EXw, EXxEVexS }, 0 },
|
|
+ { "vcvtp%XH2pd", { XM, EXxmmqdh, EXxEVexS }, 0 },
|
|
+ { "vcvts%XH2sd", { XMM, VexScalar, EXw, EXxEVexS }, 0 },
|
|
+ { "vcvtp%XD2ph%XZ", { XMM, EXx, EXxEVexR }, 0 },
|
|
+ { "vcvts%XD2sh", { XMM, VexScalar, EXq, EXxEVexR }, 0 },
|
|
},
|
|
- /* PREFIX_EVEX_MAP5_5A_W_1 */
|
|
+ /* PREFIX_EVEX_MAP5_5B */
|
|
{
|
|
- { Bad_Opcode },
|
|
- { Bad_Opcode },
|
|
- { "vcvtpd2ph%XZ", { XMM, EXx, EXxEVexR }, 0 },
|
|
- { "vcvtsd2sh", { XMM, VexScalar, EXq, EXxEVexR }, 0 },
|
|
- },
|
|
- /* PREFIX_EVEX_MAP5_5B_W_0 */
|
|
- {
|
|
- { "vcvtdq2ph%XY", { XMxmmq, EXx, EXxEVexR }, 0 },
|
|
- { "vcvttph2dq", { XM, EXxmmqh, EXxEVexS }, 0 },
|
|
- { "vcvtph2dq", { XM, EXxmmqh, EXxEVexR }, 0 },
|
|
- },
|
|
- /* PREFIX_EVEX_MAP5_5B_W_1 */
|
|
- {
|
|
- { "vcvtqq2ph%XZ", { XMM, EXx, EXxEVexR }, 0 },
|
|
+ { VEX_W_TABLE (EVEX_W_MAP5_5B_P_0) },
|
|
+ { "vcvttp%XH2dq", { XM, EXxmmqh, EXxEVexS }, 0 },
|
|
+ { "vcvtp%XH2dq", { XM, EXxmmqh, EXxEVexR }, 0 },
|
|
},
|
|
/* PREFIX_EVEX_MAP5_5C */
|
|
{
|
|
@@ -526,47 +517,47 @@
|
|
},
|
|
/* PREFIX_EVEX_MAP5_78 */
|
|
{
|
|
- { VEX_W_TABLE (EVEX_W_MAP5_78_P_0) },
|
|
+ { "vcvttp%XH2udq", { XM, EXxmmqh, EXxEVexS }, 0 },
|
|
{ "vcvttsh2usi", { Gdq, EXw, EXxEVexS }, 0 },
|
|
- { VEX_W_TABLE (EVEX_W_MAP5_78_P_2) },
|
|
+ { "vcvttp%XH2uqq", { XM, EXxmmqdh, EXxEVexS }, 0 },
|
|
},
|
|
/* PREFIX_EVEX_MAP5_79 */
|
|
{
|
|
- { VEX_W_TABLE (EVEX_W_MAP5_79_P_0) },
|
|
+ { "vcvtp%XH2udq", { XM, EXxmmqh, EXxEVexR }, 0 },
|
|
{ "vcvtsh2usi", { Gdq, EXw, EXxEVexR }, 0 },
|
|
- { VEX_W_TABLE (EVEX_W_MAP5_79_P_2) },
|
|
+ { "vcvtp%XH2uqq", { XM, EXxmmqdh, EXxEVexR }, 0 },
|
|
},
|
|
/* PREFIX_EVEX_MAP5_7A */
|
|
{
|
|
{ Bad_Opcode },
|
|
{ Bad_Opcode },
|
|
- { VEX_W_TABLE (EVEX_W_MAP5_7A_P_2) },
|
|
+ { "vcvttp%XH2qq", { XM, EXxmmqdh, EXxEVexS }, 0 },
|
|
{ VEX_W_TABLE (EVEX_W_MAP5_7A_P_3) },
|
|
},
|
|
/* PREFIX_EVEX_MAP5_7B */
|
|
{
|
|
{ Bad_Opcode },
|
|
{ "vcvtusi2sh{%LQ|}", { XMScalar, VexScalar, EXxEVexR, Edq }, 0 },
|
|
- { VEX_W_TABLE (EVEX_W_MAP5_7B_P_2) },
|
|
+ { "vcvtp%XH2qq", { XM, EXxmmqdh, EXxEVexR }, 0 },
|
|
},
|
|
/* PREFIX_EVEX_MAP5_7C */
|
|
{
|
|
- { VEX_W_TABLE (EVEX_W_MAP5_7C_P_0) },
|
|
+ { "vcvttp%XH2uw", { XM, EXxh, EXxEVexS }, 0 },
|
|
{ Bad_Opcode },
|
|
- { VEX_W_TABLE (EVEX_W_MAP5_7C_P_2) },
|
|
+ { "vcvttp%XH2w", { XM, EXxh, EXxEVexS }, 0 },
|
|
},
|
|
- /* PREFIX_EVEX_MAP5_7D_W_0 */
|
|
+ /* PREFIX_EVEX_MAP5_7D */
|
|
{
|
|
- { "vcvtph2uw", { XM, EXxh, EXxEVexR }, 0 },
|
|
- { "vcvtw2ph", { XM, EXxh, EXxEVexR }, 0 },
|
|
- { "vcvtph2w", { XM, EXxh, EXxEVexR }, 0 },
|
|
- { "vcvtuw2ph", { XM, EXxh, EXxEVexR }, 0 },
|
|
+ { "vcvtp%XH2uw", { XM, EXxh, EXxEVexR }, 0 },
|
|
+ { "vcvtw2p%XH", { XM, EXxh, EXxEVexR }, 0 },
|
|
+ { "vcvtp%XH2w", { XM, EXxh, EXxEVexR }, 0 },
|
|
+ { "vcvtuw2p%XH", { XM, EXxh, EXxEVexR }, 0 },
|
|
},
|
|
/* PREFIX_EVEX_MAP6_13 */
|
|
{
|
|
- { VEX_W_TABLE (EVEX_W_MAP6_13_P_0) },
|
|
+ { "vcvts%XH2ss", { XMM, VexScalar, EXw, EXxEVexS }, 0 },
|
|
{ Bad_Opcode },
|
|
- { VEX_W_TABLE (EVEX_W_MAP6_13_P_2) },
|
|
+ { "vcvtp%XH2psx", { XM, EXxmmqh, EXxEVexS }, 0 },
|
|
},
|
|
/* PREFIX_EVEX_MAP6_56 */
|
|
{
|
|
diff --git a/opcodes/i386-dis-evex-w.h b/opcodes/i386-dis-evex-w.h
|
|
index 62c3d3b9afb..fc0a0791d1d 100644
|
|
--- a/opcodes/i386-dis-evex-w.h
|
|
+++ b/opcodes/i386-dis-evex-w.h
|
|
@@ -550,19 +550,11 @@
|
|
{ Bad_Opcode },
|
|
{ "vpermilpd", { XM, EXx, Ib }, PREFIX_DATA },
|
|
},
|
|
- /* EVEX_W_0F3A08 */
|
|
- {
|
|
- { PREFIX_TABLE (PREFIX_EVEX_0F3A08_W_0) },
|
|
- },
|
|
/* EVEX_W_0F3A09 */
|
|
{
|
|
{ Bad_Opcode },
|
|
{ "vrndscalepd", { XM, EXx, EXxEVexS, Ib }, PREFIX_DATA },
|
|
},
|
|
- /* EVEX_W_0F3A0A */
|
|
- {
|
|
- { PREFIX_TABLE (PREFIX_EVEX_0F3A0A_W_0) },
|
|
- },
|
|
/* EVEX_W_0F3A0B */
|
|
{
|
|
{ Bad_Opcode },
|
|
@@ -636,62 +628,13 @@
|
|
{ Bad_Opcode },
|
|
{ "vpshrdw", { XM, Vex, EXx, Ib }, 0 },
|
|
},
|
|
- /* EVEX_W_MAP5_5A */
|
|
- {
|
|
- { PREFIX_TABLE (PREFIX_EVEX_MAP5_5A_W_0) },
|
|
- { PREFIX_TABLE (PREFIX_EVEX_MAP5_5A_W_1) },
|
|
- },
|
|
- /* EVEX_W_MAP5_5B */
|
|
- {
|
|
- { PREFIX_TABLE (PREFIX_EVEX_MAP5_5B_W_0) },
|
|
- { PREFIX_TABLE (PREFIX_EVEX_MAP5_5B_W_1) },
|
|
- },
|
|
- /* EVEX_W_MAP5_78_P_0 */
|
|
- {
|
|
- { "vcvttph2udq", { XM, EXxmmqh, EXxEVexS }, 0 },
|
|
- },
|
|
- /* EVEX_W_MAP5_78_P_2 */
|
|
- {
|
|
- { "vcvttph2uqq", { XM, EXxmmqdh, EXxEVexS }, 0 },
|
|
- },
|
|
- /* EVEX_W_MAP5_79_P_0 */
|
|
- {
|
|
- { "vcvtph2udq", { XM, EXxmmqh, EXxEVexR }, 0 },
|
|
- },
|
|
- /* EVEX_W_MAP5_79_P_2 */
|
|
+ /* EVEX_W_MAP5_5B_P_0 */
|
|
{
|
|
- { "vcvtph2uqq", { XM, EXxmmqdh, EXxEVexR }, 0 },
|
|
- },
|
|
- /* EVEX_W_MAP5_7A_P_2 */
|
|
- {
|
|
- { "vcvttph2qq", { XM, EXxmmqdh, EXxEVexS }, 0 },
|
|
+ { "vcvtdq2ph%XY", { XMxmmq, EXx, EXxEVexR }, 0 },
|
|
+ { "vcvtqq2ph%XZ", { XMM, EXx, EXxEVexR }, 0 },
|
|
},
|
|
/* EVEX_W_MAP5_7A_P_3 */
|
|
{
|
|
{ "vcvtudq2ph%XY", { XMxmmq, EXx, EXxEVexR }, 0 },
|
|
{ "vcvtuqq2ph%XZ", { XMM, EXx, EXxEVexR }, 0 },
|
|
},
|
|
- /* EVEX_W_MAP5_7B_P_2 */
|
|
- {
|
|
- { "vcvtph2qq", { XM, EXxmmqdh, EXxEVexR }, 0 },
|
|
- },
|
|
- /* EVEX_W_MAP5_7C_P_0 */
|
|
- {
|
|
- { "vcvttph2uw", { XM, EXxh, EXxEVexS }, 0 },
|
|
- },
|
|
- /* EVEX_W_MAP5_7C_P_2 */
|
|
- {
|
|
- { "vcvttph2w", { XM, EXxh, EXxEVexS }, 0 },
|
|
- },
|
|
- /* EVEX_W_MAP5_7D */
|
|
- {
|
|
- { PREFIX_TABLE (PREFIX_EVEX_MAP5_7D_W_0) },
|
|
- },
|
|
- /* EVEX_W_MAP6_13_P_0 */
|
|
- {
|
|
- { "vcvtsh2ss", { XMM, VexScalar, EXw, EXxEVexS }, 0 },
|
|
- },
|
|
- /* EVEX_W_MAP6_13_P_2 */
|
|
- {
|
|
- { "vcvtph2psx", { XM, EXxmmqh, EXxEVexS }, 0 },
|
|
- },
|
|
diff --git a/opcodes/i386-dis-evex.h b/opcodes/i386-dis-evex.h
|
|
index d79c78c1793..11cc257bb2e 100644
|
|
--- a/opcodes/i386-dis-evex.h
|
|
+++ b/opcodes/i386-dis-evex.h
|
|
@@ -593,9 +593,9 @@ static const struct dis386 evex_table[][256] = {
|
|
{ Bad_Opcode },
|
|
{ Bad_Opcode },
|
|
/* 08 */
|
|
- { VEX_W_TABLE (EVEX_W_0F3A08) },
|
|
+ { PREFIX_TABLE (PREFIX_EVEX_0F3A08) },
|
|
{ VEX_W_TABLE (EVEX_W_0F3A09) },
|
|
- { VEX_W_TABLE (EVEX_W_0F3A0A) },
|
|
+ { PREFIX_TABLE (PREFIX_EVEX_0F3A0A) },
|
|
{ VEX_W_TABLE (EVEX_W_0F3A0B) },
|
|
{ Bad_Opcode },
|
|
{ Bad_Opcode },
|
|
@@ -976,8 +976,8 @@ static const struct dis386 evex_table[][256] = {
|
|
/* 58 */
|
|
{ PREFIX_TABLE (PREFIX_EVEX_MAP5_58) },
|
|
{ PREFIX_TABLE (PREFIX_EVEX_MAP5_59) },
|
|
- { VEX_W_TABLE (EVEX_W_MAP5_5A) },
|
|
- { VEX_W_TABLE (EVEX_W_MAP5_5B) },
|
|
+ { PREFIX_TABLE (PREFIX_EVEX_MAP5_5A) },
|
|
+ { PREFIX_TABLE (PREFIX_EVEX_MAP5_5B) },
|
|
{ PREFIX_TABLE (PREFIX_EVEX_MAP5_5C) },
|
|
{ PREFIX_TABLE (PREFIX_EVEX_MAP5_5D) },
|
|
{ PREFIX_TABLE (PREFIX_EVEX_MAP5_5E) },
|
|
@@ -1015,7 +1015,7 @@ static const struct dis386 evex_table[][256] = {
|
|
{ PREFIX_TABLE (PREFIX_EVEX_MAP5_7A) },
|
|
{ PREFIX_TABLE (PREFIX_EVEX_MAP5_7B) },
|
|
{ PREFIX_TABLE (PREFIX_EVEX_MAP5_7C) },
|
|
- { VEX_W_TABLE (EVEX_W_MAP5_7D) },
|
|
+ { PREFIX_TABLE (PREFIX_EVEX_MAP5_7D) },
|
|
{ "vmovw", { Edw, XMScalar }, PREFIX_DATA },
|
|
{ Bad_Opcode },
|
|
/* 80 */
|
|
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
|
|
index 4e0e1559339..afc3743e4e8 100644
|
|
--- a/opcodes/i386-dis.c
|
|
+++ b/opcodes/i386-dis.c
|
|
@@ -1212,8 +1212,8 @@ enum
|
|
PREFIX_EVEX_0F38AA,
|
|
PREFIX_EVEX_0F38AB,
|
|
|
|
- PREFIX_EVEX_0F3A08_W_0,
|
|
- PREFIX_EVEX_0F3A0A_W_0,
|
|
+ PREFIX_EVEX_0F3A08,
|
|
+ PREFIX_EVEX_0F3A0A,
|
|
PREFIX_EVEX_0F3A26,
|
|
PREFIX_EVEX_0F3A27,
|
|
PREFIX_EVEX_0F3A56,
|
|
@@ -1233,10 +1233,8 @@ enum
|
|
PREFIX_EVEX_MAP5_51,
|
|
PREFIX_EVEX_MAP5_58,
|
|
PREFIX_EVEX_MAP5_59,
|
|
- PREFIX_EVEX_MAP5_5A_W_0,
|
|
- PREFIX_EVEX_MAP5_5A_W_1,
|
|
- PREFIX_EVEX_MAP5_5B_W_0,
|
|
- PREFIX_EVEX_MAP5_5B_W_1,
|
|
+ PREFIX_EVEX_MAP5_5A,
|
|
+ PREFIX_EVEX_MAP5_5B,
|
|
PREFIX_EVEX_MAP5_5C,
|
|
PREFIX_EVEX_MAP5_5D,
|
|
PREFIX_EVEX_MAP5_5E,
|
|
@@ -1246,7 +1244,7 @@ enum
|
|
PREFIX_EVEX_MAP5_7A,
|
|
PREFIX_EVEX_MAP5_7B,
|
|
PREFIX_EVEX_MAP5_7C,
|
|
- PREFIX_EVEX_MAP5_7D_W_0,
|
|
+ PREFIX_EVEX_MAP5_7D,
|
|
|
|
PREFIX_EVEX_MAP6_13,
|
|
PREFIX_EVEX_MAP6_56,
|
|
@@ -1746,9 +1744,7 @@ enum
|
|
EVEX_W_0F3883,
|
|
|
|
EVEX_W_0F3A05,
|
|
- EVEX_W_0F3A08,
|
|
EVEX_W_0F3A09,
|
|
- EVEX_W_0F3A0A,
|
|
EVEX_W_0F3A0B,
|
|
EVEX_W_0F3A18_L_n,
|
|
EVEX_W_0F3A19_L_n,
|
|
@@ -1765,21 +1761,8 @@ enum
|
|
EVEX_W_0F3A70,
|
|
EVEX_W_0F3A72,
|
|
|
|
- EVEX_W_MAP5_5A,
|
|
- EVEX_W_MAP5_5B,
|
|
- EVEX_W_MAP5_78_P_0,
|
|
- EVEX_W_MAP5_78_P_2,
|
|
- EVEX_W_MAP5_79_P_0,
|
|
- EVEX_W_MAP5_79_P_2,
|
|
- EVEX_W_MAP5_7A_P_2,
|
|
+ EVEX_W_MAP5_5B_P_0,
|
|
EVEX_W_MAP5_7A_P_3,
|
|
- EVEX_W_MAP5_7B_P_2,
|
|
- EVEX_W_MAP5_7C_P_0,
|
|
- EVEX_W_MAP5_7C_P_2,
|
|
- EVEX_W_MAP5_7D,
|
|
-
|
|
- EVEX_W_MAP6_13_P_0,
|
|
- EVEX_W_MAP6_13_P_2,
|
|
};
|
|
|
|
typedef void (*op_rtn) (instr_info *ins, int bytemode, int sizeflag);
|
|
@@ -1840,7 +1823,9 @@ struct dis386 {
|
|
"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)
|
|
+ "XD" => print 'd' if EVEX.W=1, EVEX.W=0 is not a valid encoding
|
|
"XH" => print 'h' if EVEX.W=0, EVEX.W=1 is not a valid encoding (for FP16)
|
|
+ "XS" => print 's' if EVEX.W=0, EVEX.W=1 is not a valid encoding
|
|
"XV" => print "{vex3}" pseudo prefix
|
|
"LQ" => print 'l' ('d' in Intel mode) or 'q' for memory operand, cond
|
|
being false, or no operand at all in 64bit mode, or if suffix_always
|
|
@@ -10496,6 +10481,23 @@ putop (instr_info *ins, const char *in_template, int sizeflag)
|
|
}
|
|
break;
|
|
case 'D':
|
|
+ if (l == 1)
|
|
+ {
|
|
+ switch (last[0])
|
|
+ {
|
|
+ case 'X':
|
|
+ if (ins->vex.w)
|
|
+ *ins->obufp++ = 'd';
|
|
+ else
|
|
+ oappend (ins, "{bad}");
|
|
+ break;
|
|
+ default:
|
|
+ abort ();
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+ if (l)
|
|
+ abort ();
|
|
if (ins->intel_syntax || !(sizeflag & SUFFIX_ALWAYS))
|
|
break;
|
|
USED_REX (REX_W);
|
|
@@ -10582,13 +10584,7 @@ putop (instr_info *ins, const char *in_template, int sizeflag)
|
|
if (ins->vex.w == 0)
|
|
*ins->obufp++ = 'h';
|
|
else
|
|
- {
|
|
- *ins->obufp++ = '{';
|
|
- *ins->obufp++ = 'b';
|
|
- *ins->obufp++ = 'a';
|
|
- *ins->obufp++ = 'd';
|
|
- *ins->obufp++ = '}';
|
|
- }
|
|
+ oappend (ins, "{bad}");
|
|
}
|
|
else
|
|
abort ();
|
|
@@ -10752,9 +10748,13 @@ putop (instr_info *ins, const char *in_template, int sizeflag)
|
|
ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
|
}
|
|
}
|
|
+ break;
|
|
}
|
|
- else if (l == 1 && last[0] == 'L')
|
|
+ if (l != 1)
|
|
+ abort ();
|
|
+ switch (last[0])
|
|
{
|
|
+ case 'L':
|
|
if (ins->address_mode == mode_64bit
|
|
&& !(ins->prefixes & PREFIX_ADDR))
|
|
{
|
|
@@ -10764,9 +10764,15 @@ putop (instr_info *ins, const char *in_template, int sizeflag)
|
|
}
|
|
|
|
goto case_S;
|
|
+ case 'X':
|
|
+ if (!ins->vex.w)
|
|
+ *ins->obufp++ = 's';
|
|
+ else
|
|
+ oappend (ins, "{bad}");
|
|
+ break;
|
|
+ default:
|
|
+ abort ();
|
|
}
|
|
- else
|
|
- abort ();
|
|
break;
|
|
case 'V':
|
|
if (l == 0)
|
|
--
|
|
2.33.0
|
|
|