summaryrefslogtreecommitdiff
path: root/firmware/target/coldfire/ffs-coldfire.S
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/coldfire/ffs-coldfire.S')
-rw-r--r--firmware/target/coldfire/ffs-coldfire.S62
1 files changed, 62 insertions, 0 deletions
diff --git a/firmware/target/coldfire/ffs-coldfire.S b/firmware/target/coldfire/ffs-coldfire.S
new file mode 100644
index 0000000000..4f21013123
--- /dev/null
+++ b/firmware/target/coldfire/ffs-coldfire.S
@@ -0,0 +1,62 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2008 by Michael Sevakis
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19 #include "config.h"
20
21/****************************************************************************
22 * int find_first_set_bit(uint32_t val);
23 *
24 * Find the index of the least significant set bit in the 32-bit word.
25 *
26 * return values:
27 * 0 - bit 0 is set
28 * 1 - bit 1 is set
29 * ...
30 * 31 - bit 31 is set
31 * 32 - no bits set
32 ****************************************************************************/
33 .text
34 .align 2
35 .global find_first_set_bit
36 .type find_first_set_bit,@function
37find_first_set_bit:
38 | this is a coldfire version of the ffs algorithm devised by D.Seal
39 | and posted to comp.sys.arm on 16 Feb 1994.
40 |
41 | Output modified to suit rockbox purposes.
42
43 | Standard trick to isolate bottom bit in r0 or 0 if r0 = 0 on entry
44 move.l 4(%sp), %d1 | %d1 = %d1 & -%d1
45 lea.l L_ffs_table, %a0 | %a0 = table address
46 move.l %d1, %d0 |
47 neg.l %d1 |
48 and.l %d0, %d1 |
49
50 | now %d1 has at most one set bit, call this X
51
52 move.l #0x0450fbaf, %d0 | %d0 = multiplier
53 mulu.l %d0, %d1 | %d1 = X * 0x0450fbaf
54
55 | now lookup in table indexed on top 6 bits of %d0
56 moveq.l #26, %d0 | %d0 = final shift count
57 lsr.l %d0, %d1 |
58 clr.l %d0 |
59 move.b (%a0, %d1.l), %d0 |
60 rts |
61
62 .size find_first_set_bit, .-find_first_set_bit