1 /* SPDX-License-Identifier: GPL-2.0-only */ !! 1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* !! 2 /* strlen.S: Sparc optimized strlen code 3 * Copyright (C) 2004, 2007-2010, 2011-2012 Sy !! 3 * Hand optimized from GNU libc's strlen >> 4 * Copyright (C) 1991,1996 Free Software Foundation >> 5 * Copyright (C) 1996,2008 David S. Miller (davem@davemloft.net) >> 6 * Copyright (C) 1996, 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) 4 */ 7 */ 5 8 6 #include <linux/linkage.h> 9 #include <linux/linkage.h> >> 10 #include <asm/asm.h> >> 11 #include <asm/export.h> 7 12 8 ENTRY_CFI(strlen) !! 13 #define LO_MAGIC 0x01010101 9 or r3,r0,7 !! 14 #define HI_MAGIC 0x80808080 10 ld r2,[r3,-7] << 11 ld.a r6,[r3,-3] << 12 mov r4,0x01010101 << 13 ; uses long immediate << 14 #ifdef __LITTLE_ENDIAN__ << 15 asl_s r1,r0,3 << 16 btst_s r0,2 << 17 asl r7,r4,r1 << 18 ror r5,r4 << 19 sub r1,r2,r7 << 20 bic_s r1,r1,r2 << 21 mov.eq r7,r4 << 22 sub r12,r6,r7 << 23 bic r12,r12,r6 << 24 or.eq r12,r12,r1 << 25 and r12,r12,r5 << 26 brne r12,0,.Learly_end << 27 #else /* BIG ENDIAN */ << 28 ror r5,r4 << 29 btst_s r0,2 << 30 mov_s r1,31 << 31 sub3 r7,r1,r0 << 32 sub r1,r2,r4 << 33 bic_s r1,r1,r2 << 34 bmsk r1,r1,r7 << 35 sub r12,r6,r4 << 36 bic r12,r12,r6 << 37 bmsk.ne r12,r12,r7 << 38 or.eq r12,r12,r1 << 39 and r12,r12,r5 << 40 brne r12,0,.Learly_end << 41 #endif /* ENDIAN */ << 42 15 43 .Loop: !! 16 .text 44 ld_s r2,[r3,4] !! 17 ENTRY(strlen) 45 ld.a r6,[r3,8] !! 18 mov %o0, %o1 46 ; stall for load result !! 19 andcc %o0, 3, %g0 47 sub r1,r2,r4 !! 20 BRANCH32(be, pt, 9f) 48 bic_s r1,r1,r2 !! 21 sethi %hi(HI_MAGIC), %o4 49 sub r12,r6,r4 !! 22 ldub [%o0], %o5 50 bic r12,r12,r6 !! 23 BRANCH_REG_ZERO(pn, %o5, 11f) 51 or r12,r12,r1 !! 24 add %o0, 1, %o0 52 and r12,r12,r5 !! 25 andcc %o0, 3, %g0 53 breq r12,0,.Loop !! 26 BRANCH32(be, pn, 4f) 54 .Lend: !! 27 or %o4, %lo(HI_MAGIC), %o3 55 and.f r1,r1,r5 !! 28 ldub [%o0], %o5 56 sub.ne r3,r3,4 !! 29 BRANCH_REG_ZERO(pn, %o5, 12f) 57 mov.eq r1,r12 !! 30 add %o0, 1, %o0 58 #ifdef __LITTLE_ENDIAN__ !! 31 andcc %o0, 3, %g0 59 sub_s r2,r1,1 !! 32 BRANCH32(be, pt, 5f) 60 bic_s r2,r2,r1 !! 33 sethi %hi(LO_MAGIC), %o4 61 norm r1,r2 !! 34 ldub [%o0], %o5 62 sub_s r0,r0,3 !! 35 BRANCH_REG_ZERO(pn, %o5, 13f) 63 lsr_s r1,r1,3 !! 36 add %o0, 1, %o0 64 sub r0,r3,r0 !! 37 BRANCH32(ba, pt, 8f) 65 j_s.d [blink] !! 38 or %o4, %lo(LO_MAGIC), %o2 66 sub r0,r0,r1 !! 39 9: 67 #else /* BIG ENDIAN */ !! 40 or %o4, %lo(HI_MAGIC), %o3 68 lsr_s r1,r1,7 !! 41 4: 69 mov.eq r2,r6 !! 42 sethi %hi(LO_MAGIC), %o4 70 bic_s r1,r1,r2 !! 43 5: 71 norm r1,r1 !! 44 or %o4, %lo(LO_MAGIC), %o2 72 sub r0,r3,r0 !! 45 8: 73 lsr_s r1,r1,3 !! 46 ld [%o0], %o5 74 j_s.d [blink] !! 47 2: 75 add r0,r0,r1 !! 48 sub %o5, %o2, %o4 76 #endif /* ENDIAN */ !! 49 andcc %o4, %o3, %g0 77 .Learly_end: !! 50 BRANCH32(be, pt, 8b) 78 b.d .Lend !! 51 add %o0, 4, %o0 79 sub_s.ne r1,r1,r1 !! 52 80 END_CFI(strlen) !! 53 /* Check every byte. */ >> 54 srl %o5, 24, %g7 >> 55 andcc %g7, 0xff, %g0 >> 56 BRANCH32(be, pn, 1f) >> 57 add %o0, -4, %o4 >> 58 srl %o5, 16, %g7 >> 59 andcc %g7, 0xff, %g0 >> 60 BRANCH32(be, pn, 1f) >> 61 add %o4, 1, %o4 >> 62 srl %o5, 8, %g7 >> 63 andcc %g7, 0xff, %g0 >> 64 BRANCH32(be, pn, 1f) >> 65 add %o4, 1, %o4 >> 66 andcc %o5, 0xff, %g0 >> 67 BRANCH32_ANNUL(bne, pt, 2b) >> 68 ld [%o0], %o5 >> 69 add %o4, 1, %o4 >> 70 1: >> 71 retl >> 72 sub %o4, %o1, %o0 >> 73 11: >> 74 retl >> 75 mov 0, %o0 >> 76 12: >> 77 retl >> 78 mov 1, %o0 >> 79 13: >> 80 retl >> 81 mov 2, %o0 >> 82 ENDPROC(strlen) >> 83 EXPORT_SYMBOL(strlen)
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.