Blame sysdeps/ia64/strchr.S

Packit Service 82fcde
/* Optimized version of the standard strchr() function.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
   Copyright (C) 2000-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   Contributed by Dan Pop <Dan.Pop@cern.ch>.
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
/* Return: the address of the first occurence of chr in str or NULL
Packit Service 82fcde
Packit Service 82fcde
   Inputs:
Packit Service 82fcde
        in0:    str
Packit Service 82fcde
        in1:    chr
Packit Service 82fcde
Packit Service 82fcde
   A modified version of memchr.S, the search ends when the character is
Packit Service 82fcde
   found or the terminating null character is encountered.
Packit Service 82fcde
Packit Service 82fcde
   This implementation assumes little endian mode.  For big endian mode,
Packit Service 82fcde
   the instruction czx1.r should be replaced by czx1.l.  */
Packit Service 82fcde
Packit Service 82fcde
#include <sysdep.h>
Packit Service 82fcde
#undef ret
Packit Service 82fcde
Packit Service 82fcde
#define saved_lc	r18
Packit Service 82fcde
#define poschr		r19
Packit Service 82fcde
#define pos0		r20
Packit Service 82fcde
#define val1		r21
Packit Service 82fcde
#define val2		r22
Packit Service 82fcde
#define tmp		r24
Packit Service 82fcde
#define chrx8		r25
Packit Service 82fcde
#define loopcnt		r30
Packit Service 82fcde
Packit Service 82fcde
#define str		in0
Packit Service 82fcde
#define chr		in1
Packit Service 82fcde
Packit Service 82fcde
ENTRY(strchr)
Packit Service 82fcde
	.prologue
Packit Service 82fcde
	alloc r2 = ar.pfs, 2, 0, 0, 0
Packit Service 82fcde
	.save ar.lc, saved_lc
Packit Service 82fcde
        mov 	saved_lc = ar.lc 	// save the loop counter
Packit Service 82fcde
	.body
Packit Service 82fcde
	mov 	ret0 = str
Packit Service 82fcde
	and 	tmp = 7, str		// tmp = str % 8
Packit Service 82fcde
	mux1	chrx8 = chr, @brcst
Packit Service 82fcde
	extr.u	chr = chr, 0, 8		// retain only the last byte
Packit Service 82fcde
	cmp.ne	p8, p0 = r0, r0		// clear p8
Packit Service 82fcde
	;;
Packit Service 82fcde
	sub	loopcnt = 8, tmp	// loopcnt = 8 - tmp
Packit Service 82fcde
	cmp.eq	p6, p0 = tmp, r0
Packit Service 82fcde
(p6)	br.cond.sptk	.str_aligned;;
Packit Service 82fcde
	adds	loopcnt = -1, loopcnt;;
Packit Service 82fcde
	mov	ar.lc = loopcnt
Packit Service 82fcde
.l1:
Packit Service 82fcde
	ld1	val2 = [ret0], 1
Packit Service 82fcde
	;;
Packit Service 82fcde
	cmp.eq	p6, p0 = val2, chr
Packit Service 82fcde
	cmp.eq	p7, p0 = val2, r0
Packit Service 82fcde
(p6)	br.cond.spnt	.restore_and_exit
Packit Service 82fcde
(p7)	br.cond.spnt	.notfound
Packit Service 82fcde
	br.cloop.sptk	.l1
Packit Service 82fcde
.str_aligned:
Packit Service 82fcde
	ld8	val1 = [ret0], 8;;
Packit Service 82fcde
	nop.b	0
Packit Service 82fcde
	nop.b 	0
Packit Service 82fcde
.l2:
Packit Service 82fcde
	ld8.s	val2 = [ret0], 8	// don't bomb out here
Packit Service 82fcde
	czx1.r	pos0 = val1
Packit Service 82fcde
	xor	tmp = val1, chrx8	// if val1 contains chr, tmp will
Packit Service 82fcde
	;;				// contain a zero in its position
Packit Service 82fcde
	czx1.r	poschr = tmp
Packit Service 82fcde
	cmp.ne	p6, p0 = 8, pos0
Packit Service 82fcde
	;;
Packit Service 82fcde
	cmp.ne	p7, p0 = 8, poschr
Packit Service 82fcde
(p7)	br.cond.spnt .foundit
Packit Service 82fcde
(p6)	br.cond.spnt .notfound
Packit Service 82fcde
	chk.s	val2, .recovery
Packit Service 82fcde
.back:
Packit Service 82fcde
	mov	val1 = val2
Packit Service 82fcde
	br.cond.dptk .l2
Packit Service 82fcde
.foundit:
Packit Service 82fcde
(p6)	cmp.lt	p8, p0 = pos0, poschr	// we found chr and null in the word
Packit Service 82fcde
(p8)	br.cond.spnt .notfound		// null was found before chr
Packit Service 82fcde
	add	ret0 = ret0, poschr ;;
Packit Service 82fcde
	adds	ret0 = -15, ret0 ;;	// should be -16, but we decrement
Packit Service 82fcde
.restore_and_exit:			// ret0 in the next instruction
Packit Service 82fcde
	adds	ret0 = -1, ret0		// ret0 was pointing 1 char too far
Packit Service 82fcde
	mov 	ar.lc = saved_lc	// restore the loop counter
Packit Service 82fcde
	br.ret.sptk.many b0
Packit Service 82fcde
.notfound:
Packit Service 82fcde
	mov	ret0 = r0		// return NULL if null was found
Packit Service 82fcde
	mov 	ar.lc = saved_lc
Packit Service 82fcde
	br.ret.sptk.many b0
Packit Service 82fcde
.recovery:
Packit Service 82fcde
	adds	ret0 = -8, ret0;;
Packit Service 82fcde
	ld8	val2 = [ret0], 8	// bomb out here
Packit Service 82fcde
	br.cond.sptk	.back
Packit Service 82fcde
END(strchr)
Packit Service 82fcde
Packit Service 82fcde
weak_alias (strchr, index)
Packit Service 82fcde
libc_hidden_builtin_def (strchr)