Blame sysdeps/alpha/strncat.S

Packit Service 82fcde
/* Copyright (C) 1996-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
   Contributed by Richard Henderson <rth@tamu.edu>, 1996.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library.  If not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
/* Append no more than COUNT characters from the null-terminated string SRC
Packit Service 82fcde
   to the null-terminated string DST.  Always null-terminate the new DST.  */
Packit Service 82fcde
Packit Service 82fcde
#include <sysdep.h>
Packit Service 82fcde
Packit Service 82fcde
	.text
Packit Service 82fcde
Packit Service 82fcde
ENTRY(strncat)
Packit Service 82fcde
	ldgp	gp, 0(pv)
Packit Service 82fcde
#ifdef PROF
Packit Service 82fcde
	.set noat
Packit Service 82fcde
	lda	AT, _mcount
Packit Service 82fcde
	jsr	AT, (AT), _mcount
Packit Service 82fcde
	.set at
Packit Service 82fcde
#endif
Packit Service 82fcde
	.prologue 1
Packit Service 82fcde
Packit Service 82fcde
	mov	a0, v0		# set up return value
Packit Service 82fcde
	beq	a2, $zerocount
Packit Service 82fcde
Packit Service 82fcde
	/* Find the end of the string.  */
Packit Service 82fcde
Packit Service 82fcde
	ldq_u   t0, 0(a0)	# load first quadword (a0 may be misaligned)
Packit Service 82fcde
	lda     t1, -1(zero)
Packit Service 82fcde
	insqh   t1, a0, t1
Packit Service 82fcde
	andnot  a0, 7, a0
Packit Service 82fcde
	or      t1, t0, t0
Packit Service 82fcde
	cmpbge  zero, t0, t1	# t1 <- bitmask: bit i == 1 <==> i-th byte == 0
Packit Service 82fcde
	bne     t1, $found
Packit Service 82fcde
Packit Service 82fcde
$loop:	ldq     t0, 8(a0)
Packit Service 82fcde
	addq    a0, 8, a0	# addr += 8
Packit Service 82fcde
	cmpbge  zero, t0, t1
Packit Service 82fcde
	beq     t1, $loop
Packit Service 82fcde
Packit Service 82fcde
$found:	negq    t1, t2		# clear all but least set bit
Packit Service 82fcde
	and     t1, t2, t1
Packit Service 82fcde
Packit Service 82fcde
	and     t1, 0xf0, t2	# binary search for that set bit
Packit Service 82fcde
	and	t1, 0xcc, t3
Packit Service 82fcde
	and	t1, 0xaa, t4
Packit Service 82fcde
	cmovne	t2, 4, t2
Packit Service 82fcde
	cmovne	t3, 2, t3
Packit Service 82fcde
	cmovne	t4, 1, t4
Packit Service 82fcde
	addq	t2, t3, t2
Packit Service 82fcde
	addq	a0, t4, a0
Packit Service 82fcde
	addq	a0, t2, a0
Packit Service 82fcde
Packit Service 82fcde
	/* Now do the append.  */
Packit Service 82fcde
Packit Service 82fcde
	jsr	t9, __stxncpy
Packit Service 82fcde
Packit Service 82fcde
	/* Worry about the null termination.  */
Packit Service 82fcde
Packit Service 82fcde
	zapnot	t0, t8, t1	# was last byte a null?
Packit Service 82fcde
	bne	t1, 0f
Packit Service 82fcde
	ret
Packit Service 82fcde
Packit Service 82fcde
0:	and	t10, 0x80, t1
Packit Service 82fcde
	bne	t1, 1f
Packit Service 82fcde
Packit Service 82fcde
	/* Here there are bytes left in the current word.  Clear one.  */
Packit Service 82fcde
	addq	t10, t10, t10	# end-of-count bit <<= 1
Packit Service 82fcde
	zap	t0, t10, t0
Packit Service 82fcde
	stq_u	t0, 0(a0)
Packit Service 82fcde
	ret
Packit Service 82fcde
Packit Service 82fcde
1:	/* Here we must read the next DST word and clear the first byte.  */
Packit Service 82fcde
	ldq_u	t0, 8(a0)
Packit Service 82fcde
	zap	t0, 1, t0
Packit Service 82fcde
	stq_u	t0, 8(a0)
Packit Service 82fcde
Packit Service 82fcde
$zerocount:
Packit Service 82fcde
	ret
Packit Service 82fcde
Packit Service 82fcde
	END(strncat)