1 /* SPDX-License-Identifier: GPL-2.0 */ 1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* $Id: strlen.S,v 1.2 2001/06/29 14:07:15 gni !! 2 /* >> 3 * strlen.S (c) 1995 David Mosberger (davidm@cs.arizona.edu) 3 * 4 * 4 * "strlen" implementation of SuperH !! 5 * Finds length of a 0-terminated string. Optimized for the 5 * !! 6 * Alpha architecture: 6 * Copyright (C) 1999 Kaz Kojima << 7 * 7 * >> 8 * - memory accessed as aligned quadwords only >> 9 * - uses bcmpge to compare 8 bytes in parallel >> 10 * - does binary search to find 0 byte in last >> 11 * quadword (HAKMEM needed 12 instructions to >> 12 * do this instead of the 9 instructions that >> 13 * binary search needs). 8 */ 14 */ >> 15 #include <asm/export.h> >> 16 .set noreorder >> 17 .set noat >> 18 >> 19 .align 3 >> 20 >> 21 .globl strlen >> 22 .ent strlen >> 23 >> 24 strlen: >> 25 ldq_u $1, 0($16) # load first quadword ($16 may be misaligned) >> 26 lda $2, -1($31) >> 27 insqh $2, $16, $2 >> 28 andnot $16, 7, $0 >> 29 or $2, $1, $1 >> 30 cmpbge $31, $1, $2 # $2 <- bitmask: bit i == 1 <==> i-th byte == 0 >> 31 bne $2, found >> 32 >> 33 loop: ldq $1, 8($0) >> 34 addq $0, 8, $0 # addr += 8 >> 35 nop # helps dual issue last two insns >> 36 cmpbge $31, $1, $2 >> 37 beq $2, loop >> 38 >> 39 found: blbs $2, done # make aligned case fast >> 40 negq $2, $3 >> 41 and $2, $3, $2 >> 42 >> 43 and $2, 0x0f, $1 >> 44 addq $0, 4, $3 >> 45 cmoveq $1, $3, $0 >> 46 >> 47 and $2, 0x33, $1 >> 48 addq $0, 2, $3 >> 49 cmoveq $1, $3, $0 >> 50 >> 51 and $2, 0x55, $1 >> 52 addq $0, 1, $3 >> 53 cmoveq $1, $3, $0 9 54 10 /* size_t strlen (const char *s) */ !! 55 done: subq $0, $16, $0 >> 56 ret $31, ($26) 11 57 12 #include <linux/linkage.h> !! 58 .end strlen 13 ENTRY(strlen) !! 59 EXPORT_SYMBOL(strlen) 14 mov r4,r0 << 15 and #3,r0 << 16 tst r0,r0 << 17 bt/s 1f << 18 mov #0,r2 << 19 << 20 add #-1,r0 << 21 shll2 r0 << 22 shll r0 << 23 braf r0 << 24 nop << 25 << 26 mov.b @r4+,r1 << 27 tst r1,r1 << 28 bt 8f << 29 add #1,r2 << 30 << 31 mov.b @r4+,r1 << 32 tst r1,r1 << 33 bt 8f << 34 add #1,r2 << 35 << 36 mov.b @r4+,r1 << 37 tst r1,r1 << 38 bt 8f << 39 add #1,r2 << 40 << 41 1: << 42 mov #0,r3 << 43 2: << 44 mov.l @r4+,r1 << 45 cmp/str r3,r1 << 46 bf/s 2b << 47 add #4,r2 << 48 << 49 add #-4,r2 << 50 #ifndef __LITTLE_ENDIAN__ << 51 swap.b r1,r1 << 52 swap.w r1,r1 << 53 swap.b r1,r1 << 54 #endif << 55 extu.b r1,r0 << 56 tst r0,r0 << 57 bt/s 8f << 58 shlr8 r1 << 59 add #1,r2 << 60 extu.b r1,r0 << 61 tst r0,r0 << 62 bt/s 8f << 63 shlr8 r1 << 64 add #1,r2 << 65 extu.b r1,r0 << 66 tst r0,r0 << 67 bt 8f << 68 add #1,r2 << 69 8: << 70 rts << 71 mov r2,r0 <<
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.