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

📄 trapov_.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lintstatic char	*sccsid = " @(#)trapov_.c	1.2	(ULTRIX)	1/16/86";#endif lint/************************************************************************ *									* *			Copyright (c) 1986 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//**************************************************************************			Modification History**	David Metsky		10-Jan-86** 001	Replaced old version with BSD 4.3 version as part of upgrade.**	Based on:	trapov_.c	5.2		6/7/85**************************************************************************//*	Fortran/C floating-point overflow handler * *	The idea of these routines is to catch floating-point overflows *	and print an eror message.  When we then get a reserved operand *	exception, we then fix up the value to the highest possible *	number.  Keen, no? *	Messy, yes! * *	Synopsis: *		call trapov(n) *			causes overflows to be trapped, with the first 'n' *			overflows getting an "Overflow!" message printed. *		k = ovcnt(0) *			causes 'k' to get the number of overflows since the *			last call to trapov(). * *	Gary Klimowicz, April 17, 1981 *	Integerated with libF77: David Wasley, UCB, July 1981. */# include <stdio.h># include <signal.h># include "opcodes.h"# include "../libI77/fiodefs.h"# define SIG_VAL	int (*)()/* *	Operand modes */# define LITERAL0	0x0# define LITERAL1	0x1# define LITERAL2	0x2# define LITERAL3	0x3# define INDEXED	0x4# define REGISTER	0x5# define REG_DEF	0x6# define AUTO_DEC	0x7# define AUTO_INC	0x8# define AUTO_INC_DEF	0x9# define BYTE_DISP	0xa# define BYTE_DISP_DEF	0xb# define WORD_DISP	0xc# define WORD_DISP_DEF	0xd# define LONG_DISP	0xe# define LONG_DISP_DEF	0xf/* *	Operand value types */# define F		1# define D		2# define IDUNNO		3# define PC	0xf# define SP	0xe# define FP	0xd# define AP	0xc/* * trap type codes */# define INT_OVF_T	1# define INT_DIV_T	2# define FLT_OVF_T	3# define FLT_DIV_T	4# define FLT_UND_T	5# define DEC_OVF_T	6# define SUB_RNG_T	7# define FLT_OVF_F	8# define FLT_DIV_F	9# define FLT_UND_F	10# define RES_ADR_F	0# define RES_OPC_F	1# define RES_OPR_F	2/* *	Potential operand values */typedef	union operand_types {		char	o_byte;		short	o_word;		long	o_long;		float	o_float;		long	o_quad[2];		double	o_double;	} anyval;/* *	GLOBAL VARIABLES (we need a few) * *	Actual program counter and locations of registers. */#if	vaxstatic char	*pc;static int	*regs0t6;static int	*regs7t11;static int	max_messages;static int	total_overflows;static union	{	long	v_long[2];	double	v_double;	} retrn;static int	(*sigill_default)() = (SIG_VAL)-1;static int	(*sigfpe_default)();#endif	vax/* *	the fortran unit control table */extern unit units[];/* * Fortran message table is in main */struct msgtbl {	char	*mesg;	int	dummy;};extern struct msgtbl	act_fpe[];anyval *get_operand_address(), *addr_of_reg();char *opcode_name();/* *	This routine sets up the signal handler for the floating-point *	and reserved operand interrupts. */trapov_(count, rtnval)	int *count;	double *rtnval;{#if	vax	extern got_overflow(), got_illegal_instruction();	sigfpe_default = signal(SIGFPE, got_overflow);	if (sigill_default == (SIG_VAL)-1)		sigill_default = signal(SIGILL, got_illegal_instruction);	total_overflows = 0;	max_messages = *count;	retrn.v_double = *rtnval;}/* *	got_overflow - routine called when overflow occurs * *	This routine just prints a message about the overflow. *	It is impossible to find the bad result at this point. *	Instead, we wait until we get the reserved operand exception *	when we try to use it.  This raises the SIGILL signal. *//*ARGSUSED*/got_overflow(signo, codeword, myaddr, pc, ps)	char *myaddr, *pc;{	int	*sp, i;	FILE	*ef;	signal(SIGFPE, got_overflow);	ef = units[STDERR].ufd;	switch (codeword) {		case INT_OVF_T:		case INT_DIV_T:		case FLT_UND_T:		case DEC_OVF_T:		case SUB_RNG_T:		case FLT_OVF_F:		case FLT_DIV_F:		case FLT_UND_F:				if (sigfpe_default > (SIG_VAL)7)					return((*sigfpe_default)(signo, codeword, myaddr, pc, ps));				else					sigdie(signo, codeword, myaddr, pc, ps);					/* NOTREACHED */		case FLT_OVF_T:		case FLT_DIV_T:				if (++total_overflows <= max_messages) {					fprintf(ef, "trapov: %s",						act_fpe[codeword-1].mesg);					if (total_overflows == max_messages)						fprintf(ef, ": No more messages will be printed.\n");					else						fputc('\n', ef);				}				return;	}#endif	vax}int ovcnt_(){	return total_overflows;}#if	vax/* *	got_illegal_instruction - handle "illegal instruction" signals. * *	This really deals only with reserved operand exceptions. *	Since there is no way to check this directly, we look at the *	opcode of the instruction we are executing to see if it is a *	floating-point operation (with floating-point operands, not *	just results). * *	This is complicated by the fact that the registers that will *	eventually be restored are saved in two places.  registers 7-11 *	are saved by this routine, and are in its call frame. (we have *	to take special care that these registers are specified in *	the procedure entry mask here.) *	Registers 0-6 are saved at interrupt time, and are at a offset *	-8 from the 'signo' parameter below. *	There is ane extremely inimate connection between the value of *	the entry mask set by the 'makefile' script, and the constants *	used in the register offset calculations below. *	Can someone think of a better way to do this? *//*ARGSUSED*/got_illegal_instruction(signo, codeword, myaddr, trap_pc, ps)	char *myaddr, *trap_pc;{	int first_local[1];		/* must be first */	int i, opcode, type, o_no, no_reserved;	anyval *opnd;	regs7t11 = &first_local[0];	regs0t6 = &signo - 8;	pc = trap_pc;	opcode = fetch_byte() & 0xff;	no_reserved = 0;	if (codeword != RES_OPR_F || !is_floating_operation(opcode)) {		if (sigill_default > (SIG_VAL)7)			return((*sigill_default)(signo, codeword, myaddr, trap_pc, ps));		else			sigdie(signo, codeword, myaddr, trap_pc, ps);			/* NOTREACHED */	}	if (opcode == POLYD || opcode == POLYF) {		got_illegal_poly(opcode);		return;	}	if (opcode == EMODD || opcode == EMODF) {		got_illegal_emod(opcode);		return;	}	/*	 * This opcode wasn't "unusual".	 * Look at the operands to try and find a reserved operand.	 */	for (o_no = 1; o_no <= no_operands(opcode); ++o_no) {		type = operand_type(opcode, o_no);		if (type != F && type != D) {			advance_pc(type);			continue;		}		/* F or D operand.  Check it out */		opnd = get_operand_address(type);		if (opnd == NULL) {			fprintf(units[STDERR].ufd, "Can't get operand address: 0x%x, %d\n",				pc, o_no);			f77_abort();		}		if (type == F && opnd->o_long == 0x00008000) {			/* found one */			opnd->o_long = retrn.v_long[0];			++no_reserved;		} else if (type == D && opnd->o_long == 0x00008000) {			/* found one here, too! */			opnd->o_quad[0] = retrn.v_long[0];			/* Fix next pointer */			if (opnd == addr_of_reg(6)) opnd = addr_of_reg(7);			else opnd = (anyval *) ((char *) opnd + 4);			opnd->o_quad[0] = retrn.v_long[1];			++no_reserved;		}	}	if (no_reserved == 0) {		fprintf(units[STDERR].ufd, "Can't find any reserved operand!\n");		f77_abort();	}}/* * is_floating_exception - was the operation code for a floating instruction? */is_floating_operation(opcode)	int opcode;{	switch (opcode) {		case ACBD:	case ACBF:	case ADDD2:	case ADDD3:		case ADDF2:	case ADDF3:	case CMPD:	case CMPF:		case CVTDB:	case CVTDF:	case CVTDL:	case CVTDW:		case CVTFB:	case CVTFD:	case CVTFL:	case CVTFW:		case CVTRDL:	case CVTRFL:	case DIVD2:	case DIVD3:		case DIVF2:	case DIVF3:	case EMODD:	case EMODF:		case MNEGD:	case MNEGF:	case MOVD:	case MOVF:

⌨️ 快捷键说明

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