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