stdlib: Fix stdbit.h with -Wconversion for clang
[glibc.git] / sysdeps / alpha / ffs.S
blob350d9ddd1ed19642563bd46b9a175393287881d3
1 /* Copyright (C) 1996-2024 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library.  If not, see
16    <https://www.gnu.org/licenses/>.  */
18 /* Finds the first bit set in an integer.  Optimized for the Alpha
19    architecture.  */
21 #include <sysdep.h>
23         .set noreorder
24         .set noat
27 ENTRY(__ffs)
28 #ifdef PROF
29         ldgp    gp, 0(pv)
30         lda     AT, _mcount
31         jsr     AT, (AT), _mcount
32         .prologue 1
33         zap     $16, 0xF0, $16
34         br      $ffsl..ng
35 #else
36         .prologue 0
37         zap     $16, 0xF0, $16
38         # FALLTHRU
39 #endif
40 END(__ffs)
42         .align 4
43 ENTRY(ffsl)
44 #ifdef PROF
45         ldgp    gp, 0(pv)
46         lda     AT, _mcount
47         jsr     AT, (AT), _mcount
48         .prologue 1
49 $ffsl..ng:
50 #else
51         .prologue 0
52 #endif
53         not     $16, $1         # e0    :
54         ldi     $2, -1          # .. e1 :
55         cmpbge  $1, $2, $3      # e0    : bit N == 1 for byte N == 0
56         clr     $0              # .. e1 :
57         addq    $3, 1, $4       # e0    :
58         bic     $4, $3, $3      # e1    : bit N == 1 for first byte N != 0
59         and     $3, 0xF0, $4    # e0    :
60         and     $3, 0xCC, $5    # .. e1 :
61         and     $3, 0xAA, $6    # e0    :
62         cmovne  $4, 4, $0       # .. e1 :
63         cmovne  $5, 2, $5       # e0    :
64         cmovne  $6, 1, $6       # .. e1 :
65         addl    $0, $5, $0      # e0    :
66         addl    $0, $6, $0      # e1    : $0 == N
67         extbl   $16, $0, $1     # e0    : $1 == byte N
68         ldi     $2, 1           # .. e1 :
69         negq    $1, $3          # e0    :
70         and     $3, $1, $3      # e1    : bit N == least bit set of byte N
71         and     $3, 0xF0, $4    # e0    :
72         and     $3, 0xCC, $5    # .. e1 :
73         and     $3, 0xAA, $6    # e0    :
74         cmovne  $4, 5, $2       # .. e1 :
75         cmovne  $5, 2, $5       # e0    :
76         cmovne  $6, 1, $6       # .. e1 :
77         s8addl  $0, $2, $0      # e0    : mult byte ofs by 8 and sum
78         addl    $5, $6, $5      # .. e1 :
79         addl    $0, $5, $0      # e0    :
80         nop                     # .. e1 :
81         cmoveq  $16, 0, $0      # e0    : trap input == 0 case.
82         ret                     # .. e1 : 18
84 END(ffsl)
86 weak_alias (__ffs, ffs)
87 libc_hidden_def (__ffs)
88 libc_hidden_builtin_def (ffs)
89 weak_extern (ffsl)
90 weak_alias (ffsl, ffsll)