predict-a.asm
上传用户:lctgjx
上传日期:2022-06-04
资源大小:8887k
文件大小:37k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. ;*****************************************************************************
  2. ;* predict-a.asm: h264 encoder library
  3. ;*****************************************************************************
  4. ;* Copyright (C) 2005-2008 x264 project
  5. ;*
  6. ;* Authors: Loren Merritt <lorenm@u.washington.edu>
  7. ;*          Holger Lubitz <holger@lubitz.org>
  8. ;*          Jason Garrett-Glaser <darkshikari@gmail.com>
  9. ;*
  10. ;* This program is free software; you can redistribute it and/or modify
  11. ;* it under the terms of the GNU General Public License as published by
  12. ;* the Free Software Foundation; either version 2 of the License, or
  13. ;* (at your option) any later version.
  14. ;*
  15. ;* This program is distributed in the hope that it will be useful,
  16. ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18. ;* GNU General Public License for more details.
  19. ;*
  20. ;* You should have received a copy of the GNU General Public License
  21. ;* along with this program; if not, write to the Free Software
  22. ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
  23. ;*****************************************************************************
  24. %include "x86inc.asm"
  25. %include "x86util.asm"
  26. %macro STORE8x8 2
  27.     add r0, 4*FDEC_STRIDE
  28.     movq        [r0 + -4*FDEC_STRIDE], %1
  29.     movq        [r0 + -3*FDEC_STRIDE], %1
  30.     movq        [r0 + -2*FDEC_STRIDE], %1
  31.     movq        [r0 + -1*FDEC_STRIDE], %1
  32.     movq        [r0 +  0*FDEC_STRIDE], %2
  33.     movq        [r0 +  1*FDEC_STRIDE], %2
  34.     movq        [r0 +  2*FDEC_STRIDE], %2
  35.     movq        [r0 +  3*FDEC_STRIDE], %2
  36. %endmacro
  37. %macro STORE16x16 2
  38.     mov         r1d, 4
  39. .loop:
  40.     movq        [r0 + 0*FDEC_STRIDE], %1
  41.     movq        [r0 + 1*FDEC_STRIDE], %1
  42.     movq        [r0 + 2*FDEC_STRIDE], %1
  43.     movq        [r0 + 3*FDEC_STRIDE], %1
  44.     movq        [r0 + 0*FDEC_STRIDE + 8], %2
  45.     movq        [r0 + 1*FDEC_STRIDE + 8], %2
  46.     movq        [r0 + 2*FDEC_STRIDE + 8], %2
  47.     movq        [r0 + 3*FDEC_STRIDE + 8], %2
  48.     add         r0, 4*FDEC_STRIDE
  49.     dec         r1d
  50.     jg          .loop
  51. %endmacro
  52. %macro STORE16x16_SSE2 1
  53.     add r0, 4*FDEC_STRIDE
  54.     movdqa      [r0 + -4*FDEC_STRIDE], %1
  55.     movdqa      [r0 + -3*FDEC_STRIDE], %1
  56.     movdqa      [r0 + -2*FDEC_STRIDE], %1
  57.     movdqa      [r0 + -1*FDEC_STRIDE], %1
  58.     movdqa      [r0 +  0*FDEC_STRIDE], %1
  59.     movdqa      [r0 +  1*FDEC_STRIDE], %1
  60.     movdqa      [r0 +  2*FDEC_STRIDE], %1
  61.     movdqa      [r0 +  3*FDEC_STRIDE], %1
  62.     add r0, 8*FDEC_STRIDE
  63.     movdqa      [r0 + -4*FDEC_STRIDE], %1
  64.     movdqa      [r0 + -3*FDEC_STRIDE], %1
  65.     movdqa      [r0 + -2*FDEC_STRIDE], %1
  66.     movdqa      [r0 + -1*FDEC_STRIDE], %1
  67.     movdqa      [r0 +  0*FDEC_STRIDE], %1
  68.     movdqa      [r0 +  1*FDEC_STRIDE], %1
  69.     movdqa      [r0 +  2*FDEC_STRIDE], %1
  70.     movdqa      [r0 +  3*FDEC_STRIDE], %1
  71. %endmacro
  72. SECTION_RODATA
  73. ALIGN 16
  74. pb_1:       times 16 db 1
  75. pb_3:       times 16 db 3
  76. pw_2:       times 4 dw 2
  77. pw_4:       times 4 dw 4
  78. pw_8:       times 8 dw 8
  79. pw_76543210:
  80. pw_3210:    dw 0, 1, 2, 3, 4, 5, 6, 7
  81. pb_00s_ff:  times 8 db 0
  82. pb_0s_ff:   times 7 db 0
  83.             db 0xff
  84. pw_ff00:    times 8 dw 0xff00
  85. pb_reverse: db 7, 6, 5, 4, 3, 2, 1, 0
  86. SECTION .text
  87. ; dest, left, right, src, tmp
  88. ; output: %1 = (t[n-1] + t[n]*2 + t[n+1] + 2) >> 2
  89. %macro PRED8x8_LOWPASS0 6
  90.     mov%6       %5, %2
  91.     pavgb       %2, %3
  92.     pxor        %3, %5
  93.     mov%6       %1, %4
  94.     pand        %3, [pb_1 GLOBAL]
  95.     psubusb     %2, %3
  96.     pavgb       %1, %2
  97. %endmacro
  98. %macro PRED8x8_LOWPASS 5
  99.     PRED8x8_LOWPASS0 %1, %2, %3, %4, %5, q
  100. %endmacro
  101. %macro PRED8x8_LOWPASS_XMM 5
  102.     PRED8x8_LOWPASS0 %1, %2, %3, %4, %5, dqa
  103. %endmacro
  104. %macro LOAD_PLANE_ARGS 0
  105. %ifdef ARCH_X86_64
  106.     movd        mm0, r1d
  107.     movd        mm2, r2d
  108.     movd        mm4, r3d
  109.     pshufw      mm0, mm0, 0
  110.     pshufw      mm2, mm2, 0
  111.     pshufw      mm4, mm4, 0
  112. %else
  113.     pshufw      mm0, r1m, 0
  114.     pshufw      mm2, r2m, 0
  115.     pshufw      mm4, r3m, 0
  116. %endif
  117. %endmacro
  118. ;-----------------------------------------------------------------------------
  119. ; void predict_4x4_ddl_mmxext( uint8_t *src )
  120. ;-----------------------------------------------------------------------------
  121. cglobal predict_4x4_ddl_mmxext, 1,1
  122.     movq    mm1, [r0-FDEC_STRIDE]
  123.     movq    mm2, mm1
  124.     movq    mm3, mm1
  125.     movq    mm4, mm1
  126.     psllq   mm1, 8
  127.     pxor    mm2, mm1
  128.     psrlq   mm2, 8
  129.     pxor    mm3, mm2
  130.     PRED8x8_LOWPASS mm0, mm1, mm3, mm4, mm5
  131. %assign Y 0
  132. %rep 4
  133.     psrlq       mm0, 8
  134.     movd        [r0+Y*FDEC_STRIDE], mm0
  135. %assign Y (Y+1)
  136. %endrep
  137.     RET
  138. ;-----------------------------------------------------------------------------
  139. ; void predict_4x4_ddr_mmxext( uint8_t *src )
  140. ;-----------------------------------------------------------------------------
  141. %macro PREDICT_4x4 1
  142. cglobal predict_4x4_ddr_%1, 1,1
  143.     movq      mm1, [r0+1*FDEC_STRIDE-8]
  144.     movq      mm2, [r0+0*FDEC_STRIDE-8]
  145.     punpckhbw mm2, [r0-1*FDEC_STRIDE-8]
  146.     movd      mm3, [r0-1*FDEC_STRIDE]
  147.     punpckhwd mm1, mm2
  148.     PALIGNR   mm3, mm1, 5, mm1
  149.     movq      mm1, mm3
  150.     PALIGNR   mm3, [r0+2*FDEC_STRIDE-8], 7, mm4
  151.     movq      mm2, mm3
  152.     PALIGNR   mm3, [r0+3*FDEC_STRIDE-8], 7, mm4
  153.     PRED8x8_LOWPASS mm0, mm3, mm1, mm2, mm4
  154. %assign Y 3
  155.     movd    [r0+Y*FDEC_STRIDE], mm0
  156. %rep 3
  157. %assign Y (Y-1)
  158.     psrlq    mm0, 8
  159.     movd    [r0+Y*FDEC_STRIDE], mm0
  160. %endrep
  161.     RET
  162. cglobal predict_4x4_vr_%1, 1,1
  163.     movd    mm0, [r0-1*FDEC_STRIDE]              ; ........t3t2t1t0
  164.     movq    mm7, mm0
  165.     PALIGNR mm0, [r0-1*FDEC_STRIDE-8], 7, mm1    ; ......t3t2t1t0lt
  166.     pavgb   mm7, mm0
  167.     PALIGNR mm0, [r0+0*FDEC_STRIDE-8], 7, mm1    ; ....t3t2t1t0ltl0
  168.     movq    mm1, mm0
  169.     PALIGNR mm0, [r0+1*FDEC_STRIDE-8], 7, mm2    ; ..t3t2t1t0ltl0l1
  170.     movq    mm2, mm0
  171.     PALIGNR mm0, [r0+2*FDEC_STRIDE-8], 7, mm3    ; t3t2t1t0ltl0l1l2
  172.     PRED8x8_LOWPASS mm3, mm1, mm0, mm2, mm4
  173.     movq    mm1, mm3
  174.     psrlq   mm3, 16
  175.     psllq   mm1, 48
  176.     movd   [r0+0*FDEC_STRIDE], mm7
  177.     movd   [r0+1*FDEC_STRIDE], mm3
  178.     PALIGNR mm7, mm1, 7, mm2
  179.     psllq   mm1, 8
  180.     movd   [r0+2*FDEC_STRIDE], mm7
  181.     PALIGNR mm3, mm1, 7, mm1
  182.     movd   [r0+3*FDEC_STRIDE], mm3
  183.     RET
  184. cglobal predict_4x4_hd_%1, 1,1
  185.     movd      mm0, [r0-1*FDEC_STRIDE-4] ; lt ..
  186.     punpckldq mm0, [r0-1*FDEC_STRIDE]   ; t3 t2 t1 t0 lt .. .. ..
  187.     psllq     mm0, 8                    ; t2 t1 t0 lt .. .. .. ..
  188.     movq      mm1, [r0+3*FDEC_STRIDE-8] ; l3
  189.     punpckhbw mm1, [r0+2*FDEC_STRIDE-8] ; l2 l3
  190.     movq      mm2, [r0+1*FDEC_STRIDE-8] ; l1
  191.     punpckhbw mm2, [r0+0*FDEC_STRIDE-8] ; l0 l1
  192.     punpckhwd mm1, mm2                  ; l0 l1 l2 l3
  193.     punpckhdq mm1, mm0                  ; t2 t1 t0 lt l0 l1 l2 l3
  194.     movq      mm0, mm1
  195.     movq      mm2, mm1
  196.     movq      mm7, mm1
  197.     psrlq     mm0, 16                   ; .. .. t2 t1 t0 lt l0 l1
  198.     psrlq     mm2, 8                    ; .. t2 t1 t0 lt l0 l1 l2
  199.     pavgb     mm7, mm2
  200.     PRED8x8_LOWPASS mm3, mm1, mm0, mm2, mm4
  201.     punpcklbw mm7, mm3
  202.     psrlq     mm3, 32
  203.     PALIGNR   mm3, mm7, 6, mm6
  204. %assign Y 3
  205.     movd     [r0+Y*FDEC_STRIDE], mm7
  206. %rep 2
  207. %assign Y (Y-1)
  208.     psrlq     mm7, 16
  209.     movd     [r0+Y*FDEC_STRIDE], mm7
  210. %endrep
  211.     movd     [r0+0*FDEC_STRIDE], mm3
  212.     RET
  213. %endmacro
  214. %define PALIGNR PALIGNR_MMX
  215. PREDICT_4x4 mmxext
  216. %define PALIGNR PALIGNR_SSSE3
  217. PREDICT_4x4 ssse3
  218. ;-----------------------------------------------------------------------------
  219. ; void predict_4x4_hu_mmxext( uint8_t *src )
  220. ;-----------------------------------------------------------------------------
  221. cglobal predict_4x4_hu_mmxext, 1,1
  222.     movq      mm0, [r0+0*FDEC_STRIDE-8]
  223.     punpckhbw mm0, [r0+1*FDEC_STRIDE-8]
  224.     movq      mm1, [r0+2*FDEC_STRIDE-8]
  225.     punpckhbw mm1, [r0+3*FDEC_STRIDE-8]
  226.     punpckhwd mm0, mm1
  227.     movq      mm1, mm0
  228.     punpckhbw mm1, mm1
  229.     pshufw    mm1, mm1, 0xFF
  230.     punpckhdq mm0, mm1
  231.     movq      mm2, mm0
  232.     movq      mm3, mm0
  233.     movq      mm7, mm0
  234.     psrlq     mm2, 16
  235.     psrlq     mm3, 8
  236.     pavgb     mm7, mm3
  237.     PRED8x8_LOWPASS mm4, mm0, mm2, mm3, mm5
  238.     punpcklbw mm7, mm4
  239. %assign Y 0
  240.     movd    [r0+Y*FDEC_STRIDE], mm7
  241. %rep 2
  242. %assign Y (Y+1)
  243.     psrlq    mm7, 16
  244.     movd    [r0+Y*FDEC_STRIDE], mm7
  245. %endrep
  246.     movd    [r0+3*FDEC_STRIDE], mm1
  247.     RET
  248. ;-----------------------------------------------------------------------------
  249. ; void predict_4x4_vl_mmxext( uint8_t *src )
  250. ;-----------------------------------------------------------------------------
  251. cglobal predict_4x4_vl_mmxext, 1,1
  252.     movq        mm1, [r0-FDEC_STRIDE]
  253.     movq        mm3, mm1
  254.     movq        mm2, mm1
  255.     psrlq       mm3, 8
  256.     psrlq       mm2, 16
  257.     movq        mm4, mm3
  258.     pavgb       mm4, mm1
  259.     PRED8x8_LOWPASS mm0, mm1, mm2, mm3, mm5
  260.     movd        [r0+0*FDEC_STRIDE], mm4
  261.     movd        [r0+1*FDEC_STRIDE], mm0
  262.     psrlq       mm4, 8
  263.     psrlq       mm0, 8
  264.     movd        [r0+2*FDEC_STRIDE], mm4
  265.     movd        [r0+3*FDEC_STRIDE], mm0
  266.     RET
  267. ;-----------------------------------------------------------------------------
  268. ; void predict_4x4_dc( uint8_t *src )
  269. ;-----------------------------------------------------------------------------
  270. cglobal predict_4x4_dc_mmxext, 1,4
  271.     pxor   mm7, mm7
  272.     movd   mm0, [r0-FDEC_STRIDE]
  273.     psadbw mm0, mm7
  274.     movd   r3d, mm0
  275.     movzx  r1d, byte [r0-1]
  276. %assign n 1
  277. %rep 3
  278.     movzx  r2d, byte [r0+FDEC_STRIDE*n-1]
  279.     add    r1d, r2d
  280. %assign n n+1
  281. %endrep
  282.     lea    r1d, [r1+r3+4]
  283.     shr    r1d, 3
  284.     imul   r1d, 0x01010101
  285.     mov   [r0+FDEC_STRIDE*0], r1d
  286.     mov   [r0+FDEC_STRIDE*1], r1d
  287.     mov   [r0+FDEC_STRIDE*2], r1d
  288.     mov   [r0+FDEC_STRIDE*3], r1d
  289.     RET
  290. %macro PREDICT_FILTER 1
  291. ;-----------------------------------------------------------------------------
  292. ;void predict_8x8_filter( uint8_t *src, uint8_t edge[33], int i_neighbor, int i_filters )
  293. ;-----------------------------------------------------------------------------
  294. cglobal predict_8x8_filter_%1, 4,5
  295.     add          r0, 0x58
  296. %define src r0-0x58
  297. %ifndef ARCH_X86_64
  298.     mov          r4, r1
  299. %define t1 r4
  300. %define t4 r1
  301. %else
  302. %define t1 r1
  303. %define t4 r4
  304. %endif
  305.     test        r3b, 0x01
  306.     je .check_top
  307.     movq        mm0, [src+0*FDEC_STRIDE-8]
  308.     punpckhbw   mm0, [src-1*FDEC_STRIDE-8]
  309.     movq        mm1, [src+2*FDEC_STRIDE-8]
  310.     punpckhbw   mm1, [src+1*FDEC_STRIDE-8]
  311.     punpckhwd   mm1, mm0
  312.     movq        mm2, [src+4*FDEC_STRIDE-8]
  313.     punpckhbw   mm2, [src+3*FDEC_STRIDE-8]
  314.     movq        mm3, [src+6*FDEC_STRIDE-8]
  315.     punpckhbw   mm3, [src+5*FDEC_STRIDE-8]
  316.     punpckhwd   mm3, mm2
  317.     punpckhdq   mm3, mm1
  318.     movq        mm0, [src+7*FDEC_STRIDE-8]
  319.     movq        mm1, [src-1*FDEC_STRIDE]
  320.     movq        mm4, mm3
  321.     movq        mm2, mm3
  322.     PALIGNR     mm4, mm0, 7, mm0
  323.     PALIGNR     mm1, mm2, 1, mm2
  324.     test        r2b, 0x08
  325.     je .fix_lt_1
  326. .do_left:
  327.     movq        mm0, mm4
  328.     PRED8x8_LOWPASS mm2, mm1, mm4, mm3, mm5
  329.     movq     [t1+8], mm2
  330.     movq        mm4, mm0
  331.     PRED8x8_LOWPASS mm1, mm3, mm0, mm4, mm5
  332.     movd         t4, mm1
  333.     mov      [t1+7], t4b
  334. .check_top:
  335.     test        r3b, 0x02
  336.     je .done
  337.     movq        mm0, [src-1*FDEC_STRIDE-8]
  338.     movq        mm3, [src-1*FDEC_STRIDE]
  339.     movq        mm1, [src-1*FDEC_STRIDE+8]
  340.     movq        mm2, mm3
  341.     movq        mm4, mm3
  342.     PALIGNR     mm2, mm0, 7, mm0
  343.     PALIGNR     mm1, mm4, 1, mm4
  344.     test        r2b, 0x08
  345.     je .fix_lt_2
  346.     test        r2b, 0x04
  347.     je .fix_tr_1
  348. .do_top:
  349.     PRED8x8_LOWPASS mm4, mm2, mm1, mm3, mm5
  350.     movq    [t1+16], mm4
  351.     test        r3b, 0x04
  352.     je .done
  353.     test        r2b, 0x04
  354.     je .fix_tr_2
  355.     movq        mm0, [src-1*FDEC_STRIDE+8]
  356.     movq        mm5, mm0
  357.     movq        mm2, mm0
  358.     movq        mm4, mm0
  359.     psrlq       mm5, 56
  360.     PALIGNR     mm2, mm3, 7, mm3
  361.     PALIGNR     mm5, mm4, 1, mm4
  362.     PRED8x8_LOWPASS mm1, mm2, mm5, mm0, mm4
  363.     jmp .do_topright
  364. .fix_tr_2:
  365.     punpckhbw   mm3, mm3
  366.     pshufw      mm1, mm3, 0xFF
  367. .do_topright:
  368.     movq    [t1+24], mm1
  369.     psrlq       mm1, 56
  370.     movd         t4, mm1
  371.     mov     [t1+32], t4b
  372. .done:
  373.     REP_RET
  374. .fix_lt_1:
  375.     movq        mm5, mm3
  376.     pxor        mm5, mm4
  377.     psrlq       mm5, 56
  378.     psllq       mm5, 48
  379.     pxor        mm1, mm5
  380.     jmp .do_left
  381. .fix_lt_2:
  382.     movq        mm5, mm3
  383.     pxor        mm5, mm2
  384.     psllq       mm5, 56
  385.     psrlq       mm5, 56
  386.     pxor        mm2, mm5
  387.     test        r2b, 0x04
  388.     jne .do_top
  389. .fix_tr_1:
  390.     movq        mm5, mm3
  391.     pxor        mm5, mm1
  392.     psrlq       mm5, 56
  393.     psllq       mm5, 56
  394.     pxor        mm1, mm5
  395.     jmp .do_top
  396. %endmacro
  397. %define PALIGNR PALIGNR_MMX
  398. PREDICT_FILTER mmxext
  399. %define PALIGNR PALIGNR_SSSE3
  400. PREDICT_FILTER ssse3
  401. ;-----------------------------------------------------------------------------
  402. ; void predict_8x8_v_mmxext( uint8_t *src, uint8_t *edge )
  403. ;-----------------------------------------------------------------------------
  404. cglobal predict_8x8_v_mmxext, 2,2
  405.     movq        mm0, [r1+16]
  406.     STORE8x8    mm0, mm0
  407.     RET
  408. ;-----------------------------------------------------------------------------
  409. ; void predict_8x8_h_mmxext( uint8_t *src, uint8_t edge[33] )
  410. ;-----------------------------------------------------------------------------
  411. INIT_MMX
  412. cglobal predict_8x8_h_mmxext, 2,2
  413.     movu   m3, [r1+7]
  414.     mova   m7, m3
  415.     punpckhbw m3, m3
  416.     punpcklbw m7, m7
  417.     pshufw m0, m3, 0xff
  418.     pshufw m1, m3, 0xaa
  419.     pshufw m2, m3, 0x55
  420.     pshufw m3, m3, 0x00
  421.     pshufw m4, m7, 0xff
  422.     pshufw m5, m7, 0xaa
  423.     pshufw m6, m7, 0x55
  424.     pshufw m7, m7, 0x00
  425. %assign n 0
  426. %rep 8
  427.     mova [r0+n*FDEC_STRIDE], m %+ n
  428. %assign n n+1
  429. %endrep
  430.     RET
  431. ;-----------------------------------------------------------------------------
  432. ; void predict_8x8_dc_mmxext( uint8_t *src, uint8_t *edge );
  433. ;-----------------------------------------------------------------------------
  434. cglobal predict_8x8_dc_mmxext, 2,2
  435.     pxor        mm0, mm0
  436.     pxor        mm1, mm1
  437.     psadbw      mm0, [r1+7]
  438.     psadbw      mm1, [r1+16]
  439.     paddw       mm0, [pw_8 GLOBAL]
  440.     paddw       mm0, mm1
  441.     psrlw       mm0, 4
  442.     pshufw      mm0, mm0, 0
  443.     packuswb    mm0, mm0
  444.     STORE8x8    mm0, mm0
  445.     RET
  446. ;-----------------------------------------------------------------------------
  447. ; void predict_8x8_dc_top_mmxext( uint8_t *src, uint8_t *edge );
  448. ;-----------------------------------------------------------------------------
  449. %macro PRED8x8_DC 2
  450. cglobal %1, 2,2
  451.     pxor        mm0, mm0
  452.     psadbw      mm0, [r1+%2]
  453.     paddw       mm0, [pw_4 GLOBAL]
  454.     psrlw       mm0, 3
  455.     pshufw      mm0, mm0, 0
  456.     packuswb    mm0, mm0
  457.     STORE8x8    mm0, mm0
  458.     RET
  459. %endmacro
  460. PRED8x8_DC predict_8x8_dc_top_mmxext, 16
  461. PRED8x8_DC predict_8x8_dc_left_mmxext, 7
  462. %ifndef ARCH_X86_64
  463. ; sse2 is faster even on amd, so there's no sense in spending exe size on these
  464. ; functions if we know sse2 is available.
  465. ;-----------------------------------------------------------------------------
  466. ; void predict_8x8_ddl_mmxext( uint8_t *src, uint8_t *edge )
  467. ;-----------------------------------------------------------------------------
  468. cglobal predict_8x8_ddl_mmxext, 2,2
  469.     movq        mm5, [r1+16]
  470.     movq        mm2, [r1+17]
  471.     movq        mm3, [r1+23]
  472.     movq        mm4, [r1+25]
  473.     movq        mm1, mm5
  474.     psllq       mm1, 8
  475.     PRED8x8_LOWPASS mm0, mm1, mm2, mm5, mm7
  476.     PRED8x8_LOWPASS mm1, mm3, mm4, [r1+24], mm6
  477. %assign Y 7
  478. %rep 6
  479.     movq        [r0+Y*FDEC_STRIDE], mm1
  480.     movq        mm2, mm0
  481.     psllq       mm1, 8
  482.     psrlq       mm2, 56
  483.     psllq       mm0, 8
  484.     por         mm1, mm2
  485. %assign Y (Y-1)
  486. %endrep
  487.     movq        [r0+Y*FDEC_STRIDE], mm1
  488.     psllq       mm1, 8
  489.     psrlq       mm0, 56
  490.     por         mm1, mm0
  491. %assign Y (Y-1)
  492.     movq        [r0+Y*FDEC_STRIDE], mm1
  493.     RET
  494. ;-----------------------------------------------------------------------------
  495. ; void predict_8x8_ddr_mmxext( uint8_t *src, uint8_t *edge )
  496. ;-----------------------------------------------------------------------------
  497. cglobal predict_8x8_ddr_mmxext, 2,2
  498.     movq        mm1, [r1+7]
  499.     movq        mm2, [r1+9]
  500.     movq        mm3, [r1+15]
  501.     movq        mm4, [r1+17]
  502.     PRED8x8_LOWPASS mm0, mm1, mm2, [r1+8], mm7
  503.     PRED8x8_LOWPASS mm1, mm3, mm4, [r1+16], mm6
  504. %assign Y 7
  505. %rep 6
  506.     movq        [r0+Y*FDEC_STRIDE], mm0
  507.     movq        mm2, mm1
  508.     psrlq       mm0, 8
  509.     psllq       mm2, 56
  510.     psrlq       mm1, 8
  511.     por         mm0, mm2
  512. %assign Y (Y-1)
  513. %endrep
  514.     movq        [r0+Y*FDEC_STRIDE], mm0
  515.     psrlq       mm0, 8
  516.     psllq       mm1, 56
  517.     por         mm0, mm1
  518. %assign Y (Y-1)
  519.     movq        [r0+Y*FDEC_STRIDE], mm0
  520.     RET
  521. ;-----------------------------------------------------------------------------
  522. ; void predict_8x8_hu_mmxext( uint8_t *src, uint8_t *edge )
  523. ;-----------------------------------------------------------------------------
  524. %define PALIGNR PALIGNR_MMX
  525. cglobal predict_8x8_hu_mmxext, 2,2
  526.     movq    mm1, [r1+7]         ; l0 l1 l2 l3 l4 l5 l6 l7
  527.     add      r0, 4*FDEC_STRIDE
  528.     pshufw  mm0, mm1, 00011011b ; l6 l7 l4 l5 l2 l3 l0 l1
  529.     psllq   mm1, 56             ; l7 .. .. .. .. .. .. ..
  530.     movq    mm2, mm0
  531.     psllw   mm0, 8
  532.     psrlw   mm2, 8
  533.     por     mm2, mm0            ; l7 l6 l5 l4 l3 l2 l1 l0
  534.     movq    mm3, mm2
  535.     movq    mm4, mm2
  536.     movq    mm5, mm2
  537.     psrlq   mm2, 8
  538.     psrlq   mm3, 16
  539.     por     mm2, mm1            ; l7 l7 l6 l5 l4 l3 l2 l1
  540.     punpckhbw mm1, mm1
  541.     por     mm3, mm1            ; l7 l7 l7 l6 l5 l4 l3 l2
  542.     pavgb   mm4, mm2
  543.     PRED8x8_LOWPASS mm1, mm3, mm5, mm2, mm6
  544.     movq    mm5, mm4
  545.     punpcklbw mm4, mm1          ; p4 p3 p2 p1
  546.     punpckhbw mm5, mm1          ; p8 p7 p6 p5
  547.     movq    mm6, mm5
  548.     movq    mm7, mm5
  549.     movq    mm0, mm5
  550.     PALIGNR mm5, mm4, 2, mm1
  551.     pshufw  mm1, mm6, 11111001b
  552.     PALIGNR mm6, mm4, 4, mm2
  553.     pshufw  mm2, mm7, 11111110b
  554.     PALIGNR mm7, mm4, 6, mm3
  555.     pshufw  mm3, mm0, 11111111b
  556.     movq   [r0-4*FDEC_STRIDE], mm4
  557.     movq   [r0-3*FDEC_STRIDE], mm5
  558.     movq   [r0-2*FDEC_STRIDE], mm6
  559.     movq   [r0-1*FDEC_STRIDE], mm7
  560.     movq   [r0+0*FDEC_STRIDE], mm0
  561.     movq   [r0+1*FDEC_STRIDE], mm1
  562.     movq   [r0+2*FDEC_STRIDE], mm2
  563.     movq   [r0+3*FDEC_STRIDE], mm3
  564.     RET
  565. ;-----------------------------------------------------------------------------
  566. ; void predict_8x8_vr_core_mmxext( uint8_t *src, uint8_t *edge )
  567. ;-----------------------------------------------------------------------------
  568. ; fills only some pixels:
  569. ; f01234567
  570. ; 0........
  571. ; 1,,,,,,,,
  572. ; 2 .......
  573. ; 3 ,,,,,,,
  574. ; 4  ......
  575. ; 5  ,,,,,,
  576. ; 6   .....
  577. ; 7   ,,,,,
  578. cglobal predict_8x8_vr_core_mmxext, 2,2
  579.     movq        mm2, [r1+16]
  580.     movq        mm3, [r1+15]
  581.     movq        mm1, [r1+14]
  582.     movq        mm4, mm3
  583.     pavgb       mm3, mm2
  584.     PRED8x8_LOWPASS mm0, mm1, mm2, mm4, mm7
  585. %assign Y 0
  586. %rep 3
  587.     movq        [r0+ Y   *FDEC_STRIDE], mm3
  588.     movq        [r0+(Y+1)*FDEC_STRIDE], mm0
  589.     psllq       mm3, 8
  590.     psllq       mm0, 8
  591. %assign Y (Y+2)
  592. %endrep
  593.     movq        [r0+ Y   *FDEC_STRIDE], mm3
  594.     movq        [r0+(Y+1)*FDEC_STRIDE], mm0
  595.     RET
  596. ;-----------------------------------------------------------------------------
  597. ; void predict_8x8c_p_core_mmxext( uint8_t *src, int i00, int b, int c )
  598. ;-----------------------------------------------------------------------------
  599. cglobal predict_8x8c_p_core_mmxext, 1,2
  600.     LOAD_PLANE_ARGS
  601.     movq        mm1, mm2
  602.     pmullw      mm2, [pw_3210 GLOBAL]
  603.     psllw       mm1, 2
  604.     paddsw      mm0, mm2        ; mm0 = {i+0*b, i+1*b, i+2*b, i+3*b}
  605.     paddsw      mm1, mm0        ; mm1 = {i+4*b, i+5*b, i+6*b, i+7*b}
  606.     mov         r1d, 8
  607. ALIGN 4
  608. .loop:
  609.     movq        mm5, mm0
  610.     movq        mm6, mm1
  611.     psraw       mm5, 5
  612.     psraw       mm6, 5
  613.     packuswb    mm5, mm6
  614.     movq        [r0], mm5
  615.     paddsw      mm0, mm4
  616.     paddsw      mm1, mm4
  617.     add         r0, FDEC_STRIDE
  618.     dec         r1d
  619.     jg          .loop
  620.     REP_RET
  621. ;-----------------------------------------------------------------------------
  622. ; void predict_16x16_p_core_mmxext( uint8_t *src, int i00, int b, int c )
  623. ;-----------------------------------------------------------------------------
  624. cglobal predict_16x16_p_core_mmxext, 1,2
  625.     LOAD_PLANE_ARGS
  626.     movq        mm5, mm2
  627.     movq        mm1, mm2
  628.     pmullw      mm5, [pw_3210 GLOBAL]
  629.     psllw       mm2, 3
  630.     psllw       mm1, 2
  631.     movq        mm3, mm2
  632.     paddsw      mm0, mm5        ; mm0 = {i+ 0*b, i+ 1*b, i+ 2*b, i+ 3*b}
  633.     paddsw      mm1, mm0        ; mm1 = {i+ 4*b, i+ 5*b, i+ 6*b, i+ 7*b}
  634.     paddsw      mm2, mm0        ; mm2 = {i+ 8*b, i+ 9*b, i+10*b, i+11*b}
  635.     paddsw      mm3, mm1        ; mm3 = {i+12*b, i+13*b, i+14*b, i+15*b}
  636.     mov         r1d, 16
  637. ALIGN 4
  638. .loop:
  639.     movq        mm5, mm0
  640.     movq        mm6, mm1
  641.     psraw       mm5, 5
  642.     psraw       mm6, 5
  643.     packuswb    mm5, mm6
  644.     movq        [r0], mm5
  645.     movq        mm5, mm2
  646.     movq        mm6, mm3
  647.     psraw       mm5, 5
  648.     psraw       mm6, 5
  649.     packuswb    mm5, mm6
  650.     movq        [r0+8], mm5
  651.     paddsw      mm0, mm4
  652.     paddsw      mm1, mm4
  653.     paddsw      mm2, mm4
  654.     paddsw      mm3, mm4
  655.     add         r0, FDEC_STRIDE
  656.     dec         r1d
  657.     jg          .loop
  658.     REP_RET
  659. %endif ; !ARCH_X86_64
  660. ;-----------------------------------------------------------------------------
  661. ; void predict_8x8_ddl_sse2( uint8_t *src, uint8_t *edge )
  662. ;-----------------------------------------------------------------------------
  663. cglobal predict_8x8_ddl_sse2, 2,2
  664.     movdqa      xmm3, [r1+16]
  665.     movdqu      xmm2, [r1+17]
  666.     movdqa      xmm1, xmm3
  667.     pslldq      xmm1, 1
  668.     PRED8x8_LOWPASS_XMM xmm0, xmm1, xmm2, xmm3, xmm4
  669. %assign Y 0
  670. %rep 8
  671.     psrldq      xmm0, 1
  672.     movq        [r0+Y*FDEC_STRIDE], xmm0
  673. %assign Y (Y+1)
  674. %endrep
  675.     RET
  676. ;-----------------------------------------------------------------------------
  677. ; void predict_8x8_ddr_sse2( uint8_t *src, uint8_t *edge )
  678. ;-----------------------------------------------------------------------------
  679. cglobal predict_8x8_ddr_sse2, 2,2
  680.     movdqu      xmm3, [r1+8]
  681.     movdqu      xmm1, [r1+7]
  682.     movdqa      xmm2, xmm3
  683.     psrldq      xmm2, 1
  684.     PRED8x8_LOWPASS_XMM xmm0, xmm1, xmm2, xmm3, xmm4
  685.     movdqa      xmm1, xmm0
  686.     psrldq      xmm1, 1
  687. %assign Y 7
  688. %rep 3
  689.     movq        [r0+Y*FDEC_STRIDE], xmm0
  690.     movq        [r0+(Y-1)*FDEC_STRIDE], xmm1
  691.     psrldq      xmm0, 2
  692.     psrldq      xmm1, 2
  693. %assign Y (Y-2)
  694. %endrep
  695.     movq        [r0+1*FDEC_STRIDE], xmm0
  696.     movq        [r0+0*FDEC_STRIDE], xmm1
  697.     RET
  698. ;-----------------------------------------------------------------------------
  699. ; void predict_8x8_vl_sse2( uint8_t *src, uint8_t *edge )
  700. ;-----------------------------------------------------------------------------
  701. cglobal predict_8x8_vl_sse2, 2,2
  702.     movdqa      xmm4, [r1+16]
  703.     movdqa      xmm2, xmm4
  704.     movdqa      xmm1, xmm4
  705.     movdqa      xmm3, xmm4
  706.     psrldq      xmm2, 1
  707.     pslldq      xmm1, 1
  708.     pavgb       xmm3, xmm2
  709.     PRED8x8_LOWPASS_XMM xmm0, xmm1, xmm2, xmm4, xmm5
  710. ; xmm0: (t0 + 2*t1 + t2 + 2) >> 2
  711. ; xmm3: (t0 + t1 + 1) >> 1
  712. %assign Y 0
  713. %rep 3
  714.     psrldq      xmm0, 1
  715.     movq        [r0+ Y   *FDEC_STRIDE], xmm3
  716.     movq        [r0+(Y+1)*FDEC_STRIDE], xmm0
  717.     psrldq      xmm3, 1
  718. %assign Y (Y+2)
  719. %endrep
  720.     psrldq      xmm0, 1
  721.     movq        [r0+ Y   *FDEC_STRIDE], xmm3
  722.     movq        [r0+(Y+1)*FDEC_STRIDE], xmm0
  723.     RET
  724. ;-----------------------------------------------------------------------------
  725. ; void predict_8x8_vr_sse2( uint8_t *src, uint8_t *edge )
  726. ;-----------------------------------------------------------------------------
  727. cglobal predict_8x8_vr_sse2, 2,2,7
  728.     movdqu      xmm0, [r1+8]
  729.     movdqa      xmm6, [pw_ff00 GLOBAL]
  730.     add         r0, 4*FDEC_STRIDE
  731.     movdqa      xmm1, xmm0
  732.     movdqa      xmm2, xmm0
  733.     movdqa      xmm3, xmm0
  734.     pslldq      xmm0, 1
  735.     pslldq      xmm1, 2
  736.     pavgb       xmm2, xmm0
  737.     PRED8x8_LOWPASS_XMM xmm4, xmm3, xmm1, xmm0, xmm5
  738.     pandn       xmm6, xmm4
  739.     movdqa      xmm5, xmm4
  740.     psrlw       xmm4, 8
  741.     packuswb    xmm6, xmm4
  742.     movhlps     xmm4, xmm6
  743.     movhps [r0-3*FDEC_STRIDE], xmm5
  744.     movhps [r0-4*FDEC_STRIDE], xmm2
  745.     psrldq      xmm5, 4
  746.     movss       xmm5, xmm6
  747.     psrldq      xmm2, 4
  748.     movss       xmm2, xmm4
  749. %assign Y 3
  750. %rep 3
  751.     psrldq      xmm5, 1
  752.     psrldq      xmm2, 1
  753.     movq        [r0+Y*FDEC_STRIDE], xmm5
  754.     movq        [r0+(Y-1)*FDEC_STRIDE], xmm2
  755. %assign Y (Y-2)
  756. %endrep
  757.     RET
  758. ;-----------------------------------------------------------------------------
  759. ; void predict_8x8_hd_mmxext( uint8_t *src, uint8_t *edge )
  760. ;-----------------------------------------------------------------------------
  761. %define PALIGNR PALIGNR_MMX
  762. cglobal predict_8x8_hd_mmxext, 2,2
  763.     add     r0, 4*FDEC_STRIDE
  764.     movq    mm0, [r1]           ; l7 .. .. .. .. .. .. ..
  765.     movq    mm1, [r1+8]         ; lt l0 l1 l2 l3 l4 l5 l6
  766.     movq    mm2, [r1+16]        ; t7 t6 t5 t4 t3 t2 t1 t0
  767.     movq    mm3, mm1            ; lt l0 l1 l2 l3 l4 l5 l6
  768.     movq    mm4, mm2            ; t7 t6 t5 t4 t3 t2 t1 t0
  769.     PALIGNR mm2, mm1, 7, mm5    ; t6 t5 t4 t3 t2 t1 t0 lt
  770.     PALIGNR mm1, mm0, 7, mm6    ; l0 l1 l2 l3 l4 l5 l6 l7
  771.     PALIGNR mm4, mm3, 1, mm7    ; t0 lt l0 l1 l2 l3 l4 l5
  772.     movq    mm5, mm3
  773.     pavgb   mm3, mm1
  774.     PRED8x8_LOWPASS mm0, mm4, mm1, mm5, mm7
  775.     movq    mm4, mm2
  776.     movq    mm1, mm2            ; t6 t5 t4 t3 t2 t1 t0 lt
  777.     psrlq   mm4, 16             ; .. .. t6 t5 t4 t3 t2 t1
  778.     psrlq   mm1, 8              ; .. t6 t5 t4 t3 t2 t1 t0
  779.     PRED8x8_LOWPASS mm6, mm4, mm2, mm1, mm5
  780.                                 ; .. p11 p10 p9
  781.     movq    mm7, mm3
  782.     punpcklbw mm3, mm0          ; p4 p3 p2 p1
  783.     punpckhbw mm7, mm0          ; p8 p7 p6 p5
  784.     movq    mm1, mm7
  785.     movq    mm0, mm7
  786.     movq    mm4, mm7
  787.     movq   [r0+3*FDEC_STRIDE], mm3
  788.     PALIGNR mm7, mm3, 2, mm5
  789.     movq   [r0+2*FDEC_STRIDE], mm7
  790.     PALIGNR mm1, mm3, 4, mm5
  791.     movq   [r0+1*FDEC_STRIDE], mm1
  792.     PALIGNR mm0, mm3, 6, mm3
  793.     movq    [r0+0*FDEC_STRIDE], mm0
  794.     movq    mm2, mm6
  795.     movq    mm3, mm6
  796.     movq   [r0-1*FDEC_STRIDE], mm4
  797.     PALIGNR mm6, mm4, 2, mm5
  798.     movq   [r0-2*FDEC_STRIDE], mm6
  799.     PALIGNR mm2, mm4, 4, mm5
  800.     movq   [r0-3*FDEC_STRIDE], mm2
  801.     PALIGNR mm3, mm4, 6, mm4
  802.     movq   [r0-4*FDEC_STRIDE], mm3
  803.     RET
  804. ;-----------------------------------------------------------------------------
  805. ; void predict_8x8_hd_ssse3( uint8_t *src, uint8_t *edge )
  806. ;-----------------------------------------------------------------------------
  807. %macro PREDICT_8x8_HD 1
  808. cglobal predict_8x8_hd_%1, 2,2
  809.     add       r0, 4*FDEC_STRIDE
  810.     movdqa  xmm0, [r1]
  811.     movdqa  xmm1, [r1+16]
  812.     movdqa  xmm2, xmm1
  813.     movdqa  xmm3, xmm1
  814.     PALIGNR xmm1, xmm0, 7, xmm4
  815.     PALIGNR xmm2, xmm0, 9, xmm5
  816.     PALIGNR xmm3, xmm0, 8, xmm0
  817.     movdqa  xmm4, xmm1
  818.     pavgb   xmm4, xmm3
  819.     PRED8x8_LOWPASS_XMM xmm0, xmm1, xmm2, xmm3, xmm5
  820.     punpcklbw xmm4, xmm0
  821.     movhlps xmm0, xmm4
  822. %assign Y 3
  823. %rep 3
  824.     movq   [r0+(Y)*FDEC_STRIDE], xmm4
  825.     movq   [r0+(Y-4)*FDEC_STRIDE], xmm0
  826.     psrldq xmm4, 2
  827.     psrldq xmm0, 2
  828. %assign Y (Y-1)
  829. %endrep
  830.     movq   [r0+(Y)*FDEC_STRIDE], xmm4
  831.     movq   [r0+(Y-4)*FDEC_STRIDE], xmm0
  832.     RET
  833. %endmacro
  834. INIT_XMM
  835. PREDICT_8x8_HD sse2
  836. %define PALIGNR PALIGNR_SSSE3
  837. PREDICT_8x8_HD ssse3
  838. INIT_MMX
  839. %define PALIGNR PALIGNR_MMX
  840. ;-----------------------------------------------------------------------------
  841. ; void predict_8x8_hu_sse2( uint8_t *src, uint8_t *edge )
  842. ;-----------------------------------------------------------------------------
  843. %macro PREDICT_8x8_HU 1
  844. cglobal predict_8x8_hu_%1, 2,2
  845.     add        r0, 4*FDEC_STRIDE
  846. %ifidn %1, ssse3
  847.     movq      mm5, [r1+7]
  848.     movq      mm6, [pb_reverse GLOBAL]
  849.     movq      mm1, mm5
  850.     movq      mm2, mm5
  851.     movq      mm3, mm5
  852.     pshufb    mm5, mm6
  853.     psrlq     mm6, 8
  854.     pshufb    mm2, mm6
  855.     psrlq     mm6, 8
  856.     pshufb    mm3, mm6
  857.     movq      mm4, mm5
  858. %else
  859.     movq      mm1, [r1+7]           ; l0 l1 l2 l3 l4 l5 l6 l7
  860.     pshufw    mm0, mm1, 00011011b   ; l6 l7 l4 l5 l2 l3 l0 l1
  861.     movq      mm2, mm0
  862.     psllw     mm0, 8
  863.     psrlw     mm2, 8
  864.     por       mm2, mm0              ; l7 l6 l5 l4 l3 l2 l1 l0
  865.     psllq     mm1, 56               ; l7 .. .. .. .. .. .. ..
  866.     movq      mm3, mm2
  867.     movq      mm4, mm2
  868.     movq      mm5, mm2
  869.     psrlq     mm2, 8
  870.     psrlq     mm3, 16
  871.     por       mm2, mm1              ; l7 l7 l6 l5 l4 l3 l2 l1
  872.     punpckhbw mm1, mm1
  873.     por       mm3, mm1              ; l7 l7 l7 l6 l5 l4 l3 l2
  874. %endif
  875.     pavgb     mm4, mm2
  876.     PRED8x8_LOWPASS mm1, mm3, mm5, mm2, mm6
  877.     movq2dq   xmm0, mm4
  878.     movq2dq   xmm1, mm1
  879.     punpcklbw xmm0, xmm1
  880.     punpckhbw  mm4, mm1
  881. %assign Y -4
  882. %rep 3
  883.     movq     [r0+Y*FDEC_STRIDE], xmm0
  884.     psrldq    xmm0, 2
  885. %assign Y (Y+1)
  886. %endrep
  887.     pshufw     mm5, mm4, 11111001b
  888.     pshufw     mm6, mm4, 11111110b
  889.     pshufw     mm7, mm4, 11111111b
  890.     movq     [r0+Y*FDEC_STRIDE], xmm0
  891.     movq     [r0+0*FDEC_STRIDE], mm4
  892.     movq     [r0+1*FDEC_STRIDE], mm5
  893.     movq     [r0+2*FDEC_STRIDE], mm6
  894.     movq     [r0+3*FDEC_STRIDE], mm7
  895.     RET
  896. %endmacro
  897. PREDICT_8x8_HU sse2
  898. PREDICT_8x8_HU ssse3
  899. ;-----------------------------------------------------------------------------
  900. ; void predict_8x8c_v_mmx( uint8_t *src )
  901. ;-----------------------------------------------------------------------------
  902. cglobal predict_8x8c_v_mmx, 1,1
  903.     movq        mm0, [r0 - FDEC_STRIDE]
  904.     STORE8x8    mm0, mm0
  905.     RET
  906. ;-----------------------------------------------------------------------------
  907. ; void predict_8x8c_h_mmxext( uint8_t *src )
  908. ;-----------------------------------------------------------------------------
  909. %macro PRED_8x8C_H 1
  910. cglobal predict_8x8c_h_%1, 1,1
  911. %ifidn %1, ssse3
  912.     mova   m1, [pb_3 GLOBAL]
  913. %endif
  914. %assign n 0
  915. %rep 8
  916.     SPLATB m0, r0+FDEC_STRIDE*n-1, m1
  917.     mova [r0+FDEC_STRIDE*n], m0
  918. %assign n n+1
  919. %endrep
  920.     RET
  921. %endmacro
  922. INIT_MMX
  923. %define SPLATB SPLATB_MMX
  924. PRED_8x8C_H mmxext
  925. %define SPLATB SPLATB_SSSE3
  926. PRED_8x8C_H ssse3
  927. ;-----------------------------------------------------------------------------
  928. ; void predict_8x8c_dc_core_mmxext( uint8_t *src, int s2, int s3 )
  929. ;-----------------------------------------------------------------------------
  930. cglobal predict_8x8c_dc_core_mmxext, 1,1
  931.     movq        mm0, [r0 - FDEC_STRIDE]
  932.     pxor        mm1, mm1
  933.     pxor        mm2, mm2
  934.     punpckhbw   mm1, mm0
  935.     punpcklbw   mm0, mm2
  936.     psadbw      mm1, mm2        ; s1
  937.     psadbw      mm0, mm2        ; s0
  938. %ifdef ARCH_X86_64
  939.     movd        mm4, r1d
  940.     movd        mm5, r2d
  941.     paddw       mm0, mm4
  942.     pshufw      mm2, mm5, 0
  943. %else
  944.     paddw       mm0, r1m
  945.     pshufw      mm2, r2m, 0
  946. %endif
  947.     psrlw       mm0, 3
  948.     paddw       mm1, [pw_2 GLOBAL]
  949.     movq        mm3, mm2
  950.     pshufw      mm1, mm1, 0
  951.     pshufw      mm0, mm0, 0     ; dc0 (w)
  952.     paddw       mm3, mm1
  953.     psrlw       mm3, 3          ; dc3 (w)
  954.     psrlw       mm2, 2          ; dc2 (w)
  955.     psrlw       mm1, 2          ; dc1 (w)
  956.     packuswb    mm0, mm1        ; dc0,dc1 (b)
  957.     packuswb    mm2, mm3        ; dc2,dc3 (b)
  958.     STORE8x8    mm0, mm2
  959.     RET
  960. cglobal predict_8x8c_dc_top_mmxext, 1,1
  961.     movq        mm0, [r0 - FDEC_STRIDE]
  962.     pxor        mm1, mm1
  963.     pxor        mm2, mm2
  964.     punpckhbw   mm1, mm0
  965.     punpcklbw   mm0, mm2
  966.     psadbw      mm1, mm2        ; s1
  967.     psadbw      mm0, mm2        ; s0
  968.     psrlw       mm1, 1
  969.     psrlw       mm0, 1
  970.     pavgw       mm1, mm2
  971.     pavgw       mm0, mm2
  972.     pshufw      mm1, mm1, 0
  973.     pshufw      mm0, mm0, 0     ; dc0 (w)
  974.     packuswb    mm0, mm1        ; dc0,dc1 (b)
  975.     STORE8x8    mm0, mm0
  976.     RET
  977. ;-----------------------------------------------------------------------------
  978. ; void predict_8x8c_p_core_sse2( uint8_t *src, int i00, int b, int c )
  979. ;-----------------------------------------------------------------------------
  980. cglobal predict_8x8c_p_core_sse2, 1,1
  981.     movd        xmm0, r1m
  982.     movd        xmm2, r2m
  983.     movd        xmm4, r3m
  984.     pshuflw     xmm0, xmm0, 0
  985.     pshuflw     xmm2, xmm2, 0
  986.     pshuflw     xmm4, xmm4, 0
  987.     punpcklqdq  xmm0, xmm0
  988.     punpcklqdq  xmm2, xmm2
  989.     punpcklqdq  xmm4, xmm4
  990.     pmullw      xmm2, [pw_76543210 GLOBAL]
  991.     paddsw      xmm0, xmm2        ; xmm0 = {i+0*b, i+1*b, i+2*b, i+3*b, i+4*b, i+5*b, i+6*b, i+7*b}
  992.     movdqa      xmm3, xmm0
  993.     paddsw      xmm3, xmm4
  994.     paddsw      xmm4, xmm4
  995. call .loop
  996.     add           r0, FDEC_STRIDE*4
  997. .loop:
  998.     movdqa      xmm5, xmm0
  999.     movdqa      xmm1, xmm3
  1000.     psraw       xmm0, 5
  1001.     psraw       xmm3, 5
  1002.     packuswb    xmm0, xmm3
  1003.     movq        [r0+FDEC_STRIDE*0], xmm0
  1004.     movhps      [r0+FDEC_STRIDE*1], xmm0
  1005.     paddsw      xmm5, xmm4
  1006.     paddsw      xmm1, xmm4
  1007.     movdqa      xmm0, xmm5
  1008.     movdqa      xmm3, xmm1
  1009.     psraw       xmm5, 5
  1010.     psraw       xmm1, 5
  1011.     packuswb    xmm5, xmm1
  1012.     movq        [r0+FDEC_STRIDE*2], xmm5
  1013.     movhps      [r0+FDEC_STRIDE*3], xmm5
  1014.     paddsw      xmm0, xmm4
  1015.     paddsw      xmm3, xmm4
  1016.     RET
  1017. ;-----------------------------------------------------------------------------
  1018. ; void predict_16x16_p_core_sse2( uint8_t *src, int i00, int b, int c )
  1019. ;-----------------------------------------------------------------------------
  1020. cglobal predict_16x16_p_core_sse2, 1,2,8
  1021.     movd        xmm0, r1m
  1022.     movd        xmm1, r2m
  1023.     movd        xmm2, r3m
  1024.     pshuflw     xmm0, xmm0, 0
  1025.     pshuflw     xmm1, xmm1, 0
  1026.     pshuflw     xmm2, xmm2, 0
  1027.     punpcklqdq  xmm0, xmm0
  1028.     punpcklqdq  xmm1, xmm1
  1029.     punpcklqdq  xmm2, xmm2
  1030.     movdqa      xmm3, xmm1
  1031.     pmullw      xmm3, [pw_76543210 GLOBAL]
  1032.     psllw       xmm1, 3
  1033.     paddsw      xmm0, xmm3  ; xmm0 = {i+ 0*b, i+ 1*b, i+ 2*b, i+ 3*b, i+ 4*b, i+ 5*b, i+ 6*b, i+ 7*b}
  1034.     paddsw      xmm1, xmm0  ; xmm1 = {i+ 8*b, i+ 9*b, i+10*b, i+11*b, i+12*b, i+13*b, i+14*b, i+15*b}
  1035.     movdqa      xmm7, xmm2
  1036.     paddsw      xmm7, xmm7
  1037.     mov         r1d, 8
  1038. ALIGN 4
  1039. .loop:
  1040.     movdqa      xmm3, xmm0
  1041.     movdqa      xmm4, xmm1
  1042.     movdqa      xmm5, xmm0
  1043.     movdqa      xmm6, xmm1
  1044.     psraw       xmm3, 5
  1045.     psraw       xmm4, 5
  1046.     paddsw      xmm5, xmm2
  1047.     paddsw      xmm6, xmm2
  1048.     psraw       xmm5, 5
  1049.     psraw       xmm6, 5
  1050.     packuswb    xmm3, xmm4
  1051.     packuswb    xmm5, xmm6
  1052.     movdqa      [r0+FDEC_STRIDE*0], xmm3
  1053.     movdqa      [r0+FDEC_STRIDE*1], xmm5
  1054.     paddsw      xmm0, xmm7
  1055.     paddsw      xmm1, xmm7
  1056.     add         r0, FDEC_STRIDE*2
  1057.     dec         r1d
  1058.     jg          .loop
  1059.     REP_RET
  1060. ;-----------------------------------------------------------------------------
  1061. ; void predict_16x16_v_mmx( uint8_t *src )
  1062. ;-----------------------------------------------------------------------------
  1063. cglobal predict_16x16_v_mmx, 1,2
  1064.     movq        mm0, [r0 - FDEC_STRIDE]
  1065.     movq        mm1, [r0 - FDEC_STRIDE + 8]
  1066.     STORE16x16  mm0, mm1
  1067.     REP_RET
  1068. ;-----------------------------------------------------------------------------
  1069. ; void predict_16x16_v_sse2( uint8_t *src )
  1070. ;-----------------------------------------------------------------------------
  1071. cglobal predict_16x16_v_sse2, 1,1
  1072.     movdqa      xmm0, [r0 - FDEC_STRIDE]
  1073.     STORE16x16_SSE2 xmm0
  1074.     RET
  1075. ;-----------------------------------------------------------------------------
  1076. ; void predict_16x16_h_mmxext( uint8_t *src )
  1077. ;-----------------------------------------------------------------------------
  1078. %macro PRED_16x16_H 1
  1079. cglobal predict_16x16_h_%1, 1,2
  1080.     mov r1, FDEC_STRIDE*12
  1081. %ifidn %1, ssse3
  1082.     mova   m1, [pb_3 GLOBAL]
  1083. %endif
  1084. .vloop:
  1085. %assign n 0
  1086. %rep 4
  1087.     SPLATB m0, r0+r1+FDEC_STRIDE*n-1, m1
  1088.     mova [r0+r1+FDEC_STRIDE*n], m0
  1089. %if mmsize==8
  1090.     mova [r0+r1+FDEC_STRIDE*n+8], m0
  1091. %endif
  1092. %assign n n+1
  1093. %endrep
  1094.     add r1, -FDEC_STRIDE*4
  1095.     jge .vloop
  1096.     REP_RET
  1097. %endmacro
  1098. ;no SSE2, its slower than MMX on all systems that don't support SSSE3
  1099. INIT_MMX
  1100. %define SPLATB SPLATB_MMX
  1101. PRED_16x16_H mmxext
  1102. INIT_XMM
  1103. %define SPLATB SPLATB_SSSE3
  1104. PRED_16x16_H ssse3
  1105. ;-----------------------------------------------------------------------------
  1106. ; void predict_16x16_dc_core_mmxext( uint8_t *src, int i_dc_left )
  1107. ;-----------------------------------------------------------------------------
  1108. %macro PRED16x16_DC 2
  1109.     pxor        mm0, mm0
  1110.     pxor        mm1, mm1
  1111.     psadbw      mm0, [r0 - FDEC_STRIDE]
  1112.     psadbw      mm1, [r0 - FDEC_STRIDE + 8]
  1113.     paddusw     mm0, mm1
  1114.     paddusw     mm0, %1
  1115.     psrlw       mm0, %2                       ; dc
  1116.     pshufw      mm0, mm0, 0
  1117.     packuswb    mm0, mm0                      ; dc in bytes
  1118.     STORE16x16  mm0, mm0
  1119. %endmacro
  1120. cglobal predict_16x16_dc_core_mmxext, 1,2
  1121. %ifdef ARCH_X86_64
  1122.     movd         mm2, r1d
  1123.     PRED16x16_DC mm2, 5
  1124. %else
  1125.     PRED16x16_DC r1m, 5
  1126. %endif
  1127.     REP_RET
  1128. cglobal predict_16x16_dc_top_mmxext, 1,2
  1129.     PRED16x16_DC [pw_8 GLOBAL], 4
  1130.     REP_RET
  1131. cglobal predict_16x16_dc_left_core_mmxext, 1,1
  1132.     movd       mm0, r1m
  1133.     pshufw     mm0, mm0, 0
  1134.     packuswb   mm0, mm0
  1135.     STORE16x16 mm0, mm0
  1136.     REP_RET
  1137. ;-----------------------------------------------------------------------------
  1138. ; void predict_16x16_dc_core_sse2( uint8_t *src, int i_dc_left )
  1139. ;-----------------------------------------------------------------------------
  1140. %macro PRED16x16_DC_SSE2 2
  1141.     pxor        xmm0, xmm0
  1142.     psadbw      xmm0, [r0 - FDEC_STRIDE]
  1143.     movhlps     xmm1, xmm0
  1144.     paddw       xmm0, xmm1
  1145.     paddusw     xmm0, %1
  1146.     psrlw       xmm0, %2                ; dc
  1147.     pshuflw     xmm0, xmm0, 0
  1148.     punpcklqdq  xmm0, xmm0
  1149.     packuswb    xmm0, xmm0              ; dc in bytes
  1150.     STORE16x16_SSE2 xmm0
  1151. %endmacro
  1152. cglobal predict_16x16_dc_core_sse2, 1,1
  1153.     movd xmm2, r1m
  1154.     PRED16x16_DC_SSE2 xmm2, 5
  1155.     RET
  1156. cglobal predict_16x16_dc_top_sse2, 1,1
  1157.     PRED16x16_DC_SSE2 [pw_8 GLOBAL], 4
  1158.     RET
  1159. cglobal predict_16x16_dc_left_core_sse2, 1,1
  1160.     movd       xmm0, r1m
  1161.     pshuflw    xmm0, xmm0, 0
  1162.     punpcklqdq xmm0, xmm0
  1163.     packuswb   xmm0, xmm0
  1164.     STORE16x16_SSE2 xmm0
  1165.     RET