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