jquant-3dn.asm 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. ;
  2. ; jquant.asm - sample data conversion and quantization (3DNow! & MMX)
  3. ;
  4. ; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
  5. ;
  6. ; Based on the x86 SIMD extension for IJG JPEG library
  7. ; Copyright (C) 1999-2006, MIYASAKA Masaru.
  8. ; For conditions of distribution and use, see copyright notice in jsimdext.inc
  9. ;
  10. ; This file should be assembled with NASM (Netwide Assembler),
  11. ; can *not* be assembled with Microsoft's MASM or any compatible
  12. ; assembler (including Borland's Turbo Assembler).
  13. ; NASM is available from http://nasm.sourceforge.net/ or
  14. ; http://sourceforge.net/project/showfiles.php?group_id=6208
  15. ;
  16. ; [TAB8]
  17. %include "jsimdext.inc"
  18. %include "jdct.inc"
  19. ; --------------------------------------------------------------------------
  20. SECTION SEG_TEXT
  21. BITS 32
  22. ;
  23. ; Load data into workspace, applying unsigned->signed conversion
  24. ;
  25. ; GLOBAL(void)
  26. ; jsimd_convsamp_float_3dnow (JSAMPARRAY sample_data, JDIMENSION start_col,
  27. ; FAST_FLOAT *workspace);
  28. ;
  29. %define sample_data ebp+8 ; JSAMPARRAY sample_data
  30. %define start_col ebp+12 ; JDIMENSION start_col
  31. %define workspace ebp+16 ; FAST_FLOAT *workspace
  32. align 16
  33. global EXTN(jsimd_convsamp_float_3dnow)
  34. EXTN(jsimd_convsamp_float_3dnow):
  35. push ebp
  36. mov ebp,esp
  37. push ebx
  38. ; push ecx ; need not be preserved
  39. ; push edx ; need not be preserved
  40. push esi
  41. push edi
  42. pcmpeqw mm7,mm7
  43. psllw mm7,7
  44. packsswb mm7,mm7 ; mm7 = PB_CENTERJSAMPLE (0x808080..)
  45. mov esi, JSAMPARRAY [sample_data] ; (JSAMPROW *)
  46. mov eax, JDIMENSION [start_col]
  47. mov edi, POINTER [workspace] ; (DCTELEM *)
  48. mov ecx, DCTSIZE/2
  49. alignx 16,7
  50. .convloop:
  51. mov ebx, JSAMPROW [esi+0*SIZEOF_JSAMPROW] ; (JSAMPLE *)
  52. mov edx, JSAMPROW [esi+1*SIZEOF_JSAMPROW] ; (JSAMPLE *)
  53. movq mm0, MMWORD [ebx+eax*SIZEOF_JSAMPLE]
  54. movq mm1, MMWORD [edx+eax*SIZEOF_JSAMPLE]
  55. psubb mm0,mm7 ; mm0=(01234567)
  56. psubb mm1,mm7 ; mm1=(89ABCDEF)
  57. punpcklbw mm2,mm0 ; mm2=(*0*1*2*3)
  58. punpckhbw mm0,mm0 ; mm0=(*4*5*6*7)
  59. punpcklbw mm3,mm1 ; mm3=(*8*9*A*B)
  60. punpckhbw mm1,mm1 ; mm1=(*C*D*E*F)
  61. punpcklwd mm4,mm2 ; mm4=(***0***1)
  62. punpckhwd mm2,mm2 ; mm2=(***2***3)
  63. punpcklwd mm5,mm0 ; mm5=(***4***5)
  64. punpckhwd mm0,mm0 ; mm0=(***6***7)
  65. psrad mm4,(DWORD_BIT-BYTE_BIT) ; mm4=(01)
  66. psrad mm2,(DWORD_BIT-BYTE_BIT) ; mm2=(23)
  67. pi2fd mm4,mm4
  68. pi2fd mm2,mm2
  69. psrad mm5,(DWORD_BIT-BYTE_BIT) ; mm5=(45)
  70. psrad mm0,(DWORD_BIT-BYTE_BIT) ; mm0=(67)
  71. pi2fd mm5,mm5
  72. pi2fd mm0,mm0
  73. movq MMWORD [MMBLOCK(0,0,edi,SIZEOF_FAST_FLOAT)], mm4
  74. movq MMWORD [MMBLOCK(0,1,edi,SIZEOF_FAST_FLOAT)], mm2
  75. movq MMWORD [MMBLOCK(0,2,edi,SIZEOF_FAST_FLOAT)], mm5
  76. movq MMWORD [MMBLOCK(0,3,edi,SIZEOF_FAST_FLOAT)], mm0
  77. punpcklwd mm6,mm3 ; mm6=(***8***9)
  78. punpckhwd mm3,mm3 ; mm3=(***A***B)
  79. punpcklwd mm4,mm1 ; mm4=(***C***D)
  80. punpckhwd mm1,mm1 ; mm1=(***E***F)
  81. psrad mm6,(DWORD_BIT-BYTE_BIT) ; mm6=(89)
  82. psrad mm3,(DWORD_BIT-BYTE_BIT) ; mm3=(AB)
  83. pi2fd mm6,mm6
  84. pi2fd mm3,mm3
  85. psrad mm4,(DWORD_BIT-BYTE_BIT) ; mm4=(CD)
  86. psrad mm1,(DWORD_BIT-BYTE_BIT) ; mm1=(EF)
  87. pi2fd mm4,mm4
  88. pi2fd mm1,mm1
  89. movq MMWORD [MMBLOCK(1,0,edi,SIZEOF_FAST_FLOAT)], mm6
  90. movq MMWORD [MMBLOCK(1,1,edi,SIZEOF_FAST_FLOAT)], mm3
  91. movq MMWORD [MMBLOCK(1,2,edi,SIZEOF_FAST_FLOAT)], mm4
  92. movq MMWORD [MMBLOCK(1,3,edi,SIZEOF_FAST_FLOAT)], mm1
  93. add esi, byte 2*SIZEOF_JSAMPROW
  94. add edi, byte 2*DCTSIZE*SIZEOF_FAST_FLOAT
  95. dec ecx
  96. jnz near .convloop
  97. femms ; empty MMX/3DNow! state
  98. pop edi
  99. pop esi
  100. ; pop edx ; need not be preserved
  101. ; pop ecx ; need not be preserved
  102. pop ebx
  103. pop ebp
  104. ret
  105. ; --------------------------------------------------------------------------
  106. ;
  107. ; Quantize/descale the coefficients, and store into coef_block
  108. ;
  109. ; GLOBAL(void)
  110. ; jsimd_quantize_float_3dnow (JCOEFPTR coef_block, FAST_FLOAT *divisors,
  111. ; FAST_FLOAT *workspace);
  112. ;
  113. %define coef_block ebp+8 ; JCOEFPTR coef_block
  114. %define divisors ebp+12 ; FAST_FLOAT *divisors
  115. %define workspace ebp+16 ; FAST_FLOAT *workspace
  116. align 16
  117. global EXTN(jsimd_quantize_float_3dnow)
  118. EXTN(jsimd_quantize_float_3dnow):
  119. push ebp
  120. mov ebp,esp
  121. ; push ebx ; unused
  122. ; push ecx ; unused
  123. ; push edx ; need not be preserved
  124. push esi
  125. push edi
  126. mov eax, 0x4B400000 ; (float)0x00C00000 (rndint_magic)
  127. movd mm7,eax
  128. punpckldq mm7,mm7 ; mm7={12582912.0F 12582912.0F}
  129. mov esi, POINTER [workspace]
  130. mov edx, POINTER [divisors]
  131. mov edi, JCOEFPTR [coef_block]
  132. mov eax, DCTSIZE2/16
  133. alignx 16,7
  134. .quantloop:
  135. movq mm0, MMWORD [MMBLOCK(0,0,esi,SIZEOF_FAST_FLOAT)]
  136. movq mm1, MMWORD [MMBLOCK(0,1,esi,SIZEOF_FAST_FLOAT)]
  137. pfmul mm0, MMWORD [MMBLOCK(0,0,edx,SIZEOF_FAST_FLOAT)]
  138. pfmul mm1, MMWORD [MMBLOCK(0,1,edx,SIZEOF_FAST_FLOAT)]
  139. movq mm2, MMWORD [MMBLOCK(0,2,esi,SIZEOF_FAST_FLOAT)]
  140. movq mm3, MMWORD [MMBLOCK(0,3,esi,SIZEOF_FAST_FLOAT)]
  141. pfmul mm2, MMWORD [MMBLOCK(0,2,edx,SIZEOF_FAST_FLOAT)]
  142. pfmul mm3, MMWORD [MMBLOCK(0,3,edx,SIZEOF_FAST_FLOAT)]
  143. pfadd mm0,mm7 ; mm0=(00 ** 01 **)
  144. pfadd mm1,mm7 ; mm1=(02 ** 03 **)
  145. pfadd mm2,mm7 ; mm0=(04 ** 05 **)
  146. pfadd mm3,mm7 ; mm1=(06 ** 07 **)
  147. movq mm4,mm0
  148. punpcklwd mm0,mm1 ; mm0=(00 02 ** **)
  149. punpckhwd mm4,mm1 ; mm4=(01 03 ** **)
  150. movq mm5,mm2
  151. punpcklwd mm2,mm3 ; mm2=(04 06 ** **)
  152. punpckhwd mm5,mm3 ; mm5=(05 07 ** **)
  153. punpcklwd mm0,mm4 ; mm0=(00 01 02 03)
  154. punpcklwd mm2,mm5 ; mm2=(04 05 06 07)
  155. movq mm6, MMWORD [MMBLOCK(1,0,esi,SIZEOF_FAST_FLOAT)]
  156. movq mm1, MMWORD [MMBLOCK(1,1,esi,SIZEOF_FAST_FLOAT)]
  157. pfmul mm6, MMWORD [MMBLOCK(1,0,edx,SIZEOF_FAST_FLOAT)]
  158. pfmul mm1, MMWORD [MMBLOCK(1,1,edx,SIZEOF_FAST_FLOAT)]
  159. movq mm3, MMWORD [MMBLOCK(1,2,esi,SIZEOF_FAST_FLOAT)]
  160. movq mm4, MMWORD [MMBLOCK(1,3,esi,SIZEOF_FAST_FLOAT)]
  161. pfmul mm3, MMWORD [MMBLOCK(1,2,edx,SIZEOF_FAST_FLOAT)]
  162. pfmul mm4, MMWORD [MMBLOCK(1,3,edx,SIZEOF_FAST_FLOAT)]
  163. pfadd mm6,mm7 ; mm0=(10 ** 11 **)
  164. pfadd mm1,mm7 ; mm4=(12 ** 13 **)
  165. pfadd mm3,mm7 ; mm0=(14 ** 15 **)
  166. pfadd mm4,mm7 ; mm4=(16 ** 17 **)
  167. movq mm5,mm6
  168. punpcklwd mm6,mm1 ; mm6=(10 12 ** **)
  169. punpckhwd mm5,mm1 ; mm5=(11 13 ** **)
  170. movq mm1,mm3
  171. punpcklwd mm3,mm4 ; mm3=(14 16 ** **)
  172. punpckhwd mm1,mm4 ; mm1=(15 17 ** **)
  173. punpcklwd mm6,mm5 ; mm6=(10 11 12 13)
  174. punpcklwd mm3,mm1 ; mm3=(14 15 16 17)
  175. movq MMWORD [MMBLOCK(0,0,edi,SIZEOF_JCOEF)], mm0
  176. movq MMWORD [MMBLOCK(0,1,edi,SIZEOF_JCOEF)], mm2
  177. movq MMWORD [MMBLOCK(1,0,edi,SIZEOF_JCOEF)], mm6
  178. movq MMWORD [MMBLOCK(1,1,edi,SIZEOF_JCOEF)], mm3
  179. add esi, byte 16*SIZEOF_FAST_FLOAT
  180. add edx, byte 16*SIZEOF_FAST_FLOAT
  181. add edi, byte 16*SIZEOF_JCOEF
  182. dec eax
  183. jnz near .quantloop
  184. femms ; empty MMX/3DNow! state
  185. pop edi
  186. pop esi
  187. ; pop edx ; need not be preserved
  188. ; pop ecx ; unused
  189. ; pop ebx ; unused
  190. pop ebp
  191. ret
  192. ; For some reason, the OS X linker does not honor the request to align the
  193. ; segment unless we do this.
  194. align 16