[LLD][COFF] Emit tail merge pdata for delay load thunks on ARM64EC (#116810)
[llvm-project.git] / libc / AOR_v20.02 / string / arm / strlen-armv6t2.S
blobe368e62336140b0929f0b652c020e0ba5d7a6a8d
1 /*
2  * strlen - calculate the length of a string
3  *
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-exception
7  */
9 #if __ARM_ARCH >= 6 && __ARM_ARCH_ISA_THUMB == 2
12    Assumes:
13    ARMv6T2, AArch32
15  */
17 #include "../asmdefs.h"
19 #ifdef __ARMEB__
20 #define S2LO            lsl
21 #define S2HI            lsr
22 #else
23 #define S2LO            lsr
24 #define S2HI            lsl
25 #endif
27         /* This code requires Thumb.  */
28         .thumb
29         .syntax unified
31 /* Parameters and result.  */
32 #define srcin           r0
33 #define result          r0
35 /* Internal variables.  */
36 #define src             r1
37 #define data1a          r2
38 #define data1b          r3
39 #define const_m1        r12
40 #define const_0         r4
41 #define tmp1            r4              /* Overlaps const_0  */
42 #define tmp2            r5
44 ENTRY (__strlen_armv6t2)
45         pld     [srcin, #0]
46         strd    r4, r5, [sp, #-8]!
47         bic     src, srcin, #7
48         mvn     const_m1, #0
49         ands    tmp1, srcin, #7         /* (8 - bytes) to alignment.  */
50         pld     [src, #32]
51         bne.w   L(misaligned8)
52         mov     const_0, #0
53         mov     result, #-8
54 L(loop_aligned):
55         /* Bytes 0-7.  */
56         ldrd    data1a, data1b, [src]
57         pld     [src, #64]
58         add     result, result, #8
59 L(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_m1
63         sel     data1b, data1a, const_m1        /* Only used if d1a == 0.  */
64         cbnz    data1b, L(null_found)
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, #8
70         sel     data1a, const_0, const_m1       /* Select based on GE<0:3>.  */
71         uadd8   data1b, data1b, const_m1
72         sel     data1b, data1a, const_m1        /* Only used if d1a == 0.  */
73         cbnz    data1b, L(null_found)
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, #8
79         sel     data1a, const_0, const_m1       /* Select based on GE<0:3>.  */
80         uadd8   data1b, data1b, const_m1
81         sel     data1b, data1a, const_m1        /* Only used if d1a == 0.  */
82         cbnz    data1b, L(null_found)
84         /* Bytes 24-31.  */
85         ldrd    data1a, data1b, [src, #24]
86         add     src, src, #32
87         uadd8   data1a, data1a, const_m1        /* Saturating GE<0:3> set.  */
88         add     result, result, #8
89         sel     data1a, const_0, const_m1       /* Select based on GE<0:3>.  */
90         uadd8   data1b, data1b, const_m1
91         sel     data1b, data1a, const_m1        /* Only used if d1a == 0.  */
92         cmp     data1b, #0
93         beq     L(loop_aligned)
95 L(null_found):
96         cmp     data1a, #0
97         itt     eq
98         addeq   result, result, #4
99         moveq   data1a, data1b
100 #ifndef __ARMEB__
101         rev     data1a, data1a
102 #endif
103         clz     data1a, data1a
104         ldrd    r4, r5, [sp], #8
105         add     result, result, data1a, lsr #3  /* Bits -> Bytes.  */
106         bx      lr
108 L(misaligned8):
109         ldrd    data1a, data1b, [src]
110         and     tmp2, tmp1, #3
111         rsb     result, tmp1, #0
112         lsl     tmp2, tmp2, #3                  /* Bytes -> bits.  */
113         tst     tmp1, #4
114         pld     [src, #64]
115         S2HI    tmp2, const_m1, tmp2
116         orn     data1a, data1a, tmp2
117         itt     ne
118         ornne   data1b, data1b, tmp2
119         movne   data1a, const_m1
120         mov     const_0, #0
121         b       L(start_realigned)
123 END (__strlen_armv6t2)
125 #endif /* __ARM_ARCH >= 6 && __ARM_ARCH_ISA_THUMB == 2  */