[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