head     56.3;
access   ;
symbols  ;
locks    ; strict;
comment  @# @;


56.3
date     93.01.27.13.56.03;  author jwh;  state Exp;
branches ;
next     56.2;

56.2
date     93.01.27.12.27.56;  author jwh;  state Exp;
branches ;
next     56.1;

56.1
date     91.11.07.12.28.53;  author jwh;  state Exp;
branches ;
next     1.1;

1.1
date     91.03.13.08.43.24;  author jwh;  state Exp;
branches ;
next     ;


desc
@@


56.3
log
@
pws2rcs automatic delta on Wed Jan 27 13:14:25 MST 1993
@
text
@*
*       bugfix.sa 3.1 12/10/90
*
*
*       This file contains workarounds for bugs in the 040
*       relating to the Floating-Point Software Package (FPSP)
*
*       Fixes for bugs: 1238
*
*       Bug: 1238
*
*       Description:
*       If an FP opclass 0 or opclass 2 sgl instruction has a
*       register dependency with a previous FP instruction, and that
*       previous instruction has an OVFL, UNFL, or INEX in the nu,
*       then the subsequent FRESTORE at the end of the exception
*       handler will lock up the FPU (and the part as well, I think).
*       Example situation:
*               FMUL      FP1,FP2      ---> OVFL
*               FADD      FP2,FP3
*
*       Note the OVFL may not be detected until an FP instruction
*       after the FADD.
*
*
*    Workaround: At the end of the OVFL, UNFL, and INEX handlers
*    just prior to the FRESTORE, check for this bug situation.
*
*    if (fsave_format_version != $40)   {goto NOFIX}
*
*    if !(E3_exception_just_serviced)   {goto NOFIX}
*    if  (cupc == 0000000)              {goto NOFIX}
*    if ((cmdreg1b[15:13] != 000) &&
*       (cmdreg1b[15:10] != 010001))   {goto NOFIX}
*    if (((cmdreg1b[15:13] != 000) || (cmdreg1b[12:10] != cmdreg3b[9:7])) &&
*        (cmdreg1b[ 9: 7] != cmdreg3b[9:7]))  {goto NOFIX}
*
*
*    if (cmdreg1b[15:13] != 000)   {goto FIX_OPCLASS2}
*FIX_OPCLASS0:
*    etemp  = FP_reg_[cmdreg1b[12:10]];
*    ete15  = ~ete14;
*    cmdreg1b[15:10] = 010010;
*    FRESTORE and return;
*
*
*FIX_OPCLASS2:
*    if (etemp_exponent == min_sgl)   etemp_exponent = min_dbl;
*    if (etemp_exponent == max_sgl)   etemp_exponent = max_dbl;
*    cmdreg1b[15:10] = 010101;
*    FRESTORE and return;
*
*
*NOFIX:
*    FRESTORE and return;
*
*

*               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

	def     b1238_fix
b1238_fix    equ    *
*
* This code is entered only on completion of the handling of an
* nu-generated ovfl, unfl, or inex exception.  If the version
* number of the fsave is not $40, this handler is not necessary.
* Simply branch to fix_done and exit normally.
*
	cmpi.b  #VER_40,4(a7)
	bne.w   fix_done
*
* Test for cu_savepc equal to zero.  If not, this is not a bug
* #1238 case.
*
	move.b  CU_SAVEPC(a6),d0
	andi.b  #$FE,d0
	beq     fix_done        ;if zero, this is not bug #1238

*
* Test register identity between cmdreg3b dest reg and cmdreg3b
* dest or source regs. If they are not the same, this is not a
* bug #1238 case.
*
	bfextu  CMDREG3B(a6){6:3},d1    ;get 1st dest register no.
	bfextu  CMDREG1B(a6){6:3},d0    ;test 1st dest with 2nd dest
	cmp.b   d0,d1
	beq     tst_opcl                ;if the regs are the same,
*                                       ;continue testing
	bfextu  CMDREG1B(a6){3:3},d0    ;test 1st dest with 2nd src
	cmp.b   d0,d1
	bne     fix_done                ;if the regs are not the same,
*                                       ;it is not bug #1238
*
* Test for opclass 0 or opclass 2 with size equal to single. If
* one of these conditions are not met, this is not a bug #1238 case.
* The opclass bits are the upper 3 bits of the command word.
* The size field are the following 3 bits.
*
tst_opcl    equ    *
	move.w  CMDREG1B(a6),d0
	andi.w  #$FC00,d0       ;strip all but opclass and size
	cmpi.w  #$4400,d0       ;test for opclass 2 and size=sgl
	beq     op2sgl          ;if true, it is the opclass 2 case
	andi.w  #$E000,d0       ;strip all but opclass
	beq     op0             ;if true, it is the opclass 0 case
	bra     fix_done        ;neither are true, it is not bug #1238

