blob: 7ff79a4ff00cd9fae70d83f4674f6f8a01033967 [file] [log] [blame]
Heiko Carstens535c6112012-08-14 13:20:20 +02001/*
2 * String handling functions.
3 *
4 * Copyright IBM Corp. 2012
5 */
6
7#include <linux/linkage.h>
Al Viro711f5df2016-01-12 13:30:03 -05008#include <asm/export.h>
Heiko Carstens535c6112012-08-14 13:20:20 +02009
10/*
Heiko Carstensb4623d42016-12-07 13:45:38 +010011 * void *memmove(void *dest, const void *src, size_t n)
12 */
13ENTRY(memmove)
14 ltgr %r4,%r4
15 lgr %r1,%r2
16 bzr %r14
Heiko Carstens551f4132016-12-15 08:35:10 +010017 aghi %r4,-1
Heiko Carstensb4623d42016-12-07 13:45:38 +010018 clgr %r2,%r3
19 jnh .Lmemmove_forward
Heiko Carstens551f4132016-12-15 08:35:10 +010020 la %r5,1(%r4,%r3)
Heiko Carstensb4623d42016-12-07 13:45:38 +010021 clgr %r2,%r5
22 jl .Lmemmove_reverse
23.Lmemmove_forward:
Heiko Carstensb4623d42016-12-07 13:45:38 +010024 srlg %r0,%r4,8
25 ltgr %r0,%r0
Heiko Carstens551f4132016-12-15 08:35:10 +010026 jz .Lmemmove_forward_remainder
27.Lmemmove_forward_loop:
Heiko Carstensb4623d42016-12-07 13:45:38 +010028 mvc 0(256,%r1),0(%r3)
29 la %r1,256(%r1)
30 la %r3,256(%r3)
Heiko Carstens551f4132016-12-15 08:35:10 +010031 brctg %r0,.Lmemmove_forward_loop
32.Lmemmove_forward_remainder:
Heiko Carstensb4623d42016-12-07 13:45:38 +010033 larl %r5,.Lmemmove_mvc
34 ex %r4,0(%r5)
35 br %r14
36.Lmemmove_reverse:
Heiko Carstensb4623d42016-12-07 13:45:38 +010037 ic %r0,0(%r4,%r3)
38 stc %r0,0(%r4,%r1)
Heiko Carstens551f4132016-12-15 08:35:10 +010039 brctg %r4,.Lmemmove_reverse
Heiko Carstensb4623d42016-12-07 13:45:38 +010040 ic %r0,0(%r4,%r3)
41 stc %r0,0(%r4,%r1)
42 br %r14
43.Lmemmove_mvc:
44 mvc 0(1,%r1),0(%r3)
45EXPORT_SYMBOL(memmove)
46
47/*
Heiko Carstens535c6112012-08-14 13:20:20 +020048 * memset implementation
49 *
50 * This code corresponds to the C construct below. We do distinguish
51 * between clearing (c == 0) and setting a memory array (c != 0) simply
52 * because nearly all memset invocations in the kernel clear memory and
53 * the xc instruction is preferred in such cases.
54 *
55 * void *memset(void *s, int c, size_t n)
56 * {
57 * if (likely(c == 0))
58 * return __builtin_memset(s, 0, n);
59 * return __builtin_memset(s, c, n);
60 * }
61 */
62ENTRY(memset)
63 ltgr %r4,%r4
64 bzr %r14
65 ltgr %r3,%r3
66 jnz .Lmemset_fill
67 aghi %r4,-1
68 srlg %r3,%r4,8
69 ltgr %r3,%r3
70 lgr %r1,%r2
Heiko Carstens551f4132016-12-15 08:35:10 +010071 jz .Lmemset_clear_remainder
Heiko Carstens535c6112012-08-14 13:20:20 +020072.Lmemset_clear_loop:
73 xc 0(256,%r1),0(%r1)
74 la %r1,256(%r1)
75 brctg %r3,.Lmemset_clear_loop
Heiko Carstens551f4132016-12-15 08:35:10 +010076.Lmemset_clear_remainder:
Heiko Carstens535c6112012-08-14 13:20:20 +020077 larl %r3,.Lmemset_xc
78 ex %r4,0(%r3)
79 br %r14
80.Lmemset_fill:
81 stc %r3,0(%r2)
82 cghi %r4,1
83 lgr %r1,%r2
84 ber %r14
85 aghi %r4,-2
86 srlg %r3,%r4,8
87 ltgr %r3,%r3
Heiko Carstens551f4132016-12-15 08:35:10 +010088 jz .Lmemset_fill_remainder
Heiko Carstens535c6112012-08-14 13:20:20 +020089.Lmemset_fill_loop:
90 mvc 1(256,%r1),0(%r1)
91 la %r1,256(%r1)
92 brctg %r3,.Lmemset_fill_loop
Heiko Carstens551f4132016-12-15 08:35:10 +010093.Lmemset_fill_remainder:
Heiko Carstens535c6112012-08-14 13:20:20 +020094 larl %r3,.Lmemset_mvc
95 ex %r4,0(%r3)
96 br %r14
97.Lmemset_xc:
98 xc 0(1,%r1),0(%r1)
99.Lmemset_mvc:
100 mvc 1(1,%r1),0(%r1)
Al Viro711f5df2016-01-12 13:30:03 -0500101EXPORT_SYMBOL(memset)
Heiko Carstens535c6112012-08-14 13:20:20 +0200102
103/*
104 * memcpy implementation
105 *
106 * void *memcpy(void *dest, const void *src, size_t n)
107 */
108ENTRY(memcpy)
109 ltgr %r4,%r4
110 bzr %r14
111 aghi %r4,-1
112 srlg %r5,%r4,8
113 ltgr %r5,%r5
114 lgr %r1,%r2
115 jnz .Lmemcpy_loop
Heiko Carstens551f4132016-12-15 08:35:10 +0100116.Lmemcpy_remainder:
Heiko Carstens535c6112012-08-14 13:20:20 +0200117 larl %r5,.Lmemcpy_mvc
118 ex %r4,0(%r5)
119 br %r14
120.Lmemcpy_loop:
121 mvc 0(256,%r1),0(%r3)
122 la %r1,256(%r1)
123 la %r3,256(%r3)
124 brctg %r5,.Lmemcpy_loop
Heiko Carstens551f4132016-12-15 08:35:10 +0100125 j .Lmemcpy_remainder
Heiko Carstens535c6112012-08-14 13:20:20 +0200126.Lmemcpy_mvc:
127 mvc 0(1,%r1),0(%r3)
Al Viro711f5df2016-01-12 13:30:03 -0500128EXPORT_SYMBOL(memcpy)