Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenintrin_arm.h
Go to the documentation of this file.
00001 /* 00002 Compatibility <intrin.h> header for GCC -- GCC equivalents of intrinsic 00003 Microsoft Visual C++ functions. Originally developed for the ReactOS 00004 (<http://www.reactos.org/>) and TinyKrnl (<http://www.tinykrnl.org/>) 00005 projects. 00006 00007 Copyright (c) 2006 KJK::Hyperion <hackbunny@reactos.com> 00008 00009 Permission is hereby granted, free of charge, to any person obtaining a 00010 copy of this software and associated documentation files (the "Software"), 00011 to deal in the Software without restriction, including without limitation 00012 the rights to use, copy, modify, merge, publish, distribute, sublicense, 00013 and/or sell copies of the Software, and to permit persons to whom the 00014 Software is furnished to do so, subject to the following conditions: 00015 00016 The above copyright notice and this permission notice shall be included in 00017 all copies or substantial portions of the Software. 00018 00019 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00020 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00021 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00022 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00023 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 00024 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 00025 DEALINGS IN THE SOFTWARE. 00026 */ 00027 00028 #ifndef KJK_INTRIN_ARM_H_ 00029 #define KJK_INTRIN_ARM_H_ 00030 00031 #ifndef __GNUC__ 00032 #error Unsupported compiler 00033 #endif 00034 00035 #define _ReturnAddress() (__builtin_return_address(0)) 00036 #define _ReadWriteBarrier() __sync_synchronize() 00037 00038 __INTRIN_INLINE void __yield(void) { __asm__ __volatile__("yield"); } 00039 00040 __INTRIN_INLINE void __break(unsigned int value) { __asm__ __volatile__("bkpt %0": : "M" (value)); } 00041 00042 __INTRIN_INLINE unsigned short _byteswap_ushort(unsigned short value) 00043 { 00044 return (value >> 8) || (value << 8); 00045 } 00046 00047 __INTRIN_INLINE unsigned _CountLeadingZeros(long Mask) 00048 { 00049 return Mask ? __builtin_clz(Mask) : 32; 00050 } 00051 00052 __INTRIN_INLINE unsigned _CountTrailingZeros(long Mask) 00053 { 00054 return Mask ? __builtin_ctz(Mask) : 32; 00055 } 00056 00057 __INTRIN_INLINE unsigned char _BitScanForward(unsigned long * const Index, const unsigned long Mask) 00058 { 00059 *Index = __builtin_ctz(Mask); 00060 return Mask ? 1 : 0; 00061 } 00062 00063 __INTRIN_INLINE char _InterlockedCompareExchange8(volatile char * const Destination, const char Exchange, const char Comperand) 00064 { 00065 return __sync_val_compare_and_swap(Destination, Comperand, Exchange); 00066 } 00067 00068 __INTRIN_INLINE short _InterlockedCompareExchange16(volatile short * const Destination, const short Exchange, const short Comperand) 00069 { 00070 short a, b; 00071 00072 __asm__ __volatile__ ( "0:\n\t" 00073 "ldr %1, [%2]\n\t" 00074 "cmp %1, %4\n\t" 00075 "bne 1f\n\t" 00076 "swp %0, %3, [%2]\n\t" 00077 "cmp %0, %1\n\t" 00078 "swpne %3, %0, [%2]\n\t" 00079 "bne 0b\n\t" 00080 "1:" 00081 : "=&r" (a), "=&r" (b) 00082 : "r" (Destination), "r" (Exchange), "r" (Comperand) 00083 : "cc", "memory"); 00084 00085 return a; 00086 } 00087 00088 __INTRIN_INLINE short _InterlockedExchangeAdd16(volatile short * const Addend, const short Value) 00089 { 00090 short a, b, c; 00091 00092 __asm__ __volatile__ ( "0:\n\t" 00093 "ldr %0, [%3]\n\t" 00094 "add %1, %0, %4\n\t" 00095 "swp %2, %1, [%3]\n\t" 00096 "cmp %0, %2\n\t" 00097 "swpne %1, %2, [%3]\n\t" 00098 "bne 0b" 00099 : "=&r" (a), "=&r" (b), "=&r" (c) 00100 : "r" (Value), "r" (Addend) 00101 : "cc", "memory"); 00102 00103 return a; 00104 } 00105 00106 __INTRIN_INLINE long _InterlockedCompareExchange(volatile long * const dest, const long exch, const long comp) 00107 { 00108 long a, b; 00109 00110 __asm__ __volatile__ ( "0:\n\t" 00111 "ldr %1, [%2]\n\t" 00112 "cmp %1, %4\n\t" 00113 "bne 1f\n\t" 00114 "swp %0, %3, [%2]\n\t" 00115 "cmp %0, %1\n\t" 00116 "swpne %3, %0, [%2]\n\t" 00117 "bne 0b\n\t" 00118 "1:" 00119 : "=&r" (a), "=&r" (b) 00120 : "r" (dest), "r" (exch), "r" (comp) 00121 : "cc", "memory"); 00122 00123 return a; 00124 } 00125 00126 __INTRIN_INLINE long long _InterlockedCompareExchange64(volatile long long * const dest, const long long exch, const long long comp) 00127 { 00128 // 00129 // FIXME 00130 // 00131 long long result; 00132 result = *dest; 00133 if (*dest == comp) *dest = exch; 00134 return result; 00135 } 00136 00137 __INTRIN_INLINE void * _InterlockedCompareExchangePointer(void * volatile * const Destination, void * const Exchange, void * const Comperand) 00138 { 00139 return (void*)_InterlockedCompareExchange((volatile long* const)Destination, (const long)Exchange, (const long)Comperand); 00140 } 00141 00142 00143 __INTRIN_INLINE long _InterlockedExchangeAdd(volatile long * const dest, const long add) 00144 { 00145 long a, b, c; 00146 00147 __asm__ __volatile__ ( "0:\n\t" 00148 "ldr %0, [%3]\n\t" 00149 "add %1, %0, %4\n\t" 00150 "swp %2, %1, [%3]\n\t" 00151 "cmp %0, %2\n\t" 00152 "swpne %1, %2, [%3]\n\t" 00153 "bne 0b" 00154 : "=&r" (a), "=&r" (b), "=&r" (c) 00155 : "r" (dest), "r" (add) 00156 : "cc", "memory"); 00157 00158 return a; 00159 } 00160 00161 __INTRIN_INLINE long _InterlockedExchange(volatile long * const dest, const long exch) 00162 { 00163 long a; 00164 00165 __asm__ __volatile__ ( "swp %0, %2, [%1]" 00166 : "=&r" (a) 00167 : "r" (dest), "r" (exch)); 00168 00169 return a; 00170 } 00171 00172 00173 __INTRIN_INLINE void * _InterlockedExchangePointer(void * volatile * const Target, void * const Value) 00174 { 00175 return (void *)_InterlockedExchange((volatile long * const)Target, (const long)Value); 00176 } 00177 00178 00179 00180 __INTRIN_INLINE unsigned char _BitScanReverse(unsigned long * const Index, const unsigned long Mask) 00181 { 00182 *Index = 31 - __builtin_clz(Mask); 00183 return Mask ? 1 : 0; 00184 } 00185 00186 __INTRIN_INLINE char _InterlockedAnd8(volatile char * const value, const char mask) 00187 { 00188 char x; 00189 char y; 00190 00191 y = *value; 00192 00193 do 00194 { 00195 x = y; 00196 y = _InterlockedCompareExchange8(value, x & mask, x); 00197 } 00198 while(y != x); 00199 00200 return y; 00201 } 00202 00203 __INTRIN_INLINE short _InterlockedAnd16(volatile short * const value, const short mask) 00204 { 00205 short x; 00206 short y; 00207 00208 y = *value; 00209 00210 do 00211 { 00212 x = y; 00213 y = _InterlockedCompareExchange16(value, x & mask, x); 00214 } 00215 while(y != x); 00216 00217 return y; 00218 } 00219 00220 __INTRIN_INLINE long _InterlockedAnd(volatile long * const value, const long mask) 00221 { 00222 long x; 00223 long y; 00224 00225 y = *value; 00226 00227 do 00228 { 00229 x = y; 00230 y = _InterlockedCompareExchange(value, x & mask, x); 00231 } 00232 while(y != x); 00233 00234 return y; 00235 } 00236 00237 __INTRIN_INLINE char _InterlockedOr8(volatile char * const value, const char mask) 00238 { 00239 char x; 00240 char y; 00241 00242 y = *value; 00243 00244 do 00245 { 00246 x = y; 00247 y = _InterlockedCompareExchange8(value, x | mask, x); 00248 } 00249 while(y != x); 00250 00251 return y; 00252 } 00253 00254 __INTRIN_INLINE short _InterlockedOr16(volatile short * const value, const short mask) 00255 { 00256 short x; 00257 short y; 00258 00259 y = *value; 00260 00261 do 00262 { 00263 x = y; 00264 y = _InterlockedCompareExchange16(value, x | mask, x); 00265 } 00266 while(y != x); 00267 00268 return y; 00269 } 00270 00271 __INTRIN_INLINE long _InterlockedOr(volatile long * const value, const long mask) 00272 { 00273 long x; 00274 long y; 00275 00276 y = *value; 00277 00278 do 00279 { 00280 x = y; 00281 y = _InterlockedCompareExchange(value, x | mask, x); 00282 } 00283 while(y != x); 00284 00285 return y; 00286 } 00287 00288 __INTRIN_INLINE char _InterlockedXor8(volatile char * const value, const char mask) 00289 { 00290 char x; 00291 char y; 00292 00293 y = *value; 00294 00295 do 00296 { 00297 x = y; 00298 y = _InterlockedCompareExchange8(value, x ^ mask, x); 00299 } 00300 while(y != x); 00301 00302 return y; 00303 } 00304 00305 __INTRIN_INLINE short _InterlockedXor16(volatile short * const value, const short mask) 00306 { 00307 short x; 00308 short y; 00309 00310 y = *value; 00311 00312 do 00313 { 00314 x = y; 00315 y = _InterlockedCompareExchange16(value, x ^ mask, x); 00316 } 00317 while(y != x); 00318 00319 return y; 00320 } 00321 00322 __INTRIN_INLINE long _InterlockedXor(volatile long * const value, const long mask) 00323 { 00324 long x; 00325 long y; 00326 00327 y = *value; 00328 00329 do 00330 { 00331 x = y; 00332 y = _InterlockedCompareExchange(value, x ^ mask, x); 00333 } 00334 while(y != x); 00335 00336 return y; 00337 } 00338 00339 __INTRIN_INLINE long _InterlockedDecrement(volatile long * const lpAddend) 00340 { 00341 return _InterlockedExchangeAdd(lpAddend, -1) - 1; 00342 } 00343 00344 __INTRIN_INLINE long _InterlockedIncrement(volatile long * const lpAddend) 00345 { 00346 return _InterlockedExchangeAdd(lpAddend, 1) + 1; 00347 } 00348 00349 __INTRIN_INLINE long _InterlockedDecrement16(volatile short * const lpAddend) 00350 { 00351 return _InterlockedExchangeAdd16(lpAddend, -1) - 1; 00352 } 00353 00354 __INTRIN_INLINE long _InterlockedIncrement16(volatile short * const lpAddend) 00355 { 00356 return _InterlockedExchangeAdd16(lpAddend, 1) + 1; 00357 } 00358 00359 __INTRIN_INLINE long _InterlockedAddLargeStatistic(volatile long long * const Addend, const long Value) 00360 { 00361 *Addend += Value; 00362 return Value; 00363 } 00364 00365 __INTRIN_INLINE void _disable(void) 00366 { 00367 __asm__ __volatile__ 00368 ( 00369 "cpsid i @ __cli" : : : "memory", "cc" 00370 ); 00371 } 00372 00373 __INTRIN_INLINE void _enable(void) 00374 { 00375 __asm__ __volatile__ 00376 ( 00377 "cpsie i @ __sti" : : : "memory", "cc" 00378 ); 00379 } 00380 00381 __INTRIN_INLINE unsigned char _interlockedbittestandset(volatile long * a, const long b) 00382 { 00383 return (_InterlockedOr(a, 1 << b) >> b) & 1; 00384 } 00385 00386 __INTRIN_INLINE unsigned char _interlockedbittestandreset(volatile long * a, const long b) 00387 { 00388 return (_InterlockedAnd(a, ~(1 << b)) >> b) & 1; 00389 } 00390 00391 #ifndef __MSVCRT__ 00392 __INTRIN_INLINE unsigned int _rotl(const unsigned int value, int shift) 00393 { 00394 return (((value) << ((int)(shift))) | ((value) >> (32 - (int)(shift)))); 00395 } 00396 #endif 00397 00398 #define _clz(a) \ 00399 ({ ULONG __value, __arg = (a); \ 00400 asm ("clz\t%0, %1": "=r" (__value): "r" (__arg)); \ 00401 __value; }) 00402 00403 #endif 00404 /* EOF */ Generated on Sat May 26 2012 04:28:28 for ReactOS by
1.7.6.1
|