; image_simd.asm
;
; MI01 - TP Assembleur 2 à 5
;
; Réalise le traitement d'une image bitmap 32 bits par pixel.

title image_simd.asm

.data

;rouge		dw		004ch
;vert		dw		0096h
;bleu		dw		001dh
coef		dq		0000004c0096001dh

.code

; **********************************************************************
; Sous-programme _process_image_asm 
; 
; Réalise le traitement d'une image 32 bits.
; 
; Le passage des paramètres respecte les conventions fastcall x64 sous 
; Windows. La fonction prend les paramètres suivants, dans l'ordre :
;  - biWidth : largeur d'une ligne en pixels (32 bits non signé)
;  - biHeight de l'image en lignes (32 bits non signé)
;  - img_src : adresse du premier pixel de l'image source
;  - img_temp1 : adresse du premier pixel de l'image temporaire 1
;  - img_temp2 : adresse du premier pixel de l'image temporaire 2
;  - img_dest : adresse du premier pixel de l'image finale
;
; La fonction ne retourne pas de valeur.
;
; Les registes rbx, rbp, rdi, rsi, rsp, r12, r13, r14, et r15 doivent
; être sauvegardés si vous les utilisez (sauvegarde par l'appelé). Les
; autres registres peuvent être modifiés sans risque (sauvegardés par 
; l'appelant).
; **********************************************************************

public  process_image_simd
process_image_simd  proc        ; Point d'entrée du sous programme

        ; *****************************
        ; Ajoutez votre code ci-dessous
        ; *****************************

		mov		rax, rcx				; rcx contient la largeur
		mul		rdx						; On multiplie la largeur (rcx) par la longueur (rdx) pour obtenir la taille de l'image dans rax
		mov		rcx, rax				; rcx reçoit la taille de l'image
		mov		rax, 0FFh				; pour placer le masque
		movq	xmm3, rax				; masque SSE dans xmm3
	punpcklqdq	xmm3, xmm3				; 2 masques de 64 bits
		xor		rax, rax
		xor		rbx, rbx

		
niveau:	movq	xmm0, qword ptr[r8 + rcx*4 - 8]			; -8 pour ne pas sortir de l'image à la première itération
		pxor	xmm2, xmm2
	punpcklbw	xmm0, xmm2

		movq	xmm1, qword ptr[coef]
	punpcklqdq	xmm1, xmm1

		pmullw	xmm0, xmm1
		psrlw	xmm0, 8

		paddusb	xmm2, xmm0
		psrlq	xmm2, 16
		paddusb	xmm2, xmm0
		psrlq	xmm2, 16
		paddusb	xmm2, xmm0								; la somme I est dans le dernier byte de chaque partie de 8 bytes
		pand	xmm2, xmm3								; on filtre avec notre masque

		movd	dword ptr[r9 + rcx * 4 - 8], xmm2		; on place les 4 derniers byte
		psrldq	xmm2, 8									; on décale les valeurs de 64 bits vers la droite
		movd	dword ptr[r9 + rcx * 4 - 4], xmm2		; 2e pixel traiter

		sub		rcx, 2									; -2 car deux pixel traités
		cmp		rcx, 0
		jne		niveau

        ret                     ; Retour à la fonction d'appel
process_image_simd  endp

end