OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [m68k/] [fpsp040/] [x_ovfl.S] - Rev 1765

Compare with Previous | Blame | View Log

|
|       x_ovfl.sa 3.5 7/1/91
|
|       fpsp_ovfl --- FPSP handler for overflow exception
|
|       Overflow occurs when a floating-point intermediate result is
|       too large to be represented in a floating-point data register,
|       or when storing to memory, the contents of a floating-point
|       data register are too large to be represented in the
|       destination format.
|               
| Trap disabled results
|
| If the instruction is move_out, then garbage is stored in the
| destination.  If the instruction is not move_out, then the
| destination is not affected.  For 68881 compatibility, the
| following values should be stored at the destination, based
| on the current rounding mode:
|
|  RN   Infinity with the sign of the intermediate result.
|  RZ   Largest magnitude number, with the sign of the
|       intermediate result.
|  RM   For pos overflow, the largest pos number. For neg overflow,
|       -infinity
|  RP   For pos overflow, +infinity. For neg overflow, the largest
|       neg number
|
| Trap enabled results
| All trap disabled code applies.  In addition the exceptional
| operand needs to be made available to the users exception handler
| with a bias of $6000 subtracted from the exponent.
|
|

|               Copyright (C) Motorola, Inc. 1990
|                       All Rights Reserved
|
|       THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA 
|       The copyright notice above does not evidence any  
|       actual or intended publication of such source code.

X_OVFL: |idnt    2,1 | Motorola 040 Floating Point Software Package

        |section        8

        .include "fpsp.h"

        |xref   ovf_r_x2
        |xref   ovf_r_x3
        |xref   store
        |xref   real_ovfl
        |xref   real_inex
        |xref   fpsp_done
        |xref   g_opcls
        |xref   b1238_fix

        .global fpsp_ovfl
fpsp_ovfl:
        link            %a6,#-LOCAL_SIZE
        fsave           -(%a7)
        moveml          %d0-%d1/%a0-%a1,USER_DA(%a6)
        fmovemx %fp0-%fp3,USER_FP0(%a6)
        fmoveml %fpcr/%fpsr/%fpiar,USER_FPCR(%a6)

|
|       The 040 doesn't set the AINEX bit in the FPSR, the following
|       line temporarily rectifies this error.
|
        bsetb   #ainex_bit,FPSR_AEXCEPT(%a6)
|
        bsrl    ovf_adj         |denormalize, round & store interm op
|
|       if overflow traps not enabled check for inexact exception
|
        btstb   #ovfl_bit,FPCR_ENABLE(%a6)
        beqs    ck_inex 
|
        btstb           #E3,E_BYTE(%a6)
        beqs            no_e3_1
        bfextu          CMDREG3B(%a6){#6:#3},%d0        |get dest reg no
        bclrb           %d0,FPR_DIRTY_BITS(%a6) |clr dest dirty bit
        bsrl            b1238_fix
        movel           USER_FPSR(%a6),FPSR_SHADOW(%a6)
        orl             #sx_mask,E_BYTE(%a6)
no_e3_1:
        moveml          USER_DA(%a6),%d0-%d1/%a0-%a1
        fmovemx USER_FP0(%a6),%fp0-%fp3
        fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
        frestore        (%a7)+
        unlk            %a6
        bral            real_ovfl
|
| It is possible to have either inex2 or inex1 exceptions with the
| ovfl.  If the inex enable bit is set in the FPCR, and either
| inex2 or inex1 occurred, we must clean up and branch to the
| real inex handler.
|
ck_inex:
|       move.b          FPCR_ENABLE(%a6),%d0
|       and.b           FPSR_EXCEPT(%a6),%d0
|       andi.b          #$3,%d0
        btstb           #inex2_bit,FPCR_ENABLE(%a6)
        beqs            ovfl_exit
|
| Inexact enabled and reported, and we must take an inexact exception.
|
take_inex:
        btstb           #E3,E_BYTE(%a6)
        beqs            no_e3_2
        bfextu          CMDREG3B(%a6){#6:#3},%d0        |get dest reg no
        bclrb           %d0,FPR_DIRTY_BITS(%a6) |clr dest dirty bit
        bsrl            b1238_fix
        movel           USER_FPSR(%a6),FPSR_SHADOW(%a6)
        orl             #sx_mask,E_BYTE(%a6)
no_e3_2:
        moveb           #INEX_VEC,EXC_VEC+1(%a6)
        moveml          USER_DA(%a6),%d0-%d1/%a0-%a1
        fmovemx USER_FP0(%a6),%fp0-%fp3
        fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
        frestore        (%a7)+
        unlk            %a6
        bral            real_inex
        
ovfl_exit:
        bclrb   #E3,E_BYTE(%a6) |test and clear E3 bit
        beqs    e1_set
|
| Clear dirty bit on dest resister in the frame before branching
| to b1238_fix.
|
        bfextu          CMDREG3B(%a6){#6:#3},%d0        |get dest reg no
        bclrb           %d0,FPR_DIRTY_BITS(%a6) |clr dest dirty bit
        bsrl            b1238_fix               |test for bug1238 case

        movel           USER_FPSR(%a6),FPSR_SHADOW(%a6)
        orl             #sx_mask,E_BYTE(%a6)
        moveml          USER_DA(%a6),%d0-%d1/%a0-%a1
        fmovemx USER_FP0(%a6),%fp0-%fp3
        fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
        frestore        (%a7)+
        unlk            %a6
        bral            fpsp_done
e1_set:
        moveml          USER_DA(%a6),%d0-%d1/%a0-%a1
        fmovemx USER_FP0(%a6),%fp0-%fp3
        fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
        unlk            %a6
        bral            fpsp_done

|
|       ovf_adj
|
ovf_adj:
|
| Have a0 point to the correct operand. 
|
        btstb   #E3,E_BYTE(%a6) |test E3 bit
        beqs    ovf_e1

        lea     WBTEMP(%a6),%a0
        bras    ovf_com
ovf_e1:
        lea     ETEMP(%a6),%a0

ovf_com:
        bclrb   #sign_bit,LOCAL_EX(%a0)
        sne     LOCAL_SGN(%a0)

        bsrl    g_opcls         |returns opclass in d0
        cmpiw   #3,%d0          |check for opclass3
        bnes    not_opc011

|
| FPSR_CC is saved and restored because ovf_r_x3 affects it. The
| CCs are defined to be 'not affected' for the opclass3 instruction.
|
        moveb   FPSR_CC(%a6),L_SCR1(%a6)
        bsrl    ovf_r_x3        |returns a0 pointing to result
        moveb   L_SCR1(%a6),FPSR_CC(%a6)
        bral    store           |stores to memory or register
        
not_opc011:
        bsrl    ovf_r_x2        |returns a0 pointing to result
        bral    store           |stores to memory or register

        |end

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.