strtoumax: fix typo in previous commit.
[gnulib.git] / lib / memcmp.c
index 5756bc0..ecba128 100644 (file)
@@ -1,12 +1,14 @@
-/* Copyright (C) 1991, 1993, 1995, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1993, 1995, 1997-1998, 2003, 2006, 2009-2013 Free
+   Software Foundation, Inc.
+
    Contributed by Torbjorn Granlund (tege@sics.se).
 
    NOTE: The canonical source of this file is maintained with the GNU C Library.
    Bugs can be reported to bug-glibc@prep.ai.mit.edu.
 
    Contributed by Torbjorn Granlund (tege@sics.se).
 
    NOTE: The canonical source of this file is maintained with the GNU C Library.
    Bugs can be reported to bug-glibc@prep.ai.mit.edu.
 
-   This program is free software; you can redistribute it and/or modify it
+   This program is free software: you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
    under the terms of the GNU General Public License as published by the
-   Free Software Foundation; either version 2, or (at your option) any
+   Free Software Foundation; either version 3 of the License, or any
    later version.
 
    This program is distributed in the hope that it will be useful,
    later version.
 
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-   USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
-#ifdef HAVE_CONFIG_H
-# include "config.h"
+#ifndef _LIBC
+# include <config.h>
 #endif
 
 #endif
 
-#undef __ptr_t
-#if defined __cplusplus || (defined __STDC__ && __STDC__)
-# define __ptr_t       void *
-#else /* Not C++ or ANSI C.  */
-# undef        const
-# define const
-# define __ptr_t       char *
-#endif /* C++ or ANSI C.  */
-
-#ifndef __P
-# if defined __GNUC__ || (defined __STDC__ && __STDC__)
-#  define __P(args) args
-# else
-#  define __P(args) ()
-# endif  /* GCC.  */
-#endif  /* Not __P.  */
+#include <string.h>
 
 
-#if defined HAVE_STRING_H || defined _LIBC
-# include <string.h>
-#endif
+#include <stdint.h>
 
 #undef memcmp
 
 
 #undef memcmp
 
 #  define WORDS_BIGENDIAN
 # endif
 
 #  define WORDS_BIGENDIAN
 # endif
 
-#else  /* Not in the GNU C library.  */
+#else   /* Not in the GNU C library.  */
 
 # include <sys/types.h>
 
 /* Type to use for aligned memory operations.
    This should normally be the biggest type supported by a single load
    and store.  Must be an unsigned type.  */
 
 # include <sys/types.h>
 
 /* Type to use for aligned memory operations.
    This should normally be the biggest type supported by a single load
    and store.  Must be an unsigned type.  */
-# define op_t  unsigned long int
-# define OPSIZ (sizeof(op_t))
+# define op_t   unsigned long int
+# define OPSIZ  (sizeof(op_t))
 
 /* Threshold value for when to enter the unrolled loops.  */
 
 /* Threshold value for when to enter the unrolled loops.  */
-# define OP_T_THRES    16
+# define OP_T_THRES     16
 
 /* Type to use for unaligned operations.  */
 typedef unsigned char byte;
 
 /* Type to use for unaligned operations.  */
 typedef unsigned char byte;
@@ -77,12 +60,12 @@ typedef unsigned char byte;
 #  define MERGE(w0, sh_1, w1, sh_2) (((w0) << (sh_1)) | ((w1) >> (sh_2)))
 # endif
 
 #  define MERGE(w0, sh_1, w1, sh_2) (((w0) << (sh_1)) | ((w1) >> (sh_2)))
 # endif
 
-#endif /* In the GNU C library.  */
+#endif  /* In the GNU C library.  */
 
 #ifdef WORDS_BIGENDIAN
 # define CMP_LT_OR_GT(a, b) ((a) > (b) ? 1 : -1)
 #else
 
 #ifdef WORDS_BIGENDIAN
 # define CMP_LT_OR_GT(a, b) ((a) > (b) ? 1 : -1)
 #else
-# define CMP_LT_OR_GT(a, b) memcmp_bytes ((a), (b))
+# define CMP_LT_OR_GT(a, b) memcmp_bytes (a, b)
 #endif
 
 /* BE VERY CAREFUL IF YOU CHANGE THIS CODE!  */
 #endif
 
 /* BE VERY CAREFUL IF YOU CHANGE THIS CODE!  */
@@ -103,22 +86,20 @@ typedef unsigned char byte;
    A and B are known to be different.
    This is needed only on little-endian machines.  */
 
    A and B are known to be different.
    This is needed only on little-endian machines.  */
 
-static int memcmp_bytes __P((op_t, op_t));
-
 # ifdef  __GNUC__
 __inline
 # endif
 static int
 # ifdef  __GNUC__
 __inline
 # endif
 static int
