aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorCui, Lili <lili.cui@intel.com>2023-12-28 01:06:39 +0000
committerCui, Lili <lili.cui@intel.com>2023-12-28 11:14:41 +0000
commit80d61d8d614d68a0b1932ed3a86d4cda01e5633e (patch)
treed96a3481c4563e2fd0fee9ae049626ee9dea6053 /gas
parentfcd5cdd5aeecf7eae91a402755c260bb64a0fe0f (diff)
downloadbinutils-80d61d8d614d68a0b1932ed3a86d4cda01e5633e.zip
binutils-80d61d8d614d68a0b1932ed3a86d4cda01e5633e.tar.gz
binutils-80d61d8d614d68a0b1932ed3a86d4cda01e5633e.tar.bz2
Support APX GPR32 with rex2 prefix
APX uses the REX2 prefix to support EGPR for map0 and map1 of legacy instructions. We added the NoEgpr flag in i386-gen.c for instructions that do not support EGPR. gas/ChangeLog: 2023-12-28 Lingling Kong <lingling.kong@intel.com> H.J. Lu <hongjiu.lu@intel.com> Lili Cui <lili.cui@intel.com> Lin Hu <lin1.hu@intel.com> * config/tc-i386.c (enum i386_error): Add unsupported_EGPR_for_addressing and invalid_pseudo_prefix. (struct _i386_insn): Add rex2 and rex2_encoding for gpr32. (cpu_arch): Add apx_f. (is_cpu): Ditto. (register_number): Handle RegRex2 for gpr32. (is_apx_rex2_encoding): New func. Test rex2 prefix encoding. (build_rex2_prefix): New func. Build legacy insn in opcode 0/1 use gpr32 with rex2 prefix. (establish_rex): Handle rex2 and rex2_encoding. (optimize_encoding): Handel add r16-r31 for registers. (md_assemble): Handle apx encoding. (parse_insn): Handle Prefix_REX2. (check_EgprOperands): New func. Check if Egprs operands are valid for the instruction (match_template): Handle Egpr operands check. (set_rex_rex2): New func. set i.rex and i.rex2. (build_modrm_byte): Ditto. (output_insn): Handle rex2 2-byte prefix output. (check_register): Handle check egpr illegal without target apx, 64-bit mode and with rex_prefix. * doc/c-i386.texi: Document .apx. * testsuite/gas/i386/ilp32/x86-64-opcode-inval-intel.d: D5 valid in 64-bit mode. * testsuite/gas/i386/ilp32/x86-64-opcode-inval.d: Ditto. * testsuite/gas/i386/rex-bad: Adjust rex testcase. * testsuite/gas/i386/x86-64-opcode-inval-intel.d: Ditto. * testsuite/gas/i386/x86-64-opcode-inval.d: Ditto. * testsuite/gas/i386/x86-64-opcode-inval.s: Ditto. * testsuite/gas/i386/x86-64-pseudos-bad.l: Add illegal rex2 test. * testsuite/gas/i386/x86-64-pseudos-bad.s: Ditto. * testsuite/gas/i386/x86-64-pseudos.d: Add rex2 test. * testsuite/gas/i386/x86-64-pseudos.s: Ditto. * testsuite/gas/i386/x86-64.exp: Run APX tests. * testsuite/gas/i386/x86-64-apx-egpr-inval.l: New test. * testsuite/gas/i386/x86-64-apx-egpr-inval.s: New test. * testsuite/gas/i386/x86-64-apx-rex2.d: New test. * testsuite/gas/i386/x86-64-apx-rex2.s: New test. include/ChangeLog: * opcode/i386.h (REX2_OPCODE): New. (REX2_M): Ditto. opcodes/ChangeLog: * i386-dis.c (struct instr_info): Add erex for gpr32. Add last_erex_prefix for rex2 prefix. (REX2_M): Extend for gpr32. (PREFIX_REX2): Ditto. (PREFIX_REX2_ILLEGAL): Ditto. (ckprefix): Ditto. (prefix_name): Ditto. (print_insn): Ditto. (print_register): Ditto. (OP_E_memory): Ditto. (OP_REG): Ditto. (OP_EX): Ditto. * i386-gen.c (rex2_disallowed): Some instructions are not allowed rex2 prefix. (process_i386_opcode_modifier): Set NoEgpr for VEX and some special instructions. (output_i386_opcode): Handle if_entry_needs_special_handle. * i386-init.h : Regenerated. * i386-mnem.h : Regenerated. * i386-opc.h (enum i386_cpu): Add CpuAPX_F. (NoEgpr): New. (Prefix_NoOptimize): Ditto. (Prefix_REX2): Ditto. (RegRex2): Ditto. * i386-opc.tbl: Add rex2 prefix. * i386-reg.tbl: Add egprs (r16-r31). * i386-tbl.h: Regenerated.
Diffstat (limited to 'gas')
-rw-r--r--gas/config/tc-i386.c178
-rw-r--r--gas/doc/c-i386.texi7
-rw-r--r--gas/testsuite/gas/i386/ilp32/x86-64-opcode-inval-intel.d47
-rw-r--r--gas/testsuite/gas/i386/ilp32/x86-64-opcode-inval.d47
-rw-r--r--gas/testsuite/gas/i386/rex-bad.l8
-rw-r--r--gas/testsuite/gas/i386/x86-64-apx-egpr-inval.l15
-rw-r--r--gas/testsuite/gas/i386/x86-64-apx-egpr-inval.s18
-rw-r--r--gas/testsuite/gas/i386/x86-64-apx-rex2.d83
-rw-r--r--gas/testsuite/gas/i386/x86-64-apx-rex2.s85
-rw-r--r--gas/testsuite/gas/i386/x86-64-opcode-inval-intel.d26
-rw-r--r--gas/testsuite/gas/i386/x86-64-opcode-inval.d26
-rw-r--r--gas/testsuite/gas/i386/x86-64-opcode-inval.s4
-rw-r--r--gas/testsuite/gas/i386/x86-64-pseudos-bad.l75
-rw-r--r--gas/testsuite/gas/i386/x86-64-pseudos-bad.s74
-rw-r--r--gas/testsuite/gas/i386/x86-64-pseudos.d21
-rw-r--r--gas/testsuite/gas/i386/x86-64-pseudos.s21
-rw-r--r--gas/testsuite/gas/i386/x86-64.exp2
17 files changed, 577 insertions, 160 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index cdd3b55..11b3927 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -239,6 +239,7 @@ enum i386_error
bad_imm4,
unsupported_with_intel_mnemonic,
unsupported_syntax,
+ unsupported_EGPR_for_addressing,
unsupported,
unsupported_on_arch,
unsupported_64bit,
@@ -249,6 +250,7 @@ enum i386_error
invalid_vector_register_set,
invalid_tmm_register_set,
invalid_dest_and_src_register_set,
+ invalid_pseudo_prefix,
unsupported_vector_index_register,
unsupported_broadcast,
broadcast_needed,
@@ -356,6 +358,7 @@ struct _i386_insn
modrm_byte rm;
rex_byte rex;
rex_byte vrex;
+ rex_byte rex2;
sib_byte sib;
vex_prefix vex;
@@ -429,6 +432,9 @@ struct _i386_insn
/* Prefer the REX byte in encoding. */
bool rex_encoding;
+ /* Prefer the REX2 prefix in encoding. */
+ bool rex2_encoding;
+
/* Disable instruction size optimization. */
bool no_optimize;
@@ -1149,6 +1155,7 @@ static const arch_entry cpu_arch[] =
SUBARCH (pbndkb, PBNDKB, PBNDKB, false),
VECARCH (avx10.1, AVX10_1, ANY_AVX512F, set),
SUBARCH (user_msr, USER_MSR, USER_MSR, false),
+ SUBARCH (apx_f, APX_F, APX_F, false),
};
#undef SUBARCH
@@ -1664,6 +1671,7 @@ _is_cpu (const i386_cpu_attr *a, enum i386_cpu cpu)
case CpuHLE: return a->bitfield.cpuhle;
case CpuAVX512F: return a->bitfield.cpuavx512f;
case CpuAVX512VL: return a->bitfield.cpuavx512vl;
+ case CpuAPX_F: return a->bitfield.cpuapx_f;
case Cpu64: return a->bitfield.cpu64;
case CpuNo64: return a->bitfield.cpuno64;
default:
@@ -2335,7 +2343,7 @@ register_number (const reg_entry *r)
if (r->reg_flags & RegRex)
nr += 8;
- if (r->reg_flags & RegVRex)
+ if (r->reg_flags & (RegVRex | RegRex2))
nr += 16;
return nr;
@@ -3871,6 +3879,12 @@ is_any_vex_encoding (const insn_template *t)
return t->opcode_modifier.vex || t->opcode_modifier.evex;
}
+static INLINE bool
+is_apx_rex2_encoding (void)
+{
+ return i.rex2 || i.rex2_encoding;
+}
+
static unsigned int
get_broadcast_bytes (const insn_template *t, bool diag)
{
@@ -4126,6 +4140,22 @@ build_evex_prefix (void)
i.vex.bytes[3] |= i.mask.reg->reg_num;
}
+/* Build (2 bytes) rex2 prefix.
+ | D5h |
+ | m | R4 X4 B4 | W R X B |
+
+ Rex2 reuses i.vex as they both encode i.tm.opcode_space in their prefixes.
+ */
+static void
+build_rex2_prefix (void)
+{
+ i.vex.length = 2;
+ i.vex.bytes[0] = 0xd5;
+ /* For the W R X B bits, the variables of rex prefix will be reused. */
+ i.vex.bytes[1] = ((i.tm.opcode_space << 7)
+ | (i.rex2 << 4) | i.rex);
+}
+
static void establish_rex (void)
{
/* Note that legacy encodings have at most 2 non-immediate operands. */
@@ -4140,13 +4170,16 @@ static void establish_rex (void)
registers to new ones. */
if ((i.types[first].bitfield.class == Reg && i.types[first].bitfield.byte
- && ((i.op[first].regs->reg_flags & RegRex64) != 0 || i.rex != 0))
+ && ((i.op[first].regs->reg_flags & RegRex64) != 0 || i.rex != 0
+ || i.rex2 != 0))
|| (i.types[last].bitfield.class == Reg && i.types[last].bitfield.byte
- && ((i.op[last].regs->reg_flags & RegRex64) != 0 || i.rex != 0)))
+ && ((i.op[last].regs->reg_flags & RegRex64) != 0 || i.rex != 0
+ || i.rex2 != 0)))
{
unsigned int x;
- i.rex |= REX_OPCODE;
+ if (!is_apx_rex2_encoding () && !is_any_vex_encoding(&i.tm))
+ i.rex |= REX_OPCODE;
for (x = first; x <= last; x++)
{
/* Look for 8 bit operand that uses old registers. */
@@ -4157,7 +4190,7 @@ static void establish_rex (void)
/* In case it is "hi" register, give up. */
if (i.op[x].regs->reg_num > 3)
as_bad (_("can't encode register '%s%s' in an "
- "instruction requiring REX prefix"),
+ "instruction requiring REX/REX2 prefix"),
register_prefix, i.op[x].regs->reg_name);
/* Otherwise it is equivalent to the extended register.
@@ -4168,11 +4201,11 @@ static void establish_rex (void)
}
}
- if (i.rex == 0 && i.rex_encoding)
+ if (i.rex == 0 && i.rex2 == 0 && (i.rex_encoding || i.rex2_encoding))
{
/* Check if we can add a REX_OPCODE byte. Look for 8 bit operand
that uses legacy register. If it is "hi" register, don't add
- the REX_OPCODE byte. */
+ rex and rex2 prefix. */
unsigned int x;
for (x = first; x <= last; x++)
@@ -4183,6 +4216,7 @@ static void establish_rex (void)
{
gas_assert (!(i.op[x].regs->reg_flags & RegRex));
i.rex_encoding = false;
+ i.rex2_encoding = false;
break;
}
@@ -4190,8 +4224,14 @@ static void establish_rex (void)
i.rex = REX_OPCODE;
}
- if (i.rex != 0)
- add_prefix (REX_OPCODE | i.rex);
+ if (is_apx_rex2_encoding ())
+ {
+ build_rex2_prefix ();
+ /* The individual REX.RXBW bits got consumed. */
+ i.rex &= REX_OPCODE;
+ }
+ else if (i.rex != 0)
+ add_prefix (REX_OPCODE | i.rex);
}
static void
@@ -4457,14 +4497,22 @@ optimize_encoding (void)
i.types[1].bitfield.byte = 1;
/* Ignore the suffix. */
i.suffix = 0;
- /* Convert to byte registers. */
+ /* Convert to byte registers. 8-bit registers are special,
+ RegRex64 and non-RegRex64 each have 8 registers. */
if (i.types[1].bitfield.word)
- j = 16;
- else if (i.types[1].bitfield.dword)
+ /* 32 (or 40) 8-bit registers. */
j = 32;
+ else if (i.types[1].bitfield.dword)
+ /* 32 (or 40) 8-bit registers + 32 16-bit registers. */
+ j = 64;
else
- j = 48;
- if (!(i.op[1].regs->reg_flags & RegRex) && base_regnum < 4)
+ /* 32 (or 40) 8-bit registers + 32 16-bit registers
+ + 32 32-bit registers. */
+ j = 96;
+
+ /* In 64-bit mode, the following byte registers cannot be accessed
+ if using the Rex and Rex2 prefix: AH, BH, CH, DH */
+ if (!(i.op[1].regs->reg_flags & (RegRex | RegRex2)) && base_regnum < 4)
j += 8;
i.op[1].regs -= j;
}
@@ -5354,6 +5402,9 @@ md_assemble (char *line)
case unsupported_syntax:
err_msg = _("unsupported syntax");
break;
+ case unsupported_EGPR_for_addressing:
+ err_msg = _("extended GPR cannot be used as base/index");
+ break;
case unsupported:
as_bad (_("unsupported instruction `%s'"),
pass1_mnem ? pass1_mnem : insn_name (current_templates.start));
@@ -5407,6 +5458,9 @@ md_assemble (char *line)
case invalid_dest_and_src_register_set:
err_msg = _("destination and source registers must be distinct");
break;
+ case invalid_pseudo_prefix:
+ err_msg = _("rex2 pseudo prefix cannot be used");
+ break;
case unsupported_vector_index_register:
err_msg = _("unsupported vector index register");
break;
@@ -5662,6 +5716,13 @@ md_assemble (char *line)
return;
}
+ /* Check for explicit REX2 prefix. */
+ if (i.rex2_encoding)
+ {
+ as_bad (_("{rex2} prefix invalid with `%s'"), insn_name (&i.tm));
+ return;
+ }
+
if (i.tm.opcode_modifier.vex)
build_vex_prefix (t);
else
@@ -5868,6 +5929,10 @@ parse_insn (const char *line, char *mnemonic, bool prefix_only)
/* {rex} */
i.rex_encoding = true;
break;
+ case Prefix_REX2:
+ /* {rex2} */
+ i.rex2_encoding = true;
+ break;
case Prefix_NoOptimize:
/* {nooptimize} */
i.no_optimize = true;
@@ -7015,6 +7080,43 @@ VEX_check_encoding (const insn_template *t)
return 0;
}
+/* Check if Egprs operands are valid for the instruction. */
+
+static bool
+check_EgprOperands (const insn_template *t)
+{
+ if (!t->opcode_modifier.noegpr)
+ return 0;
+
+ for (unsigned int op = 0; op < i.operands; op++)
+ {
+ if (i.types[op].bitfield.class != Reg)
+ continue;
+
+ if (i.op[op].regs->reg_flags & RegRex2)
+ {
+ i.error = register_type_mismatch;
+ return 1;
+ }
+ }
+
+ if ((i.index_reg && (i.index_reg->reg_flags & RegRex2))
+ || (i.base_reg && (i.base_reg->reg_flags & RegRex2)))
+ {
+ i.error = unsupported_EGPR_for_addressing;
+ return 1;
+ }
+
+ /* Check if pseudo prefix {rex2} is valid. */
+ if (i.rex2_encoding)
+ {
+ i.error = invalid_pseudo_prefix;
+ return 1;
+ }
+
+ return 0;
+}
+
/* Helper function for the progress() macro in match_template(). */
static INLINE enum i386_error progress (enum i386_error new,
enum i386_error last,
@@ -7159,6 +7261,13 @@ match_template (char mnem_suffix)
continue;
}
+ /* Check if pseudo prefix {rex2} is valid. */
+ if (t->opcode_modifier.noegpr && i.rex2_encoding)
+ {
+ specific_error = progress (invalid_pseudo_prefix);
+ continue;
+ }
+
/* We've found a match; break out of loop. */
break;
}
@@ -7482,6 +7591,13 @@ match_template (char mnem_suffix)
continue;
}
+ /* Check if EGPR operands(r16-r31) are valid. */
+ if (check_EgprOperands (t))
+ {
+ specific_error = progress (i.error);
+ continue;
+ }
+
/* Check if vector operands are valid. */
if (check_VecOperands (t))
{
@@ -8387,6 +8503,18 @@ static INLINE void set_rex_vrex (const reg_entry *r, unsigned int rex_bit,
if (r->reg_flags & RegVRex)
i.vrex |= rex_bit;
+
+ if (r->reg_flags & RegRex2)
+ i.rex2 |= rex_bit;
+}
+
+static INLINE void
+set_rex_rex2 (const reg_entry *r, unsigned int rex_bit)
+{
+ if ((r->reg_flags & RegRex) != 0)
+ i.rex |= rex_bit;
+ if ((r->reg_flags & RegRex2) != 0)
+ i.rex2 |= rex_bit;
}
static int
@@ -8870,8 +8998,7 @@ build_modrm_byte (void)
i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
i.types[op] = operand_type_and_not (i.types[op], anydisp);
i.types[op].bitfield.disp32 = 1;
- if ((i.index_reg->reg_flags & RegRex) != 0)
- i.rex |= REX_X;
+ set_rex_rex2 (i.index_reg, REX_X);
}
}
/* RIP addressing for 64bit mode. */
@@ -8942,8 +9069,7 @@ build_modrm_byte (void)
if (!i.tm.opcode_modifier.sib)
i.rm.regmem = i.base_reg->reg_num;
- if ((i.base_reg->reg_flags & RegRex) != 0)
- i.rex |= REX_B;
+ set_rex_rex2 (i.base_reg, REX_B);
i.sib.base = i.base_reg->reg_num;
/* x86-64 ignores REX prefix bit here to avoid decoder
complications. */
@@ -8981,8 +9107,7 @@ build_modrm_byte (void)
else
i.sib.index = i.index_reg->reg_num;
i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
- if ((i.index_reg->reg_flags & RegRex) != 0)
- i.rex |= REX_X;
+ set_rex_rex2 (i.index_reg, REX_X);
}
if (i.disp_operands
@@ -10126,6 +10251,12 @@ output_insn (const struct last_insn *last_insn)
for (j = ARRAY_SIZE (i.prefix), q = i.prefix; j > 0; j--, q++)
if (*q)
frag_opcode_byte (*q);
+
+ if (is_apx_rex2_encoding ())
+ {
+ frag_opcode_byte (i.vex.bytes[0]);
+ frag_opcode_byte (i.vex.bytes[1]);
+ }
}
else
{
@@ -14164,6 +14295,13 @@ static bool check_register (const reg_entry *r)
i.vec_encoding = vex_encoding_error;
}
+ if (r->reg_flags & RegRex2)
+ {
+ if (!cpu_arch_flags.bitfield.cpuapx_f
+ || flag_code != CODE_64BIT)
+ return false;
+ }
+
if (((r->reg_flags & (RegRex64 | RegRex)) || r->reg_type.bitfield.qword)
&& (!cpu_arch_flags.bitfield.cpu64
|| r->reg_type.bitfield.class != RegCR
diff --git a/gas/doc/c-i386.texi b/gas/doc/c-i386.texi
index 03ee980..21f48c9 100644
--- a/gas/doc/c-i386.texi
+++ b/gas/doc/c-i386.texi
@@ -217,6 +217,7 @@ accept various extension mnemonics. For example,
@code{avx10.1/256},
@code{avx10.1/128},
@code{user_msr},
+@code{apx_f},
@code{amx_int8},
@code{amx_bf16},
@code{amx_fp16},
@@ -984,6 +985,10 @@ instructions (x86-64 only). Note that this differs from the @samp{rex}
prefix which generates REX prefix unconditionally.
@item
+@samp{@{rex2@}} -- prefer REX2 prefix for integer and legacy vector
+instructions (APX_F only).
+
+@item
@samp{@{nooptimize@}} -- disable instruction size optimization.
@end itemize
@@ -1663,7 +1668,7 @@ supported on the CPU specified. The choices for @var{cpu_type} are:
@item @samp{.lwp} @tab @samp{.fma4} @tab @samp{.xop} @tab @samp{.cx16}
@item @samp{.padlock} @tab @samp{.clzero} @tab @samp{.mwaitx} @tab @samp{.rdpru}
@item @samp{.mcommit} @tab @samp{.sev_es} @tab @samp{.snp} @tab @samp{.invlpgb}
-@item @samp{.tlbsync}
+@item @samp{.tlbsync} @tab @samp{.apx_f}
@end multitable
Apart from the warning, there are only two other effects on
diff --git a/gas/testsuite/gas/i386/ilp32/x86-64-opcode-inval-intel.d b/gas/testsuite/gas/i386/ilp32/x86-64-opcode-inval-intel.d
index a2b09d2..5683437 100644
--- a/gas/testsuite/gas/i386/ilp32/x86-64-opcode-inval-intel.d
+++ b/gas/testsuite/gas/i386/ilp32/x86-64-opcode-inval-intel.d
@@ -2,49 +2,4 @@
#as: --32
#objdump: -dw -Mx86-64 -Mintel
#name: x86-64 (ILP32) illegal opcodes (Intel mode)
-
-.*: +file format .*
-
-Disassembly of section .text:
-
-0+ <aaa>:
-[ ]*[a-f0-9]+: 37 \(bad\)
-
-0+1 <aad0>:
-[ ]*[a-f0-9]+: d5 \(bad\)
-[ ]*[a-f0-9]+: 0a .byte 0xa
-
-0+3 <aad1>:
-[ ]*[a-f0-9]+: d5 \(bad\)
-[ ]*[a-f0-9]+: 02 .byte 0x2
-
-0+5 <aam0>:
-[ ]*[a-f0-9]+: d4 \(bad\)
-[ ]*[a-f0-9]+: 0a .byte 0xa
-
-0+7 <aam1>:
-[ ]*[a-f0-9]+: d4 \(bad\)
-[ ]*[a-f0-9]+: 02 .byte 0x2
-
-0+9 <aas>:
-[ ]*[a-f0-9]+: 3f \(bad\)
-
-0+a <bound>:
-[ ]*[a-f0-9]+: 62 .byte 0x62
-[ ]*[a-f0-9]+: 10 .byte 0x10
-
-0+c <daa>:
-[ ]*[a-f0-9]+: 27 \(bad\)
-
-0+d <das>:
-[ ]*[a-f0-9]+: 2f \(bad\)
-
-0+e <into>:
-[ ]*[a-f0-9]+: ce \(bad\)
-
-0+f <pusha>:
-[ ]*[a-f0-9]+: 60 \(bad\)
-
-0+10 <popa>:
-[ ]*[a-f0-9]+: 61 \(bad\)
-#pass
+#dump: ../x86-64-opcode-inval-intel.d
diff --git a/gas/testsuite/gas/i386/ilp32/x86-64-opcode-inval.d b/gas/testsuite/gas/i386/ilp32/x86-64-opcode-inval.d
index 5a17b0b..b5233a5 100644
--- a/gas/testsuite/gas/i386/ilp32/x86-64-opcode-inval.d
+++ b/gas/testsuite/gas/i386/ilp32/x86-64-opcode-inval.d
@@ -2,49 +2,4 @@
#as: --32
#objdump: -dw -Mx86-64
#name: x86-64 (ILP32) illegal opcodes
-
-.*: +file format .*
-
-Disassembly of section .text:
-
-0+ <aaa>:
-[ ]*[a-f0-9]+: 37 \(bad\)
-
-0+1 <aad0>:
-[ ]*[a-f0-9]+: d5 \(bad\)
-[ ]*[a-f0-9]+: 0a .byte 0xa
-
-0+3 <aad1>:
-[ ]*[a-f0-9]+: d5 \(bad\)
-[ ]*[a-f0-9]+: 02 .byte 0x2
-
-0+5 <aam0>:
-[ ]*[a-f0-9]+: d4 \(bad\)
-[ ]*[a-f0-9]+: 0a .byte 0xa
-
-0+7 <aam1>:
-[ ]*[a-f0-9]+: d4 \(bad\)
-[ ]*[a-f0-9]+: 02 .byte 0x2
-
-0+9 <aas>:
-[ ]*[a-f0-9]+: 3f \(bad\)
-
-0+a <bound>:
-[ ]*[a-f0-9]+: 62 .byte 0x62
-[ ]*[a-f0-9]+: 10 .byte 0x10
-
-0+c <daa>:
-[ ]*[a-f0-9]+: 27 \(bad\)
-
-0+d <das>:
-[ ]*[a-f0-9]+: 2f \(bad\)
-
-0+e <into>:
-[ ]*[a-f0-9]+: ce \(bad\)
-
-0+f <pusha>:
-[ ]*[a-f0-9]+: 60 \(bad\)
-
-0+10 <popa>:
-[ ]*[a-f0-9]+: 61 \(bad\)
-#pass
+#dump: ../x86-64-opcode-inval.d
diff --git a/gas/testsuite/gas/i386/rex-bad.l b/gas/testsuite/gas/i386/rex-bad.l
index 407558e..abd4d30 100644
--- a/gas/testsuite/gas/i386/rex-bad.l
+++ b/gas/testsuite/gas/i386/rex-bad.l
@@ -3,8 +3,8 @@
.*:5: Error: same .*
.*:6: Error: same .*
.*:7: Error: same .*
-.*:9: Error: .* REX .*
-.*:10: Error: .* REX .*
-.*:12: Error: .* REX .*
-.*:13: Error: .* REX .*
+.*:9: Error: .* REX/REX2 .*
+.*:10: Error: .* REX/REX2 .*
+.*:12: Error: .* REX/REX2 .*
+.*:13: Error: .* REX/REX2 .*
#pass
diff --git a/gas/testsuite/gas/i386/x86-64-apx-egpr-inval.l b/gas/testsuite/gas/i386/x86-64-apx-egpr-inval.l
new file mode 100644
index 0000000..bb5c602
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-apx-egpr-inval.l
@@ -0,0 +1,15 @@
+.*: Assembler messages:
+.*:4: Error: bad register name `%r17d'
+.*:7: Error: extended GPR cannot be used as base/index for `xsave'
+.*:8: Error: extended GPR cannot be used as base/index for `xsave64'
+.*:9: Error: extended GPR cannot be used as base/index for `xrstor'
+.*:10: Error: extended GPR cannot be used as base/index for `xrstor64'
+.*:11: Error: extended GPR cannot be used as base/index for `xsaves'
+.*:12: Error: extended GPR cannot be used as base/index for `xsaves64'
+.*:13: Error: extended GPR cannot be used as base/index for `xrstors'
+.*:14: Error: extended GPR cannot be used as base/index for `xrstors64'
+.*:15: Error: extended GPR cannot be used as base/index for `xsaveopt'
+.*:16: Error: extended GPR cannot be used as base/index for `xsaveopt64'
+.*:17: Error: extended GPR cannot be used as base/index for `xsavec'
+.*:18: Error: extended GPR cannot be used as base/index for `xsavec64'
+#pass
diff --git a/gas/testsuite/gas/i386/x86-64-apx-egpr-inval.s b/gas/testsuite/gas/i386/x86-64-apx-egpr-inval.s
new file mode 100644
index 0000000..bfb6b3f
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-apx-egpr-inval.s
@@ -0,0 +1,18 @@
+# Check illegal 64bit APX_F instructions
+ .text
+ .arch .noapx_f
+ test $0x7, %r17d
+ .arch .apx_f
+ test $0x7, %r17d
+ xsave (%r16, %rbx)
+ xsave64 (%r16, %r31)
+ xrstor (%r16, %rbx)
+ xrstor64 (%r16, %rbx)
+ xsaves (%rbx, %r16)
+ xsaves64 (%r16, %rbx)
+ xrstors (%rbx, %r31)
+ xrstors64 (%r16, %rbx)
+ xsaveopt (%r16, %rbx)
+ xsaveopt64 (%r16, %r31)
+ xsavec (%r16, %rbx)
+ xsavec64 (%r16, %r31)
diff --git a/gas/testsuite/gas/i386/x86-64-apx-rex2.d b/gas/testsuite/gas/i386/x86-64-apx-rex2.d
new file mode 100644
index 0000000..e3cd534
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-apx-rex2.d
@@ -0,0 +1,83 @@
+#as:
+#objdump: -dw
+#name: x86-64 APX_F use gpr32 with rex2 prefix
+#source: x86-64-apx-rex2.s
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+ <_start>:
+[ ]*[a-f0-9]+:[ ]*d5 11 f6 c0 07[ ]+test \$0x7,%r24b
+[ ]*[a-f0-9]+:[ ]*d5 11 f7 c0 07 00 00 00[ ]+test \$0x7,%r24d
+[ ]*[a-f0-9]+:[ ]*d5 19 f7 c0 07 00 00 00[ ]+test \$0x7,%r24
+[ ]*[a-f0-9]+:[ ]*66 d5 11 f7 c0 07 00[ ]+test \$0x7,%r24w
+[ ]*[a-f0-9]+:[ ]*44 0f af f8[ ]+imul %eax,%r15d
+[ ]*[a-f0-9]+:[ ]*d5 c0 af c0[ ]+imul %eax,%r16d
+[ ]*[a-f0-9]+:[ ]*d5 90 62 12[ ]+punpckldq %mm2,\(%r18\)
+[ ]*[a-f0-9]+:[ ]*d5 40 8d 00[ ]+lea \(%rax\),%r16d
+[ ]*[a-f0-9]+:[ ]*d5 40 8d 08[ ]+lea \(%rax\),%r17d
+[ ]*[a-f0-9]+:[ ]*d5 40 8d 10[ ]+lea \(%rax\),%r18d
+[ ]*[a-f0-9]+:[ ]*d5 40 8d 18[ ]+lea \(%rax\),%r19d
+[ ]*[a-f0-9]+:[ ]*d5 40 8d 20[ ]+lea \(%rax\),%r20d
+[ ]*[a-f0-9]+:[ ]*d5 40 8d 28[ ]+lea \(%rax\),%r21d
+[ ]*[a-f0-9]+:[ ]*d5 40 8d 30[ ]+lea \(%rax\),%r22d
+[ ]*[a-f0-9]+:[ ]*d5 40 8d 38[ ]+lea \(%rax\),%r23d
+[ ]*[a-f0-9]+:[ ]*d5 44 8d 00[ ]+lea \(%rax\),%r24d
+[ ]*[a-f0-9]+:[ ]*d5 44 8d 08[ ]+lea \(%rax\),%r25d
+[ ]*[a-f0-9]+:[ ]*d5 44 8d 10[ ]+lea \(%rax\),%r26d
+[ ]*[a-f0-9]+:[ ]*d5 44 8d 18[ ]+lea \(%rax\),%r27d
+[ ]*[a-f0-9]+:[ ]*d5 44 8d 20[ ]+lea \(%rax\),%r28d
+[ ]*[a-f0-9]+:[ ]*d5 44 8d 28[ ]+lea \(%rax\),%r29d
+[ ]*[a-f0-9]+:[ ]*d5 44 8d 30[ ]+lea \(%rax\),%r30d
+[ ]*[a-f0-9]+:[ ]*d5 44 8d 38[ ]+lea \(%rax\),%r31d
+[ ]*[a-f0-9]+:[ ]*d5 20 8d 04 05 00 00 00 00[ ]+lea 0x0\(,%r16,1\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 20 8d 04 0d 00 00 00 00[ ]+lea 0x0\(,%r17,1\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 20 8d 04 15 00 00 00 00[ ]+lea 0x0\(,%r18,1\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 20 8d 04 1d 00 00 00 00[ ]+lea 0x0\(,%r19,1\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 20 8d 04 25 00 00 00 00[ ]+lea 0x0\(,%r20,1\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 20 8d 04 2d 00 00 00 00[ ]+lea 0x0\(,%r21,1\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 20 8d 04 35 00 00 00 00[ ]+lea 0x0\(,%r22,1\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 20 8d 04 3d 00 00 00 00[ ]+lea 0x0\(,%r23,1\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 22 8d 04 05 00 00 00 00[ ]+lea 0x0\(,%r24,1\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 22 8d 04 0d 00 00 00 00[ ]+lea 0x0\(,%r25,1\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 22 8d 04 15 00 00 00 00[ ]+lea 0x0\(,%r26,1\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 22 8d 04 1d 00 00 00 00[ ]+lea 0x0\(,%r27,1\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 22 8d 04 25 00 00 00 00[ ]+lea 0x0\(,%r28,1\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 22 8d 04 2d 00 00 00 00[ ]+lea 0x0\(,%r29,1\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 22 8d 04 35 00 00 00 00[ ]+lea 0x0\(,%r30,1\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 22 8d 04 3d 00 00 00 00[ ]+lea 0x0\(,%r31,1\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 10 8d 00[ ]+lea \(%r16\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 10 8d 01[ ]+lea \(%r17\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 10 8d 02[ ]+lea \(%r18\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 10 8d 03[ ]+lea \(%r19\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 10 8d 04 24 lea \(%r20\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 10 8d 45 00 lea 0x0\(%r21\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 10 8d 06[ ]+lea \(%r22\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 10 8d 07[ ]+lea \(%r23\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 11 8d 00[ ]+lea \(%r24\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 11 8d 01[ ]+lea \(%r25\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 11 8d 02[ ]+lea \(%r26\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 11 8d 03[ ]+lea \(%r27\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 11 8d 04 24 lea \(%r28\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 11 8d 45 00 lea 0x0\(%r29\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 11 8d 06 lea \(%r30\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 11 8d 07 lea \(%r31\),%eax
+[ ]*[a-f0-9]+:[ ]*4c 8d 38 lea \(%rax\),%r15
+[ ]*[a-f0-9]+:[ ]*d5 48 8d 00 lea \(%rax\),%r16
+[ ]*[a-f0-9]+:[ ]*49 8d 07 lea \(%r15\),%rax
+[ ]*[a-f0-9]+:[ ]*d5 18 8d 00 lea \(%r16\),%rax
+[ ]*[a-f0-9]+:[ ]*4a 8d 04 3d 00 00 00 00 lea 0x0\(,%r15,1\),%rax
+[ ]*[a-f0-9]+:[ ]*d5 28 8d 04 05 00 00 00 00 lea 0x0\(,%r16,1\),%rax
+[ ]*[a-f0-9]+:[ ]*d5 1c 03 00 add \(%r16\),%r8
+[ ]*[a-f0-9]+:[ ]*d5 1c 03 38 add \(%r16\),%r15
+[ ]*[a-f0-9]+:[ ]*d5 4a 8b 04 0d 00 00 00 00 mov 0x0\(,%r9,1\),%r16
+[ ]*[a-f0-9]+:[ ]*d5 4a 8b 04 35 00 00 00 00 mov 0x0\(,%r14,1\),%r16
+[ ]*[a-f0-9]+:[ ]*d5 4d 2b 3a sub \(%r10\),%r31
+[ ]*[a-f0-9]+:[ ]*d5 4d 2b 7d 00 sub 0x0\(%r13\),%r31
+[ ]*[a-f0-9]+:[ ]*d5 30 8d 44 20 01 lea 0x1\(%r16,%r20,1\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 76 8d 7c 20 01 lea 0x1\(%r16,%r28,1\),%r31d
+[ ]*[a-f0-9]+:[ ]*d5 12 8d 84 04 81 00 00 00 lea 0x81\(%r20,%r8,1\),%eax
+[ ]*[a-f0-9]+:[ ]*d5 57 8d bc 04 81 00 00 00 lea 0x81\(%r28,%r8,1\),%r31d
+#pass
diff --git a/gas/testsuite/gas/i386/x86-64-apx-rex2.s b/gas/testsuite/gas/i386/x86-64-apx-rex2.s
new file mode 100644
index 0000000..eaaaaa7
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-apx-rex2.s
@@ -0,0 +1,85 @@
+# Check 64bit instructions with rex2 prefix encoding
+
+ .allow_index_reg
+ .text
+_start:
+ test $0x7, %r24b
+ test $0x7, %r24d
+ test $0x7, %r24
+ test $0x7, %r24w
+## REX2.M bit
+ imull %eax, %r15d
+ imull %eax, %r16d
+ punpckldq (%r18), %mm2
+## REX2.R4 bit
+ leal (%rax), %r16d
+ leal (%rax), %r17d
+ leal (%rax), %r18d
+ leal (%rax), %r19d
+ leal (%rax), %r20d
+ leal (%rax), %r21d
+ leal (%rax), %r22d
+ leal (%rax), %r23d
+ leal (%rax), %r24d
+ leal (%rax), %r25d
+ leal (%rax), %r26d
+ leal (%rax), %r27d
+ leal (%rax), %r28d
+ leal (%rax), %r29d
+ leal (%rax), %r30d
+ leal (%rax), %r31d
+## REX2.X4 bit
+ leal (,%r16), %eax
+ leal (,%r17), %eax
+ leal (,%r18), %eax
+ leal (,%r19), %eax
+ leal (,%r20), %eax
+ leal (,%r21), %eax
+ leal (,%r22), %eax
+ leal (,%r23), %eax
+ leal (,%r24), %eax
+ leal (,%r25), %eax
+ leal (,%r26), %eax
+ leal (,%r27), %eax
+ leal (,%r28), %eax
+ leal (,%r29), %eax
+ leal (,%r30), %eax
+ leal (,%r31), %eax
+## REX2.B4 bit
+ leal (%r16), %eax
+ leal (%r17), %eax
+ leal (%r18), %eax
+ leal (%r19), %eax
+ leal (%r20), %eax
+ leal (%r21), %eax
+ leal (%r22), %eax
+ leal (%r23), %eax
+ leal (%r24), %eax
+ leal (%r25), %eax
+ leal (%r26), %eax
+ leal (%r27), %eax
+ leal (%r28), %eax
+ leal (%r29), %eax
+ leal (%r30), %eax
+ leal (%r31), %eax
+## REX2.W bit
+ leaq (%rax), %r15
+ leaq (%rax), %r16
+ leaq (%r15), %rax
+ leaq (%r16), %rax
+ leaq (,%r15), %rax
+ leaq (,%r16), %rax
+## REX2.R3 bit
+ add (%r16), %r8
+ add (%r16), %r15
+## REX2.X3 bit
+ mov (,%r9), %r16
+ mov (,%r14), %r16
+## REX2.B3 bit
+ sub (%r10), %r31
+ sub (%r13), %r31
+## SIB
+ leal 1(%r16, %r20), %eax
+ leal 1(%r16, %r28), %r31d
+ leal 129(%r20, %r8), %eax
+ leal 129(%r28, %r8), %r31d
diff --git a/gas/testsuite/gas/i386/x86-64-opcode-inval-intel.d b/gas/testsuite/gas/i386/x86-64-opcode-inval-intel.d
index 6ee5b2f..66c4d2c 100644
--- a/gas/testsuite/gas/i386/x86-64-opcode-inval-intel.d
+++ b/gas/testsuite/gas/i386/x86-64-opcode-inval-intel.d
@@ -10,41 +10,33 @@ Disassembly of section .text:
0+ <aaa>:
[ ]*[a-f0-9]+: 37 \(bad\)
-0+1 <aad0>:
-[ ]*[a-f0-9]+: d5 \(bad\)
-[ ]*[a-f0-9]+: 0a .byte 0xa
-
-0+3 <aad1>:
-[ ]*[a-f0-9]+: d5 \(bad\)
-[ ]*[a-f0-9]+: 02 .byte 0x2
-
-0+5 <aam0>:
+0+1 <aam0>:
[ ]*[a-f0-9]+: d4 \(bad\)
[ ]*[a-f0-9]+: 0a .byte 0xa
-0+7 <aam1>:
+0+3 <aam1>:
[ ]*[a-f0-9]+: d4 \(bad\)
[ ]*[a-f0-9]+: 02 .byte 0x2
-0+9 <aas>:
+0+5 <aas>:
[ ]*[a-f0-9]+: 3f \(bad\)
-0+a <bound>:
+0+6 <bound>:
[ ]*[a-f0-9]+: 62 .byte 0x62
[ ]*[a-f0-9]+: 10 .byte 0x10
-0+c <daa>:
+0+8 <daa>:
[ ]*[a-f0-9]+: 27 \(bad\)
-0+d <das>:
+0+9 <das>:
[ ]*[a-f0-9]+: 2f \(bad\)
-0+e <into>:
+0+a <into>:
[ ]*[a-f0-9]+: ce \(bad\)
-0+f <pusha>:
+0+b <pusha>:
[ ]*[a-f0-9]+: 60 \(bad\)
-0+10 <popa>:
+0+c <popa>:
[ ]*[a-f0-9]+: 61 \(bad\)
#pass
diff --git a/gas/testsuite/gas/i386/x86-64-opcode-inval.d b/gas/testsuite/gas/i386/x86-64-opcode-inval.d
index 12f02c1..fbb850b 100644
--- a/gas/testsuite/gas/i386/x86-64-opcode-inval.d
+++ b/gas/testsuite/gas/i386/x86-64-opcode-inval.d
@@ -9,41 +9,33 @@ Disassembly of section .text:
0+ <aaa>:
[ ]*[a-f0-9]+: 37 \(bad\)
-0+1 <aad0>:
-[ ]*[a-f0-9]+: d5 \(bad\)
-[ ]*[a-f0-9]+: 0a .byte 0xa
-
-0+3 <aad1>:
-[ ]*[a-f0-9]+: d5 \(bad\)
-[ ]*[a-f0-9]+: 02 .byte 0x2
-
-0+5 <aam0>:
+0+1 <aam0>:
[ ]*[a-f0-9]+: d4 \(bad\)
[ ]*[a-f0-9]+: 0a .byte 0xa
-0+7 <aam1>:
+0+3 <aam1>:
[ ]*[a-f0-9]+: d4 \(bad\)
[ ]*[a-f0-9]+: 02 .byte 0x2
-0+9 <aas>:
+0+5 <aas>:
[ ]*[a-f0-9]+: 3f \(bad\)
-0+a <bound>:
+0+6 <bound>:
[ ]*[a-f0-9]+: 62 .byte 0x62
[ ]*[a-f0-9]+: 10 .byte 0x10
-0+c <daa>:
+0+8 <daa>:
[ ]*[a-f0-9]+: 27 \(bad\)
-0+d <das>:
+0+9 <das>:
[ ]*[a-f0-9]+: 2f \(bad\)
-0+e <into>:
+0+a <into>:
[ ]*[a-f0-9]+: ce \(bad\)
-0+f <pusha>:
+0+b <pusha>:
[ ]*[a-f0-9]+: 60 \(bad\)
-0+10 <popa>:
+0+c <popa>:
[ ]*[a-f0-9]+: 61 \(bad\)
#pass
diff --git a/gas/testsuite/gas/i386/x86-64-opcode-inval.s b/gas/testsuite/gas/i386/x86-64-opcode-inval.s
index 6cbfe77..fbcda3d 100644
--- a/gas/testsuite/gas/i386/x86-64-opcode-inval.s
+++ b/gas/testsuite/gas/i386/x86-64-opcode-inval.s
@@ -2,10 +2,6 @@
# All the followings are illegal opcodes for x86-64.
aaa:
aaa
-aad0:
- aad
-aad1:
- aad $2
aam0:
aam
aam1:
diff --git a/gas/testsuite/gas/i386/x86-64-pseudos-bad.l b/gas/testsuite/gas/i386/x86-64-pseudos-bad.l
index 3f9f67f..a72f847 100644
--- a/gas/testsuite/gas/i386/x86-64-pseudos-bad.l
+++ b/gas/testsuite/gas/i386/x86-64-pseudos-bad.l
@@ -1,6 +1,71 @@
.*: Assembler messages:
-.*:3: Error: .*`vmovaps'.*
-.*:4: Error: .*`vmovaps'.*
-.*:5: Error: .*`vmovaps'.*
-.*:6: Error: .*`vmovaps'.*
-.*:7: Error: .*`rorx'.*
+.*:[0-9]+: Error: .*`vmovaps'.*
+.*:[0-9]+: Error: .*`vmovaps'.*
+.*:[0-9]+: Error: .*`vmovaps'.*
+.*:[0-9]+: Error: .*`vmovaps'.*
+.*:[0-9]+: Error: .*`rorx'.*
+.*:[0-9]+: Error: .*`vmovaps'.*
+.*:[0-9]+: Error: .*`xsave'.*
+.*:[0-9]+: Error: .*`xsaves'.*
+.*:[0-9]+: Error: .*`xsaves64'.*
+.*:[0-9]+: Error: .*`xsavec'.*
+.*:[0-9]+: Error: .*`xrstors'.*
+.*:[0-9]+: Error: .*`xrstors64'.*
+.*:[0-9]+: Error: .*`mov'.*
+.*:[0-9]+: Error: .*`movabs'.*
+.*:[0-9]+: Error: .*`cmps'.*
+.*:[0-9]+: Error: .*`lods'.*
+.*:[0-9]+: Error: .*`lods'.*
+.*:[0-9]+: Error: .*`lods'.*
+.*:[0-9]+: Error: .*`movs'.*
+.*:[0-9]+: Error: .*`movs'.*
+.*:[0-9]+: Error: .*`scas'.*
+.*:[0-9]+: Error: .*`scas'.*
+.*:[0-9]+: Error: .*`scas'.*
+.*:[0-9]+: Error: .*`stos'.*
+.*:[0-9]+: Error: .*`stos'.*
+.*:[0-9]+: Error: .*`stos'.*
+.*:[0-9]+: Error: .*`jo'.*
+.*:[0-9]+: Error: .*`jno'.*
+.*:[0-9]+: Error: .*`jb'.*
+.*:[0-9]+: Error: .*`jae'.*
+.*:[0-9]+: Error: .*`je'.*
+.*:[0-9]+: Error: .*`jne'.*
+.*:[0-9]+: Error: .*`jbe'.*
+.*:[0-9]+: Error: .*`ja'.*
+.*:[0-9]+: Error: .*`js'.*
+.*:[0-9]+: Error: .*`jns'.*
+.*:[0-9]+: Error: .*`jp'.*
+.*:[0-9]+: Error: .*`jnp'.*
+.*:[0-9]+: Error: .*`jl'.*
+.*:[0-9]+: Error: .*`jge'.*
+.*:[0-9]+: Error: .*`jle'.*
+.*:[0-9]+: Error: .*`jg'.*
+.*:[0-9]+: Error: .*`jo'.*
+.*:[0-9]+: Error: .*`jno'.*
+.*:[0-9]+: Error: .*`jb'.*
+.*:[0-9]+: Error: .*`jae'.*
+.*:[0-9]+: Error: .*`je'.*
+.*:[0-9]+: Error: .*`jne'.*
+.*:[0-9]+: Error: .*`jbe'.*
+.*:[0-9]+: Error: .*`ja'.*
+.*:[0-9]+: Error: .*`js'.*
+.*:[0-9]+: Error: .*`jns'.*
+.*:[0-9]+: Error: .*`jp'.*
+.*:[0-9]+: Error: .*`jnp'.*
+.*:[0-9]+: Error: .*`jl'.*
+.*:[0-9]+: Error: .*`jge'.*
+.*:[0-9]+: Error: .*`jle'.*
+.*:[0-9]+: Error: .*`jg'.*
+.*:[0-9]+: Error: .*`in'.*
+.*:[0-9]+: Error: .*`in'.*
+.*:[0-9]+: Error: .*`out'.*
+.*:[0-9]+: Error: .*`out'.*
+.*:[0-9]+: Error: .*`jmp'.*
+.*:[0-9]+: Error: .*`loop'.*
+.*:[0-9]+: Error: .*`wrmsr'.*
+.*:[0-9]+: Error: .*`rdtsc'.*
+.*:[0-9]+: Error: .*`rdmsr'.*
+.*:[0-9]+: Error: .*`sysenter'.*
+.*:[0-9]+: Error: .*`sysexit'.*
+.*:[0-9]+: Error: .*`rdpmc'.*
diff --git a/gas/testsuite/gas/i386/x86-64-pseudos-bad.s b/gas/testsuite/gas/i386/x86-64-pseudos-bad.s
index 3b92359..54c17a9 100644
--- a/gas/testsuite/gas/i386/x86-64-pseudos-bad.s
+++ b/gas/testsuite/gas/i386/x86-64-pseudos-bad.s
@@ -5,3 +5,77 @@ pseudos:
{rex} vmovaps %xmm7,%xmm2
{rex} vmovaps %xmm17,%xmm2
{rex} rorx $7,%eax,%ebx
+ {rex2} vmovaps %xmm7,%xmm2
+ {rex2} xsave (%rax)
+ {rex2} xsaves (%ecx)
+ {rex2} xsaves64 (%ecx)
+ {rex2} xsavec (%ecx)
+ {rex2} xrstors (%ecx)
+ {rex2} xrstors64 (%ecx)
+
+ #All opcodes in the row 0xA* (map0) prefixed REX2 are illegal.
+ #{rex2} test (0xa8) is a special case, it will remap to test (0xf6)
+ {rex2} mov 0x90909090,%al
+ {rex2} movabs 0x1,%al
+ {rex2} cmpsb %es:(%edi),%ds:(%esi)
+ {rex2} lodsb
+ {rex2} lods %ds:(%esi),%al
+ {rex2} lodsb (%esi)
+ {rex2} movs
+ {rex2} movs (%esi), (%edi)
+ {rex2} scasl
+ {rex2} scas %es:(%edi),%eax
+ {rex2} scasb (%edi)
+ {rex2} stosb
+ {rex2} stosb (%edi)
+ {rex2} stos %eax,%es:(%edi)
+
+ #All opcodes in the row 0x7* (map0) and 0x8* (map1) prefixed REX2 are illegal.
+ {rex2} jo .+2-0x70
+ {rex2} jno .+2-0x70
+ {rex2} jb .+2-0x70
+ {rex2} jae .+2-0x70
+ {rex2} je .+2-0x70
+ {rex2} jne .+2-0x70
+ {rex2} jbe .+2-0x70
+ {rex2} ja .+2-0x70
+ {rex2} js .+2-0x70
+ {rex2} jns .+2-0x70
+ {rex2} jp .+2-0x70
+ {rex2} jnp .+2-0x70
+ {rex2} jl .+2-0x70
+ {rex2} jge .+2-0x70
+ {rex2} jle .+2-0x70
+ {rex2} jg .+2-0x70
+ {rex2} jo .+6+0x90909090
+ {rex2} jno .+6+0x90909090
+ {rex2} jb .+6+0x90909090
+ {rex2} jae .+6+0x90909090
+ {rex2} je .+6+0x90909090
+ {rex2} jne .+6+0x90909090
+ {rex2} jbe .+6+0x90909090
+ {rex2} ja .+6+0x90909090
+ {rex2} js .+6+0x90909090
+ {rex2} jns .+6+0x90909090
+ {rex2} jp .+6+0x90909090
+ {rex2} jnp .+6+0x90909090
+ {rex2} jl .+6+0x90909090
+ {rex2} jge .+6+0x90909090
+ {rex2} jle .+6+0x90909090
+ {rex2} jg .+6+0x90909090
+
+ #All opcodes in the row 0xE* (map0) prefixed REX2 are illegal.
+ {rex2} in $0x90,%al
+ {rex2} in $0x90
+ {rex2} out $0x90,%al
+ {rex2} out $0x90
+ {rex2} jmp *%eax
+ {rex2} loop foo
+
+ #All opcodes in the row 0x3* (map1) prefixed REX2 are illegal.
+ {rex2} wrmsr
+ {rex2} rdtsc
+ {rex2} rdmsr
+ {rex2} sysenter
+ {rex2} sysexitl
+ {rex2} rdpmc
diff --git a/gas/testsuite/gas/i386/x86-64-pseudos.d b/gas/testsuite/gas/i386/x86-64-pseudos.d
index 866a804..19dcd84 100644
--- a/gas/testsuite/gas/i386/x86-64-pseudos.d
+++ b/gas/testsuite/gas/i386/x86-64-pseudos.d
@@ -404,6 +404,18 @@ Disassembly of section .text:
+[a-f0-9]+: 41 0f 28 10 movaps \(%r8\),%xmm2
+[a-f0-9]+: 40 0f 38 01 01 rex phaddw \(%rcx\),%mm0
+[a-f0-9]+: 41 0f 38 01 00 phaddw \(%r8\),%mm0
+ +[a-f0-9]+: 88 c4 mov %al,%ah
+ +[a-f0-9]+: d5 00 d3 e0 {rex2 0x0} shl %cl,%eax
+ +[a-f0-9]+: d5 00 38 ca {rex2 0x0} cmp %cl,%dl
+ +[a-f0-9]+: d5 00 b3 01 {rex2 0x0} mov \$(0x)?1,%bl
+ +[a-f0-9]+: d5 00 89 c3 {rex2 0x0} mov %eax,%ebx
+ +[a-f0-9]+: d5 01 89 c6 {rex2 0x1} mov %eax,%r14d
+ +[a-f0-9]+: d5 01 89 00 {rex2 0x1} mov %eax,\(%r8\)
+ +[a-f0-9]+: d5 80 28 d7 {rex2 0x80} movaps %xmm7,%xmm2
+ +[a-f0-9]+: d5 84 28 e7 {rex2 0x84} movaps %xmm7,%xmm12
+ +[a-f0-9]+: d5 80 28 11 {rex2 0x80} movaps \(%rcx\),%xmm2
+ +[a-f0-9]+: d5 81 28 10 {rex2 0x81} movaps \(%r8\),%xmm2
+ +[a-f0-9]+: d5 80 d5 f0 {rex2 0x80} pmullw %mm0,%mm6
+[a-f0-9]+: 8a 45 00 mov 0x0\(%rbp\),%al
+[a-f0-9]+: 8a 45 00 mov 0x0\(%rbp\),%al
+[a-f0-9]+: 8a 85 00 00 00 00 mov 0x0\(%rbp\),%al
@@ -458,6 +470,15 @@ Disassembly of section .text:
+[a-f0-9]+: 41 0f 28 10 movaps \(%r8\),%xmm2
+[a-f0-9]+: 40 0f 38 01 01 rex phaddw \(%rcx\),%mm0
+[a-f0-9]+: 41 0f 38 01 00 phaddw \(%r8\),%mm0
+ +[a-f0-9]+: 88 c4 mov %al,%ah
+ +[a-f0-9]+: d5 00 89 c3 {rex2 0x0} mov %eax,%ebx
+ +[a-f0-9]+: d5 01 89 c6 {rex2 0x1} mov %eax,%r14d
+ +[a-f0-9]+: d5 01 89 00 {rex2 0x1} mov %eax,\(%r8\)
+ +[a-f0-9]+: d5 80 28 d7 {rex2 0x80} movaps %xmm7,%xmm2
+ +[a-f0-9]+: d5 84 28 e7 {rex2 0x84} movaps %xmm7,%xmm12
+ +[a-f0-9]+: d5 80 28 11 {rex2 0x80} movaps \(%rcx\),%xmm2
+ +[a-f0-9]+: d5 81 28 10 {rex2 0x81} movaps \(%r8\),%xmm2
+ +[a-f0-9]+: d5 80 d5 f0 {rex2 0x80} pmullw %mm0,%mm6
+[a-f0-9]+: 8a 45 00 mov 0x0\(%rbp\),%al
+[a-f0-9]+: 8a 45 00 mov 0x0\(%rbp\),%al
+[a-f0-9]+: 8a 85 00 00 00 00 mov 0x0\(%rbp\),%al
diff --git a/gas/testsuite/gas/i386/x86-64-pseudos.s b/gas/testsuite/gas/i386/x86-64-pseudos.s
index 06f0b62..5a53c36 100644
--- a/gas/testsuite/gas/i386/x86-64-pseudos.s
+++ b/gas/testsuite/gas/i386/x86-64-pseudos.s
@@ -360,6 +360,18 @@ _start:
{rex} movaps (%r8),%xmm2
{rex} phaddw (%rcx),%mm0
{rex} phaddw (%r8),%mm0
+ {rex2} mov %al,%ah
+ {rex2} shl %cl, %eax
+ {rex2} cmp %cl, %dl
+ {rex2} mov $1, %bl
+ {rex2} movl %eax,%ebx
+ {rex2} movl %eax,%r14d
+ {rex2} movl %eax,(%r8)
+ {rex2} movaps %xmm7,%xmm2
+ {rex2} movaps %xmm7,%xmm12
+ {rex2} movaps (%rcx),%xmm2
+ {rex2} movaps (%r8),%xmm2
+ {rex2} pmullw %mm0,%mm6
movb (%rbp),%al
{disp8} movb (%rbp),%al
@@ -422,6 +434,15 @@ _start:
{rex} movaps xmm2,XMMWORD PTR [r8]
{rex} phaddw mm0,QWORD PTR [rcx]
{rex} phaddw mm0,QWORD PTR [r8]
+ {rex2} mov ah,al
+ {rex2} mov ebx,eax
+ {rex2} mov r14d,eax
+ {rex2} mov DWORD PTR [r8],eax
+ {rex2} movaps xmm2,xmm7
+ {rex2} movaps xmm12,xmm7
+ {rex2} movaps xmm2,XMMWORD PTR [rcx]
+ {rex2} movaps xmm2,XMMWORD PTR [r8]
+ {rex2} pmullw mm6,mm0
mov al, BYTE PTR [rbp]
{disp8} mov al, BYTE PTR [rbp]
diff --git a/gas/testsuite/gas/i386/x86-64.exp b/gas/testsuite/gas/i386/x86-64.exp
index e4b0cc8..91c068d 100644
--- a/gas/testsuite/gas/i386/x86-64.exp
+++ b/gas/testsuite/gas/i386/x86-64.exp
@@ -363,6 +363,8 @@ run_dump_test "x86-64-avx512f-rcigrne-intel"
run_dump_test "x86-64-avx512f-rcigrne"
run_dump_test "x86-64-avx512f-rcigru-intel"
run_dump_test "x86-64-avx512f-rcigru"
+run_list_test "x86-64-apx-egpr-inval"
+run_dump_test "x86-64-apx-rex2"
run_dump_test "x86-64-avx512f-rcigrz-intel"
run_dump_test "x86-64-avx512f-rcigrz"
run_dump_test "x86-64-clwb"