1*09a53ad8SAndrew Turner/* Copyright (c) 2010-2011,2013 Linaro Limited 2*09a53ad8SAndrew Turner All rights reserved. 3*09a53ad8SAndrew Turner 4*09a53ad8SAndrew Turner Redistribution and use in source and binary forms, with or without 5*09a53ad8SAndrew Turner modification, are permitted provided that the following conditions 6*09a53ad8SAndrew Turner are met: 7*09a53ad8SAndrew Turner 8*09a53ad8SAndrew Turner * Redistributions of source code must retain the above copyright 9*09a53ad8SAndrew Turner notice, this list of conditions and the following disclaimer. 10*09a53ad8SAndrew Turner 11*09a53ad8SAndrew Turner * Redistributions in binary form must reproduce the above copyright 12*09a53ad8SAndrew Turner notice, this list of conditions and the following disclaimer in the 13*09a53ad8SAndrew Turner documentation and/or other materials provided with the distribution. 14*09a53ad8SAndrew Turner 15*09a53ad8SAndrew Turner * Neither the name of Linaro Limited nor the names of its 16*09a53ad8SAndrew Turner contributors may be used to endorse or promote products derived 17*09a53ad8SAndrew Turner from this software without specific prior written permission. 18*09a53ad8SAndrew Turner 19*09a53ad8SAndrew Turner THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20*09a53ad8SAndrew Turner "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21*09a53ad8SAndrew Turner LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22*09a53ad8SAndrew Turner A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23*09a53ad8SAndrew Turner HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24*09a53ad8SAndrew Turner SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25*09a53ad8SAndrew Turner LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26*09a53ad8SAndrew Turner DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27*09a53ad8SAndrew Turner THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28*09a53ad8SAndrew Turner (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29*09a53ad8SAndrew Turner OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30*09a53ad8SAndrew Turner */ 31*09a53ad8SAndrew Turner 32*09a53ad8SAndrew Turner/* 33*09a53ad8SAndrew Turner Assumes: 34*09a53ad8SAndrew Turner ARMv6T2, AArch32 35*09a53ad8SAndrew Turner 36*09a53ad8SAndrew Turner */ 37*09a53ad8SAndrew Turner 38*09a53ad8SAndrew Turner .macro def_fn f p2align=0 39*09a53ad8SAndrew Turner .text 40*09a53ad8SAndrew Turner .p2align \p2align 41*09a53ad8SAndrew Turner .global \f 42*09a53ad8SAndrew Turner .type \f, %function 43*09a53ad8SAndrew Turner\f: 44*09a53ad8SAndrew Turner .endm 45*09a53ad8SAndrew Turner 46*09a53ad8SAndrew Turner#ifdef __ARMEB__ 47*09a53ad8SAndrew Turner#define S2LO lsl 48*09a53ad8SAndrew Turner#define S2HI lsr 49*09a53ad8SAndrew Turner#else 50*09a53ad8SAndrew Turner#define S2LO lsr 51*09a53ad8SAndrew Turner#define S2HI lsl 52*09a53ad8SAndrew Turner#endif 53*09a53ad8SAndrew Turner 54*09a53ad8SAndrew Turner /* This code requires Thumb. */ 55*09a53ad8SAndrew Turner .thumb 56*09a53ad8SAndrew Turner .syntax unified 57*09a53ad8SAndrew Turner 58*09a53ad8SAndrew Turner/* Parameters and result. */ 59*09a53ad8SAndrew Turner#define srcin r0 60*09a53ad8SAndrew Turner#define result r0 61*09a53ad8SAndrew Turner 62*09a53ad8SAndrew Turner/* Internal variables. */ 63*09a53ad8SAndrew Turner#define src r1 64*09a53ad8SAndrew Turner#define data1a r2 65*09a53ad8SAndrew Turner#define data1b r3 66*09a53ad8SAndrew Turner#define const_m1 r12 67*09a53ad8SAndrew Turner#define const_0 r4 68*09a53ad8SAndrew Turner#define tmp1 r4 /* Overlaps const_0 */ 69*09a53ad8SAndrew Turner#define tmp2 r5 70*09a53ad8SAndrew Turner 71*09a53ad8SAndrew Turnerdef_fn strlen p2align=6 72*09a53ad8SAndrew Turner pld [srcin, #0] 73*09a53ad8SAndrew Turner strd r4, r5, [sp, #-8]! 74*09a53ad8SAndrew Turner bic src, srcin, #7 75*09a53ad8SAndrew Turner mvn const_m1, #0 76*09a53ad8SAndrew Turner ands tmp1, srcin, #7 /* (8 - bytes) to alignment. */ 77*09a53ad8SAndrew Turner pld [src, #32] 78*09a53ad8SAndrew Turner bne.w .Lmisaligned8 79*09a53ad8SAndrew Turner mov const_0, #0 80*09a53ad8SAndrew Turner mov result, #-8 81*09a53ad8SAndrew Turner.Lloop_aligned: 82*09a53ad8SAndrew Turner /* Bytes 0-7. */ 83*09a53ad8SAndrew Turner ldrd data1a, data1b, [src] 84*09a53ad8SAndrew Turner pld [src, #64] 85*09a53ad8SAndrew Turner add result, result, #8 86*09a53ad8SAndrew Turner.Lstart_realigned: 87*09a53ad8SAndrew Turner uadd8 data1a, data1a, const_m1 /* Saturating GE<0:3> set. */ 88*09a53ad8SAndrew Turner sel data1a, const_0, const_m1 /* Select based on GE<0:3>. */ 89*09a53ad8SAndrew Turner uadd8 data1b, data1b, const_m1 90*09a53ad8SAndrew Turner sel data1b, data1a, const_m1 /* Only used if d1a == 0. */ 91*09a53ad8SAndrew Turner cbnz data1b, .Lnull_found 92*09a53ad8SAndrew Turner 93*09a53ad8SAndrew Turner /* Bytes 8-15. */ 94*09a53ad8SAndrew Turner ldrd data1a, data1b, [src, #8] 95*09a53ad8SAndrew Turner uadd8 data1a, data1a, const_m1 /* Saturating GE<0:3> set. */ 96*09a53ad8SAndrew Turner add result, result, #8 97*09a53ad8SAndrew Turner sel data1a, const_0, const_m1 /* Select based on GE<0:3>. */ 98*09a53ad8SAndrew Turner uadd8 data1b, data1b, const_m1 99*09a53ad8SAndrew Turner sel data1b, data1a, const_m1 /* Only used if d1a == 0. */ 100*09a53ad8SAndrew Turner cbnz data1b, .Lnull_found 101*09a53ad8SAndrew Turner 102*09a53ad8SAndrew Turner /* Bytes 16-23. */ 103*09a53ad8SAndrew Turner ldrd data1a, data1b, [src, #16] 104*09a53ad8SAndrew Turner uadd8 data1a, data1a, const_m1 /* Saturating GE<0:3> set. */ 105*09a53ad8SAndrew Turner add result, result, #8 106*09a53ad8SAndrew Turner sel data1a, const_0, const_m1 /* Select based on GE<0:3>. */ 107*09a53ad8SAndrew Turner uadd8 data1b, data1b, const_m1 108*09a53ad8SAndrew Turner sel data1b, data1a, const_m1 /* Only used if d1a == 0. */ 109*09a53ad8SAndrew Turner cbnz data1b, .Lnull_found 110*09a53ad8SAndrew Turner 111*09a53ad8SAndrew Turner /* Bytes 24-31. */ 112*09a53ad8SAndrew Turner ldrd data1a, data1b, [src, #24] 113*09a53ad8SAndrew Turner add src, src, #32 114*09a53ad8SAndrew Turner uadd8 data1a, data1a, const_m1 /* Saturating GE<0:3> set. */ 115*09a53ad8SAndrew Turner add result, result, #8 116*09a53ad8SAndrew Turner sel data1a, const_0, const_m1 /* Select based on GE<0:3>. */ 117*09a53ad8SAndrew Turner uadd8 data1b, data1b, const_m1 118*09a53ad8SAndrew Turner sel data1b, data1a, const_m1 /* Only used if d1a == 0. */ 119*09a53ad8SAndrew Turner cmp data1b, #0 120*09a53ad8SAndrew Turner beq .Lloop_aligned 121*09a53ad8SAndrew Turner 122*09a53ad8SAndrew Turner.Lnull_found: 123*09a53ad8SAndrew Turner cmp data1a, #0 124*09a53ad8SAndrew Turner itt eq 125*09a53ad8SAndrew Turner addeq result, result, #4 126*09a53ad8SAndrew Turner moveq data1a, data1b 127*09a53ad8SAndrew Turner#ifndef __ARMEB__ 128*09a53ad8SAndrew Turner rev data1a, data1a 129*09a53ad8SAndrew Turner#endif 130*09a53ad8SAndrew Turner clz data1a, data1a 131*09a53ad8SAndrew Turner ldrd r4, r5, [sp], #8 132*09a53ad8SAndrew Turner add result, result, data1a, lsr #3 /* Bits -> Bytes. */ 133*09a53ad8SAndrew Turner bx lr 134*09a53ad8SAndrew Turner 135*09a53ad8SAndrew Turner.Lmisaligned8: 136*09a53ad8SAndrew Turner ldrd data1a, data1b, [src] 137*09a53ad8SAndrew Turner and tmp2, tmp1, #3 138*09a53ad8SAndrew Turner rsb result, tmp1, #0 139*09a53ad8SAndrew Turner lsl tmp2, tmp2, #3 /* Bytes -> bits. */ 140*09a53ad8SAndrew Turner tst tmp1, #4 141*09a53ad8SAndrew Turner pld [src, #64] 142*09a53ad8SAndrew Turner S2HI tmp2, const_m1, tmp2 143*09a53ad8SAndrew Turner orn data1a, data1a, tmp2 144*09a53ad8SAndrew Turner itt ne 145*09a53ad8SAndrew Turner ornne data1b, data1b, tmp2 146*09a53ad8SAndrew Turner movne data1a, const_m1 147*09a53ad8SAndrew Turner mov const_0, #0 148*09a53ad8SAndrew Turner b .Lstart_realigned 149*09a53ad8SAndrew Turner .size strlen, . - strlen 150*09a53ad8SAndrew Turner 151