From b13b1bc05435d2b8b2f1a0f48eba127a7c99fbb4 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 8 Jul 2020 11:02:08 +0200 Subject: [PATCH] x86: re-work operand swapping for FMA4 and 4-operand XOP insns There's no need for custom operand handling here, except for the VEX.W controlled operand swapping. The latter can be easily integrated into OP_REG_VexI4(). --- opcodes/ChangeLog | 7 +++ opcodes/i386-dis.c | 107 ++++++++++++++++++--------------------------- 2 files changed, 49 insertions(+), 65 deletions(-) diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 07f2594661d..5b6949cc205 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,10 @@ +2020-07-08 Jan Beulich + + * i386-dis.c (OP_EX_VexW, EXVexW, EXdVexW, EXqVexW): Delete. + (prefix_table, vex_len_table): Replace operands for FMA4 insns. + (xop_table): Replace operands of 4-operand insns. + (OP_REG_VexI4): Move VEX.W based operand swaping here. + 2020-07-07 Claudiu Zissulescu * arc-opc.c (insert_rbd): New function. diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index 956e2c35395..eb1157b6ba2 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -89,7 +89,6 @@ static void OP_XS (int, int); static void OP_M (int, int); static void OP_VEX (int, int); static void OP_EX_Vex (int, int); -static void OP_EX_VexW (int, int); static void OP_EX_VexImmW (int, int); static void OP_XMM_Vex (int, int); static void OP_XMM_VexW (int, int); @@ -423,9 +422,6 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr) #define VexGdq { OP_VEX, dq_mode } #define EXdVexScalarS { OP_EX_Vex, d_scalar_swap_mode } #define EXqVexScalarS { OP_EX_Vex, q_scalar_swap_mode } -#define EXVexW { OP_EX_VexW, x_mode } -#define EXdVexW { OP_EX_VexW, d_mode } -#define EXqVexW { OP_EX_VexW, q_mode } #define EXVexImmW { OP_EX_VexImmW, x_mode } #define XMVexScalar { OP_XMM_Vex, scalar_mode } #define XMVexW { OP_XMM_VexW, 0 } @@ -6452,28 +6448,28 @@ static const struct dis386 prefix_table[][4] = { { { Bad_Opcode }, { Bad_Opcode }, - { "vfmaddsubps", { XMVexW, Vex, EXVexW, EXVexW }, 0 }, + { "vfmaddsubps", { XM, Vex, EXx, XMVexI4 }, 0 }, }, /* PREFIX_VEX_0F3A5D */ { { Bad_Opcode }, { Bad_Opcode }, - { "vfmaddsubpd", { XMVexW, Vex, EXVexW, EXVexW }, 0 }, + { "vfmaddsubpd", { XM, Vex, EXx, XMVexI4 }, 0 }, }, /* PREFIX_VEX_0F3A5E */ { { Bad_Opcode }, { Bad_Opcode }, - { "vfmsubaddps", { XMVexW, Vex, EXVexW, EXVexW }, 0 }, + { "vfmsubaddps", { XM, Vex, EXx, XMVexI4 }, 0 }, }, /* PREFIX_VEX_0F3A5F */ { { Bad_Opcode }, { Bad_Opcode }, - { "vfmsubaddpd", { XMVexW, Vex, EXVexW, EXVexW }, 0 }, + { "vfmsubaddpd", { XM, Vex, EXx, XMVexI4 }, 0 }, }, /* PREFIX_VEX_0F3A60 */ @@ -6509,14 +6505,14 @@ static const struct dis386 prefix_table[][4] = { { { Bad_Opcode }, { Bad_Opcode }, - { "vfmaddps", { XMVexW, Vex, EXVexW, EXVexW }, 0 }, + { "vfmaddps", { XM, Vex, EXx, XMVexI4 }, 0 }, }, /* PREFIX_VEX_0F3A69 */ { { Bad_Opcode }, { Bad_Opcode }, - { "vfmaddpd", { XMVexW, Vex, EXVexW, EXVexW }, 0 }, + { "vfmaddpd", { XM, Vex, EXx, XMVexI4 }, 0 }, }, /* PREFIX_VEX_0F3A6A */ @@ -6537,14 +6533,14 @@ static const struct dis386 prefix_table[][4] = { { { Bad_Opcode }, { Bad_Opcode }, - { "vfmsubps", { XMVexW, Vex, EXVexW, EXVexW }, 0 }, + { "vfmsubps", { XM, Vex, EXx, XMVexI4 }, 0 }, }, /* PREFIX_VEX_0F3A6D */ { { Bad_Opcode }, { Bad_Opcode }, - { "vfmsubpd", { XMVexW, Vex, EXVexW, EXVexW }, 0 }, + { "vfmsubpd", { XM, Vex, EXx, XMVexI4 }, 0 }, }, /* PREFIX_VEX_0F3A6E */ @@ -6565,14 +6561,14 @@ static const struct dis386 prefix_table[][4] = { { { Bad_Opcode }, { Bad_Opcode }, - { "vfnmaddps", { XMVexW, Vex, EXVexW, EXVexW }, 0 }, + { "vfnmaddps", { XM, Vex, EXx, XMVexI4 }, 0 }, }, /* PREFIX_VEX_0F3A79 */ { { Bad_Opcode }, { Bad_Opcode }, - { "vfnmaddpd", { XMVexW, Vex, EXVexW, EXVexW }, 0 }, + { "vfnmaddpd", { XM, Vex, EXx, XMVexI4 }, 0 }, }, /* PREFIX_VEX_0F3A7A */ @@ -6593,7 +6589,7 @@ static const struct dis386 prefix_table[][4] = { { { Bad_Opcode }, { Bad_Opcode }, - { "vfnmsubps", { XMVexW, Vex, EXVexW, EXVexW }, 0 }, + { "vfnmsubps", { XM, Vex, EXx, XMVexI4 }, 0 }, { Bad_Opcode }, }, @@ -6601,7 +6597,7 @@ static const struct dis386 prefix_table[][4] = { { { Bad_Opcode }, { Bad_Opcode }, - { "vfnmsubpd", { XMVexW, Vex, EXVexW, EXVexW }, 0 }, + { "vfnmsubpd", { XM, Vex, EXx, XMVexI4 }, 0 }, }, /* PREFIX_VEX_0F3A7E */ @@ -7571,9 +7567,9 @@ static const struct dis386 xop_table[][256] = { { Bad_Opcode }, { Bad_Opcode }, { Bad_Opcode }, - { "vpmacssww", { XMVexW, Vex, EXVexW, EXVexW }, 0 }, - { "vpmacsswd", { XMVexW, Vex, EXVexW, EXVexW }, 0 }, - { "vpmacssdql", { XMVexW, Vex, EXVexW, EXVexW }, 0 }, + { "vpmacssww", { XM, Vex, EXx, XMVexI4 }, 0 }, + { "vpmacsswd", { XM, Vex, EXx, XMVexI4 }, 0 }, + { "vpmacssdql", { XM, Vex, EXx, XMVexI4 }, 0 }, /* 88 */ { Bad_Opcode }, { Bad_Opcode }, @@ -7581,17 +7577,17 @@ static const struct dis386 xop_table[][256] = { { Bad_Opcode }, { Bad_Opcode }, { Bad_Opcode }, - { "vpmacssdd", { XMVexW, Vex, EXVexW, EXVexW }, 0 }, - { "vpmacssdqh", { XMVexW, Vex, EXVexW, EXVexW }, 0 }, + { "vpmacssdd", { XM, Vex, EXx, XMVexI4 }, 0 }, + { "vpmacssdqh", { XM, Vex, EXx, XMVexI4 }, 0 }, /* 90 */ { Bad_Opcode }, { Bad_Opcode }, { Bad_Opcode }, { Bad_Opcode }, { Bad_Opcode }, - { "vpmacsww", { XMVexW, Vex, EXVexW, EXVexW }, 0 }, - { "vpmacswd", { XMVexW, Vex, EXVexW, EXVexW }, 0 }, - { "vpmacsdql", { XMVexW, Vex, EXVexW, EXVexW }, 0 }, + { "vpmacsww", { XM, Vex, EXx, XMVexI4 }, 0 }, + { "vpmacswd", { XM, Vex, EXx, XMVexI4 }, 0 }, + { "vpmacsdql", { XM, Vex, EXx, XMVexI4 }, 0 }, /* 98 */ { Bad_Opcode }, { Bad_Opcode }, @@ -7599,16 +7595,16 @@ static const struct dis386 xop_table[][256] = { { Bad_Opcode }, { Bad_Opcode }, { Bad_Opcode }, - { "vpmacsdd", { XMVexW, Vex, EXVexW, EXVexW }, 0 }, - { "vpmacsdqh", { XMVexW, Vex, EXVexW, EXVexW }, 0 }, + { "vpmacsdd", { XM, Vex, EXx, XMVexI4 }, 0 }, + { "vpmacsdqh", { XM, Vex, EXx, XMVexI4 }, 0 }, /* a0 */ { Bad_Opcode }, { Bad_Opcode }, - { "vpcmov", { XMVexW, Vex, EXVexW, EXVexW }, 0 }, - { "vpperm", { XMVexW, Vex, EXVexW, EXVexW }, 0 }, + { "vpcmov", { XM, Vex, EXx, XMVexI4 }, 0 }, + { "vpperm", { XM, Vex, EXx, XMVexI4 }, 0 }, { Bad_Opcode }, { Bad_Opcode }, - { "vpmadcsswd", { XMVexW, Vex, EXVexW, EXVexW }, 0 }, + { "vpmadcsswd", { XM, Vex, EXx, XMVexI4 }, 0 }, { Bad_Opcode }, /* a8 */ { Bad_Opcode }, @@ -7626,7 +7622,7 @@ static const struct dis386 xop_table[][256] = { { Bad_Opcode }, { Bad_Opcode }, { Bad_Opcode }, - { "vpmadcswd", { XMVexW, Vex, EXVexW, EXVexW }, 0 }, + { "vpmadcswd", { XM, Vex, EXx, XMVexI4 }, 0 }, { Bad_Opcode }, /* b8 */ { Bad_Opcode }, @@ -9633,42 +9629,42 @@ static const struct dis386 vex_len_table[][2] = { /* VEX_LEN_0F3A6A_P_2 */ { - { "vfmaddss", { XMVexW, Vex128, EXdVexW, EXdVexW }, 0 }, + { "vfmaddss", { XMScalar, VexScalar, EXxmm_md, XMVexI4 }, 0 }, }, /* VEX_LEN_0F3A6B_P_2 */ { - { "vfmaddsd", { XMVexW, Vex128, EXqVexW, EXqVexW }, 0 }, + { "vfmaddsd", { XMScalar, VexScalar, EXxmm_mq, XMVexI4 }, 0 }, }, /* VEX_LEN_0F3A6E_P_2 */ { - { "vfmsubss", { XMVexW, Vex128, EXdVexW, EXdVexW }, 0 }, + { "vfmsubss", { XMScalar, VexScalar, EXxmm_md, XMVexI4 }, 0 }, }, /* VEX_LEN_0F3A6F_P_2 */ { - { "vfmsubsd", { XMVexW, Vex128, EXqVexW, EXqVexW }, 0 }, + { "vfmsubsd", { XMScalar, VexScalar, EXxmm_mq, XMVexI4 }, 0 }, }, /* VEX_LEN_0F3A7A_P_2 */ { - { "vfnmaddss", { XMVexW, Vex128, EXdVexW, EXdVexW }, 0 }, + { "vfnmaddss", { XMScalar, VexScalar, EXxmm_md, XMVexI4 }, 0 }, }, /* VEX_LEN_0F3A7B_P_2 */ { - { "vfnmaddsd", { XMVexW, Vex128, EXqVexW, EXqVexW }, 0 }, + { "vfnmaddsd", { XMScalar, VexScalar, EXxmm_mq, XMVexI4 }, 0 }, }, /* VEX_LEN_0F3A7E_P_2 */ { - { "vfnmsubss", { XMVexW, Vex128, EXdVexW, EXdVexW }, 0 }, + { "vfnmsubss", { XMScalar, VexScalar, EXxmm_md, XMVexI4 }, 0 }, }, /* VEX_LEN_0F3A7F_P_2 */ { - { "vfnmsubsd", { XMVexW, Vex128, EXqVexW, EXqVexW }, 0 }, + { "vfnmsubsd", { XMScalar, VexScalar, EXxmm_mq, XMVexI4 }, 0 }, }, /* VEX_LEN_0F3ADF_P_2 */ @@ -16100,33 +16096,6 @@ OP_Vex_2src_2 (int bytemode, int sizeflag) } } -static void -OP_EX_VexW (int bytemode, int sizeflag) -{ - int reg = -1; - - if (!vex_w_done) - { - /* Skip mod/rm byte. */ - MODRM_CHECK; - codep++; - - if (vex.w) - reg = get_vex_imm8 (sizeflag, 0) >> 4; - } - else - { - if (!vex.w) - reg = get_vex_imm8 (sizeflag, 1) >> 4; - } - - OP_EX_VexReg (bytemode, sizeflag, reg); - - if (vex_w_done) - codep++; - vex_w_done = 1; -} - static void OP_REG_VexI4 (int bytemode, int sizeflag ATTRIBUTE_UNUSED) { @@ -16155,6 +16124,14 @@ OP_REG_VexI4 (int bytemode, int sizeflag ATTRIBUTE_UNUSED) abort (); } oappend (names[reg]); + + if (vex.w) + { + /* Swap 3rd and 4th operands. */ + strcpy (scratchbuf, op_out[3]); + strcpy (op_out[3], op_out[2]); + strcpy (op_out[2], scratchbuf); + } } static void -- 2.30.2