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 32/* 33 Assumes: 34 ARMv6T2, AArch32 35 36 */ 37 38 .macro def_fn f p2align=0 39 .text 40 .p2align \p2align 41 .global \f 42 .type \f, %function 43\f: 44 .endm 45 46#ifdef __ARMEB__ 47#define S2LO lsl 48#define S2HI lsr 49#else 50#define S2LO lsr 51#define S2HI lsl 52#endif 53 54 /* This code requires Thumb. */ 55 .thumb 56 .syntax unified 57 58/* Parameters and result. */ 59#define srcin r0 60#define result r0 61 62/* Internal variables. */ 63#define src r1 64#define data1a r2 65#define data1b r3 66#define const_m1 r12 67#define const_0 r4 68#define tmp1 r4 /* Overlaps const_0 */ 69#define tmp2 r5 70 71def_fn strlen p2align=6 72 pld [srcin, #0] 73 strd r4, r5, [sp, #-8]! 74 bic src, srcin, #7 75 mvn const_m1, #0 76 ands tmp1, srcin, #7 /* (8 - bytes) to alignment. */ 77 pld [src, #32] 78 bne.w .Lmisaligned8 79 mov const_0, #0 80 mov result, #-8 81.Lloop_aligned: 82 /* Bytes 0-7. */ 83 ldrd data1a, data1b, [src] 84 pld [src, #64] 85 add result, result, #8 86.Lstart_realigned: 87 uadd8 data1a, data1a, const_m1 /* Saturating GE<0:3> set. */ 88 sel data1a, const_0, const_m1 /* Select based on GE<0:3>. */ 89 uadd8 data1b, data1b, const_m1 90 sel data1b, data1a, const_m1 /* Only used if d1a == 0. */ 91 cbnz data1b, .Lnull_found 92 93 /* Bytes 8-15. */ 94 ldrd data1a, data1b, [src, #8] 95 uadd8 data1a, data1a, const_m1 /* Saturating GE<0:3> set. */ 96 add result, result, #8 97 sel data1a, const_0, const_m1 /* Select based on GE<0:3>. */ 98 uadd8 data1b, data1b, const_m1 99 sel data1b, data1a, const_m1 /* Only used if d1a == 0. */ 100 cbnz data1b, .Lnull_found 101 102 /* Bytes 16-23. */ 103 ldrd data1a, data1b, [src, #16] 104 uadd8 data1a, data1a, const_m1 /* Saturating GE<0:3> set. */ 105 add result, result, #8 106 sel data1a, const_0, const_m1 /* Select based on GE<0:3>. */ 107 uadd8 data1b, data1b, const_m1 108 sel data1b, data1a, const_m1 /* Only used if d1a == 0. */ 109 cbnz data1b, .Lnull_found 110 111 /* Bytes 24-31. */ 112 ldrd data1a, data1b, [src, #24] 113 add src, src, #32 114 uadd8 data1a, data1a, const_m1 /* Saturating GE<0:3> set. */ 115 add result, result, #8 116 sel data1a, const_0, const_m1 /* Select based on GE<0:3>. */ 117 uadd8 data1b, data1b, const_m1 118 sel data1b, data1a, const_m1 /* Only used if d1a == 0. */ 119 cmp data1b, #0 120 beq .Lloop_aligned 121 122.Lnull_found: 123 cmp data1a, #0 124 itt eq 125 addeq result, result, #4 126 moveq data1a, data1b 127#ifndef __ARMEB__ 128 rev data1a, data1a 129#endif 130 clz data1a, data1a 131 ldrd r4, r5, [sp], #8 132 add result, result, data1a, lsr #3 /* Bits -> Bytes. */ 133 bx lr 134 135.Lmisaligned8: 136 ldrd data1a, data1b, [src] 137 and tmp2, tmp1, #3 138 rsb result, tmp1, #0 139 lsl tmp2, tmp2, #3 /* Bytes -> bits. */ 140 tst tmp1, #4 141 pld [src, #64] 142 S2HI tmp2, const_m1, tmp2 143 orn data1a, data1a, tmp2 144 itt ne 145 ornne data1b, data1b, tmp2 146 movne data1a, const_m1 147 mov const_0, #0 148 b .Lstart_realigned 149 .size strlen, . - strlen 150 151