source: rtems/c/src/lib/libcpu/m68k/m68040/fpsp/get_op.S @ 42e243e

4.104.115
Last change on this file since 42e243e was 42e243e, checked in by Ralf Corsepius <ralf.corsepius@…>, on 12/04/09 at 04:27:21

Whitespace removal.

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