]> sourceware.org Git - glibc.git/commitdiff
Update.
authorUlrich Drepper <drepper@redhat.com>
Thu, 18 Dec 2003 04:02:31 +0000 (04:02 +0000)
committerUlrich Drepper <drepper@redhat.com>
Thu, 18 Dec 2003 04:02:31 +0000 (04:02 +0000)
2003-12-17  Carlos O'Donell  <carlos@baldric.uwo.ca>

* sysdeps/hppa/fpu/fclrexcpt.c (feclearexcept): Right shift
FE_ALL_EXCEPT before complimenting.
* sysdeps/hppa/fpu/fegetenv.c (fegetenv): Use asm 'ma,' completer,
and gcc '+r' constraint.
* sysdeps/hppa/fpu/feholdexcpt.c (feholdexcept): Likewise.
* sysdeps/hppa/fpu/fesetenv.c (fesetenv): Likewise.
* sysdeps/hppa/fpu/feupdateenv.c (feupdateenv): Read raised
exception bits, OR with envp, pass to fesetenv.
* sysdeps/hppa/fpu/fraiseexcpt.c (feraiseexcept): Add delayed
exception flushing, FE_UNDERFLOW is DBL_MIN/3.0, FE_INEXACT is
triggered by M_PI/69.69 converted to single precision.
* sysdeps/hppa/fpu/fsetexcptflg.c (fesetexceptflag): Set enable
bits not raised exception bits.

* sysdeps/hppa/Makefile: Add dl-symaddr and dl-fptr to the
correct build strings.
* sysdeps/hppa/dl-fptr.h: New file.
* sysdeps/hppa/dl-fptr.c: Removed.
* sysdeps/hppa/dl-symaddr.c (_dl_symbol_address): Use _dl_make_ftpr,
remove const qualifier for map.
(_dl_function_address): Removed.
* sysdeps/hppa/dl-lookupcfg.h: DL_LOOKUP_ADDRESS must clear
PLABEL32 bits, define DL_AUTO_FUNCTION_ADDRESS and
DL_STATIC_FUNCTION_ADDRESS, DL_DT_INIT_ADDRESS and
DL_DT_FINI_ADDRESS use the previous two macros.

* misc/mntent_r.c: Change encoding to match recently changed decoder.

12 files changed:
ChangeLog
sysdeps/hppa/dl-fptr.c [deleted file]
sysdeps/hppa/dl-fptr.h [new file with mode: 0644]
sysdeps/hppa/dl-lookupcfg.h
sysdeps/hppa/dl-symaddr.c
sysdeps/hppa/fpu/fclrexcpt.c
sysdeps/hppa/fpu/fegetenv.c
sysdeps/hppa/fpu/feholdexcpt.c
sysdeps/hppa/fpu/fesetenv.c
sysdeps/hppa/fpu/feupdateenv.c
sysdeps/hppa/fpu/fraiseexcpt.c
sysdeps/hppa/fpu/fsetexcptflg.c

index 72b76776cab3b643ded4f5a336dba0f2eff0e0a5..cc813603831335a285ef930cd386ed6642d1217d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+2003-12-17  Carlos O'Donell  <carlos@baldric.uwo.ca>
+
+       * sysdeps/hppa/fpu/fclrexcpt.c (feclearexcept): Right shift
+       FE_ALL_EXCEPT before complimenting.
+       * sysdeps/hppa/fpu/fegetenv.c (fegetenv): Use asm 'ma,' completer,
+       and gcc '+r' constraint.
+       * sysdeps/hppa/fpu/feholdexcpt.c (feholdexcept): Likewise.
+       * sysdeps/hppa/fpu/fesetenv.c (fesetenv): Likewise.
+       * sysdeps/hppa/fpu/feupdateenv.c (feupdateenv): Read raised
+       exception bits, OR with envp, pass to fesetenv.
+       * sysdeps/hppa/fpu/fraiseexcpt.c (feraiseexcept): Add delayed
+       exception flushing, FE_UNDERFLOW is DBL_MIN/3.0, FE_INEXACT is
+       triggered by M_PI/69.69 converted to single precision.
+       * sysdeps/hppa/fpu/fsetexcptflg.c (fesetexceptflag): Set enable
+       bits not raised exception bits.
+
+       * sysdeps/hppa/Makefile: Add dl-symaddr and dl-fptr to the
+       correct build strings.
+       * sysdeps/hppa/dl-fptr.h: New file.
+       * sysdeps/hppa/dl-fptr.c: Removed.
+       * sysdeps/hppa/dl-symaddr.c (_dl_symbol_address): Use _dl_make_ftpr,
+       remove const qualifier for map.
+       (_dl_function_address): Removed.
+       * sysdeps/hppa/dl-lookupcfg.h: DL_LOOKUP_ADDRESS must clear
+       PLABEL32 bits, define DL_AUTO_FUNCTION_ADDRESS and
+       DL_STATIC_FUNCTION_ADDRESS, DL_DT_INIT_ADDRESS and
+       DL_DT_FINI_ADDRESS use the previous two macros.
+
 2003-12-17  Jakub Jelinek  <jakub@redhat.com>
 
        * malloc/mtrace.c (tr_old_memalign_hook): New variable.
