On Wed, Dec 4, 2013 at 5:59 PM, Kirill Yukhin <kirill.yuk...@gmail.com> wrote:

> MSVC and ICC (currently Windows version, Linux version soon) have
> dedicated intrinsics to read/set EFLAGS register ([1], [2]).
>
> Patch introduces these intrinsics and tests for them.
>
> Bootstrapped. New tests pass.
> Although gate is closed patch is obvious.
> So, is it ok for trunk?
>
> ChangeLog/
>         * config/i386/ia32intrin.h (__readeflags): New.
>         (__writeeflags): Ditto.
>
> testsuite/ChangeLog/
>         * gcc.target/i386/readeflags-1.c: New.
>         * gcc.target/i386/writeeflags-1.c: Ditto.
>
> [1] - http://msdn.microsoft.com/en-us/library/aa983406(v=vs.90).aspx
> [2] - http://msdn.microsoft.com/en-us/library/aa983392(v=vs.90).aspx
>
> --
> Thanks, K
>
> diff --git a/gcc/config/i386/ia32intrin.h b/gcc/config/i386/ia32intrin.h
> index b26dc46..c9e68c5 100644
> --- a/gcc/config/i386/ia32intrin.h
> +++ b/gcc/config/i386/ia32intrin.h
> @@ -238,6 +238,34 @@ __rorq (unsigned long long __X, int __C)
>    return (__X >> __C) | (__X << (64 - __C));
>  }
>
> +/* Read flags register */
> +extern __inline unsigned long long
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__readeflags (void)
> +{
> +  unsigned long long result = 0;
> +  __asm__ __volatile__ ("pushf\n\t"
> +                       "popq %0\n"
> +                       :"=r"(result)
> +                       :
> +                       :
> +                       );
> +  return result;
> +}
> +
> +/* Write flags register */
> +extern __inline void
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__writeeflags (unsigned long long X)
> +{
> +  __asm__ __volatile__ ("pushq %0\n\t"
> +                       "popf\n"
> +                       :
> +                       :"r"(X)
> +                       :"flags"
> +                       );
> +}
> +

Oh, no. We don't want assembly in this century ;)

The proper implementation is to introduce a
__builtin_readflags/__builtin_writeflags that expand the sequence by
calling gen_push and gen_pop functions.

You will need new patterns for pushfl and popfl, something like:

(define_insn "*pushfl<mode>"
  [(set (match_operand:DWIH 0 "push_operand" "=<")
    (match_operand:DWIH 0 "flags_reg_operand"))]
  ""
  "pushf{<mode>}"
  [(set_attr "type" "push")
   (set_attr "mode" "<MODE>")])

(define_insn "*popfl<mode>1"
  [(set (match_operand:DWIH 0 "flags_reg_operand")
    (match_operand:DWIH 1 "pop_operand" ">"))]
  ""
  "popf{<imodesuffix>}\t%0"
  [(set_attr "type" "pop")
   (set_attr "mode" "<MODE>")])

Uros.

Reply via email to