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

📄 errors.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Real operation attempted on a NaN. *//* Returns < 0 if the exception is unmasked */int real_1op_NaN(FPU_REG *a){  int signalling, isNaN;  isNaN = (exponent(a) == EXP_OVER) && (a->sigh & 0x80000000);  /* The default result for the case of two "equal" NaNs (signs may     differ) is chosen to reproduce 80486 behaviour */  signalling = isNaN && !(a->sigh & 0x40000000);  if ( !signalling )    {      if ( !isNaN )  /* pseudo-NaN, or other unsupported? */	{	  if ( control_word & CW_Invalid )	    {	      /* Masked response */	      reg_copy(&CONST_QNaN, a);	    }	  EXCEPTION(EX_Invalid);	  return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Special;	}      return TAG_Special;    }  if ( control_word & CW_Invalid )    {      /* The masked response */      if ( !(a->sigh & 0x80000000) )  /* pseudo-NaN ? */	{	  reg_copy(&CONST_QNaN, a);	}      /* ensure a Quiet NaN */      a->sigh |= 0x40000000;    }  EXCEPTION(EX_Invalid);  return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Special;}/* Real operation attempted on two operands, one a NaN. *//* Returns < 0 if the exception is unmasked */int real_2op_NaN(FPU_REG const *b, u_char tagb,		 int deststnr,		 FPU_REG const *defaultNaN){  FPU_REG *dest = &st(deststnr);  FPU_REG const *a = dest;  u_char taga = FPU_gettagi(deststnr);  FPU_REG const *x;  int signalling, unsupported;  if ( taga == TAG_Special )    taga = FPU_Special(a);  if ( tagb == TAG_Special )    tagb = FPU_Special(b);  /* TW_NaN is also used for unsupported data types. */  unsupported = ((taga == TW_NaN)		 && !((exponent(a) == EXP_OVER) && (a->sigh & 0x80000000)))    || ((tagb == TW_NaN)	&& !((exponent(b) == EXP_OVER) && (b->sigh & 0x80000000)));  if ( unsupported )    {      if ( control_word & CW_Invalid )	{	  /* Masked response */	  FPU_copy_to_regi(&CONST_QNaN, TAG_Special, deststnr);	}      EXCEPTION(EX_Invalid);      return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Special;    }  if (taga == TW_NaN)    {      x = a;      if (tagb == TW_NaN)	{	  signalling = !(a->sigh & b->sigh & 0x40000000);	  if ( significand(b) > significand(a) )	    x = b;	  else if ( significand(b) == significand(a) )	    {	      /* The default result for the case of two "equal" NaNs (signs may		 differ) is chosen to reproduce 80486 behaviour */	      x = defaultNaN;	    }	}      else	{	  /* return the quiet version of the NaN in a */	  signalling = !(a->sigh & 0x40000000);	}    }  else#ifdef PARANOID    if (tagb == TW_NaN)#endif /* PARANOID */    {      signalling = !(b->sigh & 0x40000000);      x = b;    }#ifdef PARANOID  else    {      signalling = 0;      EXCEPTION(EX_INTERNAL|0x113);      x = &CONST_QNaN;    }#endif /* PARANOID */  if ( (!signalling) || (control_word & CW_Invalid) )    {      if ( ! x )	x = b;      if ( !(x->sigh & 0x80000000) )  /* pseudo-NaN ? */	x = &CONST_QNaN;      FPU_copy_to_regi(x, TAG_Special, deststnr);      if ( !signalling )	return TAG_Special;      /* ensure a Quiet NaN */      dest->sigh |= 0x40000000;    }  EXCEPTION(EX_Invalid);  return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Special;}/* Invalid arith operation on Valid registers *//* Returns < 0 if the exception is unmasked */asmlinkage int arith_invalid(int deststnr){  EXCEPTION(EX_Invalid);    if ( control_word & CW_Invalid )    {      /* The masked response */      FPU_copy_to_regi(&CONST_QNaN, TAG_Special, deststnr);    }    return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Valid;}/* Divide a finite number by zero */asmlinkage int FPU_divide_by_zero(int deststnr, u_char sign){  FPU_REG *dest = &st(deststnr);  int tag = TAG_Valid;  if ( control_word & CW_ZeroDiv )    {      /* The masked response */      FPU_copy_to_regi(&CONST_INF, TAG_Special, deststnr);      setsign(dest, sign);      tag = TAG_Special;    }   EXCEPTION(EX_ZeroDiv);  return (!(control_word & CW_ZeroDiv) ? FPU_Exception : 0) | tag;}/* This may be called often, so keep it lean */int set_precision_flag(int flags){  if ( control_word & CW_Precision )    {      partial_status &= ~(SW_C1 & flags);      partial_status |= flags;   /* The masked response */      return 0;    }  else    {      EXCEPTION(flags);      return 1;    }}/* This may be called often, so keep it lean */asmlinkage void set_precision_flag_up(void){  if ( control_word & CW_Precision )    partial_status |= (SW_Precision | SW_C1);   /* The masked response */  else    EXCEPTION(EX_Precision | SW_C1);}/* This may be called often, so keep it lean */asmlinkage void set_precision_flag_down(void){  if ( control_word & CW_Precision )    {   /* The masked response */      partial_status &= ~SW_C1;      partial_status |= SW_Precision;    }  else    EXCEPTION(EX_Precision);}asmlinkage int denormal_operand(void){  if ( control_word & CW_Denormal )    {   /* The masked response */      partial_status |= SW_Denorm_Op;      return TAG_Special;    }  else    {      EXCEPTION(EX_Denormal);      return TAG_Special | FPU_Exception;    }}asmlinkage int arith_overflow(FPU_REG *dest){  int tag = TAG_Valid;  if ( control_word & CW_Overflow )    {      /* The masked response *//* ###### The response here depends upon the rounding mode */      reg_copy(&CONST_INF, dest);      tag = TAG_Special;    }  else    {      /* Subtract the magic number from the exponent */      addexponent(dest, (-3 * (1 << 13)));    }  EXCEPTION(EX_Overflow);  if ( control_word & CW_Overflow )    {      /* The overflow exception is masked. */      /* By definition, precision is lost.	 The roundup bit (C1) is also set because we have	 "rounded" upwards to Infinity. */      EXCEPTION(EX_Precision | SW_C1);      return tag;    }  return tag;}asmlinkage int arith_underflow(FPU_REG *dest){  int tag = TAG_Valid;  if ( control_word & CW_Underflow )    {      /* The masked response */      if ( exponent16(dest) <= EXP_UNDER - 63 )	{	  reg_copy(&CONST_Z, dest);	  partial_status &= ~SW_C1;       /* Round down. */	  tag = TAG_Zero;	}      else	{	  stdexp(dest);	}    }  else    {      /* Add the magic number to the exponent. */      addexponent(dest, (3 * (1 << 13)) + EXTENDED_Ebias);    }  EXCEPTION(EX_Underflow);  if ( control_word & CW_Underflow )    {      /* The underflow exception is masked. */      EXCEPTION(EX_Precision);      return tag;    }  return tag;}void FPU_stack_overflow(void){ if ( control_word & CW_Invalid )    {      /* The masked response */      top--;      FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);    }  EXCEPTION(EX_StackOver);  return;}void FPU_stack_underflow(void){ if ( control_word & CW_Invalid )    {      /* The masked response */      FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);    }  EXCEPTION(EX_StackUnder);  return;}void FPU_stack_underflow_i(int i){ if ( control_word & CW_Invalid )    {      /* The masked response */      FPU_copy_to_regi(&CONST_QNaN, TAG_Special, i);    }  EXCEPTION(EX_StackUnder);  return;}void FPU_stack_underflow_pop(int i){ if ( control_word & CW_Invalid )    {      /* The masked response */      FPU_copy_to_regi(&CONST_QNaN, TAG_Special, i);      FPU_pop();    }  EXCEPTION(EX_StackUnder);  return;}

⌨️ 快捷键说明

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