1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2005 by Jens Arnold
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
23 .section .icode,"ax",@progbits
27 .type _strlen,@function
29 /* Works out the length of a string
30 * This version is optimized for speed
39 * r0 - current address
40 * r1 - current value (byte/long)
41 * r2 - mask for alignment / zero (for cmp/str)
47 mov r4,r0 /* r0 = start address */
48 tst #3,r0 /* long aligned? */
49 bt .start_l /* yes, jump directly to the longword loop */
51 /* not long aligned: check the first 3 bytes */
52 mov.b @r0+,r1 /* fetch first byte */
53 tst r1,r1 /* byte == 0 ? */
54 bt .hitzero /* yes, string end found */
55 mov.b @r0+,r1 /* fetch second byte */
56 mov #3,r2 /* prepare mask: r2 = 0..00000011b */
57 tst r1,r1 /* byte == 0 ? */
58 bt .hitzero /* yes, string end found */
59 mov.b @r0+,r1 /* fetch third byte */
60 not r2,r2 /* prepare mask: r2 = 1..11111100b */
61 tst r1,r1 /* byte == 0 ? */
62 bt .hitzero /* yes, string end found */
64 /* not yet found, fall through into longword loop */
65 and r2,r0 /* align down to long bound */
67 /* main loop: check longwords */
69 mov #0,r2 /* zero longword for cmp/str */
71 mov.l @r0+,r1 /* fetch long word */
72 cmp/str r1,r2 /* any zero byte within? */
73 bf .loop_l /* no, loop */
74 add #-4,r0 /* set address back to start of this longword */
76 /* the last longword contains the string end: figure out the byte */
77 mov.b @r0+,r1 /* fetch first byte */
78 tst r1,r1 /* byte == 0 ? */
79 bt .hitzero /* yes, string end found */
80 mov.b @r0+,r1 /* fetch second byte */
81 tst r1,r1 /* byte == 0 ? */
82 bt .hitzero /* yes, string end found */
83 mov.b @r0+,r1 /* fetch third byte */
84 tst r1,r1 /* byte == 0 ? */
85 bt .hitzero /* yes, string end found */
86 rts /* must be the fourth byte */
87 sub r4,r0 /* len = string_end - string_start */
90 add #-1,r0 /* undo address increment */
92 sub r4,r0 /* len = string_end - string_start */
95 .size _strlen,.end-_strlen