source: rtems/c/src/lib/libcpu/m68k/m68040/fpsp/get_op.s @ 010e7582

4.104.114.84.95
Last change on this file since 010e7582 was f9b93da, checked in by Joel Sherrill <joel.sherrill@…>, on 04/16/97 at 17:33:04

Added the MC68040 Floating Point Support Package. This was ported
to RTEMS by Eric Norum. It is freely distributable and was acquired
from the Motorola WWW site. More info is in the FPSP README.

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