; =========================================================================
;                  Fast floating point and memory operations
; =========================================================================

%define	ALIGN	4

%ifdef	__WIN32__

; We use stdcall calling convention under Win32
%define	DO_RET(arg)	ret	arg

%define	V_ABS_F		_v_abs_f@4
%define V_FSINCOS_F	_v_fsincos_f@12
%define V_FSINCOS_D	_v_fsincos_d@16
%define MEM_FILL	_memFill@12
%define MEM_ZERO	_memZero@8
%define MEM_COPY	_memCopy@12
%define MEM_FILL32	_memFill32@12
%define MEM_ZERO32	_memZero32@8
%define MEM_COPY32	_memCopy32@12

%endif	; __WIN32__

%ifdef	__UNIX__

; We use cdecl calling convention under UNIX
%define	DO_RET(arg)	ret

%define	V_ABS_F		v_abs_f
%define V_FSINCOS_F	v_fsincos_f
%define V_FSINCOS_D	v_fsincos_d
%define MEM_FILL	memFill
%define MEM_ZERO	memZero
%define MEM_COPY	memCopy
%define MEM_FILL32	memFill32
%define MEM_ZERO32	memZero32
%define MEM_COPY32	memCopy32

%endif	; __UNIX__

; ========================================================================
global V_ABS_F
global V_FSINCOS_F
global V_FSINCOS_D
; ========================================================================
align ALIGN
V_ABS_F:
	and     dword [esp+4], 07fffffffh
	fld     dword [esp+4]
	DO_RET(4)
; ========================================================================
align ALIGN
V_FSINCOS_F:
	fld     dword [esp+12]
	fsincos
	mov     eax, [esp+8]
	mov     edx, [esp+4]
	fstp    dword [eax]
	fstp    dword [edx]
	DO_RET(12)
; ========================================================================
align ALIGN
V_FSINCOS_D:
	fld     qword   [esp+12]
	fsincos
	mov     eax, [esp+8]
	mov     edx, [esp+4]
	fstp    qword   [eax]
	fstp    qword   [edx]
	DO_RET(16)
; ========================================================================
%ifndef	NO_MEMOPS

global MEM_FILL
global MEM_ZERO
global MEM_COPY
global MEM_FILL32
global MEM_ZERO32
global MEM_COPY32

; ========================================================================
align ALIGN
MEM_FILL:
	push    edi
	mov     edi, dword [esp+8]
	mov     al, byte [esp+12]
	mov     edx, dword [esp+16]
	mov     ah, al
	mov     ecx, eax
	shl		eax, 16
	mov     ax, cx
	mov     ecx, edx
	shr     ecx, 2
	rep     stosd
	mov     cl, dl
	and     cl, 3
	rep     stosb
	pop     edi
	DO_RET(12)
; ========================================================================
align ALIGN
MEM_ZERO:
	push    edi
	mov     edi, dword [esp+8]
	mov     edx, dword [esp+12]
	xor     eax, eax
	mov     ecx, edx
	shr     ecx, 2
	rep     stosd
	mov     cl, dl
	and     cl, 3
	rep     stosb
	pop     edi
	DO_RET(8)
; ========================================================================
align ALIGN
MEM_COPY:
	push    edi
	push    esi
	mov     edi, dword [esp+12]
	mov     esi, dword [esp+16]
	mov     eax, dword [esp+20]
	mov     ecx, eax
	shr     ecx, 2
	rep     movsd
	mov     cl, al
	and     cl, 3
	rep     movsb
	pop     esi
	pop     edi
	DO_RET(12)
; ========================================================================
align ALIGN
MEM_FILL32:
	push    edi
	mov     edi, dword [esp+8]
	mov     al, byte [esp+12]
	mov     ah, al
	mov     ecx, eax
	shl		eax, 16
	mov     ax, cx
	mov     ecx, dword [esp+16]
	rep     stosd   
	pop     edi
	DO_RET(12)
; ========================================================================
align ALIGN
MEM_ZERO32:
	push    edi
	xor     eax, eax
	mov     edi, dword [esp+8]
	mov     ecx, dword [esp+12]
	rep     stosd
	pop     edi
	DO_RET(8)
; ========================================================================
align ALIGN
MEM_COPY32:
	push    edi
	push    esi
	mov     ecx, dword [esp+20]
	mov     edi, dword [esp+12]
	mov     esi, dword [esp+16]
	rep     movsd   
	pop     esi
	pop     edi
	DO_RET(12)
; ========================================================================
%endif	; NO_MEMOPS