@@ -9,7 +37,7 @@
 
 2003-12-17  Ulrich Drepper  <drepper@redhat.com>
 
-       * misc/mntent_r.c: Change encoding to match recently change decoder.
+       * misc/mntent_r.c: Change encoding to match recently changed decoder.
        Patch by Alexander Achenbach <xela@slit.de>.
 
 2003-12-16  Steven Munroe  <sjmunroe@us.ibm.com>
diff --git a/sysdeps/hppa/dl-fptr.c b/sysdeps/hppa/dl-fptr.c
deleted file mode 100644 (file)
index f8b6424..0000000
+++ /dev/null
@@ -1,211 +0,0 @@
-/* Make dynamic PLABELs for function pointers. HPPA version.
-   Copyright (C) 1999, 2000, 2002 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 Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-#include <unistd.h>
-#include <string.h>
-#include <sys/param.h>
-#include <sys/mman.h>
-#include <link.h>
-#include <errno.h>
-#include <ldsodefs.h>
-#include <elf/dynamic-link.h>
-#include <dl-machine.h>
-#ifdef _LIBC_REENTRANT
-# include <pt-machine.h>
-
-/* Remember, we use 0 to mean that a lock is taken on PA-RISC. */
-static int __hppa_fptr_lock = 1;
-#endif
-
-/* Because ld.so is now versioned, these functions can be in their own
-   file; no relocations need to be done to call them.  Of course, if
-   ld.so is not versioned...  */
-#if 0
-#ifndef DO_VERSIONING
-# error "This will not work with versioning turned off, sorry."
-#endif
-#endif
-
-#ifdef MAP_ANON
-/* The fd is not examined when using MAP_ANON.  */
-# define ANONFD -1
-#else
-# define ANONFD GL(dl_zerofd)
-#endif
-
-struct hppa_fptr __boot_ldso_fptr[HPPA_BOOT_FPTR_SIZE];
-struct hppa_fptr *__fptr_root = NULL;
-struct hppa_fptr *__fptr_next = __boot_ldso_fptr;
-static struct hppa_fptr *__fptr_free = NULL;
-int __fptr_count = HPPA_BOOT_FPTR_SIZE;
-
-Elf32_Addr
-__hppa_make_fptr (const struct link_map *sym_map, Elf32_Addr value,
-                 struct hppa_fptr **root, struct hppa_fptr *mem)
-{
-  struct hppa_fptr **loc;
-  struct hppa_fptr *f;
-
-#ifdef _LIBC_REENTRANT
-  /* Make sure we are alone. We don't need a lock during bootstrap. */
-  if (mem == NULL)
-    while (testandset (&__hppa_fptr_lock));
-#endif
-
-  /* Search the sorted linked list for an existing entry for this
-     symbol.  */
-  loc = root;
-  f = *loc;
-  while (f != NULL && f->func <= value)
-    {
-      if (f->func == value)
-       goto found;
-      loc = &f->next;
-      f = *loc;
-    }
-
-  /* Not found.  Create a new one.  */
-  if (mem != NULL)
-    f = mem;
-  else if (__fptr_free != NULL)
-    {
-      f = __fptr_free;
-      __fptr_free = f->next;
-    }
-  else
-    {
-      if (__fptr_count == 0)
-       {
-#ifndef MAP_ANON
-# define MAP_ANON 0
-         if (GL(dl_zerofd) == -1)
-           {
-             GL(dl_zerofd) = _dl_sysdep_open_zero_fill ();
-             if (GL(dl_zerofd) == -1)
-               {
-                 __close (fd);
-                 _dl_signal_error (errno, NULL, NULL,
-                                   "cannot open zero fill device");
-               }
-           }
-#endif
-
-         __fptr_next = __mmap (0, GL(dl_pagesize), PROT_READ | PROT_WRITE,
-                               MAP_ANON | MAP_PRIVATE, ANONFD, 0);
-         if (__fptr_next == MAP_FAILED)
-           _dl_signal_error(errno, NULL, NULL, "cannot map page for fptr");
-         __fptr_count = GL(dl_pagesize) / sizeof (struct hppa_fptr);
-       }
-      f = __fptr_next++;
-      __fptr_count--;
-    }
-
-  f->func = value;
-  /* GOT has already been relocated in elf_get_dynamic_info - don't
-     try to relocate it again.  */
-  f->gp = sym_map->l_info[DT_PLTGOT]->d_un.d_ptr;
-  f->next = *loc;
-  *loc = f;
-
-found:
-#ifdef _LIBC_REENTRANT
-  /* Release the lock.  Again, remember, zero means the lock is taken!  */
-  if (mem == NULL)
-    __hppa_fptr_lock = 1;
-#endif
-
-  /* Set bit 30 to indicate to $$dyncall that this is a PLABEL. */
-  return (Elf32_Addr) f | 2;
-}
-
-void
-_dl_unmap (struct link_map *map)
-{
-  struct hppa_fptr **floc;
-  struct hppa_fptr *f;
-  struct hppa_fptr **lloc;
-  struct hppa_fptr *l;
-
-  __munmap ((void *) map->l_map_start, map->l_map_end - map->l_map_start);
-
-#ifdef _LIBC_REENTRANT
-  /* Make sure we are alone.  */
-  while (testandset (&__hppa_fptr_lock));
-#endif
-
-  /* Search the sorted linked list for the first entry for this object.  */
-  floc = &__fptr_root;
-  f = *floc;
-  while (f != NULL && f->func < map->l_map_start)
-    {
-      floc = &f->next;
-      f = *floc;
-    }
-
-  /* We found one.  */
-  if (f != NULL && f->func < map->l_map_end)
-    {
-      /* Get the last entry.  */
-      lloc = floc;
-      l = f;
-      while (l && l->func < map->l_map_end)
-       {
-         lloc = &l->next;
-         l = *lloc;
-       }
-
-      /* Updated FPTR.  */
-      *floc = l;
-
-      /* Prepend them to the free list.  */
-      *lloc = __fptr_free;
-      __fptr_free = f;
-    }
-
-#ifdef _LIBC_REENTRANT
-  /* Release the lock. */
-  __hppa_fptr_lock = 1;
-#endif
-}
-
-Elf32_Addr
-_dl_lookup_address (const void *address)
-{
-  Elf32_Addr addr = (Elf32_Addr) address;
-  struct hppa_fptr *f;
-
-#ifdef _LIBC_REENTRANT
-  /* Make sure we are alone.  */
-  while (testandset (&__hppa_fptr_lock));
-#endif
-
-  for (f = __fptr_root; f != NULL; f = f->next)
-    if (f == address)
-      {
-       addr = f->func;
-       break;
-      }
-
-#ifdef _LIBC_REENTRANT
-  /* Release the lock.   */
-  __hppa_fptr_lock = 1;
-#endif
-
-  return addr;
-}
diff --git a/sysdeps/hppa/dl-fptr.h b/sysdeps/hppa/dl-fptr.h
new file mode 100644 (file)
index 0000000..2ac9740
--- /dev/null
@@ -0,0 +1,35 @@
+/* Function descriptors.  HPPA version.
+   Copyright (C) 2003 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef dl_hppa_fptr_h
+#define dl_hppa_fptr_h 1
+
+#include <sysdeps/generic/dl-fptr.h>
+
+/* There are currently 20 dynamic symbols in ld.so.
+   ELF_MACHINE_BOOT_FPTR_TABLE_LEN needs to be at least that big.  */
+#define ELF_MACHINE_BOOT_FPTR_TABLE_LEN        200
+
+#define ELF_MACHINE_LOAD_ADDRESS(var, symbol)          \
+  asm ("       addil LT%%" #symbol ", %%r19\n"         \
+       "       ldw RT%%" #symbol "(%%sr0,%%r1), %0\n"  \
+      : "=&r" (var));
+
+
+#endif /* !dl_hppa_fptr_h */
index d76ea1221deb54a7754308556720995c5360b9a9..d393b3e4272b6429804be9ce28a07be3610dd486 100644 (file)
 /* Forward declaration.  */
 struct link_map;
 
