x86: correct decoding of nop/reserved space (0f18 ... 0x1f)

All encodings not used in this range are (reserved) NOPs. Hence their
decoding should be fully consistent. For this to work the PREFIX_IGNORED
logic needs slightly extending, such that the attribute will also
- have an effect when used inside prefix_table[], yet without always
  falling back to using slot 0,
- cause prefixes marked as ignored while decoding through prefix_table[]
  to no longer be considered decoded, when encountered in a subsequent
  decoding step.

In adjacent code also drop meaningless PREFIX_OPCODE.
This commit is contained in:
Jan Beulich 2021-03-10 08:14:11 +01:00
parent 67b0f68480
commit 319419837c
10 changed files with 2433 additions and 64 deletions

View File

@ -1,3 +1,12 @@
2021-03-10 Jan Beulich <jbeulich@suse.com>
* testsuite/gas/i386/prefetch.d,
testsuite/gas/i386/prefetch-intel.d,
testsuite/gas/i386/x86-64-prefetch.d,
testsuite/gas/i386/x86-64-prefetch-intel.d: Adjust expectations.
* testsuite/gas/i386/nops-8.s, testsuite/gas/i386/nops-8.d: New.
* testsuite/gas/i386/i386.exp: Run new test.
2021-03-09 Jan Beulich <jbeulich@suse.com>
* config/tc-i386.c (check_hle): Replace HLEPrefix* by Prefix*.

View File

