linux/arch/m68k/fpsp040/x_ovfl.S
<<
>>
Prefs
   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
  41X_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
  57fpsp_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)
  84no_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|
  97ck_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|
 106take_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)
 114no_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
 123ovfl_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
 142e1_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|
 152ovf_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
 161ovf_e1:
 162        lea     ETEMP(%a6),%a0
 163
 164ovf_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
 181not_opc011:
 182        bsrl    ovf_r_x2        |returns a0 pointing to result
 183        bral    store           |stores to memory or register
 184
 185        |end
 186