1/* Set a block of memory to some byte value. 31/64 bit S/390 version. 2 Copyright (C) 2001-2021 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