dbe5f3d8d5fa7ed5cd476a4a150e0abb91e70904
[libcds.git] / cds / compiler / gcc / x86 / bitop.h
1 //$$CDS-header$$
2
3 #ifndef __CDS_COMPILER_GCC_X86_BITOP_H
4 #define __CDS_COMPILER_GCC_X86_BITOP_H
5
6 //@cond none
7 namespace cds {
8     namespace bitop { namespace platform { namespace gcc { namespace x86 {
9         // MSB - return index (1..32) of most significant bit in nArg. If nArg == 0 return 0
10 #        define cds_bitop_msb32_DEFINED
11         static inline int msb32( uint32_t nArg )
12         {
13             int        nRet;
14             __asm__ __volatile__ (
15                 "bsrl        %[nArg], %[nRet]     ;\n\t"
16                 "jnz        1f                    ;\n\t"
17                 "xorl        %[nRet], %[nRet]    ;\n\t"
18                 "subl        $1, %[nRet]         ;\n\t"
19             "1:"
20                 "addl        $1, %[nRet]         ;\n\t"
21                 : [nRet] "=a" (nRet)
22                 : [nArg] "r" (nArg)
23                 : "cc"
24             );
25             return nRet;
26         }
27
28 #        define cds_bitop_msb32nz_DEFINED
29         static inline int msb32nz( uint32_t nArg )
30         {
31             assert( nArg != 0 );
32             int        nRet;
33             __asm__ __volatile__ (
34                 "bsrl        %[nArg], %[nRet]    ;"
35                 : [nRet] "=a" (nRet)
36                 : [nArg] "r" (nArg)
37                 : "cc"
38             );
39             return nRet;
40         }
41
42         // LSB - return index (0..31) of least significant bit in nArg. If nArg == 0 return -1U
43 #        define cds_bitop_lsb32_DEFINED
44         static inline int lsb32( uint32_t nArg )
45         {
46
47             int        nRet;
48             __asm__ __volatile__ (
49                 "bsfl        %[nArg], %[nRet]     ;"
50                 "jnz        1f        ;"
51                 "xorl        %[nRet], %[nRet]    ;"
52                 "subl        $1, %[nRet]         ;"
53                 "1:"
54                 "addl        $1, %[nRet]         ;"
55                 : [nRet] "=a" (nRet)
56                 : [nArg] "r" (nArg)
57                 : "cc"
58                 );
59             return nRet;
60
61         }
62
63         // LSB - return index (0..31) of least significant bit in nArg.
64         // Condition: nArg != 0
65 #        define cds_bitop_lsb32nz_DEFINED
66         static inline int lsb32nz( uint32_t nArg )
67         {
68             assert( nArg != 0 );
69             int        nRet;
70             __asm__ __volatile__ (
71                 "bsfl        %[nArg], %[nRet]    ;"
72                 : [nRet] "=a" (nRet)
73                 : [nArg] "r" (nArg)
74                 : "cc"
75                 );
76             return nRet;
77         }
78
79     }} // namespace gcc::x86
80
81     using namespace gcc::x86;
82
83 }}}    // namespace cds::bitop::platform
84 //@endcond
85
86 #endif    // #ifndef __CDS_ARH_X86_GCC_BITOP_H