Add i386 memset and memcpy assembly functions
authorH.J. Lu <hjl.tools@gmail.com>
Thu, 27 Aug 2015 16:04:40 +0000 (09:04 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Thu, 27 Aug 2015 16:04:54 +0000 (09:04 -0700)
Add i386 memset and memcpy assembly functions with REP MOVSB/STOSB
instructions.

* sysdeps/i386/bcopy.S: New file.
* sysdeps/i386/bzero.S: Likewise.
* sysdeps/i386/memcpy.S: Likewise.
* sysdeps/i386/memmove.S: Likewise.
* sysdeps/i386/mempcpy.S: Likewise.
* sysdeps/i386/memset.S: Likewise.
* sysdeps/i386/bzero.c: Removed.
* sysdeps/i386/memset.c: Likewise.
* sysdeps/i386/i586/memcpy_chk.S: Likewise.
* sysdeps/i386/i586/mempcpy_chk.S: Likewise.
* sysdeps/i386/i586/memset_chk.S: Likewise.
* sysdeps/i386/i686/memcpy_chk.S: Moved to ...
* sysdeps/i386/memcpy_chk.S: Here.
* sysdeps/i386/i686/memmove_chk.S: Moved to ...
* sysdeps/i386/memmove_chk.S: Here.
* sysdeps/i386/i686/mempcpy_chk.S: Moved to ...
* sysdeps/i386/mempcpy_chk.S: Likewise.
* sysdeps/i386/i686/memset_chk.S: Moved to ...
* sysdeps/i386/memset_chk.S: Likewise.

16 files changed:
ChangeLog
sysdeps/i386/bcopy.S [new file with mode: 0644]
sysdeps/i386/bzero.S [new file with mode: 0644]
sysdeps/i386/bzero.c [deleted file]
sysdeps/i386/i586/memcpy_chk.S [deleted file]
sysdeps/i386/i586/mempcpy_chk.S [deleted file]
sysdeps/i386/i586/memset_chk.S [deleted file]
sysdeps/i386/memcpy.S [new file with mode: 0644]
sysdeps/i386/memcpy_chk.S [moved from sysdeps/i386/i686/memcpy_chk.S with 92% similarity]
sysdeps/i386/memmove.S [new file with mode: 0644]
sysdeps/i386/memmove_chk.S [moved from sysdeps/i386/i686/memmove_chk.S with 78% similarity]
sysdeps/i386/mempcpy.S [new file with mode: 0644]
sysdeps/i386/mempcpy_chk.S [moved from sysdeps/i386/i686/mempcpy_chk.S with 78% similarity]
sysdeps/i386/memset.S [new file with mode: 0644]
sysdeps/i386/memset.c [deleted file]
sysdeps/i386/memset_chk.S [moved from sysdeps/i386/i686/memset_chk.S with 79% similarity]

index 8e65558..df391c2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2015-08-27  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * sysdeps/i386/bcopy.S: New file.
+       * sysdeps/i386/bzero.S: Likewise.
+       * sysdeps/i386/memcpy.S: Likewise.
+       * sysdeps/i386/memmove.S: Likewise.
+       * sysdeps/i386/mempcpy.S: Likewise.
+       * sysdeps/i386/memset.S: Likewise.
+       * sysdeps/i386/bzero.c: Removed.
+       * sysdeps/i386/memset.c: Likewise.
+       * sysdeps/i386/i586/memcpy_chk.S: Likewise.
+       * sysdeps/i386/i586/mempcpy_chk.S: Likewise.
+       * sysdeps/i386/i586/memset_chk.S: Likewise.
+       * sysdeps/i386/i686/memcpy_chk.S: Moved to ...
+       * sysdeps/i386/memcpy_chk.S: Here.
+       * sysdeps/i386/i686/memmove_chk.S: Moved to ...
+       * sysdeps/i386/memmove_chk.S: Here.
+       * sysdeps/i386/i686/mempcpy_chk.S: Moved to ...
+       * sysdeps/i386/mempcpy_chk.S: Likewise.
+       * sysdeps/i386/i686/memset_chk.S: Moved to ...
+       * sysdeps/i386/memset_chk.S: Likewise.
+
 2015-08-27  Steve Ellcey  <sellcey@imgtec.com>
 
        * soft-fp/fmasf4.c: Add include of sys/cdefs.h.
diff --git a/sysdeps/i386/bcopy.S b/sysdeps/i386/bcopy.S
new file mode 100644 (file)
index 0000000..12b8ddb
--- /dev/null
@@ -0,0 +1,4 @@
+#define USE_AS_MEMMOVE
+#define USE_AS_BCOPY
+#define MEMCPY         bcopy
+#include "memcpy.S"
diff --git a/sysdeps/i386/bzero.S b/sysdeps/i386/bzero.S
new file mode 100644 (file)
index 0000000..c8dd47b
--- /dev/null
@@ -0,0 +1,5 @@
+#define USE_AS_BZERO
+#define memset __bzero
+#include "memset.S"
+
+weak_alias (__bzero, bzero)
diff --git a/sysdeps/i386/bzero.c b/sysdeps/i386/bzero.c
deleted file mode 100644 (file)
index 1a89444..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/* bzero -- set a block of memory to zero.  For Intel 80x86, x>=3.
-   This file is part of the GNU C Library.
-   Copyright (C) 1991-2015 Free Software Foundation, Inc.
-   Contributed by Torbjorn Granlund (tege@sics.se).
-
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <string.h>
-#include <memcopy.h>
-
-#undef bzero
-#undef __bzero
-
-#ifdef __GNUC__
-
-void
-__bzero (dstpp, len)
-     void *dstpp;
-     size_t len;
-{
-  /* N.B.: This code is almost verbatim from memset.c.  */
-  int d0;
-  unsigned long int dstp = (unsigned long int) dstpp;
-
-  /* This explicit register allocation
-     improves code very much indeed.  */
-  register op_t x asm ("ax");
-
-  x = 0;
-
-  /* Clear the direction flag, so filling will move forward.  */
-  asm volatile ("cld");
-
-  /* This threshold value is optimal.  */
-  if (len >= 12)
-    {
-      /* Adjust LEN for the bytes handled in the first loop.  */
-      len -= (-dstp) % OPSIZ;
-
-      /* There are at least some bytes to set.
-        No need to test for LEN == 0 in this alignment loop.  */
-
-      /* Fill bytes until DSTP is aligned on a longword boundary.  */
-      asm volatile ("rep\n"
-                   "stosb" /* %0, %2, %3 */ :
-                   "=D" (dstp), "=c" (d0) :
-                   "0" (dstp), "1" ((-dstp) % OPSIZ), "a" (x) :
-                   "memory");
-
-      /* Fill longwords.  */
-      asm volatile ("rep\n"
-                   "stosl" /* %0, %2, %3 */ :
-                   "=D" (dstp), "=c" (d0) :
-                   "0" (dstp), "1" (len / OPSIZ), "a" (x) :
-                   "memory");
-      len %= OPSIZ;
-    }
-
-  /* Write the last few bytes.  */
-  asm volatile ("rep\n"
-               "stosb" /* %0, %2, %3 */ :
-               "=D" (dstp), "=c" (d0) :
-               "0" (dstp), "c" (len), "a" (x) :
-               "memory");
-}
-weak_alias (__bzero, bzero)
-
-#else
-#include <string/bzero.c>
-#endif
diff --git a/sysdeps/i386/i586/memcpy_chk.S b/sysdeps/i386/i586/memcpy_chk.S
deleted file mode 100644 (file)
index ab8a95c..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <sysdeps/i386/i686/memcpy_chk.S>
diff --git a/sysdeps/i386/i586/mempcpy_chk.S b/sysdeps/i386/i586/mempcpy_chk.S
deleted file mode 100644 (file)
index 9a1de1d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <sysdeps/i386/i686/mempcpy_chk.S>
diff --git a/sysdeps/i386/i586/memset_chk.S b/sysdeps/i386/i586/memset_chk.S
deleted file mode 100644 (file)
index 09f9d42..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <sysdeps/i386/i686/memset_chk.S>
diff --git a/sysdeps/i386/memcpy.S b/sysdeps/i386/memcpy.S
new file mode 100644 (file)
index 0000000..5f0196e
--- /dev/null
@@ -0,0 +1,95 @@
+/* memcpy with REP MOVSB/STOSB
+   Copyright (C) 2015 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+#ifndef MEMCPY
+# define MEMCPY                memcpy
+# define MEMCPY_CHK    __memcpy_chk
+#endif
+
+#ifdef USE_AS_BCOPY
+# define STR2          12
+# define STR1          STR2+4
+# define N                     STR1+4
+#else
+# define STR1          12
+# define STR2          STR1+4
+# define N                     STR2+4
+#endif
+
+#define CFI_PUSH(REG)                                          \
+  cfi_adjust_cfa_offset (4);                                   \
+  cfi_rel_offset (REG, 0)
+
+#define CFI_POP(REG)                                           \
+  cfi_adjust_cfa_offset (-4);                                  \
+  cfi_restore (REG)
+
+#define PUSH(REG)      pushl REG; CFI_PUSH (REG)
+#define POP(REG)       popl REG; CFI_POP (REG)
+
+       .text
+#if defined SHARED && IS_IN (libc) && !defined USE_AS_BCOPY
+ENTRY (MEMCPY_CHK)
+       movl    12(%esp), %eax
+       cmpl    %eax, 16(%esp)
+       jb      HIDDEN_JUMPTARGET (__chk_fail)
+END (MEMCPY_CHK)
+#endif
+ENTRY (MEMCPY)
+       PUSH    (%esi)
+       PUSH    (%edi)
+       movl    N(%esp), %ecx
+       movl    STR1(%esp), %edi
+       movl    STR2(%esp), %esi
+       mov     %edi, %eax
+#ifdef USE_AS_MEMPCPY
+       add     %ecx, %eax
+#endif
+
+#ifdef USE_AS_MEMMOVE
+       cmp     %esi, %edi
+       ja      L(copy_backward)
+       je      L(bwd_write_0bytes)
+#endif
+
+       rep     movsb
+       POP     (%edi)
+       POP     (%esi)
+       ret
+
+#ifdef USE_AS_MEMMOVE
+L(copy_backward):
+       lea     -1(%edi,%ecx), %edi
+       lea     -1(%esi,%ecx), %esi
+       std
+       rep     movsb
+       cld
+L(bwd_write_0bytes):
+       POP     (%edi)
+       POP     (%esi)
+       ret
+#endif
+
+END (MEMCPY)
+
+#ifndef USE_AS_BCOPY
+libc_hidden_builtin_def (MEMCPY)
+#endif
similarity index 92%
rename from sysdeps/i386/i686/memcpy_chk.S
rename to sysdeps/i386/memcpy_chk.S
index cdf807f..b3b25de 100644 (file)
@@ -1,4 +1,4 @@
-/* Checking memcpy for i686.
+/* Checking memcpy for i386.
    Copyright (C) 2004-2015 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include "asm-syntax.h"
+#ifndef SHARED
+# include <sysdep.h>
+# include "asm-syntax.h"
 
-#ifndef PIC
        /* For libc.so this is defined in memcpy.S.
           For libc.a, this is a separate source to avoid
           memcpy bringing in __chk_fail and all routines
diff --git a/sysdeps/i386/memmove.S b/sysdeps/i386/memmove.S
new file mode 100644 (file)
index 0000000..60a45d2
--- /dev/null
@@ -0,0 +1,4 @@
+#define USE_AS_MEMMOVE
+#define MEMCPY         memmove
+#define MEMCPY_CHK     __memmove_chk
+#include "memcpy.S"
similarity index 78%
rename from sysdeps/i386/i686/memmove_chk.S
rename to sysdeps/i386/memmove_chk.S
index 64bf9e0..26d2abd 100644 (file)
@@ -1,4 +1,4 @@
-/* Checking memmove for x86-64.
+/* Checking memmove for i386
    Copyright (C) 2004-2015 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include "asm-syntax.h"
+#ifndef SHARED
+# include <sysdep.h>
+# include "asm-syntax.h"
 
-#ifndef PIC
-       /* For libc.so this is defined in memmove.S.
-          For libc.a, this is a separate source to avoid
-          memmove bringing in __chk_fail and all routines
-          it calls.  */
+/* For libc.so this is defined in memmove.S.  For libc.a, this is a
+   separate source to avoid memmove bringing in __chk_fail and all
+   routines it calls.  */
         .text
 ENTRY (__memmove_chk)
        movl    12(%esp), %eax
