@@ -2613,7 +2613,10 @@ match_simd_size (const i386_operand_type *t_types, unsigned int wanted,
|| (i.types[given].bitfield.zmmword
&& !t_types[wanted].bitfield.zmmword)
|| (i.types[given].bitfield.tmmword
- && !t_types[wanted].bitfield.tmmword));
+ && !t_types[wanted].bitfield.tmmword)
+ /* RegSIMD|Byte marks %bsr0; it is not the operand size. */
+ || (i.types[given].bitfield.byte
+ && !t_types[wanted].bitfield.byte));
}
/* Return 1 if there is no conflict in any size between operand GIVEN
@@ -3972,6 +3975,7 @@ const type_names[] =
{ { .bitfield = { .class = RegSIMD, .tmmword = 1 } }, "rTMM" },
{ { .bitfield = { .class = RegMask } }, "Mask reg" },
{ { .bitfield = { .class = RegBND } }, "rBND" },
+ { { .bitfield = { .class = RegSIMD, .byte = 1 } }, "bsr" },
};
static void
@@ -9911,7 +9915,8 @@ match_template (char mnem_suffix)
&& (intel_syntax || intel_mnemonic))
found_reverse_match |= Opcode_FloatR;
}
- else if (is_cpu (t, CpuFMA4) || is_cpu (t, CpuXOP))
+ else if (is_cpu (t, CpuFMA4) || is_cpu (t, CpuXOP)
+ || is_cpu (t, CpuACE_V1))
{
found_reverse_match = Opcode_VexW;
goto check_operands_345;
@@ -10237,7 +10242,8 @@ match_template (char mnem_suffix)
i.tm.opcode_modifier.vexw ^= VEXW0 ^ VEXW1;
/* In 3-operand insns XOP.W changes which operand goes into XOP.vvvv. */
- i.tm.opcode_modifier.vexvvvv = VexVVVV_SRC1;
+ if (!is_cpu (t, CpuACE_V1))
+ i.tm.opcode_modifier.vexvvvv = VexVVVV_SRC1;
swap_first_2:
j = i.tm_types[0].bitfield.imm8;
@@ -11113,11 +11119,11 @@ process_operands (void)
else if (i.tm.opcode_modifier.immext)
process_immext ();
- /* TILEZERO is unusual in that it has a single operand encoded in ModR/M.reg,
- not ModR/M.rm. To avoid special casing this in build_modrm_byte(), fake a
- new destination operand here, while converting the source one to register
- number 0. */
- if (i.tm.mnem_off == MN_tilezero)
+ /* TILEZERO and BSRINIT are unusual in that they have a single operand
+ encoded in ModR/M.reg, not ModR/M.rm. To avoid special casing this in
+ build_modrm_byte(), fake a new destination operand here, while converting
+ the source one to register number 0. */
+ if (i.tm.mnem_off == MN_tilezero || i.tm.mnem_off == MN_bsrinit)
{
copy_operand (1, 0);
i.op[0].regs -= i.op[0].regs->reg_num;
@@ -17091,6 +17097,12 @@ static bool check_register (const reg_entry *r)
if (r->reg_type.bitfield.class == RegBND && !cpu_arch_flags.bitfield.cpumpx)
return false;
+ if (r->reg_type.bitfield.class == RegSIMD
+ && r->reg_type.bitfield.byte
+ && (!cpu_arch_flags.bitfield.cpuace_v1
+ || flag_code != CODE_64BIT))
+ return false;
+
/* Don't allow fake index register unless allow_index_reg isn't 0. */
if (!allow_index_reg && r->reg_num == RegIZ)
return false;
@@ -20,7 +20,18 @@ Disassembly of section \.text:
[ ]*[a-f0-9]+:[ ]*62 63 7f 48 07 f5 08[ ]+tcvtrowps2bf16h \$0x8,%tmm5,%zmm30
[ ]*[a-f0-9]+:[ ]*62 62 6c 48 6d f5[ ]+tcvtrowps2phh %edx,%tmm5,%zmm30
[ ]*[a-f0-9]+:[ ]*62 63 7c 48 07 f5 08[ ]+tcvtrowps2phh \$0x8,%tmm5,%zmm30
+[ ]*[a-f0-9]+:[ ]*62 d6 ff 48 95 c2[ ]+bsrmovh %zmm10,%bsr0
+[ ]*[a-f0-9]+:[ ]*62 f6 ff 48 95 41 7f[ ]+bsrmovh 0x1fc0\(%rcx\),%bsr0
+[ ]*[a-f0-9]+:[ ]*62 f6 7f 48 95 c4[ ]+bsrmovh %bsr0,%zmm4
+[ ]*[a-f0-9]+:[ ]*62 f6 7f 48 95 41 80[ ]+bsrmovh %bsr0,-0x2000\(%rcx\)
[ ]*[a-f0-9]+:[ ]*62 62 6e 48 6d f5[ ]+tcvtrowps2bf16l %edx,%tmm5,%zmm30
[ ]*[a-f0-9]+:[ ]*62 63 7e 48 77 f5 08[ ]+tcvtrowps2bf16l \$0x8,%tmm5,%zmm30
[ ]*[a-f0-9]+:[ ]*62 62 6d 48 6d f5[ ]+tcvtrowps2phl %edx,%tmm5,%zmm30
[ ]*[a-f0-9]+:[ ]*62 63 7f 48 77 f5 08[ ]+tcvtrowps2phl \$0x8,%tmm5,%zmm30
+[ ]*[a-f0-9]+:[ ]*62 d6 fe 48 95 c2[ ]+bsrmovl %zmm10,%bsr0
+[ ]*[a-f0-9]+:[ ]*62 f6 fe 48 95 41 7f[ ]+bsrmovl 0x1fc0\(%rcx\),%bsr0
+[ ]*[a-f0-9]+:[ ]*62 f6 7e 48 95 c4[ ]+bsrmovl %bsr0,%zmm4
+[ ]*[a-f0-9]+:[ ]*62 f6 7e 48 95 41 80[ ]+bsrmovl %bsr0,-0x2000\(%rcx\)
+[ ]*[a-f0-9]+:[ ]*c4 e2 fb 49 c0[ ]+bsrinit %bsr0
+[ ]*[a-f0-9]+:[ ]*62 f6 f4 48 95 c3[ ]+bsrmovf %zmm3,%zmm1,%bsr0
+[ ]*[a-f0-9]+:[ ]*62 f6 f4 48 95 41 7f[ ]+bsrmovf 0x1fc0\(%rcx\),%zmm1,%bsr0
@@ -19,4 +19,14 @@ start:
tcvtrowps2ph\p %edx, %tmm5, %zmm30
tcvtrowps2ph\p $8, %tmm5, %zmm30
+
+ bsrmov\p %zmm10, %bsr0
+ bsrmov\p 8128(%rcx), %bsr0
+
+ bsrmov\p %bsr0, %zmm4
+ bsrmov\p %bsr0, -8192(%rcx)
.endr
+
+ bsrinit %bsr0
+ bsrmovf %zmm3, %zmm1, %bsr0
+ bsrmovf 8128(%rcx), %zmm1, %bsr0
@@ -212,4 +212,16 @@ static const struct dis386 evex_len_table[][3] = {
{ "vbmacxor16x16x16", { XM, Vex, EXx }, NO_PREFIX },
{ "vbmacxor16x16x16", { XM, Vex, EXx }, NO_PREFIX },
},
+ /* EVEX_LEN_MAP6_95_X86_64_W_0 */
+ {
+ { Bad_Opcode },
+ { Bad_Opcode },
+ { PREFIX_TABLE (PREFIX_EVEX_MAP6_95_X86_64_W_0_L_2) },
+ },
+ /* EVEX_LEN_MAP6_95_X86_64_W_1 */
+ {
+ { Bad_Opcode },
+ { Bad_Opcode },
+ { PREFIX_TABLE (PREFIX_EVEX_MAP6_95_X86_64_W_1_L_2) },
+ },
};
@@ -833,6 +833,20 @@
{ Bad_Opcode },
{ "vfnmsub231p%XH", { XM, Vex, EXxh, EXxEVexR }, 0 },
},
+ /* PREFIX_EVEX_MAP6_95_X86_64_W_0_L_2 */
+ {
+ { Bad_Opcode },
+ { "bsrmovl", { EXEvexXNoBcst, BSR }, 0 },
+ { Bad_Opcode },
+ { "bsrmovh", { EXEvexXNoBcst, BSR }, 0 },
+ },
+ /* PREFIX_EVEX_MAP6_95_X86_64_W_1_L_2 */
+ {
+ { "bsrmovf", { BSR, Vex, EXEvexXNoBcst }, 0 },
+ { "bsrmovl", { BSR, EXEvexXNoBcst }, 0 },
+ { Bad_Opcode },
+ { "bsrmovh", { BSR, EXEvexXNoBcst }, 0 },
+ },
/* PREFIX_EVEX_MAP6_D6 */
{
{ Bad_Opcode },
@@ -570,4 +570,9 @@
{
{ "vbitrevb", { XM, EXx }, NO_PREFIX },
{ Bad_Opcode }
- }
+ },
+ /* EVEX_W_MAP6_95_X86_64 */
+ {
+ { EVEX_LEN_TABLE (EVEX_LEN_MAP6_95_X86_64_W_0) },
+ { EVEX_LEN_TABLE (EVEX_LEN_MAP6_95_X86_64_W_1) },
+ },
@@ -28,3 +28,8 @@
{ Bad_Opcode },
{ PREFIX_TABLE (PREFIX_EVEX_MAP5_6F_X86_64) },
},
+ /* X86_64_EVEX_MAP6_95 */
+ {
+ { Bad_Opcode },
+ { VEX_W_TABLE (EVEX_W_MAP6_95_X86_64) },
+ },
@@ -1624,7 +1624,7 @@ static const struct dis386 evex_table[][256] = {
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
- { Bad_Opcode },
+ { X86_64_TABLE (X86_64_EVEX_MAP6_95) },
{ "vfmaddsub132p%XH", { XM, Vex, EXxh, EXxEVexR }, PREFIX_DATA },
{ "vfmsubadd132p%XH", { XM, Vex, EXxh, EXxEVexR }, PREFIX_DATA },
/* 98 */
@@ -513,6 +513,7 @@ fetch_error (const instr_info *ins)
#define RMBH { OP_REG, bh_reg }
#define RMAX { OP_REG, ax_reg }
#define RMDX { OP_REG, dx_reg }
+#define BSR { OP_G, bsr_mode }
#define eAX { OP_IMREG, eAX_reg }
#define AL { OP_IMREG, al_reg }
@@ -722,6 +723,8 @@ enum
ymmq_mode,
/* TMM operand */
tmm_mode,
+ /* Block scale register operand. */
+ bsr_mode,
/* d_mode in 32bit, q_mode in 64bit mode. */
m_mode,
/* pair of v_mode operands */
@@ -971,6 +974,7 @@ enum
MOD_0F38F8,
MOD_VEX_0F3849_X86_64_L_0_W_0,
+ MOD_VEX_0F3849_X86_64_L_0_W_1,
MOD_EVEX_MAP4_60,
MOD_EVEX_MAP4_61,
@@ -995,6 +999,7 @@ enum
RM_VEX_0F3849_X86_64_L_0_W_0_M_1_P_0_R_0,
RM_VEX_0F3849_X86_64_L_0_W_0_M_1_P_3,
+ RM_VEX_0F3849_X86_64_L_0_W_1_M_1_P_3,
};
enum
@@ -1141,6 +1146,7 @@ enum
PREFIX_VEX_0F3848_X86_64_L_0_W_0,
PREFIX_VEX_0F3849_X86_64_L_0_W_0_M_0,
PREFIX_VEX_0F3849_X86_64_L_0_W_0_M_1,
+ PREFIX_VEX_0F3849_X86_64_L_0_W_1_M_1,
PREFIX_VEX_0F384A_X86_64_W_0_L_0,
PREFIX_VEX_0F384B_X86_64_L_0_W_0,
PREFIX_VEX_0F3850_W_0,
@@ -1311,6 +1317,8 @@ enum
PREFIX_EVEX_MAP6_BA,
PREFIX_EVEX_MAP6_BC,
PREFIX_EVEX_MAP6_BE,
+ PREFIX_EVEX_MAP6_95_X86_64_W_0_L_2,
+ PREFIX_EVEX_MAP6_95_X86_64_W_1_L_2,
PREFIX_EVEX_MAP6_D6,
PREFIX_EVEX_MAP6_D7,
};
@@ -1410,6 +1418,7 @@ enum
X86_64_EVEX_0F3A77,
X86_64_EVEX_MAP5_6F,
+ X86_64_EVEX_MAP6_95,
};
enum
@@ -1630,6 +1639,8 @@ enum
EVEX_LEN_MAP5_7E,
EVEX_LEN_MAP6_80_W_0,
EVEX_LEN_MAP6_80_W_1,
+ EVEX_LEN_MAP6_95_X86_64_W_0,
+ EVEX_LEN_MAP6_95_X86_64_W_1,
};
enum
@@ -1894,6 +1905,7 @@ enum
EVEX_W_MAP5_7E_P_1,
EVEX_W_MAP6_80,
EVEX_W_MAP6_81,
+ EVEX_W_MAP6_95_X86_64,
};
typedef bool (*op_rtn) (instr_info *ins, int bytemode, int sizeflag);
@@ -2720,6 +2732,10 @@ static const char att_names_tmm[][8] = {
"%tmm4", "%tmm5", "%tmm6", "%tmm7"
};
+static const char att_names_bsr[][8] = {
+ "%bsr0"
+};
+
static const char att_names_mask[][8] = {
"%k0", "%k1", "%k2", "%k3", "%k4", "%k5", "%k6", "%k7"
};
@@ -4187,6 +4203,14 @@ static const struct dis386 prefix_table[][4] = {
{ RM_TABLE (RM_VEX_0F3849_X86_64_L_0_W_0_M_1_P_3) },
},
+ /* PREFIX_VEX_0F3849_X86_64_L_0_W_1_M_1 */
+ {
+ { Bad_Opcode },
+ { Bad_Opcode },
+ { Bad_Opcode },
+ { RM_TABLE (RM_VEX_0F3849_X86_64_L_0_W_1_M_1_P_3) },
+ },
+
/* PREFIX_VEX_0F384A_X86_64_W_0_L_0 */
{
{ Bad_Opcode },
@@ -8138,6 +8162,7 @@ static const struct dis386 vex_w_table[][2] = {
{
/* VEX_W_0F3849_X86_64_L_0 */
{ MOD_TABLE (MOD_VEX_0F3849_X86_64_L_0_W_0) },
+ { MOD_TABLE (MOD_VEX_0F3849_X86_64_L_0_W_1) },
},
{
/* VEX_W_0F384A_X86_64 */
@@ -8714,6 +8739,11 @@ static const struct dis386 mod_table[][2] = {
{ PREFIX_TABLE (PREFIX_VEX_0F3849_X86_64_L_0_W_0_M_0) },
{ PREFIX_TABLE (PREFIX_VEX_0F3849_X86_64_L_0_W_0_M_1) },
},
+ {
+ /* MOD_VEX_0F3849_X86_64_L_0_W_1 */
+ { Bad_Opcode },
+ { PREFIX_TABLE (PREFIX_VEX_0F3849_X86_64_L_0_W_1_M_1) },
+ },
#include "i386-dis-evex-mod.h"
};
@@ -8824,6 +8854,10 @@ static const struct dis386 rm_table[][8] = {
/* RM_VEX_0F3849_X86_64_L_0_W_0_M_1_P_3 */
{ "tilezero", { TMM, Skip_MODRM }, 0 },
},
+ {
+ /* RM_VEX_0F3849_X86_64_L_0_W_1_M_1_P_3 */
+ { "bsrinit", { BSR, Skip_MODRM }, 0 },
+ },
};
#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
@@ -12123,6 +12157,14 @@ print_register (instr_info *ins, unsigned int reg, unsigned int rexmask,
}
names = att_names_bnd;
break;
+ case bsr_mode:
+ if (reg)
+ {
+ oappend (ins, "(bad)");
+ return;
+ }
+ names = att_names_bsr;
+ break;
case indir_v_mode:
if (ins->address_mode == mode_64bit && ins->isa64 == intel64)
{
@@ -62,6 +62,8 @@
#define RegBND Class=RegBND
+#define RegBSR Class=RegSIMD|Byte
+
#define Mmword Qword
#define Oword Xmmword
@@ -3316,6 +3318,15 @@ tdphf8ps, 0x66fd, AMX_FP8, Modrm|Vex128|Map5|Src2VVVV|VexW0|NoSuf, { RegTMM, Reg
// AMX instructions end.
+// ACE instructions.
+
+bsrinit, 0xf249, ACE_V1, Modrm|Vex128|Space0F38|VexW1|NoSuf, { RegBSR }
+bsrmovf, 0x95, ACE_V1, Modrm|EVex512|Map6|VexW1|Src1VVVV|Disp8MemShift=6|NoSuf, { RegZMM|Unspecified|BaseIndex, RegZMM, RegBSR }
+bsrmovh, 0xf295, ACE_V1, D|Modrm|EVex512|Map6|VexW1|Disp8MemShift=6|NoSuf, { RegZMM|Unspecified|BaseIndex, RegBSR }
+bsrmovl, 0xf395, ACE_V1, D|Modrm|EVex512|Map6|VexW1|Disp8MemShift=6|NoSuf, { RegZMM|Unspecified|BaseIndex, RegBSR }
+
+// ACE instructions end.
+
// KEYLOCKER instructions.
loadiwkey, 0xf30f38dc, KL, Load|Modrm|NoSuf, { RegXMM, RegXMM }
@@ -353,6 +353,8 @@ tmm4, Class=RegSIMD|Tmmword, 0, 4, Dw2Inval, Dw2Inval
tmm5, Class=RegSIMD|Tmmword, 0, 5, Dw2Inval, Dw2Inval
tmm6, Class=RegSIMD|Tmmword, 0, 6, Dw2Inval, Dw2Inval
tmm7, Class=RegSIMD|Tmmword, 0, 7, Dw2Inval, Dw2Inval
+// Block scale register for ACE
+bsr0, Class=RegSIMD|Byte, 0, 0, Dw2Inval, Dw2Inval
// Bound registers for MPX
bnd0, Class=RegBND, 0, 0, Dw2Inval, 126
bnd1, Class=RegBND, 0, 1, Dw2Inval, 127