-memcmp_bytes (long unsigned int a, long unsigned int b)
+memcmp_bytes (op_t a, op_t b)
 {
 {
-  long int srcp1 = (long int) &a;
-  long int srcp2 = (long int) &b;
+  const byte *srcp1 = (const byte *) &a;
+  const byte *srcp2 = (const byte *) &b;
   op_t a0, b0;
 
   do
     {
   op_t a0, b0;
 
   do
     {
-      a0 = ((byte *) srcp1)[0];
-      b0 = ((byte *) srcp2)[0];
+      a0 = srcp1[0];
+      b0 = srcp2[0];
       srcp1 += 1;
       srcp2 += 1;
     }
       srcp1 += 1;
       srcp2 += 1;
     }
@@ -127,16 +108,14 @@ memcmp_bytes (long unsigned int a, long unsigned int b)
 }
 #endif
 
 }
 #endif
 
-static int memcmp_common_alignment __P((long, long, size_t));
-
-/* memcmp_common_alignment -- Compare blocks at SRCP1 and SRCP2 with LEN `op_t'
+/* memcmp_common_alignment -- Compare blocks at SRCP1 and SRCP2 with LEN 'op_t'
    objects (not LEN bytes!).  Both SRCP1 and SRCP2 should be aligned for
    objects (not LEN bytes!).  Both SRCP1 and SRCP2 should be aligned for
-   memory operations on `op_t's.  */
-#ifdef __GNUC__
+   memory operations on 'op_t's.  */
+#ifdef __GNUC__
 __inline
 #endif
 static int
 __inline
 #endif
 static int
-memcmp_common_alignment (long int srcp1, long int srcp2, size_t len)
+memcmp_common_alignment (uintptr_t srcp1, uintptr_t srcp2, size_t len)
 {
   op_t a0, a1;
   op_t b0, b1;
 {
   op_t a0, a1;
   op_t b0, b1;
@@ -160,7 +139,7 @@ memcmp_common_alignment (long int srcp1, long int srcp2, size_t len)
       goto do2;
     case 0:
       if (OP_T_THRES <= 3 * OPSIZ && len == 0)
       goto do2;
     case 0:
       if (OP_T_THRES <= 3 * OPSIZ && len == 0)
-       return 0;
+        return 0;
       a0 = ((op_t *) srcp1)[0];
       b0 = ((op_t *) srcp2)[0];
       goto do3;
       a0 = ((op_t *) srcp1)[0];
       b0 = ((op_t *) srcp2)[0];
       goto do3;
@@ -171,7 +150,7 @@ memcmp_common_alignment (long int srcp1, long int srcp2, size_t len)
       srcp2 += OPSIZ;
       len -= 1;
       if (OP_T_THRES <= 3 * OPSIZ && len == 0)
       srcp2 += OPSIZ;
       len -= 1;
       if (OP_T_THRES <= 3 * OPSIZ && len == 0)
-       goto do0;
+        goto do0;
       /* Fall through.  */
     }
 
       /* Fall through.  */
     }
 
@@ -180,25 +159,25 @@ memcmp_common_alignment (long int srcp1, long int srcp2, size_t len)
       a0 = ((op_t *) srcp1)[0];
       b0 = ((op_t *) srcp2)[0];
       if (a1 != b1)
       a0 = ((op_t *) srcp1)[0];
       b0 = ((op_t *) srcp2)[0];
       if (a1 != b1)
-       return CMP_LT_OR_GT (a1, b1);
+        return CMP_LT_OR_GT (a1, b1);
 
     do3:
       a1 = ((op_t *) srcp1)[1];
       b1 = ((op_t *) srcp2)[1];
       if (a0 != b0)
 
     do3:
       a1 = ((op_t *) srcp1)[1];
       b1 = ((op_t *) srcp2)[1];
       if (a0 != b0)
-       return CMP_LT_OR_GT (a0, b0);
+        return CMP_LT_OR_GT (a0, b0);
 
     do2:
       a0 = ((op_t *) srcp1)[2];
       b0 = ((op_t *) srcp2)[2];
       if (a1 != b1)
 
     do2:
       a0 = ((op_t *) srcp1)[2];
       b0 = ((op_t *) srcp2)[2];
       if (a1 != b1)
-       return CMP_LT_OR_GT (a1, b1);
+        return CMP_LT_OR_GT (a1, b1);
 
     do1:
       a1 = ((op_t *) srcp1)[3];
       b1 = ((op_t *) srcp2)[3];
       if (a0 != b0)
 
     do1:
       a1 = ((op_t *) srcp1)[3];
       b1 = ((op_t *) srcp2)[3];
       if (a0 != b0)
