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