Linux 4.11-rc5
[linux/fpc-iii.git] / arch / s390 / lib / mem.S
blob7ff79a4ff00cd9fae70d83f4674f6f8a01033967
1 /*
2  * String handling functions.
3  *
4  * Copyright IBM Corp. 2012
5  */
7 #include <linux/linkage.h>
8 #include <asm/export.h>
11  * void *memmove(void *dest, const void *src, size_t n)
12  */
13 ENTRY(memmove)
14         ltgr    %r4,%r4
15         lgr     %r1,%r2
16         bzr     %r14
17         aghi    %r4,-1
18         clgr    %r2,%r3
19         jnh     .Lmemmove_forward
20         la      %r5,1(%r4,%r3)
21         clgr    %r2,%r5
22         jl      .Lmemmove_reverse
23 .Lmemmove_forward:
24         srlg    %r0,%r4,8
25         ltgr    %r0,%r0
26         jz      .Lmemmove_forward_remainder
27 .Lmemmove_forward_loop:
28         mvc     0(256,%r1),0(%r3)
29         la      %r1,256(%r1)
30         la      %r3,256(%r3)
31         brctg   %r0,.Lmemmove_forward_loop
32 .Lmemmove_forward_remainder:
33         larl    %r5,.Lmemmove_mvc
34         ex      %r4,0(%r5)
35         br      %r14
36 .Lmemmove_reverse:
37         ic      %r0,0(%r4,%r3)
38         stc     %r0,0(%r4,%r1)
39         brctg   %r4,.Lmemmove_reverse
40         ic      %r0,0(%r4,%r3)
41         stc     %r0,0(%r4,%r1)
42         br      %r14
43 .Lmemmove_mvc:
44         mvc     0(1,%r1),0(%r3)
45 EXPORT_SYMBOL(memmove)
48  * 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  */
62 ENTRY(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
71         jz      .Lmemset_clear_remainder
72 .Lmemset_clear_loop:
73         xc      0(256,%r1),0(%r1)
74         la      %r1,256(%r1)
75         brctg   %r3,.Lmemset_clear_loop
76 .Lmemset_clear_remainder:
77         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
88         jz      .Lmemset_fill_remainder
89 .Lmemset_fill_loop:
90         mvc     1(256,%r1),0(%r1)
91         la      %r1,256(%r1)
92         brctg   %r3,.Lmemset_fill_loop
93 .Lmemset_fill_remainder:
94         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)
101 EXPORT_SYMBOL(memset)
104  * memcpy implementation
106  * void *memcpy(void *dest, const void *src, size_t n)
107  */
108 ENTRY(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
116 .Lmemcpy_remainder:
117         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
125         j       .Lmemcpy_remainder
126 .Lmemcpy_mvc:
127         mvc     0(1,%r1),0(%r3)
128 EXPORT_SYMBOL(memcpy)