162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Returns 0 if exception before NUL or reaching the supplied limit (N),
462306a36Sopenharmony_ci * a value greater than N if the string is longer than the limit, else
562306a36Sopenharmony_ci * strlen.
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Inputs:
862306a36Sopenharmony_ci *	in0:	address of buffer
962306a36Sopenharmony_ci *	in1:	string length limit N
1062306a36Sopenharmony_ci * Outputs:
1162306a36Sopenharmony_ci *	r8:	0 in case of fault, strlen(buffer)+1 otherwise
1262306a36Sopenharmony_ci *
1362306a36Sopenharmony_ci * Copyright (C) 1999, 2001 David Mosberger-Tang <davidm@hpl.hp.com>
1462306a36Sopenharmony_ci */
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#include <linux/export.h>
1762306a36Sopenharmony_ci#include <asm/asmmacro.h>
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ciGLOBAL_ENTRY(__strnlen_user)
2062306a36Sopenharmony_ci	.prologue
2162306a36Sopenharmony_ci	alloc r2=ar.pfs,2,0,0,0
2262306a36Sopenharmony_ci	.save ar.lc, r16
2362306a36Sopenharmony_ci	mov r16=ar.lc			// preserve ar.lc
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci	.body
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci	add r3=-1,in1
2862306a36Sopenharmony_ci	;;
2962306a36Sopenharmony_ci	mov ar.lc=r3
3062306a36Sopenharmony_ci	mov r9=0
3162306a36Sopenharmony_ci	;;
3262306a36Sopenharmony_ci	// XXX braindead strlen loop---this needs to be optimized
3362306a36Sopenharmony_ci.Loop1:
3462306a36Sopenharmony_ci	EXCLR(.Lexit, ld1 r8=[in0],1)
3562306a36Sopenharmony_ci	add r9=1,r9
3662306a36Sopenharmony_ci	;;
3762306a36Sopenharmony_ci	cmp.eq p6,p0=r8,r0
3862306a36Sopenharmony_ci(p6)	br.cond.dpnt .Lexit
3962306a36Sopenharmony_ci	br.cloop.dptk.few .Loop1
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci	add r9=1,in1			// NUL not found---return N+1
4262306a36Sopenharmony_ci	;;
4362306a36Sopenharmony_ci.Lexit:
4462306a36Sopenharmony_ci	mov r8=r9
4562306a36Sopenharmony_ci	mov ar.lc=r16			// restore ar.lc
4662306a36Sopenharmony_ci	br.ret.sptk.many rp
4762306a36Sopenharmony_ciEND(__strnlen_user)
4862306a36Sopenharmony_ciEXPORT_SYMBOL(__strnlen_user)
49