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