Small modifications. Swapped %n and %N
[libfirm] / ir / adt / bitset_ia32.h
1
2
3 #undef _bitset_inside_clear
4 #undef _bitset_inside_set
5 #undef _bitset_inside_flip
6 #undef _bitset_inside_is_set
7
8 #undef _bitset_inside_nlz
9 #undef _bitset_inside_ntz
10 #undef _bitset_inside_ntz_value
11
12 #define _bitset_inside_set(unit,bit) \
13         __asm__( "btsl %1,%0" :"=m" (unit) :"Ir" (bit))
14
15 #define _bitset_inside_clear(unit,bit) \
16         __asm__( "btrl %1,%0" :"=m" (unit) :"Ir" (bit))
17
18 #define _bitset_inside_flip(unit,bit) \
19         __asm__( "btcl %1,%0" :"=m" (unit) :"Ir" (bit))
20
21 #define _bitset_inside_is_set(unit,bit) _bitset_ia32_inside_is_set(unit, bit)
22 #define _bitset_inside_nlz(unit) _bitset_ia32_inside_nlz(unit)
23 #define _bitset_inside_ntz(unit) _bitset_ia32_inside_ntz(unit)
24 #define _bitset_inside_ntz_value(unit) _bitset_ia32_inside_ntz_value(unit)
25
26 static INLINE int _bitset_ia32_inside_is_set(unsigned long *unit, unsigned bit)
27 {
28         int res = 0;
29         __asm__("mov $0,%0\n\tbtl %1,%2\n\tadc $0,%0"
30                         : "=r" (res)
31                         : "Ir" (bit), "m" (unit)
32                         : "cc");
33         return res;
34 }
35
36 static INLINE unsigned _bitset_ia32_inside_nlz(unsigned long *unit)
37 {
38         unsigned res = 0;
39         __asm__("bsrl %1,%0" :"=r" (res) :"m" (unit));
40         return *unit == 0 ? 32 : res;
41 }
42
43 static INLINE unsigned _bitset_ia32_inside_ntz(unsigned long *unit) {
44         unsigned res = 0;
45         __asm__("bsfl %1,%0" :"=r" (res) :"m" (unit));
46         return *unit == 0 ? 32 : res;
47 }
48
49 static INLINE unsigned _bitset_ia32_inside_ntz_value(unsigned long unit) {
50         unsigned res = 0;
51         __asm__("bsfl %1,%0" :"=r" (res) :"rm" (unit));
52         return unit == 0 ? 32 : res;
53 }
54
55 #if defined(__GNUC__) && defined(__SSE2__)
56
57 #include <stddef.h>
58 #include <xmmintrin.h>
59
60 #undef _bitset_units
61 #undef _bitset_overall_size
62 #undef _bitset_data_ptr
63
64 #undef _BITSET_BINOP_UNITS_INC
65
66 #undef _bitset_inside_binop_and
67 #undef _bitset_inside_binop_andnot
68 #undef _bitset_inside_binop_or
69 #undef _bitset_inside_binop_xor
70
71 #undef _bitset_inside_binop_with_zero_and
72 #undef _bitset_inside_binop_with_zero_andnot
73 #undef _bitset_inside_binop_with_zero_or
74 #undef _bitset_inside_binop_with_zero_xor
75
76 #define _bitset_units(highest_bit) (round_up2(highest_bit, 128) / BS_UNIT_SIZE_BITS)
77
78 #define _bitset_overall_size(bitset_base_size,highest_bit) \
79         ((bitset_base_size) + 16 + _bitset_units(highest_bit) * BS_UNIT_SIZE)
80
81 #define _bitset_data_ptr(data,bitset_base_size,highest_bit) \
82   _bitset_sse_data_ptr(data, bitset_base_size, highest_bit)
83
84 static INLINE unsigned long *_bitset_sse_data_ptr(void *data, size_t bitset_base_size,
85                 unsigned long highest_bit)
86 {
87         ptrdiff_t diff;
88         char *units = data;
89
90         diff = (units - (char *) 0) + bitset_base_size;
91         diff = round_up2(diff, 16);
92         units = (char *) 0 + diff;
93         return (unsigned long *) units;
94 }
95
96 #define _BITSET_BINOP_UNITS_INC 4
97 #define _bitset_inside_binop_and(tgt,src) _bitset_sse_inside_binop_and(tgt,src)
98 #define _bitset_inside_binop_andnot(tgt,src) _bitset_sse_inside_binop_andnot(tgt,src)
99 #define _bitset_inside_binop_or(tgt,src) _bitset_sse_inside_binop_or(tgt,src)
100 #define _bitset_inside_binop_xor(tgt,src) _bitset_sse_inside_binop_xor(tgt,src)
101
102 /* and with zero sets everything to zero. */
103 #define _bitset_inside_binop_with_zero_and(tgt) _bitset_sse_inside_binop_with_zero_and(tgt)
104
105 /* And Not with 0 is the identity (its like and with 1) */
106 #define _bitset_inside_binop_with_zero_andnot(tgt)
107
108 /* Or with zero is also the identity */
109 #define _bitset_inside_binop_with_zero_or(tgt)
110
111 /* Xor with 0 is like negation, we have to do it. */
112 #define _bitset_inside_binop_with_zero_xor(tgt) _bitset_sse_inside_binop_with_zero_xor(tgt)
113
114 #define _BITSET_SSE_BINOP(name) \
115 static INLINE void _bitset_sse_inside_binop_ ## name(unsigned long *tgt, unsigned long *src) \
116 { \
117         __m128i src_op = _mm_load_si128((__m128i *) src); \
118         __m128i tgt_op = _mm_load_si128((__m128i *) tgt); \
119         __m128i res = _mm_ ## name ## _si128(tgt_op, src_op); \
120         _mm_store_si128((void *) tgt, res); \
121 }
122
123
124 static INLINE void _bitset_sse_inside_binop_with_zero_and(unsigned long *tgt)
125 {
126 #ifdef _BITSET_SSE_USE_INLINE_ASM
127         asm("pxor %%xmm0,%%xmm0\n\t"
128                         "movapd %%xmm0,%0"
129                         :
130                         : "m" (tgt)
131                         : "xmm0", "memory");
132 #else
133         tgt[0] = 0;
134         tgt[1] = 0;
135         tgt[2] = 0;
136         tgt[3] = 0;
137 #endif
138 }
139
140 static INLINE void _bitset_sse_inside_binop_with_zero_xor(unsigned long *tgt)
141 {
142 #ifdef _BITSET_SSE_USE_INLINE_ASM
143         asm("pxor %%xmm0,%%xmm0\n\t"
144                         "pxor %0,%%xmm0\n\t"
145                         "movapd %%xmm0,%0"
146                         :
147                         : "m" (tgt)
148                         : "xmm0", "memory");
149 #else
150         __m128i src_op = _mm_setzero_si128();
151         __m128i tgt_op = _mm_load_si128((void *) tgt);
152         __m128i res = _mm_xor_si128(tgt_op, src_op);
153         _mm_store_si128((__m128i *) tgt, res);
154 #endif
155 }
156
157 static INLINE void _bitset_sse_inside_binop_andnot(unsigned long *tgt, unsigned long *src)
158 {
159         __m128i src_op = _mm_load_si128((void *) src);
160         __m128i tgt_op = _mm_load_si128((void *) tgt);
161         __m128i res = _mm_andnot_si128(src_op, tgt_op);
162         _mm_store_si128((__m128i *) tgt, res);
163 }
164
165 _BITSET_SSE_BINOP(and)
166 _BITSET_SSE_BINOP(or)
167 _BITSET_SSE_BINOP(xor)
168
169
170 #endif