*
* We have the opclass 2 single source situation.
*
op2sgl    equ    *
	move.b  #$15,d0
	bfins   d0,CMDREG1B(a6){0:6}    ;opclass 2, double

	cmpi.w  #$407F,ETEMP_EX(a6)     ;single +max
	bne.b   case2
	move.w  #$43FF,ETEMP_EX(a6)     ;to double +max
	bra.b   fix_done
case2      equ    *
	cmpi.w  #$C07F,ETEMP_EX(a6)     ;single -max
	bne.b   case3
	move.w  #$C3FF,ETEMP_EX(a6)     ;to double -max
	bra.b   fix_done
case3      equ    *
	cmpi.w  #$3F80,ETEMP_EX(a6)     ;single +min
	bne.b   case4
	move.w  #$3C00,ETEMP_EX(a6)     ;to double +min
	bra.b   fix_done
case4    equ    *
	cmpi.w  #$BF80,ETEMP_EX(a6)     ;single -min
	bne.b   fix_done
	move.w  #$BC00,ETEMP_EX(a6)     ;to double -min
	bra.b   fix_done


*
* We have the opclass 0 situation.
*
op0    equ    *
	bfextu  CMDREG1B(a6){3:3},d0    ;get source register no
	move.l  #7,d1
	sub.l   d0,d1
	clr.l   d0
	bset    d1,d0
	fmovem.x d0,ETEMP(a6)           ;load source to ETEMP

	move.b  #$12,d0
	bfins   d0,CMDREG1B(a6){0:6}    ;opclass 2, extended
*
*       Set ETEMP exponent bit 15 as the opposite of ete14
*
	btst    #6,ETEMP_EX(a6)         ;check etemp exponent bit 14
	beq     setete15
	bclr    #etemp15_bit,STAG(a6)
	bra.b   finish
setete15    equ    *
	bset    #etemp15_bit,STAG(a6)


*
* Set cu_savepc and finish with the restore.
*
finish    equ    *
*
* Enter here if the case is not of the situations affected by
* bug #1238, or if the fix is completed.  This is the common
* exit code for ovfl, unfl, and inex.
*
fix_done    equ    *

* Begin GSL Additions, clear process flag
*S268040_FP      equ  $00040000     * From h/proc.h in kernel build stuff
*NOT_S268040_FP  equ  $fffbffff     * From above
* Should be "_u+U_PROCP", but U_PROCP is 0x0, so forget about it.
*       move.l  a0,-(%sp)
*       move.l  _u,a0
*       andi.l  #NOT_S268040_FP,(a0)
*       move.l  (sp)+,a0
* End GSL Additions

	rts

	end
@


56.2
log
@
pws2rcs automatic delta on Wed Jan 27 11:57:27 MST 1993
@
text
@d1 192
@


56.1
log
@Automatic bump of revision number for PWS version 3.25
@
text
@a0 192
*
*       bugfix.sa 3.1 12/10/90
*
*
*       This file contains workarounds for bugs in the 040
*       relating to the Floating-Point Software Package (FPSP)
*
*       Fixes for bugs: 1238
*
*       Bug: 1238
*
*       Description:
*       If an FP opclass 0 or opclass 2 sgl instruction has a
*       register dependency with a previous FP instruction, and that
*       previous instruction has an OVFL, UNFL, or INEX in the nu,
*       then the subsequent FRESTORE at the end of the exception
*       handler will lock up the FPU (and the part as well, I think).
*       Example situation:
*               FMUL      FP1,FP2      ---> OVFL
*               FADD      FP2,FP3
*
*       Note the OVFL may not be detected until an FP instruction
*       after the FADD.
*
*
*    Workaround: At the end of the OVFL, UNFL, and INEX handlers
*    just prior to the FRESTORE, check for this bug situation.
*
*    if (fsave_format_version != $40)   {goto NOFIX}
*
*    if !(E3_exception_just_serviced)   {goto NOFIX}
*    if  (cupc == 0000000)              {goto NOFIX}
*    if ((cmdreg1b[15:13] != 000) &&
*       (cmdreg1b[15:10] != 010001))   {goto NOFIX}
*    if (((cmdreg1b[15:13] != 000) || (cmdreg1b[12:10] != cmdreg3b[9:7])) &&
*        (cmdreg1b[ 9: 7] != cmdreg3b[9:7]))  {goto NOFIX}
*
*
*    if (cmdreg1b[15:13] != 000)   {goto FIX_OPCLASS2}
*FIX_OPCLASS0:
*    etemp  = FP_reg_[cmdreg1b[12:10]];
*    ete15  = ~ete14;
*    cmdreg1b[15:10] = 010010;
*    FRESTORE and return;
*
*
*FIX_OPCLASS2:
*    if (etemp_exponent == min_sgl)   etemp_exponent = min_dbl;
*    if (etemp_exponent == max_sgl)   etemp_exponent = max_dbl;
*    cmdreg1b[15:10] = 010101;
*    FRESTORE and return;
*
*
*NOFIX:
*    FRESTORE and return;
*
*

