1259701Sdim/*===---- tbmintrin.h - TBM intrinsics -------------------------------------===
2259701Sdim *
3259701Sdim * Permission is hereby granted, free of charge, to any person obtaining a copy
4259701Sdim * of this software and associated documentation files (the "Software"), to deal
5259701Sdim * in the Software without restriction, including without limitation the rights
6259701Sdim * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7259701Sdim * copies of the Software, and to permit persons to whom the Software is
8259701Sdim * furnished to do so, subject to the following conditions:
9259701Sdim *
10259701Sdim * The above copyright notice and this permission notice shall be included in
11259701Sdim * all copies or substantial portions of the Software.
12259701Sdim *
13259701Sdim * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14259701Sdim * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15259701Sdim * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16259701Sdim * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17259701Sdim * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18259701Sdim * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19259701Sdim * THE SOFTWARE.
20259701Sdim *
21259701Sdim *===-----------------------------------------------------------------------===
22259701Sdim */
23259701Sdim
24259701Sdim#ifndef __TBM__
25259701Sdim#error "TBM instruction set is not enabled"
26259701Sdim#endif
27259701Sdim
28259701Sdim#ifndef __X86INTRIN_H
29259701Sdim#error "Never use <tbmintrin.h> directly; include <x86intrin.h> instead."
30259701Sdim#endif
31259701Sdim
32259701Sdim#ifndef __TBMINTRIN_H
33259701Sdim#define __TBMINTRIN_H
34259701Sdim
35259701Sdim#define __bextri_u32(a, b) (__builtin_ia32_bextri_u32((a), (b)))
36259701Sdim
37259701Sdimstatic __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
38259701Sdim__blcfill_u32(unsigned int a)
39259701Sdim{
40259701Sdim  return a & (a + 1);
41259701Sdim}
42259701Sdim
43259701Sdimstatic __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
44259701Sdim__blci_u32(unsigned int a)
45259701Sdim{
46259701Sdim  return a | ~(a + 1);
47259701Sdim}
48259701Sdim
49259701Sdimstatic __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
50259701Sdim__blcic_u32(unsigned int a)
51259701Sdim{
52259701Sdim  return ~a & (a + 1);
53259701Sdim}
54259701Sdim
55259701Sdimstatic __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
56259701Sdim__blcmsk_u32(unsigned int a)
57259701Sdim{
58259701Sdim  return a ^ (a + 1);
59259701Sdim}
60259701Sdim
61259701Sdimstatic __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
62259701Sdim__blcs_u32(unsigned int a)
63259701Sdim{
64259701Sdim  return a | (a + 1);
65259701Sdim}
66259701Sdim
67259701Sdimstatic __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
68259701Sdim__blsfill_u32(unsigned int a)
69259701Sdim{
70259701Sdim  return a | (a - 1);
71259701Sdim}
72259701Sdim
73259701Sdimstatic __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
74259701Sdim__blsic_u32(unsigned int a)
75259701Sdim{
76259701Sdim  return ~a | (a - 1);
77259701Sdim}
78259701Sdim
79259701Sdimstatic __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
80259701Sdim__t1mskc_u32(unsigned int a)
81259701Sdim{
82259701Sdim  return ~a | (a + 1);
83259701Sdim}
84259701Sdim
85259701Sdimstatic __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
86259701Sdim__tzmsk_u32(unsigned int a)
87259701Sdim{
88259701Sdim  return ~a & (a - 1);
89259701Sdim}
90259701Sdim
91259701Sdim#ifdef __x86_64__
92259701Sdim#define __bextri_u64(a, b) (__builtin_ia32_bextri_u64((a), (int)(b)))
93259701Sdim
94259701Sdimstatic __inline__ unsigned long long __attribute__((__always_inline__,
95259701Sdim                                                    __nodebug__))
96259701Sdim__blcfill_u64(unsigned long long a)
97259701Sdim{
98259701Sdim  return a & (a + 1);
99259701Sdim}
100259701Sdim
101259701Sdimstatic __inline__ unsigned long long __attribute__((__always_inline__,
102259701Sdim                                                    __nodebug__))
103259701Sdim__blci_u64(unsigned long long a)
104259701Sdim{
105259701Sdim  return a | ~(a + 1);
106259701Sdim}
107259701Sdim
108259701Sdimstatic __inline__ unsigned long long __attribute__((__always_inline__,
109259701Sdim                                                    __nodebug__))
110259701Sdim__blcic_u64(unsigned long long a)
111259701Sdim{
112259701Sdim  return ~a & (a + 1);
113259701Sdim}
114259701Sdim
115259701Sdimstatic __inline__ unsigned long long __attribute__((__always_inline__,
116259701Sdim                                                    __nodebug__))
117259701Sdim__blcmsk_u64(unsigned long long a)
118259701Sdim{
119259701Sdim  return a ^ (a + 1);
120259701Sdim}
121259701Sdim
122259701Sdimstatic __inline__ unsigned long long __attribute__((__always_inline__,
123259701Sdim                                                    __nodebug__))
124259701Sdim__blcs_u64(unsigned long long a)
125259701Sdim{
126259701Sdim  return a | (a + 1);
127259701Sdim}
128259701Sdim
129259701Sdimstatic __inline__ unsigned long long __attribute__((__always_inline__,
130259701Sdim                                                    __nodebug__))
131259701Sdim__blsfill_u64(unsigned long long a)
132259701Sdim{
133259701Sdim  return a | (a - 1);
134259701Sdim}
135259701Sdim
136259701Sdimstatic __inline__ unsigned long long __attribute__((__always_inline__,
137259701Sdim                                                    __nodebug__))
138259701Sdim__blsic_u64(unsigned long long a)
139259701Sdim{
140259701Sdim  return ~a | (a - 1);
141259701Sdim}
142259701Sdim
143259701Sdimstatic __inline__ unsigned long long __attribute__((__always_inline__,
144259701Sdim                                                    __nodebug__))
145259701Sdim__t1mskc_u64(unsigned long long a)
146259701Sdim{
147259701Sdim  return ~a | (a + 1);
148259701Sdim}
149259701Sdim
150259701Sdimstatic __inline__ unsigned long long __attribute__((__always_inline__,
151259701Sdim                                                    __nodebug__))
152259701Sdim__tzmsk_u64(unsigned long long a)
153259701Sdim{
154259701Sdim  return ~a & (a - 1);
155259701Sdim}
156259701Sdim#endif
157259701Sdim
158259701Sdim#endif /* __TBMINTRIN_H */
159