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

📄 errors.c

📁 汇编源码大全 有各种汇编源码 希望对你有所帮助
💻 C
📖 第 1 页 / 共 2 页
字号:
	}      else	printk("FPU emulator: Unknown Exception: 0x%04x!\n", n);            if ( n == EX_INTERNAL )	{	  printk("FPU emulator: Internal error type 0x%04x\n", int_type);	  emu_printall();	}#ifdef PRINT_MESSAGES      else	emu_printall();#endif PRINT_MESSAGES      /*       * The 80486 generates an interrupt on the next non-control FPU       * instruction. So we need some means of flagging it.       * We use the ES (Error Summary) bit for this, assuming that       * this is the way a real FPU does it (until I can check it out),       * if not, then some method such as the following kludge might       * be needed.       *//*      regs[0].tag |= TW_FPU_Interrupt; */    }  RE_ENTRANT_CHECK_ON;#ifdef __DEBUG__  math_abort(FPU_info,SIGFPE);#endif __DEBUG__}/* Real operation attempted on two operands, one a NaN. *//* Returns nz if the exception is unmasked */asmlinkage int real_2op_NaN(FPU_REG const *a, FPU_REG const *b, FPU_REG *dest){  FPU_REG const *x;  int signalling;  /* The default result for the case of two "equal" NaNs (signs may     differ) is chosen to reproduce 80486 behaviour */  x = a;  if (a->tag == TW_NaN)    {      if (b->tag == TW_NaN)	{	  signalling = !(a->sigh & b->sigh & 0x40000000);	  /* find the "larger" */	  if ( significand(a) < significand(b) )	    x = b;	}      else	{	  /* return the quiet version of the NaN in a */	  signalling = !(a->sigh & 0x40000000);	}    }  else#ifdef PARANOID    if (b->tag == 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 )    {      if ( !(x->sigh & 0x80000000) )  /* pseudo-NaN ? */	x = &CONST_QNaN;      reg_move(x, dest);      return 0;    }  if ( control_word & CW_Invalid )    {      /* The masked response */      if ( !(x->sigh & 0x80000000) )  /* pseudo-NaN ? */	x = &CONST_QNaN;      reg_move(x, dest);      /* ensure a Quiet NaN */      dest->sigh |= 0x40000000;    }  EXCEPTION(EX_Invalid);    return !(control_word & CW_Invalid);}/* Invalid arith operation on Valid registers *//* Returns nz if the exception is unmasked */asmlinkage int arith_invalid(FPU_REG *dest){  EXCEPTION(EX_Invalid);    if ( control_word & CW_Invalid )    {      /* The masked response */      reg_move(&CONST_QNaN, dest);    }    return !(control_word & CW_Invalid);}/* Divide a finite number by zero */asmlinkage int divide_by_zero(int sign, FPU_REG *dest){  if ( control_word & CW_ZeroDiv )    {      /* The masked response */      reg_move(&CONST_INF, dest);      dest->sign = (unsigned char)sign;    }   EXCEPTION(EX_ZeroDiv);  return !(control_word & CW_ZeroDiv);}/* 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 0;    }  else    {      exception(EX_Denormal);      return 1;    }}asmlinkage int arith_overflow(FPU_REG *dest){  if ( control_word & CW_Overflow )    {      char sign;      /* The masked response *//* ###### The response here depends upon the rounding mode */      sign = dest->sign;      reg_move(&CONST_INF, dest);      dest->sign = sign;    }  else    {      /* Subtract the magic number from the exponent */      dest->exp -= (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 !(control_word & CW_Precision);    }  return !(control_word & CW_Overflow);}asmlinkage int arith_underflow(FPU_REG *dest){  if ( control_word & CW_Underflow )    {      /* The masked response */      if ( dest->exp <= EXP_UNDER - 63 )	{	  reg_move(&CONST_Z, dest);	  partial_status &= ~SW_C1;       /* Round down. */	}    }  else    {      /* Add the magic number to the exponent. */      dest->exp += (3 * (1 << 13));    }  EXCEPTION(EX_Underflow);  if ( control_word & CW_Underflow )    {      /* The underflow exception is masked. */      EXCEPTION(EX_Precision);      return !(control_word & CW_Precision);    }  return !(control_word & CW_Underflow);}void stack_overflow(void){ if ( control_word & CW_Invalid )    {      /* The masked response */      top--;      reg_move(&CONST_QNaN, FPU_st0_ptr = &st(0));    }  EXCEPTION(EX_StackOver);  return;}void stack_underflow(void){ if ( control_word & CW_Invalid )    {      /* The masked response */      reg_move(&CONST_QNaN, FPU_st0_ptr);    }  EXCEPTION(EX_StackUnder);  return;}void stack_underflow_i(int i){ if ( control_word & CW_Invalid )    {      /* The masked response */      reg_move(&CONST_QNaN, &(st(i)));    }  EXCEPTION(EX_StackUnder);  return;}void stack_underflow_pop(int i){ if ( control_word & CW_Invalid )    {      /* The masked response */      reg_move(&CONST_QNaN, &(st(i)));      pop();    }  EXCEPTION(EX_StackUnder);  return;}

⌨️ 快捷键说明

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