1 | // |
---|
2 | // $Id$ |
---|
3 | // |
---|
4 | // get_op.sa 3.6 5/19/92 |
---|
5 | // |
---|
6 | // get_op.sa 3.5 4/26/91 |
---|
7 | // |
---|
8 | // Description: This routine is called by the unsupported format/data |
---|
9 | // type exception handler ('unsupp' - vector 55) and the unimplemented |
---|
10 | // instruction exception handler ('unimp' - vector 11). 'get_op' |
---|
11 | // determines the opclass (0, 2, or 3) and branches to the |
---|
12 | // opclass handler routine. See 68881/2 User's Manual table 4-11 |
---|
13 | // for a description of the opclasses. |
---|
14 | // |
---|
15 | // For UNSUPPORTED data/format (exception vector 55) and for |
---|
16 | // UNIMPLEMENTED instructions (exception vector 11) the following |
---|
17 | // applies: |
---|
18 | // |
---|
19 | // - For unnormalized numbers (opclass 0, 2, or 3) the |
---|
20 | // number(s) is normalized and the operand type tag is updated. |
---|
21 | // |
---|
22 | // - For a packed number (opclass 2) the number is unpacked and the |
---|
23 | // operand type tag is updated. |
---|
24 | // |
---|
25 | // - For denormalized numbers (opclass 0 or 2) the number(s) is not |
---|
26 | // changed but passed to the next module. The next module for |
---|
27 | // unimp is do_func, the next module for unsupp is res_func. |
---|
28 | // |
---|
29 | // For UNSUPPORTED data/format (exception vector 55) only the |
---|
30 | // following applies: |
---|
31 | // |
---|
32 | // - If there is a move out with a packed number (opclass 3) the |
---|
33 | // number is packed and written to user memory. For the other |
---|
34 | // opclasses the number(s) are written back to the fsave stack |
---|
35 | // and the instruction is then restored back into the '040. The |
---|
36 | // '040 is then able to complete the instruction. |
---|
37 | // |
---|
38 | // For example: |
---|
39 | // fadd.x fpm,fpn where the fpm contains an unnormalized number. |
---|
40 | // The '040 takes an unsupported data trap and gets to this |
---|
41 | // routine. The number is normalized, put back on the stack and |
---|
42 | // then an frestore is done to restore the instruction back into |
---|
43 | // the '040. The '040 then re-executes the fadd.x fpm,fpn with |
---|
44 | // a normalized number in the source and the instruction is |
---|
45 | // successful. |
---|
46 | // |
---|
47 | // Next consider if in the process of normalizing the un- |
---|
48 | // normalized number it becomes a denormalized number. The |
---|
49 | // routine which converts the unnorm to a norm (called mk_norm) |
---|
50 | // detects this and tags the number as a denorm. The routine |
---|
51 | // res_func sees the denorm tag and converts the denorm to a |
---|
52 | // norm. The instruction is then restored back into the '040 |
---|
53 | // which re_executes the instruction. |
---|
54 | // |
---|
55 | // |
---|
56 | // Copyright (C) Motorola, Inc. 1990 |
---|
57 | // All Rights Reserved |
---|
58 | // |
---|
59 | // THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA |
---|
60 | // The copyright notice above does not evidence any |
---|
61 | // actual or intended publication of such source code. |
---|
62 | |
---|
63 | GET_OP: //idnt 2,1 | Motorola 040 Floating Point Software Package |
---|
64 | |
---|
65 | |section 8 |
---|
66 | |
---|
67 | #include "fpsp.defs" |
---|
68 | |
---|
69 | .global PIRN,PIRZRM,PIRP |
---|
70 | .global SMALRN,SMALRZRM,SMALRP |
---|
71 | .global BIGRN,BIGRZRM,BIGRP |
---|
72 | |
---|
73 | PIRN: |
---|
74 | .long 0x40000000,0xc90fdaa2,0x2168c235 //pi |
---|
75 | PIRZRM: |
---|
76 | .long 0x40000000,0xc90fdaa2,0x2168c234 //pi |
---|
77 | PIRP: |
---|
78 | .long 0x40000000,0xc90fdaa2,0x2168c235 //pi |
---|
79 | |
---|
80 | //round to nearest |
---|
81 | SMALRN: |
---|
82 | .long 0x3ffd0000,0x9a209a84,0xfbcff798 //log10(2) |
---|
83 | .long 0x40000000,0xadf85458,0xa2bb4a9a //e |
---|
84 | .long 0x3fff0000,0xb8aa3b29,0x5c17f0bc //log2(e) |
---|
85 | .long 0x3ffd0000,0xde5bd8a9,0x37287195 //log10(e) |
---|
86 | .long 0x00000000,0x00000000,0x00000000 //0.0 |
---|
87 | // round to zero;round to negative infinity |
---|
88 | SMALRZRM: |
---|
89 | .long 0x3ffd0000,0x9a209a84,0xfbcff798 //log10(2) |
---|
90 | .long 0x40000000,0xadf85458,0xa2bb4a9a //e |
---|
91 | .long 0x3fff0000,0xb8aa3b29,0x5c17f0bb //log2(e) |
---|
92 | .long 0x3ffd0000,0xde5bd8a9,0x37287195 //log10(e) |
---|
93 | .long 0x00000000,0x00000000,0x00000000 //0.0 |
---|
94 | // round to positive infinity |
---|
95 | SMALRP: |
---|
96 | .long 0x3ffd0000,0x9a209a84,0xfbcff799 //log10(2) |
---|
97 | .long 0x40000000,0xadf85458,0xa2bb4a9b //e |
---|
98 | .long 0x3fff0000,0xb8aa3b29,0x5c17f0bc //log2(e) |
---|
99 | .long 0x3ffd0000,0xde5bd8a9,0x37287195 //log10(e) |
---|
100 | .long 0x00000000,0x00000000,0x00000000 //0.0 |
---|
101 | |
---|
102 | //round to nearest |
---|
103 | BIGRN: |
---|
104 | .long 0x3ffe0000,0xb17217f7,0xd1cf79ac //ln(2) |
---|
105 | .long 0x40000000,0x935d8ddd,0xaaa8ac17 //ln(10) |
---|
106 | .long 0x3fff0000,0x80000000,0x00000000 //10 ^ 0 |
---|
107 | |
---|
108 | .global PTENRN |
---|
109 | PTENRN: |
---|
110 | .long 0x40020000,0xA0000000,0x00000000 //10 ^ 1 |
---|
111 | .long 0x40050000,0xC8000000,0x00000000 //10 ^ 2 |
---|
112 | .long 0x400C0000,0x9C400000,0x00000000 //10 ^ 4 |
---|
113 | .long 0x40190000,0xBEBC2000,0x00000000 //10 ^ 8 |
---|
114 | .long 0x40340000,0x8E1BC9BF,0x04000000 //10 ^ 16 |
---|
115 | .long 0x40690000,0x9DC5ADA8,0x2B70B59E //10 ^ 32 |
---|
116 | .long 0x40D30000,0xC2781F49,0xFFCFA6D5 //10 ^ 64 |
---|
117 | .long 0x41A80000,0x93BA47C9,0x80E98CE0 //10 ^ 128 |
---|
118 | .long 0x43510000,0xAA7EEBFB,0x9DF9DE8E //10 ^ 256 |
---|
119 | .long 0x46A30000,0xE319A0AE,0xA60E91C7 //10 ^ 512 |
---|
120 | .long 0x4D480000,0xC9767586,0x81750C17 //10 ^ 1024 |
---|
121 | .long 0x5A920000,0x9E8B3B5D,0xC53D5DE5 //10 ^ 2048 |
---|
122 | .long 0x75250000,0xC4605202,0x8A20979B //10 ^ 4096 |
---|
123 | //round to minus infinity |
---|
124 | BIGRZRM: |
---|
125 | .long 0x3ffe0000,0xb17217f7,0xd1cf79ab //ln(2) |
---|
126 | .long 0x40000000,0x935d8ddd,0xaaa8ac16 //ln(10) |
---|
127 | .long 0x3fff0000,0x80000000,0x00000000 //10 ^ 0 |
---|
128 | |
---|
129 | .global PTENRM |
---|
130 | PTENRM: |
---|
131 | .long 0x40020000,0xA0000000,0x00000000 //10 ^ 1 |
---|
132 | .long 0x40050000,0xC8000000,0x00000000 //10 ^ 2 |
---|
133 | .long 0x400C0000,0x9C400000,0x00000000 //10 ^ 4 |
---|
134 | .long 0x40190000,0xBEBC2000,0x00000000 //10 ^ 8 |
---|
135 | .long 0x40340000,0x8E1BC9BF,0x04000000 //10 ^ 16 |
---|
136 | .long 0x40690000,0x9DC5ADA8,0x2B70B59D //10 ^ 32 |
---|
137 | .long 0x40D30000,0xC2781F49,0xFFCFA6D5 //10 ^ 64 |
---|
138 | .long 0x41A80000,0x93BA47C9,0x80E98CDF //10 ^ 128 |
---|
139 | .long 0x43510000,0xAA7EEBFB,0x9DF9DE8D //10 ^ 256 |
---|
140 | .long 0x46A30000,0xE319A0AE,0xA60E91C6 //10 ^ 512 |
---|
141 | .long 0x4D480000,0xC9767586,0x81750C17 //10 ^ 1024 |
---|
142 | .long 0x5A920000,0x9E8B3B5D,0xC53D5DE5 //10 ^ 2048 |
---|
143 | .long 0x75250000,0xC4605202,0x8A20979A //10 ^ 4096 |
---|
144 | //round to positive infinity |
---|
145 | BIGRP: |
---|
146 | .long 0x3ffe0000,0xb17217f7,0xd1cf79ac //ln(2) |
---|
147 | .long 0x40000000,0x935d8ddd,0xaaa8ac17 //ln(10) |
---|
148 | .long 0x3fff0000,0x80000000,0x00000000 //10 ^ 0 |
---|
149 | |
---|
150 | .global PTENRP |
---|
151 | PTENRP: |
---|
152 | .long 0x40020000,0xA0000000,0x00000000 //10 ^ 1 |
---|
153 | .long 0x40050000,0xC8000000,0x00000000 //10 ^ 2 |
---|
154 | .long 0x400C0000,0x9C400000,0x00000000 //10 ^ 4 |
---|
155 | .long 0x40190000,0xBEBC2000,0x00000000 //10 ^ 8 |
---|
156 | .long 0x40340000,0x8E1BC9BF,0x04000000 //10 ^ 16 |
---|
157 | .long 0x40690000,0x9DC5ADA8,0x2B70B59E //10 ^ 32 |
---|
158 | .long 0x40D30000,0xC2781F49,0xFFCFA6D6 //10 ^ 64 |
---|
159 | .long 0x41A80000,0x93BA47C9,0x80E98CE0 //10 ^ 128 |
---|
160 | .long 0x43510000,0xAA7EEBFB,0x9DF9DE8E //10 ^ 256 |
---|
161 | .long 0x46A30000,0xE319A0AE,0xA60E91C7 //10 ^ 512 |
---|
162 | .long 0x4D480000,0xC9767586,0x81750C18 //10 ^ 1024 |
---|
163 | .long 0x5A920000,0x9E8B3B5D,0xC53D5DE6 //10 ^ 2048 |
---|
164 | .long 0x75250000,0xC4605202,0x8A20979B //10 ^ 4096 |
---|
165 | |
---|
166 | |xref nrm_zero |
---|
167 | |xref decbin |
---|
168 | |xref round |
---|
169 | |
---|
170 | .global get_op |
---|
171 | .global uns_getop |
---|
172 | .global uni_getop |
---|
173 | get_op: |
---|
174 | clrb DY_MO_FLG(%a6) |
---|
175 | tstb UFLG_TMP(%a6) //test flag for unsupp/unimp state |
---|
176 | beq uni_getop |
---|
177 | |
---|
178 | uns_getop: |
---|
179 | btstb #direction_bit,CMDREG1B(%a6) |
---|
180 | bne opclass3 //branch if a fmove out (any kind) |
---|
181 | btstb #6,CMDREG1B(%a6) |
---|
182 | beqs uns_notpacked |
---|
183 | |
---|
184 | bfextu CMDREG1B(%a6){#3:#3},%d0 |
---|
185 | cmpb #3,%d0 |
---|
186 | beq pack_source //check for a packed src op, branch if so |
---|
187 | uns_notpacked: |
---|
188 | bsr chk_dy_mo //set the dyadic/monadic flag |
---|
189 | tstb DY_MO_FLG(%a6) |
---|
190 | beqs src_op_ck //if monadic, go check src op |
---|
191 | // ;else, check dst op (fall through) |
---|
192 | |
---|
193 | btstb #7,DTAG(%a6) |
---|
194 | beqs src_op_ck //if dst op is norm, check src op |
---|
195 | bras dst_ex_dnrm //else, handle destination unnorm/dnrm |
---|
196 | |
---|
197 | uni_getop: |
---|
198 | bfextu CMDREG1B(%a6){#0:#6},%d0 //get opclass and src fields |
---|
199 | cmpil #0x17,%d0 //if op class and size fields are $17, |
---|
200 | // ;it is FMOVECR; if not, continue |
---|
201 | // |
---|
202 | // If the instruction is fmovecr, exit get_op. It is handled |
---|
203 | // in do_func and smovecr.sa. |
---|
204 | // |
---|
205 | bne not_fmovecr //handle fmovecr as an unimplemented inst |
---|
206 | rts |
---|
207 | |
---|
208 | not_fmovecr: |
---|
209 | btstb #E1,E_BYTE(%a6) //if set, there is a packed operand |
---|
210 | bne pack_source //check for packed src op, branch if so |
---|
211 | |
---|
212 | // The following lines of are coded to optimize on normalized operands |
---|
213 | moveb STAG(%a6),%d0 |
---|
214 | orb DTAG(%a6),%d0 //check if either of STAG/DTAG msb set |
---|
215 | bmis dest_op_ck //if so, some op needs to be fixed |
---|
216 | rts |
---|
217 | |
---|
218 | dest_op_ck: |
---|
219 | btstb #7,DTAG(%a6) //check for unsupported data types in |
---|
220 | beqs src_op_ck //the destination, if not, check src op |
---|
221 | bsr chk_dy_mo //set dyadic/monadic flag |
---|
222 | tstb DY_MO_FLG(%a6) // |
---|
223 | beqs src_op_ck //if monadic, check src op |
---|
224 | // |
---|
225 | // At this point, destination has an extended denorm or unnorm. |
---|
226 | // |
---|
227 | dst_ex_dnrm: |
---|
228 | movew FPTEMP_EX(%a6),%d0 //get destination exponent |
---|
229 | andiw #0x7fff,%d0 //mask sign, check if exp = 0000 |
---|
230 | beqs src_op_ck //if denorm then check source op. |
---|
231 | // ;denorms are taken care of in res_func |
---|
232 | // ;(unsupp) or do_func (unimp) |
---|
233 | // ;else unnorm fall through |
---|
234 | leal FPTEMP(%a6),%a0 //point a0 to dop - used in mk_norm |
---|
235 | bsr mk_norm //go normalize - mk_norm returns: |
---|
236 | // ;L_SCR1{7:5} = operand tag |
---|
237 | // ; (000 = norm, 100 = denorm) |
---|
238 | // ;L_SCR1{4} = fpte15 or ete15 |
---|
239 | // ; 0 = exp > $3fff |
---|
240 | // ; 1 = exp <= $3fff |
---|
241 | // ;and puts the normalized num back |
---|
242 | // ;on the fsave stack |
---|
243 | // |
---|
244 | moveb L_SCR1(%a6),DTAG(%a6) //write the new tag & fpte15 |
---|
245 | // ;to the fsave stack and fall |
---|
246 | // ;through to check source operand |
---|
247 | // |
---|
248 | src_op_ck: |
---|
249 | btstb #7,STAG(%a6) |
---|
250 | beq end_getop //check for unsupported data types on the |
---|
251 | // ;source operand |
---|
252 | btstb #5,STAG(%a6) |
---|
253 | bnes src_sd_dnrm //if bit 5 set, handle sgl/dbl denorms |
---|
254 | // |
---|
255 | // At this point only unnorms or extended denorms are possible. |
---|
256 | // |
---|
257 | src_ex_dnrm: |
---|
258 | movew ETEMP_EX(%a6),%d0 //get source exponent |
---|
259 | andiw #0x7fff,%d0 //mask sign, check if exp = 0000 |
---|
260 | beq end_getop //if denorm then exit, denorms are |
---|
261 | // ;handled in do_func |
---|
262 | leal ETEMP(%a6),%a0 //point a0 to sop - used in mk_norm |
---|
263 | bsr mk_norm //go normalize - mk_norm returns: |
---|
264 | // ;L_SCR1{7:5} = operand tag |
---|
265 | // ; (000 = norm, 100 = denorm) |
---|
266 | // ;L_SCR1{4} = fpte15 or ete15 |
---|
267 | // ; 0 = exp > $3fff |
---|
268 | // ; 1 = exp <= $3fff |
---|
269 | // ;and puts the normalized num back |
---|
270 | // ;on the fsave stack |
---|
271 | // |
---|
272 | moveb L_SCR1(%a6),STAG(%a6) //write the new tag & ete15 |
---|
273 | rts //end_getop |
---|
274 | |
---|
275 | // |
---|
276 | // At this point, only single or double denorms are possible. |
---|
277 | // If the inst is not fmove, normalize the source. If it is, |
---|
278 | // do nothing to the input. |
---|
279 | // |
---|
280 | src_sd_dnrm: |
---|
281 | btstb #4,CMDREG1B(%a6) //differentiate between sgl/dbl denorm |
---|
282 | bnes is_double |
---|
283 | is_single: |
---|
284 | movew #0x3f81,%d1 //write bias for sgl denorm |
---|
285 | bras common //goto the common code |
---|
286 | is_double: |
---|
287 | movew #0x3c01,%d1 //write the bias for a dbl denorm |
---|
288 | common: |
---|
289 | btstb #sign_bit,ETEMP_EX(%a6) //grab sign bit of mantissa |
---|
290 | beqs pos |
---|
291 | bset #15,%d1 //set sign bit because it is negative |
---|
292 | pos: |
---|
293 | movew %d1,ETEMP_EX(%a6) |
---|
294 | // ;put exponent on stack |
---|
295 | |
---|
296 | movew CMDREG1B(%a6),%d1 |
---|
297 | andw #0xe3ff,%d1 //clear out source specifier |
---|
298 | orw #0x0800,%d1 //set source specifier to extended prec |
---|
299 | movew %d1,CMDREG1B(%a6) //write back to the command word in stack |
---|
300 | // ;this is needed to fix unsupp data stack |
---|
301 | leal ETEMP(%a6),%a0 //point a0 to sop |
---|
302 | |
---|
303 | bsr mk_norm //convert sgl/dbl denorm to norm |
---|
304 | moveb L_SCR1(%a6),STAG(%a6) //put tag into source tag reg - d0 |
---|
305 | rts //end_getop |
---|
306 | // |
---|
307 | // At this point, the source is definitely packed, whether |
---|
308 | // instruction is dyadic or monadic is still unknown |
---|
309 | // |
---|
310 | pack_source: |
---|
311 | movel FPTEMP_LO(%a6),ETEMP(%a6) //write ms part of packed |
---|
312 | // ;number to etemp slot |
---|
313 | bsr chk_dy_mo //set dyadic/monadic flag |
---|
314 | bsr unpack |
---|
315 | |
---|
316 | tstb DY_MO_FLG(%a6) |
---|
317 | beqs end_getop //if monadic, exit |
---|
318 | // ;else, fix FPTEMP |
---|
319 | pack_dya: |
---|
320 | bfextu CMDREG1B(%a6){#6:#3},%d0 //extract dest fp reg |
---|
321 | movel #7,%d1 |
---|
322 | subl %d0,%d1 |
---|
323 | clrl %d0 |
---|
324 | bsetl %d1,%d0 //set up d0 as a dynamic register mask |
---|
325 | fmovemx %d0,FPTEMP(%a6) //write to FPTEMP |
---|
326 | |
---|
327 | btstb #7,DTAG(%a6) //check dest tag for unnorm or denorm |
---|
328 | bne dst_ex_dnrm //else, handle the unnorm or ext denorm |
---|
329 | // |
---|
330 | // Dest is not denormalized. Check for norm, and set fpte15 |
---|
331 | // accordingly. |
---|
332 | // |
---|
333 | moveb DTAG(%a6),%d0 |
---|
334 | andib #0xf0,%d0 //strip to only dtag:fpte15 |
---|
335 | tstb %d0 //check for normalized value |
---|
336 | bnes end_getop //if inf/nan/zero leave get_op |
---|
337 | movew FPTEMP_EX(%a6),%d0 |
---|
338 | andiw #0x7fff,%d0 |
---|
339 | cmpiw #0x3fff,%d0 //check if fpte15 needs setting |
---|
340 | bges end_getop //if >= $3fff, leave fpte15=0 |
---|
341 | orb #0x10,DTAG(%a6) |
---|
342 | bras end_getop |
---|
343 | |
---|
344 | // |
---|
345 | // At this point, it is either an fmoveout packed, unnorm or denorm |
---|
346 | // |
---|
347 | opclass3: |
---|
348 | clrb DY_MO_FLG(%a6) //set dyadic/monadic flag to monadic |
---|
349 | bfextu CMDREG1B(%a6){#4:#2},%d0 |
---|
350 | cmpib #3,%d0 |
---|
351 | bne src_ex_dnrm //if not equal, must be unnorm or denorm |
---|
352 | // ;else it is a packed move out |
---|
353 | // ;exit |
---|
354 | end_getop: |
---|
355 | rts |
---|
356 | |
---|
357 | // |
---|
358 | // Sets the DY_MO_FLG correctly. This is used only on if it is an |
---|
359 | // unsupported data type exception. Set if dyadic. |
---|
360 | // |
---|
361 | chk_dy_mo: |
---|
362 | movew CMDREG1B(%a6),%d0 |
---|
363 | btstl #5,%d0 //testing extension command word |
---|
364 | beqs set_mon //if bit 5 = 0 then monadic |
---|
365 | btstl #4,%d0 //know that bit 5 = 1 |
---|
366 | beqs set_dya //if bit 4 = 0 then dyadic |
---|
367 | andiw #0x007f,%d0 //get rid of all but extension bits {6:0} |
---|
368 | cmpiw #0x0038,%d0 //if extension = $38 then fcmp (dyadic) |
---|
369 | bnes set_mon |
---|
370 | set_dya: |
---|
371 | st DY_MO_FLG(%a6) //set the inst flag type to dyadic |
---|
372 | rts |
---|
373 | set_mon: |
---|
374 | clrb DY_MO_FLG(%a6) //set the inst flag type to monadic |
---|
375 | rts |
---|
376 | // |
---|
377 | // MK_NORM |
---|
378 | // |
---|
379 | // Normalizes unnormalized numbers, sets tag to norm or denorm, sets unfl |
---|
380 | // exception if denorm. |
---|
381 | // |
---|
382 | // CASE opclass 0x0 unsupp |
---|
383 | // mk_norm till msb set |
---|
384 | // set tag = norm |
---|
385 | // |
---|
386 | // CASE opclass 0x0 unimp |
---|
387 | // mk_norm till msb set or exp = 0 |
---|
388 | // if integer bit = 0 |
---|
389 | // tag = denorm |
---|
390 | // else |
---|
391 | // tag = norm |
---|
392 | // |
---|
393 | // CASE opclass 011 unsupp |
---|
394 | // mk_norm till msb set or exp = 0 |
---|
395 | // if integer bit = 0 |
---|
396 | // tag = denorm |
---|
397 | // set unfl_nmcexe = 1 |
---|
398 | // else |
---|
399 | // tag = norm |
---|
400 | // |
---|
401 | // if exp <= $3fff |
---|
402 | // set ete15 or fpte15 = 1 |
---|
403 | // else set ete15 or fpte15 = 0 |
---|
404 | |
---|
405 | // input: |
---|
406 | // a0 = points to operand to be normalized |
---|
407 | // output: |
---|
408 | // L_SCR1{7:5} = operand tag (000 = norm, 100 = denorm) |
---|
409 | // L_SCR1{4} = fpte15 or ete15 (0 = exp > $3fff, 1 = exp <=$3fff) |
---|
410 | // the normalized operand is placed back on the fsave stack |
---|
411 | mk_norm: |
---|
412 | clrl L_SCR1(%a6) |
---|
413 | bclrb #sign_bit,LOCAL_EX(%a0) |
---|
414 | sne LOCAL_SGN(%a0) //transform into internal extended format |
---|
415 | |
---|
416 | cmpib #0x2c,1+EXC_VEC(%a6) //check if unimp |
---|
417 | bnes uns_data //branch if unsupp |
---|
418 | bsr uni_inst //call if unimp (opclass 0x0) |
---|
419 | bras reload |
---|
420 | uns_data: |
---|
421 | btstb #direction_bit,CMDREG1B(%a6) //check transfer direction |
---|
422 | bnes bit_set //branch if set (opclass 011) |
---|
423 | bsr uns_opx //call if opclass 0x0 |
---|
424 | bras reload |
---|
425 | bit_set: |
---|
426 | bsr uns_op3 //opclass 011 |
---|
427 | reload: |
---|
428 | cmpw #0x3fff,LOCAL_EX(%a0) //if exp > $3fff |
---|
429 | bgts end_mk // fpte15/ete15 already set to 0 |
---|
430 | bsetb #4,L_SCR1(%a6) //else set fpte15/ete15 to 1 |
---|
431 | // ;calling routine actually sets the |
---|
432 | // ;value on the stack (along with the |
---|
433 | // ;tag), since this routine doesn't |
---|
434 | // ;know if it should set ete15 or fpte15 |
---|
435 | // ;ie, it doesn't know if this is the |
---|
436 | // ;src op or dest op. |
---|
437 | end_mk: |
---|
438 | bfclr LOCAL_SGN(%a0){#0:#8} |
---|
439 | beqs end_mk_pos |
---|
440 | bsetb #sign_bit,LOCAL_EX(%a0) //convert back to IEEE format |
---|
441 | end_mk_pos: |
---|
442 | rts |
---|
443 | // |
---|
444 | // CASE opclass 011 unsupp |
---|
445 | // |
---|
446 | uns_op3: |
---|
447 | bsr nrm_zero //normalize till msb = 1 or exp = zero |
---|
448 | btstb #7,LOCAL_HI(%a0) //if msb = 1 |
---|
449 | bnes no_unfl //then branch |
---|
450 | set_unfl: |
---|
451 | orw #dnrm_tag,L_SCR1(%a6) //set denorm tag |
---|
452 | bsetb #unfl_bit,FPSR_EXCEPT(%a6) //set unfl exception bit |
---|
453 | no_unfl: |
---|
454 | rts |
---|
455 | // |
---|
456 | // CASE opclass 0x0 unsupp |
---|
457 | // |
---|
458 | uns_opx: |
---|
459 | bsr nrm_zero //normalize the number |
---|
460 | btstb #7,LOCAL_HI(%a0) //check if integer bit (j-bit) is set |
---|
461 | beqs uns_den //if clear then now have a denorm |
---|
462 | uns_nrm: |
---|
463 | orb #norm_tag,L_SCR1(%a6) //set tag to norm |
---|
464 | rts |
---|
465 | uns_den: |
---|
466 | orb #dnrm_tag,L_SCR1(%a6) //set tag to denorm |
---|
467 | rts |
---|
468 | // |
---|
469 | // CASE opclass 0x0 unimp |
---|
470 | // |
---|
471 | uni_inst: |
---|
472 | bsr nrm_zero |
---|
473 | btstb #7,LOCAL_HI(%a0) //check if integer bit (j-bit) is set |
---|
474 | beqs uni_den //if clear then now have a denorm |
---|
475 | uni_nrm: |
---|
476 | orb #norm_tag,L_SCR1(%a6) //set tag to norm |
---|
477 | rts |
---|
478 | uni_den: |
---|
479 | orb #dnrm_tag,L_SCR1(%a6) //set tag to denorm |
---|
480 | rts |
---|
481 | |
---|
482 | // |
---|
483 | // Decimal to binary conversion |
---|
484 | // |
---|
485 | // Special cases of inf and NaNs are completed outside of decbin. |
---|
486 | // If the input is an snan, the snan bit is not set. |
---|
487 | // |
---|
488 | // input: |
---|
489 | // ETEMP(a6) - points to packed decimal string in memory |
---|
490 | // output: |
---|
491 | // fp0 - contains packed string converted to extended precision |
---|
492 | // ETEMP - same as fp0 |
---|
493 | unpack: |
---|
494 | movew CMDREG1B(%a6),%d0 //examine command word, looking for fmove's |
---|
495 | andw #0x3b,%d0 |
---|
496 | beq move_unpack //special handling for fmove: must set FPSR_CC |
---|
497 | |
---|
498 | movew ETEMP(%a6),%d0 //get word with inf information |
---|
499 | bfextu %d0{#20:#12},%d1 //get exponent into d1 |
---|
500 | cmpiw #0x0fff,%d1 //test for inf or NaN |
---|
501 | bnes try_zero //if not equal, it is not special |
---|
502 | bfextu %d0{#17:#3},%d1 //get SE and y bits into d1 |
---|
503 | cmpiw #7,%d1 //SE and y bits must be on for special |
---|
504 | bnes try_zero //if not on, it is not special |
---|
505 | //input is of the special cases of inf and NaN |
---|
506 | tstl ETEMP_HI(%a6) //check ms mantissa |
---|
507 | bnes fix_nan //if non-zero, it is a NaN |
---|
508 | tstl ETEMP_LO(%a6) //check ls mantissa |
---|
509 | bnes fix_nan //if non-zero, it is a NaN |
---|
510 | bra finish //special already on stack |
---|
511 | fix_nan: |
---|
512 | btstb #signan_bit,ETEMP_HI(%a6) //test for snan |
---|
513 | bne finish |
---|
514 | orl #snaniop_mask,USER_FPSR(%a6) //always set snan if it is so |
---|
515 | bra finish |
---|
516 | try_zero: |
---|
517 | movew ETEMP_EX+2(%a6),%d0 //get word 4 |
---|
518 | andiw #0x000f,%d0 //clear all but last ni(y)bble |
---|
519 | tstw %d0 //check for zero. |
---|
520 | bne not_spec |
---|
521 | tstl ETEMP_HI(%a6) //check words 3 and 2 |
---|
522 | bne not_spec |
---|
523 | tstl ETEMP_LO(%a6) //check words 1 and 0 |
---|
524 | bne not_spec |
---|
525 | tstl ETEMP(%a6) //test sign of the zero |
---|
526 | bges pos_zero |
---|
527 | movel #0x80000000,ETEMP(%a6) //write neg zero to etemp |
---|
528 | clrl ETEMP_HI(%a6) |
---|
529 | clrl ETEMP_LO(%a6) |
---|
530 | bra finish |
---|
531 | pos_zero: |
---|
532 | clrl ETEMP(%a6) |
---|
533 | clrl ETEMP_HI(%a6) |
---|
534 | clrl ETEMP_LO(%a6) |
---|
535 | bra finish |
---|
536 | |
---|
537 | not_spec: |
---|
538 | fmovemx %fp0-%fp1,-(%a7) //save fp0 - decbin returns in it |
---|
539 | bsr decbin |
---|
540 | fmovex %fp0,ETEMP(%a6) //put the unpacked sop in the fsave stack |
---|
541 | fmovemx (%a7)+,%fp0-%fp1 |
---|
542 | fmovel #0,%FPSR //clr fpsr from decbin |
---|
543 | bra finish |
---|
544 | |
---|
545 | // |
---|
546 | // Special handling for packed move in: Same results as all other |
---|
547 | // packed cases, but we must set the FPSR condition codes properly. |
---|
548 | // |
---|
549 | move_unpack: |
---|
550 | movew ETEMP(%a6),%d0 //get word with inf information |
---|
551 | bfextu %d0{#20:#12},%d1 //get exponent into d1 |
---|
552 | cmpiw #0x0fff,%d1 //test for inf or NaN |
---|
553 | bnes mtry_zero //if not equal, it is not special |
---|
554 | bfextu %d0{#17:#3},%d1 //get SE and y bits into d1 |
---|
555 | cmpiw #7,%d1 //SE and y bits must be on for special |
---|
556 | bnes mtry_zero //if not on, it is not special |
---|
557 | //input is of the special cases of inf and NaN |
---|
558 | tstl ETEMP_HI(%a6) //check ms mantissa |
---|
559 | bnes mfix_nan //if non-zero, it is a NaN |
---|
560 | tstl ETEMP_LO(%a6) //check ls mantissa |
---|
561 | bnes mfix_nan //if non-zero, it is a NaN |
---|
562 | //input is inf |
---|
563 | orl #inf_mask,USER_FPSR(%a6) //set I bit |
---|
564 | tstl ETEMP(%a6) //check sign |
---|
565 | bge finish |
---|
566 | orl #neg_mask,USER_FPSR(%a6) //set N bit |
---|
567 | bra finish //special already on stack |
---|
568 | mfix_nan: |
---|
569 | orl #nan_mask,USER_FPSR(%a6) //set NaN bit |
---|
570 | moveb #nan_tag,STAG(%a6) //set stag to NaN |
---|
571 | btstb #signan_bit,ETEMP_HI(%a6) //test for snan |
---|
572 | bnes mn_snan |
---|
573 | orl #snaniop_mask,USER_FPSR(%a6) //set snan bit |
---|
574 | btstb #snan_bit,FPCR_ENABLE(%a6) //test for snan enabled |
---|
575 | bnes mn_snan |
---|
576 | bsetb #signan_bit,ETEMP_HI(%a6) //force snans to qnans |
---|
577 | mn_snan: |
---|
578 | tstl ETEMP(%a6) //check for sign |
---|
579 | bge finish //if clr, go on |
---|
580 | orl #neg_mask,USER_FPSR(%a6) //set N bit |
---|
581 | bra finish |
---|
582 | |
---|
583 | mtry_zero: |
---|
584 | movew ETEMP_EX+2(%a6),%d0 //get word 4 |
---|
585 | andiw #0x000f,%d0 //clear all but last ni(y)bble |
---|
586 | tstw %d0 //check for zero. |
---|
587 | bnes mnot_spec |
---|
588 | tstl ETEMP_HI(%a6) //check words 3 and 2 |
---|
589 | bnes mnot_spec |
---|
590 | tstl ETEMP_LO(%a6) //check words 1 and 0 |
---|
591 | bnes mnot_spec |
---|
592 | tstl ETEMP(%a6) //test sign of the zero |
---|
593 | bges mpos_zero |
---|
594 | orl #neg_mask+z_mask,USER_FPSR(%a6) //set N and Z |
---|
595 | movel #0x80000000,ETEMP(%a6) //write neg zero to etemp |
---|
596 | clrl ETEMP_HI(%a6) |
---|
597 | clrl ETEMP_LO(%a6) |
---|
598 | bras finish |
---|
599 | mpos_zero: |
---|
600 | orl #z_mask,USER_FPSR(%a6) //set Z |
---|
601 | clrl ETEMP(%a6) |
---|
602 | clrl ETEMP_HI(%a6) |
---|
603 | clrl ETEMP_LO(%a6) |
---|
604 | bras finish |
---|
605 | |
---|
606 | mnot_spec: |
---|
607 | fmovemx %fp0-%fp1,-(%a7) //save fp0 ,fp1 - decbin returns in fp0 |
---|
608 | bsr decbin |
---|
609 | fmovex %fp0,ETEMP(%a6) |
---|
610 | // ;put the unpacked sop in the fsave stack |
---|
611 | fmovemx (%a7)+,%fp0-%fp1 |
---|
612 | |
---|
613 | finish: |
---|
614 | movew CMDREG1B(%a6),%d0 //get the command word |
---|
615 | andw #0xfbff,%d0 //change the source specifier field to |
---|
616 | // ;extended (was packed). |
---|
617 | movew %d0,CMDREG1B(%a6) //write command word back to fsave stack |
---|
618 | // ;we need to do this so the 040 will |
---|
619 | // ;re-execute the inst. without taking |
---|
620 | // ;another packed trap. |
---|
621 | |
---|
622 | fix_stag: |
---|
623 | //Converted result is now in etemp on fsave stack, now set the source |
---|
624 | //tag (stag) |
---|
625 | // if (ete =$7fff) then INF or NAN |
---|
626 | // if (etemp = $x.0----0) then |
---|
627 | // stag = INF |
---|
628 | // else |
---|
629 | // stag = NAN |
---|
630 | // else |
---|
631 | // if (ete = $0000) then |
---|
632 | // stag = ZERO |
---|
633 | // else |
---|
634 | // stag = NORM |
---|
635 | // |
---|
636 | // Note also that the etemp_15 bit (just right of the stag) must |
---|
637 | // be set accordingly. |
---|
638 | // |
---|
639 | movew ETEMP_EX(%a6),%d1 |
---|
640 | andiw #0x7fff,%d1 //strip sign |
---|
641 | cmpw #0x7fff,%d1 |
---|
642 | bnes z_or_nrm |
---|
643 | movel ETEMP_HI(%a6),%d1 |
---|
644 | bnes is_nan |
---|
645 | movel ETEMP_LO(%a6),%d1 |
---|
646 | bnes is_nan |
---|
647 | is_inf: |
---|
648 | moveb #0x40,STAG(%a6) |
---|
649 | movel #0x40,%d0 |
---|
650 | rts |
---|
651 | is_nan: |
---|
652 | moveb #0x60,STAG(%a6) |
---|
653 | movel #0x60,%d0 |
---|
654 | rts |
---|
655 | z_or_nrm: |
---|
656 | tstw %d1 |
---|
657 | bnes is_nrm |
---|
658 | is_zro: |
---|
659 | // For a zero, set etemp_15 |
---|
660 | moveb #0x30,STAG(%a6) |
---|
661 | movel #0x20,%d0 |
---|
662 | rts |
---|
663 | is_nrm: |
---|
664 | // For a norm, check if the exp <= $3fff; if so, set etemp_15 |
---|
665 | cmpiw #0x3fff,%d1 |
---|
666 | bles set_bit15 |
---|
667 | moveb #0,STAG(%a6) |
---|
668 | bras end_is_nrm |
---|
669 | set_bit15: |
---|
670 | moveb #0x10,STAG(%a6) |
---|
671 | end_is_nrm: |
---|
672 | movel #0,%d0 |
---|
673 | end_fix: |
---|
674 | rts |
---|
675 | |
---|
676 | end_get: |
---|
677 | rts |
---|
678 | |end |
---|