• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * memchr - find a character in a memory zone
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	.globl	__memchr_aarch64_sve
18	.type	__memchr_aarch64_sve, %function
19	.p2align 4
20__memchr_aarch64_sve:
21	dup	z1.b, w1			/* duplicate c to a vector */
22	setffr					/* initialize FFR */
23	mov	x3, 0				/* initialize off */
24	nop
25
260:	whilelo	p1.b, x3, x2			/* make sure off < max */
27	b.none	9f
28
29	/* Read a vector's worth of bytes, bounded by max,
30	   stopping on first fault.  */
31	ldff1b	z0.b, p1/z, [x0, x3]
32	rdffrs	p0.b, p1/z
33	b.nlast	2f
34
35	/* First fault did not fail: the vector bounded by max is valid.
36	   Avoid depending on the contents of FFR beyond the branch.  */
37	incb	x3				/* speculate increment */
38	cmpeq	p2.b, p1/z, z0.b, z1.b		/* search for c */
39	b.none	0b
40	decb	x3				/* undo speculate */
41
42	/* Found C.  */
431:	brkb	p2.b, p1/z, p2.b	/* find the first c */
44	add	x0, x0, x3		/* form partial pointer */
45	incp	x0, p2.b		/* form final pointer to c */
46	ret
47
48	/* First fault failed: only some of the vector is valid.
49	   Perform the comparision only on the valid bytes.  */
502:	cmpeq	p2.b, p0/z, z0.b, z1.b
51	b.any	1b
52
53	/* No C found.  Re-init FFR, increment, and loop.  */
54	setffr
55	incp	x3, p0.b
56	b	0b
57
58	/* Found end of count.  */
599:	mov	x0, 0			/* return null */
60	ret
61
62	.size	__memchr_aarch64_sve, . - __memchr_aarch64_sve
63