Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
[cris-mirror.git] / arch / s390 / lib / mem.S
blob495c9c4bacc7b34bcfe4d966adeb28431b1dc032
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * String handling functions.
4  *
5  * Copyright IBM Corp. 2012
6  */
8 #include <linux/linkage.h>
9 #include <asm/export.h>
12  * void *memmove(void *dest, const void *src, size_t n)
13  */
14 ENTRY(memmove)
15         ltgr    %r4,%r4
16         lgr     %r1,%r2
17         bzr     %r14
18         aghi    %r4,-1
19         clgr    %r2,%r3
20         jnh     .Lmemmove_forward
21         la      %r5,1(%r4,%r3)
22         clgr    %r2,%r5
23         jl      .Lmemmove_reverse
24 .Lmemmove_forward:
25         srlg    %r0,%r4,8
26         ltgr    %r0,%r0
27         jz      .Lmemmove_forward_remainder
28 .Lmemmove_forward_loop:
29         mvc     0(256,%r1),0(%r3)
30         la      %r1,256(%r1)
31         la      %r3,256(%r3)
32         brctg   %r0,.Lmemmove_forward_loop
33 .Lmemmove_forward_remainder:
34         larl    %r5,.Lmemmove_mvc
35         ex      %r4,0(%r5)
36         br      %r14
37 .Lmemmove_reverse:
38         ic      %r0,0(%r4,%r3)
39         stc     %r0,0(%r4,%r1)
40         brctg   %r4,.Lmemmove_reverse
41         ic      %r0,0(%r4,%r3)
42         stc     %r0,0(%r4,%r1)
43         br      %r14
44 .Lmemmove_mvc:
45         mvc     0(1,%r1),0(%r3)
46 EXPORT_SYMBOL(memmove)
49  * memset implementation
50  *
51  * This code corresponds to the C construct below. We do distinguish
52  * between clearing (c == 0) and setting a memory array (c != 0) simply
53  * because nearly all memset invocations in the kernel clear memory and
54  * the xc instruction is preferred in such cases.
55  *
56  * void *memset(void *s, int c, size_t n)
57  * {
58  *      if (likely(c == 0))
59  *              return __builtin_memset(s, 0, n);
60  *      return __builtin_memset(s, c, n);
61  * }
62  */
63 ENTRY(memset)
64         ltgr    %r4,%r4
65         bzr     %r14
66         ltgr    %r3,%r3
67         jnz     .Lmemset_fill
68         aghi    %r4,-1
69         srlg    %r3,%r4,8
70         ltgr    %r3,%r3
71         lgr     %r1,%r2
72         jz      .Lmemset_clear_remainder
73 .Lmemset_clear_loop:
74         xc      0(256,%r1),0(%r1)
75         la      %r1,256(%r1)
76         brctg   %r3,.Lmemset_clear_loop
77 .Lmemset_clear_remainder:
78         larl    %r3,.Lmemset_xc
79         ex      %r4,0(%r3)
80         br      %r14
81 .Lmemset_fill:
82         cghi    %r4,1
83         lgr     %r1,%r2
84         je      .Lmemset_fill_exit
85         aghi    %r4,-2
86         srlg    %r5,%r4,8
87         ltgr    %r5,%r5
88         jz      .Lmemset_fill_remainder
89 .Lmemset_fill_loop:
90         stc     %r3,0(%r1)
91         mvc     1(255,%r1),0(%r1)
92         la      %r1,256(%r1)
93         brctg   %r5,.Lmemset_fill_loop
94 .Lmemset_fill_remainder:
95         stc     %r3,0(%r1)
96         larl    %r5,.Lmemset_mvc
97         ex      %r4,0(%r5)
98         br      %r14
99 .Lmemset_fill_exit:
100         stc     %r3,0(%r1)
101         br      %r14
102 .Lmemset_xc:
103         xc      0(1,%r1),0(%r1)
104 .Lmemset_mvc:
105         mvc     1(1,%r1),0(%r1)
106 EXPORT_SYMBOL(memset)
109  * memcpy implementation
111  * void *memcpy(void *dest, const void *src, size_t n)
112  */
113 ENTRY(memcpy)
114         ltgr    %r4,%r4
115         bzr     %r14
116         aghi    %r4,-1
117         srlg    %r5,%r4,8
118         ltgr    %r5,%r5
119         lgr     %r1,%r2
120         jnz     .Lmemcpy_loop
121 .Lmemcpy_remainder:
122         larl    %r5,.Lmemcpy_mvc
123         ex      %r4,0(%r5)
124         br      %r14
125 .Lmemcpy_loop:
126         mvc     0(256,%r1),0(%r3)
127         la      %r1,256(%r1)
128         la      %r3,256(%r3)
129         brctg   %r5,.Lmemcpy_loop
130         j       .Lmemcpy_remainder
131 .Lmemcpy_mvc:
132         mvc     0(1,%r1),0(%r3)
133 EXPORT_SYMBOL(memcpy)
136  * __memset16/32/64
138  * void *__memset16(uint16_t *s, uint16_t v, size_t count)
139  * void *__memset32(uint32_t *s, uint32_t v, size_t count)
140  * void *__memset64(uint64_t *s, uint64_t v, size_t count)
141  */
142 .macro __MEMSET bits,bytes,insn
143 ENTRY(__memset\bits)
144         ltgr    %r4,%r4
145         bzr     %r14
146         cghi    %r4,\bytes
147         je      .L__memset_exit\bits
148         aghi    %r4,-(\bytes+1)
149         srlg    %r5,%r4,8
150         ltgr    %r5,%r5
151         lgr     %r1,%r2
152         jz      .L__memset_remainder\bits
153 .L__memset_loop\bits:
154         \insn   %r3,0(%r1)
155         mvc     \bytes(256-\bytes,%r1),0(%r1)
156         la      %r1,256(%r1)
157         brctg   %r5,.L__memset_loop\bits
158 .L__memset_remainder\bits:
159         \insn   %r3,0(%r1)
160         larl    %r5,.L__memset_mvc\bits
161         ex      %r4,0(%r5)
162         br      %r14
163 .L__memset_exit\bits:
164         \insn   %r3,0(%r2)
165         br      %r14
166 .L__memset_mvc\bits:
167         mvc     \bytes(1,%r1),0(%r1)
168 .endm
170 __MEMSET 16,2,sth
171 EXPORT_SYMBOL(__memset16)
173 __MEMSET 32,4,st
174 EXPORT_SYMBOL(__memset32)
176 __MEMSET 64,8,stg
177 EXPORT_SYMBOL(__memset64)