Resolve conflicts between macros in fenv.h and ieeefp.h

This is a follow-up to r321483, which disabled -Wmacro-redefined for
some lib/msun tests.

If an application included both fenv.h and ieeefp.h, several macros such
as __fldcw(), __fldenv() were defined in both headers, with slightly
different arguments, leading to conflicts.

Fix this by putting all the common macros in the machine-specific
versions of ieeefp.h.  Where needed, update the arguments in places
where the macros are invoked.

This also slightly reduces the differences between the amd64 and i386
versions of ieeefp.h.

Reviewed by:	kib
MFC after:	1 week
Differential Revision: https://reviews.freebsd.org/D15633
This commit is contained in:
Dimitry Andric 2018-05-31 20:22:47 +00:00
parent f93497fe64
commit b451efbedc
6 changed files with 30 additions and 38 deletions

View File

@ -60,12 +60,12 @@ fesetexceptflag(const fexcept_t *flagp, int excepts)
__fnstenv(&env.__x87); __fnstenv(&env.__x87);
env.__x87.__status &= ~excepts; env.__x87.__status &= ~excepts;
env.__x87.__status |= *flagp & excepts; env.__x87.__status |= *flagp & excepts;
__fldenv(env.__x87); __fldenv(&env.__x87);
__stmxcsr(&env.__mxcsr); __stmxcsr(&env.__mxcsr);
env.__mxcsr &= ~excepts; env.__mxcsr &= ~excepts;
env.__mxcsr |= *flagp & excepts; env.__mxcsr |= *flagp & excepts;
__ldmxcsr(env.__mxcsr); __ldmxcsr(&env.__mxcsr);
return (0); return (0);
} }
@ -94,7 +94,7 @@ fegetenv(fenv_t *envp)
* fnstenv masks all exceptions, so we need to restore the * fnstenv masks all exceptions, so we need to restore the
* control word to avoid this side effect. * control word to avoid this side effect.
*/ */
__fldcw(envp->__x87.__control); __fldcw(&envp->__x87.__control);
return (0); return (0);
} }
@ -109,7 +109,7 @@ feholdexcept(fenv_t *envp)
envp->__mxcsr = mxcsr; envp->__mxcsr = mxcsr;
mxcsr &= ~FE_ALL_EXCEPT; mxcsr &= ~FE_ALL_EXCEPT;
mxcsr |= FE_ALL_EXCEPT << _SSE_EMASK_SHIFT; mxcsr |= FE_ALL_EXCEPT << _SSE_EMASK_SHIFT;
__ldmxcsr(mxcsr); __ldmxcsr(&mxcsr);
return (0); return (0);
} }
@ -139,9 +139,9 @@ __feenableexcept(int mask)
__stmxcsr(&mxcsr); __stmxcsr(&mxcsr);
omask = ~(control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT; omask = ~(control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT;
control &= ~mask; control &= ~mask;
__fldcw(control); __fldcw(&control);
mxcsr &= ~(mask << _SSE_EMASK_SHIFT); mxcsr &= ~(mask << _SSE_EMASK_SHIFT);
__ldmxcsr(mxcsr); __ldmxcsr(&mxcsr);
return (omask); return (omask);
} }
@ -156,9 +156,9 @@ __fedisableexcept(int mask)
__stmxcsr(&mxcsr); __stmxcsr(&mxcsr);
omask = ~(control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT; omask = ~(control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT;
control |= mask; control |= mask;
__fldcw(control); __fldcw(&control);
mxcsr |= mask << _SSE_EMASK_SHIFT; mxcsr |= mask << _SSE_EMASK_SHIFT;
__ldmxcsr(mxcsr); __ldmxcsr(&mxcsr);
return (omask); return (omask);
} }

View File

