2006-02-09 Joseph S. Myers <joseph@codesourcery.com>
[glibc-ports.git] / sysdeps / alpha / ffs.S
blob5f2074ee7c427b9d2796aba7bc1be1782bc943a0
1 /* Copyright (C) 1996, 1997, 1998, 2004 Free Software Foundation, Inc.
2    Contributed by David Mosberger (davidm@cs.arizona.edu).
3    This file is part of the GNU C Library.
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
20 /* Finds the first bit set in an integer.  Optimized for the Alpha
21    architecture.  */
23 #include <sysdep.h>
25         .set noreorder
26         .set noat
29 ENTRY(__ffs)
30 #ifdef PROF
31         ldgp    gp, 0(pv)
32         lda     AT, _mcount
33         jsr     AT, (AT), _mcount
34         .prologue 1
35         zap     $16, 0xF0, $16
36         br      $ffsl..ng
37 #else
38         .prologue 0
39         zap     $16, 0xF0, $16
40         # FALLTHRU
41 #endif
42 END(__ffs)
44         .align 4
45 ENTRY(ffsl)
46 #ifdef PROF
47         ldgp    gp, 0(pv)
48         lda     AT, _mcount
49         jsr     AT, (AT), _mcount
50         .prologue 1
51 $ffsl..ng:
52 #else
53         .prologue 0
54 #endif
55         not     $16, $1         # e0    :
56         ldi     $2, -1          # .. e1 :
57         cmpbge  $1, $2, $3      # e0    : bit N == 1 for byte N == 0
58         clr     $0              # .. e1 :
59         addq    $3, 1, $4       # e0    :
60         bic     $4, $3, $3      # e1    : bit N == 1 for first byte N != 0
61         and     $3, 0xF0, $4    # e0    :
62         and     $3, 0xCC, $5    # .. e1 :
63         and     $3, 0xAA, $6    # e0    :
64         cmovne  $4, 4, $0       # .. e1 :
65         cmovne  $5, 2, $5       # e0    :
66         cmovne  $6, 1, $6       # .. e1 :
67         addl    $0, $5, $0      # e0    :
68         addl    $0, $6, $0      # e1    : $0 == N
69         extbl   $16, $0, $1     # e0    : $1 == byte N
70         ldi     $2, 1           # .. e1 :
71         negq    $1, $3          # e0    :
72         and     $3, $1, $3      # e1    : bit N == least bit set of byte N
73         and     $3, 0xF0, $4    # e0    :
74         and     $3, 0xCC, $5    # .. e1 :
75         and     $3, 0xAA, $6    # e0    :
76         cmovne  $4, 5, $2       # .. e1 :
77         cmovne  $5, 2, $5       # e0    :
78         cmovne  $6, 1, $6       # .. e1 :
79         s8addl  $0, $2, $0      # e0    : mult byte ofs by 8 and sum
80         addl    $5, $6, $5      # .. e1 :
81         addl    $0, $5, $0      # e0    :
82         nop                     # .. e1 :
83         cmoveq  $16, 0, $0      # e0    : trap input == 0 case.
84         ret                     # .. e1 : 18
86 END(ffsl)
88 weak_alias (__ffs, ffs)
89 libc_hidden_builtin_def (ffs)
90 weak_extern (ffsl)
91 weak_alias (ffsl, ffsll)