OSDN Git Service

2007-08-30 Andrew Pinski <andrew_pinski@playstation.sony.com>
[pf3gnuchains/gcc-fork.git] / gcc / config / rs6000 / ppu_intrinsics.h
1 /* PPU intrinsics as defined by the C/C++ Language extension for Cell BEA.
2    Copyright (C) 2007 Free Software Foundation, Inc.
3
4    This file is free software; you can redistribute it and/or modify it under
5    the terms of the GNU General Public License as published by the Free
6    Software Foundation; either version 2 of the License, or (at your option)
7    any later version.
8
9    This file is distributed in the hope that it will be useful, but WITHOUT
10    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12    for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this file; see the file COPYING.  If not, write to the Free
16    Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
17    02110-1301, USA.  */
18
19 /* As a special exception, if you include this header file into source files
20    compiled by GCC, this header file does not by itself cause  the resulting
21    executable to be covered by the GNU General Public License.  This exception
22    does not however invalidate any other reasons why the executable file might
23    be covered by the GNU General Public License.  */
24
25 /*  TODO:
26     misc ops (traps)
27     supervisor/hypervisor mode ops.  */
28
29 #ifndef  _PPU_INTRINSICS_H
30 #define _PPU_INTRINSICS_H
31
32 #if !defined(__PPU__) && !defined(__ppc__) && !defined(__ppc64__) \
33     && !defined(__GNUC__)
34   #error ppu_intrinsics.h included on wrong platform/compiler
35 #endif
36
37 #ifdef __cplusplus
38 extern "C" {
39 #endif 
40
41 /*
42  * unsigned int __cntlzw(unsigned int)
43  * unsigned int __cntlzd(unsigned long long)
44  * int __mulhw(int, int)
45  * unsigned int __mulhwu(unsigned int, unsigned int)
46  * long long __mulhd(long long, long long)
47  * unsigned long long __mulhdu(unsigned long long, unsigned long long)
48  *
49  * void __sync(void)
50  * void __isync(void)
51  * void __lwsync(void)
52  * void __eieio(void)
53  *
54  * void __nop(void)
55  * void __cctpl(void)
56  * void __cctpm(void)
57  * void __cctph(void)
58  * void __db8cyc(void)
59  * void __db10cyc(void)
60  * void __db12cyc(void)
61  * void __db16cyc(void)
62  *
63  * void __mtspr(unsigned int spr, unsigned long long value)
64  * unsigned long long __mfspr(unsigned int spr)
65  * unsigned long long __mftb(void)
66  *
67  * void __icbi(void *base)
68  * void __dcbi(void *base)
69  *
70  * void __dcbf(void *base)
71  * void __dcbz(void *base)
72  * void __dcbst(void *base)
73  * void __dcbtst(void *base)
74  * void __dcbt(void *base)
75  * void __dcbt_TH1000(void *EATRUNC, bool D, bool UG, int ID)
76  * void __dcbt_TH1010(bool GO, int S, int UNITCNT, bool T, bool U, int ID)
77  *
78  * unsigned __lwarx(void *base)
79  * unsigned long long __ldarx(void *base)
80  * bool __stwcx(void *base, unsigned value)
81  * bool __stdcx(void *base, unsigned long long value)
82  *
83  * unsigned short __lhbrx(void *base)
84  * unsigned int __lwbrx(void *base)
85  * unsigned long long __ldbrx(void *base)
86  * void __sthbrx(void *base, unsigned short value)
87  * void __stwbrx(void *base, unsigned int value)
88  * void __stdbrx(void *base, unsigned long long value)
89  *
90  * double __fabs(double x)
91  * float __fabsf(float x)
92  * double __fnabs(double x)
93  * float __fnabsf(float x)
94  * double __fmadd(double x, double y, double z)
95  * double __fmsub(double x, double y, double z)
96  * double __fnmadd(double x, double y, double z)
97  * double __fnmsub(double x, double y, double z)
98  * float __fmadds(float x, float y, float z)
99  * float __fmsubs(float x, float y, float z)
100  * float __fnmadds(float x, float y, float z)
101  * float __fnmsubs(float x, float y, float z)
102  * double __fsel(double x, double y, double z)
103  * float __fsels(float x, float y, float z)
104  * double __frsqrte(double x)
105  * float __fres(float x)
106  * double __fsqrt(double x)
107  * float __fsqrts(float x)
108  * long long __fctid(double x)
109  * long long __fctiw(double x)
110  * double __fcfid(long long x)
111  * double __mffs(void)
112  * void __mtfsf(int mask, double value)
113  * void __mtfsfi(int bits, int field)
114  * void __mtfsb0(int)
115  * void __mtfsb1(int)
116  * double __setflm(double)
117  *
118  * dcbt intrinsics 
119  * void __protected_unlimited_stream_set (unsigned int direction, const void *add, unsigned int ID)
120  * void __protected_stream_set (unsigned int direction, const void *add, unsigned int ID)
121  * void __protected_stream_stop_all (void)
122  * void __protected_stream_stop (unsigned int ID)
123  * void __protected_stream_count (unsigned int unit_cnt, unsigned int ID)
124  * void __protected_stream_go (void)
125  */
126
127 typedef int __V4SI __attribute__((vector_size(16)));
128
129 #define __cntlzw(v) __builtin_clz(v)
130 #define __cntlzd(v) __builtin_clzll(v)
131
132 #define __mulhw(a,b) __extension__ \
133   ({int result;                    \
134   __asm__ ("mulhw %0,%1,%2"        \
135            : "=r" (result)         \
136            : "r" ((int) (a)),      \
137              "r" ((int) (b)));     \
138   result; })
139
140 #define __mulhwu(a,b) __extension__     \
141   ({unsigned int result;                \
142   __asm__ ("mulhwu %0,%1,%2"            \
143            : "=r" (result)              \
144            : "r" ((unsigned int) (a)),  \
145              "r" ((unsigned int) (b))); \
146   result; })
147
148 #ifdef __powerpc64__
149 #define __mulhd(a,b) __extension__   \
150   ({ long long result;               \
151   __asm__ ("mulhd %0,%1,%2"          \
152            : "=r" (result)           \
153            : "r" ((long long) (a)),  \
154              "r" ((long long) (b))); \
155   result; })
156
157 #define __mulhdu(a,b) __extension__           \
158   ({unsigned long long result;                \
159   __asm__ ("mulhdu %0,%1,%2"                  \
160            : "=r" (result)                    \
161            : "r" ((unsigned long long) (a)),  \
162              "r" ((unsigned long long) (b))); \
163   result; })
164 #endif /* __powerpc64__ */
165
166 #define __sync() __asm__ volatile ("sync" : : : "memory")
167 #define __isync() __asm__ volatile ("isync" : : : "memory")
168 #define __lwsync() __asm__ volatile ("lwsync" : : : "memory")
169 #define __eieio() __asm__ volatile ("eieio" : : : "memory")
170
171 #define __nop() __asm__ volatile ("ori 0,0,0" : : : "memory")
172 #define __cctpl() __asm__ volatile ("or 1,1,1" : : : "memory")
173 #define __cctpm() __asm__ volatile ("or 2,2,2" : : : "memory")
174 #define __cctph() __asm__ volatile ("or 3,3,3" : : : "memory")
175 #define __db8cyc() __asm__ volatile ("or 28,28,28" : : : "memory")
176 #define __db10cyc() __asm__ volatile ("or 29,29,29" : : : "memory")
177 #define __db12cyc() __asm__ volatile ("or 30,30,30" : : : "memory")
178 #define __db16cyc() __asm__ volatile ("or 31,31,31" : : : "memory")
179
180 #ifdef __powerpc64__
181 #define __mtspr(spr, value) \
182   __asm__ volatile ("mtspr %0,%1" : : "n" (spr), "r" (value))
183   
184 #define __mfspr(spr) __extension__                              \
185   ({ unsigned long long result;                                 \
186   __asm__ volatile ("mfspr %0,%1" : "=r" (result) : "n" (spr)); \
187   result; })
188 #endif /* __powerpc64__ */
189
190 #ifdef __powerpc64__
191 /* Work around the hadware bug in the current Cell implemention.  */
192 #define __mftb() __extension__                                  \
193   ({ unsigned long long result;                                 \
194   __asm__ volatile ("1: mftb %[current_tb]\n"                   \
195       "\tcmpwi 7, %[current_tb], 0\n"                           \
196       "\tbeq-  7, 1b"                                           \
197       : [current_tb] "=r" (result):                             \
198       :"cr7");                                                  \
199   result; })
200 #else
201 #define __mftb() __extension__                  \
202   ({ unsigned long long result;                 \
203   unsigned long t;                              \
204   __asm__ volatile ("1:\n"                      \
205                     "\tmftbu %0\n"              \
206                     "\tmftb %L0\n"              \
207                     "\tmftbu %1\n"              \
208                     "\tcmpw %0,%1\n"            \
209                     "\tbne 1b"                  \
210                     : "=r" (result), "=r" (t)); \
211   result; })
212 #endif /* __powerpc64__ */
213
214 #define __dcbf(base) \
215   __asm__ volatile ("dcbf %y0" : "=Z" (*(__V4SI*) (base)) : : "memory")
216   
217 #define __dcbz(base) \
218   __asm__ volatile ("dcbz %y0" : "=Z" (*(__V4SI*) (base)) : : "memory")
219
220 #define __dcbst(base) \
221   __asm__ volatile ("dcbst %y0" : "=Z" (*(__V4SI*) (base)) : : "memory")
222
223 #define __dcbtst(base) \
224   __asm__ volatile ("dcbtst %y0" : "=Z" (*(__V4SI*) (base)) : : "memory")
225
226 #define __dcbt(base) \
227   __asm__ volatile ("dcbt %y0" : "=Z" (*(__V4SI*) (base)) : : "memory")
228
229 #define __icbi(base) \
230   __asm__ volatile ("icbi %y0" : "=Z" (*(__V4SI*) (base)) : : "memory")
231   
232 #define __dcbt_TH1000(EATRUNC, D, UG, ID)                               \
233   __asm__ volatile ("dcbt %y0,8"                                        \
234            : "=Z" (*(__V4SI*) (__SIZE_TYPE__)((((__SIZE_TYPE__) (EATRUNC)) & ~0x7F)     \
235                                | ((((D) & 1) << 6)                      \
236                                | (((UG) & 1) << 5)                      \
237                                | ((ID) & 0xF)))) : : "memory")
238
239 #define __dcbt_TH1010(GO, S, UNITCNT, T, U, ID)                      \
240   __asm__ volatile ("dcbt %y0,10"                                    \
241            : "=Z" (*(__V4SI*) (__SIZE_TYPE__)((((__SIZE_TYPE__) (GO) & 1) << 31) \
242                                | (((S) & 0x3) << 29)                 \
243                                | (((UNITCNT) & 0x3FF) << 7)          \
244                                | (((T) & 1) << 6)                            \
245                                | (((U) & 1) << 5)                            \
246                                | ((ID) & 0xF))) : : "memory")
247
248 #define __protected_unlimited_stream_set(DIRECTION, ADDR, ID)   \
249         __dcbt_TH1000 ((ADDR), (DIRECTION)>>1, 0, (ID))
250
251 #define __protected_stream_set(DIRECTION, ADDR, ID)     \
252         __dcbt_TH1000 ((ADDR), (DIRECTION)>>1, 1, (ID))
253
254 #define __protected_stream_stop_all()                   \
255         __dcbt_TH1010 (0, 3, 0, 0, 0, 0)
256
257 #define __protected_stream_stop(ID)                     \
258         __dcbt_TH1010 (0, 2, 0, 0, 0, (ID))
259
260 #define __protected_stream_count(CNT, ID)               \
261         __dcbt_TH1010 (0, 0, (CNT), 0, 0, (ID))
262
263 #define __protected_stream_go()                         \
264         __dcbt_TH1010 (1, 0, 0, 0, 0, 0)
265
266 #define __lhbrx(base) __extension__             \
267   ({unsigned short result;                      \
268     typedef  struct {char a[2];} halfwordsize;  \
269     halfwordsize *ptrp = (halfwordsize*)(void*)(base);  \
270   __asm__ ("lhbrx %0,%y1"                       \
271            : "=r" (result)                      \
272            : "Z" (*ptrp));                      \
273   result; })
274
275 #define __lwbrx(base) __extension__             \
276   ({unsigned int result;                        \
277     typedef  struct {char a[4];} wordsize;      \
278     wordsize *ptrp = (wordsize*)(void*)(base);          \
279   __asm__ ("lwbrx %0,%y1"                       \
280            : "=r" (result)                      \
281            : "Z" (*ptrp));                      \
282   result; })
283
284
285 #ifdef __powerpc64__
286 #define __ldbrx(base) __extension__                     \
287   ({unsigned long long result;                          \
288     typedef  struct {char a[8];} doublewordsize;        \
289     doublewordsize *ptrp = (doublewordsize*)(void*)(base);      \
290   __asm__ ("ldbrx %0,%y1"                               \
291            : "=r" (result)                              \
292            : "Z" (*ptrp));                              \
293   result; })
294 #else
295 #define __ldbrx(base) __extension__                     \
296   ({unsigned long long result;                          \
297     typedef  struct {char a[8];} doublewordsize;        \
298     doublewordsize *ptrp = (doublewordsize*)(void*)(base);      \
299   __asm__ ("lwbrx %L0,%y1\n"                            \
300            "\tlwbrx %0,%y2"                             \
301            : "=&r" (result)                             \
302            : "Z" (*ptrp), "Z" (*((char *) ptrp + 4)));  \
303   result; })
304 #endif /* __powerpc64__ */
305
306
307 #define __sthbrx(base, value) do {                      \
308     typedef  struct {char a[2];} halfwordsize;          \
309     halfwordsize *ptrp = (halfwordsize*)(void*)(base);          \
310     __asm__ ("sthbrx %1,%y0"                            \
311            : "=Z" (*ptrp)                               \
312            : "r" (value));                              \
313    } while (0)
314
315 #define __stwbrx(base, value) do {              \
316     typedef  struct {char a[4];} wordsize;      \
317     wordsize *ptrp = (wordsize*)(void*)(base);          \
318     __asm__ ("stwbrx %1,%y0"                    \
319            : "=Z" (*ptrp)                       \
320            : "r" (value));                      \
321    } while (0)
322
323 #ifdef __powerpc64__
324 #define __stdbrx(base, value) do {                      \
325     typedef  struct {char a[8];} doublewordsize;        \
326     doublewordsize *ptrp = (doublewordsize*)(void*)(base);      \
327     __asm__ ("stdbrx %1,%y0"                            \
328            : "=Z" (*ptrp)                               \
329            : "r" (value));                              \
330    } while (0)
331 #else
332 #define __stdbrx(base, value) do {                      \
333     typedef  struct {char a[8];} doublewordsize;        \
334     doublewordsize *ptrp = (doublewordsize*)(void*)(base);      \
335     __asm__ ("stwbrx %L2,%y0\n"                         \
336              "\tstwbrx %2,%y1"                          \
337            : "=Z" (*ptrp), "=Z" (*((char *) ptrp + 4))  \
338            : "r" (value));                              \
339    } while (0)
340 #endif /* __powerpc64__ */
341
342
343 #define __lwarx(base) __extension__             \
344   ({unsigned int result;                        \
345     typedef  struct {char a[4];} wordsize;      \
346     wordsize *ptrp = (wordsize*)(void*)(base);  \
347   __asm__ volatile ("lwarx %0,%y1"              \
348            : "=r" (result)                      \
349            : "Z" (*ptrp));                      \
350   result; })
351
352 #ifdef __powerpc64__
353 #define __ldarx(base) __extension__                     \
354   ({unsigned long long result;                          \
355     typedef  struct {char a[8];} doublewordsize;        \
356     doublewordsize *ptrp = (doublewordsize*)(void*)(base);      \
357   __asm__ volatile ("ldarx %0,%y1"                      \
358            : "=r" (result)                              \
359            : "m" (*ptrp));                              \
360   result; })
361 #endif /* __powerpc64__ */
362
363 #define __stwcx(base, value) __extension__      \
364   ({unsigned int result;                        \
365     typedef  struct {char a[4];} wordsize;      \
366     wordsize *ptrp = (wordsize*)(void*)(base);  \
367   __asm__ volatile ("stwcx. %2,%y1\n"           \
368            "\tmfocrf %0,0x80"                   \
369            : "=r" (result),                     \
370              "=Z" (*ptrp)                       \
371            : "r" (value) : "cr0");              \
372   (result & 0x20000000); })
373
374
375 #ifdef __powerpc64__
376 #define __stdcx(base, value) __extension__              \
377   ({unsigned long long result;                          \
378     typedef  struct {char a[8];} doublewordsize;        \
379     doublewordsize *ptrp = (doublewordsize*)(void*)(base);      \
380   __asm__ ("stdcx. %2,%y1\n"                            \
381            "\tmfocrf %0,0x80"                           \
382            : "=r" (result),                             \
383              "=Z" (*ptrp)                               \
384            : "r" (value) : "cr0");                      \
385   (result & 0x20000000); })
386 #endif /* __powerpc64__ */
387
388 #define __mffs() __extension__                  \
389   ({double result;                              \
390   __asm__ volatile ("mffs %0" : "=f" (result)); \
391   result; })
392
393 #define __mtfsf(mask,value) \
394   __asm__ volatile ("mtfsf %0,%1" : : "n" (mask), "f" ((double) (value)))
395   
396 #define __mtfsfi(bits,field) \
397   __asm__ volatile ("mtfsfi %0,%1" : : "n" (bits), "n" (field))
398
399 #define __mtfsb0(bit) __asm__ volatile ("mtfsb0 %0" : : "n" (bit))
400 #define __mtfsb1(bit) __asm__ volatile ("mtfsb1 %0" : : "n" (bit))
401
402 #define __setflm(v) __extension__             \
403   ({double result;                            \
404   __asm__ volatile ("mffs %0\n\tmtfsf 255,%1" \
405                     : "=&f" (result)          \
406                     : "f" ((double) (v)));    \
407   result; })
408
409 /* __builtin_fabs may perform unnecessary rounding.  */
410
411 /* Rename __fabs and __fabsf to work around internal prototypes defined 
412    in bits/mathcalls.h with some glibc versions.  */ 
413 #define __fabs __ppu_fabs 
414 #define __fabsf __ppu_fabsf 
415
416 static __inline__ double __fabs(double x) __attribute__((always_inline));
417 static __inline__ double
418 __fabs(double x)
419 {
420   double r;
421   __asm__("fabs %0,%1" : "=f"(r) : "f"(x));
422   return r;
423 }
424
425 static __inline__ float __fabsf(float x) __attribute__((always_inline));
426 static __inline__ float
427 __fabsf(float x)
428 {
429   float r;
430   __asm__("fabs %0,%1" : "=f"(r) : "f"(x));
431   return r;
432 }
433
434 static __inline__ double __fnabs(double x) __attribute__((always_inline));
435 static __inline__ double
436 __fnabs(double x)
437 {
438   double r;
439   __asm__("fnabs %0,%1" : "=f"(r) : "f"(x));
440   return r;
441 }
442
443 static __inline__ float __fnabsf(float x) __attribute__((always_inline));
444 static __inline__ float
445 __fnabsf(float x)
446 {
447   float r;
448   __asm__("fnabs %0,%1" : "=f"(r) : "f"(x));
449   return r;
450 }
451
452 static __inline__ double __fmadd(double x, double y, double z)
453   __attribute__((always_inline));
454 static __inline__ double
455 __fmadd(double x, double y, double z)
456 {
457   double r;
458   __asm__("fmadd %0,%1,%2,%3" : "=f"(r) : "f"(x),"f"(y),"f"(z));
459   return r;
460 }
461
462 static __inline__ double __fmsub(double x, double y, double z)
463   __attribute__((always_inline));
464 static __inline__ double
465 __fmsub(double x, double y, double z)
466 {
467   double r;
468   __asm__("fmsub %0,%1,%2,%3" : "=f"(r) : "f"(x),"f"(y),"f"(z));
469   return r;
470 }
471
472 static __inline__ double __fnmadd(double x, double y, double z)
473   __attribute__((always_inline));
474 static __inline__ double
475 __fnmadd(double x, double y, double z)
476 {
477   double r;
478   __asm__("fnmadd %0,%1,%2,%3" : "=f"(r) : "f"(x),"f"(y),"f"(z));
479   return r;
480 }
481
482 static __inline__ double __fnmsub(double x, double y, double z)
483   __attribute__((always_inline));
484 static __inline__ double
485 __fnmsub(double x, double y, double z)
486 {
487   double r;
488   __asm__("fnmsub %0,%1,%2,%3" : "=f"(r) : "f"(x),"f"(y),"f"(z));
489   return r;
490 }
491
492 static __inline__ float __fmadds(float x, float y, float z)
493   __attribute__((always_inline));
494 static __inline__ float
495 __fmadds(float x, float y, float z)
496 {
497   float r;
498   __asm__("fmadds %0,%1,%2,%3" : "=f"(r) : "f"(x),"f"(y),"f"(z));
499   return r;
500 }
501
502 static __inline__ float __fmsubs(float x, float y, float z)
503   __attribute__((always_inline));
504 static __inline__ float
505 __fmsubs(float x, float y, float z)
506 {
507   float r;
508   __asm__("fmsubs %0,%1,%2,%3" : "=f"(r) : "f"(x),"f"(y),"f"(z));
509   return r;
510 }
511
512 static __inline__ float __fnmadds(float x, float y, float z)
513   __attribute__((always_inline));
514 static __inline__ float
515 __fnmadds(float x, float y, float z)
516 {
517   float r;
518   __asm__("fnmadds %0,%1,%2,%3" : "=f"(r) : "f"(x),"f"(y),"f"(z));
519   return r;
520 }
521
522 static __inline__ float __fnmsubs(float x, float y, float z)
523   __attribute__((always_inline));
524 static __inline__ float
525 __fnmsubs(float x, float y, float z)
526 {
527   float r;
528   __asm__("fnmsubs %0,%1,%2,%3" : "=f"(r) : "f"(x),"f"(y),"f"(z));
529   return r;
530 }
531
532 static __inline__ double __fsel(double x, double y, double z)
533   __attribute__((always_inline));
534 static __inline__ double
535 __fsel(double x, double y, double z)
536 {
537   double r;
538   __asm__("fsel %0,%1,%2,%3" : "=f"(r) : "f"(x),"f"(y),"f"(z));
539   return r;
540 }
541
542 static __inline__ float __fsels(float x, float y, float z)
543   __attribute__((always_inline));
544 static __inline__ float
545 __fsels(float x, float y, float z)
546 {
547   float r;
548   __asm__("fsel %0,%1,%2,%3" : "=f"(r) : "f"(x),"f"(y),"f"(z));
549   return r;
550 }
551
552 static __inline__ double __frsqrte(double x) __attribute__((always_inline));
553 static __inline__ double
554 __frsqrte(double x)
555 {
556   double r;
557   __asm__("frsqrte %0,%1" : "=f" (r) : "f" (x));
558   return r;
559 }
560
561 static __inline__ float __fres(float x) __attribute__((always_inline));
562 static __inline__ float
563 __fres(float x)
564 {
565   float r;
566   __asm__("fres %0,%1" : "=f"(r) : "f"(x));
567   return r;
568 }
569
570 static __inline__ double __fsqrt(double x) __attribute__((always_inline));
571 static __inline__ double
572 __fsqrt(double x)
573 {
574   double r;
575   __asm__("fsqrt %0,%1" : "=f"(r) : "f"(x));
576   return r;
577 }
578
579 static __inline__ float __fsqrts(float x) __attribute__((always_inline));
580 static __inline__ float
581 __fsqrts(float x)
582 {
583   float r;
584   __asm__("fsqrts %0,%1" : "=f"(r) : "f"(x));
585   return r;
586 }
587
588 static __inline__ double __fmul (double a, double b) __attribute__ ((always_inline));
589 static __inline__ double
590 __fmul(double a, double b)
591 {
592   double d;
593   __asm__ ("fmul %0,%1,%2" : "=f" (d) : "f" (a), "f" (b));
594   return d;
595 }
596
597 static __inline__ float __fmuls (float a, float b) __attribute__ ((always_inline));
598 static __inline__ float
599 __fmuls (float a, float b)
600 {
601   float d;
602   __asm__ ("fmuls %0,%1,%2" : "=f" (d) : "f" (a), "f" (b));
603   return d;
604 }
605
606 static __inline__ float __frsp (float a) __attribute__ ((always_inline));
607 static __inline__ float
608 __frsp (float a)
609 {
610   float d;
611   __asm__ ("frsp %0,%1" : "=f" (d) : "f" (a));
612   return d;
613 }
614
615 static __inline__ double __fcfid (long long a) __attribute__((always_inline));
616 static __inline__ double
617 __fcfid (long long a)
618 {
619   double d;
620   __asm__ ("fcfid %0,%1" : "=f" (d) : "f" (a));
621   return d;
622 }
623
624 static __inline__ long long __fctid (double a) __attribute__ ((always_inline));
625 static __inline__ long long
626 __fctid (double a)
627 {
628   long long d;
629   __asm__ ("fctid %0,%1" : "=f" (d) : "f" (a));
630   return d;
631 }
632
633 static __inline__ long long __fctidz (double a) __attribute__ ((always_inline));
634 static __inline__ long long
635 __fctidz (double a)
636 {
637   long long d;
638   __asm__ ("fctidz %0,%1" : "=f" (d) : "f" (a));
639   return d;
640 }
641
642 static __inline__ int __fctiw (double a) __attribute__ ((always_inline));
643 static __inline__ int
644 __fctiw (double a)
645 {
646   unsigned long long d;
647   __asm__ ("fctiw %0,%1" : "=f" (d) : "f" (a));
648   return (int) d;
649 }
650
651 static __inline__ int __fctiwz (double a) __attribute__ ((always_inline));
652 static __inline__ int
653 __fctiwz (double a)
654 {
655   long long d;
656   __asm__ ("fctiwz %0,%1" : "=f" (d) : "f" (a));
657   return (int) d;
658 }
659
660 #ifdef __powerpc64__
661 #define __rldcl(a,b,mb) __extension__ \
662   ({ \
663     unsigned long long d; \
664     __asm__ ("rldcl %0,%1,%2,%3" : "=r" (d) : "r" (a), "r" (b), "i" (mb)); \
665     d; \
666   })
667
668 #define __rldcr(a,b,me) __extension__ \
669   ({ \
670     unsigned long long d; \
671     __asm__ ("rldcr %0,%1,%2,%3" : "=r" (d) : "r" (a), "r" (b), "i" (me)); \
672     d; \
673   })
674
675 #define __rldic(a,sh,mb) __extension__ \
676   ({ \
677     unsigned long long d; \
678     __asm__ ("rldic %0,%1,%2,%3" : "=r" (d) : "r" (a), "i" (sh), "i" (mb)); \
679     d; \
680   })
681
682 #define __rldicl(a,sh,mb) __extension__ \
683   ({ \
684     unsigned long long d; \
685     __asm__ ("rldicl %0,%1,%2,%3" : "=r" (d) : "r" (a), "i" (sh), "i" (mb)); \
686     d; \
687   })
688
689 #define __rldicr(a,sh,me) __extension__ \
690   ({ \
691     unsigned long long d; \
692     __asm__ ("rldicr %0,%1,%2,%3" : "=r" (d) : "r" (a), "i" (sh), "i" (me)); \
693     d; \
694   })
695
696 #define __rldimi(a,b,sh,mb) __extension__ \
697   ({ \
698     unsigned long long d; \
699     __asm__ ("rldimi %0,%1,%2,%3" : "=r" (d) : "r" (b), "i" (sh), "i" (mb), "0" (a)); \
700     d; \
701   })
702 #endif /* __powerpc64__ */
703
704 #define __rlwimi(a,b,sh,mb,me) __extension__ \
705   ({ \
706     unsigned int d; \
707     __asm__ ("rlwimi %0,%1,%2,%3,%4" : "=r" (d) : "r" (b), "i" (sh), "i" (mb), "i" (me), "0" (a)); \
708     d; \
709   })
710
711 #define __rlwinm(a,sh,mb,me) __extension__ \
712   ({ \
713     unsigned int d; \
714     __asm__ ("rlwinm %0,%1,%2,%3,%4" : "=r" (d) : "r" (a), "i" (sh), "i" (mb), "i" (me)); \
715     d; \
716   })
717
718 #define __rlwnm(a,b,mb,me) __extension__ \
719   ({ \
720     unsigned int d; \
721     __asm__ ("rlwnm %0,%1,%2,%3,%4" : "=r" (d) : "r" (a), "r" (b), "i" (mb), "i" (me)); \
722     d; \
723   })
724
725 #ifdef __cplusplus
726 }
727 #endif
728
729 #endif /* _PPU_INTRINSICS_H */