]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S
Prefer https to http for gnu.org and fsf.org URLs
[thirdparty/glibc.git] / sysdeps / x86_64 / multiarch / strcpy-sse2-unaligned.S
index 9a8d1860a05317616f2621ec929412329b5009b8..456226d064e351f5f730e2f4528d3fd68114c4bb 100644 (file)
@@ -1,5 +1,5 @@
 /* strcpy with SSE2 and unaligned load
-   Copyright (C) 2011 Free Software Foundation, Inc.
+   Copyright (C) 2011-2019 Free Software Foundation, Inc.
    Contributed by Intel Corporation.
    This file is part of the GNU C Library.
 
    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.  */
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
 
-#ifndef NOT_IN_libc
+#if IS_IN (libc)
 
-# include <sysdep.h>
+# ifndef USE_AS_STRCAT
+#  include <sysdep.h>
+
+#  ifndef STRCPY
+#   define STRCPY  __strcpy_sse2_unaligned
+#  endif
 
-# ifndef STRCPY
-#  define STRCPY  __strcpy_sse2_unaligned
 # endif
 
 # define JMPTBL(I, B)  I - B
        lea     TABLE(%rip), %r11;                              \
        movslq  (%r11, INDEX, SCALE), %rcx;                     \
        lea     (%r11, %rcx), %rcx;                             \
-       jmp     *%rcx
+       _CET_NOTRACK jmp *%rcx
 
-       .text
+# ifndef USE_AS_STRCAT
+
+.text
 ENTRY (STRCPY)
-# ifdef USE_AS_STRNCPY
-       mov     %rdx, %r8
-       test    %r8, %r8
+#  ifdef USE_AS_STRNCPY
+       mov     %RDX_LP, %R8_LP
+       test    %R8_LP, %R8_LP
        jz      L(ExitZero)
-# endif
+#  endif
        mov     %rsi, %rcx
-# ifndef USE_AS_STPCPY
+#  ifndef USE_AS_STPCPY
        mov     %rdi, %rax      /* save result */
+#  endif
+
 # endif
 
-       and     $15, %rcx
-       jz      L(SourceStringAlignmentZero)
+       and     $63, %rcx
+       cmp     $32, %rcx
+       jbe     L(SourceStringAlignmentLess32)
 
        and     $-16, %rsi
+       and     $15, %rcx
        pxor    %xmm0, %xmm0
        pxor    %xmm1, %xmm1
 
        pcmpeqb (%rsi), %xmm1
-# ifdef USE_AS_STRNCPY
-       add     %rcx, %r8
-# endif
        pmovmskb %xmm1, %rdx
        shr     %cl, %rdx
+
 # ifdef USE_AS_STRNCPY
-#  if defined USE_AS_STPCPY
-       cmp     $16, %r8
+#  if defined USE_AS_STPCPY || defined USE_AS_STRCAT
+       mov     $16, %r10
+       sub     %rcx, %r10
+       cmp     %r10, %r8
 #  else
-       cmp     $17, %r8
+       mov     $17, %r10
+       sub     %rcx, %r10
+       cmp     %r10, %r8
 #  endif
        jbe     L(CopyFrom1To16BytesTailCase2OrCase3)
 # endif
@@ -71,12 +81,10 @@ ENTRY (STRCPY)
 
        pcmpeqb 16(%rsi), %xmm0
        pmovmskb %xmm0, %rdx
+
 # ifdef USE_AS_STRNCPY
-#  if defined USE_AS_STPCPY
-       cmp     $32, %r8
-#  else
-       cmp     $33, %r8
-#  endif
+       add     $16, %r10
+       cmp     %r10, %r8
        jbe     L(CopyFrom1To32BytesCase2OrCase3)
 # endif
        test    %rdx, %rdx
@@ -85,11 +93,15 @@ ENTRY (STRCPY)
        movdqu  (%rsi, %rcx), %xmm1   /* copy 16 bytes */
        movdqu  %xmm1, (%rdi)
 
-       sub     %rcx, %rdi
-
-/* If source adress alignment != destination adress alignment */
+/* If source address alignment != destination address alignment */
        .p2align 4
 L(Unalign16Both):