-void *_dl_symbol_address (const struct link_map *map, const ElfW(Sym) *ref);
+void *_dl_symbol_address (struct link_map *map, const ElfW(Sym) *ref);
 
 #define DL_SYMBOL_ADDRESS(map, ref) _dl_symbol_address(map, ref)
 
 Elf32_Addr _dl_lookup_address (const void *address);
 
-#define DL_LOOKUP_ADDRESS(addr) _dl_lookup_address (addr)
+/* Clear the bottom two bits so generic code can find the fdesc entry */
+#define DL_LOOKUP_ADDRESS(addr) \
+  (_dl_lookup_address ((void *)((unsigned long)addr & ~3)))
 
 void _dl_unmap (struct link_map *map);
 
 #define DL_UNMAP(map) _dl_unmap (map)
 
-extern Elf32_Addr _dl_function_address (const struct link_map *map,
-                                       Elf32_Addr start);
+#define DL_AUTO_FUNCTION_ADDRESS(map, addr)                            \
+({                                                                     \
+  unsigned int fptr[2];                                                        \
+  fptr[0] = (unsigned int) (addr);                                     \
+  fptr[1] = (map)->l_info[DT_PLTGOT]->d_un.d_ptr;                      \
+  /* Set bit 30 to indicate to $$dyncall that this is a PLABEL. */     \
+  (ElfW(Addr))((unsigned int)fptr | 2);                                        \
+})
+
+#define DL_STATIC_FUNCTION_ADDRESS(map, addr)                          \
+({                                                                     \
+  static unsigned int fptr[2];                                         \
+  fptr[0] = (unsigned int) (addr);                                     \
+  fptr[1] = (map)->l_info[DT_PLTGOT]->d_un.d_ptr;                      \
+  /* Set bit 30 to indicate to $$dyncall that this is a PLABEL. */     \
+  (ElfW(Addr))((unsigned int)fptr | 2);                                        \
+})
 
