Esempio n. 1
0
/*
 * arccos(x) = pi/2 - arcsin(x)
 */
struct fpn *
fpu_acos(struct fpemu *fe)
{
    struct fpn *r;

    if (ISNAN(&fe->fe_f2))
        return &fe->fe_f2;
    if (ISINF(&fe->fe_f2))
        return fpu_newnan(fe);

    r = fpu_asin(fe);
    CPYFPN(&fe->fe_f2, r);

    /* pi/2 - asin(x) */
    fpu_const(&fe->fe_f1, FPU_CONST_PI);
    fe->fe_f1.fp_exp--;
    fe->fe_f2.fp_sign = !fe->fe_f2.fp_sign;
    r = fpu_add(fe);

    return r;
}
Esempio n. 2
0
/*
 *                          x
 * arcsin(x) = arctan(---------------)
 *                     sqrt(1 - x^2)
 */
struct fpn *
fpu_asin(struct fpemu *fe)
{
    struct fpn x;
    struct fpn *r;

    if (ISNAN(&fe->fe_f2))
        return &fe->fe_f2;
    if (ISZERO(&fe->fe_f2))
        return &fe->fe_f2;

    if (ISINF(&fe->fe_f2))
        return fpu_newnan(fe);

    CPYFPN(&x, &fe->fe_f2);

    /* x^2 */
    CPYFPN(&fe->fe_f1, &fe->fe_f2);
    r = fpu_mul(fe);

    /* 1 - x^2 */
    CPYFPN(&fe->fe_f2, r);
    fe->fe_f2.fp_sign = 1;
    fpu_const(&fe->fe_f1, FPU_CONST_1);
    r = fpu_add(fe);

    /* sqrt(1-x^2) */
    CPYFPN(&fe->fe_f2, r);
    r = fpu_sqrt(fe);

    /* x/sqrt */
    CPYFPN(&fe->fe_f2, r);
    CPYFPN(&fe->fe_f1, &x);
    r = fpu_div(fe);

    /* arctan */
    CPYFPN(&fe->fe_f2, r);
    return fpu_atan(fe);
}
Esempio n. 3
0
int main(int argc, char * argv[])
{
    unsigned short int fpucw = 0x1234;
    double dbls[3] = {123.45, 0.123, 0.0};
    /* generate double constants */
    unsigned long dbl = 0x4000000000000000;
    double * wsk = &dbl;
    dbls[1] = *wsk;
    printf("unsigned long: %lx\n", dbl);
    printf("unsigned long: %lf\n", *wsk);

    /* add two numbers */
    dbls[2] = fpu_add(dbls[0], dbls[1]);
    printf("default: %lf + %lf = %lf\n", dbls[0], dbls[1], dbls[2]); 

    /* print FPU control word */
    fpucw = get_fpu();
    printf("FPU CW: %04hx\n", fpucw);

    /* Return 0 if exiting normally.
     */
    return 0;
}
static struct fpn *
__fpu_modrem(struct fpemu *fe, int is_mod)
{
	static struct fpn X, Y;
	struct fpn *x, *y, *r;
	uint32_t signX, signY, signQ;
	int j, k, l, q;
	int cmp;

	if (ISNAN(&fe->fe_f1) || ISNAN(&fe->fe_f2))
		return fpu_newnan(fe);
	if (ISINF(&fe->fe_f1) || ISZERO(&fe->fe_f2))
		return fpu_newnan(fe);

	CPYFPN(&X, &fe->fe_f1);
	CPYFPN(&Y, &fe->fe_f2);
	x = &X;
	y = &Y;
	q = 0;
	r = &fe->fe_f2;

	/*
	 * Step 1
	 */
	signX = x->fp_sign;
	signY = y->fp_sign;
	signQ = (signX ^ signY);
	x->fp_sign = y->fp_sign = 0;

	/* Special treatment that just return input value but Q is necessary */
	if (ISZERO(x) || ISINF(y)) {
		r = &fe->fe_f1;
		goto Step7;
	}

	/*
	 * Step 2
	 */
	l = x->fp_exp - y->fp_exp;
	k = 0;
	CPYFPN(r, x);
	if (l >= 0) {
		r->fp_exp -= l;
		j = l;

		/*
		 * Step 3
		 */
		for (;;) {
			cmp = abscmp3(r, y);

			/* Step 3.1 */
			if (cmp == 0)
				break;

			/* Step 3.2 */
			if (cmp > 0) {
				CPYFPN(&fe->fe_f1, r);
				CPYFPN(&fe->fe_f2, y);
				fe->fe_f2.fp_sign = 1;
				r = fpu_add(fe);
				q++;
			}

			/* Step 3.3 */
			if (j == 0)
				goto Step4;

			/* Step 3.4 */
			k++;
			j--;
			q += q;
			r->fp_exp++;
		}
		/* R == Y */
		q++;
		r->fp_class = FPC_ZERO;
		goto Step7;
	}
 Step4:
	r->fp_sign = signX;

	/*
	 * Step 5
	 */
	if (is_mod)
		goto Step7;

	/*
	 * Step 6
	 */
	/* y = y / 2 */
	y->fp_exp--;
	/* abscmp3 ignore sign */
	cmp = abscmp3(r, y);
	/* revert y */
	y->fp_exp++;

	if (cmp > 0 || (cmp == 0 && q % 2)) {
		q++;
		CPYFPN(&fe->fe_f1, r);
		CPYFPN(&fe->fe_f2, y);
		fe->fe_f2.fp_sign = !signX;
		r = fpu_add(fe);
	}

	/*
	 * Step 7
	 */
 Step7:
	q &= 0x7f;
	q |= (signQ << 7);
	fe->fe_fpframe->fpf_fpsr =
	fe->fe_fpsr =
	    (fe->fe_fpsr & ~FPSR_QTT) | (q << 16);
	return r;
}
Esempio n. 5
0
/*
 * sin(x):
 *
 *	if (x < 0) {
 *		x = abs(x);
 *		sign = 1;
 *	}
 *	if (x > 2*pi) {
 *		x %= 2*pi;
 *	}
 *	if (x > pi) {
 *		x -= pi;
 *		sign inverse;
 *	}
 *	if (x > pi/2) {
 *		y = cos(x - pi/2);
 *	} else {
 *		y = sin(x);
 *	}
 *	if (sign) {
 *		y = -y;
 *	}
 */
