You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

516 lines
12KB

  1. ;*****************************************************************************
  2. ;* x86util.asm
  3. ;*****************************************************************************
  4. ;* Copyright (C) 2008 Loren Merritt <lorenm@u.washington.edu>
  5. ;*
  6. ;* This program is free software; you can redistribute it and/or modify
  7. ;* it under the terms of the GNU General Public License as published by
  8. ;* the Free Software Foundation; either version 2 of the License, or
  9. ;* (at your option) any later version.
  10. ;*
  11. ;* This program is distributed in the hope that it will be useful,
  12. ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. ;* GNU General Public License for more details.
  15. ;*
  16. ;* You should have received a copy of the GNU General Public License
  17. ;* along with this program; if not, write to the Free Software
  18. ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
  19. ;*****************************************************************************
  20. %macro SBUTTERFLY 4
  21. mova m%4, m%2
  22. punpckl%1 m%2, m%3
  23. punpckh%1 m%4, m%3
  24. SWAP %3, %4
  25. %endmacro
  26. %macro TRANSPOSE4x4W 5
  27. SBUTTERFLY wd, %1, %2, %5
  28. SBUTTERFLY wd, %3, %4, %5
  29. SBUTTERFLY dq, %1, %3, %5
  30. SBUTTERFLY dq, %2, %4, %5
  31. SWAP %2, %3
  32. %endmacro
  33. %macro TRANSPOSE2x4x4W 5
  34. SBUTTERFLY wd, %1, %2, %5
  35. SBUTTERFLY wd, %3, %4, %5
  36. SBUTTERFLY dq, %1, %3, %5
  37. SBUTTERFLY dq, %2, %4, %5
  38. SBUTTERFLY qdq, %1, %2, %5
  39. SBUTTERFLY qdq, %3, %4, %5
  40. %endmacro
  41. %macro TRANSPOSE4x4D 5
  42. SBUTTERFLY dq, %1, %2, %5
  43. SBUTTERFLY dq, %3, %4, %5
  44. SBUTTERFLY qdq, %1, %3, %5
  45. SBUTTERFLY qdq, %2, %4, %5
  46. SWAP %2, %3
  47. %endmacro
  48. %macro TRANSPOSE8x8W 9-11
  49. %ifdef ARCH_X86_64
  50. SBUTTERFLY wd, %1, %2, %9
  51. SBUTTERFLY wd, %3, %4, %9
  52. SBUTTERFLY wd, %5, %6, %9
  53. SBUTTERFLY wd, %7, %8, %9
  54. SBUTTERFLY dq, %1, %3, %9
  55. SBUTTERFLY dq, %2, %4, %9
  56. SBUTTERFLY dq, %5, %7, %9
  57. SBUTTERFLY dq, %6, %8, %9
  58. SBUTTERFLY qdq, %1, %5, %9
  59. SBUTTERFLY qdq, %2, %6, %9
  60. SBUTTERFLY qdq, %3, %7, %9
  61. SBUTTERFLY qdq, %4, %8, %9
  62. SWAP %2, %5
  63. SWAP %4, %7
  64. %else
  65. ; in: m0..m7, unless %11 in which case m6 is in %9
  66. ; out: m0..m7, unless %11 in which case m4 is in %10
  67. ; spills into %9 and %10
  68. %if %0<11
  69. movdqa %9, m%7
  70. %endif
  71. SBUTTERFLY wd, %1, %2, %7
  72. movdqa %10, m%2
  73. movdqa m%7, %9
  74. SBUTTERFLY wd, %3, %4, %2
  75. SBUTTERFLY wd, %5, %6, %2
  76. SBUTTERFLY wd, %7, %8, %2
  77. SBUTTERFLY dq, %1, %3, %2
  78. movdqa %9, m%3
  79. movdqa m%2, %10
  80. SBUTTERFLY dq, %2, %4, %3
  81. SBUTTERFLY dq, %5, %7, %3
  82. SBUTTERFLY dq, %6, %8, %3
  83. SBUTTERFLY qdq, %1, %5, %3
  84. SBUTTERFLY qdq, %2, %6, %3
  85. movdqa %10, m%2
  86. movdqa m%3, %9
  87. SBUTTERFLY qdq, %3, %7, %2
  88. SBUTTERFLY qdq, %4, %8, %2
  89. SWAP %2, %5
  90. SWAP %4, %7
  91. %if %0<11
  92. movdqa m%5, %10
  93. %endif
  94. %endif
  95. %endmacro
  96. %macro ABS1_MMX 2 ; a, tmp
  97. pxor %2, %2
  98. psubw %2, %1
  99. pmaxsw %1, %2
  100. %endmacro
  101. %macro ABS2_MMX 4 ; a, b, tmp0, tmp1
  102. pxor %3, %3
  103. pxor %4, %4
  104. psubw %3, %1
  105. psubw %4, %2
  106. pmaxsw %1, %3
  107. pmaxsw %2, %4
  108. %endmacro
  109. %macro ABS1_SSSE3 2
  110. pabsw %1, %1
  111. %endmacro
  112. %macro ABS2_SSSE3 4
  113. pabsw %1, %1
  114. pabsw %2, %2
  115. %endmacro
  116. %define ABS1 ABS1_MMX
  117. %define ABS2 ABS2_MMX
  118. %macro ABS4 6
  119. ABS2 %1, %2, %5, %6
  120. ABS2 %3, %4, %5, %6
  121. %endmacro
  122. %macro SPLATB_MMX 3
  123. movd %1, [%2-3] ;to avoid crossing a cacheline
  124. punpcklbw %1, %1
  125. %if mmsize==16
  126. pshuflw %1, %1, 0xff
  127. punpcklqdq %1, %1
  128. %else
  129. pshufw %1, %1, 0xff
  130. %endif
  131. %endmacro
  132. %macro SPLATB_SSSE3 3
  133. movd %1, [%2-3]
  134. pshufb %1, %3
  135. %endmacro
  136. %macro PALIGNR_MMX 4
  137. %ifnidn %4, %2
  138. mova %4, %2
  139. %endif
  140. %if mmsize == 8
  141. psllq %1, (8-%3)*8
  142. psrlq %4, %3*8
  143. %else
  144. pslldq %1, 16-%3
  145. psrldq %4, %3
  146. %endif
  147. por %1, %4
  148. %endmacro
  149. %macro PALIGNR_SSSE3 4
  150. palignr %1, %2, %3
  151. %endmacro
  152. %macro DEINTB 5 ; mask, reg1, mask, reg2, optional src to fill masks from
  153. %ifnum %5
  154. mova m%1, m%5
  155. mova m%3, m%5
  156. %else
  157. mova m%1, %5
  158. mova m%3, m%1
  159. %endif
  160. pand m%1, m%2 ; dst .. y6 .. y4
  161. pand m%3, m%4 ; src .. y6 .. y4
  162. psrlw m%2, 8 ; dst .. y7 .. y5
  163. psrlw m%4, 8 ; src .. y7 .. y5
  164. %endmacro
  165. %macro SUMSUB_BA 2-3
  166. %if %0==2
  167. paddw %1, %2
  168. paddw %2, %2
  169. psubw %2, %1
  170. %else
  171. mova %3, %1
  172. paddw %1, %2
  173. psubw %2, %3
  174. %endif
  175. %endmacro
  176. %macro SUMSUB_BADC 4-5
  177. %if %0==5
  178. SUMSUB_BA %1, %2, %5
  179. SUMSUB_BA %3, %4, %5
  180. %else
  181. paddw %1, %2
  182. paddw %3, %4
  183. paddw %2, %2
  184. paddw %4, %4
  185. psubw %2, %1
  186. psubw %4, %3
  187. %endif
  188. %endmacro
  189. %macro HADAMARD4_V 4+
  190. SUMSUB_BADC %1, %2, %3, %4
  191. SUMSUB_BADC %1, %3, %2, %4
  192. %endmacro
  193. %macro HADAMARD8_V 8+
  194. SUMSUB_BADC %1, %2, %3, %4
  195. SUMSUB_BADC %5, %6, %7, %8
  196. SUMSUB_BADC %1, %3, %2, %4
  197. SUMSUB_BADC %5, %7, %6, %8
  198. SUMSUB_BADC %1, %5, %2, %6
  199. SUMSUB_BADC %3, %7, %4, %8
  200. %endmacro
  201. %macro TRANS_SSE2 5-6
  202. ; TRANSPOSE2x2
  203. ; %1: transpose width (d/q) - use SBUTTERFLY qdq for dq
  204. ; %2: ord/unord (for compat with sse4, unused)
  205. ; %3/%4: source regs
  206. ; %5/%6: tmp regs
  207. %ifidn %1, d
  208. %define mask [mask_10 GLOBAL]
  209. %define shift 16
  210. %elifidn %1, q
  211. %define mask [mask_1100 GLOBAL]
  212. %define shift 32
  213. %endif
  214. %if %0==6 ; less dependency if we have two tmp
  215. mova m%5, mask ; ff00
  216. mova m%6, m%4 ; x5x4
  217. psll%1 m%4, shift ; x4..
  218. pand m%6, m%5 ; x5..
  219. pandn m%5, m%3 ; ..x0
  220. psrl%1 m%3, shift ; ..x1
  221. por m%4, m%5 ; x4x0
  222. por m%3, m%6 ; x5x1
  223. %else ; more dependency, one insn less. sometimes faster, sometimes not
  224. mova m%5, m%4 ; x5x4
  225. psll%1 m%4, shift ; x4..
  226. pxor m%4, m%3 ; (x4^x1)x0
  227. pand m%4, mask ; (x4^x1)..
  228. pxor m%3, m%4 ; x4x0
  229. psrl%1 m%4, shift ; ..(x1^x4)
  230. pxor m%5, m%4 ; x5x1
  231. SWAP %4, %3, %5
  232. %endif
  233. %endmacro
  234. %macro TRANS_SSE4 5-6 ; see above
  235. %ifidn %1, d
  236. mova m%5, m%3
  237. %ifidn %2, ord
  238. psrl%1 m%3, 16
  239. %endif
  240. pblendw m%3, m%4, 10101010b
  241. psll%1 m%4, 16
  242. %ifidn %2, ord
  243. pblendw m%4, m%5, 01010101b
  244. %else
  245. psrl%1 m%5, 16
  246. por m%4, m%5
  247. %endif
  248. %elifidn %1, q
  249. mova m%5, m%3
  250. shufps m%3, m%4, 10001000b
  251. shufps m%5, m%4, 11011101b
  252. SWAP %4, %5
  253. %endif
  254. %endmacro
  255. %macro HADAMARD 5-6
  256. ; %1=distance in words (0 for vertical pass, 1/2/4 for horizontal passes)
  257. ; %2=sumsub/max/amax (sum and diff / maximum / maximum of absolutes)
  258. ; %3/%4: regs
  259. ; %5(%6): tmpregs
  260. %if %1!=0 ; have to reorder stuff for horizontal op
  261. %ifidn %2, sumsub
  262. %define ORDER ord
  263. ; sumsub needs order because a-b != b-a unless a=b
  264. %else
  265. %define ORDER unord
  266. ; if we just max, order doesn't matter (allows pblendw+or in sse4)
  267. %endif
  268. %if %1==1
  269. TRANS d, ORDER, %3, %4, %5, %6
  270. %elif %1==2
  271. %if mmsize==8
  272. SBUTTERFLY dq, %3, %4, %5
  273. %else
  274. TRANS q, ORDER, %3, %4, %5, %6
  275. %endif
  276. %elif %1==4
  277. SBUTTERFLY qdq, %3, %4, %5
  278. %endif
  279. %endif
  280. %ifidn %2, sumsub
  281. SUMSUB_BA m%3, m%4, m%5
  282. %else
  283. %ifidn %2, amax
  284. %if %0==6
  285. ABS2 m%3, m%4, m%5, m%6
  286. %else
  287. ABS1 m%3, m%5
  288. ABS1 m%4, m%5
  289. %endif
  290. %endif
  291. pmaxsw m%3, m%4
  292. %endif
  293. %endmacro
  294. %macro HADAMARD2_2D 6-7 sumsub
  295. HADAMARD 0, sumsub, %1, %2, %5
  296. HADAMARD 0, sumsub, %3, %4, %5
  297. SBUTTERFLY %6, %1, %2, %5
  298. %ifnum %7
  299. HADAMARD 0, amax, %1, %2, %5, %7
  300. %else
  301. HADAMARD 0, %7, %1, %2, %5
  302. %endif
  303. SBUTTERFLY %6, %3, %4, %5
  304. %ifnum %7
  305. HADAMARD 0, amax, %3, %4, %5, %7
  306. %else
  307. HADAMARD 0, %7, %3, %4, %5
  308. %endif
  309. %endmacro
  310. %macro HADAMARD4_2D 5-6 sumsub
  311. HADAMARD2_2D %1, %2, %3, %4, %5, wd
  312. HADAMARD2_2D %1, %3, %2, %4, %5, dq, %6
  313. SWAP %2, %3
  314. %endmacro
  315. %macro HADAMARD4_2D_SSE 5-6 sumsub
  316. HADAMARD 0, sumsub, %1, %2, %5 ; 1st V row 0 + 1
  317. HADAMARD 0, sumsub, %3, %4, %5 ; 1st V row 2 + 3
  318. SBUTTERFLY wd, %1, %2, %5 ; %1: m0 1+0 %2: m1 1+0
  319. SBUTTERFLY wd, %3, %4, %5 ; %3: m0 3+2 %4: m1 3+2
  320. HADAMARD2_2D %1, %3, %2, %4, %5, dq
  321. SBUTTERFLY qdq, %1, %2, %5
  322. HADAMARD 0, %6, %1, %2, %5 ; 2nd H m1/m0 row 0+1
  323. SBUTTERFLY qdq, %3, %4, %5
  324. HADAMARD 0, %6, %3, %4, %5 ; 2nd H m1/m0 row 2+3
  325. %endmacro
  326. %macro HADAMARD8_2D 9-10 sumsub
  327. HADAMARD2_2D %1, %2, %3, %4, %9, wd
  328. HADAMARD2_2D %5, %6, %7, %8, %9, wd
  329. HADAMARD2_2D %1, %3, %2, %4, %9, dq
  330. HADAMARD2_2D %5, %7, %6, %8, %9, dq
  331. HADAMARD2_2D %1, %5, %3, %7, %9, qdq, %10
  332. HADAMARD2_2D %2, %6, %4, %8, %9, qdq, %10
  333. %ifnidn %10, amax
  334. SWAP %2, %5
  335. SWAP %4, %7
  336. %endif
  337. %endmacro
  338. %macro SUMSUB2_AB 3
  339. mova %3, %1
  340. paddw %1, %1
  341. paddw %1, %2
  342. psubw %3, %2
  343. psubw %3, %2
  344. %endmacro
  345. %macro SUMSUB2_BA 3
  346. mova m%3, m%1
  347. paddw m%1, m%2
  348. paddw m%1, m%2
  349. psubw m%2, m%3
  350. psubw m%2, m%3
  351. %endmacro
  352. %macro SUMSUBD2_AB 4
  353. mova %4, %1
  354. mova %3, %2
  355. psraw %2, 1
  356. psraw %1, 1
  357. paddw %2, %4
  358. psubw %1, %3
  359. %endmacro
  360. %macro DCT4_1D 5
  361. %ifnum %5
  362. SUMSUB_BADC m%4, m%1, m%3, m%2; m%5
  363. SUMSUB_BA m%3, m%4, m%5
  364. SUMSUB2_AB m%1, m%2, m%5
  365. SWAP %1, %3, %4, %5, %2
  366. %else
  367. SUMSUB_BADC m%4, m%1, m%3, m%2
  368. SUMSUB_BA m%3, m%4
  369. mova [%5], m%2
  370. SUMSUB2_AB m%1, [%5], m%2
  371. SWAP %1, %3, %4, %2
  372. %endif
  373. %endmacro
  374. %macro IDCT4_1D 5-6
  375. %ifnum %5
  376. SUMSUBD2_AB m%2, m%4, m%6, m%5
  377. SUMSUB_BA m%3, m%1, m%6
  378. SUMSUB_BADC m%4, m%3, m%2, m%1, m%6
  379. %else
  380. SUMSUBD2_AB m%2, m%4, [%5], [%5+16]
  381. SUMSUB_BA m%3, m%1
  382. SUMSUB_BADC m%4, m%3, m%2, m%1
  383. %endif
  384. SWAP %1, %4, %3
  385. %endmacro
  386. %macro LOAD_DIFF 5
  387. %ifidn %3, none
  388. movh %1, %4
  389. movh %2, %5
  390. punpcklbw %1, %2
  391. punpcklbw %2, %2
  392. psubw %1, %2
  393. %else
  394. movh %1, %4
  395. punpcklbw %1, %3
  396. movh %2, %5
  397. punpcklbw %2, %3
  398. psubw %1, %2
  399. %endif
  400. %endmacro
  401. %macro LOAD_DIFF8x4_SSE2 8
  402. LOAD_DIFF m%1, m%5, m%6, [%7+%1*FENC_STRIDE], [%8+%1*FDEC_STRIDE]
  403. LOAD_DIFF m%2, m%5, m%6, [%7+%2*FENC_STRIDE], [%8+%2*FDEC_STRIDE]
  404. LOAD_DIFF m%3, m%5, m%6, [%7+%3*FENC_STRIDE], [%8+%3*FDEC_STRIDE]
  405. LOAD_DIFF m%4, m%5, m%6, [%7+%4*FENC_STRIDE], [%8+%4*FDEC_STRIDE]
  406. %endmacro
  407. %macro LOAD_DIFF8x4_SSSE3 8 ; 4x dst, 1x tmp, 1x mul, 2x ptr
  408. movh m%2, [%8+%1*FDEC_STRIDE]
  409. movh m%1, [%7+%1*FENC_STRIDE]
  410. punpcklbw m%1, m%2
  411. movh m%3, [%8+%2*FDEC_STRIDE]
  412. movh m%2, [%7+%2*FENC_STRIDE]
  413. punpcklbw m%2, m%3
  414. movh m%4, [%8+%3*FDEC_STRIDE]
  415. movh m%3, [%7+%3*FENC_STRIDE]
  416. punpcklbw m%3, m%4
  417. movh m%5, [%8+%4*FDEC_STRIDE]
  418. movh m%4, [%7+%4*FENC_STRIDE]
  419. punpcklbw m%4, m%5
  420. pmaddubsw m%1, m%6
  421. pmaddubsw m%2, m%6
  422. pmaddubsw m%3, m%6
  423. pmaddubsw m%4, m%6
  424. %endmacro
  425. %macro STORE_DCT 6
  426. movq [%5+%6+ 0], m%1
  427. movq [%5+%6+ 8], m%2
  428. movq [%5+%6+16], m%3
  429. movq [%5+%6+24], m%4
  430. movhps [%5+%6+32], m%1
  431. movhps [%5+%6+40], m%2
  432. movhps [%5+%6+48], m%3
  433. movhps [%5+%6+56], m%4
  434. %endmacro
  435. %macro STORE_IDCT 4
  436. movhps [r0-4*FDEC_STRIDE], %1
  437. movh [r0-3*FDEC_STRIDE], %1
  438. movhps [r0-2*FDEC_STRIDE], %2
  439. movh [r0-1*FDEC_STRIDE], %2
  440. movhps [r0+0*FDEC_STRIDE], %3
  441. movh [r0+1*FDEC_STRIDE], %3
  442. movhps [r0+2*FDEC_STRIDE], %4
  443. movh [r0+3*FDEC_STRIDE], %4
  444. %endmacro
  445. %macro LOAD_DIFF_8x4P 7-10 r0,r2,0 ; 4x dest, 2x temp, 2x pointer, increment?
  446. LOAD_DIFF m%1, m%5, m%7, [%8], [%9]
  447. LOAD_DIFF m%2, m%6, m%7, [%8+r1], [%9+r3]
  448. LOAD_DIFF m%3, m%5, m%7, [%8+2*r1], [%9+2*r3]
  449. LOAD_DIFF m%4, m%6, m%7, [%8+r4], [%9+r5]
  450. %if %10
  451. lea %8, [%8+4*r1]
  452. lea %9, [%9+4*r3]
  453. %endif
  454. %endmacro
  455. %macro DIFFx2 6-7
  456. movh %3, %5
  457. punpcklbw %3, %4
  458. psraw %1, 6
  459. paddsw %1, %3
  460. movh %3, %6
  461. punpcklbw %3, %4
  462. psraw %2, 6
  463. paddsw %2, %3
  464. packuswb %2, %1
  465. %endmacro
  466. %macro STORE_DIFF 4
  467. movh %2, %4
  468. punpcklbw %2, %3
  469. psraw %1, 6
  470. paddsw %1, %2
  471. packuswb %1, %1
  472. movh %4, %1
  473. %endmacro