*               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

	def     b1238_fix
b1238_fix    equ    *
*
* This code is entered only on completion of the handling of an
* nu-generated ovfl, unfl, or inex exception.  If the version
* number of the fsave is not $40, this handler is not necessary.
* Simply branch to fix_done and exit normally.
*
	cmpi.b  #VER_40,4(a7)
	bne.w   fix_done
*
* Test for cu_savepc equal to zero.  If not, this is not a bug
* #1238 case.
*
	move.b  CU_SAVEPC(a6),d0
	andi.b  #$FE,d0
	beq     fix_done        ;if zero, this is not bug #1238

*
* Test register identity between cmdreg3b dest reg and cmdreg3b
* dest or source regs. If they are not the same, this is not a
* bug #1238 case.
*
	bfextu  CMDREG3B(a6){6:3},d1    ;get 1st dest register no.
	bfextu  CMDREG1B(a6){6:3},d0    ;test 1st dest with 2nd dest
	cmp.b   d0,d1
	beq     tst_opcl                ;if the regs are the same,
*                                       ;continue testing
	bfextu  CMDREG1B(a6){3:3},d0    ;test 1st dest with 2nd src
	cmp.b   d0,d1
	bne     fix_done                ;if the regs are not the same,
*                                       ;it is not bug #1238
*
* Test for opclass 0 or opclass 2 with size equal to single. If
* one of these conditions are not met, this is not a bug #1238 case.
* The opclass bits are the upper 3 bits of the command word.
* The size field are the following 3 bits.
*
tst_opcl    equ    *
	move.w  CMDREG1B(a6),d0
	andi.w  #$FC00,d0       ;strip all but opclass and size
	cmpi.w  #$4400,d0       ;test for opclass 2 and size=sgl
	beq     op2sgl          ;if true, it is the opclass 2 case
	andi.w  #$E000,d0       ;strip all but opclass
	beq     op0             ;if true, it is the opclass 0 case
	bra     fix_done        ;neither are true, it is not bug #1238

*
* We have the opclass 2 single source situation.
*
op2sgl    equ    *
	move.b  #$15,d0
	bfins   d0,CMDREG1B(a6){0:6}    ;opclass 2, double

	cmpi.w  #$407F,ETEMP_EX(a6)     ;single +max
	bne.b   case2
	move.w  #$43FF,ETEMP_EX(a6)     ;to double +max
	bra.b   fix_done
case2      equ    *
	cmpi.w  #$C07F,ETEMP_EX(a6)     ;single -max
	bne.b   case3
	move.w  #$C3FF,ETEMP_EX(a6)     ;to double -max
	bra.b   fix_done
case3      equ    *
	cmpi.w  #$3F80,ETEMP_EX(a6)     ;single +min
	bne.b   case4
	move.w  #$3C00,ETEMP_EX(a6)     ;to double +min
	bra.b   fix_done
case4    equ    *
	cmpi.w  #$BF80,ETEMP_EX(a6)     ;single -min
	bne.b   fix_done
	move.w  #$BC00,ETEMP_EX(a6)     ;to double -min
	bra.b   fix_done


*
* We have the opclass 0 situation.
*
op0    equ    *
	bfextu  CMDREG1B(a6){3:3},d0    ;get source register no
	move.l  #7,d1
	sub.l   d0,d1
	clr.l   d0
	bset    d1,d0
	fmovem.x d0,ETEMP(a6)           ;load source to ETEMP

	move.b  #$12,d0
	bfins   d0,CMDREG1B(a6){0:6}    ;opclass 2, extended
*
*       Set ETEMP exponent bit 15 as the opposite of ete14
*
	btst    #6,ETEMP_EX(a6)         ;check etemp exponent bit 14
	beq     setete15
	bclr    #etemp15_bit,STAG(a6)
	bra.b   finish
setete15    equ    *
	bset    #etemp15_bit,STAG(a6)


*
* Set cu_savepc and finish with the restore.
*
finish    equ    *
*
* Enter here if the case is not of the situations affected by
* bug #1238, or if the fix is completed.  This is the common
* exit code for ovfl, unfl, and inex.
*
fix_done    equ    *

* Begin GSL Additions, clear process flag
*S268040_FP      equ  $00040000     * From h/proc.h in kernel build stuff
*NOT_S268040_FP  equ  $fffbffff     * From above
* Should be "_u+U_PROCP", but U_PROCP is 0x0, so forget about it.
*       move.l  a0,-(%sp)
*       move.l  _u,a0
*       andi.l  #NOT_S268040_FP,(a0)
*       move.l  (sp)+,a0
* End GSL Additions

	rts

	end
@


1.1
log
@Initial revision
@
text
@@
