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