.text
.macro find_first, endian, set, name
ENTRY(_find_first_\name\()bit_\endian)
UNWIND( .fnstart)
teq r1,
beq 3f
mov r2,
1: ldr r3, [r0],
.ifeq \set
mvns r3, r3 @ invert/test bits
.else
movs r3, r3 @ test bits
.endif
.ifc \endian, SWAB_ENDIAN
bne .L_found_swab
.else
bne .L_found @ found the bit?
.endif
add r2, r2,
2: cmp r2, r1 @ any more?
blo 1b
3: mov r0, r1 @ no more bits
ret lr
UNWIND( .fnend)
ENDPROC(_find_first_\name\()bit_\endian)
.endm
.macro find_next, endian, set, name
ENTRY(_find_next_\name\()bit_\endian)
UNWIND( .fnstart)
cmp r2, r1
bhs 3b
mov ip, r2, lsr
add r0, r0, ip, lsl
ands ip, r2,
beq 1b
ldr r3, [r0],
.ifeq \set
mvn r3, r3 @ invert bits
.endif
.ifc \endian, SWAB_ENDIAN
rev_l r3, ip
.if .Lrev_l_uses_tmp
@ we need to recompute ip because rev_l will have overwritten
@ it.
and ip, r2,
.endif
.endif
movs r3, r3, lsr ip @ shift off unused bits
bne .L_found
orr r2, r2,
add r2, r2,
b 2b @ loop for next bit
UNWIND( .fnend)
ENDPROC(_find_next_\name\()bit_\endian)
.endm
.macro find_bit, endian, set, name
find_first \endian, \set, \name
find_next \endian, \set, \name
.endm
find_bit le, 0, zero_
find_bit le, 1
find_bit be, 0, zero_
find_bit be, 1
.L_found_swab:
UNWIND( .fnstart)
rev_l r3, ip
.L_found:
rbit r3, r3 @ reverse bits
clz r3, r3 @ count high zero bits
add r0, r2, r3 @ add offset of first set bit
rsb r0, r3,
and r3, r3, r0 @ mask out lowest bit set
clz r3, r3 @ count high zero bits
rsb r3, r3,
add r0, r2, r3 @ add offset of first set bit
mov ip,
tst r3, ip, lsr
addeq r2, r2,
moveq r3, r3, lsr
tst r3,
addeq r2, r2,
moveq r3, r3, lsr
tst r3,
addeq r2, r2,
moveq r3, r3, lsr
tst r3,
addeq r2, r2,
moveq r3, r3, lsr
tst r3,
addeq r2, r2,
mov r0, r2
cmp r1, r0 @ Clamp to maxbit
movlo r0, r1
ret lr
UNWIND( .fnend)