GNU Linux-libre 4.9.294-gnu1
[releases.git] / arch / s390 / lib / mem.S
1 /*
2  * String handling functions.
3  *
4  * Copyright IBM Corp. 2012
5  */
6
7 #include <linux/linkage.h>
8 #include <asm/export.h>
9 #include <asm/nospec-insn.h>
10
11         GEN_BR_THUNK %r14
12
13 /*
14  * memset implementation
15  *
16  * This code corresponds to the C construct below. We do distinguish
17  * between clearing (c == 0) and setting a memory array (c != 0) simply
18  * because nearly all memset invocations in the kernel clear memory and
19  * the xc instruction is preferred in such cases.
20  *
21  * void *memset(void *s, int c, size_t n)
22  * {
23  *      if (likely(c == 0))
24  *              return __builtin_memset(s, 0, n);
25  *      return __builtin_memset(s, c, n);
26  * }
27  */
28 ENTRY(memset)
29         ltgr    %r4,%r4
30         jz      .Lmemset_exit
31         ltgr    %r3,%r3
32         jnz     .Lmemset_fill
33         aghi    %r4,-1
34         srlg    %r3,%r4,8
35         ltgr    %r3,%r3
36         lgr     %r1,%r2
37         jz      .Lmemset_clear_rest
38 .Lmemset_clear_loop:
39         xc      0(256,%r1),0(%r1)
40         la      %r1,256(%r1)
41         brctg   %r3,.Lmemset_clear_loop
42 .Lmemset_clear_rest:
43         larl    %r3,.Lmemset_xc
44         ex      %r4,0(%r3)
45 .Lmemset_exit:
46         BR_EX   %r14
47 .Lmemset_fill:
48         stc     %r3,0(%r2)
49         cghi    %r4,1
50         lgr     %r1,%r2
51         je      .Lmemset_fill_exit
52         aghi    %r4,-2
53         srlg    %r3,%r4,8
54         ltgr    %r3,%r3
55         jz      .Lmemset_fill_rest
56 .Lmemset_fill_loop:
57         mvc     1(256,%r1),0(%r1)
58         la      %r1,256(%r1)
59         brctg   %r3,.Lmemset_fill_loop
60 .Lmemset_fill_rest:
61         larl    %r3,.Lmemset_mvc
62         ex      %r4,0(%r3)
63 .Lmemset_fill_exit:
64         BR_EX   %r14
65 .Lmemset_xc:
66         xc      0(1,%r1),0(%r1)
67 .Lmemset_mvc:
68         mvc     1(1,%r1),0(%r1)
69 EXPORT_SYMBOL(memset)
70
71 /*
72  * memcpy implementation
73  *
74  * void *memcpy(void *dest, const void *src, size_t n)
75  */
76 ENTRY(memcpy)
77         ltgr    %r4,%r4
78         jz      .Lmemcpy_exit
79         aghi    %r4,-1
80         srlg    %r5,%r4,8
81         ltgr    %r5,%r5
82         lgr     %r1,%r2
83         jnz     .Lmemcpy_loop
84 .Lmemcpy_rest:
85         larl    %r5,.Lmemcpy_mvc
86         ex      %r4,0(%r5)
87 .Lmemcpy_exit:
88         BR_EX   %r14
89 .Lmemcpy_loop:
90         mvc     0(256,%r1),0(%r3)
91         la      %r1,256(%r1)
92         la      %r3,256(%r3)
93         brctg   %r5,.Lmemcpy_loop
94         j       .Lmemcpy_rest
95 .Lmemcpy_mvc:
96         mvc     0(1,%r1),0(%r3)
97 EXPORT_SYMBOL(memcpy)