]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
s390/string: Convert memcpy() to C
authorHeiko Carstens <hca@linux.ibm.com>
Tue, 9 Jun 2026 10:33:40 +0000 (12:33 +0200)
committerAlexander Gordeev <agordeev@linux.ibm.com>
Wed, 10 Jun 2026 14:55:21 +0000 (16:55 +0200)
Convert memcpy() from assembler to C, which should make it easier to
read and change, if required. And it allows the compiler to optimize
the code, and use different instructions, except for the used inline
assemblies.

Reviewed-by: Juergen Christ <jchrist@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
arch/s390/lib/mem.S
arch/s390/lib/string.c

index a27b103d7450cfd128e3ce41f4a2da09e0d2baa3..d2e1ca87a568073bfea48899bd3e384970679fa3 100644 (file)
 
        GEN_BR_THUNK %r14
 
-/*
- * memcpy implementation
- *
- * void *memcpy(void *dest, const void *src, size_t n)
- */
-SYM_FUNC_START(__memcpy)
-       ltgr    %r4,%r4
-       jz      .Lmemcpy_exit
-       aghi    %r4,-1
-       srlg    %r5,%r4,8
-       ltgr    %r5,%r5
-       lgr     %r1,%r2
-       jnz     .Lmemcpy_loop
-.Lmemcpy_remainder:
-       exrl    %r4,.Lmemcpy_mvc
-.Lmemcpy_exit:
-       BR_EX   %r14
-.Lmemcpy_loop:
-       mvc     0(256,%r1),0(%r3)
-       la      %r1,256(%r1)
-       la      %r3,256(%r3)
-       brctg   %r5,.Lmemcpy_loop
-       j       .Lmemcpy_remainder
-.Lmemcpy_mvc:
-       mvc     0(1,%r1),0(%r3)
-SYM_FUNC_END(__memcpy)
-EXPORT_SYMBOL(__memcpy)
-
-SYM_FUNC_ALIAS(memcpy, __memcpy)
-EXPORT_SYMBOL(memcpy)
-
 /*
  * __memset16/32/64
  *
index f59d67925e772b725b871cd404c74fe1cc25ef0e..056ea2027ddd2d435f0b93f1214c66beb3ce6ccd 100644 (file)
@@ -124,6 +124,40 @@ EXPORT_SYMBOL(__memset);
 EXPORT_SYMBOL(memset);
 #endif
 
+#ifdef __HAVE_ARCH_MEMCPY
+noinstr void *__memcpy(void *dest, const void *src, size_t n)
+{
+       void *d = dest;
+
+       if (!n)
+               return d;
+       while (n >= 256) {
+               asm volatile(
+                       "       mvc     0(256,%[dest]),0(%[src])"
+                       :
+                       : [dest] "a" (dest), [src] "a" (src)
+                       : "memory");
+               dest += 256;
+               src += 256;
+               n -= 256;
+       }
+       if (!n)
+               return d;
+       asm volatile(
+               "       exrl    %[n],1f\n"
+               "       j       2f\n"
+               "1:     mvc     0(1,%[dest]),0(%[src])\n"
+               "2:"
+               :
+               : [dest] "a" (dest), [src] "a" (src), [n] "a" (n - 1)
+               : "memory");
+       return d;
+}
+SYMBOL_FUNCTION_ALIAS(memcpy, __memcpy);
+EXPORT_SYMBOL(__memcpy);
+EXPORT_SYMBOL(memcpy);
+#endif
+
 /*
  * Helper functions to find the end of a string
  */