[PATCH] x86: conditionalize x87 instructions and registers
Jan Beulich
JBeulich@novell.com
Fri Jul 24 15:45:00 GMT 2009
>>> "H.J. Lu" <hjl.tools@gmail.com> 24.07.09 16:50 >>>
>I think those new options are also supported on command
>line. Please add a new testcase with command line option,
>update md_show_usag and doc/c-i386.texi. OK with those
>changes.
Indeed, I overlooked that. This is the patch I'm checking in:
gas/
2009-07-24 Jan Beulich <jbeulich@novell.com>
* tc-i386.c (cpu_arch): Add .8087, .287, .387, .no87, .nommx,
.nosse, and .noavx.
(cpu_flags_and_not): New.
(set_cpu_arch): Check whether sub-architecture specified is a
feature disable.
(md_parse_option): Likewise.
(parse_real_register): Don't return floating point register
when x87 functionality is disabled.
(md_show_usage): Add new sub-options.
* doc/c-i386.texi: Update with new command line sub-options.
gas/testsuite/
2009-07-24 Jan Beulich <jbeulich@novell.com>
* gas/i386/8087.[ds]: New.
* gas/i386/287.[ds]: New.
* gas/i386/387.[ds]: New.
* gas/i386/no87.[ls]: New.
* gas/i386/no87-2.[ls]: New.
* gas/i386/i386.exp: Run new tests.
* gas/i386/att-regs.s: Also check FPU register access.
* gas/i386/intel-regs.s: Likewise.
* gas/i386/att-regs.d: Adjust expectations.
* gas/i386/intel-regs.d: Likewise.
opcodes/
2009-07-24 Jan Beulich <jbeulich@novell.com>
* i386-dis.c (fgrps): Correct annotation for feni/fdisi. Add
frstpm.
* i386-gen.c (cpu_flag_init): Add FP enabling flags where needed.
(cpu_flags): Add Cpu8087, Cpu287, Cpu387, Cpu687, and CpuFISTTP.
(set_bitfield): Expand CpuFP to Cpu8087|Cpu287|Cpu387.
* i386-opc.h (Cpu8087, Cpu287, Cpu387, Cpu687, CpuFISTTP):
Define.
(union i386_cpu_flags): Add cpu8087, cpu287, cpu387, cpu687,
and cpufisttp.
* i386-opc.tbl: Qualify floating point instructions by their
respective CpuXXX flag. Fix fucom{,p,pp}, fprem1, fsin, fcos,
and fsincos to be avilable only on 387. Fix fstsw ax to be
available only on 287+. Add f{,n}eni, f{,n}disi, f{,n}setpm,
and frstpm.
* i386-init.h, i386-tbl.h: Regenerate.
--- 2009-07-24/gas/config/tc-i386.c 2009-07-23 15:06:32.000000000 +0200
+++ 2009-07-24/gas/config/tc-i386.c 2009-07-24 17:18:06.000000000 +0200
@@ -591,8 +591,18 @@ static const arch_entry cpu_arch[] =
CPU_K8_FLAGS },
{ "amdfam10", PROCESSOR_AMDFAM10,
CPU_AMDFAM10_FLAGS },
+ { ".8087", PROCESSOR_UNKNOWN,
+ CPU_8087_FLAGS },
+ { ".287", PROCESSOR_UNKNOWN,
+ CPU_287_FLAGS },
+ { ".387", PROCESSOR_UNKNOWN,
+ CPU_387_FLAGS },
+ { ".no87", PROCESSOR_UNKNOWN,
+ CPU_ANY87_FLAGS },
{ ".mmx", PROCESSOR_UNKNOWN,
CPU_MMX_FLAGS },
+ { ".nommx", PROCESSOR_UNKNOWN,
+ CPU_3DNOWA_FLAGS },
{ ".sse", PROCESSOR_UNKNOWN,
CPU_SSE_FLAGS },
{ ".sse2", PROCESSOR_UNKNOWN,
@@ -607,8 +617,12 @@ static const arch_entry cpu_arch[] =
CPU_SSE4_2_FLAGS },
{ ".sse4", PROCESSOR_UNKNOWN,
CPU_SSE4_2_FLAGS },
+ { ".nosse", PROCESSOR_UNKNOWN,
+ CPU_ANY_SSE_FLAGS },
{ ".avx", PROCESSOR_UNKNOWN,
CPU_AVX_FLAGS },
+ { ".noavx", PROCESSOR_UNKNOWN,
+ CPU_ANY_AVX_FLAGS },
{ ".vmx", PROCESSOR_UNKNOWN,
CPU_VMX_FLAGS },
{ ".smx", PROCESSOR_UNKNOWN,
@@ -1236,6 +1250,24 @@ cpu_flags_or (i386_cpu_flags x, i386_cpu
return x;
}
+static INLINE i386_cpu_flags
+cpu_flags_and_not (i386_cpu_flags x, i386_cpu_flags y)
+{
+ switch (ARRAY_SIZE (x.array))
+ {
+ case 3:
+ x.array [2] &= ~y.array [2];
+ case 2:
+ x.array [1] &= ~y.array [1];
+ case 1:
+ x.array [0] &= ~y.array [0];
+ break;
+ default:
+ abort ();
+ }
+ return x;
+}
+
#define CPU_FLAGS_ARCH_MATCH 0x1
#define CPU_FLAGS_64BIT_MATCH 0x2
#define CPU_FLAGS_AES_MATCH 0x4
@@ -1964,8 +1996,12 @@ set_cpu_arch (int dummy ATTRIBUTE_UNUSED
break;
}
- flags = cpu_flags_or (cpu_arch_flags,
- cpu_arch[i].flags);
+ if (strncmp (string + 1, "no", 2))
+ flags = cpu_flags_or (cpu_arch_flags,
+ cpu_arch[i].flags);
+ else
+ flags = cpu_flags_and_not (cpu_arch_flags,
+ cpu_arch[i].flags);
if (!cpu_flags_equal (&flags, &cpu_arch_flags))
{
if (cpu_sub_arch_name)
@@ -7484,6 +7520,12 @@ parse_real_register (char *reg_string, c
&& !cpu_arch_flags.bitfield.cpui386)
return (const reg_entry *) NULL;
+ if (r->reg_type.bitfield.floatreg
+ && !cpu_arch_flags.bitfield.cpu8087
+ && !cpu_arch_flags.bitfield.cpu287
+ && !cpu_arch_flags.bitfield.cpu387)
+ return (const reg_entry *) NULL;
+
if (r->reg_type.bitfield.regmmx && !cpu_arch_flags.bitfield.cpummx)
return (const reg_entry *) NULL;
@@ -7759,8 +7801,13 @@ md_parse_option (int c, char *arg)
{
/* ISA entension. */
i386_cpu_flags flags;
- flags = cpu_flags_or (cpu_arch_flags,
- cpu_arch[i].flags);
+
+ if (strncmp (arch, "no", 2))
+ flags = cpu_flags_or (cpu_arch_flags,
+ cpu_arch[i].flags);
+ else
+ flags = cpu_flags_and_not (cpu_arch_flags,
+ cpu_arch[i].flags);
if (!cpu_flags_equal (&flags, &cpu_arch_flags))
{
if (cpu_sub_arch_name)
@@ -7892,8 +7939,9 @@ md_show_usage (stream)
core, core2, corei7, k6, k6_2, athlon, k8, amdfam10,\n\
generic32, generic64\n\
EXTENSION is combination of:\n\
- mmx, sse, sse2, sse3, ssse3, sse4.1, sse4.2, sse4,\n\
- avx, vmx, smx, xsave, movbe, ept, aes, pclmul, fma,\n\
+ 8087, 287, 387, no87, mmx, nommx, sse, sse2, sse3,\n\
+ ssse3, sse4.1, sse4.2, sse4, nosse, avx, noavx,\n\
+ vmx, smx, xsave, movbe, ept, aes, pclmul, fma,\n\
clflush, syscall, rdtscp, 3dnow, 3dnowa, sse4a,\n\
svme, abm, padlock, fma4\n"));
fprintf (stream, _("\
--- 2009-07-24/gas/doc/c-i386.texi 2009-02-05 08:59:52.000000000 +0100
+++ 2009-07-24/gas/doc/c-i386.texi 2009-07-24 17:04:26.000000000 +0200
@@ -114,7 +114,12 @@ In addition to the basic instruction set
accept various extension mnemonics. For example,
@code{-march=i686+sse4+vmx} extends @var{i686} with @var{sse4} and
@var{vmx}. The following extensions are currently supported:
+@code{8087},
+@code{287},
+@code{387},
+@code{no87},
@code{mmx},
+@code{nommx},
@code{sse},
@code{sse2},
@code{sse3},
@@ -122,7 +127,9 @@ accept various extension mnemonics. For
@code{sse4.1},
@code{sse4.2},
@code{sse4},
+@code{nosse},
@code{avx},
+@code{noavx},
@code{vmx},
@code{smx},
@code{xsave},
@@ -141,6 +148,8 @@ accept various extension mnemonics. For
@code{svme},
@code{abm} and
@code{padlock}.
+Note that rather than extending a basic instruction set, the extension
+mnemonics starting with @code{no} revoke the respective functionality.
When the @code{.arch} directive is used with @option{-march}, the
@code{.arch} directive will take precedent.
--- 2009-07-24/gas/testsuite/gas/i386/287.d 1970-01-01 01:00:00.000000000 +0100
+++ 2009-07-24/gas/testsuite/gas/i386/287.d 2009-07-20 12:27:31.000000000 +0200
@@ -0,0 +1,12 @@
+#objdump: -dw
+#name: i386 287
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+ <_8087>:
+[ ]*[0-9a-f]+: db e4[ ]+fnsetpm.*
+[ ]*[0-9a-f]+: db e5[ ]+frstpm.*
+[ ]*[0-9a-f]+: 9b db e4[ ]+fsetpm.*
+#pass
--- 2009-07-24/gas/testsuite/gas/i386/287.s 1970-01-01 01:00:00.000000000 +0100
+++ 2009-07-24/gas/testsuite/gas/i386/287.s 2009-07-20 12:19:08.000000000 +0200
@@ -0,0 +1,10 @@
+# Check 287-only instructions.
+
+ .text
+ .arch i286
+ .arch .287
+ .code16
+_8087:
+ fnsetpm
+ frstpm
+ fsetpm
--- 2009-07-24/gas/testsuite/gas/i386/387.d 1970-01-01 01:00:00.000000000 +0100
+++ 2009-07-24/gas/testsuite/gas/i386/387.d 2009-07-24 17:27:49.000000000 +0200
@@ -0,0 +1,17 @@
+#objdump: -dw
+#name: i386 387 (cmdline)
+#as: -march=i386+387
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+ <_387>:
+[ ]*[0-9a-f]+: d9 ff[ ]+fcos[ ]*
+[ ]*[0-9a-f]+: d9 f5[ ]+fprem1[ ]*
+[ ]*[0-9a-f]+: d9 fe[ ]+fsin[ ]*
+[ ]*[0-9a-f]+: d9 fb[ ]+fsincos[ ]*
+[ ]*[0-9a-f]+: dd e1[ ]+fucom[ ]+%st\(1\)
+[ ]*[0-9a-f]+: dd e9[ ]+fucomp[ ]+%st\(1\)
+[ ]*[0-9a-f]+: da e9[ ]+fucompp[ ]*
+#pass
--- 2009-07-24/gas/testsuite/gas/i386/387.s 1970-01-01 01:00:00.000000000 +0100
+++ 2009-07-24/gas/testsuite/gas/i386/387.s 2009-07-24 17:23:28.000000000 +0200
@@ -0,0 +1,11 @@
+# Check 387+ instructions.
+
+ .text
+_387:
+ fcos
+ fprem1
+ fsin
+ fsincos
+ fucom
+ fucomp
+ fucompp
--- 2009-07-24/gas/testsuite/gas/i386/8087.d 1970-01-01 01:00:00.000000000 +0100
+++ 2009-07-24/gas/testsuite/gas/i386/8087.d 2009-07-20 12:42:36.000000000 +0200
@@ -0,0 +1,13 @@
+#objdump: -dw
+#name: i386 8087
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+ <_8087>:
+[ ]*[0-9a-f]+: 9b db e1[ ]+fdisi.*
+[ ]*[0-9a-f]+: 9b db e0[ ]+feni.*
+[ ]*[0-9a-f]+: db e1[ ]+fndisi.*
+[ ]*[0-9a-f]+: db e0[ ]+fneni.*
+#pass
--- 2009-07-24/gas/testsuite/gas/i386/8087.s 1970-01-01 01:00:00.000000000 +0100
+++ 2009-07-24/gas/testsuite/gas/i386/8087.s 2009-07-20 12:19:11.000000000 +0200
@@ -0,0 +1,11 @@
+# Check 8087-only instructions.
+
+ .text
+ .arch i8086
+ .arch .8087
+ .code16
+_8087:
+ fdisi
+ feni
+ fndisi
+ fneni
--- 2009-07-24/gas/testsuite/gas/i386/att-regs.d 2008-05-14 09:42:48.000000000 +0200
+++ 2009-07-24/gas/testsuite/gas/i386/att-regs.d 2009-07-24 10:10:05.000000000 +0200
@@ -13,7 +13,7 @@ Disassembly of section \.text:
.*[ ]+R_386_16[ ]+r8d
.*[ ]+R_386_16[ ]+r8
.*[ ]+R_386_16[ ]+fs
-#.*[ ]+R_386_16[ ]+st
+.*[ ]+R_386_16[ ]+st
.*[ ]+R_386_16[ ]+cr0
.*[ ]+R_386_16[ ]+dr0
.*[ ]+R_386_16[ ]+tr0
@@ -25,7 +25,7 @@ Disassembly of section \.text:
.*[ ]+R_386_32[ ]+r8w
.*[ ]+R_386_32[ ]+r8d
.*[ ]+R_386_32[ ]+r8
-#.*[ ]+R_386_32[ ]+st
+.*[ ]+R_386_32[ ]+st
.*:[ ]+0f 20 c0[ ]+mov[ ]+%cr0,%eax
.*:[ ]+0f 21 c0[ ]+mov[ ]+%db0,%eax
.*:[ ]+0f 24 c0[ ]+mov[ ]+%tr0,%eax
--- 2009-07-24/gas/testsuite/gas/i386/att-regs.s 2008-05-14 09:42:48.000000000 +0200
+++ 2009-07-24/gas/testsuite/gas/i386/att-regs.s 2009-07-24 10:10:05.000000000 +0200
@@ -11,7 +11,7 @@
mov r8d, ax ; add al, (bx,si)
mov r8, ax ; add al, (bx,si)
mov fs, ax ; add al, (bx,si)
-#todo mov st, ax ; add al, (bx,si)
+ mov st, ax ; add al, (bx,si)
mov cr0, ax ; add al, (bx,si)
mov dr0, ax ; add al, (bx,si)
mov tr0, ax ; add al, (bx,si)
@@ -26,7 +26,7 @@
mov r8w, eax
mov r8d, eax
mov r8, eax
-#todo mov st, eax
+ mov st, eax
mov cr0, eax
mov dr0, eax
mov tr0, eax
@@ -34,7 +34,7 @@
mov xmm0, eax
mov ymm0, eax
-#todo .arch i387
+ .arch .387
ffree st
.arch .mmx
--- 2009-07-24/gas/testsuite/gas/i386/i386.exp 2009-07-23 15:06:33.000000000 +0200
+++ 2009-07-24/gas/testsuite/gas/i386/i386.exp 2009-07-24 17:21:53.000000000 +0200
@@ -114,6 +114,11 @@ if [expr ([istarget "i*86-*-*"] || [ist
run_list_test "arch-10-4" "-march=i686+sse4+vmx+smx -I${srcdir}/$subdir -al"
run_dump_test "arch-11"
run_dump_test "arch-12"
+ run_dump_test "8087"
+ run_dump_test "287"
+ run_dump_test "387"
+ run_list_test "no87" "-al"
+ run_list_test "no87-2" "-march=i686+no87 -al"
run_dump_test "xsave"
run_dump_test "xsave-intel"
run_dump_test "aes"
--- 2009-07-24/gas/testsuite/gas/i386/intel-regs.d 2008-05-14 09:42:48.000000000 +0200
+++ 2009-07-24/gas/testsuite/gas/i386/intel-regs.d 2009-07-24 10:10:05.000000000 +0200
@@ -13,7 +13,7 @@ Disassembly of section \.text:
.*[ ]+R_386_16[ ]+r8d
.*[ ]+R_386_16[ ]+r8
.*[ ]+R_386_16[ ]+fs
-#.*[ ]+R_386_16[ ]+st
+.*[ ]+R_386_16[ ]+st
.*[ ]+R_386_16[ ]+cr0
.*[ ]+R_386_16[ ]+dr0
.*[ ]+R_386_16[ ]+tr0
@@ -25,7 +25,7 @@ Disassembly of section \.text:
.*[ ]+R_386_32[ ]+r8w
.*[ ]+R_386_32[ ]+r8d
.*[ ]+R_386_32[ ]+r8
-#.*[ ]+R_386_32[ ]+st
+.*[ ]+R_386_32[ ]+st
.*:[ ]+0f 20 c0[ ]+mov[ ]+%cr0,%eax
.*:[ ]+0f 21 c0[ ]+mov[ ]+%db0,%eax
.*:[ ]+0f 24 c0[ ]+mov[ ]+%tr0,%eax
--- 2009-07-24/gas/testsuite/gas/i386/intel-regs.s 2008-05-14 09:42:48.000000000 +0200
+++ 2009-07-24/gas/testsuite/gas/i386/intel-regs.s 2009-07-24 10:10:05.000000000 +0200
@@ -11,7 +11,7 @@
mov ax, r8d ; add [bx+si], al
mov ax, r8 ; add [bx+si], al
mov ax, fs ; add [bx+si], al
-#todo mov ax, st ; add [bx+si], al
+ mov ax, st ; add [bx+si], al
mov ax, cr0 ; add [bx+si], al
mov ax, dr0 ; add [bx+si], al
mov ax, tr0 ; add [bx+si], al
@@ -26,7 +26,7 @@
mov eax, r8w
mov eax, r8d
mov eax, r8
-#todo mov eax, st
+ mov eax, st
mov eax, cr0
mov eax, dr0
mov eax, tr0
@@ -34,7 +34,7 @@
mov eax, xmm0
mov eax, ymm0
-#todo .arch i387
+ .arch .387
ffree st
.arch .mmx
--- 2009-07-24/gas/testsuite/gas/i386/no87-2.l 1970-01-01 01:00:00.000000000 +0100
+++ 2009-07-24/gas/testsuite/gas/i386/no87-2.l 2009-07-24 17:15:16.000000000 +0200
@@ -0,0 +1,19 @@
+.*: Assembler messages:
+.*:3: Error: .*no87.*
+.*:6: Error: .*287.*
+.*:9: Error: .*387.*
+.*:12: Error: .*i686.*
+GAS LISTING .*
+#...
+[ ]*[1-9][0-9]*[ ]+fninit
+[ ]*[1-9][0-9]*[ ]+\.arch \.287
+[ ]*[1-9][0-9]*[ ]+\?+ DBE3[ ]+fninit
+[ ]*[1-9][0-9]*[ ]+fsincos
+[ ]*[1-9][0-9]*[ ]+\.arch \.387
+[ ]*[1-9][0-9]*[ ]+\?+ D9FB[ ]+fsincos
+[ ]*[1-9][0-9]*[ ]+fcomi
+[ ]*[1-9][0-9]*[ ]+\.arch i686
+[ ]*[1-9][0-9]*[ ]+\?+ DBF1[ ]+fcomi
+[ ]*[1-9][0-9]*[ ]+fisttpl[ ].*
+[ ]*[1-9][0-9]*[ ]+\.arch prescott
+[ ]*[1-9][0-9]*[ ]+\?+ DB08[ ]+fisttpl[ ].*
--- 2009-07-24/gas/testsuite/gas/i386/no87-2.s 1970-01-01 01:00:00.000000000 +0100
+++ 2009-07-24/gas/testsuite/gas/i386/no87-2.s 2009-07-24 17:14:22.000000000 +0200
@@ -0,0 +1,14 @@
+# Test -march=...+no87
+ .text
+ fninit
+ .arch .287
+ fninit
+ fsincos
+ .arch .387
+ fsincos
+ fcomi
+ .arch i686
+ fcomi
+ fisttpl (%eax)
+ .arch prescott
+ fisttpl (%eax)
--- 2009-07-24/gas/testsuite/gas/i386/no87.l 1970-01-01 01:00:00.000000000 +0100
+++ 2009-07-24/gas/testsuite/gas/i386/no87.l 2009-07-20 14:00:24.000000000 +0200
@@ -0,0 +1,25 @@
+.*: Assembler messages:
+.*:4: Error: .*generic.*
+.*:7: Error: .*287.*
+.*:10: Error: .*387.*
+.*:13: Error: .*i686.*
+.*:17: Error: .*no87.*
+.*:18: Error: .*no87.*
+GAS LISTING .*
+#...
+[ ]*[1-9][0-9]*[ ]+\.arch generic32
+[ ]*[1-9][0-9]*[ ]+fninit
+[ ]*[1-9][0-9]*[ ]+\.arch \.287
+[ ]*[1-9][0-9]*[ ]+\?+ DBE3[ ]+fninit
+[ ]*[1-9][0-9]*[ ]+fsincos
+[ ]*[1-9][0-9]*[ ]+\.arch \.387
+[ ]*[1-9][0-9]*[ ]+\?+ D9FB[ ]+fsincos
+[ ]*[1-9][0-9]*[ ]+fcomi
+[ ]*[1-9][0-9]*[ ]+\.arch i686
+[ ]*[1-9][0-9]*[ ]+\?+ DBF1[ ]+fcomi
+[ ]*[1-9][0-9]*[ ]+fisttpl[ ].*
+[ ]*[1-9][0-9]*[ ]+\.arch prescott
+[ ]*[1-9][0-9]*[ ]+\?+ DB08[ ]+fisttpl[ ].*
+[ ]*[1-9][0-9]*[ ]+\.arch \.no87
+[ ]*[1-9][0-9]*[ ]+fcomi
+[ ]*[1-9][0-9]*[ ]+fisttpl[ ].*
--- 2009-07-24/gas/testsuite/gas/i386/no87.s 1970-01-01 01:00:00.000000000 +0100
+++ 2009-07-24/gas/testsuite/gas/i386/no87.s 2009-07-20 13:21:48.000000000 +0200
@@ -0,0 +1,18 @@
+# Test .arch .no87
+ .text
+ .arch generic32
+ fninit
+ .arch .287
+ fninit
+ fsincos
+ .arch .387
+ fsincos
+ fcomi
+ .arch i686
+ fcomi
+ fisttpl (%eax)
+ .arch prescott
+ fisttpl (%eax)
+ .arch .no87
+ fcomi
+ fisttpl (%eax)
--- 2009-07-24/opcodes/i386-dis.c 2009-07-21 13:11:36.000000000 +0200
+++ 2009-07-24/opcodes/i386-dis.c 2009-07-24 10:10:05.000000000 +0200
@@ -10080,8 +10080,8 @@ static char *fgrps[][8] = {
/* db_4 6 */
{
- "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
- "fNsetpm(287 only)","(bad)","(bad)","(bad)",
+ "fNeni(8087 only)","fNdisi(8087 only)","fNclex","fNinit",
+ "fNsetpm(287 only)","frstpm(287 only)","(bad)","(bad)",
},
/* de_3 7 */
--- 2009-07-24/opcodes/i386-gen.c 2009-07-21 13:11:36.000000000 +0200
+++ 2009-07-24/opcodes/i386-gen.c 2009-07-24 10:13:19.000000000 +0200
@@ -47,7 +47,7 @@ static initializer cpu_flag_init[] =
{ "CPU_GENERIC32_FLAGS",
"Cpu186|Cpu286|Cpu386" },
{ "CPU_GENERIC64_FLAGS",
- "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|CpuMMX|CpuSSE|CpuSSE2|CpuLM" },
+ "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu38
More information about the Binutils
mailing list