-       return CMP_LT_OR_GT (a0, b0);
+        return CMP_LT_OR_GT (a0, b0);
 
       srcp1 += 4 * OPSIZ;
       srcp2 += 4 * OPSIZ;
 
       srcp1 += 4 * OPSIZ;
       srcp2 += 4 * OPSIZ;
@@ -214,16 +193,14 @@ memcmp_common_alignment (long int srcp1, long int srcp2, size_t len)
   return 0;
 }
 
   return 0;
 }
 
-static int memcmp_not_common_alignment __P((long, long, size_t));
-
 /* memcmp_not_common_alignment -- Compare blocks at SRCP1 and SRCP2 with LEN
 /* memcmp_not_common_alignment -- Compare blocks at SRCP1 and SRCP2 with LEN
-   `op_t' objects (not LEN bytes!).  SRCP2 should be aligned for memory
-   operations on `op_t', but SRCP1 *should be unaligned*.  */
-#ifdef __GNUC__
+   'op_t' objects (not LEN bytes!).  SRCP2 should be aligned for memory
+   operations on 'op_t', but SRCP1 *should be unaligned*.  */
+#ifdef __GNUC__
 __inline
 #endif
 static int
 __inline
 #endif
 static int
-memcmp_not_common_alignment (long int srcp1, long int srcp2, size_t len)
+memcmp_not_common_alignment (uintptr_t srcp1, uintptr_t srcp2, size_t len)
 {
   op_t a0, a1, a2, a3;
   op_t b0, b1, b2, b3;
 {
   op_t a0, a1, a2, a3;
   op_t b0, b1, b2, b3;
@@ -236,7 +213,7 @@ memcmp_not_common_alignment (long int srcp1, long int srcp2, size_t len)
   shl = 8 * (srcp1 % OPSIZ);
   shr = 8 * OPSIZ - shl;
 
   shl = 8 * (srcp1 % OPSIZ);
   shr = 8 * OPSIZ - shl;
 
-  /* Make SRCP1 aligned by rounding it down to the beginning of the `op_t'
+  /* Make SRCP1 aligned by rounding it down to the beginning of the 'op_t'
      it points in the middle of.  */
   srcp1 &= -OPSIZ;
 
      it points in the middle of.  */
   srcp1 &= -OPSIZ;
 
@@ -260,7 +237,7 @@ memcmp_not_common_alignment (long int srcp1, long int srcp2, size_t len)
       goto do2;
     case 0:
       if (OP_T_THRES <= 3 * OPSIZ && len == 0)
       goto do2;
     case 0:
       if (OP_T_THRES <= 3 * OPSIZ && len == 0)
-       return 0;
+        return 0;
       a3 = ((op_t *) srcp1)[0];
       a0 = ((op_t *) srcp1)[1];
       b0 = ((op_t *) srcp2)[0];
       a3 = ((op_t *) srcp1)[0];
       a0 = ((op_t *) srcp1)[1];
       b0 = ((op_t *) srcp2)[0];
@@ -274,7 +251,7 @@ memcmp_not_common_alignment (long int srcp1, long int srcp2, size_t len)
       srcp2 += 1 * OPSIZ;
       len -= 1;
       if (OP_T_THRES <= 3 * OPSIZ && len == 0)
       srcp2 += 1 * OPSIZ;
       len -= 1;
       if (OP_T_THRES <= 3 * OPSIZ && len == 0)
-       goto do0;
+        goto do0;
       /* Fall through.  */
     }
 
       /* Fall through.  */
     }
 
