Thu Jun 13 00:02:25 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
[kopensolaris-gnu/glibc.git] / sysdeps / alpha / strlen.S
1 /* Copyright (C) 1996 Free Software Foundation, Inc.
2    Contributed by David Mosberger (davidm@cs.arizona.edu).
3
4 This file is part of the GNU C Library.
5
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
10
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public
17 License along with the GNU C Library; see the file COPYING.LIB.  If
18 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
19 Cambridge, MA 02139, USA.  */
20
21 /* Finds length of a 0-terminated string.  Optimized for the Alpha
22 architecture:
23
24       - memory accessed as aligned quadwords only
25       - uses bcmpge to compare 8 bytes in parallel
26       - does binary search to find 0 byte in last
27         quadword (HAKMEM needed 12 instructions to
28         do this instead of the 9 instructions that
29         binary search needs).  */
30
31 #include <sysdep.h>
32
33         .set noreorder
34         .set noat
35
36 ENTRY(strlen)
37         ldq_u   t0, 0(a0)       # load first quadword (a0 may be misaligned)
38         lda     t1, -1(zero)
39         insqh   t1, a0, t1
40         andnot  a0, 7, v0
41         or      t1, t0, t0
42         cmpbge  zero, t0, t1    # t1 <- bitmask: bit i == 1 <==> i-th byte == 0
43         bne     t1, found
44
45 loop:   ldq     t0, 8(v0)
46         addq    v0, 8, v0       # addr += 8
47         nop                     # helps dual issue last two insns
48         cmpbge  zero, t0, t1
49         beq     t1, loop
50
51 found:  blbs    t1, done        # make aligned case fast
52         negq    t1, t2
53         and     t1, t2, t1
54
55         and     t1, 0x0f, t0
56         addq    v0, 4, t2
57         cmoveq  t0, t2, v0
58
59         and     t1, 0x33, t0
60         addq    v0, 2, t2
61         cmoveq  t0, t2, v0
62
63         and     t1, 0x55, t0
64         addq    v0, 1, t2
65         cmoveq  t0, t2, v0
66
67 done:   subq    v0, a0, v0
68         ret
69
70         END(strlen)