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.

708 lines
14KB

  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 Libav.
  10. ;*
  11. ;* Libav 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. ;* Libav 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 Libav; 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. ; Interleave low src0 with low src1 and store in src0,
  30. ; interleave high src0 with high src1 and store in src1.
  31. ; %1 - types
  32. ; %2 - index of the register with src0
  33. ; %3 - index of the register with src1
  34. ; %4 - index of the register for intermediate results
  35. ; example for %1 - wd: input: src0: x0 x1 x2 x3 z0 z1 z2 z3
  36. ; src1: y0 y1 y2 y3 q0 q1 q2 q3
  37. ; output: src0: x0 y0 x1 y1 x2 y2 x3 y3
  38. ; src1: z0 q0 z1 q1 z2 q2 z3 q3
  39. %macro SBUTTERFLY 4
  40. %if avx_enabled == 0
  41. mova m%4, m%2
  42. punpckl%1 m%2, m%3
  43. punpckh%1 m%4, m%3
  44. %else
  45. punpckh%1 m%4, m%2, m%3
  46. punpckl%1 m%2, m%3
  47. %endif
  48. SWAP %3, %4
  49. %endmacro
  50. %macro SBUTTERFLY2 4
  51. punpckl%1 m%4, m%2, m%3
  52. punpckh%1 m%2, m%2, m%3
  53. SWAP %2, %4, %3
  54. %endmacro
  55. %macro SBUTTERFLYPS 3
  56. unpcklps m%3, m%1, m%2
  57. unpckhps m%1, m%1, m%2
  58. SWAP %1, %3, %2
  59. %endmacro
  60. %macro TRANSPOSE4x4B 5
  61. SBUTTERFLY bw, %1, %2, %5
  62. SBUTTERFLY bw, %3, %4, %5
  63. SBUTTERFLY wd, %1, %3, %5
  64. SBUTTERFLY wd, %2, %4, %5
  65. SWAP %2, %3
  66. %endmacro
  67. %macro TRANSPOSE4x4W 5
  68. SBUTTERFLY wd, %1, %2, %5
  69. SBUTTERFLY wd, %3, %4, %5
  70. SBUTTERFLY dq, %1, %3, %5
  71. SBUTTERFLY dq, %2, %4, %5
  72. SWAP %2, %3
  73. %endmacro
  74. %macro TRANSPOSE2x4x4W 5
  75. SBUTTERFLY wd, %1, %2, %5
  76. SBUTTERFLY wd, %3, %4, %5
  77. SBUTTERFLY dq, %1, %3, %5
  78. SBUTTERFLY dq, %2, %4, %5
  79. SBUTTERFLY qdq, %1, %2, %5
  80. SBUTTERFLY qdq, %3, %4, %5
  81. %endmacro
  82. %macro TRANSPOSE4x4D 5
  83. SBUTTERFLY dq, %1, %2, %5
  84. SBUTTERFLY dq, %3, %4, %5
  85. SBUTTERFLY qdq, %1, %3, %5
  86. SBUTTERFLY qdq, %2, %4, %5
  87. SWAP %2, %3
  88. %endmacro
  89. ; identical behavior to TRANSPOSE4x4D, but using SSE1 float ops
  90. %macro TRANSPOSE4x4PS 5
  91. SBUTTERFLYPS %1, %2, %5
  92. SBUTTERFLYPS %3, %4, %5
  93. movlhps m%5, m%1, m%3
  94. movhlps m%3, m%1
  95. SWAP %5, %1
  96. movlhps m%5, m%2, m%4
  97. movhlps m%4, m%2
  98. SWAP %5, %2, %3
  99. %endmacro
  100. %macro TRANSPOSE8x8W 9-11
  101. %if ARCH_X86_64
  102. SBUTTERFLY wd, %1, %2, %9
  103. SBUTTERFLY wd, %3, %4, %9
  104. SBUTTERFLY wd, %5, %6, %9
  105. SBUTTERFLY wd, %7, %8, %9
  106. SBUTTERFLY dq, %1, %3, %9
  107. SBUTTERFLY dq, %2, %4, %9
  108. SBUTTERFLY dq, %5, %7, %9
  109. SBUTTERFLY dq, %6, %8, %9
  110. SBUTTERFLY qdq, %1, %5, %9
  111. SBUTTERFLY qdq, %2, %6, %9
  112. SBUTTERFLY qdq, %3, %7, %9
  113. SBUTTERFLY qdq, %4, %8, %9
  114. SWAP %2, %5
  115. SWAP %4, %7
  116. %else
  117. ; in: m0..m7, unless %11 in which case m6 is in %9
  118. ; out: m0..m7, unless %11 in which case m4 is in %10
  119. ; spills into %9 and %10
  120. %if %0<11
  121. movdqa %9, m%7
  122. %endif
  123. SBUTTERFLY wd, %1, %2, %7
  124. movdqa %10, m%2
  125. movdqa m%7, %9
  126. SBUTTERFLY wd, %3, %4, %2
  127. SBUTTERFLY wd, %5, %6, %2
  128. SBUTTERFLY wd, %7, %8, %2
  129. SBUTTERFLY dq, %1, %3, %2
  130. movdqa %9, m%3
  131. movdqa m%2, %10
  132. SBUTTERFLY dq, %2, %4, %3
  133. SBUTTERFLY dq, %5, %7, %3
  134. SBUTTERFLY dq, %6, %8, %3
  135. SBUTTERFLY qdq, %1, %5, %3
  136. SBUTTERFLY qdq, %2, %6, %3
  137. movdqa %10, m%2
  138. movdqa m%3, %9
  139. SBUTTERFLY qdq, %3, %7, %2
  140. SBUTTERFLY qdq, %4, %8, %2
  141. SWAP %2, %5
  142. SWAP %4, %7
  143. %if %0<11
  144. movdqa m%5, %10
  145. %endif
  146. %endif
  147. %endmacro
  148. ; PABSW macro assumes %1 != %2, while ABS1/2 macros work in-place
  149. %macro PABSW 2
  150. %if cpuflag(ssse3)
  151. pabsw %1, %2
  152. %elif cpuflag(mmxext)
  153. pxor %1, %1
  154. psubw %1, %2
  155. pmaxsw %1, %2
  156. %else
  157. pxor %1, %1
  158. pcmpgtw %1, %2
  159. pxor %2, %1
  160. psubw %2, %1
  161. SWAP %1, %2
  162. %endif
  163. %endmacro
  164. %macro PSIGNW 2
  165. %if cpuflag(ssse3)
  166. psignw %1, %2
  167. %else
  168. pxor %1, %2
  169. psubw %1, %2
  170. %endif
  171. %endmacro
  172. %macro ABS1 2
  173. %if cpuflag(ssse3)
  174. pabsw %1, %1
  175. %elif cpuflag(mmxext) ; a, tmp
  176. pxor %2, %2
  177. psubw %2, %1
  178. pmaxsw %1, %2
  179. %else ; a, tmp
  180. pxor %2, %2
  181. pcmpgtw %2, %1
  182. pxor %1, %2
  183. psubw %1, %2
  184. %endif
  185. %endmacro
  186. %macro ABS2 4
  187. %if cpuflag(ssse3)
  188. pabsw %1, %1
  189. pabsw %2, %2
  190. %elif cpuflag(mmxext) ; a, b, tmp0, tmp1
  191. pxor %3, %3
  192. pxor %4, %4
  193. psubw %3, %1
  194. psubw %4, %2
  195. pmaxsw %1, %3
  196. pmaxsw %2, %4
  197. %else ; a, b, tmp0, tmp1
  198. pxor %3, %3
  199. pxor %4, %4
  200. pcmpgtw %3, %1
  201. pcmpgtw %4, %2
  202. pxor %1, %3
  203. pxor %2, %4
  204. psubw %1, %3
  205. psubw %2, %4
  206. %endif
  207. %endmacro
  208. %macro ABSB 2 ; source mmreg, temp mmreg (unused for SSSE3)
  209. %if cpuflag(ssse3)
  210. pabsb %1, %1
  211. %else
  212. pxor %2, %2
  213. psubb %2, %1
  214. pminub %1, %2
  215. %endif
  216. %endmacro
  217. %macro ABSB2 4 ; src1, src2, tmp1, tmp2 (tmp1/2 unused for SSSE3)
  218. %if cpuflag(ssse3)
  219. pabsb %1, %1
  220. pabsb %2, %2
  221. %else
  222. pxor %3, %3
  223. pxor %4, %4
  224. psubb %3, %1
  225. psubb %4, %2
  226. pminub %1, %3
  227. pminub %2, %4
  228. %endif
  229. %endmacro
  230. %macro ABSD2 4
  231. pxor %3, %3
  232. pxor %4, %4
  233. pcmpgtd %3, %1
  234. pcmpgtd %4, %2
  235. pxor %1, %3
  236. pxor %2, %4
  237. psubd %1, %3
  238. psubd %2, %4
  239. %endmacro
  240. %macro ABS4 6
  241. ABS2 %1, %2, %5, %6
  242. ABS2 %3, %4, %5, %6
  243. %endmacro
  244. %macro SPLATB_LOAD 3
  245. %if cpuflag(ssse3)
  246. movd %1, [%2-3]
  247. pshufb %1, %3
  248. %else
  249. movd %1, [%2-3] ;to avoid crossing a cacheline
  250. punpcklbw %1, %1
  251. SPLATW %1, %1, 3
  252. %endif
  253. %endmacro
  254. %macro SPLATB_REG 3
  255. %if cpuflag(ssse3)
  256. movd %1, %2d
  257. pshufb %1, %3
  258. %else
  259. movd %1, %2d
  260. punpcklbw %1, %1
  261. SPLATW %1, %1, 0
  262. %endif
  263. %endmacro
  264. %macro PALIGNR 4-5
  265. %if cpuflag(ssse3)
  266. %if %0==5
  267. palignr %1, %2, %3, %4
  268. %else
  269. palignr %1, %2, %3
  270. %endif
  271. %else ; [dst,] src1, src2, imm, tmp
  272. %define %%dst %1
  273. %if %0==5
  274. %ifnidn %1, %2
  275. mova %%dst, %2
  276. %endif
  277. %rotate 1
  278. %endif
  279. %ifnidn %4, %2
  280. mova %4, %2
  281. %endif
  282. %if mmsize==8
  283. psllq %%dst, (8-%3)*8
  284. psrlq %4, %3*8
  285. %else
  286. pslldq %%dst, 16-%3
  287. psrldq %4, %3
  288. %endif
  289. por %%dst, %4
  290. %endif
  291. %endmacro
  292. %macro PAVGB 2
  293. %if cpuflag(mmxext)
  294. pavgb %1, %2
  295. %elif cpuflag(3dnow)
  296. pavgusb %1, %2
  297. %endif
  298. %endmacro
  299. %macro PSHUFLW 1+
  300. %if mmsize == 8
  301. pshufw %1
  302. %else
  303. pshuflw %1
  304. %endif
  305. %endmacro
  306. %macro PSWAPD 2
  307. %if cpuflag(mmxext)
  308. pshufw %1, %2, q1032
  309. %elif cpuflag(3dnowext)
  310. pswapd %1, %2
  311. %elif cpuflag(3dnow)
  312. movq %1, %2
  313. psrlq %1, 32
  314. punpckldq %1, %2
  315. %endif
  316. %endmacro
  317. %macro DEINTB 5 ; mask, reg1, mask, reg2, optional src to fill masks from
  318. %ifnum %5
  319. pand m%3, m%5, m%4 ; src .. y6 .. y4
  320. pand m%1, m%5, m%2 ; dst .. y6 .. y4
  321. %else
  322. mova m%1, %5
  323. pand m%3, m%1, m%4 ; src .. y6 .. y4
  324. pand m%1, m%1, m%2 ; dst .. y6 .. y4
  325. %endif
  326. psrlw m%2, 8 ; dst .. y7 .. y5
  327. psrlw m%4, 8 ; src .. y7 .. y5
  328. %endmacro
  329. %macro SUMSUB_BA 3-4
  330. %if %0==3
  331. padd%1 m%2, m%3
  332. padd%1 m%3, m%3
  333. psub%1 m%3, m%2
  334. %else
  335. %if avx_enabled == 0
  336. mova m%4, m%2
  337. padd%1 m%2, m%3
  338. psub%1 m%3, m%4
  339. %else
  340. padd%1 m%4, m%2, m%3
  341. psub%1 m%3, m%2
  342. SWAP %2, %4
  343. %endif
  344. %endif
  345. %endmacro
  346. %macro SUMSUB_BADC 5-6
  347. %if %0==6
  348. SUMSUB_BA %1, %2, %3, %6
  349. SUMSUB_BA %1, %4, %5, %6
  350. %else
  351. padd%1 m%2, m%3
  352. padd%1 m%4, m%5
  353. padd%1 m%3, m%3
  354. padd%1 m%5, m%5
  355. psub%1 m%3, m%2
  356. psub%1 m%5, m%4
  357. %endif
  358. %endmacro
  359. %macro SUMSUB2_AB 4
  360. %ifnum %3
  361. psub%1 m%4, m%2, m%3
  362. psub%1 m%4, m%3
  363. padd%1 m%2, m%2
  364. padd%1 m%2, m%3
  365. %else
  366. mova m%4, m%2
  367. padd%1 m%2, m%2
  368. padd%1 m%2, %3
  369. psub%1 m%4, %3
  370. psub%1 m%4, %3
  371. %endif
  372. %endmacro
  373. %macro SUMSUB2_BA 4
  374. %if avx_enabled == 0
  375. mova m%4, m%2
  376. padd%1 m%2, m%3
  377. padd%1 m%2, m%3
  378. psub%1 m%3, m%4
  379. psub%1 m%3, m%4
  380. %else
  381. padd%1 m%4, m%2, m%3
  382. padd%1 m%4, m%3
  383. psub%1 m%3, m%2
  384. psub%1 m%3, m%2
  385. SWAP %2, %4
  386. %endif
  387. %endmacro
  388. %macro SUMSUBD2_AB 5
  389. %ifnum %4
  390. psra%1 m%5, m%2, 1 ; %3: %3>>1
  391. psra%1 m%4, m%3, 1 ; %2: %2>>1
  392. padd%1 m%4, m%2 ; %3: %3>>1+%2
  393. psub%1 m%5, m%3 ; %2: %2>>1-%3
  394. SWAP %2, %5
  395. SWAP %3, %4
  396. %else
  397. mova %5, m%2
  398. mova %4, m%3
  399. psra%1 m%3, 1 ; %3: %3>>1
  400. psra%1 m%2, 1 ; %2: %2>>1
  401. padd%1 m%3, %5 ; %3: %3>>1+%2
  402. psub%1 m%2, %4 ; %2: %2>>1-%3
  403. %endif
  404. %endmacro
  405. %macro DCT4_1D 5
  406. %ifnum %5
  407. SUMSUB_BADC w, %4, %1, %3, %2, %5
  408. SUMSUB_BA w, %3, %4, %5
  409. SUMSUB2_AB w, %1, %2, %5
  410. SWAP %1, %3, %4, %5, %2
  411. %else
  412. SUMSUB_BADC w, %4, %1, %3, %2
  413. SUMSUB_BA w, %3, %4
  414. mova [%5], m%2
  415. SUMSUB2_AB w, %1, [%5], %2
  416. SWAP %1, %3, %4, %2
  417. %endif
  418. %endmacro
  419. %macro IDCT4_1D 6-7
  420. %ifnum %6
  421. SUMSUBD2_AB %1, %3, %5, %7, %6
  422. ; %3: %3>>1-%5 %5: %3+%5>>1
  423. SUMSUB_BA %1, %4, %2, %7
  424. ; %4: %2+%4 %2: %2-%4
  425. SUMSUB_BADC %1, %5, %4, %3, %2, %7
  426. ; %5: %2+%4 + (%3+%5>>1)
  427. ; %4: %2+%4 - (%3+%5>>1)
  428. ; %3: %2-%4 + (%3>>1-%5)
  429. ; %2: %2-%4 - (%3>>1-%5)
  430. %else
  431. %ifidn %1, w
  432. SUMSUBD2_AB %1, %3, %5, [%6], [%6+16]
  433. %else
  434. SUMSUBD2_AB %1, %3, %5, [%6], [%6+32]
  435. %endif
  436. SUMSUB_BA %1, %4, %2
  437. SUMSUB_BADC %1, %5, %4, %3, %2
  438. %endif
  439. SWAP %2, %5, %4
  440. ; %2: %2+%4 + (%3+%5>>1) row0
  441. ; %3: %2-%4 + (%3>>1-%5) row1
  442. ; %4: %2-%4 - (%3>>1-%5) row2
  443. ; %5: %2+%4 - (%3+%5>>1) row3
  444. %endmacro
  445. %macro LOAD_DIFF 5
  446. %ifidn %3, none
  447. movh %1, %4
  448. movh %2, %5
  449. punpcklbw %1, %2
  450. punpcklbw %2, %2
  451. psubw %1, %2
  452. %else
  453. movh %1, %4
  454. punpcklbw %1, %3
  455. movh %2, %5
  456. punpcklbw %2, %3
  457. psubw %1, %2
  458. %endif
  459. %endmacro
  460. %macro STORE_DCT 6
  461. movq [%5+%6+ 0], m%1
  462. movq [%5+%6+ 8], m%2
  463. movq [%5+%6+16], m%3
  464. movq [%5+%6+24], m%4
  465. movhps [%5+%6+32], m%1
  466. movhps [%5+%6+40], m%2
  467. movhps [%5+%6+48], m%3
  468. movhps [%5+%6+56], m%4
  469. %endmacro
  470. %macro LOAD_DIFF_8x4P 7-10 r0,r2,0 ; 4x dest, 2x temp, 2x pointer, increment?
  471. LOAD_DIFF m%1, m%5, m%7, [%8], [%9]
  472. LOAD_DIFF m%2, m%6, m%7, [%8+r1], [%9+r3]
  473. LOAD_DIFF m%3, m%5, m%7, [%8+2*r1], [%9+2*r3]
  474. LOAD_DIFF m%4, m%6, m%7, [%8+r4], [%9+r5]
  475. %if %10
  476. lea %8, [%8+4*r1]
  477. lea %9, [%9+4*r3]
  478. %endif
  479. %endmacro
  480. %macro DIFFx2 6-7
  481. movh %3, %5
  482. punpcklbw %3, %4
  483. psraw %1, 6
  484. paddsw %1, %3
  485. movh %3, %6
  486. punpcklbw %3, %4
  487. psraw %2, 6
  488. paddsw %2, %3
  489. packuswb %2, %1
  490. %endmacro
  491. %macro STORE_DIFF 4
  492. movh %2, %4
  493. punpcklbw %2, %3
  494. psraw %1, 6
  495. paddsw %1, %2
  496. packuswb %1, %1
  497. movh %4, %1
  498. %endmacro
  499. %macro STORE_DIFFx2 8 ; add1, add2, reg1, reg2, zero, shift, source, stride
  500. movh %3, [%7]
  501. movh %4, [%7+%8]
  502. psraw %1, %6
  503. psraw %2, %6
  504. punpcklbw %3, %5
  505. punpcklbw %4, %5
  506. paddw %3, %1
  507. paddw %4, %2
  508. packuswb %3, %5
  509. packuswb %4, %5
  510. movh [%7], %3
  511. movh [%7+%8], %4
  512. %endmacro
  513. %macro PMINUB 3 ; dst, src, ignored
  514. %if cpuflag(mmxext)
  515. pminub %1, %2
  516. %else ; dst, src, tmp
  517. mova %3, %1
  518. psubusb %3, %2
  519. psubb %1, %3
  520. %endif
  521. %endmacro
  522. %macro SPLATW 2-3 0
  523. %if cpuflag(avx2) && %3 == 0
  524. vpbroadcastw %1, %2
  525. %elif mmsize == 16
  526. pshuflw %1, %2, (%3)*0x55
  527. punpcklqdq %1, %1
  528. %elif cpuflag(mmxext)
  529. pshufw %1, %2, (%3)*0x55
  530. %else
  531. %ifnidn %1, %2
  532. mova %1, %2
  533. %endif
  534. %if %3 & 2
  535. punpckhwd %1, %1
  536. %else
  537. punpcklwd %1, %1
  538. %endif
  539. %if %3 & 1
  540. punpckhwd %1, %1
  541. %else
  542. punpcklwd %1, %1
  543. %endif
  544. %endif
  545. %endmacro
  546. %macro SPLATD 1
  547. %if mmsize == 8
  548. punpckldq %1, %1
  549. %elif cpuflag(sse2)
  550. pshufd %1, %1, 0
  551. %elif cpuflag(sse)
  552. shufps %1, %1, 0
  553. %endif
  554. %endmacro
  555. %macro CLIPUB 3 ;(dst, min, max)
  556. pmaxub %1, %2
  557. pminub %1, %3
  558. %endmacro
  559. %macro CLIPW 3 ;(dst, min, max)
  560. pmaxsw %1, %2
  561. pminsw %1, %3
  562. %endmacro
  563. %macro PMINSD 3 ; dst, src, tmp/unused
  564. %if cpuflag(sse4)
  565. pminsd %1, %2
  566. %elif cpuflag(sse2)
  567. cvtdq2ps %1, %1
  568. minps %1, %2
  569. cvtps2dq %1, %1
  570. %else
  571. mova %3, %2
  572. pcmpgtd %3, %1
  573. pxor %1, %2
  574. pand %1, %3
  575. pxor %1, %2
  576. %endif
  577. %endmacro
  578. %macro PMAXSD 3 ; dst, src, tmp/unused
  579. %if cpuflag(sse4)
  580. pmaxsd %1, %2
  581. %else
  582. mova %3, %1
  583. pcmpgtd %3, %2
  584. pand %1, %3
  585. pandn %3, %2
  586. por %1, %3
  587. %endif
  588. %endmacro
  589. %macro CLIPD 3-4
  590. %if cpuflag(sse4); src/dst, min, max, unused
  591. pminsd %1, %3
  592. pmaxsd %1, %2
  593. %elif cpuflag(sse2) ; src/dst, min (float), max (float), unused
  594. cvtdq2ps %1, %1
  595. minps %1, %3
  596. maxps %1, %2
  597. cvtps2dq %1, %1
  598. %else ; src/dst, min, max, tmp
  599. PMINSD %1, %3, %4
  600. PMAXSD %1, %2, %4
  601. %endif
  602. %endmacro
  603. %macro VBROADCASTSS 2 ; dst xmm/ymm, src m32
  604. %if cpuflag(avx)
  605. vbroadcastss %1, %2
  606. %else ; sse
  607. movss %1, %2
  608. shufps %1, %1, 0
  609. %endif
  610. %endmacro
  611. %macro VBROADCASTSD 2 ; dst xmm/ymm, src m64
  612. %if cpuflag(avx) && mmsize == 32
  613. vbroadcastsd %1, %2
  614. %elif cpuflag(sse3)
  615. movddup %1, %2
  616. %else ; sse2
  617. movsd %1, %2
  618. movlhps %1, %1
  619. %endif
  620. %endmacro
  621. %macro SHUFFLE_MASK_W 8
  622. %rep 8
  623. %if %1>=0x80
  624. db %1, %1
  625. %else
  626. db %1*2
  627. db %1*2+1
  628. %endif
  629. %rotate 1
  630. %endrep
  631. %endmacro
  632. %macro PMOVSXWD 2; dst, src
  633. %if cpuflag(sse4)
  634. pmovsxwd %1, %2
  635. %else
  636. %ifnidn %1, %2
  637. mova %1, %2
  638. %endif
  639. punpcklwd %1, %1
  640. psrad %1, 16
  641. %endif
  642. %endmacro
  643. ; Wrapper for non-FMA version of fmaddps
  644. %macro FMULADD_PS 5
  645. %if cpuflag(fma3) || cpuflag(fma4)
  646. fmaddps %1, %2, %3, %4
  647. %elifidn %1, %4
  648. mulps %5, %2, %3
  649. addps %1, %4, %5
  650. %else
  651. mulps %1, %2, %3
  652. addps %1, %4
  653. %endif
  654. %endmacro