162306a36Sopenharmony_ci| 262306a36Sopenharmony_ci| x_ovfl.sa 3.5 7/1/91 362306a36Sopenharmony_ci| 462306a36Sopenharmony_ci| fpsp_ovfl --- FPSP handler for overflow exception 562306a36Sopenharmony_ci| 662306a36Sopenharmony_ci| Overflow occurs when a floating-point intermediate result is 762306a36Sopenharmony_ci| too large to be represented in a floating-point data register, 862306a36Sopenharmony_ci| or when storing to memory, the contents of a floating-point 962306a36Sopenharmony_ci| data register are too large to be represented in the 1062306a36Sopenharmony_ci| destination format. 1162306a36Sopenharmony_ci| 1262306a36Sopenharmony_ci| Trap disabled results 1362306a36Sopenharmony_ci| 1462306a36Sopenharmony_ci| If the instruction is move_out, then garbage is stored in the 1562306a36Sopenharmony_ci| destination. If the instruction is not move_out, then the 1662306a36Sopenharmony_ci| destination is not affected. For 68881 compatibility, the 1762306a36Sopenharmony_ci| following values should be stored at the destination, based 1862306a36Sopenharmony_ci| on the current rounding mode: 1962306a36Sopenharmony_ci| 2062306a36Sopenharmony_ci| RN Infinity with the sign of the intermediate result. 2162306a36Sopenharmony_ci| RZ Largest magnitude number, with the sign of the 2262306a36Sopenharmony_ci| intermediate result. 2362306a36Sopenharmony_ci| RM For pos overflow, the largest pos number. For neg overflow, 2462306a36Sopenharmony_ci| -infinity 2562306a36Sopenharmony_ci| RP For pos overflow, +infinity. For neg overflow, the largest 2662306a36Sopenharmony_ci| neg number 2762306a36Sopenharmony_ci| 2862306a36Sopenharmony_ci| Trap enabled results 2962306a36Sopenharmony_ci| All trap disabled code applies. In addition the exceptional 3062306a36Sopenharmony_ci| operand needs to be made available to the users exception handler 3162306a36Sopenharmony_ci| with a bias of $6000 subtracted from the exponent. 3262306a36Sopenharmony_ci| 3362306a36Sopenharmony_ci| 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci| Copyright (C) Motorola, Inc. 1990 3662306a36Sopenharmony_ci| All Rights Reserved 3762306a36Sopenharmony_ci| 3862306a36Sopenharmony_ci| For details on the license for this file, please see the 3962306a36Sopenharmony_ci| file, README, in this same directory. 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ciX_OVFL: |idnt 2,1 | Motorola 040 Floating Point Software Package 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci |section 8 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci#include "fpsp.h" 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci |xref ovf_r_x2 4862306a36Sopenharmony_ci |xref ovf_r_x3 4962306a36Sopenharmony_ci |xref store 5062306a36Sopenharmony_ci |xref real_ovfl 5162306a36Sopenharmony_ci |xref real_inex 5262306a36Sopenharmony_ci |xref fpsp_done 5362306a36Sopenharmony_ci |xref g_opcls 5462306a36Sopenharmony_ci |xref b1238_fix 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci .global fpsp_ovfl 5762306a36Sopenharmony_cifpsp_ovfl: 5862306a36Sopenharmony_ci link %a6,#-LOCAL_SIZE 5962306a36Sopenharmony_ci fsave -(%a7) 6062306a36Sopenharmony_ci moveml %d0-%d1/%a0-%a1,USER_DA(%a6) 6162306a36Sopenharmony_ci fmovemx %fp0-%fp3,USER_FP0(%a6) 6262306a36Sopenharmony_ci fmoveml %fpcr/%fpsr/%fpiar,USER_FPCR(%a6) 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci| 6562306a36Sopenharmony_ci| The 040 doesn't set the AINEX bit in the FPSR, the following 6662306a36Sopenharmony_ci| line temporarily rectifies this error. 6762306a36Sopenharmony_ci| 6862306a36Sopenharmony_ci bsetb #ainex_bit,FPSR_AEXCEPT(%a6) 6962306a36Sopenharmony_ci| 7062306a36Sopenharmony_ci bsrl ovf_adj |denormalize, round & store interm op 7162306a36Sopenharmony_ci| 7262306a36Sopenharmony_ci| if overflow traps not enabled check for inexact exception 7362306a36Sopenharmony_ci| 7462306a36Sopenharmony_ci btstb #ovfl_bit,FPCR_ENABLE(%a6) 7562306a36Sopenharmony_ci beqs ck_inex 7662306a36Sopenharmony_ci| 7762306a36Sopenharmony_ci btstb #E3,E_BYTE(%a6) 7862306a36Sopenharmony_ci beqs no_e3_1 7962306a36Sopenharmony_ci bfextu CMDREG3B(%a6){#6:#3},%d0 |get dest reg no 8062306a36Sopenharmony_ci bclrb %d0,FPR_DIRTY_BITS(%a6) |clr dest dirty bit 8162306a36Sopenharmony_ci bsrl b1238_fix 8262306a36Sopenharmony_ci movel USER_FPSR(%a6),FPSR_SHADOW(%a6) 8362306a36Sopenharmony_ci orl #sx_mask,E_BYTE(%a6) 8462306a36Sopenharmony_cino_e3_1: 8562306a36Sopenharmony_ci moveml USER_DA(%a6),%d0-%d1/%a0-%a1 8662306a36Sopenharmony_ci fmovemx USER_FP0(%a6),%fp0-%fp3 8762306a36Sopenharmony_ci fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar 8862306a36Sopenharmony_ci frestore (%a7)+ 8962306a36Sopenharmony_ci unlk %a6 9062306a36Sopenharmony_ci bral real_ovfl 9162306a36Sopenharmony_ci| 9262306a36Sopenharmony_ci| It is possible to have either inex2 or inex1 exceptions with the 9362306a36Sopenharmony_ci| ovfl. If the inex enable bit is set in the FPCR, and either 9462306a36Sopenharmony_ci| inex2 or inex1 occurred, we must clean up and branch to the 9562306a36Sopenharmony_ci| real inex handler. 9662306a36Sopenharmony_ci| 9762306a36Sopenharmony_cick_inex: 9862306a36Sopenharmony_ci| move.b FPCR_ENABLE(%a6),%d0 9962306a36Sopenharmony_ci| and.b FPSR_EXCEPT(%a6),%d0 10062306a36Sopenharmony_ci| andi.b #$3,%d0 10162306a36Sopenharmony_ci btstb #inex2_bit,FPCR_ENABLE(%a6) 10262306a36Sopenharmony_ci beqs ovfl_exit 10362306a36Sopenharmony_ci| 10462306a36Sopenharmony_ci| Inexact enabled and reported, and we must take an inexact exception. 10562306a36Sopenharmony_ci| 10662306a36Sopenharmony_citake_inex: 10762306a36Sopenharmony_ci btstb #E3,E_BYTE(%a6) 10862306a36Sopenharmony_ci beqs no_e3_2 10962306a36Sopenharmony_ci bfextu CMDREG3B(%a6){#6:#3},%d0 |get dest reg no 11062306a36Sopenharmony_ci bclrb %d0,FPR_DIRTY_BITS(%a6) |clr dest dirty bit 11162306a36Sopenharmony_ci bsrl b1238_fix 11262306a36Sopenharmony_ci movel USER_FPSR(%a6),FPSR_SHADOW(%a6) 11362306a36Sopenharmony_ci orl #sx_mask,E_BYTE(%a6) 11462306a36Sopenharmony_cino_e3_2: 11562306a36Sopenharmony_ci moveb #INEX_VEC,EXC_VEC+1(%a6) 11662306a36Sopenharmony_ci moveml USER_DA(%a6),%d0-%d1/%a0-%a1 11762306a36Sopenharmony_ci fmovemx USER_FP0(%a6),%fp0-%fp3 11862306a36Sopenharmony_ci fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar 11962306a36Sopenharmony_ci frestore (%a7)+ 12062306a36Sopenharmony_ci unlk %a6 12162306a36Sopenharmony_ci bral real_inex 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ciovfl_exit: 12462306a36Sopenharmony_ci bclrb #E3,E_BYTE(%a6) |test and clear E3 bit 12562306a36Sopenharmony_ci beqs e1_set 12662306a36Sopenharmony_ci| 12762306a36Sopenharmony_ci| Clear dirty bit on dest resister in the frame before branching 12862306a36Sopenharmony_ci| to b1238_fix. 12962306a36Sopenharmony_ci| 13062306a36Sopenharmony_ci bfextu CMDREG3B(%a6){#6:#3},%d0 |get dest reg no 13162306a36Sopenharmony_ci bclrb %d0,FPR_DIRTY_BITS(%a6) |clr dest dirty bit 13262306a36Sopenharmony_ci bsrl b1238_fix |test for bug1238 case 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci movel USER_FPSR(%a6),FPSR_SHADOW(%a6) 13562306a36Sopenharmony_ci orl #sx_mask,E_BYTE(%a6) 13662306a36Sopenharmony_ci moveml USER_DA(%a6),%d0-%d1/%a0-%a1 13762306a36Sopenharmony_ci fmovemx USER_FP0(%a6),%fp0-%fp3 13862306a36Sopenharmony_ci fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar 13962306a36Sopenharmony_ci frestore (%a7)+ 14062306a36Sopenharmony_ci unlk %a6 14162306a36Sopenharmony_ci bral fpsp_done 14262306a36Sopenharmony_cie1_set: 14362306a36Sopenharmony_ci moveml USER_DA(%a6),%d0-%d1/%a0-%a1 14462306a36Sopenharmony_ci fmovemx USER_FP0(%a6),%fp0-%fp3 14562306a36Sopenharmony_ci fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar 14662306a36Sopenharmony_ci unlk %a6 14762306a36Sopenharmony_ci bral fpsp_done 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci| 15062306a36Sopenharmony_ci| ovf_adj 15162306a36Sopenharmony_ci| 15262306a36Sopenharmony_ciovf_adj: 15362306a36Sopenharmony_ci| 15462306a36Sopenharmony_ci| Have a0 point to the correct operand. 15562306a36Sopenharmony_ci| 15662306a36Sopenharmony_ci btstb #E3,E_BYTE(%a6) |test E3 bit 15762306a36Sopenharmony_ci beqs ovf_e1 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci lea WBTEMP(%a6),%a0 16062306a36Sopenharmony_ci bras ovf_com 16162306a36Sopenharmony_ciovf_e1: 16262306a36Sopenharmony_ci lea ETEMP(%a6),%a0 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ciovf_com: 16562306a36Sopenharmony_ci bclrb #sign_bit,LOCAL_EX(%a0) 16662306a36Sopenharmony_ci sne LOCAL_SGN(%a0) 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci bsrl g_opcls |returns opclass in d0 16962306a36Sopenharmony_ci cmpiw #3,%d0 |check for opclass3 17062306a36Sopenharmony_ci bnes not_opc011 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci| 17362306a36Sopenharmony_ci| FPSR_CC is saved and restored because ovf_r_x3 affects it. The 17462306a36Sopenharmony_ci| CCs are defined to be 'not affected' for the opclass3 instruction. 17562306a36Sopenharmony_ci| 17662306a36Sopenharmony_ci moveb FPSR_CC(%a6),L_SCR1(%a6) 17762306a36Sopenharmony_ci bsrl ovf_r_x3 |returns a0 pointing to result 17862306a36Sopenharmony_ci moveb L_SCR1(%a6),FPSR_CC(%a6) 17962306a36Sopenharmony_ci bral store |stores to memory or register 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_cinot_opc011: 18262306a36Sopenharmony_ci bsrl ovf_r_x2 |returns a0 pointing to result 18362306a36Sopenharmony_ci bral store |stores to memory or register 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci |end 186