Blame sysdeps/s390/s390-32/strncpy-z900.S

Packit 6c4009
/* strncpy - copy at most n characters from a string from source to
Packit 6c4009
   destination.  For IBM S390
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
   Copyright (C) 2000-2018 Free Software Foundation, Inc.
Packit 6c4009
   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
/*
Packit 6c4009
 * R2 = address of destination (dst)
Packit 6c4009
 * R3 = address of source (src)
Packit 6c4009
 * R4 = max of bytes to copy
Packit 6c4009
 */
Packit 6c4009
Packit Service cee91b
#include <ifunc-strncpy.h>
Packit 6c4009
#include "sysdep.h"
Packit 6c4009
#include "asm-syntax.h"
Packit 6c4009
Packit Service cee91b
#if HAVE_STRNCPY_Z900_G5
Packit Service cee91b
ENTRY(STRNCPY_Z900_G5)
Packit 6c4009
	.text
Packit 6c4009
	st    %r2,24(%r15)          # save dst pointer
Packit 6c4009
	slr   %r2,%r3               # %r3 points to src, %r2+%r3 to dst
Packit 6c4009
	lhi   %r1,3
Packit 6c4009
	nr    %r1,%r4               # last 2 bits of # bytes
Packit 6c4009
	srl   %r4,2
Packit 6c4009
	ltr   %r4,%r4               # less than 4 bytes to copy ?
Packit 6c4009
	jz    .L1
Packit 6c4009
	bras  %r5,.L0               # enter loop & load address of a 0
Packit 6c4009
	.long 0
Packit 6c4009
.L0:    icm   %r0,8,0(%r3)          # first byte
Packit 6c4009
	jz    .L3
Packit 6c4009
	icm   %r0,4,1(%r3)          # second byte
Packit 6c4009
	jz    .L4
Packit 6c4009
	icm   %r0,2,2(%r3)          # third byte
Packit 6c4009
	jz    .L5
Packit 6c4009
	icm   %r0,1,3(%r3)          # fourth byte
Packit 6c4009
	jz    .L6
Packit 6c4009
	st    %r0,0(%r2,%r3)        # store all four to dest.
Packit 6c4009
	la    %r3,4(%r3)
Packit 6c4009
	brct  %r4,.L0
Packit 6c4009
.L1:    ltr   %r1,%r1
Packit 6c4009
	jz    .Lexit
Packit 6c4009
.L2:    icm   %r0,1,0(%r3)
Packit 6c4009
	stc   %r0,0(%r2,%r3)
Packit 6c4009
	la    %r3,1(%r3)
Packit 6c4009
	jz    .L7
Packit 6c4009
	brct  %r1,.L2
Packit 6c4009
	j     .Lexit
Packit 6c4009
.L3:    icm   %r0,4,0(%r5)
Packit 6c4009
.L4:    icm   %r0,2,0(%r5)
Packit 6c4009
.L5:    icm   %r0,1,0(%r5)
Packit 6c4009
.L6:    st    %r0,0(%r2,%r3)
Packit 6c4009
	la    %r3,4(%r3)
Packit 6c4009
	ahi   %r4,-1
Packit 6c4009
	j     .L8
Packit 6c4009
.L7:    ahi   %r1,-1
Packit 6c4009
.L8:    sll   %r4,2
Packit 6c4009
	alr   %r4,%r1
Packit 6c4009
	alr   %r2,%r3               # start of dst area to be zeroed
Packit 6c4009
	lr    %r3,%r4
Packit 6c4009
	slr   %r4,%r4
Packit 6c4009
	slr   %r5,%r5
Packit 6c4009
.L9:    mvcle %r2,%r4,0             # pad dst with zeroes
Packit 6c4009
	jo    .L9
Packit 6c4009
.Lexit: l     %r2,24(%r15)          # return dst pointer
Packit 6c4009
	br    %r14
Packit Service cee91b
END(STRNCPY_Z900_G5)
Packit Service cee91b
Packit Service cee91b
# if ! HAVE_STRNCPY_IFUNC
Packit Service cee91b
strong_alias (STRNCPY_Z900_G5, strncpy)
Packit Service cee91b
# endif
Packit Service cee91b
Packit Service cee91b
# if defined SHARED && IS_IN (libc)
Packit Service cee91b
strong_alias (STRNCPY_Z900_G5, __GI_strncpy)
Packit Service cee91b
# endif
Packit Service cee91b
#endif