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