]> git.sesse.net Git - casparcg/blob - tbb/include/tbb/machine/linux_ia32.h
Added missing ffmpeg file.
[casparcg] / tbb / include / tbb / machine / linux_ia32.h
1 /*
2     Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
3
4     This file is part of Threading Building Blocks.
5
6     Threading Building Blocks is free software; you can redistribute it
7     and/or modify it under the terms of the GNU General Public License
8     version 2 as published by the Free Software Foundation.
9
10     Threading Building Blocks is distributed in the hope that it will be
11     useful, but WITHOUT ANY WARRANTY; without even the implied warranty
12     of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with Threading Building Blocks; if not, write to the Free Software
17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
19     As a special exception, you may use this file as part of a free software
20     library without restriction.  Specifically, if other files instantiate
21     templates or use macros or inline functions from this file, or you compile
22     this file and link it with other files to produce an executable, this
23     file does not by itself cause the resulting executable to be covered by
24     the GNU General Public License.  This exception does not however
25     invalidate any other reasons why the executable file might be covered by
26     the GNU General Public License.
27 */
28
29 #ifndef __TBB_machine_H
30 #error Do not include this file directly; include tbb_machine.h instead
31 #endif
32
33 #include <stdint.h>
34 #include <unistd.h>
35
36 #define __TBB_WORDSIZE 4
37 #define __TBB_BIG_ENDIAN 0
38
39 #define __TBB_release_consistency_helper() __asm__ __volatile__("": : :"memory")
40 #define __TBB_full_memory_fence() __asm__ __volatile__("mfence": : :"memory")
41
42 #if __TBB_ICC_ASM_VOLATILE_BROKEN
43 #define __TBB_VOLATILE
44 #else
45 #define __TBB_VOLATILE volatile
46 #endif
47
48 #define __MACHINE_DECL_ATOMICS(S,T,X,R) \
49 static inline T __TBB_machine_cmpswp##S (volatile void *ptr, T value, T comparand )  \
50 {                                                                                    \
51     T result;                                                                        \
52                                                                                      \
53     __asm__ __volatile__("lock\ncmpxchg" X " %2,%1"                                  \
54                           : "=a"(result), "=m"(*(__TBB_VOLATILE T*)ptr)              \
55                           : "q"(value), "0"(comparand), "m"(*(__TBB_VOLATILE T*)ptr) \
56                           : "memory");                                               \
57     return result;                                                                   \
58 }                                                                                    \
59                                                                                      \
60 static inline T __TBB_machine_fetchadd##S(volatile void *ptr, T addend)              \
61 {                                                                                    \
62     T result;                                                                        \
63     __asm__ __volatile__("lock\nxadd" X " %0,%1"                                     \
64                           : R (result), "=m"(*(__TBB_VOLATILE T*)ptr)            \
65                           : "0"(addend), "m"(*(__TBB_VOLATILE T*)ptr)                \
66                           : "memory");                                               \
67     return result;                                                                   \
68 }                                                                                    \
69                                                                                      \
70 static inline  T __TBB_machine_fetchstore##S(volatile void *ptr, T value)            \
71 {                                                                                    \
72     T result;                                                                        \
73     __asm__ __volatile__("lock\nxchg" X " %0,%1"                                     \
74                           : R (result), "=m"(*(__TBB_VOLATILE T*)ptr)            \
75                           : "0"(value), "m"(*(__TBB_VOLATILE T*)ptr)                 \
76                           : "memory");                                               \
77     return result;                                                                   \
78 }                                                                                    \
79                                                                                      
80 __MACHINE_DECL_ATOMICS(1,int8_t,"","=q")
81 __MACHINE_DECL_ATOMICS(2,int16_t,"","=r")
82 __MACHINE_DECL_ATOMICS(4,int32_t,"l","=r")
83
84 static inline int64_t __TBB_machine_cmpswp8 (volatile void *ptr, int64_t value, int64_t comparand )
85 {
86     int64_t result;
87     union {
88         int64_t i64;
89         int32_t i32[2];
90     };
91     i64 = value;
92 #if __PIC__ 
93     /* compiling position-independent code */
94     // EBX register preserved for compliance with position-independent code rules on IA32
95     int32_t tmp;
96     __asm__ __volatile__ (
97             "movl  %%ebx,%2\n\t"
98             "movl  %5,%%ebx\n\t"
99 #if __GNUC__==3
100             "lock\n\t cmpxchg8b %1\n\t"
101 #else
102             "lock\n\t cmpxchg8b (%3)\n\t"
103 #endif
104             "movl  %2,%%ebx"
105              : "=A"(result)
106              , "=m"(*(__TBB_VOLATILE int64_t *)ptr)
107              , "=m"(tmp)
108 #if __GNUC__==3
109              : "m"(*(__TBB_VOLATILE int64_t *)ptr)
110 #else
111              : "SD"(ptr)
112 #endif
113              , "0"(comparand)
114              , "m"(i32[0]), "c"(i32[1])
115              : "memory"
116 #if __INTEL_COMPILER
117              ,"ebx"
118 #endif
119     );
120 #else /* !__PIC__ */
121     __asm__ __volatile__ (
122             "lock\n\t cmpxchg8b %1\n\t"
123              : "=A"(result), "=m"(*(__TBB_VOLATILE int64_t *)ptr)
124              : "m"(*(__TBB_VOLATILE int64_t *)ptr)
125              , "0"(comparand)
126              , "b"(i32[0]), "c"(i32[1])
127              : "memory"
128     );
129 #endif /* __PIC__ */
130     return result;
131 }
132
133 static inline int32_t __TBB_machine_lg( uint32_t x ) {
134     int32_t j;
135     __asm__ ("bsr %1,%0" : "=r"(j) : "r"(x));
136     return j;
137 }
138
139 static inline void __TBB_machine_or( volatile void *ptr, uint32_t addend ) {
140     __asm__ __volatile__("lock\norl %1,%0" : "=m"(*(__TBB_VOLATILE uint32_t *)ptr) : "r"(addend), "m"(*(__TBB_VOLATILE uint32_t *)ptr) : "memory");
141 }
142
143 static inline void __TBB_machine_and( volatile void *ptr, uint32_t addend ) {
144     __asm__ __volatile__("lock\nandl %1,%0" : "=m"(*(__TBB_VOLATILE uint32_t *)ptr) : "r"(addend), "m"(*(__TBB_VOLATILE uint32_t *)ptr) : "memory");
145 }
146
147 static inline void __TBB_machine_pause( int32_t delay ) {
148     for (int32_t i = 0; i < delay; i++) {
149        __asm__ __volatile__("pause;");
150     }
151     return;
152 }   
153
154 static inline int64_t __TBB_machine_load8 (const volatile void *ptr) {
155     int64_t result;
156     if( ((uint32_t)ptr&7u)==0 ) {
157         // Aligned load
158         __asm__ __volatile__ ( "fildq %1\n\t"
159                                "fistpq %0" :  "=m"(result) : "m"(*(const __TBB_VOLATILE uint64_t*)ptr) : "memory" );
160     } else {
161         // Unaligned load
162         result = __TBB_machine_cmpswp8(const_cast<void*>(ptr),0,0);
163     }
164     return result;
165 }
166
167 //! Handles misaligned 8-byte store
168 /** Defined in tbb_misc.cpp */
169 extern "C" void __TBB_machine_store8_slow( volatile void *ptr, int64_t value );
170 extern "C" void __TBB_machine_store8_slow_perf_warning( volatile void *ptr );
171
172 static inline void __TBB_machine_store8(volatile void *ptr, int64_t value) {
173     if( ((uint32_t)ptr&7u)==0 ) {
174         // Aligned store
175         __asm__ __volatile__ ( "fildq %1\n\t"
176                                "fistpq %0" :  "=m"(*(__TBB_VOLATILE int64_t*)ptr) : "m"(value) : "memory" );
177     } else {
178         // Unaligned store
179 #if TBB_USE_PERFORMANCE_WARNINGS
180         __TBB_machine_store8_slow_perf_warning(ptr);
181 #endif /* TBB_USE_PERFORMANCE_WARNINGS */
182         __TBB_machine_store8_slow(ptr,value);
183     }
184 }
185  
186 // Machine specific atomic operations
187
188 #define __TBB_CompareAndSwap1(P,V,C) __TBB_machine_cmpswp1(P,V,C)
189 #define __TBB_CompareAndSwap2(P,V,C) __TBB_machine_cmpswp2(P,V,C)
190 #define __TBB_CompareAndSwap4(P,V,C) __TBB_machine_cmpswp4(P,V,C)
191 #define __TBB_CompareAndSwap8(P,V,C) __TBB_machine_cmpswp8(P,V,C)
192 #define __TBB_CompareAndSwapW(P,V,C) __TBB_machine_cmpswp4(P,V,C)
193
194 #define __TBB_FetchAndAdd1(P,V) __TBB_machine_fetchadd1(P,V)
195 #define __TBB_FetchAndAdd2(P,V) __TBB_machine_fetchadd2(P,V)
196 #define __TBB_FetchAndAdd4(P,V) __TBB_machine_fetchadd4(P,V)
197 #define __TBB_FetchAndAddW(P,V) __TBB_machine_fetchadd4(P,V)
198
199 #define __TBB_FetchAndStore1(P,V) __TBB_machine_fetchstore1(P,V)
200 #define __TBB_FetchAndStore2(P,V) __TBB_machine_fetchstore2(P,V)
201 #define __TBB_FetchAndStore4(P,V) __TBB_machine_fetchstore4(P,V)
202 #define __TBB_FetchAndStoreW(P,V) __TBB_machine_fetchstore4(P,V)
203
204 #define __TBB_Store8(P,V) __TBB_machine_store8(P,V)
205 #define __TBB_Load8(P)    __TBB_machine_load8(P)
206
207 #define __TBB_AtomicOR(P,V) __TBB_machine_or(P,V)
208 #define __TBB_AtomicAND(P,V) __TBB_machine_and(P,V)
209
210
211 // Those we chose not to implement (they will be implemented generically using CMPSWP8)
212 #undef __TBB_FetchAndAdd8
213 #undef __TBB_FetchAndStore8
214
215 // Definition of other functions
216 #define __TBB_Pause(V) __TBB_machine_pause(V)
217 #define __TBB_Log2(V)  __TBB_machine_lg(V)
218
219 // Special atomic functions
220 #define __TBB_FetchAndAddWrelease(P,V) __TBB_FetchAndAddW(P,V)
221 #define __TBB_FetchAndIncrementWacquire(P) __TBB_FetchAndAddW(P,1)
222 #define __TBB_FetchAndDecrementWrelease(P) __TBB_FetchAndAddW(P,-1)
223
224 // Use generic definitions from tbb_machine.h
225 #undef __TBB_TryLockByte
226 #undef __TBB_LockByte
227
228 // API to retrieve/update FPU control setting
229 #define __TBB_CPU_CTL_ENV_PRESENT 1
230
231 struct __TBB_cpu_ctl_env_t {
232     int     mxcsr;
233     short   x87cw;
234 };
235
236 inline void __TBB_get_cpu_ctl_env ( __TBB_cpu_ctl_env_t* ctl ) {
237     __asm__ __volatile__ (
238             "stmxcsr %0\n\t"
239             "fstcw   %1"
240             : "=m"(ctl->mxcsr), "=m"(ctl->x87cw)
241     );
242 }
243 inline void __TBB_set_cpu_ctl_env ( const __TBB_cpu_ctl_env_t* ctl ) {
244     __asm__ __volatile__ (
245             "ldmxcsr %0\n\t"
246             "fldcw   %1"
247             : : "m"(ctl->mxcsr), "m"(ctl->x87cw)
248     );
249 }
250