VirtualBox

source: vbox/trunk/src/recompiler/Sun/e_powl-x86.S@ 76553

Last change on this file since 76553 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: 9.1 KB
Line 
1/* ix87 specific implementation of pow function.
2 Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2005
3 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
5 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
6
7 The GNU C Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 The GNU C Library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with the GNU C Library; if not, write to the Free
19 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 02111-1307 USA. */
21
22/*
23 * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
24 * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
25 * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
26 * a choice of LGPL license versions is made available with the language indicating
27 * that LGPLv2 or any later version may be used, or where a choice of which version
28 * of the LGPL is applied is otherwise unspecified.
29 */
30
31/*#include <machine/asm.h>*/
32#include <iprt/cdefs.h>
33
34#ifdef __MINGW32__
35# define ASM_TYPE_DIRECTIVE(name,typearg)
36# define ASM_SIZE_DIRECTIVE(name)
37# define cfi_adjust_cfa_offset(a)
38# define C_LABEL(name) _ ## name:
39# define C_SYMBOL_NAME(name) _ ## name
40# define ASM_GLOBAL_DIRECTIVE .global
41# define ALIGNARG(log2) 1<<log2
42#elif __APPLE__
43# define ASM_TYPE_DIRECTIVE(name,typearg)
44# define ASM_SIZE_DIRECTIVE(name)
45# define cfi_adjust_cfa_offset(a)
46# define C_LABEL(name) _ ## name:
47# define C_SYMBOL_NAME(name) _ ## name
48# define ASM_GLOBAL_DIRECTIVE .globl
49# define ALIGNARG(log2) log2
50#else
51# define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg;
52# define ASM_SIZE_DIRECTIVE(name) .size name,.-name;
53# define C_LABEL(name) name:
54# define C_SYMBOL_NAME(name) name
55# /* figure this one out. */
56# define cfi_adjust_cfa_offset(a)
57# define ASM_GLOBAL_DIRECTIVE .global
58# define ALIGNARG(log2) 1<<log2
59#endif
60
61#define ENTRY(name) \
62 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
63 ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
64 .align ALIGNARG(4); \
65 C_LABEL(name)
66
67#undef END
68#define END(name) \
69 ASM_SIZE_DIRECTIVE(name)
70
71#ifdef __ELF__
72 .section .rodata
73#else
74 .text
75#endif
76
77 .align ALIGNARG(4)
78 ASM_TYPE_DIRECTIVE(infinity,@object)
79inf_zero:
80infinity:
81 .byte 0, 0, 0, 0, 0, 0, 0xf0, 0x7f
82 ASM_SIZE_DIRECTIVE(infinity)
83 ASM_TYPE_DIRECTIVE(zero,@object)
84zero: .double 0.0
85 ASM_SIZE_DIRECTIVE(zero)
86 ASM_TYPE_DIRECTIVE(minf_mzero,@object)
87minf_mzero:
88minfinity:
89 .byte 0, 0, 0, 0, 0, 0, 0xf0, 0xff
90mzero:
91 .byte 0, 0, 0, 0, 0, 0, 0, 0x80
92 ASM_SIZE_DIRECTIVE(minf_mzero)
93 ASM_TYPE_DIRECTIVE(one,@object)
94one: .double 1.0
95 ASM_SIZE_DIRECTIVE(one)
96 ASM_TYPE_DIRECTIVE(limit,@object)
97limit: .double 0.29
98 ASM_SIZE_DIRECTIVE(limit)
99 ASM_TYPE_DIRECTIVE(p63,@object)
100p63: .byte 0, 0, 0, 0, 0, 0, 0xe0, 0x43
101 ASM_SIZE_DIRECTIVE(p63)
102
103#ifdef PIC
104#define MO(op) op##@GOTOFF(%ecx)
105#define MOX(op,x,f) op##@GOTOFF(%ecx,x,f)
106#else
107#define MO(op) op
108#define MOX(op,x,f) op(,x,f)
109#endif
110
111 .text
112//ENTRY(__ieee754_powl)
113ENTRY(RT_NOCRT(powl))
114#ifdef RT_OS_DARWIN /* 16-byte long double with 8 byte alignment requirements */
115 fldt 20(%esp) // y
116#else
117 fldt 16(%esp) // y
118#endif
119 fxam
120
121#ifdef PIC
122 LOAD_PIC_REG (cx)
123#endif
124
125 fnstsw
126 movb %ah, %dl
127 andb $0x45, %ah
128 cmpb $0x40, %ah // is y == 0 ?
129 je .L11
130
131 cmpb $0x05, %ah // is y == ±inf ?
132 je .L12
133
134 cmpb $0x01, %ah // is y == NaN ?
135 je .L30
136
137 fldt 4(%esp) // x : y
138
139 subl $8,%esp
140 cfi_adjust_cfa_offset (8)
141
142 fxam
143 fnstsw
144 movb %ah, %dh
145 andb $0x45, %ah
146 cmpb $0x40, %ah
147 je .L20 // x is ±0
148
149 cmpb $0x05, %ah
150 je .L15 // x is ±inf
151
152 fxch // y : x
153
154 /* fistpll raises invalid exception for |y| >= 1L<<63. */
155 fld %st // y : y : x
156 fabs // |y| : y : x
157 fcompl MO(p63) // y : x
158 fnstsw
159 sahf
160 jnc .L2
161
162 /* First see whether `y' is a natural number. In this case we
163 can use a more precise algorithm. */
164 fld %st // y : y : x
165 fistpll (%esp) // y : x
166 fildll (%esp) // int(y) : y : x
167 fucomp %st(1) // y : x
168 fnstsw
169 sahf
170 jne .L2
171
172 /* OK, we have an integer value for y. */
173 popl %eax
174 cfi_adjust_cfa_offset (-4)
175 popl %edx
176 cfi_adjust_cfa_offset (-4)
177 orl $0, %edx
178 fstp %st(0) // x
179 jns .L4 // y >= 0, jump
180 fdivrl MO(one) // 1/x (now referred to as x)
181 negl %eax
182 adcl $0, %edx
183 negl %edx
184.L4: fldl MO(one) // 1 : x
185 fxch
186
187.L6: shrdl $1, %edx, %eax
188 jnc .L5
189 fxch
190 fmul %st(1) // x : ST*x
191 fxch
192.L5: fmul %st(0), %st // x*x : ST*x
193 shrl $1, %edx
194 movl %eax, %ecx
195 orl %edx, %ecx
196 jnz .L6
197 fstp %st(0) // ST*x
198 ret
199
200 /* y is ±NAN */
201.L30: fldt 4(%esp) // x : y
202 fldl MO(one) // 1.0 : x : y
203 fucomp %st(1) // x : y
204 fnstsw
205 sahf
206 je .L31
207 fxch // y : x
208.L31: fstp %st(1)
209 ret
210
211 cfi_adjust_cfa_offset (8)
212 .align ALIGNARG(4)
213.L2: /* y is a real number. */
214 fxch // x : y
215 fldl MO(one) // 1.0 : x : y
216 fld %st(1) // x : 1.0 : x : y
217 fsub %st(1) // x-1 : 1.0 : x : y
218 fabs // |x-1| : 1.0 : x : y
219 fcompl MO(limit) // 1.0 : x : y
220 fnstsw
221 fxch // x : 1.0 : y
222 sahf
223 ja .L7
224 fsub %st(1) // x-1 : 1.0 : y
225 fyl2xp1 // log2(x) : y
226 jmp .L8
227
228.L7: fyl2x // log2(x) : y
229.L8: fmul %st(1) // y*log2(x) : y
230 fxam
231 fnstsw
232 andb $0x45, %ah
233 cmpb $0x05, %ah // is y*log2(x) == ±inf ?
234 je .L28
235 fst %st(1) // y*log2(x) : y*log2(x)
236 frndint // int(y*log2(x)) : y*log2(x)
237 fsubr %st, %st(1) // int(y*log2(x)) : fract(y*log2(x))
238 fxch // fract(y*log2(x)) : int(y*log2(x))
239 f2xm1 // 2^fract(y*log2(x))-1 : int(y*log2(x))
240 faddl MO(one) // 2^fract(y*log2(x)) : int(y*log2(x))
241 fscale // 2^fract(y*log2(x))*2^int(y*log2(x)) : int(y*log2(x))
242 addl $8, %esp
243 cfi_adjust_cfa_offset (-8)
244 fstp %st(1) // 2^fract(y*log2(x))*2^int(y*log2(x))
245 ret
246
247 cfi_adjust_cfa_offset (8)
248.L28: fstp %st(1) // y*log2(x)
249 fldl MO(one) // 1 : y*log2(x)
250 fscale // 2^(y*log2(x)) : y*log2(x)
251 addl $8, %esp
252 cfi_adjust_cfa_offset (-8)
253 fstp %st(1) // 2^(y*log2(x))
254 ret
255
256 // pow(x,±0) = 1
257 .align ALIGNARG(4)
258.L11: fstp %st(0) // pop y
259 fldl MO(one)
260 ret
261
262 // y == ±inf
263 .align ALIGNARG(4)
264.L12: fstp %st(0) // pop y
265 fldt 4(%esp) // x
266 fabs
267 fcompl MO(one) // < 1, == 1, or > 1
268 fnstsw
269 andb $0x45, %ah
270 cmpb $0x45, %ah
271 je .L13 // jump if x is NaN
272
273 cmpb $0x40, %ah
274 je .L14 // jump if |x| == 1
275
276 shlb $1, %ah
277 xorb %ah, %dl
278 andl $2, %edx
279 fldl MOX(inf_zero, %edx, 4)
280 ret
281
282 .align ALIGNARG(4)
283.L14: fldl MO(one)
284 ret
285
286 .align ALIGNARG(4)
287.L13: fldt 4(%esp) // load x == NaN
288 ret
289
290 cfi_adjust_cfa_offset (8)
291 .align ALIGNARG(4)
292 // x is ±inf
293.L15: fstp %st(0) // y
294 testb $2, %dh
295 jz .L16 // jump if x == +inf
296
297 // We must find out whether y is an odd integer.
298 fld %st // y : y
299 fistpll (%esp) // y
300 fildll (%esp) // int(y) : y
301 fucompp // <empty>
302 fnstsw
303 sahf
304 jne .L17
305
306 // OK, the value is an integer, but is it odd?
307 popl %eax
308 cfi_adjust_cfa_offset (-4)
309 popl %edx
310 cfi_adjust_cfa_offset (-4)
311 andb $1, %al
312 jz .L18 // jump if not odd
313 // It's an odd integer.
314 shrl $31, %edx
315 fldl MOX(minf_mzero, %edx, 8)
316 ret
317
318 cfi_adjust_cfa_offset (8)
319 .align ALIGNARG(4)
320.L16: fcompl MO(zero)
321 addl $8, %esp
322 cfi_adjust_cfa_offset (-8)
323 fnstsw
324 shrl $5, %eax
325 andl $8, %eax
326 fldl MOX(inf_zero, %eax, 1)
327 ret
328
329 cfi_adjust_cfa_offset (8)
330 .align ALIGNARG(4)
331.L17: shll $30, %edx // sign bit for y in right position
332 addl $8, %esp
333 cfi_adjust_cfa_offset (-8)
334.L18: shrl $31, %edx
335 fldl MOX(inf_zero, %edx, 8)
336 ret
337
338 cfi_adjust_cfa_offset (8)
339 .align ALIGNARG(4)
340 // x is ±0
341.L20: fstp %st(0) // y
342 testb $2, %dl
343 jz .L21 // y > 0
344
345 // x is ±0 and y is < 0. We must find out whether y is an odd integer.
346 testb $2, %dh
347 jz .L25
348
349 fld %st // y : y
350 fistpll (%esp) // y
351 fildll (%esp) // int(y) : y
352 fucompp // <empty>
353 fnstsw
354 sahf
355 jne .L26
356
357 // OK, the value is an integer, but is it odd?
358 popl %eax
359 cfi_adjust_cfa_offset (-4)
360 popl %edx
361 cfi_adjust_cfa_offset (-4)
362 andb $1, %al
363 jz .L27 // jump if not odd
364 // It's an odd integer.
365 // Raise divide-by-zero exception and get minus infinity value.
366 fldl MO(one)
367 fdivl MO(zero)
368 fchs
369 ret
370
371 cfi_adjust_cfa_offset (8)
372.L25: fstp %st(0)
373.L26: addl $8, %esp
374 cfi_adjust_cfa_offset (-8)
375.L27: // Raise divide-by-zero exception and get infinity value.
376 fldl MO(one)
377 fdivl MO(zero)
378 ret
379
380 cfi_adjust_cfa_offset (8)
381 .align ALIGNARG(4)
382 // x is ±0 and y is > 0. We must find out whether y is an odd integer.
383.L21: testb $2, %dh
384 jz .L22
385
386 fld %st // y : y
387 fistpll (%esp) // y
388 fildll (%esp) // int(y) : y
389 fucompp // <empty>
390 fnstsw
391 sahf
392 jne .L23
393
394 // OK, the value is an integer, but is it odd?
395 popl %eax
396 cfi_adjust_cfa_offset (-4)
397 popl %edx
398 cfi_adjust_cfa_offset (-4)
399 andb $1, %al
400 jz .L24 // jump if not odd
401 // It's an odd integer.
402 fldl MO(mzero)
403 ret
404
405 cfi_adjust_cfa_offset (8)
406.L22: fstp %st(0)
407.L23: addl $8, %esp // Don't use 2 x pop
408 cfi_adjust_cfa_offset (-8)
409.L24: fldl MO(zero)
410 ret
411
412END(RT_NOCRT(powl))
413//END(__ieee754_powl)
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use