@ -134,6 +134,7 @@ if [gas_32_check] then {
run_dump_test "nops-5-i686"
run_dump_test "nops-6"
run_dump_test "nops-7"
run_dump_test "nops-8"
run_dump_test "noreg16"
run_list_test "noreg16"
run_dump_test "noreg16-data32"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,19 @@
.text
.irp opc, 18, 19, 1a, 1b, 1c, 1d, 1e, 1f
_0f\opc:
.irp pfx, , 66, f3, f2
.irp mod, 3, 0
.irp reg, 0, 1, 2, 3, 4, 5, 6, 7
.irp rm, 0, 1, 2, 3, 4, 5, 6, 7
.if !\mod && \rm
.exitm
.endif
.ifnb \pfx
.byte 0x\pfx
.endif
.byte 0xf, 0x\opc, (\mod << 6) | (\reg << 3) | \rm
.endr
.endr
.endr
.endr
.endr

View File

@ -21,7 +21,7 @@ Disassembly of section .text:
\s*[a-f0-9]+: 0f 18 08 prefetcht0 BYTE PTR \[eax\]
\s*[a-f0-9]+: 0f 18 10 prefetcht1 BYTE PTR \[eax\]
\s*[a-f0-9]+: 0f 18 18 prefetcht2 BYTE PTR \[eax\]
\s*[a-f0-9]+: 0f 18 20 nop/reserved BYTE PTR \[eax\]
\s*[a-f0-9]+: 0f 18 28 nop/reserved BYTE PTR \[eax\]
\s*[a-f0-9]+: 0f 18 30 nop/reserved BYTE PTR \[eax\]
\s*[a-f0-9]+: 0f 18 38 nop/reserved BYTE PTR \[eax\]
\s*[a-f0-9]+: 0f 18 20 nop DWORD PTR \[eax\]
\s*[a-f0-9]+: 0f 18 28 nop DWORD PTR \[eax\]
\s*[a-f0-9]+: 0f 18 30 nop DWORD PTR \[eax\]
\s*[a-f0-9]+: 0f 18 38 nop DWORD PTR \[eax\]

View File

@ -20,7 +20,7 @@ Disassembly of section .text:
\s*[a-f0-9]+: 0f 18 08 prefetcht0 \(%eax\)
\s*[a-f0-9]+: 0f 18 10 prefetcht1 \(%eax\)
\s*[a-f0-9]+: 0f 18 18 prefetcht2 \(%eax\)
\s*[a-f0-9]+: 0f 18 20 nop/reserved \(%eax\)
\s*[a-f0-9]+: 0f 18 28 nop/reserved \(%eax\)
\s*[a-f0-9]+: 0f 18 30 nop/reserved \(%eax\)
\s*[a-f0-9]+: 0f 18 38 nop/reserved \(%eax\)
\s*[a-f0-9]+: 0f 18 20 nopl \(%eax\)
\s*[a-f0-9]+: 0f 18 28 nopl \(%eax\)
\s*[a-f0-9]+: 0f 18 30 nopl \(%eax\)
\s*[a-f0-9]+: 0f 18 38 nopl \(%eax\)

View File

@ -21,7 +21,7 @@ Disassembly of section .text:
\s*[a-f0-9]+: 0f 18 08 prefetcht0 BYTE PTR \[rax\]
\s*[a-f0-9]+: 0f 18 10 prefetcht1 BYTE PTR \[rax\]
\s*[a-f0-9]+: 0f 18 18 prefetcht2 BYTE PTR \[rax\]
\s*[a-f0-9]+: 0f 18 20 nop/reserved BYTE PTR \[rax\]
\s*[a-f0-9]+: 0f 18 28 nop/reserved BYTE PTR \[rax\]
\s*[a-f0-9]+: 0f 18 30 nop/reserved BYTE PTR \[rax\]
\s*[a-f0-9]+: 0f 18 38 nop/reserved BYTE PTR \[rax\]
\s*[a-f0-9]+: 0f 18 20 nop DWORD PTR \[rax\]
\s*[a-f0-9]+: 0f 18 28 nop DWORD PTR \[rax\]
\s*[a-f0-9]+: 0f 18 30 nop DWORD PTR \[rax\]
\s*[a-f0-9]+: 0f 18 38 nop DWORD PTR \[rax\]

View File

@ -21,7 +21,7 @@ Disassembly of section .text:
\s*[a-f0-9]+: 0f 18 08 prefetcht0 \(%rax\)
\s*[a-f0-9]+: 0f 18 10 prefetcht1 \(%rax\)
\s*[a-f0-9]+: 0f 18 18 prefetcht2 \(%rax\)
\s*[a-f0-9]+: 0f 18 20 nop/reserved \(%rax\)
\s*[a-f0-9]+: 0f 18 28 nop/reserved \(%rax\)
\s*[a-f0-9]+: 0f 18 30 nop/reserved \(%rax\)
\s*[a-f0-9]+: 0f 18 38 nop/reserved \(%rax\)
\s*[a-f0-9]+: 0f 18 20 nopl \(%rax\)
\s*[a-f0-9]+: 0f 18 28 nopl \(%rax\)
\s*[a-f0-9]+: 0f 18 30 nopl \(%rax\)
\s*[a-f0-9]+: 0f 18 38 nopl \(%rax\)

View File

@ -1,3 +1,19 @@
2021-03-10 Jan Beulich <jbeulich@suse.com>
* opcodes/i386-dis.c (MOD_0F18_REG_4, MOD_0F18_REG_5,
MOD_0F18_REG_6, MOD_0F18_REG_7): Delete.
(reg_table): Don't link to mod_table[] where not needed. Add
PREFIX_IGNORED to nop entries.
(prefix_table): Replace PREFIX_OPCODE in nop entries.
(mod_table): Add nop entries next to prefetch ones. Drop
MOD_0F18_REG_4, MOD_0F18_REG_5, MOD_0F18_REG_6, and
MOD_0F18_REG_7 entries. Add PREFIX_IGNORED to nop entries.
(rm_table): Add PREFIX_IGNORED to nop entries. Drop
PREFIX_OPCODE from endbr* entries.
(get_valid_dis386): Also consider entry's name when zapping
vindex.
(print_insn): Handle PREFIX_IGNORED.
2021-03-09 Jan Beulich <jbeulich@suse.com>
* opcodes/i386-gen.c (opcode_modifiers): Delete NoTrackPrefixOk,

View File

@ -743,10 +743,6 @@ enum
MOD_0F18_REG_1,
MOD_0F18_REG_2,
MOD_0F18_REG_3,
MOD_0F18_REG_4,
MOD_0F18_REG_5,
MOD_0F18_REG_6,
MOD_0F18_REG_7,
MOD_0F1A_PREFIX_0,
MOD_0F1B_PREFIX_0,
MOD_0F1B_PREFIX_1,
@ -2907,10 +2903,10 @@ static const struct dis386 reg_table[][8] = {
{ MOD_TABLE (MOD_0F18_REG_1) },
{ MOD_TABLE (MOD_0F18_REG_2) },
{ MOD_TABLE (MOD_0F18_REG_3) },
{ MOD_TABLE (MOD_0F18_REG_4) },
{ MOD_TABLE (MOD_0F18_REG_5) },
{ MOD_TABLE (MOD_0F18_REG_6) },
{ MOD_TABLE (MOD_0F18_REG_7) },
{ "nopQ", { Ev }, 0 },
{ "nopQ", { Ev }, 0 },
{ "nopQ", { Ev }, 0 },
{ "nopQ", { Ev }, 0 },
},
/* REG_0F1C_P_0_MOD_0 */
{
@ -2925,13 +2921,13 @@ static const struct dis386 reg_table[][8] = {
},
/* REG_0F1E_P_1_MOD_3 */
{
{ "nopQ", { Ev }, 0 },
{ "rdsspK", { Edq }, PREFIX_OPCODE },
{ "nopQ", { Ev }, 0 },
{ "nopQ", { Ev }, 0 },
{ "nopQ", { Ev }, 0 },
{ "nopQ", { Ev }, 0 },
{ "nopQ", { Ev }, 0 },
{ "nopQ", { Ev }, PREFIX_IGNORED },
{ "rdsspK", { Edq }, 0 },
{ "nopQ", { Ev }, PREFIX_IGNORED },
{ "nopQ", { Ev }, PREFIX_IGNORED },
{ "nopQ", { Ev }, PREFIX_IGNORED },
{ "nopQ", { Ev }, PREFIX_IGNORED },
{ "nopQ", { Ev }, PREFIX_IGNORED },
{ RM_TABLE (RM_0F1E_P_1_MOD_3_REG_7) },
},
/* REG_0F38D8_PREFIX_1 */
@ -3287,17 +3283,17 @@ static const struct dis386 prefix_table[][4] = {
/* PREFIX_0F1C */
{
{ MOD_TABLE (MOD_0F1C_PREFIX_0) },
{ "nopQ", { Ev }, PREFIX_OPCODE },
{ "nopQ", { Ev }, PREFIX_OPCODE },
{ "nopQ", { Ev }, PREFIX_OPCODE },
{ "nopQ", { Ev }, PREFIX_IGNORED },
{ "nopQ", { Ev }, 0 },
{ "nopQ", { Ev }, PREFIX_IGNORED },
},
/* PREFIX_0F1E */
{
{ "nopQ", { Ev }, PREFIX_OPCODE },
{ "nopQ", { Ev }, 0 },
{ MOD_TABLE (MOD_0F1E_PREFIX_1) },
{ "nopQ", { Ev }, PREFIX_OPCODE },
{ "nopQ", { Ev }, PREFIX_OPCODE },
{ "nopQ", { Ev }, 0 },
{ NULL, { XX }, PREFIX_IGNORED },
},
/* PREFIX_0F2A */
@ -8201,34 +8197,22 @@ static const struct dis386 mod_table[][2] = {
{
/* MOD_0F18_REG_0 */
{ "prefetchnta", { Mb }, 0 },
{ "nopQ", { Ev }, 0 },
},
{
/* MOD_0F18_REG_1 */
{ "prefetcht0", { Mb }, 0 },
{ "nopQ", { Ev }, 0 },
},
{
/* MOD_0F18_REG_2 */
{ "prefetcht1", { Mb }, 0 },
{ "nopQ", { Ev }, 0 },
},
{
/* MOD_0F18_REG_3 */
{ "prefetcht2", { Mb }, 0 },
},
{
/* MOD_0F18_REG_4 */
{ "nop/reserved", { Mb }, 0 },
},
{
/* MOD_0F18_REG_5 */
{ "nop/reserved", { Mb }, 0 },
},
{
/* MOD_0F18_REG_6 */
{ "nop/reserved", { Mb }, 0 },
},
{
/* MOD_0F18_REG_7 */
{ "nop/reserved", { Mb }, 0 },
{ "nopQ", { Ev }, 0 },
},
{
/* MOD_0F1A_PREFIX_0 */
@ -8243,7 +8227,7 @@ static const struct dis386 mod_table[][2] = {
{
/* MOD_0F1B_PREFIX_1 */
{ "bndmk", { Gbnd, Mv_bnd }, 0 },
{ "nopQ", { Ev }, 0 },
{ "nopQ", { Ev }, PREFIX_IGNORED },
},
{
/* MOD_0F1C_PREFIX_0 */
@ -8252,7 +8236,7 @@ static const struct dis386 mod_table[][2] = {
},
{
/* MOD_0F1E_PREFIX_1 */
{ "nopQ", { Ev }, 0 },
{ "nopQ", { Ev }, PREFIX_IGNORED },
{ REG_TABLE (REG_0F1E_P_1_MOD_3) },
},
{
@ -9034,14 +9018,14 @@ static const struct dis386 rm_table[][8] = {
},
{
/* RM_0F1E_P_1_MOD_3_REG_7 */
{ "nopQ", { Ev }, 0 },
{ "nopQ", { Ev }, 0 },
{ "endbr64", { Skip_MODRM }, PREFIX_OPCODE },
{ "endbr32", { Skip_MODRM }, PREFIX_OPCODE },
{ "nopQ", { Ev }, 0 },
{ "nopQ", { Ev }, 0 },
{ "nopQ", { Ev }, 0 },
{ "nopQ", { Ev }, 0 },
{ "nopQ", { Ev }, PREFIX_IGNORED },
{ "nopQ", { Ev }, PREFIX_IGNORED },
{ "endbr64", { Skip_MODRM }, 0 },
{ "endbr32", { Skip_MODRM }, 0 },
{ "nopQ", { Ev }, PREFIX_IGNORED },
{ "nopQ", { Ev }, PREFIX_IGNORED },
{ "nopQ", { Ev }, PREFIX_IGNORED },
{ "nopQ", { Ev }, PREFIX_IGNORED },
},
{
/* RM_0F3A0F_P_1_MOD_3_REG_0 */
@ -9471,7 +9455,8 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
/* Check if prefix should be ignored. */
if ((((prefix_table[dp->op[1].bytemode][vindex].prefix_requirement
& PREFIX_IGNORED) >> PREFIX_IGNORED_SHIFT)
& prefix) != 0)
& prefix) != 0
&& !prefix_table[dp->op[1].bytemode][vindex].name)
vindex = 0;
}
@ -10245,6 +10230,18 @@ print_insn (bfd_vma pc, disassemble_info *info)
return end_codep - priv.the_buffer;
}
break;
case PREFIX_IGNORED:
/* Zap data size and rep prefixes from used_prefixes and reinstate their
origins in all_prefixes. */
used_prefixes &= ~PREFIX_OPCODE;
if (last_data_prefix >= 0)
all_prefixes[last_repz_prefix] = 0x66;
if (last_repz_prefix >= 0)
all_prefixes[last_repz_prefix] = 0xf3;
if (last_repnz_prefix >= 0)
all_prefixes[last_repnz_prefix] = 0xf2;
break;
}
/* Check if the REX prefix is used. */