bits 64				;Yeah, baby, 64 bits, c'est plus du p'tit 32, c'est du moderne, du nouveau, du balèze
  
global incDV		;Ici, mon jeune ami, on dit que le label incDV est accessible à qui veut l'appeler.
global incSV
global sqrtDV
global sinDV
global cosDV

section .text align=16	;Oui, une section .text. Admettons 
incDV:
	xor r8, r8			;Une MàZ d'un registre qui va se souvenir de la parité du nombre d'éléments à sommer. Ah ben oui, on fait 2 sommes d'un coup, d'accord, mais si c'est impair ?
	mov rcx, rdi		;Nombre d'éléments à sommer mis dans RCX parce que c'est le registre compteur
	shr rcx, 1			;qu'on divise par 2, parce qu'on va les sommer par 2
	jnc .somme		;Et si la retenue (carry flag) est posée, la taille est impaire
	inc r8				;On se souvient que c'est impair pour plus tard
	test cl, cl;
	jz .dernier
.somme:
	movapd xmm0, oword [rsi];On met dans un registre du processeur à virgule flottante 2 double
	movapd xmm1, oword [rdx];Idem pour l'autre
	addpd xmm0, xmm1	;L'instruction de la somme
	movntpd oword [rsi], xmm0;On stocke le résultat dans l'accumulateur
	add rsi, 16			;On passe à la paire de double suivante
	add rdx, 16			;
	loop .somme			;Et on boucle sur RCX

	cmp r8, 0			;Si la taille des vecteurs est paire
	jz .retour			;Merci, c'est fini. Sinon, c'est impair.
.dernier:
	movsd xmm0, qword [rsi]	;On met dans un registre du processeur à virgule flottante le dernier double
	movsd xmm1, qword [rdx]	;Idem
	addsd xmm0, xmm1	;On fait une seule somme
	movsd qword [rsi], xmm0	;Et donc une seule sauvegarde. Et fin.
	
.retour:
	ret

incSV:
	xor r8, r8		;Une MàZ d'un registre qui va se souvenir de la parité du nombre d'éléments à sommer. Ah ben oui, on fait 2 sommes d'un coup, d'accord, mais si c'est impair ?
	mov rcx, rdi	;Nombre d'éléments à sommer mis dans RCX parce que c'est le registre compteur
	shr rcx, 1		;qu'on divise par 2, parce qu'on va les sommer par 2
	jnc .divPar4	;Et si la retenue (carry flag) est posée, la taille est impaire
	inc r8			;On se souvient que c'est impair pour plus tard
.divPar4:
	shr rcx, 1		;qu'on divise par 2, parce qu'on va les sommer par 2
	jnc .lecture	;Et si la retenue (carry flag) est posée, la taille est impaire
	or r8, 2		;On se souvient que c'est impair pour plus tard
.lecture:
.somme:
	movaps xmm0, oword [rsi];On met dans un registre du processeur à virgule flottante 2 double
	movaps xmm1, oword [rdx];Idem pour l'autre
	addps xmm0, xmm1	;L'instruction de la somme
	movntps oword [rsi], xmm0;On stocke le résultat dans l'accumulateur
	add rsi, 16		;On passe à la paire de double suivante
	add rdx, 16		;
	loop .somme		;Et on boucle sur RCX

	cmp r8, 0		;Si la taille des vecteurs est paire
	je .retour		;Merci, c'est fini. Sinon, c'est impair.
	cmp r8, 2		;Si la taille des vecteurs est paire
	je .pair
	cmp r8, 1
	je .dernier
	jmp .impair
	
.pair:
	movlps xmm0, qword [rsi]	;On met dans un registre du processeur à virgule flottante deux single
	movlps xmm1, qword [rdx]	;Idem
	addps xmm0, xmm1	;On fait les 4 sommes
	movd qword [rsi], xmm0	;On n'en sauve que 2.
	ret
.impair:
	movlps xmm0, qword [rsi]	;On met dans un registre du processeur à virgule flottante deux single
	movlps xmm1, qword [rdx]	;Idem
	addps xmm0, xmm1	;On fait les 4 sommes
	movd qword [rsi], xmm0	;On n'en sauve que 2.
	add rsi, 8	;On passe à la paire de single suivante
	add rdx, 8		;
.dernier:
	movss xmm0, dword [rsi]	;On met dans un registre du processeur à virgule flottante le dernier single
	movss xmm1, dword [rdx]	;Idem
	addss xmm0, xmm1	;On fait une seule somme
	movss dword [rsi], xmm0	;Et donc une seule sauvegarde. Et fin.
	
.retour:
	ret

sqrtDV:
	xor r8, r8		;Une MàZ d'un registre qui va se souvenir de la parité du nombre d'éléments à traiter.
	mov rcx, rdi	;Nombre d'éléments à sommer mis dans RCX parce que c'est le registre compteur
	shr rcx, 1		;qu'on divise par 2, parce qu'on va les traiter par 2
	jnc .racine		;Et si la retenue (carry flag) est posée, la taille est impaire
	inc r8			;On se souvient que c'est impair pour plus tard
	test cl, cl
	jz .dernier
.racine:
	movapd xmm0, oword [rsi];On met dans un registre du processeur à virgule flottante 2 double
	sqrtpd xmm0, xmm0		;L'instruction de la racine carrée
	movntpd oword [rsi], xmm0;On stocke le résultat dans l'accumulateur
	add rsi, 16		;On passe à la paire de double suivante
	loop .racine		;Et on boucle sur RCX

.dernier:
	test r8, r8		;Si la taille des vecteurs est paire
	jz .retour		;Merci, c'est fini. Sinon, c'est impair.
	movsd xmm0, qword [rsi]	;On met dans un registre du processeur à virgule flottante le dernier double
	sqrtsd xmm0, xmm0	;On fait une seule somme
	movsd qword [rsi], xmm0	;Et donc une seule sauvegarde. Et fin.
	
.retour:
	ret

sinDV:
	fldpi
	fadd st0, st0
	mov rcx, rdi					;Nombre d'éléments à traiter mis dans RCX parce que c'est le registre compteur
.sin:
	fld qword [rsi - 8 + 8 * rcx]	;On met dans un registre du processeur à virgule flottante un double
.calcul:
	fsin
	fnstsw ax
	test ax, 0x400
	jnz .prem
	fstp qword [rsi - 8 + 8 * rcx]	;On stocke le résultat
	loop .sin						;Et on boucle sur RCX
	ffree st0
	ret
.prem:
	fprem1
	jmp .calcul

cosDV:
	fldpi
	fadd st0, st0
	mov rcx, rdi					;Nombre d'éléments à traiter mis dans RCX parce que c'est le registre compteur
.cos:
	fld qword [rsi - 8 + 8 * rcx]	;On met dans un registre du processeur à virgule flottante un double
.calcul:
	fcos
	fnstsw ax
	test ax, 0x400
	jnz .prem
	fstp qword [rsi - 8 + 8 * rcx]	;On stocke le résultat
	loop .cos						;Et on boucle sur RCX
	ffree st0
	ret
.prem:
	fprem1
	jmp .calcul
