head     56.1;
access   paws bayes jws quist dew jwh;
symbols  ;
locks    ; strict;
comment  @# @;


56.1
date     91.11.05.09.33.07;  author jwh;  state Exp;
branches ;
next     55.1;

55.1
date     91.08.25.10.11.23;  author jwh;  state Exp;
branches ;
next     54.2;

54.2
date     91.08.21.14.37.52;  author jwh;  state Exp;
branches ;
next     54.1;

54.1
date     91.03.18.15.18.33;  author jwh;  state Exp;
branches ;
next     53.1;

53.1
date     91.03.11.19.19.14;  author jwh;  state Exp;
branches ;
next     52.1;

52.1
date     91.02.19.09.04.09;  author jwh;  state Exp;
branches ;
next     51.2;

51.2
date     91.02.10.16.21.54;  author jwh;  state Exp;
branches ;
next     51.1;

51.1
date     91.01.30.16.03.21;  author jwh;  state Exp;
branches ;
next     1.1;

1.1
date     91.01.30.10.20.45;  author jwh;  state tmp;
branches ;
next     ;


desc
@Base file for PWS 3.3 release.

@


56.1
log
@Automatic bump of revision number for PWS version 3.25
@
text
@@


55.1
log
@Automatic bump of revision number for PWS version 3.25A
@
text
@@


54.2
log
@
pws2rcs automatic delta on Wed Aug 21 13:42:03 MDT 1991
@
text
@@


54.1
log
@Automatic bump of revision number for PWS version 3.24
@
text
@a0 383
*
*       gen_except.sa 3.1 12/10/90
*
*       gen_except --- FPSP routine to detect reportable exceptions
*
*       This routine compares the exception enable byte of the
*       user_FPCONTROL on the stack with the exception status byte
*       of the user_FPSTATUS.
*
*       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.



	include fpsp_h

	refr    real_trace
	refr    fpsp_done
	refr    fpsp_fmt_error

exc_tbl    equ    *
	dc.l    bsun_exc
	dc.l    commonE1
	dc.l    commonE1
	dc.l    ovfl_unfl
	dc.l    ovfl_unfl
	dc.l    commonE1
	dc.l    commonE3
	dc.l    commonE3
	dc.l    no_match

	def     gen_except
gen_except    equ    *
	cmpi.b  #IDLE_SIZE-4,1(a7)      ;test for idle frame
	beq.w   do_check                ;go handle idle frame
	cmpi.b  #UNIMP_40_SIZE-4,1(a7)  ;test for orig unimp frame
	beq.b   unimp_x                 ;go handle unimp frame
	cmpi.b  #UNIMP_41_SIZE-4,1(a7)  ;test for rev unimp frame
	beq.b   unimp_x                 ;go handle unimp frame
	cmpi.b  #BUSY_SIZE-4,1(a7)      ;if size <> $60, fmt error
	bne     fpsp_fmt_error
	lea     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
*
	move.l  ETEMP_EX(a6),ETEMP_EX(a1) ;copy etemp from unimp
	move.l  ETEMP_HI(a6),ETEMP_HI(a1) ;frame to busy frame
	move.l  ETEMP_LO(a6),ETEMP_LO(a1)
	move.l  CMDREG1B(a6),CMDREG1B(a1) ;set inst in frame to unimp
	move.l  CMDREG1B(a6),d0         ;fix cmd1b to make it
	and.l   #$03800000,d0           ;work for cmd3b
	move.l  d0,CMDREG3B(a1)         ;in the busy frame
*
* Or in the FPSTATUS from the emulation with the USER_FPSTATUS on the stack.
*
	fmove.l FPSTATUS,d0
	or.l    d0,USER_FPSTATUS(a6)
	move.l  USER_FPSTATUS(a6),FPSTATUS_SHADOW(a1) ;set exc bits
	ori.l   #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    equ    *
	cmpi.b  #UNIMP_40_SIZE-4,1(a7)  ;test for orig unimp frame
	bne.b   test_rev
	lea     UNIMP_40_SIZE+LOCAL_SIZE(a7),a1
	bra.b   unimp_con
test_rev    equ    *
	cmpi.b  #UNIMP_41_SIZE-4,1(a7)  ;test for rev unimp frame
	bne     fpsp_fmt_error          ;if not $28 or $30
	lea     UNIMP_41_SIZE+LOCAL_SIZE(a7),a1

unimp_con    equ    *
*
* Fix up the new unimp frame with entries from the old unimp frame
*
	move.l  CMDREG1B(a6),CMDREG1B(a1) ;set inst in frame to unimp
*
* Or in the FPSTATUS from the emulation with the USER_FPSTATUS on the stack.
*
	fmove.l FPSTATUS,d0
	or.l    d0,USER_FPSTATUS(a6)
	bra     do_clean

