VirtualBox

Changeset 96201 in vbox for trunk/include/iprt/nocrt/x86


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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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