source: trunk/GDE/RAxML/ll_asm.h

Last change on this file was 13845, checked in by westram, 10 years ago
  • remove executable flag
File size: 5.9 KB
Line 
1/*
2 *   Copyright (C) 2009, 2010, 2011 Lockless Inc., Steven Von Fuerst.
3 *
4 * This library is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17
18/*
19 * Functions that require asm for efficiency, or to work at all...
20 */
21#if 1
22#ifndef LL_ASM_H
23#define LL_ASM_H
24
25#include "compiler.h"
26#include <stdint.h>
27#ifdef GCC_ASM
28#include <stdint.h>
29#define atomic_or(P, V) __sync_or_and_fetch((P), (V))
30#define atomic_and(P, V) __sync_and_and_fetch((P), (V))
31#define atomic_add(P, V) __sync_add_and_fetch((P), (V))
32#define atomic_xadd(P, V) __sync_fetch_and_add((P), (V))
33#define atomic_cmpxchg_bool(P, O, N) __sync_bool_compare_and_swap((P), (O), (N))
34#define atomic_access(V) (*(volatile typeof(V) *)&(V))
35
36
37#if 0
38static inline int bts(volatile void *mem, size_t offset)
39{
40        asm goto (
41                "lock; bts %0, (%1)\n"
42                "jc %l[carry]\n"
43                :
44                : "r" (offset), "r" (mem)
45                : "memory", "cc"
46                : carry);
47        return 0;
48
49        carry:
50        return 1;
51}
52
53static inline int btr(volatile void *mem, size_t offset)
54{
55        asm goto (
56                "lock; btr %0, (%1)\n"
57                "jnc %l[ncarry]\n"
58                :
59                : "r" (offset), "r" (mem)
60                : "memory", "cc"
61                : ncarry);
62        return 1;
63
64        ncarry:
65        return 0;
66}
67#endif
68static inline int ffsu(unsigned x)
69{
70        int result;
71
72        asm ("bsf %[x], %[result]"
73                : [result] "=r" (result)
74                : [x] "mr" (x)
75                :"cc");
76
77        return result;
78}
79
80static inline size_t flsu(unsigned x)
81{
82        size_t result;
83
84        asm ("bsr %[x], %[result]"
85                : [result] "=r" (result)
86                : [x] "mr" (x)
87                :"cc");
88
89        return result;
90}
91
92#ifdef __x86_64__
93static inline size_t ffsq(size_t x)
94{
95        size_t result;
96
97        asm ("bsfq %[x], %[result]"
98                : [result] "=r" (result)
99                : [x] "mr" (x)
100                :"cc");
101
102        return result;
103}
104
105static inline size_t flsq(size_t x)
106{
107        size_t result;
108
109        asm ("bsrq %[x], %[result]"
110                : [result] "=r" (result)
111                : [x] "mr" (x)
112                :"cc");
113
114        return result;
115}
116
117#else
118static inline size_t ffsq(unsigned long long x)
119{
120        size_t result;
121
122        unsigned xlo = x & 0xffffffff;
123        unsigned xhi = x >> 32;
124
125        unsigned tmp;
126
127        asm ("bsfl %[xhi], %[tmp]\n"
128                 "addl $0x20, %[tmp]\n"
129                 "bsfl %[xlo], %[result]\n"
130                 "cmove %[tmp], %[result]\n"
131                 :[result] "=r" (result), [tmp] "=&r" (tmp)
132                 :[xlo] "rm" (xlo), [xhi] "rm" (xhi)
133                 :"cc");
134
135        return result;
136}
137
138static inline size_t flsq(unsigned long long x)
139{
140        size_t result;
141
142        unsigned xlo = x & 0xffffffff;
143        unsigned xhi = x >> 32;
144        unsigned tmp;
145
146        asm ("bsrl %[xlo], %[tmp]\n"
147                 "addl $-0x20, %[tmp]\n"
148                 "bsrl %[xhi], %[result]\n"
149                 "cmove %[tmp], %[result]\n"
150                 "addl $0x20, %[result]\n"
151                 :[result] "=r" (result), [tmp] "=&r" (tmp)
152                 :[xlo] "rm" (xlo), [xhi] "rm" (xhi)
153                 :"cc");
154
155        return result;
156}
157
158#endif
159
160static inline unsigned char xchg_8(void *ptr, unsigned char x)
161{
162        asm volatile("xchgb %0,%1"
163                                :"=r" ((unsigned char) x)
164                                :"m" (*(volatile unsigned char *)ptr), "0" (x)
165                                :"memory");
166
167        return x;
168}
169
170static inline unsigned short xchg_16(void *ptr, unsigned short x)
171{
172        asm volatile("xchgw %0,%1"
173                                :"=r" ((unsigned short) x)
174                                :"m" (*(volatile unsigned short *)ptr), "0" (x)
175                                :"memory");
176
177        return x;
178}
179
180
181static inline unsigned xchg_32(void *ptr, unsigned x)
182{
183        asm volatile("xchgl %0,%1"
184                                :"=r" ((unsigned) x)
185                                :"m" (*(volatile unsigned *)ptr), "0" (x)
186                                :"memory");
187
188        return x;
189}
190
191#ifdef __x86_64__
192static inline unsigned long long xchg_64(void *ptr, unsigned long long x)
193{
194        asm volatile("xchgq %0,%1"
195                                :"=r" ((unsigned long long) x)
196                                :"m" (*(volatile unsigned long long *)ptr), "0" (x)
197                                :"memory");
198
199        return x;
200}
201
202static inline void *xchg_ptr(void *ptr, void *x)
203{
204        __asm__ __volatile__("xchgq %0,%1"
205                                :"=r" ((uintptr_t) x)
206                                :"m" (*(volatile uintptr_t *)ptr), "0" ((uintptr_t) x)
207                                :"memory");
208
209        return x;
210}
211#else
212static inline void *xchg_ptr(void *ptr, void *x)
213{
214        __asm__ __volatile__("xchgl %k0,%1"
215                                :"=r" ((uintptr_t) x)
216                                :"m" (*(volatile uintptr_t *)ptr), "0" ((uintptr_t) x)
217                                :"memory");
218        return x;
219}
220#endif
221
222static inline unsigned long long rdtsc(void)
223{
224        unsigned hi, lo;
225        asm volatile ("rdtsc" : "=a"(lo), "=d"(hi));
226        return lo + ((unsigned long long)hi << 32);
227}
228
229#else /* GCC_ASM */
230
231static inline int ffsu(unsigned x)
232{
233        unsigned long result;
234        __assume(x);
235        _BitScanForward(&result, x);
236
237        return result;
238}
239
240static inline int flsu(unsigned x)
241{
242        unsigned long result;
243        __assume(x);
244        _BitScanReverse(&result, x);
245
246        return result;
247}
248
249static inline size_t ffsq(unsigned long long x)
250{
251        unsigned long result;
252        __assume(x);
253        _BitScanForward64(&result, x);
254
255        return result;
256}
257
258static inline size_t fflq(unsigned long long x)
259{
260        unsigned long result;
261        __assume(x);
262        _BitScanReverse64(&result, x);
263
264        return result;
265}
266
267#ifdef __x86_64__
268static inline void *xchg_ptr(void *ptr, void *x)
269{
270        return (void *) _InterlockedExchange64(ptr, (int64_t) x);
271}
272#else
273static inline void *xchg_ptr(void *ptr, void *x)
274{
275        return (void *) _InterlockedExchange(ptr, (long) x);
276}
277#endif
278
279
280#endif /* GCC_ASM */
281
282#endif /* LL_ASM_H */
283
284#endif
285#if 0
286static inline int ffsu(unsigned x)
287{
288        unsigned long result = __builtin_ffs(x);
289
290
291        return result - 1;
292}
293
294static inline int flsu(unsigned x)
295{
296        unsigned long result;
297        __assume(x);
298        _BitScanReverse(&result, x);
299
300        return result;
301}
302
303static inline size_t ffsq(unsigned long long x)
304{
305        unsigned long result;
306        __assume(x);
307        _BitScanForward64(&result, x);
308
309        return result;
310}
311
312static inline size_t fflq(unsigned long long x)
313{
314        unsigned long result;
315        __assume(x);
316        _BitScanReverse64(&result, x);
317
318        return result;
319}
320#endif
Note: See TracBrowser for help on using the repository browser.