blur_asm.asm 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. default rel global _blur_asm
  2. global blur_asm
  3. extern convulcion_matriz
  4. ; Alias para no volverme loco con los registros
  5. %define src rdi
  6. %define dst rsi
  7. %define cols rdx
  8. %define filas r14
  9. %define sigma xmm0
  10. %define radius r8
  11. %define cont_c r9
  12. %define matriz r10
  13. %define filas_faltan r11
  14. %define col_faltan r12
  15. %define basura r13
  16. ; Algunos defines ultiles
  17. %define PIXEL_SIZE 4
  18. ; Mascaras y esas cosas
  19. section .data
  20. section .text
  21. ;void blur_asm (
  22. ;unsigned char *src,
  23. ;unsigned char *dst,
  24. ;int filas,
  25. ;int cols,
  26. ;float sigma,
  27. ;int radius)
  28. _blur_asm:
  29. blur_asm:
  30. push rbp
  31. mov rbp, rsp ; Stack frame
  32. push r9
  33. push r10
  34. push r11
  35. push r12
  36. push r13
  37. push r14
  38. push r15
  39. .init:
  40. mov r14,rcx ;guardo rcx para loop
  41. mov r9, rdx ;salvo rdx por los mul
  42. mov rax, PIXEL_SIZE
  43. mul cols
  44. mul radius
  45. ; rax:=cols*pix_size*radius => cuantas filas debo saltear
  46. ;add src, rax
  47. add dst, rax ; Avanzo "radius" filas (col*pix_size*radius)
  48. sub filas, radius ;acomodo filas para ignorar los bordes
  49. sub filas, radius ;acomodo filas para ignorar los bordes
  50. mov cols, r9 ;recupero cols por el mul
  51. sub cols, radius ;resto radius columnas
  52. sub cols, radius ;resto radius columnas
  53. mov rax, PIXEL_SIZE
  54. mul cols
  55. mov cols, rax ;cols:=cols*pix_size
  56. .iniciarFila:
  57. ;lea src, [src+PIXEL_SIZE*radius] ;avanzo radius pixeles (borde)
  58. lea dst, [dst+PIXEL_SIZE*radius] ;avanzo radius pixeles (borde)
  59. xor cont_c,cont_c
  60. .loop:
  61. cmp cols, cont_c ; Comparo tamaño con el contador
  62. je .finFila ; Si ya recorri la imagen voy al final
  63. mov filas_faltan, radius;FIXME este radius es pixeles no bytes
  64. add filas_faltan, radius
  65. add filas_faltan, PIXEL_SIZE ; 2r+1 filas
  66. .loopInterno:
  67. mov col_faltan, radius
  68. add col_faltan, radius
  69. add col_faltan, PIXEL_SIZE ; 2r+1 columnas
  70. .loopFila:
  71. ;faltan <4? me muevo para atras 4-faltantes pix
  72. ;levanto 4px
  73. movdqu xmm2, [src] ; Cargo 4 pix de la imagen 1 => xmm0 = |B(P1)|G(P1)|R(P1)|A(P1)|B(P2)|G(P2)|......|
  74. mov basura, 4
  75. sub basura, col_faltan
  76. mov rax, PIXEL_SIZE
  77. mul basura;rdx?
  78. ;shift (4-faltantes) bytes
  79. psrldq xmm2, basura ;ok, borre los que no queria
  80. ;desempaqueto cada pixel a un registro (cada elem como dword)
  81. punpcklbw xmm2, xmm3
  82. punpckhbw xmm2, xmm4
  83. punpcklwd xmm3, xmm5
  84. punpckhwd xmm3, xmm6
  85. punpcklwd xmm4, xmm7
  86. punpckhwd xmm4, xmm8
  87. ;cargo 1 elem de matriz como single
  88. ;FIXME esto carga 4
  89. movdqu xmm9, [matriz]
  90. ;lo clono con mascara a los 4 elem del xmm
  91. ;multiplico cada pixel por su coeficiente de la matriz(float)
  92. mulps xmm5, xmm9
  93. mulps xmm6, xmm9
  94. mulps xmm7, xmm9
  95. mulps xmm8, xmm9
  96. ;acumulo
  97. addps xmm10, xmm5
  98. addps xmm10, xmm6
  99. addps xmm10, xmm7
  100. addps xmm10, xmm8
  101. ;actualizo cuantos faltan
  102. sub col_faltan, 4*PIXEL_SIZE
  103. cmp col_faltan, 4
  104. jg .loopFila
  105. cmp col_faltan, 0
  106. jle .finFilaInterna
  107. ;me faltan entre 0 y 4 pixeles, retrocedo suficiente para que me falten 4 exactos
  108. lea src, [src-(4-col_faltan)]
  109. jmp .loopFila
  110. .finFilaInterna:
  111. dec filas_faltan
  112. cmp filas_faltan, 0
  113. je .sumar
  114. jmp .loopInterno
  115. ;avanzo ancho img - (2k+1 pix)
  116. ;faltan >0 filas? jmp .loopInterno
  117. .sumar:
  118. .write:
  119. movdqu [dst], xmm10 ; Escribo en el destino
  120. .endLoop:
  121. add src, PIXEL_SIZE ; Incremento 4 pixeles
  122. add dst, PIXEL_SIZE
  123. add cont_c, PIXEL_SIZE
  124. jmp .loop
  125. .finFila:
  126. dec filas
  127. cmp filas, qword 0
  128. je .fin
  129. lea src, [src+PIXEL_SIZE*radius] ;agrego radius a la columna (termino la fila)
  130. lea dst, [dst+PIXEL_SIZE*radius]
  131. jmp .iniciarFila
  132. .fin:
  133. pop r15
  134. pop r14
  135. pop r13
  136. pop r12
  137. pop r11
  138. pop r10
  139. pop r9
  140. pop rbp
  141. ret