c75772e3f0
On platforms where long double used to have the same format as double, but later switched to a different format (alpha, s390, sparc, and powerpc), accessing the older behavior is possible and it happens via __nldbl_* functions (not on the API, but accessible from header redirection and from compat symbols). These functions write to the global flag __ldbl_is_dbl, which tells other functions that long double variables should be handled as double. This patch takes the first step towards removing this global flag and creates __vstrfmon_l_internal, which takes an explicit flags parameter. This change arguably makes the generated code slightly worse on architectures where __ldbl_is_dbl is never true; right now, on those architectures, it's a compile-time constant; after this change, the compiler could theoretically prove that __vstrfmon_l_internal was never called with a nonzero flags argument, but it would probably need LTO to do it. This is not performance critical code and I tend to think that the maintainability benefits of removing action at a distance are worth it. However, we _could_ wrap the runtime flag check with a macro that was defined to ignore its argument and always return false on architectures where __ldbl_is_dbl is never true, if people think the codegen benefits are important. Tested for powerpc and powerpc64le.
20 lines
567 B
C
20 lines
567 B
C
#include <stdlib/monetary.h>
|
|
#ifndef _ISOMAC
|
|
#include <stdarg.h>
|
|
|
|
extern ssize_t
|
|
__vstrfmon_l_internal (char *s, size_t maxsize, locale_t loc,
|
|
const char *format, va_list ap,
|
|
unsigned int flags)
|
|
attribute_hidden;
|
|
|
|
/* Flags for __vstrfmon_l_internal.
|
|
|
|
STRFMON_LDBL_IS_DBL is a one-bit mask for the flags parameter that
|
|
indicates whether long double values are to be handled as having the
|
|
same format as double, in which case the flag should be set to one,
|
|
or as another format, otherwise. */
|
|
#define STRFMON_LDBL_IS_DBL 0x0001
|
|
|
|
#endif
|