xref: /openbmc/linux/arch/s390/lib/mem.S (revision b24413180f5600bcb3bb70fbed5cf186b60864bd)
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	stc	%r3,0(%r2)
83	cghi	%r4,1
84	lgr	%r1,%r2
85	ber	%r14
86	aghi	%r4,-2
87	srlg	%r3,%r4,8
88	ltgr	%r3,%r3
89	jz	.Lmemset_fill_remainder
90.Lmemset_fill_loop:
91	mvc	1(256,%r1),0(%r1)
92	la	%r1,256(%r1)
93	brctg	%r3,.Lmemset_fill_loop
94.Lmemset_fill_remainder:
95	larl	%r3,.Lmemset_mvc
96	ex	%r4,0(%r3)
97	br	%r14
98.Lmemset_xc:
99	xc	0(1,%r1),0(%r1)
100.Lmemset_mvc:
101	mvc	1(1,%r1),0(%r1)
102EXPORT_SYMBOL(memset)
103
104/*
105 * memcpy implementation
106 *
107 * void *memcpy(void *dest, const void *src, size_t n)
108 */
109ENTRY(memcpy)
110	ltgr	%r4,%r4
111	bzr	%r14
112	aghi	%r4,-1
113	srlg	%r5,%r4,8
114	ltgr	%r5,%r5
115	lgr	%r1,%r2
116	jnz	.Lmemcpy_loop
117.Lmemcpy_remainder:
118	larl	%r5,.Lmemcpy_mvc
119	ex	%r4,0(%r5)
120	br	%r14
121.Lmemcpy_loop:
122	mvc	0(256,%r1),0(%r3)
123	la	%r1,256(%r1)
124	la	%r3,256(%r3)
125	brctg	%r5,.Lmemcpy_loop
126	j	.Lmemcpy_remainder
127.Lmemcpy_mvc:
128	mvc	0(1,%r1),0(%r3)
129EXPORT_SYMBOL(memcpy)
130