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