entered into RCS
authorbrendan <brendan>
Thu, 23 Dec 1993 05:57:47 +0000 (05:57 +0000)
committerbrendan <brendan>
Thu, 23 Dec 1993 05:57:47 +0000 (05:57 +0000)
sysdeps/alpha/Dist
sysdeps/alpha/Makefile
sysdeps/alpha/divrem.m4 [new file with mode: 0644]
sysdeps/alpha/macros.m4 [new file with mode: 0644]
sysdeps/alpha/memchr.c
sysdeps/alpha/setjmp.S
sysdeps/alpha/strchr.c
sysdeps/alpha/strlen.c

index ad6ea03..c4ea856 100644 (file)
@@ -1 +1,4 @@
 setjmp_aux.c
+DEFS.h
+divrem.m4 macros.m4
+divl.S divlu.S divq.S divqu.S reml.S remlu.S remq.S remqu.S
index 7364141..5490776 100644 (file)
@@ -1,3 +1,91 @@
+# Copyright (C) 1993 Free Software Foundation, Inc.
+# Contributed by Brendan Kehoe (brendan@zen.org).
+
+# 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., 675 Mass Ave,
+# Cambridge, MA 02139, USA.
+
 ifeq ($(subdir),setjmp)
 sysdep_routines := $(sysdep_routines) setjmp_aux
 endif
