• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * strchr/strchrnul - find a character in a string
3 *
4 * Copyright (c) 2018, Arm Limited.
5 * SPDX-License-Identifier: MIT
6 */
7
8/* Assumptions:
9 *
10 * ARMv8-a, AArch64
11 * SVE Available.
12 */
13
14	.arch	armv8-a+sve
15	.text
16
17/* To build as strchrnul, define BUILD_STRCHRNUL before compiling this file.  */
18#ifdef BUILD_STRCHRNUL
19#define FUNC  __strchrnul_aarch64_sve
20#else
21#define FUNC  __strchr_aarch64_sve
22#endif
23
24	.globl	FUNC
25	.type	FUNC, %function
26	.p2align 4
27FUNC:
28	dup	z1.b, w1		/* replicate byte across vector */
29	setffr				/* initialize FFR */
30	ptrue	p1.b			/* all ones; loop invariant */
31
32	.p2align 4
33	/* Read a vector's worth of bytes, stopping on first fault.  */
340:	ldff1b	z0.b, p1/z, [x0, xzr]
35	rdffrs	p0.b, p1/z
36	b.nlast	2f
37
38	/* First fault did not fail: the whole vector is valid.
39	   Avoid depending on the contents of FFR beyond the branch.  */
40	incb	x0				/* speculate increment */
41	cmpeq	p2.b, p1/z, z0.b, z1.b		/* search for c */
42	cmpeq	p3.b, p1/z, z0.b, 0		/* search for 0 */
43	orrs	p4.b, p1/z, p2.b, p3.b		/* c | 0 */
44	b.none	0b
45	decb	x0				/* undo speculate */
46
47	/* Found C or 0.  */
481:	brka	p4.b, p1/z, p4.b	/* find first such */
49	sub	x0, x0, 1		/* adjust pointer for that byte */
50	incp	x0, p4.b
51#ifndef BUILD_STRCHRNUL
52	ptest	p4, p2.b		/* was first in c? */
53	csel	x0, xzr, x0, none	/* if there was no c, return null */
54#endif
55	ret
56
57	/* First fault failed: only some of the vector is valid.
58	   Perform the comparision only on the valid bytes.  */
592:	cmpeq	p2.b, p0/z, z0.b, z1.b		/* search for c */
60	cmpeq	p3.b, p0/z, z0.b, 0		/* search for 0 */
61	orrs	p4.b, p0/z, p2.b, p3.b		/* c | 0 */
62	b.any	1b
63
64	/* No C or 0 found.  Re-init FFR, increment, and loop.  */
65	setffr
66	incp	x0, p0.b
67	b	0b
68
69	.size	FUNC, . - FUNC
70