s390/string: Convert memcpy() to C

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>
This commit is contained in:
Heiko Carstens
2026-06-09 12:33:40 +02:00
committed by Alexander Gordeev
parent 0a8be1f9c7
commit 611b5c1f60
2 changed files with 34 additions and 31 deletions

View File

@@ -11,37 +11,6 @@
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
*

View 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
*/