URL
https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk
Subversion Repositories openrisc_2011-10-31
[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libcpu/] [m68k/] [m68040/] [fpsp/] [x_ovfl.S] - Rev 173
Compare with Previous | Blame | View Log
//
// $Id: x_ovfl.S,v 1.2 2001-09-27 12:01:22 chris Exp $
//
// 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.defs"
|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