1/* Copyright (C) 2010-2021 Free Software Foundation, Inc. 2 This file is part of the GNU C Library. 3 4 The GNU C Library is free software; you can redistribute it and/or 5 modify it under the terms of the GNU Lesser General Public 6 License as published by the Free Software Foundation; either 7 version 2.1 of the License, or (at your option) any later version. 8 9 The GNU C Library is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Lesser General Public License for more details. 13 14 You should have received a copy of the GNU Lesser General Public 15 License along with the GNU C Library. If not, see 16 <https://www.gnu.org/licenses/>. */ 17 18/* 19 Assumes: 20 ARMv6T2, AArch32 21 22 */ 23 24#include <arm-features.h> 25#include <sysdep.h> 26 27#ifdef __ARMEB__ 28#define S2LO lsl 29#define S2HI lsr 30#else 31#define S2LO lsr 32#define S2HI lsl 33#endif 34 35/* This code is best on Thumb. */ 36 .thumb 37 38/* Parameters and result. */ 39#define srcin r0 40#define result r0 41 42/* Internal variables. */ 43#define src r1 44#define data1a r2 45#define data1b r3 46#define const_m1 r12 47#define const_0 r4 48#define tmp1 r4 /* Overlaps const_0 */ 49#define tmp2 r5 50 51 .text 52 .p2align 6 53ENTRY(strlen) 54 pld [srcin, #0] 55 strd r4, r5, [sp, #-8]! 56 cfi_adjust_cfa_offset (8) 57 cfi_rel_offset (r4, 0) 58 cfi_rel_offset (r5, 4) 59 cfi_remember_state 60 bic src, srcin, #7 61 mvn const_m1, #0 62 ands tmp1, srcin, #7 /* (8 - bytes) to alignment. */ 63 pld [src, #32] 64 bne.w .Lmisaligned8 65 mov const_0, #0 66 mov result, #-8 67.Lloop_aligned: 68 /* Bytes 0-7. */ 69 ldrd data1a, data1b, [src] 70 pld [src, #64] 71 add result, result, #8 72.Lstart_realigned: 73 uadd8 data1a, data1a, const_m1 /* Saturating GE<0:3> set. */ 74 sel data1a, const_0, const_m1 /* Select based on GE<0:3>. */ 75 uadd8 data1b, data1b, const_m1 76 sel data1b, data1a, const_m1 /* Only used if d1a == 0. */ 77 cbnz data1b, .Lnull_found 78 79 /* Bytes 8-15. */ 80 ldrd data1a, data1b, [src, #8] 81 uadd8 data1a, data1a, const_m1 /* Saturating GE<0:3> set. */ 82 add result, result, #8 83 sel data1a, const_0, const_m1 /* Select based on GE<0:3>. */ 84 uadd8 data1b, data1b, const_m1 85 sel data1b, data1a, const_m1 /* Only used if d1a == 0. */ 86 cbnz data1b, .Lnull_found 87 88 /* Bytes 16-23. */ 89 ldrd data1a, data1b, [src, #16] 90 uadd8 data1a, data1a, const_m1 /* Saturating GE<0:3> set. */ 91 add result, result, #8 92 sel data1a, const_0, const_m1 /* Select based on GE<0:3>. */ 93 uadd8 data1b, data1b, const_m1 94 sel data1b, data1a, const_m1 /* Only used if d1a == 0. */ 95 cbnz data1b, .Lnull_found 96 97 /* Bytes 24-31. */ 98 ldrd data1a, data1b, [src, #24] 99 add src, src, #32 100 uadd8 data1a, data1a, const_m1 /* Saturating GE<0:3> set. */ 101 add result, result, #8 102 sel data1a, const_0, const_m1 /* Select based on GE<0:3>. */ 103 uadd8 data1b, data1b, const_m1 104 sel data1b, data1a, const_m1 /* Only used if d1a == 0. */ 105 cmp data1b, #0 106 beq .Lloop_aligned 107 108.Lnull_found: 109 cmp data1a, #0 110 itt eq 111 addeq result, result, #4 112 moveq data1a, data1b 113#ifndef __ARMEB__ 114 rev data1a, data1a 115#endif 116 clz data1a, data1a 117 ldrd r4, r5, [sp], #8 118 cfi_adjust_cfa_offset (-8) 119 cfi_restore (r4) 120 cfi_restore (r5) 121 add result, result, data1a, lsr #3 /* Bits -> Bytes. */ 122 DO_RET(lr) 123 124.Lmisaligned8: 125 cfi_restore_state 126 ldrd data1a, data1b, [src] 127 and tmp2, tmp1, #3 128 rsb result, tmp1, #0 129 lsl tmp2, tmp2, #3 /* Bytes -> bits. */ 130 tst tmp1, #4 131 pld [src, #64] 132 S2HI tmp2, const_m1, tmp2 133 orn data1a, data1a, tmp2 134 itt ne 135 ornne data1b, data1b, tmp2 136 movne data1a, const_m1 137 mov const_0, #0 138 b .Lstart_realigned 139 140END(strlen) 141libc_hidden_builtin_def (strlen) 142