summaryrefslogtreecommitdiff
path: root/sys/arch/m68k/fpsp/x_snan.sa
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
commitd6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch)
treeece253b876159b39c620e62b6c9b1174642e070e /sys/arch/m68k/fpsp/x_snan.sa
initial import of NetBSD tree
Diffstat (limited to 'sys/arch/m68k/fpsp/x_snan.sa')
-rw-r--r--sys/arch/m68k/fpsp/x_snan.sa302
1 files changed, 302 insertions, 0 deletions
diff --git a/sys/arch/m68k/fpsp/x_snan.sa b/sys/arch/m68k/fpsp/x_snan.sa
new file mode 100644
index 00000000000..0dba98298ab
--- /dev/null
+++ b/sys/arch/m68k/fpsp/x_snan.sa
@@ -0,0 +1,302 @@
+* $NetBSD: x_snan.sa,v 1.3 1994/10/26 07:50:28 cgd Exp $
+
+* MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
+* M68000 Hi-Performance Microprocessor Division
+* M68040 Software Package
+*
+* M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
+* All rights reserved.
+*
+* THE SOFTWARE is provided on an "AS IS" basis and without warranty.
+* To the maximum extent permitted by applicable law,
+* MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
+* INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
+* PARTICULAR PURPOSE and any warranty against infringement with
+* regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
+* and any accompanying written materials.
+*
+* To the maximum extent permitted by applicable law,
+* IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
+* (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS
+* PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR
+* OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE
+* SOFTWARE. Motorola assumes no responsibility for the maintenance
+* and support of the SOFTWARE.
+*
+* You are hereby granted a copyright license to use, modify, and
+* distribute the SOFTWARE so long as this entire notice is retained
+* without alteration in any modified and/or redistributed versions,
+* and that such modified versions are clearly identified as such.
+* No licenses are granted by implication, estoppel or otherwise
+* under any patents or trademarks of Motorola, Inc.
+
+*
+* x_snan.sa 3.3 7/1/91
+*
+* fpsp_snan --- FPSP handler for signalling NAN exception
+*
+* SNAN for float -> integer conversions (integer conversion of
+* an SNAN) is a non-maskable run-time exception.
+*
+* For trap disabled the 040 does the following:
+* If the dest data format is s, d, or x, then the SNAN bit in the NAN
+* is set to one and the resulting non-signaling NAN (truncated if
+* necessary) is transferred to the dest. If the dest format is b, w,
+* or l, then garbage is written to the dest (actually the upper 32 bits
+* of the mantissa are sent to the integer unit).
+*
+* For trap enabled the 040 does the following:
+* If the inst is move_out, then the results are the same as for trap
+* disabled with the exception posted. If the instruction is not move_
+* out, the dest. is not modified, and the exception is posted.
+*
+
+X_SNAN IDNT 2,1 Motorola 040 Floating Point Software Package
+
+ section 8
+
+ include fpsp.h
+
+ xref get_fline
+ xref mem_write
+ xref real_snan
+ xref real_inex
+ xref fpsp_done
+ xref reg_dest
+
+ xdef fpsp_snan
+fpsp_snan:
+ link a6,#-LOCAL_SIZE
+ fsave -(a7)
+ movem.l d0-d1/a0-a1,USER_DA(a6)
+ fmovem.x fp0-fp3,USER_FP0(a6)
+ fmovem.l fpcr/fpsr/fpiar,USER_FPCR(a6)
+
+*
+* Check if trap enabled
+*
+ btst.b #snan_bit,FPCR_ENABLE(a6)
+ bne.b ena ;If enabled, then branch
+
+ bsr.l move_out ;else SNAN disabled
+*
+* It is possible to have an inex1 exception with the
+* snan. If the inex enable bit is set in the FPCR, and either
+* inex2 or inex1 occured, 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
+ beq.w end_snan
+*
+* Inexact enabled and reported, and we must take an inexact exception.
+*
+take_inex:
+ move.b #INEX_VEC,EXC_VEC+1(a6)
+ movem.l USER_DA(a6),d0-d1/a0-a1
+ fmovem.x USER_FP0(a6),fp0-fp3
+ fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar
+ frestore (a7)+
+ unlk a6
+ bra.l real_inex
+*
+* SNAN is enabled. Check if inst is move_out.
+* Make any corrections to the 040 output as necessary.
+*
+ena:
+ btst.b #5,CMDREG1B(a6) ;if set, inst is move out
+ beq.w not_out
+
+ bsr.l move_out
+
+report_snan:
+ move.b (a7),VER_TMP(a6)
+ cmpi.b #VER_40,(a7) ;test for orig unimp frame
+ bne.b ck_rev
+ moveq.l #13,d0 ;need to zero 14 lwords
+ bra.b rep_con
+ck_rev:
+ moveq.l #11,d0 ;need to zero 12 lwords
+rep_con:
+ clr.l (a7)
+loop1:
+ clr.l -(a7) ;clear and dec a7
+ dbra.w d0,loop1
+ move.b VER_TMP(a6),(a7) ;format a busy frame
+ move.b #BUSY_SIZE-4,1(a7)
+ move.l USER_FPSR(a6),FPSR_SHADOW(a6)
+ or.l #sx_mask,E_BYTE(a6)
+ movem.l USER_DA(a6),d0-d1/a0-a1
+ fmovem.x USER_FP0(a6),fp0-fp3
+ fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar
+ frestore (a7)+
+ unlk a6
+ bra.l real_snan
+*
+* Exit snan handler by expanding the unimp frame into a busy frame
+*
+end_snan:
+ bclr.b #E1,E_BYTE(a6)
+
+ move.b (a7),VER_TMP(a6)
+ cmpi.b #VER_40,(a7) ;test for orig unimp frame
+ bne.b ck_rev2
+ moveq.l #13,d0 ;need to zero 14 lwords
+ bra.b rep_con2
+ck_rev2:
+ moveq.l #11,d0 ;need to zero 12 lwords
+rep_con2:
+ clr.l (a7)
+loop2:
+ clr.l -(a7) ;clear and dec a7
+ dbra.w d0,loop2
+ move.b VER_TMP(a6),(a7) ;format a busy frame
+ move.b #BUSY_SIZE-4,1(a7) ;write busy size
+ move.l USER_FPSR(a6),FPSR_SHADOW(a6)
+ or.l #sx_mask,E_BYTE(a6)
+ movem.l USER_DA(a6),d0-d1/a0-a1
+ fmovem.x USER_FP0(a6),fp0-fp3
+ fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar
+ frestore (a7)+
+ unlk a6
+ bra.l fpsp_done
+
+*
+* Move_out
+*
+move_out:
+ move.l EXC_EA(a6),a0 ;get <ea> from exc frame
+
+ bfextu CMDREG1B(a6){3:3},d0 ;move rx field to d0{2:0}
+ tst.l d0 ;check for long
+ beq.b sto_long ;branch if move_out long
+
+ cmpi.l #4,d0 ;check for word
+ beq.b sto_word ;branch if move_out word
+
+ cmpi.l #6,d0 ;check for byte
+ beq.b sto_byte ;branch if move_out byte
+
+*
+* Not byte, word or long
+*
+ rts
+*
+* Get the 32 most significant bits of etemp mantissa
+*
+sto_long:
+ move.l ETEMP_HI(a6),d1
+ move.l #4,d0 ;load byte count
+*
+* Set signalling nan bit
+*
+ bset.l #30,d1
+*
+* Store to the users destination address
+*
+ tst.l a0 ;check if <ea> is 0
+ beq.b wrt_dn ;destination is a data register
+
+ move.l d1,-(a7) ;move the snan onto the stack
+ move.l a0,a1 ;load dest addr into a1
+ move.l a7,a0 ;load src addr of snan into a0
+ bsr.l mem_write ;write snan to user memory
+ move.l (a7)+,d1 ;clear off stack
+ rts
+*
+* Get the 16 most significant bits of etemp mantissa
+*
+sto_word:
+ move.l ETEMP_HI(a6),d1
+ move.l #2,d0 ;load byte count
+*
+* Set signalling nan bit
+*
+ bset.l #30,d1
+*
+* Store to the users destination address
+*
+ tst.l a0 ;check if <ea> is 0
+ beq.b wrt_dn ;destination is a data register
+
+ move.l d1,-(a7) ;move the snan onto the stack
+ move.l a0,a1 ;load dest addr into a1
+ move.l a7,a0 ;point to low word
+ bsr.l mem_write ;write snan to user memory
+ move.l (a7)+,d1 ;clear off stack
+ rts
+*
+* Get the 8 most significant bits of etemp mantissa
+*
+sto_byte:
+ move.l ETEMP_HI(a6),d1
+ move.l #1,d0 ;load byte count
+*
+* Set signalling nan bit
+*
+ bset.l #30,d1
+*
+* Store to the users destination address
+*
+ tst.l a0 ;check if <ea> is 0
+ beq.b wrt_dn ;destination is a data register
+ move.l d1,-(a7) ;move the snan onto the stack
+ move.l a0,a1 ;load dest addr into a1
+ move.l a7,a0 ;point to source byte
+ bsr.l mem_write ;write snan to user memory
+ move.l (a7)+,d1 ;clear off stack
+ rts
+
+*
+* wrt_dn --- write to a data register
+*
+* We get here with D1 containing the data to write and D0 the
+* number of bytes to write: 1=byte,2=word,4=long.
+*
+wrt_dn:
+ move.l d1,L_SCR1(a6) ;data
+ move.l d0,-(a7) ;size
+ bsr.l get_fline ;returns fline word in d0
+ move.l d0,d1
+ andi.l #$7,d1 ;d1 now holds register number
+ move.l (sp)+,d0 ;get original size
+ cmpi.l #4,d0
+ beq.b wrt_long
+ cmpi.l #2,d0
+ bne.b wrt_byte
+wrt_word:
+ or.l #$8,d1
+ bra.l reg_dest
+wrt_long:
+ or.l #$10,d1
+ bra.l reg_dest
+wrt_byte:
+ bra.l reg_dest
+*
+* Check if it is a src nan or dst nan
+*
+not_out:
+ move.l DTAG(a6),d0
+ bfextu d0{0:3},d0 ;isolate dtag in lsbs
+
+ cmpi.b #3,d0 ;check for nan in destination
+ bne.b issrc ;destination nan has priority
+dst_nan:
+ btst.b #6,FPTEMP_HI(a6) ;check if dest nan is an snan
+ bne.b issrc ;no, so check source for snan
+ move.w FPTEMP_EX(a6),d0
+ bra.b cont
+issrc:
+ move.w ETEMP_EX(a6),d0
+cont:
+ btst.l #15,d0 ;test for sign of snan
+ beq.b clr_neg
+ bset.b #neg_bit,FPSR_CC(a6)
+ bra.w report_snan
+clr_neg:
+ bclr.b #neg_bit,FPSR_CC(a6)
+ bra.w report_snan
+
+ end