ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

intrin_x86.h
Go to the documentation of this file.
00001 /*
00002     Compatibility <intrin_x86.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_X86_H_
00029 #define KJK_INTRIN_X86_H_
00030 
00031 /*
00032     FIXME: review all "memory" clobbers, add/remove to match Visual C++
00033     behavior: some "obvious" memory barriers are not present in the Visual C++
00034     implementation - e.g. __stosX; on the other hand, some memory barriers that
00035     *are* present could have been missed
00036 */
00037 
00038 /*
00039     NOTE: this is a *compatibility* header. Some functions may look wrong at
00040     first, but they're only "as wrong" as they would be on Visual C++. Our
00041     priority is compatibility
00042 
00043     NOTE: unlike most people who write inline asm for GCC, I didn't pull the
00044     constraints and the uses of __volatile__ out of my... hat. Do not touch
00045     them. I hate cargo cult programming
00046 
00047     NOTE: be very careful with declaring "memory" clobbers. Some "obvious"
00048     barriers aren't there in Visual C++ (e.g. __stosX)
00049 
00050     NOTE: review all intrinsics with a return value, add/remove __volatile__
00051     where necessary. If an intrinsic whose value is ignored generates a no-op
00052     under Visual C++, __volatile__ must be omitted; if it always generates code
00053     (for example, if it has side effects), __volatile__ must be specified. GCC
00054     will only optimize out non-volatile asm blocks with outputs, so input-only
00055     blocks are safe. Oddities such as the non-volatile 'rdmsr' are intentional
00056     and follow Visual C++ behavior
00057 
00058     NOTE: on GCC 4.1.0, please use the __sync_* built-ins for barriers and
00059     atomic operations. Test the version like this:
00060 
00061     #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
00062         ...
00063 
00064     Pay attention to the type of barrier. Make it match with what Visual C++
00065     would use in the same case
00066 */
00067 
00068 #ifdef __cplusplus
00069 extern "C" {
00070 #endif
00071 
00072 /*** Stack frame juggling ***/
00073 #define _ReturnAddress() (__builtin_return_address(0))
00074 #define _AddressOfReturnAddress() (&(((void **)(__builtin_frame_address(0)))[1]))
00075 /* TODO: __getcallerseflags but how??? */
00076 
00077 /* Maybe the same for x86? */
00078 #ifdef __x86_64__
00079 #define _alloca(s) __builtin_alloca(s)
00080 #endif
00081 
00082 /*** Memory barriers ***/
00083 
00084 __INTRIN_INLINE void _ReadWriteBarrier(void)
00085 {
00086     __asm__ __volatile__("" : : : "memory");
00087 }
00088 
00089 /* GCC only supports full barriers */
00090 #define _ReadBarrier _ReadWriteBarrier
00091 #define _WriteBarrier _ReadWriteBarrier
00092 
00093 __INTRIN_INLINE void _mm_mfence(void)
00094 {
00095     __asm__ __volatile__("mfence" : : : "memory");
00096 }
00097 
00098 __INTRIN_INLINE void _mm_lfence(void)
00099 {
00100     _ReadBarrier();
00101     __asm__ __volatile__("lfence");
00102     _ReadBarrier();
00103 }
00104 
00105 __INTRIN_INLINE void _mm_sfence(void)
00106 {
00107     _WriteBarrier();
00108     __asm__ __volatile__("sfence");
00109     _WriteBarrier();
00110 }
00111 
00112 #ifdef __x86_64__
00113 __INTRIN_INLINE void __faststorefence(void)
00114 {
00115     long local;
00116     __asm__ __volatile__("lock; orl $0, %0;" : : "m"(local));
00117 }
00118 #endif
00119 
00120 
00121 /*** Atomic operations ***/
00122 
00123 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
00124 
00125 __INTRIN_INLINE char _InterlockedCompareExchange8(volatile char * const Destination, const char Exchange, const char Comperand)
00126 {
00127     return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
00128 }
00129 
00130 __INTRIN_INLINE short _InterlockedCompareExchange16(volatile short * const Destination, const short Exchange, const short Comperand)
00131 {
00132     return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
00133 }
00134 
00135 __INTRIN_INLINE long _InterlockedCompareExchange(volatile long * const Destination, const long Exchange, const long Comperand)
00136 {
00137     return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
00138 }
00139 
00140 __INTRIN_INLINE void * _InterlockedCompareExchangePointer(void * volatile * const Destination, void * const Exchange, void * const Comperand)
00141 {
00142     return (void *)__sync_val_compare_and_swap(Destination, Comperand, Exchange);
00143 }
00144 
00145 __INTRIN_INLINE long _InterlockedExchange(volatile long * const Target, const long Value)
00146 {
00147     /* NOTE: __sync_lock_test_and_set would be an acquire barrier, so we force a full barrier */
00148     __sync_synchronize();
00149     return __sync_lock_test_and_set(Target, Value);
00150 }
00151 
00152 #if defined(_M_AMD64)
00153 __INTRIN_INLINE long long _InterlockedExchange64(volatile long long * const Target, const long long Value)
00154 {
00155     /* NOTE: __sync_lock_test_and_set would be an acquire barrier, so we force a full barrier */
00156     __sync_synchronize();
00157     return __sync_lock_test_and_set(Target, Value);
00158 }
00159 #endif
00160 
00161 __INTRIN_INLINE void * _InterlockedExchangePointer(void * volatile * const Target, void * const Value)
00162 {
00163     /* NOTE: ditto */
00164     __sync_synchronize();
00165     return (void *)__sync_lock_test_and_set(Target, Value);
00166 }
00167 
00168 __INTRIN_INLINE long _InterlockedExchangeAdd16(volatile short * const Addend, const short Value)
00169 {
00170     return __sync_fetch_and_add(Addend, Value);
00171 }
00172 
00173 __INTRIN_INLINE long _InterlockedExchangeAdd(volatile long * const Addend, const long Value)
00174 {
00175     return __sync_fetch_and_add(Addend, Value);
00176 }
00177 
00178 #if defined(_M_AMD64)
00179 __INTRIN_INLINE long long _InterlockedExchangeAdd64(volatile long long * const Addend, const long long Value)
00180 {
00181     return __sync_fetch_and_add(Addend, Value);
00182 }
00183 #endif
00184 
00185 __INTRIN_INLINE char _InterlockedAnd8(volatile char * const value, const char mask)
00186 {
00187     return __sync_fetch_and_and(value, mask);
00188 }
00189 
00190 __INTRIN_INLINE short _InterlockedAnd16(volatile short * const value, const short mask)
00191 {
00192     return __sync_fetch_and_and(value, mask);
00193 }
00194 
00195 __INTRIN_INLINE long _InterlockedAnd(volatile long * const value, const long mask)
00196 {
00197     return __sync_fetch_and_and(value, mask);
00198 }
00199 
00200 #if defined(_M_AMD64)
00201 __INTRIN_INLINE long long _InterlockedAnd64(volatile long long * const value, const long long mask)
00202 {
00203     return __sync_fetch_and_and(value, mask);
00204 }
00205 #endif
00206 
00207 __INTRIN_INLINE char _InterlockedOr8(volatile char * const value, const char mask)
00208 {
00209     return __sync_fetch_and_or(value, mask);
00210 }
00211 
00212 __INTRIN_INLINE short _InterlockedOr16(volatile short * const value, const short mask)
00213 {
00214     return __sync_fetch_and_or(value, mask);
00215 }
00216 
00217 __INTRIN_INLINE long _InterlockedOr(volatile long * const value, const long mask)
00218 {
00219     return __sync_fetch_and_or(value, mask);
00220 }
00221 
00222 #if defined(_M_AMD64)
00223 __INTRIN_INLINE long long _InterlockedOr64(volatile long long * const value, const long long mask)
00224 {
00225     return __sync_fetch_and_or(value, mask);
00226 }
00227 #endif
00228 
00229 __INTRIN_INLINE char _InterlockedXor8(volatile char * const value, const char mask)
00230 {
00231     return __sync_fetch_and_xor(value, mask);
00232 }
00233 
00234 __INTRIN_INLINE short _InterlockedXor16(volatile short * const value, const short mask)
00235 {
00236     return __sync_fetch_and_xor(value, mask);
00237 }
00238 
00239 __INTRIN_INLINE long _InterlockedXor(volatile long * const value, const long mask)
00240 {
00241     return __sync_fetch_and_xor(value, mask);
00242 }
00243 
00244 #if defined(_M_AMD64)
00245 __INTRIN_INLINE long long _InterlockedXor64(volatile long long * const value, const long long mask)
00246 {
00247     return __sync_fetch_and_xor(value, mask);
00248 }
00249 #endif
00250 
00251 #else
00252 
00253 __INTRIN_INLINE char _InterlockedCompareExchange8(volatile char * const Destination, const char Exchange, const char Comperand)
00254 {
00255     char retval = Comperand;
00256     __asm__("lock; cmpxchgb %b[Exchange], %[Destination]" : [retval] "+a" (retval) : [Destination] "m" (*Destination), [Exchange] "q" (Exchange) : "memory");
00257     return retval;
00258 }
00259 
00260 __INTRIN_INLINE short _InterlockedCompareExchange16(volatile short * const Destination, const short Exchange, const short Comperand)
00261 {
00262     short retval = Comperand;
00263     __asm__("lock; cmpxchgw %w[Exchange], %[Destination]" : [retval] "+a" (retval) : [Destination] "m" (*Destination), [Exchange] "q" (Exchange): "memory");
00264     return retval;
00265 }
00266 
00267 __INTRIN_INLINE long _InterlockedCompareExchange(volatile long * const Destination, const long Exchange, const long Comperand)
00268 {
00269     long retval = Comperand;
00270     __asm__("lock; cmpxchgl %k[Exchange], %[Destination]" : [retval] "+a" (retval) : [Destination] "m" (*Destination), [Exchange] "q" (Exchange): "memory");
00271     return retval;
00272 }
00273 
00274 __INTRIN_INLINE void * _InterlockedCompareExchangePointer(void * volatile * const Destination, void * const Exchange, void * const Comperand)
00275 {
00276     void * retval = (void *)Comperand;
00277     __asm__("lock; cmpxchgl %k[Exchange], %[Destination]" : [retval] "=a" (retval) : "[retval]" (retval), [Destination] "m" (*Destination), [Exchange] "q" (Exchange) : "memory");
00278     return retval;
00279 }
00280 
00281 __INTRIN_INLINE long _InterlockedExchange(volatile long * const Target, const long Value)
00282 {
00283     long retval = Value;
00284     __asm__("xchgl %[retval], %[Target]" : [retval] "+r" (retval) : [Target] "m" (*Target) : "memory");
00285     return retval;
00286 }
00287 
00288 __INTRIN_INLINE void * _InterlockedExchangePointer(void * volatile * const Target, void * const Value)
00289 {
00290     void * retval = Value;
00291     __asm__("xchgl %[retval], %[Target]" : [retval] "+r" (retval) : [Target] "m" (*Target) : "memory");
00292     return retval;
00293 }
00294 
00295 __INTRIN_INLINE long _InterlockedExchangeAdd16(volatile short * const Addend, const short Value)
00296 {
00297     long retval = Value;
00298     __asm__("lock; xaddw %[retval], %[Addend]" : [retval] "+r" (retval) : [Addend] "m" (*Addend) : "memory");
00299     return retval;
00300 }
00301 
00302 __INTRIN_INLINE long _InterlockedExchangeAdd(volatile long * const Addend, const long Value)
00303 {
00304     long retval = Value;
00305     __asm__("lock; xaddl %[retval], %[Addend]" : [retval] "+r" (retval) : [Addend] "m" (*Addend) : "memory");
00306     return retval;
00307 }
00308 
00309 __INTRIN_INLINE char _InterlockedAnd8(volatile char * const value, const char mask)
00310 {
00311     char x;
00312     char y;
00313 
00314     y = *value;
00315 
00316     do
00317     {
00318         x = y;
00319         y = _InterlockedCompareExchange8(value, x & mask, x);
00320     }
00321     while(y != x);
00322 
00323     return y;
00324 }
00325 
00326 __INTRIN_INLINE short _InterlockedAnd16(volatile short * const value, const short mask)
00327 {
00328     short x;
00329     short y;
00330 
00331     y = *value;
00332 
00333     do
00334     {
00335         x = y;
00336         y = _InterlockedCompareExchange16(value, x & mask, x);
00337     }
00338     while(y != x);
00339 
00340     return y;
00341 }
00342 
00343 __INTRIN_INLINE long _InterlockedAnd(volatile long * const value, const long mask)
00344 {
00345     long x;
00346     long y;
00347 
00348     y = *value;
00349 
00350     do
00351     {
00352         x = y;
00353         y = _InterlockedCompareExchange(value, x & mask, x);
00354     }
00355     while(y != x);
00356 
00357     return y;
00358 }
00359 
00360 __INTRIN_INLINE char _InterlockedOr8(volatile char * const value, const char mask)
00361 {
00362     char x;
00363     char y;
00364 
00365     y = *value;
00366 
00367     do
00368     {
00369         x = y;
00370         y = _InterlockedCompareExchange8(value, x | mask, x);
00371     }
00372     while(y != x);
00373 
00374     return y;
00375 }
00376 
00377 __INTRIN_INLINE short _InterlockedOr16(volatile short * const value, const short mask)
00378 {
00379     short x;
00380     short y;
00381 
00382     y = *value;
00383 
00384     do
00385     {
00386         x = y;
00387         y = _InterlockedCompareExchange16(value, x | mask, x);
00388     }
00389     while(y != x);
00390 
00391     return y;
00392 }
00393 
00394 __INTRIN_INLINE long _InterlockedOr(volatile long * const value, const long mask)
00395 {
00396     long x;
00397     long y;
00398 
00399     y = *value;
00400 
00401     do
00402     {
00403         x = y;
00404         y = _InterlockedCompareExchange(value, x | mask, x);
00405     }
00406     while(y != x);
00407 
00408     return y;
00409 }
00410 
00411 __INTRIN_INLINE char _InterlockedXor8(volatile char * const value, const char mask)
00412 {
00413     char x;
00414     char y;
00415 
00416     y = *value;
00417 
00418     do
00419     {
00420         x = y;
00421         y = _InterlockedCompareExchange8(value, x ^ mask, x);
00422     }
00423     while(y != x);
00424 
00425     return y;
00426 }
00427 
00428 __INTRIN_INLINE short _InterlockedXor16(volatile short * const value, const short mask)
00429 {
00430     short x;
00431     short y;
00432 
00433     y = *value;
00434 
00435     do
00436     {
00437         x = y;
00438         y = _InterlockedCompareExchange16(value, x ^ mask, x);
00439     }
00440     while(y != x);
00441 
00442     return y;
00443 }
00444 
00445 __INTRIN_INLINE long _InterlockedXor(volatile long * const value, const long mask)
00446 {
00447     long x;
00448     long y;
00449 
00450     y = *value;
00451 
00452     do
00453     {
00454         x = y;
00455         y = _InterlockedCompareExchange(value, x ^ mask, x);
00456     }
00457     while(y != x);
00458 
00459     return y;
00460 }
00461 
00462 #endif
00463 
00464 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100 && defined(__x86_64__)
00465 
00466 __INTRIN_INLINE long long _InterlockedCompareExchange64(volatile long long * const Destination, const long long Exchange, const long long Comperand)
00467 {
00468     return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
00469 }
00470 
00471 #else
00472 
00473 __INTRIN_INLINE long long _InterlockedCompareExchange64(volatile long long * const Destination, const long long Exchange, const long long Comperand)
00474 {
00475     long long retval = Comperand;
00476 
00477     __asm__
00478     (
00479         "lock; cmpxchg8b %[Destination]" :
00480         [retval] "+A" (retval) :
00481             [Destination] "m" (*Destination),
00482             "b" ((unsigned long)((Exchange >>  0) & 0xFFFFFFFF)),
00483             "c" ((unsigned long)((Exchange >> 32) & 0xFFFFFFFF)) :
00484         "memory"
00485     );
00486 
00487     return retval;
00488 }
00489 
00490 #endif
00491 
00492 __INTRIN_INLINE long _InterlockedAddLargeStatistic(volatile long long * const Addend, const long Value)
00493 {
00494     __asm__
00495     (
00496         "lock; add %[Value], %[Lo32];"
00497         "jae LABEL%=;"
00498         "lock; adc $0, %[Hi32];"
00499         "LABEL%=:;" :
00500         [Lo32] "+m" (*((volatile long *)(Addend) + 0)), [Hi32] "+m" (*((volatile long *)(Addend) + 1)) :
00501         [Value] "ir" (Value) :
00502         "memory"
00503     );
00504 
00505     return Value;
00506 }
00507 
00508 __INTRIN_INLINE long _InterlockedDecrement(volatile long * const lpAddend)
00509 {
00510     return _InterlockedExchangeAdd(lpAddend, -1) - 1;
00511 }
00512 
00513 __INTRIN_INLINE long _InterlockedIncrement(volatile long * const lpAddend)
00514 {
00515     return _InterlockedExchangeAdd(lpAddend, 1) + 1;
00516 }
00517 
00518 __INTRIN_INLINE short _InterlockedDecrement16(volatile short * const lpAddend)
00519 {
00520     return _InterlockedExchangeAdd16(lpAddend, -1) - 1;
00521 }
00522 
00523 __INTRIN_INLINE short _InterlockedIncrement16(volatile short * const lpAddend)
00524 {
00525     return _InterlockedExchangeAdd16(lpAddend, 1) + 1;
00526 }
00527 
00528 #if defined(_M_AMD64)
00529 __INTRIN_INLINE long long _InterlockedDecrement64(volatile long long * const lpAddend)
00530 {
00531     return _InterlockedExchangeAdd64(lpAddend, -1) - 1;
00532 }
00533 
00534 __INTRIN_INLINE long long _InterlockedIncrement64(volatile long long * const lpAddend)
00535 {
00536     return _InterlockedExchangeAdd64(lpAddend, 1) + 1;
00537 }
00538 #endif
00539 
00540 __INTRIN_INLINE unsigned char _interlockedbittestandreset(volatile long * a, const long b)
00541 {
00542     unsigned char retval;
00543     __asm__("lock; btrl %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval), [a] "+m" (*a) : [b] "Ir" (b) : "memory");
00544     return retval;
00545 }
00546 
00547 #if defined(_M_AMD64)
00548 __INTRIN_INLINE unsigned char _interlockedbittestandreset64(volatile long long * a, const long long b)
00549 {
00550     unsigned char retval;
00551     __asm__("lock; btrq %[b], %[a]; setb %b[retval]" : [retval] "=r" (retval), [a] "+m" (*a) : [b] "Ir" (b) : "memory");
00552     return retval;
00553 }
00554 #endif
00555 
00556 __INTRIN_INLINE unsigned char _interlockedbittestandset(volatile long * a, const long b)
00557 {
00558     unsigned char retval;
00559     __asm__("lock; btsl %[b], %[a]; setc %b[retval]" : [retval] "=q" (retval), [a] "+m" (*a) : [b] "Ir" (b) : "memory");
00560     return retval;
00561 }
00562 
00563 #if defined(_M_AMD64)
00564 __INTRIN_INLINE unsigned char _interlockedbittestandset64(volatile long long * a, const long long b)
00565 {
00566     unsigned char retval;
00567     __asm__("lock; btsq %[b], %[a]; setc %b[retval]" : [retval] "=r" (retval), [a] "+m" (*a) : [b] "Ir" (b) : "memory");
00568     return retval;
00569 }
00570 #endif
00571 
00572 /*** String operations ***/
00573 /* NOTE: we don't set a memory clobber in the __stosX functions because Visual C++ doesn't */
00574 __INTRIN_INLINE void __stosb(unsigned char * Dest, const unsigned char Data, size_t Count)
00575 {
00576     __asm__ __volatile__
00577     (
00578         "rep; stosb" :
00579         [Dest] "=D" (Dest), [Count] "=c" (Count) :
00580         "[Dest]" (Dest), "a" (Data), "[Count]" (Count)
00581     );
00582 }
00583 
00584 __INTRIN_INLINE void __stosw(unsigned short * Dest, const unsigned short Data, size_t Count)
00585 {
00586     __asm__ __volatile__
00587     (
00588         "rep; stosw" :
00589         [Dest] "=D" (Dest), [Count] "=c" (Count) :
00590         "[Dest]" (Dest), "a" (Data), "[Count]" (Count)
00591     );
00592 }
00593 
00594 __INTRIN_INLINE void __stosd(unsigned long * Dest, const unsigned long Data, size_t Count)
00595 {
00596     __asm__ __volatile__
00597     (
00598         "rep; stosl" :
00599         [Dest] "=D" (Dest), [Count] "=c" (Count) :
00600         "[Dest]" (Dest), "a" (Data), "[Count]" (Count)
00601     );
00602 }
00603 
00604 #ifdef _M_AMD64
00605 __INTRIN_INLINE void __stosq(unsigned __int64 * Dest, const unsigned __int64 Data, size_t Count)
00606 {
00607     __asm__ __volatile__
00608     (
00609         "rep; stosq" :
00610         [Dest] "=D" (Dest), [Count] "=c" (Count) :
00611         "[Dest]" (Dest), "a" (Data), "[Count]" (Count)
00612     );
00613 }
00614 #endif
00615 
00616 __INTRIN_INLINE void __movsb(unsigned char * Destination, const unsigned char * Source, size_t Count)
00617 {
00618     __asm__ __volatile__
00619     (
00620         "rep; movsb" :
00621         [Destination] "=D" (Destination), [Source] "=S" (Source), [Count] "=c" (Count) :
00622         "[Destination]" (Destination), "[Source]" (Source), "[Count]" (Count)
00623     );
00624 }
00625 
00626 __INTRIN_INLINE void __movsw(unsigned short * Destination, const unsigned short * Source, size_t Count)
00627 {
00628     __asm__ __volatile__
00629     (
00630         "rep; movsw" :
00631         [Destination] "=D" (Destination), [Source] "=S" (Source), [Count] "=c" (Count) :
00632         "[Destination]" (Destination), "[Source]" (Source), "[Count]" (Count)
00633     );
00634 }
00635 
00636 __INTRIN_INLINE void __movsd(unsigned long * Destination, const unsigned long * Source, size_t Count)
00637 {
00638     __asm__ __volatile__
00639     (
00640         "rep; movsd" :
00641         [Destination] "=D" (Destination), [Source] "=S" (Source), [Count] "=c" (Count) :
00642         "[Destination]" (Destination), "[Source]" (Source), "[Count]" (Count)
00643     );
00644 }
00645 
00646 #ifdef _M_AMD64
00647 __INTRIN_INLINE void __movsq(unsigned long * Destination, const unsigned long * Source, size_t Count)
00648 {
00649     __asm__ __volatile__
00650     (
00651         "rep; movsq" :
00652         [Destination] "=D" (Destination), [Source] "=S" (Source), [Count] "=c" (Count) :
00653         "[Destination]" (Destination), "[Source]" (Source), "[Count]" (Count)
00654     );
00655 }
00656 #endif
00657 
00658 #if defined(_M_AMD64)
00659 /*** GS segment addressing ***/
00660 
00661 __INTRIN_INLINE void __writegsbyte(const unsigned long Offset, const unsigned char Data)
00662 {
00663     __asm__ __volatile__("movb %b[Data], %%gs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "ir" (Data) : "memory");
00664 }
00665 
00666 __INTRIN_INLINE void __writegsword(const unsigned long Offset, const unsigned short Data)
00667 {
00668     __asm__ __volatile__("movw %w[Data], %%gs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "ir" (Data) : "memory");
00669 }
00670 
00671 __INTRIN_INLINE void __writegsdword(const unsigned long Offset, const unsigned long Data)
00672 {
00673     __asm__ __volatile__("movl %k[Data], %%gs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "ir" (Data) : "memory");
00674 }
00675 
00676 __INTRIN_INLINE void __writegsqword(const unsigned long Offset, const unsigned __int64 Data)
00677 {
00678     __asm__ __volatile__("movq %q[Data], %%gs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "ir" (Data) : "memory");
00679 }
00680 
00681 __INTRIN_INLINE unsigned char __readgsbyte(const unsigned long Offset)
00682 {
00683     unsigned char value;
00684     __asm__ __volatile__("movb %%gs:%a[Offset], %b[value]" : [value] "=r" (value) : [Offset] "ir" (Offset));
00685     return value;
00686 }
00687 
00688 __INTRIN_INLINE unsigned short __readgsword(const unsigned long Offset)
00689 {
00690     unsigned short value;
00691     __asm__ __volatile__("movw %%gs:%a[Offset], %w[value]" : [value] "=r" (value) : [Offset] "ir" (Offset));
00692     return value;
00693 }
00694 
00695 __INTRIN_INLINE unsigned long __readgsdword(const unsigned long Offset)
00696 {
00697     unsigned long value;
00698     __asm__ __volatile__("movl %%gs:%a[Offset], %k[value]" : [value] "=r" (value) : [Offset] "ir" (Offset));
00699     return value;
00700 }
00701 
00702 __INTRIN_INLINE unsigned __int64 __readgsqword(const unsigned long Offset)
00703 {
00704     unsigned __int64 value;
00705     __asm__ __volatile__("movq %%gs:%a[Offset], %q[value]" : [value] "=r" (value) : [Offset] "ir" (Offset));
00706     return value;
00707 }
00708 
00709 __INTRIN_INLINE void __incgsbyte(const unsigned long Offset)
00710 {
00711     __asm__ __volatile__("incb %%gs:%a[Offset]" : : [Offset] "ir" (Offset) : "memory");
00712 }
00713 
00714 __INTRIN_INLINE void __incgsword(const unsigned long Offset)
00715 {
00716     __asm__ __volatile__("incw %%gs:%a[Offset]" : : [Offset] "ir" (Offset) : "memory");
00717 }
00718 
00719 __INTRIN_INLINE void __incgsdword(const unsigned long Offset)
00720 {
00721     __asm__ __volatile__("incl %%gs:%a[Offset]" : : [Offset] "ir" (Offset) : "memory");
00722 }
00723 
00724 __INTRIN_INLINE void __addgsbyte(const unsigned long Offset, const unsigned char Data)
00725 {
00726     __asm__ __volatile__("addb %b[Data], %%gs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "ir" (Data) : "memory");
00727 }
00728 
00729 __INTRIN_INLINE void __addgsword(const unsigned long Offset, const unsigned short Data)
00730 {
00731     __asm__ __volatile__("addw %w[Data], %%gs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "ir" (Data) : "memory");
00732 }
00733 
00734 __INTRIN_INLINE void __addgsdword(const unsigned long Offset, const unsigned int Data)
00735 {
00736     __asm__ __volatile__("addl %k[Data], %%gs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "ir" (Data) : "memory");
00737 }
00738 
00739 __INTRIN_INLINE void __addgsqword(const unsigned long Offset, const unsigned __int64 Data)
00740 {
00741     __asm__ __volatile__("addq %k[Data], %%gs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "ir" (Data) : "memory");
00742 }
00743 
00744 #else
00745 /*** FS segment addressing ***/
00746 __INTRIN_INLINE void __writefsbyte(const unsigned long Offset, const unsigned char Data)
00747 {
00748     __asm__ __volatile__("movb %b[Data], %%fs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "iq" (Data) : "memory");
00749 }
00750 
00751 __INTRIN_INLINE void __writefsword(const unsigned long Offset, const unsigned short Data)
00752 {
00753     __asm__ __volatile__("movw %w[Data], %%fs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "ir" (Data) : "memory");
00754 }
00755 
00756 __INTRIN_INLINE void __writefsdword(const unsigned long Offset, const unsigned long Data)
00757 {
00758     __asm__ __volatile__("movl %k[Data], %%fs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "ir" (Data) : "memory");
00759 }
00760 
00761 __INTRIN_INLINE unsigned char __readfsbyte(const unsigned long Offset)
00762 {
00763     unsigned char value;
00764     __asm__ __volatile__("movb %%fs:%a[Offset], %b[value]" : [value] "=q" (value) : [Offset] "ir" (Offset));
00765     return value;
00766 }
00767 
00768 __INTRIN_INLINE unsigned short __readfsword(const unsigned long Offset)
00769 {
00770     unsigned short value;
00771     __asm__ __volatile__("movw %%fs:%a[Offset], %w[value]" : [value] "=r" (value) : [Offset] "ir" (Offset));
00772     return value;
00773 }
00774 
00775 __INTRIN_INLINE unsigned long __readfsdword(const unsigned long Offset)
00776 {
00777     unsigned long value;
00778     __asm__ __volatile__("movl %%fs:%a[Offset], %k[value]" : [value] "=r" (value) : [Offset] "ir" (Offset));
00779     return value;
00780 }
00781 
00782 __INTRIN_INLINE void __incfsbyte(const unsigned long Offset)
00783 {
00784     __asm__ __volatile__("incb %%fs:%a[Offset]" : : [Offset] "ir" (Offset) : "memory");
00785 }
00786 
00787 __INTRIN_INLINE void __incfsword(const unsigned long Offset)
00788 {
00789     __asm__ __volatile__("incw %%fs:%a[Offset]" : : [Offset] "ir" (Offset) : "memory");
00790 }
00791 
00792 __INTRIN_INLINE void __incfsdword(const unsigned long Offset)
00793 {
00794     __asm__ __volatile__("incl %%fs:%a[Offset]" : : [Offset] "ir" (Offset) : "memory");
00795 }
00796 
00797 /* NOTE: the bizarre implementation of __addfsxxx mimics the broken Visual C++ behavior */
00798 __INTRIN_INLINE void __addfsbyte(const unsigned long Offset, const unsigned char Data)
00799 {
00800     if(!__builtin_constant_p(Offset))
00801         __asm__ __volatile__("addb %b[Offset], %%fs:%a[Offset]" : : [Offset] "r" (Offset) : "memory");
00802     else
00803         __asm__ __volatile__("addb %b[Data], %%fs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "iq" (Data) : "memory");
00804 }
00805 
00806 __INTRIN_INLINE void __addfsword(const unsigned long Offset, const unsigned short Data)
00807 {
00808     if(!__builtin_constant_p(Offset))
00809         __asm__ __volatile__("addw %w[Offset], %%fs:%a[Offset]" : : [Offset] "r" (Offset) : "memory");
00810     else
00811         __asm__ __volatile__("addw %w[Data], %%fs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "iq" (Data) : "memory");
00812 }
00813 
00814 __INTRIN_INLINE void __addfsdword(const unsigned long Offset, const unsigned int Data)
00815 {
00816     if(!__builtin_constant_p(Offset))
00817         __asm__ __volatile__("addl %k[Offset], %%fs:%a[Offset]" : : [Offset] "r" (Offset) : "memory");
00818     else
00819         __asm__ __volatile__("addl %k[Data], %%fs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "iq" (Data) : "memory");
00820 }
00821 #endif
00822 
00823 
00824 /*** Bit manipulation ***/
00825 __INTRIN_INLINE unsigned char _BitScanForward(unsigned long * const Index, const unsigned long Mask)
00826 {
00827     __asm__("bsfl %[Mask], %[Index]" : [Index] "=r" (*Index) : [Mask] "mr" (Mask));
00828     return Mask ? 1 : 0;
00829 }
00830 
00831 __INTRIN_INLINE unsigned char _BitScanReverse(unsigned long * const Index, const unsigned long Mask)
00832 {
00833     __asm__("bsrl %[Mask], %[Index]" : [Index] "=r" (*Index) : [Mask] "mr" (Mask));
00834     return Mask ? 1 : 0;
00835 }
00836 
00837 /* NOTE: again, the bizarre implementation follows Visual C++ */
00838 __INTRIN_INLINE unsigned char _bittest(const long * const a, const long b)
00839 {
00840     unsigned char retval;
00841 
00842     if(__builtin_constant_p(b))
00843         __asm__("bt %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*(a + (b / 32))), [b] "Ir" (b % 32));
00844     else
00845         __asm__("bt %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*a), [b] "r" (b));
00846 
00847     return retval;
00848 }
00849 
00850 #ifdef _M_AMD64
00851 __INTRIN_INLINE unsigned char _bittest64(const __int64 * const a, const __int64 b)
00852 {
00853     unsigned char retval;
00854 
00855     if(__builtin_constant_p(b))
00856         __asm__("bt %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*(a + (b / 64))), [b] "Ir" (b % 64));
00857     else
00858         __asm__("bt %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*a), [b] "r" (b));
00859 
00860     return retval;
00861 }
00862 #endif
00863 
00864 __INTRIN_INLINE unsigned char _bittestandcomplement(long * const a, const long b)
00865 {
00866     unsigned char retval;
00867 
00868     if(__builtin_constant_p(b))
00869         __asm__("btc %[b], %[a]; setb %b[retval]" : [a] "+mr" (*(a + (b / 32))), [retval] "=q" (retval) : [b] "Ir" (b % 32));
00870     else
00871         __asm__("btc %[b], %[a]; setb %b[retval]" : [a] "+mr" (*a), [retval] "=q" (retval) : [b] "r" (b));
00872 
00873     return retval;
00874 }
00875 
00876 __INTRIN_INLINE unsigned char _bittestandreset(long * const a, const long b)
00877 {
00878     unsigned char retval;
00879 
00880     if(__builtin_constant_p(b))
00881         __asm__("btr %[b], %[a]; setb %b[retval]" : [a] "+mr" (*(a + (b / 32))), [retval] "=q" (retval) : [b] "Ir" (b % 32));
00882     else
00883         __asm__("btr %[b], %[a]; setb %b[retval]" : [a] "+mr" (*a), [retval] "=q" (retval) : [b] "r" (b));
00884 
00885     return retval;
00886 }
00887 
00888 __INTRIN_INLINE unsigned char _bittestandset(long * const a, const long b)
00889 {
00890     unsigned char retval;
00891 
00892     if(__builtin_constant_p(b))
00893         __asm__("bts %[b], %[a]; setb %b[retval]" : [a] "+mr" (*(a + (b / 32))), [retval] "=q" (retval) : [b] "Ir" (b % 32));
00894     else
00895         __asm__("bts %[b], %[a]; setb %b[retval]" : [a] "+mr" (*a), [retval] "=q" (retval) : [b] "r" (b));
00896 
00897     return retval;
00898 }
00899 
00900 __INTRIN_INLINE unsigned char _rotl8(unsigned char value, unsigned char shift)
00901 {
00902     unsigned char retval;
00903     __asm__("rolb %b[shift], %b[retval]" : [retval] "=rm" (retval) : "[retval]" (value), [shift] "Nc" (shift));
00904     return retval;
00905 }
00906 
00907 __INTRIN_INLINE unsigned short _rotl16(unsigned short value, unsigned char shift)
00908 {
00909     unsigned short retval;
00910     __asm__("rolw %b[shift], %w[retval]" : [retval] "=rm" (retval) : "[retval]" (value), [shift] "Nc" (shift));
00911     return retval;
00912 }
00913 
00914 __INTRIN_INLINE unsigned int _rotl(unsigned int value, int shift)
00915 {
00916     unsigned long retval;
00917     __asm__("roll %b[shift], %k[retval]" : [retval] "=rm" (retval) : "[retval]" (value), [shift] "Nc" (shift));
00918     return retval;
00919 }
00920 
00921 __INTRIN_INLINE unsigned int _rotr(unsigned int value, int shift)
00922 {
00923     unsigned long retval;
00924     __asm__("rorl %b[shift], %k[retval]" : [retval] "=rm" (retval) : "[retval]" (value), [shift] "Nc" (shift));
00925     return retval;
00926 }
00927 
00928 __INTRIN_INLINE unsigned char _rotr8(unsigned char value, unsigned char shift)
00929 {
00930     unsigned char retval;
00931     __asm__("rorb %b[shift], %b[retval]" : [retval] "=qm" (retval) : "[retval]" (value), [shift] "Nc" (shift));
00932     return retval;
00933 }
00934 
00935 __INTRIN_INLINE unsigned short _rotr16(unsigned short value, unsigned char shift)
00936 {
00937     unsigned short retval;
00938     __asm__("rorw %b[shift], %w[retval]" : [retval] "=rm" (retval) : "[retval]" (value), [shift] "Nc" (shift));
00939     return retval;
00940 }
00941 
00942 /*
00943     NOTE: in __ll_lshift, __ll_rshift and __ull_rshift we use the "A"
00944     constraint (edx:eax) for the Mask argument, because it's the only way GCC
00945     can pass 64-bit operands around - passing the two 32 bit parts separately
00946     just confuses it. Also we declare Bit as an int and then truncate it to
00947     match Visual C++ behavior
00948 */
00949 __INTRIN_INLINE unsigned long long __ll_lshift(const unsigned long long Mask, const int Bit)
00950 {
00951     unsigned long long retval = Mask;
00952 
00953     __asm__
00954     (
00955         "shldl %b[Bit], %%eax, %%edx; sall %b[Bit], %%eax" :
00956         "+A" (retval) :
00957         [Bit] "Nc" ((unsigned char)((unsigned long)Bit) & 0xFF)
00958     );
00959 
00960     return retval;
00961 }
00962 
00963 __INTRIN_INLINE long long __ll_rshift(const long long Mask, const int Bit)
00964 {
00965     unsigned long long retval = Mask;
00966 
00967     __asm__
00968     (
00969         "shldl %b[Bit], %%eax, %%edx; sarl %b[Bit], %%eax" :
00970         "+A" (retval) :
00971         [Bit] "Nc" ((unsigned char)((unsigned long)Bit) & 0xFF)
00972     );
00973 
00974     return retval;
00975 }
00976 
00977 __INTRIN_INLINE unsigned long long __ull_rshift(const unsigned long long Mask, int Bit)
00978 {
00979     unsigned long long retval = Mask;
00980 
00981     __asm__
00982     (
00983         "shrdl %b[Bit], %%eax, %%edx; shrl %b[Bit], %%eax" :
00984         "+A" (retval) :
00985         [Bit] "Nc" ((unsigned char)((unsigned long)Bit) & 0xFF)
00986     );
00987 
00988     return retval;
00989 }
00990 
00991 __INTRIN_INLINE unsigned short _byteswap_ushort(unsigned short value)
00992 {
00993     unsigned short retval;
00994     __asm__("rorw $8, %w[retval]" : [retval] "=rm" (retval) : "[retval]" (value));
00995     return retval;
00996 }
00997 
00998 __INTRIN_INLINE unsigned long _byteswap_ulong(unsigned long value)
00999 {
01000     unsigned long retval;
01001     __asm__("bswapl %[retval]" : [retval] "=r" (retval) : "[retval]" (value));
01002     return retval;
01003 }
01004 
01005 #ifdef _M_AMD64
01006 __INTRIN_INLINE unsigned __int64 _byteswap_uint64(unsigned __int64 value)
01007 {
01008     unsigned __int64 retval;
01009     __asm__("bswapq %[retval]" : [retval] "=r" (retval) : "[retval]" (value));
01010     return retval;
01011 }
01012 #else
01013 __INTRIN_INLINE unsigned __int64 _byteswap_uint64(unsigned __int64 value)
01014 {
01015     union {
01016         __int64 int64part;
01017         struct {
01018             unsigned long lowpart;
01019             unsigned long hipart;
01020         };
01021     } retval;
01022     retval.int64part = value;
01023     __asm__("bswapl %[lowpart]\n"
01024             "bswapl %[hipart]\n"
01025             : [lowpart] "=r" (retval.hipart), [hipart] "=r" (retval.lowpart)  : "[lowpart]" (retval.lowpart), "[hipart]" (retval.hipart) );
01026     return retval.int64part;
01027 }
01028 #endif
01029 
01030 /*** 64-bit math ***/
01031 __INTRIN_INLINE long long __emul(const int a, const int b)
01032 {
01033     long long retval;
01034     __asm__("imull %[b]" : "=A" (retval) : [a] "a" (a), [b] "rm" (b));
01035     return retval;
01036 }
01037 
01038 __INTRIN_INLINE unsigned long long __emulu(const unsigned int a, const unsigned int b)
01039 {
01040     unsigned long long retval;
01041     __asm__("mull %[b]" : "=A" (retval) : [a] "a" (a), [b] "rm" (b));
01042     return retval;
01043 }
01044 
01045 #ifdef _M_AMD64
01046 
01047 __INTRIN_INLINE __int64 __mulh(__int64 a, __int64 b)
01048 {
01049     __int64 retval;
01050     __asm__("imulq %[b]" : "=d" (retval) : [a] "a" (a), [b] "rm" (b));
01051     return retval;
01052 }
01053 
01054 __INTRIN_INLINE unsigned __int64 __umulh(unsigned __int64 a, unsigned __int64 b)
01055 {
01056     unsigned __int64 retval;
01057     __asm__("mulq %[b]" : "=d" (retval) : [a] "a" (a), [b] "rm" (b));
01058     return retval;
01059 }
01060 
01061 #endif
01062 
01063 /*** Port I/O ***/
01064 __INTRIN_INLINE unsigned char __inbyte(const unsigned short Port)
01065 {
01066     unsigned char byte;
01067     __asm__ __volatile__("inb %w[Port], %b[byte]" : [byte] "=a" (byte) : [Port] "Nd" (Port));
01068     return byte;
01069 }
01070 
01071 __INTRIN_INLINE unsigned short __inword(const unsigned short Port)
01072 {
01073     unsigned short word;
01074     __asm__ __volatile__("inw %w[Port], %w[word]" : [word] "=a" (word) : [Port] "Nd" (Port));
01075     return word;
01076 }
01077 
01078 __INTRIN_INLINE unsigned long __indword(const unsigned short Port)
01079 {
01080     unsigned long dword;
01081     __asm__ __volatile__("inl %w[Port], %k[dword]" : [dword] "=a" (dword) : [Port] "Nd" (Port));
01082     return dword;
01083 }
01084 
01085 __INTRIN_INLINE void __inbytestring(unsigned short Port, unsigned char * Buffer, unsigned long Count)
01086 {
01087     __asm__ __volatile__
01088     (
01089         "rep; insb" :
01090         [Buffer] "=D" (Buffer), [Count] "=c" (Count) :
01091         "d" (Port), "[Buffer]" (Buffer), "[Count]" (Count) :
01092         "memory"
01093     );
01094 }
01095 
01096 __INTRIN_INLINE void __inwordstring(unsigned short Port, unsigned short * Buffer, unsigned long Count)
01097 {
01098     __asm__ __volatile__
01099     (
01100         "rep; insw" :
01101         [Buffer] "=D" (Buffer), [Count] "=c" (Count) :
01102         "d" (Port), "[Buffer]" (Buffer), "[Count]" (Count) :
01103         "memory"
01104     );
01105 }
01106 
01107 __INTRIN_INLINE void __indwordstring(unsigned short Port, unsigned long * Buffer, unsigned long Count)
01108 {
01109     __asm__ __volatile__
01110     (
01111         "rep; insl" :
01112         [Buffer] "=D" (Buffer), [Count] "=c" (Count) :
01113         "d" (Port), "[Buffer]" (Buffer), "[Count]" (Count) :
01114         "memory"
01115     );
01116 }
01117 
01118 __INTRIN_INLINE void __outbyte(unsigned short const Port, const unsigned char Data)
01119 {
01120     __asm__ __volatile__("outb %b[Data], %w[Port]" : : [Port] "Nd" (Port), [Data] "a" (Data));
01121 }
01122 
01123 __INTRIN_INLINE void __outword(unsigned short const Port, const unsigned short Data)
01124 {
01125     __asm__ __volatile__("outw %w[Data], %w[Port]" : : [Port] "Nd" (Port), [Data] "a" (Data));
01126 }
01127 
01128 __INTRIN_INLINE void __outdword(unsigned short const Port, const unsigned long Data)
01129 {
01130     __asm__ __volatile__("outl %k[Data], %w[Port]" : : [Port] "Nd" (Port), [Data] "a" (Data));
01131 }
01132 
01133 __INTRIN_INLINE void __outbytestring(unsigned short const Port, const unsigned char * const Buffer, const unsigned long Count)
01134 {
01135     __asm__ __volatile__("rep; outsb" : : [Port] "d" (Port), [Buffer] "S" (Buffer), "c" (Count));
01136 }
01137 
01138 __INTRIN_INLINE void __outwordstring(unsigned short const Port, const unsigned short * const Buffer, const unsigned long Count)
01139 {
01140     __asm__ __volatile__("rep; outsw" : : [Port] "d" (Port), [Buffer] "S" (Buffer), "c" (Count));
01141 }
01142 
01143 __INTRIN_INLINE void __outdwordstring(unsigned short const Port, const unsigned long * const Buffer, const unsigned long Count)
01144 {
01145     __asm__ __volatile__("rep; outsl" : : [Port] "d" (Port), [Buffer] "S" (Buffer), "c" (Count));
01146 }
01147 
01148 __INTRIN_INLINE int _inp(unsigned short Port)
01149 {
01150     return __inbyte(Port);
01151 }
01152 
01153 __INTRIN_INLINE unsigned short _inpw(unsigned short Port)
01154 {
01155     return __inword(Port);
01156 }
01157 
01158 __INTRIN_INLINE unsigned long _inpd(unsigned short Port)
01159 {
01160     return __indword(Port);
01161 }
01162 
01163 __INTRIN_INLINE int _outp(unsigned short Port, int databyte)
01164 {
01165     __outbyte(Port, databyte);
01166     return databyte;
01167 }
01168 
01169 __INTRIN_INLINE unsigned short _outpw(unsigned short Port, unsigned short dataword)
01170 {
01171     __outword(Port, dataword);
01172     return dataword;
01173 }
01174 
01175 __INTRIN_INLINE unsigned long _outpd(unsigned short Port, unsigned long dataword)
01176 {
01177     __outdword(Port, dataword);
01178     return dataword;
01179 }
01180 
01181 
01182 /*** System information ***/
01183 __INTRIN_INLINE void __cpuid(int CPUInfo[], const int InfoType)
01184 {
01185     __asm__ __volatile__("cpuid" : "=a" (CPUInfo[0]), "=b" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3]) : "a" (InfoType));
01186 }
01187 
01188 __INTRIN_INLINE unsigned long long __rdtsc(void)
01189 {
01190 #ifdef _M_AMD64
01191     unsigned long long low, high;
01192     __asm__ __volatile__("rdtsc" : "=a"(low), "=d"(high));
01193     return low | (high << 32);
01194 #else
01195     unsigned long long retval;
01196     __asm__ __volatile__("rdtsc" : "=A"(retval));
01197     return retval;
01198 #endif
01199 }
01200 
01201 __INTRIN_INLINE void __writeeflags(uintptr_t Value)
01202 {
01203     __asm__ __volatile__("push %0\n popf" : : "rim"(Value));
01204 }
01205 
01206 __INTRIN_INLINE uintptr_t __readeflags(void)
01207 {
01208     uintptr_t retval;
01209     __asm__ __volatile__("pushf\n pop %0" : "=rm"(retval));
01210     return retval;
01211 }
01212 
01213 /*** Interrupts ***/
01214 #ifdef __clang__
01215 #define __debugbreak() __asm__("int $3")
01216 #else
01217 __INTRIN_INLINE void __debugbreak(void)
01218 {
01219     __asm__("int $3");
01220 }
01221 #endif
01222 
01223 __INTRIN_INLINE void __int2c(void)
01224 {
01225     __asm__("int $0x2c");
01226 }
01227 
01228 __INTRIN_INLINE void _disable(void)
01229 {
01230     __asm__("cli" : : : "memory");
01231 }
01232 
01233 __INTRIN_INLINE void _enable(void)
01234 {
01235     __asm__("sti" : : : "memory");
01236 }
01237 
01238 __INTRIN_INLINE void __halt(void)
01239 {
01240     __asm__("hlt\n\t" : : : "memory");
01241 }
01242 
01243 /*** Protected memory management ***/
01244 
01245 #ifdef _M_AMD64
01246 __INTRIN_INLINE void __writecr0(const unsigned __int64 Data)
01247 {
01248     __asm__("mov %[Data], %%cr0" : : [Data] "r" (Data) : "memory");
01249 }
01250 
01251 __INTRIN_INLINE void __writecr3(const unsigned __int64 Data)
01252 {
01253     __asm__("mov %[Data], %%cr3" : : [Data] "r" (Data) : "memory");
01254 }
01255 
01256 __INTRIN_INLINE void __writecr4(const unsigned __int64 Data)
01257 {
01258     __asm__("mov %[Data], %%cr4" : : [Data] "r" (Data) : "memory");
01259 }
01260 
01261 __INTRIN_INLINE void __writecr8(const unsigned __int64 Data)
01262 {
01263     __asm__("mov %[Data], %%cr8" : : [Data] "r" (Data) : "memory");
01264 }
01265 
01266 __INTRIN_INLINE unsigned __int64 __readcr0(void)
01267 {
01268     unsigned __int64 value;
01269     __asm__ __volatile__("mov %%cr0, %[value]" : [value] "=r" (value));
01270     return value;
01271 }
01272 
01273 __INTRIN_INLINE unsigned __int64 __readcr2(void)
01274 {
01275     unsigned __int64 value;
01276     __asm__ __volatile__("mov %%cr2, %[value]" : [value] "=r" (value));
01277     return value;
01278 }
01279 
01280 __INTRIN_INLINE unsigned __int64 __readcr3(void)
01281 {
01282     unsigned __int64 value;
01283     __asm__ __volatile__("mov %%cr3, %[value]" : [value] "=r" (value));
01284     return value;
01285 }
01286 
01287 __INTRIN_INLINE unsigned __int64 __readcr4(void)
01288 {
01289     unsigned __int64 value;
01290     __asm__ __volatile__("mov %%cr4, %[value]" : [value] "=r" (value));
01291     return value;
01292 }
01293 
01294 __INTRIN_INLINE unsigned __int64 __readcr8(void)
01295 {
01296     unsigned __int64 value;
01297     __asm__ __volatile__("movq %%cr8, %q[value]" : [value] "=r" (value));
01298     return value;
01299 }
01300 #else
01301 __INTRIN_INLINE void __writecr0(const unsigned int Data)
01302 {
01303     __asm__("mov %[Data], %%cr0" : : [Data] "r" (Data) : "memory");
01304 }
01305 
01306 __INTRIN_INLINE void __writecr3(const unsigned int Data)
01307 {
01308     __asm__("mov %[Data], %%cr3" : : [Data] "r" (Data) : "memory");
01309 }
01310 
01311 __INTRIN_INLINE void __writecr4(const unsigned int Data)
01312 {
01313     __asm__("mov %[Data], %%cr4" : : [Data] "r" (Data) : "memory");
01314 }
01315 
01316 __INTRIN_INLINE unsigned long __readcr0(void)
01317 {
01318     unsigned long value;
01319     __asm__ __volatile__("mov %%cr0, %[value]" : [value] "=r" (value));
01320     return value;
01321 }
01322 
01323 __INTRIN_INLINE unsigned long __readcr2(void)
01324 {
01325     unsigned long value;
01326     __asm__ __volatile__("mov %%cr2, %[value]" : [value] "=r" (value));
01327     return value;
01328 }
01329 
01330 __INTRIN_INLINE unsigned long __readcr3(void)
01331 {
01332     unsigned long value;
01333     __asm__ __volatile__("mov %%cr3, %[value]" : [value] "=r" (value));
01334     return value;
01335 }
01336 
01337 __INTRIN_INLINE unsigned long __readcr4(void)
01338 {
01339     unsigned long value;
01340     __asm__ __volatile__("mov %%cr4, %[value]" : [value] "=r" (value));
01341     return value;
01342 }
01343 #endif
01344 
01345 #ifdef _M_AMD64
01346 __INTRIN_INLINE unsigned __int64 __readdr(unsigned int reg)
01347 {
01348     unsigned __int64 value;
01349     switch (reg)
01350     {
01351         case 0:
01352             __asm__ __volatile__("movq %%dr0, %q[value]" : [value] "=r" (value));
01353             break;
01354         case 1:
01355             __asm__ __volatile__("movq %%dr1, %q[value]" : [value] "=r" (value));
01356             break;
01357         case 2:
01358             __asm__ __volatile__("movq %%dr2, %q[value]" : [value] "=r" (value));
01359             break;
01360         case 3:
01361             __asm__ __volatile__("movq %%dr3, %q[value]" : [value] "=r" (value));
01362             break;
01363         case 4:
01364             __asm__ __volatile__("movq %%dr4, %q[value]" : [value] "=r" (value));
01365             break;
01366         case 5:
01367             __asm__ __volatile__("movq %%dr5, %q[value]" : [value] "=r" (value));
01368             break;
01369         case 6:
01370             __asm__ __volatile__("movq %%dr6, %q[value]" : [value] "=r" (value));
01371             break;
01372         case 7:
01373             __asm__ __volatile__("movq %%dr7, %q[value]" : [value] "=r" (value));
01374             break;
01375     }
01376     return value;
01377 }
01378 
01379 __INTRIN_INLINE void __writedr(unsigned reg, unsigned __int64 value)
01380 {
01381     switch (reg)
01382     {
01383         case 0:
01384             __asm__("movq %q[value], %%dr0" : : [value] "r" (value) : "memory");
01385             break;
01386         case 1:
01387             __asm__("movq %q[value], %%dr1" : : [value] "r" (value) : "memory");
01388             break;
01389         case 2:
01390             __asm__("movq %q[value], %%dr2" : : [value] "r" (value) : "memory");
01391             break;
01392         case 3:
01393             __asm__("movq %q[value], %%dr3" : : [value] "r" (value) : "memory");
01394             break;
01395         case 4:
01396             __asm__("movq %q[value], %%dr4" : : [value] "r" (value) : "memory");
01397             break;
01398         case 5:
01399             __asm__("movq %q[value], %%dr5" : : [value] "r" (value) : "memory");
01400             break;
01401         case 6:
01402             __asm__("movq %q[value], %%dr6" : : [value] "r" (value) : "memory");
01403             break;
01404         case 7:
01405             __asm__("movq %q[value], %%dr7" : : [value] "r" (value) : "memory");
01406             break;
01407     }
01408 }
01409 #else
01410 __INTRIN_INLINE unsigned int __readdr(unsigned int reg)
01411 {
01412     unsigned int value;
01413     switch (reg)
01414     {
01415         case 0:
01416             __asm__ __volatile__("mov %%dr0, %[value]" : [value] "=r" (value));
01417             break;
01418         case 1:
01419             __asm__ __volatile__("mov %%dr1, %[value]" : [value] "=r" (value));
01420             break;
01421         case 2:
01422             __asm__ __volatile__("mov %%dr2, %[value]" : [value] "=r" (value));
01423             break;
01424         case 3:
01425             __asm__ __volatile__("mov %%dr3, %[value]" : [value] "=r" (value));
01426             break;
01427         case 4:
01428             __asm__ __volatile__("mov %%dr4, %[value]" : [value] "=r" (value));
01429             break;
01430         case 5:
01431             __asm__ __volatile__("mov %%dr5, %[value]" : [value] "=r" (value));
01432             break;
01433         case 6:
01434             __asm__ __volatile__("mov %%dr6, %[value]" : [value] "=r" (value));
01435             break;
01436         case 7:
01437             __asm__ __volatile__("mov %%dr7, %[value]" : [value] "=r" (value));
01438             break;
01439     }
01440     return value;
01441 }
01442 
01443 __INTRIN_INLINE void __writedr(unsigned reg, unsigned int value)
01444 {
01445     switch (reg)
01446     {
01447         case 0:
01448             __asm__("mov %[value], %%dr0" : : [value] "r" (value) : "memory");
01449             break;
01450         case 1:
01451             __asm__("mov %[value], %%dr1" : : [value] "r" (value) : "memory");
01452             break;
01453         case 2:
01454             __asm__("mov %[value], %%dr2" : : [value] "r" (value) : "memory");
01455             break;
01456         case 3:
01457             __asm__("mov %[value], %%dr3" : : [value] "r" (value) : "memory");
01458             break;
01459         case 4:
01460             __asm__("mov %[value], %%dr4" : : [value] "r" (value) : "memory");
01461             break;
01462         case 5:
01463             __asm__("mov %[value], %%dr5" : : [value] "r" (value) : "memory");
01464             break;
01465         case 6:
01466             __asm__("mov %[value], %%dr6" : : [value] "r" (value) : "memory");
01467             break;
01468         case 7:
01469             __asm__("mov %[value], %%dr7" : : [value] "r" (value) : "memory");
01470             break;
01471     }
01472 }
01473 #endif
01474 
01475 __INTRIN_INLINE void __invlpg(void * const Address)
01476 {
01477     __asm__("invlpg %[Address]" : : [Address] "m" (*((unsigned char *)(Address))) : "memory");
01478 }
01479 
01480 
01481 /*** System operations ***/
01482 __INTRIN_INLINE unsigned long long __readmsr(const int reg)
01483 {
01484 #ifdef _M_AMD64
01485     unsigned long low, high;
01486     __asm__ __volatile__("rdmsr" : "=a" (low), "=d" (high) : "c" (reg));
01487     return ((unsigned long long)high << 32) | low;
01488 #else
01489     unsigned long long retval;
01490     __asm__ __volatile__("rdmsr" : "=A" (retval) : "c" (reg));
01491     return retval;
01492 #endif
01493 }
01494 
01495 __INTRIN_INLINE void __writemsr(const unsigned long Register, const unsigned long long Value)
01496 {
01497 #ifdef _M_AMD64
01498     __asm__ __volatile__("wrmsr" : : "a" (Value), "d" (Value >> 32), "c" (Register));
01499 #else
01500     __asm__ __volatile__("wrmsr" : : "A" (Value), "c" (Register));
01501 #endif
01502 }
01503 
01504 __INTRIN_INLINE unsigned long long __readpmc(const int counter)
01505 {
01506     unsigned long long retval;
01507     __asm__ __volatile__("rdpmc" : "=A" (retval) : "c" (counter));
01508     return retval;
01509 }
01510 
01511 /* NOTE: an immediate value for 'a' will raise an ICE in Visual C++ */
01512 __INTRIN_INLINE unsigned long __segmentlimit(const unsigned long a)
01513 {
01514     unsigned long retval;
01515     __asm__ __volatile__("lsl %[a], %[retval]" : [retval] "=r" (retval) : [a] "rm" (a));
01516     return retval;
01517 }
01518 
01519 __INTRIN_INLINE void __wbinvd(void)
01520 {
01521     __asm__ __volatile__("wbinvd" : : : "memory");
01522 }
01523 
01524 __INTRIN_INLINE void __lidt(void *Source)
01525 {
01526     __asm__ __volatile__("lidt %0" : : "m"(*(short*)Source));
01527 }
01528 
01529 __INTRIN_INLINE void __sidt(void *Destination)
01530 {
01531     __asm__ __volatile__("sidt %0" : : "m"(*(short*)Destination) : "memory");
01532 }
01533 
01534 /*** Misc operations ***/
01535 
01536 __INTRIN_INLINE void _mm_pause(void)
01537 {
01538     __asm__ __volatile__("pause" : : : "memory");
01539 }
01540 
01541 __INTRIN_INLINE void __nop(void)
01542 {
01543     __asm__ __volatile__("nop");
01544 }
01545 
01546 #ifdef __cplusplus
01547 }
01548 #endif
01549 
01550 #endif /* KJK_INTRIN_X86_H_ */
01551 
01552 /* EOF */

Generated on Sun May 27 2012 04:29:53 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.