-#define DL_FUNCTION_ADDRESS(map, addr) _dl_function_address (map, addr)
 
 /* The test for "addr & 2" below is to accomodate old binaries which
    violated the ELF ABI by pointing DT_INIT and DT_FINI at a function
-   pointer.  */
+   descriptor.  */
 #define DL_DT_INIT_ADDRESS(map, addr) \
-  ((Elf32_Addr)(addr) & 2 ? (addr) : DL_FUNCTION_ADDRESS (map, addr))
+  ((Elf32_Addr)(addr) & 2 ? (addr) : DL_AUTO_FUNCTION_ADDRESS (map, addr))
 #define DL_DT_FINI_ADDRESS(map, addr) \
-  ((Elf32_Addr)(addr) & 2 ? (addr) : DL_FUNCTION_ADDRESS (map, addr))
+  ((Elf32_Addr)(addr) & 2 ? (addr) : DL_AUTO_FUNCTION_ADDRESS (map, addr))
+
index 1aec19ab195c80550789a7dbe5854d228577de0b..e5ce6a9c03a59ac2e6f0284d03464b32d9354e5b 100644 (file)
 #include <dl-machine.h>
 
 void *
-_dl_symbol_address (const struct link_map *map, const ElfW(Sym) *ref)
+_dl_symbol_address (struct link_map *map, const ElfW(Sym) *ref)
 {
+  /* Find the "ip" from the "map" and symbol "ref" */
   Elf32_Addr value = (map ? map->l_addr : 0) + ref->st_value;
 
-  /* On hppa, we have to return the pointer to function descriptor. */
-  if (ELFW(ST_TYPE) (ref->st_info) == STT_FUNC)
-    return (void *) __hppa_make_fptr (map, value, &__fptr_root, NULL);
+  /* On hppa, we have to return the pointer to function descriptor.
+     This involves an "| 2" to inform $$dyncall that this is a plabel32  */
+  if (ELFW(ST_TYPE) (ref->st_info) == STT_FUNC){
+    return (void *)((unsigned long)_dl_make_fptr (map, ref, value) | 2);
+  }
   else
     return (void *) value;
 }
