Home | History | Annotate | Line # | Download | only in fpsp
gen_except.sa revision 1.3.172.1
      1  1.3.172.1     yamt *	$NetBSD: gen_except.sa,v 1.3.172.1 2010/03/11 15:02:33 yamt Exp $
      2        1.3      cgd 
      3        1.1  mycroft *	MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
      4        1.1  mycroft *	M68000 Hi-Performance Microprocessor Division
      5        1.1  mycroft *	M68040 Software Package 
      6        1.1  mycroft *
      7        1.1  mycroft *	M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
      8        1.1  mycroft *	All rights reserved.
      9        1.1  mycroft *
     10        1.1  mycroft *	THE SOFTWARE is provided on an "AS IS" basis and without warranty.
     11        1.1  mycroft *	To the maximum extent permitted by applicable law,
     12        1.1  mycroft *	MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
     13        1.1  mycroft *	INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
     14        1.1  mycroft *	PARTICULAR PURPOSE and any warranty against infringement with
     15        1.1  mycroft *	regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
     16        1.1  mycroft *	and any accompanying written materials. 
     17        1.1  mycroft *
     18        1.1  mycroft *	To the maximum extent permitted by applicable law,
     19        1.1  mycroft *	IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
     20        1.1  mycroft *	(INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS
     21        1.1  mycroft *	PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR
     22        1.1  mycroft *	OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE
     23        1.1  mycroft *	SOFTWARE.  Motorola assumes no responsibility for the maintenance
     24        1.1  mycroft *	and support of the SOFTWARE.  
     25        1.1  mycroft *
     26        1.1  mycroft *	You are hereby granted a copyright license to use, modify, and
     27        1.1  mycroft *	distribute the SOFTWARE so long as this entire notice is retained
     28        1.1  mycroft *	without alteration in any modified and/or redistributed versions,
     29        1.1  mycroft *	and that such modified versions are clearly identified as such.
     30        1.1  mycroft *	No licenses are granted by implication, estoppel or otherwise
     31        1.1  mycroft *	under any patents or trademarks of Motorola, Inc.
     32        1.1  mycroft 
     33        1.1  mycroft *
     34        1.1  mycroft *	gen_except.sa 3.7 1/16/92
     35        1.1  mycroft *
     36        1.1  mycroft *	gen_except --- FPSP routine to detect reportable exceptions
     37        1.1  mycroft *	
     38        1.1  mycroft *	This routine compares the exception enable byte of the
     39        1.1  mycroft *	user_fpcr on the stack with the exception status byte
     40        1.1  mycroft *	of the user_fpsr. 
     41        1.1  mycroft *
     42        1.1  mycroft *	Any routine which may report an exceptions must load
     43        1.1  mycroft *	the stack frame in memory with the exceptional operand(s).
     44        1.1  mycroft *
     45        1.1  mycroft *	Priority for exceptions is:
     46        1.1  mycroft *
     47        1.1  mycroft *	Highest:	bsun
     48        1.1  mycroft *			snan
     49        1.1  mycroft *			operr
     50        1.1  mycroft *			ovfl
     51        1.1  mycroft *			unfl
     52        1.1  mycroft *			dz
     53        1.1  mycroft *			inex2
     54        1.1  mycroft *	Lowest:		inex1
     55        1.1  mycroft *
     56        1.1  mycroft *	Note: The IEEE standard specifies that inex2 is to be
     57        1.1  mycroft *	reported if ovfl occurs and the ovfl enable bit is not
     58        1.1  mycroft *	set but the inex2 enable bit is.  
     59        1.1  mycroft *
     60        1.1  mycroft 
     61        1.1  mycroft GEN_EXCEPT    IDNT    2,1 Motorola 040 Floating Point Software Package
     62        1.1  mycroft 
     63        1.1  mycroft 	section 8
     64        1.1  mycroft 
     65        1.1  mycroft 	include fpsp.h
     66        1.1  mycroft 
     67        1.1  mycroft 	xref	real_trace
     68        1.1  mycroft 	xref	fpsp_done
     69        1.1  mycroft 	xref	fpsp_fmt_error
     70        1.1  mycroft 
     71        1.1  mycroft exc_tbl:
     72        1.1  mycroft 	dc.l	bsun_exc
     73        1.1  mycroft 	dc.l	commonE1
     74        1.1  mycroft 	dc.l	commonE1
     75        1.1  mycroft 	dc.l	ovfl_unfl
     76        1.1  mycroft 	dc.l	ovfl_unfl
     77        1.1  mycroft 	dc.l	commonE1
     78        1.1  mycroft 	dc.l	commonE3
     79        1.1  mycroft 	dc.l	commonE3
     80        1.1  mycroft 	dc.l	no_match
     81        1.1  mycroft 
     82        1.1  mycroft 	xdef	gen_except
     83        1.1  mycroft gen_except:
     84        1.1  mycroft 	cmpi.b	#IDLE_SIZE-4,1(a7)	;test for idle frame
     85        1.1  mycroft 	beq.w	do_check		;go handle idle frame
     86        1.1  mycroft 	cmpi.b	#UNIMP_40_SIZE-4,1(a7)	;test for orig unimp frame
     87        1.1  mycroft 	beq.b	unimp_x			;go handle unimp frame
     88        1.1  mycroft 	cmpi.b	#UNIMP_41_SIZE-4,1(a7)	;test for rev unimp frame
     89        1.1  mycroft 	beq.b	unimp_x			;go handle unimp frame
     90        1.1  mycroft 	cmpi.b	#BUSY_SIZE-4,1(a7)	;if size <> $60, fmt error
     91        1.2  mycroft 	bne.l	fpsp_fmt_error
     92        1.1  mycroft 	lea.l	BUSY_SIZE+LOCAL_SIZE(a7),a1 ;init a1 so fpsp.h
     93        1.1  mycroft *					;equates will work
     94        1.1  mycroft * Fix up the new busy frame with entries from the unimp frame
     95        1.1  mycroft *
     96        1.1  mycroft 	move.l	ETEMP_EX(a6),ETEMP_EX(a1) ;copy etemp from unimp
     97        1.1  mycroft 	move.l	ETEMP_HI(a6),ETEMP_HI(a1) ;frame to busy frame
     98        1.1  mycroft 	move.l	ETEMP_LO(a6),ETEMP_LO(a1) 
     99        1.1  mycroft 	move.l	CMDREG1B(a6),CMDREG1B(a1) ;set inst in frame to unimp
    100        1.1  mycroft 	move.l	CMDREG1B(a6),d0		;fix cmd1b to make it
    101        1.1  mycroft 	and.l	#$03c30000,d0		;work for cmd3b
    102        1.1  mycroft 	bfextu	CMDREG1B(a6){13:1},d1	;extract bit 2
    103        1.1  mycroft 	lsl.l	#5,d1			
    104        1.1  mycroft 	swap	d1
    105        1.1  mycroft 	or.l	d1,d0			;put it in the right place
    106        1.1  mycroft 	bfextu	CMDREG1B(a6){10:3},d1	;extract bit 3,4,5
    107        1.1  mycroft 	lsl.l	#2,d1
    108        1.1  mycroft 	swap	d1
    109        1.1  mycroft 	or.l	d1,d0			;put them in the right place
    110        1.1  mycroft 	move.l	d0,CMDREG3B(a1)		;in the busy frame
    111        1.1  mycroft *
    112        1.1  mycroft * Or in the FPSR from the emulation with the USER_FPSR on the stack.
    113        1.1  mycroft *
    114        1.1  mycroft 	fmove.l	FPSR,d0		
    115        1.1  mycroft 	or.l	d0,USER_FPSR(a6)
    116        1.1  mycroft 	move.l	USER_FPSR(a6),FPSR_SHADOW(a1) ;set exc bits
    117        1.1  mycroft 	or.l	#sx_mask,E_BYTE(a1)
    118        1.1  mycroft 	bra	do_clean
    119        1.1  mycroft 
    120        1.1  mycroft *
    121        1.1  mycroft * Frame is an unimp frame possible resulting from an fmove <ea>,fp0
    122        1.1  mycroft * that caused an exception
    123        1.1  mycroft *
    124        1.1  mycroft * a1 is modified to point into the new frame allowing fpsp equates
    125        1.1  mycroft * to be valid.
    126        1.1  mycroft *
    127        1.1  mycroft unimp_x:
    128        1.1  mycroft 	cmpi.b	#UNIMP_40_SIZE-4,1(a7)	;test for orig unimp frame
    129        1.1  mycroft 	bne.b	test_rev
    130        1.1  mycroft 	lea.l	UNIMP_40_SIZE+LOCAL_SIZE(a7),a1
    131        1.1  mycroft 	bra.b	unimp_con
    132        1.1  mycroft test_rev:
    133        1.1  mycroft 	cmpi.b	#UNIMP_41_SIZE-4,1(a7)	;test for rev unimp frame
    134        1.2  mycroft 	bne.l	fpsp_fmt_error		;if not $28 or $30
    135        1.1  mycroft 	lea.l	UNIMP_41_SIZE+LOCAL_SIZE(a7),a1
    136        1.1  mycroft 	
    137        1.1  mycroft unimp_con:
    138        1.1  mycroft *
    139        1.1  mycroft * Fix up the new unimp frame with entries from the old unimp frame
    140        1.1  mycroft *
    141        1.1  mycroft 	move.l	CMDREG1B(a6),CMDREG1B(a1) ;set inst in frame to unimp
    142        1.1  mycroft *
    143        1.1  mycroft * Or in the FPSR from the emulation with the USER_FPSR on the stack.
    144        1.1  mycroft *
    145        1.1  mycroft 	fmove.l	FPSR,d0		
    146        1.1  mycroft 	or.l	d0,USER_FPSR(a6)
    147        1.1  mycroft 	bra	do_clean
    148        1.1  mycroft 
    149        1.1  mycroft *
    150        1.1  mycroft * Frame is idle, so check for exceptions reported through
    151        1.1  mycroft * USER_FPSR and set the unimp frame accordingly.  
    152        1.1  mycroft * A7 must be incremented to the point before the
    153        1.1  mycroft * idle fsave vector to the unimp vector.
    154        1.1  mycroft *
    155        1.1  mycroft 	
    156        1.1  mycroft do_check:
    157        1.1  mycroft 	add.l	#4,A7			;point A7 back to unimp frame
    158        1.1  mycroft *
    159        1.1  mycroft * Or in the FPSR from the emulation with the USER_FPSR on the stack.
    160        1.1  mycroft *
    161        1.1  mycroft 	fmove.l	FPSR,d0		
    162        1.1  mycroft 	or.l	d0,USER_FPSR(a6)
    163        1.1  mycroft *
    164        1.1  mycroft * On a busy frame, we must clear the nmnexc bits.
    165        1.1  mycroft *
    166        1.1  mycroft 	cmpi.b	#BUSY_SIZE-4,1(a7)	;check frame type
    167        1.1  mycroft 	bne.b	check_fr		;if busy, clr nmnexc
    168        1.1  mycroft 	clr.w	NMNEXC(a6)		;clr nmnexc & nmcexc
    169        1.1  mycroft 	btst.b	#5,CMDREG1B(a6)		;test for fmove out
    170        1.1  mycroft 	bne.b	frame_com
    171        1.1  mycroft 	move.l	USER_FPSR(a6),FPSR_SHADOW(a6) ;set exc bits
    172        1.1  mycroft 	or.l	#sx_mask,E_BYTE(a6)
    173        1.1  mycroft 	bra.b	frame_com
    174        1.1  mycroft check_fr:
    175        1.1  mycroft 	cmp.b	#UNIMP_40_SIZE-4,1(a7)
    176        1.1  mycroft 	beq.b	frame_com
    177        1.1  mycroft 	clr.w	NMNEXC(a6)
    178        1.1  mycroft frame_com:
    179        1.1  mycroft 	move.b	FPCR_ENABLE(a6),d0	;get fpcr enable byte
    180        1.1  mycroft 	and.b	FPSR_EXCEPT(a6),d0	;and in the fpsr exc byte
    181        1.1  mycroft 	bfffo	d0{24:8},d1		;test for first set bit
    182        1.1  mycroft 	lea.l	exc_tbl,a0		;load jmp table address
    183        1.1  mycroft 	subi.b	#24,d1			;normalize bit offset to 0-8
    184        1.1  mycroft 	move.l	(a0,d1.w*4),a0		;load routine address based
    185        1.1  mycroft *					;based on first enabled exc
    186        1.1  mycroft 	jmp	(a0)			;jump to routine
    187        1.1  mycroft *
    188        1.1  mycroft * Bsun is not possible in unimp or unsupp
    189        1.1  mycroft *
    190        1.1  mycroft bsun_exc:
    191        1.1  mycroft 	bra	do_clean
    192        1.1  mycroft *
    193        1.1  mycroft * The typical work to be done to the unimp frame to report an 
    194        1.1  mycroft * exception is to set the E1/E3 byte and clr the U flag.
    195        1.1  mycroft * commonE1 does this for E1 exceptions, which are snan, 
    196        1.1  mycroft * operr, and dz.  commonE3 does this for E3 exceptions, which 
    197        1.1  mycroft * are inex2 and inex1, and also clears the E1 exception bit
    198        1.1  mycroft * left over from the unimp exception.
    199        1.1  mycroft *
    200        1.1  mycroft commonE1:
    201        1.1  mycroft 	bset.b	#E1,E_BYTE(a6)		;set E1 flag
    202        1.1  mycroft 	bra.w	commonE			;go clean and exit
    203        1.1  mycroft 
    204        1.1  mycroft commonE3:
    205        1.1  mycroft 	tst.b	UFLG_TMP(a6)		;test flag for unsup/unimp state
    206        1.1  mycroft 	bne.b	unsE3
    207        1.1  mycroft uniE3:
    208        1.1  mycroft 	bset.b	#E3,E_BYTE(a6)		;set E3 flag
    209        1.1  mycroft 	bclr.b	#E1,E_BYTE(a6)		;clr E1 from unimp
    210        1.1  mycroft 	bra.w	commonE
    211        1.1  mycroft 
    212        1.1  mycroft unsE3:
    213        1.1  mycroft 	tst.b	RES_FLG(a6)
    214        1.1  mycroft 	bne.b	unsE3_0	
    215        1.1  mycroft unsE3_1:
    216        1.1  mycroft 	bset.b	#E3,E_BYTE(a6)		;set E3 flag
    217        1.1  mycroft unsE3_0:
    218        1.1  mycroft 	bclr.b	#E1,E_BYTE(a6)		;clr E1 flag
    219        1.1  mycroft 	move.l	CMDREG1B(a6),d0
    220        1.1  mycroft 	and.l	#$03c30000,d0		;work for cmd3b
    221        1.1  mycroft 	bfextu	CMDREG1B(a6){13:1},d1	;extract bit 2
    222        1.1  mycroft 	lsl.l	#5,d1			
    223        1.1  mycroft 	swap	d1
    224        1.1  mycroft 	or.l	d1,d0			;put it in the right place
    225        1.1  mycroft 	bfextu	CMDREG1B(a6){10:3},d1	;extract bit 3,4,5
    226        1.1  mycroft 	lsl.l	#2,d1
    227        1.1  mycroft 	swap	d1
    228        1.1  mycroft 	or.l	d1,d0			;put them in the right place
    229        1.1  mycroft 	move.l	d0,CMDREG3B(a6)		;in the busy frame
    230        1.1  mycroft 
    231        1.1  mycroft commonE:
    232        1.1  mycroft 	bclr.b	#UFLAG,T_BYTE(a6)	;clr U flag from unimp
    233        1.1  mycroft 	bra.w	do_clean		;go clean and exit
    234        1.1  mycroft *
    235        1.1  mycroft * No bits in the enable byte match existing exceptions.  Check for
    236        1.1  mycroft * the case of the ovfl exc without the ovfl enabled, but with
    237        1.1  mycroft * inex2 enabled.
    238        1.1  mycroft *
    239        1.1  mycroft no_match:
    240        1.1  mycroft 	btst.b	#inex2_bit,FPCR_ENABLE(a6) ;check for ovfl/inex2 case
    241        1.1  mycroft 	beq.b	no_exc			;if clear, exit
    242        1.1  mycroft 	btst.b	#ovfl_bit,FPSR_EXCEPT(a6) ;now check ovfl
    243        1.1  mycroft 	beq.b	no_exc			;if clear, exit
    244        1.1  mycroft 	bra.b	ovfl_unfl		;go to unfl_ovfl to determine if
    245        1.1  mycroft *					;it is an unsupp or unimp exc
    246        1.1  mycroft 	
    247        1.1  mycroft * No exceptions are to be reported.  If the instruction was 
    248        1.1  mycroft * unimplemented, no FPU restore is necessary.  If it was
    249        1.1  mycroft * unsupported, we must perform the restore.
    250        1.1  mycroft no_exc:
    251        1.1  mycroft 	tst.b	UFLG_TMP(a6)	;test flag for unsupp/unimp state
    252        1.1  mycroft 	beq.b	uni_no_exc
    253        1.1  mycroft uns_no_exc:
    254        1.1  mycroft 	tst.b	RES_FLG(a6)	;check if frestore is needed
    255        1.1  mycroft 	bne.w	do_clean 	;if clear, no frestore needed
    256        1.1  mycroft uni_no_exc:
    257        1.1  mycroft 	movem.l	USER_DA(a6),d0-d1/a0-a1
    258        1.1  mycroft 	fmovem.x USER_FP0(a6),fp0-fp3
    259        1.1  mycroft 	fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar
    260        1.1  mycroft 	unlk	a6
    261        1.1  mycroft 	bra	finish_up
    262        1.1  mycroft *
    263        1.1  mycroft * Unsupported Data Type Handler:
    264        1.1  mycroft * Ovfl:
    265        1.1  mycroft *   An fmoveout that results in an overflow is reported this way.
    266        1.1  mycroft * Unfl:
    267        1.1  mycroft *   An fmoveout that results in an underflow is reported this way.
    268        1.1  mycroft *
    269        1.1  mycroft * Unimplemented Instruction Handler:
    270        1.1  mycroft * Ovfl:
    271        1.1  mycroft *   Only scosh, setox, ssinh, stwotox, and scale can set overflow in 
    272        1.1  mycroft *   this manner.
    273        1.1  mycroft * Unfl:
    274        1.1  mycroft *   Stwotox, setox, and scale can set underflow in this manner.
    275        1.1  mycroft *   Any of the other Library Routines such that f(x)=x in which
    276        1.1  mycroft *   x is an extended denorm can report an underflow exception. 
    277        1.1  mycroft *   It is the responsibility of the exception-causing exception 
    278        1.1  mycroft *   to make sure that WBTEMP is correct.
    279        1.1  mycroft *
    280        1.1  mycroft *   The exceptional operand is in FP_SCR1.
    281        1.1  mycroft *
    282        1.1  mycroft ovfl_unfl:
    283        1.1  mycroft 	tst.b	UFLG_TMP(a6)	;test flag for unsupp/unimp state
    284        1.1  mycroft 	beq.b	ofuf_con
    285        1.1  mycroft *
    286        1.1  mycroft * The caller was from an unsupported data type trap.  Test if the
    287        1.1  mycroft * caller set CU_ONLY.  If so, the exceptional operand is expected in
    288        1.1  mycroft * FPTEMP, rather than WBTEMP.
    289        1.1  mycroft *
    290        1.1  mycroft 	tst.b	CU_ONLY(a6)		;test if inst is cu-only
    291        1.1  mycroft 	beq.w	unsE3
    292        1.1  mycroft *	move.w	#$fe,CU_SAVEPC(a6)
    293        1.1  mycroft 	clr.b	CU_SAVEPC(a6)
    294        1.1  mycroft 	bset.b	#E1,E_BYTE(a6)		;set E1 exception flag
    295        1.1  mycroft 	move.w	ETEMP_EX(a6),FPTEMP_EX(a6)
    296        1.1  mycroft 	move.l	ETEMP_HI(a6),FPTEMP_HI(a6)
    297        1.1  mycroft 	move.l	ETEMP_LO(a6),FPTEMP_LO(a6)
    298        1.1  mycroft 	bset.b	#fptemp15_bit,DTAG(a6)	;set fpte15
    299        1.1  mycroft 	bclr.b	#UFLAG,T_BYTE(a6)	;clr U flag from unimp
    300        1.1  mycroft 	bra.w	do_clean		;go clean and exit
    301        1.1  mycroft 
    302        1.1  mycroft ofuf_con:
    303        1.1  mycroft 	move.b	(a7),VER_TMP(a6)	;save version number
    304        1.1  mycroft 	cmpi.b	#BUSY_SIZE-4,1(a7)	;check for busy frame
    305        1.1  mycroft 	beq.b	busy_fr			;if unimp, grow to busy
    306        1.1  mycroft 	cmpi.b	#VER_40,(a7)		;test for orig unimp frame
    307        1.1  mycroft 	bne.b	try_41			;if not, test for rev frame
    308        1.1  mycroft 	moveq.l	#13,d0			;need to zero 14 lwords
    309        1.1  mycroft 	bra.b	ofuf_fin
    310        1.1  mycroft try_41:
    311        1.1  mycroft 	cmpi.b	#VER_41,(a7)		;test for rev unimp frame
    312        1.2  mycroft 	bne.l	fpsp_fmt_error		;if neither, exit with error
    313        1.1  mycroft 	moveq.l	#11,d0			;need to zero 12 lwords
    314        1.1  mycroft 
    315        1.1  mycroft ofuf_fin:
    316        1.1  mycroft 	clr.l	(a7)
    317        1.1  mycroft loop1:
    318        1.1  mycroft 	clr.l	-(a7)			;clear and dec a7
    319        1.1  mycroft 	dbra.w	d0,loop1
    320        1.1  mycroft 	move.b	VER_TMP(a6),(a7)
    321        1.1  mycroft 	move.b	#BUSY_SIZE-4,1(a7)		;write busy fmt word.
    322        1.1  mycroft busy_fr:
    323        1.1  mycroft 	move.l	FP_SCR1(a6),WBTEMP_EX(a6)	;write
    324  1.3.172.1     yamt 	move.l	FP_SCR1+4(a6),WBTEMP_HI(a6)	;exceptional op to
    325        1.1  mycroft 	move.l	FP_SCR1+8(a6),WBTEMP_LO(a6)	;wbtemp
    326        1.1  mycroft 	bset.b	#E3,E_BYTE(a6)			;set E3 flag
    327        1.1  mycroft 	bclr.b	#E1,E_BYTE(a6)			;make sure E1 is clear
    328        1.1  mycroft 	bclr.b	#UFLAG,T_BYTE(a6)		;clr U flag
    329        1.1  mycroft 	move.l	USER_FPSR(a6),FPSR_SHADOW(a6)
    330        1.1  mycroft 	or.l	#sx_mask,E_BYTE(a6)
    331        1.1  mycroft 	move.l	CMDREG1B(a6),d0		;fix cmd1b to make it
    332        1.1  mycroft 	and.l	#$03c30000,d0		;work for cmd3b
    333        1.1  mycroft 	bfextu	CMDREG1B(a6){13:1},d1	;extract bit 2
    334        1.1  mycroft 	lsl.l	#5,d1			
    335        1.1  mycroft 	swap	d1
    336        1.1  mycroft 	or.l	d1,d0			;put it in the right place
    337        1.1  mycroft 	bfextu	CMDREG1B(a6){10:3},d1	;extract bit 3,4,5
    338        1.1  mycroft 	lsl.l	#2,d1
    339        1.1  mycroft 	swap	d1
    340        1.1  mycroft 	or.l	d1,d0			;put them in the right place
    341        1.1  mycroft 	move.l	d0,CMDREG3B(a6)		;in the busy frame
    342        1.1  mycroft 
    343        1.1  mycroft *
    344        1.1  mycroft * Check if the frame to be restored is busy or unimp.
    345        1.1  mycroft *** NOTE *** Bug fix for errata (0d43b #3)
    346        1.1  mycroft * If the frame is unimp, we must create a busy frame to 
    347        1.1  mycroft * fix the bug with the nmnexc bits in cases in which they
    348        1.1  mycroft * are set by a previous instruction and not cleared by
    349        1.1  mycroft * the save. The frame will be unimp only if the final 
    350        1.1  mycroft * instruction in an emulation routine caused the exception
    351        1.1  mycroft * by doing an fmove <ea>,fp0.  The exception operand, in
    352        1.1  mycroft * internal format, is in fptemp.
    353        1.1  mycroft *
    354        1.1  mycroft do_clean:
    355        1.1  mycroft 	cmpi.b	#UNIMP_40_SIZE-4,1(a7)
    356        1.1  mycroft 	bne.b	do_con
    357        1.1  mycroft 	moveq.l	#13,d0			;in orig, need to zero 14 lwords
    358        1.1  mycroft 	bra.b	do_build
    359        1.1  mycroft do_con:
    360        1.1  mycroft 	cmpi.b	#UNIMP_41_SIZE-4,1(a7)
    361        1.1  mycroft 	bne.b	do_restore		;frame must be busy
    362        1.1  mycroft 	moveq.l	#11,d0			;in rev, need to zero 12 lwords
    363        1.1  mycroft 
    364        1.1  mycroft do_build:
    365        1.1  mycroft 	move.b	(a7),VER_TMP(a6)
    366        1.1  mycroft 	clr.l	(a7)
    367        1.1  mycroft loop2:
    368        1.1  mycroft 	clr.l	-(a7)			;clear and dec a7
    369        1.1  mycroft 	dbra.w	d0,loop2
    370        1.1  mycroft *
    371        1.1  mycroft * Use a1 as pointer into new frame.  a6 is not correct if an unimp or
    372        1.1  mycroft * busy frame was created as the result of an exception on the final
    373        1.1  mycroft * instruction of an emulation routine.
    374        1.1  mycroft *
    375        1.1  mycroft * We need to set the nmcexc bits if the exception is E1. Otherwise,
    376        1.1  mycroft * the exc taken will be inex2.
    377        1.1  mycroft *
    378        1.1  mycroft 	lea.l	BUSY_SIZE+LOCAL_SIZE(a7),a1	;init a1 for new frame
    379        1.1  mycroft 	move.b	VER_TMP(a6),(a7)	;write busy fmt word
    380        1.1  mycroft 	move.b	#BUSY_SIZE-4,1(a7)
    381        1.1  mycroft 	move.l	FP_SCR1(a6),WBTEMP_EX(a1) 	;write
    382        1.1  mycroft 	move.l	FP_SCR1+4(a6),WBTEMP_HI(a1)	;exceptional op to
    383        1.1  mycroft 	move.l	FP_SCR1+8(a6),WBTEMP_LO(a1)	;wbtemp
    384        1.1  mycroft *	btst.b	#E1,E_BYTE(a1)
    385        1.1  mycroft *	beq.b	do_restore
    386        1.1  mycroft 	bfextu	USER_FPSR(a6){17:4},d0	;get snan/operr/ovfl/unfl bits
    387        1.1  mycroft 	bfins	d0,NMCEXC(a1){4:4}	;and insert them in nmcexc
    388        1.1  mycroft 	move.l	USER_FPSR(a6),FPSR_SHADOW(a1) ;set exc bits
    389        1.1  mycroft 	or.l	#sx_mask,E_BYTE(a1)
    390        1.1  mycroft 	
    391        1.1  mycroft do_restore:
    392        1.1  mycroft 	movem.l	USER_DA(a6),d0-d1/a0-a1
    393        1.1  mycroft 	fmovem.x USER_FP0(a6),fp0-fp3
    394        1.1  mycroft 	fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar
    395        1.1  mycroft 	frestore (a7)+
    396        1.1  mycroft 	tst.b	RES_FLG(a6)	;RES_FLG indicates a "continuation" frame
    397        1.1  mycroft 	beq	cont
    398        1.1  mycroft 	bsr	bug1384
    399        1.1  mycroft cont:
    400        1.1  mycroft 	unlk	a6
    401        1.1  mycroft *
    402        1.1  mycroft * If trace mode enabled, then go to trace handler.  This handler 
    403        1.1  mycroft * cannot have any fp instructions.  If there are fp inst's and an 
    404        1.1  mycroft * exception has been restored into the machine then the exception 
    405        1.1  mycroft * will occur upon execution of the fp inst.  This is not desirable 
    406        1.1  mycroft * in the kernel (supervisor mode).  See MC68040 manual Section 9.3.8.
    407        1.1  mycroft *
    408        1.1  mycroft finish_up:
    409        1.1  mycroft 	btst.b	#7,(a7)		;test T1 in SR
    410        1.1  mycroft 	bne.b	g_trace
    411        1.1  mycroft 	btst.b	#6,(a7)		;test T0 in SR
    412        1.1  mycroft 	bne.b	g_trace
    413        1.2  mycroft 	bra.l	fpsp_done
    414        1.1  mycroft *
    415        1.1  mycroft * Change integer stack to look like trace stack
    416        1.1  mycroft * The address of the instruction that caused the
    417        1.1  mycroft * exception is already in the integer stack (is
    418        1.1  mycroft * the same as the saved friar)
    419        1.1  mycroft *
    420        1.1  mycroft * If the current frame is already a 6-word stack then all
    421        1.1  mycroft * that needs to be done is to change the vector# to TRACE.
    422        1.1  mycroft * If the frame is only a 4-word stack (meaning we got here
    423        1.1  mycroft * on an Unsupported data type exception), then we need to grow
    424        1.1  mycroft * the stack an extra 2 words and get the FPIAR from the FPU.
    425        1.1  mycroft *
    426        1.1  mycroft g_trace:
    427        1.1  mycroft 	bftst	EXC_VEC-4(sp){0:4}
    428        1.1  mycroft 	bne	g_easy
    429        1.1  mycroft 
    430        1.2  mycroft 	subq.l	#4,sp		make room
    431        1.1  mycroft 	move.l	4(sp),(sp)
    432        1.1  mycroft 	move.l	8(sp),4(sp)
    433        1.2  mycroft 	sub.l	#BUSY_SIZE,sp
    434        1.1  mycroft 	fsave	(sp)
    435        1.2  mycroft 	fmove.l	fpiar,BUSY_SIZE+EXC_EA-4(sp)
    436        1.1  mycroft 	frestore (sp)
    437        1.2  mycroft 	add.l	#BUSY_SIZE,sp
    438        1.1  mycroft 
    439        1.1  mycroft g_easy:
    440        1.1  mycroft 	move.w	#TRACE_VEC,EXC_VEC-4(a7)
    441        1.2  mycroft 	bra.l	real_trace
    442        1.1  mycroft *
    443        1.1  mycroft *  This is a work-around for hardware bug 1384.
    444        1.1  mycroft *
    445        1.1  mycroft bug1384:
    446        1.1  mycroft 	link	a5,#0
    447        1.1  mycroft 	fsave	-(sp)
    448        1.1  mycroft 	cmpi.b	#$41,(sp)	; check for correct frame
    449        1.1  mycroft 	beq	frame_41
    450        1.1  mycroft 	bgt	nofix		; if more advanced mask, do nada
    451        1.1  mycroft 
    452        1.1  mycroft frame_40:
    453        1.1  mycroft 	tst.b	1(sp)		; check to see if idle
    454        1.1  mycroft 	bne	notidle
    455        1.1  mycroft idle40:
    456        1.1  mycroft 	clr.l	(sp)		; get rid of old fsave frame
    457        1.1  mycroft         move.l  d1,USER_D1(a6)  ; save d1
    458        1.1  mycroft 	move.w	#8,d1		; place unimp frame instead
    459        1.1  mycroft loop40:	clr.l	-(sp)
    460        1.1  mycroft 	dbra	d1,loop40
    461        1.1  mycroft         move.l  USER_D1(a6),d1  ; restore d1
    462        1.1  mycroft 	move.l	#$40280000,-(sp)
    463        1.1  mycroft 	frestore (sp)+
    464        1.1  mycroft 	unlk  	a5	
    465        1.1  mycroft 	rts
    466        1.1  mycroft 
    467        1.1  mycroft frame_41:
    468        1.1  mycroft 	tst.b	1(sp)		; check to see if idle
    469        1.1  mycroft 	bne	notidle	
    470        1.1  mycroft idle41:
    471        1.1  mycroft 	clr.l	(sp)		; get rid of old fsave frame
    472        1.1  mycroft         move.l  d1,USER_D1(a6)  ; save d1
    473        1.1  mycroft 	move.w	#10,d1		; place unimp frame instead
    474        1.1  mycroft loop41:	clr.l	-(sp)
    475        1.1  mycroft 	dbra	d1,loop41
    476        1.1  mycroft         move.l  USER_D1(a6),d1  ; restore d1
    477        1.1  mycroft 	move.l	#$41300000,-(sp)
    478        1.1  mycroft 	frestore (sp)+
    479        1.1  mycroft 	unlk	a5	
    480        1.1  mycroft 	rts
    481        1.1  mycroft 
    482        1.1  mycroft notidle:
    483        1.1  mycroft 	bclr.b	#etemp15_bit,-40(a5) 
    484        1.1  mycroft 	frestore (sp)+
    485        1.1  mycroft 	unlk	a5	
    486        1.1  mycroft 	rts
    487        1.1  mycroft 
    488        1.1  mycroft nofix:
    489        1.1  mycroft 	frestore (sp)+
    490        1.1  mycroft 	unlk	a5	
    491        1.1  mycroft 	rts
    492        1.1  mycroft 
    493        1.1  mycroft 	end
    494