From: Heiko Carstens Date: Tue, 9 Jun 2026 10:33:42 +0000 (+0200) Subject: s390/memmove: Optimize backward copy case X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=661fd726e0ea8ee6b5ab4b719629cd51a2b836b0;p=thirdparty%2Flinux.git s390/memmove: Optimize backward copy case memmove() copies byte wise for the backward copy case, when the mvc instruction cannot be used. This is quite slow, but can be optimized with the mvcrl instruction, which is available since z15. Some numbers (measured on a shared z16 LPAR) show that the new implementation is nearly always faster, except for the non realistic one and two byte cases: size old new 1 2ns 3ns 2 4ns 5ns 4 5ns 5ns 8 8ns 5ns 16 12ns 6ns 32 8ns 7ns 64 15ns 7ns 128 31ns 9ns 256 64ns 10ns 512 129ns 18ns 1024 250ns 19ns 2048 498ns 38ns Reviewed-by: Juergen Christ Signed-off-by: Heiko Carstens Signed-off-by: Alexander Gordeev --- diff --git a/arch/s390/lib/string.c b/arch/s390/lib/string.c index cb65b8f5392a9..32e0e6b1e6239 100644 --- a/arch/s390/lib/string.c +++ b/arch/s390/lib/string.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #define SYMBOL_FUNCTION_ALIAS(alias, name) \ @@ -51,8 +52,29 @@ noinstr void *__memmove(void *dest, const void *src, size_t n) : [d] "a" (d), [s] "a" (s), [n] "a" (n - 1) : "memory"); } + return dest; + } + /* Backward copy */ + if (test_facility(61)) { + /* Use mvcrl instruction if available */ + while (n >= 256) { + asm volatile( + " lghi %%r0,255\n" + " .insn sse,0xe50a00000000,%[d],%[s]\n" + : [d] "=Q" (*(d + n - 256)) + : [s] "Q" (*(s + n - 256)) + : "0", "memory"); + n -= 256; + } + if (n) { + asm volatile( + " lgr %%r0,%[n]\n" + " .insn sse,0xe50a00000000,%[d],%[s]\n" + : [d] "=Q" (*d) + : [s] "Q" (*s), [n] "d" (n - 1) + : "0", "memory"); + } } else { - /* Backward copy */ while (n--) d[n] = s[n]; }