From dd33e89fb2693e88ba64e6b947184c5abf70ff00 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 17 Apr 1997 15:10:04 +0000 Subject: Update. 1997-04-17 16:55 Ulrich Drepper * misc/libgen.h: Change prototype for of basename to XPG variant. * stdlib/Makefile (routines): Add xpg_basename. * stdlib/basename.c: New file. * string/string.h: Don't declare basename function if basename macro is available. 1997-04-16 17:33 Miles Bader * login/utmp_file.c (proc_utmp_eq): Only use ut_id field if valid. 1997-04-15 12:47 Andreas Schwab * sysdeps/m68k/fpu/fclrexcpt.c: New file. * sysdeps/m68k/fpu/fenvbits.h: New file. * sysdeps/m68k/fpu/fegetenv.c: New file. * sysdeps/m68k/fpu/fegetround.c: New file. * sysdeps/m68k/fpu/fesetenv.c: New file. * sysdeps/m68k/fpu/fesetround.c: New file. * sysdeps/m68k/fpu/feupdateenv.c: New file. * sysdeps/m68k/fpu/fgetexcptflg.c: New file. * sysdeps/m68k/fpu/fraiseexcpt.c: New file. * sysdeps/m68k/fpu/fsetexcptflg.c: New file. * sysdeps/m68k/fpu/ftestexcept.c: New file. * sysdeps/m68k/fpu/mathbits.h: New file. * sysdeps/m68k/fpu/s_remquo.c: New file. * sysdeps/m68k/fpu/s_remquol.c: New file. * sysdeps/m68k/fpu/s_remquof.c: New file. * sysdeps/libm-ieee754/s_roundl.c: Restore integer bit when mantissa overflows into exponent. Fix priority of >> vs +. * math/libm-test.c (basic_tests): Use the appropriate isnan and isinf function to test the value of the nan function. 1997-04-15 13:40 Ulrich Drepper * sysdeps/libm-i387/s_finite.S: Fix typo. * sysdeps/i386/fpu/__math.h: Add optimized versions of isgreater, isgreaterequal, isless, islessequal, islessgreater, and isunordered. --- ChangeLog | 45 +++++++++++++++++++++++ login/utmp_file.c | 4 ++- math/libm-test.c | 8 ++--- misc/libgen.h | 10 ++++-- stdlib/Makefile | 2 +- stdlib/xpg_basename.c | 69 +++++++++++++++++++++++++++++++++++ string/string.h | 7 ++-- sysdeps/i386/fpu/__math.h | 53 +++++++++++++++++++++++++++ sysdeps/libm-i387/s_finite.S | 4 +-- sysdeps/libm-ieee754/s_cexp.c | 19 ++++++---- sysdeps/libm-ieee754/s_roundl.c | 14 +++++--- sysdeps/m68k/fpu/fclrexcpt.c | 39 ++++++++++++++++++++ sysdeps/m68k/fpu/fegetenv.c | 27 ++++++++++++++ sysdeps/m68k/fpu/fegetround.c | 31 ++++++++++++++++ sysdeps/m68k/fpu/feholdexcpt.c | 39 ++++++++++++++++++++ sysdeps/m68k/fpu/fenvbits.h | 80 +++++++++++++++++++++++++++++++++++++++++ sysdeps/m68k/fpu/fesetenv.c | 48 +++++++++++++++++++++++++ sysdeps/m68k/fpu/fesetround.c | 38 ++++++++++++++++++++ sysdeps/m68k/fpu/feupdateenv.c | 39 ++++++++++++++++++++ sysdeps/m68k/fpu/fgetexcptflg.c | 32 +++++++++++++++++ sysdeps/m68k/fpu/fraiseexcpt.c | 74 ++++++++++++++++++++++++++++++++++++++ sysdeps/m68k/fpu/fsetexcptflg.c | 38 ++++++++++++++++++++ sysdeps/m68k/fpu/ftestexcept.c | 32 +++++++++++++++++ sysdeps/m68k/fpu/mathbits.h | 36 +++++++++++++++++++ sysdeps/m68k/fpu/s_remquo.c | 58 ++++++++++++++++++++++++++++++ sysdeps/m68k/fpu/s_remquof.c | 3 ++ sysdeps/m68k/fpu/s_remquol.c | 3 ++ 27 files changed, 830 insertions(+), 22 deletions(-) create mode 100644 stdlib/xpg_basename.c create mode 100644 sysdeps/m68k/fpu/fclrexcpt.c create mode 100644 sysdeps/m68k/fpu/fegetenv.c create mode 100644 sysdeps/m68k/fpu/fegetround.c create mode 100644 sysdeps/m68k/fpu/feholdexcpt.c create mode 100644 sysdeps/m68k/fpu/fenvbits.h create mode 100644 sysdeps/m68k/fpu/fesetenv.c create mode 100644 sysdeps/m68k/fpu/fesetround.c create mode 100644 sysdeps/m68k/fpu/feupdateenv.c create mode 100644 sysdeps/m68k/fpu/fgetexcptflg.c create mode 100644 sysdeps/m68k/fpu/fraiseexcpt.c create mode 100644 sysdeps/m68k/fpu/fsetexcptflg.c create mode 100644 sysdeps/m68k/fpu/ftestexcept.c create mode 100644 sysdeps/m68k/fpu/mathbits.h create mode 100644 sysdeps/m68k/fpu/s_remquo.c create mode 100644 sysdeps/m68k/fpu/s_remquof.c create mode 100644 sysdeps/m68k/fpu/s_remquol.c diff --git a/ChangeLog b/ChangeLog index a43ebf0ab5..341fa189f8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,48 @@ +1997-04-17 16:55 Ulrich Drepper + + * misc/libgen.h: Change prototype for of basename to XPG variant. + * stdlib/Makefile (routines): Add xpg_basename. + * stdlib/basename.c: New file. + * string/string.h: Don't declare basename function if basename + macro is available. + +1997-04-16 17:33 Miles Bader + + * login/utmp_file.c (proc_utmp_eq): Only use ut_id field if valid. + +1997-04-15 12:47 Andreas Schwab + + * sysdeps/m68k/fpu/fclrexcpt.c: New file. + * sysdeps/m68k/fpu/fenvbits.h: New file. + * sysdeps/m68k/fpu/fegetenv.c: New file. + * sysdeps/m68k/fpu/fegetround.c: New file. + * sysdeps/m68k/fpu/fesetenv.c: New file. + * sysdeps/m68k/fpu/fesetround.c: New file. + * sysdeps/m68k/fpu/feupdateenv.c: New file. + * sysdeps/m68k/fpu/fgetexcptflg.c: New file. + * sysdeps/m68k/fpu/fraiseexcpt.c: New file. + * sysdeps/m68k/fpu/fsetexcptflg.c: New file. + * sysdeps/m68k/fpu/ftestexcept.c: New file. + * sysdeps/m68k/fpu/mathbits.h: New file. + + * sysdeps/m68k/fpu/s_remquo.c: New file. + * sysdeps/m68k/fpu/s_remquol.c: New file. + * sysdeps/m68k/fpu/s_remquof.c: New file. + + * sysdeps/libm-ieee754/s_roundl.c: Restore integer bit when + mantissa overflows into exponent. Fix priority of >> vs +. + + * math/libm-test.c (basic_tests): Use the appropriate isnan and + isinf function to test the value of the nan function. + +1997-04-15 13:40 Ulrich Drepper + + * sysdeps/libm-i387/s_finite.S: Fix typo. + + * sysdeps/i386/fpu/__math.h: Add optimized versions of isgreater, + isgreaterequal, isless, islessequal, islessgreater, and + isunordered. + 1997-04-15 03:14 Ulrich Drepper * wcsmbs/wcsstr.c: Add weak alias wcswcs for Unix98 compliance. diff --git a/login/utmp_file.c b/login/utmp_file.c index a0b0aa4346..9a5d687291 100644 --- a/login/utmp_file.c +++ b/login/utmp_file.c @@ -231,7 +231,9 @@ proc_utmp_eq (const struct utmp *entry, const struct utmp *match) && #endif #if _HAVE_UT_ID - 0 - strncmp (entry->ut_id, match->ut_id, sizeof match->ut_id) == 0 + (entry->ut_id[0] && match->ut_id[0] + ? strncmp (entry->ut_id, match->ut_id, sizeof match->ut_id) == 0 + : strncmp (entry->ut_line, match->ut_line, sizeof match->ut_line) == 0) #else strncmp (entry->ut_line, match->ut_line, sizeof match->ut_line) == 0 #endif diff --git a/math/libm-test.c b/math/libm-test.c index 356cc91a16..72c27b16ca 100644 --- a/math/libm-test.c +++ b/math/libm-test.c @@ -3499,10 +3499,10 @@ basic_tests (void) /* And again with the value returned by the `nan' function. */ - check_bool ("isnan (NAN)", isnan (FUNC(nan) (""))); - check_bool ("isnan (-NAN)", isnan (-FUNC(nan) (""))); - check_bool ("!isinf (NAN)", !(isinf (FUNC(nan) ("")))); - check_bool ("!isinf (-NAN)", !(isinf (-FUNC(nan) ("")))); + check_bool ("isnan (NAN)", FUNC(isnan) (FUNC(nan) (""))); + check_bool ("isnan (-NAN)", FUNC(isnan) (-FUNC(nan) (""))); + check_bool ("!isinf (NAN)", !(FUNC(isinf) (FUNC(nan) ("")))); + check_bool ("!isinf (-NAN)", !(FUNC(isinf) (-FUNC(nan) ("")))); check_bool ("NAN != NAN", FUNC(nan) ("") != FUNC(nan) ("")); /* test if EPSILON is ok */ diff --git a/misc/libgen.h b/misc/libgen.h index 2c5d642e15..4eb4d15ff8 100644 --- a/misc/libgen.h +++ b/misc/libgen.h @@ -26,8 +26,14 @@ __BEGIN_DECLS /* Return directory part of PATH or "." if none is available. */ extern char *dirname __P ((char *__path)); -/* Return filename part of PATH. */ -extern char *basename __P ((__const char *__path)); +/* Return final component of PATH. + + This is the weird XPG version of this function. It sometimes will + modify its argument. Therefore we normally use the GNU version (in + ) and only if this header is included make the XPG + version available under the real name. */ +extern char *__xpg_basename __P ((char *__path)); +#define basename(path) __xpg_basename (path) __END_DECLS diff --git a/stdlib/Makefile b/stdlib/Makefile index a9e22ac44b..7e70e5a1bb 100644 --- a/stdlib/Makefile +++ b/stdlib/Makefile @@ -42,7 +42,7 @@ routines := \ strtof strtod strtold \ system canonicalize \ a64l l64a \ - rpmatch strfmon strfmon_l getsubopt + rpmatch strfmon strfmon_l getsubopt xpg_basename distribute := exit.h grouping.h abort-instr.h tests := tst-strtol tst-strtod testmb testrand testsort testdiv \ diff --git a/stdlib/xpg_basename.c b/stdlib/xpg_basename.c new file mode 100644 index 0000000000..b789bc9a1a --- /dev/null +++ b/stdlib/xpg_basename.c @@ -0,0 +1,69 @@ +/* Return basename of given pathname according to the weird XPG specification. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include +#include + + +char * +__xpg_basename (char *filename) +{ + char *p; + + if (filename == NULL || filename[0] == '\0') + /* We return a pointer to a static string containing ".". */ + p = (char *) "."; + else + { + p = strrchr (filename, '/'); + + if (p == NULL) + /* There is no slash in the filename. Return the whole string. */ + p = filename; + else + { + if (p[1] == '\0') + { + /* We must remove trailing '/'. */ + while (p > filename && p[-1] == '/') + --p; + + /* Now we can be in two situations: + a) the string only contains '/' characters, so we return + '/' + b) p points past the last component, but we have to remove + the trailing slash. */ + if (p > filename) + { + *p-- = '\0'; + while (p > filename && p[-1] != '/') + --p; + } + else + /* The last slash we already found is the right position + to return. */ + while (p[1] != '\0') + ++p; + } + } + } + + return p; +} diff --git a/string/string.h b/string/string.h index 9602886910..7a6ad1235f 100644 --- a/string/string.h +++ b/string/string.h @@ -260,8 +260,11 @@ extern char *strfry __P ((char *__string)); extern __ptr_t memfrob __P ((__ptr_t __s, size_t __n)); #endif -#ifdef __USE_MISC -/* Return the file name within directory of FILENAME. */ +#if defined __USE_MISC || !defined basename +/* Return the file name within directory of FILENAME. We don't + declare the function if the `basename' macro is available (defined + in ) which makes the XPG version of this function + available. */ extern char *basename __P ((__const char *__filename)); #endif diff --git a/sysdeps/i386/fpu/__math.h b/sysdeps/i386/fpu/__math.h index 080d0ec220..4e34fa0263 100644 --- a/sysdeps/i386/fpu/__math.h +++ b/sysdeps/i386/fpu/__math.h @@ -466,8 +466,61 @@ __finite (double __x) : "=q" (__result) : "0" (((int *) &__x)[1])); return __result; } + + +/* ISO C 9X defines some macros to perform unordered comparisons. The + ix87 FPU supports this with special opcodes and we should use them. + This must not be inline functions since we have to be able to handle + all floating-point types. */ +#undef isgreater +#define isgreater(x, y) \ + ({ int result; \ + __asm__ ("fucompp; fnstsw; andb $0x45, %%ah; setz %%al;" \ + "andl $0xff, %0" \ + : "=a" (result) : "t" (x), "u" (y) : "cc"); \ + result; }) + +#undef isgreaterequal +#define isgreaterequal(x, y) \ + ({ int result; \ + __asm__ ("fucompp; fnstsw; testb $0x05, %%ah; setz %%al;" \ + "andl $0xff, %0" \ + : "=a" (result) : "t" (x), "u" (y) : "cc"); \ + result; }) + +#undef isless +#define isless(x, y) \ + ({ int result; \ + __asm__ ("fucompp; fnstsw; xorb $0x01, %%ah; testb $0x45, %%ah;" \ + "setz %%al; andl $0xff, %0" \ + : "=a" (result) : "t" (x), "u" (y) : "cc"); \ + result; }) + +#undef islessequal +#define islessequal(x, y) \ + ({ int result; \ + __asm__ ("fucompp; fnstsw; xorb $0x01, %%ah; testb $0x05, %%ah;" \ + "setz %%al; andl $0xff, %0" \ + : "=a" (result) : "t" (x), "u" (y) : "cc"); \ + result; }) + +#undef islessgreater +#define islessgreater(x, y) \ + ({ int result; \ + __asm__ ("fucompp; fnstsw; testb $0x44, %%ah; setz %%al;" \ + "andl $0xff, %0" \ + : "=a" (result) : "t" (x), "u" (y) : "cc"); \ + result; }) + +#undef isunordered +#define isunordered(x, y) \ + ({ int result; \ + __asm__ ("fucompp; fnstsw; sahf; setp %%al; andl $0xff, %0" \ + : "=a" (result) : "t" (x), "u" (y) : "cc"); \ + result; }) #endif + #ifdef __USE_MISC __MATH_INLINE double coshm1 (double __x); __MATH_INLINE double diff --git a/sysdeps/libm-i387/s_finite.S b/sysdeps/libm-i387/s_finite.S index 198eb809a9..63c766a950 100644 --- a/sysdeps/libm-i387/s_finite.S +++ b/sysdeps/libm-i387/s_finite.S @@ -5,10 +5,10 @@ #include ENTRY(__finite) - movl 8(%esp) + movl 8(%esp),%eax movl $0xFFEFFFFF,%ecx subl %eax,%ecx - xorl %ecx,%eax,%eax + xorl %ecx,%eax shrl $31, %eax ret END (__finite) diff --git a/sysdeps/libm-ieee754/s_cexp.c b/sysdeps/libm-ieee754/s_cexp.c index 5e68f585f7..3181af08c7 100644 --- a/sysdeps/libm-ieee754/s_cexp.c +++ b/sysdeps/libm-ieee754/s_cexp.c @@ -38,16 +38,19 @@ __cexp (__complex__ double x) { /* Imaginary part is finite. */ double exp_val = __ieee754_exp (__real__ x); + double sinix, cosix; + + __sincos (__imag__ x, &sinix, &cosix); if (isfinite (exp_val)) { - __real__ retval = exp_val * __cos (__imag__ x); - __imag__ retval = exp_val * __sin (__imag__ x); + __real__ retval = exp_val * cosix; + __imag__ retval = exp_val * sinix; } else { - __real__ retval = __copysign (exp_val, __cos (__imag__ x)); - __imag__ retval = __copysign (exp_val, __sin (__imag__ x)); + __real__ retval = __copysign (exp_val, cosix); + __imag__ retval = __copysign (exp_val, sinix); } } else @@ -74,8 +77,12 @@ __cexp (__complex__ double x) } else { - __real__ retval = __copysign (value, __cos (__imag__ x)); - __imag__ retval = __copysign (value, __sin (__imag__ x)); + double sinix, cosix; + + __sincos (__imag__ x, &sinix, &cosix); + + __real__ retval = __copysign (value, cosix); + __imag__ retval = __copysign (value, sinix); } } else if (signbit (__real__ x) == 0) diff --git a/sysdeps/libm-ieee754/s_roundl.c b/sysdeps/libm-ieee754/s_roundl.c index db87154089..d7482b9b7c 100644 --- a/sysdeps/libm-ieee754/s_roundl.c +++ b/sysdeps/libm-ieee754/s_roundl.c @@ -41,9 +41,12 @@ __roundl (long double x) if (huge + x > 0.0) { se &= 0x8000; - if (j0 == -1) - se |= 0x3fff; i0 = i1 = 0; + if (j0 == -1) + { + se |= 0x3fff; + i0 = 0x80000000; + } } } else @@ -55,7 +58,7 @@ __roundl (long double x) if (huge + x > 0.0) { /* Raise inexact if x != 0. */ - u_int32_t j = i0 + 0x40000000 >> j0; + u_int32_t j = i0 + (0x40000000 >> j0); if (j < i0) se += 1; i0 = (j & ~i) | 0x80000000; @@ -86,7 +89,10 @@ __roundl (long double x) { u_int32_t k = i0 + 1; if (k < i0) - se += 1; + { + se += 1; + k |= 0x80000000; + } i0 = k; } i1 = j; diff --git a/sysdeps/m68k/fpu/fclrexcpt.c b/sysdeps/m68k/fpu/fclrexcpt.c new file mode 100644 index 0000000000..b914bac9f9 --- /dev/null +++ b/sysdeps/m68k/fpu/fclrexcpt.c @@ -0,0 +1,39 @@ +/* Clear given exceptions in current floating-point environment. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include + +void +feclearexcept (int excepts) +{ + fexcept_t fpsr; + + /* Mask out unsupported bits/exceptions. */ + excepts &= FE_ALL_EXCEPT; + + /* Fetch the fpu status register. */ + __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr)); + + /* Clear the relevant bits. */ + fpsr &= ~excepts; + + /* Put the new data in effect. */ + __asm__ __volatile__ ("fmove%.l %0,%/fpsr" : : "dm" (fpsr)); +} diff --git a/sysdeps/m68k/fpu/fegetenv.c b/sysdeps/m68k/fpu/fegetenv.c new file mode 100644 index 0000000000..59f743aecf --- /dev/null +++ b/sysdeps/m68k/fpu/fegetenv.c @@ -0,0 +1,27 @@ +/* Store current floating-point environment. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include + +void +fegetenv (fenv_t *envp) +{ + __asm__ ("fmovem%.l %/fpcr/%/fpsr,%0" : "=m" (*envp)); +} diff --git a/sysdeps/m68k/fpu/fegetround.c b/sysdeps/m68k/fpu/fegetround.c new file mode 100644 index 0000000000..1837a84271 --- /dev/null +++ b/sysdeps/m68k/fpu/fegetround.c @@ -0,0 +1,31 @@ +/* Return current rounding direction. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include + +int +fegetround (void) +{ + int fpcr; + + __asm__ ("fmove%.l %!,%0" : "=dm" (fpcr)); + + return fpcr & FE_UPWARD; +} diff --git a/sysdeps/m68k/fpu/feholdexcpt.c b/sysdeps/m68k/fpu/feholdexcpt.c new file mode 100644 index 0000000000..351fa8ae75 --- /dev/null +++ b/sysdeps/m68k/fpu/feholdexcpt.c @@ -0,0 +1,39 @@ +/* Store current floating-point environment and clear exceptions. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include + +int +feholdexcept (fenv_t *envp) +{ + fexcept_t fpcr, fpsr; + + /* Store the environment. */ + __asm__ ("fmovem%.l %/fpcr/%/fpsr,%0" : "=m" (*envp)); + + /* Now clear all exceptions. */ + fpsr = envp->status_register & ~FE_ALL_EXCEPT; + __asm__ __volatile__ ("fmove%.l %0,%/fpsr" : : "dm" (fpsr)); + /* And set all exceptions to non-stop. */ + fpcr = envp->control_register & ~(FE_ALL_EXCEPT << 5); + __asm__ __volatile__ ("fmove%.l %0,%!" : : "dm" (fpcr)); + + return 1; +} diff --git a/sysdeps/m68k/fpu/fenvbits.h b/sysdeps/m68k/fpu/fenvbits.h new file mode 100644 index 0000000000..b653b1aafd --- /dev/null +++ b/sysdeps/m68k/fpu/fenvbits.h @@ -0,0 +1,80 @@ +/* Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* This file should never be included directly. */ + +#ifndef _FENVBITS_H +#define _FENVBITS_H 1 + +/* Define bits representing the exception. We use the bit positions of + the appropriate bits in the FPSR Accrued Exception Byte. */ +enum + { + FE_INEXACT = 1 << 3, +#define FE_INEXACT FE_INEXACT + FE_DIVBYZERO = 1 << 4, +#define FE_DIVBYZERO FE_DIVBYZERO + FE_UNDERFLOW = 1 << 5, +#define FE_UNDERFLOW FE_UNDERFLOW + FE_OVERFLOW = 1 << 6, +#define FE_OVERFLOW FE_OVERFLOW + FE_INVALID = 1 << 7 +#define FE_INVALID FE_INVALID + }; + +#define FE_ALL_EXCEPT \ + (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID) + +/* The m68k FPU supports all of the four defined rounding modes. We use + the bit positions in the FPCR Mode Control Byte as the values for the + appropriate macros. */ +enum + { + FE_TONEAREST = 0, +#define FE_TONEAREST FE_TONEAREST + FE_TOWARDSZERO = 1 << 4, +#define FE_TOWARDSZERO FE_TOWARDSZERO + FE_DOWNWARD = 2 << 4, +#define FE_DOWNWARD FE_DOWNWARD + FE_UPWARD = 3 << 4 +#define FE_UPWARD FE_UPWARD + }; + + +/* Type representing exception flags. */ +typedef unsigned int fexcept_t; + + +/* Type representing floating-point environment. This structure + corresponds to the layout of the block written by `fmovem'. */ +typedef struct + { + fexcept_t control_register; + fexcept_t status_register; + } +fenv_t; + +/* If the default argument is used we use this value. */ +#define FE_DFL_ENV ((fenv_t *) -1) + +#ifdef __USE_GNU +/* Floating-point environment where none of the exceptions are masked. */ +# define FE_NOMASK_ENV ((fenv_t *) -2) +#endif + +#endif /* fenvbits.h */ diff --git a/sysdeps/m68k/fpu/fesetenv.c b/sysdeps/m68k/fpu/fesetenv.c new file mode 100644 index 0000000000..f6611a20e0 --- /dev/null +++ b/sysdeps/m68k/fpu/fesetenv.c @@ -0,0 +1,48 @@ +/* Install given floating-point environment. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include + +void +fesetenv (const fenv_t *envp) +{ + fenv_t temp; + + /* Install the environment specified by ENVP. But there are a few + values which we do not want to come from the saved environment. + Therefore, we get the current environment and replace the values + we want to use from the environment specified by the parameter. */ + __asm__ ("fmovem%.l %/fpcr/%/fpsr,%0" : "=m" (*&temp)); + + temp.status_register &= ~FE_ALL_EXCEPT; + temp.control_register &= ~((FE_ALL_EXCEPT << 5) | FE_UPWARD); + if (envp == FE_DFL_ENV) + ; + else if (envp == FE_NOMASK_ENV) + temp.control_register |= FE_ALL_EXCEPT << 5; + else + { + temp.control_register |= (envp->control_register + & ((FE_ALL_EXCEPT << 5) | FE_UPWARD)); + temp.status_register |= envp->status_register & FE_ALL_EXCEPT; + } + + __asm__ __volatile__ ("fmovem%.l %0,%/fpcr/%/fpsr" : : "m" (temp)); +} diff --git a/sysdeps/m68k/fpu/fesetround.c b/sysdeps/m68k/fpu/fesetround.c new file mode 100644 index 0000000000..8d5466c956 --- /dev/null +++ b/sysdeps/m68k/fpu/fesetround.c @@ -0,0 +1,38 @@ +/* Set current rounding direction. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include + +int +fesetround (int round) +{ + fexcept_t fpcr; + + if (round & ~FE_UPWARD) + /* ROUND is no valid rounding mode. */ + return 0; + + __asm__ ("fmove%.l %!,%0" : "=dm" (fpcr)); + fpcr &= ~FE_UPWARD; + fpcr |= round; + __asm__ __volatile__ ("fmove%.l %0,%!" : : "dm" (fpcr)); + + return 1; +} diff --git a/sysdeps/m68k/fpu/feupdateenv.c b/sysdeps/m68k/fpu/feupdateenv.c new file mode 100644 index 0000000000..f5922b4de4 --- /dev/null +++ b/sysdeps/m68k/fpu/feupdateenv.c @@ -0,0 +1,39 @@ +/* Install given floating-point environment and raise exceptions. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include + +void +feupdateenv (const fenv_t *envp) +{ + fexcept_t fpsr; + + /* Save current exceptions. */ + __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr)); + fpsr &= FE_ALL_EXCEPT; + + /* Install new environment. */ + fesetenv (envp); + + /* Raise the saved exception. Incidently for us the implementation + defined format of the values in objects of type fexcept_t is the + same as the ones specified using the FE_* constants. */ + feraiseexcept ((int) fpsr); +} diff --git a/sysdeps/m68k/fpu/fgetexcptflg.c b/sysdeps/m68k/fpu/fgetexcptflg.c new file mode 100644 index 0000000000..4086e1a97f --- /dev/null +++ b/sysdeps/m68k/fpu/fgetexcptflg.c @@ -0,0 +1,32 @@ +/* Store current representation for exceptions. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include + +void +fegetexceptflag (fexcept_t *flagp, int excepts) +{ + fexcept_t fpsr; + + /* Get the current exceptions. */ + __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr)); + + *flagp = fpsr & excepts & FE_ALL_EXCEPT; +} diff --git a/sysdeps/m68k/fpu/fraiseexcpt.c b/sysdeps/m68k/fpu/fraiseexcpt.c new file mode 100644 index 0000000000..b6ff82760d --- /dev/null +++ b/sysdeps/m68k/fpu/fraiseexcpt.c @@ -0,0 +1,74 @@ +/* Raise given exceptions. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include +#include + +void +feraiseexcept (int excepts) +{ + /* Raise exceptions represented by EXCEPTS. But we must raise only one + signal at a time. It is important that if the overflow/underflow + exception and the divide by zero exception are given at the same + time, the overflow/underflow exception follows the divide by zero + exception. */ + + /* First: invalid exception. */ + if (excepts & FE_INVALID) + { + /* One example of a invalid operation is 0 * Infinity. */ + double d = 0.0 * HUGE_VAL; + /* Now force the exception. */ + __asm__ __volatile__ ("fnop" : : "f" (d)); + } + + /* Next: division by zero. */ + if (excepts & FE_DIVBYZERO) + { + double d = 1.0; + __asm__ __volatile__ ("fdiv%.s %#0r0,%0; fnop" : "=f" (d) : "0" (d)); + } + + /* Next: overflow. */ + if (excepts & FE_OVERFLOW) + { + long double d = LDBL_MAX * LDBL_MAX; + /* Now force the exception. */ + __asm__ __volatile__ ("fnop" : : "f" (d)); + } + + /* Next: underflow. */ + if (excepts & FE_UNDERFLOW) + { + long double d = LDBL_MIN / 16.0; + /* Now force the exception. */ + __asm__ __volatile__ ("fnop" : : "f" (d)); + } + + /* Last: inexact. */ + if (excepts & FE_INEXACT) + { + long double d1, d2 = 1.0; + __asm__ __volatile__ ("fmovecr %#0,%0\n\t" + "fdiv%.x %1,%0\n\t" + "fnop" + : "=&f" (d1) : "f" (d2)); + } +} diff --git a/sysdeps/m68k/fpu/fsetexcptflg.c b/sysdeps/m68k/fpu/fsetexcptflg.c new file mode 100644 index 0000000000..aa92ffd0c5 --- /dev/null +++ b/sysdeps/m68k/fpu/fsetexcptflg.c @@ -0,0 +1,38 @@ +/* Set floating-point environment exception handling. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include +#include + +void +fesetexceptflag (const fexcept_t *flagp, int excepts) +{ + fexcept_t fpsr; + + /* Get the current status register. */ + __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr)); + + /* Install the new exception bits in the Accrued Exception Byte. */ + fpsr &= ~(excepts & FE_ALL_EXCEPT); + fpsr |= *flagp & excepts & FE_ALL_EXCEPT; + + /* Store the new status register. */ + __asm__ __volatile__ ("fmove%.l %0,%/fpsr" : : "dm" (fpsr)); +} diff --git a/sysdeps/m68k/fpu/ftestexcept.c b/sysdeps/m68k/fpu/ftestexcept.c new file mode 100644 index 0000000000..c092ce18e3 --- /dev/null +++ b/sysdeps/m68k/fpu/ftestexcept.c @@ -0,0 +1,32 @@ +/* Test exception in current environment. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include + +int +fetestexcept (int excepts) +{ + fexcept_t fpsr; + + /* Get current exceptions. */ + __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr)); + + return fpsr & excepts & FE_ALL_EXCEPT; +} diff --git a/sysdeps/m68k/fpu/mathbits.h b/sysdeps/m68k/fpu/mathbits.h new file mode 100644 index 0000000000..049662319a --- /dev/null +++ b/sysdeps/m68k/fpu/mathbits.h @@ -0,0 +1,36 @@ +/* Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _MATHBITS_H +#define _MATHBITS_H 1 + +/* The m68k FPUs evaluate all values in the 96 bit floating-point format + which is also available for the user as `long double'. Therefore we + define: */ +typedef long double float_t; /* `float' expressions are evaluated as + `long double'. */ +typedef long double double_t; /* `double' expressions are evaluated as + `long double'. */ + +/* Signal that both types are `long double'. */ +#define FLT_EVAL_METHOD 2 + +/* Define `INFINITY' as value of type `float_t'. */ +#define INFINITY HUGE_VALL + +#endif /* mathbits.h */ diff --git a/sysdeps/m68k/fpu/s_remquo.c b/sysdeps/m68k/fpu/s_remquo.c new file mode 100644 index 0000000000..3682ba7896 --- /dev/null +++ b/sysdeps/m68k/fpu/s_remquo.c @@ -0,0 +1,58 @@ +/* Compute remainder and a congruent to the quotient. m68k fpu version + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#define __LIBC_M81_MATH_INLINES +#include + +#ifndef SUFF +#define SUFF +#endif +#ifndef float_type +#define float_type double +#endif + +#define CONCATX(a,b) __CONCAT(a,b) +#define s(name) CONCATX(name,SUFF) + +float_type +s(__remquo) (float_type x, float_type y, int *quo) +{ + float_type result; + int cquo, fpsr; + + /* FIXME: Which of frem and fmod is correct? */ +#if 1 + __asm ("frem%.x %2,%0\n\tfmove%.l %/fpsr,%1" + : "=f" (result), "=dm" (fpsr) : "f" (y), "0" (x)); + cquo = (fpsr >> 16) & 0x7f; + if ((result > 0) != (x > 0)) + cquo--; +#else + __asm ("fmod%.x %2,%0\n\tfmove%.l %/fpsr,%1" + : "=f" (result), "=dm" (fpsr) : "f" (y), "0" (x)); + cquo = (fpsr >> 16) & 0x7f; +#endif + if (fpsr & (1 << 23)) + cquo = -cquo; + *quo = cquo; + return result; +} +#define weak_aliasx(a,b) weak_alias(a,b) +weak_aliasx (s(__remquo), s(remquo)) diff --git a/sysdeps/m68k/fpu/s_remquof.c b/sysdeps/m68k/fpu/s_remquof.c new file mode 100644 index 0000000000..8a292fc26c --- /dev/null +++ b/sysdeps/m68k/fpu/s_remquof.c @@ -0,0 +1,3 @@ +#define SUFF f +#define float_type float +#include diff --git a/sysdeps/m68k/fpu/s_remquol.c b/sysdeps/m68k/fpu/s_remquol.c new file mode 100644 index 0000000000..d236cfd1f9 --- /dev/null +++ b/sysdeps/m68k/fpu/s_remquol.c @@ -0,0 +1,3 @@ +#define SUFF l +#define float_type long double +#include -- cgit v1.2.3-65-gdbad