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

📄 gen_except.s

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 S
字号:
////      $Id: gen_except.S,v 1.1 1998/12/14 23:15:21 joel Exp $////	gen_except.sa 3.7 1/16/92////	gen_except --- FPSP routine to detect reportable exceptions//	//	This routine compares the exception enable byte of the//	user_fpcr on the stack with the exception status byte//	of the user_fpsr. ////	Any routine which may report an exceptions must load//	the stack frame in memory with the exceptional operand(s).////	Priority for exceptions is:////	Highest:	bsun//			snan//			operr//			ovfl//			unfl//			dz//			inex2//	Lowest:		inex1////	Note: The IEEE standard specifies that inex2 is to be//	reported if ovfl occurs and the ovfl enable bit is not//	set but the inex2 enable bit is.  //////		Copyright (C) Motorola, Inc. 1990//			All Rights Reserved////	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA //	The copyright notice above does not evidence any  //	actual or intended publication of such source code.GEN_EXCEPT:    //idnt    2,1 | Motorola 040 Floating Point Software Package	|section 8#include "fpsp.defs"	|xref	real_trace	|xref	fpsp_done	|xref	fpsp_fmt_errorexc_tbl:	.long	bsun_exc	.long	commonE1	.long	commonE1	.long	ovfl_unfl	.long	ovfl_unfl	.long	commonE1	.long	commonE3	.long	commonE3	.long	no_match	.global	gen_exceptgen_except:	cmpib	#IDLE_SIZE-4,1(%a7)	//test for idle frame	beq	do_check		//go handle idle frame	cmpib	#UNIMP_40_SIZE-4,1(%a7)	//test for orig unimp frame	beqs	unimp_x			//go handle unimp frame	cmpib	#UNIMP_41_SIZE-4,1(%a7)	//test for rev unimp frame	beqs	unimp_x			//go handle unimp frame	cmpib	#BUSY_SIZE-4,1(%a7)	//if size <> $60, fmt error	bnel	fpsp_fmt_error	leal	BUSY_SIZE+LOCAL_SIZE(%a7),%a1 //init a1 so fpsp.h//					;equates will work// Fix up the new busy frame with entries from the unimp frame//	movel	ETEMP_EX(%a6),ETEMP_EX(%a1) //copy etemp from unimp	movel	ETEMP_HI(%a6),ETEMP_HI(%a1) //frame to busy frame	movel	ETEMP_LO(%a6),ETEMP_LO(%a1) 	movel	CMDREG1B(%a6),CMDREG1B(%a1) //set inst in frame to unimp	movel	CMDREG1B(%a6),%d0		//fix cmd1b to make it	andl	#0x03c30000,%d0		//work for cmd3b	bfextu	CMDREG1B(%a6){#13:#1},%d1	//extract bit 2	lsll	#5,%d1				swap	%d1	orl	%d1,%d0			//put it in the right place	bfextu	CMDREG1B(%a6){#10:#3},%d1	//extract bit 3,4,5	lsll	#2,%d1	swap	%d1	orl	%d1,%d0			//put them in the right place	movel	%d0,CMDREG3B(%a1)		//in the busy frame//// Or in the FPSR from the emulation with the USER_FPSR on the stack.//	fmovel	%FPSR,%d0			orl	%d0,USER_FPSR(%a6)	movel	USER_FPSR(%a6),FPSR_SHADOW(%a1) //set exc bits	orl	#sx_mask,E_BYTE(%a1)	bra	do_clean//// Frame is an unimp frame possible resulting from an fmove <ea>,fp0// that caused an exception//// a1 is modified to point into the new frame allowing fpsp equates// to be valid.//unimp_x:	cmpib	#UNIMP_40_SIZE-4,1(%a7)	//test for orig unimp frame	bnes	test_rev	leal	UNIMP_40_SIZE+LOCAL_SIZE(%a7),%a1	bras	unimp_contest_rev:	cmpib	#UNIMP_41_SIZE-4,1(%a7)	//test for rev unimp frame	bnel	fpsp_fmt_error		//if not $28 or $30	leal	UNIMP_41_SIZE+LOCAL_SIZE(%a7),%a1	unimp_con://// Fix up the new unimp frame with entries from the old unimp frame//	movel	CMDREG1B(%a6),CMDREG1B(%a1) //set inst in frame to unimp//// Or in the FPSR from the emulation with the USER_FPSR on the stack.//	fmovel	%FPSR,%d0			orl	%d0,USER_FPSR(%a6)	bra	do_clean//// Frame is idle, so check for exceptions reported through// USER_FPSR and set the unimp frame accordingly.  // A7 must be incremented to the point before the// idle fsave vector to the unimp vector.//	do_check:	addl	#4,%a7			//point A7 back to unimp frame//// Or in the FPSR from the emulation with the USER_FPSR on the stack.//	fmovel	%FPSR,%d0			orl	%d0,USER_FPSR(%a6)//// On a busy frame, we must clear the nmnexc bits.//	cmpib	#BUSY_SIZE-4,1(%a7)	//check frame type	bnes	check_fr		//if busy, clr nmnexc	clrw	NMNEXC(%a6)		//clr nmnexc & nmcexc	btstb	#5,CMDREG1B(%a6)		//test for fmove out	bnes	frame_com	movel	USER_FPSR(%a6),FPSR_SHADOW(%a6) //set exc bits	orl	#sx_mask,E_BYTE(%a6)	bras	frame_comcheck_fr:	cmpb	#UNIMP_40_SIZE-4,1(%a7)	beqs	frame_com	clrw	NMNEXC(%a6)frame_com:	moveb	FPCR_ENABLE(%a6),%d0	//get fpcr enable byte	andb	FPSR_EXCEPT(%a6),%d0	//and in the fpsr exc byte	bfffo	%d0{#24:#8},%d1		//test for first set bit	leal	exc_tbl,%a0		//load jmp table address	subib	#24,%d1			//normalize bit offset to 0-8	movel	(%a0,%d1.w*4),%a0		//load routine address based//					;based on first enabled exc	jmp	(%a0)			//jump to routine//// Bsun is not possible in unimp or unsupp//bsun_exc:	bra	do_clean//// The typical work to be done to the unimp frame to report an // exception is to set the E1/E3 byte and clr the U flag.// commonE1 does this for E1 exceptions, which are snan, // operr, and dz.  commonE3 does this for E3 exceptions, which // are inex2 and inex1, and also clears the E1 exception bit// left over from the unimp exception.//commonE1:	bsetb	#E1,E_BYTE(%a6)		//set E1 flag	bra	commonE			//go clean and exitcommonE3:	tstb	UFLG_TMP(%a6)		//test flag for unsup/unimp state	bnes	unsE3uniE3:	bsetb	#E3,E_BYTE(%a6)		//set E3 flag	bclrb	#E1,E_BYTE(%a6)		//clr E1 from unimp	bra	commonEunsE3:	tstb	RES_FLG(%a6)	bnes	unsE3_0	unsE3_1:	bsetb	#E3,E_BYTE(%a6)		//set E3 flagunsE3_0:	bclrb	#E1,E_BYTE(%a6)		//clr E1 flag	movel	CMDREG1B(%a6),%d0	andl	#0x03c30000,%d0		//work for cmd3b	bfextu	CMDREG1B(%a6){#13:#1},%d1	//extract bit 2	lsll	#5,%d1				swap	%d1	orl	%d1,%d0			//put it in the right place	bfextu	CMDREG1B(%a6){#10:#3},%d1	//extract bit 3,4,5	lsll	#2,%d1	swap	%d1	orl	%d1,%d0			//put them in the right place	movel	%d0,CMDREG3B(%a6)		//in the busy framecommonE:	bclrb	#UFLAG,T_BYTE(%a6)	//clr U flag from unimp	bra	do_clean		//go clean and exit//// No bits in the enable byte match existing exceptions.  Check for// the case of the ovfl exc without the ovfl enabled, but with// inex2 enabled.//no_match:	btstb	#inex2_bit,FPCR_ENABLE(%a6) //check for ovfl/inex2 case	beqs	no_exc			//if clear, exit	btstb	#ovfl_bit,FPSR_EXCEPT(%a6) //now check ovfl	beqs	no_exc			//if clear, exit	bras	ovfl_unfl		//go to unfl_ovfl to determine if//					;it is an unsupp or unimp exc	// No exceptions are to be reported.  If the instruction was // unimplemented, no FPU restore is necessary.  If it was// unsupported, we must perform the restore.no_exc:	tstb	UFLG_TMP(%a6)	//test flag for unsupp/unimp state	beqs	uni_no_excuns_no_exc:	tstb	RES_FLG(%a6)	//check if frestore is needed	bne	do_clean 	//if clear, no frestore neededuni_no_exc:	moveml	USER_DA(%a6),%d0-%d1/%a0-%a1	fmovemx USER_FP0(%a6),%fp0-%fp3	fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar	unlk	%a6	bra	finish_up//// Unsupported Data Type Handler:// Ovfl://   An fmoveout that results in an overflow is reported this way.// Unfl://   An fmoveout that results in an underflow is reported this way.//// Unimplemented Instruction Handler:// Ovfl://   Only scosh, setox, ssinh, stwotox, and scale can set overflow in //   this manner.// Unfl://   Stwotox, setox, and scale can set underflow in this manner.//   Any of the other Library Routines such that f(x)=x in which//   x is an extended denorm can report an underflow exception. //   It is the responsibility of the exception-causing exception //   to make sure that WBTEMP is correct.////   The exceptional operand is in FP_SCR1.//ovfl_unfl:	tstb	UFLG_TMP(%a6)	//test flag for unsupp/unimp state	beqs	ofuf_con//// The caller was from an unsupported data type trap.  Test if the// caller set CU_ONLY.  If so, the exceptional operand is expected in// FPTEMP, rather than WBTEMP.//	tstb	CU_ONLY(%a6)		//test if inst is cu-only	beq	unsE3//	move.w	#$fe,CU_SAVEPC(%a6)	clrb	CU_SAVEPC(%a6)	bsetb	#E1,E_BYTE(%a6)		//set E1 exception flag	movew	ETEMP_EX(%a6),FPTEMP_EX(%a6)	movel	ETEMP_HI(%a6),FPTEMP_HI(%a6)	movel	ETEMP_LO(%a6),FPTEMP_LO(%a6)	bsetb	#fptemp15_bit,DTAG(%a6)	//set fpte15	bclrb	#UFLAG,T_BYTE(%a6)	//clr U flag from unimp	bra	do_clean		//go clean and exitofuf_con:	moveb	(%a7),VER_TMP(%a6)	//save version number	cmpib	#BUSY_SIZE-4,1(%a7)	//check for busy frame	beqs	busy_fr			//if unimp, grow to busy	cmpib	#VER_40,(%a7)		//test for orig unimp frame	bnes	try_41			//if not, test for rev frame	moveql	#13,%d0			//need to zero 14 lwords	bras	ofuf_fintry_41:	cmpib	#VER_41,(%a7)		//test for rev unimp frame	bnel	fpsp_fmt_error		//if neither, exit with error	moveql	#11,%d0			//need to zero 12 lwordsofuf_fin:	clrl	(%a7)loop1:	clrl	-(%a7)			//clear and dec a7	dbra	%d0,loop1	moveb	VER_TMP(%a6),(%a7)	moveb	#BUSY_SIZE-4,1(%a7)		//write busy fmt word.busy_fr:	movel	FP_SCR1(%a6),WBTEMP_EX(%a6)	//write	movel	FP_SCR1+4(%a6),WBTEMP_HI(%a6)	//exceptional op to	movel	FP_SCR1+8(%a6),WBTEMP_LO(%a6)	//wbtemp	bsetb	#E3,E_BYTE(%a6)			//set E3 flag	bclrb	#E1,E_BYTE(%a6)			//make sure E1 is clear	bclrb	#UFLAG,T_BYTE(%a6)		//clr U flag	movel	USER_FPSR(%a6),FPSR_SHADOW(%a6)	orl	#sx_mask,E_BYTE(%a6)	movel	CMDREG1B(%a6),%d0		//fix cmd1b to make it	andl	#0x03c30000,%d0		//work for cmd3b	bfextu	CMDREG1B(%a6){#13:#1},%d1	//extract bit 2	lsll	#5,%d1				swap	%d1	orl	%d1,%d0			//put it in the right place	bfextu	CMDREG1B(%a6){#10:#3},%d1	//extract bit 3,4,5	lsll	#2,%d1	swap	%d1	orl	%d1,%d0			//put them in the right place	movel	%d0,CMDREG3B(%a6)		//in the busy frame//// Check if the frame to be restored is busy or unimp.//** NOTE *** Bug fix for errata (0d43b #3)// If the frame is unimp, we must create a busy frame to // fix the bug with the nmnexc bits in cases in which they// are set by a previous instruction and not cleared by// the save. The frame will be unimp only if the final // instruction in an emulation routine caused the exception// by doing an fmove <ea>,fp0.  The exception operand, in// internal format, is in fptemp.//do_clean:	cmpib	#UNIMP_40_SIZE-4,1(%a7)	bnes	do_con	moveql	#13,%d0			//in orig, need to zero 14 lwords	bras	do_builddo_con:	cmpib	#UNIMP_41_SIZE-4,1(%a7)	bnes	do_restore		//frame must be busy	moveql	#11,%d0			//in rev, need to zero 12 lwordsdo_build:	moveb	(%a7),VER_TMP(%a6)	clrl	(%a7)loop2:	clrl	-(%a7)			//clear and dec a7	dbra	%d0,loop2//// Use a1 as pointer into new frame.  a6 is not correct if an unimp or// busy frame was created as the result of an exception on the final// instruction of an emulation routine.//// We need to set the nmcexc bits if the exception is E1. Otherwise,// the exc taken will be inex2.//	leal	BUSY_SIZE+LOCAL_SIZE(%a7),%a1	//init a1 for new frame	moveb	VER_TMP(%a6),(%a7)	//write busy fmt word	moveb	#BUSY_SIZE-4,1(%a7)	movel	FP_SCR1(%a6),WBTEMP_EX(%a1) 	//write	movel	FP_SCR1+4(%a6),WBTEMP_HI(%a1)	//exceptional op to	movel	FP_SCR1+8(%a6),WBTEMP_LO(%a1)	//wbtemp//	btst.b	#E1,E_BYTE(%a1)//	beq.b	do_restore	bfextu	USER_FPSR(%a6){#17:#4},%d0	//get snan/operr/ovfl/unfl bits	bfins	%d0,NMCEXC(%a1){#4:#4}	//and insert them in nmcexc	movel	USER_FPSR(%a6),FPSR_SHADOW(%a1) //set exc bits	orl	#sx_mask,E_BYTE(%a1)	do_restore:	moveml	USER_DA(%a6),%d0-%d1/%a0-%a1	fmovemx USER_FP0(%a6),%fp0-%fp3	fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar	frestore (%a7)+	tstb	RES_FLG(%a6)	//RES_FLG indicates a "continuation" frame	beq	cont	bsr	bug1384cont:	unlk	%a6//// If trace mode enabled, then go to trace handler.  This handler // cannot have any fp instructions.  If there are fp inst's and an // exception has been restored into the machine then the exception // will occur upon execution of the fp inst.  This is not desirable // in the kernel (supervisor mode).  See MC68040 manual Section 9.3.8.//finish_up:	btstb	#7,(%a7)		//test T1 in SR	bnes	g_trace	btstb	#6,(%a7)		//test T0 in SR	bnes	g_trace	bral	fpsp_done//// Change integer stack to look like trace stack// The address of the instruction that caused the// exception is already in the integer stack (is// the same as the saved friar)//// If the current frame is already a 6-word stack then all// that needs to be done is to change the vector# to TRACE.// If the frame is only a 4-word stack (meaning we got here// on an Unsupported data type exception), then we need to grow// the stack an extra 2 words and get the FPIAR from the FPU.//g_trace:	bftst	EXC_VEC-4(%sp){#0:#4}	bne	g_easy	subw	#4,%sp		// make room	movel	4(%sp),(%sp)	movel	8(%sp),4(%sp)	subw	#BUSY_SIZE,%sp	fsave	(%sp)	fmovel	%fpiar,BUSY_SIZE+EXC_EA-4(%sp)	frestore (%sp)	addw	#BUSY_SIZE,%spg_easy:	movew	#TRACE_VEC,EXC_VEC-4(%a7)	bral	real_trace////  This is a work-around for hardware bug 1384.//bug1384:	link	%a5,#0	fsave	-(%sp)	cmpib	#0x41,(%sp)	// check for correct frame	beq	frame_41	bgt	nofix		// if more advanced mask, do nadaframe_40:	tstb	1(%sp)		// check to see if idle	bne	notidleidle40:	clrl	(%sp)		// get rid of old fsave frame        movel  %d1,USER_D1(%a6)  // save d1	movew	#8,%d1		// place unimp frame insteadloop40:	clrl	-(%sp)	dbra	%d1,loop40        movel  USER_D1(%a6),%d1  // restore d1	movel	#0x40280000,-(%sp)	frestore (%sp)+	unlk  	%a5		rtsframe_41:	tstb	1(%sp)		// check to see if idle	bne	notidle	idle41:	clrl	(%sp)		// get rid of old fsave frame        movel  %d1,USER_D1(%a6)  // save d1	movew	#10,%d1		// place unimp frame insteadloop41:	clrl	-(%sp)	dbra	%d1,loop41        movel  USER_D1(%a6),%d1  // restore d1	movel	#0x41300000,-(%sp)	frestore (%sp)+	unlk	%a5		rtsnotidle:	bclrb	#etemp15_bit,-40(%a5) 	frestore (%sp)+	unlk	%a5		rtsnofix:	frestore (%sp)+	unlk	%a5		rts	|end

⌨️ 快捷键说明

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