summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/m68k/m68040/fpsp/x_ovfl.S
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1998-12-14 23:15:38 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1998-12-14 23:15:38 +0000
commit01629105c2817a59a4f1f05039593f211cf5ddaa (patch)
tree76f6bb8f9ca6ddbd015e3b81964a8dacffaf5cf9 /c/src/lib/libcpu/m68k/m68040/fpsp/x_ovfl.S
parentPatch from Ralf Corsepius <corsepiu@faw.uni-ulm.de> to rename all (diff)
downloadrtems-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.S188
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