ReactOS  0.4.12-dev-375-g61fed54
intrin_ppc.h
Go to the documentation of this file.
1 /*
2  Compatibility <intrin.h> header for GCC -- GCC equivalents of intrinsic
3  Microsoft Visual C++ functions. Originally developed for the ReactOS
4  (<http://www.reactos.org/>) and TinyKrnl (<http://www.tinykrnl.org/>)
5  projects.
6 
7  Copyright (c) 2006 KJK::Hyperion <hackbunny@reactos.com>
8 
9  Permission is hereby granted, free of charge, to any person obtaining a
10  copy of this software and associated documentation files (the "Software"),
11  to deal in the Software without restriction, including without limitation
12  the rights to use, copy, modify, merge, publish, distribute, sublicense,
13  and/or sell copies of the Software, and to permit persons to whom the
14  Software is furnished to do so, subject to the following conditions:
15 
16  The above copyright notice and this permission notice shall be included in
17  all copies or substantial portions of the Software.
18 
19  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25  DEALINGS IN THE SOFTWARE.
26 */
27 
28 #ifndef KJK_INTRIN_PPC_H_
29 #define KJK_INTRIN_PPC_H_
30 
31 //#define PPC_QUAL static __inline__ __attribute__((always_inline))
32 #define PPC_QUAL extern __inline__
33 
34 #ifndef __GNUC__
35 #error Unsupported compiler
36 #endif
37 
38 /*** Stack frame juggling ***/
39 #define _ReturnAddress() (__builtin_return_address(0))
40 #define _AddressOfReturnAddress() (&(((void **)(__builtin_frame_address(0)))[1]))
41 /* TODO: __getcallerseflags but how??? */
42 
43 
44 /*** Atomic operations ***/
45 /* TODO: _ReadBarrier */
46 /* TODO: _WriteBarrier */
47 
48 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
49 #define _ReadWriteBarrier() __sync_synchronize()
50 #else
51 /* TODO: _ReadWriteBarrier() */
52 #endif
53 
54 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
55 
56 PPC_QUAL char _InterlockedCompareExchange8(volatile char * const Destination, const char Exchange, const char Comperand)
57 {
58  return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
59 }
60 
61 PPC_QUAL short _InterlockedCompareExchange16(volatile short * const Destination, const short Exchange, const short Comperand)
62 {
63  return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
64 }
65 
66 PPC_QUAL long _InterlockedCompareExchange(volatile long * const Destination, const long Exchange, const long Comperand)
67 {
68  return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
69 }
70 
71 PPC_QUAL long long _InterlockedCompareExchange64(volatile long long * const Destination, const long long Exchange, const long long Comperand)
72 {
73  return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
74 }
75 
76 PPC_QUAL void * _InterlockedCompareExchangePointer(void * volatile * const Destination, void * const Exchange, void * const Comperand)
77 {
78  return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
79 }
80 
81 PPC_QUAL long _InterlockedExchange(volatile long * const Target, const long Value)
82 {
83  /* NOTE: __sync_lock_test_and_set would be an acquire barrier, so we force a full barrier */
84  __sync_synchronize();
85  return __sync_lock_test_and_set(Target, Value);
86 }
87 
88 PPC_QUAL void * _InterlockedExchangePointer(void * volatile * const Target, void * const Value)
89 {
90  /* NOTE: ditto */
91  __sync_synchronize();
92  return __sync_lock_test_and_set(Target, Value);
93 }
94 
95 PPC_QUAL long _InterlockedExchangeAdd(volatile long * const Addend, const long Value)
96 {
97  return __sync_fetch_and_add(Addend, Value);
98 }
99 
100 PPC_QUAL char _InterlockedAnd8(volatile char * const value, const char mask)
101 {
102  return __sync_fetch_and_and(value, mask);
103 }
104 
105 PPC_QUAL short _InterlockedAnd16(volatile short * const value, const short mask)
106 {
107  return __sync_fetch_and_and(value, mask);
108 }
109 
110 PPC_QUAL long _InterlockedAnd(volatile long * const value, const long mask)
111 {
112  return __sync_fetch_and_and(value, mask);
113 }
114 
115 PPC_QUAL char _InterlockedOr8(volatile char * const value, const char mask)
116 {
117  return __sync_fetch_and_or(value, mask);
118 }
119 
120 PPC_QUAL short _InterlockedOr16(volatile short * const value, const short mask)
121 {
122  return __sync_fetch_and_or(value, mask);
123 }
124 
125 PPC_QUAL long _InterlockedOr(volatile long * const value, const long mask)
126 {
127  return __sync_fetch_and_or(value, mask);
128 }
129 
130 PPC_QUAL char _InterlockedXor8(volatile char * const value, const char mask)
131 {
132  return __sync_fetch_and_xor(value, mask);
133 }
134 
135 PPC_QUAL short _InterlockedXor16(volatile short * const value, const short mask)
136 {
137  return __sync_fetch_and_xor(value, mask);
138 }
139 
140 PPC_QUAL long _InterlockedXor(volatile long * const value, const long mask)
141 {
142  return __sync_fetch_and_xor(value, mask);
143 }
144 
145 #else
146 
147 PPC_QUAL char _InterlockedCompareExchange8(volatile char * const Destination, const char Exchange, const char Comperand)
148 {
149  volatile long retval __asm__("r8") = 0;
150  __asm__ __volatile__ (
151  "sync\n"
152  "1: lbarx %0,0,%1\n"
153  : "=r" (retval) : "r" (Destination));
154  __asm__ __volatile__ (
155  " cmpw %3,%1\n"
156  " bne- 2f\n"
157  " stbcx. %2,0,%0\n"
158  " bne- 1b\n"
159  "2: isync"
160  :
161  : "r" (Destination), "r" (Comperand), "r" (Exchange), "r" (retval));
162  return retval;
163 }
164 
165 PPC_QUAL short _InterlockedCompareExchange16(volatile short * const Destination, const short Exchange, const short Comperand)
166 {
167  volatile long retval __asm__("r8") = 0;
168  __asm__ __volatile__ (
169  "sync\n"
170  "1: lharx %0,0,%1\n"
171  : "=&r" (retval) : "r" (Destination));
172  __asm__ __volatile__ (
173  " cmpw %3,%1\n"
174  " bne- 2f\n"
175  " sthcx. %2,0,%0\n"
176  " bne- 1b\n"
177  "2: isync"
178  :
179  : "r" (Destination), "r" (Comperand), "r" (Exchange), "r" (retval));
180  return retval;
181 }
182 
183 PPC_QUAL long _InterlockedCompareExchange(volatile long * const Destination, const long Exchange, const long Comperand)
184 {
185  volatile long retval __asm__("r8") = 0;
186  __asm__ __volatile__ (
187  "sync\n"
188  "1: lwarx %0,0,%1\n"
189  : "=&r" (retval) : "r" (Destination));
190  __asm__ __volatile__ (
191  " cmpw %3,%1\n"
192  " bne- 2f\n"
193  " stwcx. %2,0,%0\n"
194  " bne- 1b\n"
195  "2: isync"
196  :
197  : "r" (Destination), "r" (Comperand), "r" (Exchange), "r" (retval));
198  return retval;
199 }
200 
201 PPC_QUAL long long _InterlockedCompareExchange64(volatile long long * const Target, const long long Exchange, const long long Comperand)
202 {
203  long long capture = *Target;
204  if (*Target == Comperand) *Target = Exchange;
205  return capture;
206 }
207 
208 PPC_QUAL void * _InterlockedCompareExchangePointer(void * volatile * const Destination, void * const Exchange, void * const Comperand)
209 {
210  return (void *)_InterlockedCompareExchange
211  ((long *)Destination, (long) Exchange, (long) Comperand);
212 }
213 
214 PPC_QUAL long _InterlockedExchange(volatile long * const Target, const long Value)
215 {
216  long retval __asm__("r8");
217  __asm__ __volatile__ (
218  "sync\n"
219  "1: lwarx 8,0,3\n"
220  " stwcx. 4,0,3\n"
221  " bne- 1b\n"
222  " mr 3,8\n"
223  : "=b" (retval)
224  : "b" (Target), "b" (Value)
225  : "cr0", "memory");
226  return retval;
227 }
228 
229 PPC_QUAL void * _InterlockedExchangePointer(void * volatile * const Target, void * const Value)
230 {
231  return (void *)_InterlockedExchange((long *)Target, (long)Value);
232 }
233 
234 #define PPC_MakeInterlockedFunction(type,name,op,proto) \
235 PPC_QUAL type name proto \
236 { \
237  long addend, y; \
238  do \
239  { \
240  addend = *value; \
241  y = _InterlockedCompareExchange(value, addend op modify, addend); \
242  } \
243  while(y != addend); \
244  \
245  return y; \
246 }
247 
248 PPC_QUAL unsigned char _interlockedbittestandreset(volatile long * const a, const long b)
249 {
250  long x;
251  long y;
252  long mask = ~(1<<b);
253 
254  do
255  {
256  x = *a;
258  }
259  while(y != x);
260 
261  return (y & ~mask) != 0;
262 }
263 
264 PPC_MakeInterlockedFunction(long,_InterlockedExchangeAdd,+,(volatile long * const value, const long modify))
274 
276 {
277  long x;
278  long y;
279  long mask = 1<<b;
280 
281  do
282  {
283  x = *a;
285  }
286  while(y != x);
287 
288  return (y & ~mask) != 0;
289 }
290 #endif
291 
292 PPC_QUAL long _InterlockedDecrement(volatile long * const lpAddend)
293 {
294  return _InterlockedExchangeAdd(lpAddend, -1) - 1;
295 }
296 
297 PPC_QUAL long _InterlockedIncrement(volatile long * const lpAddend)
298 {
299  return _InterlockedExchangeAdd(lpAddend, 1) + 1;
300 }
301 
302 /*** String operations ***/
303 /* NOTE: we don't set a memory clobber in the __stosX functions because Visual C++ doesn't */
304 /* Note that the PPC store multiple operations may raise an exception in LE
305  * mode */
306 PPC_QUAL void __stosb(unsigned char * Dest, const unsigned char Data, unsigned long Count)
307 {
308  memset(Dest, Data, Count);
309 }
310 
311 PPC_QUAL void __stosw(unsigned short * Dest, const unsigned short Data, unsigned long Count)
312 {
313  while(Count--)
314  *Dest++ = Data;
315 }
316 
317 PPC_QUAL void __stosd(unsigned long * Dest, const unsigned long Data, unsigned long Count)
318 {
319  while(Count--)
320  *Dest++ = Data;
321 }
322 
323 PPC_QUAL void __movsb(unsigned char * Destination, const unsigned char * Source, unsigned long Count)
324 {
326 }
327 
328 PPC_QUAL void __movsw(unsigned short * Destination, const unsigned short * Source, unsigned long Count)
329 {
330  memcpy(Destination, Source, Count * sizeof(*Source));
331 }
332 
333 PPC_QUAL void __movsd(unsigned long * Destination, const unsigned long * Source, unsigned long Count)
334 {
335  memcpy(Destination, Source, Count * sizeof(*Source));
336 }
337 
338 
339 /*** FS segment addressing ***/
340 /* On PowerPC, r13 points to TLS data, including the TEB at 0(r13) from what I
341  * can tell */
342 PPC_QUAL void __writefsbyte(const unsigned long Offset, const unsigned char Data)
343 {
344  char *addr;
345  __asm__("\tadd %0,13,%1\n\tstb %2,0(%0)" : "=r" (addr) : "r" (Offset), "r" (Data));
346 }
347 
348 PPC_QUAL void __writefsword(const unsigned long Offset, const unsigned short Data)
349 {
350  char *addr;
351  __asm__("\tadd %0,13,%1\n\tsth %2,0(%0)" : "=r" (addr) : "r" (Offset), "r" (Data));
352 }
353 
354 PPC_QUAL void __writefsdword(const unsigned long Offset, const unsigned long Data)
355 {
356  char *addr;
357  __asm__("\tadd %0,13,%1\n\tstw %2,0(%0)" : "=r" (addr) : "r" (Offset), "r" (Data));
358 }
359 
360 PPC_QUAL unsigned char __readfsbyte(const unsigned long Offset)
361 {
362  unsigned short result;
363  __asm__("\tadd 7,13,%1\n"
364  "\tlbz %0,0(7)\n"
365  : "=r" (result)
366  : "r" (Offset)
367  : "r7");
368  return result;
369 }
370 
371 PPC_QUAL unsigned short __readfsword(const unsigned long Offset)
372 {
373  unsigned short result;
374  __asm__("\tadd 7,13,%1\n"
375  "\tlhz %0,0(7)\n"
376  : "=r" (result)
377  : "r" (Offset)
378  : "r7");
379  return result;
380 }
381 
382 PPC_QUAL unsigned long __readfsdword(const unsigned long Offset)
383 {
384  unsigned long result;
385  __asm__("\tadd 7,13,%1\n"
386  "\tlwz %0,0(7)\n"
387  : "=r" (result)
388  : "r" (Offset)
389  : "r7");
390  return result;
391 }
392 
393 PPC_QUAL void __incfsbyte(const unsigned long Offset)
394 {
396 }
397 
398 PPC_QUAL void __incfsword(const unsigned long Offset)
399 {
401 }
402 
403 PPC_QUAL void __incfsdword(const unsigned long Offset)
404 {
406 }
407 
408 /* NOTE: the bizarre implementation of __addfsxxx mimics the broken Visual C++ behavior */
409 /* PPC Note: Not sure about the bizarre behavior. We'll try to emulate it later */
410 PPC_QUAL void __addfsbyte(const unsigned long Offset, const unsigned char Data)
411 {
413 }
414 
415 PPC_QUAL void __addfsword(const unsigned long Offset, const unsigned short Data)
416 {
418 }
419 
420 PPC_QUAL void __addfsdword(const unsigned long Offset, const unsigned int Data)
421 {
423 }
424 
425 
426 /*** Bit manipulation ***/
427 PPC_QUAL unsigned char _BitScanForward(unsigned long * const Index, const unsigned long Mask)
428 {
429  if(Mask == 0) return 0;
430  else {
431  unsigned long mask = Mask;
432  mask &= -mask;
433  *Index =
434  ((mask & 0xffff0000) ? 16 : 0) +
435  ((mask & 0xff00ff00) ? 8 : 0) +
436  ((mask & 0xf0f0f0f0) ? 4 : 0) +
437  ((mask & 0xcccccccc) ? 2 : 0) +
438  ((mask & 0xaaaaaaaa) ? 1 : 0);
439  return 1;
440  }
441 }
442 
443 /* Thanks http://www.jjj.de/bitwizardry/files/bithigh.h */
444 PPC_QUAL unsigned char _BitScanReverse(unsigned long * const Index, const unsigned long Mask)
445 {
446  unsigned long check = 16, checkmask;
447  if(Mask == 0) return 0;
448  else {
449  unsigned long mask = Mask;
450  *Index = 0;
451  while(check) {
452  checkmask = ((1<<check)-1) << check;
453  if( mask & checkmask ) {
454  mask >>= check;
455  *Index += check;
456  }
457  check >>= 1;
458  }
459  return 1;
460  }
461 }
462 
463 /* NOTE: again, the bizarre implementation follows Visual C++ */
464 PPC_QUAL unsigned char _bittest(const long * const a, const long b)
465 {
466  return ((*a) & (1<<b)) != 0;
467 }
468 
469 PPC_QUAL unsigned char _bittestandcomplement(long * const a, const long b)
470 {
471  unsigned char ret = ((*a) & (1<<b)) != 0;
472  (*a) ^= (1<<b);
473  return ret;
474 }
475 
476 PPC_QUAL unsigned char _bittestandreset(long * const a, const long b)
477 {
478  unsigned char ret = ((*a) & (1<<b)) != 0;
479  (*a) &= ~(1<<b);
480  return ret;
481 }
482 
483 PPC_QUAL unsigned char _bittestandset(long * const a, const long b)
484 {
485  unsigned char ret = ((*a) & (1<<b)) != 0;
486  (*a) |= (1<<b);
487  return ret;
488 }
489 
490 PPC_QUAL unsigned char _rotl8(const unsigned char value, const unsigned char shift)
491 {
492  return (value << shift) | (value >> (8-shift));
493 }
494 
495 PPC_QUAL unsigned short _rotl16(const unsigned short value, const unsigned char shift)
496 {
497  return (value << shift) | (value >> (16-shift));
498 }
499 
500 PPC_QUAL unsigned char _rotr8(const unsigned char value, const unsigned char shift)
501 {
502  return (value >> shift) | (value << (8-shift));
503 }
504 
505 PPC_QUAL unsigned short _rotr16(const unsigned short value, const unsigned char shift)
506 {
507  return (value >> shift) | (value << (16-shift));
508 }
509 
510 PPC_QUAL unsigned long long __ll_lshift(const unsigned long long Mask, int Bit)
511 {
512  return Mask << Bit;
513 }
514 
515 PPC_QUAL long long __ll_rshift(const long long Mask, const int Bit)
516 {
517  return Mask >> Bit;
518 }
519 
520 PPC_QUAL unsigned long long __ull_rshift(const unsigned long long Mask, int Bit)
521 {
522  return Mask >> Bit;
523 }
524 
525 
526 /*** 64-bit math ***/
527 PPC_QUAL long long __emul(const int a, const int b)
528 {
529  return a * b;
530 }
531 
532 PPC_QUAL unsigned long long __emulu(const unsigned int a, const unsigned int b)
533 {
534  return a * b;
535 }
536 
537 
538 /*** Port I/O ***/
539 PPC_QUAL unsigned char __inbyte(const unsigned long Port)
540 {
541  int ret;
542  __asm__(
543  "mfmsr 5\n\t"
544  "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
545  "mtmsr 6\n\t"
546  "isync\n\t"
547  "sync\n\t"
548  "lbz %0,0(%1)\n\t" /* Get actual value at phys addr r3 */
549  "mtmsr 5\n\t" : "=r" (ret) : "b" (Port)
550  );
551  return ret;
552 }
553 
554 PPC_QUAL unsigned short __inword(const unsigned long Port)
555 {
556  int ret;
557  __asm__(
558  "mfmsr 5\n\t"
559  "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
560  "mtmsr 6\n\t"
561  "isync\n\t"
562  "sync\n\t"
563  "lhz %0,0(%1)\n\t" /* Get actual value at phys addr r3 */
564  "mtmsr 5\n\t" : "=r" (ret) : "b" (Port)
565  );
566  return ret;
567 }
568 
569 PPC_QUAL unsigned long __indword(const unsigned long Port)
570 {
571  int ret;
572  __asm__(
573  "mfmsr 5\n\t"
574  "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
575  "mtmsr 6\n\t"
576  "isync\n\t"
577  "sync\n\t"
578  "lwz %0,0(%1)\n\t" /* Get actual value at phys addr r3 */
579  "mtmsr 5\n\t" : "=r" (ret) : "b" (Port)
580  );
581  return ret;
582 }
583 
584 PPC_QUAL void __inbytestring(unsigned long Port, unsigned char * Buffer, unsigned long Count)
585 {
586  while(Count--) {
587  *Buffer++ = __inbyte(Port);
588  }
589 }
590 
591 PPC_QUAL void __inwordstring(unsigned long Port, unsigned short * Buffer, unsigned long Count)
592 {
593  while(Count--) {
594  *Buffer++ = __inword(Port);
595  }
596 }
597 
598 PPC_QUAL void __indwordstring(unsigned long Port, unsigned long * Buffer, unsigned long Count)
599 {
600  while(Count--) {
601  *Buffer++ = __indword(Port);
602  }
603 }
604 
605 PPC_QUAL void __outbyte(unsigned long const Port, const unsigned char Data)
606 {
607  __asm__(
608  "mfmsr 5\n\t"
609  "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
610  "mtmsr 6\n\t"
611  "sync\n\t"
612  "eieio\n\t"
613  "stb %1,0(%0)\n\t" /* Set actual value at phys addr r3 */
614  "dcbst 0,%1\n\t"
615  "mtmsr 5\n\t"
616  "sync\n\t"
617  "eieio\n\t" : : "b" (Port), "r" (Data)
618  );
619 }
620 
621 PPC_QUAL void __outword(unsigned long const Port, const unsigned short Data)
622 {
623  __asm__(
624  "mfmsr 5\n\t"
625  "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
626  "mtmsr 6\n\t"
627  "sync\n\t"
628  "eieio\n\t"
629  "sth %1,0(%0)\n\t" /* Set actual value at phys addr r3 */
630  "dcbst 0,%1\n\t"
631  "mtmsr 5\n\t"
632  "sync\n\t"
633  "eieio\n\t" : : "b" (Port), "b" (Data)
634  );
635 }
636 
637 PPC_QUAL void __outdword(unsigned long const Port, const unsigned long Data)
638 {
639  __asm__(
640  "mfmsr 5\n\t"
641  "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
642  "mtmsr 6\n\t"
643  "sync\n\t"
644  "eieio\n\t"
645  "stw %1,0(%0)\n\t" /* Set actual value at phys addr r3 */
646  "dcbst 0,%1\n\t"
647  "mtmsr 5\n\t"
648  "sync\n\t"
649  "eieio\n\t" : : "b" (Port), "b" (Data)
650  );
651 }
652 
653 PPC_QUAL void __outbytestring(unsigned long const Port, const unsigned char * const Buffer, const unsigned long Count)
654 {
655  unsigned long count = Count;
656  const unsigned char *buffer = Buffer;
657  while(count--) {
658  __outbyte(Port, *buffer++);
659  }
660 }
661 
662 PPC_QUAL void __outwordstring(unsigned long const Port, const unsigned short * const Buffer, const unsigned long Count)
663 {
664  unsigned long count = Count;
665  const unsigned short *buffer = Buffer;
666  while(count--) {
667  __outword(Port, *buffer++);
668  }
669 }
670 
671 PPC_QUAL void __outdwordstring(unsigned long const Port, const unsigned long * const Buffer, const unsigned long Count)
672 {
673  unsigned long count = Count;
674  const unsigned long *buffer = Buffer;
675  while(count--) {
676  __outdword(Port, *buffer++);
677  }
678 }
679 
680 
681 /*** System information ***/
682 PPC_QUAL void __cpuid(int CPUInfo[], const int InfoType)
683 {
684  unsigned long lo32;
685  __asm__("mfpvr" : "=b" (lo32));
686 }
687 
688 PPC_QUAL unsigned long long __rdtsc(void)
689 {
690  unsigned long lo32;
691  __asm__("mfdec %0" : "=b" (lo32));
692  return -lo32;
693 }
694 
695 
696 /*** Interrupts ***/
697 /* Finally decided to do this by enabling single step trap */
699 {
700 
701 }
702 
703 PPC_QUAL void __int2c(void)
704 {
705  /* Not sure yet */
706 }
707 
708 #ifndef _ENABLE_DISABLE_DEFINED
709 #define _ENABLE_DISABLE_DEFINED
710 PPC_QUAL void _disable(void)
711 {
712  __asm__ __volatile__("mfmsr 0\n\t" \
713  "li 8,0x7fff\n\t" \
714  "and 0,8,0\n\t" \
715  "mtmsr 0\n\t");
716 }
717 
718 PPC_QUAL void _enable(void)
719 {
720  __asm__ __volatile__("mfmsr 8\n\t" \
721  "ori 8,8,0x8000\n\t" \
722  "mtmsr 8\n\t");
723 }
724 
725 /*** Protected memory management ***/
726 PPC_QUAL unsigned long __readsdr1(void)
727 {
728  unsigned long value;
729  __asm__("mfsdr1 %0" : "=b" (value));
730  return value;
731 }
732 
733 PPC_QUAL void __writesdr1(const unsigned long long Data)
734 {
735  __asm__("mtsdr1 %0" : : "b" (Data));
736 }
737 
738 /*** System operations ***/
739 /* This likely has a different meaning from the X86 equivalent. We'll keep
740  * the name cause it fits */
741 PPC_QUAL unsigned long long __readmsr()
742 {
743  unsigned long temp;
744  __asm__("mfmsr %0" : "=b" (temp));
745  return temp;
746 }
747 
748 PPC_QUAL void __writemsr(const unsigned long Value)
749 {
750  __asm__("mtmsr %0" : : "b" (Value));
751 }
752 
753 /* We'll make sure of the following:
754  * IO operations have completed
755  * Write operations through cache have completed
756  * We've reloaded anything in the data or instruction cache that might have
757  * changed in real ram.
758  */
759 PPC_QUAL void __wbinvd(void)
760 {
761  __asm__("eieio\n\t"
762  "dcs\n\t"
763  "sync\n\t"
764  "isync\n\t");
765 }
766 #endif
767 
768 PPC_QUAL long _InterlockedAddLargeStatistic(volatile long long * const Addend, const long Value)
769 {
770 #if 0
771  __asm__
772  (
773  "lock; add %[Value], %[Lo32];"
774  "jae LABEL%=;"
775  "lock; adc $0, %[Hi32];"
776  "LABEL%=:;" :
777  [Lo32] "=m" (*((volatile long *)(Addend) + 0)), [Hi32] "=m" (*((volatile long *)(Addend) + 1)) :
778  [Value] "ir" (Value)
779  );
780 #endif
781  return Value;
782 }
783 
784 /*** Miscellaneous ***/
785 /* BUGBUG: only good for use in macros. Cannot be taken the address of */
786 #define __noop(...) ((void)0)
787 
788 #define __assume(x) if (!(x)) __builtin_unreachable()
789 
790 #endif
791 /* EOF */
PPC_QUAL unsigned char _bittest(const long *const a, const long b)
Definition: intrin_ppc.h:464
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2327
volatile char *const const char modify volatile long *const const long modify volatile short *const const short modify _InterlockedXor8
Definition: intrin_ppc.h:271
CPPORT Port[4]
Definition: headless.c:34
PPC_QUAL void __inbytestring(unsigned long Port, unsigned char *Buffer, unsigned long Count)
Definition: intrin_ppc.h:584
Definition: get.c:139
#define shift
Definition: input.c:1668
PPC_QUAL void __stosw(unsigned short *Dest, const unsigned short Data, unsigned long Count)
Definition: intrin_ppc.h:311
PPC_QUAL void __addfsdword(const unsigned long Offset, const unsigned int Data)
Definition: intrin_ppc.h:420
PPC_QUAL unsigned char _bittestandreset(long *const a, const long b)
Definition: intrin_ppc.h:476
GLuint GLuint GLsizei count
Definition: gl.h:1545
PPC_QUAL void __outbytestring(unsigned long const Port, const unsigned char *const Buffer, const unsigned long Count)
Definition: intrin_ppc.h:653
PPC_QUAL unsigned long long __rdtsc(void)
Definition: intrin_ppc.h:688
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
PPC_QUAL unsigned long __indword(const unsigned long Port)
Definition: intrin_ppc.h:569
GLuint buffer
Definition: glext.h:5915
PPC_QUAL void __stosd(unsigned long *Dest, const unsigned long Data, unsigned long Count)
Definition: intrin_ppc.h:317
short _InterlockedXor16(_Interlocked_operand_ short volatile *_Value, short _Mask)
PPC_QUAL void __outbyte(unsigned long const Port, const unsigned char Data)
Definition: intrin_ppc.h:605
PPC_QUAL unsigned long __readsdr1(void)
Definition: intrin_ppc.h:726
PPC_QUAL unsigned char _interlockedbittestandreset(volatile long *const a, const long b)
Definition: intrin_ppc.h:248
GLuint const GLubyte mask[]
Definition: s_context.h:57
IN OUT PLONG Addend
Definition: CrNtStubs.h:22
char _InterlockedOr8(_Interlocked_operand_ char volatile *_Value, char _Mask)
PPC_QUAL void __outdwordstring(unsigned long const Port, const unsigned long *const Buffer, const unsigned long Count)
Definition: intrin_ppc.h:671
PPC_QUAL long _InterlockedDecrement(volatile long *const lpAddend)
Definition: intrin_ppc.h:292
INT INT y
Definition: msvc.h:62
PPC_QUAL long long __ll_rshift(const long long Mask, const int Bit)
Definition: intrin_ppc.h:515
GLenum GLint GLuint mask
Definition: glext.h:6028
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_InterlockedAnd8
Definition: intrin_ppc.h:265
__asm__("\t.globl GetPhys\n" "GetPhys:\t\n" "mflr 0\n\t" "stwu 0,-16(1)\n\t" "mfmsr 5\n\t" "andi. 6,5,0xffef\n\t" "mtmsr 6\n\t" "isync\n\t" "sync\n\t" "lwz 3,0(3)\n\t" "mtmsr 5\n\t" "isync\n\t" "sync\n\t" "lwz 0,0(1)\n\t" "addi 1,1,16\n\t" "mtlr 0\n\t" "blr")
#define a
Definition: ke_i.h:78
PPC_QUAL void __int2c(void)
Definition: intrin_ppc.h:703
PPC_QUAL long _InterlockedIncrement(volatile long *const lpAddend)
Definition: intrin_ppc.h:297
PPC_QUAL long _InterlockedAddLargeStatistic(volatile long long *const Addend, const long Value)
Definition: intrin_ppc.h:768
PPC_QUAL unsigned long long __readmsr()
Definition: intrin_ppc.h:741
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
short _InterlockedAnd16(_Interlocked_operand_ short volatile *_Value, short _Mask)
PPC_QUAL unsigned long __readfsdword(const unsigned long Offset)
Definition: intrin_ppc.h:382
Definition: bufpool.h:45
PPC_QUAL void _enable(void)
Definition: intrin_ppc.h:718
PPC_QUAL unsigned short __inword(const unsigned long Port)
Definition: intrin_ppc.h:554
#define b
Definition: ke_i.h:79
PPC_QUAL void __outword(unsigned long const Port, const unsigned short Data)
Definition: intrin_ppc.h:621
PPC_QUAL unsigned long long __emulu(const unsigned int a, const unsigned int b)
Definition: intrin_ppc.h:532
PPC_QUAL void __incfsword(const unsigned long Offset)
Definition: intrin_ppc.h:398
PPC_QUAL unsigned char _BitScanReverse(unsigned long *const Index, const unsigned long Mask)
Definition: intrin_ppc.h:444
PPC_QUAL void __movsb(unsigned char *Destination, const unsigned char *Source, unsigned long Count)
Definition: intrin_ppc.h:323
#define volatile
Definition: prototyp.h:117
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
PPC_QUAL void __addfsbyte(const unsigned long Offset, const unsigned char Data)
Definition: intrin_ppc.h:410
PPC_QUAL void __incfsdword(const unsigned long Offset)
Definition: intrin_ppc.h:403
PPC_QUAL unsigned char _bittestandset(long *const a, const long b)
Definition: intrin_ppc.h:483
volatile char *const const char modify _InterlockedAnd
Definition: intrin_ppc.h:267
PPC_QUAL unsigned long long __ll_lshift(const unsigned long long Mask, int Bit)
Definition: intrin_ppc.h:510
PPC_QUAL unsigned short _rotl16(const unsigned short value, const unsigned char shift)
Definition: intrin_ppc.h:495
PPC_QUAL void __debugbreak(void)
Definition: intrin_ppc.h:698
PPC_QUAL unsigned char __readfsbyte(const unsigned long Offset)
Definition: intrin_ppc.h:360
PPC_QUAL unsigned char _rotr8(const unsigned char value, const unsigned char shift)
Definition: intrin_ppc.h:500
static const UCHAR Index[8]
Definition: usbohci.c:18
PPC_QUAL void __outwordstring(unsigned long const Port, const unsigned short *const Buffer, const unsigned long Count)
Definition: intrin_ppc.h:662
PPC_QUAL void __writefsbyte(const unsigned long Offset, const unsigned char Data)
Definition: intrin_ppc.h:342
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:2875
#define PPC_QUAL
Definition: intrin_ppc.h:32
void check(CONTEXT *pContext)
Definition: NtContinue.c:61
_Must_inspect_result_ typedef _In_ ULONG _In_ BOOLEAN Target
Definition: iotypes.h:1067
PPC_QUAL void __wbinvd(void)
Definition: intrin_ppc.h:759
int ret
PPC_QUAL short _InterlockedCompareExchange16(volatile short *const Destination, const short Exchange, const short Comperand)
Definition: intrin_ppc.h:165
GLenum const GLvoid * addr
Definition: glext.h:9621
PPC_QUAL void * _InterlockedCompareExchangePointer(void *volatile *const Destination, void *const Exchange, void *const Comperand)
Definition: intrin_ppc.h:208
PPC_QUAL unsigned char _BitScanForward(unsigned long *const Index, const unsigned long Mask)
Definition: intrin_ppc.h:427
PPC_QUAL unsigned char _bittestandcomplement(long *const a, const long b)
Definition: intrin_ppc.h:469
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
PPC_QUAL void __indwordstring(unsigned long Port, unsigned long *Buffer, unsigned long Count)
Definition: intrin_ppc.h:598
static stack_node_t temp
Definition: rpn.c:18
#define PPC_MakeInterlockedFunction(type, name, op, proto)
Definition: intrin_ppc.h:234
PPC_QUAL unsigned short __readfsword(const unsigned long Offset)
Definition: intrin_ppc.h:371
volatile char *const const char modify volatile long *const const long modify _InterlockedOr16
Definition: intrin_ppc.h:269
PPC_QUAL void __writemsr(const unsigned long Value)
Definition: intrin_ppc.h:748
PPC_QUAL void __writefsword(const unsigned long Offset, const unsigned short Data)
Definition: intrin_ppc.h:348
PPC_QUAL char _InterlockedCompareExchange8(volatile char *const Destination, const char Exchange, const char Comperand)
Definition: intrin_ppc.h:147
PPC_QUAL unsigned char _rotl8(const unsigned char value, const unsigned char shift)
Definition: intrin_ppc.h:490
volatile char *const const char modify volatile long *const const long modify volatile short *const const short modify volatile char *const const char modify _InterlockedXor
Definition: intrin_ppc.h:273
volatile char *const const char modify volatile long *const const long modify volatile short *const const short modify volatile char *const const char modify volatile long *const const long modify PPC_QUAL unsigned char _interlockedbittestandset(volatile long *const a, const long b)
Definition: intrin_ppc.h:275
PPC_QUAL void __movsw(unsigned short *Destination, const unsigned short *Source, unsigned long Count)
Definition: intrin_ppc.h:328
PPC_QUAL void __cpuid(int CPUInfo[], const int InfoType)
Definition: intrin_ppc.h:682
PPC_QUAL void * _InterlockedExchangePointer(void *volatile *const Target, void *const Value)
Definition: intrin_ppc.h:229
INT x
Definition: msvc.h:62
PPC_QUAL void __incfsbyte(const unsigned long Offset)
Definition: intrin_ppc.h:393
CPUINFO CPUInfo[]
Definition: parse.c:231
PPC_QUAL void __writefsdword(const unsigned long Offset, const unsigned long Data)
Definition: intrin_ppc.h:354
PPC_QUAL void __outdword(unsigned long const Port, const unsigned long Data)
Definition: intrin_ppc.h:637
PPC_QUAL void __inwordstring(unsigned long Port, unsigned short *Buffer, unsigned long Count)
Definition: intrin_ppc.h:591
volatile char *const value
Definition: intrin_ppc.h:265
PPC_QUAL void __stosb(unsigned char *Dest, const unsigned char Data, unsigned long Count)
Definition: intrin_ppc.h:306
PPC_QUAL void __movsd(unsigned long *Destination, const unsigned long *Source, unsigned long Count)
Definition: intrin_ppc.h:333
PPC_QUAL unsigned short _rotr16(const unsigned short value, const unsigned char shift)
Definition: intrin_ppc.h:505
PPC_QUAL long long __emul(const int a, const int b)
Definition: intrin_ppc.h:527
#define const
Definition: zconf.h:230
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3149
PPC_QUAL void _disable(void)
Definition: intrin_ppc.h:710
long _InterlockedOr(_Interlocked_operand_ long volatile *_Value, long _Mask)
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
PPC_QUAL long _InterlockedCompareExchange(volatile long *const Destination, const long Exchange, const long Comperand)
Definition: intrin_ppc.h:183
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
PPC_QUAL long _InterlockedExchange(volatile long *const Target, const long Value)
Definition: intrin_ppc.h:214
PPC_QUAL unsigned long long __ull_rshift(const unsigned long long Mask, int Bit)
Definition: intrin_ppc.h:520
GLuint64EXT * result
Definition: glext.h:11304
#define memset(x, y, z)
Definition: compat.h:39
long __cdecl _InterlockedExchangeAdd(_Interlocked_operand_ long volatile *_Addend, long _Value)
PPC_QUAL void __addfsword(const unsigned long Offset, const unsigned short Data)
Definition: intrin_ppc.h:415
PPC_QUAL void __writesdr1(const unsigned long long Data)
Definition: intrin_ppc.h:733
PPC_QUAL long long _InterlockedCompareExchange64(volatile long long *const Target, const long long Exchange, const long long Comperand)
Definition: intrin_ppc.h:201
PPC_QUAL unsigned char __inbyte(const unsigned long Port)
Definition: intrin_ppc.h:539