123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- |
- | 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.
- |
- |
- | Copyright (C) Motorola, Inc. 1990
- | All Rights Reserved
- |
- | For details on the license for this file, please see the
- | file, README, in this same directory.
- 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
- .global fpsp_ovfl
- fpsp_ovfl:
- link %a6,#-LOCAL_SIZE
- fsave -(%a7)
- moveml %d0-%d1/%a0-%a1,USER_DA(%a6)
- fmovemx %fp0-%fp3,USER_FP0(%a6)
- fmoveml %fpcr/%fpsr/%fpiar,USER_FPCR(%a6)
- |
- | The 040 doesn't set the AINEX bit in the FPSR, the following
- | line temporarily rectifies this error.
- |
- bsetb #ainex_bit,FPSR_AEXCEPT(%a6)
- |
- bsrl ovf_adj |denormalize, round & store interm op
- |
- | if overflow traps not enabled check for inexact exception
- |
- btstb #ovfl_bit,FPCR_ENABLE(%a6)
- beqs ck_inex
- |
- btstb #E3,E_BYTE(%a6)
- beqs no_e3_1
- bfextu CMDREG3B(%a6){#6:#3},%d0 |get dest reg no
- bclrb %d0,FPR_DIRTY_BITS(%a6) |clr dest dirty bit
- bsrl b1238_fix
- movel USER_FPSR(%a6),FPSR_SHADOW(%a6)
- orl #sx_mask,E_BYTE(%a6)
- no_e3_1:
- moveml USER_DA(%a6),%d0-%d1/%a0-%a1
- fmovemx USER_FP0(%a6),%fp0-%fp3
- fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
- frestore (%a7)+
- unlk %a6
- bral 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
- btstb #inex2_bit,FPCR_ENABLE(%a6)
- beqs ovfl_exit
- |
- | Inexact enabled and reported, and we must take an inexact exception.
- |
- take_inex:
- btstb #E3,E_BYTE(%a6)
- beqs no_e3_2
- bfextu CMDREG3B(%a6){#6:#3},%d0 |get dest reg no
- bclrb %d0,FPR_DIRTY_BITS(%a6) |clr dest dirty bit
- bsrl b1238_fix
- movel USER_FPSR(%a6),FPSR_SHADOW(%a6)
- orl #sx_mask,E_BYTE(%a6)
- no_e3_2:
- moveb #INEX_VEC,EXC_VEC+1(%a6)
- moveml USER_DA(%a6),%d0-%d1/%a0-%a1
- fmovemx USER_FP0(%a6),%fp0-%fp3
- fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
- frestore (%a7)+
- unlk %a6
- bral real_inex
- ovfl_exit:
- bclrb #E3,E_BYTE(%a6) |test and clear E3 bit
- beqs 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
- bclrb %d0,FPR_DIRTY_BITS(%a6) |clr dest dirty bit
- bsrl b1238_fix |test for bug1238 case
- movel USER_FPSR(%a6),FPSR_SHADOW(%a6)
- orl #sx_mask,E_BYTE(%a6)
- moveml USER_DA(%a6),%d0-%d1/%a0-%a1
- fmovemx USER_FP0(%a6),%fp0-%fp3
- fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
- frestore (%a7)+
- unlk %a6
- bral fpsp_done
- e1_set:
- moveml USER_DA(%a6),%d0-%d1/%a0-%a1
- fmovemx USER_FP0(%a6),%fp0-%fp3
- fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
- unlk %a6
- bral fpsp_done
- |
- | ovf_adj
- |
- ovf_adj:
- |
- | Have a0 point to the correct operand.
- |
- btstb #E3,E_BYTE(%a6) |test E3 bit
- beqs ovf_e1
- lea WBTEMP(%a6),%a0
- bras ovf_com
- ovf_e1:
- lea ETEMP(%a6),%a0
- ovf_com:
- bclrb #sign_bit,LOCAL_EX(%a0)
- sne LOCAL_SGN(%a0)
- bsrl g_opcls |returns opclass in d0
- cmpiw #3,%d0 |check for opclass3
- bnes 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.
- |
- moveb FPSR_CC(%a6),L_SCR1(%a6)
- bsrl ovf_r_x3 |returns a0 pointing to result
- moveb L_SCR1(%a6),FPSR_CC(%a6)
- bral store |stores to memory or register
- not_opc011:
- bsrl ovf_r_x2 |returns a0 pointing to result
- bral store |stores to memory or register
- |end
|