Source file: /~heha/hs/Funkuhr.zip/src/amd64.asm

;Zu übersetzen mit YASM; ml64 weigert sich, x87-Kode zu übersetzen
global sincos,llrint,hypotf,mydiv, exp,sin,cos,tan,atan,atan2,log,fmod, sqrt,fsincos

;****************************************************************
;* Integer-Sinus/Kosinusberechnung (fehlt in der Win32-API)	*
;* Parameter: int Radius, int Winkel in Zehntelgrad		*
;* Ergebnis: POINT-Struktur mit 				*
;* x=lrint(cos(Winkel*PI/1800)*Radius) und y=lrint(sin(...	*
;****************************************************************
v180	dw	1800
sincos:
	shl	rcx,32			;Radius
	or	rcx,rdx			;Winkel in Zehntelgrad
	push	rcx			;es können nur 64 Bits gepusht werden
	fild	dword[rsp+4]		;Radius laden
	fild	dword[rsp]		;Winkel laden
	fldpi				;PI laden
	fmulp	st1,st0
	fidiv	word[rel v180]		;jetzt st0 = Winkel im Bogenmaß, st1 = Radius
	fsincos				;st0 = Kosinus, st1 = Sinus, st2 = Radius
	fmul	st0,st2
	fxch	st1			;st0 = Sinus, st1 = Kosinus, st2 = Radius
	fmulp	st2,st0			;st0 = Kosinus, st1 = Sinus
	fistp	dword[rsp]		;Kosinuswert
	fistp	dword[rsp+4]		;Sinuswert
	pop	rax
	ret

;****************************************
;* double -> __int64 mit Rundung	*
;* Standard: Mathematische Rundung,	*
;* also 0,5 -> 0, 1,5 -> 2		*
;* Ersetzt (int)floor(x+0.5)		*
;****************************************
llrint:
	cvtpd2dq xmm0,xmm0		;umwandeln
	movq	rax,xmm0		;dorthin, wo's C erwartet
	ret

;********************************************************
;* Division mit Rest					*
;* Bitbreiten: __int64 / unsigned = int REST unsigned	*
;* Besonderheit: Divisionsergebnis rundet zu -unendlich,*
;* Rest stets >= 0 (und < Divisor natürlich)		*
;* Einschränkung: Divisor darf nicht > INT_MAX sein.	*
;* Ergebnis muss in 32 bit (div_t) passen		*
;********************************************************
mydiv:
	mov	eax,edx
	sar	rdx,32		;mache aus rdx -> edx:eax
	idiv	ecx
	or	edx,edx		;Rest negativ?
	jns	.pos
	dec	eax		;Divisionsergebnis abrunden
	add	edx,ecx		;Rest positiv machen (Voraussetzung: Divisor ist positiv!)
.pos:	shl	rdx,32
	or	rax,rdx		;Returnwert in RAX!
	ret

;************************
;* Hypotenuse berechnen *
;************************
hypotf:				;lohnt nicht so recht
	mulss	xmm0,xmm0
	mulss	xmm1,xmm1
	addss	xmm0,xmm1
	sqrtss	xmm0,xmm0
	ret
;wird für etwas älteren C-Compiler (WinXP SDK) benötigt, nicht für MSVC 2005 und neuer
sqrt:	sqrtsd	xmm0,xmm0
	ret
$fsincos:
	movq	rax,xmm1
	push	rax
	fld	qword[rsp]
	fsincos
	fstp	qword[rcx]
	fstp	qword[rcx+8]
	pop	rax
	ret

;**********************
;* Standardfunktionen *
;**********************
exp:
	movq	rax,xmm0
	push	rax
	fld	qword[rsp]
	fldl2e
	fmulp	st1,st0		;st = f * log2 e
	fld	st0		;duplizieren
	frndint			;st0 = ganzzahliger Teil (Rundung kaufmännisch)
	fsub	st1,st0		;st1 = gebrochener Teil (± 0,5)
	fxch	st1
	f2xm1			;st0 = 2^gebrochener_Teil-1 (f2xm1 kann nur im Intervall ±1 arbeiten!)
	fld1
	faddp	st1,st0		;1 addieren: st0 = 2^gebrochener_Teil
	fscale			;st0 = 2^gebrochener_Teil * 2^ganzzahliger_Teil
pop2:	fstp	st1		;ganzzahligen Teil entfernen
pop1:	fstp	qword[rsp]
	pop	rax
	movq	xmm0,rax
	ret
sin:
	movq	rax,xmm0
	push	rax
	fld	qword[rsp]
	fsin
	jmp	pop1
cos:
	movq	rax,xmm0
	push	rax
	fld	qword[rsp]
	fcos
	jmp	pop1
tan:
	movq	rax,xmm0
	push	rax
	fld	qword[rsp]
	fptan
	fstp	st0
	jmp	pop1
atan:
	xor	eax,eax
	inc	eax
	cvtsi2sd xmm1,eax	;1 laden
atan2:
	movq	rax,xmm0
	push	rax
	fld	qword[rsp]
	movq	[rsp],xmm1
	fld	qword[rsp]
	fpatan
	jmp	pop1
log:
	movq	rax,xmm0
	push	rax
	fldln2
	fld	qword[rsp]
	fyl2x
	jmp	pop1
fmod:
	movq	rax,xmm1	;Argumente verkehrt herum laden
	push	rax
	fld	qword[rsp]
	movq	[rsp],xmm0
	fld	qword[rsp]
	fprem			;Modulo-Division, 0<=Ergebnis<Divisor (Divisor>0)
	jmp	pop2		;st1 entfernen und st0 liefern
end
Detected encoding: ANSI (CP1252)4
Wrong umlauts? - Assume file is ANSI (CP1252) encoded