1/* Copyright (c) 2010-2011,2013 Linaro Limited 2 All rights reserved. 3 4 Redistribution and use in source and binary forms, with or without 5 modification, are permitted provided that the following conditions 6 are met: 7 8 * Redistributions of source code must retain the above copyright 9 notice, this list of conditions and the following disclaimer. 10 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. 14 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. 18 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. 30 31 Assumes: 32 ARMv6T2 or ARMv7E-M, AArch32 33 */ 34 35/* Copyright (c) 2015 ARM Ltd. 36 All rights reserved. 37 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. 48 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. */ 60 61#include "arm_asm.h" 62 63 .macro def_fn f p2align=0 64 .text 65 .p2align \p2align 66 .global \f 67 .type \f, %function 68\f: 69 .endm 70 71#ifdef __ARMEB__ 72#define S2LO lsl 73#define S2HI lsr 74#else 75#define S2LO lsr 76#define S2HI lsl 77#endif 78 79 /* This code requires Thumb. */ 80#if __ARM_ARCH_PROFILE == 'M' 81#if __ARM_ARCH >= 8 82 /* keep config inherited from -march=. */ 83#else 84 .arch armv7e-m 85#endif /* if __ARM_ARCH >= 8 */ 86#else 87 .arch armv6t2 88#endif 89 .eabi_attribute Tag_ARM_ISA_use, 0 90 .thumb 91 .syntax unified 92 93/* Parameters and result. */ 94#define srcin r0 95#define result r0 96 97/* Internal variables. */ 98#define src r1 99#define data1a r2 100#define data1b r3 101#define const_m1 r12 102#define const_0 r4 103#define tmp1 r4 /* Overlaps const_0 */ 104#define tmp2 r5 105 106def_fn strlen p2align=6 107 .fnstart 108 .cfi_startproc 109 prologue 4 5 push_ip=HAVE_PAC_LEAF 110 pld [srcin, #0] 111 bic src, srcin, #7 112 mvn const_m1, #0 113 ands tmp1, srcin, #7 /* (8 - bytes) to alignment. */ 114 pld [src, #32] 115 bne.w .Lmisaligned8 116 mov const_0, #0 117 mov result, #-8 118.Lloop_aligned: 119 /* Bytes 0-7. */ 120 ldrd data1a, data1b, [src] 121 pld [src, #64] 122 add result, result, #8 123.Lstart_realigned: 124 uadd8 data1a, data1a, const_m1 /* Saturating GE<0:3> set. */ 125 sel data1a, const_0, const_m1 /* Select based on GE<0:3>. */ 126 uadd8 data1b, data1b, const_m1 127 sel data1b, data1a, const_m1 /* Only used if d1a == 0. */ 128 cbnz data1b, .Lnull_found 129 130 /* Bytes 8-15. */ 131 ldrd data1a, data1b, [src, #8] 132 uadd8 data1a, data1a, const_m1 /* Saturating GE<0:3> set. */ 133 add result, result, #8 134 sel data1a, const_0, const_m1 /* Select based on GE<0:3>. */ 135 uadd8 data1b, data1b, const_m1 136 sel data1b, data1a, const_m1 /* Only used if d1a == 0. */ 137 cbnz data1b, .Lnull_found 138 139 /* Bytes 16-23. */ 140 ldrd data1a, data1b, [src, #16] 141 uadd8 data1a, data1a, const_m1 /* Saturating GE<0:3> set. */ 142 add result, result, #8 143 sel data1a, const_0, const_m1 /* Select based on GE<0:3>. */ 144 uadd8 data1b, data1b, const_m1 145 sel data1b, data1a, const_m1 /* Only used if d1a == 0. */ 146 cbnz data1b, .Lnull_found 147 148 /* Bytes 24-31. */ 149 ldrd data1a, data1b, [src, #24] 150 add src, src, #32 151 uadd8 data1a, data1a, const_m1 /* Saturating GE<0:3> set. */ 152 add result, result, #8 153 sel data1a, const_0, const_m1 /* Select based on GE<0:3>. */ 154 uadd8 data1b, data1b, const_m1 155 sel data1b, data1a, const_m1 /* Only used if d1a == 0. */ 156 cmp data1b, #0 157 beq .Lloop_aligned 158 159.Lnull_found: 160 .cfi_remember_state 161 cmp data1a, #0 162 itt eq 163 addeq result, result, #4 164 moveq data1a, data1b 165#ifndef __ARMEB__ 166 rev data1a, data1a 167#endif 168 clz data1a, data1a 169 add result, result, data1a, lsr #3 /* Bits -> Bytes. */ 170 epilogue 4 5 push_ip=HAVE_PAC_LEAF 171 172.Lmisaligned8: 173 .cfi_restore_state 174 ldrd data1a, data1b, [src] 175 and tmp2, tmp1, #3 176 rsb result, tmp1, #0 177 lsl tmp2, tmp2, #3 /* Bytes -> bits. */ 178 tst tmp1, #4 179 pld [src, #64] 180 S2HI tmp2, const_m1, tmp2 181 orn data1a, data1a, tmp2 182 itt ne 183 ornne data1b, data1b, tmp2 184 movne data1a, const_m1 185 mov const_0, #0 186 b .Lstart_realigned 187 .cfi_endproc 188 .cantunwind 189 .fnend 190 .size strlen, . - strlen 191 192#if defined(__linux__) && defined(__ELF__) 193.section .note.GNU-stack,"",%progbits 194#endif 195