From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.7]) by sourceware.org (Postfix) with ESMTPS id 860FA3858CDB for ; Thu, 2 Nov 2023 11:29:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 860FA3858CDB Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=intel.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 860FA3858CDB Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=192.198.163.7 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1698924573; cv=none; b=Wgy1TS5YP6cTPIF/MGgf1ReoXq9Yx8hHAHvj7jSQxeytUESFTnG/CiJKjFlMrXlXtILYr3ukZ99VbLrtDhPILtx5rByRpVgjR13rJFt8bBoPcCejC/DcxMJqiLgbfXbnroNDond0YMNjlcqoT8rG9ULCjqzKini+u30RaXZghwY= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1698924573; c=relaxed/simple; bh=vAPjdYMdS+BmBLYoZkRHJ+XRjsrW4v7ley3wPRDwBO4=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=MZ6hhMuAQRhBFEvGuGcPb2CxcqhNUf0R9tzpgVw3CS8c9Da8swToRDC4WFRe39FHKyfjsYCK3PstqcN1cIPzouNyeE7Pa4WTsW1QQih9BARJU9ewyCoIZpKnVooAh/sUvVX8iQ3Asz2N2LcAIAx8w/FuStSED2jgGVGvcJxNJZI= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1698924562; x=1730460562; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=vAPjdYMdS+BmBLYoZkRHJ+XRjsrW4v7ley3wPRDwBO4=; b=Ch0OW3+eYj92sYxolyWtg7TSujANFno2Z1AI7o6NDT5X0YwlA+LSJ4r/ eKNwvuz8hvXi1hq9Y2MJxAUfCaE1ShWeQbtnY9WSkOujT/4GTpW6Jq7DW Qr+V6VocUDbATWDSogt+o/usOBoiRVLKxLNcfiUSShnH1tXFdys8EOG70 NsYxjvZDfh1tFjjcMBEiZUSXp6gZaRdVMkJ3ZR7aEU82z42LMb3KuwKtn or9B5KPoyDco+0pSyMHePvT888/dXBCoS2vLbU9VnYYD5yjYepZ2StYNK +hohPOFlYn/UhongOtsQMbfMOmLq/N79oIslf8ZUc2KjyWnbMnHk9zz4l Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10881"; a="10222444" X-IronPort-AV: E=Sophos;i="6.03,271,1694761200"; d="scan'208";a="10222444" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmvoesa101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Nov 2023 04:29:20 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10881"; a="737722592" X-IronPort-AV: E=Sophos;i="6.03,271,1694761200"; d="scan'208";a="737722592" Received: from scymds03.sc.intel.com ([10.148.94.166]) by orsmga006.jf.intel.com with ESMTP; 02 Nov 2023 04:29:19 -0700 Received: from shgcc101.sh.intel.com (shgcc101.sh.intel.com [10.239.85.97]) by scymds03.sc.intel.com (Postfix) with ESMTP id 6A35A5C; Thu, 2 Nov 2023 04:29:18 -0700 (PDT) From: "Cui, Lili" To: binutils@sourceware.org Cc: jbeulich@suse.com, hongjiu.lu@intel.com, ccoutant@gmail.com Subject: [PATCH 3/8] Support APX GPR32 with extend evex prefix Date: Thu, 2 Nov 2023 11:29:06 +0000 Message-Id: <20231102112911.2372810-4-lili.cui@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231102112911.2372810-1-lili.cui@intel.com> References: <20231102112911.2372810-1-lili.cui@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-11.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,SPF_HELO_NONE,SPF_NONE,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: This patch adds non-ND, non-NF forms of EVEX promotion insn. EVEX extension of legacy instructions: All promoted legacy instructions are placed in EVEX map 4, which is currently reserved. EVEX extension of EVEX instructions: All existing EVEX instructions are extended by APX using the extended EVEX prefix, so that they can access all 32 GPRs. EVEX extension of VEX instructions: Promoting a VEX instruction into the EVEX space does not change the map id, the opcode, or the operand encoding of the VEX instruction. Note: The promoted versions of MOVBE will be extended to include the “MOVBE reg1, reg2”. gas/ChangeLog: * config/tc-i386.c (cpu_flags_not_or_check): Add a new function for APX cpu flag checking. (cpu_flags_match): handle cpu_flags_not_or_check. (install_template): Add AMX_TILE and APX combine. (is_any_apx_evex_encoding): Test apx evex encoding. (build_apx_evex_prefix): Enabe APX evex prefix. (md_assemble): Handle apx with evex encoding. (check_EgprOperands): Add nodgpr check for apx. (process_suffix): Handle apx map4 prefix. (check_register): Assign i.vec_encoding for APX evex instructions. * testsuite/gas/i386/x86-64-evex.d: Adjust test cases. * gas/testsuite/gas/i386/x86-64-inval-movbe.s: Ditto. * gas/testsuite/gas/i386/x86-64-inval-movbe.l: Ditto. opcodes/ChangeLog: * i386-dis-evex-len.h: Handle EVEX_LEN_0F38F2, EVEX_LEN_0F38F3. * i386-dis-evex-mod.h: Handle MOD_EVEX_MAP4_65, MOD_EVEX_MAP4_66_PREFIX_0, MOD_EVEX_MAP4_8A_W_0, MOD_EVEX_MAP4_DA_PREFIX_1, MOD_EVEX_MAP4_DB_PREFIX_1, MOD_EVEX_MAP4_DC_PREFIX_1, MOD_EVEX_MAP4_DD_PREFIX_1, MOD_EVEX_MAP4_DE_PREFIX_1, MOD_EVEX_MAP4_DF_PREFIX_1, MOD_EVEX_MAP4_F8_PREFIX_1, MOD_EVEX_MAP4_F8_PREFIX_2, MOD_EVEX_MAP4_F8_PREFIX_3, MOD_EVEX_MAP4_F9, MOD_EVEX_MAP4_8B. * i386-dis-evex-prefix.h: Handle PREFIX_EVEX_MAP4_60, PREFIX_EVEX_MAP4_61, PREFIX_EVEX_MAP4_66, PREFIX_EVEX_MAP4_8B_M_0, PREFIX_EVEX_MAP4_D8, PREFIX_EVEX_MAP4_DA, PREFIX_EVEX_MAP4_DB, PREFIX_EVEX_MAP4_DC, PREFIX_EVEX_MAP4_DD, PREFIX_EVEX_MAP4_DE, PREFIX_EVEX_MAP4_DF, PREFIX_EVEX_MAP4_F0, PREFIX_EVEX_MAP4_F1, PREFIX_EVEX_MAP4_F2, PREFIX_EVEX_MAP4_F8, PREFIX_EVEX_MAP4_FC. * i386-dis-evex-reg.h: Handle REG_EVEX_MAP4_D8_PREFIX_1, REG_EVEX_0F38F3_L_0. * i386-dis-evex.h: Add EVEX_MAP4_ for legacy insn promote to apx to use gpr32 * i386-dis.c (REG enum): Add REG_EVEX_MAP4_D8_PREFIX_1. (MOD enum): Add MOD_EVEX_MAP4_65, MOD_EVEX_MAP4_66_PREFIX_0, MOD_EVEX_MAP4_8A_W_0, MOD_EVEX_MAP4_8B, MOD_EVEX_MAP4_DA_PREFIX_1, MOD_EVEX_MAP4_DB_PREFIX_1, MOD_EVEX_MAP4_DC_PREFIX_1, MOD_EVEX_MAP4_DD_PREFIX_1, MOD_EVEX_MAP4_DE_PREFIX_1, MOD_EVEX_MAP4_DF_PREFIX_1, MOD_EVEX_MAP4_F8_PREFIX_1, MOD_EVEX_MAP4_F8_PREFIX_2, MOD_EVEX_MAP4_F8_PREFIX_3, MOD_EVEX_MAP4_F9, REG_EVEX_0F38F3_L_0. (PREFIX enum): Add PREFIX_EVEX_MAP4_60, PREFIX_EVEX_MAP4_61, PREFIX_EVEX_MAP4_66, PREFIX_EVEX_MAP4_8B_M_0, PREFIX_EVEX_MAP4_D8, PREFIX_EVEX_MAP4_DA, PREFIX_EVEX_MAP4_DB, PREFIX_EVEX_MAP4_DC, PREFIX_EVEX_MAP4_DD, PREFIX_EVEX_MAP4_DE, PREFIX_EVEX_MAP4_DF, PREFIX_EVEX_MAP4_F0, PREFIX_EVEX_MAP4_F1, PREFIX_EVEX_MAP4_F2, PREFIX_EVEX_MAP4_F8, PREFIX_EVEX_MAP4_FC. (EVEX_LEN_enum): Add EVEX_LEN_0F38F2, EVEX_LEN_0F38F3. (EVEX_X86_enum): Add X86_64_EVEX_0F90, X86_64_EVEX_0F91, X86_64_EVEX_0F92, X86_64_EVEX_0F93, X86_64_EVEX_0F3849, X86_64_EVEX_0F384B, X86_64_EVEX_0F38E0, X86_64_EVEX_0F38E1, X86_64_EVEX_0F38E2, X86_64_EVEX_0F38E3, X86_64_EVEX_0F38E4, X86_64_EVEX_0F38E5, X86_64_EVEX_0F38E6, X86_64_EVEX_0F38E7, X86_64_EVEX_0F38E8, X86_64_EVEX_0F38E9, X86_64_EVEX_0F38EA, X86_64_EVEX_0F38EB, X86_64_EVEX_0F38EC, X86_64_EVEX_0F38ED, X86_64_EVEX_0F38EE, X86_64_EVEX_0F38EF, X86_64_EVEX_0F38F2, X86_64_EVEX_0F38F3, X86_64_EVEX_0F38F5, X86_64_EVEX_0F38F6, X86_64_EVEX_0F38F7, X86_64_EVEX_0F3AF0. (struct instr_info): Deleted bool r. (putop): Ditto. (PREFIX_DATA_AND_NP_ONLY): New define. (X86_64_EVEX_FROM_VEX_TABLE): Diito. (get_valid_dis386): Decode insn erex in extend evex prefix. Handle EVEX_MAP4 (print_insn): Handle PREFIX_DATA_AND_NP_ONLY. (print_register): Handle apx instructions decode. (OP_E_memory): Diito. (OP_G): Diito. (OP_XMM): Diito. (DistinctDest_Fixup): Diito. * i386-gen.c (process_i386_opcode_modifier): * i386-opc.h (SPACE_EVEXMAP4): Add legacy insn promote to evex. * i386-opc.tbl: Handle some legacy and vex insns don't support gpr32. And add some legacy insn (map2 / 3) promote to evex. --- gas/config/tc-i386.c | 127 +++++++++++++-- gas/testsuite/gas/i386/x86-64-evex.d | 2 +- gas/testsuite/gas/i386/x86-64-inval-movbe.l | 31 ++-- gas/testsuite/gas/i386/x86-64-inval-movbe.s | 1 + opcodes/i386-dis-evex-len.h | 10 ++ opcodes/i386-dis-evex-mod.h | 42 +++++ opcodes/i386-dis-evex-prefix.h | 69 +++++++++ opcodes/i386-dis-evex-reg.h | 14 ++ opcodes/i386-dis-evex-x86-64.h | 140 +++++++++++++++++ opcodes/i386-dis-evex.h | 94 +++++------ opcodes/i386-dis.c | 163 ++++++++++++++++++-- opcodes/i386-gen.c | 2 + opcodes/i386-opc.h | 2 + opcodes/i386-opc.tbl | 69 ++++++++- 14 files changed, 664 insertions(+), 102 deletions(-) create mode 100644 opcodes/i386-dis-evex-x86-64.h diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 3d917c34d15..398909a6a30 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -1796,6 +1796,36 @@ cpu_flags_equal (const union i386_cpu_flags *x, } } +static INLINE int +cpu_flags_not_or_check (const union i386_cpu_flags *x, + const union i386_cpu_flags *y) +{ + switch (ARRAY_SIZE(x->array)) + { + case 5: + if ((~x->array[4] | y->array[4]) != 0xffffffff) + return 0; + /* Fall through. */ + case 4: + if ((~x->array[3] | y->array[3]) != 0xffffffff) + return 0; + /* Fall through. */ + case 3: + if ((~x->array[2] | y->array[2]) != 0xffffffff) + return 0; + /* Fall through. */ + case 2: + if ((~x->array[1] | y->array[1]) != 0xffffffff) + return 0; + /* Fall through. */ + case 1: + return ((~x->array[1] | y->array[1]) == 0Xffffffff); + break; + default: + abort (); + } +} + static INLINE int cpu_flags_check_cpu64 (const insn_template *t) { @@ -1989,6 +2019,12 @@ cpu_flags_match (const insn_template *t) && (!x.bitfield.cpugfni || cpu.bitfield.cpugfni)) match |= CPU_FLAGS_ARCH_MATCH; } + else if (x.bitfield.cpuapx_f) + { + /* All cpu in x need to be enabled in cpu_arch_flags. */ + if (cpu_flags_not_or_check (&x, &cpu_arch_flags)) + match |= CPU_FLAGS_ARCH_MATCH; + } else match |= CPU_FLAGS_ARCH_MATCH; } @@ -3712,16 +3748,16 @@ install_template (const insn_template *t) /* Dual VEX/EVEX templates need stripping one of the possible variants. */ if (t->opcode_modifier.vex && t->opcode_modifier.evex) - { - if ((is_cpu (t, CpuAVX) || is_cpu (t, CpuAVX2)) - && is_cpu (t, CpuAVX512F)) + { + if ((is_cpu (t, CpuAVX) || is_cpu (t, CpuAVX2) || is_cpu (t, CpuAMX_TILE)) + && (is_cpu (t, CpuAVX512F) || is_cpu (t, CpuAPX_F))) { if (need_evex_encoding ()) { i.tm.opcode_modifier.vex = 0; i.tm.cpu.bitfield.cpuavx = 0; if (is_cpu (&i.tm, CpuAVX2)) - i.tm.cpu.bitfield.isa = 0; + i.tm.cpu.bitfield.isa = 0; } else { @@ -3729,7 +3765,7 @@ install_template (const insn_template *t) i.tm.cpu.bitfield.cpuavx512f = 0; } } - } + } /* Note that for pseudo prefixes this produces a length of 1. But for them the length isn't interesting at all. */ @@ -3919,6 +3955,14 @@ is_any_vex_encoding (const insn_template *t) return t->opcode_modifier.vex || is_evex_encoding (t); } +static INLINE bool +is_any_apx_evex_encoding (void) +{ + return i.rex2 || i.tm.opcode_space == SPACE_EVEXMAP4 + || (i.vex.register_specifier + && i.vex.register_specifier->reg_flags & RegRex2); +} + static INLINE bool is_any_apx_rex2_encoding (void) { @@ -4195,6 +4239,27 @@ build_rex2_prefix (void) | (i.rex2 << 4) | i.rex); } +/* Build the EVEX prefix (4-byte) for evex insn + | 62h | + | `R`X`B`R' | B'mmm | + | W | v`v`v`v | `x' | pp | + | z| L'L | b | `v | aaa | +*/ +static void +build_apx_evex_prefix (void) +{ + build_evex_prefix (); + if (i.rex2 & REX_R) + i.vex.bytes[1] &= 0xef; + if (i.vex.register_specifier + && register_number (i.vex.register_specifier) > 0xf) + i.vex.bytes[3] &= 0xf7; + if (i.rex2 & REX_B) + i.vex.bytes[1] |= 0x08; + if (i.rex2 & REX_X) + i.vex.bytes[2] &= 0xfb; +} + static void process_immext (void) { @@ -5642,19 +5707,42 @@ md_assemble (char *line) } /* Check for explicit REX2 prefix. */ - if (i.rex2 || i.rex2_encoding) + if (i.rex2_encoding) { as_bad (_("REX2 prefix invalid with `%s'"), insn_name (&i.tm)); return; } - if (i.tm.opcode_modifier.vex) + if (is_any_apx_evex_encoding ()) + { + if (i.tm.opcode_space == SPACE_EVEXMAP4 && (i.prefix[DATA_PREFIX] != 0)) + { + i.tm.opcode_modifier.opcodeprefix = PREFIX_0X66; + i.prefix[DATA_PREFIX] = 0; + } + + build_apx_evex_prefix (); + + /* Encode the NDD bit of the instruction promoted from the legacy + space. */ + if (i.vex.register_specifier && i.tm.opcode_space == SPACE_EVEXMAP4) + i.vex.bytes[3] |= 0x10; + + /* Encode the NF bit of the instruction promoted from legacy and vex + space. */ + if (i.has_nf) + i.vex.bytes[3] |= 0x04; + } + else if (i.tm.opcode_modifier.vex) build_vex_prefix (t); else build_evex_prefix (); /* The individual REX.RXBW bits got consumed. */ i.rex &= REX_OPCODE; + + /* The rex2 bits got consumed. */ + i.rex2 = 0; } /* Handle conversion of 'int $3' --> special int3 insn. */ @@ -5681,16 +5769,17 @@ md_assemble (char *line) instruction already has a prefix, we need to convert old registers to new ones. */ - if ((i.types[0].bitfield.class == Reg && i.types[0].bitfield.byte - && (i.op[0].regs->reg_flags & RegRex64) != 0) - || (i.types[1].bitfield.class == Reg && i.types[1].bitfield.byte - && (i.op[1].regs->reg_flags & RegRex64) != 0) - || (((i.types[0].bitfield.class == Reg && i.types[0].bitfield.byte) - || (i.types[1].bitfield.class == Reg && i.types[1].bitfield.byte)) - && (i.rex != 0 || i.rex2 != 0))) + if (!is_any_vex_encoding (&i.tm) + && ((i.types[0].bitfield.class == Reg && i.types[0].bitfield.byte + && (i.op[0].regs->reg_flags & RegRex64) != 0) + || (i.types[1].bitfield.class == Reg && i.types[1].bitfield.byte + && (i.op[1].regs->reg_flags & RegRex64) != 0) + || (((i.types[0].bitfield.class == Reg && i.types[0].bitfield.byte) + || (i.types[1].bitfield.class == Reg && i.types[1].bitfield.byte)) + && (i.rex != 0 || i.rex2 != 0)))) { int x; - if (!i.rex2) + if (!is_any_apx_rex2_encoding ()) i.rex |= REX_OPCODE; for (x = 0; x < 2; x++) { @@ -7061,7 +7150,7 @@ VEX_check_encoding (const insn_template *t) static int check_EgprOperands (const insn_template *t) { - if (t->opcode_modifier.noegpr) + if (t->opcode_modifier.noegpr && !need_evex_encoding()) { for (unsigned int op = 0; op < i.operands; op++) { @@ -8049,7 +8138,8 @@ process_suffix (void) if (i.suffix != QWORD_MNEM_SUFFIX && i.tm.opcode_modifier.mnemonicsize != IGNORESIZE && !i.tm.opcode_modifier.floatmf - && !is_any_vex_encoding (&i.tm) + && (!is_any_vex_encoding (&i.tm) + || i.tm.opcode_space == SPACE_EVEXMAP4) && ((i.suffix == LONG_MNEM_SUFFIX) == (flag_code == CODE_16BIT) || (flag_code == CODE_64BIT && i.tm.opcode_modifier.jump == JUMP_BYTE))) @@ -14260,6 +14350,9 @@ static bool check_register (const reg_entry *r) if (r->reg_flags & RegRex2) { + if (is_evex_encoding (current_templates->start)) + i.vec_encoding = vex_encoding_evex; + if (!cpu_arch_flags.bitfield.cpuapx_f || flag_code != CODE_64BIT) return false; diff --git a/gas/testsuite/gas/i386/x86-64-evex.d b/gas/testsuite/gas/i386/x86-64-evex.d index 041747db892..5d974c312da 100644 --- a/gas/testsuite/gas/i386/x86-64-evex.d +++ b/gas/testsuite/gas/i386/x86-64-evex.d @@ -17,6 +17,6 @@ Disassembly of section .text: +[a-f0-9]+: 62 f1 d6 38 7b f0 vcvtusi2ss %rax,\{rd-sae\},%xmm5,%xmm6 +[a-f0-9]+: 62 f1 57 38 7b f0 vcvtusi2sd %eax,\{rd-bad\},%xmm5,%xmm6 +[a-f0-9]+: 62 f1 d7 38 7b f0 vcvtusi2sd %rax,\{rd-sae\},%xmm5,%xmm6 - +[a-f0-9]+: 62 e1 7e 08 2d c0 vcvtss2si %xmm0,\(bad\) + +[a-f0-9]+: 62 e1 7e 08 2d c0 vcvtss2si %xmm0,%r16d +[a-f0-9]+: 62 e1 7c 08 c2 c0 00 vcmpeqps %xmm0,%xmm0,\(bad\) #pass diff --git a/gas/testsuite/gas/i386/x86-64-inval-movbe.l b/gas/testsuite/gas/i386/x86-64-inval-movbe.l index 1c8ceb55c11..44ddfe4f034 100644 --- a/gas/testsuite/gas/i386/x86-64-inval-movbe.l +++ b/gas/testsuite/gas/i386/x86-64-inval-movbe.l @@ -1,29 +1,30 @@ .*: Assembler messages: -.*:4: Error: .* .*:5: Error: .* .*:6: Error: .* .*:7: Error: .* .*:8: Error: .* -.*:11: Error: .* +.*:9: Error: .* .*:12: Error: .* .*:13: Error: .* .*:14: Error: .* .*:15: Error: .* +.*:16: Error: .* GAS LISTING .* [ ]*1[ ]+\# Check illegal movbe in 64bit mode\. [ ]*2[ ]+\.text -[ ]*3[ ]+foo: -[ ]*4[ ]+movbe \(%rcx\),%bl -[ ]*5[ ]+movbe %ecx,%ebx -[ ]*6[ ]+movbe %bx,%rcx -[ ]*7[ ]+movbe %rbx,%rcx -[ ]*8[ ]+movbe %bl,\(%rcx\) -[ ]*9[ ]+ -[ ]*10[ ]+\.intel_syntax noprefix -[ ]*11[ ]+movbe bl, byte ptr \[rcx\] -[ ]*12[ ]+movbe ebx, ecx -[ ]*13[ ]+movbe rcx, bx -[ ]*14[ ]+movbe rcx, rbx -[ ]*15[ ]+movbe byte ptr \[rcx\], bl +[ ]*3[ ]+\.arch \.noapx_f +[ ]*4[ ]+foo: +[ ]*5[ ]+movbe \(%rcx\),%bl +[ ]*6[ ]+movbe %ecx,%ebx +[ ]*7[ ]+movbe %bx,%rcx +[ ]*8[ ]+movbe %rbx,%rcx +[ ]*9[ ]+movbe %bl,\(%rcx\) +[ ]*10[ ]+ +[ ]*11[ ]+\.intel_syntax noprefix +[ ]*12[ ]+movbe bl, byte ptr \[rcx\] +[ ]*13[ ]+movbe ebx, ecx +[ ]*14[ ]+movbe rcx, bx +[ ]*15[ ]+movbe rcx, rbx +[ ]*16[ ]+movbe byte ptr \[rcx\], bl diff --git a/gas/testsuite/gas/i386/x86-64-inval-movbe.s b/gas/testsuite/gas/i386/x86-64-inval-movbe.s index 38f09b14d64..380a9191b6a 100644 --- a/gas/testsuite/gas/i386/x86-64-inval-movbe.s +++ b/gas/testsuite/gas/i386/x86-64-inval-movbe.s @@ -1,5 +1,6 @@ # Check illegal movbe in 64bit mode. .text + .arch .noapx_f foo: movbe (%rcx),%bl movbe %ecx,%ebx diff --git a/opcodes/i386-dis-evex-len.h b/opcodes/i386-dis-evex-len.h index a02609c50f2..1933a045822 100644 --- a/opcodes/i386-dis-evex-len.h +++ b/opcodes/i386-dis-evex-len.h @@ -62,6 +62,16 @@ static const struct dis386 evex_len_table[][3] = { { REG_TABLE (REG_EVEX_0F38C7_L_2) }, }, + /* EVEX_LEN_0F38F2 */ + { + { "andnS", { Gdq, VexGdq, Edq }, 0 }, + }, + + /* EVEX_LEN_0F38F3 */ + { + { REG_TABLE(REG_EVEX_0F38F3_L_0) }, + }, + /* EVEX_LEN_0F3A00 */ { { Bad_Opcode }, diff --git a/opcodes/i386-dis-evex-mod.h b/opcodes/i386-dis-evex-mod.h index f9f912c5094..a60c19add3c 100644 --- a/opcodes/i386-dis-evex-mod.h +++ b/opcodes/i386-dis-evex-mod.h @@ -1 +1,43 @@ /* Nothing at present. */ + /* MOD_EVEX_MAP4_DA_PREFIX_1 */ + { + { Bad_Opcode }, + { "encodekey128", { Gd, Ed }, 0 }, + }, + /* MOD_EVEX_MAP4_DB_PREFIX_1 */ + { + { Bad_Opcode }, + { "encodekey256", { Gd, Ed }, 0 }, + }, + /* MOD_EVEX_MAP4_DC_PREFIX_1 */ + { + { "aesenc128kl", { XM, M }, 0 }, + }, + /* MOD_EVEX_MAP4_DD_PREFIX_1 */ + { + { "aesdec128kl", { XM, M }, 0 }, + }, + /* MOD_EVEX_MAP4_DE_PREFIX_1 */ + { + { "aesenc256kl", { XM, M }, 0 }, + }, + /* MOD_EVEX_MAP4_DF_PREFIX_1 */ + { + { "aesdec256kl", { XM, M }, 0 }, + }, + /* MOD_EVEX_MAP4_F8_PREFIX_1 */ + { + { "enqcmds", { Gva, M }, 0 }, + }, + /* MOD_EVEX_MAP4_F8_PREFIX_2 */ + { + { "movdir64b", { Gva, M }, 0 }, + }, + /* MOD_EVEX_MAP4_F8_PREFIX_3 */ + { + { "enqcmd", { Gva, M }, 0 }, + }, + /* MOD_EVEX_MAP4_F9 */ + { + { "movdiri", { Edq, Gdq }, 0 }, + }, diff --git a/opcodes/i386-dis-evex-prefix.h b/opcodes/i386-dis-evex-prefix.h index 28da54922c7..e8f32324ade 100644 --- a/opcodes/i386-dis-evex-prefix.h +++ b/opcodes/i386-dis-evex-prefix.h @@ -338,6 +338,75 @@ { "vcmpp%XH", { MaskG, Vex, EXxh, EXxEVexS, CMP }, 0 }, { "vcmps%XH", { MaskG, VexScalar, EXw, EXxEVexS, CMP }, 0 }, }, + /* PREFIX_EVEX_MAP4_66 */ + { + { "wrssK", { M, Gdq }, 0 }, + }, + /* PREFIX_EVEX_MAP4_D8 */ + { + { "sha1nexte", { XM, EXxmm }, 0 }, + { REG_TABLE (REG_EVEX_MAP4_D8_PREFIX_1) }, + }, + /* PREFIX_EVEX_MAP4_DA */ + { + { "sha1msg2", { XM, EXxmm }, 0 }, + { MOD_TABLE (MOD_EVEX_MAP4_DA_PREFIX_1) }, + }, + /* PREFIX_EVEX_MAP4_DB */ + { + { "sha256rnds2", { XM, EXxmm, XMM0 }, 0 }, + { MOD_TABLE (MOD_EVEX_MAP4_DB_PREFIX_1) }, + }, + /* PREFIX_EVEX_MAP4_DC */ + { + { "sha256msg1", { XM, EXxmm }, 0 }, + { MOD_TABLE (MOD_EVEX_MAP4_DC_PREFIX_1) }, + }, + /* PREFIX_EVEX_MAP4_DD */ + { + { "sha256msg2", { XM, EXxmm }, 0 }, + { MOD_TABLE (MOD_EVEX_MAP4_DD_PREFIX_1) }, + }, + /* PREFIX_EVEX_MAP4_DE */ + { + { Bad_Opcode }, + { MOD_TABLE (MOD_EVEX_MAP4_DE_PREFIX_1) }, + }, + /* PREFIX_EVEX_MAP4_DF */ + { + { Bad_Opcode }, + { MOD_TABLE (MOD_EVEX_MAP4_DF_PREFIX_1) }, + }, + /* PREFIX_EVEX_MAP4_F0 */ + { + { "crc32A", { Gdq, Eb }, 0 }, + { "invept", { Gm, Mo }, 0 }, + }, + /* PREFIX_EVEX_MAP4_F1 */ + { + { "crc32Q", { Gdq, Ev }, 0 }, + { "invvpid", { Gm, Mo }, 0 }, + { "crc32Q", { Gdq, Ev }, 0 }, + }, + /* PREFIX_EVEX_MAP4_F2 */ + { + { Bad_Opcode }, + { "invpcid", { Gm, M }, 0 }, + }, + /* PREFIX_EVEX_MAP4_F8 */ + { + { Bad_Opcode }, + { MOD_TABLE (MOD_EVEX_MAP4_F8_PREFIX_1) }, + { MOD_TABLE (MOD_EVEX_MAP4_F8_PREFIX_2) }, + { MOD_TABLE (MOD_EVEX_MAP4_F8_PREFIX_3) }, + }, + /* PREFIX_EVEX_MAP4_FC */ + { + { "aadd", { Mdq, Gdq }, 0 }, + { "axor", { Mdq, Gdq }, 0 }, + { "aand", { Mdq, Gdq }, 0 }, + { "aor", { Mdq, Gdq }, 0 }, + }, /* PREFIX_EVEX_MAP5_10 */ { { Bad_Opcode }, diff --git a/opcodes/i386-dis-evex-reg.h b/opcodes/i386-dis-evex-reg.h index 2885063628b..c3b4f083346 100644 --- a/opcodes/i386-dis-evex-reg.h +++ b/opcodes/i386-dis-evex-reg.h @@ -49,3 +49,17 @@ { "vscatterpf0qp%XW", { MVexVSIBQWpX }, PREFIX_DATA }, { "vscatterpf1qp%XW", { MVexVSIBQWpX }, PREFIX_DATA }, }, + /* REG_EVEX_0F38F3_L_0 */ + { + { Bad_Opcode }, + { "blsrS", { VexGdq, Edq }, 0 }, + { "blsmskS", { VexGdq, Edq }, 0 }, + { "blsiS", { VexGdq, Edq }, 0 }, + }, + /* REG_EVEX_MAP4_D8_PREFIX_1 */ + { + { "aesencwide128kl", { M }, 0 }, + { "aesdecwide128kl", { M }, 0 }, + { "aesencwide256kl", { M }, 0 }, + { "aesdecwide256kl", { M }, 0 }, + }, diff --git a/opcodes/i386-dis-evex-x86-64.h b/opcodes/i386-dis-evex-x86-64.h new file mode 100644 index 00000000000..1121223d877 --- /dev/null +++ b/opcodes/i386-dis-evex-x86-64.h @@ -0,0 +1,140 @@ + /* X86_64_EVEX_0F90 */ + { + { Bad_Opcode }, + { VEX_LEN_TABLE (VEX_LEN_0F90) }, + }, + /* X86_64_EVEX_0F91 */ + { + { Bad_Opcode }, + { VEX_LEN_TABLE (VEX_LEN_0F91) }, + }, + /* X86_64_EVEX_0F92 */ + { + { Bad_Opcode }, + { VEX_LEN_TABLE (VEX_LEN_0F92) }, + }, + /* X86_64_EVEX_0F93 */ + { + { Bad_Opcode }, + { VEX_LEN_TABLE (VEX_LEN_0F93) }, + }, + /* X86_64_EVEX_0F3849 */ + { + { Bad_Opcode }, + { VEX_LEN_TABLE (VEX_LEN_0F3849_X86_64) }, + }, + /* X86_64_EVEX_0F384B */ + { + { Bad_Opcode }, + { VEX_LEN_TABLE (VEX_LEN_0F384B_X86_64) }, + }, + /* X86_64_EVEX_0F38E0 */ + { + { Bad_Opcode }, + { "cmpoxadd", { Mdq, Gdq, VexGdq }, PREFIX_DATA }, + }, + /* X86_64_EVEX_0F38E1 */ + { + { Bad_Opcode }, + { "cmpnoxadd", { Mdq, Gdq, VexGdq }, PREFIX_DATA }, + }, + /* X86_64_EVEX_0F38E2 */ + { + { Bad_Opcode }, + { "cmpbxadd", { Mdq, Gdq, VexGdq }, PREFIX_DATA }, + }, + /* X86_64_EVEX_0F38E3 */ + { + { Bad_Opcode }, + { "cmpnbxadd", { Mdq, Gdq, VexGdq }, PREFIX_DATA }, + }, + /* X86_64_EVEX_0F38E4 */ + { + { Bad_Opcode }, + { "cmpzxadd", { Mdq, Gdq, VexGdq }, PREFIX_DATA }, + }, + /* X86_64_EVEX_0F38E5 */ + { + { Bad_Opcode }, + { "cmpnzxadd", { Mdq, Gdq, VexGdq }, PREFIX_DATA }, + }, + /* X86_64_EVEX_0F38E6 */ + { + { Bad_Opcode }, + { "cmpbexadd", { Mdq, Gdq, VexGdq }, PREFIX_DATA }, + }, + /* X86_64_EVEX_0F38E7 */ + { + { Bad_Opcode }, + { "cmpnbexadd", { Mdq, Gdq, VexGdq }, PREFIX_DATA }, + }, + /* X86_64_EVEX_0F38E8 */ + { + { Bad_Opcode }, + { "cmpsxadd", { Mdq, Gdq, VexGdq }, PREFIX_DATA }, + }, + /* X86_64_EVEX_0F38E9 */ + { + { Bad_Opcode }, + { "cmpnsxadd", { Mdq, Gdq, VexGdq }, PREFIX_DATA }, + }, + /* X86_64_EVEX_0F38EA */ + { + { Bad_Opcode }, + { "cmppxadd", { Mdq, Gdq, VexGdq }, PREFIX_DATA }, + }, + /* X86_64_EVEX_0F38EB */ + { + { Bad_Opcode }, + { "cmpnpxadd", { Mdq, Gdq, VexGdq }, PREFIX_DATA }, + }, + /* X86_64_EVEX_0F38EC */ + { + { Bad_Opcode }, + { "cmplxadd", { Mdq, Gdq, VexGdq }, PREFIX_DATA }, + }, + /* X86_64_EVEX_0F38ED */ + { + { Bad_Opcode }, + { "cmpnlxadd", { Mdq, Gdq, VexGdq }, PREFIX_DATA }, + }, + /* X86_64_EVEX_0F38EE */ + { + { Bad_Opcode }, + { "cmplexadd", { Mdq, Gdq, VexGdq }, PREFIX_DATA }, + }, + /* X86_64_EVEX_0F38EF */ + { + { Bad_Opcode }, + { "cmpnlexadd", { Mdq, Gdq, VexGdq }, PREFIX_DATA }, + }, + /* X86_64_EVEX_0F38F2 */ + { + { Bad_Opcode }, + { EVEX_LEN_TABLE (EVEX_LEN_0F38F2) }, + }, + /* X86_64_EVEX_0F38F3 */ + { + { Bad_Opcode }, + { EVEX_LEN_TABLE (EVEX_LEN_0F38F3) }, + }, + /* X86_64_EVEX_0F38F5 */ + { + { Bad_Opcode }, + { VEX_LEN_TABLE (VEX_LEN_0F38F5) }, + }, + /* X86_64_EVEX_0F38F6 */ + { + { Bad_Opcode }, + { VEX_LEN_TABLE (VEX_LEN_0F38F6) }, + }, + /* X86_64_EVEX_0F38F7 */ + { + { Bad_Opcode }, + { VEX_LEN_TABLE (VEX_LEN_0F38F7) }, + }, + /* X86_64_EVEX_0F3AF0 */ + { + { Bad_Opcode }, + { VEX_LEN_TABLE (VEX_LEN_0F3AF0) }, + }, diff --git a/opcodes/i386-dis-evex.h b/opcodes/i386-dis-evex.h index 7ad1edbe72d..65a2cbeaeb2 100644 --- a/opcodes/i386-dis-evex.h +++ b/opcodes/i386-dis-evex.h @@ -164,10 +164,10 @@ static const struct dis386 evex_table[][256] = { { Bad_Opcode }, { Bad_Opcode }, /* 90 */ - { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, + { X86_64_EVEX_FROM_VEX_TABLE (X86_64_EVEX_0F90) }, + { X86_64_EVEX_FROM_VEX_TABLE (X86_64_EVEX_0F91) }, + { X86_64_EVEX_FROM_VEX_TABLE (X86_64_EVEX_0F92) }, + { X86_64_EVEX_FROM_VEX_TABLE (X86_64_EVEX_0F93) }, { Bad_Opcode }, { Bad_Opcode }, { Bad_Opcode }, @@ -375,9 +375,9 @@ static const struct dis386 evex_table[][256] = { { "vpsllv%DQ", { XM, Vex, EXx }, PREFIX_DATA }, /* 48 */ { Bad_Opcode }, + { X86_64_EVEX_FROM_VEX_TABLE (X86_64_EVEX_0F3849) }, { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, + { X86_64_EVEX_FROM_VEX_TABLE (X86_64_EVEX_0F384B) }, { "vrcp14p%XW", { XM, EXx }, PREFIX_DATA }, { "vrcp14s%XW", { XMScalar, VexScalar, EXdq }, PREFIX_DATA }, { "vrsqrt14p%XW", { XM, EXx }, 0 }, @@ -545,32 +545,32 @@ static const struct dis386 evex_table[][256] = { { "%XEvaesdecY", { XM, Vex, EXx }, PREFIX_DATA }, { "%XEvaesdeclastY", { XM, Vex, EXx }, PREFIX_DATA }, /* E0 */ - { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, + { X86_64_EVEX_FROM_VEX_TABLE (X86_64_EVEX_0F38E0) }, + { X86_64_EVEX_FROM_VEX_TABLE (X86_64_EVEX_0F38E1) }, + { X86_64_EVEX_FROM_VEX_TABLE (X86_64_EVEX_0F38E2) }, + { X86_64_EVEX_FROM_VEX_TABLE (X86_64_EVEX_0F38E3) }, + { X86_64_EVEX_FROM_VEX_TABLE (X86_64_EVEX_0F38E4) }, + { X86_64_EVEX_FROM_VEX_TABLE (X86_64_EVEX_0F38E5) }, + { X86_64_EVEX_FROM_VEX_TABLE (X86_64_EVEX_0F38E6) }, + { X86_64_EVEX_FROM_VEX_TABLE (X86_64_EVEX_0F38E7) }, /* E8 */ - { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, + { X86_64_EVEX_FROM_VEX_TABLE (X86_64_EVEX_0F38E8) }, + { X86_64_EVEX_FROM_VEX_TABLE (X86_64_EVEX_0F38E9) }, + { X86_64_EVEX_FROM_VEX_TABLE (X86_64_EVEX_0F38EA) }, + { X86_64_EVEX_FROM_VEX_TABLE (X86_64_EVEX_0F38EB) }, + { X86_64_EVEX_FROM_VEX_TABLE (X86_64_EVEX_0F38EC) }, + { X86_64_EVEX_FROM_VEX_TABLE (X86_64_EVEX_0F38ED) }, + { X86_64_EVEX_FROM_VEX_TABLE (X86_64_EVEX_0F38EE) }, + { X86_64_EVEX_FROM_VEX_TABLE (X86_64_EVEX_0F38EF) }, /* F0 */ { Bad_Opcode }, { Bad_Opcode }, + { X86_64_EVEX_FROM_VEX_TABLE (X86_64_EVEX_0F38F2) }, + { X86_64_EVEX_FROM_VEX_TABLE (X86_64_EVEX_0F38F3) }, { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, + { X86_64_EVEX_FROM_VEX_TABLE (X86_64_EVEX_0F38F5) }, + { X86_64_EVEX_FROM_VEX_TABLE (X86_64_EVEX_0F38F6) }, + { X86_64_EVEX_FROM_VEX_TABLE (X86_64_EVEX_0F38F7) }, /* F8 */ { Bad_Opcode }, { Bad_Opcode }, @@ -854,7 +854,7 @@ static const struct dis386 evex_table[][256] = { { Bad_Opcode }, { Bad_Opcode }, /* F0 */ - { Bad_Opcode }, + { X86_64_EVEX_FROM_VEX_TABLE (X86_64_EVEX_0F3AF0) }, { Bad_Opcode }, { Bad_Opcode }, { Bad_Opcode }, @@ -983,13 +983,13 @@ static const struct dis386 evex_table[][256] = { { Bad_Opcode }, { Bad_Opcode }, /* 60 */ + { "movbeS", { Gv, Ev }, PREFIX_NP_OR_DATA }, + { "movbeS", { Ev, Gv }, PREFIX_NP_OR_DATA }, { Bad_Opcode }, { Bad_Opcode }, { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, + { "wrussK", { M, Gdq }, PREFIX_DATA }, + { PREFIX_TABLE (PREFIX_EVEX_MAP4_66) }, { Bad_Opcode }, /* 68 */ { Bad_Opcode }, @@ -1113,19 +1113,19 @@ static const struct dis386 evex_table[][256] = { { Bad_Opcode }, { Bad_Opcode }, { Bad_Opcode }, - { Bad_Opcode }, + { "sha1rnds4", { XM, EXxmm, Ib }, 0 }, { Bad_Opcode }, { Bad_Opcode }, { Bad_Opcode }, /* D8 */ - { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, + { PREFIX_TABLE (PREFIX_EVEX_MAP4_D8) }, + { "sha1msg1", { XM, EXxmm }, 0 }, + { PREFIX_TABLE (PREFIX_EVEX_MAP4_DA) }, + { PREFIX_TABLE (PREFIX_EVEX_MAP4_DB) }, + { PREFIX_TABLE (PREFIX_EVEX_MAP4_DC) }, + { PREFIX_TABLE (PREFIX_EVEX_MAP4_DD) }, + { PREFIX_TABLE (PREFIX_EVEX_MAP4_DE) }, + { PREFIX_TABLE (PREFIX_EVEX_MAP4_DF) }, /* E0 */ { Bad_Opcode }, { Bad_Opcode }, @@ -1145,20 +1145,20 @@ static const struct dis386 evex_table[][256] = { { Bad_Opcode }, { Bad_Opcode }, /* F0 */ - { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, + { PREFIX_TABLE (PREFIX_EVEX_MAP4_F0) }, + { PREFIX_TABLE (PREFIX_EVEX_MAP4_F1) }, + { PREFIX_TABLE (PREFIX_EVEX_MAP4_F2) }, { Bad_Opcode }, { Bad_Opcode }, { Bad_Opcode }, { Bad_Opcode }, { Bad_Opcode }, /* F8 */ + { PREFIX_TABLE (PREFIX_EVEX_MAP4_F8) }, + { MOD_TABLE (MOD_EVEX_MAP4_F9) }, { Bad_Opcode }, { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, + { PREFIX_TABLE (PREFIX_EVEX_MAP4_FC) }, { Bad_Opcode }, { Bad_Opcode }, { Bad_Opcode }, diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index 0754b4c22dd..ef431087ba5 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -132,6 +132,13 @@ enum x86_64_isa intel64 }; +enum evex_type +{ + evex_default = 0, + evex_from_legacy, + evex_from_vex, +}; + struct instr_info { enum address_mode address_mode; @@ -211,7 +218,6 @@ struct instr_info int ll; bool w; bool evex; - bool r; bool v; bool zeroing; bool b; @@ -219,6 +225,8 @@ struct instr_info } vex; + enum evex_type evex_type; + /* Remember if the current op is a jump instruction. */ bool op_is_jump; @@ -301,6 +309,7 @@ struct dis_private { #define PREFIX_ADDR 0x400 #define PREFIX_FWAIT 0x800 #define PREFIX_REX2 0x1000 +#define PREFIX_NP_OR_DATA 0x2000 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive) to ADDR (exclusive) are valid. Returns true for success, false @@ -794,6 +803,7 @@ enum USE_RM_TABLE, USE_PREFIX_TABLE, USE_X86_64_TABLE, + USE_X86_64_EVEX_FROM_VEX_TABLE, USE_3BYTE_TABLE, USE_XOP_8F_TABLE, USE_VEX_C4_TABLE, @@ -812,6 +822,8 @@ enum #define RM_TABLE(I) DIS386 (USE_RM_TABLE, (I)) #define PREFIX_TABLE(I) DIS386 (USE_PREFIX_TABLE, (I)) #define X86_64_TABLE(I) DIS386 (USE_X86_64_TABLE, (I)) +#define X86_64_EVEX_FROM_VEX_TABLE(I) \ + DIS386 (USE_X86_64_EVEX_FROM_VEX_TABLE, (I)) #define THREE_BYTE_TABLE(I) DIS386 (USE_3BYTE_TABLE, (I)) #define XOP_8F_TABLE() DIS386 (USE_XOP_8F_TABLE, 0) #define VEX_C4_TABLE() DIS386 (USE_VEX_C4_TABLE, 0) @@ -871,7 +883,9 @@ enum REG_EVEX_0F72, REG_EVEX_0F73, REG_EVEX_0F38C6_L_2, - REG_EVEX_0F38C7_L_2 + REG_EVEX_0F38C7_L_2, + REG_EVEX_0F38F3_L_0, + REG_EVEX_MAP4_D8_PREFIX_1 }; enum @@ -911,6 +925,17 @@ enum MOD_0F38DC_PREFIX_1, MOD_VEX_0F3849_X86_64_L_0_W_0, + + MOD_EVEX_MAP4_DA_PREFIX_1, + MOD_EVEX_MAP4_DB_PREFIX_1, + MOD_EVEX_MAP4_DC_PREFIX_1, + MOD_EVEX_MAP4_DD_PREFIX_1, + MOD_EVEX_MAP4_DE_PREFIX_1, + MOD_EVEX_MAP4_DF_PREFIX_1, + MOD_EVEX_MAP4_F8_PREFIX_1, + MOD_EVEX_MAP4_F8_PREFIX_2, + MOD_EVEX_MAP4_F8_PREFIX_3, + MOD_EVEX_MAP4_F9, }; enum @@ -1146,6 +1171,20 @@ enum PREFIX_EVEX_0F3A67, PREFIX_EVEX_0F3AC2, + PREFIX_EVEX_MAP4_66, + PREFIX_EVEX_MAP4_D8, + PREFIX_EVEX_MAP4_DA, + PREFIX_EVEX_MAP4_DB, + PREFIX_EVEX_MAP4_DC, + PREFIX_EVEX_MAP4_DD, + PREFIX_EVEX_MAP4_DE, + PREFIX_EVEX_MAP4_DF, + PREFIX_EVEX_MAP4_F0, + PREFIX_EVEX_MAP4_F1, + PREFIX_EVEX_MAP4_F2, + PREFIX_EVEX_MAP4_F8, + PREFIX_EVEX_MAP4_FC, + PREFIX_EVEX_MAP5_10, PREFIX_EVEX_MAP5_11, PREFIX_EVEX_MAP5_1D, @@ -1256,6 +1295,35 @@ enum X86_64_VEX_0F38ED, X86_64_VEX_0F38EE, X86_64_VEX_0F38EF, + + X86_64_EVEX_0F90, + X86_64_EVEX_0F91, + X86_64_EVEX_0F92, + X86_64_EVEX_0F93, + X86_64_EVEX_0F3849, + X86_64_EVEX_0F384B, + X86_64_EVEX_0F38E0, + X86_64_EVEX_0F38E1, + X86_64_EVEX_0F38E2, + X86_64_EVEX_0F38E3, + X86_64_EVEX_0F38E4, + X86_64_EVEX_0F38E5, + X86_64_EVEX_0F38E6, + X86_64_EVEX_0F38E7, + X86_64_EVEX_0F38E8, + X86_64_EVEX_0F38E9, + X86_64_EVEX_0F38EA, + X86_64_EVEX_0F38EB, + X86_64_EVEX_0F38EC, + X86_64_EVEX_0F38ED, + X86_64_EVEX_0F38EE, + X86_64_EVEX_0F38EF, + X86_64_EVEX_0F38F2, + X86_64_EVEX_0F38F3, + X86_64_EVEX_0F38F5, + X86_64_EVEX_0F38F6, + X86_64_EVEX_0F38F7, + X86_64_EVEX_0F3AF0, }; enum @@ -1286,6 +1354,7 @@ enum EVEX_MAP4, EVEX_MAP5, EVEX_MAP6, + EVEX_MAP7, }; enum @@ -1438,6 +1507,8 @@ enum EVEX_LEN_0F385B, EVEX_LEN_0F38C6, EVEX_LEN_0F38C7, + EVEX_LEN_0F38F2, + EVEX_LEN_0F38F3, EVEX_LEN_0F3A00, EVEX_LEN_0F3A01, EVEX_LEN_0F3A18, @@ -4478,6 +4549,8 @@ static const struct dis386 x86_64_table[][2] = { { Bad_Opcode }, { "cmpnlexadd", { Mdq, Gdq, VexGdq }, PREFIX_DATA }, }, + +#include "i386-dis-evex-x86-64.h" }; static const struct dis386 three_byte_table[][256] = { @@ -8668,6 +8741,9 @@ get_valid_dis386 (const struct dis386 *dp, instr_info *ins) dp = &prefix_table[dp->op[1].bytemode][vindex]; break; + case USE_X86_64_EVEX_FROM_VEX_TABLE: + ins->evex_type = evex_from_vex; + /* Fall through. */ case USE_X86_64_TABLE: vindex = ins->address_mode == mode_64bit ? 1 : 0; dp = &x86_64_table[dp->op[1].bytemode][vindex]; @@ -8905,9 +8981,13 @@ get_valid_dis386 (const struct dis386 *dp, instr_info *ins) if (!fetch_code (ins->info, ins->codep + 4)) return &err_opcode; /* The first byte after 0x62. */ + if (*ins->codep & 0x8) + ins->rex2 |= REX_B; + if (!(*ins->codep & 0x10)) + ins->rex2 |= REX_R; + ins->rex = ~(*ins->codep >> 5) & 0x7; - ins->vex.r = *ins->codep & 0x10; - switch ((*ins->codep & 0xf)) + switch ((*ins->codep & 0x7)) { default: return &bad_opcode; @@ -8920,12 +9000,19 @@ get_valid_dis386 (const struct dis386 *dp, instr_info *ins) case 0x3: vex_table_index = EVEX_0F3A; break; + case 0x4: + vex_table_index = EVEX_MAP4; + ins->evex_type = evex_from_legacy; + break; case 0x5: vex_table_index = EVEX_MAP5; break; case 0x6: vex_table_index = EVEX_MAP6; break; + case 0x7: + vex_table_index = EVEX_MAP7; + break; } /* The second byte after 0x62. */ @@ -8936,9 +9023,8 @@ get_valid_dis386 (const struct dis386 *dp, instr_info *ins) ins->vex.register_specifier = (~(*ins->codep >> 3)) & 0xf; - /* The U bit. */ if (!(*ins->codep & 0x4)) - return &bad_opcode; + ins->rex2 |= REX_X; switch ((*ins->codep & 0x3)) { @@ -8968,12 +9054,31 @@ get_valid_dis386 (const struct dis386 *dp, instr_info *ins) if (ins->address_mode != mode_64bit) { + if (ins->evex_type != evex_default + || (ins->rex2 & (REX_B | REX_X))) + return &bad_opcode; /* In 16/32-bit mode silently ignore following bits. */ ins->rex &= ~REX_B; - ins->vex.r = true; + ins->rex2 &= ~REX_R; } ins->need_vex = 4; + + /* EVEX from legacy instructions require that EVEX.L’L, EVEX.z and the + lower 2 bits of EVEX.aaa must be 0. + EVEX from evex instrucions require that EVEX.L’L and the lower 2 bits of + EVEX.aaa must be 0. */ + if (ins->evex_type == evex_from_legacy || ins->evex_type == evex_from_vex) + { + if ((*ins->codep & 0x3) != 0 + || (*ins->codep >> 6 & 0x3) != 0 + || (ins->evex_type == evex_from_legacy + && (*ins->codep >> 5 & 0x1) != 0) + || (ins->evex_type == evex_from_vex + && !ins->vex.b)) + return &bad_opcode; + } + ins->codep++; vindex = *ins->codep++; dp = &evex_table[vex_table_index][vindex]; @@ -9386,6 +9491,13 @@ print_insn (bfd_vma pc, disassemble_info *info, int intel_syntax) dp = get_valid_dis386 (dp, &ins); if (dp == &err_opcode) goto fetch_error_out; + + /* For APX instructions promoted from legacy maps 0/1, prefix + 0x66 is interpreted as the operand size override. */ + if (ins.evex_type == evex_from_legacy + && ins.vex.prefix == DATA_PREFIX_OPCODE) + sizeflag ^= DFLAG; + if (dp != NULL && putop (&ins, dp->name, sizeflag) == 0) { if (!get_sib (&ins, sizeflag)) @@ -9566,6 +9678,19 @@ print_insn (bfd_vma pc, disassemble_info *info, int intel_syntax) if (ins.last_repnz_prefix >= 0) ins.all_prefixes[ins.last_repnz_prefix] = 0xf2; break; + + case PREFIX_NP_OR_DATA: + if (ins.vex.prefix & ~DATA_PREFIX_OPCODE) + { + i386_dis_printf (info, dis_style_text, "(bad)"); + ret = ins.end_codep - priv.the_buffer; + goto out; + } + break; + + default: + break; + } /* Check if the REX prefix is used. */ @@ -10274,7 +10399,7 @@ putop (instr_info *ins, const char *in_template, int sizeflag) { case 'X': if (!ins->vex.evex || ins->vex.b || ins->vex.ll >= 2 - || !ins->vex.r + || (ins->rex2 & REX_R) || (ins->modrm.mod == 3 && (ins->rex & REX_X)) || !ins->vex.v || ins->vex.mask_register_specifier) break; @@ -11168,7 +11293,7 @@ print_register (instr_info *ins, unsigned int reg, unsigned int rexmask, case b_swap_mode: if (reg & 4) USED_REX (0); - if (ins->rex) + if (ins->rex || ins->rex2) names = att_names8rex; else names = att_names8; @@ -11385,7 +11510,7 @@ OP_E_memory (instr_info *ins, int bytemode, int sizeflag) add += (ins->rex2 & REX_B) ? 16 : 0; - if (ins->vex.evex) + if (ins->vex.evex && ins->evex_type == evex_default) { /* Zeroing-masking is invalid for memory destinations. Set the flag @@ -11533,6 +11658,13 @@ OP_E_memory (instr_info *ins, int bytemode, int sizeflag) abort (); if (ins->vex.evex) { + /* S/G EVEX insns require REX_X not to be set. */ + if (ins->rex2 & REX_X) + { + oappend (ins, "(bad)"); + return true; + } + if (!ins->vex.v) vindex += 16; check_gather = ins->obufp == ins->op_out[1]; @@ -11732,7 +11864,7 @@ OP_E_memory (instr_info *ins, int bytemode, int sizeflag) if (ins->rex & REX_R) modrm_reg += 8; - if (!ins->vex.r) + if (ins->rex2 & REX_R) modrm_reg += 16; if (vindex == modrm_reg) oappend (ins, "/(bad)"); @@ -11934,10 +12066,7 @@ OP_indirE (instr_info *ins, int bytemode, int sizeflag) static bool OP_G (instr_info *ins, int bytemode, int sizeflag) { - if (ins->vex.evex && !ins->vex.r && ins->address_mode == mode_64bit) - oappend (ins, "(bad)"); - else - print_register (ins, ins->modrm.reg, REX_R, bytemode, sizeflag); + print_register (ins, ins->modrm.reg, REX_R, bytemode, sizeflag); return true; } @@ -12567,7 +12696,7 @@ OP_XMM (instr_info *ins, int bytemode, int sizeflag ATTRIBUTE_UNUSED) reg += 8; if (ins->vex.evex) { - if (!ins->vex.r) + if (ins->rex2 & REX_R) reg += 16; } @@ -13574,7 +13703,7 @@ DistinctDest_Fixup (instr_info *ins, int bytemode, int sizeflag) /* Calc destination register number. */ if (ins->rex & REX_R) modrm_reg += 8; - if (!ins->vex.r) + if (ins->rex2 & REX_R) modrm_reg += 16; /* Calc src1 register number. */ diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c index 589f9682699..3ab2362a3cc 100644 --- a/opcodes/i386-gen.c +++ b/opcodes/i386-gen.c @@ -1050,6 +1050,7 @@ process_i386_opcode_modifier (FILE *table, char *mod, unsigned int space, SPACE(0F), SPACE(0F38), SPACE(0F3A), + SPACE(EVEXMAP4), SPACE(EVEXMAP5), SPACE(EVEXMAP6), SPACE(XOP08), @@ -1153,6 +1154,7 @@ process_i386_opcode_modifier (FILE *table, char *mod, unsigned int space, is_evex_encoding. */ if (modifiers[Vex].value || ((space > SPACE_0F || has_special_handle) + && !(space == SPACE_EVEXMAP4) && !modifiers[EVex].value && !modifiers[Disp8MemShift].value && !modifiers[Broadcast].value diff --git a/opcodes/i386-opc.h b/opcodes/i386-opc.h index c8082971f81..d7d28bf3d93 100644 --- a/opcodes/i386-opc.h +++ b/opcodes/i386-opc.h @@ -972,6 +972,7 @@ typedef struct insn_template 1: 0F opcode prefix / space. 2: 0F38 opcode prefix / space. 3: 0F3A opcode prefix / space. + 4: EVEXMAP4 opcode prefix / space. 5: EVEXMAP5 opcode prefix / space. 6: EVEXMAP6 opcode prefix / space. 8: XOP 08 opcode space. @@ -982,6 +983,7 @@ typedef struct insn_template #define SPACE_0F 1 #define SPACE_0F38 2 #define SPACE_0F3A 3 +#define SPACE_EVEXMAP4 4 #define SPACE_EVEXMAP5 5 #define SPACE_EVEXMAP6 6 #define SPACE_XOP08 8 diff --git a/opcodes/i386-opc.tbl b/opcodes/i386-opc.tbl index 17be21fdf0e..bb42270483b 100644 --- a/opcodes/i386-opc.tbl +++ b/opcodes/i386-opc.tbl @@ -109,6 +109,7 @@ #define SpaceXOP09 OpcodeSpace=SPACE_XOP09 #define SpaceXOP0A OpcodeSpace=SPACE_XOP0A +#define EVexMap4 OpcodeSpace=SPACE_EVEXMAP4 #define EVexMap5 OpcodeSpace=SPACE_EVEXMAP5 #define EVexMap6 OpcodeSpace=SPACE_EVEXMAP6 @@ -136,6 +137,8 @@ #define Vsz256 Vsz=VSZ256 #define Vsz512 Vsz=VSZ512 +#define APX_F APX_F|x64 + // The EVEX purpose of StaticRounding appears only together with SAE. Re-use // the bit to mark commutative VEX encodings where swapping the source // operands may allow to switch from 3-byte to 2-byte VEX encoding. @@ -189,6 +192,7 @@ mov, 0xf24, i386|No64, D|RegMem|IgnoreSize|No_bSuf|No_wSuf|No_sSuf|No_qSuf, { Te // Move after swapping the bytes movbe, 0x0f38f0, Movbe, D|Modrm|CheckOperandSize|No_bSuf|No_sSuf, { Word|Dword|Qword|Unspecified|BaseIndex, Reg16|Reg32|Reg64 } +movbe, 0x60, Movbe|APX_F, D|Modrm|CheckOperandSize|No_bSuf|No_sSuf|EVex128|EVexMap4, { Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64 } // Move with sign extend. movsb, 0xfbe, i386, Modrm|No_bSuf|No_sSuf, { Reg8|Unspecified|BaseIndex, Reg16|Reg32|Reg64 } @@ -336,6 +340,7 @@ adc, 0x14, 0, W|No_sSuf, { Imm8|Imm16|Imm32|Imm32S, Acc|Byte|Word|Dword|Qword } adc, 0x80/2, 0, W|Modrm|No_sSuf|HLEPrefixLock, { Imm8|Imm16|Imm32|Imm32S, Reg8|Reg16|Reg32|Reg64|Byte|Word|Dword|Qword|Unspecified|BaseIndex } neg, 0xf6/3, 0, W|Modrm|No_sSuf|HLEPrefixLock, { Reg8|Reg16|Reg32|Reg64|Byte|Word|Dword|Qword|Unspecified|BaseIndex } + not, 0xf6/2, 0, W|Modrm|No_sSuf|HLEPrefixLock, { Reg8|Reg16|Reg32|Reg64|Byte|Word|Dword|Qword|Unspecified|BaseIndex } aaa, 0x37, No64, NoSuf, {} @@ -1314,13 +1319,16 @@ getsec, 0xf37, SMX, NoSuf, {} invept, 0x660f3880, EPT|No64, Modrm|IgnoreSize|NoSuf, { Oword|Unspecified|BaseIndex, Reg32 } invept, 0x660f3880, EPT|x64, Modrm|NoSuf|NoRex64, { Oword|Unspecified|BaseIndex, Reg64 } +invept, 0xf3f0, APX_F|EPT, Modrm|NoSuf|EVex128|EVexMap4, { Oword|Unspecified|BaseIndex, Reg64 } invvpid, 0x660f3881, EPT|No64, Modrm|IgnoreSize|NoSuf, { Oword|Unspecified|BaseIndex, Reg32 } invvpid, 0x660f3881, EPT|x64, Modrm|NoSuf|NoRex64, { Oword|Unspecified|BaseIndex, Reg64 } +invvpid, 0xf3f1, APX_F|EPT, Modrm|NoSuf|EVex128|EVexMap4, { Oword|Unspecified|BaseIndex, Reg64 } // INVPCID instruction invpcid, 0x660f3882, INVPCID|No64, Modrm|IgnoreSize|NoSuf, { Oword|Unspecified|BaseIndex, Reg32 } invpcid, 0x660f3882, INVPCID|x64, Modrm|NoSuf|NoRex64, { Oword|Unspecified|BaseIndex, Reg64 } +invpcid, 0xf3f2, APX_F|INVPCID, Modrm|NoSuf|EVex128|EVexMap4, { Oword|Unspecified|BaseIndex, Reg64 } // SSSE3 instructions. @@ -1420,7 +1428,9 @@ pcmpestrm, 0x660f3a60, SSE4_2|x64, Modrm|IgnoreSize|No_bSuf|No_wSuf|No_sSuf, { I pcmpistri, 0x660f3a63, , Modrm||NoSuf, { Imm8, RegXMM|Unspecified|BaseIndex, RegXMM } pcmpistrm, 0x660f3a62, , Modrm||NoSuf, { Imm8, RegXMM|Unspecified|BaseIndex, RegXMM } crc32, 0xf20f38f0, SSE4_2, W|Modrm|No_sSuf|No_qSuf, { Reg8|Reg16|Reg32|Unspecified|BaseIndex, Reg32 } +crc32, 0xf0, APX_F, W|Modrm|No_sSuf|No_qSuf|EVex128|EVexMap4, { Reg8|Reg16|Reg32|Unspecified|BaseIndex, Reg32 } crc32, 0xf20f38f0, SSE4_2|x64, W|Modrm|No_wSuf|No_lSuf|No_sSuf, { Reg8|Reg64|Unspecified|BaseIndex, Reg64 } +crc32, 0xf0, APX_F, W|Modrm|No_wSuf|No_lSuf|No_sSuf|EVex128|EVexMap4, { Reg8|Reg64|Unspecified|BaseIndex, Reg64 } // xsave/xrstor New Instructions. @@ -1832,13 +1842,21 @@ xtest, 0xf01d6, HLE|RTM, NoSuf, {} // BMI2 instructions. bzhi, 0xf5, BMI2, Modrm|CheckOperandSize|Vex128|Space0F38|VexVVVV|SwapSources|No_bSuf|No_wSuf|No_sSuf, { Reg32|Reg64, Reg32|Reg64|Unspecified|BaseIndex, Reg32|Reg64 } +bzhi, 0xf5, BMI2|APX_F, Modrm|CheckOperandSize|EVex128|Space0F38|VexVVVV|SwapSources|No_bSuf|No_wSuf|No_sSuf, { Reg32|Reg64, Reg32|Reg64|Unspecified|BaseIndex, Reg32|Reg64 } mulx, 0xf2f6, BMI2, Modrm|CheckOperandSize|Vex128|Space0F38|VexVVVV|No_bSuf|No_wSuf|No_sSuf, { Reg32|Reg64|Unspecified|BaseIndex, Reg32|Reg64, Reg32|Reg64 } +mulx, 0xf2f6, BMI2|APX_F, Modrm|CheckOperandSize|EVex128|Space0F38|VexVVVV|No_bSuf|No_wSuf|No_sSuf, { Reg32|Reg64|Unspecified|BaseIndex, Reg32|Reg64, Reg32|Reg64 } pdep, 0xf2f5, BMI2, Modrm|CheckOperandSize|Vex128|Space0F38|VexVVVV|No_bSuf|No_wSuf|No_sSuf, { Reg32|Reg64|Unspecified|BaseIndex, Reg32|Reg64, Reg32|Reg64 } +pdep, 0xf2f5, BMI2|APX_F, Modrm|CheckOperandSize|EVex128|Space0F38|VexVVVV|No_bSuf|No_wSuf|No_sSuf, { Reg32|Reg64|Unspecified|BaseIndex, Reg32|Reg64, Reg32|Reg64 } pext, 0xf3f5, BMI2, Modrm|CheckOperandSize|Vex128|Space0F38|VexVVVV|No_bSuf|No_wSuf|No_sSuf, { Reg32|Reg64|Unspecified|BaseIndex, Reg32|Reg64, Reg32|Reg64 } +pext, 0xf3f5, BMI2|APX_F, Modrm|CheckOperandSize|EVex128|Space0F38|VexVVVV|No_bSuf|No_wSuf|No_sSuf, { Reg32|Reg64|Unspecified|BaseIndex, Reg32|Reg64, Reg32|Reg64 } rorx, 0xf2f0, BMI2, Modrm|CheckOperandSize|Vex128|Space0F3A|No_bSuf|No_wSuf|No_sSuf, { Imm8|Imm8S, Reg32|Reg64|Dword|Qword|Unspecified|BaseIndex, Reg32|Reg64 } +rorx, 0xf2f0, BMI2|APX_F, Modrm|CheckOperandSize|EVex128|Space0F3A|No_bSuf|No_wSuf|No_sSuf, { Imm8|Imm8S, Reg32|Reg64|Dword|Qword|Unspecified|BaseIndex, Reg32|Reg64 } sarx, 0xf3f7, BMI2, Modrm|CheckOperandSize|Vex128|Space0F38|VexVVVV|SwapSources|No_bSuf|No_wSuf|No_sSuf, { Reg32|Reg64, Reg32|Reg64|Unspecified|BaseIndex, Reg32|Reg64 } +sarx, 0xf3f7, BMI2|APX_F, Modrm|CheckOperandSize|EVex128|Space0F38|VexVVVV|SwapSources|No_bSuf|No_wSuf|No_sSuf, { Reg32|Reg64, Reg32|Reg64|Unspecified|BaseIndex, Reg32|Reg64 } shlx, 0x66f7, BMI2, Modrm|CheckOperandSize|Vex128|Space0F38|VexVVVV|SwapSources|No_bSuf|No_wSuf|No_sSuf, { Reg32|Reg64, Reg32|Reg64|Unspecified|BaseIndex, Reg32|Reg64 } +shlx, 0x66f7, BMI2|APX_F, Modrm|CheckOperandSize|EVex128|Space0F38|VexVVVV|SwapSources|No_bSuf|No_wSuf|No_sSuf, { Reg32|Reg64, Reg32|Reg64|Unspecified|BaseIndex, Reg32|Reg64 } shrx, 0xf2f7, BMI2, Modrm|CheckOperandSize|Vex128|Space0F38|VexVVVV|SwapSources|No_bSuf|No_wSuf|No_sSuf, { Reg32|Reg64, Reg32|Reg64|Unspecified|BaseIndex, Reg32|Reg64 } +shrx, 0xf2f7, BMI2|APX_F, Modrm|CheckOperandSize|EVex128|Space0F38|VexVVVV|SwapSources|No_bSuf|No_wSuf|No_sSuf, { Reg32|Reg64, Reg32|Reg64|Unspecified|BaseIndex, Reg32|Reg64 } // FMA4 instructions @@ -1909,10 +1927,15 @@ lwpins, 0x12/0, LWP, Modrm|SpaceXOP0A|NoSuf|VexVVVV|Vex, { Imm32|Imm32S, Reg32|U // BMI instructions andn, 0xf2, BMI, Modrm|CheckOperandSize|Vex128|Space0F38|VexVVVV|No_bSuf|No_wSuf|No_sSuf, { Reg32|Reg64|Unspecified|BaseIndex, Reg32|Reg64, Reg32|Reg64 } +andn, 0xf2, BMI|APX_F, Modrm|CheckOperandSize|EVex128|Space0F38|VexVVVV|No_bSuf|No_wSuf|No_sSuf, { Reg32|Reg64|Unspecified|BaseIndex, Reg32|Reg64, Reg32|Reg64 } bextr, 0xf7, BMI, Modrm|CheckOperandSize|Vex128|Space0F38|VexVVVV|SwapSources|No_bSuf|No_wSuf|No_sSuf, { Reg32|Reg64, Reg32|Reg64|Unspecified|BaseIndex, Reg32|Reg64 } +bextr, 0xf7, BMI|APX_F, Modrm|CheckOperandSize|EVex128|Space0F38|VexVVVV|SwapSources|No_bSuf|No_wSuf|No_sSuf, { Reg32|Reg64, Reg32|Reg64|Unspecified|BaseIndex, Reg32|Reg64 } blsi, 0xf3/3, BMI, Modrm|CheckOperandSize|Vex128|Space0F38|VexVVVV|No_bSuf|No_wSuf|No_sSuf, { Reg32|Reg64|Unspecified|BaseIndex, Reg32|Reg64 } +blsi, 0xf3/3, BMI|APX_F, Modrm|CheckOperandSize|EVex128|Space0F38|VexVVVV|No_bSuf|No_wSuf|No_sSuf, { Reg32|Reg64|Unspecified|BaseIndex, Reg32|Reg64 } blsmsk, 0xf3/2, BMI, Modrm|CheckOperandSize|Vex128|Space0F38|VexVVVV|No_bSuf|No_wSuf|No_sSuf, { Reg32|Reg64|Unspecified|BaseIndex, Reg32|Reg64 } +blsmsk, 0xf3/2, BMI|APX_F, Modrm|CheckOperandSize|EVex128|Space0F38|VexVVVV|No_bSuf|No_wSuf|No_sSuf, { Reg32|Reg64|Unspecified|BaseIndex, Reg32|Reg64 } blsr, 0xf3/1, BMI, Modrm|CheckOperandSize|Vex128|Space0F38|VexVVVV|No_bSuf|No_wSuf|No_sSuf, { Reg32|Reg64|Unspecified|BaseIndex, Reg32|Reg64 } +blsr, 0xf3/1, BMI|APX_F, Modrm|CheckOperandSize|EVex128|Space0F38|VexVVVV|No_bSuf|No_wSuf|No_sSuf, { Reg32|Reg64|Unspecified|BaseIndex, Reg32|Reg64 } tzcnt, 0xf30fbc, BMI, Modrm|CheckOperandSize|No_bSuf|No_sSuf, { Reg16|Reg32|Reg64|Word|Dword|Qword|Unspecified|BaseIndex, Reg16|Reg32|Reg64 } // TBM instructions @@ -2041,13 +2064,20 @@ bndldx, 0x0f1a, MPX, Modrm|Anysize|IgnoreSize|NoSuf, { BaseIndex, RegBND } // SHA instructions. sha1rnds4, 0xf3acc, SHA, Modrm|NoSuf, { Imm8|Imm8S, RegXMM|Unspecified|BaseIndex, RegXMM } +sha1rnds4, 0xd4, SHA|APX_F, Modrm|NoSuf|EVex128|EVexMap4, { Imm8|Imm8S, RegXMM|Unspecified|BaseIndex, RegXMM } sha1nexte, 0xf38c8, SHA, Modrm|NoSuf, { RegXMM|Unspecified|BaseIndex, RegXMM } +sha1nexte, 0xd8, SHA|APX_F, Modrm|NoSuf|EVex128|EVexMap4, { RegXMM|Unspecified|BaseIndex, RegXMM } sha1msg1, 0xf38c9, SHA, Modrm|NoSuf, { RegXMM|Unspecified|BaseIndex, RegXMM } +sha1msg1, 0xd9, SHA|APX_F, Modrm|NoSuf|EVex128|EVexMap4, { RegXMM|Unspecified|BaseIndex, RegXMM } sha1msg2, 0xf38ca, SHA, Modrm|NoSuf, { RegXMM|Unspecified|BaseIndex, RegXMM } +sha1msg2, 0xda, SHA|APX_F, Modrm|NoSuf|EVex128|EVexMap4, { RegXMM|Unspecified|BaseIndex, RegXMM } sha256rnds2, 0xf38cb, SHA, Modrm|NoSuf, { Acc|Xmmword, RegXMM|Unspecified|BaseIndex, RegXMM } sha256rnds2, 0xf38cb, SHA, Modrm|NoSuf, { RegXMM|Unspecified|BaseIndex, RegXMM } +sha256rnds2, 0xdb, SHA|APX_F, Modrm|NoSuf|EVex128|EVexMap4, { RegXMM|Unspecified|BaseIndex, RegXMM } sha256msg1, 0xf38cc, SHA, Modrm|NoSuf, { RegXMM|Unspecified|BaseIndex, RegXMM } +sha256msg1, 0xdc, SHA|APX_F, Modrm|NoSuf|EVex128|EVexMap4, { RegXMM|Unspecified|BaseIndex, RegXMM } sha256msg2, 0xf38cd, SHA, Modrm|NoSuf, { RegXMM|Unspecified|BaseIndex, RegXMM } +sha256msg2, 0xdd, SHA|APX_F, Modrm|NoSuf|EVex128|EVexMap4, { RegXMM|Unspecified|BaseIndex, RegXMM } // SHA512 instructions. @@ -2107,8 +2137,11 @@ kxnor, 0x46, , Modrm|Vex256|Space0F|VexVVVV|VexW0|NoSuf, { kxor, 0x47, , Modrm|Vex256|Space0F|VexVVVV|VexW0|NoSuf, { RegMask, RegMask, RegMask } kmov, 0x90, , Modrm|Vex128|Space0F|VexW0|NoSuf, { RegMask||Unspecified|BaseIndex, RegMask } +kmov, 0x90, |APX_F, Modrm|EVex128|Space0F|VexW0|NoSuf, { RegMask||Unspecified|BaseIndex, RegMask } kmov, 0x91, , Modrm|Vex128|Space0F|VexW0|NoSuf, { RegMask, |Unspecified|BaseIndex } +kmov, 0x91, |APX_F, Modrm|EVex128|Space0F|VexW0|NoSuf, { RegMask, |Unspecified|BaseIndex } kmov, 0x92, , D|Modrm|Vex128|Space0F|VexW0|NoSuf, { Reg32, RegMask } +kmov, 0x92, |APX_F, D|Modrm|EVex128|Space0F|VexW0|NoSuf, { Reg32, RegMask } knot, 0x44, , Modrm|Vex128|Space0F|VexW0|NoSuf, { RegMask, RegMask } kortest, 0x98, , Modrm|Vex128|Space0F|VexW0|NoSuf, { RegMask, RegMask } @@ -2584,8 +2617,11 @@ kadd, 0x4a, AVX512BW, Modrm|Vex256|Space0F|VexVVVV|VexW1|| kand, 0x41, AVX512BW, Modrm|Vex256|Space0F|VexVVVV|VexW1||NoSuf, { RegMask, RegMask, RegMask } kandn, 0x42, AVX512BW, Modrm|Vex256|Space0F|VexVVVV|VexW1||NoSuf|Optimize, { RegMask, RegMask, RegMask } kmov, 0x90, AVX512BW, Modrm|Vex128|Space0F|VexW1||NoSuf, { RegMask||Unspecified|BaseIndex, RegMask } +kmov, 0x90, AVX512BW|APX_F, Modrm|EVex128|Space0F|VexW1||NoSuf, { RegMask||Unspecified|BaseIndex, RegMask } kmov, 0x91, AVX512BW, Modrm|Vex128|Space0F|VexW1||NoSuf, { RegMask, |Unspecified|BaseIndex } +kmov, 0x91, AVX512BW|APX_F, Modrm|EVex128|Space0F|VexW1||NoSuf, { RegMask, |Unspecified|BaseIndex } kmov, 0xf292, AVX512BW, D|Modrm|Vex128|Space0F|||NoSuf, { , RegMask } +kmov, 0xf292, AVX512BW|APX_F, D|Modrm|EVex128|Space0F|||NoSuf, { , RegMask } knot, 0x44, AVX512BW, Modrm|Vex128|Space0F|VexW1||NoSuf, { RegMask, RegMask } kor, 0x45, AVX512BW, Modrm|Vex256|Space0F|VexVVVV|VexW1||NoSuf, { RegMask, RegMask, RegMask } kortest, 0x98, AVX512BW, Modrm|Vex128|Space0F|VexW1||NoSuf, { RegMask, RegMask } @@ -2984,9 +3020,13 @@ rdsspq, 0xf30f1e/1, SHSTK|x64, Modrm|NoSuf, { Reg64 } saveprevssp, 0xf30f01ea, SHSTK, NoSuf, {} rstorssp, 0xf30f01/5, SHSTK, Modrm|NoSuf, { Qword|Unspecified|BaseIndex } wrssd, 0x0f38f6, SHSTK, Modrm|IgnoreSize|NoSuf, { Reg32, Dword|Unspecified|BaseIndex } +wrssd, 0x66, SHSTK|APX_F, Modrm|IgnoreSize|NoSuf|EVex128|EVexMap4, { Reg32, Dword|Unspecified|BaseIndex } wrssq, 0x0f38f6, SHSTK|x64, Modrm|NoSuf|Size64, { Reg64, Qword|Unspecified|BaseIndex } +wrssq, 0x66, APX_F|SHSTK, Modrm|NoSuf|Size64|EVex128|EVexMap4, { Reg64, Qword|Unspecified|BaseIndex } wrussd, 0x660f38f5, SHSTK, Modrm|IgnoreSize|NoSuf, { Reg32, Dword|Unspecified|BaseIndex } +wrussd, 0x6665, SHSTK|APX_F, Modrm|IgnoreSize|NoSuf|EVex128|EVexMap4, { Reg32, Dword|Unspecified|BaseIndex } wrussq, 0x660f38f5, SHSTK|x64, Modrm|NoSuf, { Reg64, Qword|Unspecified|BaseIndex } +wrussq, 0x6665, SHSTK|APX_F, Modrm|NoSuf|EVex128|EVexMap4, { Reg64, Qword|Unspecified|BaseIndex } setssbsy, 0xf30f01e8, SHSTK, NoSuf, {} clrssbsy, 0xf30fae/6, SHSTK, Modrm|NoSuf, { Qword|Unspecified|BaseIndex } endbr64, 0xf30f1efa, IBT, NoSuf, {} @@ -3034,7 +3074,9 @@ cldemote, 0x0f1c/0, CLDEMOTE, Modrm|Anysize|IgnoreSize|NoSuf, { BaseIndex } // MOVDIR[I,64B] instructions. movdiri, 0xf38f9, MOVDIRI, Modrm|CheckOperandSize|IgnoreSize|No_bSuf|No_wSuf|No_sSuf, { Reg32|Reg64, Dword|Qword|Unspecified|BaseIndex } +movdiri, 0xf9, MOVDIRI|APX_F, Modrm|CheckOperandSize|IgnoreSize|No_bSuf|No_wSuf|No_sSuf|EVex128|EVexMap4, { Reg32|Reg64, Dword|Qword|Unspecified|BaseIndex } movdir64b, 0x660f38f8, MOVDIR64B, Modrm|AddrPrefixOpReg|NoSuf, { Unspecified|BaseIndex, Reg16|Reg32|Reg64 } +movdir64b, 0x66f8, MOVDIR64B|APX_F, Modrm|AddrPrefixOpReg|NoSuf|EVex128|EVexMap4, { Unspecified|BaseIndex, Reg32|Reg64 } // MOVEDIR instructions end. @@ -3063,7 +3105,9 @@ vcvtneps2bf16, 0xf372, AVX_NE_CONVERT, Modrm||Space0F38|VexW0|NoSu // ENQCMD instructions. enqcmd, 0xf20f38f8, ENQCMD, Modrm|AddrPrefixOpReg|NoSuf, { Unspecified|BaseIndex, Reg16|Reg32|Reg64 } +enqcmd, 0xf2f8, ENQCMD|APX_F, Modrm|AddrPrefixOpReg|NoSuf|EVex128|EVexMap4, { Unspecified|BaseIndex, Reg32|Reg64 } enqcmds, 0xf30f38f8, ENQCMD, Modrm|AddrPrefixOpReg|NoSuf, { Unspecified|BaseIndex, Reg16|Reg32|Reg64 } +enqcmds, 0xf3f8, ENQCMD|APX_F, Modrm|AddrPrefixOpReg|NoSuf|EVex128|EVexMap4, { Unspecified|BaseIndex, Reg32|Reg64 } // ENQCMD instructions end. @@ -3124,8 +3168,8 @@ xresldtrk, 0xf20f01e9, TSXLDTRK, NoSuf, {} // AMX instructions. -ldtilecfg, 0x49/0, AMX_TILE|x64, Modrm|Vex128|Space0F38|VexW0|NoSuf, { Unspecified|BaseIndex } -sttilecfg, 0x6649/0, AMX_TILE|x64, Modrm|Vex128|Space0F38|VexW0|NoSuf, { Unspecified|BaseIndex } +ldtilecfg, 0x49/0, AMX_TILE|APX_F, Modrm|Vex128|EVex128|Space0F38|VexW0|NoSuf, { Unspecified|BaseIndex } +sttilecfg, 0x6649/0, AMX_TILE|APX_F, Modrm|Vex128|EVex128|Space0F38|VexW0|NoSuf, { Unspecified|BaseIndex } tcmmimfp16ps, 0x666c, AMX_COMPLEX|x64, Modrm|Vex128|Space0F38|VexVVVV|VexW0|SwapSources|NoSuf, { RegTMM, RegTMM, RegTMM } tcmmrlfp16ps, 0x6c, AMX_COMPLEX|x64, Modrm|Vex128|Space0F38|VexVVVV|VexW0|SwapSources|NoSuf, { RegTMM, RegTMM, RegTMM } @@ -3137,9 +3181,9 @@ tdpbuud, 0x5e, AMX_INT8|x64, Modrm|Vex128|Space0F38|VexVVVV|VexW0|SwapSources|No tdpbusd, 0x665e, AMX_INT8|x64, Modrm|Vex128|Space0F38|VexVVVV|VexW0|SwapSources|NoSuf, { RegTMM, RegTMM, RegTMM } tdpbsud, 0xf35e, AMX_INT8|x64, Modrm|Vex128|Space0F38|VexVVVV|VexW0|SwapSources|NoSuf, { RegTMM, RegTMM, RegTMM } -tileloadd, 0xf24b, AMX_TILE|x64, Sibmem|Vex128|Space0F38|VexW0|NoSuf, { Unspecified|BaseIndex, RegTMM } -tileloaddt1, 0x664b, AMX_TILE|x64, Sibmem|Vex128|Space0F38|VexW0|NoSuf, { Unspecified|BaseIndex, RegTMM } -tilestored, 0xf34b, AMX_TILE|x64, Sibmem|Vex128|Space0F38|VexW0|NoSuf, { RegTMM, Unspecified|BaseIndex } +tileloadd, 0xf24b, AMX_TILE|APX_F, Sibmem|Vex128|EVex128|Space0F38|VexW0|NoSuf, { Unspecified|BaseIndex, RegTMM } +tileloaddt1, 0x664b, AMX_TILE|APX_F, Sibmem|Vex128|EVex128|Space0F38|VexW0|NoSuf, { Unspecified|BaseIndex, RegTMM } +tilestored, 0xf34b, AMX_TILE|APX_F, Sibmem|Vex128|EVex128|Space0F38|VexW0|NoSuf, { RegTMM, Unspecified|BaseIndex } tilerelease, 0x49c0, AMX_TILE|x64, Vex128|Space0F38|VexW0|NoSuf, {} @@ -3151,15 +3195,25 @@ tilezero, 0xf249, AMX_TILE|x64, Modrm|Vex128|Space0F38|VexW0|NoSuf, { RegTMM } loadiwkey, 0xf30f38dc, KL, Load|Modrm|NoSuf, { RegXMM, RegXMM } encodekey128, 0xf30f38fa, KL, Modrm|NoSuf, { Reg32, Reg32 } +encodekey128, 0xf3da, KL|APX_F, Modrm|NoSuf|EVex128|EVexMap4, { Reg32, Reg32 } encodekey256, 0xf30f38fb, KL, Modrm|NoSuf, { Reg32, Reg32 } +encodekey256, 0xf3db, KL|APX_F, Modrm|NoSuf|EVex128|EVexMap4, { Reg32, Reg32 } aesenc128kl, 0xf30f38dc, KL, Modrm|NoSuf, { Unspecified|BaseIndex, RegXMM } +aesenc128kl, 0xf3dc, KL|APX_F, Modrm|NoSuf|EVex128|EVexMap4, { Unspecified|BaseIndex, RegXMM } aesdec128kl, 0xf30f38dd, KL, Modrm|NoSuf, { Unspecified|BaseIndex, RegXMM } +aesdec128kl, 0xf3dd, KL|APX_F, Modrm|NoSuf|EVex128|EVexMap4, { Unspecified|BaseIndex, RegXMM } aesenc256kl, 0xf30f38de, KL, Modrm|NoSuf, { Unspecified|BaseIndex, RegXMM } +aesenc256kl, 0xf3de, KL|APX_F, Modrm|NoSuf|EVex128|EVexMap4, { Unspecified|BaseIndex, RegXMM } aesdec256kl, 0xf30f38df, KL, Modrm|NoSuf, { Unspecified|BaseIndex, RegXMM } +aesdec256kl, 0xf3df, KL|APX_F, Modrm|NoSuf|EVex128|EVexMap4, { Unspecified|BaseIndex, RegXMM } aesencwide128kl, 0xf30f38d8/0, WideKL, Modrm|NoSuf, { Unspecified|BaseIndex } +aesencwide128kl, 0xf3d8/0, WideKL|APX_F, Modrm|NoSuf|EVex128|EVexMap4, { Unspecified|BaseIndex } aesdecwide128kl, 0xf30f38d8/1, WideKL, Modrm|NoSuf, { Unspecified|BaseIndex } +aesdecwide128kl, 0xf3d8/1, WideKL|APX_F, Modrm|NoSuf|EVex128|EVexMap4, { Unspecified|BaseIndex } aesencwide256kl, 0xf30f38d8/2, WideKL, Modrm|NoSuf, { Unspecified|BaseIndex } +aesencwide256kl, 0xf3d8/2, WideKL|APX_F, Modrm|NoSuf|EVex128|EVexMap4, { Unspecified|BaseIndex } aesdecwide256kl, 0xf30f38d8/3, WideKL, Modrm|NoSuf, { Unspecified|BaseIndex } +aesdecwide256kl, 0xf3d8/3, WideKL|APX_F, Modrm|NoSuf|EVex128|EVexMap4, { Unspecified|BaseIndex } // KEYLOCKER instructions end. @@ -3308,6 +3362,7 @@ prefetchit1, 0xf18/6, PREFETCHI|x64, Modrm|Anysize|IgnoreSize|NoSuf, { BaseIndex // CMPCCXADD instructions. cmpxadd, 0x66e, CMPCCXADD|x64, Modrm|Vex|Space0F38|VexVVVV|SwapSources|CheckOperandSize|NoSuf, { Reg32|Reg64, Reg32|Reg64, Dword|Qword|Unspecified|BaseIndex } +cmpxadd, 0x66e, CMPCCXADD|x64|APX_F, Modrm|EVex128|Space0F38|VexVVVV|SwapSources|CheckOperandSize|NoSuf, { Reg32|Reg64, Reg32|Reg64, Dword|Qword|Unspecified|BaseIndex } // CMPCCXADD instructions end. @@ -3327,9 +3382,13 @@ wrmsrlist, 0xf30f01c6, MSRLIST|x64, NoSuf, {} // RAO-INT instructions. aadd, 0xf38fc, RAO_INT, Modrm|IgnoreSize|CheckOperandSize|NoSuf, { Reg32|Reg64, Dword|Qword|Unspecified|BaseIndex } +aadd, 0xfc, RAO_INT|APX_F, Modrm|IgnoreSize|CheckOperandSize|NoSuf|EVex128|EVexMap4, { Reg32|Reg64, Dword|Qword|Unspecified|BaseIndex } aand, 0x660f38fc, RAO_INT, Modrm|IgnoreSize|CheckOperandSize|NoSuf, { Reg32|Reg64, Dword|Qword|Unspecified|BaseIndex } +aand, 0x66fc, RAO_INT|APX_F, Modrm|IgnoreSize|CheckOperandSize|NoSuf|EVex128|EVexMap4, { Reg32|Reg64, Dword|Qword|Unspecified|BaseIndex } aor, 0xf20f38fc, RAO_INT, Modrm|IgnoreSize|CheckOperandSize|NoSuf, { Reg32|Reg64, Dword|Qword|Unspecified|BaseIndex } +aor, 0xf2fc, RAO_INT|APX_F, Modrm|IgnoreSize|CheckOperandSize|NoSuf|EVex128|EVexMap4, { Reg32|Reg64, Dword|Qword|Unspecified|BaseIndex } axor, 0xf30f38fc, RAO_INT, Modrm|IgnoreSize|CheckOperandSize|NoSuf, { Reg32|Reg64, Dword|Qword|Unspecified|BaseIndex } +axor, 0xf3fc, RAO_INT|APX_F, Modrm|IgnoreSize|CheckOperandSize|NoSuf|EVex128|EVexMap4, { Reg32|Reg64, Dword|Qword|Unspecified|BaseIndex } // RAO-INT instructions end. -- 2.25.1