VirtualBox

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

Last change on this file since 28800 was 18083, checked in by vboxsync, 16 years ago

eol

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.4 KB
Line 
1/* ix87 specific implementation of pow function.
2 Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004 Free Software Founda
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/*#include <machine/asm.h>*/
22#include <iprt/cdefs.h>
23
24#define ALIGNARG(log2) 1<<log2
25#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg;
26#define ASM_SIZE_DIRECTIVE(name) .size name,.-name;
27#define ASM_GLOBAL_DIRECTIVE .global
28
29#define C_LABEL(name) name:
30#define C_SYMBOL_NAME(name) name
31
32#define ENTRY(name) \
33 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
34 ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
35 .align ALIGNARG(4); \
36 C_LABEL(name)
37
38#undef END
39#define END(name) \
40 ASM_SIZE_DIRECTIVE(name)
41
42
43#ifdef __ELF__
44 .section .rodata
45#else
46 .text
47#endif
48
49 .align ALIGNARG(4)
50 ASM_TYPE_DIRECTIVE(infinity,@object)
51inf_zero:
52infinity:
53 .byte 0, 0, 0, 0, 0, 0, 0xf0, 0x7f
54 ASM_SIZE_DIRECTIVE(infinity)
55 ASM_TYPE_DIRECTIVE(zero,@object)
56zero: .double 0.0
57 ASM_SIZE_DIRECTIVE(zero)
58 ASM_TYPE_DIRECTIVE(minf_mzero,@object)
59minf_mzero:
60minfinity:
61 .byte 0, 0, 0, 0, 0, 0, 0xf0, 0xff
62mzero:
63 .byte 0, 0, 0, 0, 0, 0, 0, 0x80
64 ASM_SIZE_DIRECTIVE(minf_mzero)
65 ASM_TYPE_DIRECTIVE(one,@object)
66one: .double 1.0
67 ASM_SIZE_DIRECTIVE(one)
68 ASM_TYPE_DIRECTIVE(limit,@object)
69limit: .double 0.29
70 ASM_SIZE_DIRECTIVE(limit)
71 ASM_TYPE_DIRECTIVE(p63,@object)
72p63:
73 .byte 0, 0, 0, 0, 0, 0, 0xe0, 0x43
74 ASM_SIZE_DIRECTIVE(p63)
75
76//#ifdef PIC
77//#define MO(op) op##(%rip)
78//#else
79#define MO(op) op
80//#endif
81
82 .text
83/*ENTRY(__ieee754_powl)*/
84ENTRY(RT_NOCRT(powl))
85
86 fldt 24(%rsp) // y
87 fxam
88
89
90 fnstsw
91 movb %ah, %dl
92 andb $0x45, %ah
93 cmpb $0x40, %ah // is y == 0 ?
94 je 11f
95
96 cmpb $0x05, %ah // is y == ±inf ?
97 je 12f
98
99 cmpb $0x01, %ah // is y == NaN ?
100 je 30f
101
102 fldt 8(%rsp) // x : y
103
104 fxam
105 fnstsw
106 movb %ah, %dh
107 andb $0x45, %ah
108 cmpb $0x40, %ah
109 je 20f // x is ±0
110
111 cmpb $0x05, %ah
112 je 15f // x is ±inf
113
114 fxch // y : x
115
116 /* fistpll raises invalid exception for |y| >= 1L<<63. */
117 fldl MO(p63) // 1L<<63 : y : x
118 fld %st(1) // y : 1L<<63 : y : x
119 fabs // |y| : 1L<<63 : y : x
120 fcomip %st(1), %st // 1L<<63 : y : x
121 fstp %st(0) // y : x
122 jnc 2f
123
124 /* First see whether `y' is a natural number. In this case we
125 can use a more precise algorithm. */
126 fld %st // y : y : x
127 fistpll -8(%rsp) // y : x
128 fildll -8(%rsp) // int(y) : y : x
129 fucomip %st(1),%st // y : x
130 jne 2f
131
132 /* OK, we have an integer value for y. */
133 mov -8(%rsp),%eax
134 mov -4(%rsp),%edx
135 orl $0, %edx
136 fstp %st(0) // x
137 jns 4f // y >= 0, jump
138 fdivrl MO(one) // 1/x (now referred to as x)
139 negl %eax
140 adcl $0, %edx
141 negl %edx
1424: fldl MO(one) // 1 : x
143 fxch
144
1456: shrdl $1, %edx, %eax
146 jnc 5f
147 fxch
148 fmul %st(1) // x : ST*x
149 fxch
1505: fmul %st(0), %st // x*x : ST*x
151 shrl $1, %edx
152 movl %eax, %ecx
153 orl %edx, %ecx
154 jnz 6b
155 fstp %st(0) // ST*x
156 ret
157
158 /* y is ±NAN */
15930: fldt 8(%rsp) // x : y
160 fldl MO(one) // 1.0 : x : y
161 fucomip %st(1),%st // x : y
162 je 31f
163 fxch // y : x
16431: fstp %st(1)
165 ret
166
167 .align ALIGNARG(4)
1682: /* y is a real number. */
169 fxch // x : y
170 fldl MO(one) // 1.0 : x : y
171 fld %st(1) // x : 1.0 : x : y
172 fsub %st(1) // x-1 : 1.0 : x : y
173 fabs // |x-1| : 1.0 : x : y
174 fcompl MO(limit) // 1.0 : x : y
175 fnstsw
176 fxch // x : 1.0 : y
177 test $4500,%eax
178 jz 7f
179 fsub %st(1) // x-1 : 1.0 : y
180 fyl2xp1 // log2(x) : y
181 jmp 8f
182
1837: fyl2x // log2(x) : y
1848: fmul %st(1) // y*log2(x) : y
185 fxam
186 fnstsw
187 andb $0x45, %ah
188 cmpb $0x05, %ah // is y*log2(x) == ±inf ?
189 je 28f
190 fst %st(1) // y*log2(x) : y*log2(x)
191 frndint // int(y*log2(x)) : y*log2(x)
192 fsubr %st, %st(1) // int(y*log2(x)) : fract(y*log2(x))
193 fxch // fract(y*log2(x)) : int(y*log2(x))
194 f2xm1 // 2^fract(y*log2(x))-1 : int(y*log2(x))
195 faddl MO(one) // 2^fract(y*log2(x)) : int(y*log2(x))
196 fscale // 2^fract(y*log2(x))*2^int(y*log2(x)) : int(y*log2(x))
197 fstp %st(1) // 2^fract(y*log2(x))*2^int(y*log2(x))
198 ret
199
20028: fstp %st(1) // y*log2(x)
201 fldl MO(one) // 1 : y*log2(x)
202 fscale // 2^(y*log2(x)) : y*log2(x)
203 fstp %st(1) // 2^(y*log2(x))
204 ret
205
206 // pow(x,±0) = 1
207 .align ALIGNARG(4)
20811: fstp %st(0) // pop y
209 fldl MO(one)
210 ret
211
212 // y == ±inf
213 .align ALIGNARG(4)
21412: fstp %st(0) // pop y
215 fldt 8(%rsp) // x
216 fabs
217 fcompl MO(one) // < 1, == 1, or > 1
218 fnstsw
219 andb $0x45, %ah
220 cmpb $0x45, %ah
221 je 13f // jump if x is NaN
222
223 cmpb $0x40, %ah
224 je 14f // jump if |x| == 1
225
226 shlb $1, %ah
227 xorb %ah, %dl
228 andl $2, %edx
229#ifdef PIC
230 lea inf_zero(%rip),%rcx
231 fldl (%rcx, %rdx, 4)
232#else
233 fldl inf_zero(,%rdx, 4)
234#endif
235 ret
236
237 .align ALIGNARG(4)
23814: fldl MO(one)
239 ret
240
241 .align ALIGNARG(4)
24213: fldt 8(%rsp) // load x == NaN
243 ret
244
245 .align ALIGNARG(4)
246 // x is ±inf
24715: fstp %st(0) // y
248 testb $2, %dh
249 jz 16f // jump if x == +inf
250
251 // We must find out whether y is an odd integer.
252 fld %st // y : y
253 fistpll -8(%rsp) // y
254 fildll -8(%rsp) // int(y) : y
255 fucomip %st(1),%st
256 ffreep %st // <empty>
257 jne 17f
258
259 // OK, the value is an integer, but is it odd?
260 mov -8(%rsp), %eax
261 mov -4(%rsp), %edx
262 andb $1, %al
263 jz 18f // jump if not odd
264 // It's an odd integer.
265 shrl $31, %edx
266#ifdef PIC
267 lea minf_mzero(%rip),%rcx
268 fldl (%rcx, %rdx, 8)
269#else
270 fldl minf_mzero(,%rdx, 8)
271#endif
272 ret
273
274 .align ALIGNARG(4)
27516: fcompl MO(zero)
276 fnstsw
277 shrl $5, %eax
278 andl $8, %eax
279#ifdef PIC
280 lea inf_zero(%rip),%rcx
281 fldl (%rcx, %rax, 1)
282#else
283 fldl inf_zero(,%rax, 1)
284#endif
285 ret
286
287 .align ALIGNARG(4)
28817: shll $30, %edx // sign bit for y in right position
28918: shrl $31, %edx
290#ifdef PIC
291 lea inf_zero(%rip),%rcx
292 fldl (%rcx, %rdx, 8)
293#else
294 fldl inf_zero(,%rdx, 8)
295#endif
296 ret
297
298 .align ALIGNARG(4)
299 // x is ±0
30020: fstp %st(0) // y
301 testb $2, %dl
302 jz 21f // y > 0
303
304 // x is ±0 and y is < 0. We must find out whether y is an odd integer.
305 testb $2, %dh
306 jz 25f
307
308 fld %st // y : y
309 fistpll -8(%rsp) // y
310 fildll -8(%rsp) // int(y) : y
311 fucomip %st(1),%st
312 ffreep %st // <empty>
313 jne 26f
314
315 // OK, the value is an integer, but is it odd?
316 mov -8(%rsp),%eax
317 mov -4(%rsp),%edx
318 andb $1, %al
319 jz 27f // jump if not odd
320 // It's an odd integer.
321 // Raise divide-by-zero exception and get minus infinity value.
322 fldl MO(one)
323 fdivl MO(zero)
324 fchs
325 ret
326
32725: fstp %st(0)
32826:
32927: // Raise divide-by-zero exception and get infinity value.
330 fldl MO(one)
331 fdivl MO(zero)
332 ret
333
334 .align ALIGNARG(4)
335 // x is ±0 and y is > 0. We must find out whether y is an odd integer.
33621: testb $2, %dh
337 jz 22f
338
339 fld %st // y : y
340 fistpll -8(%rsp) // y
341 fildll -8(%rsp) // int(y) : y
342 fucomip %st(1),%st
343 ffreep %st // <empty>
344 jne 23f
345
346 // OK, the value is an integer, but is it odd?
347 mov -8(%rsp),%eax
348 mov -4(%rsp),%edx
349 andb $1, %al
350 jz 24f // jump if not odd
351 // It's an odd integer.
352 fldl MO(mzero)
353 ret
354
35522: fstp %st(0)
35623:
35724: fldl MO(zero)
358 ret
359
360/*END(__ieee754_powl)*/
361END(RT_NOCRT(powl))
362
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