xref: /freebsd/lib/libc/riscv/string/strrchr.S (revision 63ff982b17ee398c7808be323d8fd37819a5863c)
1df21a004SStrahinja Stanišić/*-
2df21a004SStrahinja Stanišić * SPDX-License-Identifier: BSD-2-Clause
3df21a004SStrahinja Stanišić *
4df21a004SStrahinja Stanišić * Copyright (c) 2024 Strahinja Stanisic <strajabot@FreeBSD.org>
5df21a004SStrahinja Stanišić */
6df21a004SStrahinja Stanišić
7df21a004SStrahinja Stanišić#include <machine/asm.h>
8df21a004SStrahinja Stanišić
9*63ff982bSStrahinja Stanišić        .weak   rindex
10*63ff982bSStrahinja Stanišić        .set    rindex, strrchr
11*63ff982bSStrahinja Stanišić
12df21a004SStrahinja Stanišić/*
13df21a004SStrahinja Stanišić * a0 - const char *s
14df21a004SStrahinja Stanišić * a1 - int c
15df21a004SStrahinja Stanišić */
16df21a004SStrahinja StanišićENTRY(strrchr)
17df21a004SStrahinja Stanišić	/*
18df21a004SStrahinja Stanišić	 * a0 - const char *ptr_align
19df21a004SStrahinja Stanišić	 * a1 - temporary
20df21a004SStrahinja Stanišić	 * a2 -	temporary
21df21a004SStrahinja Stanišić	 * a3 - temporary
22df21a004SStrahinja Stanišić	 * a4 -	temporary
23df21a004SStrahinja Stanišić	 * a5 - const char[8] cccccccc
24df21a004SStrahinja Stanišić	 * a6 - const uint64_t *save_align
25df21a004SStrahinja Stanišić	 * a7 - const uint64_t save_iter
26df21a004SStrahinja Stanišić	 * t0 - const uintr64_t REP8_0X01
27df21a004SStrahinja Stanišić	 * t1 - const uintr64_t REP8_0X80
28df21a004SStrahinja Stanišić	 */
29df21a004SStrahinja Stanišić
30df21a004SStrahinja Stanišić	/*
31df21a004SStrahinja Stanišić	 * save_align = 0
32df21a004SStrahinja Stanišić	 * save_iter = 0xFFFFFFFFFFFFFF00
33df21a004SStrahinja Stanišić	 * REP8_0X01 = 0x0101010101010101
34df21a004SStrahinja Stanišić	 * cccccccc = (char)c * REP8_0X01
35df21a004SStrahinja Stanišić	 * REP8_0X80 = (REP8_0X80 << 7) << ((str % 8) * 8)
36df21a004SStrahinja Stanišić	 * ptr_align = str - str % 8
37df21a004SStrahinja Stanišić	 */
38df21a004SStrahinja Stanišić	li t0, 0x01010101
39df21a004SStrahinja Stanišić	li a6, 0
40df21a004SStrahinja Stanišić	slli a2, a0, 3
41df21a004SStrahinja Stanišić	slli t1, t0, 32
42df21a004SStrahinja Stanišić	li a7, 0xFFFFFFFFFFFFFF00
43df21a004SStrahinja Stanišić	or t0, t0, t1
44df21a004SStrahinja Stanišić	andi a1, a1, 0xFF
45df21a004SStrahinja Stanišić	slli t1, t0, 7
46df21a004SStrahinja Stanišić	andi a0, a0, ~0b111
47df21a004SStrahinja Stanišić	mul a5, a1, t0
48df21a004SStrahinja Stanišić	sll t1, t1, a2
49df21a004SStrahinja Stanišić
50df21a004SStrahinja Stanišić.Lloop:					/* do {				*/
51df21a004SStrahinja Stanišić	ld a1, 0(a0)			/* a1 -> data = *ptr_align	*/
52df21a004SStrahinja Stanišić	not a3, a1			/* a3 -> nhz = ~data		*/
53df21a004SStrahinja Stanišić	xor a2, a1, a5			/* a2 -> iter = data ^ cccccccc	*/
54df21a004SStrahinja Stanišić	sub a1, a1, t0			/* a1 -> hz = data - REP8_0X01	*/
55df21a004SStrahinja Stanišić	not a4, a2			/* a4 -> nhc = ~iter		*/
56df21a004SStrahinja Stanišić	and a1, a1, a3			/* hz = hz & nhz		*/
57df21a004SStrahinja Stanišić	sub a3, a2, t0			/* a3 -> hc = iter - REP8_0X01	*/
58df21a004SStrahinja Stanišić	and a1, a1, t1			/* hz = hz & REP8_0X80		*/
59df21a004SStrahinja Stanišić	and a3, a3, a4			/* hc = hc & nhc		*/
60df21a004SStrahinja Stanišić	addi a4, a1, -1			/* a4 -> mask_end = hz - 1	*/
61df21a004SStrahinja Stanišić	and a3, a3, t1			/* hc = hc & REP8_0X80		*/
62df21a004SStrahinja Stanišić	xor a4, a4, a1			/* mask_end = mask_end ^ hz	*/
63df21a004SStrahinja Stanišić	addi a0, a0, 8			/* ptr_align = ptr_align + 8	*/
64df21a004SStrahinja Stanišić	and a3, a3, a4			/* hc = hc & mask_end		*/
65df21a004SStrahinja Stanišić	slli t1, t0, 7			/* REP8_0X80 = REP8_0X01 << 7	*/
66df21a004SStrahinja Stanišić	not a4, a4			/* mask_end = ~mask_end		*/
67df21a004SStrahinja Stanišić
68df21a004SStrahinja Stanišić	beqz a3, .Lskip_save		/* if(!hc) goto skip_save	*/
69df21a004SStrahinja Stanišić	or a2, a2, a4			/* iter = iter | mask_end	*/
70df21a004SStrahinja Stanišić	addi a6, a0, -8			/* save_align = ptr_align - 8	*/
71df21a004SStrahinja Stanišić	mv a7, a2			/* save_iter = iter		*/
72df21a004SStrahinja Stanišić
73df21a004SStrahinja Stanišić.Lskip_save:
74df21a004SStrahinja Stanišić	beqz a1, .Lloop			/* } while(!hz)			*/
75df21a004SStrahinja Stanišić
76df21a004SStrahinja Stanišić.Lfind_char:
77df21a004SStrahinja Stanišić	/*
78df21a004SStrahinja Stanišić	 * a1 -> iter = save_iter
79df21a004SStrahinja Stanišić	 * a2 -> mask_iter = 0xFF00000000000000
80df21a004SStrahinja Stanišić	 * a3 -> match_off = 7
81df21a004SStrahinja Stanišić	 */
82df21a004SStrahinja Stanišić	li a2, 0xFF
83df21a004SStrahinja Stanišić	mv a1, a7
84df21a004SStrahinja Stanišić	slli a2, a2, 56
85df21a004SStrahinja Stanišić	li a3, 7
86df21a004SStrahinja Stanišić
87df21a004SStrahinja Stanišić	and a0, a1, a2
88df21a004SStrahinja Stanišić	srli a2, a2, 8
89df21a004SStrahinja Stanišić	beqz a0, .Lret
90df21a004SStrahinja Stanišić
91df21a004SStrahinja Stanišić	addi a3, a3, -1
92df21a004SStrahinja Stanišić	and a0, a1, a2
93df21a004SStrahinja Stanišić	srli a2, a2, 8
94df21a004SStrahinja Stanišić	beqz a0, .Lret
95df21a004SStrahinja Stanišić
96df21a004SStrahinja Stanišić	addi a3, a3, -1
97df21a004SStrahinja Stanišić	and a0, a1, a2
98df21a004SStrahinja Stanišić	srli a2, a2, 8
99df21a004SStrahinja Stanišić	beqz a0, .Lret
100df21a004SStrahinja Stanišić
101df21a004SStrahinja Stanišić	addi a3, a3, -1
102df21a004SStrahinja Stanišić	and a0, a1, a2
103df21a004SStrahinja Stanišić	srli a2, a2, 8
104df21a004SStrahinja Stanišić	beqz a0, .Lret
105df21a004SStrahinja Stanišić
106df21a004SStrahinja Stanišić	addi a3, a3, -1
107df21a004SStrahinja Stanišić	and a0, a1, a2
108df21a004SStrahinja Stanišić	srli a2, a2, 8
109df21a004SStrahinja Stanišić	beqz a0, .Lret
110df21a004SStrahinja Stanišić
111df21a004SStrahinja Stanišić	addi a3, a3, -1
112df21a004SStrahinja Stanišić	and a0, a1, a2
113df21a004SStrahinja Stanišić	srli a2, a2, 8
114df21a004SStrahinja Stanišić	beqz a0, .Lret
115df21a004SStrahinja Stanišić
116df21a004SStrahinja Stanišić	addi a3, a3, -1
117df21a004SStrahinja Stanišić	and a0, a1, a2
118df21a004SStrahinja Stanišić	srli a2, a2, 8
119df21a004SStrahinja Stanišić	beqz a0, .Lret
120df21a004SStrahinja Stanišić
121df21a004SStrahinja Stanišić	addi a3, a3, -1
122df21a004SStrahinja Stanišić
123df21a004SStrahinja Stanišić.Lret:
124df21a004SStrahinja Stanišić	/* return save_align + match_offset */
125df21a004SStrahinja Stanišić	add a0, a6, a3
126df21a004SStrahinja Stanišić	ret
127df21a004SStrahinja StanišićEND(strrchr)
128