⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fpu_trig.c

📁 汇编源码大全 有各种汇编源码 希望对你有所帮助
💻 C
📖 第 1 页 / 共 3 页
字号:
	    pop();	}      return;    }}static void fpatan(void){  FPU_REG *st1_ptr = &st(1);  char st1_tag = st1_ptr->tag;  char st1_sign = st1_ptr->sign, st0_sign = FPU_st0_ptr->sign;  clear_C1();  if ( !((FPU_st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid)) )    {      int saved_control, saved_status;      FPU_REG sum;      char inverted;#ifdef DENORM_OPERAND      if ( ((FPU_st0_ptr->exp <= EXP_UNDER) ||	    (st1_ptr->exp <= EXP_UNDER)) && (denormal_operand()) )	return;#endif DENORM_OPERAND      /* We use the general purpose arithmetic so we need to save these. */      saved_status = partial_status;      saved_control = control_word;      control_word = FULL_PRECISION;      st1_ptr->sign = FPU_st0_ptr->sign = SIGN_POS;      if ( (compare(st1_ptr) & ~COMP_Denormal) == COMP_A_lt_B )	{	  inverted = 1;	  reg_div(FPU_st0_ptr, st1_ptr, &sum, FULL_PRECISION);	}      else	{	  inverted = 0;	  if ( (st0_sign == 0) &&	      (st1_ptr->exp - FPU_st0_ptr->exp < -64) )	    {	      control_word = saved_control;	      partial_status = saved_status;	      reg_div(st1_ptr, FPU_st0_ptr, st1_ptr,		      control_word | PR_64_BITS);	      st1_ptr->sign = st1_sign;	      pop();	      set_precision_flag_down();	      return;	    }	  reg_div(st1_ptr, FPU_st0_ptr, &sum, FULL_PRECISION);	}      poly_atan(&sum);      if ( inverted )	{	  reg_sub(&CONST_PI2, &sum, &sum, FULL_PRECISION);	}      if ( st0_sign )	{	  reg_sub(&CONST_PI, &sum, &sum, FULL_PRECISION);	}      sum.sign = st1_sign;      /* All of the basic arithmetic is done now */      control_word = saved_control;      partial_status = saved_status;      reg_move(&sum, st1_ptr);    }  else if ( (FPU_st0_tag == TW_Empty) || (st1_tag == TW_Empty) )    {      stack_underflow_pop(1);      return;    }  else if ( (FPU_st0_tag == TW_NaN) || (st1_tag == TW_NaN) )    {      if ( !real_2op_NaN(FPU_st0_ptr, st1_ptr, st1_ptr) )	  pop();      return;    }  else if ( (FPU_st0_tag == TW_Infinity) || (st1_tag == TW_Infinity) )    {      char sign = st1_ptr->sign;      if ( FPU_st0_tag == TW_Infinity )	{	  if ( st1_tag == TW_Infinity )	    {	      if ( FPU_st0_ptr->sign == SIGN_POS )		{ reg_move(&CONST_PI4, st1_ptr); }	      else		reg_add(&CONST_PI4, &CONST_PI2, st1_ptr, FULL_PRECISION);	    }	  else	    {#ifdef DENORM_OPERAND	      if ( st1_tag != TW_Zero )		{		  if ( (st1_ptr->exp <= EXP_UNDER) && (denormal_operand()) )		    return;		}#endif DENORM_OPERAND	      if ( FPU_st0_ptr->sign == SIGN_POS )		{		  reg_move(&CONST_Z, st1_ptr);		  st1_ptr->sign = sign;   /* An 80486 preserves the sign */		  pop();		  return;		}	      else		reg_move(&CONST_PI, st1_ptr);	    }	}      else	{	  /* st(1) is infinity, st(0) not infinity */#ifdef DENORM_OPERAND	  if ( FPU_st0_tag != TW_Zero )	    {	      if ( (FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()) )		return;	    }#endif DENORM_OPERAND	  reg_move(&CONST_PI2, st1_ptr);	}      st1_ptr->sign = sign;    }  else if ( st1_tag == TW_Zero )    {      /* st(0) must be valid or zero */      char sign = st1_ptr->sign;#ifdef DENORM_OPERAND      if ( FPU_st0_tag != TW_Zero )	{	  if ( (FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()) )	    return;	}#endif DENORM_OPERAND      if ( FPU_st0_ptr->sign == SIGN_POS )	{ /* An 80486 preserves the sign */ pop(); return; }      else	reg_move(&CONST_PI, st1_ptr);      st1_ptr->sign = sign;    }  else if ( FPU_st0_tag == TW_Zero )    {      /* st(1) must be TW_Valid here */      char sign = st1_ptr->sign;#ifdef DENORM_OPERAND      if ( (st1_ptr->exp <= EXP_UNDER) && (denormal_operand()) )	return;#endif DENORM_OPERAND      reg_move(&CONST_PI2, st1_ptr);      st1_ptr->sign = sign;    }#ifdef PARANOID  else    EXCEPTION(EX_INTERNAL | 0x125);#endif PARANOID  pop();  set_precision_flag_up();  /* We do not really know if up or down */}static void fprem(void){  do_fprem(RC_CHOP);}static void fprem1(void){  do_fprem(RC_RND);}static void fyl2xp1(void){  FPU_REG *st1_ptr = &st(1);  char st1_tag = st1_ptr->tag;  clear_C1();  if ( !((FPU_st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid)) )    {      int saved_control, saved_status;#ifdef DENORM_OPERAND      if ( ((FPU_st0_ptr->exp <= EXP_UNDER) ||	    (st1_ptr->exp <= EXP_UNDER)) && denormal_operand() )	return;#endif DENORM_OPERAND      /* We use the general purpose arithmetic so we need to save these. */      saved_status = partial_status;      saved_control = control_word;      control_word = FULL_PRECISION;      if ( poly_l2p1(FPU_st0_ptr, FPU_st0_ptr) )	{#ifdef PECULIAR_486   /* Stupid 80486 doesn't worry about log(negative). */	  st1_ptr->sign ^= SIGN_POS^SIGN_NEG;	  control_word = saved_control;	  partial_status = saved_status;	  set_precision_flag_down();#else	  if ( arith_invalid(st1_ptr) )  /* poly_l2p1() returned invalid */	    return;#endif PECULIAR_486	  pop(); return;	}            /* Enough of the basic arithmetic is done now */      control_word = saved_control;      partial_status = saved_status;      /* Let the multiply set the flags */      reg_mul(FPU_st0_ptr, st1_ptr, st1_ptr, FULL_PRECISION);      pop();    }  else if ( (FPU_st0_tag == TW_Empty) | (st1_tag == TW_Empty) )    {      stack_underflow_pop(1);      return;    }  else if ( FPU_st0_tag == TW_Zero )    {      if ( st1_tag <= TW_Zero )	{#ifdef DENORM_OPERAND	  if ( (st1_tag == TW_Valid) && (st1_ptr->exp <= EXP_UNDER) &&	      (denormal_operand()) )	    return;#endif DENORM_OPERAND	  	  FPU_st0_ptr->sign ^= st1_ptr->sign;	  reg_move(FPU_st0_ptr, st1_ptr);	}      else if ( st1_tag == TW_Infinity )	{	  /* Infinity*log(1) */	  if ( !arith_invalid(st1_ptr) )	    pop();	  return;	}      else if ( st1_tag == TW_NaN )	{	  if ( !real_2op_NaN(FPU_st0_ptr, st1_ptr, st1_ptr) )	    pop();	  return;	}#ifdef PARANOID      else	{	  EXCEPTION(EX_INTERNAL | 0x116);	  return;	}#endif PARANOID      pop(); return;    }  else if ( FPU_st0_tag == TW_Valid )    {      if ( st1_tag == TW_Zero )	{	  if ( FPU_st0_ptr->sign == SIGN_NEG )	    {	      if ( FPU_st0_ptr->exp >= EXP_BIAS )		{		  /* st(0) holds <= -1.0 */#ifdef PECULIAR_486   /* Stupid 80486 doesn't worry about log(negative). */		  st1_ptr->sign ^= SIGN_POS^SIGN_NEG;#else		  if ( arith_invalid(st1_ptr) ) return;#endif PECULIAR_486		  pop(); return;		}#ifdef DENORM_OPERAND	      if ( (FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()) )		return;#endif DENORM_OPERAND	      st1_ptr->sign ^= SIGN_POS^SIGN_NEG;	      pop(); return;	    }#ifdef DENORM_OPERAND	  if ( (FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()) )	    return;#endif DENORM_OPERAND	  pop(); return;	}      if ( st1_tag == TW_Infinity )	{	  if ( FPU_st0_ptr->sign == SIGN_NEG )	    {	      if ( (FPU_st0_ptr->exp >= EXP_BIAS) &&		  !((FPU_st0_ptr->sigh == 0x80000000) &&		    (FPU_st0_ptr->sigl == 0)) )		{		  /* st(0) holds < -1.0 */#ifdef PECULIAR_486   /* Stupid 80486 doesn't worry about log(negative). */		  st1_ptr->sign ^= SIGN_POS^SIGN_NEG;#else		  if ( arith_invalid(st1_ptr) ) return;#endif PECULIAR_486		  pop(); return;		}#ifdef DENORM_OPERAND	      if ( (FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()) )		return;#endif DENORM_OPERAND	      st1_ptr->sign ^= SIGN_POS^SIGN_NEG;	      pop(); return;	    }#ifdef DENORM_OPERAND	  if ( (FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()) )	    return;#endif DENORM_OPERAND	  pop(); return;	}      if ( st1_tag == TW_NaN )	{	  if ( !real_2op_NaN(FPU_st0_ptr, st1_ptr, st1_ptr) )	    pop();	  return;	}    }  else if ( FPU_st0_tag == TW_NaN )    {      if ( !real_2op_NaN(FPU_st0_ptr, st1_ptr, st1_ptr) )	pop();      return;    }  else if ( FPU_st0_tag == TW_Infinity )    {      if ( st1_tag == TW_NaN )	{	  if ( !real_2op_NaN(FPU_st0_ptr, st1_ptr, st1_ptr) )	    pop();	  return;	}      else if ( FPU_st0_ptr->sign == SIGN_NEG )	{	  int exponent = st1_ptr->exp;#ifndef PECULIAR_486	  /* This should have higher priority than denormals, but... */	  if ( arith_invalid(st1_ptr) )  /* log(-infinity) */	    return;#endif PECULIAR_486#ifdef DENORM_OPERAND	  if ( st1_tag != TW_Zero )	    {	      if ( (exponent <= EXP_UNDER) && (denormal_operand()) )		return;	    }#endif DENORM_OPERAND#ifdef PECULIAR_486	  /* Denormal operands actually get higher priority */	  if ( arith_invalid(st1_ptr) )  /* log(-infinity) */	    return;#endif PECULIAR_486	  pop();	  return;	}      else if ( st1_tag == TW_Zero )	{	  /* log(infinity) */	  if ( !arith_invalid(st1_ptr) )	    pop();	  return;	}	      /* st(1) must be valid here. */#ifdef DENORM_OPERAND      if ( (st1_ptr->exp <= EXP_UNDER) && (denormal_operand()) )	return;#endif DENORM_OPERAND      /* The Manual says that log(Infinity) is invalid, but a real	 80486 sensibly says that it is o.k. */      { char sign = st1_ptr->sign;	reg_move(&CONST_INF, st1_ptr);	st1_ptr->sign = sign;      }      pop();      return;    }#ifdef PARANOID  else    {      EXCEPTION(EX_INTERNAL | 0x117);    }#endif PARANOID}static void fscale(void){  FPU_REG *st1_ptr = &st(1);  char st1_tag = st1_ptr->tag;  int old_cw = control_word;  char sign = FPU_st0_ptr->sign;  clear_C1();  if ( !((FPU_st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid)) )    {      long scale;      FPU_REG tmp;#ifdef DENORM_OPERAND      if ( ((FPU_st0_ptr->exp <= EXP_UNDER) ||	    (st1_ptr->exp <= EXP_UNDER)) && (denormal_operand()) )	return;#endif DENORM_OPERAND      if ( st1_ptr->exp > EXP_BIAS + 30 )	{	  /* 2^31 is far too large, would require 2^(2^30) or 2^(-2^30) */	  char sign;	  if ( st1_ptr->sign == SIGN_POS )	    {	      EXCEPTION(EX_Overflow);	      sign = FPU_st0_ptr->sign;	      reg_move(&CONST_INF, FPU_st0_ptr);	      FPU_st0_ptr->sign = sign;	    }	  else	    {	      EXCEPTION(EX_Underflow);	      sign = FPU_st0_ptr->sign;	      reg_move(&CONST_Z, FPU_st0_ptr);	      FPU_st0_ptr->sign = sign;	    }	  return;	}      control_word &= ~CW_RC;      control_word |= RC_CHOP;      reg_move(st1_ptr, &tmp);      round_to_int(&tmp);               /* This can never overflow here */      control_word = old_cw;      scale = st1_ptr->sign ? -tmp.sigl : tmp.sigl;      scale += FPU_st0_ptr->exp;      FPU_st0_ptr->exp = scale;      /* Use round_reg() to properly detect under/overflow etc */      round_reg(FPU_st0_ptr, 0, control_word);      return;    }  else if ( FPU_st0_tag == TW_Valid )    {      if ( st1_tag == TW_Zero )	{#ifdef DENORM_OPERAND	  if ( (FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()) )	    return;#endif DENORM_OPERAND	  return;	}      if ( st1_tag == TW_Infinity )	{#ifdef DENORM_OPERAND	  if ( (FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()) )	    return;#endif DENORM_OPERAND	  if ( st1_ptr->sign == SIGN_POS )	    { reg_move(&CONST_INF, FPU_st0_ptr); }	  else	      reg_move(&CONST_Z, FPU_st0_ptr);	  FPU_st0_ptr->sign = sign;	  return;	}      if ( st1_tag == TW_NaN )	{ real_2op_NaN(FPU_st0_ptr, st1_ptr, FPU_st0_ptr); return; }    }  else if ( FPU_st0_tag == TW_Zero )    {      if ( st1_tag == TW_Valid )	{#ifdef DENORM_OPERAND	  if ( (st1_ptr->exp <= EXP_UNDER) && (denormal_operand()) )	    return;#endif DENORM_OPERAND	  return;	}      else if ( st1_tag == TW_Zero ) { return; }      else if ( st1_tag == TW_Infinity )	{	  if ( st1_ptr->sign == SIGN_NEG )	    return;	  else	    {	      arith_invalid(FPU_st0_ptr); /* Zero scaled by +Infinity */	      return;	    }	}      else if ( st1_tag == TW_NaN )	{ real_2op_NaN(FPU_st0_ptr, st1_ptr, FPU_st0_ptr); return; }    }  else if ( FPU_st0_tag == TW_Infinity )    {      if ( st1_tag == TW_Valid )	{#ifdef DENORM_OPERAND	  if ( (st1_ptr->exp <= EXP_UNDER) && (denormal_operand()) )	    return;#endif DENORM_OPERAND	  return;	}      if ( ((st1_tag == TW_Infinity) && (st1_ptr->sign == SIGN_POS))	  || (st1_tag == TW_Zero) )	return;      else if ( st1_tag == TW_Infinity )	{	  arith_invalid(FPU_st0_ptr); /* Infinity scaled by -Infinity */	  return;	}      else if ( st1_tag == TW_NaN )	{ real_2op_NaN(FPU_st0_ptr, st1_ptr, FPU_st0_ptr); return; }    }  else if ( FPU_st0_tag == TW_NaN )    {      if ( st1_tag != TW_Empty )	{ real_2op_NaN(FPU_st0_ptr, st1_ptr, FPU_st0_ptr); return; }    }#ifdef PARANOID  if ( !((FPU_st0_tag == TW_Empty) || (st1_tag == TW_Empty)) )    {      EXCEPTION(EX_INTERNAL | 0x115);      return;    }#endif  /* At least one of st(0), st(1) must be empty */  stack_underflow();}/*---------------------------------------------------------------------------*/static FUNC const trig_table_a[] = {  f2xm1, fyl2x, fptan, fpatan, fxtract, fprem1, fdecstp, fincstp};void trig_a(void){  (trig_table_a[FPU_rm])();}static FUNC const trig_table_b[] =  {    fprem, fyl2xp1, fsqrt_, fsincos, frndint_, fscale, fsin, fcos  };void trig_b(void){  (trig_table_b[FPU_rm])();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -