File: an-fls.h

package info (click to toggle)
astrometry.net 0.76%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 18,120 kB
  • sloc: ansic: 161,636; python: 19,915; makefile: 1,439; awk: 159; cpp: 78; pascal: 67; sh: 61; perl: 9
file content (141 lines) | stat: -rw-r--r-- 2,528 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/**
 This file includes code copied from three source files in the Linux kernel
 v 2.6.23.1:
 - include/asm-generic/bitops/fls.h
 - include/asm-i386/bitops.h
 - include/asm-x86_64/bitops.h

 The second and third files contain this notice:
 * Copyright 1992, Linus Torvalds.

 And of course the kernel is distributed under the terms of the GPL v2.
 */

#ifndef AN_FLS_H
#define AN_FLS_H

#include <stdint.h>
#include <assert.h>

/**
 * fls - find last (most-significant) bit set
 *
 * @x: the word to search
 *
 * This is defined the same way as ffs.
 *
 * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
 */
static inline int an_fls(int x);

/**
 * flsB()  =  fls() - 1.
 *
 * Note that x MUST be > 0.
 */
static inline uint8_t an_flsB(uint32_t x);



/**** Below this line are the implementations for different CPUs. ****/

#if AN_I386

static inline int an_fls(int x) {
    int r;
    __asm__("bsrl %1,%0\n\t"
            "jnz 1f\n\t"
            "movl $-1,%0\n"
            "1:" : "=r" (r) : "rm" (x));
    return r+1;
} 

static inline uint8_t an_flsB(uint32_t x) {
    int r;
    assert(x);
    __asm__("bsrl %1,%0\n\t"
            "jnz 1f\n\t"
            "movl $-1,%0\n"
            "1:" : "=r" (r) : "rm" (x));
    return r;
} 

#elif AN_X86_64

static __inline__ int an_fls(int x) {
    int r;
    __asm__("bsrl %1,%0\n\t"
            "cmovzl %2,%0"
            : "=&r" (r) : "rm" (x), "rm" (-1));
    return r+1;
} 

static inline uint8_t an_flsB(uint32_t x) {
    int r;
    assert(x);
    __asm__("bsrl %1,%0\n\t"
            "cmovzl %2,%0"
            : "=&r" (r) : "rm" (x), "rm" (-1));
    return r;
}

#else

static inline int an_fls(int x) {
    int r = 32;
    if (!x)
        return 0;
    if (!(x & 0xffff0000u)) {
        x <<= 16;
        r -= 16;
    }
    if (!(x & 0xff000000u)) {
        x <<= 8;
        r -= 8;
    }
    if (!(x & 0xf0000000u)) {
        x <<= 4;
        r -= 4;
    }
    if (!(x & 0xc0000000u)) {
        x <<= 2;
        r -= 2;
    }
    if (!(x & 0x80000000u)) {
        x <<= 1;
        r -= 1;
    }
    return r;
}

static inline uint8_t an_flsB(uint32_t x) {
    int r = 31;
    assert(x);
    if (!(x & 0xffff0000u)) {
        x <<= 16;
        r -= 16;
    }
    if (!(x & 0xff000000u)) {
        x <<= 8;
        r -= 8;
    }
    if (!(x & 0xf0000000u)) {
        x <<= 4;
        r -= 4;
    }
    if (!(x & 0xc0000000u)) {
        x <<= 2;
        r -= 2;
    }
    if (!(x & 0x80000000u)) {
        x <<= 1;
        r -= 1;
    }
    return r;
}

#endif

#endif