VirtualBox

Changeset 96201 in vbox for trunk/include


Ignore:
Timestamp:
Aug 14, 2022 3:26:28 AM (2 years ago)
Author:
vboxsync
Message:

IPRT/nocrt: Implemented fegetround and fesetround to workaround the MSC versions not modifying FCW in 64-bit mode and impeding testing. bugref:10261

Location:
trunk/include/iprt/nocrt
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/nocrt/amd64/fenv.h

    r93115 r96201  
    8181                         FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
    8282
    83 /* Rounding modes */
     83/* Rounding modes (x87 rounding flags) */
    8484#define FE_TONEAREST    0x0000
    8585#define FE_DOWNWARD     0x0400
    8686#define FE_UPWARD       0x0800
    8787#define FE_TOWARDZERO   0x0c00
    88 #define _ROUND_MASK     (FE_TONEAREST | FE_DOWNWARD | \
    89                          FE_UPWARD | FE_TOWARDZERO)
     88#define _ROUND_MASK     0x0c00
    9089
    9190/*
     
    102101extern const fenv_t     RT_NOCRT(__fe_dfl_env);
    103102#define FE_DFL_ENV      (&__fe_dfl_env)
     103
     104#ifdef __GNUC__
    104105
    105106#define __fldcw(__cw)           __asm __volatile("fldcw %0" : : "m" (__cw))
     
    147148}
    148149
    149 int RT_NOCRT(fesetexceptflag)(const fexcept_t *__flagp, int __excepts);
    150 int RT_NOCRT(feraiseexcept)(int __excepts);
    151 
    152150DECLINLINE(int)
    153151fetestexcept(int __excepts)
     
    161159
    162160DECLINLINE(int)
    163 fegetround(void)
    164 {
    165         int __control;
    166 
    167         /*
    168          * We assume that the x87 and the SSE unit agree on the
    169          * rounding mode.  Reading the control word on the x87 turns
    170          * out to be about 5 times faster than reading it on the SSE
    171          * unit on an Opteron 244.
    172          */
    173         __fnstcw(&__control);
    174         return (__control & _ROUND_MASK);
    175 }
    176 
    177 DECLINLINE(int)
    178 fesetround(int __round)
    179 {
    180         int __mxcsr, __control;
    181 
    182         if (__round & ~_ROUND_MASK)
    183                 return (-1);
    184 
    185         __fnstcw(&__control);
    186         __control &= ~_ROUND_MASK;
    187         __control |= __round;
    188         __fldcw(__control);
    189 
    190         __stmxcsr(&__mxcsr);
    191         __mxcsr &= ~(_ROUND_MASK << _SSE_ROUND_SHIFT);
    192         __mxcsr |= __round << _SSE_ROUND_SHIFT;
    193         __ldmxcsr(__mxcsr);
    194 
    195         return (0);
    196 }
    197 
    198 int RT_NOCRT(fegetenv)(fenv_t *__envp);
    199 int RT_NOCRT(feholdexcept)(fenv_t *__envp);
    200 
    201 DECLINLINE(int)
    202161fesetenv(const fenv_t *__envp)
    203162{
     
    207166        return (0);
    208167}
    209 
    210 int RT_NOCRT(feupdateenv)(const fenv_t *__envp);
    211 int RT_NOCRT(feenableexcept)(int __mask);
    212 int RT_NOCRT(fedisableexcept)(int __mask);
    213168
    214169DECLINLINE(int)
     
    228183# pragma GCC diagnostic pop
    229184#endif
     185
     186#endif /* __GNUC__ */
     187
     188int RT_NOCRT(fesetexceptflag)(const fexcept_t *__flagp, int __excepts);
     189int RT_NOCRT(feraiseexcept)(int __excepts);
     190int RT_NOCRT(fegetround)(void);
     191int RT_NOCRT(fesetround)(int);
     192int RT_NOCRT(fegetenv)(fenv_t *__envp);
     193int RT_NOCRT(feholdexcept)(fenv_t *__envp);
     194int RT_NOCRT(feupdateenv)(const fenv_t *__envp);
     195int RT_NOCRT(feenableexcept)(int __mask);
     196int RT_NOCRT(fedisableexcept)(int __mask);
     197
    230198
    231199RT_C_DECLS_END
  • trunk/include/iprt/nocrt/x86/fenv.h

    r93115 r96201  
    8484
    8585/* Exception flags */
    86 #define FE_INVALID  0x01
    87 #define FE_DENORMAL 0x02
     86#define FE_INVALID      0x01
     87#define FE_DENORMAL     0x02
    8888#define FE_DIVBYZERO    0x04
    89 #define FE_OVERFLOW 0x08
     89#define FE_OVERFLOW     0x08
    9090#define FE_UNDERFLOW    0x10
    91 #define FE_INEXACT  0x20
    92 #define FE_ALL_EXCEPT   (FE_DIVBYZERO | FE_DENORMAL | FE_INEXACT | \
    93              FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
    94 
    95 /* Rounding modes */
     91#define FE_INEXACT      0x20
     92#define FE_ALL_EXCEPT   (FE_DIVBYZERO | FE_DENORMAL | FE_INEXACT \
     93                         | FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
     94
     95/* Rounding modes (x87 constants) */
    9696#define FE_TONEAREST    0x0000
    97 #define FE_DOWNWARD 0x0400
    98 #define FE_UPWARD   0x0800
     97#define FE_DOWNWARD     0x0400
     98#define FE_UPWARD       0x0800
    9999#define FE_TOWARDZERO   0x0c00
    100 #define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \
    101              FE_UPWARD | FE_TOWARDZERO)
     100#define _ROUND_MASK     0x0c00
    102101
    103102/*
     
    125124extern const fenv_t __fe_dfl_env;
    126125#define FE_DFL_ENV  (&__fe_dfl_env)
     126
     127#ifdef __GNUC__
    127128
    128129#define __fldcw(__cw)       __asm __volatile("fldcw %0" : : "m" (__cw))
     
    176177}
    177178
    178 int RT_NOCRT(fesetexceptflag)(const fexcept_t *__flagp, int __excepts);
    179 int RT_NOCRT(feraiseexcept)(int __excepts);
    180 
    181179DECLINLINE(int)
    182180fetestexcept(int __excepts)
     
    193191
    194192DECLINLINE(int)
    195 fegetround(void)
    196 {
    197     int __control;
    198 
    199     /*
    200      * We assume that the x87 and the SSE unit agree on the
    201      * rounding mode.  Reading the control word on the x87 turns
    202      * out to be about 5 times faster than reading it on the SSE
    203      * unit on an Opteron 244.
    204      */
    205     __fnstcw(&__control);
    206     return (__control & _ROUND_MASK);
    207 }
    208 
    209 DECLINLINE(int)
    210 fesetround(int __round)
    211 {
    212     int __mxcsr, __control;
    213 
    214     if (__round & ~_ROUND_MASK)
    215         return (-1);
    216 
    217     __fnstcw(&__control);
    218     __control &= ~_ROUND_MASK;
    219     __control |= __round;
    220     __fldcw(__control);
    221 
    222     if (__HAS_SSE()) {
    223         __stmxcsr(&__mxcsr);
    224         __mxcsr &= ~(_ROUND_MASK << _SSE_ROUND_SHIFT);
    225         __mxcsr |= __round << _SSE_ROUND_SHIFT;
    226         __ldmxcsr(__mxcsr);
    227     }
    228 
    229     return (0);
    230 }
    231 
    232 int RT_NOCRT(fegetenv)(fenv_t *__envp);
    233 int RT_NOCRT(feholdexcept)(fenv_t *__envp);
    234 
    235 DECLINLINE(int)
    236193fesetenv(const fenv_t *__envp)
    237194{
     
    247204}
    248205
    249 int RT_NOCRT(feupdateenv)(const fenv_t *__envp);
    250 int RT_NOCRT(feenableexcept)(int __mask);
    251 int RT_NOCRT(fedisableexcept)(int __mask);
    252 
    253206DECLINLINE(int)
    254207fegetexcept(void)
     
    267220# pragma GCC diagnostic pop
    268221#endif
     222
     223#endif /* __GNUC__ */
     224
     225int RT_NOCRT(fesetexceptflag)(const fexcept_t *__flagp, int __excepts);
     226int RT_NOCRT(feraiseexcept)(int __excepts);
     227int RT_NOCRT(fegetround)(void);
     228int RT_NOCRT(fesetround)(int);
     229int RT_NOCRT(fegetenv)(fenv_t *__envp);
     230int RT_NOCRT(feholdexcept)(fenv_t *__envp);
     231int RT_NOCRT(feupdateenv)(const fenv_t *__envp);
     232int RT_NOCRT(feenableexcept)(int __mask);
     233int RT_NOCRT(fedisableexcept)(int __mask);
     234
    269235
    270236RT_C_DECLS_END
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette