root/arch/m68k/fpsp040/x_ovfl.S

/* [<][>][^][v][top][bottom][index][help] */
   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 |
  38 |       For details on the license for this file, please see the
  39 |       file, README, in this same directory.
  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

/* [<][>][^][v][top][bottom][index][help] */