VirtualBox

source: vbox/trunk/src/recompiler/Sun/e_powl-amd64.S@ 80990

Last change on this file since 80990 was 69505, checked in by vboxsync, 7 years ago

More scm updates

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 7.9 KB
Line 
1/* ix87 specific implementation of pow function.
2 Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004 Free Software Foundation
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <[email protected]>, 1996.
5
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA. */
20
21/*
22 * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
23 * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
24 * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
25 * a choice of LGPL license versions is made available with the language indicating
26 * that LGPLv2 or any later version may be used, or where a choice of which version
27 * of the LGPL is applied is otherwise unspecified.
28 */
29
30/*#include <machine/asm.h>*/
31#include <iprt/cdefs.h>
32
33#define ALIGNARG(log2) 1<<log2
34#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg;
35#define ASM_SIZE_DIRECTIVE(name) .size name,.-name;
36#define ASM_GLOBAL_DIRECTIVE .global
37
38#define C_LABEL(name) name:
39#define C_SYMBOL_NAME(name) name
40
41#define ENTRY(name) \
42 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
43 ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
44 .align ALIGNARG(4); \
45 C_LABEL(name)
46
47#undef END
48#define END(name) \
49 ASM_SIZE_DIRECTIVE(name)
50
51
52#ifdef __ELF__
53 .section .rodata
54#else
55 .text
56#endif
57
58 .align ALIGNARG(4)
59 ASM_TYPE_DIRECTIVE(infinity,@object)
60inf_zero:
61infinity:
62 .byte 0, 0, 0, 0, 0, 0, 0xf0, 0x7f
63 ASM_SIZE_DIRECTIVE(infinity)
64 ASM_TYPE_DIRECTIVE(zero,@object)
65zero: .double 0.0
66 ASM_SIZE_DIRECTIVE(zero)
67 ASM_TYPE_DIRECTIVE(minf_mzero,@object)
68minf_mzero:
69minfinity:
70 .byte 0, 0, 0, 0, 0, 0, 0xf0, 0xff
71mzero:
72 .byte 0, 0, 0, 0, 0, 0, 0, 0x80
73 ASM_SIZE_DIRECTIVE(minf_mzero)
74 ASM_TYPE_DIRECTIVE(one,@object)
75one: .double 1.0
76 ASM_SIZE_DIRECTIVE(one)
77 ASM_TYPE_DIRECTIVE(limit,@object)
78limit: .double 0.29
79 ASM_SIZE_DIRECTIVE(limit)
80 ASM_TYPE_DIRECTIVE(p63,@object)
81p63:
82 .byte 0, 0, 0, 0, 0, 0, 0xe0, 0x43
83 ASM_SIZE_DIRECTIVE(p63)
84
85//#ifdef PIC
86//#define MO(op) op##(%rip)
87//#else
88#define MO(op) op
89//#endif
90
91 .text
92/*ENTRY(__ieee754_powl)*/
93ENTRY(RT_NOCRT(powl))
94
95 fldt 24(%rsp) // y
96 fxam
97
98
99 fnstsw
100 movb %ah, %dl
101 andb $0x45, %ah
102 cmpb $0x40, %ah // is y == 0 ?
103 je 11f
104
105 cmpb $0x05, %ah // is y == ±inf ?
106 je 12f
107
108 cmpb $0x01, %ah // is y == NaN ?
109 je 30f
110
111 fldt 8(%rsp) // x : y
112
113 fxam
114 fnstsw
115 movb %ah, %dh
116 andb $0x45, %ah
117 cmpb $0x40, %ah
118 je 20f // x is ±0
119
120 cmpb $0x05, %ah
121 je 15f // x is ±inf
122
123 fxch // y : x
124
125 /* fistpll raises invalid exception for |y| >= 1L<<63. */
126 fldl MO(p63) // 1L<<63 : y : x
127 fld %st(1) // y : 1L<<63 : y : x
128 fabs // |y| : 1L<<63 : y : x
129 fcomip %st(1), %st // 1L<<63 : y : x
130 fstp %st(0) // y : x
131 jnc 2f
132
133 /* First see whether `y' is a natural number. In this case we
134 can use a more precise algorithm. */
135 fld %st // y : y : x
136 fistpll -8(%rsp) // y : x
137 fildll -8(%rsp) // int(y) : y : x
138 fucomip %st(1),%st // y : x
139 jne 2f
140
141 /* OK, we have an integer value for y. */
142 mov -8(%rsp),%eax
143 mov -4(%rsp),%edx
144 orl $0, %edx
145 fstp %st(0) // x
146 jns 4f // y >= 0, jump
147 fdivrl MO(one) // 1/x (now referred to as x)
148 negl %eax
149 adcl $0, %edx
150 negl %edx
1514: fldl MO(one) // 1 : x
152 fxch
153
1546: shrdl $1, %edx, %eax
155 jnc 5f
156 fxch
157 fmul %st(1) // x : ST*x
158 fxch
1595: fmul %st(0), %st // x*x : ST*x
160 shrl $1, %edx
161 movl %eax, %ecx
162 orl %edx, %ecx
163 jnz 6b
164 fstp %st(0) // ST*x
165 ret
166
167 /* y is ±NAN */
16830: fldt 8(%rsp) // x : y
169 fldl MO(one) // 1.0 : x : y
170 fucomip %st(1),%st // x : y
171 je 31f
172 fxch // y : x
17331: fstp %st(1)
174 ret
175
176 .align ALIGNARG(4)
1772: /* y is a real number. */
178 fxch // x : y
179 fldl MO(one) // 1.0 : x : y
180 fld %st(1) // x : 1.0 : x : y
181 fsub %st(1) // x-1 : 1.0 : x : y
182 fabs // |x-1| : 1.0 : x : y
183 fcompl MO(limit) // 1.0 : x : y
184 fnstsw
185 fxch // x : 1.0 : y
186 test $4500,%eax
187 jz 7f
188 fsub %st(1) // x-1 : 1.0 : y
189 fyl2xp1 // log2(x) : y
190 jmp 8f
191
1927: fyl2x // log2(x) : y
1938: fmul %st(1) // y*log2(x) : y
194 fxam
195 fnstsw
196 andb $0x45, %ah
197 cmpb $0x05, %ah // is y*log2(x) == ±inf ?
198 je 28f
199 fst %st(1) // y*log2(x) : y*log2(x)
200 frndint // int(y*log2(x)) : y*log2(x)
201 fsubr %st, %st(1) // int(y*log2(x)) : fract(y*log2(x))
202 fxch // fract(y*log2(x)) : int(y*log2(x))
203 f2xm1 // 2^fract(y*log2(x))-1 : int(y*log2(x))
204 faddl MO(one) // 2^fract(y*log2(x)) : int(y*log2(x))
205 fscale // 2^fract(y*log2(x))*2^int(y*log2(x)) : int(y*log2(x))
206 fstp %st(1) // 2^fract(y*log2(x))*2^int(y*log2(x))
207 ret
208
20928: fstp %st(1) // y*log2(x)
210 fldl MO(one) // 1 : y*log2(x)
211 fscale // 2^(y*log2(x)) : y*log2(x)
212 fstp %st(1) // 2^(y*log2(x))
213 ret
214
215 // pow(x,±0) = 1
216 .align ALIGNARG(4)
21711: fstp %st(0) // pop y
218 fldl MO(one)
219 ret
220
221 // y == ±inf
222 .align ALIGNARG(4)
22312: fstp %st(0) // pop y
224 fldt 8(%rsp) // x
225 fabs
226 fcompl MO(one) // < 1, == 1, or > 1
227 fnstsw
228 andb $0x45, %ah
229 cmpb $0x45, %ah
230 je 13f // jump if x is NaN
231
232 cmpb $0x40, %ah
233 je 14f // jump if |x| == 1
234
235 shlb $1, %ah
236 xorb %ah, %dl
237 andl $2, %edx
238#ifdef PIC
239 lea inf_zero(%rip),%rcx
240 fldl (%rcx, %rdx, 4)
241#else
242 fldl inf_zero(,%rdx, 4)
243#endif
244 ret
245
246 .align ALIGNARG(4)
24714: fldl MO(one)
248 ret
249
250 .align ALIGNARG(4)
25113: fldt 8(%rsp) // load x == NaN
252 ret
253
254 .align ALIGNARG(4)
255 // x is ±inf
25615: fstp %st(0) // y
257 testb $2, %dh
258 jz 16f // jump if x == +inf
259
260 // We must find out whether y is an odd integer.
261 fld %st // y : y
262 fistpll -8(%rsp) // y
263 fildll -8(%rsp) // int(y) : y
264 fucomip %st(1),%st
265 ffreep %st // <empty>
266 jne 17f
267
268 // OK, the value is an integer, but is it odd?
269 mov -8(%rsp), %eax
270 mov -4(%rsp), %edx
271 andb $1, %al
272 jz 18f // jump if not odd
273 // It's an odd integer.
274 shrl $31, %edx
275#ifdef PIC
276 lea minf_mzero(%rip),%rcx
277 fldl (%rcx, %rdx, 8)
278#else
279 fldl minf_mzero(,%rdx, 8)
280#endif
281 ret
282
283 .align ALIGNARG(4)
28416: fcompl MO(zero)
285 fnstsw
286 shrl $5, %eax
287 andl $8, %eax
288#ifdef PIC
289 lea inf_zero(%rip),%rcx
290 fldl (%rcx, %rax, 1)
291#else
292 fldl inf_zero(,%rax, 1)
293#endif
294 ret
295
296 .align ALIGNARG(4)
29717: shll $30, %edx // sign bit for y in right position
29818: shrl $31, %edx
299#ifdef PIC
300 lea inf_zero(%rip),%rcx
301 fldl (%rcx, %rdx, 8)
302#else
303 fldl inf_zero(,%rdx, 8)
304#endif
305 ret
306
307 .align ALIGNARG(4)
308 // x is ±0
30920: fstp %st(0) // y
310 testb $2, %dl
311 jz 21f // y > 0
312
313 // x is ±0 and y is < 0. We must find out whether y is an odd integer.
314 testb $2, %dh
315 jz 25f
316
317 fld %st // y : y
318 fistpll -8(%rsp) // y
319 fildll -8(%rsp) // int(y) : y
320 fucomip %st(1),%st
321 ffreep %st // <empty>
322 jne 26f
323
324 // OK, the value is an integer, but is it odd?
325 mov -8(%rsp),%eax
326 mov -4(%rsp),%edx
327 andb $1, %al
328 jz 27f // jump if not odd
329 // It's an odd integer.
330 // Raise divide-by-zero exception and get minus infinity value.
331 fldl MO(one)
332 fdivl MO(zero)
333 fchs
334 ret
335
33625: fstp %st(0)
33726:
33827: // Raise divide-by-zero exception and get infinity value.
339 fldl MO(one)
340 fdivl MO(zero)
341 ret
342
343 .align ALIGNARG(4)
344 // x is ±0 and y is > 0. We must find out whether y is an odd integer.
34521: testb $2, %dh
346 jz 22f
347
348 fld %st // y : y
349 fistpll -8(%rsp) // y
350 fildll -8(%rsp) // int(y) : y
351 fucomip %st(1),%st
352 ffreep %st // <empty>
353 jne 23f
354
355 // OK, the value is an integer, but is it odd?
356 mov -8(%rsp),%eax
357 mov -4(%rsp),%edx
358 andb $1, %al
359 jz 24f // jump if not odd
360 // It's an odd integer.
361 fldl MO(mzero)
362 ret
363
36422: fstp %st(0)
36523:
36624: fldl MO(zero)
367 ret
368
369/*END(__ieee754_powl)*/
370END(RT_NOCRT(powl))
371
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette