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 .text 30 31#if HAVE_MEMSET_Z900_G5 32# if defined __s390x__ 33# define LTGR ltgr 34# define CGHI cghi 35# define LGR lgr 36# define AGHI aghi 37# define BRCTG brctg 38# else 39# define LTGR ltr 40# define CGHI chi 41# define LGR lr 42# define AGHI ahi 43# define BRCTG brct 44# endif /* ! defined __s390x__ */ 45 46ENTRY(MEMSET_Z900_G5) 47.L_Z900_G5_start: 48#if defined __s390x__ 49 .machine "z900" 50#else 51 .machine "g5" 52#endif /* ! defined __s390x__ */ 53 LTGR %r4,%r4 54 je .L_Z900_G5_4 55 stc %r3,0(%r2) 56 CGHI %r4,1 57 LGR %r1,%r2 58 je .L_Z900_G5_4 59 AGHI %r4,-2 60#if defined __s390x__ 61 larl %r5,.L_Z900_G5_18 62 srlg %r3,%r4,8 63# define Z900_G5_EX_D 0 64#else 65 basr %r5,0 66.L_Z900_G5_19: 67# define Z900_G5_EX_D .L_Z900_G5_18-.L_Z900_G5_19 68 lr %r3,%r4 69 srl %r3,8 70#endif /* ! defined __s390x__ */ 71 LTGR %r3,%r3 72 jne .L_Z900_G5_14 73.L_Z900_G5_3: 74 ex %r4,Z900_G5_EX_D(%r5) 75.L_Z900_G5_4: 76 br %r14 77.L_Z900_G5_14: 78 mvc 1(256,%r1),0(%r1) 79 la %r1,256(%r1) 80 BRCTG %r3,.L_Z900_G5_14 81 j .L_Z900_G5_3 82.L_Z900_G5_18: 83 mvc 1(1,%r1),0(%r1) 84END(MEMSET_Z900_G5) 85# undef LTGR 86# undef CGHI 87# undef LGR 88# undef AGHI 89# undef BRCTG 90#endif /* HAVE_MEMSET_Z900_G5 */ 91 92#if HAVE_MEMSET_Z10 93ENTRY(MEMSET_Z10) 94.L_Z10_start: 95 .machine "z10" 96 .machinemode "zarch_nohighgprs" 97# if !defined __s390x__ 98 llgfr %r4,%r4 99# endif /* !defined __s390x__ */ 100 cgije %r4,0,.L_Z10_4 101 stc %r3,0(%r2) 102 lgr %r1,%r2 103 cgije %r4,1,.L_Z10_4 104 aghi %r4,-2 105 srlg %r5,%r4,8 106 cgijlh %r5,0,.L_Z10_15 107.L_Z10_3: 108 exrl %r4,.L_Z10_18 109.L_Z10_4: 110 br %r14 111.L_Z10_15: 112 cgfi %r5,163840 # Switch to mvcle for >40MB 113 jh __memset_mvcle 114.L_Z10_14: 115 pfd 2,1024(%r1) 116 mvc 1(256,%r1),0(%r1) 117 la %r1,256(%r1) 118 brctg %r5,.L_Z10_14 119 j .L_Z10_3 120.L_Z10_18: 121 mvc 1(1,%r1),0(%r1) 122END(MEMSET_Z10) 123#endif /* HAVE_MEMSET_Z10 */ 124 125#if HAVE_MEMSET_Z196 126ENTRY(MEMSET_Z196) 127.L_Z196_start: 128 .machine "z196" 129 .machinemode "zarch_nohighgprs" 130# if !defined __s390x__ 131 llgfr %r4,%r4 132# endif /* !defined __s390x__ */ 133 clgfi %r4,1 134 jl .L_Z196_4 # n == 0 135 stc %r3,0(%r2) 136 je .L_Z196_4 # n == 1 137 aghi %r4,-2 138 lgr %r1,%r2 139 risbg %r5,%r4,8,128+63,56 # r5 = n / 256 140 jne .L_Z196_1 # Jump away if r5 != 0 141.L_Z196_3: 142 exrl %r4,.L_Z196_17 143.L_Z196_4: 144 br %r14 145.L_Z196_1: 146 cgfi %r5,1048576 147 jh __memset_mvcle # Switch to mvcle for >256MB 148.L_Z196_2: 149 pfd 2,1024(%r1) 150 mvc 1(255,%r1),0(%r1) 151 aghi %r5,-1 152 la %r1,256(%r1) 153 stc %r3,0(%r1) 154 jne .L_Z196_2 155 j .L_Z196_3 156.L_Z196_17: 157 mvc 1(1,%r1),0(%r1) 158END(MEMSET_Z196) 159#endif /* HAVE_MEMSET_Z196 */ 160 161#if HAVE_MEMSET_MVCLE 162ENTRY(__memset_mvcle) 163 aghi %r4,2 # take back the change done by the caller 164 lgr %r0,%r2 # save source address 165 lgr %r1,%r3 # move pad byte to R1 166 lgr %r3,%r4 # move length to r3 167 sgr %r4,%r4 # no source for MVCLE, only a pad byte 168 sgr %r5,%r5 169.L0: mvcle %r2,%r4,0(%r1) # thats it, MVCLE is your friend 170 jo .L0 171 lgr %r2,%r0 # return value is source address 172.L1: 173 br %r14 174END(__memset_mvcle) 175#endif /* HAVE_MEMSET_MVCLE */ 176 177#if ! HAVE_MEMSET_IFUNC 178/* If we don't use ifunc, define an alias for memset here. 179 Otherwise see sysdeps/s390/memset.c. */ 180strong_alias (MEMSET_DEFAULT, memset) 181#endif 182 183#if defined SHARED && IS_IN (libc) 184/* Defines the internal symbol. 185 Compare to libc_hidden_builtin_def (memset) in string/memset.c. */ 186strong_alias (MEMSET_DEFAULT, __GI_memset) 187#endif 188