jidctred-sse2-64.asm 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  1. ;
  2. ; jidctred.asm - reduced-size IDCT (64-bit SSE2)
  3. ;
  4. ; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
  5. ; Copyright (C) 2009, D. R. Commander.
  6. ;
  7. ; Based on the x86 SIMD extension for IJG JPEG library
  8. ; Copyright (C) 1999-2006, MIYASAKA Masaru.
  9. ; For conditions of distribution and use, see copyright notice in jsimdext.inc
  10. ;
  11. ; This file should be assembled with NASM (Netwide Assembler),
  12. ; can *not* be assembled with Microsoft's MASM or any compatible
  13. ; assembler (including Borland's Turbo Assembler).
  14. ; NASM is available from http://nasm.sourceforge.net/ or
  15. ; http://sourceforge.net/project/showfiles.php?group_id=6208
  16. ;
  17. ; This file contains inverse-DCT routines that produce reduced-size
  18. ; output: either 4x4 or 2x2 pixels from an 8x8 DCT block.
  19. ; The following code is based directly on the IJG's original jidctred.c;
  20. ; see the jidctred.c for more details.
  21. ;
  22. ; [TAB8]
  23. %include "jsimdext.inc"
  24. %include "jdct.inc"
  25. ; --------------------------------------------------------------------------
  26. %define CONST_BITS 13
  27. %define PASS1_BITS 2
  28. %define DESCALE_P1_4 (CONST_BITS-PASS1_BITS+1)
  29. %define DESCALE_P2_4 (CONST_BITS+PASS1_BITS+3+1)
  30. %define DESCALE_P1_2 (CONST_BITS-PASS1_BITS+2)
  31. %define DESCALE_P2_2 (CONST_BITS+PASS1_BITS+3+2)
  32. %if CONST_BITS == 13
  33. F_0_211 equ 1730 ; FIX(0.211164243)
  34. F_0_509 equ 4176 ; FIX(0.509795579)
  35. F_0_601 equ 4926 ; FIX(0.601344887)
  36. F_0_720 equ 5906 ; FIX(0.720959822)
  37. F_0_765 equ 6270 ; FIX(0.765366865)
  38. F_0_850 equ 6967 ; FIX(0.850430095)
  39. F_0_899 equ 7373 ; FIX(0.899976223)
  40. F_1_061 equ 8697 ; FIX(1.061594337)
  41. F_1_272 equ 10426 ; FIX(1.272758580)
  42. F_1_451 equ 11893 ; FIX(1.451774981)
  43. F_1_847 equ 15137 ; FIX(1.847759065)
  44. F_2_172 equ 17799 ; FIX(2.172734803)
  45. F_2_562 equ 20995 ; FIX(2.562915447)
  46. F_3_624 equ 29692 ; FIX(3.624509785)
  47. %else
  48. ; NASM cannot do compile-time arithmetic on floating-point constants.
  49. %define DESCALE(x,n) (((x)+(1<<((n)-1)))>>(n))
  50. F_0_211 equ DESCALE( 226735879,30-CONST_BITS) ; FIX(0.211164243)
  51. F_0_509 equ DESCALE( 547388834,30-CONST_BITS) ; FIX(0.509795579)
  52. F_0_601 equ DESCALE( 645689155,30-CONST_BITS) ; FIX(0.601344887)
  53. F_0_720 equ DESCALE( 774124714,30-CONST_BITS) ; FIX(0.720959822)
  54. F_0_765 equ DESCALE( 821806413,30-CONST_BITS) ; FIX(0.765366865)
  55. F_0_850 equ DESCALE( 913142361,30-CONST_BITS) ; FIX(0.850430095)
  56. F_0_899 equ DESCALE( 966342111,30-CONST_BITS) ; FIX(0.899976223)
  57. F_1_061 equ DESCALE(1139878239,30-CONST_BITS) ; FIX(1.061594337)
  58. F_1_272 equ DESCALE(1366614119,30-CONST_BITS) ; FIX(1.272758580)
  59. F_1_451 equ DESCALE(1558831516,30-CONST_BITS) ; FIX(1.451774981)
  60. F_1_847 equ DESCALE(1984016188,30-CONST_BITS) ; FIX(1.847759065)
  61. F_2_172 equ DESCALE(2332956230,30-CONST_BITS) ; FIX(2.172734803)
  62. F_2_562 equ DESCALE(2751909506,30-CONST_BITS) ; FIX(2.562915447)
  63. F_3_624 equ DESCALE(3891787747,30-CONST_BITS) ; FIX(3.624509785)
  64. %endif
  65. ; --------------------------------------------------------------------------
  66. SECTION SEG_CONST
  67. alignz 16
  68. global EXTN(jconst_idct_red_sse2)
  69. EXTN(jconst_idct_red_sse2):
  70. PW_F184_MF076 times 4 dw F_1_847,-F_0_765
  71. PW_F256_F089 times 4 dw F_2_562, F_0_899
  72. PW_F106_MF217 times 4 dw F_1_061,-F_2_172
  73. PW_MF060_MF050 times 4 dw -F_0_601,-F_0_509
  74. PW_F145_MF021 times 4 dw F_1_451,-F_0_211
  75. PW_F362_MF127 times 4 dw F_3_624,-F_1_272
  76. PW_F085_MF072 times 4 dw F_0_850,-F_0_720
  77. PD_DESCALE_P1_4 times 4 dd 1 << (DESCALE_P1_4-1)
  78. PD_DESCALE_P2_4 times 4 dd 1 << (DESCALE_P2_4-1)
  79. PD_DESCALE_P1_2 times 4 dd 1 << (DESCALE_P1_2-1)
  80. PD_DESCALE_P2_2 times 4 dd 1 << (DESCALE_P2_2-1)
  81. PB_CENTERJSAMP times 16 db CENTERJSAMPLE
  82. alignz 16
  83. ; --------------------------------------------------------------------------
  84. SECTION SEG_TEXT
  85. BITS 64
  86. ;
  87. ; Perform dequantization and inverse DCT on one block of coefficients,
  88. ; producing a reduced-size 4x4 output block.
  89. ;
  90. ; GLOBAL(void)
  91. ; jsimd_idct_4x4_sse2 (void *dct_table, JCOEFPTR coef_block,
  92. ; JSAMPARRAY output_buf, JDIMENSION output_col)
  93. ;
  94. ; r10 = void *dct_table
  95. ; r11 = JCOEFPTR coef_block
  96. ; r12 = JSAMPARRAY output_buf
  97. ; r13 = JDIMENSION output_col
  98. %define original_rbp rbp+0
  99. %define wk(i) rbp-(WK_NUM-(i))*SIZEOF_XMMWORD ; xmmword wk[WK_NUM]
  100. %define WK_NUM 2
  101. align 16
  102. global EXTN(jsimd_idct_4x4_sse2)
  103. EXTN(jsimd_idct_4x4_sse2):
  104. push rbp
  105. mov rax,rsp ; rax = original rbp
  106. sub rsp, byte 4
  107. and rsp, byte (-SIZEOF_XMMWORD) ; align to 128 bits
  108. mov [rsp],rax
  109. mov rbp,rsp ; rbp = aligned rbp
  110. lea rsp, [wk(0)]
  111. collect_args
  112. ; ---- Pass 1: process columns from input.
  113. mov rdx, r10 ; quantptr
  114. mov rsi, r11 ; inptr
  115. %ifndef NO_ZERO_COLUMN_TEST_4X4_SSE2
  116. mov eax, DWORD [DWBLOCK(1,0,rsi,SIZEOF_JCOEF)]
  117. or eax, DWORD [DWBLOCK(2,0,rsi,SIZEOF_JCOEF)]
  118. jnz short .columnDCT
  119. movdqa xmm0, XMMWORD [XMMBLOCK(1,0,rsi,SIZEOF_JCOEF)]
  120. movdqa xmm1, XMMWORD [XMMBLOCK(2,0,rsi,SIZEOF_JCOEF)]
  121. por xmm0, XMMWORD [XMMBLOCK(3,0,rsi,SIZEOF_JCOEF)]
  122. por xmm1, XMMWORD [XMMBLOCK(5,0,rsi,SIZEOF_JCOEF)]
  123. por xmm0, XMMWORD [XMMBLOCK(6,0,rsi,SIZEOF_JCOEF)]
  124. por xmm1, XMMWORD [XMMBLOCK(7,0,rsi,SIZEOF_JCOEF)]
  125. por xmm0,xmm1
  126. packsswb xmm0,xmm0
  127. packsswb xmm0,xmm0
  128. movd eax,xmm0
  129. test rax,rax
  130. jnz short .columnDCT
  131. ; -- AC terms all zero
  132. movdqa xmm0, XMMWORD [XMMBLOCK(0,0,rsi,SIZEOF_JCOEF)]
  133. pmullw xmm0, XMMWORD [XMMBLOCK(0,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
  134. psllw xmm0,PASS1_BITS
  135. movdqa xmm3,xmm0 ; xmm0=in0=(00 01 02 03 04 05 06 07)
  136. punpcklwd xmm0,xmm0 ; xmm0=(00 00 01 01 02 02 03 03)
  137. punpckhwd xmm3,xmm3 ; xmm3=(04 04 05 05 06 06 07 07)
  138. pshufd xmm1,xmm0,0x50 ; xmm1=[col0 col1]=(00 00 00 00 01 01 01 01)
  139. pshufd xmm0,xmm0,0xFA ; xmm0=[col2 col3]=(02 02 02 02 03 03 03 03)
  140. pshufd xmm6,xmm3,0x50 ; xmm6=[col4 col5]=(04 04 04 04 05 05 05 05)
  141. pshufd xmm3,xmm3,0xFA ; xmm3=[col6 col7]=(06 06 06 06 07 07 07 07)
  142. jmp near .column_end
  143. %endif
  144. .columnDCT:
  145. ; -- Odd part
  146. movdqa xmm0, XMMWORD [XMMBLOCK(1,0,rsi,SIZEOF_JCOEF)]
  147. movdqa xmm1, XMMWORD [XMMBLOCK(3,0,rsi,SIZEOF_JCOEF)]
  148. pmullw xmm0, XMMWORD [XMMBLOCK(1,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
  149. pmullw xmm1, XMMWORD [XMMBLOCK(3,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
  150. movdqa xmm2, XMMWORD [XMMBLOCK(5,0,rsi,SIZEOF_JCOEF)]
  151. movdqa xmm3, XMMWORD [XMMBLOCK(7,0,rsi,SIZEOF_JCOEF)]
  152. pmullw xmm2, XMMWORD [XMMBLOCK(5,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
  153. pmullw xmm3, XMMWORD [XMMBLOCK(7,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
  154. movdqa xmm4,xmm0
  155. movdqa xmm5,xmm0
  156. punpcklwd xmm4,xmm1
  157. punpckhwd xmm5,xmm1
  158. movdqa xmm0,xmm4
  159. movdqa xmm1,xmm5
  160. pmaddwd xmm4,[rel PW_F256_F089] ; xmm4=(tmp2L)
  161. pmaddwd xmm5,[rel PW_F256_F089] ; xmm5=(tmp2H)
  162. pmaddwd xmm0,[rel PW_F106_MF217] ; xmm0=(tmp0L)
  163. pmaddwd xmm1,[rel PW_F106_MF217] ; xmm1=(tmp0H)
  164. movdqa xmm6,xmm2
  165. movdqa xmm7,xmm2
  166. punpcklwd xmm6,xmm3
  167. punpckhwd xmm7,xmm3
  168. movdqa xmm2,xmm6
  169. movdqa xmm3,xmm7
  170. pmaddwd xmm6,[rel PW_MF060_MF050] ; xmm6=(tmp2L)
  171. pmaddwd xmm7,[rel PW_MF060_MF050] ; xmm7=(tmp2H)
  172. pmaddwd xmm2,[rel PW_F145_MF021] ; xmm2=(tmp0L)
  173. pmaddwd xmm3,[rel PW_F145_MF021] ; xmm3=(tmp0H)
  174. paddd xmm6,xmm4 ; xmm6=tmp2L
  175. paddd xmm7,xmm5 ; xmm7=tmp2H
  176. paddd xmm2,xmm0 ; xmm2=tmp0L
  177. paddd xmm3,xmm1 ; xmm3=tmp0H
  178. movdqa XMMWORD [wk(0)], xmm2 ; wk(0)=tmp0L
  179. movdqa XMMWORD [wk(1)], xmm3 ; wk(1)=tmp0H
  180. ; -- Even part
  181. movdqa xmm4, XMMWORD [XMMBLOCK(0,0,rsi,SIZEOF_JCOEF)]
  182. movdqa xmm5, XMMWORD [XMMBLOCK(2,0,rsi,SIZEOF_JCOEF)]
  183. movdqa xmm0, XMMWORD [XMMBLOCK(6,0,rsi,SIZEOF_JCOEF)]
  184. pmullw xmm4, XMMWORD [XMMBLOCK(0,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
  185. pmullw xmm5, XMMWORD [XMMBLOCK(2,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
  186. pmullw xmm0, XMMWORD [XMMBLOCK(6,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
  187. pxor xmm1,xmm1
  188. pxor xmm2,xmm2
  189. punpcklwd xmm1,xmm4 ; xmm1=tmp0L
  190. punpckhwd xmm2,xmm4 ; xmm2=tmp0H
  191. psrad xmm1,(16-CONST_BITS-1) ; psrad xmm1,16 & pslld xmm1,CONST_BITS+1
  192. psrad xmm2,(16-CONST_BITS-1) ; psrad xmm2,16 & pslld xmm2,CONST_BITS+1
  193. movdqa xmm3,xmm5 ; xmm5=in2=z2
  194. punpcklwd xmm5,xmm0 ; xmm0=in6=z3
  195. punpckhwd xmm3,xmm0
  196. pmaddwd xmm5,[rel PW_F184_MF076] ; xmm5=tmp2L
  197. pmaddwd xmm3,[rel PW_F184_MF076] ; xmm3=tmp2H
  198. movdqa xmm4,xmm1
  199. movdqa xmm0,xmm2
  200. paddd xmm1,xmm5 ; xmm1=tmp10L
  201. paddd xmm2,xmm3 ; xmm2=tmp10H
  202. psubd xmm4,xmm5 ; xmm4=tmp12L
  203. psubd xmm0,xmm3 ; xmm0=tmp12H
  204. ; -- Final output stage
  205. movdqa xmm5,xmm1
  206. movdqa xmm3,xmm2
  207. paddd xmm1,xmm6 ; xmm1=data0L
  208. paddd xmm2,xmm7 ; xmm2=data0H
  209. psubd xmm5,xmm6 ; xmm5=data3L
  210. psubd xmm3,xmm7 ; xmm3=data3H
  211. movdqa xmm6,[rel PD_DESCALE_P1_4] ; xmm6=[rel PD_DESCALE_P1_4]
  212. paddd xmm1,xmm6
  213. paddd xmm2,xmm6
  214. psrad xmm1,DESCALE_P1_4
  215. psrad xmm2,DESCALE_P1_4
  216. paddd xmm5,xmm6
  217. paddd xmm3,xmm6
  218. psrad xmm5,DESCALE_P1_4
  219. psrad xmm3,DESCALE_P1_4
  220. packssdw xmm1,xmm2 ; xmm1=data0=(00 01 02 03 04 05 06 07)
  221. packssdw xmm5,xmm3 ; xmm5=data3=(30 31 32 33 34 35 36 37)
  222. movdqa xmm7, XMMWORD [wk(0)] ; xmm7=tmp0L
  223. movdqa xmm6, XMMWORD [wk(1)] ; xmm6=tmp0H
  224. movdqa xmm2,xmm4
  225. movdqa xmm3,xmm0
  226. paddd xmm4,xmm7 ; xmm4=data1L
  227. paddd xmm0,xmm6 ; xmm0=data1H
  228. psubd xmm2,xmm7 ; xmm2=data2L
  229. psubd xmm3,xmm6 ; xmm3=data2H
  230. movdqa xmm7,[rel PD_DESCALE_P1_4] ; xmm7=[rel PD_DESCALE_P1_4]
  231. paddd xmm4,xmm7
  232. paddd xmm0,xmm7
  233. psrad xmm4,DESCALE_P1_4
  234. psrad xmm0,DESCALE_P1_4
  235. paddd xmm2,xmm7
  236. paddd xmm3,xmm7
  237. psrad xmm2,DESCALE_P1_4
  238. psrad xmm3,DESCALE_P1_4
  239. packssdw xmm4,xmm0 ; xmm4=data1=(10 11 12 13 14 15 16 17)
  240. packssdw xmm2,xmm3 ; xmm2=data2=(20 21 22 23 24 25 26 27)
  241. movdqa xmm6,xmm1 ; transpose coefficients(phase 1)
  242. punpcklwd xmm1,xmm4 ; xmm1=(00 10 01 11 02 12 03 13)
  243. punpckhwd xmm6,xmm4 ; xmm6=(04 14 05 15 06 16 07 17)
  244. movdqa xmm7,xmm2 ; transpose coefficients(phase 1)
  245. punpcklwd xmm2,xmm5 ; xmm2=(20 30 21 31 22 32 23 33)
  246. punpckhwd xmm7,xmm5 ; xmm7=(24 34 25 35 26 36 27 37)
  247. movdqa xmm0,xmm1 ; transpose coefficients(phase 2)
  248. punpckldq xmm1,xmm2 ; xmm1=[col0 col1]=(00 10 20 30 01 11 21 31)
  249. punpckhdq xmm0,xmm2 ; xmm0=[col2 col3]=(02 12 22 32 03 13 23 33)
  250. movdqa xmm3,xmm6 ; transpose coefficients(phase 2)
  251. punpckldq xmm6,xmm7 ; xmm6=[col4 col5]=(04 14 24 34 05 15 25 35)
  252. punpckhdq xmm3,xmm7 ; xmm3=[col6 col7]=(06 16 26 36 07 17 27 37)
  253. .column_end:
  254. ; -- Prefetch the next coefficient block
  255. prefetchnta [rsi + DCTSIZE2*SIZEOF_JCOEF + 0*32]
  256. prefetchnta [rsi + DCTSIZE2*SIZEOF_JCOEF + 1*32]
  257. prefetchnta [rsi + DCTSIZE2*SIZEOF_JCOEF + 2*32]
  258. prefetchnta [rsi + DCTSIZE2*SIZEOF_JCOEF + 3*32]
  259. ; ---- Pass 2: process rows, store into output array.
  260. mov rax, [original_rbp]
  261. mov rdi, r12 ; (JSAMPROW *)
  262. mov eax, r13d
  263. ; -- Even part
  264. pxor xmm4,xmm4
  265. punpcklwd xmm4,xmm1 ; xmm4=tmp0
  266. psrad xmm4,(16-CONST_BITS-1) ; psrad xmm4,16 & pslld xmm4,CONST_BITS+1
  267. ; -- Odd part
  268. punpckhwd xmm1,xmm0
  269. punpckhwd xmm6,xmm3
  270. movdqa xmm5,xmm1
  271. movdqa xmm2,xmm6
  272. pmaddwd xmm1,[rel PW_F256_F089] ; xmm1=(tmp2)
  273. pmaddwd xmm6,[rel PW_MF060_MF050] ; xmm6=(tmp2)
  274. pmaddwd xmm5,[rel PW_F106_MF217] ; xmm5=(tmp0)
  275. pmaddwd xmm2,[rel PW_F145_MF021] ; xmm2=(tmp0)
  276. paddd xmm6,xmm1 ; xmm6=tmp2
  277. paddd xmm2,xmm5 ; xmm2=tmp0
  278. ; -- Even part
  279. punpcklwd xmm0,xmm3
  280. pmaddwd xmm0,[rel PW_F184_MF076] ; xmm0=tmp2
  281. movdqa xmm7,xmm4
  282. paddd xmm4,xmm0 ; xmm4=tmp10
  283. psubd xmm7,xmm0 ; xmm7=tmp12
  284. ; -- Final output stage
  285. movdqa xmm1,[rel PD_DESCALE_P2_4] ; xmm1=[rel PD_DESCALE_P2_4]
  286. movdqa xmm5,xmm4
  287. movdqa xmm3,xmm7
  288. paddd xmm4,xmm6 ; xmm4=data0=(00 10 20 30)
  289. paddd xmm7,xmm2 ; xmm7=data1=(01 11 21 31)
  290. psubd xmm5,xmm6 ; xmm5=data3=(03 13 23 33)
  291. psubd xmm3,xmm2 ; xmm3=data2=(02 12 22 32)
  292. paddd xmm4,xmm1
  293. paddd xmm7,xmm1
  294. psrad xmm4,DESCALE_P2_4
  295. psrad xmm7,DESCALE_P2_4
  296. paddd xmm5,xmm1
  297. paddd xmm3,xmm1
  298. psrad xmm5,DESCALE_P2_4
  299. psrad xmm3,DESCALE_P2_4
  300. packssdw xmm4,xmm3 ; xmm4=(00 10 20 30 02 12 22 32)
  301. packssdw xmm7,xmm5 ; xmm7=(01 11 21 31 03 13 23 33)
  302. movdqa xmm0,xmm4 ; transpose coefficients(phase 1)
  303. punpcklwd xmm4,xmm7 ; xmm4=(00 01 10 11 20 21 30 31)
  304. punpckhwd xmm0,xmm7 ; xmm0=(02 03 12 13 22 23 32 33)
  305. movdqa xmm6,xmm4 ; transpose coefficients(phase 2)
  306. punpckldq xmm4,xmm0 ; xmm4=(00 01 02 03 10 11 12 13)
  307. punpckhdq xmm6,xmm0 ; xmm6=(20 21 22 23 30 31 32 33)
  308. packsswb xmm4,xmm6 ; xmm4=(00 01 02 03 10 11 12 13 20 ..)
  309. paddb xmm4,[rel PB_CENTERJSAMP]
  310. pshufd xmm2,xmm4,0x39 ; xmm2=(10 11 12 13 20 21 22 23 30 ..)
  311. pshufd xmm1,xmm4,0x4E ; xmm1=(20 21 22 23 30 31 32 33 00 ..)
  312. pshufd xmm3,xmm4,0x93 ; xmm3=(30 31 32 33 00 01 02 03 10 ..)
  313. mov rdx, JSAMPROW [rdi+0*SIZEOF_JSAMPROW]
  314. mov rsi, JSAMPROW [rdi+1*SIZEOF_JSAMPROW]
  315. movd XMM_DWORD [rdx+rax*SIZEOF_JSAMPLE], xmm4
  316. movd XMM_DWORD [rsi+rax*SIZEOF_JSAMPLE], xmm2
  317. mov rdx, JSAMPROW [rdi+2*SIZEOF_JSAMPROW]
  318. mov rsi, JSAMPROW [rdi+3*SIZEOF_JSAMPROW]
  319. movd XMM_DWORD [rdx+rax*SIZEOF_JSAMPLE], xmm1
  320. movd XMM_DWORD [rsi+rax*SIZEOF_JSAMPLE], xmm3
  321. uncollect_args
  322. mov rsp,rbp ; rsp <- aligned rbp
  323. pop rsp ; rsp <- original rbp
  324. pop rbp
  325. ret
  326. ; --------------------------------------------------------------------------
  327. ;
  328. ; Perform dequantization and inverse DCT on one block of coefficients,
  329. ; producing a reduced-size 2x2 output block.
  330. ;
  331. ; GLOBAL(void)
  332. ; jsimd_idct_2x2_sse2 (void *dct_table, JCOEFPTR coef_block,
  333. ; JSAMPARRAY output_buf, JDIMENSION output_col)
  334. ;
  335. ; r10 = void *dct_table
  336. ; r11 = JCOEFPTR coef_block
  337. ; r12 = JSAMPARRAY output_buf
  338. ; r13 = JDIMENSION output_col
  339. align 16
  340. global EXTN(jsimd_idct_2x2_sse2)
  341. EXTN(jsimd_idct_2x2_sse2):
  342. push rbp
  343. mov rax,rsp
  344. mov rbp,rsp
  345. collect_args
  346. push rbx
  347. ; ---- Pass 1: process columns from input.
  348. mov rdx, r10 ; quantptr
  349. mov rsi, r11 ; inptr
  350. ; | input: | result: |
  351. ; | 00 01 ** 03 ** 05 ** 07 | |
  352. ; | 10 11 ** 13 ** 15 ** 17 | |
  353. ; | ** ** ** ** ** ** ** ** | |
  354. ; | 30 31 ** 33 ** 35 ** 37 | A0 A1 A3 A5 A7 |
  355. ; | ** ** ** ** ** ** ** ** | B0 B1 B3 B5 B7 |
  356. ; | 50 51 ** 53 ** 55 ** 57 | |
  357. ; | ** ** ** ** ** ** ** ** | |
  358. ; | 70 71 ** 73 ** 75 ** 77 | |
  359. ; -- Odd part
  360. movdqa xmm0, XMMWORD [XMMBLOCK(1,0,rsi,SIZEOF_JCOEF)]
  361. movdqa xmm1, XMMWORD [XMMBLOCK(3,0,rsi,SIZEOF_JCOEF)]
  362. pmullw xmm0, XMMWORD [XMMBLOCK(1,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
  363. pmullw xmm1, XMMWORD [XMMBLOCK(3,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
  364. movdqa xmm2, XMMWORD [XMMBLOCK(5,0,rsi,SIZEOF_JCOEF)]
  365. movdqa xmm3, XMMWORD [XMMBLOCK(7,0,rsi,SIZEOF_JCOEF)]
  366. pmullw xmm2, XMMWORD [XMMBLOCK(5,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
  367. pmullw xmm3, XMMWORD [XMMBLOCK(7,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
  368. ; xmm0=(10 11 ** 13 ** 15 ** 17), xmm1=(30 31 ** 33 ** 35 ** 37)
  369. ; xmm2=(50 51 ** 53 ** 55 ** 57), xmm3=(70 71 ** 73 ** 75 ** 77)
  370. pcmpeqd xmm7,xmm7
  371. pslld xmm7,WORD_BIT ; xmm7={0x0000 0xFFFF 0x0000 0xFFFF ..}
  372. movdqa xmm4,xmm0 ; xmm4=(10 11 ** 13 ** 15 ** 17)
  373. movdqa xmm5,xmm2 ; xmm5=(50 51 ** 53 ** 55 ** 57)
  374. punpcklwd xmm4,xmm1 ; xmm4=(10 30 11 31 ** ** 13 33)
  375. punpcklwd xmm5,xmm3 ; xmm5=(50 70 51 71 ** ** 53 73)
  376. pmaddwd xmm4,[rel PW_F362_MF127]
  377. pmaddwd xmm5,[rel PW_F085_MF072]
  378. psrld xmm0,WORD_BIT ; xmm0=(11 -- 13 -- 15 -- 17 --)
  379. pand xmm1,xmm7 ; xmm1=(-- 31 -- 33 -- 35 -- 37)
  380. psrld xmm2,WORD_BIT ; xmm2=(51 -- 53 -- 55 -- 57 --)
  381. pand xmm3,xmm7 ; xmm3=(-- 71 -- 73 -- 75 -- 77)
  382. por xmm0,xmm1 ; xmm0=(11 31 13 33 15 35 17 37)
  383. por xmm2,xmm3 ; xmm2=(51 71 53 73 55 75 57 77)
  384. pmaddwd xmm0,[rel PW_F362_MF127]
  385. pmaddwd xmm2,[rel PW_F085_MF072]
  386. paddd xmm4,xmm5 ; xmm4=tmp0[col0 col1 **** col3]
  387. paddd xmm0,xmm2 ; xmm0=tmp0[col1 col3 col5 col7]
  388. ; -- Even part
  389. movdqa xmm6, XMMWORD [XMMBLOCK(0,0,rsi,SIZEOF_JCOEF)]
  390. pmullw xmm6, XMMWORD [XMMBLOCK(0,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
  391. ; xmm6=(00 01 ** 03 ** 05 ** 07)
  392. movdqa xmm1,xmm6 ; xmm1=(00 01 ** 03 ** 05 ** 07)
  393. pslld xmm6,WORD_BIT ; xmm6=(-- 00 -- ** -- ** -- **)
  394. pand xmm1,xmm7 ; xmm1=(-- 01 -- 03 -- 05 -- 07)
  395. psrad xmm6,(WORD_BIT-CONST_BITS-2) ; xmm6=tmp10[col0 **** **** ****]
  396. psrad xmm1,(WORD_BIT-CONST_BITS-2) ; xmm1=tmp10[col1 col3 col5 col7]
  397. ; -- Final output stage
  398. movdqa xmm3,xmm6
  399. movdqa xmm5,xmm1
  400. paddd xmm6,xmm4 ; xmm6=data0[col0 **** **** ****]=(A0 ** ** **)
  401. paddd xmm1,xmm0 ; xmm1=data0[col1 col3 col5 col7]=(A1 A3 A5 A7)
  402. psubd xmm3,xmm4 ; xmm3=data1[col0 **** **** ****]=(B0 ** ** **)
  403. psubd xmm5,xmm0 ; xmm5=data1[col1 col3 col5 col7]=(B1 B3 B5 B7)
  404. movdqa xmm2,[rel PD_DESCALE_P1_2] ; xmm2=[rel PD_DESCALE_P1_2]
  405. punpckldq xmm6,xmm3 ; xmm6=(A0 B0 ** **)
  406. movdqa xmm7,xmm1
  407. punpcklqdq xmm1,xmm5 ; xmm1=(A1 A3 B1 B3)
  408. punpckhqdq xmm7,xmm5 ; xmm7=(A5 A7 B5 B7)
  409. paddd xmm6,xmm2
  410. psrad xmm6,DESCALE_P1_2
  411. paddd xmm1,xmm2
  412. paddd xmm7,xmm2
  413. psrad xmm1,DESCALE_P1_2
  414. psrad xmm7,DESCALE_P1_2
  415. ; -- Prefetch the next coefficient block
  416. prefetchnta [rsi + DCTSIZE2*SIZEOF_JCOEF + 0*32]
  417. prefetchnta [rsi + DCTSIZE2*SIZEOF_JCOEF + 1*32]
  418. prefetchnta [rsi + DCTSIZE2*SIZEOF_JCOEF + 2*32]
  419. prefetchnta [rsi + DCTSIZE2*SIZEOF_JCOEF + 3*32]
  420. ; ---- Pass 2: process rows, store into output array.
  421. mov rdi, r12 ; (JSAMPROW *)
  422. mov eax, r13d
  423. ; | input:| result:|
  424. ; | A0 B0 | |
  425. ; | A1 B1 | C0 C1 |
  426. ; | A3 B3 | D0 D1 |
  427. ; | A5 B5 | |
  428. ; | A7 B7 | |
  429. ; -- Odd part
  430. packssdw xmm1,xmm1 ; xmm1=(A1 A3 B1 B3 A1 A3 B1 B3)
  431. packssdw xmm7,xmm7 ; xmm7=(A5 A7 B5 B7 A5 A7 B5 B7)
  432. pmaddwd xmm1,[rel PW_F362_MF127]
  433. pmaddwd xmm7,[rel PW_F085_MF072]
  434. paddd xmm1,xmm7 ; xmm1=tmp0[row0 row1 row0 row1]
  435. ; -- Even part
  436. pslld xmm6,(CONST_BITS+2) ; xmm6=tmp10[row0 row1 **** ****]
  437. ; -- Final output stage
  438. movdqa xmm4,xmm6
  439. paddd xmm6,xmm1 ; xmm6=data0[row0 row1 **** ****]=(C0 C1 ** **)
  440. psubd xmm4,xmm1 ; xmm4=data1[row0 row1 **** ****]=(D0 D1 ** **)
  441. punpckldq xmm6,xmm4 ; xmm6=(C0 D0 C1 D1)
  442. paddd xmm6,[rel PD_DESCALE_P2_2]
  443. psrad xmm6,DESCALE_P2_2
  444. packssdw xmm6,xmm6 ; xmm6=(C0 D0 C1 D1 C0 D0 C1 D1)
  445. packsswb xmm6,xmm6 ; xmm6=(C0 D0 C1 D1 C0 D0 C1 D1 ..)
  446. paddb xmm6,[rel PB_CENTERJSAMP]
  447. pextrw ebx,xmm6,0x00 ; ebx=(C0 D0 -- --)
  448. pextrw ecx,xmm6,0x01 ; ecx=(C1 D1 -- --)
  449. mov rdx, JSAMPROW [rdi+0*SIZEOF_JSAMPROW]
  450. mov rsi, JSAMPROW [rdi+1*SIZEOF_JSAMPROW]
  451. mov WORD [rdx+rax*SIZEOF_JSAMPLE], bx
  452. mov WORD [rsi+rax*SIZEOF_JSAMPLE], cx
  453. pop rbx
  454. uncollect_args
  455. pop rbp
  456. ret
  457. ; For some reason, the OS X linker does not honor the request to align the
  458. ; segment unless we do this.
  459. align 16