@ -103,13 +103,13 @@ fesetexceptflag(const fexcept_t *flagp, int excepts)
__fnstenv(&env); __fnstenv(&env);
env.__status &= ~excepts; env.__status &= ~excepts;
env.__status |= *flagp & excepts; env.__status |= *flagp & excepts;
__fldenv(env); __fldenv(&env);
if (__HAS_SSE()) { if (__HAS_SSE()) {
__stmxcsr(&mxcsr); __stmxcsr(&mxcsr);
mxcsr &= ~excepts; mxcsr &= ~excepts;
mxcsr |= *flagp & excepts; mxcsr |= *flagp & excepts;
__ldmxcsr(mxcsr); __ldmxcsr(&mxcsr);
} }
return (0); return (0);
@ -139,7 +139,7 @@ fegetenv(fenv_t *envp)
* fnstenv masks all exceptions, so we need to restore * fnstenv masks all exceptions, so we need to restore
* the old control word to avoid this side effect. * the old control word to avoid this side effect.
*/ */
__fldcw(envp->__control); __fldcw(&envp->__control);
if (__HAS_SSE()) { if (__HAS_SSE()) {
__stmxcsr(&mxcsr); __stmxcsr(&mxcsr);
__set_mxcsr(*envp, mxcsr); __set_mxcsr(*envp, mxcsr);
@ -159,7 +159,7 @@ feholdexcept(fenv_t *envp)
__set_mxcsr(*envp, mxcsr); __set_mxcsr(*envp, mxcsr);
mxcsr &= ~FE_ALL_EXCEPT; mxcsr &= ~FE_ALL_EXCEPT;
mxcsr |= FE_ALL_EXCEPT << _SSE_EMASK_SHIFT; mxcsr |= FE_ALL_EXCEPT << _SSE_EMASK_SHIFT;
__ldmxcsr(mxcsr); __ldmxcsr(&mxcsr);
} }
return (0); return (0);
} }
@ -196,10 +196,10 @@ __feenableexcept(int mask)
mxcsr = 0; mxcsr = 0;
omask = ~(control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT; omask = ~(control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT;
control &= ~mask; control &= ~mask;
__fldcw(control); __fldcw(&control);
if (__HAS_SSE()) { if (__HAS_SSE()) {
mxcsr &= ~(mask << _SSE_EMASK_SHIFT); mxcsr &= ~(mask << _SSE_EMASK_SHIFT);
__ldmxcsr(mxcsr); __ldmxcsr(&mxcsr);
} }
return (omask); return (omask);
} }
@ -218,10 +218,10 @@ __fedisableexcept(int mask)
mxcsr = 0; mxcsr = 0;
omask = ~(control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT; omask = ~(control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT;
control |= mask; control |= mask;
__fldcw(control); __fldcw(&control);
if (__HAS_SSE()) { if (__HAS_SSE()) {
mxcsr |= mask << _SSE_EMASK_SHIFT; mxcsr |= mask << _SSE_EMASK_SHIFT;
__ldmxcsr(mxcsr); __ldmxcsr(&mxcsr);
} }
return (omask); return (omask);
} }

View File

@ -84,10 +84,6 @@ SRCS.ilogb2_test= ilogb_test.c
LIBADD+= m LIBADD+= m
.if ${MACHINE_CPUARCH} == "i386"
# XXX: __fldcw macro mismatch between fenv.h and ieeefp.h .
CWARNFLAGS.clang+= -Wno-error=macro-redefined
.endif
WARNS?= 1 WARNS?= 1
# Copied from lib/msun/Makefile # Copied from lib/msun/Makefile

View File

