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