aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2023-11-17 11:23:20 +0100
committerJan Beulich <jbeulich@suse.com>2023-11-17 11:23:20 +0100
commit3086ed9a458f9bc3a52633fc2a10ffc3f21753f4 (patch)
tree2aacba95741530a3bf6d1f7f7c9dca296e79c0fc
parented049bd6d8108f0e762c58b9c90334ea1f2cb0e9 (diff)
downloadbinutils-3086ed9a458f9bc3a52633fc2a10ffc3f21753f4.zip
binutils-3086ed9a458f9bc3a52633fc2a10ffc3f21753f4.tar.gz
binutils-3086ed9a458f9bc3a52633fc2a10ffc3f21753f4.tar.bz2
x86: CPU-qualify {disp16} / {disp32}
{disp16} is invalid to use in 64-bit mode, while {disp32} is invalid to use on pre-386 CPUs. The latter, also affecting other (real) prefixes, further requires that like for insns we fully check the CPU flags; till now only Cpu64/CpuNo64 were taken into consideration.
-rw-r--r--gas/config/tc-i386.c11
-rw-r--r--gas/testsuite/gas/i386/prefix32.l21
-rw-r--r--gas/testsuite/gas/i386/prefix32.s14
-rw-r--r--gas/testsuite/gas/i386/prefix64.l39
-rw-r--r--gas/testsuite/gas/i386/prefix64.s2
-rw-r--r--opcodes/i386-opc.tbl2
-rw-r--r--opcodes/i386-tbl.h4
7 files changed, 71 insertions, 22 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 96065ae..6e788d8 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -5769,7 +5769,8 @@ parse_insn (const char *line, char *mnemonic, bool prefix_only)
&& current_templates
&& current_templates->start->opcode_modifier.isprefix)
{
- if (!cpu_flags_check_cpu64 (current_templates->start))
+ supported = cpu_flags_match (current_templates->start);
+ if (!(supported & CPU_FLAGS_64BIT_MATCH))
{
as_bad ((flag_code != CODE_64BIT
? _("`%s' is only supported in 64-bit mode")
@@ -5777,6 +5778,14 @@ parse_insn (const char *line, char *mnemonic, bool prefix_only)
insn_name (current_templates->start));
return NULL;
}
+ if (supported != CPU_FLAGS_PERFECT_MATCH)
+ {
+ as_bad (_("`%s' is not supported on `%s%s'"),
+ insn_name (current_templates->start),
+ cpu_arch_name ? cpu_arch_name : default_arch,
+ cpu_sub_arch_name ? cpu_sub_arch_name : "");
+ return NULL;
+ }
/* If we are in 16-bit mode, do not allow addr16 or data16.
Similarly, in 32-bit mode, do not allow addr32 or data32. */
if ((current_templates->start->opcode_modifier.size == SIZE16
diff --git a/gas/testsuite/gas/i386/prefix32.l b/gas/testsuite/gas/i386/prefix32.l
index e43abbd..72d7972 100644
--- a/gas/testsuite/gas/i386/prefix32.l
+++ b/gas/testsuite/gas/i386/prefix32.l
@@ -10,6 +10,13 @@
.*:20: Error: data size .* `vaddps'
.*:21: Error: data size .* `vaddpd'
.*:25: Error: same type of prefix .*
+.*:31: Error: `xacquire' is not supported on `i386'
+.*:32: Error: `notrack' is not supported on `i386'
+.*:33: Error: `bnd' is not supported on `i386'
+.*:38: Error: `gs' is not supported on `i286'
+.*:39: Error: `data32' is not supported on `i286'
+.*:40: Error: `addr32' is not supported on `i286'
+.*:41: Error: .*disp32.* is not supported on `i286'
GAS LISTING .*
#...
[ ]*1[ ]+\.text
@@ -40,4 +47,18 @@ GAS LISTING .*
[ ]*26[ ]+\?\?\?\? 3E8B4500[ ]+ds mov %ss:\(%ebp\), %eax
[ ]*27[ ]+\?\?\?\? 3E8B4500[ ]+ds mov %ds:\(%ebp\), %eax
[ ]*28[ ]*
+[ ]*[0-9]+[ ]+\.L386:
+[ ]*[0-9]+[ ]+\.arch i386
+[ ]*[0-9]+[ ]+xacquire lock add \[esi\], eax
+[ ]*[0-9]+[ ]+notrack call eax
+[ ]*[0-9]+[ ]+bnd call eax
+[ ]*[0-9]+[ ]*
+[ ]*[0-9]+[ ]+\.L286:
+[ ]*[0-9]+[ ]+\.code16
+[ ]*[0-9]+[ ]+\.arch i286
+[ ]*[0-9]+[ ]+gs inc word ptr \[si\]
+[ ]*[0-9]+[ ]+data32 nop
+[ ]*[0-9]+[ ]+addr32 nop
+[ ]*[0-9]+[ ]+\{disp32\} nop
+[ ]*[0-9]+[ ]*
#pass
diff --git a/gas/testsuite/gas/i386/prefix32.s b/gas/testsuite/gas/i386/prefix32.s
index 598b0a7..9274f66 100644
--- a/gas/testsuite/gas/i386/prefix32.s
+++ b/gas/testsuite/gas/i386/prefix32.s
@@ -26,4 +26,18 @@ prefix:
ds mov %ss:(%ebp), %eax
ds mov %ds:(%ebp), %eax
+.L386:
+ .arch i386
+ xacquire lock add [esi], eax
+ notrack call eax
+ bnd call eax
+
+.L286:
+ .code16
+ .arch i286
+ gs inc word ptr [si]
+ data32 nop
+ addr32 nop
+ {disp32} nop
+
.p2align 4,0
diff --git a/gas/testsuite/gas/i386/prefix64.l b/gas/testsuite/gas/i386/prefix64.l
index 712f4e0..9bf8503 100644
--- a/gas/testsuite/gas/i386/prefix64.l
+++ b/gas/testsuite/gas/i386/prefix64.l
@@ -3,12 +3,13 @@
.*:7: Error: invalid .* `addss' after `repne'
.*:8: Error: invalid .* `vaddss' after `repe'
.*:9: Error: invalid .* `vaddss' after `repne'
-.*:14: Error: same type of prefix .*
-.*:15: Error: same type of prefix .*
-.*:18: Error: data size .* `addps'
-.*:19: Error: data size .* `addpd'
-.*:20: Error: data size .* `vaddps'
-.*:21: Error: data size .* `vaddpd'
+.*:11: Error: .*disp16.* is not supported .*
+.*:16: Error: same type of prefix .*
+.*:17: Error: same type of prefix .*
+.*:20: Error: data size .* `addps'
+.*:21: Error: data size .* `addpd'
+.*:22: Error: data size .* `vaddps'
+.*:23: Error: data size .* `vaddpd'
GAS LISTING .*
#...
[ ]*1[ ]+\.text
@@ -21,16 +22,18 @@ GAS LISTING .*
[ ]*8[ ]+repe vaddss %xmm0, %xmm0, %xmm0
[ ]*9[ ]+repne vaddss %xmm0, %xmm0, %xmm0
[ ]*10[ ]*
-[ ]*11[ ]+\.Lrep_ret:
-[ ]*12[ ]+\?\?\?\? F2C3[ ]+bnd ret
-[ ]*13[ ]+\?\?\?\? F3C3[ ]+rep ret
-[ ]*14[ ]+bnd rep ret
-[ ]*15[ ]+rep bnd ret
-[ ]*16[ ]*
-[ ]*17[ ]+\.Ldata16:
-[ ]*18[ ]+data16 addps %xmm0, %xmm0
-[ ]*19[ ]+data16 addpd %xmm0, %xmm0
-[ ]*20[ ]+data16 vaddps %xmm0, %xmm0, %xmm0
-[ ]*21[ ]+data16 vaddpd %xmm0, %xmm0, %xmm0
-[ ]*22[ ]*
+[ ]*[0-9]+[ ]+\{disp16\} nop
+[ ]*[0-9]+[ ]*
+[ ]*[0-9]+[ ]+\.Lrep_ret:
+[ ]*[0-9]+[ ]+\?\?\?\? F2C3[ ]+bnd ret
+[ ]*[0-9]+[ ]+\?\?\?\? F3C3[ ]+rep ret
+[ ]*[0-9]+[ ]+bnd rep ret
+[ ]*[0-9]+[ ]+rep bnd ret
+[ ]*[0-9]+[ ]*
+[ ]*[0-9]+[ ]+\.Ldata16:
+[ ]*[0-9]+[ ]+data16 addps %xmm0, %xmm0
+[ ]*[0-9]+[ ]+data16 addpd %xmm0, %xmm0
+[ ]*[0-9]+[ ]+data16 vaddps %xmm0, %xmm0, %xmm0
+[ ]*[0-9]+[ ]+data16 vaddpd %xmm0, %xmm0, %xmm0
+[ ]*[0-9]+[ ]*
#pass
diff --git a/gas/testsuite/gas/i386/prefix64.s b/gas/testsuite/gas/i386/prefix64.s
index 32091c7..4a0ec6a 100644
--- a/gas/testsuite/gas/i386/prefix64.s
+++ b/gas/testsuite/gas/i386/prefix64.s
@@ -8,6 +8,8 @@ prefix:
repe vaddss %xmm0, %xmm0, %xmm0
repne vaddss %xmm0, %xmm0, %xmm0
+ {disp16} nop
+
.Lrep_ret:
bnd ret
rep ret
diff --git a/opcodes/i386-opc.tbl b/opcodes/i386-opc.tbl
index c31bf20..167c0a0 100644
--- a/opcodes/i386-opc.tbl
+++ b/opcodes/i386-opc.tbl
@@ -892,7 +892,7 @@ rex.wrxb, 0x4f, x64, NoSuf|IsPrefix, {}
// Pseudo prefixes (base_opcode == PSEUDO_PREFIX)
-<pseudopfx:ident:cpu, disp8:Disp8:0, disp16:Disp16:0, disp32:Disp32:0, +
+<pseudopfx:ident:cpu, disp8:Disp8:0, disp16:Disp16:No64, disp32:Disp32:i386, +
load:Load:0, store:Store:0, +
vex:VEX:0, vex2:VEX:0, vex3:VEX3:0, evex:EVEX:0, +
rex:REX:x64, nooptimize:NoOptimize:0>
diff --git a/opcodes/i386-tbl.h b/opcodes/i386-tbl.h
index 527793c..e662a50 100644
--- a/opcodes/i386-tbl.h
+++ b/opcodes/i386-tbl.h
@@ -5164,7 +5164,7 @@ static const insn_template i386_optab[] =
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0 },
- { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 } },
{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
{ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0 } } } },
@@ -5172,7 +5172,7 @@ static const insn_template i386_optab[] =
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0 },
- { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
{ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0 } } } },