+
+ifeq ($(subdir),gnulib)
+routines = $(divrem) 
+endif  # gnulib
+
+# We distribute these files, even though they are generated,
+# so as to avoid the need for a functioning m4 to build the library.
+divrem := divl divlu divq divqu reml remlu remq remqu
+
++divrem-NAME-divl := divl
++divrem-NAME-divlu := divlu
++divrem-NAME-divq := divq
++divrem-NAME-divqu := divqu
++divrem-NAME-reml := reml
++divrem-NAME-remlu := remlu
++divrem-NAME-remq := remq
++divrem-NAME-remqu := remqu
++divrem-NAME = $(+divrem-NAME-$(basename $(notdir $@)))
+
++divrem-OP-divl := divl
++divrem-OP-divlu := divlu
++divrem-OP-divq := divq
++divrem-OP-divqu := divqu
++divrem-OP-reml := reml
++divrem-OP-remlu := remlu
++divrem-OP-remq := remq
++divrem-OP-remqu := remqu
++divrem-BASEOP-divl := div
++divrem-BASEOP-divlu := div
++divrem-BASEOP-divq := div
++divrem-BASEOP-divqu := div
++divrem-BASEOP-reml := rem
++divrem-BASEOP-remlu := rem
++divrem-BASEOP-remq := rem
++divrem-BASEOP-remqu := rem
++divrem-S-divl := true
++divrem-S-divlu := false
++divrem-S-divq := true
++divrem-S-divqu := false
++divrem-S-reml := true
++divrem-S-remlu := false
++divrem-S-remq := true
++divrem-S-remqu := false
++divrem-SIZE-divl := l
++divrem-SIZE-divlu := l
++divrem-SIZE-divq := q
++divrem-SIZE-divqu := q
++divrem-SIZE-reml := l
++divrem-SIZE-remlu := l
++divrem-SIZE-remq := q
++divrem-SIZE-remqu := q
++divrem-MODE-divl := l
++divrem-MODE-divlu := lu
++divrem-MODE-divq := q
++divrem-MODE-divqu := qu
++divrem-MODE-reml := l
++divrem-MODE-remlu := lu
++divrem-MODE-remq := q
++divrem-MODE-remqu := qu
+
+$(divrem:%=$(sysdep_dir)/alpha/%.S): $(sysdep_dir)/alpha/divrem.m4 $(sysdep_dir)/alpha/DEFS.h $(sysdep_dir)/alpha/macros.m4
+       (echo "define(OP,\`$(+divrem-NAME)')\
+              define(BASEOP,\`$(+divrem-BASEOP-$(+divrem-NAME))')\
+              define(MODE,\`$(+divrem-MODE-$(+divrem-NAME))')\
+              define(SIZE,\`$(+divrem-SIZE-$(+divrem-NAME))')\
+              define(SIGNED,\`$(+divrem-S-$(+divrem-NAME))')\
+              define(SYSDEP_DIR, \`$(sysdep_dir)/alpha')\
+              /* This file is generated from divrem.m4; DO NOT EDIT! */"; \
+        cat $<) | $(M4) > $@-tmp
+       mv $@-tmp $@
diff --git a/sysdeps/alpha/divrem.m4 b/sysdeps/alpha/divrem.m4
new file mode 100644 (file)
index 0000000..ab86128
--- /dev/null
@@ -0,0 +1,48 @@
+/* For each N divided by D, we do:
+      result = (double) N / (double) D
+   Then, for each N mod D, we do:
+      result = N - (D * divMODE (N, D))
+
+   FIXME:
+   The q and qu versions won't deal with operands > 50 bits.  We also
+   don't check for divide by zero.  */
+
+#include "DEFS.h"
+#if 0
+/* We do not handle div by zero yet.  */
+#include <machine/pal.h>
+#endif
+#include <regdef.h>
+
+define(path, `SYSDEP_DIR/macros.m4')dnl
+include(path)
+
+FUNC__(OP)
+       ! First set up the dividend.
+       EXTEND(t10)
+       stq t10,0(sp)
+       ldt $f10,0(sp)
+       cvtqt $f10,$f10
+       ADJQU($f10)
+
+       ! Then set up the divisor.
+       EXTEND(t11)
+       stq t11,0(sp)
+       ldt $f1,0(sp)
+       cvtqt $f1,$f1
+       ADJQU($f1)
+
+       ! Do the division.
+       divt $f10,$f1,$f10
+       cvttqc $f10,$f10
+
+       ! Put the result in t12.
+       stt $f10,0(sp)
+       ldq t12,0(sp)
+       FULLEXTEND(t12)
+
+       DOREM
+
+       lda sp,16(sp)
+       ret zero,(t9),1
+       .end NAME__(OP)
diff --git a/sysdeps/alpha/macros.m4 b/sysdeps/alpha/macros.m4
new file mode 100644 (file)
index 0000000..982e705
--- /dev/null
@@ -0,0 +1,34 @@
+dnl NOTE: The $1 below is the argument to EXTEND, not register $1.
+define(EXTEND,
+`ifelse(SIZE, `l',
+`ifelse(SIGNED, `true',
+`      sextl $1, $1
+',dnl
+`      zapnot $1, 0xf, $1
+')')')dnl
+
+dnl FULLEXTEND -- extend the register named in the first argument
+define(FULLEXTEND,
+`ifelse(SIZE, `l',
+`      sextl $1, $1
+')')dnl
+
+dnl This is used by divqu.
+define(ADJQU,
+`ifelse(MODE, `qu',
+`      ldit    $f26, 18446744073709551616.0
+       addt    $f26, $1, $f26
+       fcmovlt $1, $f26, $1
+')')dnl
+
+define(DOREM,
+`ifelse(BASEOP, `rem',
+`      ! Compute the remainder.
+ifelse(SIZE, `l',
+`      mull t11, t12, t11
+       subl t10, t11, t12
+',dnl Note mulq/subq were only really used in remq, but we will find out
+dnl   if assuming they apply to remqu as well is wrong or not.
+`      mulq t11, t12, t11
+       subq t10, t11, t12
+')')')dnl
index 048c9fa..c6f99bf 100644 (file)
@@ -25,6 +25,7 @@ memchr (const void *s, int c, size_t n)
   const char *char_ptr;
   const unsigned long int *longword_ptr;
   unsigned long int charmask;
+  size_t x;
 
   c = (unsigned char) c;
 
@@ -35,18 +36,29 @@ memchr (const void *s, int c, size_t n)
     if (*char_ptr == c)
       return (void *) char_ptr;
 
+  if (n == (size_t)0)
+    return NULL;
+
+  x = n;
+
   longword_ptr = (unsigned long int *) char_ptr;
 
   /* Set up a longword, each of whose bytes is C.  */
   charmask = c | (c << 8);
   charmask |= charmask << 16;
   charmask |= charmask << 32;
+  charmask |= charmask << 64;
 
   for (;;)
     {
       const unsigned long int longword = *longword_ptr++;
       int ge, le;
 
+      if (x < 4)
+       x = (size_t) 0;
+      else
+       x -= 4;
+
       /* Set bits in GE if bytes in CHARMASK are >= bytes in LONGWORD.  */
       asm ("cmpbge %1, %2, %0" : "=r" (ge) : "r" (charmask), "r" (longword));
 
@@ -58,15 +70,18 @@ memchr (const void *s, int c, size_t n)
        {
          /* Which of the bytes was the C?  */
 
-         char *cp = (char *) (longword_ptr - 1);
+         unsigned char *cp = (unsigned char *) (longword_ptr - 1);
+         int i;
 
-         if (cp[0] == c)
-           return cp;
-         if (cp[1] == c)
-           return &cp[1];
-         if (cp[2] == c)
-           return &cp[2];
-         return &cp[3];
+         for (i = 0; i < 6; i++)
+           if (cp[i] == c)
+             return &cp[i];
+         return &cp[7];
        }
+
+      if (x == (size_t)0)
+       break;
     }
+
+  return NULL;
 }
index a5de80c..3880d0f 100644 (file)
@@ -26,3 +26,4 @@ ENTRY (__setjmp)
        bis $15, $15, $17       /* Pass FP as 2nd arg.  */
        bis $30, $30, $18       /* Pass SP as 3nd arg.  */
        jmp $31, ($27), __setjmp_aux /* Call __setjmp_aux.  */
+       .end __setjmp
index db279de..fc56d51 100644 (file)
@@ -32,10 +32,10 @@ strchr (const char *str, int c)
   /* Handle the first few characters by reading one character at a time.
      Do this until STR is aligned on a 8-byte border.  */
   for (char_ptr = str; ((unsigned long int) char_ptr & 7) != 0; ++char_ptr)
-    if (*char_ptr == '\0')
-      return NULL;
-    else if (*char_ptr == c)
+    if (*char_ptr == c)
       return (char *) char_ptr;
+    else if (*char_ptr == '\0')
+      return NULL;
 
   longword_ptr = (unsigned long int *) char_ptr;
 
@@ -43,6 +43,7 @@ strchr (const char *str, int c)
   charmask = c | (c << 8);
   charmask |= charmask << 16;
   charmask |= charmask << 32;
+  charmask |= charmask << 64;
 
   for (;;)
     {
@@ -64,21 +65,15 @@ strchr (const char *str, int c)
          /* Which of the bytes was the C?  */
 
          char *cp = (char *) (longword_ptr - 1);
-
-         if (cp[0] == c)
-           return cp;
-         if (cp[0] == 0)
-           return NULL;
-         if (cp[1] == c)
-           return &cp[1];
-         if (cp[1] == 0)
-           return NULL;
-         if (cp[2] == c)
-           return &cp[2];
-         if (cp[2] == 0)
-           return NULL;
-         if (cp[3] == c)
-           return &cp[3];
+         int i;
+
+         for (i = 0; i < 8; i++)
+           {
+             if (cp[i] == c)
+               return &cp[i];
+             if (cp[i] == 0)
+               return NULL;
+           }
          return NULL;
        }
     }
index 3fd1b25..d774447 100644 (file)
@@ -43,14 +43,12 @@ strlen (const char *str)
          /* Which of the bytes was the zero?  */
 
          const char *cp = (const char *) (longword_ptr - 1);
+         int i;
 
-         if (cp[0] == 0)
-           return cp - str;
-         if (cp[1] == 0)
-           return cp - str + 1;
-         if (cp[2] == 0)
-           return cp - str + 2;
-         return cp - str + 3;
+         for (i = 0; i < 6; i++)
+           if (cp[i] == 0)
+             return cp - str + i;
+         return cp - str + 7;
        }
     }
 }