| /* | |
| * 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 |