diff --git a/sysdeps/i386/mempcpy.S b/sysdeps/i386/mempcpy.S
new file mode 100644 (file)
index 0000000..61addb7
--- /dev/null
@@ -0,0 +1,7 @@
+#define USE_AS_MEMPCPY
+#define MEMCPY         __mempcpy
+#define MEMCPY_CHK     __mempcpy_chk
+#include "memcpy.S"
+
+weak_alias (__mempcpy, mempcpy)
+libc_hidden_builtin_def (mempcpy)
similarity index 78%
rename from sysdeps/i386/i686/mempcpy_chk.S
rename to sysdeps/i386/mempcpy_chk.S
index a61757b..05f86c3 100644 (file)
@@ -1,4 +1,4 @@
-/* Checking mempcpy for x86-64.
+/* Checking mempcpy for i386
    Copyright (C) 2004-2015 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include "asm-syntax.h"
+#ifndef SHARED
+# include <sysdep.h>
+# include "asm-syntax.h"
 
-#ifndef PIC
-       /* For libc.so this is defined in mempcpy.S.
-          For libc.a, this is a separate source to avoid
-          mempcpy bringing in __chk_fail and all routines
-          it calls.  */
+/* For libc.so this is defined in mempcpy.S.  For libc.a, this is a
+   separate source to avoid mempcpy bringing in __chk_fail and all
+   routines it calls.  */
         .text
 ENTRY (__mempcpy_chk)
        movl    12(%esp), %eax
