On Tuesday 13 January 2026 16:09:09 LIU Hao wrote:
> 在 2025-12-28 02:32, Pali Rohár 写道:
> > x87 fldcw instruction triggers pending x87 exception. So if there is a
> > pending x87 exception and __mingw_setfp() is trying to disable some other
> > x87 type then it will trigger pending exception.
> > 
> > There is no non-waiting variant of x87 fldcw instruction. So for setting
> > new control word use x87 fldenv instruction like for setting new status
> > word. For using x87 fldenv instruction it is first need to load whole
> > x87 env via x87 fnstenv instruction.
> > 
> > Optimize code to not use x87 fnstenv when it is known that x87 fldenv would
> > not be used - when cw_mask or sw_mask is empty (used just for quering 
> > cw/sw).
> > ---
> >   mingw-w64-crt/misc/mingw_setfp.c | 63 +++++++++++++++++++-------------
> >   1 file changed, 38 insertions(+), 25 deletions(-)
> > 
> > diff --git a/mingw-w64-crt/misc/mingw_setfp.c 
> > b/mingw-w64-crt/misc/mingw_setfp.c
> > index fb03781292ce..2298515128b5 100644
> > --- a/mingw-w64-crt/misc/mingw_setfp.c
> > +++ b/mingw-w64-crt/misc/mingw_setfp.c
> > ...
> > +    if ((!sw || sw_mask == 0) && (!cw || cw_mask == 0))
> > +    {
> > +        /* Fast path: when we are not going to change sw/cw which is 
> > indicated
> > +         * by zero mask then load sw/cw via fast fnstsw/fnstcw instruction.
> > +         */
> > +        if (sw && sw_mask == 0)
> > +            __asm__ __volatile__( "fnstsw %0" : "=m" (newsw) );
> > +        if (cw && cw_mask == 0)
> > +            __asm__ __volatile__( "fnstcw %0" : "=m" (newcw) );
> > +    }
> > +    else
> > +    {
> > +        /* Slow path: when we are going to change sw/cw or we do not know 
> > yet then
> > +         * load whole x87 env via slow fnstenv as it is needed for 
> > changing sw/cw.
> > +         */
> > +        __asm__ __volatile__( "fnstenv %0" : "=m" (fenv) );
> > +        newsw = fenv.status_word;
> > +        newcw = fenv.control_word;
> > +    }
> > +
> >       if (sw)
> >       {
> > -        __asm__ __volatile__( "fnstsw %0" : "=m" (newsw) );
> >           oldsw = newsw;
> > 
> At a first glance this doesn't look quite correct: When `sw` is null, `cw`
> is non-null and `cw_mask` is non-zero, this takes the slow path, and leaves
> `newsw` as zero, and eventually zeroes the status word.
> 
> Since the use of FLDENV is subject to a change in either word, it's
> necessary to initialize {old,new}{cw,sw} unconditionally.

Yes, you are right. I tried to make the change minimal but forgot about that.

> I'm testing this series of patches with this change for now:
> 
> 
> diff --git a/mingw-w64-crt/misc/mingw_setfp.c 
> b/mingw-w64-crt/misc/mingw_setfp.c
> index 229851512..dcd767d9a 100644
> --- a/mingw-w64-crt/misc/mingw_setfp.c
> +++ b/mingw-w64-crt/misc/mingw_setfp.c
> @@ -144,10 +144,8 @@ void __mingw_setfp( unsigned int *cw, unsigned int 
> cw_mask,
>          /* Fast path: when we are not going to change sw/cw which is 
> indicated
>           * by zero mask then load sw/cw via fast fnstsw/fnstcw instruction.
>           */
> -        if (sw && sw_mask == 0)
> -            __asm__ __volatile__( "fnstsw %0" : "=m" (newsw) );
> -        if (cw && cw_mask == 0)
> -            __asm__ __volatile__( "fnstcw %0" : "=m" (newcw) );
> +        __asm__ __volatile__( "fnstsw %0" : "=m" (newsw) );
> +        __asm__ __volatile__( "fnstcw %0" : "=m" (newcw) );
>      }
>      else
>      {
> @@ -159,10 +157,11 @@ void __mingw_setfp( unsigned int *cw, unsigned int 
> cw_mask,
>          newcw = fenv.control_word;
>      }
> 
> +    oldsw = newsw;
> +    oldcw = newcw;
> +
>      if (sw)
>      {
> -        oldsw = newsw;
> -
>          flags = 0;
>          if (newsw & 0x1) flags |= _SW_INVALID;
>          if (newsw & 0x2) flags |= _SW_DENORMAL;
> @@ -184,8 +183,6 @@ void __mingw_setfp( unsigned int *cw, unsigned int 
> cw_mask,
> 
>      if (cw)
>      {
> -        oldcw = newcw;
> -
>          flags = 0;
>          if (newcw & 0x1) flags |= _EM_INVALID;
>          if (newcw & 0x2) flags |= _EM_DENORMAL;
> 
> 
> 
> 
> -- 
> Best regards,
> LIU Hao
> 


_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to