diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 1998-12-14 23:15:38 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 1998-12-14 23:15:38 +0000 |
commit | 01629105c2817a59a4f1f05039593f211cf5ddaa (patch) | |
tree | 76f6bb8f9ca6ddbd015e3b81964a8dacffaf5cf9 /c/src/lib/libcpu/m68k/m68040/fpsp/x_ovfl.S | |
parent | Patch from Ralf Corsepius <corsepiu@faw.uni-ulm.de> to rename all (diff) | |
download | rtems-01629105c2817a59a4f1f05039593f211cf5ddaa.tar.bz2 |
Patch from Ralf Corsepius <corsepiu@faw.uni-ulm.de> to rename all
.s files to .S in conformance with GNU conventions. This is a
minor step along the way to supporting automake.
Diffstat (limited to 'c/src/lib/libcpu/m68k/m68040/fpsp/x_ovfl.S')
-rw-r--r-- | c/src/lib/libcpu/m68k/m68040/fpsp/x_ovfl.S | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/c/src/lib/libcpu/m68k/m68040/fpsp/x_ovfl.S b/c/src/lib/libcpu/m68k/m68040/fpsp/x_ovfl.S new file mode 100644 index 0000000000..e56f2b88c5 --- /dev/null +++ b/c/src/lib/libcpu/m68k/m68040/fpsp/x_ovfl.S @@ -0,0 +1,188 @@ +// +// $Id$ +// +// 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 |