2
0

x86util.asm 22 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028
  1. ;*****************************************************************************
  2. ;* x86util.asm
  3. ;*****************************************************************************
  4. ;* Copyright (C) 2008-2010 x264 project
  5. ;*
  6. ;* Authors: Loren Merritt <lorenm@u.washington.edu>
  7. ;* Holger Lubitz <holger@lubitz.org>
  8. ;*
  9. ;* This file is part of FFmpeg.
  10. ;*
  11. ;* FFmpeg is free software; you can redistribute it and/or
  12. ;* modify it under the terms of the GNU Lesser General Public
  13. ;* License as published by the Free Software Foundation; either
  14. ;* version 2.1 of the License, or (at your option) any later version.
  15. ;*
  16. ;* FFmpeg is distributed in the hope that it will be useful,
  17. ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  19. ;* Lesser General Public License for more details.
  20. ;*
  21. ;* You should have received a copy of the GNU Lesser General Public
  22. ;* License along with FFmpeg; if not, write to the Free Software
  23. ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  24. ;******************************************************************************
  25. %define private_prefix ff
  26. %define public_prefix avpriv
  27. %define cpuflags_mmxext cpuflags_mmx2
  28. %include "libavutil/x86/x86inc.asm"
  29. ; expands to [base],...,[base+7*stride]
  30. %define PASS8ROWS(base, base3, stride, stride3) \
  31. [base], [base + stride], [base + 2*stride], [base3], \
  32. [base3 + stride], [base3 + 2*stride], [base3 + stride3], [base3 + stride*4]
  33. ; Interleave low src0 with low src1 and store in src0,
  34. ; interleave high src0 with high src1 and store in src1.
  35. ; %1 - types
  36. ; %2 - index of the register with src0
  37. ; %3 - index of the register with src1
  38. ; %4 - index of the register for intermediate results
  39. ; example for %1 - wd: input: src0: x0 x1 x2 x3 z0 z1 z2 z3
  40. ; src1: y0 y1 y2 y3 q0 q1 q2 q3
  41. ; output: src0: x0 y0 x1 y1 x2 y2 x3 y3
  42. ; src1: z0 q0 z1 q1 z2 q2 z3 q3
  43. %macro SBUTTERFLY 4
  44. %ifidn %1, dqqq
  45. vperm2i128 m%4, m%2, m%3, q0301
  46. vinserti128 m%2, m%2, xm%3, 1
  47. %elif avx_enabled == 0
  48. mova m%4, m%2
  49. punpckl%1 m%2, m%3
  50. punpckh%1 m%4, m%3
  51. %else
  52. punpckh%1 m%4, m%2, m%3
  53. punpckl%1 m%2, m%3
  54. %endif
  55. SWAP %3, %4
  56. %endmacro
  57. %macro SBUTTERFLY2 4
  58. punpckl%1 m%4, m%2, m%3
  59. punpckh%1 m%2, m%2, m%3
  60. SWAP %2, %4, %3
  61. %endmacro
  62. %macro SBUTTERFLYPS 3
  63. unpcklps m%3, m%1, m%2
  64. unpckhps m%1, m%1, m%2
  65. SWAP %1, %3, %2
  66. %endmacro
  67. %macro SBUTTERFLYPD 3
  68. movlhps m%3, m%1, m%2
  69. movhlps m%2, m%2, m%1
  70. SWAP %1, %3
  71. %endmacro
  72. %macro TRANSPOSE4x4B 5
  73. SBUTTERFLY bw, %1, %2, %5
  74. SBUTTERFLY bw, %3, %4, %5
  75. SBUTTERFLY wd, %1, %3, %5
  76. SBUTTERFLY wd, %2, %4, %5
  77. SWAP %2, %3
  78. %endmacro
  79. %macro TRANSPOSE4x4W 5
  80. SBUTTERFLY wd, %1, %2, %5
  81. SBUTTERFLY wd, %3, %4, %5
  82. SBUTTERFLY dq, %1, %3, %5
  83. SBUTTERFLY dq, %2, %4, %5
  84. SWAP %2, %3
  85. %endmacro
  86. %macro TRANSPOSE2x4x4B 5
  87. SBUTTERFLY bw, %1, %2, %5
  88. SBUTTERFLY bw, %3, %4, %5
  89. SBUTTERFLY wd, %1, %3, %5
  90. SBUTTERFLY wd, %2, %4, %5
  91. SBUTTERFLY dq, %1, %2, %5
  92. SBUTTERFLY dq, %3, %4, %5
  93. %endmacro
  94. %macro TRANSPOSE2x4x4W 5
  95. SBUTTERFLY wd, %1, %2, %5
  96. SBUTTERFLY wd, %3, %4, %5
  97. SBUTTERFLY dq, %1, %3, %5
  98. SBUTTERFLY dq, %2, %4, %5
  99. SBUTTERFLY qdq, %1, %2, %5
  100. SBUTTERFLY qdq, %3, %4, %5
  101. %endmacro
  102. %macro TRANSPOSE4x4D 5
  103. SBUTTERFLY dq, %1, %2, %5
  104. SBUTTERFLY dq, %3, %4, %5
  105. SBUTTERFLY qdq, %1, %3, %5
  106. SBUTTERFLY qdq, %2, %4, %5
  107. SWAP %2, %3
  108. %endmacro
  109. ; identical behavior to TRANSPOSE4x4D, but using SSE1 float ops
  110. %macro TRANSPOSE4x4PS 5
  111. SBUTTERFLYPS %1, %2, %5
  112. SBUTTERFLYPS %3, %4, %5
  113. SBUTTERFLYPD %1, %3, %5
  114. SBUTTERFLYPD %2, %4, %5
  115. SWAP %2, %3
  116. %endmacro
  117. %macro TRANSPOSE8x4D 9-11
  118. %if ARCH_X86_64
  119. SBUTTERFLY dq, %1, %2, %9
  120. SBUTTERFLY dq, %3, %4, %9
  121. SBUTTERFLY dq, %5, %6, %9
  122. SBUTTERFLY dq, %7, %8, %9
  123. SBUTTERFLY qdq, %1, %3, %9
  124. SBUTTERFLY qdq, %2, %4, %9
  125. SBUTTERFLY qdq, %5, %7, %9
  126. SBUTTERFLY qdq, %6, %8, %9
  127. SWAP %2, %5
  128. SWAP %4, %7
  129. %else
  130. ; in: m0..m7
  131. ; out: m0..m7, unless %11 in which case m2 is in %9
  132. ; spills into %9 and %10
  133. movdqa %9, m%7
  134. SBUTTERFLY dq, %1, %2, %7
  135. movdqa %10, m%2
  136. movdqa m%7, %9
  137. SBUTTERFLY dq, %3, %4, %2
  138. SBUTTERFLY dq, %5, %6, %2
  139. SBUTTERFLY dq, %7, %8, %2
  140. SBUTTERFLY qdq, %1, %3, %2
  141. movdqa %9, m%3
  142. movdqa m%2, %10
  143. SBUTTERFLY qdq, %2, %4, %3
  144. SBUTTERFLY qdq, %5, %7, %3
  145. SBUTTERFLY qdq, %6, %8, %3
  146. SWAP %2, %5
  147. SWAP %4, %7
  148. %if %0<11
  149. movdqa m%3, %9
  150. %endif
  151. %endif
  152. %endmacro
  153. %macro TRANSPOSE8x8W 9-11
  154. %if ARCH_X86_64
  155. SBUTTERFLY wd, %1, %2, %9
  156. SBUTTERFLY wd, %3, %4, %9
  157. SBUTTERFLY wd, %5, %6, %9
  158. SBUTTERFLY wd, %7, %8, %9
  159. SBUTTERFLY dq, %1, %3, %9
  160. SBUTTERFLY dq, %2, %4, %9
  161. SBUTTERFLY dq, %5, %7, %9
  162. SBUTTERFLY dq, %6, %8, %9
  163. SBUTTERFLY qdq, %1, %5, %9
  164. SBUTTERFLY qdq, %2, %6, %9
  165. SBUTTERFLY qdq, %3, %7, %9
  166. SBUTTERFLY qdq, %4, %8, %9
  167. SWAP %2, %5
  168. SWAP %4, %7
  169. %else
  170. ; in: m0..m7, unless %11 in which case m6 is in %9
  171. ; out: m0..m7, unless %11 in which case m4 is in %10
  172. ; spills into %9 and %10
  173. %if %0<11
  174. movdqa %9, m%7
  175. %endif
  176. SBUTTERFLY wd, %1, %2, %7
  177. movdqa %10, m%2
  178. movdqa m%7, %9
  179. SBUTTERFLY wd, %3, %4, %2
  180. SBUTTERFLY wd, %5, %6, %2
  181. SBUTTERFLY wd, %7, %8, %2
  182. SBUTTERFLY dq, %1, %3, %2
  183. movdqa %9, m%3
  184. movdqa m%2, %10
  185. SBUTTERFLY dq, %2, %4, %3
  186. SBUTTERFLY dq, %5, %7, %3
  187. SBUTTERFLY dq, %6, %8, %3
  188. SBUTTERFLY qdq, %1, %5, %3
  189. SBUTTERFLY qdq, %2, %6, %3
  190. movdqa %10, m%2
  191. movdqa m%3, %9
  192. SBUTTERFLY qdq, %3, %7, %2
  193. SBUTTERFLY qdq, %4, %8, %2
  194. SWAP %2, %5
  195. SWAP %4, %7
  196. %if %0<11
  197. movdqa m%5, %10
  198. %endif
  199. %endif
  200. %endmacro
  201. %macro TRANSPOSE16x16W 18-19
  202. ; in: m0..m15, unless %19 in which case m6 is in %17
  203. ; out: m0..m15, unless %19 in which case m4 is in %18
  204. ; spills into %17 and %18
  205. %if %0 < 19
  206. mova %17, m%7
  207. %endif
  208. SBUTTERFLY dqqq, %1, %9, %7
  209. SBUTTERFLY dqqq, %2, %10, %7
  210. SBUTTERFLY dqqq, %3, %11, %7
  211. SBUTTERFLY dqqq, %4, %12, %7
  212. SBUTTERFLY dqqq, %5, %13, %7
  213. SBUTTERFLY dqqq, %6, %14, %7
  214. mova %18, m%14
  215. mova m%7, %17
  216. SBUTTERFLY dqqq, %7, %15, %14
  217. SBUTTERFLY dqqq, %8, %16, %14
  218. SBUTTERFLY wd, %1, %2, %14
  219. SBUTTERFLY wd, %3, %4, %14
  220. SBUTTERFLY wd, %5, %6, %14
  221. SBUTTERFLY wd, %7, %8, %14
  222. SBUTTERFLY wd, %9, %10, %14
  223. SBUTTERFLY wd, %11, %12, %14
  224. mova %17, m%12
  225. mova m%14, %18
  226. SBUTTERFLY wd, %13, %14, %12
  227. SBUTTERFLY wd, %15, %16, %12
  228. SBUTTERFLY dq, %1, %3, %12
  229. SBUTTERFLY dq, %2, %4, %12
  230. SBUTTERFLY dq, %5, %7, %12
  231. SBUTTERFLY dq, %6, %8, %12
  232. SBUTTERFLY dq, %9, %11, %12
  233. mova %18, m%11
  234. mova m%12, %17
  235. SBUTTERFLY dq, %10, %12, %11
  236. SBUTTERFLY dq, %13, %15, %11
  237. SBUTTERFLY dq, %14, %16, %11
  238. SBUTTERFLY qdq, %1, %5, %11
  239. SBUTTERFLY qdq, %2, %6, %11
  240. SBUTTERFLY qdq, %3, %7, %11
  241. SBUTTERFLY qdq, %4, %8, %11
  242. SWAP %2, %5
  243. SWAP %4, %7
  244. SBUTTERFLY qdq, %9, %13, %11
  245. SBUTTERFLY qdq, %10, %14, %11
  246. mova m%11, %18
  247. mova %18, m%5
  248. SBUTTERFLY qdq, %11, %15, %5
  249. SBUTTERFLY qdq, %12, %16, %5
  250. %if %0 < 19
  251. mova m%5, %18
  252. %endif
  253. SWAP %10, %13
  254. SWAP %12, %15
  255. %endmacro
  256. %macro TRANSPOSE_8X8B 8
  257. %if mmsize == 8
  258. %error "This macro does not support mmsize == 8"
  259. %endif
  260. punpcklbw m%1, m%2
  261. punpcklbw m%3, m%4
  262. punpcklbw m%5, m%6
  263. punpcklbw m%7, m%8
  264. TRANSPOSE4x4W %1, %3, %5, %7, %2
  265. MOVHL m%2, m%1
  266. MOVHL m%4, m%3
  267. MOVHL m%6, m%5
  268. MOVHL m%8, m%7
  269. %endmacro
  270. ; PABSW macro assumes %1 != %2, while ABS1/2 macros work in-place
  271. %macro PABSW 2
  272. %if cpuflag(ssse3)
  273. pabsw %1, %2
  274. %elif cpuflag(mmxext)
  275. pxor %1, %1
  276. psubw %1, %2
  277. pmaxsw %1, %2
  278. %else
  279. pxor %1, %1
  280. pcmpgtw %1, %2
  281. pxor %2, %1
  282. psubw %2, %1
  283. SWAP %1, %2
  284. %endif
  285. %endmacro
  286. %macro PSIGNW 2
  287. %if cpuflag(ssse3)
  288. psignw %1, %2
  289. %else
  290. pxor %1, %2
  291. psubw %1, %2
  292. %endif
  293. %endmacro
  294. %macro ABS1 2
  295. %if cpuflag(ssse3)
  296. pabsw %1, %1
  297. %elif cpuflag(mmxext) ; a, tmp
  298. pxor %2, %2
  299. psubw %2, %1
  300. pmaxsw %1, %2
  301. %else ; a, tmp
  302. pxor %2, %2
  303. pcmpgtw %2, %1
  304. pxor %1, %2
  305. psubw %1, %2
  306. %endif
  307. %endmacro
  308. %macro ABS2 4
  309. %if cpuflag(ssse3)
  310. pabsw %1, %1
  311. pabsw %2, %2
  312. %elif cpuflag(mmxext) ; a, b, tmp0, tmp1
  313. pxor %3, %3
  314. pxor %4, %4
  315. psubw %3, %1
  316. psubw %4, %2
  317. pmaxsw %1, %3
  318. pmaxsw %2, %4
  319. %else ; a, b, tmp0, tmp1
  320. pxor %3, %3
  321. pxor %4, %4
  322. pcmpgtw %3, %1
  323. pcmpgtw %4, %2
  324. pxor %1, %3
  325. pxor %2, %4
  326. psubw %1, %3
  327. psubw %2, %4
  328. %endif
  329. %endmacro
  330. %macro ABSB 2 ; source mmreg, temp mmreg (unused for SSSE3)
  331. %if cpuflag(ssse3)
  332. pabsb %1, %1
  333. %else
  334. pxor %2, %2
  335. psubb %2, %1
  336. pminub %1, %2
  337. %endif
  338. %endmacro
  339. %macro ABSB2 4 ; src1, src2, tmp1, tmp2 (tmp1/2 unused for SSSE3)
  340. %if cpuflag(ssse3)
  341. pabsb %1, %1
  342. pabsb %2, %2
  343. %else
  344. pxor %3, %3
  345. pxor %4, %4
  346. psubb %3, %1
  347. psubb %4, %2
  348. pminub %1, %3
  349. pminub %2, %4
  350. %endif
  351. %endmacro
  352. %macro ABSD2 4
  353. pxor %3, %3
  354. pxor %4, %4
  355. pcmpgtd %3, %1
  356. pcmpgtd %4, %2
  357. pxor %1, %3
  358. pxor %2, %4
  359. psubd %1, %3
  360. psubd %2, %4
  361. %endmacro
  362. %macro ABS4 6
  363. ABS2 %1, %2, %5, %6
  364. ABS2 %3, %4, %5, %6
  365. %endmacro
  366. %macro SPLATB_LOAD 3
  367. %if cpuflag(ssse3)
  368. movd %1, [%2-3]
  369. pshufb %1, %3
  370. %else
  371. movd %1, [%2-3] ;to avoid crossing a cacheline
  372. punpcklbw %1, %1
  373. SPLATW %1, %1, 3
  374. %endif
  375. %endmacro
  376. %macro SPLATB_REG 3
  377. %if cpuflag(ssse3)
  378. movd %1, %2d
  379. pshufb %1, %3
  380. %else
  381. movd %1, %2d
  382. punpcklbw %1, %1
  383. SPLATW %1, %1, 0
  384. %endif
  385. %endmacro
  386. %macro HADDD 2 ; sum junk
  387. %if sizeof%1 == 32
  388. %define %2 xmm%2
  389. vextracti128 %2, %1, 1
  390. %define %1 xmm%1
  391. paddd %1, %2
  392. %endif
  393. %if mmsize >= 16
  394. %if cpuflag(xop) && sizeof%1 == 16
  395. vphadddq %1, %1
  396. %endif
  397. movhlps %2, %1
  398. paddd %1, %2
  399. %endif
  400. %if notcpuflag(xop) || sizeof%1 != 16
  401. %if cpuflag(mmxext)
  402. PSHUFLW %2, %1, q0032
  403. %else ; mmx
  404. mova %2, %1
  405. psrlq %2, 32
  406. %endif
  407. paddd %1, %2
  408. %endif
  409. %undef %1
  410. %undef %2
  411. %endmacro
  412. %macro HADDW 2 ; reg, tmp
  413. %if cpuflag(xop) && sizeof%1 == 16
  414. vphaddwq %1, %1
  415. movhlps %2, %1
  416. paddd %1, %2
  417. %else
  418. pmaddwd %1, [pw_1]
  419. HADDD %1, %2
  420. %endif
  421. %endmacro
  422. %macro HADDPS 3 ; dst, src, tmp
  423. %if cpuflag(sse3)
  424. haddps %1, %1, %2
  425. %else
  426. movaps %3, %1
  427. shufps %1, %2, q2020
  428. shufps %3, %2, q3131
  429. addps %1, %3
  430. %endif
  431. %endmacro
  432. %macro PALIGNR 4-5
  433. %if cpuflag(ssse3)
  434. %if %0==5
  435. palignr %1, %2, %3, %4
  436. %else
  437. palignr %1, %2, %3
  438. %endif
  439. %else ; [dst,] src1, src2, imm, tmp
  440. %define %%dst %1
  441. %if %0==5
  442. %ifnidn %1, %2
  443. mova %%dst, %2
  444. %endif
  445. %rotate 1
  446. %endif
  447. %ifnidn %4, %2
  448. mova %4, %2
  449. %endif
  450. %if mmsize==8
  451. psllq %%dst, (8-%3)*8
  452. psrlq %4, %3*8
  453. %else
  454. pslldq %%dst, 16-%3
  455. psrldq %4, %3
  456. %endif
  457. por %%dst, %4
  458. %endif
  459. %endmacro
  460. %macro PAVGB 2-4
  461. %if cpuflag(mmxext)
  462. pavgb %1, %2
  463. %elif cpuflag(3dnow)
  464. pavgusb %1, %2
  465. %elif cpuflag(mmx)
  466. movu %3, %2
  467. por %3, %1
  468. pxor %1, %2
  469. pand %1, %4
  470. psrlq %1, 1
  471. psubb %3, %1
  472. SWAP %1, %3
  473. %endif
  474. %endmacro
  475. %macro PSHUFLW 1+
  476. %if mmsize == 8
  477. pshufw %1
  478. %else
  479. pshuflw %1
  480. %endif
  481. %endmacro
  482. %macro PSWAPD 2
  483. %if cpuflag(mmxext)
  484. pshufw %1, %2, q1032
  485. %elif cpuflag(3dnowext)
  486. pswapd %1, %2
  487. %elif cpuflag(3dnow)
  488. movq %1, %2
  489. psrlq %1, 32
  490. punpckldq %1, %2
  491. %endif
  492. %endmacro
  493. %macro DEINTB 5 ; mask, reg1, mask, reg2, optional src to fill masks from
  494. %ifnum %5
  495. pand m%3, m%5, m%4 ; src .. y6 .. y4
  496. pand m%1, m%5, m%2 ; dst .. y6 .. y4
  497. %else
  498. mova m%1, %5
  499. pand m%3, m%1, m%4 ; src .. y6 .. y4
  500. pand m%1, m%1, m%2 ; dst .. y6 .. y4
  501. %endif
  502. psrlw m%2, 8 ; dst .. y7 .. y5
  503. psrlw m%4, 8 ; src .. y7 .. y5
  504. %endmacro
  505. %macro SUMSUB_BA 3-4
  506. %if %0==3
  507. padd%1 m%2, m%3
  508. padd%1 m%3, m%3
  509. psub%1 m%3, m%2
  510. %else
  511. %if avx_enabled == 0
  512. mova m%4, m%2
  513. padd%1 m%2, m%3
  514. psub%1 m%3, m%4
  515. %else
  516. padd%1 m%4, m%2, m%3
  517. psub%1 m%3, m%2
  518. SWAP %2, %4
  519. %endif
  520. %endif
  521. %endmacro
  522. %macro SUMSUB_BADC 5-6
  523. %if %0==6
  524. SUMSUB_BA %1, %2, %3, %6
  525. SUMSUB_BA %1, %4, %5, %6
  526. %else
  527. padd%1 m%2, m%3
  528. padd%1 m%4, m%5
  529. padd%1 m%3, m%3
  530. padd%1 m%5, m%5
  531. psub%1 m%3, m%2
  532. psub%1 m%5, m%4
  533. %endif
  534. %endmacro
  535. %macro SUMSUB2_AB 4
  536. %ifnum %3
  537. psub%1 m%4, m%2, m%3
  538. psub%1 m%4, m%3
  539. padd%1 m%2, m%2
  540. padd%1 m%2, m%3
  541. %else
  542. mova m%4, m%2
  543. padd%1 m%2, m%2
  544. padd%1 m%2, %3
  545. psub%1 m%4, %3
  546. psub%1 m%4, %3
  547. %endif
  548. %endmacro
  549. %macro SUMSUB2_BA 4
  550. %if avx_enabled == 0
  551. mova m%4, m%2
  552. padd%1 m%2, m%3
  553. padd%1 m%2, m%3
  554. psub%1 m%3, m%4
  555. psub%1 m%3, m%4
  556. %else
  557. padd%1 m%4, m%2, m%3
  558. padd%1 m%4, m%3
  559. psub%1 m%3, m%2
  560. psub%1 m%3, m%2
  561. SWAP %2, %4
  562. %endif
  563. %endmacro
  564. %macro SUMSUBD2_AB 5
  565. %ifnum %4
  566. psra%1 m%5, m%2, 1 ; %3: %3>>1
  567. psra%1 m%4, m%3, 1 ; %2: %2>>1
  568. padd%1 m%4, m%2 ; %3: %3>>1+%2
  569. psub%1 m%5, m%3 ; %2: %2>>1-%3
  570. SWAP %2, %5
  571. SWAP %3, %4
  572. %else
  573. mova %5, m%2
  574. mova %4, m%3
  575. psra%1 m%3, 1 ; %3: %3>>1
  576. psra%1 m%2, 1 ; %2: %2>>1
  577. padd%1 m%3, %5 ; %3: %3>>1+%2
  578. psub%1 m%2, %4 ; %2: %2>>1-%3
  579. %endif
  580. %endmacro
  581. %macro DCT4_1D 5
  582. %ifnum %5
  583. SUMSUB_BADC w, %4, %1, %3, %2, %5
  584. SUMSUB_BA w, %3, %4, %5
  585. SUMSUB2_AB w, %1, %2, %5
  586. SWAP %1, %3, %4, %5, %2
  587. %else
  588. SUMSUB_BADC w, %4, %1, %3, %2
  589. SUMSUB_BA w, %3, %4
  590. mova [%5], m%2
  591. SUMSUB2_AB w, %1, [%5], %2
  592. SWAP %1, %3, %4, %2
  593. %endif
  594. %endmacro
  595. %macro IDCT4_1D 6-7
  596. %ifnum %6
  597. SUMSUBD2_AB %1, %3, %5, %7, %6
  598. ; %3: %3>>1-%5 %5: %3+%5>>1
  599. SUMSUB_BA %1, %4, %2, %7
  600. ; %4: %2+%4 %2: %2-%4
  601. SUMSUB_BADC %1, %5, %4, %3, %2, %7
  602. ; %5: %2+%4 + (%3+%5>>1)
  603. ; %4: %2+%4 - (%3+%5>>1)
  604. ; %3: %2-%4 + (%3>>1-%5)
  605. ; %2: %2-%4 - (%3>>1-%5)
  606. %else
  607. %ifidn %1, w
  608. SUMSUBD2_AB %1, %3, %5, [%6], [%6+16]
  609. %else
  610. SUMSUBD2_AB %1, %3, %5, [%6], [%6+32]
  611. %endif
  612. SUMSUB_BA %1, %4, %2
  613. SUMSUB_BADC %1, %5, %4, %3, %2
  614. %endif
  615. SWAP %2, %5, %4
  616. ; %2: %2+%4 + (%3+%5>>1) row0
  617. ; %3: %2-%4 + (%3>>1-%5) row1
  618. ; %4: %2-%4 - (%3>>1-%5) row2
  619. ; %5: %2+%4 - (%3+%5>>1) row3
  620. %endmacro
  621. %macro LOAD_DIFF 5
  622. %ifidn %3, none
  623. movh %1, %4
  624. movh %2, %5
  625. punpcklbw %1, %2
  626. punpcklbw %2, %2
  627. psubw %1, %2
  628. %else
  629. movh %1, %4
  630. punpcklbw %1, %3
  631. movh %2, %5
  632. punpcklbw %2, %3
  633. psubw %1, %2
  634. %endif
  635. %endmacro
  636. %macro STORE_DCT 6
  637. movq [%5+%6+ 0], m%1
  638. movq [%5+%6+ 8], m%2
  639. movq [%5+%6+16], m%3
  640. movq [%5+%6+24], m%4
  641. movhps [%5+%6+32], m%1
  642. movhps [%5+%6+40], m%2
  643. movhps [%5+%6+48], m%3
  644. movhps [%5+%6+56], m%4
  645. %endmacro
  646. %macro LOAD_DIFF_8x4P 7-10 r0,r2,0 ; 4x dest, 2x temp, 2x pointer, increment?
  647. LOAD_DIFF m%1, m%5, m%7, [%8], [%9]
  648. LOAD_DIFF m%2, m%6, m%7, [%8+r1], [%9+r3]
  649. LOAD_DIFF m%3, m%5, m%7, [%8+2*r1], [%9+2*r3]
  650. LOAD_DIFF m%4, m%6, m%7, [%8+r4], [%9+r5]
  651. %if %10
  652. lea %8, [%8+4*r1]
  653. lea %9, [%9+4*r3]
  654. %endif
  655. %endmacro
  656. %macro DIFFx2 6-7
  657. movh %3, %5
  658. punpcklbw %3, %4
  659. psraw %1, 6
  660. paddsw %1, %3
  661. movh %3, %6
  662. punpcklbw %3, %4
  663. psraw %2, 6
  664. paddsw %2, %3
  665. packuswb %2, %1
  666. %endmacro
  667. %macro STORE_DIFF 4
  668. movh %2, %4
  669. punpcklbw %2, %3
  670. psraw %1, 6
  671. paddsw %1, %2
  672. packuswb %1, %1
  673. movh %4, %1
  674. %endmacro
  675. %macro STORE_DIFFx2 8 ; add1, add2, reg1, reg2, zero, shift, source, stride
  676. movh %3, [%7]
  677. movh %4, [%7+%8]
  678. psraw %1, %6
  679. psraw %2, %6
  680. punpcklbw %3, %5
  681. punpcklbw %4, %5
  682. paddw %3, %1
  683. paddw %4, %2
  684. packuswb %3, %5
  685. packuswb %4, %5
  686. movh [%7], %3
  687. movh [%7+%8], %4
  688. %endmacro
  689. %macro PMINUB 3 ; dst, src, ignored
  690. %if cpuflag(mmxext)
  691. pminub %1, %2
  692. %else ; dst, src, tmp
  693. mova %3, %1
  694. psubusb %3, %2
  695. psubb %1, %3
  696. %endif
  697. %endmacro
  698. %macro SPLATW 2-3 0
  699. %if cpuflag(avx2) && %3 == 0
  700. vpbroadcastw %1, %2
  701. %elif mmsize == 16
  702. pshuflw %1, %2, (%3)*0x55
  703. punpcklqdq %1, %1
  704. %elif cpuflag(mmxext)
  705. pshufw %1, %2, (%3)*0x55
  706. %else
  707. %ifnidn %1, %2
  708. mova %1, %2
  709. %endif
  710. %if %3 & 2
  711. punpckhwd %1, %1
  712. %else
  713. punpcklwd %1, %1
  714. %endif
  715. %if %3 & 1
  716. punpckhwd %1, %1
  717. %else
  718. punpcklwd %1, %1
  719. %endif
  720. %endif
  721. %endmacro
  722. %macro SPLATD 1
  723. %if mmsize == 8
  724. punpckldq %1, %1
  725. %elif cpuflag(sse2)
  726. pshufd %1, %1, 0
  727. %elif cpuflag(sse)
  728. shufps %1, %1, 0
  729. %endif
  730. %endmacro
  731. %macro CLIPUB 3 ;(dst, min, max)
  732. pmaxub %1, %2
  733. pminub %1, %3
  734. %endmacro
  735. %macro CLIPW 3 ;(dst, min, max)
  736. pmaxsw %1, %2
  737. pminsw %1, %3
  738. %endmacro
  739. %macro PMINSD 3 ; dst, src, tmp/unused
  740. %if cpuflag(sse4)
  741. pminsd %1, %2
  742. %elif cpuflag(sse2)
  743. cvtdq2ps %1, %1
  744. minps %1, %2
  745. cvtps2dq %1, %1
  746. %else
  747. mova %3, %2
  748. pcmpgtd %3, %1
  749. pxor %1, %2
  750. pand %1, %3
  751. pxor %1, %2
  752. %endif
  753. %endmacro
  754. %macro PMAXSD 3 ; dst, src, tmp/unused
  755. %if cpuflag(sse4)
  756. pmaxsd %1, %2
  757. %else
  758. mova %3, %1
  759. pcmpgtd %3, %2
  760. pand %1, %3
  761. pandn %3, %2
  762. por %1, %3
  763. %endif
  764. %endmacro
  765. %macro CLIPD 3-4
  766. %if cpuflag(sse4); src/dst, min, max, unused
  767. pminsd %1, %3
  768. pmaxsd %1, %2
  769. %elif cpuflag(sse2) ; src/dst, min (float), max (float), unused
  770. cvtdq2ps %1, %1
  771. minps %1, %3
  772. maxps %1, %2
  773. cvtps2dq %1, %1
  774. %else ; src/dst, min, max, tmp
  775. PMINSD %1, %3, %4
  776. PMAXSD %1, %2, %4
  777. %endif
  778. %endmacro
  779. %macro VBROADCASTSS 2 ; dst xmm/ymm, src m32/xmm
  780. %if cpuflag(avx2)
  781. vbroadcastss %1, %2
  782. %elif cpuflag(avx)
  783. %ifnum sizeof%2 ; avx1 register
  784. shufps xmm%1, xmm%2, xmm%2, q0000
  785. %if sizeof%1 >= 32 ; mmsize>=32
  786. vinsertf128 %1, %1, xmm%1, 1
  787. %endif
  788. %else ; avx1 memory
  789. vbroadcastss %1, %2
  790. %endif
  791. %else
  792. %ifnum sizeof%2 ; sse register
  793. shufps %1, %2, %2, q0000
  794. %else ; sse memory
  795. movss %1, %2
  796. shufps %1, %1, 0
  797. %endif
  798. %endif
  799. %endmacro
  800. %macro VBROADCASTSD 2 ; dst xmm/ymm, src m64
  801. %if cpuflag(avx) && mmsize == 32
  802. vbroadcastsd %1, %2
  803. %elif cpuflag(sse3)
  804. movddup %1, %2
  805. %else ; sse2
  806. movsd %1, %2
  807. movlhps %1, %1
  808. %endif
  809. %endmacro
  810. %macro VPBROADCASTD 2 ; dst xmm/ymm, src m32/xmm
  811. %if cpuflag(avx2)
  812. vpbroadcastd %1, %2
  813. %elif cpuflag(avx) && sizeof%1 >= 32
  814. %error vpbroadcastd not possible with ymm on avx1. try vbroadcastss
  815. %else
  816. %ifnum sizeof%2 ; sse2 register
  817. pshufd %1, %2, q0000
  818. %else ; sse memory
  819. movd %1, %2
  820. pshufd %1, %1, 0
  821. %endif
  822. %endif
  823. %endmacro
  824. %macro VBROADCASTI128 2 ; dst xmm/ymm, src : 128bits val
  825. %if mmsize > 16
  826. vbroadcasti128 %1, %2
  827. %else
  828. mova %1, %2
  829. %endif
  830. %endmacro
  831. %macro SHUFFLE_MASK_W 8
  832. %rep 8
  833. %if %1>=0x80
  834. db %1, %1
  835. %else
  836. db %1*2
  837. db %1*2+1
  838. %endif
  839. %rotate 1
  840. %endrep
  841. %endmacro
  842. %macro PMOVSXWD 2; dst, src
  843. %if cpuflag(sse4)
  844. pmovsxwd %1, %2
  845. %else
  846. %ifnidn %1, %2
  847. mova %1, %2
  848. %endif
  849. punpcklwd %1, %1
  850. psrad %1, 16
  851. %endif
  852. %endmacro
  853. ; Wrapper for non-FMA version of fmaddps
  854. %macro FMULADD_PS 5
  855. %if cpuflag(fma3) || cpuflag(fma4)
  856. fmaddps %1, %2, %3, %4
  857. %elifidn %1, %4
  858. mulps %5, %2, %3
  859. addps %1, %4, %5
  860. %else
  861. mulps %1, %2, %3
  862. addps %1, %4
  863. %endif
  864. %endmacro
  865. %macro LSHIFT 2
  866. %if mmsize > 8
  867. pslldq %1, %2
  868. %else
  869. psllq %1, 8*(%2)
  870. %endif
  871. %endmacro
  872. %macro RSHIFT 2
  873. %if mmsize > 8
  874. psrldq %1, %2
  875. %else
  876. psrlq %1, 8*(%2)
  877. %endif
  878. %endmacro
  879. %macro MOVHL 2 ; dst, src
  880. %ifidn %1, %2
  881. punpckhqdq %1, %2
  882. %elif cpuflag(avx)
  883. punpckhqdq %1, %2, %2
  884. %elif cpuflag(sse4)
  885. pshufd %1, %2, q3232 ; pshufd is slow on some older CPUs, so only use it on more modern ones
  886. %else
  887. movhlps %1, %2 ; may cause an int/float domain transition and has a dependency on dst
  888. %endif
  889. %endmacro
  890. ; Horizontal Sum of Packed Single precision floats
  891. ; The resulting sum is in all elements.
  892. %macro HSUMPS 2 ; dst/src, tmp
  893. %if cpuflag(avx)
  894. %if sizeof%1>=32 ; avx
  895. vperm2f128 %2, %1, %1, (0)*16+(1)
  896. addps %1, %2
  897. %endif
  898. shufps %2, %1, %1, q1032
  899. addps %1, %2
  900. shufps %2, %1, %1, q0321
  901. addps %1, %2
  902. %else ; this form is a bit faster than the short avx-like emulation.
  903. movaps %2, %1
  904. shufps %1, %1, q1032
  905. addps %1, %2
  906. movaps %2, %1
  907. shufps %1, %1, q0321
  908. addps %1, %2
  909. ; all %1 members should be equal for as long as float a+b==b+a
  910. %endif
  911. %endmacro
  912. ; Emulate blendvps if not available
  913. ;
  914. ; src_b is destroyed when using emulation with logical operands
  915. ; SSE41 blendv instruction is hard coded to use xmm0 as mask
  916. %macro BLENDVPS 3 ; dst/src_a, src_b, mask
  917. %if cpuflag(avx)
  918. blendvps %1, %1, %2, %3
  919. %elif cpuflag(sse4)
  920. %ifnidn %3,xmm0
  921. %error sse41 blendvps uses xmm0 as default 3d operand, you used %3
  922. %endif
  923. blendvps %1, %2, %3
  924. %else
  925. xorps %2, %1
  926. andps %2, %3
  927. xorps %1, %2
  928. %endif
  929. %endmacro
  930. ; Emulate pblendvb if not available
  931. ;
  932. ; src_b is destroyed when using emulation with logical operands
  933. ; SSE41 blendv instruction is hard coded to use xmm0 as mask
  934. %macro PBLENDVB 3 ; dst/src_a, src_b, mask
  935. %if cpuflag(avx)
  936. %if cpuflag(avx) && notcpuflag(avx2) && sizeof%1 >= 32
  937. %error pblendb not possible with ymm on avx1, try blendvps.
  938. %endif
  939. pblendvb %1, %1, %2, %3
  940. %elif cpuflag(sse4)
  941. %ifnidn %3,xmm0
  942. %error sse41 pblendvd uses xmm0 as default 3d operand, you used %3
  943. %endif
  944. pblendvb %1, %2, %3
  945. %else
  946. pxor %2, %1
  947. pand %2, %3
  948. pxor %1, %2
  949. %endif
  950. %endmacro