Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * String handling functions.
4 *
5 * Copyright IBM Corp. 2012
6 */
7
8#include <linux/linkage.h>
9#include <asm/export.h>
10
11/*
12 * void *memmove(void *dest, const void *src, size_t n)
13 */
14ENTRY(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)
46EXPORT_SYMBOL(memmove)
47
48/*
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 */
63ENTRY(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)
106EXPORT_SYMBOL(memset)
107
108/*
109 * memcpy implementation
110 *
111 * void *memcpy(void *dest, const void *src, size_t n)
112 */
113ENTRY(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)
133EXPORT_SYMBOL(memcpy)
134
135/*
136 * __memset16/32/64
137 *
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
143ENTRY(__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
169
170__MEMSET 16,2,sth
171EXPORT_SYMBOL(__memset16)
172
173__MEMSET 32,4,st
174EXPORT_SYMBOL(__memset32)
175
176__MEMSET 64,8,stg
177EXPORT_SYMBOL(__memset64)