1| 2| x_snan.sa 3.3 7/1/91 3| 4| fpsp_snan --- FPSP handler for signalling NAN exception 5| 6| SNAN for float -> integer conversions (integer conversion of 7| an SNAN) is a non-maskable run-time exception. 8| 9| For trap disabled the 040 does the following: 10| If the dest data format is s, d, or x, then the SNAN bit in the NAN 11| is set to one and the resulting non-signaling NAN (truncated if 12| necessary) is transferred to the dest. If the dest format is b, w, 13| or l, then garbage is written to the dest (actually the upper 32 bits 14| of the mantissa are sent to the integer unit). 15| 16| For trap enabled the 040 does the following: 17| If the inst is move_out, then the results are the same as for trap 18| disabled with the exception posted. If the instruction is not move_ 19| out, the dest. is not modified, and the exception is posted. 20| 21 22| Copyright (C) Motorola, Inc. 1990 23| All Rights Reserved 24| 25| THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA 26| The copyright notice above does not evidence any 27| actual or intended publication of such source code. 28 29X_SNAN: |idnt 2,1 | Motorola 040 Floating Point Software Package 30 31 |section 8 32 33 .include "fpsp.h" 34 35 |xref get_fline 36 |xref mem_write 37 |xref real_snan 38 |xref real_inex 39 |xref fpsp_done 40 |xref reg_dest 41 42 .global fpsp_snan 43fpsp_snan: 44 link %a6,#-LOCAL_SIZE 45 fsave -(%a7) 46 moveml %d0-%d1/%a0-%a1,USER_DA(%a6) 47 fmovemx %fp0-%fp3,USER_FP0(%a6) 48 fmoveml %fpcr/%fpsr/%fpiar,USER_FPCR(%a6) 49 50| 51| Check if trap enabled 52| 53 btstb #snan_bit,FPCR_ENABLE(%a6) 54 bnes ena |If enabled, then branch 55 56 bsrl move_out |else SNAN disabled 57| 58| It is possible to have an inex1 exception with the 59| snan. If the inex enable bit is set in the FPCR, and either 60| inex2 or inex1 occurred, we must clean up and branch to the 61| real inex handler. 62| 63ck_inex: 64 moveb FPCR_ENABLE(%a6),%d0 65 andb FPSR_EXCEPT(%a6),%d0 66 andib #0x3,%d0 67 beq end_snan 68| 69| Inexact enabled and reported, and we must take an inexact exception. 70| 71take_inex: 72 moveb #INEX_VEC,EXC_VEC+1(%a6) 73 moveml USER_DA(%a6),%d0-%d1/%a0-%a1 74 fmovemx USER_FP0(%a6),%fp0-%fp3 75 fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar 76 frestore (%a7)+ 77 unlk %a6 78 bral real_inex 79| 80| SNAN is enabled. Check if inst is move_out. 81| Make any corrections to the 040 output as necessary. 82| 83ena: 84 btstb #5,CMDREG1B(%a6) |if set, inst is move out 85 beq not_out 86 87 bsrl move_out 88 89report_snan: 90 moveb (%a7),VER_TMP(%a6) 91 cmpib #VER_40,(%a7) |test for orig unimp frame 92 bnes ck_rev 93 moveql #13,%d0 |need to zero 14 lwords 94 bras rep_con 95ck_rev: 96 moveql #11,%d0 |need to zero 12 lwords 97rep_con: 98 clrl (%a7) 99loop1: 100 clrl -(%a7) |clear and dec a7 101 dbra %d0,loop1 102 moveb VER_TMP(%a6),(%a7) |format a busy frame 103 moveb #BUSY_SIZE-4,1(%a7) 104 movel USER_FPSR(%a6),FPSR_SHADOW(%a6) 105 orl #sx_mask,E_BYTE(%a6) 106 moveml USER_DA(%a6),%d0-%d1/%a0-%a1 107 fmovemx USER_FP0(%a6),%fp0-%fp3 108 fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar 109 frestore (%a7)+ 110 unlk %a6 111 bral real_snan 112| 113| Exit snan handler by expanding the unimp frame into a busy frame 114| 115end_snan: 116 bclrb #E1,E_BYTE(%a6) 117 118 moveb (%a7),VER_TMP(%a6) 119 cmpib #VER_40,(%a7) |test for orig unimp frame 120 bnes ck_rev2 121 moveql #13,%d0 |need to zero 14 lwords 122 bras rep_con2 123ck_rev2: 124 moveql #11,%d0 |need to zero 12 lwords 125rep_con2: 126 clrl (%a7) 127loop2: 128 clrl -(%a7) |clear and dec a7 129 dbra %d0,loop2 130 moveb VER_TMP(%a6),(%a7) |format a busy frame 131 moveb #BUSY_SIZE-4,1(%a7) |write busy size 132 movel USER_FPSR(%a6),FPSR_SHADOW(%a6) 133 orl #sx_mask,E_BYTE(%a6) 134 moveml USER_DA(%a6),%d0-%d1/%a0-%a1 135 fmovemx USER_FP0(%a6),%fp0-%fp3 136 fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar 137 frestore (%a7)+ 138 unlk %a6 139 bral fpsp_done 140 141| 142| Move_out 143| 144move_out: 145 movel EXC_EA(%a6),%a0 |get <ea> from exc frame 146 147 bfextu CMDREG1B(%a6){#3:#3},%d0 |move rx field to d0{2:0} 148 cmpil #0,%d0 |check for long 149 beqs sto_long |branch if move_out long 150 151 cmpil #4,%d0 |check for word 152 beqs sto_word |branch if move_out word 153 154 cmpil #6,%d0 |check for byte 155 beqs sto_byte |branch if move_out byte 156 157| 158| Not byte, word or long 159| 160 rts 161| 162| Get the 32 most significant bits of etemp mantissa 163| 164sto_long: 165 movel ETEMP_HI(%a6),%d1 166 movel #4,%d0 |load byte count 167| 168| Set signalling nan bit 169| 170 bsetl #30,%d1 171| 172| Store to the users destination address 173| 174 tstl %a0 |check if <ea> is 0 175 beqs wrt_dn |destination is a data register 176 177 movel %d1,-(%a7) |move the snan onto the stack 178 movel %a0,%a1 |load dest addr into a1 179 movel %a7,%a0 |load src addr of snan into a0 180 bsrl mem_write |write snan to user memory 181 movel (%a7)+,%d1 |clear off stack 182 rts 183| 184| Get the 16 most significant bits of etemp mantissa 185| 186sto_word: 187 movel ETEMP_HI(%a6),%d1 188 movel #2,%d0 |load byte count 189| 190| Set signalling nan bit 191| 192 bsetl #30,%d1 193| 194| Store to the users destination address 195| 196 tstl %a0 |check if <ea> is 0 197 beqs wrt_dn |destination is a data register 198 199 movel %d1,-(%a7) |move the snan onto the stack 200 movel %a0,%a1 |load dest addr into a1 201 movel %a7,%a0 |point to low word 202 bsrl mem_write |write snan to user memory 203 movel (%a7)+,%d1 |clear off stack 204 rts 205| 206| Get the 8 most significant bits of etemp mantissa 207| 208sto_byte: 209 movel ETEMP_HI(%a6),%d1 210 movel #1,%d0 |load byte count 211| 212| Set signalling nan bit 213| 214 bsetl #30,%d1 215| 216| Store to the users destination address 217| 218 tstl %a0 |check if <ea> is 0 219 beqs wrt_dn |destination is a data register 220 movel %d1,-(%a7) |move the snan onto the stack 221 movel %a0,%a1 |load dest addr into a1 222 movel %a7,%a0 |point to source byte 223 bsrl mem_write |write snan to user memory 224 movel (%a7)+,%d1 |clear off stack 225 rts 226 227| 228| wrt_dn --- write to a data register 229| 230| We get here with D1 containing the data to write and D0 the 231| number of bytes to write: 1=byte,2=word,4=long. 232| 233wrt_dn: 234 movel %d1,L_SCR1(%a6) |data 235 movel %d0,-(%a7) |size 236 bsrl get_fline |returns fline word in d0 237 movel %d0,%d1 238 andil #0x7,%d1 |d1 now holds register number 239 movel (%sp)+,%d0 |get original size 240 cmpil #4,%d0 241 beqs wrt_long 242 cmpil #2,%d0 243 bnes wrt_byte 244wrt_word: 245 orl #0x8,%d1 246 bral reg_dest 247wrt_long: 248 orl #0x10,%d1 249 bral reg_dest 250wrt_byte: 251 bral reg_dest 252| 253| Check if it is a src nan or dst nan 254| 255not_out: 256 movel DTAG(%a6),%d0 257 bfextu %d0{#0:#3},%d0 |isolate dtag in lsbs 258 259 cmpib #3,%d0 |check for nan in destination 260 bnes issrc |destination nan has priority 261dst_nan: 262 btstb #6,FPTEMP_HI(%a6) |check if dest nan is an snan 263 bnes issrc |no, so check source for snan 264 movew FPTEMP_EX(%a6),%d0 265 bras cont 266issrc: 267 movew ETEMP_EX(%a6),%d0 268cont: 269 btstl #15,%d0 |test for sign of snan 270 beqs clr_neg 271 bsetb #neg_bit,FPSR_CC(%a6) 272 bra report_snan 273clr_neg: 274 bclrb #neg_bit,FPSR_CC(%a6) 275 bra report_snan 276 277 |end 278