Aligning memcpy/memmove/mempcpy/memset for libcom32
authorH. Peter Anvin <hpa@zytor.com>
Fri, 6 Jun 2008 19:18:18 +0000 (12:18 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Fri, 6 Jun 2008 19:18:18 +0000 (12:18 -0700)
Aligning versions of memcpy/memmove/mempcpy/memset for libcom32.

com32/lib/memcpy.S
com32/lib/memmove.S
com32/lib/mempcpy.S
com32/lib/memset.S [new file with mode: 0644]
com32/lib/memset.c [deleted file]

index a893d24..5f2c4ec 100644 (file)
@@ -1,35 +1,86 @@
-#
-# memcpy.S
-#
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * memcpy.S
+ *
+ * Reasonably efficient memcpy, using aligned transfers at least
+ * for the destination operand.
+ */
 
        .text
        .globl  memcpy
        .type   memcpy, @function
 memcpy:
+       jecxz   1f
+
        pushl   %esi
        pushl   %edi
-#ifdef REGPARM
-       movl    %edx, %esi
-#else
-       movl    12(%esp), %eax
-       movl    16(%esp), %esi
-       movl    20(%esp), %ecx
-#endif
-       movl    %eax, %edi
-       movl    %ecx, %edx
-
-       shrl    $2, %ecx
-       rep ; movsl
-
-       jnc     1f              # The shrl had carry out if odd word count
+       pushl   %eax            /* Return value */
+
+       movl    %eax,%edi
+       movl    %edx,%esi
+
+       /* Initial alignment */
+       movl    %edi,%edx
+       shrl    $1,%edx
+       jnc     11f
+       movsb
+       decl    %ecx
+11:
+       movb    %cl,%al
+       cmpl    $2,%ecx
+       jb      13f
+
+       shrl    $1,%edx
+       jnc     12f
+       movsw
+       subl    $2,%ecx
+12:
+       /* Bulk transfer */
+       movb    %cl,%al
+       shrl    $2,%ecx
+       rep; movsl
+
+       /* Final alignment */
+       testb   $2,%al
+       jz      14f
        movsw
-1:
-       testb   $1, %dl
-       jz      2f
+13:
+14:
+       testb   $1,%al
+       jz      15f
        movsb
-2:
+15:
+
+       popl    %eax            /* Return value */
        popl    %edi
        popl    %esi
+1:     
        ret
 
        .size   memcpy, .-memcpy
index e39f884..90bbf3b 100644 (file)
@@ -1,6 +1,6 @@
 /* ----------------------------------------------------------------------- *
  *
- *   Copyright 2008 rPath, Inc. - All Rights Reserved
+ *   Copyright 2008 H. Peter Anvin - All Rights Reserved
  *
  *   Permission is hereby granted, free of charge, to any person
  *   obtaining a copy of this software and associated documentation
 /*
  * memmove.S
  *
- * Reasonably efficient memmove
+ * Reasonably efficient memmove, using aligned transfers at least
+ * for the destination operand.
  */
 
        .globl  memmove
        .type   memmove,@function
        .text
 memmove:
+       jecxz   3f
+
        pushl   %esi
        pushl   %edi
-
+       pushl   %eax            /* Return value */
+       
        movl    %eax,%edi
        movl    %edx,%esi
 
@@ -45,35 +49,91 @@ memmove:
        jb      1f
 
        /* source >= dest, forwards move */
-       movl    %ecx,%edx
-       shrl    $2,%ecx
-       andl    $3,%edx
 
+       /* Initial alignment */
+       movl    %edi,%edx
+       shrl    $1,%edx
+       jnc     11f
+       movsb
+       decl    %ecx
+11:
+       movb    %cl,%al
+       cmpl    $2,%ecx
+       jb      13f
+
+       shrl    $1,%edx
+       jnc     12f
+       movsw
+       subl    $2,%ecx
+12:
+       /* Bulk transfer */
+       movb    %cl,%al
+       shrl    $2,%ecx
        rep; movsl
-       movl    %edx,%ecx
-       rep; movsb
 
+       /* Final alignment */
+       testb   $2,%al
+       jz      14f
+       movsw
+13:
+14:
+       testb   $1,%al
+       jz      15f
+       movsb
+15:
        jmp     2f
+
+
 1:
        /* source < dest, backwards move */
-       leal    -4(%ecx,%esi),%esi
-       leal    -4(%ecx,%edi),%edi
+       std
+       leal    -1(%ecx,%esi),%esi
+       leal    -1(%ecx,%edi),%edi
 
-       movl    %ecx,%edx
+       /* Initial alignment */
+       movl    %edi,%edx
+       shrl    $1,%edx
+       jnc     21f
+       movsb
+       decl    %ecx
+21:
+       decl    %esi
+       decl    %edi
+       movb    %cl,%al
+       cmpl    $2,%ecx
+       jb      23f
+       shrl    $1,%edx
+       jnc     22f
+       movsw
+       subl    $2,%ecx
+22:
+       /* Bulk transfer */
+       subl    $2,%esi
+       subl    $2,%edi
+       movb    %cl,%al
        shrl    $2,%ecx
-       andl    $3,%edx
-
-       std
        rep; movsl
-       movl    %edx,%ecx
-       addl    $3,%esi
-       addl    $3,%edi
-       rep; movsb
-       cld
 
+       /* Final alignment */
+       addl    $2,%esi
+       addl    $2,%edi
+       testb   $2,%al
+       jz      24f
+       movsw
+23:
+24:
+       incl    %esi
+       incl    %edi
+       testb   $1,%al
+       jz      25f
+       movsb
+25:
+       cld
 2:
+       popl    %eax            /* Return value */
        popl    %edi
        popl    %esi
+3:
        ret
 
        .size   memmove, .-memmove
index eeab918..f6961f6 100644 (file)
@@ -1,36 +1,85 @@
-#
-# mempcpy.S
-#
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * mempcpy.S
+ *
+ * Reasonably efficient mempcpy, using aligned transfers at least
+ * for the destination operand.
+ */
 
        .text
        .globl  mempcpy
        .type   mempcpy, @function
 mempcpy:
+       jecxz   1f
+
        pushl   %esi
        pushl   %edi
-#ifdef REGPARM
-       movl    %edx, %esi
-#else
-       movl    12(%esp), %eax
-       movl    16(%esp), %esi
-       movl    20(%esp), %ecx
-#endif
-       movl    %eax, %edi
-       movl    %ecx, %edx
-
-       shrl    $2, %ecx
-       rep ; movsl
-
-       jnc     1f              # The shrl had carry out if odd word count
+
+       movl    %eax,%edi
+       movl    %edx,%esi
+
+       /* Initial alignment */
+       movl    %edi,%edx
+       shrl    $1,%edx
+       jnc     11f
+       movsb
+       decl    %ecx
+11:
+       movb    %cl,%al
+       cmpl    $2,%ecx
+       jb      13f
+
+       shrl    $1,%edx
+       jnc     12f
+       movsw
+       subl    $2,%ecx
+12:
+       /* Bulk transfer */
+       movb    %cl,%al
+       shrl    $2,%ecx
+       rep; movsl
+
+       /* Final alignment */
+       testb   $2,%al
+       jz      14f
        movsw
-1:
-       testb   $1, %dl
-       jz      2f
+13:
+14:
+       testb   $1,%al
+       jz      15f
        movsb
-2:
-       movl    %edi, %eax
+15:
+
+       movl    %edi,%eax       /* Return value */
        popl    %edi
        popl    %esi
+1:     
        ret
 
        .size   mempcpy, .-mempcpy
diff --git a/com32/lib/memset.S b/com32/lib/memset.S
new file mode 100644 (file)
index 0000000..4b2583c
--- /dev/null
@@ -0,0 +1,86 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * memset.S
+ *
+ * Reasonably efficient memset, using aligned transfers at least
+ * for the destination operand.
+ */
+
+       .globl  memset
+       .type   memset,@function
+       .text
+memset:
+       jecxz   6f
+
+       pushl   %edi
+       pushl   %ebx
+       pushl   %eax            /* Return value */
+
+       movl    %eax,%edi
+       movb    %dl,%dh
+       movzwl  %dx,%eax
+       shll    $16,%edx
+       orl     %edx,%eax
+       
+       /* Initial alignment */
+       movl    %edi,%edx
+       shrl    $1,%edx
+       jnc     1f
+       stosb
+       decl    %ecx
+1:
+       movb    %cl,%bl
+       cmpl    $2,%ecx
+       jb      3f
+       shrl    $1,%edx
+       jnc     2f
+       stosw
+       subl    $2,%ecx
+2:
+       /* Bulk transfer */
+       movb    %cl,%bl
+       shrl    $2,%ecx
+       rep; stosl
+
+       testb   $2,%bl
+       jz      4f
+       stosw
+3:
+4:
+       testb   $1,%bl
+       jz      5f
+       stosb
+5:
+       popl    %eax            /* Return value */
+       popl    %ebx
+       popl    %edi
+6:
+       ret
+
+       .size   memset, .-memset
diff --git a/com32/lib/memset.c b/com32/lib/memset.c
deleted file mode 100644 (file)
index 516ad47..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * memset.c
- */
-
-#include <string.h>
-#include <stdint.h>
-
-void *memset(void *dst, int c, size_t n)
-{
-  char *q = dst;
-  size_t nl = n >> 2;
-
-  asm volatile("rep ; stosl ; movl %3,%0 ; rep ; stosb"
-              : "+c" (nl), "+D" (q)
-              : "a" ((unsigned char)c * 0x01010101U), "r" (n & 3));
-
-  return dst;
-}