@ -33,6 +33,7 @@
#include <sys/cdefs.h> #include <sys/cdefs.h>
#include <sys/_types.h> #include <sys/_types.h>
#include <ieeefp.h>
#ifndef __fenv_static #ifndef __fenv_static
#define __fenv_static static #define __fenv_static static
@ -97,18 +98,10 @@ __BEGIN_DECLS
extern const fenv_t __fe_dfl_env; extern const fenv_t __fe_dfl_env;
#define FE_DFL_ENV (&__fe_dfl_env) #define FE_DFL_ENV (&__fe_dfl_env)
#define __fldcw(__cw) __asm __volatile("fldcw %0" : : "m" (__cw))
#define __fldenv(__env) __asm __volatile("fldenv %0" : : "m" (__env))
#define __fldenvx(__env) __asm __volatile("fldenv %0" : : "m" (__env) \ #define __fldenvx(__env) __asm __volatile("fldenv %0" : : "m" (__env) \
: "st", "st(1)", "st(2)", "st(3)", "st(4)", \ : "st", "st(1)", "st(2)", "st(3)", "st(4)", \
"st(5)", "st(6)", "st(7)") "st(5)", "st(6)", "st(7)")
#define __fnclex() __asm __volatile("fnclex")
#define __fnstenv(__env) __asm __volatile("fnstenv %0" : "=m" (*(__env)))
#define __fnstcw(__cw) __asm __volatile("fnstcw %0" : "=m" (*(__cw)))
#define __fnstsw(__sw) __asm __volatile("fnstsw %0" : "=am" (*(__sw)))
#define __fwait() __asm __volatile("fwait") #define __fwait() __asm __volatile("fwait")
#define __ldmxcsr(__csr) __asm __volatile("ldmxcsr %0" : : "m" (__csr))
#define __stmxcsr(__csr) __asm __volatile("stmxcsr %0" : "=m" (*(__csr)))
int fegetenv(fenv_t *__envp); int fegetenv(fenv_t *__envp);
int feholdexcept(fenv_t *__envp); int feholdexcept(fenv_t *__envp);
@ -183,12 +176,12 @@ feclearexcept(int __excepts)
} else { } else {
__fnstenv(&__env); __fnstenv(&__env);
__env.__status &= ~__excepts; __env.__status &= ~__excepts;
__fldenv(__env); __fldenv(&__env);
} }
if (__HAS_SSE()) { if (__HAS_SSE()) {
__stmxcsr(&__mxcsr); __stmxcsr(&__mxcsr);
__mxcsr &= ~__excepts; __mxcsr &= ~__excepts;
__ldmxcsr(__mxcsr); __ldmxcsr(&__mxcsr);
} }
return (0); return (0);
} }
@ -234,13 +227,13 @@ fesetround(int __round)
__fnstcw(&__control); __fnstcw(&__control);
__control &= ~_ROUND_MASK; __control &= ~_ROUND_MASK;
__control |= __round; __control |= __round;
__fldcw(__control); __fldcw(&__control);
if (__HAS_SSE()) { if (__HAS_SSE()) {
__stmxcsr(&__mxcsr); __stmxcsr(&__mxcsr);
__mxcsr &= ~(_ROUND_MASK << _SSE_ROUND_SHIFT); __mxcsr &= ~(_ROUND_MASK << _SSE_ROUND_SHIFT);
__mxcsr |= __round << _SSE_ROUND_SHIFT; __mxcsr |= __round << _SSE_ROUND_SHIFT;
__ldmxcsr(__mxcsr); __ldmxcsr(&__mxcsr);
} }
return (0); return (0);
@ -264,7 +257,7 @@ fesetenv(const fenv_t *__envp)
*/ */
__fldenvx(__env); __fldenvx(__env);
if (__HAS_SSE()) if (__HAS_SSE())
__ldmxcsr(__mxcsr); __ldmxcsr(&__mxcsr);
return (0); return (0);
} }
@ -280,11 +273,11 @@ feclearexcept(int __excepts)
} else { } else {
__fnstenv(&__env.__x87); __fnstenv(&__env.__x87);
__env.__x87.__status &= ~__excepts; __env.__x87.__status &= ~__excepts;
__fldenv(__env.__x87); __fldenv(&__env.__x87);
} }
__stmxcsr(&__env.__mxcsr); __stmxcsr(&__env.__mxcsr);
__env.__mxcsr &= ~__excepts; __env.__mxcsr &= ~__excepts;
__ldmxcsr(__env.__mxcsr); __ldmxcsr(&__env.__mxcsr);
return (0); return (0);
} }
@ -323,12 +316,12 @@ fesetround(int __round)
__fnstcw(&__control); __fnstcw(&__control);
__control &= ~_ROUND_MASK; __control &= ~_ROUND_MASK;
__control |= __round; __control |= __round;
__fldcw(__control); __fldcw(&__control);
__stmxcsr(&__mxcsr); __stmxcsr(&__mxcsr);
__mxcsr &= ~(_ROUND_MASK << _SSE_ROUND_SHIFT); __mxcsr &= ~(_ROUND_MASK << _SSE_ROUND_SHIFT);
__mxcsr |= __round << _SSE_ROUND_SHIFT; __mxcsr |= __round << _SSE_ROUND_SHIFT;
__ldmxcsr(__mxcsr); __ldmxcsr(&__mxcsr);
return (0); return (0);
} }
@ -346,7 +339,7 @@ fesetenv(const fenv_t *__envp)
* inlined, so we need to be more careful. * inlined, so we need to be more careful.
*/ */
__fldenvx(__envp->__x87); __fldenvx(__envp->__x87);
__ldmxcsr(__envp->__mxcsr); __ldmxcsr(&__envp->__mxcsr);
return (0); return (0);
} }

View File

@ -130,6 +130,7 @@ typedef enum {
#define __fldcw(addr) __asm __volatile("fldcw %0" : : "m" (*(addr))) #define __fldcw(addr) __asm __volatile("fldcw %0" : : "m" (*(addr)))
#define __fldenv(addr) __asm __volatile("fldenv %0" : : "m" (*(addr))) #define __fldenv(addr) __asm __volatile("fldenv %0" : : "m" (*(addr)))
#define __fnclex() __asm __volatile("fnclex")
#define __fnstcw(addr) __asm __volatile("fnstcw %0" : "=m" (*(addr))) #define __fnstcw(addr) __asm __volatile("fnstcw %0" : "=m" (*(addr)))
#define __fnstenv(addr) __asm __volatile("fnstenv %0" : "=m" (*(addr))) #define __fnstenv(addr) __asm __volatile("fnstenv %0" : "=m" (*(addr)))
#define __fnstsw(addr) __asm __volatile("fnstsw %0" : "=m" (*(addr))) #define __fnstsw(addr) __asm __volatile("fnstsw %0" : "=m" (*(addr)))

View File

@ -116,6 +116,8 @@ typedef enum {
#define __fnstcw(addr) __asm __volatile("fnstcw %0" : "=m" (*(addr))) #define __fnstcw(addr) __asm __volatile("fnstcw %0" : "=m" (*(addr)))
#define __fnstenv(addr) __asm __volatile("fnstenv %0" : "=m" (*(addr))) #define __fnstenv(addr) __asm __volatile("fnstenv %0" : "=m" (*(addr)))
#define __fnstsw(addr) __asm __volatile("fnstsw %0" : "=m" (*(addr))) #define __fnstsw(addr) __asm __volatile("fnstsw %0" : "=m" (*(addr)))
#define __ldmxcsr(addr) __asm __volatile("ldmxcsr %0" : : "m" (*(addr)))
#define __stmxcsr(addr) __asm __volatile("stmxcsr %0" : "=m" (*(addr)))
/* /*
* Load the control word. Be careful not to trap if there is a currently * Load the control word. Be careful not to trap if there is a currently