* $NetBSD: x_ovfl.sa,v 1.3 2001/09/16 16:34:32 wiz Exp $
* MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
* M68000 Hi-Performance Microprocessor Division
* M68040 Software Package
*
* M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
* All rights reserved.
*
* THE SOFTWARE is provided on an "AS IS" basis and without warranty.
* To the maximum extent permitted by applicable law,
* MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
* INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
* PARTICULAR PURPOSE and any warranty against infringement with
* regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
* and any accompanying written materials.
*
* To the maximum extent permitted by applicable law,
* IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
* (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS
* PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR
* OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE
* SOFTWARE. Motorola assumes no responsibility for the maintenance
* and support of the SOFTWARE.
*
* You are hereby granted a copyright license to use, modify, and
* distribute the SOFTWARE so long as this entire notice is retained
* without alteration in any modified and/or redistributed versions,
* and that such modified versions are clearly identified as such.
* No licenses are granted by implication, estoppel or otherwise
* under any patents or trademarks of Motorola, Inc.
*
* x_ovfl.sa 3.5 7/1/91
*
* fpsp_ovfl --- FPSP handler for overflow exception
*
* Overflow occurs when a floating-point intermediate result is
* too large to be represented in a floating-point data register,
* or when storing to memory, the contents of a floating-point
* data register are too large to be represented in the
* destination format.
*
* Trap disabled results
*
* If the instruction is move_out, then garbage is stored in the
* destination. If the instruction is not move_out, then the
* destination is not affected. For 68881 compatibility, the
* following values should be stored at the destination, based
* on the current rounding mode:
*
* RN Infinity with the sign of the intermediate result.
* RZ Largest magnitude number, with the sign of the
* intermediate result.
* RM For pos overflow, the largest pos number. For neg overflow,
* -infinity
* RP For pos overflow, +infinity. For neg overflow, the largest
* neg number
*
* Trap enabled results
* All trap disabled code applies. In addition the exceptional
* operand needs to be made available to the users exception handler
* with a bias of $6000 subtracted from the exponent.
*
X_OVFL IDNT 2,1 Motorola 040 Floating Point Software Package
section 8
include fpsp.h
xref ovf_r_x2
xref ovf_r_x3
xref store
xref real_ovfl
xref real_inex
xref fpsp_done
xref g_opcls
xref b1238_fix
xdef fpsp_ovfl
fpsp_ovfl:
link a6,#-LOCAL_SIZE
fsave -(a7)
movem.l d0-d1/a0-a1,USER_DA(a6)
fmovem.x fp0-fp3,USER_FP0(a6)
fmovem.l fpcr/fpsr/fpiar,USER_FPCR(a6)
*
* The 040 doesn't set the AINEX bit in the FPSR, the following
* line temporarily rectifies this error.
*
bset.b #ainex_bit,FPSR_AEXCEPT(a6)
*
bsr.l ovf_adj ;denormalize, round & store interm op
*
* if overflow traps not enabled check for inexact exception
*
btst.b #ovfl_bit,FPCR_ENABLE(a6)
beq.b ck_inex
*
btst.b #E3,E_BYTE(a6)
beq.b no_e3_1
bfextu CMDREG3B(a6){6:3},d0 ;get dest reg no
bclr.b d0,FPR_DIRTY_BITS(a6) ;clr dest dirty bit
bsr.l b1238_fix
move.l USER_FPSR(a6),FPSR_SHADOW(a6)
or.l #sx_mask,E_BYTE(a6)
no_e3_1:
movem.l USER_DA(a6),d0-d1/a0-a1
fmovem.x USER_FP0(a6),fp0-fp3
fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar
frestore (a7)+
unlk a6
bra.l real_ovfl
*
* It is possible to have either inex2 or inex1 exceptions with the
* ovfl. If the inex enable bit is set in the FPCR, and either
* inex2 or inex1 occurred, we must clean up and branch to the
* real inex handler.
*
ck_inex:
* move.b FPCR_ENABLE(a6),d0
* and.b FPSR_EXCEPT(a6),d0
* andi.b #$3,d0
btst.b #inex2_bit,FPCR_ENABLE(a6)
beq.b ovfl_exit
*
* Inexact enabled and reported, and we must take an inexact exception.
*
take_inex:
btst.b #E3,E_BYTE(a6)
beq.b no_e3_2
bfextu CMDREG3B(a6){6:3},d0 ;get dest reg no
bclr.b d0,FPR_DIRTY_BITS(a6) ;clr dest dirty bit
bsr.l b1238_fix
move.l USER_FPSR(a6),FPSR_SHADOW(a6)
or.l #sx_mask,E_BYTE(a6)
no_e3_2:
move.b #INEX_VEC,EXC_VEC+1(a6)
movem.l USER_DA(a6),d0-d1/a0-a1
fmovem.x USER_FP0(a6),fp0-fp3
fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar
frestore (a7)+
unlk a6
bra.l real_inex
ovfl_exit:
bclr.b #E3,E_BYTE(a6) ;test and clear E3 bit
beq.b e1_set
*
* Clear dirty bit on dest resister in the frame before branching
* to b1238_fix.
*
bfextu CMDREG3B(a6){6:3},d0 ;get dest reg no
bclr.b d0,FPR_DIRTY_BITS(a6) ;clr dest dirty bit
bsr.l b1238_fix ;test for bug1238 case
move.l USER_FPSR(a6),FPSR_SHADOW(a6)
or.l #sx_mask,E_BYTE(a6)
movem.l USER_DA(a6),d0-d1/a0-a1
fmovem.x USER_FP0(a6),fp0-fp3
fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar
frestore (a7)+
unlk a6
bra.l fpsp_done
e1_set:
movem.l USER_DA(a6),d0-d1/a0-a1
fmovem.x USER_FP0(a6),fp0-fp3
fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar
unlk a6
bra.l fpsp_done
*
* ovf_adj
*
ovf_adj:
*
* Have a0 point to the correct operand.
*
btst.b #E3,E_BYTE(a6) ;test E3 bit
beq.b ovf_e1
lea WBTEMP(a6),a0
bra.b ovf_com
ovf_e1:
lea ETEMP(a6),a0
ovf_com:
bclr.b #sign_bit,LOCAL_EX(a0)
sne LOCAL_SGN(a0)
bsr.l g_opcls ;returns opclass in d0
cmpi.w #3,d0 ;check for opclass3
bne.b not_opc011
*
* FPSR_CC is saved and restored because ovf_r_x3 affects it. The
* CCs are defined to be 'not affected' for the opclass3 instruction.
*
move.b FPSR_CC(a6),L_SCR1(a6)
bsr.l ovf_r_x3 ;returns a0 pointing to result
move.b L_SCR1(a6),FPSR_CC(a6)
bra.l store ;stores to memory or register
not_opc011:
bsr.l ovf_r_x2 ;returns a0 pointing to result
bra.l store ;stores to memory or register
end