/* SCE CONFIDENTIAL
PLAYSTATION(R)3 Programmer Tool Runtime Library 084.006
* Copyright (C) 2004 Sony Computer Entertainment Inc. 
* All Rights Reserved.
*/

//
// Computes the inverse sine of all four slots of x
//
_FUNC_DEF(vec_float4, asinf4, (vec_float4 x))
{
    // positive = (x > 0)
    //
    vec_uint4 positive = (vec_uint4)vec_cmpgt(x,(vec_float4)(0.0f));

    // x = absf(x)
    //
    x = vec_abs(x);

    // gtHalf = (|x| > 0.5)
    //
    vec_uint4 gtHalf = (vec_uint4)vec_cmpgt(x,(vec_float4)(0.5f));    


    // if (x > 0.5)
    //    g = 0.5 - 0.5*x
    //    x = -2 * sqrtf(g)
    // else
    //    g = x * x
    //
    vec_float4 g = vec_sel(vec_madd(x,x,(vec_float4)(0.0f)),vec_madd((vec_float4)(-0.5f),x,(vec_float4)(0.5f)),gtHalf);
    
    x = vec_sel(x,vec_madd((vec_float4)(-2.0f),sqrtf4(g),(vec_float4)(0.0f)),gtHalf);

    // Compute the polynomials and take their ratio
    //  denom = (1.0f*g + -0.554846723e+1f)*g + 5.603603363f
    //  num = x * g * (-0.504400557f * g + 0.933933258f)
    //
    vec_float4 denom = vec_add(g,(vec_float4)(-5.54846723f));
    vec_float4 num = vec_madd((vec_float4)(-0.504400557f),g,(vec_float4)(0.933933258f));
    denom = vec_madd(denom,g,(vec_float4)(5.603603363f));
    num = vec_madd(vec_madd(x,g,(vec_float4)(0.0f)),num,(vec_float4)(0.0f));

    
    // x = x + num / denom
    //
    x = vec_add(x,divf4(num,denom));

    // if (x > 0.5)
    //    x = x + M_PI_2
    //
    x = vec_sel(x,vec_add(x,(vec_float4)(1.57079632679489661923f)),gtHalf);

    
    // if (!positive) x = -x
    //
    x = vec_sel((vec_float4)vec_xor((vec_int4)(0x80000000),(vec_int4)x),x,positive);

    return x;
}

