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