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