summaryrefslogtreecommitdiffstats
path: root/mdk-stage1/dietlibc/i386/pow.S
blob: 46562a299194f91450e61e00dfb1c875e5b32354 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
.text
.global pow
.type   pow,@function

# pow(x,y)
.global powf,pow,powl
	.type	powf,@function
	.type	pow,@function
	.type	powl,@function
powf:
	flds 4(%esp)	# x
	flds 8(%esp)	# y
	jmp .L__pow
powl:
	fldt 4(%esp)
	fldt 16(%esp)
	jmp .L__pow
pow:
	fldl 4(%esp)
	fldl 12(%esp)
# x^y; st(0)=y, st(1)=x
.L__pow:
	ftst		# y = 0 ?
	fstsw %ax
	fld1		# st(0)=1, st(1)=y, st(2)=x
	sahf
	jz 1f		# return 1
	fcomp %st(1)	# y = 1 ?
	fstsw %ax
	fxch		# st(0)=x, st(1)=y
	sahf
	jz 1f		# return x
	ftst		# x = 0 ?
	fstsw %ax
	sahf
	jz 1f
	jnc .Lfinpow	# x > 0
	fxch		# st(0)=y, st(1)=x
	fld %st(0)	# st(0)=y, st(1)=y, st(2)=x
	frndint		# st(0)=int(y)
	fcomp %st(1)	# y = int(y)?
	fstsw %ax
	fxch
	sahf
	jnz .Lfinpow	# fyl2x -> st(0) = NaN
# y even or odd ?
	fld1
	fadd %st(0)	# st(0) = 2
	fdivr %st(2),%st(0) # st(0)=st(2)/2
	frndint
	fadd %st(0),%st(0)
	fcomp %st(2)	# st(0) = x, st(1) = y
	fstsw %ax
	fchs		# st(0) = -x
	sahf
	jz .Lfinpow	# y even
	call .Lfinpow	# y odd
	fchs
1:	ret
.Lfinpow:
	fyl2x
	jmp __finexp

.Lende:
.size    pow,.Lende-pow
.size    powf,.Lende-powf
.size    powl,.Lende-powl