1*f2bd390aSGetz Mikalsen/*- 2*f2bd390aSGetz Mikalsen * SPDX-License-Identifier: BSD-2-Clause 3*f2bd390aSGetz Mikalsen * 4*f2bd390aSGetz Mikalsen * Copyright (c) 2024 Getz Mikalsen <getz@FreeBSD.org> 5*f2bd390aSGetz Mikalsen*/ 6*f2bd390aSGetz Mikalsen 7*f2bd390aSGetz Mikalsen#include <machine/asm.h> 8*f2bd390aSGetz Mikalsen 9*f2bd390aSGetz Mikalsen .weak strcspn 10*f2bd390aSGetz Mikalsen .set strcspn, __strcspn 11*f2bd390aSGetz Mikalsen .text 12*f2bd390aSGetz Mikalsen 13*f2bd390aSGetz MikalsenENTRY(__strcspn) 14*f2bd390aSGetz Mikalsen stp x29, x30, [sp, #-16]! 15*f2bd390aSGetz Mikalsen mov x29, sp 16*f2bd390aSGetz Mikalsen mov x15, #1 // preload register with 1 for stores 17*f2bd390aSGetz Mikalsen 18*f2bd390aSGetz Mikalsen /* check for special cases */ 19*f2bd390aSGetz Mikalsen ldrb w4, [x1] // first character in the set 20*f2bd390aSGetz Mikalsen cbz w4, .Lstrlen 21*f2bd390aSGetz Mikalsen 22*f2bd390aSGetz Mikalsen movi v0.16b, #0 23*f2bd390aSGetz Mikalsen 24*f2bd390aSGetz Mikalsen ldrb w5, [x1, #1] // second character in the set 25*f2bd390aSGetz Mikalsen cbz w5, .Lstrchr 26*f2bd390aSGetz Mikalsen 27*f2bd390aSGetz Mikalsen sub sp, sp, #256 // allocate 256 bytes on the stack 28*f2bd390aSGetz Mikalsen 29*f2bd390aSGetz Mikalsen /* no special case matches -- prepare lookup table */ 30*f2bd390aSGetz Mikalsen mov w3, #20 31*f2bd390aSGetz Mikalsen .p2align 4 32*f2bd390aSGetz Mikalsen0: add x9, sp, x3, lsl #3 33*f2bd390aSGetz Mikalsen stp xzr, xzr, [x9] 34*f2bd390aSGetz Mikalsen stp xzr, xzr, [x9, #16] 35*f2bd390aSGetz Mikalsen subs w3, w3, #4 36*f2bd390aSGetz Mikalsen b.cs 0b 37*f2bd390aSGetz Mikalsen 38*f2bd390aSGetz Mikalsen /* utilize SIMD stores to speed up zeroing the table */ 39*f2bd390aSGetz Mikalsen stp q0, q0, [sp, #6*32] 40*f2bd390aSGetz Mikalsen stp q0, q0, [sp, #7*32] 41*f2bd390aSGetz Mikalsen 42*f2bd390aSGetz Mikalsen add x1, x1, #2 43*f2bd390aSGetz Mikalsen strb w15, [sp, x4] // register first chars in the set 44*f2bd390aSGetz Mikalsen strb w15, [sp, x5] 45*f2bd390aSGetz Mikalsen 46*f2bd390aSGetz Mikalsen mov x4, x0 // stash a copy of src 47*f2bd390aSGetz Mikalsen 48*f2bd390aSGetz Mikalsen /* process remaining chars in set */ 49*f2bd390aSGetz Mikalsen .p2align 4 50*f2bd390aSGetz Mikalsen0: ldrb w5, [x1] 51*f2bd390aSGetz Mikalsen strb w15, [sp, x5] 52*f2bd390aSGetz Mikalsen cbz w5, 1f // end of set? 53*f2bd390aSGetz Mikalsen 54*f2bd390aSGetz Mikalsen ldrb w5, [x1, #1] 55*f2bd390aSGetz Mikalsen strb w15, [sp, x5] 56*f2bd390aSGetz Mikalsen cbz w5, 1f 57*f2bd390aSGetz Mikalsen 58*f2bd390aSGetz Mikalsen add x1, x1, #2 59*f2bd390aSGetz Mikalsen b 0b 60*f2bd390aSGetz Mikalsen 61*f2bd390aSGetz Mikalsen /* find match */ 62*f2bd390aSGetz Mikalsen .p2align 4 63*f2bd390aSGetz Mikalsen1: ldrb w8, [x0] 64*f2bd390aSGetz Mikalsen ldrb w9, [sp, x8] 65*f2bd390aSGetz Mikalsen cbnz w9, 2f 66*f2bd390aSGetz Mikalsen 67*f2bd390aSGetz Mikalsen ldrb w8, [x0, #1] 68*f2bd390aSGetz Mikalsen ldrb w9, [sp, x8] 69*f2bd390aSGetz Mikalsen cbnz w9, 3f 70*f2bd390aSGetz Mikalsen 71*f2bd390aSGetz Mikalsen ldrb w8, [x0, #2] 72*f2bd390aSGetz Mikalsen ldrb w9, [sp, x8] 73*f2bd390aSGetz Mikalsen cbnz w9, 4f 74*f2bd390aSGetz Mikalsen 75*f2bd390aSGetz Mikalsen ldrb w8, [x0, #3] 76*f2bd390aSGetz Mikalsen ldrb w9, [sp, x8] 77*f2bd390aSGetz Mikalsen add x0, x0, #4 78*f2bd390aSGetz Mikalsen cbz w9, 1b 79*f2bd390aSGetz Mikalsen 80*f2bd390aSGetz Mikalsen sub x0, x0, #3 // fix up return value 81*f2bd390aSGetz Mikalsen4: sub x4, x4, #1 82*f2bd390aSGetz Mikalsen3: add x0, x0, #1 83*f2bd390aSGetz Mikalsen2: sub x0, x0, x4 84*f2bd390aSGetz Mikalsen mov sp, x29 85*f2bd390aSGetz Mikalsen ldp x29, x30, [sp], #16 // restore sp and lr 86*f2bd390aSGetz Mikalsen ret 87*f2bd390aSGetz Mikalsen 88*f2bd390aSGetz Mikalsen /* set is empty, degrades to strlen */ 89*f2bd390aSGetz Mikalsen .p2align 4 90*f2bd390aSGetz Mikalsen.Lstrlen: 91*f2bd390aSGetz Mikalsen mov sp, x29 92*f2bd390aSGetz Mikalsen ldp x29, x30, [sp], #16 // restore sp and lr 93*f2bd390aSGetz Mikalsen b strlen 94*f2bd390aSGetz Mikalsen 95*f2bd390aSGetz Mikalsen /* just one character in set, degrades to strchrnul */ 96*f2bd390aSGetz Mikalsen .p2align 4 97*f2bd390aSGetz Mikalsen.Lstrchr: 98*f2bd390aSGetz Mikalsen stp x0, x1, [sp, #-16]! 99*f2bd390aSGetz Mikalsen mov x1, x4 100*f2bd390aSGetz Mikalsen 101*f2bd390aSGetz Mikalsen bl strchrnul 102*f2bd390aSGetz Mikalsen 103*f2bd390aSGetz Mikalsen ldp x18, x17, [sp], #16 // restore stashed src 104*f2bd390aSGetz Mikalsen sub x0, x0, x18 105*f2bd390aSGetz Mikalsen 106*f2bd390aSGetz Mikalsen ldp x29, x30, [sp], #16 // Restore sp and lr 107*f2bd390aSGetz Mikalsen ret 108*f2bd390aSGetz Mikalsen 109*f2bd390aSGetz MikalsenEND(__strcspn) 110