* $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