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

📄 reg_ld_s.c

📁 汇编源码大全 有各种汇编源码 希望对你有所帮助
💻 C
📖 第 1 页 / 共 3 页
字号:
      reg_move(FPU_st0_ptr, &tmp);      exp = tmp.exp - EXP_BIAS;      if ( exp < DOUBLE_Emin )     /* It may be a denormal */	{	  int precision_loss;	  /* A denormal will always underflow. */#ifndef PECULIAR_486	  /* An 80486 is supposed to be able to generate	     a denormal exception here, but... */	  if ( FPU_st0_ptr->exp <= EXP_UNDER )	    {	      /* Underflow has priority. */	      if ( control_word & CW_Underflow )		denormal_operand();	    }#endif PECULIAR_486	  tmp.exp += -DOUBLE_Emin + 52;  /* largest exp to be 51 */	  if ( (precision_loss = round_to_int(&tmp)) )	    {#ifdef PECULIAR_486	      /* Did it round to a non-denormal ? */	      /* This behaviour might be regarded as peculiar, it appears		 that the 80486 rounds to the dest precision, then		 converts to decide underflow. */	      if ( !((tmp.sigh == 0x00100000) && (tmp.sigl == 0) &&		  (FPU_st0_ptr->sigl & 0x000007ff)) )#endif PECULIAR_486		{		  EXCEPTION(EX_Underflow);		  /* This is a special case: see sec 16.2.5.1 of		     the 80486 book */		  if ( !(control_word & CW_Underflow) )		    return 0;		}	      EXCEPTION(precision_loss);	      if ( !(control_word & CW_Precision) )		return 0;	    }	  l[0] = tmp.sigl;	  l[1] = tmp.sigh;	}      else	{	  if ( tmp.sigl & 0x000007ff )	    {	      switch (control_word & CW_RC)		{		case RC_RND:		  /* Rounding can get a little messy.. */		  increment = ((tmp.sigl & 0x7ff) > 0x400) |  /* nearest */		    ((tmp.sigl & 0xc00) == 0xc00);            /* odd -> even */		  break;		case RC_DOWN:   /* towards -infinity */		  increment = (tmp.sign == SIGN_POS) ? 0 : tmp.sigl & 0x7ff;		  break;		case RC_UP:     /* towards +infinity */		  increment = (tmp.sign == SIGN_POS) ? tmp.sigl & 0x7ff : 0;		  break;		case RC_CHOP:		  increment = 0;		  break;		}	  	      /* Truncate the mantissa */	      tmp.sigl &= 0xfffff800;	  	      if ( increment )		{		  set_precision_flag_up();		  if ( tmp.sigl >= 0xfffff800 )		    {		      /* the sigl part overflows */		      if ( tmp.sigh == 0xffffffff )			{			  /* The sigh part overflows */			  tmp.sigh = 0x80000000;			  exp++;			  if (exp >= EXP_OVER)			    goto overflow;			}		      else			{			  tmp.sigh ++;			}		      tmp.sigl = 0x00000000;		    }		  else		    {		      /* We only need to increment sigl */		      tmp.sigl += 0x00000800;		    }		}	      else		set_precision_flag_down();	    }	  	  l[0] = (tmp.sigl >> 11) | (tmp.sigh << 21);	  l[1] = ((tmp.sigh >> 11) & 0xfffff);	  if ( exp > DOUBLE_Emax )	    {	    overflow:	      EXCEPTION(EX_Overflow);	      if ( !(control_word & CW_Overflow) )		return 0;	      set_precision_flag_up();	      if ( !(control_word & CW_Precision) )		return 0;	      /* This is a special case: see sec 16.2.5.1 of the 80486 book */	      /* Overflow to infinity */	      l[0] = 0x00000000;	/* Set to */	      l[1] = 0x7ff00000;	/* + INF */	    }	  else	    {	      /* Add the exponent */	      l[1] |= (((exp+DOUBLE_Ebias) & 0x7ff) << 20);	    }	}    }  else if (FPU_st0_tag == TW_Zero)    {      /* Number is zero */      l[0] = 0;      l[1] = 0;    }  else if (FPU_st0_tag == TW_Infinity)    {      l[0] = 0;      l[1] = 0x7ff00000;    }  else if (FPU_st0_tag == TW_NaN)    {      /* See if we can get a valid NaN from the FPU_REG */      l[0] = (FPU_st0_ptr->sigl >> 11) | (FPU_st0_ptr->sigh << 21);      l[1] = ((FPU_st0_ptr->sigh >> 11) & 0xfffff);      if ( !(FPU_st0_ptr->sigh & 0x40000000) )	{	  /* It is a signalling NaN */	  EXCEPTION(EX_Invalid);	  if ( !(control_word & CW_Invalid) )	    return 0;	  l[1] |= (0x40000000 >> 11);	}      l[1] |= 0x7ff00000;    }  else if ( FPU_st0_tag == TW_Empty )    {      /* Empty register (stack underflow) */      EXCEPTION(EX_StackUnder);      if ( control_word & CW_Invalid )	{	  /* The masked response */	  /* Put out the QNaN indefinite */	  RE_ENTRANT_CHECK_OFF;	  FPU_verify_area(VERIFY_WRITE,(void *)dfloat,8);	  put_fs_long(0, (unsigned long *) dfloat);	  put_fs_long(0xfff80000, 1 + (unsigned long *) dfloat);	  RE_ENTRANT_CHECK_ON;	  return 1;	}      else	return 0;    }  if (FPU_st0_ptr->sign)    l[1] |= 0x80000000;  RE_ENTRANT_CHECK_OFF;  FPU_verify_area(VERIFY_WRITE,(void *)dfloat,8);  put_fs_long(l[0], (unsigned long *)dfloat);  put_fs_long(l[1], 1 + (unsigned long *)dfloat);  RE_ENTRANT_CHECK_ON;  return 1;}/* Put a float into user memory */int reg_store_single(void){  float *single = (float *)FPU_data_address;  long templ;  unsigned long increment = 0;     	/* avoid gcc warnings */  if (FPU_st0_tag == TW_Valid)    {      int exp;      FPU_REG tmp;      reg_move(FPU_st0_ptr, &tmp);      exp = tmp.exp - EXP_BIAS;      if ( exp < SINGLE_Emin )	{	  int precision_loss;	  /* A denormal will always underflow. */#ifndef PECULIAR_486	  /* An 80486 is supposed to be able to generate	     a denormal exception here, but... */	  if ( FPU_st0_ptr->exp <= EXP_UNDER )	    {	      /* Underflow has priority. */	      if ( control_word & CW_Underflow )		denormal_operand();	    }#endif PECULIAR_486	  tmp.exp += -SINGLE_Emin + 23;  /* largest exp to be 22 */	  if ( (precision_loss = round_to_int(&tmp)) )	    {#ifdef PECULIAR_486	      /* Did it round to a non-denormal ? */	      /* This behaviour might be regarded as peculiar, it appears		 that the 80486 rounds to the dest precision, then		 converts to decide underflow. */	      if ( !((tmp.sigl == 0x00800000) &&		  ((FPU_st0_ptr->sigh & 0x000000ff) || FPU_st0_ptr->sigl)) )#endif PECULIAR_486		{		  EXCEPTION(EX_Underflow);		  /* This is a special case: see sec 16.2.5.1 of		     the 80486 book */		  if ( !(control_word & EX_Underflow) )		    return 0;		}	      EXCEPTION(precision_loss);	      if ( !(control_word & EX_Precision) )		return 0;	    }	  templ = tmp.sigl;	}      else	{	  if ( tmp.sigl | (tmp.sigh & 0x000000ff) )	    {	      unsigned long sigh = tmp.sigh;	      unsigned long sigl = tmp.sigl;	      	      switch (control_word & CW_RC)		{		case RC_RND:		  increment = ((sigh & 0xff) > 0x80)       /* more than half */		    || (((sigh & 0xff) == 0x80) && sigl)   /* more than half */		      || ((sigh & 0x180) == 0x180);        /* round to even */		  break;		case RC_DOWN:   /* towards -infinity */		  increment = (tmp.sign == SIGN_POS)		              ? 0 : (sigl | (sigh & 0xff));		  break;		case RC_UP:     /* towards +infinity */		  increment = (tmp.sign == SIGN_POS)		              ? (sigl | (sigh & 0xff)) : 0;		  break;		case RC_CHOP:		  increment = 0;		  break;		}	  	      /* Truncate part of the mantissa */	      tmp.sigl = 0;	  	      if (increment)		{		  set_precision_flag_up();		  if ( sigh >= 0xffffff00 )		    {		      /* The sigh part overflows */		      tmp.sigh = 0x80000000;		      exp++;		      if ( exp >= EXP_OVER )			goto overflow;		    }		  else		    {		      tmp.sigh &= 0xffffff00;		      tmp.sigh += 0x100;		    }		}	      else		{		  set_precision_flag_down();		  tmp.sigh &= 0xffffff00;  /* Finish the truncation */		}	    }	  templ = (tmp.sigh >> 8) & 0x007fffff;	  if ( exp > SINGLE_Emax )	    {	    overflow:	      EXCEPTION(EX_Overflow);	      if ( !(control_word & CW_Overflow) )		return 0;	      set_precision_flag_up();	      if ( !(control_word & CW_Precision) )		return 0;	      /* This is a special case: see sec 16.2.5.1 of the 80486 book. */	      /* Masked respose is overflow to infinity. */	      templ = 0x7f800000;	    }	  else	    templ |= ((exp+SINGLE_Ebias) & 0xff) << 23;	}    }  else if (FPU_st0_tag == TW_Zero)    {      templ = 0;    }  else if (FPU_st0_tag == TW_Infinity)    {      templ = 0x7f800000;    }  else if (FPU_st0_tag == TW_NaN)    {      /* See if we can get a valid NaN from the FPU_REG */      templ = FPU_st0_ptr->sigh >> 8;      if ( !(FPU_st0_ptr->sigh & 0x40000000) )	{	  /* It is a signalling NaN */	  EXCEPTION(EX_Invalid);	  if ( !(control_word & CW_Invalid) )	    return 0;	  templ |= (0x40000000 >> 8);	}      templ |= 0x7f800000;    }  else if ( FPU_st0_tag == TW_Empty )    {      /* Empty register (stack underflow) */      EXCEPTION(EX_StackUnder);      if ( control_word & EX_Invalid )	{	  /* The masked response */	  /* Put out the QNaN indefinite */	  RE_ENTRANT_CHECK_OFF;	  FPU_verify_area(VERIFY_WRITE,(void *)single,4);	  put_fs_long(0xffc00000, (unsigned long *) single);	  RE_ENTRANT_CHECK_ON;	  return 1;	}      else	return 0;    }#ifdef PARANOID  else    {      EXCEPTION(EX_INTERNAL|0x106);      return 0;    }#endif  if (FPU_st0_ptr->sign)    templ |= 0x80000000;  RE_ENTRANT_CHECK_OFF;  FPU_verify_area(VERIFY_WRITE,(void *)single,4);  put_fs_long(templ,(unsigned long *) single);  RE_ENTRANT_CHECK_ON;  return 1;}/* Put a long long into user memory */int reg_store_int64(void){  long long *d = (long long *)FPU_data_address;  FPU_REG t;  long long tll;  int precision_loss;  if ( FPU_st0_tag == TW_Empty )    {      /* Empty register (stack underflow) */      EXCEPTION(EX_StackUnder);      goto invalid_operand;    }  else if ( (FPU_st0_tag == TW_Infinity) ||	   (FPU_st0_tag == TW_NaN) )    {      EXCEPTION(EX_Invalid);      goto invalid_operand;    }  reg_move(FPU_st0_ptr, &t);  precision_loss = round_to_int(&t);  ((long *)&tll)[0] = t.sigl;  ((long *)&tll)[1] = t.sigh;  if ( (precision_loss == 1) ||      ((t.sigh & 0x80000000) &&       !((t.sigh == 0x80000000) && (t.sigl == 0) &&	 (t.sign == SIGN_NEG))) )    {      EXCEPTION(EX_Invalid);      /* This is a special case: see sec 16.2.5.1 of the 80486 book */    invalid_operand:      if ( control_word & EX_Invalid )	{	  /* Produce something like QNaN "indefinite" */	  tll = 0x8000000000000000LL;	}      else	return 0;    }  else    {      if ( precision_loss )	set_precision_flag(precision_loss);      if ( t.sign )	tll = - tll;    }  RE_ENTRANT_CHECK_OFF;  FPU_verify_area(VERIFY_WRITE,(void *)d,8);  put_fs_long(((long *)&tll)[0],(unsigned long *) d);  put_fs_long(((long *)&tll)[1],1 + (unsigned long *) d);  RE_ENTRANT_CHECK_ON;  return 1;}/* Put a long into user memory */int reg_store_int32(void){  long *d = (long *)FPU_data_address;  FPU_REG t;  int precision_loss;  if ( FPU_st0_tag == TW_Empty )    {      /* Empty register (stack underflow) */      EXCEPTION(EX_StackUnder);      goto invalid_operand;    }  else if ( (FPU_st0_tag == TW_Infinity) ||	   (FPU_st0_tag == TW_NaN) )    {      EXCEPTION(EX_Invalid);      goto invalid_operand;    }  reg_move(FPU_st0_ptr, &t);  precision_loss = round_to_int(&t);  if (t.sigh ||      ((t.sigl & 0x80000000) &&       !((t.sigl == 0x80000000) && (t.sign == SIGN_NEG))) )    {      EXCEPTION(EX_Invalid);      /* This is a special case: see sec 16.2.5.1 of the 80486 book */    invalid_operand:      if ( control_word & EX_Invalid )	{	  /* Produce something like QNaN "indefinite" */	  t.sigl = 0x80000000;	}      else	return 0;    }  else    {      if ( precision_loss )	set_precision_flag(precision_loss);      if ( t.sign )	t.sigl = -(long)t.sigl;    }  RE_ENTRANT_CHECK_OFF;  FPU_verify_area(VERIFY_WRITE,d,4);  put_fs_long(t.sigl, (unsigned long *) d);  RE_ENTRANT_CHECK_ON;  return 1;}/* Put a short into user memory */int reg_store_int16(void){

⌨️ 快捷键说明

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