-
-ElfW(Addr)
-_dl_function_address (const struct link_map *map, ElfW(Addr) start)
-{
-  return __hppa_make_fptr (map, start, &__fptr_root, NULL);
-}
index 8ad67b969829f220f764e7cb061293604d21c67b..a7c698206e5dbb384fac4972e7ed55dba321c801 100644 (file)
@@ -29,7 +29,7 @@ feclearexcept (int excepts)
   __asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw));
 
   /* Clear all the relevant bits. */
-  sw[0] &= ~(excepts & FE_ALL_EXCEPT) << 27;
+  sw[0] &= ~((excepts & FE_ALL_EXCEPT) << 27);
   __asm__ ("fldd 0(%0),%%fr0" : : "r" (sw));
 
   /* Success.  */
index 1ed18daa2c1e2fd7ab026bc5e25601c8828691cb..b87317b78957f5e2b207ce4d07eabfdd86ec4485 100644 (file)
@@ -24,10 +24,10 @@ int
 fegetenv (fenv_t *envp)
 {
   __asm__ (
-          "fstd %%fr0,0(%2)\n"
-          "fstd,ma %%fr1,8(%2)\n"
-          "fstd,ma %%fr2,8(%2)\n"
-          "fstd %%fr3,0(%2)\n"
-          : "=m" (*envp), "=r" (envp) : "1" (envp));
+          "fstd,ma %%fr0,8(%1)\n"
+          "fstd,ma %%fr1,8(%1)\n"
+          "fstd,ma %%fr2,8(%1)\n"
+          "fstd %%fr3,0(%1)\n"
+          : "=m" (*envp), "+r" (envp));
   return 0;
 }
index 27133365bccffa33046312ed7c3f52a1315b9b3f..db9fb409ae06a5fa4b74500dbdacb3956ae5b4a4 100644 (file)
@@ -25,18 +25,16 @@ int
 feholdexcept (fenv_t *envp)
 {
   fenv_t clear;
+  fenv_t * _regs = envp;
 
   /* Store the environment.  */
-  {
-    fenv_t * _regs = envp;
-    __asm__ (
-            "fstd %%fr0,0(%2)\n"
-            "fstd,ma %%fr1,8(%2)\n"
-            "fstd,ma %%fr2,8(%2)\n"
-            "fstd %%fr3,0(%2)\n"
-            : "=m" (*_regs), "=r" (_regs) : "1" (_regs));
-    memcpy (&clear, envp, sizeof (clear));
-  }
+  __asm__ (
+          "fstd,ma %%fr0,8(%1)\n"
+          "fstd,ma %%fr1,8(%1)\n"
+          "fstd,ma %%fr2,8(%1)\n"
+          "fstd %%fr3,0(%1)\n"
+          : "=m" (*_regs), "+r" (_regs));
+  memcpy (&clear, envp, sizeof (clear));
 
   /* Now clear all exceptions.  */
   clear.__status_word &= ~(FE_ALL_EXCEPT << 27);
@@ -46,15 +44,13 @@ feholdexcept (fenv_t *envp)
   clear.__status_word &= ~FE_ALL_EXCEPT;
 
   /* Load the new environment. */
-  {
-    fenv_t * _regs = &clear + 1;
-    __asm__ (
-            "fldd,mb -8(%2),%%fr3\n"
-            "fldd,mb -8(%2),%%fr2\n"
-            "fldd,mb -8(%2),%%fr1\n"
-            "fldd -8(%2),%%fr0\n"
-            : "=m" (*_regs), "=r" (_regs) : "1" (_regs));
-  }
+  _regs = &clear;
+  __asm__ (
+          "fldd,ma -8(%1),%%fr3\n"
+          "fldd,ma -8(%1),%%fr2\n"
+          "fldd,ma -8(%1),%%fr1\n"
+          "fldd 0(%1),%%fr0\n"
+          : "=m" (*_regs), "+r" (_regs));
 
   return 0;
 }
