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_ppc.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_PPC_H_
00029 #define KJK_INTRIN_PPC_H_
00030 
00031 //#define PPC_QUAL static __inline__ __attribute__((always_inline))
00032 #define PPC_QUAL extern __inline__
00033 
00034 #ifndef __GNUC__
00035 #error Unsupported compiler
00036 #endif
00037 
00038 /*** Stack frame juggling ***/
00039 #define _ReturnAddress() (__builtin_return_address(0))
00040 #define _AddressOfReturnAddress() (&(((void **)(__builtin_frame_address(0)))[1]))
00041 /* TODO: __getcallerseflags but how??? */
00042 
00043 
00044 /*** Atomic operations ***/
00045 /* TODO: _ReadBarrier */
00046 /* TODO: _WriteBarrier */
00047 
00048 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
00049 #define _ReadWriteBarrier() __sync_synchronize()
00050 #else
00051 /* TODO: _ReadWriteBarrier() */
00052 #endif
00053 
00054 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
00055 
00056 PPC_QUAL char _InterlockedCompareExchange8(volatile char * const Destination, const char Exchange, const char Comperand)
00057 {
00058     return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
00059 }
00060 
00061 PPC_QUAL short _InterlockedCompareExchange16(volatile short * const Destination, const short Exchange, const short Comperand)
00062 {
00063     return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
00064 }
00065 
00066 PPC_QUAL long _InterlockedCompareExchange(volatile long * const Destination, const long Exchange, const long Comperand)
00067 {
00068     return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
00069 }
00070 
00071 PPC_QUAL long long _InterlockedCompareExchange64(volatile long long * const Destination, const long long Exchange, const long long Comperand)
00072 {
00073     return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
00074 }
00075 
00076 PPC_QUAL void * _InterlockedCompareExchangePointer(void * volatile * const Destination, void * const Exchange, void * const Comperand)
00077 {
00078     return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
00079 }
00080 
00081 PPC_QUAL long _InterlockedExchange(volatile long * const Target, const long Value)
00082 {
00083     /* NOTE: __sync_lock_test_and_set would be an acquire barrier, so we force a full barrier */
00084     __sync_synchronize();
00085     return __sync_lock_test_and_set(Target, Value);
00086 }
00087 
00088 PPC_QUAL void * _InterlockedExchangePointer(void * volatile * const Target, void * const Value)
00089 {
00090     /* NOTE: ditto */
00091     __sync_synchronize();
00092     return __sync_lock_test_and_set(Target, Value);
00093 }
00094 
00095 PPC_QUAL long _InterlockedExchangeAdd(volatile long * const Addend, const long Value)
00096 {
00097     return __sync_fetch_and_add(Addend, Value);
00098 }
00099 
00100 PPC_QUAL char _InterlockedAnd8(volatile char * const value, const char mask)
00101 {
00102     return __sync_fetch_and_and(value, mask);
00103 }
00104 
00105 PPC_QUAL short _InterlockedAnd16(volatile short * const value, const short mask)
00106 {
00107     return __sync_fetch_and_and(value, mask);
00108 }
00109 
00110 PPC_QUAL long _InterlockedAnd(volatile long * const value, const long mask)
00111 {
00112     return __sync_fetch_and_and(value, mask);
00113 }
00114 
00115 PPC_QUAL char _InterlockedOr8(volatile char * const value, const char mask)
00116 {
00117     return __sync_fetch_and_or(value, mask);
00118 }
00119 
00120 PPC_QUAL short _InterlockedOr16(volatile short * const value, const short mask)
00121 {
00122     return __sync_fetch_and_or(value, mask);
00123 }
00124 
00125 PPC_QUAL long _InterlockedOr(volatile long * const value, const long mask)
00126 {
00127     return __sync_fetch_and_or(value, mask);
00128 }
00129 
00130 PPC_QUAL char _InterlockedXor8(volatile char * const value, const char mask)
00131 {
00132     return __sync_fetch_and_xor(value, mask);
00133 }
00134 
00135 PPC_QUAL short _InterlockedXor16(volatile short * const value, const short mask)
00136 {
00137     return __sync_fetch_and_xor(value, mask);
00138 }
00139 
00140 PPC_QUAL long _InterlockedXor(volatile long * const value, const long mask)
00141 {
00142     return __sync_fetch_and_xor(value, mask);
00143 }
00144 
00145 #else
00146 
00147 PPC_QUAL char _InterlockedCompareExchange8(volatile char * const Destination, const char Exchange, const char Comperand)
00148 {
00149         volatile long retval __asm__("r8") = 0;
00150     __asm__ __volatile__ (
00151         "sync\n"
00152         "1: lbarx   %0,0,%1\n" 
00153             : "=r" (retval) : "r" (Destination));
00154         __asm__ __volatile__ (
00155         "   cmpw    %3,%1\n"
00156         "   bne-    2f\n"
00157         "   stbcx.  %2,0,%0\n"
00158         "   bne-    1b\n"
00159         "2: isync"
00160         : 
00161         : "r" (Destination), "r" (Comperand), "r" (Exchange), "r" (retval));
00162     return retval;
00163 }
00164 
00165 PPC_QUAL short _InterlockedCompareExchange16(volatile short * const Destination, const short Exchange, const short Comperand)
00166 {
00167         volatile long retval __asm__("r8") = 0;
00168     __asm__ __volatile__ (
00169         "sync\n"
00170         "1: lharx   %0,0,%1\n" 
00171             : "=&r" (retval) : "r" (Destination));
00172         __asm__ __volatile__ (
00173         "   cmpw    %3,%1\n"
00174         "   bne-    2f\n"
00175         "   sthcx.  %2,0,%0\n"
00176         "   bne-    1b\n"
00177         "2: isync"
00178         : 
00179         : "r" (Destination), "r" (Comperand), "r" (Exchange), "r" (retval));
00180     return retval;
00181 }
00182 
00183 PPC_QUAL long _InterlockedCompareExchange(volatile long * const Destination, const long Exchange, const long Comperand)
00184 {
00185         volatile long retval __asm__("r8") = 0;
00186     __asm__ __volatile__ (
00187         "sync\n"
00188         "1: lwarx   %0,0,%1\n" 
00189             : "=&r" (retval) : "r" (Destination));
00190         __asm__ __volatile__ (
00191         "   cmpw    %3,%1\n"
00192         "   bne-    2f\n"
00193         "   stwcx.  %2,0,%0\n"
00194         "   bne-    1b\n"
00195         "2: isync"
00196         : 
00197         : "r" (Destination), "r" (Comperand), "r" (Exchange), "r" (retval));
00198     return retval;
00199 }
00200 
00201 PPC_QUAL long long _InterlockedCompareExchange64(volatile long long * const Target, const long long Exchange, const long long Comperand)
00202 {
00203     long long capture = *Target;
00204     if (*Target == Comperand) *Target = Exchange;
00205     return capture;
00206 }
00207 
00208 PPC_QUAL void * _InterlockedCompareExchangePointer(void * volatile * const Destination, void * const Exchange, void * const Comperand)
00209 {
00210     return (void *)_InterlockedCompareExchange
00211     ((long *)Destination, (long) Exchange, (long) Comperand);
00212 }
00213 
00214 PPC_QUAL long _InterlockedExchange(volatile long * const Target, const long Value)
00215 {
00216     long retval __asm__("r8");
00217     __asm__ __volatile__ (
00218         "sync\n"
00219         "1: lwarx   8,0,3\n"
00220         "   stwcx.  4,0,3\n"
00221         "   bne-    1b\n"
00222         "   mr      3,8\n"
00223         : "=b" (retval)
00224         : "b" (Target), "b" (Value)
00225         : "cr0", "memory");
00226     return retval;
00227 }
00228 
00229 PPC_QUAL void * _InterlockedExchangePointer(void * volatile * const Target, void * const Value)
00230 {
00231     return (void *)_InterlockedExchange((long *)Target, (long)Value);
00232 }
00233 
00234 #define PPC_MakeInterlockedFunction(type,name,op,proto) \
00235 PPC_QUAL type name proto \
00236 { \
00237         long addend, y; \
00238         do \
00239         { \
00240                 addend = *value; \
00241                 y = _InterlockedCompareExchange(value, addend op modify, addend); \
00242     } \
00243     while(y != addend); \
00244  \
00245     return y; \
00246 }
00247 
00248 PPC_QUAL unsigned char _interlockedbittestandreset(volatile long * const a, const long b)
00249 {
00250     long x;
00251     long y;
00252     long mask = ~(1<<b);
00253 
00254     do
00255     {
00256         x = *a;
00257         y = _InterlockedCompareExchange(a, x & mask, x);
00258     }
00259     while(y != x);
00260 
00261     return (y & ~mask) != 0;
00262 }
00263 
00264 PPC_MakeInterlockedFunction(long,_InterlockedExchangeAdd,+,(volatile long * const value, const long modify))
00265 PPC_MakeInterlockedFunction(char,_InterlockedAnd8,&,(volatile char * const value, const char modify))
00266 PPC_MakeInterlockedFunction(short,_InterlockedAnd16,&,(volatile short * const value, const short modify))
00267 PPC_MakeInterlockedFunction(long,_InterlockedAnd,&,(volatile long * const value, const long modify))
00268 PPC_MakeInterlockedFunction(char,_InterlockedOr8,|,(volatile char * const value, const char modify))
00269 PPC_MakeInterlockedFunction(short,_InterlockedOr16,|,(volatile short * const value, const short modify))
00270 PPC_MakeInterlockedFunction(long,_InterlockedOr,|,(volatile long * const value, const long modify))
00271 PPC_MakeInterlockedFunction(char,_InterlockedXor8,^,(volatile char * const value, const char modify))
00272 PPC_MakeInterlockedFunction(short,_InterlockedXor16,^,(volatile short * const value, const short modify))
00273 PPC_MakeInterlockedFunction(long,_InterlockedXor,^,(volatile long * const value, const long modify))
00274 
00275 PPC_QUAL unsigned char _interlockedbittestandset(volatile long * const a, const long b)
00276 {
00277     long x;
00278     long y;
00279     long mask = 1<<b;
00280 
00281     do
00282     {
00283                 x = *a;
00284         y = _InterlockedCompareExchange(a, x | mask, x);
00285     }
00286     while(y != x);
00287 
00288     return (y & ~mask) != 0;
00289 }
00290 #endif
00291 
00292 PPC_QUAL long _InterlockedDecrement(volatile long * const lpAddend)
00293 {
00294     return _InterlockedExchangeAdd(lpAddend, -1) - 1;
00295 }
00296 
00297 PPC_QUAL long _InterlockedIncrement(volatile long * const lpAddend)
00298 {
00299     return _InterlockedExchangeAdd(lpAddend, 1) + 1;
00300 }
00301 
00302 /*** String operations ***/
00303 /* NOTE: we don't set a memory clobber in the __stosX functions because Visual C++ doesn't */
00304 /* Note that the PPC store multiple operations may raise an exception in LE
00305  * mode */
00306 PPC_QUAL void __stosb(unsigned char * Dest, const unsigned char Data, unsigned long Count)
00307 {
00308     memset(Dest, Data, Count);
00309 }
00310 
00311 PPC_QUAL void __stosw(unsigned short * Dest, const unsigned short Data, unsigned long Count)
00312 {
00313     while(Count--)
00314     *Dest++ = Data;
00315 }
00316 
00317 PPC_QUAL void __stosd(unsigned long * Dest, const unsigned long Data, unsigned long Count)
00318 {
00319     while(Count--)
00320     *Dest++ = Data;
00321 }
00322 
00323 PPC_QUAL void __movsb(unsigned char * Destination, const unsigned char * Source, unsigned long Count)
00324 {
00325     memcpy(Destination, Source, Count);
00326 }
00327 
00328 PPC_QUAL void __movsw(unsigned short * Destination, const unsigned short * Source, unsigned long Count)
00329 {
00330     memcpy(Destination, Source, Count * sizeof(*Source));
00331 }
00332 
00333 PPC_QUAL void __movsd(unsigned long * Destination, const unsigned long * Source, unsigned long Count)
00334 {
00335     memcpy(Destination, Source, Count * sizeof(*Source));
00336 }
00337 
00338 
00339 /*** FS segment addressing ***/
00340 /* On PowerPC, r13 points to TLS data, including the TEB at 0(r13) from what I
00341  * can tell */
00342 PPC_QUAL void __writefsbyte(const unsigned long Offset, const unsigned char Data)
00343 {
00344     char *addr;
00345     __asm__("\tadd %0,13,%1\n\tstb %2,0(%0)" : "=r" (addr) : "r" (Offset), "r" (Data));
00346 }
00347 
00348 PPC_QUAL void __writefsword(const unsigned long Offset, const unsigned short Data)
00349 {
00350     char *addr;
00351     __asm__("\tadd %0,13,%1\n\tsth %2,0(%0)" : "=r" (addr) : "r" (Offset), "r" (Data));
00352 }
00353 
00354 PPC_QUAL void __writefsdword(const unsigned long Offset, const unsigned long Data)
00355 {
00356     char *addr;
00357     __asm__("\tadd %0,13,%1\n\tstw %2,0(%0)" : "=r" (addr) : "r" (Offset), "r" (Data));
00358 }
00359 
00360 PPC_QUAL unsigned char __readfsbyte(const unsigned long Offset)
00361 {
00362     unsigned short result;
00363     __asm__("\tadd 7,13,%1\n"
00364         "\tlbz %0,0(7)\n"
00365         : "=r" (result)
00366         : "r" (Offset)
00367         : "r7");
00368     return result;
00369 }
00370 
00371 PPC_QUAL unsigned short __readfsword(const unsigned long Offset)
00372 {
00373     unsigned short result;
00374     __asm__("\tadd 7,13,%1\n"
00375         "\tlhz %0,0(7)\n"
00376         : "=r" (result)
00377         : "r" (Offset)
00378         : "r7");
00379     return result;
00380 }
00381 
00382 PPC_QUAL unsigned long __readfsdword(const unsigned long Offset)
00383 {
00384     unsigned long result;
00385     __asm__("\tadd 7,13,%1\n"
00386         "\tlwz %0,0(7)\n"
00387         : "=r" (result)
00388         : "r" (Offset)
00389         : "r7");
00390     return result;
00391 }
00392 
00393 PPC_QUAL void __incfsbyte(const unsigned long Offset)
00394 {
00395     __writefsbyte(Offset, __readfsbyte(Offset)+1);
00396 }
00397 
00398 PPC_QUAL void __incfsword(const unsigned long Offset)
00399 {
00400     __writefsword(Offset, __readfsword(Offset)+1);
00401 }
00402 
00403 PPC_QUAL void __incfsdword(const unsigned long Offset)
00404 {
00405     __writefsdword(Offset, __readfsdword(Offset)+1);
00406 }
00407 
00408 /* NOTE: the bizarre implementation of __addfsxxx mimics the broken Visual C++ behavior */
00409 /* PPC Note: Not sure about the bizarre behavior.  We'll try to emulate it later */
00410 PPC_QUAL void __addfsbyte(const unsigned long Offset, const unsigned char Data)
00411 {
00412     __writefsbyte(Offset, __readfsbyte(Offset) + Data);
00413 }
00414 
00415 PPC_QUAL void __addfsword(const unsigned long Offset, const unsigned short Data)
00416 {
00417     __writefsword(Offset, __readfsword(Offset) + Data);
00418 }
00419 
00420 PPC_QUAL void __addfsdword(const unsigned long Offset, const unsigned int Data)
00421 {
00422     __writefsdword(Offset, __readfsdword(Offset) + Data);
00423 }
00424 
00425 
00426 /*** Bit manipulation ***/
00427 PPC_QUAL unsigned char _BitScanForward(unsigned long * const Index, const unsigned long Mask)
00428 {
00429     if(Mask == 0) return 0;
00430     else {
00431     unsigned long mask = Mask;
00432     mask &= -mask;
00433     *Index =
00434         ((mask & 0xffff0000) ? 16 : 0) +
00435         ((mask & 0xff00ff00) ? 8  : 0) +
00436         ((mask & 0xf0f0f0f0) ? 4  : 0) +
00437         ((mask & 0xcccccccc) ? 2  : 0) +
00438         ((mask & 0xaaaaaaaa) ? 1  : 0);
00439     return 1;
00440     }
00441 }
00442 
00443 /* Thanks http://www.jjj.de/bitwizardry/files/bithigh.h */
00444 PPC_QUAL unsigned char _BitScanReverse(unsigned long * const Index, const unsigned long Mask)
00445 {
00446     unsigned long check = 16, checkmask;
00447     if(Mask == 0) return 0;
00448     else {
00449     unsigned long mask = Mask;
00450     *Index = 0;
00451     while(check) {
00452         checkmask = ((1<<check)-1) << check;
00453         if( mask & checkmask ) {
00454         mask >>= check;
00455         *Index += check;
00456         }
00457         check >>= 1;
00458     }
00459     return 1;
00460     }
00461 }
00462 
00463 /* NOTE: again, the bizarre implementation follows Visual C++ */
00464 PPC_QUAL unsigned char _bittest(const long * const a, const long b)
00465 {
00466     return ((*a) & (1<<b)) != 0;
00467 }
00468 
00469 PPC_QUAL unsigned char _bittestandcomplement(long * const a, const long b)
00470 {
00471     unsigned char ret = ((*a) & (1<<b)) != 0;
00472     (*a) ^= (1<<b);
00473     return ret;
00474 }
00475 
00476 PPC_QUAL unsigned char _bittestandreset(long * const a, const long b)
00477 {
00478     unsigned char ret = ((*a) & (1<<b)) != 0;
00479     (*a) &= ~(1<<b);
00480     return ret;
00481 }
00482 
00483 PPC_QUAL unsigned char _bittestandset(long * const a, const long b)
00484 {
00485     unsigned char ret = ((*a) & (1<<b)) != 0;
00486     (*a) |= (1<<b);
00487     return ret;
00488 }
00489 
00490 PPC_QUAL unsigned char _rotl8(const unsigned char value, const unsigned char shift)
00491 {
00492     return (value << shift) | (value >> (8-shift));
00493 }
00494 
00495 PPC_QUAL unsigned short _rotl16(const unsigned short value, const unsigned char shift)
00496 {
00497     return (value << shift) | (value >> (16-shift));
00498 }
00499 
00500 PPC_QUAL unsigned char _rotr8(const unsigned char value, const unsigned char shift)
00501 {
00502     return (value >> shift) | (value << (8-shift));
00503 }
00504 
00505 PPC_QUAL unsigned short _rotr16(const unsigned short value, const unsigned char shift)
00506 {
00507     return (value >> shift) | (value << (16-shift));
00508 }
00509 
00510 PPC_QUAL unsigned long long __ll_lshift(const unsigned long long Mask, int Bit)
00511 {
00512     return Mask << Bit;
00513 }
00514 
00515 PPC_QUAL long long __ll_rshift(const long long Mask, const int Bit)
00516 {
00517     return Mask >> Bit;
00518 }
00519 
00520 PPC_QUAL unsigned long long __ull_rshift(const unsigned long long Mask, int Bit)
00521 {
00522     return Mask >> Bit;
00523 }
00524 
00525 
00526 /*** 64-bit math ***/
00527 PPC_QUAL long long __emul(const int a, const int b)
00528 {
00529     return a * b;
00530 }
00531 
00532 PPC_QUAL unsigned long long __emulu(const unsigned int a, const unsigned int b)
00533 {
00534     return a * b;
00535 }
00536 
00537 
00538 /*** Port I/O ***/
00539 PPC_QUAL unsigned char __inbyte(const unsigned long Port)
00540 {
00541     int ret;
00542     __asm__(
00543     "mfmsr 5\n\t"
00544     "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
00545     "mtmsr 6\n\t"
00546     "isync\n\t"
00547     "sync\n\t"
00548     "lbz   %0,0(%1)\n\t"    /* Get actual value at phys addr r3 */
00549     "mtmsr 5\n\t" : "=r" (ret) : "b" (Port)
00550     );
00551     return ret;
00552 }
00553 
00554 PPC_QUAL unsigned short __inword(const unsigned long Port)
00555 {
00556     int ret;
00557     __asm__(
00558     "mfmsr 5\n\t"
00559     "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
00560     "mtmsr 6\n\t"
00561     "isync\n\t"
00562     "sync\n\t"
00563     "lhz   %0,0(%1)\n\t"    /* Get actual value at phys addr r3 */
00564     "mtmsr 5\n\t" : "=r" (ret) : "b" (Port)
00565     );
00566     return ret;
00567 }
00568 
00569 PPC_QUAL unsigned long __indword(const unsigned long Port)
00570 {
00571     int ret;
00572     __asm__(
00573     "mfmsr 5\n\t"
00574     "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
00575     "mtmsr 6\n\t"
00576     "isync\n\t"
00577     "sync\n\t"
00578     "lwz   %0,0(%1)\n\t"    /* Get actual value at phys addr r3 */
00579     "mtmsr 5\n\t" : "=r" (ret) : "b" (Port)
00580     );
00581     return ret;
00582 }
00583 
00584 PPC_QUAL void __inbytestring(unsigned long Port, unsigned char * Buffer, unsigned long Count)
00585 {
00586     while(Count--) {
00587     *Buffer++ = __inbyte(Port);
00588     }
00589 }
00590 
00591 PPC_QUAL void __inwordstring(unsigned long Port, unsigned short * Buffer, unsigned long Count)
00592 {
00593     while(Count--) {
00594     *Buffer++ = __inword(Port);
00595     }
00596 }
00597 
00598 PPC_QUAL void __indwordstring(unsigned long Port, unsigned long * Buffer, unsigned long Count)
00599 {
00600     while(Count--) {
00601     *Buffer++ = __indword(Port);
00602     }
00603 }
00604 
00605 PPC_QUAL void __outbyte(unsigned long const Port, const unsigned char Data)
00606 {
00607     __asm__(
00608     "mfmsr 5\n\t"
00609     "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
00610     "mtmsr 6\n\t"
00611     "sync\n\t"
00612     "eieio\n\t"
00613     "stb   %1,0(%0)\n\t"    /* Set actual value at phys addr r3 */
00614     "dcbst 0,%1\n\t"
00615     "mtmsr 5\n\t"
00616     "sync\n\t"
00617     "eieio\n\t" : : "b" (Port), "r" (Data)
00618     );
00619 }
00620 
00621 PPC_QUAL void __outword(unsigned long const Port, const unsigned short Data)
00622 {
00623     __asm__(
00624     "mfmsr 5\n\t"
00625     "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
00626     "mtmsr 6\n\t"
00627     "sync\n\t"
00628     "eieio\n\t"
00629     "sth   %1,0(%0)\n\t"    /* Set actual value at phys addr r3 */
00630     "dcbst 0,%1\n\t"
00631     "mtmsr 5\n\t"
00632     "sync\n\t"
00633     "eieio\n\t" : : "b" (Port), "b" (Data)
00634     );
00635 }
00636 
00637 PPC_QUAL void __outdword(unsigned long const Port, const unsigned long Data)
00638 {
00639     __asm__(
00640     "mfmsr 5\n\t"
00641     "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
00642     "mtmsr 6\n\t"
00643     "sync\n\t"
00644     "eieio\n\t"
00645     "stw   %1,0(%0)\n\t"    /* Set actual value at phys addr r3 */
00646     "dcbst 0,%1\n\t"
00647     "mtmsr 5\n\t"
00648     "sync\n\t"
00649     "eieio\n\t" : : "b" (Port), "b" (Data)
00650     );
00651 }
00652 
00653 PPC_QUAL void __outbytestring(unsigned long const Port, const unsigned char * const Buffer, const unsigned long Count)
00654 {
00655     unsigned long count = Count;
00656     const unsigned char *buffer = Buffer;
00657     while(count--) {
00658     __outbyte(Port, *buffer++);
00659     }
00660 }
00661 
00662 PPC_QUAL void __outwordstring(unsigned long const Port, const unsigned short * const Buffer, const unsigned long Count)
00663 {
00664     unsigned long count = Count;
00665     const unsigned short *buffer = Buffer;
00666     while(count--) {
00667     __outword(Port, *buffer++);
00668     }
00669 }
00670 
00671 PPC_QUAL void __outdwordstring(unsigned long const Port, const unsigned long * const Buffer, const unsigned long Count)
00672 {
00673     unsigned long count = Count;
00674     const unsigned long *buffer = Buffer;
00675     while(count--) {
00676     __outdword(Port, *buffer++);
00677     }
00678 }
00679 
00680 
00681 /*** System information ***/
00682 PPC_QUAL void __cpuid(int CPUInfo[], const int InfoType)
00683 {
00684     unsigned long lo32;
00685     __asm__("mfpvr" : "=b" (lo32));
00686 }
00687 
00688 PPC_QUAL unsigned long long __rdtsc(void)
00689 {
00690     unsigned long lo32;
00691     __asm__("mfdec %0" : "=b" (lo32));
00692     return -lo32;
00693 }
00694 
00695 
00696 /*** Interrupts ***/
00697 /* Finally decided to do this by enabling single step trap */
00698 PPC_QUAL void __debugbreak(void)
00699 {
00700 
00701 }
00702 
00703 PPC_QUAL void __int2c(void)
00704 {
00705     /* Not sure yet */
00706 }
00707 
00708 #ifndef _ENABLE_DISABLE_DEFINED
00709 #define _ENABLE_DISABLE_DEFINED
00710 PPC_QUAL void _disable(void)
00711 {
00712     __asm__ __volatile__("mfmsr 0\n\t" \
00713              "li    8,0x7fff\n\t" \
00714              "and   0,8,0\n\t" \
00715              "mtmsr 0\n\t");
00716 }
00717 
00718 PPC_QUAL void _enable(void)
00719 {
00720     __asm__ __volatile__("mfmsr 8\n\t" \
00721              "ori   8,8,0x8000\n\t" \
00722              "mtmsr 8\n\t");
00723 }
00724 
00725 /*** Protected memory management ***/
00726 PPC_QUAL unsigned long __readsdr1(void)
00727 {
00728     unsigned long value;
00729     __asm__("mfsdr1 %0" : "=b" (value));
00730     return value;
00731 }
00732 
00733 PPC_QUAL void __writesdr1(const unsigned long long Data)
00734 {
00735     __asm__("mtsdr1 %0" : : "b" (Data));
00736 }
00737 
00738 /*** System operations ***/
00739 /* This likely has a different meaning from the X86 equivalent.  We'll keep
00740  * the name cause it fits */
00741 PPC_QUAL unsigned long long __readmsr()
00742 {
00743     unsigned long temp;
00744     __asm__("mfmsr %0" : "=b" (temp));
00745     return temp;
00746 }
00747 
00748 PPC_QUAL void __writemsr(const unsigned long Value)
00749 {
00750     __asm__("mtmsr %0" : : "b" (Value));
00751 }
00752 
00753 /* We'll make sure of the following:
00754  * IO operations have completed
00755  * Write operations through cache have completed
00756  * We've reloaded anything in the data or instruction cache that might have
00757  * changed in real ram.
00758  */
00759 PPC_QUAL void __wbinvd(void)
00760 {
00761     __asm__("eieio\n\t"
00762         "dcs\n\t"
00763         "sync\n\t"
00764         "isync\n\t");
00765 }
00766 #endif
00767 
00768 PPC_QUAL long _InterlockedAddLargeStatistic(volatile long long * const Addend, const long Value)
00769 {
00770 #if 0
00771     __asm__
00772     (
00773         "lock; add %[Value], %[Lo32];"
00774         "jae LABEL%=;"
00775         "lock; adc $0, %[Hi32];"
00776         "LABEL%=:;" :
00777         [Lo32] "=m" (*((volatile long *)(Addend) + 0)), [Hi32] "=m" (*((volatile long *)(Addend) + 1)) :
00778         [Value] "ir" (Value)
00779     );
00780 #endif
00781     return Value;
00782 }
00783 
00784 /*** Miscellaneous ***/
00785 /* BUGBUG: only good for use in macros. Cannot be taken the address of */
00786 #define __noop(...) ((void)0)
00787 
00788 /* TODO: __assume. GCC only supports the weaker __builtin_expect */
00789 
00790 #endif
00791 /* EOF */

Generated on Sat May 26 2012 04:28:28 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.