linux/arch/avr32/lib/findbit.S
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2006 Atmel Corporation
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License version 2 as
   6 * published by the Free Software Foundation.
   7 */
   8#include <linux/linkage.h>
   9
  10        .text
  11        /*
  12         * unsigned long find_first_zero_bit(const unsigned long *addr,
  13         *                                   unsigned long size)
  14         */
  15ENTRY(find_first_zero_bit)
  16        cp.w    r11, 0
  17        reteq   r11
  18        mov     r9, r11
  191:      ld.w    r8, r12[0]
  20        com     r8
  21        brne    .L_found
  22        sub     r12, -4
  23        sub     r9, 32
  24        brgt    1b
  25        retal   r11
  26
  27        /*
  28         * unsigned long find_next_zero_bit(const unsigned long *addr,
  29         *                                  unsigned long size,
  30         *                                  unsigned long offset)
  31         */
  32ENTRY(find_next_zero_bit)
  33        lsr     r8, r10, 5
  34        sub     r9, r11, r10
  35        retle   r11
  36
  37        lsl     r8, 2
  38        add     r12, r8
  39        andl    r10, 31, COH
  40        breq    1f
  41
  42        /* offset is not word-aligned. Handle the first (32 - r10) bits */
  43        ld.w    r8, r12[0]
  44        com     r8
  45        sub     r12, -4
  46        lsr     r8, r8, r10
  47        brne    .L_found
  48
  49        /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */
  50        add     r9, r10
  51        sub     r9, 32
  52        retle   r11
  53
  54        /* Main loop. offset must be word-aligned */
  551:      ld.w    r8, r12[0]
  56        com     r8
  57        brne    .L_found
  58        sub     r12, -4
  59        sub     r9, 32
  60        brgt    1b
  61        retal   r11
  62
  63        /* Common return path for when a bit is actually found. */
  64.L_found:
  65        brev    r8
  66        clz     r10, r8
  67        rsub    r9, r11
  68        add     r10, r9
  69
  70        /* XXX: If we don't have to return exactly "size" when the bit
  71           is not found, we may drop this "min" thing */
  72        min     r12, r11, r10
  73        retal   r12
  74
  75        /*
  76         * unsigned long find_first_bit(const unsigned long *addr,
  77         *                              unsigned long size)
  78         */
  79ENTRY(find_first_bit)
  80        cp.w    r11, 0
  81        reteq   r11
  82        mov     r9, r11
  831:      ld.w    r8, r12[0]
  84        cp.w    r8, 0
  85        brne    .L_found
  86        sub     r12, -4
  87        sub     r9, 32
  88        brgt    1b
  89        retal   r11
  90
  91        /*
  92         * unsigned long find_next_bit(const unsigned long *addr,
  93         *                             unsigned long size,
  94         *                             unsigned long offset)
  95         */
  96ENTRY(find_next_bit)
  97        lsr     r8, r10, 5
  98        sub     r9, r11, r10
  99        retle   r11
 100
 101        lsl     r8, 2
 102        add     r12, r8
 103        andl    r10, 31, COH
 104        breq    1f
 105
 106        /* offset is not word-aligned. Handle the first (32 - r10) bits */
 107        ld.w    r8, r12[0]
 108        sub     r12, -4
 109        lsr     r8, r8, r10
 110        brne    .L_found
 111
 112        /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */
 113        add     r9, r10
 114        sub     r9, 32
 115        retle   r11
 116
 117        /* Main loop. offset must be word-aligned */
 1181:      ld.w    r8, r12[0]
 119        cp.w    r8, 0
 120        brne    .L_found
 121        sub     r12, -4
 122        sub     r9, 32
 123        brgt    1b
 124        retal   r11
 125
 126ENTRY(find_next_bit_le)
 127        lsr     r8, r10, 5
 128        sub     r9, r11, r10
 129        retle   r11
 130
 131        lsl     r8, 2
 132        add     r12, r8
 133        andl    r10, 31, COH
 134        breq    1f
 135
 136        /* offset is not word-aligned. Handle the first (32 - r10) bits */
 137        ldswp.w r8, r12[0]
 138        sub     r12, -4
 139        lsr     r8, r8, r10
 140        brne    .L_found
 141
 142        /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */
 143        add     r9, r10
 144        sub     r9, 32
 145        retle   r11
 146
 147        /* Main loop. offset must be word-aligned */
 1481:      ldswp.w r8, r12[0]
 149        cp.w    r8, 0
 150        brne    .L_found
 151        sub     r12, -4
 152        sub     r9, 32
 153        brgt    1b
 154        retal   r11
 155
 156ENTRY(find_next_zero_bit_le)
 157        lsr     r8, r10, 5
 158        sub     r9, r11, r10
 159        retle   r11
 160
 161        lsl     r8, 2
 162        add     r12, r8
 163        andl    r10, 31, COH
 164        breq    1f
 165
 166        /* offset is not word-aligned. Handle the first (32 - r10) bits */
 167        ldswp.w r8, r12[0]
 168        sub     r12, -4
 169        com     r8
 170        lsr     r8, r8, r10
 171        brne    .L_found
 172
 173        /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */
 174        add     r9, r10
 175        sub     r9, 32
 176        retle   r11
 177
 178        /* Main loop. offset must be word-aligned */
 1791:      ldswp.w r8, r12[0]
 180        com     r8
 181        brne    .L_found
 182        sub     r12, -4
 183        sub     r9, 32
 184        brgt    1b
 185        retal   r11
 186