predict-a.asm
上传用户:hjq518
上传日期:2021-12-09
资源大小:5084k
文件大小:19k
源码类别:

Audio

开发平台:

Visual C++

  1. ;*****************************************************************************
  2. ;* predict-a.asm: h264 encoder library
  3. ;*****************************************************************************
  4. ;* Copyright (C) 2005 x264 project
  5. ;*
  6. ;* Authors: Loren Merritt <lorenm@u.washington.edu>
  7. ;*
  8. ;* This program is free software; you can redistribute it and/or modify
  9. ;* it under the terms of the GNU General Public License as published by
  10. ;* the Free Software Foundation; either version 2 of the License, or
  11. ;* (at your option) any later version.
  12. ;*
  13. ;* This program is distributed in the hope that it will be useful,
  14. ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. ;* GNU General Public License for more details.
  17. ;*
  18. ;* You should have received a copy of the GNU General Public License
  19. ;* along with this program; if not, write to the Free Software
  20. ;* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  21. ;*****************************************************************************
  22. BITS 64
  23. ;=============================================================================
  24. ; Macros and other preprocessor constants
  25. ;=============================================================================
  26. %include "amd64inc.asm"
  27. %macro STORE8x8 2
  28.     movq        [parm1q + 1*FDEC_STRIDE], %1
  29.     movq        [parm1q + 2*FDEC_STRIDE], %1
  30.     movq        [parm1q + 3*FDEC_STRIDE], %1
  31.     movq        [parm1q + 4*FDEC_STRIDE], %1
  32.     movq        [parm1q + 5*FDEC_STRIDE], %2
  33.     movq        [parm1q + 6*FDEC_STRIDE], %2
  34.     movq        [parm1q + 7*FDEC_STRIDE], %2
  35.     movq        [parm1q + 8*FDEC_STRIDE], %2
  36. %endmacro
  37. %macro STORE16x16 2
  38.     mov         eax, 4
  39. ALIGN 4
  40. .loop:
  41.     movq        [parm1q + 1*FDEC_STRIDE], %1
  42.     movq        [parm1q + 2*FDEC_STRIDE], %1
  43.     movq        [parm1q + 3*FDEC_STRIDE], %1
  44.     movq        [parm1q + 4*FDEC_STRIDE], %1
  45.     movq        [parm1q + 1*FDEC_STRIDE + 8], %2
  46.     movq        [parm1q + 2*FDEC_STRIDE + 8], %2
  47.     movq        [parm1q + 3*FDEC_STRIDE + 8], %2
  48.     movq        [parm1q + 4*FDEC_STRIDE + 8], %2
  49.     dec         eax
  50.     lea         parm1q, [parm1q + 4*FDEC_STRIDE]
  51.     jnz         .loop
  52.     nop
  53. %endmacro
  54. SECTION .rodata align=16
  55. ALIGN 16
  56. pw_2: times 4 dw 2
  57. pw_8: times 4 dw 8
  58. pb_1: times 16 db 1
  59. pw_3210:
  60.     dw 0
  61.     dw 1
  62.     dw 2
  63.     dw 3
  64. ALIGN 16
  65. pb_00s_ff:
  66.     times 8 db 0
  67. pb_0s_ff:
  68.     times 7 db 0
  69.     db 0xff
  70. ;=============================================================================
  71. ; Code
  72. ;=============================================================================
  73. SECTION .text
  74. cglobal predict_4x4_ddl_mmxext
  75. cglobal predict_4x4_vl_mmxext
  76. cglobal predict_8x8_v_mmxext
  77. cglobal predict_8x8_ddl_mmxext
  78. cglobal predict_8x8_ddl_sse2
  79. cglobal predict_8x8_ddr_sse2
  80. cglobal predict_8x8_vl_sse2
  81. cglobal predict_8x8_vr_core_mmxext
  82. cglobal predict_8x8_dc_core_mmxext
  83. cglobal predict_8x8c_v_mmx
  84. cglobal predict_8x8c_dc_core_mmxext
  85. cglobal predict_8x8c_p_core_mmxext
  86. cglobal predict_16x16_p_core_mmxext
  87. cglobal predict_16x16_v_mmx
  88. cglobal predict_16x16_dc_core_mmxext
  89. cglobal predict_16x16_dc_top_mmxext
  90. ; dest, left, right, src, tmp
  91. ; output: %1 = (t[n-1] + t[n]*2 + t[n+1] + 2) >> 2
  92. %macro PRED8x8_LOWPASS0 6
  93.     mov%6       %5, %2
  94.     pavgb       %2, %3
  95.     pxor        %3, %5
  96.     mov%6       %1, %4
  97.     pand        %3, [pb_1 GLOBAL]
  98.     psubusb     %2, %3
  99.     pavgb       %1, %2
  100. %endmacro
  101. %macro PRED8x8_LOWPASS 5
  102.     PRED8x8_LOWPASS0 %1, %2, %3, %4, %5, q
  103. %endmacro
  104. %macro PRED8x8_LOWPASS_XMM 5
  105.     PRED8x8_LOWPASS0 %1, %2, %3, %4, %5, dqa
  106. %endmacro
  107. ; output: mm0 = filtered t0..t7
  108. %macro PRED8x8_LOAD_TOP_FILT 0
  109.     sub         parm1q, FDEC_STRIDE
  110.     and         parm2d, 12
  111.     movq        mm1, [parm1q-1]
  112.     movq        mm2, [parm1q+1]
  113.     cmp         parm2d, byte 8
  114.     jge         .have_topleft
  115.     mov         al,  [parm1q]
  116.     mov         ah,  al
  117.     pinsrw      mm1, eax, 0
  118. .have_topleft:
  119.     and         parm2d, byte 4
  120.     jne         .have_topright
  121.     mov         al,  [parm1q+7]
  122.     mov         ah,  al
  123.     pinsrw      mm2, eax, 3
  124. .have_topright:
  125.     PRED8x8_LOWPASS mm0, mm1, mm2, [parm1q], mm7
  126. %endmacro
  127. ; output: xmm0 = unfiltered t0..t15
  128. ;         xmm1 = unfiltered t1..t15
  129. ;         xmm2 = unfiltered tl..t14
  130. %macro PRED8x8_LOAD_TOP_TOPRIGHT_XMM 0
  131.     sub         parm1q, FDEC_STRIDE
  132.     and         parm2d, 12
  133.     movdqu      xmm1, [parm1q-1]
  134.     cmp         parm2d, byte 8
  135.     jge         .have_topleft
  136.     mov         al,   [parm1q]
  137.     mov         ah,   al
  138.     pinsrw      xmm1, eax, 0
  139. .have_topleft:
  140.     and         parm2d, byte 4
  141.     jne         .have_topright
  142.     mov         al,   [parm1q+7]
  143.     mov         ah,   al
  144.     pinsrw      xmm1, eax, 4
  145.     pshufhw     xmm1, xmm1, 0
  146.     movdqa      xmm0, xmm1
  147.     movdqa      xmm2, xmm1
  148.     psrldq      xmm0, 1
  149.     psrldq      xmm2, 2
  150.     pshufhw     xmm0, xmm0, 0
  151.     pshufhw     xmm2, xmm2, 0
  152.     jmp         .done_topright
  153. .have_topright:
  154.     movdqu      xmm0, [parm1q]
  155.     movdqa      xmm2, xmm0
  156.     psrldq      xmm2, 1
  157.     mov         al,   [parm1q+15]
  158.     mov         ah,   al
  159.     pinsrw      xmm2, eax, 7
  160. .done_topright:
  161. %endmacro
  162. ;-----------------------------------------------------------------------------
  163. ;
  164. ; void predict_4x4_ddl_mmxext( uint8_t *src )
  165. ;
  166. ;-----------------------------------------------------------------------------
  167. ALIGN 16
  168. predict_4x4_ddl_mmxext:
  169.     sub         parm1q, FDEC_STRIDE
  170.     movq        mm3, [parm1q]
  171.     movq        mm1, [parm1q-1]
  172.     movq        mm2, mm3
  173.     movq        mm4, [pb_0s_ff GLOBAL]
  174.     psrlq       mm2, 8
  175.     pand        mm4, mm3
  176.     por         mm2, mm4
  177.     PRED8x8_LOWPASS mm0, mm1, mm2, mm3, mm5
  178. %assign Y 1
  179. %rep 4
  180.     psrlq       mm0, 8
  181.     movd        [parm1q+Y*FDEC_STRIDE], mm0
  182. %assign Y (Y+1)
  183. %endrep
  184.     ret
  185. ;-----------------------------------------------------------------------------
  186. ;
  187. ; void predict_4x4_vl_mmxext( uint8_t *src )
  188. ;
  189. ;-----------------------------------------------------------------------------
  190. ALIGN 16
  191. predict_4x4_vl_mmxext:
  192.     movq        mm1, [parm1q-FDEC_STRIDE]
  193.     movq        mm3, mm1
  194.     movq        mm2, mm1
  195.     psrlq       mm3, 8
  196.     psrlq       mm2, 16
  197.     movq        mm4, mm3
  198.     pavgb       mm4, mm1
  199.     PRED8x8_LOWPASS mm0, mm1, mm2, mm3, mm5
  200.     movd        [parm1q+0*FDEC_STRIDE], mm4
  201.     movd        [parm1q+1*FDEC_STRIDE], mm0
  202.     psrlq       mm4, 8
  203.     psrlq       mm0, 8
  204.     movd        [parm1q+2*FDEC_STRIDE], mm4
  205.     movd        [parm1q+3*FDEC_STRIDE], mm0
  206.     ret
  207. ;-----------------------------------------------------------------------------
  208. ;
  209. ; void predict_8x8_v_mmxext( uint8_t *src, int i_neighbors )
  210. ;
  211. ;-----------------------------------------------------------------------------
  212. ALIGN 16
  213. predict_8x8_v_mmxext:
  214.     PRED8x8_LOAD_TOP_FILT
  215.     STORE8x8    mm0, mm0
  216.     ret
  217. ;-----------------------------------------------------------------------------
  218. ;
  219. ; void predict_8x8_dc_core_mmxext( uint8_t *src, int i_neighbors, uint8_t *pix_left );
  220. ;
  221. ;-----------------------------------------------------------------------------
  222. ALIGN 16
  223. predict_8x8_dc_core_mmxext:
  224.     movq        mm1, [parm3q-1]
  225.     movq        mm2, [parm3q+1]
  226.     PRED8x8_LOWPASS mm4, mm1, mm2, [parm3q], mm7
  227.     PRED8x8_LOAD_TOP_FILT
  228.     pxor        mm1, mm1
  229.     psadbw      mm0, mm1
  230.     psadbw      mm4, mm1
  231.     paddw       mm0, [pw_8 GLOBAL]
  232.     paddw       mm0, mm4
  233.     psrlw       mm0, 4
  234.     pshufw      mm0, mm0, 0
  235.     packuswb    mm0, mm0
  236.     STORE8x8    mm0, mm0
  237.     ret
  238. ;-----------------------------------------------------------------------------
  239. ;
  240. ; void predict_8x8_ddl_mmxext( uint8_t *src, int i_neighbors )
  241. ;
  242. ;-----------------------------------------------------------------------------
  243. ALIGN 16
  244. predict_8x8_ddl_mmxext:
  245.     sub         parm1q, FDEC_STRIDE
  246.     and         parm2d, 12
  247.     movq        mm1, [parm1q-1]
  248.     movq        mm2, [parm1q+1]
  249.     cmp         parm2d, byte 8
  250.     jge         .have_topleft
  251.     mov         al,  [parm1q]
  252.     mov         ah,  al
  253.     pinsrw      mm1, eax, 0
  254. .have_topleft:
  255.     and         parm2d, byte 4
  256.     jne         .have_topright
  257.     mov         al,  [parm1q+7]
  258.     mov         ah,  [parm1q+7]
  259.     pinsrw      mm2, eax, 3
  260.     pshufw      mm3, mm2, 0xff
  261.     jmp         .done_topright
  262. .have_topright:
  263.     movq        mm5, [parm1q+9];
  264.     mov         al,  [parm1q+15]
  265.     mov         ah,  al
  266.     pinsrw      mm5, eax, 3
  267.     movq        mm4, [parm1q+7];
  268.     PRED8x8_LOWPASS mm3, mm4, mm5, [parm1q+8], mm7
  269. .done_topright:
  270. ;?0123456789abcdeff
  271. ; [-mm0--][-mm3--]
  272. ;[-mm1--][-mm4--]
  273. ;  [-mm2--][-mm5--]
  274.     PRED8x8_LOWPASS mm0, mm1, mm2, [parm1q], mm7
  275.     movq        mm1, mm0
  276.     movq        mm2, mm0
  277.     psllq       mm1, 8
  278.     psrlq       mm2, 8
  279.     movq        mm6, mm3
  280.     movq        mm4, mm3
  281.     psllq       mm6, 56
  282.     movq        mm7, mm0
  283.     por         mm2, mm6
  284.     psllq       mm4, 8
  285.     movq        mm5, mm3
  286.     movq        mm6, mm3
  287.     psrlq       mm5, 8
  288.     pand        mm6, [pb_0s_ff GLOBAL]
  289.     psrlq       mm7, 56
  290.     por         mm5, mm6
  291.     por         mm4, mm7
  292.     PRED8x8_LOWPASS mm6, mm1, mm2, mm0, mm7
  293.     PRED8x8_LOWPASS mm7, mm4, mm5, mm3, mm2
  294. %assign Y 8
  295. %rep 6
  296.     movq        [parm1q+Y*FDEC_STRIDE], mm7
  297.     movq        mm1, mm6
  298.     psllq       mm7, 8
  299.     psrlq       mm1, 56
  300.     psllq       mm6, 8
  301.     por         mm7, mm1
  302. %assign Y (Y-1)
  303. %endrep
  304.     movq        [parm1q+Y*FDEC_STRIDE], mm7
  305.     psllq       mm7, 8
  306.     psrlq       mm6, 56
  307.     por         mm7, mm6
  308. %assign Y (Y-1)
  309.     movq        [parm1q+Y*FDEC_STRIDE], mm7
  310.     ret
  311. ;-----------------------------------------------------------------------------
  312. ;
  313. ; void predict_8x8_ddl_sse2( uint8_t *src, int i_neighbors )
  314. ;
  315. ;-----------------------------------------------------------------------------
  316. ALIGN 16
  317. predict_8x8_ddl_sse2:
  318.     PRED8x8_LOAD_TOP_TOPRIGHT_XMM
  319. ;?0123456789abcdeff
  320. ; [-----xmm0-----]
  321. ;[-----xmm1-----]
  322. ;  [-----xmm2-----]
  323.     movdqa      xmm3, [pb_00s_ff GLOBAL]
  324.     PRED8x8_LOWPASS_XMM xmm4, xmm1, xmm2, xmm0, xmm5
  325.     movdqa      xmm1, xmm4
  326.     movdqa      xmm2, xmm4
  327.     pand        xmm3, xmm4
  328.     psrldq      xmm2, 1
  329.     pslldq      xmm1, 1
  330.     por         xmm2, xmm3
  331.     PRED8x8_LOWPASS_XMM xmm0, xmm1, xmm2, xmm4, xmm5
  332. %assign Y 1
  333. %rep 8
  334.     psrldq      xmm0, 1
  335.     movq        [parm1q+Y*FDEC_STRIDE], xmm0
  336. %assign Y (Y+1)
  337. %endrep
  338.     ret
  339. ;-----------------------------------------------------------------------------
  340. ;
  341. ; void predict_8x8_ddr_sse2( uint8_t *src, int i_neighbors )
  342. ;
  343. ;-----------------------------------------------------------------------------
  344. ALIGN 16
  345. predict_8x8_ddr_sse2:
  346.     lea         r8, [rsp-24]
  347.     movq        mm0, [parm1q-FDEC_STRIDE]
  348.     movq        [r8+8], mm0
  349.     and         parm2d, byte 4
  350.     mov         al,  [parm1q-FDEC_STRIDE+7]
  351.     cmovnz      ax,  [parm1q-FDEC_STRIDE+8]
  352.     mov         [r8+16], al
  353.     mov         dh,  [parm1q+3*FDEC_STRIDE-1]
  354.     mov         dl,  [parm1q+4*FDEC_STRIDE-1]
  355.     mov         ah,  [parm1q-1*FDEC_STRIDE-1]
  356.     mov         al,  [parm1q+0*FDEC_STRIDE-1]
  357.     shl         edx, 16
  358.     shl         eax, 16
  359.     mov         dh,  [parm1q+5*FDEC_STRIDE-1]
  360.     mov         dl,  [parm1q+6*FDEC_STRIDE-1]
  361.     mov         ah,  [parm1q+1*FDEC_STRIDE-1]
  362.     mov         al,  [parm1q+2*FDEC_STRIDE-1]
  363.     mov         [r8+4], eax
  364.     mov         [r8], edx
  365.     movzx       eax, byte [parm1q+7*FDEC_STRIDE-1]
  366.     movd        xmm4, eax
  367.     movzx       edx, dl
  368.     lea         eax, [rax+2*rax+2]
  369.     add         eax, edx
  370.     shr         eax, 2
  371.     movd        xmm5, eax
  372. ; r8 -> {l6 l5 l4 l3 l2 l1 l0 lt t0 t1 t2 t3 t4 t5 t6 t7 t8}
  373.     movdqu      xmm0, [r8]
  374.     movdqu      xmm2, [r8+1]
  375.     movdqa      xmm1, xmm0
  376.     pslldq      xmm1, 1
  377.     por         xmm1, xmm4
  378.     PRED8x8_LOWPASS_XMM xmm3, xmm1, xmm2, xmm0, xmm4
  379.     movdqa      xmm1, xmm3
  380.     movdqa      xmm2, xmm3
  381.     pslldq      xmm1, 1
  382.     psrldq      xmm2, 1
  383.     por         xmm1, xmm5
  384.     PRED8x8_LOWPASS_XMM xmm0, xmm1, xmm2, xmm3, xmm4
  385.     movdqa      xmm1, xmm0
  386.     psrldq      xmm1, 1
  387. %assign Y 7
  388. %rep 3
  389.     movq        [parm1q+Y*FDEC_STRIDE], xmm0
  390.     psrldq      xmm0, 2
  391.     movq        [parm1q+(Y-1)*FDEC_STRIDE], xmm1
  392.     psrldq      xmm1, 2
  393. %assign Y (Y-2)
  394. %endrep
  395.     movq        [parm1q+1*FDEC_STRIDE], xmm0
  396.     movq        [parm1q+0*FDEC_STRIDE], xmm1
  397.     ret
  398. ;-----------------------------------------------------------------------------
  399. ;
  400. ; void predict_8x8_vl_sse2( uint8_t *src, int i_neighbors )
  401. ;
  402. ;-----------------------------------------------------------------------------
  403. ALIGN 16
  404. predict_8x8_vl_sse2:
  405.     PRED8x8_LOAD_TOP_TOPRIGHT_XMM
  406.     PRED8x8_LOWPASS_XMM xmm4, xmm1, xmm2, xmm0, xmm5
  407.     movdqa      xmm2, xmm4
  408.     movdqa      xmm1, xmm4
  409.     movdqa      xmm3, xmm4
  410.     psrldq      xmm2, 1
  411.     pslldq      xmm1, 1
  412.     pavgb       xmm3, xmm2
  413.     PRED8x8_LOWPASS_XMM xmm0, xmm1, xmm2, xmm4, xmm5
  414. ; xmm0: (t0 + 2*t1 + t2 + 2) >> 2
  415. ; xmm3: (t0 + t1 + 1) >> 1
  416. %assign Y 1
  417. %rep 3
  418.     psrldq      xmm0, 1
  419.     movq        [parm1q+ Y   *FDEC_STRIDE], xmm3
  420.     movq        [parm1q+(Y+1)*FDEC_STRIDE], xmm0
  421.     psrldq      xmm3, 1
  422. %assign Y (Y+2)
  423. %endrep
  424.     psrldq      xmm0, 1
  425.     movq        [parm1q+ Y   *FDEC_STRIDE], xmm3
  426.     movq        [parm1q+(Y+1)*FDEC_STRIDE], xmm0
  427.     ret
  428. ;-----------------------------------------------------------------------------
  429. ;
  430. ; void predict_8x8_vr_core_mmxext( uint8_t *src, int i_neighbors, uint16_t ltt0 )
  431. ;
  432. ;-----------------------------------------------------------------------------
  433. ; fills only some pixels:
  434. ; f0123456789abcdef
  435. ; 0 .......
  436. ; 1  ,,,,,,
  437. ; 2  ......
  438. ; 3   ,,,,,
  439. ; 4   .....
  440. ; 5    ,,,,
  441. ; 6    ....
  442. ; 7     ,,,
  443. ALIGN 16
  444. predict_8x8_vr_core_mmxext:
  445.     sub         parm1q, FDEC_STRIDE
  446.     movq        mm1, [parm1q-1]
  447.     movq        mm2, [parm1q+1]
  448.     and         parm2d, byte 4
  449.     jne         .have_topright
  450.     mov         al,  [parm1q+7]
  451.     mov         ah,  al
  452.     pinsrw      mm2, eax, 3
  453. .have_topright:
  454.     PRED8x8_LOWPASS mm4, mm1, mm2, [parm1q], mm7
  455.     movq        mm1, mm4
  456.     movq        mm2, mm4
  457.     psllq       mm1, 8
  458.     movq        mm3, mm4
  459.     pinsrw      mm1, parm3d, 0
  460.     psrlq       mm2, 8
  461.     pavgb       mm3, mm1
  462.     PRED8x8_LOWPASS mm0, mm1, mm2, mm4, mm5
  463. %assign Y 1
  464. %rep 3
  465.     psllq       mm0, 8
  466.     movq        [parm1q+ Y   *FDEC_STRIDE], mm3
  467.     movq        [parm1q+(Y+1)*FDEC_STRIDE], mm0
  468.     psllq       mm3, 8
  469. %assign Y (Y+2)
  470. %endrep
  471.     psllq       mm0, 8
  472.     movq        [parm1q+ Y   *FDEC_STRIDE], mm3
  473.     movq        [parm1q+(Y+1)*FDEC_STRIDE], mm0
  474.     ret
  475. ;-----------------------------------------------------------------------------
  476. ;
  477. ; void predict_8x8c_v_mmx( uint8_t *src )
  478. ;
  479. ;-----------------------------------------------------------------------------
  480. ALIGN 16
  481. predict_8x8c_v_mmx :
  482.     sub         parm1q, FDEC_STRIDE
  483.     movq        mm0, [parm1q]
  484.     STORE8x8    mm0, mm0
  485.     ret
  486. ;-----------------------------------------------------------------------------
  487. ;
  488. ; void predict_8x8c_dc_core_mmxext( uint8_t *src, int s2, int s3 )
  489. ;
  490. ;-----------------------------------------------------------------------------
  491. ALIGN 16
  492. predict_8x8c_dc_core_mmxext:
  493.     sub         parm1q, FDEC_STRIDE
  494.     movq        mm0, [parm1q]
  495.     pxor        mm1, mm1
  496.     pxor        mm2, mm2
  497.     punpckhbw   mm1, mm0
  498.     punpcklbw   mm0, mm2
  499.     psadbw      mm1, mm2        ; s1
  500.     psadbw      mm0, mm2        ; s0
  501.     movd        mm4, parm2d
  502.     movd        mm5, parm3d
  503.     paddw       mm0, mm4
  504.     pshufw      mm2, mm5, 0
  505.     psrlw       mm0, 3
  506.     paddw       mm1, [pw_2 GLOBAL]
  507.     movq        mm3, mm2
  508.     pshufw      mm1, mm1, 0
  509.     pshufw      mm0, mm0, 0     ; dc0 (w)
  510.     paddw       mm3, mm1
  511.     psrlw       mm3, 3          ; dc3 (w)
  512.     psrlw       mm2, 2          ; dc2 (w)
  513.     psrlw       mm1, 2          ; dc1 (w)
  514.     packuswb    mm0, mm1        ; dc0,dc1 (b)
  515.     packuswb    mm2, mm3        ; dc2,dc3 (b)
  516.     STORE8x8    mm0, mm2
  517.     ret
  518. ;-----------------------------------------------------------------------------
  519. ;
  520. ; void predict_8x8c_p_core_mmxext( uint8_t *src, int i00, int b, int c )
  521. ;
  522. ;-----------------------------------------------------------------------------
  523. ALIGN 16
  524. predict_8x8c_p_core_mmxext:
  525.     movd        mm0, parm2d
  526.     movd        mm2, parm3d
  527.     movd        mm4, parm4d
  528.     pshufw      mm0, mm0, 0
  529.     pshufw      mm2, mm2, 0
  530.     pshufw      mm4, mm4, 0
  531.     movq        mm1, mm2
  532.     pmullw      mm2, [pw_3210 GLOBAL]
  533.     psllw       mm1, 2
  534.     paddsw      mm0, mm2        ; mm0 = {i+0*b, i+1*b, i+2*b, i+3*b}
  535.     paddsw      mm1, mm0        ; mm1 = {i+4*b, i+5*b, i+6*b, i+7*b}
  536.     mov         eax, 8
  537. ALIGN 4
  538. .loop:
  539.     movq        mm5, mm0
  540.     movq        mm6, mm1
  541.     psraw       mm5, 5
  542.     psraw       mm6, 5
  543.     packuswb    mm5, mm6
  544.     movq        [parm1q], mm5
  545.     paddsw      mm0, mm4
  546.     paddsw      mm1, mm4
  547.     add         parm1q, FDEC_STRIDE
  548.     dec         eax
  549.     jg          .loop
  550.     nop
  551.     ret
  552. ;-----------------------------------------------------------------------------
  553. ;
  554. ; void predict_16x16_p_core_mmxext( uint8_t *src, int i00, int b, int c )
  555. ;
  556. ;-----------------------------------------------------------------------------
  557. ALIGN 16
  558. predict_16x16_p_core_mmxext:
  559.     movd        mm0, parm2d
  560.     movd        mm2, parm3d
  561.     movd        mm4, parm4d
  562.     pshufw      mm0, mm0, 0
  563.     pshufw      mm2, mm2, 0
  564.     pshufw      mm4, mm4, 0
  565.     movq        mm5, mm2
  566.     movq        mm1, mm2
  567.     pmullw      mm5, [pw_3210 GLOBAL]
  568.     psllw       mm2, 3
  569.     psllw       mm1, 2
  570.     movq        mm3, mm2
  571.     paddsw      mm0, mm5        ; mm0 = {i+ 0*b, i+ 1*b, i+ 2*b, i+ 3*b}
  572.     paddsw      mm1, mm0        ; mm1 = {i+ 4*b, i+ 5*b, i+ 6*b, i+ 7*b}
  573.     paddsw      mm2, mm0        ; mm2 = {i+ 8*b, i+ 9*b, i+10*b, i+11*b}
  574.     paddsw      mm3, mm1        ; mm3 = {i+12*b, i+13*b, i+14*b, i+15*b}
  575.     mov         eax, 16
  576. ALIGN 4
  577. .loop:
  578.     movq        mm5, mm0
  579.     movq        mm6, mm1
  580.     psraw       mm5, 5
  581.     psraw       mm6, 5
  582.     packuswb    mm5, mm6
  583.     movq        [parm1q], mm5
  584.     movq        mm5, mm2
  585.     movq        mm6, mm3
  586.     psraw       mm5, 5
  587.     psraw       mm6, 5
  588.     packuswb    mm5, mm6
  589.     movq        [parm1q+8], mm5
  590.     paddsw      mm0, mm4
  591.     paddsw      mm1, mm4
  592.     paddsw      mm2, mm4
  593.     paddsw      mm3, mm4
  594.     add         parm1q, FDEC_STRIDE
  595.     dec         eax
  596.     jg          .loop
  597.     nop
  598.     ret
  599.     
  600. ;-----------------------------------------------------------------------------
  601. ;
  602. ; void predict_16x16_v_mmx( uint8_t *src )
  603. ;
  604. ;-----------------------------------------------------------------------------
  605. ALIGN 16
  606. predict_16x16_v_mmx :
  607.     sub         parm1q, FDEC_STRIDE
  608.     movq        mm0, [parm1q]
  609.     movq        mm1, [parm1q + 8]
  610.     STORE16x16  mm0, mm1
  611.     ret
  612. ;-----------------------------------------------------------------------------
  613. ;
  614. ; void predict_16x16_dc_core_mmxext( uint8_t *src, int i_dc_left )
  615. ;
  616. ;-----------------------------------------------------------------------------
  617. %macro PRED16x16_DC 2
  618.     sub         parm1q, FDEC_STRIDE
  619.     pxor        mm0, mm0
  620.     pxor        mm1, mm1
  621.     psadbw      mm0, [parm1q]
  622.     psadbw      mm1, [parm1q + 8]
  623.     paddusw     mm0, mm1
  624.     paddusw     mm0, %1
  625.     psrlw       mm0, %2                       ; dc
  626.     pshufw      mm0, mm0, 0
  627.     packuswb    mm0, mm0                      ; dc in bytes
  628.     STORE16x16  mm0, mm0
  629. %endmacro
  630. ALIGN 16
  631. predict_16x16_dc_core_mmxext:
  632.     movd         mm2, parm2d
  633.     PRED16x16_DC mm2, 5
  634.     ret
  635. ALIGN 16
  636. predict_16x16_dc_top_mmxext:
  637.     PRED16x16_DC [pw_8 GLOBAL], 4
  638.     ret