+       sub     %rcx, %rdi
+# ifdef USE_AS_STRNCPY
+       add     %rcx, %r8
+       sbb     %rcx, %rcx
+       or      %rcx, %r8
+# endif
        mov     $16, %rcx
        movdqa  (%rsi, %rcx), %xmm1
        movaps  16(%rsi, %rcx), %xmm2
@@ -102,7 +114,7 @@ L(Unalign16Both):
        jbe     L(CopyFrom1To16BytesCase2OrCase3)
 # endif
        test    %rdx, %rdx
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        jnz     L(CopyFrom1To16BytesUnalignedXmm2)
 # else
        jnz     L(CopyFrom1To16Bytes)
@@ -118,7 +130,7 @@ L(Unalign16Both):
        jbe     L(CopyFrom1To16BytesCase2OrCase3)
 # endif
        test    %rdx, %rdx
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        jnz     L(CopyFrom1To16BytesUnalignedXmm3)
 # else
        jnz     L(CopyFrom1To16Bytes)
@@ -134,7 +146,7 @@ L(Unalign16Both):
        jbe     L(CopyFrom1To16BytesCase2OrCase3)
 # endif
        test    %rdx, %rdx
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        jnz     L(CopyFrom1To16BytesUnalignedXmm4)
 # else
        jnz     L(CopyFrom1To16Bytes)
@@ -150,7 +162,7 @@ L(Unalign16Both):
        jbe     L(CopyFrom1To16BytesCase2OrCase3)
 # endif
        test    %rdx, %rdx
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        jnz     L(CopyFrom1To16BytesUnalignedXmm1)
 # else
        jnz     L(CopyFrom1To16Bytes)
@@ -166,7 +178,7 @@ L(Unalign16Both):
        jbe     L(CopyFrom1To16BytesCase2OrCase3)
 # endif
        test    %rdx, %rdx
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        jnz     L(CopyFrom1To16BytesUnalignedXmm2)
 # else
        jnz     L(CopyFrom1To16Bytes)
@@ -182,7 +194,7 @@ L(Unalign16Both):
        jbe     L(CopyFrom1To16BytesCase2OrCase3)
 # endif
        test    %rdx, %rdx
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        jnz     L(CopyFrom1To16BytesUnalignedXmm3)
 # else
        jnz     L(CopyFrom1To16Bytes)
@@ -264,10 +276,10 @@ L(Unaligned64Leave):
        movdqu  %xmm4, (%rdi)
        movdqu  %xmm5, 16(%rdi)
        movdqu  %xmm6, 32(%rdi)
-# if defined USE_AS_STRNCPY
-#  ifdef USE_AS_STPCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
+# ifdef USE_AS_STPCPY
        lea     48(%rdi, %rdx), %rax
-#  endif
+# endif
        movdqu  %xmm7, 48(%rdi)
        add     $15, %r8
        sub     %rdx, %r8
@@ -279,16 +291,17 @@ L(Unaligned64Leave):
        BRANCH_TO_JMPTBL_ENTRY (L(ExitTable), %rdx, 4)
 # endif
 
-/* If source adress alignment == destination adress alignment */
+/* If source address alignment == destination address alignment */
 
-L(SourceStringAlignmentZero):
+L(SourceStringAlignmentLess32):
        pxor    %xmm0, %xmm0
-       movdqa  (%rsi), %xmm1
+       movdqu  (%rsi), %xmm1
+       movdqu  16(%rsi), %xmm2
        pcmpeqb %xmm1, %xmm0
        pmovmskb %xmm0, %rdx
 
 # ifdef USE_AS_STRNCPY
-#  if defined USE_AS_STPCPY
+#  if defined USE_AS_STPCPY || defined USE_AS_STRCAT
        cmp     $16, %r8
 #  else
        cmp     $17, %r8
@@ -298,12 +311,12 @@ L(SourceStringAlignmentZero):
        test    %rdx, %rdx
        jnz     L(CopyFrom1To16BytesTail1)
 