*
* Frame is idle, so check for exceptions reported through
* USER_FPSTATUS and set the unimp frame accordingly.
* A7 must be incremented to the point before the
* idle fsave vector to the unimp vector.
*

do_check    equ    *
	add.l   #4,A7                   ;point A7 back to unimp frame
*
* Or in the FPSTATUS from the emulation with the USER_FPSTATUS on the stack.
*
	fmove.l FPSTATUS,d0
	or.l    d0,USER_FPSTATUS(a6)
*
* On a busy frame, we must clear the nmnexc bits.
*
	cmpi.b  #BUSY_SIZE-4,1(a7)      ;check frame type
	bne.b   check_fr                ;if busy, clr nmnexc
	clr.w   NMNEXC(a6)              ;clr nmnexc & nmcexc
	btst    #5,CMDREG1B(a6)         ;test for fmove out
	bne.b   check_fr
	move.l  USER_FPSTATUS(a6),FPSTATUS_SHADOW(a6) ;set exc bits
	ori.l   #sx_mask,E_BYTE(a6)

check_fr    equ    *
	move.b  FPCONTROL_ENABLE(a6),d0 ;get FPCONTROL enable byte
	and.b   FPSTATUS_EXCEPT(a6),d0  ;and in the FPSTATUS exc byte
	bfffo   d0{24:8},d1             ;test for first set bit
	lea     exc_tbl,a0              ;load jmp table address
	subi.b  #24,d1                  ;normalize bit offset to 0-8
	move.l  (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    equ    *
	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    equ    *
	bset    #E1,E_BYTE(a6)          ;set E1 flag
	bra.w   commonE                 ;go clean and exit

commonE3    equ    *
	tst.b   UFLG_TMP(a6)            ;test flag for unsup/unimp state
	bne.b   unsE3
uniE3    equ    *
	bset    #E3,E_BYTE(a6)          ;set E3 flag
	bclr    #E1,E_BYTE(a6)          ;clr E1 from unimp
	bra.w   commonE

unsE3    equ    *
	tst.b   RES_FLG(a6)
	bne.b   unsE3_0
unsE3_1    equ    *
	bset    #E3,E_BYTE(a6)          ;set E3 flag
unsE3_0    equ    *
	bclr    #E1,E_BYTE(a6)          ;clr E1 flag
	move.l  CMDREG1B(a6),d0
	and.l   #$03800000,d0           ;work for cmd3b
	move.l  d0,CMDREG3B(a6)         ;in the busy frame

commonE    equ    *
	bclr    #UFLAG,T_BYTE(a6)       ;clr U flag from unimp
	bra.w   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    equ    *
	btst    #inex2_bit,FPCONTROL_ENABLE(a6) ;check for ovfl/inex2 case
	beq.b   no_exc                  ;if clear, exit
	btst    #ovfl_bit,FPSTATUS_EXCEPT(a6) ;now check ovfl
	beq.b   no_exc                  ;if clear, exit
	bra.b   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    equ    *
	tst.b   UFLG_TMP(a6)    ;test flag for unsupp/unimp state
	beq.b   uni_no_exc
uns_no_exc    equ    *
	tst.b   RES_FLG(a6)     ;check if frestore is needed
	bne.w   do_clean        ;if clear, no frestore needed
uni_no_exc    equ    *
	movem.l USER_DA(a6),d0-d1/a0-a1
	fmovem.x USER_FP0(a6),fp0-fp3
	fmovem.l USER_FPCONTROL(a6),FPCONTROL/FPSTATUS/FPIADDR
	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    equ    *
	tst.b   UFLG_TMP(a6)    ;test flag for unsupp/unimp state
	beq.b   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.
*
	tst.b   CU_ONLY(a6)             ;test if inst is cu-only
	beq.b   unsE3
	move.w  #$fe,CU_SAVEPC(a6)
	bset    #E1,E_BYTE(a6)          ;set E1 exception flag
	move.w  ETEMP_EX(a6),FPTEMP_EX(a6)
	move.l  ETEMP_HI(a6),FPTEMP_HI(a6)
	move.l  ETEMP_LO(a6),FPTEMP_LO(a6)
	bset    #fptemp15_bit,DTAG(a6)  ;set fpte15
	bclr    #UFLAG,T_BYTE(a6)       ;clr U flag from unimp
	bra.w   do_clean                ;go clean and exit

ofuf_con    equ    *
	move.b  (a7),VER_TMP(a6)        ;save version number
	cmpi.b  #BUSY_SIZE-4,1(a7)      ;check for busy frame
	beq.b   busy_fr                 ;if unimp, grow to busy
	cmpi.b  #VER_40,(a7)            ;test for orig unimp frame
	bne.b   try_41                  ;if not, test for rev frame
	moveq   #13,d0                  ;need to zero 14 lwords
	bra.b   ofuf_fin
try_41    equ    *
	cmpi.b  #VER_41,(a7)            ;test for rev unimp frame
	bne     fpsp_fmt_error          ;if neither, exit with error
	moveq   #11,d0                  ;need to zero 12 lwords

ofuf_fin    equ    *
	clr.l   (a7)
loop1    equ    *
	clr.l   -(a7)                   ;clear and dec a7
	dbra    d0,loop1
	move.b  VER_TMP(a6),(a7)
	move.b  #BUSY_SIZE-4,1(a7)              ;write busy fmt word.
busy_fr    equ    *
	move.l  FP_SCR1(a6),WBTEMP_EX(a6)       ;write
	move.l  FP_SCR1+4(a6),WBTEMP_HI(a6)     ;execptional op to
	move.l  FP_SCR1+8(a6),WBTEMP_LO(a6)     ;wbtemp
	bset    #E3,E_BYTE(a6)                  ;set E3 flag
	bclr    #E1,E_BYTE(a6)                  ;make sure E1 is clear
	bclr    #UFLAG,T_BYTE(a6)               ;clr U flag
	move.l  USER_FPSTATUS(a6),FPSTATUS_SHADOW(a6)
	ori.l   #sx_mask,E_BYTE(a6)
	move.l  CMDREG1B(a6),d0         ;fix cmd1b to make it
	and.l   #$03800000,d0           ;work for cmd3b
	move.l  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    equ    *
	cmpi.b  #UNIMP_40_SIZE-4,1(a7)
	bne.b   do_con
	moveq   #13,d0                  ;in orig, need to zero 14 lwords
	bra.b   do_build
do_con    equ    *
	cmpi.b  #UNIMP_41_SIZE-4,1(a7)
	bne.b   do_restore              ;frame must be busy
	moveq   #11,d0                  ;in rev, need to zero 12 lwords

do_build    equ    *
	move.b  (a7),VER_TMP(a6)
	clr.l   (a7)
loop2    equ    *
	clr.l   -(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.
*
	lea     BUSY_SIZE+LOCAL_SIZE(a7),a1     ;init a1 for new frame
	move.b  VER_TMP(a6),(a7)        ;write busy fmt word
	move.b  #BUSY_SIZE-4,1(a7)
	move.l  FP_SCR1(a6),WBTEMP_EX(a1)       ;write
	move.l  FP_SCR1+4(a6),WBTEMP_HI(a1)     ;exceptional op to
	move.l  FP_SCR1+8(a6),WBTEMP_LO(a1)     ;wbtemp
	btst    #E1,E_BYTE(a1)
	beq.b   do_restore
	bfextu  USER_FPSTATUS(a6){17:4},d0      ;get snan/operr/ovfl/unfl bits
	bfins   d0,NMCEXC(a1){4:4}      ;and insert them in nmcexc
	move.l  USER_FPSTATUS(a6),FPSTATUS_SHADOW(a1) ;set exc bits
	ori.l   #sx_mask,E_BYTE(a1)

do_restore    equ    *
	movem.l USER_DA(a6),d0-d1/a0-a1
	fmovem.x USER_FP0(a6),fp0-fp3
	fmovem.l USER_FPCONTROL(a6),FPCONTROL/FPSTATUS/FPIADDR
	frestore (a7)+
	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    equ    *
	btst    #7,(a7)         ;test T1 in SR
	bne.b   g_trace
	btst    #6,(a7)         ;test T0 in SR
	bne.b   g_trace
	bra     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 FPIADDR from the FPU.
*
g_trace    equ    *
	bftst   EXC_VEC-4(sp){0:4}
	bne     g_easy

	sub.w   #4,sp           make room
	move.l  4(sp),(sp)
	move.l  8(sp),4(sp)
	sub.w   #BUSY_SIZE,sp
	fsave   (sp)
	fmove   FPIADDR,BUSY_SIZE+EXC_EA-4(sp)
	frestore (sp)
	add.w   #BUSY_SIZE,sp

g_easy    equ    *
	move.w  #TRACE_VEC,EXC_VEC-4(a7)
	bra     real_trace
*
	end
@


53.1
log
@Automatic bump of revision number for PWS version 3.24B
@
text
@@


52.1
log
@Automatic bump of revision number for PWS version 3.24A
@
text
@@


51.2
log
@*** empty log message ***
@
text
@@


51.1
log
@Automatic bump of revision number for PWS version 3.24d
@
text
@d38 1
a38 1
	include fpsp.h
@


1.1
log
@Initial revision
@
text
@@