index 2c7986987bf3734f9d8a7eb04389024cef896c56..526773214b73bfd75500c6c7ef13231028770156 100644 (file)
@@ -26,20 +26,18 @@ int
 fesetenv (const fenv_t *envp)
 {
   fenv_t temp;
+  fenv_t * _regs = &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.  */
-  {
-    fenv_t * _regs = &temp;
-    __asm__ (
-            "fstd %%fr0,0(%2)\n"
-            "fstd,ma %%fr1,8(%2)\n"
-            "fstd,ma %%fr2,8(%2)\n"
-            "fstd %%fr3,0(%2)\n"
-            : "=m" (*_regs), "=r" (_regs) : "1" (_regs));
-  }
+  __asm__ (
+          "fstd,ma %%fr0,8(%1)\n"
+          "fstd,ma %%fr1,8(%1)\n"
+          "fstd,ma %%fr2,8(%1)\n"
+          "fstd %%fr3,0(%1)\n"
+          : "=m" (*_regs), "+r" (_regs));
 
   temp.__status_word &= ~(FE_ALL_EXCEPT
                          | (FE_ALL_EXCEPT << 27)
@@ -55,15 +53,12 @@ fesetenv (const fenv_t *envp)
                              | (FE_ALL_EXCEPT << 27)));
 
   /* Load the new environment. */
-  {
-    fenv_t * _regs = &temp + 1;
-    __asm__ (
-            "fldd,mb -8(%2),%%fr3\n"
-            "fldd,mb -8(%2),%%fr2\n"
-            "fldd,mb -8(%2),%%fr1\n"
-            "fldd -8(%2),%%fr0\n"
-            : "=m" (*_regs), "=r" (_regs) : "1" (_regs));
-  }
+  __asm__ (
+          "fldd,ma -8(%1),%%fr3\n"
+          "fldd,ma -8(%1),%%fr2\n"
+          "fldd,ma -8(%1),%%fr1\n"
+          "fldd 0(%1),%%fr0\n"
+          : "=m" (*_regs), "+r" (_regs));
 
   /* Success.  */
   return 0;
index c61b7b298ada42dd7bb3149e0094e28e85f313f6..8980dfd69caf365dd55b64ea53e42222bc10bbd5 100644 (file)
@@ -27,14 +27,12 @@ feupdateenv (const fenv_t *envp)
 
   /* Get the current exception status. */
   __asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw));
-  sw[0] &= (FE_ALL_EXCEPT << 27);
-
+  sw[0] &= FE_ALL_EXCEPT;
+  envp->__status_word = envp->__status_word | sw[0];
+  
   /* Install new environment.  */
   fesetenv (envp);
 
-  /* Raise the saved exception. */
-  feraiseexcept (sw[0] >> 27);
-
   /* Success.  */
   return 0;
 }
index a13668f954a485083518b3a6fdedc02fc436871a..b064dc1527c6681c6e0373dee1380eae21450a4a 100644 (file)
@@ -22,6 +22,9 @@
 #include <float.h>
 #include <math.h>
 
