//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============// // // Purpose: // //=====================================================================================// #include "mathlib/ssemath.h" // NOTE: This has to be the last file included! #include "tier0/memdbgon.h" fltx4 Pow_FixedPoint_Exponent_SIMD(const fltx4& x, int exponent) { fltx4 rslt = Four_Ones; // x^0=1.0 int xp = abs(exponent); if (xp & 3) // fraction present? { fltx4 sq_rt = SqrtEstSIMD(x); if (xp & 1) // .25? rslt = SqrtEstSIMD(sq_rt); // x^.25 if (xp & 2) rslt = MulSIMD(rslt, sq_rt); } xp >>= 2; // strip fraction fltx4 curpower = x; // curpower iterates through x,x^2,x^4,x^8,x^16... while (1) { if (xp & 1) rslt = MulSIMD(rslt, curpower); xp >>= 1; if (xp) curpower = MulSIMD(curpower, curpower); else break; } if (exponent < 0) return ReciprocalEstSaturateSIMD(rslt); // pow(x,-b)=1/pow(x,b) else return rslt; } #ifndef _PS3 // these aren't fast (or correct) on the PS3 /* * (c) Ian Stephenson * * ian@dctsystems.co.uk * * Fast pow() reference implementation */ static float shift23 = (1 << 23); static float OOshift23 = 1.0 / (1 << 23); float FastLog2(float i) { float LogBodge = 0.346607f; float x; float y; x = float(*(int*)&i); x *= OOshift23; //1/pow(2,23); x = x - 127; y = x - floorf(x); y = (y - y * y) * LogBodge; return x + y; } float FastPow2(float i) { float PowBodge = 0.33971f; float x; float y = i - floorf(i); y = (y - y * y) * PowBodge; x = i + 127 - y; x *= shift23; //pow(2,23); *(int*)&x = (int)x; return x; } float FastPow(float a, float b) { if (a <= OOshift23) { return 0.0f; } return FastPow2(b * FastLog2(a)); } float FastPow10(float i) { return FastPow2(i * 3.321928f); } #else #pragma message("TODO: revisit fast logs on all PPC hardware") #endif