18c2ecf20Sopenharmony_ci| 28c2ecf20Sopenharmony_ci| x_ovfl.sa 3.5 7/1/91 38c2ecf20Sopenharmony_ci| 48c2ecf20Sopenharmony_ci| fpsp_ovfl --- FPSP handler for overflow exception 58c2ecf20Sopenharmony_ci| 68c2ecf20Sopenharmony_ci| Overflow occurs when a floating-point intermediate result is 78c2ecf20Sopenharmony_ci| too large to be represented in a floating-point data register, 88c2ecf20Sopenharmony_ci| or when storing to memory, the contents of a floating-point 98c2ecf20Sopenharmony_ci| data register are too large to be represented in the 108c2ecf20Sopenharmony_ci| destination format. 118c2ecf20Sopenharmony_ci| 128c2ecf20Sopenharmony_ci| Trap disabled results 138c2ecf20Sopenharmony_ci| 148c2ecf20Sopenharmony_ci| If the instruction is move_out, then garbage is stored in the 158c2ecf20Sopenharmony_ci| destination. If the instruction is not move_out, then the 168c2ecf20Sopenharmony_ci| destination is not affected. For 68881 compatibility, the 178c2ecf20Sopenharmony_ci| following values should be stored at the destination, based 188c2ecf20Sopenharmony_ci| on the current rounding mode: 198c2ecf20Sopenharmony_ci| 208c2ecf20Sopenharmony_ci| RN Infinity with the sign of the intermediate result. 218c2ecf20Sopenharmony_ci| RZ Largest magnitude number, with the sign of the 228c2ecf20Sopenharmony_ci| intermediate result. 238c2ecf20Sopenharmony_ci| RM For pos overflow, the largest pos number. For neg overflow, 248c2ecf20Sopenharmony_ci| -infinity 258c2ecf20Sopenharmony_ci| RP For pos overflow, +infinity. For neg overflow, the largest 268c2ecf20Sopenharmony_ci| neg number 278c2ecf20Sopenharmony_ci| 288c2ecf20Sopenharmony_ci| Trap enabled results 298c2ecf20Sopenharmony_ci| All trap disabled code applies. In addition the exceptional 308c2ecf20Sopenharmony_ci| operand needs to be made available to the users exception handler 318c2ecf20Sopenharmony_ci| with a bias of $6000 subtracted from the exponent. 328c2ecf20Sopenharmony_ci| 338c2ecf20Sopenharmony_ci| 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci| Copyright (C) Motorola, Inc. 1990 368c2ecf20Sopenharmony_ci| All Rights Reserved 378c2ecf20Sopenharmony_ci| 388c2ecf20Sopenharmony_ci| For details on the license for this file, please see the 398c2ecf20Sopenharmony_ci| file, README, in this same directory. 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ciX_OVFL: |idnt 2,1 | Motorola 040 Floating Point Software Package 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci |section 8 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci#include "fpsp.h" 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci |xref ovf_r_x2 488c2ecf20Sopenharmony_ci |xref ovf_r_x3 498c2ecf20Sopenharmony_ci |xref store 508c2ecf20Sopenharmony_ci |xref real_ovfl 518c2ecf20Sopenharmony_ci |xref real_inex 528c2ecf20Sopenharmony_ci |xref fpsp_done 538c2ecf20Sopenharmony_ci |xref g_opcls 548c2ecf20Sopenharmony_ci |xref b1238_fix 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci .global fpsp_ovfl 578c2ecf20Sopenharmony_cifpsp_ovfl: 588c2ecf20Sopenharmony_ci link %a6,#-LOCAL_SIZE 598c2ecf20Sopenharmony_ci fsave -(%a7) 608c2ecf20Sopenharmony_ci moveml %d0-%d1/%a0-%a1,USER_DA(%a6) 618c2ecf20Sopenharmony_ci fmovemx %fp0-%fp3,USER_FP0(%a6) 628c2ecf20Sopenharmony_ci fmoveml %fpcr/%fpsr/%fpiar,USER_FPCR(%a6) 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci| 658c2ecf20Sopenharmony_ci| The 040 doesn't set the AINEX bit in the FPSR, the following 668c2ecf20Sopenharmony_ci| line temporarily rectifies this error. 678c2ecf20Sopenharmony_ci| 688c2ecf20Sopenharmony_ci bsetb #ainex_bit,FPSR_AEXCEPT(%a6) 698c2ecf20Sopenharmony_ci| 708c2ecf20Sopenharmony_ci bsrl ovf_adj |denormalize, round & store interm op 718c2ecf20Sopenharmony_ci| 728c2ecf20Sopenharmony_ci| if overflow traps not enabled check for inexact exception 738c2ecf20Sopenharmony_ci| 748c2ecf20Sopenharmony_ci btstb #ovfl_bit,FPCR_ENABLE(%a6) 758c2ecf20Sopenharmony_ci beqs ck_inex 768c2ecf20Sopenharmony_ci| 778c2ecf20Sopenharmony_ci btstb #E3,E_BYTE(%a6) 788c2ecf20Sopenharmony_ci beqs no_e3_1 798c2ecf20Sopenharmony_ci bfextu CMDREG3B(%a6){#6:#3},%d0 |get dest reg no 808c2ecf20Sopenharmony_ci bclrb %d0,FPR_DIRTY_BITS(%a6) |clr dest dirty bit 818c2ecf20Sopenharmony_ci bsrl b1238_fix 828c2ecf20Sopenharmony_ci movel USER_FPSR(%a6),FPSR_SHADOW(%a6) 838c2ecf20Sopenharmony_ci orl #sx_mask,E_BYTE(%a6) 848c2ecf20Sopenharmony_cino_e3_1: 858c2ecf20Sopenharmony_ci moveml USER_DA(%a6),%d0-%d1/%a0-%a1 868c2ecf20Sopenharmony_ci fmovemx USER_FP0(%a6),%fp0-%fp3 878c2ecf20Sopenharmony_ci fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar 888c2ecf20Sopenharmony_ci frestore (%a7)+ 898c2ecf20Sopenharmony_ci unlk %a6 908c2ecf20Sopenharmony_ci bral real_ovfl 918c2ecf20Sopenharmony_ci| 928c2ecf20Sopenharmony_ci| It is possible to have either inex2 or inex1 exceptions with the 938c2ecf20Sopenharmony_ci| ovfl. If the inex enable bit is set in the FPCR, and either 948c2ecf20Sopenharmony_ci| inex2 or inex1 occurred, we must clean up and branch to the 958c2ecf20Sopenharmony_ci| real inex handler. 968c2ecf20Sopenharmony_ci| 978c2ecf20Sopenharmony_cick_inex: 988c2ecf20Sopenharmony_ci| move.b FPCR_ENABLE(%a6),%d0 998c2ecf20Sopenharmony_ci| and.b FPSR_EXCEPT(%a6),%d0 1008c2ecf20Sopenharmony_ci| andi.b #$3,%d0 1018c2ecf20Sopenharmony_ci btstb #inex2_bit,FPCR_ENABLE(%a6) 1028c2ecf20Sopenharmony_ci beqs ovfl_exit 1038c2ecf20Sopenharmony_ci| 1048c2ecf20Sopenharmony_ci| Inexact enabled and reported, and we must take an inexact exception. 1058c2ecf20Sopenharmony_ci| 1068c2ecf20Sopenharmony_citake_inex: 1078c2ecf20Sopenharmony_ci btstb #E3,E_BYTE(%a6) 1088c2ecf20Sopenharmony_ci beqs no_e3_2 1098c2ecf20Sopenharmony_ci bfextu CMDREG3B(%a6){#6:#3},%d0 |get dest reg no 1108c2ecf20Sopenharmony_ci bclrb %d0,FPR_DIRTY_BITS(%a6) |clr dest dirty bit 1118c2ecf20Sopenharmony_ci bsrl b1238_fix 1128c2ecf20Sopenharmony_ci movel USER_FPSR(%a6),FPSR_SHADOW(%a6) 1138c2ecf20Sopenharmony_ci orl #sx_mask,E_BYTE(%a6) 1148c2ecf20Sopenharmony_cino_e3_2: 1158c2ecf20Sopenharmony_ci moveb #INEX_VEC,EXC_VEC+1(%a6) 1168c2ecf20Sopenharmony_ci moveml USER_DA(%a6),%d0-%d1/%a0-%a1 1178c2ecf20Sopenharmony_ci fmovemx USER_FP0(%a6),%fp0-%fp3 1188c2ecf20Sopenharmony_ci fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar 1198c2ecf20Sopenharmony_ci frestore (%a7)+ 1208c2ecf20Sopenharmony_ci unlk %a6 1218c2ecf20Sopenharmony_ci bral real_inex 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ciovfl_exit: 1248c2ecf20Sopenharmony_ci bclrb #E3,E_BYTE(%a6) |test and clear E3 bit 1258c2ecf20Sopenharmony_ci beqs e1_set 1268c2ecf20Sopenharmony_ci| 1278c2ecf20Sopenharmony_ci| Clear dirty bit on dest resister in the frame before branching 1288c2ecf20Sopenharmony_ci| to b1238_fix. 1298c2ecf20Sopenharmony_ci| 1308c2ecf20Sopenharmony_ci bfextu CMDREG3B(%a6){#6:#3},%d0 |get dest reg no 1318c2ecf20Sopenharmony_ci bclrb %d0,FPR_DIRTY_BITS(%a6) |clr dest dirty bit 1328c2ecf20Sopenharmony_ci bsrl b1238_fix |test for bug1238 case 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci movel USER_FPSR(%a6),FPSR_SHADOW(%a6) 1358c2ecf20Sopenharmony_ci orl #sx_mask,E_BYTE(%a6) 1368c2ecf20Sopenharmony_ci moveml USER_DA(%a6),%d0-%d1/%a0-%a1 1378c2ecf20Sopenharmony_ci fmovemx USER_FP0(%a6),%fp0-%fp3 1388c2ecf20Sopenharmony_ci fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar 1398c2ecf20Sopenharmony_ci frestore (%a7)+ 1408c2ecf20Sopenharmony_ci unlk %a6 1418c2ecf20Sopenharmony_ci bral fpsp_done 1428c2ecf20Sopenharmony_cie1_set: 1438c2ecf20Sopenharmony_ci moveml USER_DA(%a6),%d0-%d1/%a0-%a1 1448c2ecf20Sopenharmony_ci fmovemx USER_FP0(%a6),%fp0-%fp3 1458c2ecf20Sopenharmony_ci fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar 1468c2ecf20Sopenharmony_ci unlk %a6 1478c2ecf20Sopenharmony_ci bral fpsp_done 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci| 1508c2ecf20Sopenharmony_ci| ovf_adj 1518c2ecf20Sopenharmony_ci| 1528c2ecf20Sopenharmony_ciovf_adj: 1538c2ecf20Sopenharmony_ci| 1548c2ecf20Sopenharmony_ci| Have a0 point to the correct operand. 1558c2ecf20Sopenharmony_ci| 1568c2ecf20Sopenharmony_ci btstb #E3,E_BYTE(%a6) |test E3 bit 1578c2ecf20Sopenharmony_ci beqs ovf_e1 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci lea WBTEMP(%a6),%a0 1608c2ecf20Sopenharmony_ci bras ovf_com 1618c2ecf20Sopenharmony_ciovf_e1: 1628c2ecf20Sopenharmony_ci lea ETEMP(%a6),%a0 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ciovf_com: 1658c2ecf20Sopenharmony_ci bclrb #sign_bit,LOCAL_EX(%a0) 1668c2ecf20Sopenharmony_ci sne LOCAL_SGN(%a0) 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci bsrl g_opcls |returns opclass in d0 1698c2ecf20Sopenharmony_ci cmpiw #3,%d0 |check for opclass3 1708c2ecf20Sopenharmony_ci bnes not_opc011 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci| 1738c2ecf20Sopenharmony_ci| FPSR_CC is saved and restored because ovf_r_x3 affects it. The 1748c2ecf20Sopenharmony_ci| CCs are defined to be 'not affected' for the opclass3 instruction. 1758c2ecf20Sopenharmony_ci| 1768c2ecf20Sopenharmony_ci moveb FPSR_CC(%a6),L_SCR1(%a6) 1778c2ecf20Sopenharmony_ci bsrl ovf_r_x3 |returns a0 pointing to result 1788c2ecf20Sopenharmony_ci moveb L_SCR1(%a6),FPSR_CC(%a6) 1798c2ecf20Sopenharmony_ci bral store |stores to memory or register 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_cinot_opc011: 1828c2ecf20Sopenharmony_ci bsrl ovf_r_x2 |returns a0 pointing to result 1838c2ecf20Sopenharmony_ci bral store |stores to memory or register 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci |end 186