1*         $NetBSD: sgetem.sa,v 1.2 1994/10/26 07:49:45 cgd Exp $
2
3*         MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
4*         M68000 Hi-Performance Microprocessor Division
5*         M68040 Software Package
6*
7*         M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
8*         All rights reserved.
9*
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.
17*
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.
25*
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.
32
33*
34*         sgetem.sa 3.1 12/10/90
35*
36*         The entry point sGETEXP returns the exponent portion
37*         of the input argument.  The exponent bias is removed
38*         and the exponent value is returned as an extended
39*         precision number in fp0.  sGETEXPD handles denormalized
40*         numbers.
41*
42*         The entry point sGETMAN extracts the mantissa of the
43*         input argument.  The mantissa is converted to an
44*         extended precision number and returned in fp0.  The
45*         range of the result is [1.0 - 2.0).
46*
47*
48*         Input:  Double-extended number X in the ETEMP space in
49*                   the floating-point save stack.
50*
51*         Output:   The functions return exp(X) or man(X) in fp0.
52*
53*         Modified: fp0.
54*
55
56SGETEM    IDNT      2,1 Motorola 040 Floating Point Software Package
57
58          section 8
59
60          include fpsp.h
61
62          xref      nrm_set
63
64*
65* This entry point is used by the unimplemented instruction exception
66* handler.  It points a0 to the input operand.
67*
68*
69*
70*         SGETEXP
71*
72
73          xdef      sgetexp
74sgetexp:
75          move.w    LOCAL_EX(a0),d0     ;get the exponent
76          bclr.l    #15,d0              ;clear the sign bit
77          sub.w     #$3fff,d0 ;subtract off the bias
78          fmove.w  d0,fp0               ;move the exp to fp0
79          rts
80
81          xdef      sgetexpd
82sgetexpd:
83          bclr.b    #sign_bit,LOCAL_EX(a0)
84          bsr       nrm_set             ;normalize (exp will go negative)
85          move.w    LOCAL_EX(a0),d0     ;load resulting exponent into d0
86          sub.w     #$3fff,d0 ;subtract off the bias
87          fmove.w   d0,fp0              ;move the exp to fp0
88          rts
89*
90*
91* This entry point is used by the unimplemented instruction exception
92* handler.  It points a0 to the input operand.
93*
94*
95*
96*         SGETMAN
97*
98*
99* For normalized numbers, leave the mantissa alone, simply load
100* with an exponent of +/- $3fff.
101*
102          xdef      sgetman
103sgetman:
104          move.l    USER_FPCR(a6),d0
105          andi.l    #$ffffff00,d0       ;clear rounding precision and mode
106          fmove.l   d0,fpcr             ;this fpcr setting is used by the 882
107          move.w    LOCAL_EX(a0),d0     ;get the exp (really just want sign bit)
108          or.w      #$7fff,d0 ;clear old exp
109          bclr.l    #14,d0              ;make it the new exp +-3fff
110          move.w    d0,LOCAL_EX(a0)     ;move the sign & exp back to fsave stack
111          fmove.x   (a0),fp0  ;put new value back in fp0
112          rts
113
114*
115* For denormalized numbers, shift the mantissa until the j-bit = 1,
116* then load the exponent with +/1 $3fff.
117*
118          xdef      sgetmand
119sgetmand:
120          move.l    LOCAL_HI(a0),d0     ;load ms mant in d0
121          move.l    LOCAL_LO(a0),d1     ;load ls mant in d1
122          bsr       shft                ;shift mantissa bits till msbit is set
123          move.l    d0,LOCAL_HI(a0)     ;put ms mant back on stack
124          move.l    d1,LOCAL_LO(a0)     ;put ls mant back on stack
125          bra.b     sgetman
126
127*
128*         SHFT
129*
130*         Shifts the mantissa bits until msbit is set.
131*         input:
132*                   ms mantissa part in d0
133*                   ls mantissa part in d1
134*         output:
135*                   shifted bits in d0 and d1
136shft:
137          tst.l     d0                  ;if any bits set in ms mant
138          bne.b     upper               ;then branch
139*                                       ;else no bits set in ms mant
140          tst.l     d1                  ;test if any bits set in ls mant
141          bne.b     cont                ;if set then continue
142          bra.b     shft_end  ;else return
143cont:
144          move.l    d3,-(a7)  ;save d3
145          exg       d0,d1               ;shift ls mant to ms mant
146          bfffo     d0{0:32},d3         ;find first 1 in ls mant to d0
147          lsl.l     d3,d0               ;shift first 1 to integer bit in ms mant
148          move.l    (a7)+,d3  ;restore d3
149          bra.b     shft_end
150upper:
151
152          movem.l   d3/d5/d6,-(a7)      ;save registers
153          bfffo     d0{0:32},d3         ;find first 1 in ls mant to d0
154          lsl.l     d3,d0               ;shift ms mant until j-bit is set
155          move.l    d1,d6               ;save ls mant in d6
156          lsl.l     d3,d1               ;shift ls mant by count
157          move.l    #32,d5
158          sub.l     d3,d5               ;sub 32 from shift for ls mant
159          lsr.l     d5,d6               ;shift off all bits but those that will
160*                                       ;be shifted into ms mant
161          or.l      d6,d0               ;shift the ls mant bits into the ms mant
162          movem.l   (a7)+,d3/d5/d6      ;restore registers
163shft_end:
164          rts
165
166          end
167