1/*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2024 Getz Mikalsen <getz@FreeBSD.org> 5*/ 6 7#include <machine/asm.h> 8 9 .weak strspn 10 .set strspn, __strspn 11 .text 12 13ENTRY(__strspn) 14 15 /* check for special cases */ 16 ldrb w4, [x1] // first character in set 17 cbz w4, .Lzero // empty set always returns 0 18 19 mov x15, #1 // preload register with 1 for stores 20 21 // set is only one character 22 ldrb w5, [x1, #1] // second character in the set 23 cbz w5, .Lsingle 24 25 stp x29, x30, [sp, #-16]! 26 mov x29, sp 27 sub sp, sp, #256 // allocate 256 bytes on the stack 28 29 /* no special case matches -- prepare lookup table */ 30 mov w3, #28 310: add x9, sp, x3, lsl #3 32 stp xzr, xzr, [x9] 33 stp xzr, xzr, [x9, #16] 34 subs w3, w3, #4 35 b.cs 0b 36 37 strb w15, [sp, x4] // register first character in set 38 add x1, x1, #2 39 40 /* process remaining chars in set */ 41 .p2align 4 42 43 440: ldrb w4, [x1] // next char in set 45 strb w15, [sp, x5] // register previous char 46 cbz w4, 1f // NUL encountered? 47 48 ldrb w5, [x1, #1] 49 add x1, x1, #2 50 strb w15, [sp, x4] 51 cbnz w5, 0b 52 531: mov x5, x0 // stash a copy of src 54 55 /* find mismatch */ 56 .p2align 4 570: ldrb w8, [x0] 58 ldrb w9, [sp, x8] 59 cbz w9, 2f 60 61 ldrb w8, [x0, #1] 62 ldrb w9, [sp, x8] 63 cbz w9, 3f 64 65 ldrb w8, [x0, #2] 66 ldrb w9, [sp, x8] 67 cbz w9, 4f 68 69 ldrb w8, [x0, #3] 70 add x0, x0, #4 71 ldrb w9, [sp, x8] 72 cbnz w9, 0b 73 74 sub x0, x0, #3 754: sub x5, x5, #1 763: add x0, x0, #1 772: sub x0, x0, x5 78 mov sp, x29 79 ldp x29, x30, [sp], #16 80 ret 81 82.Lzero: 83 mov x0, #0 84 ret 85 86.Lsingle: 87 ldrb w8, [x0, x5] 88 cmp w4, w8 89 b.ne 1f 90 91 add x5, x5, #1 92 ldrb w8, [x0, x5] 93 cmp w4, w8 94 b.ne 1f 95 96 add x5, x5, #1 97 ldrb w8, [x0, x5] 98 cmp w4, w8 99 b.ne 1f 100 101 add x5, x5, #1 102 ldrb w8, [x0, x5] 103 add x5, x5, #1 104 cmp w4, w8 105 b.eq .Lsingle 106 107 sub x5, x5, #1 1081: mov x0, x5 109 ret 110 111END(__strspn) 112