xref: /openbmc/linux/arch/s390/lib/mem.S (revision 1c2dd16a)
1/*
2 * String handling functions.
3 *
4 * Copyright IBM Corp. 2012
5 */
6
7#include <linux/linkage.h>
8#include <asm/export.h>
9
10/*
11 * void *memmove(void *dest, const void *src, size_t n)
12 */
13ENTRY(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)
45EXPORT_SYMBOL(memmove)
46
47/*
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 */
62ENTRY(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)
101EXPORT_SYMBOL(memset)
102
103/*
104 * memcpy implementation
105 *
106 * void *memcpy(void *dest, const void *src, size_t n)
107 */
108ENTRY(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)
128EXPORT_SYMBOL(memcpy)
129