@@ -282,30 +259,30 @@ memcmp_not_common_alignment (long int srcp1, long int srcp2, size_t len)
     {
       a0 = ((op_t *) srcp1)[0];
       b0 = ((op_t *) srcp2)[0];
     {
       a0 = ((op_t *) srcp1)[0];
       b0 = ((op_t *) srcp2)[0];
-      x = MERGE(a2, shl, a3, shr);
+      x = MERGE (a2, shl, a3, shr);
       if (x != b3)
       if (x != b3)
-       return CMP_LT_OR_GT (x, b3);
+        return CMP_LT_OR_GT (x, b3);
 
     do3:
       a1 = ((op_t *) srcp1)[1];
       b1 = ((op_t *) srcp2)[1];
 
     do3:
       a1 = ((op_t *) srcp1)[1];
       b1 = ((op_t *) srcp2)[1];
-      x = MERGE(a3, shl, a0, shr);
+      x = MERGE (a3, shl, a0, shr);
       if (x != b0)
       if (x != b0)
-       return CMP_LT_OR_GT (x, b0);
+        return CMP_LT_OR_GT (x, b0);
 
     do2:
       a2 = ((op_t *) srcp1)[2];
       b2 = ((op_t *) srcp2)[2];
 
     do2:
       a2 = ((op_t *) srcp1)[2];
       b2 = ((op_t *) srcp2)[2];
-      x = MERGE(a0, shl, a1, shr);
+      x = MERGE (a0, shl, a1, shr);
       if (x != b1)
       if (x != b1)
-       return CMP_LT_OR_GT (x, b1);
+        return CMP_LT_OR_GT (x, b1);
 
     do1:
       a3 = ((op_t *) srcp1)[3];
       b3 = ((op_t *) srcp2)[3];
 
     do1:
       a3 = ((op_t *) srcp1)[3];
       b3 = ((op_t *) srcp2)[3];
-      x = MERGE(a1, shl, a2, shr);
+      x = MERGE (a1, shl, a2, shr);
       if (x != b2)
       if (x != b2)
-       return CMP_LT_OR_GT (x, b2);
+        return CMP_LT_OR_GT (x, b2);
 
       srcp1 += 4 * OPSIZ;
       srcp2 += 4 * OPSIZ;
 
       srcp1 += 4 * OPSIZ;
       srcp2 += 4 * OPSIZ;
@@ -316,7 +293,7 @@ memcmp_not_common_alignment (long int srcp1, long int srcp2, size_t len)
   /* This is the right position for do0.  Please don't move
      it into the loop.  */
  do0:
   /* This is the right position for do0.  Please don't move
      it into the loop.  */
  do0:
-  x = MERGE(a2, shl, a3, shr);
+  x = MERGE (a2, shl, a3, shr);
   if (x != b3)
     return CMP_LT_OR_GT (x, b3);
   return 0;
   if (x != b3)
     return CMP_LT_OR_GT (x, b3);
   return 0;
@@ -327,36 +304,36 @@ rpl_memcmp (const void *s1, const void *s2, size_t len)
 {
   op_t a0;
   op_t b0;
 {
   op_t a0;
   op_t b0;
-  long int srcp1 = (long int) s1;
-  long int srcp2 = (long int) s2;
+  uintptr_t srcp1 = (uintptr_t) s1;
+  uintptr_t srcp2 = (uintptr_t) s2;
   op_t res;
 
   if (len >= OP_T_THRES)
     {
       /* There are at least some bytes to compare.  No need to test
   op_t res;
 
   if (len >= OP_T_THRES)
     {
       /* There are at least some bytes to compare.  No need to test
-        for LEN == 0 in this alignment loop.  */
+         for LEN == 0 in this alignment loop.  */
       while (srcp2 % OPSIZ != 0)
       while (srcp2 % OPSIZ != 0)
-       {
-         a0 = ((byte *) srcp1)[0];
-         b0 = ((byte *) srcp2)[0];
-         srcp1 += 1;
-         srcp2 += 1;
-         res = a0 - b0;
-         if (res != 0)
-           return res;
-         len -= 1;
-       }
-
-      /* SRCP2 is now aligned for memory operations on `op_t'.
-        SRCP1 alignment determines if we can do a simple,
-        aligned compare or need to shuffle bits.  */
+        {
+          a0 = ((byte *) srcp1)[0];
+          b0 = ((byte *) srcp2)[0];
+          srcp1 += 1;
+          srcp2 += 1;
+          res = a0 - b0;
+          if (res != 0)
+            return res;
+          len -= 1;
+        }
+
+      /* SRCP2 is now aligned for memory operations on 'op_t'.
+         SRCP1 alignment determines if we can do a simple,
+         aligned compare or need to shuffle bits.  */
 
       if (srcp1 % OPSIZ == 0)
 
       if (srcp1 % OPSIZ == 0)
-       res = memcmp_common_alignment (srcp1, srcp2, len / OPSIZ);
+        res = memcmp_common_alignment (srcp1, srcp2, len / OPSIZ);
       else
       else
-       res = memcmp_not_common_alignment (srcp1, srcp2, len / OPSIZ);
+        res = memcmp_not_common_alignment (srcp1, srcp2, len / OPSIZ);
       if (res != 0)
       if (res != 0)
-       return res;
+        return res;
 
       /* Number of bytes remaining in the interval [0..OPSIZ-1].  */
       srcp1 += len & -OPSIZ;
 
       /* Number of bytes remaining in the interval [0..OPSIZ-1].  */
       srcp1 += len & -OPSIZ;
@@ -373,7 +350,7 @@ rpl_memcmp (const void *s1, const void *s2, size_t len)
       srcp2 += 1;
       res = a0 - b0;
       if (res != 0)
       srcp2 += 1;
       res = a0 - b0;
       if (res != 0)
-       return res;
+        return res;
       len -= 1;
     }
 
       len -= 1;
     }