+2020-05-06 Uroš Bizjak <ubizjak@gmail.com>
+
+ * config/x86/fenv.c (__math_force_eval): Remove.
+ (__math_force_eval_div): New define.
+ (__atomic_deraiseexcept): Use __math_force_eval_div to use
+ generic division to generate INVALID, DIVZERO and INEXACT
+ exceptions.
+
2020-05-01 Uroš Bizjak <ubizjak@gmail.com>
* config/x86/fenv.c (__math_force_eval): New define.
- (__atomic_feraiseexcept): Use __math_force_eval to evaluete
+ (__atomic_feraiseexcept): Use __math_force_eval to evaluate
generic division to generate INVALID and DIVZERO exceptions.
2020-04-19 Uroš Bizjak <ubizjak@gmail.com>
};
#ifdef __SSE_MATH__
-# define __math_force_eval(x) asm volatile ("" : : "x" (x));
+# define __math_force_eval_div(x, y) \
+ do { asm ("" : "+x" (x)); asm volatile ("" : : "x" (x / y)); } while (0)
#else
-# define __math_force_eval(x) asm volatile ("" : : "f" (x));
+# define __math_force_eval_div(x, y) \
+ do { asm ("" : "+t" (x)); asm volatile ("" : : "f" (x / y)); } while (0)
#endif
/* Raise the supported floating-point exceptions from EXCEPTS. Other
void
__atomic_feraiseexcept (int excepts)
{
+ struct fenv temp;
+
if (excepts & FE_INVALID)
{
float f = 0.0f;
- __math_force_eval (f / f);
+ __math_force_eval_div (f, f);
}
if (excepts & FE_DENORM)
{
- struct fenv temp;
asm volatile ("fnstenv\t%0" : "=m" (temp));
temp.__status_word |= FE_DENORM;
asm volatile ("fldenv\t%0" : : "m" (temp));
if (excepts & FE_DIVBYZERO)
{
float f = 1.0f, g = 0.0f;
- __math_force_eval (f / g);
+ __math_force_eval_div (f, g);
}
if (excepts & FE_OVERFLOW)
{
- struct fenv temp;
asm volatile ("fnstenv\t%0" : "=m" (temp));
temp.__status_word |= FE_OVERFLOW;
asm volatile ("fldenv\t%0" : : "m" (temp));
}
if (excepts & FE_UNDERFLOW)
{
- struct fenv temp;
asm volatile ("fnstenv\t%0" : "=m" (temp));
temp.__status_word |= FE_UNDERFLOW;
asm volatile ("fldenv\t%0" : : "m" (temp));
if (excepts & FE_INEXACT)
{
float f = 1.0f, g = 3.0f;
-#ifdef __SSE_MATH__
- asm volatile ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g));
-#else
- asm volatile ("fdivs\t%1" : "+t" (f) : "m" (g));
- /* No need for fwait, exception is triggered by emitted fstp. */
-#endif
+ __math_force_eval_div (f, g);
}
}
+2020-05-06 Uroš Bizjak <ubizjak@gmail.com>
+
+ * config/i386/sfp-exceptions.c (__math_force_eval): Remove.
+ (__math_force_eval_div): New define.
+ (__sfp_handle_exceptions): Use __math_force_eval_div to use
+ generic division to generate INVALID, DIVZERO and INEXACT
+ exceptions.
+
2020-05-06 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/aarch64/lse-init.c (init_have_lse_atomics): Use __getauxval
2020-05-01 Uroš Bizjak <ubizjak@gmail.com>
* config/i386/sfp-exceptions.c (__math_force_eval): New define.
- (__sfp_handle_exceptions): Use __math_force_eval to evaluete
+ (__sfp_handle_exceptions): Use __math_force_eval to evaluate
generic division to generate INVALID and DIVZERO exceptions.
2020-04-27 Sebastian Huber <sebastian.huber@embedded-brains.de>
};
#ifdef __SSE_MATH__
-# define __math_force_eval(x) asm volatile ("" : : "x" (x));
+# define __math_force_eval_div(x, y) \
+ do { asm ("" : "+x" (x)); asm volatile ("" : : "x" (x / y)); } while (0)
#else
-# define __math_force_eval(x) asm volatile ("" : : "f" (x));
+# define __math_force_eval_div(x, y) \
+ do { asm ("" : "+t" (x)); asm volatile ("" : : "f" (x / y)); } while (0)
#endif
void
__sfp_handle_exceptions (int _fex)
{
+ struct fenv temp;
+
if (_fex & FP_EX_INVALID)
{
float f = 0.0f;
- __math_force_eval (f / f);
+ __math_force_eval_div (f, f);
}
if (_fex & FP_EX_DENORM)
{
- struct fenv temp;
asm volatile ("fnstenv\t%0" : "=m" (temp));
temp.__status_word |= FP_EX_DENORM;
asm volatile ("fldenv\t%0" : : "m" (temp));
if (_fex & FP_EX_DIVZERO)
{
float f = 1.0f, g = 0.0f;
- __math_force_eval (f / g);
+ __math_force_eval_div (f, g);
}
if (_fex & FP_EX_OVERFLOW)
{
- struct fenv temp;
asm volatile ("fnstenv\t%0" : "=m" (temp));
temp.__status_word |= FP_EX_OVERFLOW;
asm volatile ("fldenv\t%0" : : "m" (temp));
}
if (_fex & FP_EX_UNDERFLOW)
{
- struct fenv temp;
asm volatile ("fnstenv\t%0" : "=m" (temp));
temp.__status_word |= FP_EX_UNDERFLOW;
asm volatile ("fldenv\t%0" : : "m" (temp));
if (_fex & FP_EX_INEXACT)
{
float f = 1.0f, g = 3.0f;
-#ifdef __SSE_MATH__
- asm volatile ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g));
-#else
- asm volatile ("fdivs\t%1" : "+t" (f) : "m" (g));
- /* No need for fwait, exception is triggered by emitted fstp. */
-#endif
+ __math_force_eval_div (f, g);
}
}
#endif
+2020-05-06 Uroš Bizjak <ubizjak@gmail.com>
+
+ * config/fpu-387.h (__math_force_eval): Remove.
+ (__math_force_eval_div): New define.
+ (local_feraiseexcept): Use __math_force_eval_div to use
+ generic division to generate INVALID, DIVZERO and INEXACT
+ exceptions.
+ (struct fenv): Define named struct instead of typedef.
+
2020-05-01 Uroš Bizjak <ubizjak@gmail.com>
* config/fpu-387.h (__math_force_eval): New define.
- (local_feraiseexcept): Use __math_force_eval to evaluete
+ (local_feraiseexcept): Use __math_force_eval to evaluate
generic division to generate INVALID and DIVZERO exceptions.
2020-04-22 Fritz Reese <foreese@gcc.gnu.org>
/* This structure corresponds to the layout of the block
written by FSTENV. */
-typedef struct
+struct fenv
{
unsigned short int __control_word;
unsigned short int __unused1;
unsigned short int __unused3;
unsigned int __eip;
unsigned short int __cs_selector;
- unsigned short int __opcode;
+ unsigned int __opcode:11;
+ unsigned int __unused4:5;
unsigned int __data_offset;
unsigned short int __data_selector;
unsigned short int __unused5;
unsigned int __mxcsr;
-}
-my_fenv_t;
+};
/* Check we can actually store the FPU state in the allocated size. */
-_Static_assert (sizeof(my_fenv_t) <= (size_t) GFC_FPE_STATE_BUFFER_SIZE,
+_Static_assert (sizeof(struct fenv) <= (size_t) GFC_FPE_STATE_BUFFER_SIZE,
"GFC_FPE_STATE_BUFFER_SIZE is too small");
#ifdef __SSE_MATH__
-# define __math_force_eval(x) __asm__ __volatile__ ("" : : "x" (x));
+# define __math_force_eval_div(x, y) \
+ do { \
+ __asm__ ("" : "+x" (x)); __asm__ __volatile__ ("" : : "x" (x / y)); \
+ } while (0)
#else
-# define __math_force_eval(x) __asm__ __volatile__ ("" : : "f" (x));
+# define __math_force_eval_div(x, y) \
+ do { \
+ __asm__ ("" : "+t" (x)); __asm__ __volatile__ ("" : : "f" (x / y)); \
+ } while (0)
#endif
/* Raise the supported floating-point exceptions from EXCEPTS. Other
static void
local_feraiseexcept (int excepts)
{
+ struct fenv temp;
+
if (excepts & _FPU_MASK_IM)
{
float f = 0.0f;
- __math_force_eval (f / f);
+ __math_force_eval_div (f, f);
}
if (excepts & _FPU_MASK_DM)
{
- my_fenv_t temp;
__asm__ __volatile__ ("fnstenv\t%0" : "=m" (temp));
temp.__status_word |= _FPU_MASK_DM;
__asm__ __volatile__ ("fldenv\t%0" : : "m" (temp));
if (excepts & _FPU_MASK_ZM)
{
float f = 1.0f, g = 0.0f;
- __math_force_eval (f / g);
+ __math_force_eval_div (f, g);
}
if (excepts & _FPU_MASK_OM)
{
- my_fenv_t temp;
__asm__ __volatile__ ("fnstenv\t%0" : "=m" (temp));
temp.__status_word |= _FPU_MASK_OM;
__asm__ __volatile__ ("fldenv\t%0" : : "m" (temp));
}
if (excepts & _FPU_MASK_UM)
{
- my_fenv_t temp;
__asm__ __volatile__ ("fnstenv\t%0" : "=m" (temp));
temp.__status_word |= _FPU_MASK_UM;
__asm__ __volatile__ ("fldenv\t%0" : : "m" (temp));
if (excepts & _FPU_MASK_PM)
{
float f = 1.0f, g = 3.0f;
-#ifdef __SSE_MATH__
- __asm__ __volatile__ ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g));
-#else
- __asm__ __volatile__ ("fdivs\t%1" : "+t" (f) : "m" (g));
- /* No need for fwait, exception is triggered by emitted fstp. */
-#endif
+ __math_force_eval_div (f, g);
}
}
void
set_fpu_except_flags (int set, int clear)
{
- my_fenv_t temp;
+ struct fenv temp;
int exc_set = 0, exc_clr = 0;
/* Translate from GFC_PE_* values to _FPU_MASK_* values. */
void
get_fpu_state (void *state)
{
- my_fenv_t *envp = state;
+ struct fenv *envp = state;
__asm__ __volatile__ ("fnstenv\t%0" : "=m" (*envp));
void
set_fpu_state (void *state)
{
- my_fenv_t *envp = state;
+ struct fenv *envp = state;
/* glibc sources (sysdeps/x86_64/fpu/fesetenv.c) do something more
complex than this, but I think it suffices in our case. */