diff --git a/sysdeps/i386/memset.S b/sysdeps/i386/memset.S
new file mode 100644 (file)
index 0000000..21b3430
--- /dev/null
@@ -0,0 +1,68 @@
+/* memset with REP MOVSB/STOSB
+   Copyright (C) 2015 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+#define CFI_PUSH(REG)                                          \
+  cfi_adjust_cfa_offset (4);                                   \
+  cfi_rel_offset (REG, 0)
+
+#define CFI_POP(REG)                                           \
+  cfi_adjust_cfa_offset (-4);                                  \
+  cfi_restore (REG)
+
+#define PUSH(REG)      pushl REG; CFI_PUSH (REG)
+#define POP(REG)       popl REG; CFI_POP (REG)
+
+#define STR1  8
+#ifdef USE_AS_BZERO
+#define N     STR1+4
+#else
+#define STR2  STR1+4
+#define N     STR2+4
+#endif
+
+       .text
+#if defined SHARED && IS_IN (libc) && !defined USE_AS_BZERO
+ENTRY (__memset_chk)
+       movl    12(%esp), %eax
+       cmpl    %eax, 16(%esp)
+       jb      HIDDEN_JUMPTARGET (__chk_fail)
+END (__memset_chk)
+#endif
+ENTRY (memset)
+       PUSH    (%edi)
+       movl    N(%esp), %ecx
+       movl    STR1(%esp), %edi
+#ifdef USE_AS_BZERO
+       xor     %eax, %eax
+#else
+       movzbl  STR2(%esp), %eax
+       mov     %edi, %edx
+#endif
+       rep     stosb
+#ifndef USE_AS_BZERO
+       mov     %edx, %eax
+#endif
+       POP     (%edi)
+       ret
+END (memset)
+
+#ifndef USE_AS_BZERO
+libc_hidden_builtin_def (memset)
+#endif
diff --git a/sysdeps/i386/memset.c b/sysdeps/i386/memset.c
deleted file mode 100644 (file)
index bf11590..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Set a block of memory to some byte value.
-   For Intel 80x86, x>=3.
-   Copyright (C) 1991-2015 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Torbjorn Granlund (tege@sics.se).
-
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <string.h>
-#include <memcopy.h>
-
-#ifdef __GNUC__
-
-#undef memset
-
-void *
-memset (void *dstpp, int c, size_t len)
-{
-  int d0;
-  unsigned long int dstp = (unsigned long int) dstpp;
-
-  /* This explicit register allocation
-     improves code very much indeed.  */
-  register op_t x asm("ax");
-
-  x = (unsigned char) c;
-
-  /* Clear the direction flag, so filling will move forward.  */
-  asm volatile("cld");
-
-  /* This threshold value is optimal.  */
-  if (len >= 12)
-    {
-      /* Fill X with four copies of the char we want to fill with.  */
-      x |= (x << 8);
-      x |= (x << 16);
-
-      /* Adjust LEN for the bytes handled in the first loop.  */
-      len -= (-dstp) % OPSIZ;
-
-      /* There are at least some bytes to set.
-        No need to test for LEN == 0 in this alignment loop.  */
-
-      /* Fill bytes until DSTP is aligned on a longword boundary.  */
-      asm volatile("rep\n"
-                  "stosb" /* %0, %2, %3 */ :
-                  "=D" (dstp), "=c" (d0) :
-                  "0" (dstp), "1" ((-dstp) % OPSIZ), "a" (x) :
-                  "memory");
-
-      /* Fill longwords.  */
-      asm volatile("rep\n"
-                  "stosl" /* %0, %2, %3 */ :
-                  "=D" (dstp), "=c" (d0) :
-                  "0" (dstp), "1" (len / OPSIZ), "a" (x) :
-                  "memory");
-      len %= OPSIZ;
-    }
-
-  /* Write the last few bytes.  */
-  asm volatile("rep\n"
-              "stosb" /* %0, %2, %3 */ :
-              "=D" (dstp), "=c" (d0) :
-              "0" (dstp), "1" (len), "a" (x) :
-              "memory");
-
-  return dstpp;
-}
-libc_hidden_builtin_def (memset)
-
-#else
-#include <string/memset.c>
-#endif
similarity index 79%
rename from sysdeps/i386/i686/memset_chk.S
rename to sysdeps/i386/memset_chk.S
index da982fd..2312d32 100644 (file)
@@ -1,4 +1,4 @@
-/* Checking memset for i686.
+/* Checking memset for i386.
    Copyright (C) 2004-2015 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include "asm-syntax.h"
-
 #ifndef SHARED
-       /* For libc.so this is defined in memset.S.
-          For libc.a, this is a separate source to avoid
-          memset bringing in __chk_fail and all routines
-          it calls.  */
+# include <sysdep.h>
+# include "asm-syntax.h"
+
+/* For libc.so this is defined in memset.S.  For libc.a, this is a
+   separate source to avoid memset bringing in __chk_fail and all
+   routines it calls.  */
         .text
 ENTRY (__memset_chk)
        movl    12(%esp), %eax