-       pcmpeqb 16(%rsi), %xmm0
+       pcmpeqb %xmm2, %xmm0
        movdqu  %xmm1, (%rdi)
        pmovmskb %xmm0, %rdx
 
 # ifdef USE_AS_STRNCPY
-#  if defined USE_AS_STPCPY
+#  if defined USE_AS_STPCPY || defined USE_AS_STRCAT
        cmp     $32, %r8
 #  else
        cmp     $33, %r8
@@ -312,13 +325,16 @@ L(SourceStringAlignmentZero):
 # endif
        test    %rdx, %rdx
        jnz     L(CopyFrom1To32Bytes1)
+
+       and     $-16, %rsi
+       and     $15, %rcx
        jmp     L(Unalign16Both)
 
-/* ------End of main part with loops--------------------- */
+/*------End of main part with loops---------------------*/
 
 /* Case1 */
 
-# if (!defined USE_AS_STRNCPY)
+# if (!defined USE_AS_STRNCPY) || (defined USE_AS_STRCAT)
        .p2align 4
 L(CopyFrom1To16Bytes):
        add     %rcx, %rdi
@@ -328,9 +344,6 @@ L(CopyFrom1To16Bytes):
 # endif
        .p2align 4
 L(CopyFrom1To16BytesTail):
-# if defined USE_AS_STRNCPY
-       sub     %rcx, %r8
-# endif
        add     %rcx, %rsi
        bsf     %rdx, %rdx
        BRANCH_TO_JMPTBL_ENTRY (L(ExitTable), %rdx, 4)
@@ -339,7 +352,7 @@ L(CopyFrom1To16BytesTail):
 L(CopyFrom1To32Bytes1):
        add     $16, %rsi
        add     $16, %rdi
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $16, %r8
 # endif
 L(CopyFrom1To16BytesTail1):
@@ -348,9 +361,6 @@ L(CopyFrom1To16BytesTail1):
 
        .p2align 4
 L(CopyFrom1To32Bytes):
-# if defined USE_AS_STRNCPY
-       sub     %rcx, %r8
-# endif
        bsf     %rdx, %rdx
        add     %rcx, %rsi
        add     $16, %rdx
@@ -360,10 +370,10 @@ L(CopyFrom1To32Bytes):
        .p2align 4
 L(CopyFrom1To16BytesUnaligned_0):
        bsf     %rdx, %rdx
-# if defined USE_AS_STRNCPY
-#  ifdef USE_AS_STPCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
+# ifdef USE_AS_STPCPY
        lea     (%rdi, %rdx), %rax
-#  endif
+# endif
        movdqu  %xmm4, (%rdi)
        add     $63, %r8
        sub     %rdx, %r8
@@ -377,10 +387,10 @@ L(CopyFrom1To16BytesUnaligned_0):
 L(CopyFrom1To16BytesUnaligned_16):
        bsf     %rcx, %rdx
        movdqu  %xmm4, (%rdi)
-# if defined USE_AS_STRNCPY
-#  ifdef USE_AS_STPCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
+# ifdef USE_AS_STPCPY
        lea     16(%rdi, %rdx), %rax
-#  endif
+# endif
        movdqu  %xmm5, 16(%rdi)
        add     $47, %r8
        sub     %rdx, %r8
@@ -397,10 +407,10 @@ L(CopyFrom1To16BytesUnaligned_32):
        bsf     %rdx, %rdx
        movdqu  %xmm4, (%rdi)
        movdqu  %xmm5, 16(%rdi)
-# if defined USE_AS_STRNCPY
-#  ifdef USE_AS_STPCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
+# ifdef USE_AS_STPCPY
        lea     32(%rdi, %rdx), %rax
-#  endif
+# endif
        movdqu  %xmm6, 32(%rdi)
        add     $31, %r8
        sub     %rdx, %r8
@@ -413,6 +423,7 @@ L(CopyFrom1To16BytesUnaligned_32):
 # endif
 
 # ifdef USE_AS_STRNCPY
+#  ifndef USE_AS_STRCAT
        .p2align 4
 L(CopyFrom1To16BytesUnalignedXmm6):
        movdqu  %xmm6, (%rdi, %rcx)
