mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 01:55:51 +02:00
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:
parent
78016b6da7
commit
c3e4b7eb1b
|
|
@ -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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user