blob: e7169e25db7397b1589192ebbfb15dda1afd7039 [file] [log] [blame]
Jens Arnold78826de2005-01-22 13:18:33 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 by Jens Arnold
11 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012 * 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.
Jens Arnold78826de2005-01-22 13:18:33 +000016 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "config.h"
22
23 .section .icode,"ax",@progbits
24
25 .align 2
26 .global _strlen
27 .type _strlen,@function
28
29/* Works out the length of a string
30 * This version is optimized for speed
31 *
32 * arguments:
33 * r4 - start address
34 *
35 * return value:
36 * r0 - string length
37 *
38 * register usage:
39 * r0 - current address
40 * r1 - current value (byte/long)
41 * r2 - mask for alignment / zero (for cmp/str)
42 * r4 - start address
43 *
44 */
45
46_strlen:
47 mov r4,r0 /* r0 = start address */
48 tst #3,r0 /* long aligned? */
49 bt .start_l /* yes, jump directly to the longword loop */
50
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 */
63
64 /* not yet found, fall through into longword loop */
65 and r2,r0 /* align down to long bound */
66
67 /* main loop: check longwords */
68.start_l:
69 mov #0,r2 /* zero longword for cmp/str */
70.loop_l:
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 */
75
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 */
88
89.hitzero:
90 add #-1,r0 /* undo address increment */
91 rts
92 sub r4,r0 /* len = string_end - string_start */
93
94.end:
95 .size _strlen,.end-_strlen
96