@@ -437,6 +448,7 @@ L(CopyFrom1To16BytesUnalignedXmm3):
 L(CopyFrom1To16BytesUnalignedXmm1):
        movdqu  %xmm1, (%rdi, %rcx)
        jmp     L(CopyFrom1To16BytesXmmExit)
+#  endif
 
        .p2align 4
 L(CopyFrom1To16BytesExit):
@@ -456,7 +468,6 @@ L(CopyFrom1To16BytesCase2):
 
        .p2align 4
 L(CopyFrom1To32BytesCase2):
-       sub     %rcx, %r8
        add     %rcx, %rsi
        bsf     %rdx, %rdx
        add     $16, %rdx
@@ -466,7 +477,6 @@ L(CopyFrom1To32BytesCase2):
        BRANCH_TO_JMPTBL_ENTRY (L(ExitStrncpyTable), %r8, 4)
 
 L(CopyFrom1To16BytesTailCase2):
-       sub     %rcx, %r8
        add     %rcx, %rsi
        bsf     %rdx, %rdx
        cmp     %r8, %rdx
@@ -495,7 +505,6 @@ L(CopyFrom1To16BytesCase3):
 L(CopyFrom1To32BytesCase2OrCase3):
        test    %rdx, %rdx
        jnz     L(CopyFrom1To32BytesCase2)
-       sub     %rcx, %r8
        add     %rcx, %rsi
        BRANCH_TO_JMPTBL_ENTRY (L(ExitStrncpyTable), %r8, 4)
 
@@ -503,7 +512,6 @@ L(CopyFrom1To32BytesCase2OrCase3):
 L(CopyFrom1To16BytesTailCase2OrCase3):
        test    %rdx, %rdx
        jnz     L(CopyFrom1To16BytesTailCase2)
-       sub     %rcx, %r8
        add     %rcx, %rsi
        BRANCH_TO_JMPTBL_ENTRY (L(ExitStrncpyTable), %r8, 4)
 
@@ -519,7 +527,7 @@ L(CopyFrom1To16BytesTail1Case2OrCase3):
 
 # endif
 
-/* ----End labels regarding with copying 1-16 bytes--and 1-32 bytes---- */
+/*------------End labels regarding with copying 1-16 bytes--and 1-32 bytes----*/
 
        .p2align 4
 L(Exit1):
