[PATCH 1/6] Split x86_64 out of main Linux kernel-features.h.
[glibc.git] / sysdeps / alpha / ffs.S
blob8d762efb36197a3382c76600f3c48a2ff639005a
1 /* Copyright (C) 1996-2014 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, see
17    <http://www.gnu.org/licenses/>.  */
19 /* Finds the first bit set in an integer.  Optimized for the Alpha
20    architecture.  */
22 #include <sysdep.h>
24         .set noreorder
25         .set noat
28 ENTRY(__ffs)
29 #ifdef PROF
30         ldgp    gp, 0(pv)
31         lda     AT, _mcount
32         jsr     AT, (AT), _mcount
33         .prologue 1
34         zap     $16, 0xF0, $16
35         br      $ffsl..ng
36 #else
37         .prologue 0
38         zap     $16, 0xF0, $16
39         # FALLTHRU
40 #endif
41 END(__ffs)
43         .align 4
44 ENTRY(ffsl)
45 #ifdef PROF
46         ldgp    gp, 0(pv)
47         lda     AT, _mcount
48         jsr     AT, (AT), _mcount
49         .prologue 1
50 $ffsl..ng:
51 #else
52         .prologue 0
53 #endif
54         not     $16, $1         # e0    :
55         ldi     $2, -1          # .. e1 :
56         cmpbge  $1, $2, $3      # e0    : bit N == 1 for byte N == 0
57         clr     $0              # .. e1 :
58         addq    $3, 1, $4       # e0    :
59         bic     $4, $3, $3      # e1    : bit N == 1 for first byte N != 0
60         and     $3, 0xF0, $4    # e0    :
61         and     $3, 0xCC, $5    # .. e1 :
62         and     $3, 0xAA, $6    # e0    :
63         cmovne  $4, 4, $0       # .. e1 :
64         cmovne  $5, 2, $5       # e0    :
65         cmovne  $6, 1, $6       # .. e1 :
66         addl    $0, $5, $0      # e0    :
67         addl    $0, $6, $0      # e1    : $0 == N
68         extbl   $16, $0, $1     # e0    : $1 == byte N
69         ldi     $2, 1           # .. e1 :
70         negq    $1, $3          # e0    :
71         and     $3, $1, $3      # e1    : bit N == least bit set of byte N
72         and     $3, 0xF0, $4    # e0    :
73         and     $3, 0xCC, $5    # .. e1 :
74         and     $3, 0xAA, $6    # e0    :
75         cmovne  $4, 5, $2       # .. e1 :
76         cmovne  $5, 2, $5       # e0    :
77         cmovne  $6, 1, $6       # .. e1 :
78         s8addl  $0, $2, $0      # e0    : mult byte ofs by 8 and sum
79         addl    $5, $6, $5      # .. e1 :
80         addl    $0, $5, $0      # e0    :
81         nop                     # .. e1 :
82         cmoveq  $16, 0, $0      # e0    : trap input == 0 case.
83         ret                     # .. e1 : 18
85 END(ffsl)
87 weak_alias (__ffs, ffs)
88 libc_hidden_def (__ffs)
89 libc_hidden_builtin_def (ffs)
90 weak_extern (ffsl)
91 weak_alias (ffsl, ffsll)