Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:49

0001 #include "fpsp-namespace.h"
0002 //
0003 //
0004 //  x_ovfl.sa 3.5 7/1/91
0005 //
0006 //  fpsp_ovfl --- FPSP handler for overflow exception
0007 //
0008 //  Overflow occurs when a floating-point intermediate result is
0009 //  too large to be represented in a floating-point data register,
0010 //  or when storing to memory, the contents of a floating-point
0011 //  data register are too large to be represented in the
0012 //  destination format.
0013 //
0014 // Trap disabled results
0015 //
0016 // If the instruction is move_out, then garbage is stored in the
0017 // destination.  If the instruction is not move_out, then the
0018 // destination is not affected.  For 68881 compatibility, the
0019 // following values should be stored at the destination, based
0020 // on the current rounding mode:
0021 //
0022 //  RN  Infinity with the sign of the intermediate result.
0023 //  RZ  Largest magnitude number, with the sign of the
0024 //  intermediate result.
0025 //  RM   For pos overflow, the largest pos number. For neg overflow,
0026 //  -infinity
0027 //  RP   For pos overflow, +infinity. For neg overflow, the largest
0028 //  neg number
0029 //
0030 // Trap enabled results
0031 // All trap disabled code applies.  In addition the exceptional
0032 // operand needs to be made available to the users exception handler
0033 // with a bias of $6000 subtracted from the exponent.
0034 //
0035 //
0036 
0037 //      Copyright (C) Motorola, Inc. 1990
0038 //          All Rights Reserved
0039 //
0040 //  THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
0041 //  The copyright notice above does not evidence any
0042 //  actual or intended publication of such source code.
0043 
0044 X_OVFL: //idnt    2,1 | Motorola 040 Floating Point Software Package
0045 
0046     |section    8
0047 
0048 #include "fpsp.defs"
0049 
0050     |xref   ovf_r_x2
0051     |xref   ovf_r_x3
0052     |xref   store
0053     |xref   real_ovfl
0054     |xref   real_inex
0055     |xref   fpsp_done
0056     |xref   g_opcls
0057     |xref   b1238_fix
0058 
0059     .global fpsp_ovfl
0060 fpsp_ovfl:
0061     link        %a6,#-LOCAL_SIZE
0062     fsave       -(%a7)
0063     moveml      %d0-%d1/%a0-%a1,USER_DA(%a6)
0064     fmovemx %fp0-%fp3,USER_FP0(%a6)
0065     fmoveml %fpcr/%fpsr/%fpiar,USER_FPCR(%a6)
0066 
0067 //
0068 //  The 040 doesn't set the AINEX bit in the FPSR, the following
0069 //  line temporarily rectifies this error.
0070 //
0071     bsetb   #ainex_bit,FPSR_AEXCEPT(%a6)
0072 //
0073     bsrl    ovf_adj     //denormalize, round & store interm op
0074 //
0075 //  if overflow traps not enabled check for inexact exception
0076 //
0077     btstb   #ovfl_bit,FPCR_ENABLE(%a6)
0078     beqs    ck_inex
0079 //
0080     btstb       #E3,E_BYTE(%a6)
0081     beqs        no_e3_1
0082     bfextu      CMDREG3B(%a6){#6:#3},%d0    //get dest reg no
0083     bclrb       %d0,FPR_DIRTY_BITS(%a6) //clr dest dirty bit
0084     bsrl        b1238_fix
0085     movel       USER_FPSR(%a6),FPSR_SHADOW(%a6)
0086     orl     #sx_mask,E_BYTE(%a6)
0087 no_e3_1:
0088     moveml      USER_DA(%a6),%d0-%d1/%a0-%a1
0089     fmovemx USER_FP0(%a6),%fp0-%fp3
0090     fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
0091     frestore    (%a7)+
0092     unlk        %a6
0093     bral        real_ovfl
0094 //
0095 // It is possible to have either inex2 or inex1 exceptions with the
0096 // ovfl.  If the inex enable bit is set in the FPCR, and either
0097 // inex2 or inex1 occurred, we must clean up and branch to the
0098 // real inex handler.
0099 //
0100 ck_inex:
0101 //  move.b      FPCR_ENABLE(%a6),%d0
0102 //  and.b       FPSR_EXCEPT(%a6),%d0
0103 //  andi.b      #$3,%d0
0104     btstb       #inex2_bit,FPCR_ENABLE(%a6)
0105     beqs        ovfl_exit
0106 //
0107 // Inexact enabled and reported, and we must take an inexact exception.
0108 //
0109 take_inex:
0110     btstb       #E3,E_BYTE(%a6)
0111     beqs        no_e3_2
0112     bfextu      CMDREG3B(%a6){#6:#3},%d0    //get dest reg no
0113     bclrb       %d0,FPR_DIRTY_BITS(%a6) //clr dest dirty bit
0114     bsrl        b1238_fix
0115     movel       USER_FPSR(%a6),FPSR_SHADOW(%a6)
0116     orl     #sx_mask,E_BYTE(%a6)
0117 no_e3_2:
0118     moveb       #INEX_VEC,EXC_VEC+1(%a6)
0119     moveml      USER_DA(%a6),%d0-%d1/%a0-%a1
0120     fmovemx USER_FP0(%a6),%fp0-%fp3
0121     fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
0122     frestore    (%a7)+
0123     unlk        %a6
0124     bral        real_inex
0125 
0126 ovfl_exit:
0127     bclrb   #E3,E_BYTE(%a6) //test and clear E3 bit
0128     beqs    e1_set
0129 //
0130 // Clear dirty bit on dest resister in the frame before branching
0131 // to b1238_fix.
0132 //
0133     bfextu      CMDREG3B(%a6){#6:#3},%d0    //get dest reg no
0134     bclrb       %d0,FPR_DIRTY_BITS(%a6) //clr dest dirty bit
0135     bsrl        b1238_fix       //test for bug1238 case
0136 
0137     movel       USER_FPSR(%a6),FPSR_SHADOW(%a6)
0138     orl     #sx_mask,E_BYTE(%a6)
0139     moveml      USER_DA(%a6),%d0-%d1/%a0-%a1
0140     fmovemx USER_FP0(%a6),%fp0-%fp3
0141     fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
0142     frestore    (%a7)+
0143     unlk        %a6
0144     bral        fpsp_done
0145 e1_set:
0146     moveml      USER_DA(%a6),%d0-%d1/%a0-%a1
0147     fmovemx USER_FP0(%a6),%fp0-%fp3
0148     fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
0149     unlk        %a6
0150     bral        fpsp_done
0151 
0152 //
0153 //  ovf_adj
0154 //
0155 ovf_adj:
0156 //
0157 // Have a0 point to the correct operand.
0158 //
0159     btstb   #E3,E_BYTE(%a6) //test E3 bit
0160     beqs    ovf_e1
0161 
0162     lea WBTEMP(%a6),%a0
0163     bras    ovf_com
0164 ovf_e1:
0165     lea ETEMP(%a6),%a0
0166 
0167 ovf_com:
0168     bclrb   #sign_bit,LOCAL_EX(%a0)
0169     sne LOCAL_SGN(%a0)
0170 
0171     bsrl    g_opcls     //returns opclass in d0
0172     cmpiw   #3,%d0      //check for opclass3
0173     bnes    not_opc011
0174 
0175 //
0176 // FPSR_CC is saved and restored because ovf_r_x3 affects it. The
0177 // CCs are defined to be 'not affected' for the opclass3 instruction.
0178 //
0179     moveb   FPSR_CC(%a6),L_SCR1(%a6)
0180     bsrl    ovf_r_x3    //returns a0 pointing to result
0181     moveb   L_SCR1(%a6),FPSR_CC(%a6)
0182     bral    store       //stores to memory or register
0183 
0184 not_opc011:
0185     bsrl    ovf_r_x2    //returns a0 pointing to result
0186     bral    store       //stores to memory or register
0187 
0188     |end