126 lines · plain
1/*2 * strlen - calculate the length of a string3 *4 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5 * See https://llvm.org/LICENSE.txt for license information.6 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7 */8 9#if __ARM_ARCH >= 6 && __ARM_ARCH_ISA_THUMB == 210 11/*12 Assumes:13 ARMv6T2, AArch3214 15 */16 17#include "../asmdefs.h"18 19#ifdef __ARMEB__20#define S2LO lsl21#define S2HI lsr22#else23#define S2LO lsr24#define S2HI lsl25#endif26 27 /* This code requires Thumb. */28 .thumb29 .syntax unified30 31/* Parameters and result. */32#define srcin r033#define result r034 35/* Internal variables. */36#define src r137#define data1a r238#define data1b r339#define const_m1 r1240#define const_0 r441#define tmp1 r4 /* Overlaps const_0 */42#define tmp2 r543 44ENTRY (__strlen_armv6t2)45 pld [srcin, #0]46 strd r4, r5, [sp, #-8]!47 bic src, srcin, #748 mvn const_m1, #049 ands tmp1, srcin, #7 /* (8 - bytes) to alignment. */50 pld [src, #32]51 bne.w L(misaligned8)52 mov const_0, #053 mov result, #-854L(loop_aligned):55 /* Bytes 0-7. */56 ldrd data1a, data1b, [src]57 pld [src, #64]58 add result, result, #859L(start_realigned):60 uadd8 data1a, data1a, const_m1 /* Saturating GE<0:3> set. */61 sel data1a, const_0, const_m1 /* Select based on GE<0:3>. */62 uadd8 data1b, data1b, const_m163 sel data1b, data1a, const_m1 /* Only used if d1a == 0. */64 cbnz data1b, L(null_found)65 66 /* Bytes 8-15. */67 ldrd data1a, data1b, [src, #8]68 uadd8 data1a, data1a, const_m1 /* Saturating GE<0:3> set. */69 add result, result, #870 sel data1a, const_0, const_m1 /* Select based on GE<0:3>. */71 uadd8 data1b, data1b, const_m172 sel data1b, data1a, const_m1 /* Only used if d1a == 0. */73 cbnz data1b, L(null_found)74 75 /* Bytes 16-23. */76 ldrd data1a, data1b, [src, #16]77 uadd8 data1a, data1a, const_m1 /* Saturating GE<0:3> set. */78 add result, result, #879 sel data1a, const_0, const_m1 /* Select based on GE<0:3>. */80 uadd8 data1b, data1b, const_m181 sel data1b, data1a, const_m1 /* Only used if d1a == 0. */82 cbnz data1b, L(null_found)83 84 /* Bytes 24-31. */85 ldrd data1a, data1b, [src, #24]86 add src, src, #3287 uadd8 data1a, data1a, const_m1 /* Saturating GE<0:3> set. */88 add result, result, #889 sel data1a, const_0, const_m1 /* Select based on GE<0:3>. */90 uadd8 data1b, data1b, const_m191 sel data1b, data1a, const_m1 /* Only used if d1a == 0. */92 cmp data1b, #093 beq L(loop_aligned)94 95L(null_found):96 cmp data1a, #097 itt eq98 addeq result, result, #499 moveq data1a, data1b100#ifndef __ARMEB__101 rev data1a, data1a102#endif103 clz data1a, data1a104 ldrd r4, r5, [sp], #8105 add result, result, data1a, lsr #3 /* Bits -> Bytes. */106 bx lr107 108L(misaligned8):109 ldrd data1a, data1b, [src]110 and tmp2, tmp1, #3111 rsb result, tmp1, #0112 lsl tmp2, tmp2, #3 /* Bytes -> bits. */113 tst tmp1, #4114 pld [src, #64]115 S2HI tmp2, const_m1, tmp2116 orn data1a, data1a, tmp2117 itt ne118 ornne data1b, data1b, tmp2119 movne data1a, const_m1120 mov const_0, #0121 b L(start_realigned)122 123END (__strlen_armv6t2)124 125#endif /* __ARM_ARCH >= 6 && __ARM_ARCH_ISA_THUMB == 2 */126