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

📄 errors.c

📁 freebsd v4.4内核源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	      0x213  in wm_sqrt.S	      0x214  in wm_sqrt.S	      0x215  in wm_sqrt.S	      0x216  in reg_round.S	      0x217  in reg_round.S	      0x218  in reg_round.S */voidexception(int n){	int     i, int_type;	int_type = 0;		/* Needed only to stop compiler warnings */	if (n & EX_INTERNAL) {		int_type = n - EX_INTERNAL;		n = EX_INTERNAL;		/* Set lots of exception bits! */		status_word |= (SW_Exc_Mask | SW_Summary | FPU_BUSY);	} else {		/* Extract only the bits which we use to set the status word */		n &= (SW_Exc_Mask);		/* Set the corresponding exception bit */		status_word |= n;		if (status_word & ~control_word & CW_Exceptions)			status_word |= SW_Summary;		if (n & (SW_Stack_Fault | EX_Precision)) {			if (!(n & SW_C1))				/* This bit distinguishes over- from underflow				 * for a stack fault, and roundup from				 * round-down for precision loss. */				status_word &= ~SW_C1;		}	}	REENTRANT_CHECK(OFF);	if ((~control_word & n & CW_Exceptions) || (n == EX_INTERNAL)) {#ifdef PRINT_MESSAGES		/* My message from the sponsor */		printf(FPU_VERSION " " __DATE__ " (C) W. Metzenthen.\n");#endif				/* PRINT_MESSAGES */		/* Get a name string for error reporting */		for (i = 0; exception_names[i].type; i++)			if ((exception_names[i].type & n) == exception_names[i].type)				break;		if (exception_names[i].type) {#ifdef PRINT_MESSAGES			printf("FP Exception: %s!\n", exception_names[i].name);#endif				/* PRINT_MESSAGES */		} else			printf("FP emulator: Unknown Exception: 0x%04x!\n", n);		if (n == EX_INTERNAL) {			printf("FP 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; */	}	REENTRANT_CHECK(ON);#ifdef __DEBUG__	math_abort(SIGFPE);#endif				/* __DEBUG__ */}/* Real operation attempted on two operands, one a NaN */voidreal_2op_NaN(FPU_REG * a, FPU_REG * b, FPU_REG * dest){	FPU_REG *x;	int     signalling;	x = a;	if (a->tag == TW_NaN) {		if (b->tag == TW_NaN) {			signalling = !(a->sigh & b->sigh & 0x40000000);			/* find the "larger" */			if (*(long long *) &(a->sigl) < *(long long *) &(b->sigl))				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;	}	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;}/* Invalid arith operation on Valid registers */voidarith_invalid(FPU_REG * dest){	if (control_word & CW_Invalid) {		/* The masked response */		reg_move(&CONST_QNaN, dest);	}	EXCEPTION(EX_Invalid);	return;}/* Divide a finite number by zero */voiddivide_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;}/* This may be called often, so keep it lean */voidset_precision_flag_up(void){	if (control_word & CW_Precision)		status_word |= (SW_Precision | SW_C1);	/* The masked response */	else		exception(EX_Precision | SW_C1);}/* This may be called often, so keep it lean */voidset_precision_flag_down(void){	if (control_word & CW_Precision) {	/* The masked response */		status_word &= ~SW_C1;		status_word |= SW_Precision;	} else		exception(EX_Precision);}intdenormal_operand(void){	if (control_word & CW_Denormal) {	/* The masked response */		status_word |= SW_Denorm_Op;		return 0;	} else {		exception(EX_Denormal);		return 1;	}}voidarith_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));	}	/* By definition, precision is lost. It appears that the roundup bit	 * (C1) is also set by convention. */	EXCEPTION(EX_Overflow | EX_Precision | SW_C1);	return;}voidarith_underflow(FPU_REG * dest){	if (control_word & CW_Underflow) {		/* The masked response */		if (dest->exp <= EXP_UNDER - 63)			reg_move(&CONST_Z, dest);	} else {		/* Add the magic number to the exponent */		dest->exp += (3 * (1 << 13));	}	EXCEPTION(EX_Underflow);	return;}voidstack_overflow(void){	if (control_word & CW_Invalid) {		/* The masked response */		top--;		reg_move(&CONST_QNaN, FPU_st0_ptr = &st(0));	}	EXCEPTION(EX_StackOver);	return;}voidstack_underflow(void){	if (control_word & CW_Invalid) {		/* The masked response */		reg_move(&CONST_QNaN, FPU_st0_ptr);	}	EXCEPTION(EX_StackUnder);	return;}voidstack_underflow_i(int i){	if (control_word & CW_Invalid) {		/* The masked response */		reg_move(&CONST_QNaN, &(st(i)));	}	EXCEPTION(EX_StackUnder);	return;}voidstack_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 + -