[PATCH] x86: conditionalize x87 instructions and registers
H.J. Lu
hjl.tools@gmail.com
Fri Jul 24 14:25:00 GMT 2009
On Fri, Jul 24, 2009 at 3:05 AM, Jan Beulich<JBeulich@novell.com> wrote:
> Just like with MMX, SSE, and AVX, FPU instructions and registers should
> not be available for certain architecture settings, so that programmers
> at least have the option of enforcing discipline on themselves.
>
> Along with the core changes to accomplish this, the patch also adds
> directives to selectively disable FPU, MMX, SSE, and AVX - with the
> primary goal to have a way to make the respectively added registers
> inaccessible (and available for use as normal symbols when not
> requiring register prefixes).
>
> 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.
> (parse_real_register): Don't return floating point register
> when x87 functionality is disabled.
>
> gas/testsuite/
> 2009-07-24 Jan Beulich <jbeulich@novell.com>
>
> * gas/i386/287.[ds]: New.
> * gas/i386/8087.[ds]: New.
> * gas/i386/no87.[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 10:10:05.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;
> +
I assume FISTTP > 687 > 387 > 287 > 8087. If it is
the case, please change it to
if (r->reg_type.bitfield.floatreg && !cpu_arch_flags.bitfield.cpu8087)
return (const reg_entry *) NULL;
OK with this change.
Thanks.
H.J.
--
H.J.
More information about the Binutils
mailing list