;/////////////////////////////////////////////////////////////////////////////
;// fpu.asm
;//
;// FPU support code (C Libs replacement)
;//
;// 25/10/1999	fOSSiL		Initial version
;// 2000/01/14	The Owl		nasm port
;// 2000/01/16	The Owl		nasm port


global __CIpow
global __ftol


bits 32


segment _LTEXT

__CIpow:
; C-intrinsic pow()
; this version is almost perfect
; the only limitation is that it will not detect
; attempts to compute things like -3 ^ 1.25
; (as we all know root4(-3) does not have an irrational result)

	fxch	st1
	ftst
	fstsw	[esp-2]
	fabs

	fyl2x	; get y*log x

; split exponent into integer and -1 < 0 < 1 decimal
	fld	st0
	frndint
	fxch	st1
	fsub	st0, st1
	ftst
	fstsw	[esp-4]
	fabs

; compute 2^x (where x is decimal part)
	f2xm1
	fld1
	faddp	st1, st0
	test	byte [esp-3], 1		; is decimal exponent negative ?
	jz	.loc1			; no, skip 1/x calc

	fld1
	fdivrp	st1, st0

.loc1:
	fscale		; compute x *= 2^y

	test	byte [esp-1], 1		; is base value negative ?
	jz	.loc3			; no, no sign change

	fchs

.loc3:
	fxch	st1
	fstp	st0
	retn


__ftol:
; C-intrinsic float-to-longlong (64-bit)
; uses round-up method (important for decoder)

	sub	esp, byte 12

%define lVal esp-8
%define SaveCW esp-10
%define WorkCW esp-12

	fstcw	[SaveCW]
	wait
	mov	ax, [SaveCW]
	or	ah, 0Ch
	mov	[WorkCW], ax
	fldcw	[WorkCW]

	fistp	qword [lVal]

	fldcw	[WorkCW]

	mov	eax, [lVal]
	mov	edx, [lVal+4]

	lea	esp, [esp+12]
	retn
