s390/string: Convert memmove() to C

Convert memmove() 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:38 +02:00 committed by Alexander Gordeev
parent 78016b6da7
commit c3e4b7eb1b
2 changed files with 46 additions and 41 deletions

View File

@ -11,47 +11,6 @@
GEN_BR_THUNK %r14
/*
* void *memmove(void *dest, const void *src, size_t n)
*/
SYM_FUNC_START(__memmove)
ltgr %r4,%r4
lgr %r1,%r2
jz .Lmemmove_exit
aghi %r4,-1
clgr %r2,%r3
jnh .Lmemmove_forward
la %r5,1(%r4,%r3)
clgr %r2,%r5
jl .Lmemmove_reverse
.Lmemmove_forward:
srlg %r0,%r4,8
ltgr %r0,%r0
jz .Lmemmove_forward_remainder
.Lmemmove_forward_loop:
mvc 0(256,%r1),0(%r3)
la %r1,256(%r1)
la %r3,256(%r3)
brctg %r0,.Lmemmove_forward_loop
.Lmemmove_forward_remainder:
exrl %r4,.Lmemmove_mvc
.Lmemmove_exit:
BR_EX %r14
.Lmemmove_reverse:
ic %r0,0(%r4,%r3)
stc %r0,0(%r4,%r1)
brctg %r4,.Lmemmove_reverse
ic %r0,0(%r4,%r3)
stc %r0,0(%r4,%r1)
BR_EX %r14
.Lmemmove_mvc:
mvc 0(1,%r1),0(%r3)
SYM_FUNC_END(__memmove)
EXPORT_SYMBOL(__memmove)
SYM_FUNC_ALIAS(memmove, __memmove)
EXPORT_SYMBOL(memmove)
/*
* memset implementation
*

View File

@ -17,6 +17,52 @@
#include <linux/export.h>
#include <asm/asm.h>
#define SYMBOL_FUNCTION_ALIAS(alias, name) \
asm(".globl " __stringify(alias) "\n\t" \
".set " __stringify(alias) "," __stringify(name))
#ifdef __HAVE_ARCH_MEMMOVE
noinstr void *__memmove(void *dest, const void *src, size_t n)
{
const char *s = src;
char *d = dest;
if (!n)
return dest;
if ((d <= s || d >= s + n)) {
/* Forward copy */
while (n >= 256) {
asm volatile(
" mvc 0(256,%[d]),0(%[s])\n"
:
: [d] "a" (d), [s] "a" (s)
: "memory");
d += 256;
s += 256;
n -= 256;
}
if (n) {
asm volatile(
" exrl %[n],0f\n"
" j 1f\n"
"0: mvc 0(1,%[d]),0(%[s])\n"
"1:"
:
: [d] "a" (d), [s] "a" (s), [n] "a" (n - 1)
: "memory");
}
} else {
/* Backward copy */
while (n--)
d[n] = s[n];
}
return dest;
}
SYMBOL_FUNCTION_ALIAS(memmove, __memmove);
EXPORT_SYMBOL(__memmove);
EXPORT_SYMBOL(memmove);
#endif
/*
* Helper functions to find the end of a string
*/