Esempio n. 1
0
File: fpu_trig.c Progetto: 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();
    }
}
Esempio n. 2
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);
    }
}
Esempio n. 3
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);
	}
}