1327952Sdim/* PPU intrinsics as defined by the C/C++ Language extension for Cell BEA. 2259698Sdim Copyright (C) 2007-2020 Free Software Foundation, Inc. 3353358Sdim 4353358Sdim This file is free software; you can redistribute it and/or modify it under 5353358Sdim the terms of the GNU General Public License as published by the Free 6259698Sdim Software Foundation; either version 3 of the License, or (at your option) 7259698Sdim any later version. 8259698Sdim 9259698Sdim This file is distributed in the hope that it will be useful, but WITHOUT 10259698Sdim ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11259698Sdim FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12259698Sdim for more details. 13259698Sdim 14259698Sdim Under Section 7 of GPL version 3, you are granted additional 15341825Sdim permissions described in the GCC Runtime Library Exception, version 16259698Sdim 3.1, as published by the Free Software Foundation. 17327952Sdim 18259698Sdim You should have received a copy of the GNU General Public License and 19327952Sdim a copy of the GCC Runtime Library Exception along with this program; 20327952Sdim see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 21327952Sdim <http://www.gnu.org/licenses/>. */ 22327952Sdim 23327952Sdim/* TODO: 24259698Sdim misc ops (traps) 25259698Sdim supervisor/hypervisor mode ops. */ 26259698Sdim 27327952Sdim#ifndef _PPU_INTRINSICS_H 28327952Sdim#define _PPU_INTRINSICS_H 29259698Sdim 30259698Sdim#if !defined(__PPU__) && !defined(__ppc__) && !defined(__ppc64__) \ 31276479Sdim && !defined(__GNUC__) 32276479Sdim #error ppu_intrinsics.h included on wrong platform/compiler 33259698Sdim#endif 34327952Sdim 35259698Sdim#ifdef __cplusplus 36259698Sdimextern "C" { 37327952Sdim#endif 38341825Sdim 39259698Sdim/* 40296417Sdim * unsigned int __cntlzw(unsigned int) 41327952Sdim * unsigned int __cntlzd(unsigned long long) 42341825Sdim * int __mulhw(int, int) 43259698Sdim * unsigned int __mulhwu(unsigned int, unsigned int) 44259698Sdim * long long __mulhd(long long, long long) 45296417Sdim * unsigned long long __mulhdu(unsigned long long, unsigned long long) 46327952Sdim * 47341825Sdim * void __sync(void) 48259698Sdim * void __isync(void) 49259698Sdim * void __lwsync(void) 50259698Sdim * void __eieio(void) 51259698Sdim * 52259698Sdim * void __nop(void) 53259698Sdim * void __cctpl(void) 54259698Sdim * void __cctpm(void) 55259698Sdim * void __cctph(void) 56259698Sdim * void __db8cyc(void) 57327952Sdim * void __db10cyc(void) 58259698Sdim * void __db12cyc(void) 59259698Sdim * void __db16cyc(void) 60259698Sdim * 61327952Sdim * void __mtspr(unsigned int spr, unsigned long long value) 62327952Sdim * unsigned long long __mfspr(unsigned int spr) 63259698Sdim * unsigned long long __mftb(void) 64259698Sdim * 65259698Sdim * void __icbi(void *base) 66259698Sdim * void __dcbi(void *base) 67259698Sdim * 68259698Sdim * void __dcbf(void *base) 69259698Sdim * void __dcbz(void *base) 70360784Sdim * void __dcbst(void *base) 71259698Sdim * void __dcbtst(void *base) 72259698Sdim * void __dcbt(void *base) 73259698Sdim * void __dcbt_TH1000(void *EATRUNC, bool D, bool UG, int ID) 74259698Sdim * void __dcbt_TH1010(bool GO, int S, int UNITCNT, bool T, bool U, int ID) 75259698Sdim * 76259698Sdim * unsigned __lwarx(void *base) 77259698Sdim * unsigned long long __ldarx(void *base) 78259698Sdim * bool __stwcx(void *base, unsigned value) 79259698Sdim * bool __stdcx(void *base, unsigned long long value) 80259698Sdim * 81259698Sdim * unsigned short __lhbrx(void *base) 82259698Sdim * unsigned int __lwbrx(void *base) 83259698Sdim * unsigned long long __ldbrx(void *base) 84259698Sdim * void __sthbrx(void *base, unsigned short value) 85259698Sdim * void __stwbrx(void *base, unsigned int value) 86259698Sdim * void __stdbrx(void *base, unsigned long long value) 87259698Sdim * 88259698Sdim * double __fabs(double x) 89259698Sdim * float __fabsf(float x) 90259698Sdim * double __fnabs(double x) 91259698Sdim * float __fnabsf(float x) 92259698Sdim * double __fmadd(double x, double y, double z) 93259698Sdim * double __fmsub(double x, double y, double z) 94259698Sdim * double __fnmadd(double x, double y, double z) 95259698Sdim * double __fnmsub(double x, double y, double z) 96259698Sdim * float __fmadds(float x, float y, float z) 97259698Sdim * float __fmsubs(float x, float y, float z) 98259698Sdim * float __fnmadds(float x, float y, float z) 99259698Sdim * float __fnmsubs(float x, float y, float z) 100259698Sdim * double __fsel(double x, double y, double z) 101259698Sdim * float __fsels(float x, float y, float z) 102259698Sdim * double __frsqrte(double x) 103259698Sdim * float __fres(float x) 104259698Sdim * double __fsqrt(double x) 105259698Sdim * float __fsqrts(float x) 106259698Sdim * long long __fctid(double x) 107259698Sdim * long long __fctiw(double x) 108259698Sdim * double __fcfid(long long x) 109259698Sdim * double __mffs(void) 110259698Sdim * void __mtfsf(int mask, double value) 111259698Sdim * void __mtfsfi(int bits, int field) 112259698Sdim * void __mtfsb0(int) 113259698Sdim * void __mtfsb1(int) 114259698Sdim * double __setflm(double) 115259698Sdim * 116259698Sdim * dcbt intrinsics 117259698Sdim * void __protected_unlimited_stream_set (unsigned int direction, const void *add, unsigned int ID) 118259698Sdim * void __protected_stream_set (unsigned int direction, const void *add, unsigned int ID) 119259698Sdim * void __protected_stream_stop_all (void) 120259698Sdim * void __protected_stream_stop (unsigned int ID) 121259698Sdim * void __protected_stream_count (unsigned int unit_cnt, unsigned int ID) 122259698Sdim * void __protected_stream_go (void) 123259698Sdim */ 124259698Sdim 125259698Sdimtypedef int __V4SI __attribute__((vector_size(16))); 126259698Sdim 127259698Sdim#define __cntlzw(v) __builtin_clz(v) 128259698Sdim#define __cntlzd(v) __builtin_clzll(v) 129259698Sdim 130259698Sdim#define __mulhw(a,b) __extension__ \ 131259698Sdim ({int result; \ 132259698Sdim __asm__ ("mulhw %0,%1,%2" \ 133259698Sdim : "=r" (result) \ 134259698Sdim : "r" ((int) (a)), \ 135259698Sdim "r" ((int) (b))); \ 136296417Sdim result; }) 137259698Sdim 138259698Sdim#define __mulhwu(a,b) __extension__ \ 139259698Sdim ({unsigned int result; \ 140259698Sdim __asm__ ("mulhwu %0,%1,%2" \ 141276479Sdim : "=r" (result) \ 142276479Sdim : "r" ((unsigned int) (a)), \ 143276479Sdim "r" ((unsigned int) (b))); \ 144259698Sdim result; }) 145259698Sdim 146259698Sdim#ifdef __powerpc64__ 147259698Sdim#define __mulhd(a,b) __extension__ \ 148259698Sdim ({ long long result; \ 149259698Sdim __asm__ ("mulhd %0,%1,%2" \ 150259698Sdim : "=r" (result) \ 151259698Sdim : "r" ((long long) (a)), \ 152259698Sdim "r" ((long long) (b))); \ 153259698Sdim result; }) 154259698Sdim 155259698Sdim#define __mulhdu(a,b) __extension__ \ 156259698Sdim ({unsigned long long result; \ 157259698Sdim __asm__ ("mulhdu %0,%1,%2" \ 158259698Sdim : "=r" (result) \ 159259698Sdim : "r" ((unsigned long long) (a)), \ 160259698Sdim "r" ((unsigned long long) (b))); \ 161259698Sdim result; }) 162259698Sdim#endif /* __powerpc64__ */ 163259698Sdim 164259698Sdim#define __sync() __asm__ volatile ("sync" : : : "memory") 165259698Sdim#define __isync() __asm__ volatile ("isync" : : : "memory") 166259698Sdim#define __lwsync() __asm__ volatile ("lwsync" : : : "memory") 167259698Sdim#define __eieio() __asm__ volatile ("eieio" : : : "memory") 168259698Sdim 169259698Sdim#define __nop() __asm__ volatile ("ori 0,0,0" : : : "memory") 170259698Sdim#define __cctpl() __asm__ volatile ("or 1,1,1" : : : "memory") 171259698Sdim#define __cctpm() __asm__ volatile ("or 2,2,2" : : : "memory") 172259698Sdim#define __cctph() __asm__ volatile ("or 3,3,3" : : : "memory") 173259698Sdim#define __db8cyc() __asm__ volatile ("or 28,28,28" : : : "memory") 174259698Sdim#define __db10cyc() __asm__ volatile ("or 29,29,29" : : : "memory") 175259698Sdim#define __db12cyc() __asm__ volatile ("or 30,30,30" : : : "memory") 176259698Sdim#define __db16cyc() __asm__ volatile ("or 31,31,31" : : : "memory") 177259698Sdim 178259698Sdim#ifdef __powerpc64__ 179259698Sdim#define __mtspr(spr, value) \ 180259698Sdim __asm__ volatile ("mtspr %0,%1" : : "n" (spr), "r" (value)) 181259698Sdim 182259698Sdim#define __mfspr(spr) __extension__ \ 183259698Sdim ({ unsigned long long result; \ 184259698Sdim __asm__ volatile ("mfspr %0,%1" : "=r" (result) : "n" (spr)); \ 185259698Sdim result; }) 186259698Sdim#endif /* __powerpc64__ */ 187259698Sdim 188259698Sdim#ifdef __powerpc64__ 189259698Sdim/* Work around the hardware bug in the current Cell implementation. */ 190296417Sdim#define __mftb() __extension__ \ 191296417Sdim ({ unsigned long long result; \ 192296417Sdim __asm__ volatile ("1: mftb %[current_tb]\n" \ 193259698Sdim "\tcmpwi 7, %[current_tb], 0\n" \ 194259698Sdim "\tbeq- 7, 1b" \ 195259698Sdim : [current_tb] "=r" (result): \ 196259698Sdim :"cr7"); \ 197259698Sdim result; }) 198259698Sdim#else 199259698Sdim#define __mftb() __extension__ \ 200259698Sdim ({ unsigned long long result; \ 201259698Sdim unsigned long t; \ 202259698Sdim __asm__ volatile ("1:\n" \ 203259698Sdim "\tmftbu %0\n" \ 204259698Sdim "\tmftb %L0\n" \ 205259698Sdim "\tmftbu %1\n" \ 206259698Sdim "\tcmpw %0,%1\n" \ 207259698Sdim "\tbne 1b" \ 208259698Sdim : "=r" (result), "=r" (t)); \ 209259698Sdim result; }) 210259698Sdim#endif /* __powerpc64__ */ 211259698Sdim 212259698Sdim#define __dcbf(base) \ 213259698Sdim __asm__ volatile ("dcbf %y0" : "=Z" (*(__V4SI*) (base)) : : "memory") 214259698Sdim 215259698Sdim#define __dcbz(base) \ 216259698Sdim __asm__ volatile ("dcbz %y0" : "=Z" (*(__V4SI*) (base)) : : "memory") 217259698Sdim 218259698Sdim#define __dcbst(base) \ 219259698Sdim __asm__ volatile ("dcbst %y0" : "=Z" (*(__V4SI*) (base)) : : "memory") 220259698Sdim 221259698Sdim#define __dcbtst(base) \ 222259698Sdim __asm__ volatile ("dcbtst %y0" : "=Z" (*(__V4SI*) (base)) : : "memory") 223259698Sdim 224259698Sdim#define __dcbt(base) \ 225259698Sdim __asm__ volatile ("dcbt %y0" : "=Z" (*(__V4SI*) (base)) : : "memory") 226259698Sdim 227259698Sdim#define __icbi(base) \ 228259698Sdim __asm__ volatile ("icbi %y0" : "=Z" (*(__V4SI*) (base)) : : "memory") 229259698Sdim 230259698Sdim#define __dcbt_TH1000(EATRUNC, D, UG, ID) \ 231259698Sdim __asm__ volatile ("dcbt %y0,8" \ 232259698Sdim : "=Z" (*(__V4SI*) (__SIZE_TYPE__)((((__SIZE_TYPE__) (EATRUNC)) & ~0x7F) \ 233259698Sdim | ((((D) & 1) << 6) \ 234344779Sdim | (((UG) & 1) << 5) \ 235259698Sdim | ((ID) & 0xF)))) : : "memory") 236259698Sdim 237259698Sdim#define __dcbt_TH1010(GO, S, UNITCNT, T, U, ID) \ 238259698Sdim __asm__ volatile ("dcbt %y0,10" \ 239259698Sdim : "=Z" (*(__V4SI*) (__SIZE_TYPE__)((((__SIZE_TYPE__) (GO) & 1) << 31) \ 240259698Sdim | (((S) & 0x3) << 29) \ 241259698Sdim | (((UNITCNT) & 0x3FF) << 7) \ 242259698Sdim | (((T) & 1) << 6) \ 243259698Sdim | (((U) & 1) << 5) \ 244259698Sdim | ((ID) & 0xF))) : : "memory") 245259698Sdim 246259698Sdim#define __protected_unlimited_stream_set(DIRECTION, ADDR, ID) \ 247259698Sdim __dcbt_TH1000 ((ADDR), (DIRECTION)>>1, 1, (ID)) 248259698Sdim 249259698Sdim#define __protected_stream_set(DIRECTION, ADDR, ID) \ 250259698Sdim __dcbt_TH1000 ((ADDR), (DIRECTION)>>1, 0, (ID)) 251259698Sdim 252327952Sdim#define __protected_stream_stop_all() \ 253327952Sdim __dcbt_TH1010 (0, 3, 0, 0, 0, 0) 254360784Sdim 255360784Sdim#define __protected_stream_stop(ID) \ 256280031Sdim __dcbt_TH1010 (0, 2, 0, 0, 0, (ID)) 257280031Sdim 258280031Sdim#define __protected_stream_count(COUNT, ID) \ 259259698Sdim __dcbt_TH1010 (0, 0, (COUNT), 0, 0, (ID)) 260276479Sdim 261259698Sdim#define __protected_stream_go() \ 262259698Sdim __dcbt_TH1010 (1, 0, 0, 0, 0, 0) 263259698Sdim 264259698Sdim#define __lhbrx(base) __extension__ \ 265259698Sdim ({unsigned short result; \ 266259698Sdim typedef struct {char a[2];} halfwordsize; \ 267259698Sdim halfwordsize *ptrp = (halfwordsize*)(void*)(base); \ 268259698Sdim __asm__ ("lhbrx %0,%y1" \ 269259698Sdim : "=r" (result) \ 270259698Sdim : "Z" (*ptrp)); \ 271259698Sdim result; }) 272259698Sdim 273259698Sdim#define __lwbrx(base) __extension__ \ 274259698Sdim ({unsigned int result; \ 275259698Sdim typedef struct {char a[4];} wordsize; \ 276259698Sdim wordsize *ptrp = (wordsize*)(void*)(base); \ 277259698Sdim __asm__ ("lwbrx %0,%y1" \ 278259698Sdim : "=r" (result) \ 279259698Sdim : "Z" (*ptrp)); \ 280259698Sdim result; }) 281360784Sdim 282259698Sdim 283259698Sdim#ifdef __powerpc64__ 284259698Sdim#define __ldbrx(base) __extension__ \ 285259698Sdim ({unsigned long long result; \ 286259698Sdim typedef struct {char a[8];} doublewordsize; \ 287259698Sdim doublewordsize *ptrp = (doublewordsize*)(void*)(base); \ 288259698Sdim __asm__ ("ldbrx %0,%y1" \ 289259698Sdim : "=r" (result) \ 290259698Sdim : "Z" (*ptrp)); \ 291259698Sdim result; }) 292259698Sdim#else 293259698Sdim#define __ldbrx(base) __extension__ \ 294259698Sdim ({unsigned long long result; \ 295259698Sdim typedef struct {char a[8];} doublewordsize; \ 296259698Sdim doublewordsize *ptrp = (doublewordsize*)(void*)(base); \ 297259698Sdim __asm__ ("lwbrx %L0,%y1\n" \ 298259698Sdim "\tlwbrx %0,%y2" \ 299259698Sdim : "=&r" (result) \ 300259698Sdim : "Z" (*ptrp), "Z" (*((char *) ptrp + 4))); \ 301259698Sdim result; }) 302259698Sdim#endif /* __powerpc64__ */ 303259698Sdim 304259698Sdim 305259698Sdim#define __sthbrx(base, value) do { \ 306259698Sdim typedef struct {char a[2];} halfwordsize; \ 307259698Sdim halfwordsize *ptrp = (halfwordsize*)(void*)(base); \ 308259698Sdim __asm__ ("sthbrx %1,%y0" \ 309259698Sdim : "=Z" (*ptrp) \ 310259698Sdim : "r" (value)); \ 311259698Sdim } while (0) 312259698Sdim 313259698Sdim#define __stwbrx(base, value) do { \ 314341825Sdim typedef struct {char a[4];} wordsize; \ 315259698Sdim wordsize *ptrp = (wordsize*)(void*)(base); \ 316259698Sdim __asm__ ("stwbrx %1,%y0" \ 317259698Sdim : "=Z" (*ptrp) \ 318259698Sdim : "r" (value)); \ 319259698Sdim } while (0) 320259698Sdim 321259698Sdim#ifdef __powerpc64__ 322259698Sdim#define __stdbrx(base, value) do { \ 323259698Sdim typedef struct {char a[8];} doublewordsize; \ 324259698Sdim doublewordsize *ptrp = (doublewordsize*)(void*)(base); \ 325259698Sdim __asm__ ("stdbrx %1,%y0" \ 326259698Sdim : "=Z" (*ptrp) \ 327344779Sdim : "r" (value)); \ 328296417Sdim } while (0) 329259698Sdim#else 330259698Sdim#define __stdbrx(base, value) do { \ 331259698Sdim typedef struct {char a[8];} doublewordsize; \ 332259698Sdim doublewordsize *ptrp = (doublewordsize*)(void*)(base); \ 333259698Sdim __asm__ ("stwbrx %L2,%y0\n" \ 334259698Sdim "\tstwbrx %2,%y1" \ 335259698Sdim : "=Z" (*ptrp), "=Z" (*((char *) ptrp + 4)) \ 336259698Sdim : "r" (value)); \ 337259698Sdim } while (0) 338259698Sdim#endif /* __powerpc64__ */ 339259698Sdim 340296417Sdim 341259698Sdim#define __lwarx(base) __extension__ \ 342296417Sdim ({unsigned int result; \ 343259698Sdim typedef struct {char a[4];} wordsize; \ 344327952Sdim wordsize *ptrp = (wordsize*)(void*)(base); \ 345259698Sdim __asm__ volatile ("lwarx %0,%y1" \ 346259698Sdim : "=r" (result) \ 347259698Sdim : "Z" (*ptrp)); \ 348259698Sdim result; }) 349259698Sdim 350259698Sdim#ifdef __powerpc64__ 351296417Sdim#define __ldarx(base) __extension__ \ 352259698Sdim ({unsigned long long result; \ 353259698Sdim typedef struct {char a[8];} doublewordsize; \ 354259698Sdim doublewordsize *ptrp = (doublewordsize*)(void*)(base); \ 355259698Sdim __asm__ volatile ("ldarx %0,%y1" \ 356259698Sdim : "=r" (result) \ 357259698Sdim : "Z" (*ptrp)); \ 358259698Sdim result; }) 359259698Sdim#endif /* __powerpc64__ */ 360259698Sdim 361259698Sdim#define __stwcx(base, value) __extension__ \ 362259698Sdim ({unsigned int result; \ 363259698Sdim typedef struct {char a[4];} wordsize; \ 364259698Sdim wordsize *ptrp = (wordsize*)(void*)(base); \ 365259698Sdim __asm__ volatile ("stwcx. %2,%y1\n" \ 366259698Sdim "\tmfocrf %0,0x80" \ 367259698Sdim : "=r" (result), \ 368259698Sdim "=Z" (*ptrp) \ 369296417Sdim : "r" (value) : "cr0"); \ 370259698Sdim ((result & 0x20000000) >> 29); }) 371259698Sdim 372296417Sdim 373259698Sdim#ifdef __powerpc64__ 374259698Sdim#define __stdcx(base, value) __extension__ \ 375259698Sdim ({unsigned long long result; \ 376259698Sdim typedef struct {char a[8];} doublewordsize; \ 377259698Sdim doublewordsize *ptrp = (doublewordsize*)(void*)(base); \ 378259698Sdim __asm__ volatile ("stdcx. %2,%y1\n" \ 379259698Sdim "\tmfocrf %0,0x80" \ 380259698Sdim : "=r" (result), \ 381259698Sdim "=Z" (*ptrp) \ 382259698Sdim : "r" (value) : "cr0"); \ 383259698Sdim ((result & 0x20000000) >> 29); }) 384259698Sdim#endif /* __powerpc64__ */ 385259698Sdim 386259698Sdim#define __mffs() __extension__ \ 387259698Sdim ({double result; \ 388259698Sdim __asm__ volatile ("mffs %0" : "=d" (result)); \ 389259698Sdim result; }) 390259698Sdim 391259698Sdim#define __mtfsf(mask,value) \ 392259698Sdim __asm__ volatile ("mtfsf %0,%1" : : "n" (mask), "d" ((double) (value))) 393259698Sdim 394259698Sdim#define __mtfsfi(bits,field) \ 395259698Sdim __asm__ volatile ("mtfsfi %0,%1" : : "n" (bits), "n" (field)) 396259698Sdim 397259698Sdim#define __mtfsb0(bit) __asm__ volatile ("mtfsb0 %0" : : "n" (bit)) 398296417Sdim#define __mtfsb1(bit) __asm__ volatile ("mtfsb1 %0" : : "n" (bit)) 399259698Sdim 400259698Sdim#define __setflm(v) __extension__ \ 401259698Sdim ({double result; \ 402259698Sdim __asm__ volatile ("mffs %0\n\tmtfsf 255,%1" \ 403259698Sdim : "=&d" (result) \ 404259698Sdim : "d" ((double) (v))); \ 405259698Sdim result; }) 406259698Sdim 407259698Sdim/* __builtin_fabs may perform unnecessary rounding. */ 408259698Sdim 409259698Sdim/* Rename __fabs and __fabsf to work around internal prototypes defined 410259698Sdim in bits/mathcalls.h with some glibc versions. */ 411259698Sdim#define __fabs __ppu_fabs 412259698Sdim#define __fabsf __ppu_fabsf 413259698Sdim 414259698Sdimstatic __inline__ double __fabs(double x) __attribute__((always_inline)); 415259698Sdimstatic __inline__ double 416259698Sdim__fabs(double x) 417259698Sdim{ 418259698Sdim double r; 419259698Sdim __asm__("fabs %0,%1" : "=d"(r) : "d"(x)); 420259698Sdim return r; 421259698Sdim} 422259698Sdim 423344779Sdimstatic __inline__ float __fabsf(float x) __attribute__((always_inline)); 424296417Sdimstatic __inline__ float 425259698Sdim__fabsf(float x) 426259698Sdim{ 427259698Sdim float r; 428259698Sdim __asm__("fabs %0,%1" : "=f"(r) : "f"(x)); 429259698Sdim return r; 430259698Sdim} 431259698Sdim 432259698Sdimstatic __inline__ double __fnabs(double x) __attribute__((always_inline)); 433259698Sdimstatic __inline__ double 434259698Sdim__fnabs(double x) 435259698Sdim{ 436296417Sdim double r; 437296417Sdim __asm__("fnabs %0,%1" : "=d"(r) : "d"(x)); 438259698Sdim return r; 439259698Sdim} 440259698Sdim 441259698Sdimstatic __inline__ float __fnabsf(float x) __attribute__((always_inline)); 442259698Sdimstatic __inline__ float 443259698Sdim__fnabsf(float x) 444259698Sdim{ 445259698Sdim float r; 446259698Sdim __asm__("fnabs %0,%1" : "=f"(r) : "f"(x)); 447360784Sdim return r; 448259698Sdim} 449259698Sdim 450259698Sdimstatic __inline__ double __fmadd(double x, double y, double z) 451259698Sdim __attribute__((always_inline)); 452259698Sdimstatic __inline__ double 453259698Sdim__fmadd(double x, double y, double z) 454259698Sdim{ 455259698Sdim double r; 456360784Sdim __asm__("fmadd %0,%1,%2,%3" : "=d"(r) : "d"(x),"d"(y),"d"(z)); 457360784Sdim return r; 458360784Sdim} 459360784Sdim 460360784Sdimstatic __inline__ double __fmsub(double x, double y, double z) 461360784Sdim __attribute__((always_inline)); 462360784Sdimstatic __inline__ double 463360784Sdim__fmsub(double x, double y, double z) 464360784Sdim{ 465360784Sdim double r; 466259698Sdim __asm__("fmsub %0,%1,%2,%3" : "=d"(r) : "d"(x),"d"(y),"d"(z)); 467259698Sdim return r; 468259698Sdim} 469259698Sdim 470259698Sdimstatic __inline__ double __fnmadd(double x, double y, double z) 471259698Sdim __attribute__((always_inline)); 472259698Sdimstatic __inline__ double 473259698Sdim__fnmadd(double x, double y, double z) 474259698Sdim{ 475259698Sdim double r; 476259698Sdim __asm__("fnmadd %0,%1,%2,%3" : "=d"(r) : "d"(x),"d"(y),"d"(z)); 477259698Sdim return r; 478259698Sdim} 479259698Sdim 480259698Sdimstatic __inline__ double __fnmsub(double x, double y, double z) 481341825Sdim __attribute__((always_inline)); 482259698Sdimstatic __inline__ double 483259698Sdim__fnmsub(double x, double y, double z) 484259698Sdim{ 485259698Sdim double r; 486259698Sdim __asm__("fnmsub %0,%1,%2,%3" : "=d"(r) : "d"(x),"d"(y),"d"(z)); 487259698Sdim return r; 488259698Sdim} 489259698Sdim 490259698Sdimstatic __inline__ float __fmadds(float x, float y, float z) 491314564Sdim __attribute__((always_inline)); 492259698Sdimstatic __inline__ float 493314564Sdim__fmadds(float x, float y, float z) 494259698Sdim{ 495259698Sdim float r; 496259698Sdim __asm__("fmadds %0,%1,%2,%3" : "=f"(r) : "f"(x),"f"(y),"f"(z)); 497259698Sdim return r; 498327952Sdim} 499259698Sdim 500259698Sdimstatic __inline__ float __fmsubs(float x, float y, float z) 501259698Sdim __attribute__((always_inline)); 502static __inline__ float 503__fmsubs(float x, float y, float z) 504{ 505 float r; 506 __asm__("fmsubs %0,%1,%2,%3" : "=f"(r) : "f"(x),"f"(y),"f"(z)); 507 return r; 508} 509 510static __inline__ float __fnmadds(float x, float y, float z) 511 __attribute__((always_inline)); 512static __inline__ float 513__fnmadds(float x, float y, float z) 514{ 515 float r; 516 __asm__("fnmadds %0,%1,%2,%3" : "=f"(r) : "f"(x),"f"(y),"f"(z)); 517 return r; 518} 519 520static __inline__ float __fnmsubs(float x, float y, float z) 521 __attribute__((always_inline)); 522static __inline__ float 523__fnmsubs(float x, float y, float z) 524{ 525 float r; 526 __asm__("fnmsubs %0,%1,%2,%3" : "=f"(r) : "f"(x),"f"(y),"f"(z)); 527 return r; 528} 529 530static __inline__ double __fsel(double x, double y, double z) 531 __attribute__((always_inline)); 532static __inline__ double 533__fsel(double x, double y, double z) 534{ 535 double r; 536 __asm__("fsel %0,%1,%2,%3" : "=d"(r) : "d"(x),"d"(y),"d"(z)); 537 return r; 538} 539 540static __inline__ float __fsels(float x, float y, float z) 541 __attribute__((always_inline)); 542static __inline__ float 543__fsels(float x, float y, float z) 544{ 545 float r; 546 __asm__("fsel %0,%1,%2,%3" : "=f"(r) : "f"(x),"f"(y),"f"(z)); 547 return r; 548} 549 550static __inline__ double __frsqrte(double x) __attribute__((always_inline)); 551static __inline__ double 552__frsqrte(double x) 553{ 554 double r; 555 __asm__("frsqrte %0,%1" : "=d" (r) : "d" (x)); 556 return r; 557} 558 559static __inline__ float __fres(float x) __attribute__((always_inline)); 560static __inline__ float 561__fres(float x) 562{ 563 float r; 564 __asm__("fres %0,%1" : "=f"(r) : "f"(x)); 565 return r; 566} 567 568static __inline__ double __fsqrt(double x) __attribute__((always_inline)); 569static __inline__ double 570__fsqrt(double x) 571{ 572 double r; 573 __asm__("fsqrt %0,%1" : "=d"(r) : "d"(x)); 574 return r; 575} 576 577static __inline__ float __fsqrts(float x) __attribute__((always_inline)); 578static __inline__ float 579__fsqrts(float x) 580{ 581 float r; 582 __asm__("fsqrts %0,%1" : "=f"(r) : "f"(x)); 583 return r; 584} 585 586static __inline__ double __fmul (double a, double b) __attribute__ ((always_inline)); 587static __inline__ double 588__fmul(double a, double b) 589{ 590 double d; 591 __asm__ ("fmul %0,%1,%2" : "=d" (d) : "d" (a), "d" (b)); 592 return d; 593} 594 595static __inline__ float __fmuls (float a, float b) __attribute__ ((always_inline)); 596static __inline__ float 597__fmuls (float a, float b) 598{ 599 float d; 600 __asm__ ("fmuls %0,%1,%2" : "=d" (d) : "f" (a), "f" (b)); 601 return d; 602} 603 604static __inline__ float __frsp (float a) __attribute__ ((always_inline)); 605static __inline__ float 606__frsp (float a) 607{ 608 float d; 609 __asm__ ("frsp %0,%1" : "=d" (d) : "f" (a)); 610 return d; 611} 612 613static __inline__ double __fcfid (long long a) __attribute__((always_inline)); 614static __inline__ double 615__fcfid (long long a) 616{ 617 double d; 618 __asm__ ("fcfid %0,%1" : "=d" (d) : "d" (a)); 619 return d; 620} 621 622static __inline__ long long __fctid (double a) __attribute__ ((always_inline)); 623static __inline__ long long 624__fctid (double a) 625{ 626 long long d; 627 __asm__ ("fctid %0,%1" : "=d" (d) : "d" (a)); 628 return d; 629} 630 631static __inline__ long long __fctidz (double a) __attribute__ ((always_inline)); 632static __inline__ long long 633__fctidz (double a) 634{ 635 long long d; 636 __asm__ ("fctidz %0,%1" : "=d" (d) : "d" (a)); 637 return d; 638} 639 640static __inline__ int __fctiw (double a) __attribute__ ((always_inline)); 641static __inline__ int 642__fctiw (double a) 643{ 644 unsigned long long d; 645 __asm__ ("fctiw %0,%1" : "=d" (d) : "d" (a)); 646 return (int) d; 647} 648 649static __inline__ int __fctiwz (double a) __attribute__ ((always_inline)); 650static __inline__ int 651__fctiwz (double a) 652{ 653 long long d; 654 __asm__ ("fctiwz %0,%1" : "=d" (d) : "d" (a)); 655 return (int) d; 656} 657 658#ifdef __powerpc64__ 659#define __rldcl(a,b,mb) __extension__ \ 660 ({ \ 661 unsigned long long d; \ 662 __asm__ ("rldcl %0,%1,%2,%3" : "=r" (d) : "r" (a), "r" (b), "i" (mb)); \ 663 d; \ 664 }) 665 666#define __rldcr(a,b,me) __extension__ \ 667 ({ \ 668 unsigned long long d; \ 669 __asm__ ("rldcr %0,%1,%2,%3" : "=r" (d) : "r" (a), "r" (b), "i" (me)); \ 670 d; \ 671 }) 672 673#define __rldic(a,sh,mb) __extension__ \ 674 ({ \ 675 unsigned long long d; \ 676 __asm__ ("rldic %0,%1,%2,%3" : "=r" (d) : "r" (a), "i" (sh), "i" (mb)); \ 677 d; \ 678 }) 679 680#define __rldicl(a,sh,mb) __extension__ \ 681 ({ \ 682 unsigned long long d; \ 683 __asm__ ("rldicl %0,%1,%2,%3" : "=r" (d) : "r" (a), "i" (sh), "i" (mb)); \ 684 d; \ 685 }) 686 687#define __rldicr(a,sh,me) __extension__ \ 688 ({ \ 689 unsigned long long d; \ 690 __asm__ ("rldicr %0,%1,%2,%3" : "=r" (d) : "r" (a), "i" (sh), "i" (me)); \ 691 d; \ 692 }) 693 694#define __rldimi(a,b,sh,mb) __extension__ \ 695 ({ \ 696 unsigned long long d; \ 697 __asm__ ("rldimi %0,%1,%2,%3" : "=r" (d) : "r" (b), "i" (sh), "i" (mb), "0" (a)); \ 698 d; \ 699 }) 700#endif /* __powerpc64__ */ 701 702#define __rlwimi(a,b,sh,mb,me) __extension__ \ 703 ({ \ 704 unsigned int d; \ 705 __asm__ ("rlwimi %0,%1,%2,%3,%4" : "=r" (d) : "r" (b), "i" (sh), "i" (mb), "i" (me), "0" (a)); \ 706 d; \ 707 }) 708 709#define __rlwinm(a,sh,mb,me) __extension__ \ 710 ({ \ 711 unsigned int d; \ 712 __asm__ ("rlwinm %0,%1,%2,%3,%4" : "=r" (d) : "r" (a), "i" (sh), "i" (mb), "i" (me)); \ 713 d; \ 714 }) 715 716#define __rlwnm(a,b,mb,me) __extension__ \ 717 ({ \ 718 unsigned int d; \ 719 __asm__ ("rlwnm %0,%1,%2,%3,%4" : "=r" (d) : "r" (a), "r" (b), "i" (mb), "i" (me)); \ 720 d; \ 721 }) 722 723#ifdef __cplusplus 724} 725#endif 726 727#endif /* _PPU_INTRINSICS_H */ 728