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 54 X_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 68 fpsp_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 * 88 ck_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 * 96 take_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 * 108 ena: 109 btst.b #5,CMDREG1B(a6) ;if set, inst is move out 110 beq.w not_out 111 112 bsr.l move_out 113 114 report_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 120 ck_rev: 121 moveq.l #11,d0 ;need to zero 12 lwords 122 rep_con: 123 clr.l (a7) 124 loop1: 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 * 140 end_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 148 ck_rev2: 149 moveq.l #11,d0 ;need to zero 12 lwords 150 rep_con2: 151 clr.l (a7) 152 loop2: 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 * 169 move_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 * 189 sto_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 * 211 sto_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 * 233 sto_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 * 258 wrt_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 269 wrt_word: 270 or.l #$8,d1 271 bra.l reg_dest 272 wrt_long: 273 or.l #$10,d1 274 bra.l reg_dest 275 wrt_byte: 276 bra.l reg_dest 277 * 278 * Check if it is a src nan or dst nan 279 * 280 not_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 286 dst_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 291 issrc: 292 move.w ETEMP_EX(a6),d0 293 cont: 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 298 clr_neg: 299 bclr.b #neg_bit,FPSR_CC(a6) 300 bra.w report_snan 301 302 end 303