forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
185 lines
4.6 KiB
185 lines
4.6 KiB
| |
|
| 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
|
|
|