1/* Set a block of memory to some byte value. 31/64 bit S/390 version.
2 Copyright (C) 2001-2022 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19
20#include <sysdep.h>
21#include "asm-syntax.h"
22#include <ifunc-memset.h>
23
24/* INPUT PARAMETERS - MEMSET
25 %r2 = address of memory area
26 %r3 = byte to fill memory with
27 %r4 = number of bytes to fill.
28
29 INPUT PARAMETERS - BZERO
30 %r2 = address of memory area
31 %r3 = number of bytes to fill. */
32
33 .text
34
35#if HAVE_MEMSET_Z900_G5
36# if defined __s390x__
37# define LTGR ltgr
38# define CGHI cghi
39# define LGR lgr
40# define AGHI aghi
41# define BRCTG brctg
42# else
43# define LTGR ltr
44# define CGHI chi
45# define LGR lr
46# define AGHI ahi
47# define BRCTG brct
48# endif /* ! defined __s390x__ */
49
50ENTRY(BZERO_Z900_G5)
51 LGR %r4,%r3
52 xr %r3,%r3
53 j .L_Z900_G5_start
54END(BZERO_Z900_G5)
55
56ENTRY(MEMSET_Z900_G5)
57.L_Z900_G5_start:
58#if defined __s390x__
59 .machine "z900"
60#else
61 .machine "g5"
62#endif /* ! defined __s390x__ */
63 LTGR %r4,%r4
64 je .L_Z900_G5_4
65 stc %r3,0(%r2)
66 CGHI %r4,1
67 LGR %r1,%r2
68 je .L_Z900_G5_4
69 AGHI %r4,-2
70#if defined __s390x__
71 larl %r5,.L_Z900_G5_18
72 srlg %r3,%r4,8
73# define Z900_G5_EX_D 0
74#else
75 basr %r5,0
76.L_Z900_G5_19:
77# define Z900_G5_EX_D .L_Z900_G5_18-.L_Z900_G5_19
78 lr %r3,%r4
79 srl %r3,8
80#endif /* ! defined __s390x__ */
81 LTGR %r3,%r3
82 jne .L_Z900_G5_14
83.L_Z900_G5_3:
84 ex %r4,Z900_G5_EX_D(%r5)
85.L_Z900_G5_4:
86 br %r14
87.L_Z900_G5_14:
88 mvc 1(256,%r1),0(%r1)
89 la %r1,256(%r1)
90 BRCTG %r3,.L_Z900_G5_14
91 j .L_Z900_G5_3
92.L_Z900_G5_18:
93 mvc 1(1,%r1),0(%r1)
94END(MEMSET_Z900_G5)
95# undef LTGR
96# undef CGHI
97# undef LGR
98# undef AGHI
99# undef BRCTG
100#endif /* HAVE_MEMSET_Z900_G5 */
101
102#if HAVE_MEMSET_Z10
103ENTRY(BZERO_Z10)
104 .machine "z10"
105 .machinemode "zarch_nohighgprs"
106 lgr %r4,%r3
107 xr %r3,%r3
108 j .L_Z10_start
109END(BZERO_Z10)
110
111ENTRY(MEMSET_Z10)
112.L_Z10_start:
113 .machine "z10"
114 .machinemode "zarch_nohighgprs"
115# if !defined __s390x__
116 llgfr %r4,%r4
117# endif /* !defined __s390x__ */
118 cgije %r4,0,.L_Z10_4
119 stc %r3,0(%r2)
120 lgr %r1,%r2
121 cgije %r4,1,.L_Z10_4
122 aghi %r4,-2
123 srlg %r5,%r4,8
124 cgijlh %r5,0,.L_Z10_15
125.L_Z10_3:
126 exrl %r4,.L_Z10_18
127.L_Z10_4:
128 br %r14
129.L_Z10_15:
130 cgfi %r5,163840 # Switch to mvcle for >40MB
131 jh __memset_mvcle
132.L_Z10_14:
133 pfd 2,1024(%r1)
134 mvc 1(256,%r1),0(%r1)
135 la %r1,256(%r1)
136 brctg %r5,.L_Z10_14
137 j .L_Z10_3
138.L_Z10_18:
139 mvc 1(1,%r1),0(%r1)
140END(MEMSET_Z10)
141#endif /* HAVE_MEMSET_Z10 */
142
143#if HAVE_MEMSET_Z196
144ENTRY(BZERO_Z196)
145 .machine "z196"
146 .machinemode "zarch_nohighgprs"
147 lgr %r4,%r3
148 xr %r3,%r3
149 j .L_Z196_start
150END(BZERO_Z196)
151
152ENTRY(MEMSET_Z196)
153.L_Z196_start:
154 .machine "z196"
155 .machinemode "zarch_nohighgprs"
156# if !defined __s390x__
157 llgfr %r4,%r4
158# endif /* !defined __s390x__ */
159 clgfi %r4,1
160 jl .L_Z196_4 # n == 0
161 stc %r3,0(%r2)
162 je .L_Z196_4 # n == 1
163 aghi %r4,-2
164 lgr %r1,%r2
165 risbg %r5,%r4,8,128+63,56 # r5 = n / 256
166 jne .L_Z196_1 # Jump away if r5 != 0
167.L_Z196_3:
168 exrl %r4,.L_Z196_17
169.L_Z196_4:
170 br %r14
171.L_Z196_1:
172 cgfi %r5,1048576
173 jh __memset_mvcle # Switch to mvcle for >256MB
174.L_Z196_2:
175 pfd 2,1024(%r1)
176 mvc 1(255,%r1),0(%r1)
177 aghi %r5,-1
178 la %r1,256(%r1)
179 stc %r3,0(%r1)
180 jne .L_Z196_2
181 j .L_Z196_3
182.L_Z196_17:
183 mvc 1(1,%r1),0(%r1)
184END(MEMSET_Z196)
185#endif /* HAVE_MEMSET_Z196 */
186
187#if HAVE_MEMSET_MVCLE
188ENTRY(__memset_mvcle)
189 aghi %r4,2 # take back the change done by the caller
190 lgr %r0,%r2 # save source address
191 lgr %r1,%r3 # move pad byte to R1
192 lgr %r3,%r4 # move length to r3
193 sgr %r4,%r4 # no source for MVCLE, only a pad byte
194 sgr %r5,%r5
195.L0: mvcle %r2,%r4,0(%r1) # thats it, MVCLE is your friend
196 jo .L0
197 lgr %r2,%r0 # return value is source address
198.L1:
199 br %r14
200END(__memset_mvcle)
201#endif /* HAVE_MEMSET_MVCLE */
202
203#if ! HAVE_MEMSET_IFUNC
204/* If we don't use ifunc, define an alias for memset here.
205 Otherwise see sysdeps/s390/memset.c. */
206strong_alias (MEMSET_DEFAULT, memset)
207/* Same for bzero. If ifunc is used, see
208 sysdeps/s390/bzero.c. */
209strong_alias (BZERO_DEFAULT, __bzero)
210weak_alias (__bzero, bzero)
211#endif
212
213#if defined SHARED && IS_IN (libc)
214/* Defines the internal symbol.
215 Compare to libc_hidden_builtin_def (memset) in string/memset.c. */
216strong_alias (MEMSET_DEFAULT, __GI_memset)
217#endif
218

source code of glibc/sysdeps/s390/memset-z900.S