@@ -527,7 +535,7 @@ L(Exit1):
 # ifdef USE_AS_STPCPY
        lea     (%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $1, %r8
        lea     1(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -541,7 +549,7 @@ L(Exit2):
 # ifdef USE_AS_STPCPY
        lea     1(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $2, %r8
        lea     2(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -556,7 +564,7 @@ L(Exit3):
 # ifdef USE_AS_STPCPY
        lea     2(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $3, %r8
        lea     3(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -570,7 +578,7 @@ L(Exit4):
 # ifdef USE_AS_STPCPY
        lea     3(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $4, %r8
        lea     4(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -585,7 +593,7 @@ L(Exit5):
 # ifdef USE_AS_STPCPY
        lea     4(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $5, %r8
        lea     5(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -601,7 +609,7 @@ L(Exit6):
 # ifdef USE_AS_STPCPY
        lea     5(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $6, %r8
        lea     6(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -617,7 +625,7 @@ L(Exit7):
 # ifdef USE_AS_STPCPY
        lea     6(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $7, %r8
        lea     7(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -631,7 +639,7 @@ L(Exit8):
 # ifdef USE_AS_STPCPY
        lea     7(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $8, %r8
        lea     8(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -646,7 +654,7 @@ L(Exit9):
 # ifdef USE_AS_STPCPY
        lea     8(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $9, %r8
        lea     9(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -662,7 +670,7 @@ L(Exit10):
 # ifdef USE_AS_STPCPY
        lea     9(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $10, %r8
        lea     10(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -678,7 +686,7 @@ L(Exit11):
 # ifdef USE_AS_STPCPY
        lea     10(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $11, %r8
        lea     11(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -694,7 +702,7 @@ L(Exit12):
 # ifdef USE_AS_STPCPY
        lea     11(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $12, %r8
        lea     12(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -710,7 +718,7 @@ L(Exit13):
 # ifdef USE_AS_STPCPY
        lea     12(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $13, %r8
        lea     13(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -726,7 +734,7 @@ L(Exit14):
 # ifdef USE_AS_STPCPY
        lea     13(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $14, %r8
        lea     14(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -742,7 +750,7 @@ L(Exit15):
 # ifdef USE_AS_STPCPY
        lea     14(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $15, %r8
        lea     15(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -756,7 +764,7 @@ L(Exit16):
 # ifdef USE_AS_STPCPY
        lea     15(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $16, %r8
        lea     16(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -771,7 +779,7 @@ L(Exit17):
 # ifdef USE_AS_STPCPY
        lea     16(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $17, %r8
        lea     17(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -787,7 +795,7 @@ L(Exit18):
 # ifdef USE_AS_STPCPY
        lea     17(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $18, %r8
        lea     18(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -803,7 +811,7 @@ L(Exit19):
 # ifdef USE_AS_STPCPY
        lea     18(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $19, %r8
        lea     19(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -819,7 +827,7 @@ L(Exit20):
 # ifdef USE_AS_STPCPY
        lea     19(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $20, %r8
        lea     20(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -836,7 +844,7 @@ L(Exit21):
 # ifdef USE_AS_STPCPY
        lea     20(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $21, %r8
        lea     21(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -852,7 +860,7 @@ L(Exit22):
 # ifdef USE_AS_STPCPY
        lea     21(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $22, %r8
        lea     22(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -868,7 +876,7 @@ L(Exit23):
 # ifdef USE_AS_STPCPY
        lea     22(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $23, %r8
        lea     23(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -884,7 +892,7 @@ L(Exit24):
 # ifdef USE_AS_STPCPY
        lea     23(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $24, %r8
        lea     24(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -901,7 +909,7 @@ L(Exit25):
 # ifdef USE_AS_STPCPY
        lea     24(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $25, %r8
        lea     25(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -919,7 +927,7 @@ L(Exit26):
 # ifdef USE_AS_STPCPY
        lea     25(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $26, %r8
        lea     26(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -937,7 +945,7 @@ L(Exit27):
 # ifdef USE_AS_STPCPY
        lea     26(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $27, %r8
        lea     27(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -955,7 +963,7 @@ L(Exit28):
 # ifdef USE_AS_STPCPY
        lea     27(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $28, %r8
        lea     28(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -971,7 +979,7 @@ L(Exit29):
 # ifdef USE_AS_STPCPY
        lea     28(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $29, %r8
        lea     29(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -987,7 +995,7 @@ L(Exit30):
 # ifdef USE_AS_STPCPY
        lea     29(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $30, %r8
        lea     30(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -1003,7 +1011,7 @@ L(Exit31):
 # ifdef USE_AS_STPCPY
        lea     30(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $31, %r8
        lea     31(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -1019,7 +1027,7 @@ L(Exit32):
 # ifdef USE_AS_STPCPY
        lea     31(%rdi), %rax
 # endif
-# if defined USE_AS_STRNCPY
+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT
        sub     $32, %r8
        lea     32(%rdi), %rdi
        jnz     L(StrncpyFillTailWithZero)
@@ -1030,27 +1038,39 @@ L(Exit32):
 
        .p2align 4
 L(StrncpyExit0):
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        mov     %rdi, %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, (%rdi)
+#  endif
        ret
 
        .p2align 4
 L(StrncpyExit1):
        mov     (%rsi), %dl
        mov     %dl, (%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     1(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 1(%rdi)
+#  endif
        ret
 
        .p2align 4
 L(StrncpyExit2):
        mov     (%rsi), %dx
        mov     %dx, (%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     2(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 2(%rdi)
+#  endif
        ret
 
        .p2align 4
@@ -1059,18 +1079,26 @@ L(StrncpyExit3):
        mov     2(%rsi), %dl
        mov     %cx, (%rdi)
        mov     %dl, 2(%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     3(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 3(%rdi)
+#  endif
        ret
 
        .p2align 4
 L(StrncpyExit4):
        mov     (%rsi), %edx
        mov     %edx, (%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     4(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 4(%rdi)
+#  endif
        ret
 
        .p2align 4
@@ -1079,9 +1107,13 @@ L(StrncpyExit5):
        mov     4(%rsi), %dl
        mov     %ecx, (%rdi)
        mov     %dl, 4(%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     5(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 5(%rdi)
+#  endif
        ret
 
        .p2align 4
@@ -1090,9 +1122,13 @@ L(StrncpyExit6):
        mov     4(%rsi), %dx
        mov     %ecx, (%rdi)
        mov     %dx, 4(%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     6(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 6(%rdi)
+#  endif
        ret
 
        .p2align 4
@@ -1101,18 +1137,26 @@ L(StrncpyExit7):
        mov     3(%rsi), %edx
        mov     %ecx, (%rdi)
        mov     %edx, 3(%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     7(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 7(%rdi)
+#  endif
        ret
 
        .p2align 4
 L(StrncpyExit8):
        mov     (%rsi), %rdx
        mov     %rdx, (%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     8(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 8(%rdi)
+#  endif
        ret
 
        .p2align 4
@@ -1121,9 +1165,13 @@ L(StrncpyExit9):
        mov     8(%rsi), %dl
        mov     %rcx, (%rdi)
        mov     %dl, 8(%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     9(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 9(%rdi)
+#  endif
        ret
 
        .p2align 4
@@ -1132,9 +1180,13 @@ L(StrncpyExit10):
        mov     8(%rsi), %dx
        mov     %rcx, (%rdi)
        mov     %dx, 8(%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     10(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 10(%rdi)
+#  endif
        ret
 
        .p2align 4
@@ -1143,9 +1195,13 @@ L(StrncpyExit11):
        mov     7(%rsi), %edx
        mov     %rcx, (%rdi)
        mov     %edx, 7(%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     11(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 11(%rdi)
+#  endif
        ret
 
        .p2align 4
@@ -1154,9 +1210,13 @@ L(StrncpyExit12):
        mov     8(%rsi), %edx
        mov     %rcx, (%rdi)
        mov     %edx, 8(%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     12(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 12(%rdi)
+#  endif
        ret
 
        .p2align 4
@@ -1165,9 +1225,13 @@ L(StrncpyExit13):
        mov     5(%rsi), %rdx
        mov     %rcx, (%rdi)
        mov     %rdx, 5(%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     13(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 13(%rdi)
+#  endif
        ret
 
        .p2align 4
@@ -1176,9 +1240,13 @@ L(StrncpyExit14):
        mov     6(%rsi), %rdx
        mov     %rcx, (%rdi)
        mov     %rdx, 6(%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     14(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 14(%rdi)
+#  endif
        ret
 
        .p2align 4
@@ -1187,18 +1255,26 @@ L(StrncpyExit15):
        mov     7(%rsi), %rdx
        mov     %rcx, (%rdi)
        mov     %rdx, 7(%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     15(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 15(%rdi)
+#  endif
        ret
 
        .p2align 4
 L(StrncpyExit16):
        movdqu  (%rsi), %xmm0
        movdqu  %xmm0, (%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     16(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 16(%rdi)
+#  endif
        ret
 
        .p2align 4
@@ -1207,9 +1283,13 @@ L(StrncpyExit17):
        mov     16(%rsi), %cl
        movdqu  %xmm0, (%rdi)
        mov     %cl, 16(%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     17(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 17(%rdi)
+#  endif
        ret
 
        .p2align 4
@@ -1218,9 +1298,13 @@ L(StrncpyExit18):
        mov     16(%rsi), %cx
        movdqu  %xmm0, (%rdi)
        mov     %cx, 16(%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     18(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 18(%rdi)
+#  endif
        ret
 
        .p2align 4
@@ -1229,9 +1313,13 @@ L(StrncpyExit19):
        mov     15(%rsi), %ecx
        movdqu  %xmm0, (%rdi)
        mov     %ecx, 15(%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     19(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 19(%rdi)
+#  endif
        ret
 
        .p2align 4
@@ -1240,9 +1328,13 @@ L(StrncpyExit20):
        mov     16(%rsi), %ecx
        movdqu  %xmm0, (%rdi)
        mov     %ecx, 16(%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     20(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 20(%rdi)
+#  endif
        ret
 
        .p2align 4
@@ -1253,9 +1345,13 @@ L(StrncpyExit21):
        movdqu  %xmm0, (%rdi)
        mov     %ecx, 16(%rdi)
        mov     %dl, 20(%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     21(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 21(%rdi)
+#  endif
        ret
 
        .p2align 4
@@ -1264,9 +1360,13 @@ L(StrncpyExit22):
        mov     14(%rsi), %rcx
        movdqu  %xmm0, (%rdi)
        mov     %rcx, 14(%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     22(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 22(%rdi)
+#  endif
        ret
 
        .p2align 4
@@ -1275,9 +1375,13 @@ L(StrncpyExit23):
        mov     15(%rsi), %rcx
        movdqu  %xmm0, (%rdi)
        mov     %rcx, 15(%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     23(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 23(%rdi)
+#  endif
        ret
 
        .p2align 4
@@ -1286,9 +1390,13 @@ L(StrncpyExit24):
        mov     16(%rsi), %rcx
        movdqu  %xmm0, (%rdi)
        mov     %rcx, 16(%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     24(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 24(%rdi)
+#  endif
        ret
 
        .p2align 4
@@ -1299,9 +1407,13 @@ L(StrncpyExit25):
        movdqu  %xmm0, (%rdi)
        mov     %rdx, 16(%rdi)
        mov     %cl, 24(%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     25(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 25(%rdi)
+#  endif
        ret
 
        .p2align 4
@@ -1312,9 +1424,13 @@ L(StrncpyExit26):
        movdqu  %xmm0, (%rdi)
        mov     %rdx, 16(%rdi)
        mov     %cx, 24(%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     26(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 26(%rdi)
+#  endif
        ret
 
        .p2align 4
@@ -1325,9 +1441,13 @@ L(StrncpyExit27):
        movdqu  %xmm0, (%rdi)
        mov     %rdx, 16(%rdi)
        mov     %ecx, 23(%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     27(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 27(%rdi)
+#  endif
        ret
 
        .p2align 4
@@ -1338,9 +1458,13 @@ L(StrncpyExit28):
        movdqu  %xmm0, (%rdi)
        mov     %rdx, 16(%rdi)
        mov     %ecx, 24(%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     28(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 28(%rdi)
+#  endif
        ret
 
        .p2align 4
@@ -1349,9 +1473,13 @@ L(StrncpyExit29):
        movdqu  13(%rsi), %xmm2
        movdqu  %xmm0, (%rdi)
        movdqu  %xmm2, 13(%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     29(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 29(%rdi)
+#  endif
        ret
 
        .p2align 4
@@ -1360,9 +1488,13 @@ L(StrncpyExit30):
        movdqu  14(%rsi), %xmm2
        movdqu  %xmm0, (%rdi)
        movdqu  %xmm2, 14(%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     30(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 30(%rdi)
+#  endif
        ret
 
        .p2align 4
@@ -1371,9 +1503,13 @@ L(StrncpyExit31):
        movdqu  15(%rsi), %xmm2
        movdqu  %xmm0, (%rdi)
        movdqu  %xmm2, 15(%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     31(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 31(%rdi)
+#  endif
        ret
 
        .p2align 4
@@ -1382,9 +1518,13 @@ L(StrncpyExit32):
        movdqu  16(%rsi), %xmm2
        movdqu  %xmm0, (%rdi)
        movdqu  %xmm2, 16(%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     32(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 32(%rdi)
+#  endif
        ret
 
        .p2align 4
@@ -1395,8 +1535,14 @@ L(StrncpyExit33):
        movdqu  %xmm0, (%rdi)
        movdqu  %xmm2, 16(%rdi)
        mov     %cl, 32(%rdi)
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 33(%rdi)
+#  endif
        ret
 
+#  ifndef USE_AS_STRCAT
+
        .p2align 4
 L(Fill0):
        ret
@@ -1498,9 +1644,9 @@ L(CopyFrom1To16BytesXmmExit):
        bsf     %rdx, %rdx
        add     $15, %r8
        add     %rcx, %rdi
-# ifdef USE_AS_STPCPY
+#   ifdef USE_AS_STPCPY
        lea     (%rdi, %rdx), %rax
-# endif
+#   endif
        sub     %rdx, %r8
        lea     1(%rdi, %rdx), %rdi
 
@@ -1553,6 +1699,9 @@ L(StrncpyFillExit):
        add     $16, %r8
        BRANCH_TO_JMPTBL_ENTRY (L(FillTable), %r8, 4)
 
+/* end of ifndef USE_AS_STRCAT */
+#  endif
+
        .p2align 4
 L(UnalignedLeaveCase2OrCase3):
        test    %rdx, %rdx
@@ -1572,9 +1721,13 @@ L(Unaligned64LeaveCase3):
        sub     $16, %r8
        jb      L(CopyFrom1To16BytesCase3)
        movdqu  %xmm7, 48(%rdi)
-# ifdef USE_AS_STPCPY
+#  ifdef USE_AS_STPCPY
        lea     64(%rdi), %rax
-# endif
+#  endif
+#  ifdef USE_AS_STRCAT
+       xor     %ch, %ch
+       movb    %ch, 64(%rdi)
+#  endif
        ret
 
        .p2align 4
@@ -1585,8 +1738,11 @@ L(Unaligned64LeaveCase2):
        add     $48, %r8
        jle     L(CopyFrom1To16BytesCase2OrCase3)
        test    %rdx, %rdx
+#  ifndef USE_AS_STRCAT
        jnz     L(CopyFrom1To16BytesUnalignedXmm4)
-
+#  else
+       jnz     L(CopyFrom1To16Bytes)
+#  endif
        pcmpeqb %xmm5, %xmm0
        pmovmskb %xmm0, %rdx
        movdqu  %xmm4, (%rdi)
@@ -1594,7 +1750,11 @@ L(Unaligned64LeaveCase2):
        sub     $16, %r8
        jbe     L(CopyFrom1To16BytesCase2OrCase3)
        test    %rdx, %rdx
+#  ifndef USE_AS_STRCAT
        jnz     L(CopyFrom1To16BytesUnalignedXmm5)
+#  else
+       jnz     L(CopyFrom1To16Bytes)
+#  endif
 
        pcmpeqb %xmm6, %xmm0
        pmovmskb %xmm0, %rdx
@@ -1603,7 +1763,11 @@ L(Unaligned64LeaveCase2):
        sub     $16, %r8
        jbe     L(CopyFrom1To16BytesCase2OrCase3)
        test    %rdx, %rdx
+#  ifndef USE_AS_STRCAT
        jnz     L(CopyFrom1To16BytesUnalignedXmm6)
+#  else
+       jnz     L(CopyFrom1To16Bytes)
+#  endif
 
        pcmpeqb %xmm7, %xmm0
        pmovmskb %xmm0, %rdx
@@ -1617,13 +1781,18 @@ L(Unaligned64LeaveCase2):
 
        .p2align 4
 L(ExitZero):
+#  ifndef USE_AS_STRCAT
        mov     %rdi, %rax
+#  endif
        ret
 
 # endif
 
+# ifndef USE_AS_STRCAT
 END (STRCPY)
-
+# else
+END (STRCAT)
+# endif
        .p2align 4
        .section .rodata
 L(ExitTable):
@@ -1695,6 +1864,7 @@ L(ExitStrncpyTable):
        .int    JMPTBL(L(StrncpyExit31), L(ExitStrncpyTable))
        .int    JMPTBL(L(StrncpyExit32), L(ExitStrncpyTable))
        .int    JMPTBL(L(StrncpyExit33), L(ExitStrncpyTable))
+#  ifndef USE_AS_STRCAT
        .p2align 4
 L(FillTable):
        .int    JMPTBL(L(Fill0), L(FillTable))
@@ -1714,5 +1884,6 @@ L(FillTable):
        .int    JMPTBL(L(Fill14), L(FillTable))
        .int    JMPTBL(L(Fill15), L(FillTable))
        .int    JMPTBL(L(Fill16), L(FillTable))
+#  endif
 # endif
 #endif