Commit | Line | Data |
---|---|---|
1da177e4 LT |
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 | | | |
e00d82d0 MW |
25 | | For details on the license for this file, please see the |
26 | | file, README, in this same directory. | |
1da177e4 LT |
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 |