Explorar el Código

Merge branch 'master' of ssh://git.davidventura.com.ar:443/david/orga2-simd

David hace 11 años
padre
commit
3fb6e40d03
Se han modificado 2 ficheros con 65 adiciones y 2 borrados
  1. 4 0
      .gitignore
  2. 61 2
      filtros/diff_asm.asm

+ 4 - 0
.gitignore

@@ -1,2 +1,6 @@
 img/
 *.o
+*.bmp
+*.swp
+tp2
+build/*

+ 61 - 2
filtros/diff_asm.asm

@@ -1,11 +1,22 @@
+; asmsyntax=nasm
+
 default rel
 global _diff_asm
 global diff_asm
 
+; Alias para no volverme loco con los registros
+%define src rdi
+%define src2 rsi
+%define dst rdx
+%define cont rcx
+%define size r8
 
-section .data
-
+; Algunos defines ultiles
+%define PIXEL_SIZE	4
 
+section .data
+    ; Mascara para realizar un shuffle para repetir los valores del diff
+	SHUFFLE_MASK: db 2,2,2,255,3,3,3,255,0,0,0,255,1,1,1,255
 
 section .text
 ;void diff_asm    (
@@ -17,6 +28,54 @@ section .text
 
 _diff_asm:
 diff_asm:
+    push rbp
+    mov rbp, rsp
+
+.calc_size:                     ; Calculo el tamaño de la imagen en bytes
+    mov r9, dst                 ; Muevo el destino un rato para hacer el calculo del tamaño de la imagen
+    mov rax, cont               ; Cargo filas
+    mul size                    ; Multiplico por las columnas
+    xor dst, dst                ; Limpio temportal
+    mov dst, PIXEL_SIZE         ; Multiplico temporal
+    mul dst                     ; Multiplico por el tamaño del pixel
+    mov size, rax               ; Guardo el tamaño
+    mov dst, r9
+
+    xor cont, cont              ; Limpio el contador
+
+.loop:
+    cmp cont, size              ; Comparo tamaño con el contador
+    jge .fin                    ; Si ya recorri la imagen voy al final
+    pxor xmm1, xmm1
+    movdqu xmm0, [src]          ; Cargo la imagen 1 => xmm0 = |B(P1)|G(P1)|R(P1)|A(P1)|B(P2)|G(P2)|......|
+    movdqu xmm1, [src2]         ; Cargo la imagen 2 => xmm1 = |B(P1)|G(P1)|R(P1)|A(P1)|B(P2)|G(P2)|......|
+
+.cuentas:                       ; Resto componente a componente de 4 pixeles de cada imagen
+    psubb xmm1, xmm0            ; xmm1 = |B(img1_P1) - R(img2_P1)|G(Img1_P1) - Img2_P2|....|
+	pabsb xmm0, xmm1            ; Almaceno en xmm0 el valor absoluto de la resta anterior
+
+    ; TODO: Arreglar los comentarios por que estan desordenados los pixeles
+	pxor xmm2, xmm2
+	movdqu xmm1, xmm0           ; Copio xmm0 a xmm1
+	punpckhbw xmm0, xmm2        ; Desempaqueto la parte alta => xmm0 = |B(P1)|G(P1)|R(P1)|A(P1)|B(P2)|G(P2)|R(P2)|A(P2)|
+	punpcklbw xmm1, xmm2        ; Desempaqueto la parte baja => xmm1 = |B(P3)|G(P3)|R(P3)|A(P3)|B(P4)|G(P4)|R(P4)|A(P4)|
+
+	phaddw xmm0, xmm1           ; xmm0 = |B(P1)+G(P1)|R(P1)+A(P1)|B(P2)+G(P2)|R(P2)+A(P2)|....|
+	phaddw xmm0, xmm2           ; xmm0 = |B+G+R+A (P1)| B+G+R+A(P2) | B+G+R+A(P3) | B+G+R+A(P4)| 0x0 | 0x0 | 0x0 | 0x0 |
+	packuswb xmm0, xmm2         ; xmm0 = |P1|P2|P3|P4|0x0|0x0|0x0|0x0|0x0|....|
 
+	movdqu xmm2, [SHUFFLE_MASK] ; Cargo la mascara para shuffle
+	pshufb xmm0, xmm2           ; Le hago un shuffle a xmm0 con los nuevos valores calculados
+.write:
+    movdqu [dst], xmm0          ; Escribo en el destino
+.endLoop:
+    ; TODO: Si el tamaño de la imagen no es multiplo de 4 acá va a sumar y hacer invalid read al llegar al final
+    add src, PIXEL_SIZE	* 4     ; Incremento 4 pixeles
+    add src2, PIXEL_SIZE * 4
+    add dst, PIXEL_SIZE * 4
+    add cont, PIXEL_SIZE * 4
+    jmp .loop
 
+.fin:
+    pop rbp
     ret