1* $NetBSD: x_snan.sa,v 1.4 2001/09/16 16:34:32 wiz Exp $ 2 3* MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP 4* M68000 Hi-Performance Microprocessor Division 5* M68040 Software Package 6* 7* M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc. 8* All rights reserved. 9* 10* THE SOFTWARE is provided on an "AS IS" basis and without warranty. 11* To the maximum extent permitted by applicable law, 12* MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, 13* INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A 14* PARTICULAR PURPOSE and any warranty against infringement with 15* regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF) 16* and any accompanying written materials. 17* 18* To the maximum extent permitted by applicable law, 19* IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER 20* (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS 21* PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR 22* OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE 23* SOFTWARE. Motorola assumes no responsibility for the maintenance 24* and support of the SOFTWARE. 25* 26* You are hereby granted a copyright license to use, modify, and 27* distribute the SOFTWARE so long as this entire notice is retained 28* without alteration in any modified and/or redistributed versions, 29* and that such modified versions are clearly identified as such. 30* No licenses are granted by implication, estoppel or otherwise 31* under any patents or trademarks of Motorola, Inc. 32 33* 34* x_snan.sa 3.3 7/1/91 35* 36* fpsp_snan --- FPSP handler for signalling NAN exception 37* 38* SNAN for float -> integer conversions (integer conversion of 39* an SNAN) is a non-maskable run-time exception. 40* 41* For trap disabled the 040 does the following: 42* If the dest data format is s, d, or x, then the SNAN bit in the NAN 43* is set to one and the resulting non-signaling NAN (truncated if 44* necessary) is transferred to the dest. If the dest format is b, w, 45* or l, then garbage is written to the dest (actually the upper 32 bits 46* of the mantissa are sent to the integer unit). 47* 48* For trap enabled the 040 does the following: 49* If the inst is move_out, then the results are the same as for trap 50* disabled with the exception posted. If the instruction is not move_ 51* out, the dest. is not modified, and the exception is posted. 52* 53 54X_SNAN IDNT 2,1 Motorola 040 Floating Point Software Package 55 56 section 8 57 58 include fpsp.h 59 60 xref get_fline 61 xref mem_write 62 xref real_snan 63 xref real_inex 64 xref fpsp_done 65 xref reg_dest 66 67 xdef fpsp_snan 68fpsp_snan: 69 link a6,#-LOCAL_SIZE 70 fsave -(a7) 71 movem.l d0-d1/a0-a1,USER_DA(a6) 72 fmovem.x fp0-fp3,USER_FP0(a6) 73 fmovem.l fpcr/fpsr/fpiar,USER_FPCR(a6) 74 75* 76* Check if trap enabled 77* 78 btst.b #snan_bit,FPCR_ENABLE(a6) 79 bne.b ena ;If enabled, then branch 80 81 bsr.l move_out ;else SNAN disabled 82* 83* It is possible to have an inex1 exception with the 84* snan. If the inex enable bit is set in the FPCR, and either 85* inex2 or inex1 occurred, we must clean up and branch to the 86* real inex handler. 87* 88ck_inex: 89 move.b FPCR_ENABLE(a6),d0 90 and.b FPSR_EXCEPT(a6),d0 91 andi.b #$3,d0 92 beq.w end_snan 93* 94* Inexact enabled and reported, and we must take an inexact exception. 95* 96take_inex: 97 move.b #INEX_VEC,EXC_VEC+1(a6) 98 movem.l USER_DA(a6),d0-d1/a0-a1 99 fmovem.x USER_FP0(a6),fp0-fp3 100 fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar 101 frestore (a7)+ 102 unlk a6 103 bra.l real_inex 104* 105* SNAN is enabled. Check if inst is move_out. 106* Make any corrections to the 040 output as necessary. 107* 108ena: 109 btst.b #5,CMDREG1B(a6) ;if set, inst is move out 110 beq.w not_out 111 112 bsr.l move_out 113 114report_snan: 115 move.b (a7),VER_TMP(a6) 116 cmpi.b #VER_40,(a7) ;test for orig unimp frame 117 bne.b ck_rev 118 moveq.l #13,d0 ;need to zero 14 lwords 119 bra.b rep_con 120ck_rev: 121 moveq.l #11,d0 ;need to zero 12 lwords 122rep_con: 123 clr.l (a7) 124loop1: 125 clr.l -(a7) ;clear and dec a7 126 dbra.w d0,loop1 127 move.b VER_TMP(a6),(a7) ;format a busy frame 128 move.b #BUSY_SIZE-4,1(a7) 129 move.l USER_FPSR(a6),FPSR_SHADOW(a6) 130 or.l #sx_mask,E_BYTE(a6) 131 movem.l USER_DA(a6),d0-d1/a0-a1 132 fmovem.x USER_FP0(a6),fp0-fp3 133 fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar 134 frestore (a7)+ 135 unlk a6 136 bra.l real_snan 137* 138* Exit snan handler by expanding the unimp frame into a busy frame 139* 140end_snan: 141 bclr.b #E1,E_BYTE(a6) 142 143 move.b (a7),VER_TMP(a6) 144 cmpi.b #VER_40,(a7) ;test for orig unimp frame 145 bne.b ck_rev2 146 moveq.l #13,d0 ;need to zero 14 lwords 147 bra.b rep_con2 148ck_rev2: 149 moveq.l #11,d0 ;need to zero 12 lwords 150rep_con2: 151 clr.l (a7) 152loop2: 153 clr.l -(a7) ;clear and dec a7 154 dbra.w d0,loop2 155 move.b VER_TMP(a6),(a7) ;format a busy frame 156 move.b #BUSY_SIZE-4,1(a7) ;write busy size 157 move.l USER_FPSR(a6),FPSR_SHADOW(a6) 158 or.l #sx_mask,E_BYTE(a6) 159 movem.l USER_DA(a6),d0-d1/a0-a1 160 fmovem.x USER_FP0(a6),fp0-fp3 161 fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar 162 frestore (a7)+ 163 unlk a6 164 bra.l fpsp_done 165 166* 167* Move_out 168* 169move_out: 170 move.l EXC_EA(a6),a0 ;get <ea> from exc frame 171 172 bfextu CMDREG1B(a6){3:3},d0 ;move rx field to d0{2:0} 173 tst.l d0 ;check for long 174 beq.b sto_long ;branch if move_out long 175 176 cmpi.l #4,d0 ;check for word 177 beq.b sto_word ;branch if move_out word 178 179 cmpi.l #6,d0 ;check for byte 180 beq.b sto_byte ;branch if move_out byte 181 182* 183* Not byte, word or long 184* 185 rts 186* 187* Get the 32 most significant bits of etemp mantissa 188* 189sto_long: 190 move.l ETEMP_HI(a6),d1 191 move.l #4,d0 ;load byte count 192* 193* Set signalling nan bit 194* 195 bset.l #30,d1 196* 197* Store to the users destination address 198* 199 tst.l a0 ;check if <ea> is 0 200 beq.b wrt_dn ;destination is a data register 201 202 move.l d1,-(a7) ;move the snan onto the stack 203 move.l a0,a1 ;load dest addr into a1 204 move.l a7,a0 ;load src addr of snan into a0 205 bsr.l mem_write ;write snan to user memory 206 move.l (a7)+,d1 ;clear off stack 207 rts 208* 209* Get the 16 most significant bits of etemp mantissa 210* 211sto_word: 212 move.l ETEMP_HI(a6),d1 213 move.l #2,d0 ;load byte count 214* 215* Set signalling nan bit 216* 217 bset.l #30,d1 218* 219* Store to the users destination address 220* 221 tst.l a0 ;check if <ea> is 0 222 beq.b wrt_dn ;destination is a data register 223 224 move.l d1,-(a7) ;move the snan onto the stack 225 move.l a0,a1 ;load dest addr into a1 226 move.l a7,a0 ;point to low word 227 bsr.l mem_write ;write snan to user memory 228 move.l (a7)+,d1 ;clear off stack 229 rts 230* 231* Get the 8 most significant bits of etemp mantissa 232* 233sto_byte: 234 move.l ETEMP_HI(a6),d1 235 move.l #1,d0 ;load byte count 236* 237* Set signalling nan bit 238* 239 bset.l #30,d1 240* 241* Store to the users destination address 242* 243 tst.l a0 ;check if <ea> is 0 244 beq.b wrt_dn ;destination is a data register 245 move.l d1,-(a7) ;move the snan onto the stack 246 move.l a0,a1 ;load dest addr into a1 247 move.l a7,a0 ;point to source byte 248 bsr.l mem_write ;write snan to user memory 249 move.l (a7)+,d1 ;clear off stack 250 rts 251 252* 253* wrt_dn --- write to a data register 254* 255* We get here with D1 containing the data to write and D0 the 256* number of bytes to write: 1=byte,2=word,4=long. 257* 258wrt_dn: 259 move.l d1,L_SCR1(a6) ;data 260 move.l d0,-(a7) ;size 261 bsr.l get_fline ;returns fline word in d0 262 move.l d0,d1 263 andi.l #$7,d1 ;d1 now holds register number 264 move.l (sp)+,d0 ;get original size 265 cmpi.l #4,d0 266 beq.b wrt_long 267 cmpi.l #2,d0 268 bne.b wrt_byte 269wrt_word: 270 or.l #$8,d1 271 bra.l reg_dest 272wrt_long: 273 or.l #$10,d1 274 bra.l reg_dest 275wrt_byte: 276 bra.l reg_dest 277* 278* Check if it is a src nan or dst nan 279* 280not_out: 281 move.l DTAG(a6),d0 282 bfextu d0{0:3},d0 ;isolate dtag in lsbs 283 284 cmpi.b #3,d0 ;check for nan in destination 285 bne.b issrc ;destination nan has priority 286dst_nan: 287 btst.b #6,FPTEMP_HI(a6) ;check if dest nan is an snan 288 bne.b issrc ;no, so check source for snan 289 move.w FPTEMP_EX(a6),d0 290 bra.b cont 291issrc: 292 move.w ETEMP_EX(a6),d0 293cont: 294 btst.l #15,d0 ;test for sign of snan 295 beq.b clr_neg 296 bset.b #neg_bit,FPSR_CC(a6) 297 bra.w report_snan 298clr_neg: 299 bclr.b #neg_bit,FPSR_CC(a6) 300 bra.w report_snan 301 302 end 303