
/*
*  Copyright (C) 2008-2009 Advanced Micro Devices, Inc. All Rights Reserved.
*
*  This file is part of libacml_mv.
*
*  libacml_mv is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Lesser General Public
*  License as published by the Free Software Foundation; either
*  version 2.1 of the License, or (at your option) any later version.
*
*  libacml_mv is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*  Lesser General Public License for more details.
*
*  You should have received a copy of the GNU Lesser General Public
*  License along with libacml_mv.  If not, see
*  <http://www.gnu.org/licenses/>.
*
*/


#include <emmintrin.h>
#include <math.h>
#include <errno.h>


#include "../inc/libm_util_amd.h"
#include "../inc/libm_special.h"

double _sin_cos_special(double x, const char *name)
{
    UT64 xu;
	unsigned int is_snan;

	xu.f64 = x;

    if((xu.u64 & EXPBITS_DP64) == EXPBITS_DP64)
    {
        // x is Inf or NaN
        if((xu.u64 & MANTBITS_DP64) == 0x0)
        {
            // x is Inf
            _mm_setcsr(_mm_getcsr() | MXCSR_ES_INVALID); 
#ifdef WIN64
            xu.u64 = INDEFBITPATT_DP64;
			__amd_handle_error(DOMAIN, EDOM, name, x, 0, xu.f64);
#else
			xu.u64 = QNANBITPATT_DP64;
            name = *(&name); // dummy statement to avoid warning
#endif
		}
		else {
			// x is NaN
            is_snan = (((xu.u64 & QNAN_MASK_64) == QNAN_MASK_64) ? 0 : 1);
			if(is_snan){
				xu.u64 |= QNAN_MASK_64;
#ifdef WIN64
#else
				_mm_setcsr(_mm_getcsr() | MXCSR_ES_INVALID);
#endif
			}
#ifdef WIN64
			__amd_handle_error(DOMAIN, EDOM, name, x, 0, xu.f64);
#endif
		}
		
	}

	return xu.f64;
}

float _sinf_cosf_special(float x, const char *name)
{
    UT32 xu;
	unsigned int is_snan;

	xu.f32 = x;

    if((xu.u32 & EXPBITS_SP32) == EXPBITS_SP32)
    {
        // x is Inf or NaN
        if((xu.u32 & MANTBITS_SP32) == 0x0)
        {
            // x is Inf	
            _mm_setcsr(_mm_getcsr() | MXCSR_ES_INVALID);
#ifdef WIN64
            xu.u32 = INDEFBITPATT_SP32;
			__amd_handle_errorf(DOMAIN, EDOM, name, x, 0, 0.0f, 0, xu.f32, 0);
#else
			xu.u32 = QNANBITPATT_SP32; 
            name = *(&name); // dummy statement to avoid warning
#endif
		}
		else {
			// x is NaN
            is_snan = (((xu.u32 & QNAN_MASK_32) == QNAN_MASK_32) ? 0 : 1);
			if(is_snan) {
				xu.u32 |= QNAN_MASK_32;
				_mm_setcsr(_mm_getcsr() | MXCSR_ES_INVALID);
			}
#ifdef WIN64
			__amd_handle_errorf(DOMAIN, EDOM, name, x, is_snan, 0.0f, 0, xu.f32, 0);
#endif
		}
		
	}

	return xu.f32;
}

float _sinf_special(float x)
{
	return _sinf_cosf_special(x, "sinf");
}

double _sin_special(double x)
{
	return _sin_cos_special(x, "sin");
}

float _cosf_special(float x)
{
	return _sinf_cosf_special(x, "cosf");
}

double _cos_special(double x)
{
	return _sin_cos_special(x, "cos");
}

void _sincosf_special(float x, float *sy, float *cy)
{
    float xu = _sinf_cosf_special(x, "sincosf");

	*sy = xu;
	*cy = xu;

	return;
}

void _sincos_special(double x, double *sy, double *cy)
{
    double xu = _sin_cos_special(x, "sincos");

	*sy = xu;
	*cy = xu;

	return;
}