+/* Please see section 10, 
+   page 10-5 "Delayed Trapping" in the PA-RISC 2.0 Architecture manual */
+
 int
 feraiseexcept (int excepts)
 {
@@ -33,56 +36,64 @@ feraiseexcept (int excepts)
 
   /* We do these bits in assembly to be certain GCC doesn't optimize
      away something important, and so we can force delayed traps to
-     occur.  */
-
-  /* FIXME: These all need verification! */
+     occur. */
 
-  /* First: invalid exception.  */
+  /* We use "fldd 0(%%sr0,%%sp),%0" to flush the delayed exception */
+       
+  /* First: Invalid exception.  */
   if (excepts & FE_INVALID)
     {
       /* One example of a invalid operation is 0 * Infinity.  */
       double d = HUGE_VAL;
-      __asm__ __volatile__ ("fmpy,dbl %1,%%fr0,%0\n\t"
-                           /* FIXME: is this a proper trap barrier? */
-                           "fcpy,dbl %%fr0,%%fr0" : "=f" (d) : "0" (d));
+      __asm__ __volatile__ (
+               "       fcpy,dbl %%fr0,%%fr22\n"
+               "       fmpy,dbl %0,%%fr22,%0\n"
+               "       fldd 0(%%sr0,%%sp),%0"
+               : "+f" (d) : : "%fr22" );
     }
 
-  /* Next: division by zero.  */
+  /* Second: Division by zero.  */
   if (excepts & FE_DIVBYZERO)
     {
       double d = 1.0;
-      __asm__ __volatile__ ("fdiv,dbl %1,%%fr0,%0\n\t"
-                           "fcpy,dbl %%fr0,%%fr0" : "=f" (d) : "0" (d));
+      __asm__ __volatile__ (
+               "       fcpy,dbl %%fr0,%%fr22\n"
+               "       fdiv,dbl %0,%%fr22,%0\n"
+               "       fldd 0(%%sr0,%%sp),%0"
+               : "+f" (d) : : "%fr22" );
     }
 
-  /* Next: overflow.  */
-  /* FIXME: Compare with IA-64 - do we have the same problem? */
+  /* Third: Overflow.  */
   if (excepts & FE_OVERFLOW)
     {
       double d = DBL_MAX;
-
-      __asm__ __volatile__ ("fmpy,dbl %1,%1,%0\n\t"
-                           "fcpy,dbl %%fr0,%%fr0" : "=f" (d) : "0" (d));
+      __asm__ __volatile__ (
+               "       fadd,dbl %0,%0,%0\n"
+               "       fldd 0(%%sr0,%%sp),%0"
+               : "+f" (d) );
     }
 
-  /* Next: underflow.  */
+  /* Fourth: Underflow.  */
   if (excepts & FE_UNDERFLOW)
     {
       double d = DBL_MIN;
-      double e = 69.69;
-
-      __asm__ __volatile__ ("fdiv,dbl %1,%2,%0\n\t"
-                           "fcpy,dbl %%fr0,%%fr0" : "=f" (d) : "0" (d), "f" (e));
+      double e = 3.0;
+      __asm__ __volatile__ (
+               "       fdiv,dbl %0,%1,%0\n"
+               "       fldd 0(%%sr0,%%sp),%0"
+               : "+f" (d) : "f" (e) );
     }
 
-  /* Last: inexact.  */
+  /* Fifth: Inexact */
   if (excepts & FE_INEXACT)
     {
-      double d = 1.0;
-      double e = M_PI;
-
-      __asm__ __volatile__ ("fdiv,dbl %1,%2,%0\n\t"
-                           "fcpy,dbl %%fr0,%%fr0" : "=f" (d) : "0" (d), "f" (e));
+      double d = M_PI;
+      double e = 69.69;
+      __asm__ __volatile__ (
+               "       fdiv,dbl %0,%1,%%fr22\n"
+               "       fcnvfxt,dbl,sgl %%fr22,%%fr22L\n"
+               "       fldd 0(%%sr0,%%sp),%%fr22"
+               : : "f" (d), "f" (e) : "%fr22" );
     }
 
   /* Success.  */
index 343ddad943328370ecb1d15fa4ed1d181be6e1c8..af35f5ae351d19aa254c76b9bf52cd6a8af83f44 100644 (file)
@@ -29,8 +29,7 @@ fesetexceptflag (const fexcept_t *flagp, int excepts)
   /* Get the current status word. */
   __asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw));
 
-  /* Install the new exception flags bits.  */
-  sw[0] &= ~(excepts & (FE_ALL_EXCEPT >> 27));
+  /* Install new enable trap bits  */
   sw[0] |= (*flagp & excepts & FE_ALL_EXCEPT) << 27;
 
   /* Store the new status word.  */
This page took 0.075467 seconds and 5 git commands to generate.