| /* |
| * Copyright (C) 2006 Atmel Corporation |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License version 2 as |
| * published by the Free Software Foundation. |
| */ |
| #include <linux/linkage.h> |
| |
| .text |
| /* |
| * unsigned long find_first_zero_bit(const unsigned long *addr, |
| * unsigned long size) |
| */ |
| ENTRY(find_first_zero_bit) |
| cp.w r11, 0 |
| reteq r11 |
| mov r9, r11 |
| 1: ld.w r8, r12[0] |
| com r8 |
| brne .L_found |
| sub r12, -4 |
| sub r9, 32 |
| brgt 1b |
| retal r11 |
| |
| /* |
| * unsigned long find_next_zero_bit(const unsigned long *addr, |
| * unsigned long size, |
| * unsigned long offset) |
| */ |
| ENTRY(find_next_zero_bit) |
| lsr r8, r10, 5 |
| sub r9, r11, r10 |
| retle r11 |
| |
| lsl r8, 2 |
| add r12, r8 |
| andl r10, 31, COH |
| breq 1f |
| |
| /* offset is not word-aligned. Handle the first (32 - r10) bits */ |
| ld.w r8, r12[0] |
| com r8 |
| sub r12, -4 |
| lsr r8, r8, r10 |
| brne .L_found |
| |
| /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */ |
| add r9, r10 |
| sub r9, 32 |
| retle r11 |
| |
| /* Main loop. offset must be word-aligned */ |
| 1: ld.w r8, r12[0] |
| com r8 |
| brne .L_found |
| sub r12, -4 |
| sub r9, 32 |
| brgt 1b |
| retal r11 |
| |
| /* Common return path for when a bit is actually found. */ |
| .L_found: |
| brev r8 |
| clz r10, r8 |
| rsub r9, r11 |
| add r10, r9 |
| |
| /* XXX: If we don't have to return exactly "size" when the bit |
| is not found, we may drop this "min" thing */ |
| min r12, r11, r10 |
| retal r12 |
| |
| /* |
| * unsigned long find_first_bit(const unsigned long *addr, |
| * unsigned long size) |
| */ |
| ENTRY(find_first_bit) |
| cp.w r11, 0 |
| reteq r11 |
| mov r9, r11 |
| 1: ld.w r8, r12[0] |
| cp.w r8, 0 |
| brne .L_found |
| sub r12, -4 |
| sub r9, 32 |
| brgt 1b |
| retal r11 |
| |
| /* |
| * unsigned long find_next_bit(const unsigned long *addr, |
| * unsigned long size, |
| * unsigned long offset) |
| */ |
| ENTRY(find_next_bit) |
| lsr r8, r10, 5 |
| sub r9, r11, r10 |
| retle r11 |
| |
| lsl r8, 2 |
| add r12, r8 |
| andl r10, 31, COH |
| breq 1f |
| |
| /* offset is not word-aligned. Handle the first (32 - r10) bits */ |
| ld.w r8, r12[0] |
| sub r12, -4 |
| lsr r8, r8, r10 |
| brne .L_found |
| |
| /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */ |
| add r9, r10 |
| sub r9, 32 |
| retle r11 |
| |
| /* Main loop. offset must be word-aligned */ |
| 1: ld.w r8, r12[0] |
| cp.w r8, 0 |
| brne .L_found |
| sub r12, -4 |
| sub r9, 32 |
| brgt 1b |
| retal r11 |
| |
| ENTRY(find_next_bit_le) |
| lsr r8, r10, 5 |
| sub r9, r11, r10 |
| retle r11 |
| |
| lsl r8, 2 |
| add r12, r8 |
| andl r10, 31, COH |
| breq 1f |
| |
| /* offset is not word-aligned. Handle the first (32 - r10) bits */ |
| ldswp.w r8, r12[0] |
| sub r12, -4 |
| lsr r8, r8, r10 |
| brne .L_found |
| |
| /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */ |
| add r9, r10 |
| sub r9, 32 |
| retle r11 |
| |
| /* Main loop. offset must be word-aligned */ |
| 1: ldswp.w r8, r12[0] |
| cp.w r8, 0 |
| brne .L_found |
| sub r12, -4 |
| sub r9, 32 |
| brgt 1b |
| retal r11 |
| |
| ENTRY(find_next_zero_bit_le) |
| lsr r8, r10, 5 |
| sub r9, r11, r10 |
| retle r11 |
| |
| lsl r8, 2 |
| add r12, r8 |
| andl r10, 31, COH |
| breq 1f |
| |
| /* offset is not word-aligned. Handle the first (32 - r10) bits */ |
| ldswp.w r8, r12[0] |
| sub r12, -4 |
| com r8 |
| lsr r8, r8, r10 |
| brne .L_found |
| |
| /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */ |
| add r9, r10 |
| sub r9, 32 |
| retle r11 |
| |
| /* Main loop. offset must be word-aligned */ |
| 1: ldswp.w r8, r12[0] |
| com r8 |
| brne .L_found |
| sub r12, -4 |
| sub r9, 32 |
| brgt 1b |
| retal r11 |