make.tmpl: add missing compiler attribute to build_progs
[AROS.git] / arch / m68k-all / m680x0 / fpsp / get_op.sa
blob93f986e6bc27aa5b73d58bf5cf89281cbf383434
1 *       $NetBSD: get_op.sa,v 1.4 2001/12/09 01:43:13 briggs Exp $
3 *       MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
4 *       M68000 Hi-Performance Microprocessor Division
5 *       M68040 Software Package 
7 *       M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
8 *       All rights reserved.
10 *       THE SOFTWARE is provided on an "AS IS" basis and without warranty.
11 *       To the maximum extent permitted by applicable law,
12 *       MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
13 *       INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
14 *       PARTICULAR PURPOSE and any warranty against infringement with
15 *       regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
16 *       and any accompanying written materials. 
18 *       To the maximum extent permitted by applicable law,
19 *       IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
20 *       (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS
21 *       PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR
22 *       OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE
23 *       SOFTWARE.  Motorola assumes no responsibility for the maintenance
24 *       and support of the SOFTWARE.  
26 *       You are hereby granted a copyright license to use, modify, and
27 *       distribute the SOFTWARE so long as this entire notice is retained
28 *       without alteration in any modified and/or redistributed versions,
29 *       and that such modified versions are clearly identified as such.
30 *       No licenses are granted by implication, estoppel or otherwise
31 *       under any patents or trademarks of Motorola, Inc.
34 *       get_op.sa 3.6 5/19/92
36 *       get_op.sa 3.5 4/26/91
38 *  Description: This routine is called by the unsupported format/data
39 * type exception handler ('unsupp' - vector 55) and the unimplemented
40 * instruction exception handler ('unimp' - vector 11).  'get_op'
41 * determines the opclass (0, 2, or 3) and branches to the
42 * opclass handler routine.  See 68881/2 User's Manual table 4-11
43 * for a description of the opclasses.
45 * For UNSUPPORTED data/format (exception vector 55) and for
46 * UNIMPLEMENTED instructions (exception vector 11) the following
47 * applies:
49 * - For unnormormalized numbers (opclass 0, 2, or 3) the
50 * number(s) is normalized and the operand type tag is updated.
51 *               
52 * - For a packed number (opclass 2) the number is unpacked and the
53 * operand type tag is updated.
55 * - For denormalized numbers (opclass 0 or 2) the number(s) is not
56 * changed but passed to the next module.  The next module for
57 * unimp is do_func, the next module for unsupp is res_func.
59 * For UNSUPPORTED data/format (exception vector 55) only the
60 * following applies:
62 * - If there is a move out with a packed number (opclass 3) the
63 * number is packed and written to user memory.  For the other
64 * opclasses the number(s) are written back to the fsave stack
65 * and the instruction is then restored back into the '040.  The
66 * '040 is then able to complete the instruction.
68 * For example:
69 * fadd.x fpm,fpn where the fpm contains an unnormalized number.
70 * The '040 takes an unsupported data trap and gets to this
71 * routine.  The number is normalized, put back on the stack and
72 * then an frestore is done to restore the instruction back into
73 * the '040.  The '040 then re-executes the fadd.x fpm,fpn with
74 * a normalized number in the source and the instruction is
75 * successful.
76 *               
77 * Next consider if in the process of normalizing the un-
78 * normalized number it becomes a denormalized number.  The
79 * routine which converts the unnorm to a norm (called mk_norm)
80 * detects this and tags the number as a denorm.  The routine
81 * res_func sees the denorm tag and converts the denorm to a
82 * norm.  The instruction is then restored back into the '040
83 * which re_executess the instruction.
86 GET_OP    IDNT    2,1 Motorola 040 Floating Point Software Package
88         section 8
90         include fpsp.h
92         xdef    PIRN,PIRZRM,PIRP
93         xdef    SMALRN,SMALRZRM,SMALRP
94         xdef    BIGRN,BIGRZRM,BIGRP
96 PIRN:
97         dc.l $40000000,$c90fdaa2,$2168c235    ;pi
98 PIRZRM:
99         dc.l $40000000,$c90fdaa2,$2168c234    ;pi
100 PIRP:
101         dc.l $40000000,$c90fdaa2,$2168c235    ;pi
103 *round to nearest
104 SMALRN:
105         dc.l $3ffd0000,$9a209a84,$fbcff798    ;log10(2)
106         dc.l $40000000,$adf85458,$a2bb4a9a    ;e
107         dc.l $3fff0000,$b8aa3b29,$5c17f0bc    ;log2(e)
108         dc.l $3ffd0000,$de5bd8a9,$37287195    ;log10(e)
109         dc.l $00000000,$00000000,$00000000    ;0.0
110 * round to zero;round to negative infinity
111 SMALRZRM:
112         dc.l $3ffd0000,$9a209a84,$fbcff798    ;log10(2)
113         dc.l $40000000,$adf85458,$a2bb4a9a    ;e
114         dc.l $3fff0000,$b8aa3b29,$5c17f0bb    ;log2(e)
115         dc.l $3ffd0000,$de5bd8a9,$37287195    ;log10(e)
116         dc.l $00000000,$00000000,$00000000    ;0.0
117 * round to positive infinity
118 SMALRP:
119         dc.l $3ffd0000,$9a209a84,$fbcff799    ;log10(2)
120         dc.l $40000000,$adf85458,$a2bb4a9b    ;e
121         dc.l $3fff0000,$b8aa3b29,$5c17f0bc    ;log2(e)
122         dc.l $3ffd0000,$de5bd8a9,$37287195    ;log10(e)
123         dc.l $00000000,$00000000,$00000000    ;0.0
125 *round to nearest
126 BIGRN:
127         dc.l $3ffe0000,$b17217f7,$d1cf79ac    ;ln(2)
128         dc.l $40000000,$935d8ddd,$aaa8ac17    ;ln(10)
129         dc.l $3fff0000,$80000000,$00000000    ;10 ^ 0
131         xdef    PTENRN
132 PTENRN:
133         dc.l $40020000,$A0000000,$00000000    ;10 ^ 1
134         dc.l $40050000,$C8000000,$00000000    ;10 ^ 2
135         dc.l $400C0000,$9C400000,$00000000    ;10 ^ 4
136         dc.l $40190000,$BEBC2000,$00000000    ;10 ^ 8
137         dc.l $40340000,$8E1BC9BF,$04000000    ;10 ^ 16
138         dc.l $40690000,$9DC5ADA8,$2B70B59E    ;10 ^ 32
139         dc.l $40D30000,$C2781F49,$FFCFA6D5    ;10 ^ 64
140         dc.l $41A80000,$93BA47C9,$80E98CE0    ;10 ^ 128
141         dc.l $43510000,$AA7EEBFB,$9DF9DE8E    ;10 ^ 256
142         dc.l $46A30000,$E319A0AE,$A60E91C7    ;10 ^ 512
143         dc.l $4D480000,$C9767586,$81750C17    ;10 ^ 1024
144         dc.l $5A920000,$9E8B3B5D,$C53D5DE5    ;10 ^ 2048
145         dc.l $75250000,$C4605202,$8A20979B    ;10 ^ 4096
146 *round to minus infinity
147 BIGRZRM:
148         dc.l $3ffe0000,$b17217f7,$d1cf79ab    ;ln(2)
149         dc.l $40000000,$935d8ddd,$aaa8ac16    ;ln(10)
150         dc.l $3fff0000,$80000000,$00000000    ;10 ^ 0
152         xdef    PTENRM
153 PTENRM:
154         dc.l $40020000,$A0000000,$00000000    ;10 ^ 1
155         dc.l $40050000,$C8000000,$00000000    ;10 ^ 2
156         dc.l $400C0000,$9C400000,$00000000    ;10 ^ 4
157         dc.l $40190000,$BEBC2000,$00000000    ;10 ^ 8
158         dc.l $40340000,$8E1BC9BF,$04000000    ;10 ^ 16
159         dc.l $40690000,$9DC5ADA8,$2B70B59D    ;10 ^ 32
160         dc.l $40D30000,$C2781F49,$FFCFA6D5    ;10 ^ 64
161         dc.l $41A80000,$93BA47C9,$80E98CDF    ;10 ^ 128
162         dc.l $43510000,$AA7EEBFB,$9DF9DE8D    ;10 ^ 256
163         dc.l $46A30000,$E319A0AE,$A60E91C6    ;10 ^ 512
164         dc.l $4D480000,$C9767586,$81750C17    ;10 ^ 1024
165         dc.l $5A920000,$9E8B3B5D,$C53D5DE5    ;10 ^ 2048
166         dc.l $75250000,$C4605202,$8A20979A    ;10 ^ 4096
167 *round to positive infinity
168 BIGRP:
169         dc.l $3ffe0000,$b17217f7,$d1cf79ac    ;ln(2)
170         dc.l $40000000,$935d8ddd,$aaa8ac17    ;ln(10)
171         dc.l $3fff0000,$80000000,$00000000    ;10 ^ 0
173         xdef    PTENRP
174 PTENRP:
175         dc.l $40020000,$A0000000,$00000000    ;10 ^ 1
176         dc.l $40050000,$C8000000,$00000000    ;10 ^ 2
177         dc.l $400C0000,$9C400000,$00000000    ;10 ^ 4
178         dc.l $40190000,$BEBC2000,$00000000    ;10 ^ 8
179         dc.l $40340000,$8E1BC9BF,$04000000    ;10 ^ 16
180         dc.l $40690000,$9DC5ADA8,$2B70B59E    ;10 ^ 32
181         dc.l $40D30000,$C2781F49,$FFCFA6D6    ;10 ^ 64
182         dc.l $41A80000,$93BA47C9,$80E98CE0    ;10 ^ 128
183         dc.l $43510000,$AA7EEBFB,$9DF9DE8E    ;10 ^ 256
184         dc.l $46A30000,$E319A0AE,$A60E91C7    ;10 ^ 512
185         dc.l $4D480000,$C9767586,$81750C18    ;10 ^ 1024
186         dc.l $5A920000,$9E8B3B5D,$C53D5DE6    ;10 ^ 2048
187         dc.l $75250000,$C4605202,$8A20979B    ;10 ^ 4096
189         xref    nrm_zero
190         xref    decbin
191         xref    round
193         xdef    get_op
194         xdef    uns_getop
195         xdef    uni_getop
196 get_op:
197         clr.b   DY_MO_FLG(a6)
198         tst.b   UFLG_TMP(a6)    ;test flag for unsupp/unimp state
199         beq.b   short_uni_getop
201 uns_getop:
202         btst.b  #direction_bit,CMDREG1B(a6)
203         bne.w   opclass3        ;branch if a fmove out (any kind)
204         btst.b  #6,CMDREG1B(a6)
205         beq.b   uns_notpacked
207         bfextu  CMDREG1B(a6){3:3},d0
208         cmp.b   #3,d0
209         beq.w   pack_source     ;check for a packed src op, branch if so
210 uns_notpacked:
211         bsr     chk_dy_mo       ;set the dyadic/monadic flag
212         tst.b   DY_MO_FLG(a6)
213         beq.b   src_op_ck       ;if monadic, go check src op
214 *                               ;else, check dst op (fall through)
216         btst.b  #7,DTAG(a6)
217         beq.b   src_op_ck       ;if dst op is norm, check src op
218         bra.b   dst_ex_dnrm     ;else, handle destination unnorm/dnrm
220 uni_getop:
221 short_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
226 * If the instruction is fmovecr, exit get_op.  It is handled
227 * in do_func and smovecr.sa.
229         bne.w   not_fmovecr     ;handle fmovecr as an unimplemented inst
230         rts
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
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
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
249 * At this point, destination has an extended denorm or unnorm.
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
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
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
279 * At this point only unnorms or extended denorms are possible.
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
296         move.b  L_SCR1(a6),STAG(a6) ;write the new tag & ete15 
297         rts                     ;end_getop
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.
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
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
331 * At this point, the source is definitely packed, whether
332 * instruction is dyadic or monadic is still unknown
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
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
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
354 * Dest is not denormalized.  Check for norm, and set fpte15 
355 * accordingly.
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
369 * At this point, it is either an fmoveout packed, unnorm or denorm
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
382 * Sets the DY_MO_FLG correctly. This is used only on if it is an
383 * unuspported data type exception.  Set if dyadic.
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
401 *       MK_NORM
403 * Normalizes unnormalized numbers, sets tag to norm or denorm, sets unfl
404 * exception if denorm.
406 * CASE opclass 0x0 unsupp
407 *       mk_norm till msb set
408 *       set tag = norm
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
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
425 * if exp <= $3fff
426 *   set ete15 or fpte15 = 1
427 * else set ete15 or fpte15 = 0
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
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
468 *     CASE opclass 011 unsupp
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
480 *     CASE opclass 0x0 unsupp
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
493 *     CASE opclass 0x0 unimp
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
507 *       Decimal to binary conversion
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.
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
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
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
570 * Special handling for packed move in:  Same results as all other
571 * packed cases, but we must set the FPSR condition codes properly.
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
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
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
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.
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
660 * Note also that the etemp_15 bit (just right of the stag) must
661 * be set accordingly.  
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
700 end_get:
701         rts
702         end