示例#1
0
文件: fpu_trig.c 项目: kame/kame
static void
fptan(void)
{
    FPU_REG *st_new_ptr;
    int     q;
    char    arg_sign = FPU_st0_ptr->sign;

    if (STACK_OVERFLOW) {
        stack_overflow();
        return;
    }
    switch (FPU_st0_tag) {
    case TW_Valid:

#ifdef DENORM_OPERAND
        if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()))
            return;
#endif				/* DENORM_OPERAND */

        FPU_st0_ptr->sign = SIGN_POS;
        if ((q = trig_arg(FPU_st0_ptr)) != -1) {
            if (q & 1)
                reg_sub(&CONST_1, FPU_st0_ptr, FPU_st0_ptr, FULL_PRECISION);

            poly_tan(FPU_st0_ptr, FPU_st0_ptr);

            FPU_st0_ptr->sign = (q & 1) ^ arg_sign;

            if (FPU_st0_ptr->exp <= EXP_UNDER)
                arith_underflow(FPU_st0_ptr);

            push();
            reg_move(&CONST_1, FPU_st0_ptr);
            setcc(0);
        } else {
            /* Operand is out of range */
            setcc(SW_C2);
            FPU_st0_ptr->sign = arg_sign;	/* restore st(0) */
            return;
        }
        break;
    case TW_Infinity:
        /* Operand is out of range */
        setcc(SW_C2);
        FPU_st0_ptr->sign = arg_sign;	/* restore st(0) */
        return;
    case TW_Zero:
        push();
        reg_move(&CONST_1, FPU_st0_ptr);
        setcc(0);
        break;
    default:
        single_arg_error();
        break;
    }
}
示例#2
0
文件: fpu_trig.c 项目: kame/kame
static void
f2xm1(void)
{
    switch (FPU_st0_tag) {
    case TW_Valid:
    {
        FPU_REG rv, tmp;

#ifdef DENORM_OPERAND
        if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()))
            return;
#endif				/* DENORM_OPERAND */

        if (FPU_st0_ptr->sign == SIGN_POS) {
            /* poly_2xm1(x) requires 0 < x < 1. */
            if (poly_2xm1(FPU_st0_ptr, &rv))
                return;	/* error */
            reg_mul(&rv, FPU_st0_ptr, FPU_st0_ptr, FULL_PRECISION);
        } else {
            /* **** Should change poly_2xm1() to at least handle numbers near 0 */
            /* poly_2xm1(x) doesn't handle negative
             * numbers. */
            /* So we compute (poly_2xm1(x+1)-1)/2, for -1
             * < x < 0 */
            reg_add(FPU_st0_ptr, &CONST_1, &tmp, FULL_PRECISION);
            poly_2xm1(&tmp, &rv);
            reg_mul(&rv, &tmp, &tmp, FULL_PRECISION);
            reg_sub(&tmp, &CONST_1, FPU_st0_ptr, FULL_PRECISION);
            FPU_st0_ptr->exp--;
            if (FPU_st0_ptr->exp <= EXP_UNDER)
                arith_underflow(FPU_st0_ptr);
        }
        return;
    }
    case TW_Zero:
        return;
    case TW_Infinity:
        if (FPU_st0_ptr->sign == SIGN_NEG) {
            /* -infinity gives -1 (p16-10) */
            reg_move(&CONST_1, FPU_st0_ptr);
            FPU_st0_ptr->sign = SIGN_NEG;
        }
        return;
    default:
        single_arg_error();
    }
}
示例#3
0
static void f2xm1(FPU_REG *st0_ptr, u_char tag)
{
  FPU_REG a;

  clear_C1();

  if ( tag == TAG_Valid )
    {
      /* For an 80486 FPU, the result is undefined if the arg is >= 1.0 */
      if ( exponent(st0_ptr) < 0 )
	{
	denormal_arg:

	  FPU_to_exp16(st0_ptr, &a);

	  /* poly_2xm1(x) requires 0 < st(0) < 1. */
	  poly_2xm1(getsign(st0_ptr), &a, st0_ptr);
	}
      set_precision_flag_up();   /* 80486 appears to always do this */
      return;
    }

  if ( tag == TAG_Zero )
    return;

  if ( tag == TAG_Special )
    tag = FPU_Special(st0_ptr);

  switch ( tag )
    {
    case TW_Denormal:
      if ( denormal_operand() < 0 )
	return;
      goto denormal_arg;
    case TW_Infinity:
      if ( signnegative(st0_ptr) )
	{
	  /* -infinity gives -1 (p16-10) */
	  FPU_copy_to_reg0(&CONST_1, TAG_Valid);
	  setnegative(st0_ptr);
	}
      return;
    default:
      single_arg_error(st0_ptr, tag);
    }
}
示例#4
0
static void f2xm1(FPU_REG *st0_ptr, u_char tag)
{
	FPU_REG a;

	clear_C1();

	if (tag == TAG_Valid) {
		
		if (exponent(st0_ptr) < 0) {
		      denormal_arg:

			FPU_to_exp16(st0_ptr, &a);

			
			poly_2xm1(getsign(st0_ptr), &a, st0_ptr);
		}
		set_precision_flag_up();	
		return;
	}

	if (tag == TAG_Zero)
		return;

	if (tag == TAG_Special)
		tag = FPU_Special(st0_ptr);

	switch (tag) {
	case TW_Denormal:
		if (denormal_operand() < 0)
			return;
		goto denormal_arg;
	case TW_Infinity:
		if (signnegative(st0_ptr)) {
			
			FPU_copy_to_reg0(&CONST_1, TAG_Valid);
			setnegative(st0_ptr);
		}
		return;
	default:
		single_arg_error(st0_ptr, tag);
	}
}