xref: /illumos-gate/usr/src/lib/libm/i386/src/locallibm.il (revision 9ef28348)
1/
2/ CDDL HEADER START
3/
4/ The contents of this file are subject to the terms of the
5/ Common Development and Distribution License (the "License").
6/ You may not use this file except in compliance with the License.
7/
8/ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9/ or http://www.opensolaris.org/os/licensing.
10/ See the License for the specific language governing permissions
11/ and limitations under the License.
12/
13/ When distributing Covered Code,  this CDDL HEADER in each
14/ file and  the License file at usr/src/OPENSOLARIS.LICENSE.
15/ If applicable, add the following below this CDDL HEADER, with the
16/ fields enclosed by brackets "[]" replaced with your own identifying
17/ information: Portions Copyright [yyyy] [name of copyright owner]
18/
19/ CDDL HEADER END
20/
21/ Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
22/
23/ Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24/ Use is subject to license terms.
25/
26
27/ Portions of this file are duplicated as GCC inline assembly in
28/ libm_inlines.h.  Keep them in sync.
29
30	.inline	__ieee754_sqrt,0
31	fldl	(%esp)
32	fsqrt
33	.end
34
35	.inline	__inline_rint,0
36	fldl	(%esp)
37        movl	4(%esp),%eax
38        andl	$0x7fffffff,%eax
39        cmpl	$0x43300000,%eax
40        jae	1f
41	frndint
421:
43	fwait		/ in case we jumped around the frndint
44	.end
45
46	.inline	__inline_sqrtf,0
47	flds	(%esp)
48	fsqrt
49	.end
50
51	.inline	__inline_sqrt,0
52	fldl	(%esp)
53	fsqrt
54	.end
55
56	.inline	__inline_fstsw,0
57	fstsw	%ax
58	.end
59
60/
61/ 00 - 24 bits
62/ 01 - reserved
63/ 10 - 53 bits
64/ 11 - 64 bits
65/
66	.inline	__swapRP,0
67	subl	$4,%esp
68	fstcw	(%esp)
69	movw	(%esp),%ax
70	movw	%ax,%cx
71	andw	$0xfcff,%cx
72	movl	4(%esp),%edx		///
73	andl	$0x3,%edx
74	shlw	$8,%dx
75	orw	%dx,%cx
76	movl	%ecx,(%esp)
77	fldcw	(%esp)
78	shrw	$8,%ax
79	andl	$0x3,%eax
80	addl	$4,%esp
81	.end
82
83/
84/ 00 - Round to nearest, with even preferred
85/ 01 - Round down
86/ 10 - Round up
87/ 11 - Chop
88/
89	.inline	__swap87RD,0
90	subl	$4,%esp
91	fstcw	(%esp)
92	movw	(%esp),%ax
93	movw	%ax,%cx
94	andw	$0xf3ff,%cx
95	movl	4(%esp),%edx
96	andl	$0x3,%edx
97	shlw	$10,%dx
98	orw	%dx,%cx
99	movl	%ecx,(%esp)
100	fldcw	(%esp)
101	shrw	$10,%ax
102	andl	$0x3,%eax
103	addl	$4,%esp
104	.end
105
106/
107/	Convert Top-of-Stack to long
108/
109	.inline	__xtol,0
110	subl	$8,%esp			/ 8 bytes of stack space
111	fstcw	2(%esp)			/ byte[2:3] = old_cw
112	movw	2(%esp),%ax
113	andw	$0xf3ff,%ax
114	orw	$0x0c00,%ax		/ RD set to Chop
115	movw	%ax,(%esp)		/ byte[0:1] = new_cw
116	fldcw	(%esp)			/ set new_cw
117	fistpl	4(%esp)			/ byte[4:7] = converted long
118	fstcw	(%esp)			/ restore old RD
119	movw	(%esp),%ax
120	andw	$0xf3ff,%ax
121	movw	2(%esp),%dx
122	andw	$0x0c00,%dx
123	orw	%ax,%dx
124	movw	%dx,2(%esp)
125 	fldcw	2(%esp)
126 	movl	4(%esp),%eax
127	addl	$8,%esp
128	.end
129
130	.inline	ceil,0
131	subl	$8,%esp
132	fstcw	(%esp)
133	fldl	8(%esp)			///
134	movw	(%esp),%cx
135	orw	$0x0c00,%cx
136	xorw	$0x0400,%cx
137	movw	%cx,4(%esp)
138	fldcw	4(%esp)			/ set RD = up
139	frndint
140	fstcw	4(%esp)			/ restore RD
141	movw	4(%esp),%dx
142	andw	$0xf3ff,%dx
143	movw	(%esp),%cx
144	andw	$0x0c00,%cx
145	orw	%dx,%cx
146	movw	%cx,(%esp)
147	fldcw	(%esp)
148	addl	$8,%esp
149	.end
150
151	.inline	copysign,0
152	movl	4(%esp),%eax		/// eax <-- hi_32(x)
153	movl	12(%esp),%ecx		/// ecx <-- hi_32(y)
154	andl	$0x7fffffff,%eax	/ eax <-- hi_32(abs(x))
155	andl	$0x80000000,%ecx	/ ecx[31] <-- sign_bit(y)
156	orl	%ecx,%eax		/ eax <-- hi_32(__copysign(x,y))
157	movl	(%esp),%ecx		/// ecx <-- lo_32(x)
158					/	= lo_32(__copysign(x,y))
159	subl	$8,%esp			/ set up loading dock for result
160	movl	%ecx,(%esp)		/ copy lo_32(result) to loading dock
161	movl	%eax,4(%esp)		/ copy hi_32(result) to loading dock
162	fldl	(%esp)			/ load __copysign(x,y)
163	fwait				/ in case fldl causes exception
164	addl	$8,%esp			/ restore stack-pointer
165	.end
166
167	.inline	__d_sqrt_,0
168	movl	(%esp),%eax
169	fldl	(%eax)
170	fsqrt
171	.end
172
173	.inline	fabs,0
174	fldl	(%esp)			///
175	fabs
176	.end
177
178	.inline	fabsf,0
179	flds	(%esp)
180	fabs
181	.end
182
183	.inline	fabsl,0
184	fldt	(%esp)
185	fabs
186	.end
187
188/
189/	branchless _finite
190/
191	.inline	finite,0
192        movl    4(%esp),%eax		/// eax <-- hi_32(x)
193        notl	%eax			/ not(bexp) = 0 iff bexp = all 1's
194        andl    $0x7ff00000,%eax
195	negl	%eax
196	shrl	$31,%eax
197        .end
198
199	.inline	floor,0
200	subl	$8,%esp
201	fstcw	(%esp)
202	fldl	8(%esp)			///
203	movw	(%esp),%cx
204	orw	$0x0c00,%cx
205	xorw	$0x0800,%cx
206	movw	%cx,4(%esp)
207	fldcw	4(%esp)			/ set RD = down
208	frndint
209	fstcw	4(%esp)			/ restore RD
210	movw	4(%esp),%dx
211	andw	$0xf3ff,%dx
212	movw	(%esp),%cx
213	andw	$0x0c00,%cx
214	orw	%dx,%cx
215	movw	%cx,(%esp)
216	fldcw	(%esp)			/ restore RD
217	addl	$8,%esp
218	.end
219
220	.inline	isnanf,0
221	movl	(%esp),%eax
222	andl	$0x7fffffff,%eax
223	negl	%eax
224	addl	$0x7f800000,%eax
225	shrl	$31,%eax
226	.end
227
228
229	.inline	__isnormal,0
230					/ TRUE iff (x is _finite, but
231					/           neither subnormal nor +/-0)
232					/      iff (0 < bexp(x) < 0x7ff)
233	movl	4(%esp),%eax		/ eax <-- hi_32(x)
234	andl    $0x7ff00000,%eax        / eax[20..30]  <-- bexp(x),
235					/ rest_of(eax) <-- 0
236	pushfl
237	popl    %ecx                    / bit 6 of ecx <-- not bexp(x)
238	subl    $0x7ff00000,%eax
239	pushfl
240	popl    %eax                    / bit 6 of eax <-- not bexp(x)
241	orl     %ecx,%eax
242	andl    $0x40,%eax
243	xorl    $0x40,%eax
244	shrl    $6,%eax
245	.end
246
247	.inline	__issubnormal,0
248					/ TRUE iff (bexp(x) = 0 and
249					/	    frac(x) /= 0)
250	movl    $0,%eax
251        movl    4(%esp),%ecx            / ecx <-- hi_32(x)
252	andl    $0x7fffffff,%ecx        / ecx <-- hi_32(abs(x))
253	cmpl    $0x00100000,%ecx        / is bexp(x) = 0?
254	adcl    $0,%eax                 / jump if bexp(x) = 0
255	orl     (%esp),%ecx             / = 0 iff sgnfcnd(x) = 0
256					/     iff x = +/- 0.0 here
257	pushfl
258	popl    %ecx
259	andl    $0x40,%ecx
260	xorl    $0x40,%ecx
261	shrl    $6,%ecx
262	andl    %ecx,%eax
263	.end
264
265	.inline	__iszero,0
266	movl	4(%esp),%eax		/ eax <-- hi_32(x)
267	andl    $0x7fffffff,%eax        / eax <-- hi_32(abs(x))
268	orl     (%esp),%eax             / = 0 iff x = +/- 0.0
269	pushfl
270	popl    %eax
271	andl    $0x40,%eax
272	shrl    $6,%eax
273	.end
274
275	.inline	__r_sqrt_,0
276	movl	(%esp),%eax
277	flds	(%eax)
278	fsqrt
279	.end
280
281	.inline	rint,0
282	fldl	(%esp)
283        movl	4(%esp),%eax
284        andl	$0x7fffffff,%eax
285        cmpl	$0x43300000,%eax
286        jae	1f
287	frndint
2881:
289	fwait			/ in case we jumped around frndint
290	.end
291
292	.inline	scalbn,0
293	fildl	8(%esp)			/// convert N to extended
294	fldl	(%esp)			/// push x
295	fscale
296	fstp	%st(1)
297	.end
298
299	.inline	signbit,0
300	movl	4(%esp),%eax		/// high part of x
301	shrl	$31,%eax
302	.end
303
304	.inline	signbitf,0
305	movl	(%esp),%eax
306	shrl	$31,%eax
307	.end
308
309	.inline	sqrt,0
310	fldl	(%esp)
311	fsqrt
312	.end
313
314	.inline	sqrtf,0
315	flds	(%esp)
316	fsqrt
317	.end
318
319	.inline	sqrtl,0
320	fldt	(%esp)
321	fsqrt
322	.end
323
324	.inline	isnanl,0
325	movl    8(%esp),%eax            / ax <-- sign bit and __exp
326	andl    $0x00007fff,%eax
327	jz      1f                      / jump if __exp is all 0
328	xorl    $0x00007fff,%eax
329	jz      2f                      / jump if __exp is all 1
330	testl   $0x80000000,4(%esp)
331	jz      3f                      / jump if leading bit is 0
332	movl    $0,%eax
333	jmp     1f
3342:                                      / note that %eax = 0 from before
335	cmpl    $0x80000000,4(%esp)     / what is first half of __significand?
336	jnz     3f                      / jump if not equal to 0x80000000
337	testl   $0xffffffff,(%esp)      / is second half of __significand 0?
338	jnz     3f                      / jump if not equal to 0
339	jmp     1f
3403:
341	movl    $1,%eax
3421:
343	.end
344
345	.inline	__f95_signf,0
346	sub	$4,%esp
347	mov	4(%esp),%edx
348	mov	(%edx),%eax
349	and	$0x7fffffff,%eax
350	mov	8(%esp),%edx
351	mov	(%edx),%ecx
352	and	$0x80000000,%ecx
353	or	%ecx,%eax
354	mov	%eax,(%esp)
355	flds	(%esp)
356	add	$4,%esp
357	.end
358
359	.inline	__f95_sign,0
360	mov	(%esp),%edx
361	fldl	(%edx)
362	fabs
363	mov	4(%esp),%edx
364	mov	4(%edx),%eax
365	test	%eax,%eax
366	jns	1f
367	fchs
3681:
369	.end
370
371