xref: /OK3568_Linux_fs/kernel/arch/m68k/fpsp040/stwotox.S (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun|
2*4882a593Smuzhiyun|	stwotox.sa 3.1 12/10/90
3*4882a593Smuzhiyun|
4*4882a593Smuzhiyun|	stwotox  --- 2**X
5*4882a593Smuzhiyun|	stwotoxd --- 2**X for denormalized X
6*4882a593Smuzhiyun|	stentox  --- 10**X
7*4882a593Smuzhiyun|	stentoxd --- 10**X for denormalized X
8*4882a593Smuzhiyun|
9*4882a593Smuzhiyun|	Input: Double-extended number X in location pointed to
10*4882a593Smuzhiyun|		by address register a0.
11*4882a593Smuzhiyun|
12*4882a593Smuzhiyun|	Output: The function values are returned in Fp0.
13*4882a593Smuzhiyun|
14*4882a593Smuzhiyun|	Accuracy and Monotonicity: The returned result is within 2 ulps in
15*4882a593Smuzhiyun|		64 significant bit, i.e. within 0.5001 ulp to 53 bits if the
16*4882a593Smuzhiyun|		result is subsequently rounded to double precision. The
17*4882a593Smuzhiyun|		result is provably monotonic in double precision.
18*4882a593Smuzhiyun|
19*4882a593Smuzhiyun|	Speed: The program stwotox takes approximately 190 cycles and the
20*4882a593Smuzhiyun|		program stentox takes approximately 200 cycles.
21*4882a593Smuzhiyun|
22*4882a593Smuzhiyun|	Algorithm:
23*4882a593Smuzhiyun|
24*4882a593Smuzhiyun|	twotox
25*4882a593Smuzhiyun|	1. If |X| > 16480, go to ExpBig.
26*4882a593Smuzhiyun|
27*4882a593Smuzhiyun|	2. If |X| < 2**(-70), go to ExpSm.
28*4882a593Smuzhiyun|
29*4882a593Smuzhiyun|	3. Decompose X as X = N/64 + r where |r| <= 1/128. Furthermore
30*4882a593Smuzhiyun|		decompose N as
31*4882a593Smuzhiyun|		 N = 64(M + M') + j,  j = 0,1,2,...,63.
32*4882a593Smuzhiyun|
33*4882a593Smuzhiyun|	4. Overwrite r := r * log2. Then
34*4882a593Smuzhiyun|		2**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r).
35*4882a593Smuzhiyun|		Go to expr to compute that expression.
36*4882a593Smuzhiyun|
37*4882a593Smuzhiyun|	tentox
38*4882a593Smuzhiyun|	1. If |X| > 16480*log_10(2) (base 10 log of 2), go to ExpBig.
39*4882a593Smuzhiyun|
40*4882a593Smuzhiyun|	2. If |X| < 2**(-70), go to ExpSm.
41*4882a593Smuzhiyun|
42*4882a593Smuzhiyun|	3. Set y := X*log_2(10)*64 (base 2 log of 10). Set
43*4882a593Smuzhiyun|		N := round-to-int(y). Decompose N as
44*4882a593Smuzhiyun|		 N = 64(M + M') + j,  j = 0,1,2,...,63.
45*4882a593Smuzhiyun|
46*4882a593Smuzhiyun|	4. Define r as
47*4882a593Smuzhiyun|		r := ((X - N*L1)-N*L2) * L10
48*4882a593Smuzhiyun|		where L1, L2 are the leading and trailing parts of log_10(2)/64
49*4882a593Smuzhiyun|		and L10 is the natural log of 10. Then
50*4882a593Smuzhiyun|		10**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r).
51*4882a593Smuzhiyun|		Go to expr to compute that expression.
52*4882a593Smuzhiyun|
53*4882a593Smuzhiyun|	expr
54*4882a593Smuzhiyun|	1. Fetch 2**(j/64) from table as Fact1 and Fact2.
55*4882a593Smuzhiyun|
56*4882a593Smuzhiyun|	2. Overwrite Fact1 and Fact2 by
57*4882a593Smuzhiyun|		Fact1 := 2**(M) * Fact1
58*4882a593Smuzhiyun|		Fact2 := 2**(M) * Fact2
59*4882a593Smuzhiyun|		Thus Fact1 + Fact2 = 2**(M) * 2**(j/64).
60*4882a593Smuzhiyun|
61*4882a593Smuzhiyun|	3. Calculate P where 1 + P approximates exp(r):
62*4882a593Smuzhiyun|		P = r + r*r*(A1+r*(A2+...+r*A5)).
63*4882a593Smuzhiyun|
64*4882a593Smuzhiyun|	4. Let AdjFact := 2**(M'). Return
65*4882a593Smuzhiyun|		AdjFact * ( Fact1 + ((Fact1*P) + Fact2) ).
66*4882a593Smuzhiyun|		Exit.
67*4882a593Smuzhiyun|
68*4882a593Smuzhiyun|	ExpBig
69*4882a593Smuzhiyun|	1. Generate overflow by Huge * Huge if X > 0; otherwise, generate
70*4882a593Smuzhiyun|		underflow by Tiny * Tiny.
71*4882a593Smuzhiyun|
72*4882a593Smuzhiyun|	ExpSm
73*4882a593Smuzhiyun|	1. Return 1 + X.
74*4882a593Smuzhiyun|
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun|		Copyright (C) Motorola, Inc. 1990
77*4882a593Smuzhiyun|			All Rights Reserved
78*4882a593Smuzhiyun|
79*4882a593Smuzhiyun|       For details on the license for this file, please see the
80*4882a593Smuzhiyun|       file, README, in this same directory.
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun|STWOTOX	idnt	2,1 | Motorola 040 Floating Point Software Package
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun	|section	8
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun#include "fpsp.h"
87*4882a593Smuzhiyun
88*4882a593SmuzhiyunBOUNDS1:	.long 0x3FB98000,0x400D80C0 | ... 2^(-70),16480
89*4882a593SmuzhiyunBOUNDS2:	.long 0x3FB98000,0x400B9B07 | ... 2^(-70),16480 LOG2/LOG10
90*4882a593Smuzhiyun
91*4882a593SmuzhiyunL2TEN64:	.long 0x406A934F,0x0979A371 | ... 64LOG10/LOG2
92*4882a593SmuzhiyunL10TWO1:	.long 0x3F734413,0x509F8000 | ... LOG2/64LOG10
93*4882a593Smuzhiyun
94*4882a593SmuzhiyunL10TWO2:	.long 0xBFCD0000,0xC0219DC1,0xDA994FD2,0x00000000
95*4882a593Smuzhiyun
96*4882a593SmuzhiyunLOG10:	.long 0x40000000,0x935D8DDD,0xAAA8AC17,0x00000000
97*4882a593Smuzhiyun
98*4882a593SmuzhiyunLOG2:	.long 0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000
99*4882a593Smuzhiyun
100*4882a593SmuzhiyunEXPA5:	.long 0x3F56C16D,0x6F7BD0B2
101*4882a593SmuzhiyunEXPA4:	.long 0x3F811112,0x302C712C
102*4882a593SmuzhiyunEXPA3:	.long 0x3FA55555,0x55554CC1
103*4882a593SmuzhiyunEXPA2:	.long 0x3FC55555,0x55554A54
104*4882a593SmuzhiyunEXPA1:	.long 0x3FE00000,0x00000000,0x00000000,0x00000000
105*4882a593Smuzhiyun
106*4882a593SmuzhiyunHUGE:	.long 0x7FFE0000,0xFFFFFFFF,0xFFFFFFFF,0x00000000
107*4882a593SmuzhiyunTINY:	.long 0x00010000,0xFFFFFFFF,0xFFFFFFFF,0x00000000
108*4882a593Smuzhiyun
109*4882a593SmuzhiyunEXPTBL:
110*4882a593Smuzhiyun	.long  0x3FFF0000,0x80000000,0x00000000,0x3F738000
111*4882a593Smuzhiyun	.long  0x3FFF0000,0x8164D1F3,0xBC030773,0x3FBEF7CA
112*4882a593Smuzhiyun	.long  0x3FFF0000,0x82CD8698,0xAC2BA1D7,0x3FBDF8A9
113*4882a593Smuzhiyun	.long  0x3FFF0000,0x843A28C3,0xACDE4046,0x3FBCD7C9
114*4882a593Smuzhiyun	.long  0x3FFF0000,0x85AAC367,0xCC487B15,0xBFBDE8DA
115*4882a593Smuzhiyun	.long  0x3FFF0000,0x871F6196,0x9E8D1010,0x3FBDE85C
116*4882a593Smuzhiyun	.long  0x3FFF0000,0x88980E80,0x92DA8527,0x3FBEBBF1
117*4882a593Smuzhiyun	.long  0x3FFF0000,0x8A14D575,0x496EFD9A,0x3FBB80CA
118*4882a593Smuzhiyun	.long  0x3FFF0000,0x8B95C1E3,0xEA8BD6E7,0xBFBA8373
119*4882a593Smuzhiyun	.long  0x3FFF0000,0x8D1ADF5B,0x7E5BA9E6,0xBFBE9670
120*4882a593Smuzhiyun	.long  0x3FFF0000,0x8EA4398B,0x45CD53C0,0x3FBDB700
121*4882a593Smuzhiyun	.long  0x3FFF0000,0x9031DC43,0x1466B1DC,0x3FBEEEB0
122*4882a593Smuzhiyun	.long  0x3FFF0000,0x91C3D373,0xAB11C336,0x3FBBFD6D
123*4882a593Smuzhiyun	.long  0x3FFF0000,0x935A2B2F,0x13E6E92C,0xBFBDB319
124*4882a593Smuzhiyun	.long  0x3FFF0000,0x94F4EFA8,0xFEF70961,0x3FBDBA2B
125*4882a593Smuzhiyun	.long  0x3FFF0000,0x96942D37,0x20185A00,0x3FBE91D5
126*4882a593Smuzhiyun	.long  0x3FFF0000,0x9837F051,0x8DB8A96F,0x3FBE8D5A
127*4882a593Smuzhiyun	.long  0x3FFF0000,0x99E04593,0x20B7FA65,0xBFBCDE7B
128*4882a593Smuzhiyun	.long  0x3FFF0000,0x9B8D39B9,0xD54E5539,0xBFBEBAAF
129*4882a593Smuzhiyun	.long  0x3FFF0000,0x9D3ED9A7,0x2CFFB751,0xBFBD86DA
130*4882a593Smuzhiyun	.long  0x3FFF0000,0x9EF53260,0x91A111AE,0xBFBEBEDD
131*4882a593Smuzhiyun	.long  0x3FFF0000,0xA0B0510F,0xB9714FC2,0x3FBCC96E
132*4882a593Smuzhiyun	.long  0x3FFF0000,0xA2704303,0x0C496819,0xBFBEC90B
133*4882a593Smuzhiyun	.long  0x3FFF0000,0xA43515AE,0x09E6809E,0x3FBBD1DB
134*4882a593Smuzhiyun	.long  0x3FFF0000,0xA5FED6A9,0xB15138EA,0x3FBCE5EB
135*4882a593Smuzhiyun	.long  0x3FFF0000,0xA7CD93B4,0xE965356A,0xBFBEC274
136*4882a593Smuzhiyun	.long  0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x3FBEA83C
137*4882a593Smuzhiyun	.long  0x3FFF0000,0xAB7A39B5,0xA93ED337,0x3FBECB00
138*4882a593Smuzhiyun	.long  0x3FFF0000,0xAD583EEA,0x42A14AC6,0x3FBE9301
139*4882a593Smuzhiyun	.long  0x3FFF0000,0xAF3B78AD,0x690A4375,0xBFBD8367
140*4882a593Smuzhiyun	.long  0x3FFF0000,0xB123F581,0xD2AC2590,0xBFBEF05F
141*4882a593Smuzhiyun	.long  0x3FFF0000,0xB311C412,0xA9112489,0x3FBDFB3C
142*4882a593Smuzhiyun	.long  0x3FFF0000,0xB504F333,0xF9DE6484,0x3FBEB2FB
143*4882a593Smuzhiyun	.long  0x3FFF0000,0xB6FD91E3,0x28D17791,0x3FBAE2CB
144*4882a593Smuzhiyun	.long  0x3FFF0000,0xB8FBAF47,0x62FB9EE9,0x3FBCDC3C
145*4882a593Smuzhiyun	.long  0x3FFF0000,0xBAFF5AB2,0x133E45FB,0x3FBEE9AA
146*4882a593Smuzhiyun	.long  0x3FFF0000,0xBD08A39F,0x580C36BF,0xBFBEAEFD
147*4882a593Smuzhiyun	.long  0x3FFF0000,0xBF1799B6,0x7A731083,0xBFBCBF51
148*4882a593Smuzhiyun	.long  0x3FFF0000,0xC12C4CCA,0x66709456,0x3FBEF88A
149*4882a593Smuzhiyun	.long  0x3FFF0000,0xC346CCDA,0x24976407,0x3FBD83B2
150*4882a593Smuzhiyun	.long  0x3FFF0000,0xC5672A11,0x5506DADD,0x3FBDF8AB
151*4882a593Smuzhiyun	.long  0x3FFF0000,0xC78D74C8,0xABB9B15D,0xBFBDFB17
152*4882a593Smuzhiyun	.long  0x3FFF0000,0xC9B9BD86,0x6E2F27A3,0xBFBEFE3C
153*4882a593Smuzhiyun	.long  0x3FFF0000,0xCBEC14FE,0xF2727C5D,0xBFBBB6F8
154*4882a593Smuzhiyun	.long  0x3FFF0000,0xCE248C15,0x1F8480E4,0xBFBCEE53
155*4882a593Smuzhiyun	.long  0x3FFF0000,0xD06333DA,0xEF2B2595,0xBFBDA4AE
156*4882a593Smuzhiyun	.long  0x3FFF0000,0xD2A81D91,0xF12AE45A,0x3FBC9124
157*4882a593Smuzhiyun	.long  0x3FFF0000,0xD4F35AAB,0xCFEDFA1F,0x3FBEB243
158*4882a593Smuzhiyun	.long  0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x3FBDE69A
159*4882a593Smuzhiyun	.long  0x3FFF0000,0xD99D15C2,0x78AFD7B6,0xBFB8BC61
160*4882a593Smuzhiyun	.long  0x3FFF0000,0xDBFBB797,0xDAF23755,0x3FBDF610
161*4882a593Smuzhiyun	.long  0x3FFF0000,0xDE60F482,0x5E0E9124,0xBFBD8BE1
162*4882a593Smuzhiyun	.long  0x3FFF0000,0xE0CCDEEC,0x2A94E111,0x3FBACB12
163*4882a593Smuzhiyun	.long  0x3FFF0000,0xE33F8972,0xBE8A5A51,0x3FBB9BFE
164*4882a593Smuzhiyun	.long  0x3FFF0000,0xE5B906E7,0x7C8348A8,0x3FBCF2F4
165*4882a593Smuzhiyun	.long  0x3FFF0000,0xE8396A50,0x3C4BDC68,0x3FBEF22F
166*4882a593Smuzhiyun	.long  0x3FFF0000,0xEAC0C6E7,0xDD24392F,0xBFBDBF4A
167*4882a593Smuzhiyun	.long  0x3FFF0000,0xED4F301E,0xD9942B84,0x3FBEC01A
168*4882a593Smuzhiyun	.long  0x3FFF0000,0xEFE4B99B,0xDCDAF5CB,0x3FBE8CAC
169*4882a593Smuzhiyun	.long  0x3FFF0000,0xF281773C,0x59FFB13A,0xBFBCBB3F
170*4882a593Smuzhiyun	.long  0x3FFF0000,0xF5257D15,0x2486CC2C,0x3FBEF73A
171*4882a593Smuzhiyun	.long  0x3FFF0000,0xF7D0DF73,0x0AD13BB9,0xBFB8B795
172*4882a593Smuzhiyun	.long  0x3FFF0000,0xFA83B2DB,0x722A033A,0x3FBEF84B
173*4882a593Smuzhiyun	.long  0x3FFF0000,0xFD3E0C0C,0xF486C175,0xBFBEF581
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun	.set	N,L_SCR1
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun	.set	X,FP_SCR1
178*4882a593Smuzhiyun	.set	XDCARE,X+2
179*4882a593Smuzhiyun	.set	XFRAC,X+4
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun	.set	ADJFACT,FP_SCR2
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun	.set	FACT1,FP_SCR3
184*4882a593Smuzhiyun	.set	FACT1HI,FACT1+4
185*4882a593Smuzhiyun	.set	FACT1LOW,FACT1+8
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun	.set	FACT2,FP_SCR4
188*4882a593Smuzhiyun	.set	FACT2HI,FACT2+4
189*4882a593Smuzhiyun	.set	FACT2LOW,FACT2+8
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun	| xref	t_unfl
192*4882a593Smuzhiyun	|xref	t_ovfl
193*4882a593Smuzhiyun	|xref	t_frcinx
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun	.global	stwotoxd
196*4882a593Smuzhiyunstwotoxd:
197*4882a593Smuzhiyun|--ENTRY POINT FOR 2**(X) FOR DENORMALIZED ARGUMENT
198*4882a593Smuzhiyun
199*4882a593Smuzhiyun	fmovel		%d1,%fpcr		| ...set user's rounding mode/precision
200*4882a593Smuzhiyun	fmoves		#0x3F800000,%fp0  | ...RETURN 1 + X
201*4882a593Smuzhiyun	movel		(%a0),%d0
202*4882a593Smuzhiyun	orl		#0x00800001,%d0
203*4882a593Smuzhiyun	fadds		%d0,%fp0
204*4882a593Smuzhiyun	bra		t_frcinx
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun	.global	stwotox
207*4882a593Smuzhiyunstwotox:
208*4882a593Smuzhiyun|--ENTRY POINT FOR 2**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
209*4882a593Smuzhiyun	fmovemx	(%a0),%fp0-%fp0	| ...LOAD INPUT, do not set cc's
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun	movel		(%a0),%d0
212*4882a593Smuzhiyun	movew		4(%a0),%d0
213*4882a593Smuzhiyun	fmovex		%fp0,X(%a6)
214*4882a593Smuzhiyun	andil		#0x7FFFFFFF,%d0
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun	cmpil		#0x3FB98000,%d0		| ...|X| >= 2**(-70)?
217*4882a593Smuzhiyun	bges		TWOOK1
218*4882a593Smuzhiyun	bra		EXPBORS
219*4882a593Smuzhiyun
220*4882a593SmuzhiyunTWOOK1:
221*4882a593Smuzhiyun	cmpil		#0x400D80C0,%d0		| ...|X| > 16480?
222*4882a593Smuzhiyun	bles		TWOMAIN
223*4882a593Smuzhiyun	bra		EXPBORS
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun
226*4882a593SmuzhiyunTWOMAIN:
227*4882a593Smuzhiyun|--USUAL CASE, 2^(-70) <= |X| <= 16480
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun	fmovex		%fp0,%fp1
230*4882a593Smuzhiyun	fmuls		#0x42800000,%fp1  | ...64 * X
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun	fmovel		%fp1,N(%a6)		| ...N = ROUND-TO-INT(64 X)
233*4882a593Smuzhiyun	movel		%d2,-(%sp)
234*4882a593Smuzhiyun	lea		EXPTBL,%a1	| ...LOAD ADDRESS OF TABLE OF 2^(J/64)
235*4882a593Smuzhiyun	fmovel		N(%a6),%fp1		| ...N --> FLOATING FMT
236*4882a593Smuzhiyun	movel		N(%a6),%d0
237*4882a593Smuzhiyun	movel		%d0,%d2
238*4882a593Smuzhiyun	andil		#0x3F,%d0		| ...D0 IS J
239*4882a593Smuzhiyun	asll		#4,%d0		| ...DISPLACEMENT FOR 2^(J/64)
240*4882a593Smuzhiyun	addal		%d0,%a1		| ...ADDRESS FOR 2^(J/64)
241*4882a593Smuzhiyun	asrl		#6,%d2		| ...d2 IS L, N = 64L + J
242*4882a593Smuzhiyun	movel		%d2,%d0
243*4882a593Smuzhiyun	asrl		#1,%d0		| ...D0 IS M
244*4882a593Smuzhiyun	subl		%d0,%d2		| ...d2 IS M', N = 64(M+M') + J
245*4882a593Smuzhiyun	addil		#0x3FFF,%d2
246*4882a593Smuzhiyun	movew		%d2,ADJFACT(%a6)	| ...ADJFACT IS 2^(M')
247*4882a593Smuzhiyun	movel		(%sp)+,%d2
248*4882a593Smuzhiyun|--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64),
249*4882a593Smuzhiyun|--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN.
250*4882a593Smuzhiyun|--ADJFACT = 2^(M').
251*4882a593Smuzhiyun|--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2.
252*4882a593Smuzhiyun
253*4882a593Smuzhiyun	fmuls		#0x3C800000,%fp1  | ...(1/64)*N
254*4882a593Smuzhiyun	movel		(%a1)+,FACT1(%a6)
255*4882a593Smuzhiyun	movel		(%a1)+,FACT1HI(%a6)
256*4882a593Smuzhiyun	movel		(%a1)+,FACT1LOW(%a6)
257*4882a593Smuzhiyun	movew		(%a1)+,FACT2(%a6)
258*4882a593Smuzhiyun	clrw		FACT2+2(%a6)
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun	fsubx		%fp1,%fp0		| ...X - (1/64)*INT(64 X)
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun	movew		(%a1)+,FACT2HI(%a6)
263*4882a593Smuzhiyun	clrw		FACT2HI+2(%a6)
264*4882a593Smuzhiyun	clrl		FACT2LOW(%a6)
265*4882a593Smuzhiyun	addw		%d0,FACT1(%a6)
266*4882a593Smuzhiyun
267*4882a593Smuzhiyun	fmulx		LOG2,%fp0	| ...FP0 IS R
268*4882a593Smuzhiyun	addw		%d0,FACT2(%a6)
269*4882a593Smuzhiyun
270*4882a593Smuzhiyun	bra		expr
271*4882a593Smuzhiyun
272*4882a593SmuzhiyunEXPBORS:
273*4882a593Smuzhiyun|--FPCR, D0 SAVED
274*4882a593Smuzhiyun	cmpil		#0x3FFF8000,%d0
275*4882a593Smuzhiyun	bgts		EXPBIG
276*4882a593Smuzhiyun
277*4882a593SmuzhiyunEXPSM:
278*4882a593Smuzhiyun|--|X| IS SMALL, RETURN 1 + X
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun	fmovel		%d1,%FPCR		|restore users exceptions
281*4882a593Smuzhiyun	fadds		#0x3F800000,%fp0  | ...RETURN 1 + X
282*4882a593Smuzhiyun
283*4882a593Smuzhiyun	bra		t_frcinx
284*4882a593Smuzhiyun
285*4882a593SmuzhiyunEXPBIG:
286*4882a593Smuzhiyun|--|X| IS LARGE, GENERATE OVERFLOW IF X > 0; ELSE GENERATE UNDERFLOW
287*4882a593Smuzhiyun|--REGISTERS SAVE SO FAR ARE FPCR AND  D0
288*4882a593Smuzhiyun	movel		X(%a6),%d0
289*4882a593Smuzhiyun	cmpil		#0,%d0
290*4882a593Smuzhiyun	blts		EXPNEG
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun	bclrb		#7,(%a0)		|t_ovfl expects positive value
293*4882a593Smuzhiyun	bra		t_ovfl
294*4882a593Smuzhiyun
295*4882a593SmuzhiyunEXPNEG:
296*4882a593Smuzhiyun	bclrb		#7,(%a0)		|t_unfl expects positive value
297*4882a593Smuzhiyun	bra		t_unfl
298*4882a593Smuzhiyun
299*4882a593Smuzhiyun	.global	stentoxd
300*4882a593Smuzhiyunstentoxd:
301*4882a593Smuzhiyun|--ENTRY POINT FOR 10**(X) FOR DENORMALIZED ARGUMENT
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun	fmovel		%d1,%fpcr		| ...set user's rounding mode/precision
304*4882a593Smuzhiyun	fmoves		#0x3F800000,%fp0  | ...RETURN 1 + X
305*4882a593Smuzhiyun	movel		(%a0),%d0
306*4882a593Smuzhiyun	orl		#0x00800001,%d0
307*4882a593Smuzhiyun	fadds		%d0,%fp0
308*4882a593Smuzhiyun	bra		t_frcinx
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun	.global	stentox
311*4882a593Smuzhiyunstentox:
312*4882a593Smuzhiyun|--ENTRY POINT FOR 10**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
313*4882a593Smuzhiyun	fmovemx	(%a0),%fp0-%fp0	| ...LOAD INPUT, do not set cc's
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun	movel		(%a0),%d0
316*4882a593Smuzhiyun	movew		4(%a0),%d0
317*4882a593Smuzhiyun	fmovex		%fp0,X(%a6)
318*4882a593Smuzhiyun	andil		#0x7FFFFFFF,%d0
319*4882a593Smuzhiyun
320*4882a593Smuzhiyun	cmpil		#0x3FB98000,%d0		| ...|X| >= 2**(-70)?
321*4882a593Smuzhiyun	bges		TENOK1
322*4882a593Smuzhiyun	bra		EXPBORS
323*4882a593Smuzhiyun
324*4882a593SmuzhiyunTENOK1:
325*4882a593Smuzhiyun	cmpil		#0x400B9B07,%d0		| ...|X| <= 16480*log2/log10 ?
326*4882a593Smuzhiyun	bles		TENMAIN
327*4882a593Smuzhiyun	bra		EXPBORS
328*4882a593Smuzhiyun
329*4882a593SmuzhiyunTENMAIN:
330*4882a593Smuzhiyun|--USUAL CASE, 2^(-70) <= |X| <= 16480 LOG 2 / LOG 10
331*4882a593Smuzhiyun
332*4882a593Smuzhiyun	fmovex		%fp0,%fp1
333*4882a593Smuzhiyun	fmuld		L2TEN64,%fp1	| ...X*64*LOG10/LOG2
334*4882a593Smuzhiyun
335*4882a593Smuzhiyun	fmovel		%fp1,N(%a6)		| ...N=INT(X*64*LOG10/LOG2)
336*4882a593Smuzhiyun	movel		%d2,-(%sp)
337*4882a593Smuzhiyun	lea		EXPTBL,%a1	| ...LOAD ADDRESS OF TABLE OF 2^(J/64)
338*4882a593Smuzhiyun	fmovel		N(%a6),%fp1		| ...N --> FLOATING FMT
339*4882a593Smuzhiyun	movel		N(%a6),%d0
340*4882a593Smuzhiyun	movel		%d0,%d2
341*4882a593Smuzhiyun	andil		#0x3F,%d0		| ...D0 IS J
342*4882a593Smuzhiyun	asll		#4,%d0		| ...DISPLACEMENT FOR 2^(J/64)
343*4882a593Smuzhiyun	addal		%d0,%a1		| ...ADDRESS FOR 2^(J/64)
344*4882a593Smuzhiyun	asrl		#6,%d2		| ...d2 IS L, N = 64L + J
345*4882a593Smuzhiyun	movel		%d2,%d0
346*4882a593Smuzhiyun	asrl		#1,%d0		| ...D0 IS M
347*4882a593Smuzhiyun	subl		%d0,%d2		| ...d2 IS M', N = 64(M+M') + J
348*4882a593Smuzhiyun	addil		#0x3FFF,%d2
349*4882a593Smuzhiyun	movew		%d2,ADJFACT(%a6)	| ...ADJFACT IS 2^(M')
350*4882a593Smuzhiyun	movel		(%sp)+,%d2
351*4882a593Smuzhiyun
352*4882a593Smuzhiyun|--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64),
353*4882a593Smuzhiyun|--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN.
354*4882a593Smuzhiyun|--ADJFACT = 2^(M').
355*4882a593Smuzhiyun|--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2.
356*4882a593Smuzhiyun
357*4882a593Smuzhiyun	fmovex		%fp1,%fp2
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun	fmuld		L10TWO1,%fp1	| ...N*(LOG2/64LOG10)_LEAD
360*4882a593Smuzhiyun	movel		(%a1)+,FACT1(%a6)
361*4882a593Smuzhiyun
362*4882a593Smuzhiyun	fmulx		L10TWO2,%fp2	| ...N*(LOG2/64LOG10)_TRAIL
363*4882a593Smuzhiyun
364*4882a593Smuzhiyun	movel		(%a1)+,FACT1HI(%a6)
365*4882a593Smuzhiyun	movel		(%a1)+,FACT1LOW(%a6)
366*4882a593Smuzhiyun	fsubx		%fp1,%fp0		| ...X - N L_LEAD
367*4882a593Smuzhiyun	movew		(%a1)+,FACT2(%a6)
368*4882a593Smuzhiyun
369*4882a593Smuzhiyun	fsubx		%fp2,%fp0		| ...X - N L_TRAIL
370*4882a593Smuzhiyun
371*4882a593Smuzhiyun	clrw		FACT2+2(%a6)
372*4882a593Smuzhiyun	movew		(%a1)+,FACT2HI(%a6)
373*4882a593Smuzhiyun	clrw		FACT2HI+2(%a6)
374*4882a593Smuzhiyun	clrl		FACT2LOW(%a6)
375*4882a593Smuzhiyun
376*4882a593Smuzhiyun	fmulx		LOG10,%fp0	| ...FP0 IS R
377*4882a593Smuzhiyun
378*4882a593Smuzhiyun	addw		%d0,FACT1(%a6)
379*4882a593Smuzhiyun	addw		%d0,FACT2(%a6)
380*4882a593Smuzhiyun
381*4882a593Smuzhiyunexpr:
382*4882a593Smuzhiyun|--FPCR, FP2, FP3 ARE SAVED IN ORDER AS SHOWN.
383*4882a593Smuzhiyun|--ADJFACT CONTAINS 2**(M'), FACT1 + FACT2 = 2**(M) * 2**(J/64).
384*4882a593Smuzhiyun|--FP0 IS R. THE FOLLOWING CODE COMPUTES
385*4882a593Smuzhiyun|--	2**(M'+M) * 2**(J/64) * EXP(R)
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun	fmovex		%fp0,%fp1
388*4882a593Smuzhiyun	fmulx		%fp1,%fp1		| ...FP1 IS S = R*R
389*4882a593Smuzhiyun
390*4882a593Smuzhiyun	fmoved		EXPA5,%fp2	| ...FP2 IS A5
391*4882a593Smuzhiyun	fmoved		EXPA4,%fp3	| ...FP3 IS A4
392*4882a593Smuzhiyun
393*4882a593Smuzhiyun	fmulx		%fp1,%fp2		| ...FP2 IS S*A5
394*4882a593Smuzhiyun	fmulx		%fp1,%fp3		| ...FP3 IS S*A4
395*4882a593Smuzhiyun
396*4882a593Smuzhiyun	faddd		EXPA3,%fp2	| ...FP2 IS A3+S*A5
397*4882a593Smuzhiyun	faddd		EXPA2,%fp3	| ...FP3 IS A2+S*A4
398*4882a593Smuzhiyun
399*4882a593Smuzhiyun	fmulx		%fp1,%fp2		| ...FP2 IS S*(A3+S*A5)
400*4882a593Smuzhiyun	fmulx		%fp1,%fp3		| ...FP3 IS S*(A2+S*A4)
401*4882a593Smuzhiyun
402*4882a593Smuzhiyun	faddd		EXPA1,%fp2	| ...FP2 IS A1+S*(A3+S*A5)
403*4882a593Smuzhiyun	fmulx		%fp0,%fp3		| ...FP3 IS R*S*(A2+S*A4)
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun	fmulx		%fp1,%fp2		| ...FP2 IS S*(A1+S*(A3+S*A5))
406*4882a593Smuzhiyun	faddx		%fp3,%fp0		| ...FP0 IS R+R*S*(A2+S*A4)
407*4882a593Smuzhiyun
408*4882a593Smuzhiyun	faddx		%fp2,%fp0		| ...FP0 IS EXP(R) - 1
409*4882a593Smuzhiyun
410*4882a593Smuzhiyun
411*4882a593Smuzhiyun|--FINAL RECONSTRUCTION PROCESS
412*4882a593Smuzhiyun|--EXP(X) = 2^M*2^(J/64) + 2^M*2^(J/64)*(EXP(R)-1)  -  (1 OR 0)
413*4882a593Smuzhiyun
414*4882a593Smuzhiyun	fmulx		FACT1(%a6),%fp0
415*4882a593Smuzhiyun	faddx		FACT2(%a6),%fp0
416*4882a593Smuzhiyun	faddx		FACT1(%a6),%fp0
417*4882a593Smuzhiyun
418*4882a593Smuzhiyun	fmovel		%d1,%FPCR		|restore users exceptions
419*4882a593Smuzhiyun	clrw		ADJFACT+2(%a6)
420*4882a593Smuzhiyun	movel		#0x80000000,ADJFACT+4(%a6)
421*4882a593Smuzhiyun	clrl		ADJFACT+8(%a6)
422*4882a593Smuzhiyun	fmulx		ADJFACT(%a6),%fp0	| ...FINAL ADJUSTMENT
423*4882a593Smuzhiyun
424*4882a593Smuzhiyun	bra		t_frcinx
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun	|end
427