struct fpn *
fpu_sin(struct fpemu *fe)
{
    struct fpn x;
    struct fpn p;
    struct fpn *r;
    int sign;

    if (ISNAN(&fe->fe_f2))
        return &fe->fe_f2;
    if (ISINF(&fe->fe_f2))
        return fpu_newnan(fe);

    /* if x is +0/-0, return +0/-0 */
    if (ISZERO(&fe->fe_f2))
        return &fe->fe_f2;

    CPYFPN(&x, &fe->fe_f2);

    /* x = abs(input) */
    sign = x.fp_sign;
    x.fp_sign = 0;

    /* p <- 2*pi */
    fpu_const(&p, FPU_CONST_PI);
    p.fp_exp++;

    /*
     * if (x > 2*pi*N)
     *  sin(x) is sin(x - 2*pi*N)
     */
    CPYFPN(&fe->fe_f1, &x);
    CPYFPN(&fe->fe_f2, &p);
    r = fpu_cmp(fe);
    if (r->fp_sign == 0) {
        CPYFPN(&fe->fe_f1, &x);
        CPYFPN(&fe->fe_f2, &p);
        r = fpu_mod(fe);
        CPYFPN(&x, r);
    }

    /* p <- pi */
    p.fp_exp--;

    /*
     * if (x > pi)
     *  sin(x) is -sin(x - pi)
     */
    CPYFPN(&fe->fe_f1, &x);
    CPYFPN(&fe->fe_f2, &p);
    fe->fe_f2.fp_sign = 1;
    r = fpu_add(fe);
    if (r->fp_sign == 0) {
        CPYFPN(&x, r);
        sign ^= 1;
    }

    /* p <- pi/2 */
    p.fp_exp--;

    /*
     * if (x > pi/2)
     *  sin(x) is cos(x - pi/2)
     * else
     *  sin(x)
     */
    CPYFPN(&fe->fe_f1, &x);
    CPYFPN(&fe->fe_f2, &p);
    fe->fe_f2.fp_sign = 1;
    r = fpu_add(fe);
    if (r->fp_sign == 0) {
        __fpu_sincos_cordic(fe, r);
        r = &fe->fe_f2;
    } else {
        __fpu_sincos_cordic(fe, &x);
        r = &fe->fe_f1;
    }
    r->fp_sign = sign;
    return r;
}