Annotation of sys/arch/m68k/fpsp/get_op.sa, Revision 1.1.1.1
1.1 nbrk 1: * $OpenBSD: get_op.sa,v 1.2 1996/05/29 21:05:29 niklas Exp $
2: * $NetBSD: get_op.sa,v 1.3 1994/10/26 07:49:09 cgd Exp $
3:
4: * MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
5: * M68000 Hi-Performance Microprocessor Division
6: * M68040 Software Package
7: *
8: * M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
9: * All rights reserved.
10: *
11: * THE SOFTWARE is provided on an "AS IS" basis and without warranty.
12: * To the maximum extent permitted by applicable law,
13: * MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
14: * INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
15: * PARTICULAR PURPOSE and any warranty against infringement with
16: * regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
17: * and any accompanying written materials.
18: *
19: * To the maximum extent permitted by applicable law,
20: * IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
21: * (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS
22: * PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR
23: * OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE
24: * SOFTWARE. Motorola assumes no responsibility for the maintenance
25: * and support of the SOFTWARE.
26: *
27: * You are hereby granted a copyright license to use, modify, and
28: * distribute the SOFTWARE so long as this entire notice is retained
29: * without alteration in any modified and/or redistributed versions,
30: * and that such modified versions are clearly identified as such.
31: * No licenses are granted by implication, estoppel or otherwise
32: * under any patents or trademarks of Motorola, Inc.
33:
34: *
35: * get_op.sa 3.6 5/19/92
36: *
37: * get_op.sa 3.5 4/26/91
38: *
39: * Description: This routine is called by the unsupported format/data
40: * type exception handler ('unsupp' - vector 55) and the unimplemented
41: * instruction exception handler ('unimp' - vector 11). 'get_op'
42: * determines the opclass (0, 2, or 3) and branches to the
43: * opclass handler routine. See 68881/2 User's Manual table 4-11
44: * for a description of the opclasses.
45: *
46: * For UNSUPPORTED data/format (exception vector 55) and for
47: * UNIMPLEMENTED instructions (exception vector 11) the following
48: * applies:
49: *
50: * - For unnormormalized numbers (opclass 0, 2, or 3) the
51: * number(s) is normalized and the operand type tag is updated.
52: *
53: * - For a packed number (opclass 2) the number is unpacked and the
54: * operand type tag is updated.
55: *
56: * - For denormalized numbers (opclass 0 or 2) the number(s) is not
57: * changed but passed to the next module. The next module for
58: * unimp is do_func, the next module for unsupp is res_func.
59: *
60: * For UNSUPPORTED data/format (exception vector 55) only the
61: * following applies:
62: *
63: * - If there is a move out with a packed number (opclass 3) the
64: * number is packed and written to user memory. For the other
65: * opclasses the number(s) are written back to the fsave stack
66: * and the instruction is then restored back into the '040. The
67: * '040 is then able to complete the instruction.
68: *
69: * For example:
70: * fadd.x fpm,fpn where the fpm contains an unnormalized number.
71: * The '040 takes an unsupported data trap and gets to this
72: * routine. The number is normalized, put back on the stack and
73: * then an frestore is done to restore the instruction back into
74: * the '040. The '040 then re-executes the fadd.x fpm,fpn with
75: * a normalized number in the source and the instruction is
76: * successful.
77: *
78: * Next consider if in the process of normalizing the un-
79: * normalized number it becomes a denormalized number. The
80: * routine which converts the unnorm to a norm (called mk_norm)
81: * detects this and tags the number as a denorm. The routine
82: * res_func sees the denorm tag and converts the denorm to a
83: * norm. The instruction is then restored back into the '040
84: * which re_executess the instruction.
85: *
86:
87: GET_OP IDNT 2,1 Motorola 040 Floating Point Software Package
88:
89: section 8
90:
91: include fpsp.h
92:
93: xdef PIRN,PIRZRM,PIRP
94: xdef SMALRN,SMALRZRM,SMALRP
95: xdef BIGRN,BIGRZRM,BIGRP
96:
97: PIRN:
98: dc.l $40000000,$c90fdaa2,$2168c235 ;pi
99: PIRZRM:
100: dc.l $40000000,$c90fdaa2,$2168c234 ;pi
101: PIRP:
102: dc.l $40000000,$c90fdaa2,$2168c235 ;pi
103:
104: *round to nearest
105: SMALRN:
106: dc.l $3ffd0000,$9a209a84,$fbcff798 ;log10(2)
107: dc.l $40000000,$adf85458,$a2bb4a9a ;e
108: dc.l $3fff0000,$b8aa3b29,$5c17f0bc ;log2(e)
109: dc.l $3ffd0000,$de5bd8a9,$37287195 ;log10(e)
110: dc.l $00000000,$00000000,$00000000 ;0.0
111: * round to zero;round to negative infinity
112: SMALRZRM:
113: dc.l $3ffd0000,$9a209a84,$fbcff798 ;log10(2)
114: dc.l $40000000,$adf85458,$a2bb4a9a ;e
115: dc.l $3fff0000,$b8aa3b29,$5c17f0bb ;log2(e)
116: dc.l $3ffd0000,$de5bd8a9,$37287195 ;log10(e)
117: dc.l $00000000,$00000000,$00000000 ;0.0
118: * round to positive infinity
119: SMALRP:
120: dc.l $3ffd0000,$9a209a84,$fbcff799 ;log10(2)
121: dc.l $40000000,$adf85458,$a2bb4a9b ;e
122: dc.l $3fff0000,$b8aa3b29,$5c17f0bc ;log2(e)
123: dc.l $3ffd0000,$de5bd8a9,$37287195 ;log10(e)
124: dc.l $00000000,$00000000,$00000000 ;0.0
125:
126: *round to nearest
127: BIGRN:
128: dc.l $3ffe0000,$b17217f7,$d1cf79ac ;ln(2)
129: dc.l $40000000,$935d8ddd,$aaa8ac17 ;ln(10)
130: dc.l $3fff0000,$80000000,$00000000 ;10 ^ 0
131:
132: xdef PTENRN
133: PTENRN:
134: dc.l $40020000,$A0000000,$00000000 ;10 ^ 1
135: dc.l $40050000,$C8000000,$00000000 ;10 ^ 2
136: dc.l $400C0000,$9C400000,$00000000 ;10 ^ 4
137: dc.l $40190000,$BEBC2000,$00000000 ;10 ^ 8
138: dc.l $40340000,$8E1BC9BF,$04000000 ;10 ^ 16
139: dc.l $40690000,$9DC5ADA8,$2B70B59E ;10 ^ 32
140: dc.l $40D30000,$C2781F49,$FFCFA6D5 ;10 ^ 64
141: dc.l $41A80000,$93BA47C9,$80E98CE0 ;10 ^ 128
142: dc.l $43510000,$AA7EEBFB,$9DF9DE8E ;10 ^ 256
143: dc.l $46A30000,$E319A0AE,$A60E91C7 ;10 ^ 512
144: dc.l $4D480000,$C9767586,$81750C17 ;10 ^ 1024
145: dc.l $5A920000,$9E8B3B5D,$C53D5DE5 ;10 ^ 2048
146: dc.l $75250000,$C4605202,$8A20979B ;10 ^ 4096
147: *round to minus infinity
148: BIGRZRM:
149: dc.l $3ffe0000,$b17217f7,$d1cf79ab ;ln(2)
150: dc.l $40000000,$935d8ddd,$aaa8ac16 ;ln(10)
151: dc.l $3fff0000,$80000000,$00000000 ;10 ^ 0
152:
153: xdef PTENRM
154: PTENRM:
155: dc.l $40020000,$A0000000,$00000000 ;10 ^ 1
156: dc.l $40050000,$C8000000,$00000000 ;10 ^ 2
157: dc.l $400C0000,$9C400000,$00000000 ;10 ^ 4
158: dc.l $40190000,$BEBC2000,$00000000 ;10 ^ 8
159: dc.l $40340000,$8E1BC9BF,$04000000 ;10 ^ 16
160: dc.l $40690000,$9DC5ADA8,$2B70B59D ;10 ^ 32
161: dc.l $40D30000,$C2781F49,$FFCFA6D5 ;10 ^ 64
162: dc.l $41A80000,$93BA47C9,$80E98CDF ;10 ^ 128
163: dc.l $43510000,$AA7EEBFB,$9DF9DE8D ;10 ^ 256
164: dc.l $46A30000,$E319A0AE,$A60E91C6 ;10 ^ 512
165: dc.l $4D480000,$C9767586,$81750C17 ;10 ^ 1024
166: dc.l $5A920000,$9E8B3B5D,$C53D5DE5 ;10 ^ 2048
167: dc.l $75250000,$C4605202,$8A20979A ;10 ^ 4096
168: *round to positive infinity
169: BIGRP:
170: dc.l $3ffe0000,$b17217f7,$d1cf79ac ;ln(2)
171: dc.l $40000000,$935d8ddd,$aaa8ac17 ;ln(10)
172: dc.l $3fff0000,$80000000,$00000000 ;10 ^ 0
173:
174: xdef PTENRP
175: PTENRP:
176: dc.l $40020000,$A0000000,$00000000 ;10 ^ 1
177: dc.l $40050000,$C8000000,$00000000 ;10 ^ 2
178: dc.l $400C0000,$9C400000,$00000000 ;10 ^ 4
179: dc.l $40190000,$BEBC2000,$00000000 ;10 ^ 8
180: dc.l $40340000,$8E1BC9BF,$04000000 ;10 ^ 16
181: dc.l $40690000,$9DC5ADA8,$2B70B59E ;10 ^ 32
182: dc.l $40D30000,$C2781F49,$FFCFA6D6 ;10 ^ 64
183: dc.l $41A80000,$93BA47C9,$80E98CE0 ;10 ^ 128
184: dc.l $43510000,$AA7EEBFB,$9DF9DE8E ;10 ^ 256
185: dc.l $46A30000,$E319A0AE,$A60E91C7 ;10 ^ 512
186: dc.l $4D480000,$C9767586,$81750C18 ;10 ^ 1024
187: dc.l $5A920000,$9E8B3B5D,$C53D5DE6 ;10 ^ 2048
188: dc.l $75250000,$C4605202,$8A20979B ;10 ^ 4096
189:
190: xref nrm_zero
191: xref decbin
192: xref round
193:
194: xdef get_op
195: xdef uns_getop
196: xdef uni_getop
197: get_op:
198: clr.b DY_MO_FLG(a6)
199: tst.b UFLG_TMP(a6) ;test flag for unsupp/unimp state
200: beq.b uni_getop
201:
202: uns_getop:
203: btst.b #direction_bit,CMDREG1B(a6)
204: bne.w opclass3 ;branch if a fmove out (any kind)
205: btst.b #6,CMDREG1B(a6)
206: beq.b uns_notpacked
207:
208: bfextu CMDREG1B(a6){3:3},d0
209: cmp.b #3,d0
210: beq.w pack_source ;check for a packed src op, branch if so
211: uns_notpacked:
212: bsr chk_dy_mo ;set the dyadic/monadic flag
213: tst.b DY_MO_FLG(a6)
214: beq.b src_op_ck ;if monadic, go check src op
215: * ;else, check dst op (fall through)
216:
217: btst.b #7,DTAG(a6)
218: beq.b src_op_ck ;if dst op is norm, check src op
219: bra.b dst_ex_dnrm ;else, handle destination unnorm/dnrm
220:
221: uni_getop:
222: bfextu CMDREG1B(a6){0:6},d0 ;get opclass and src fields
223: cmpi.l #$17,d0 ;if op class and size fields are $17,
224: * ;it is FMOVECR; if not, continue
225: *
226: * If the instruction is fmovecr, exit get_op. It is handled
227: * in do_func and smovecr.sa.
228: *
229: bne.w not_fmovecr ;handle fmovecr as an unimplemented inst
230: rts
231:
232: not_fmovecr:
233: btst.b #E1,E_BYTE(a6) ;if set, there is a packed operand
234: bne.w pack_source ;check for packed src op, branch if so
235:
236: * The following lines of are coded to optimize on normalized operands
237: move.b STAG(a6),d0
238: or.b DTAG(a6),d0 ;check if either of STAG/DTAG msb set
239: bmi.b dest_op_ck ;if so, some op needs to be fixed
240: rts
241:
242: dest_op_ck:
243: btst.b #7,DTAG(a6) ;check for unsupported data types in
244: beq.b src_op_ck ;the destination, if not, check src op
245: bsr chk_dy_mo ;set dyadic/monadic flag
246: tst.b DY_MO_FLG(a6) ;
247: beq.b src_op_ck ;if monadic, check src op
248: *
249: * At this point, destination has an extended denorm or unnorm.
250: *
251: dst_ex_dnrm:
252: move.w FPTEMP_EX(a6),d0 ;get destination exponent
253: andi.w #$7fff,d0 ;mask sign, check if exp = 0000
254: beq.b src_op_ck ;if denorm then check source op.
255: * ;denorms are taken care of in res_func
256: * ;(unsupp) or do_func (unimp)
257: * ;else unnorm fall through
258: lea.l FPTEMP(a6),a0 ;point a0 to dop - used in mk_norm
259: bsr mk_norm ;go normalize - mk_norm returns:
260: * ;L_SCR1{7:5} = operand tag
261: * ; (000 = norm, 100 = denorm)
262: * ;L_SCR1{4} = fpte15 or ete15
263: * ; 0 = exp > $3fff
264: * ; 1 = exp <= $3fff
265: * ;and puts the normalized num back
266: * ;on the fsave stack
267: *
268: move.b L_SCR1(a6),DTAG(a6) ;write the new tag & fpte15
269: * ;to the fsave stack and fall
270: * ;through to check source operand
271: *
272: src_op_ck:
273: btst.b #7,STAG(a6)
274: beq.w end_getop ;check for unsupported data types on the
275: * ;source operand
276: btst.b #5,STAG(a6)
277: bne.b src_sd_dnrm ;if bit 5 set, handle sgl/dbl denorms
278: *
279: * At this point only unnorms or extended denorms are possible.
280: *
281: src_ex_dnrm:
282: move.w ETEMP_EX(a6),d0 ;get source exponent
283: andi.w #$7fff,d0 ;mask sign, check if exp = 0000
284: beq.w end_getop ;if denorm then exit, denorms are
285: * ;handled in do_func
286: lea.l ETEMP(a6),a0 ;point a0 to sop - used in mk_norm
287: bsr mk_norm ;go normalize - mk_norm returns:
288: * ;L_SCR1{7:5} = operand tag
289: * ; (000 = norm, 100 = denorm)
290: * ;L_SCR1{4} = fpte15 or ete15
291: * ; 0 = exp > $3fff
292: * ; 1 = exp <= $3fff
293: * ;and puts the normalized num back
294: * ;on the fsave stack
295: *
296: move.b L_SCR1(a6),STAG(a6) ;write the new tag & ete15
297: rts ;end_getop
298:
299: *
300: * At this point, only single or double denorms are possible.
301: * If the inst is not fmove, normalize the source. If it is,
302: * do nothing to the input.
303: *
304: src_sd_dnrm:
305: btst.b #4,CMDREG1B(a6) ;differentiate between sgl/dbl denorm
306: bne.b is_double
307: is_single:
308: move.w #$3f81,d1 ;write bias for sgl denorm
309: bra.b common ;goto the common code
310: is_double:
311: move.w #$3c01,d1 ;write the bias for a dbl denorm
312: common:
313: btst.b #sign_bit,ETEMP_EX(a6) ;grab sign bit of mantissa
314: beq.b pos
315: bset #15,d1 ;set sign bit because it is negative
316: pos:
317: move.w d1,ETEMP_EX(a6)
318: * ;put exponent on stack
319:
320: move.w CMDREG1B(a6),d1
321: and.w #$e3ff,d1 ;clear out source specifier
322: or.w #$0800,d1 ;set source specifier to extended prec
323: move.w d1,CMDREG1B(a6) ;write back to the command word in stack
324: * ;this is needed to fix unsupp data stack
325: lea.l ETEMP(a6),a0 ;point a0 to sop
326:
327: bsr mk_norm ;convert sgl/dbl denorm to norm
328: move.b L_SCR1(a6),STAG(a6) ;put tag into source tag reg - d0
329: rts ;end_getop
330: *
331: * At this point, the source is definitely packed, whether
332: * instruction is dyadic or monadic is still unknown
333: *
334: pack_source:
335: move.l FPTEMP_LO(a6),ETEMP(a6) ;write ms part of packed
336: * ;number to etemp slot
337: bsr chk_dy_mo ;set dyadic/monadic flag
338: bsr unpack
339:
340: tst.b DY_MO_FLG(a6)
341: beq.b end_getop ;if monadic, exit
342: * ;else, fix FPTEMP
343: pack_dya:
344: bfextu CMDREG1B(a6){6:3},d0 ;extract dest fp reg
345: move.l #7,d1
346: sub.l d0,d1
347: clr.l d0
348: bset.l d1,d0 ;set up d0 as a dynamic register mask
349: fmovem.x d0,FPTEMP(a6) ;write to FPTEMP
350:
351: btst.b #7,DTAG(a6) ;check dest tag for unnorm or denorm
352: bne.w dst_ex_dnrm ;else, handle the unnorm or ext denorm
353: *
354: * Dest is not denormalized. Check for norm, and set fpte15
355: * accordingly.
356: *
357: move.b DTAG(a6),d0
358: andi.b #$f0,d0 ;strip to only dtag:fpte15
359: tst.b d0 ;check for normalized value
360: bne.b end_getop ;if inf/nan/zero leave get_op
361: move.w FPTEMP_EX(a6),d0
362: andi.w #$7fff,d0
363: cmpi.w #$3fff,d0 ;check if fpte15 needs setting
364: bge.b end_getop ;if >= $3fff, leave fpte15=0
365: or.b #$10,DTAG(a6)
366: bra.b end_getop
367:
368: *
369: * At this point, it is either an fmoveout packed, unnorm or denorm
370: *
371: opclass3:
372: clr.b DY_MO_FLG(a6) ;set dyadic/monadic flag to monadic
373: bfextu CMDREG1B(a6){4:2},d0
374: cmpi.b #3,d0
375: bne.w src_ex_dnrm ;if not equal, must be unnorm or denorm
376: * ;else it is a packed move out
377: * ;exit
378: end_getop:
379: rts
380:
381: *
382: * Sets the DY_MO_FLG correctly. This is used only on if it is an
383: * unuspported data type exception. Set if dyadic.
384: *
385: chk_dy_mo:
386: move.w CMDREG1B(a6),d0
387: btst.l #5,d0 ;testing extension command word
388: beq.b set_mon ;if bit 5 = 0 then monadic
389: btst.l #4,d0 ;know that bit 5 = 1
390: beq.b set_dya ;if bit 4 = 0 then dyadic
391: andi.w #$007f,d0 ;get rid of all but extension bits {6:0}
392: cmpi.w #$0038,d0 ;if extension = $38 then fcmp (dyadic)
393: bne.b set_mon
394: set_dya:
395: st.b DY_MO_FLG(a6) ;set the inst flag type to dyadic
396: rts
397: set_mon:
398: clr.b DY_MO_FLG(a6) ;set the inst flag type to monadic
399: rts
400: *
401: * MK_NORM
402: *
403: * Normalizes unnormalized numbers, sets tag to norm or denorm, sets unfl
404: * exception if denorm.
405: *
406: * CASE opclass 0x0 unsupp
407: * mk_norm till msb set
408: * set tag = norm
409: *
410: * CASE opclass 0x0 unimp
411: * mk_norm till msb set or exp = 0
412: * if integer bit = 0
413: * tag = denorm
414: * else
415: * tag = norm
416: *
417: * CASE opclass 011 unsupp
418: * mk_norm till msb set or exp = 0
419: * if integer bit = 0
420: * tag = denorm
421: * set unfl_nmcexe = 1
422: * else
423: * tag = norm
424: *
425: * if exp <= $3fff
426: * set ete15 or fpte15 = 1
427: * else set ete15 or fpte15 = 0
428:
429: * input:
430: * a0 = points to operand to be normalized
431: * output:
432: * L_SCR1{7:5} = operand tag (000 = norm, 100 = denorm)
433: * L_SCR1{4} = fpte15 or ete15 (0 = exp > $3fff, 1 = exp <=$3fff)
434: * the normalized operand is placed back on the fsave stack
435: mk_norm:
436: clr.l L_SCR1(a6)
437: bclr.b #sign_bit,LOCAL_EX(a0)
438: sne LOCAL_SGN(a0) ;transform into internal extended format
439:
440: cmpi.b #$2c,1+EXC_VEC(a6) ;check if unimp
441: bne.b uns_data ;branch if unsupp
442: bsr uni_inst ;call if unimp (opclass 0x0)
443: bra.b reload
444: uns_data:
445: btst.b #direction_bit,CMDREG1B(a6) ;check transfer direction
446: bne.b bit_set ;branch if set (opclass 011)
447: bsr uns_opx ;call if opclass 0x0
448: bra.b reload
449: bit_set:
450: bsr uns_op3 ;opclass 011
451: reload:
452: cmp.w #$3fff,LOCAL_EX(a0) ;if exp > $3fff
453: bgt.b end_mk ; fpte15/ete15 already set to 0
454: bset.b #4,L_SCR1(a6) ;else set fpte15/ete15 to 1
455: * ;calling routine actually sets the
456: * ;value on the stack (along with the
457: * ;tag), since this routine doesn't
458: * ;know if it should set ete15 or fpte15
459: * ;ie, it doesn't know if this is the
460: * ;src op or dest op.
461: end_mk:
462: bfclr LOCAL_SGN(a0){0:8}
463: beq.b end_mk_pos
464: bset.b #sign_bit,LOCAL_EX(a0) ;convert back to IEEE format
465: end_mk_pos:
466: rts
467: *
468: * CASE opclass 011 unsupp
469: *
470: uns_op3:
471: bsr nrm_zero ;normalize till msb = 1 or exp = zero
472: btst.b #7,LOCAL_HI(a0) ;if msb = 1
473: bne.b no_unfl ;then branch
474: set_unfl:
475: or.b #dnrm_tag,L_SCR1(a6) ;set denorm tag
476: bset.b #unfl_bit,FPSR_EXCEPT(a6) ;set unfl exception bit
477: no_unfl:
478: rts
479: *
480: * CASE opclass 0x0 unsupp
481: *
482: uns_opx:
483: bsr nrm_zero ;normalize the number
484: btst.b #7,LOCAL_HI(a0) ;check if integer bit (j-bit) is set
485: beq.b uns_den ;if clear then now have a denorm
486: uns_nrm:
487: or.b #norm_tag,L_SCR1(a6) ;set tag to norm
488: rts
489: uns_den:
490: or.b #dnrm_tag,L_SCR1(a6) ;set tag to denorm
491: rts
492: *
493: * CASE opclass 0x0 unimp
494: *
495: uni_inst:
496: bsr nrm_zero
497: btst.b #7,LOCAL_HI(a0) ;check if integer bit (j-bit) is set
498: beq.b uni_den ;if clear then now have a denorm
499: uni_nrm:
500: or.b #norm_tag,L_SCR1(a6) ;set tag to norm
501: rts
502: uni_den:
503: or.b #dnrm_tag,L_SCR1(a6) ;set tag to denorm
504: rts
505:
506: *
507: * Decimal to binary conversion
508: *
509: * Special cases of inf and NaNs are completed outside of decbin.
510: * If the input is an snan, the snan bit is not set.
511: *
512: * input:
513: * ETEMP(a6) - points to packed decimal string in memory
514: * output:
515: * fp0 - contains packed string converted to extended precision
516: * ETEMP - same as fp0
517: unpack:
518: move.w CMDREG1B(a6),d0 ;examine command word, looking for fmove's
519: and.w #$3b,d0
520: beq move_unpack ;special handling for fmove: must set FPSR_CC
521:
522: move.w ETEMP(a6),d0 ;get word with inf information
523: bfextu d0{20:12},d1 ;get exponent into d1
524: cmpi.w #$0fff,d1 ;test for inf or NaN
525: bne.b try_zero ;if not equal, it is not special
526: bfextu d0{17:3},d1 ;get SE and y bits into d1
527: cmpi.w #7,d1 ;SE and y bits must be on for special
528: bne.b try_zero ;if not on, it is not special
529: *input is of the special cases of inf and NaN
530: tst.l ETEMP_HI(a6) ;check ms mantissa
531: bne.b fix_nan ;if non-zero, it is a NaN
532: tst.l ETEMP_LO(a6) ;check ls mantissa
533: bne.b fix_nan ;if non-zero, it is a NaN
534: bra.w finish ;special already on stack
535: fix_nan:
536: btst.b #signan_bit,ETEMP_HI(a6) ;test for snan
537: bne.w finish
538: or.l #snaniop_mask,USER_FPSR(a6) ;always set snan if it is so
539: bra.w finish
540: try_zero:
541: move.w ETEMP_EX+2(a6),d0 ;get word 4
542: andi.w #$000f,d0 ;clear all but last ni(y)bble
543: tst.w d0 ;check for zero.
544: bne.w not_spec
545: tst.l ETEMP_HI(a6) ;check words 3 and 2
546: bne.w not_spec
547: tst.l ETEMP_LO(a6) ;check words 1 and 0
548: bne.w not_spec
549: tst.l ETEMP(a6) ;test sign of the zero
550: bge.b pos_zero
551: move.l #$80000000,ETEMP(a6) ;write neg zero to etemp
552: clr.l ETEMP_HI(a6)
553: clr.l ETEMP_LO(a6)
554: bra.w finish
555: pos_zero:
556: clr.l ETEMP(a6)
557: clr.l ETEMP_HI(a6)
558: clr.l ETEMP_LO(a6)
559: bra.w finish
560:
561: not_spec:
562: fmovem.x fp0-fp1,-(a7) ;save fp0 - decbin returns in it
563: bsr decbin
564: fmove.x fp0,ETEMP(a6) ;put the unpacked sop in the fsave stack
565: fmovem.x (a7)+,fp0-fp1
566: fmove.l #0,FPSR ;clr fpsr from decbin
567: bra finish
568:
569: *
570: * Special handling for packed move in: Same results as all other
571: * packed cases, but we must set the FPSR condition codes properly.
572: *
573: move_unpack:
574: move.w ETEMP(a6),d0 ;get word with inf information
575: bfextu d0{20:12},d1 ;get exponent into d1
576: cmpi.w #$0fff,d1 ;test for inf or NaN
577: bne.b mtry_zero ;if not equal, it is not special
578: bfextu d0{17:3},d1 ;get SE and y bits into d1
579: cmpi.w #7,d1 ;SE and y bits must be on for special
580: bne.b mtry_zero ;if not on, it is not special
581: *input is of the special cases of inf and NaN
582: tst.l ETEMP_HI(a6) ;check ms mantissa
583: bne.b mfix_nan ;if non-zero, it is a NaN
584: tst.l ETEMP_LO(a6) ;check ls mantissa
585: bne.b mfix_nan ;if non-zero, it is a NaN
586: *input is inf
587: or.l #inf_mask,USER_FPSR(a6) ;set I bit
588: tst.l ETEMP(a6) ;check sign
589: bge.w finish
590: or.l #neg_mask,USER_FPSR(a6) ;set N bit
591: bra.w finish ;special already on stack
592: mfix_nan:
593: or.l #nan_mask,USER_FPSR(a6) ;set NaN bit
594: move.b #nan_tag,STAG(a6) ;set stag to NaN
595: btst.b #signan_bit,ETEMP_HI(a6) ;test for snan
596: bne.b mn_snan
597: or.l #snaniop_mask,USER_FPSR(a6) ;set snan bit
598: btst.b #snan_bit,FPCR_ENABLE(a6) ;test for snan enabled
599: bne.b mn_snan
600: bset.b #signan_bit,ETEMP_HI(a6) ;force snans to qnans
601: mn_snan:
602: tst.l ETEMP(a6) ;check for sign
603: bge.w finish ;if clr, go on
604: or.l #neg_mask,USER_FPSR(a6) ;set N bit
605: bra.w finish
606:
607: mtry_zero:
608: move.w ETEMP_EX+2(a6),d0 ;get word 4
609: andi.w #$000f,d0 ;clear all but last ni(y)bble
610: tst.w d0 ;check for zero.
611: bne.b mnot_spec
612: tst.l ETEMP_HI(a6) ;check words 3 and 2
613: bne.b mnot_spec
614: tst.l ETEMP_LO(a6) ;check words 1 and 0
615: bne.b mnot_spec
616: tst.l ETEMP(a6) ;test sign of the zero
617: bge.b mpos_zero
618: or.l #neg_mask+z_mask,USER_FPSR(a6) ;set N and Z
619: move.l #$80000000,ETEMP(a6) ;write neg zero to etemp
620: clr.l ETEMP_HI(a6)
621: clr.l ETEMP_LO(a6)
622: bra.b finish
623: mpos_zero:
624: or.l #z_mask,USER_FPSR(a6) ;set Z
625: clr.l ETEMP(a6)
626: clr.l ETEMP_HI(a6)
627: clr.l ETEMP_LO(a6)
628: bra.b finish
629:
630: mnot_spec:
631: fmovem.x fp0-fp1,-(a7) ;save fp0 ,fp1 - decbin returns in fp0
632: bsr decbin
633: fmove.x fp0,ETEMP(a6)
634: * ;put the unpacked sop in the fsave stack
635: fmovem.x (a7)+,fp0-fp1
636:
637: finish:
638: move.w CMDREG1B(a6),d0 ;get the command word
639: and.w #$fbff,d0 ;change the source specifier field to
640: * ;extended (was packed).
641: move.w d0,CMDREG1B(a6) ;write command word back to fsave stack
642: * ;we need to do this so the 040 will
643: * ;re-execute the inst. without taking
644: * ;another packed trap.
645:
646: fix_stag:
647: *Converted result is now in etemp on fsave stack, now set the source
648: *tag (stag)
649: * if (ete =$7fff) then INF or NAN
650: * if (etemp = $x.0----0) then
651: * stag = INF
652: * else
653: * stag = NAN
654: * else
655: * if (ete = $0000) then
656: * stag = ZERO
657: * else
658: * stag = NORM
659: *
660: * Note also that the etemp_15 bit (just right of the stag) must
661: * be set accordingly.
662: *
663: move.w ETEMP_EX(a6),d1
664: andi.w #$7fff,d1 ;strip sign
665: cmp.w #$7fff,d1
666: bne.b z_or_nrm
667: move.l ETEMP_HI(a6),d1
668: bne.b is_nan
669: move.l ETEMP_LO(a6),d1
670: bne.b is_nan
671: is_inf:
672: move.b #$40,STAG(a6)
673: move.l #$40,d0
674: rts
675: is_nan:
676: move.b #$60,STAG(a6)
677: move.l #$60,d0
678: rts
679: z_or_nrm:
680: tst.w d1
681: bne.b is_nrm
682: is_zro:
683: * For a zero, set etemp_15
684: move.b #$30,STAG(a6)
685: move.l #$20,d0
686: rts
687: is_nrm:
688: * For a norm, check if the exp <= $3fff; if so, set etemp_15
689: cmpi.w #$3fff,d1
690: ble.b set_bit15
691: clr.b STAG(a6)
692: bra.b end_is_nrm
693: set_bit15:
694: move.b #$10,STAG(a6)
695: end_is_nrm:
696: clr.l d0
697: end_fix:
698: rts
699:
700: end_get:
701: rts
702: end
CVSweb