diff --git a/cucul/math.c b/cucul/math.c index 3ffd870..3bedccb 100644 --- a/cucul/math.c +++ b/cucul/math.c @@ -70,26 +70,36 @@ unsigned int cucul_sqrt(unsigned int a) return 2 * cucul_sqrt(a / 4); } - /** * \brief powf substitute (x^y) * \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 */ - 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 }