| @@ -70,26 +70,36 @@ unsigned int cucul_sqrt(unsigned int a) | |||||
| return 2 * cucul_sqrt(a / 4); | return 2 * cucul_sqrt(a / 4); | ||||
| } | } | ||||
| /** | /** | ||||
| * \brief powf substitute (x^y) | * \brief powf substitute (x^y) | ||||
| * \param x The value to be raised | * \param x The value to be raised | ||||
| * \param y The power to raise x of. | |||||
| * \param y The power to raise x to (only works with integers) | |||||
| * \return \p x raised to the power of \p y | * \return \p x raised to the power of \p y | ||||
| */ | */ | ||||
| float cucul_powf(float x, float y) | float cucul_powf(float x, float y) | ||||
| { | { | ||||
| int i=((int)y); | |||||
| float r=x; | |||||
| #ifdef __i386__ | |||||
| /* FIXME: this can be optimised by directly calling fyl2x for x and y */ | |||||
| register double logx; | |||||
| register long double v, e; | |||||
| if(((int)y)==1 || ((int)x)==1) | |||||
| return x; | |||||
| asm volatile("fldln2; fxch; fyl2x" | |||||
| : "=t" (logx) : "0" (x) : "st(1)"); | |||||
| i--; | |||||
| while(i--) | |||||
| { | |||||
| r*=x; | |||||
| } | |||||
| return r; | |||||
| asm volatile("fldl2e\n\t" | |||||
| "fmul %%st(1)\n\t" | |||||
| "fst %%st(1)\n\t" | |||||
| "frndint\n\t" | |||||
| "fxch\n\t" | |||||
| "fsub %%st(1)\n\t" | |||||
| "f2xm1\n\t" | |||||
| : "=t" (v), "=u" (e) : "0" (y * logx)); | |||||
| v += 1.0; | |||||
| asm volatile("fscale" | |||||
| : "=t" (v) : "0" (v), "u" (e)); | |||||
| return v; | |||||
| #else | |||||
| return x; /* HAHAHA VIEUX PORC */ | |||||
| #endif | |||||
| } | } | ||||