1*4882a593Smuzhiyun| 2*4882a593Smuzhiyun| x_ovfl.sa 3.5 7/1/91 3*4882a593Smuzhiyun| 4*4882a593Smuzhiyun| fpsp_ovfl --- FPSP handler for overflow exception 5*4882a593Smuzhiyun| 6*4882a593Smuzhiyun| Overflow occurs when a floating-point intermediate result is 7*4882a593Smuzhiyun| too large to be represented in a floating-point data register, 8*4882a593Smuzhiyun| or when storing to memory, the contents of a floating-point 9*4882a593Smuzhiyun| data register are too large to be represented in the 10*4882a593Smuzhiyun| destination format. 11*4882a593Smuzhiyun| 12*4882a593Smuzhiyun| Trap disabled results 13*4882a593Smuzhiyun| 14*4882a593Smuzhiyun| If the instruction is move_out, then garbage is stored in the 15*4882a593Smuzhiyun| destination. If the instruction is not move_out, then the 16*4882a593Smuzhiyun| destination is not affected. For 68881 compatibility, the 17*4882a593Smuzhiyun| following values should be stored at the destination, based 18*4882a593Smuzhiyun| on the current rounding mode: 19*4882a593Smuzhiyun| 20*4882a593Smuzhiyun| RN Infinity with the sign of the intermediate result. 21*4882a593Smuzhiyun| RZ Largest magnitude number, with the sign of the 22*4882a593Smuzhiyun| intermediate result. 23*4882a593Smuzhiyun| RM For pos overflow, the largest pos number. For neg overflow, 24*4882a593Smuzhiyun| -infinity 25*4882a593Smuzhiyun| RP For pos overflow, +infinity. For neg overflow, the largest 26*4882a593Smuzhiyun| neg number 27*4882a593Smuzhiyun| 28*4882a593Smuzhiyun| Trap enabled results 29*4882a593Smuzhiyun| All trap disabled code applies. In addition the exceptional 30*4882a593Smuzhiyun| operand needs to be made available to the users exception handler 31*4882a593Smuzhiyun| with a bias of $6000 subtracted from the exponent. 32*4882a593Smuzhiyun| 33*4882a593Smuzhiyun| 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun| Copyright (C) Motorola, Inc. 1990 36*4882a593Smuzhiyun| All Rights Reserved 37*4882a593Smuzhiyun| 38*4882a593Smuzhiyun| For details on the license for this file, please see the 39*4882a593Smuzhiyun| file, README, in this same directory. 40*4882a593Smuzhiyun 41*4882a593SmuzhiyunX_OVFL: |idnt 2,1 | Motorola 040 Floating Point Software Package 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun |section 8 44*4882a593Smuzhiyun 45*4882a593Smuzhiyun#include "fpsp.h" 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun |xref ovf_r_x2 48*4882a593Smuzhiyun |xref ovf_r_x3 49*4882a593Smuzhiyun |xref store 50*4882a593Smuzhiyun |xref real_ovfl 51*4882a593Smuzhiyun |xref real_inex 52*4882a593Smuzhiyun |xref fpsp_done 53*4882a593Smuzhiyun |xref g_opcls 54*4882a593Smuzhiyun |xref b1238_fix 55*4882a593Smuzhiyun 56*4882a593Smuzhiyun .global fpsp_ovfl 57*4882a593Smuzhiyunfpsp_ovfl: 58*4882a593Smuzhiyun link %a6,#-LOCAL_SIZE 59*4882a593Smuzhiyun fsave -(%a7) 60*4882a593Smuzhiyun moveml %d0-%d1/%a0-%a1,USER_DA(%a6) 61*4882a593Smuzhiyun fmovemx %fp0-%fp3,USER_FP0(%a6) 62*4882a593Smuzhiyun fmoveml %fpcr/%fpsr/%fpiar,USER_FPCR(%a6) 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun| 65*4882a593Smuzhiyun| The 040 doesn't set the AINEX bit in the FPSR, the following 66*4882a593Smuzhiyun| line temporarily rectifies this error. 67*4882a593Smuzhiyun| 68*4882a593Smuzhiyun bsetb #ainex_bit,FPSR_AEXCEPT(%a6) 69*4882a593Smuzhiyun| 70*4882a593Smuzhiyun bsrl ovf_adj |denormalize, round & store interm op 71*4882a593Smuzhiyun| 72*4882a593Smuzhiyun| if overflow traps not enabled check for inexact exception 73*4882a593Smuzhiyun| 74*4882a593Smuzhiyun btstb #ovfl_bit,FPCR_ENABLE(%a6) 75*4882a593Smuzhiyun beqs ck_inex 76*4882a593Smuzhiyun| 77*4882a593Smuzhiyun btstb #E3,E_BYTE(%a6) 78*4882a593Smuzhiyun beqs no_e3_1 79*4882a593Smuzhiyun bfextu CMDREG3B(%a6){#6:#3},%d0 |get dest reg no 80*4882a593Smuzhiyun bclrb %d0,FPR_DIRTY_BITS(%a6) |clr dest dirty bit 81*4882a593Smuzhiyun bsrl b1238_fix 82*4882a593Smuzhiyun movel USER_FPSR(%a6),FPSR_SHADOW(%a6) 83*4882a593Smuzhiyun orl #sx_mask,E_BYTE(%a6) 84*4882a593Smuzhiyunno_e3_1: 85*4882a593Smuzhiyun moveml USER_DA(%a6),%d0-%d1/%a0-%a1 86*4882a593Smuzhiyun fmovemx USER_FP0(%a6),%fp0-%fp3 87*4882a593Smuzhiyun fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar 88*4882a593Smuzhiyun frestore (%a7)+ 89*4882a593Smuzhiyun unlk %a6 90*4882a593Smuzhiyun bral real_ovfl 91*4882a593Smuzhiyun| 92*4882a593Smuzhiyun| It is possible to have either inex2 or inex1 exceptions with the 93*4882a593Smuzhiyun| ovfl. If the inex enable bit is set in the FPCR, and either 94*4882a593Smuzhiyun| inex2 or inex1 occurred, we must clean up and branch to the 95*4882a593Smuzhiyun| real inex handler. 96*4882a593Smuzhiyun| 97*4882a593Smuzhiyunck_inex: 98*4882a593Smuzhiyun| move.b FPCR_ENABLE(%a6),%d0 99*4882a593Smuzhiyun| and.b FPSR_EXCEPT(%a6),%d0 100*4882a593Smuzhiyun| andi.b #$3,%d0 101*4882a593Smuzhiyun btstb #inex2_bit,FPCR_ENABLE(%a6) 102*4882a593Smuzhiyun beqs ovfl_exit 103*4882a593Smuzhiyun| 104*4882a593Smuzhiyun| Inexact enabled and reported, and we must take an inexact exception. 105*4882a593Smuzhiyun| 106*4882a593Smuzhiyuntake_inex: 107*4882a593Smuzhiyun btstb #E3,E_BYTE(%a6) 108*4882a593Smuzhiyun beqs no_e3_2 109*4882a593Smuzhiyun bfextu CMDREG3B(%a6){#6:#3},%d0 |get dest reg no 110*4882a593Smuzhiyun bclrb %d0,FPR_DIRTY_BITS(%a6) |clr dest dirty bit 111*4882a593Smuzhiyun bsrl b1238_fix 112*4882a593Smuzhiyun movel USER_FPSR(%a6),FPSR_SHADOW(%a6) 113*4882a593Smuzhiyun orl #sx_mask,E_BYTE(%a6) 114*4882a593Smuzhiyunno_e3_2: 115*4882a593Smuzhiyun moveb #INEX_VEC,EXC_VEC+1(%a6) 116*4882a593Smuzhiyun moveml USER_DA(%a6),%d0-%d1/%a0-%a1 117*4882a593Smuzhiyun fmovemx USER_FP0(%a6),%fp0-%fp3 118*4882a593Smuzhiyun fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar 119*4882a593Smuzhiyun frestore (%a7)+ 120*4882a593Smuzhiyun unlk %a6 121*4882a593Smuzhiyun bral real_inex 122*4882a593Smuzhiyun 123*4882a593Smuzhiyunovfl_exit: 124*4882a593Smuzhiyun bclrb #E3,E_BYTE(%a6) |test and clear E3 bit 125*4882a593Smuzhiyun beqs e1_set 126*4882a593Smuzhiyun| 127*4882a593Smuzhiyun| Clear dirty bit on dest resister in the frame before branching 128*4882a593Smuzhiyun| to b1238_fix. 129*4882a593Smuzhiyun| 130*4882a593Smuzhiyun bfextu CMDREG3B(%a6){#6:#3},%d0 |get dest reg no 131*4882a593Smuzhiyun bclrb %d0,FPR_DIRTY_BITS(%a6) |clr dest dirty bit 132*4882a593Smuzhiyun bsrl b1238_fix |test for bug1238 case 133*4882a593Smuzhiyun 134*4882a593Smuzhiyun movel USER_FPSR(%a6),FPSR_SHADOW(%a6) 135*4882a593Smuzhiyun orl #sx_mask,E_BYTE(%a6) 136*4882a593Smuzhiyun moveml USER_DA(%a6),%d0-%d1/%a0-%a1 137*4882a593Smuzhiyun fmovemx USER_FP0(%a6),%fp0-%fp3 138*4882a593Smuzhiyun fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar 139*4882a593Smuzhiyun frestore (%a7)+ 140*4882a593Smuzhiyun unlk %a6 141*4882a593Smuzhiyun bral fpsp_done 142*4882a593Smuzhiyune1_set: 143*4882a593Smuzhiyun moveml USER_DA(%a6),%d0-%d1/%a0-%a1 144*4882a593Smuzhiyun fmovemx USER_FP0(%a6),%fp0-%fp3 145*4882a593Smuzhiyun fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar 146*4882a593Smuzhiyun unlk %a6 147*4882a593Smuzhiyun bral fpsp_done 148*4882a593Smuzhiyun 149*4882a593Smuzhiyun| 150*4882a593Smuzhiyun| ovf_adj 151*4882a593Smuzhiyun| 152*4882a593Smuzhiyunovf_adj: 153*4882a593Smuzhiyun| 154*4882a593Smuzhiyun| Have a0 point to the correct operand. 155*4882a593Smuzhiyun| 156*4882a593Smuzhiyun btstb #E3,E_BYTE(%a6) |test E3 bit 157*4882a593Smuzhiyun beqs ovf_e1 158*4882a593Smuzhiyun 159*4882a593Smuzhiyun lea WBTEMP(%a6),%a0 160*4882a593Smuzhiyun bras ovf_com 161*4882a593Smuzhiyunovf_e1: 162*4882a593Smuzhiyun lea ETEMP(%a6),%a0 163*4882a593Smuzhiyun 164*4882a593Smuzhiyunovf_com: 165*4882a593Smuzhiyun bclrb #sign_bit,LOCAL_EX(%a0) 166*4882a593Smuzhiyun sne LOCAL_SGN(%a0) 167*4882a593Smuzhiyun 168*4882a593Smuzhiyun bsrl g_opcls |returns opclass in d0 169*4882a593Smuzhiyun cmpiw #3,%d0 |check for opclass3 170*4882a593Smuzhiyun bnes not_opc011 171*4882a593Smuzhiyun 172*4882a593Smuzhiyun| 173*4882a593Smuzhiyun| FPSR_CC is saved and restored because ovf_r_x3 affects it. The 174*4882a593Smuzhiyun| CCs are defined to be 'not affected' for the opclass3 instruction. 175*4882a593Smuzhiyun| 176*4882a593Smuzhiyun moveb FPSR_CC(%a6),L_SCR1(%a6) 177*4882a593Smuzhiyun bsrl ovf_r_x3 |returns a0 pointing to result 178*4882a593Smuzhiyun moveb L_SCR1(%a6),FPSR_CC(%a6) 179*4882a593Smuzhiyun bral store |stores to memory or register 180*4882a593Smuzhiyun 181*4882a593Smuzhiyunnot_opc011: 182*4882a593Smuzhiyun bsrl ovf_r_x2 |returns a0 pointing to result 183*4882a593Smuzhiyun bral store |stores to memory or register 184*4882a593Smuzhiyun 185*4882a593Smuzhiyun |end 186