Cygwin: Add new APIs tc[gs]etwinsize()
[newlib-cygwin.git] / newlib / libc / machine / arm / strlen-armv7.S
blob1c2b5c532bb4a6392159b4284cfe48d318e19b62
1 /* Copyright (c) 2010-2011,2013 Linaro Limited
2    All rights reserved.
4    Redistribution and use in source and binary forms, with or without
5    modification, are permitted provided that the following conditions
6    are met:
8       * Redistributions of source code must retain the above copyright
9       notice, this list of conditions and the following disclaimer.
11       * Redistributions in binary form must reproduce the above copyright
12       notice, this list of conditions and the following disclaimer in the
13       documentation and/or other materials provided with the distribution.
15       * Neither the name of Linaro Limited nor the names of its
16       contributors may be used to endorse or promote products derived
17       from this software without specific prior written permission.
19    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23    HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31    Assumes:
32    ARMv6T2 or ARMv7E-M, AArch32
33  */
35 /* Copyright (c) 2015 ARM Ltd.
36    All rights reserved.
38    Redistribution and use in source and binary forms, with or without
39    modification, are permitted provided that the following conditions are met:
40        * Redistributions of source code must retain the above copyright
41          notice, this list of conditions and the following disclaimer.
42        * Redistributions in binary form must reproduce the above copyright
43          notice, this list of conditions and the following disclaimer in the
44          documentation and/or other materials provided with the distribution.
45        * Neither the name of the Linaro nor the
46          names of its contributors may be used to endorse or promote products
47          derived from this software without specific prior written permission.
49    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
50    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
51    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
52    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
53    HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
54    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
55    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
56    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
57    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
58    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
59    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  */
61 #include "arm-acle-compat.h"
62 #include "arm_asm.h"
64         .macro def_fn f p2align=0
65         .text
66         .p2align \p2align
67         .global \f
68         .type \f, %function
69 \f:
70         .endm
72 #ifdef __ARMEB__
73 #define S2LO            lsl
74 #define S2HI            lsr
75 #else
76 #define S2LO            lsr
77 #define S2HI            lsl
78 #endif
80         /* This code requires Thumb.  */
81 #if __ARM_ARCH_PROFILE == 'M'
82 #if __ARM_ARCH >= 8
83         /* keep config inherited from -march=.  */
84 #else
85         .arch   armv7e-m
86 #endif /* if __ARM_ARCH >= 8 */
87 #else
88         .arch   armv6t2
89 #endif
90         .eabi_attribute Tag_ARM_ISA_use, 0
91         .thumb
92         .syntax unified
94 /* Parameters and result.  */
95 #define srcin           r0
96 #define result          r0
98 /* Internal variables.  */
99 #define src             r1
100 #define data1a          r2
101 #define data1b          r3
102 #define const_m1        r12
103 #define const_0         r4
104 #define tmp1            r4              /* Overlaps const_0  */
105 #define tmp2            r5
107 def_fn  strlen p2align=6
108         .fnstart
109         .cfi_sections .debug_frame
110         .cfi_startproc
111         prologue 4 5 push_ip=HAVE_PAC_LEAF
112         pld     [srcin, #0]
113         bic     src, srcin, #7
114         mvn     const_m1, #0
115         ands    tmp1, srcin, #7         /* (8 - bytes) to alignment.  */
116         pld     [src, #32]
117         bne.w   .Lmisaligned8
118         mov     const_0, #0
119         mov     result, #-8
120 .Lloop_aligned:
121         /* Bytes 0-7.  */
122         ldrd    data1a, data1b, [src]
123         pld     [src, #64]
124         add     result, result, #8
125 .Lstart_realigned:
126         uadd8   data1a, data1a, const_m1        /* Saturating GE<0:3> set.  */
127         sel     data1a, const_0, const_m1       /* Select based on GE<0:3>.  */
128         uadd8   data1b, data1b, const_m1
129         sel     data1b, data1a, const_m1        /* Only used if d1a == 0.  */
130         cbnz    data1b, .Lnull_found
132         /* Bytes 8-15.  */
133         ldrd    data1a, data1b, [src, #8]
134         uadd8   data1a, data1a, const_m1        /* Saturating GE<0:3> set.  */
135         add     result, result, #8
136         sel     data1a, const_0, const_m1       /* Select based on GE<0:3>.  */
137         uadd8   data1b, data1b, const_m1
138         sel     data1b, data1a, const_m1        /* Only used if d1a == 0.  */
139         cbnz    data1b, .Lnull_found
141         /* Bytes 16-23.  */
142         ldrd    data1a, data1b, [src, #16]
143         uadd8   data1a, data1a, const_m1        /* Saturating GE<0:3> set.  */
144         add     result, result, #8
145         sel     data1a, const_0, const_m1       /* Select based on GE<0:3>.  */
146         uadd8   data1b, data1b, const_m1
147         sel     data1b, data1a, const_m1        /* Only used if d1a == 0.  */
148         cbnz    data1b, .Lnull_found
150         /* Bytes 24-31.  */
151         ldrd    data1a, data1b, [src, #24]
152         add     src, src, #32
153         uadd8   data1a, data1a, const_m1        /* Saturating GE<0:3> set.  */
154         add     result, result, #8
155         sel     data1a, const_0, const_m1       /* Select based on GE<0:3>.  */
156         uadd8   data1b, data1b, const_m1
157         sel     data1b, data1a, const_m1        /* Only used if d1a == 0.  */
158         cmp     data1b, #0
159         beq     .Lloop_aligned
161 .Lnull_found:
162         .cfi_remember_state
163         cmp     data1a, #0
164         itt     eq
165         addeq   result, result, #4
166         moveq   data1a, data1b
167 #ifndef __ARMEB__
168         rev     data1a, data1a
169 #endif
170         clz     data1a, data1a
171         add     result, result, data1a, lsr #3  /* Bits -> Bytes.  */
172         epilogue 4 5 push_ip=HAVE_PAC_LEAF
174 .Lmisaligned8:
175         .cfi_restore_state
176         ldrd    data1a, data1b, [src]
177         and     tmp2, tmp1, #3
178         rsb     result, tmp1, #0
179         lsl     tmp2, tmp2, #3                  /* Bytes -> bits.  */
180         tst     tmp1, #4
181         pld     [src, #64]
182         S2HI    tmp2, const_m1, tmp2
183         orn     data1a, data1a, tmp2
184         itt     ne
185         ornne   data1b, data1b, tmp2
186         movne   data1a, const_m1
187         mov     const_0, #0
188         b       .Lstart_realigned
189         .cfi_endproc
190         .cantunwind
191         .fnend
192         .size   strlen, . - strlen