Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. ;******************************************************************************
  2. ;* VP8 MMXEXT optimizations
  3. ;* Copyright (c) 2010 Ronald S. Bultje <rsbultje@gmail.com>
  4. ;* Copyright (c) 2010 Jason Garrett-Glaser <darkshikari@gmail.com>
  5. ;*
  6. ;* This file is part of FFmpeg.
  7. ;*
  8. ;* FFmpeg is free software; you can redistribute it and/or
  9. ;* modify it under the terms of the GNU Lesser General Public
  10. ;* License as published by the Free Software Foundation; either
  11. ;* version 2.1 of the License, or (at your option) any later version.
  12. ;*
  13. ;* FFmpeg 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 GNU
  16. ;* Lesser General Public License for more details.
  17. ;*
  18. ;* You should have received a copy of the GNU Lesser General Public
  19. ;* License along with FFmpeg; if not, write to the Free Software
  20. ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. ;******************************************************************************
  22.  
  23. %include "libavutil/x86/x86util.asm"
  24.  
  25. SECTION_RODATA
  26.  
  27. fourtap_filter_hw_m: times 4 dw  -6, 123
  28.                      times 4 dw  12,  -1
  29.                      times 4 dw  -9,  93
  30.                      times 4 dw  50,  -6
  31.                      times 4 dw  -6,  50
  32.                      times 4 dw  93,  -9
  33.                      times 4 dw  -1,  12
  34.                      times 4 dw 123,  -6
  35.  
  36. sixtap_filter_hw_m:  times 4 dw   2, -11
  37.                      times 4 dw 108,  36
  38.                      times 4 dw  -8,   1
  39.                      times 4 dw   3, -16
  40.                      times 4 dw  77,  77
  41.                      times 4 dw -16,   3
  42.                      times 4 dw   1,  -8
  43.                      times 4 dw  36, 108
  44.                      times 4 dw -11,   2
  45.  
  46. fourtap_filter_hb_m: times 8 db  -6, 123
  47.                      times 8 db  12,  -1
  48.                      times 8 db  -9,  93
  49.                      times 8 db  50,  -6
  50.                      times 8 db  -6,  50
  51.                      times 8 db  93,  -9
  52.                      times 8 db  -1,  12
  53.                      times 8 db 123,  -6
  54.  
  55. sixtap_filter_hb_m:  times 8 db   2,   1
  56.                      times 8 db -11, 108
  57.                      times 8 db  36,  -8
  58.                      times 8 db   3,   3
  59.                      times 8 db -16,  77
  60.                      times 8 db  77, -16
  61.                      times 8 db   1,   2
  62.                      times 8 db  -8,  36
  63.                      times 8 db 108, -11
  64.  
  65. fourtap_filter_v_m:  times 8 dw  -6
  66.                      times 8 dw 123
  67.                      times 8 dw  12
  68.                      times 8 dw  -1
  69.                      times 8 dw  -9
  70.                      times 8 dw  93
  71.                      times 8 dw  50
  72.                      times 8 dw  -6
  73.                      times 8 dw  -6
  74.                      times 8 dw  50
  75.                      times 8 dw  93
  76.                      times 8 dw  -9
  77.                      times 8 dw  -1
  78.                      times 8 dw  12
  79.                      times 8 dw 123
  80.                      times 8 dw  -6
  81.  
  82. sixtap_filter_v_m:   times 8 dw   2
  83.                      times 8 dw -11
  84.                      times 8 dw 108
  85.                      times 8 dw  36
  86.                      times 8 dw  -8
  87.                      times 8 dw   1
  88.                      times 8 dw   3
  89.                      times 8 dw -16
  90.                      times 8 dw  77
  91.                      times 8 dw  77
  92.                      times 8 dw -16
  93.                      times 8 dw   3
  94.                      times 8 dw   1
  95.                      times 8 dw  -8
  96.                      times 8 dw  36
  97.                      times 8 dw 108
  98.                      times 8 dw -11
  99.                      times 8 dw   2
  100.  
  101. bilinear_filter_vw_m: times 8 dw 1
  102.                       times 8 dw 2
  103.                       times 8 dw 3
  104.                       times 8 dw 4
  105.                       times 8 dw 5
  106.                       times 8 dw 6
  107.                       times 8 dw 7
  108.  
  109. bilinear_filter_vb_m: times 8 db 7, 1
  110.                       times 8 db 6, 2
  111.                       times 8 db 5, 3
  112.                       times 8 db 4, 4
  113.                       times 8 db 3, 5
  114.                       times 8 db 2, 6
  115.                       times 8 db 1, 7
  116.  
  117. %ifdef PIC
  118. %define fourtap_filter_hw  picregq
  119. %define sixtap_filter_hw   picregq
  120. %define fourtap_filter_hb  picregq
  121. %define sixtap_filter_hb   picregq
  122. %define fourtap_filter_v   picregq
  123. %define sixtap_filter_v    picregq
  124. %define bilinear_filter_vw picregq
  125. %define bilinear_filter_vb picregq
  126. %define npicregs 1
  127. %else
  128. %define fourtap_filter_hw  fourtap_filter_hw_m
  129. %define sixtap_filter_hw   sixtap_filter_hw_m
  130. %define fourtap_filter_hb  fourtap_filter_hb_m
  131. %define sixtap_filter_hb   sixtap_filter_hb_m
  132. %define fourtap_filter_v   fourtap_filter_v_m
  133. %define sixtap_filter_v    sixtap_filter_v_m
  134. %define bilinear_filter_vw bilinear_filter_vw_m
  135. %define bilinear_filter_vb bilinear_filter_vb_m
  136. %define npicregs 0
  137. %endif
  138.  
  139. filter_h2_shuf:  db 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5,  6, 6,  7,  7,  8
  140. filter_h4_shuf:  db 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,  8, 8,  9,  9, 10
  141.  
  142. filter_h6_shuf1: db 0, 5, 1, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 11,  7, 12
  143. filter_h6_shuf2: db 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,  7, 7,  8,  8,  9
  144. filter_h6_shuf3: db 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,  9, 9, 10, 10, 11
  145.  
  146. pw_27:    times 8 dw 27
  147. pw_63:    times 8 dw 63
  148. pw_256:   times 8 dw 256
  149. pw_20091: times 4 dw 20091
  150. pw_17734: times 4 dw 17734
  151.  
  152. pb_4:     times 16 db 4
  153. pb_F8:    times 16 db 0xF8
  154. pb_FE:    times 16 db 0xFE
  155. pb_27_63: times 8 db 27, 63
  156. pb_18_63: times 8 db 18, 63
  157. pb_9_63:  times 8 db  9, 63
  158.  
  159. cextern pb_1
  160. cextern pw_3
  161. cextern pb_3
  162. cextern pw_4
  163. cextern pw_9
  164. cextern pw_18
  165. cextern pw_64
  166. cextern pb_80
  167.  
  168. SECTION .text
  169.  
  170. ;-----------------------------------------------------------------------------
  171. ; subpel MC functions:
  172. ;
  173. ; void put_vp8_epel<size>_h<htap>v<vtap>_<opt>(uint8_t *dst, int deststride,
  174. ;                                              uint8_t *src, int srcstride,
  175. ;                                              int height,   int mx, int my);
  176. ;-----------------------------------------------------------------------------
  177.  
  178. %macro FILTER_SSSE3 1
  179. cglobal put_vp8_epel%1_h6, 6, 6 + npicregs, 8, dst, dststride, src, srcstride, height, mx, picreg
  180.     lea      mxd, [mxq*3]
  181.     mova      m3, [filter_h6_shuf2]
  182.     mova      m4, [filter_h6_shuf3]
  183. %ifdef PIC
  184.     lea  picregq, [sixtap_filter_hb_m]
  185. %endif
  186.     mova      m5, [sixtap_filter_hb+mxq*8-48] ; set up 6tap filter in bytes
  187.     mova      m6, [sixtap_filter_hb+mxq*8-32]
  188.     mova      m7, [sixtap_filter_hb+mxq*8-16]
  189.  
  190. .nextrow:
  191.     movu      m0, [srcq-2]
  192.     mova      m1, m0
  193.     mova      m2, m0
  194. %if mmsize == 8
  195. ; For epel4, we need 9 bytes, but only 8 get loaded; to compensate, do the
  196. ; shuffle with a memory operand
  197.     punpcklbw m0, [srcq+3]
  198. %else
  199.     pshufb    m0, [filter_h6_shuf1]
  200. %endif
  201.     pshufb    m1, m3
  202.     pshufb    m2, m4
  203.     pmaddubsw m0, m5
  204.     pmaddubsw m1, m6
  205.     pmaddubsw m2, m7
  206.     paddsw    m0, m1
  207.     paddsw    m0, m2
  208.     pmulhrsw  m0, [pw_256]
  209.     packuswb  m0, m0
  210.     movh  [dstq], m0        ; store
  211.  
  212.     ; go to next line
  213.     add     dstq, dststrideq
  214.     add     srcq, srcstrideq
  215.     dec  heightd            ; next row
  216.     jg .nextrow
  217.     REP_RET
  218.  
  219. cglobal put_vp8_epel%1_h4, 6, 6 + npicregs, 7, dst, dststride, src, srcstride, height, mx, picreg
  220.     shl      mxd, 4
  221.     mova      m2, [pw_256]
  222.     mova      m3, [filter_h2_shuf]
  223.     mova      m4, [filter_h4_shuf]
  224. %ifdef PIC
  225.     lea  picregq, [fourtap_filter_hb_m]
  226. %endif
  227.     mova      m5, [fourtap_filter_hb+mxq-16] ; set up 4tap filter in bytes
  228.     mova      m6, [fourtap_filter_hb+mxq]
  229.  
  230. .nextrow:
  231.     movu      m0, [srcq-1]
  232.     mova      m1, m0
  233.     pshufb    m0, m3
  234.     pshufb    m1, m4
  235.     pmaddubsw m0, m5
  236.     pmaddubsw m1, m6
  237.     paddsw    m0, m1
  238.     pmulhrsw  m0, m2
  239.     packuswb  m0, m0
  240.     movh  [dstq], m0        ; store
  241.  
  242.     ; go to next line
  243.     add     dstq, dststrideq
  244.     add     srcq, srcstrideq
  245.     dec  heightd            ; next row
  246.     jg .nextrow
  247.     REP_RET
  248.  
  249. cglobal put_vp8_epel%1_v4, 7, 7, 8, dst, dststride, src, srcstride, height, picreg, my
  250.     shl      myd, 4
  251. %ifdef PIC
  252.     lea  picregq, [fourtap_filter_hb_m]
  253. %endif
  254.     mova      m5, [fourtap_filter_hb+myq-16]
  255.     mova      m6, [fourtap_filter_hb+myq]
  256.     mova      m7, [pw_256]
  257.  
  258.     ; read 3 lines
  259.     sub     srcq, srcstrideq
  260.     movh      m0, [srcq]
  261.     movh      m1, [srcq+  srcstrideq]
  262.     movh      m2, [srcq+2*srcstrideq]
  263.     add     srcq, srcstrideq
  264.  
  265. .nextrow:
  266.     movh      m3, [srcq+2*srcstrideq]      ; read new row
  267.     mova      m4, m0
  268.     mova      m0, m1
  269.     punpcklbw m4, m1
  270.     mova      m1, m2
  271.     punpcklbw m2, m3
  272.     pmaddubsw m4, m5
  273.     pmaddubsw m2, m6
  274.     paddsw    m4, m2
  275.     mova      m2, m3
  276.     pmulhrsw  m4, m7
  277.     packuswb  m4, m4
  278.     movh  [dstq], m4
  279.  
  280.     ; go to next line
  281.     add      dstq, dststrideq
  282.     add      srcq, srcstrideq
  283.     dec   heightd                          ; next row
  284.     jg .nextrow
  285.     REP_RET
  286.  
  287. cglobal put_vp8_epel%1_v6, 7, 7, 8, dst, dststride, src, srcstride, height, picreg, my
  288.     lea      myd, [myq*3]
  289. %ifdef PIC
  290.     lea  picregq, [sixtap_filter_hb_m]
  291. %endif
  292.     lea      myq, [sixtap_filter_hb+myq*8]
  293.  
  294.     ; read 5 lines
  295.     sub     srcq, srcstrideq
  296.     sub     srcq, srcstrideq
  297.     movh      m0, [srcq]
  298.     movh      m1, [srcq+srcstrideq]
  299.     movh      m2, [srcq+srcstrideq*2]
  300.     lea     srcq, [srcq+srcstrideq*2]
  301.     add     srcq, srcstrideq
  302.     movh      m3, [srcq]
  303.     movh      m4, [srcq+srcstrideq]
  304.  
  305. .nextrow:
  306.     movh      m5, [srcq+2*srcstrideq]      ; read new row
  307.     mova      m6, m0
  308.     punpcklbw m6, m5
  309.     mova      m0, m1
  310.     punpcklbw m1, m2
  311.     mova      m7, m3
  312.     punpcklbw m7, m4
  313.     pmaddubsw m6, [myq-48]
  314.     pmaddubsw m1, [myq-32]
  315.     pmaddubsw m7, [myq-16]
  316.     paddsw    m6, m1
  317.     paddsw    m6, m7
  318.     mova      m1, m2
  319.     mova      m2, m3
  320.     pmulhrsw  m6, [pw_256]
  321.     mova      m3, m4
  322.     packuswb  m6, m6
  323.     mova      m4, m5
  324.     movh  [dstq], m6
  325.  
  326.     ; go to next line
  327.     add      dstq, dststrideq
  328.     add      srcq, srcstrideq
  329.     dec   heightd                          ; next row
  330.     jg .nextrow
  331.     REP_RET
  332. %endmacro
  333.  
  334. INIT_MMX ssse3
  335. FILTER_SSSE3 4
  336. INIT_XMM ssse3
  337. FILTER_SSSE3 8
  338.  
  339. ; 4x4 block, H-only 4-tap filter
  340. INIT_MMX mmxext
  341. cglobal put_vp8_epel4_h4, 6, 6 + npicregs, 0, dst, dststride, src, srcstride, height, mx, picreg
  342.     shl       mxd, 4
  343. %ifdef PIC
  344.     lea   picregq, [fourtap_filter_hw_m]
  345. %endif
  346.     movq      mm4, [fourtap_filter_hw+mxq-16] ; set up 4tap filter in words
  347.     movq      mm5, [fourtap_filter_hw+mxq]
  348.     movq      mm7, [pw_64]
  349.     pxor      mm6, mm6
  350.  
  351. .nextrow:
  352.     movq      mm1, [srcq-1]                ; (ABCDEFGH) load 8 horizontal pixels
  353.  
  354.     ; first set of 2 pixels
  355.     movq      mm2, mm1                     ; byte ABCD..
  356.     punpcklbw mm1, mm6                     ; byte->word ABCD
  357.     pshufw    mm0, mm2, 9                  ; byte CDEF..
  358.     punpcklbw mm0, mm6                     ; byte->word CDEF
  359.     pshufw    mm3, mm1, 0x94               ; word ABBC
  360.     pshufw    mm1, mm0, 0x94               ; word CDDE
  361.     pmaddwd   mm3, mm4                     ; multiply 2px with F0/F1
  362.     movq      mm0, mm1                     ; backup for second set of pixels
  363.     pmaddwd   mm1, mm5                     ; multiply 2px with F2/F3
  364.     paddd     mm3, mm1                     ; finish 1st 2px
  365.  
  366.     ; second set of 2 pixels, use backup of above
  367.     punpckhbw mm2, mm6                     ; byte->word EFGH
  368.     pmaddwd   mm0, mm4                     ; multiply backed up 2px with F0/F1
  369.     pshufw    mm1, mm2, 0x94               ; word EFFG
  370.     pmaddwd   mm1, mm5                     ; multiply 2px with F2/F3
  371.     paddd     mm0, mm1                     ; finish 2nd 2px
  372.  
  373.     ; merge two sets of 2 pixels into one set of 4, round/clip/store
  374.     packssdw  mm3, mm0                     ; merge dword->word (4px)
  375.     paddsw    mm3, mm7                     ; rounding
  376.     psraw     mm3, 7
  377.     packuswb  mm3, mm6                     ; clip and word->bytes
  378.     movd   [dstq], mm3                     ; store
  379.  
  380.     ; go to next line
  381.     add      dstq, dststrideq
  382.     add      srcq, srcstrideq
  383.     dec   heightd                          ; next row
  384.     jg .nextrow
  385.     REP_RET
  386.  
  387. ; 4x4 block, H-only 6-tap filter
  388. INIT_MMX mmxext
  389. cglobal put_vp8_epel4_h6, 6, 6 + npicregs, 0, dst, dststride, src, srcstride, height, mx, picreg
  390.     lea       mxd, [mxq*3]
  391. %ifdef PIC
  392.     lea   picregq, [sixtap_filter_hw_m]
  393. %endif
  394.     movq      mm4, [sixtap_filter_hw+mxq*8-48] ; set up 4tap filter in words
  395.     movq      mm5, [sixtap_filter_hw+mxq*8-32]
  396.     movq      mm6, [sixtap_filter_hw+mxq*8-16]
  397.     movq      mm7, [pw_64]
  398.     pxor      mm3, mm3
  399.  
  400. .nextrow:
  401.     movq      mm1, [srcq-2]                ; (ABCDEFGH) load 8 horizontal pixels
  402.  
  403.     ; first set of 2 pixels
  404.     movq      mm2, mm1                     ; byte ABCD..
  405.     punpcklbw mm1, mm3                     ; byte->word ABCD
  406.     pshufw    mm0, mm2, 0x9                ; byte CDEF..
  407.     punpckhbw mm2, mm3                     ; byte->word EFGH
  408.     punpcklbw mm0, mm3                     ; byte->word CDEF
  409.     pshufw    mm1, mm1, 0x94               ; word ABBC
  410.     pshufw    mm2, mm2, 0x94               ; word EFFG
  411.     pmaddwd   mm1, mm4                     ; multiply 2px with F0/F1
  412.     pshufw    mm3, mm0, 0x94               ; word CDDE
  413.     movq      mm0, mm3                     ; backup for second set of pixels
  414.     pmaddwd   mm3, mm5                     ; multiply 2px with F2/F3
  415.     paddd     mm1, mm3                     ; add to 1st 2px cache
  416.     movq      mm3, mm2                     ; backup for second set of pixels
  417.     pmaddwd   mm2, mm6                     ; multiply 2px with F4/F5
  418.     paddd     mm1, mm2                     ; finish 1st 2px
  419.  
  420.     ; second set of 2 pixels, use backup of above
  421.     movd      mm2, [srcq+3]                ; byte FGHI (prevent overreads)
  422.     pmaddwd   mm0, mm4                     ; multiply 1st backed up 2px with F0/F1
  423.     pmaddwd   mm3, mm5                     ; multiply 2nd backed up 2px with F2/F3
  424.     paddd     mm0, mm3                     ; add to 2nd 2px cache
  425.     pxor      mm3, mm3
  426.     punpcklbw mm2, mm3                     ; byte->word FGHI
  427.     pshufw    mm2, mm2, 0xE9               ; word GHHI
  428.     pmaddwd   mm2, mm6                     ; multiply 2px with F4/F5
  429.     paddd     mm0, mm2                     ; finish 2nd 2px
  430.  
  431.     ; merge two sets of 2 pixels into one set of 4, round/clip/store
  432.     packssdw  mm1, mm0                     ; merge dword->word (4px)
  433.     paddsw    mm1, mm7                     ; rounding
  434.     psraw     mm1, 7
  435.     packuswb  mm1, mm3                     ; clip and word->bytes
  436.     movd   [dstq], mm1                     ; store
  437.  
  438.     ; go to next line
  439.     add      dstq, dststrideq
  440.     add      srcq, srcstrideq
  441.     dec   heightd                          ; next row
  442.     jg .nextrow
  443.     REP_RET
  444.  
  445. INIT_XMM sse2
  446. cglobal put_vp8_epel8_h4, 6, 6 + npicregs, 10, dst, dststride, src, srcstride, height, mx, picreg
  447.     shl      mxd, 5
  448. %ifdef PIC
  449.     lea  picregq, [fourtap_filter_v_m]
  450. %endif
  451.     lea      mxq, [fourtap_filter_v+mxq-32]
  452.     pxor      m7, m7
  453.     mova      m4, [pw_64]
  454.     mova      m5, [mxq+ 0]
  455.     mova      m6, [mxq+16]
  456. %ifdef m8
  457.     mova      m8, [mxq+32]
  458.     mova      m9, [mxq+48]
  459. %endif
  460. .nextrow:
  461.     movq      m0, [srcq-1]
  462.     movq      m1, [srcq-0]
  463.     movq      m2, [srcq+1]
  464.     movq      m3, [srcq+2]
  465.     punpcklbw m0, m7
  466.     punpcklbw m1, m7
  467.     punpcklbw m2, m7
  468.     punpcklbw m3, m7
  469.     pmullw    m0, m5
  470.     pmullw    m1, m6
  471. %ifdef m8
  472.     pmullw    m2, m8
  473.     pmullw    m3, m9
  474. %else
  475.     pmullw    m2, [mxq+32]
  476.     pmullw    m3, [mxq+48]
  477. %endif
  478.     paddsw    m0, m1
  479.     paddsw    m2, m3
  480.     paddsw    m0, m2
  481.     paddsw    m0, m4
  482.     psraw     m0, 7
  483.     packuswb  m0, m7
  484.     movh  [dstq], m0        ; store
  485.  
  486.     ; go to next line
  487.     add     dstq, dststrideq
  488.     add     srcq, srcstrideq
  489.     dec  heightd            ; next row
  490.     jg .nextrow
  491.     REP_RET
  492.  
  493. INIT_XMM sse2
  494. cglobal put_vp8_epel8_h6, 6, 6 + npicregs, 14, dst, dststride, src, srcstride, height, mx, picreg
  495.     lea      mxd, [mxq*3]
  496.     shl      mxd, 4
  497. %ifdef PIC
  498.     lea  picregq, [sixtap_filter_v_m]
  499. %endif
  500.     lea      mxq, [sixtap_filter_v+mxq-96]
  501.     pxor      m7, m7
  502.     mova      m6, [pw_64]
  503. %ifdef m8
  504.     mova      m8, [mxq+ 0]
  505.     mova      m9, [mxq+16]
  506.     mova     m10, [mxq+32]
  507.     mova     m11, [mxq+48]
  508.     mova     m12, [mxq+64]
  509.     mova     m13, [mxq+80]
  510. %endif
  511. .nextrow:
  512.     movq      m0, [srcq-2]
  513.     movq      m1, [srcq-1]
  514.     movq      m2, [srcq-0]
  515.     movq      m3, [srcq+1]
  516.     movq      m4, [srcq+2]
  517.     movq      m5, [srcq+3]
  518.     punpcklbw m0, m7
  519.     punpcklbw m1, m7
  520.     punpcklbw m2, m7
  521.     punpcklbw m3, m7
  522.     punpcklbw m4, m7
  523.     punpcklbw m5, m7
  524. %ifdef m8
  525.     pmullw    m0, m8
  526.     pmullw    m1, m9
  527.     pmullw    m2, m10
  528.     pmullw    m3, m11
  529.     pmullw    m4, m12
  530.     pmullw    m5, m13
  531. %else
  532.     pmullw    m0, [mxq+ 0]
  533.     pmullw    m1, [mxq+16]
  534.     pmullw    m2, [mxq+32]
  535.     pmullw    m3, [mxq+48]
  536.     pmullw    m4, [mxq+64]
  537.     pmullw    m5, [mxq+80]
  538. %endif
  539.     paddsw    m1, m4
  540.     paddsw    m0, m5
  541.     paddsw    m1, m2
  542.     paddsw    m0, m3
  543.     paddsw    m0, m1
  544.     paddsw    m0, m6
  545.     psraw     m0, 7
  546.     packuswb  m0, m7
  547.     movh  [dstq], m0        ; store
  548.  
  549.     ; go to next line
  550.     add     dstq, dststrideq
  551.     add     srcq, srcstrideq
  552.     dec  heightd            ; next row
  553.     jg .nextrow
  554.     REP_RET
  555.  
  556. %macro FILTER_V 1
  557. ; 4x4 block, V-only 4-tap filter
  558. cglobal put_vp8_epel%1_v4, 7, 7, 8, dst, dststride, src, srcstride, height, picreg, my
  559.     shl      myd, 5
  560. %ifdef PIC
  561.     lea  picregq, [fourtap_filter_v_m]
  562. %endif
  563.     lea      myq, [fourtap_filter_v+myq-32]
  564.     mova      m6, [pw_64]
  565.     pxor      m7, m7
  566.     mova      m5, [myq+48]
  567.  
  568.     ; read 3 lines
  569.     sub     srcq, srcstrideq
  570.     movh      m0, [srcq]
  571.     movh      m1, [srcq+  srcstrideq]
  572.     movh      m2, [srcq+2*srcstrideq]
  573.     add     srcq, srcstrideq
  574.     punpcklbw m0, m7
  575.     punpcklbw m1, m7
  576.     punpcklbw m2, m7
  577.  
  578. .nextrow:
  579.     ; first calculate negative taps (to prevent losing positive overflows)
  580.     movh      m4, [srcq+2*srcstrideq]      ; read new row
  581.     punpcklbw m4, m7
  582.     mova      m3, m4
  583.     pmullw    m0, [myq+0]
  584.     pmullw    m4, m5
  585.     paddsw    m4, m0
  586.  
  587.     ; then calculate positive taps
  588.     mova      m0, m1
  589.     pmullw    m1, [myq+16]
  590.     paddsw    m4, m1
  591.     mova      m1, m2
  592.     pmullw    m2, [myq+32]
  593.     paddsw    m4, m2
  594.     mova      m2, m3
  595.  
  596.     ; round/clip/store
  597.     paddsw    m4, m6
  598.     psraw     m4, 7
  599.     packuswb  m4, m7
  600.     movh  [dstq], m4
  601.  
  602.     ; go to next line
  603.     add     dstq, dststrideq
  604.     add     srcq, srcstrideq
  605.     dec  heightd                           ; next row
  606.     jg .nextrow
  607.     REP_RET
  608.  
  609.  
  610. ; 4x4 block, V-only 6-tap filter
  611. cglobal put_vp8_epel%1_v6, 7, 7, 8, dst, dststride, src, srcstride, height, picreg, my
  612.     shl      myd, 4
  613.     lea      myq, [myq*3]
  614. %ifdef PIC
  615.     lea  picregq, [sixtap_filter_v_m]
  616. %endif
  617.     lea      myq, [sixtap_filter_v+myq-96]
  618.     pxor      m7, m7
  619.  
  620.     ; read 5 lines
  621.     sub     srcq, srcstrideq
  622.     sub     srcq, srcstrideq
  623.     movh      m0, [srcq]
  624.     movh      m1, [srcq+srcstrideq]
  625.     movh      m2, [srcq+srcstrideq*2]
  626.     lea     srcq, [srcq+srcstrideq*2]
  627.     add     srcq, srcstrideq
  628.     movh      m3, [srcq]
  629.     movh      m4, [srcq+srcstrideq]
  630.     punpcklbw m0, m7
  631.     punpcklbw m1, m7
  632.     punpcklbw m2, m7
  633.     punpcklbw m3, m7
  634.     punpcklbw m4, m7
  635.  
  636. .nextrow:
  637.     ; first calculate negative taps (to prevent losing positive overflows)
  638.     mova      m5, m1
  639.     pmullw    m5, [myq+16]
  640.     mova      m6, m4
  641.     pmullw    m6, [myq+64]
  642.     paddsw    m6, m5
  643.  
  644.     ; then calculate positive taps
  645.     movh      m5, [srcq+2*srcstrideq]      ; read new row
  646.     punpcklbw m5, m7
  647.     pmullw    m0, [myq+0]
  648.     paddsw    m6, m0
  649.     mova      m0, m1
  650.     mova      m1, m2
  651.     pmullw    m2, [myq+32]
  652.     paddsw    m6, m2
  653.     mova      m2, m3
  654.     pmullw    m3, [myq+48]
  655.     paddsw    m6, m3
  656.     mova      m3, m4
  657.     mova      m4, m5
  658.     pmullw    m5, [myq+80]
  659.     paddsw    m6, m5
  660.  
  661.     ; round/clip/store
  662.     paddsw    m6, [pw_64]
  663.     psraw     m6, 7
  664.     packuswb  m6, m7
  665.     movh  [dstq], m6
  666.  
  667.     ; go to next line
  668.     add     dstq, dststrideq
  669.     add     srcq, srcstrideq
  670.     dec  heightd                           ; next row
  671.     jg .nextrow
  672.     REP_RET
  673. %endmacro
  674.  
  675. INIT_MMX mmxext
  676. FILTER_V 4
  677. INIT_XMM sse2
  678. FILTER_V 8
  679.  
  680. %macro FILTER_BILINEAR 1
  681. cglobal put_vp8_bilinear%1_v, 7, 7, 7, dst, dststride, src, srcstride, height, picreg, my
  682.     shl      myd, 4
  683. %ifdef PIC
  684.     lea  picregq, [bilinear_filter_vw_m]
  685. %endif
  686.     pxor      m6, m6
  687.     mova      m5, [bilinear_filter_vw+myq-1*16]
  688.     neg      myq
  689.     mova      m4, [bilinear_filter_vw+myq+7*16]
  690. .nextrow:
  691.     movh      m0, [srcq+srcstrideq*0]
  692.     movh      m1, [srcq+srcstrideq*1]
  693.     movh      m3, [srcq+srcstrideq*2]
  694.     punpcklbw m0, m6
  695.     punpcklbw m1, m6
  696.     punpcklbw m3, m6
  697.     mova      m2, m1
  698.     pmullw    m0, m4
  699.     pmullw    m1, m5
  700.     pmullw    m2, m4
  701.     pmullw    m3, m5
  702.     paddsw    m0, m1
  703.     paddsw    m2, m3
  704.     psraw     m0, 2
  705.     psraw     m2, 2
  706.     pavgw     m0, m6
  707.     pavgw     m2, m6
  708. %if mmsize == 8
  709.     packuswb  m0, m0
  710.     packuswb  m2, m2
  711.     movh   [dstq+dststrideq*0], m0
  712.     movh   [dstq+dststrideq*1], m2
  713. %else
  714.     packuswb  m0, m2
  715.     movh   [dstq+dststrideq*0], m0
  716.     movhps [dstq+dststrideq*1], m0
  717. %endif
  718.  
  719.     lea     dstq, [dstq+dststrideq*2]
  720.     lea     srcq, [srcq+srcstrideq*2]
  721.     sub  heightd, 2
  722.     jg .nextrow
  723.     REP_RET
  724.  
  725. cglobal put_vp8_bilinear%1_h, 6, 6 + npicregs, 7, dst, dststride, src, srcstride, height, mx, picreg
  726.     shl      mxd, 4
  727. %ifdef PIC
  728.     lea  picregq, [bilinear_filter_vw_m]
  729. %endif
  730.     pxor      m6, m6
  731.     mova      m5, [bilinear_filter_vw+mxq-1*16]
  732.     neg      mxq
  733.     mova      m4, [bilinear_filter_vw+mxq+7*16]
  734. .nextrow:
  735.     movh      m0, [srcq+srcstrideq*0+0]
  736.     movh      m1, [srcq+srcstrideq*0+1]
  737.     movh      m2, [srcq+srcstrideq*1+0]
  738.     movh      m3, [srcq+srcstrideq*1+1]
  739.     punpcklbw m0, m6
  740.     punpcklbw m1, m6
  741.     punpcklbw m2, m6
  742.     punpcklbw m3, m6
  743.     pmullw    m0, m4
  744.     pmullw    m1, m5
  745.     pmullw    m2, m4
  746.     pmullw    m3, m5
  747.     paddsw    m0, m1
  748.     paddsw    m2, m3
  749.     psraw     m0, 2
  750.     psraw     m2, 2
  751.     pavgw     m0, m6
  752.     pavgw     m2, m6
  753. %if mmsize == 8
  754.     packuswb  m0, m0
  755.     packuswb  m2, m2
  756.     movh   [dstq+dststrideq*0], m0
  757.     movh   [dstq+dststrideq*1], m2
  758. %else
  759.     packuswb  m0, m2
  760.     movh   [dstq+dststrideq*0], m0
  761.     movhps [dstq+dststrideq*1], m0
  762. %endif
  763.  
  764.     lea     dstq, [dstq+dststrideq*2]
  765.     lea     srcq, [srcq+srcstrideq*2]
  766.     sub  heightd, 2
  767.     jg .nextrow
  768.     REP_RET
  769. %endmacro
  770.  
  771. INIT_MMX mmxext
  772. FILTER_BILINEAR 4
  773. INIT_XMM sse2
  774. FILTER_BILINEAR 8
  775.  
  776. %macro FILTER_BILINEAR_SSSE3 1
  777. cglobal put_vp8_bilinear%1_v, 7, 7, 5, dst, dststride, src, srcstride, height, picreg, my
  778.     shl      myd, 4
  779. %ifdef PIC
  780.     lea  picregq, [bilinear_filter_vb_m]
  781. %endif
  782.     pxor      m4, m4
  783.     mova      m3, [bilinear_filter_vb+myq-16]
  784. .nextrow:
  785.     movh      m0, [srcq+srcstrideq*0]
  786.     movh      m1, [srcq+srcstrideq*1]
  787.     movh      m2, [srcq+srcstrideq*2]
  788.     punpcklbw m0, m1
  789.     punpcklbw m1, m2
  790.     pmaddubsw m0, m3
  791.     pmaddubsw m1, m3
  792.     psraw     m0, 2
  793.     psraw     m1, 2
  794.     pavgw     m0, m4
  795.     pavgw     m1, m4
  796. %if mmsize==8
  797.     packuswb  m0, m0
  798.     packuswb  m1, m1
  799.     movh   [dstq+dststrideq*0], m0
  800.     movh   [dstq+dststrideq*1], m1
  801. %else
  802.     packuswb  m0, m1
  803.     movh   [dstq+dststrideq*0], m0
  804.     movhps [dstq+dststrideq*1], m0
  805. %endif
  806.  
  807.     lea     dstq, [dstq+dststrideq*2]
  808.     lea     srcq, [srcq+srcstrideq*2]
  809.     sub  heightd, 2
  810.     jg .nextrow
  811.     REP_RET
  812.  
  813. cglobal put_vp8_bilinear%1_h, 6, 6 + npicregs, 5, dst, dststride, src, srcstride, height, mx, picreg
  814.     shl      mxd, 4
  815. %ifdef PIC
  816.     lea  picregq, [bilinear_filter_vb_m]
  817. %endif
  818.     pxor      m4, m4
  819.     mova      m2, [filter_h2_shuf]
  820.     mova      m3, [bilinear_filter_vb+mxq-16]
  821. .nextrow:
  822.     movu      m0, [srcq+srcstrideq*0]
  823.     movu      m1, [srcq+srcstrideq*1]
  824.     pshufb    m0, m2
  825.     pshufb    m1, m2
  826.     pmaddubsw m0, m3
  827.     pmaddubsw m1, m3
  828.     psraw     m0, 2
  829.     psraw     m1, 2
  830.     pavgw     m0, m4
  831.     pavgw     m1, m4
  832. %if mmsize==8
  833.     packuswb  m0, m0
  834.     packuswb  m1, m1
  835.     movh   [dstq+dststrideq*0], m0
  836.     movh   [dstq+dststrideq*1], m1
  837. %else
  838.     packuswb  m0, m1
  839.     movh   [dstq+dststrideq*0], m0
  840.     movhps [dstq+dststrideq*1], m0
  841. %endif
  842.  
  843.     lea     dstq, [dstq+dststrideq*2]
  844.     lea     srcq, [srcq+srcstrideq*2]
  845.     sub  heightd, 2
  846.     jg .nextrow
  847.     REP_RET
  848. %endmacro
  849.  
  850. INIT_MMX ssse3
  851. FILTER_BILINEAR_SSSE3 4
  852. INIT_XMM ssse3
  853. FILTER_BILINEAR_SSSE3 8
  854.  
  855. INIT_MMX mmx
  856. cglobal put_vp8_pixels8, 5, 5, 0, dst, dststride, src, srcstride, height
  857. .nextrow:
  858.     movq    mm0, [srcq+srcstrideq*0]
  859.     movq    mm1, [srcq+srcstrideq*1]
  860.     lea    srcq, [srcq+srcstrideq*2]
  861.     movq [dstq+dststrideq*0], mm0
  862.     movq [dstq+dststrideq*1], mm1
  863.     lea    dstq, [dstq+dststrideq*2]
  864.     sub heightd, 2
  865.     jg .nextrow
  866.     REP_RET
  867.  
  868. %if ARCH_X86_32
  869. INIT_MMX mmx
  870. cglobal put_vp8_pixels16, 5, 5, 0, dst, dststride, src, srcstride, height
  871. .nextrow:
  872.     movq    mm0, [srcq+srcstrideq*0+0]
  873.     movq    mm1, [srcq+srcstrideq*0+8]
  874.     movq    mm2, [srcq+srcstrideq*1+0]
  875.     movq    mm3, [srcq+srcstrideq*1+8]
  876.     lea    srcq, [srcq+srcstrideq*2]
  877.     movq [dstq+dststrideq*0+0], mm0
  878.     movq [dstq+dststrideq*0+8], mm1
  879.     movq [dstq+dststrideq*1+0], mm2
  880.     movq [dstq+dststrideq*1+8], mm3
  881.     lea    dstq, [dstq+dststrideq*2]
  882.     sub heightd, 2
  883.     jg .nextrow
  884.     REP_RET
  885. %endif
  886.  
  887. INIT_XMM sse
  888. cglobal put_vp8_pixels16, 5, 5, 2, dst, dststride, src, srcstride, height
  889. .nextrow:
  890.     movups xmm0, [srcq+srcstrideq*0]
  891.     movups xmm1, [srcq+srcstrideq*1]
  892.     lea    srcq, [srcq+srcstrideq*2]
  893.     movaps [dstq+dststrideq*0], xmm0
  894.     movaps [dstq+dststrideq*1], xmm1
  895.     lea    dstq, [dstq+dststrideq*2]
  896.     sub heightd, 2
  897.     jg .nextrow
  898.     REP_RET
  899.  
  900. ;-----------------------------------------------------------------------------
  901. ; void vp8_idct_dc_add_<opt>(uint8_t *dst, int16_t block[16], int stride);
  902. ;-----------------------------------------------------------------------------
  903.  
  904. %macro ADD_DC 4
  905.     %4        m2, [dst1q+%3]
  906.     %4        m3, [dst1q+strideq+%3]
  907.     %4        m4, [dst2q+%3]
  908.     %4        m5, [dst2q+strideq+%3]
  909.     paddusb   m2, %1
  910.     paddusb   m3, %1
  911.     paddusb   m4, %1
  912.     paddusb   m5, %1
  913.     psubusb   m2, %2
  914.     psubusb   m3, %2
  915.     psubusb   m4, %2
  916.     psubusb   m5, %2
  917.     %4 [dst1q+%3], m2
  918.     %4 [dst1q+strideq+%3], m3
  919.     %4 [dst2q+%3], m4
  920.     %4 [dst2q+strideq+%3], m5
  921. %endmacro
  922.  
  923. INIT_MMX mmx
  924. cglobal vp8_idct_dc_add, 3, 3, 0, dst, block, stride
  925.     ; load data
  926.     movd       m0, [blockq]
  927.  
  928.     ; calculate DC
  929.     paddw      m0, [pw_4]
  930.     pxor       m1, m1
  931.     psraw      m0, 3
  932.     movd [blockq], m1
  933.     psubw      m1, m0
  934.     packuswb   m0, m0
  935.     packuswb   m1, m1
  936.     punpcklbw  m0, m0
  937.     punpcklbw  m1, m1
  938.     punpcklwd  m0, m0
  939.     punpcklwd  m1, m1
  940.  
  941.     ; add DC
  942.     DEFINE_ARGS dst1, dst2, stride
  943.     lea     dst2q, [dst1q+strideq*2]
  944.     ADD_DC     m0, m1, 0, movh
  945.     RET
  946.  
  947. INIT_XMM sse4
  948. cglobal vp8_idct_dc_add, 3, 3, 6, dst, block, stride
  949.     ; load data
  950.     movd       m0, [blockq]
  951.     pxor       m1, m1
  952.  
  953.     ; calculate DC
  954.     paddw      m0, [pw_4]
  955.     movd [blockq], m1
  956.     DEFINE_ARGS dst1, dst2, stride
  957.     lea     dst2q, [dst1q+strideq*2]
  958.     movd       m2, [dst1q]
  959.     movd       m3, [dst1q+strideq]
  960.     movd       m4, [dst2q]
  961.     movd       m5, [dst2q+strideq]
  962.     psraw      m0, 3
  963.     pshuflw    m0, m0, 0
  964.     punpcklqdq m0, m0
  965.     punpckldq  m2, m3
  966.     punpckldq  m4, m5
  967.     punpcklbw  m2, m1
  968.     punpcklbw  m4, m1
  969.     paddw      m2, m0
  970.     paddw      m4, m0
  971.     packuswb   m2, m4
  972.     movd   [dst1q], m2
  973.     pextrd [dst1q+strideq], m2, 1
  974.     pextrd [dst2q], m2, 2
  975.     pextrd [dst2q+strideq], m2, 3
  976.     RET
  977.  
  978. ;-----------------------------------------------------------------------------
  979. ; void vp8_idct_dc_add4y_<opt>(uint8_t *dst, int16_t block[4][16], int stride);
  980. ;-----------------------------------------------------------------------------
  981.  
  982. %if ARCH_X86_32
  983. INIT_MMX mmx
  984. cglobal vp8_idct_dc_add4y, 3, 3, 0, dst, block, stride
  985.     ; load data
  986.     movd      m0, [blockq+32*0] ; A
  987.     movd      m1, [blockq+32*2] ; C
  988.     punpcklwd m0, [blockq+32*1] ; A B
  989.     punpcklwd m1, [blockq+32*3] ; C D
  990.     punpckldq m0, m1        ; A B C D
  991.     pxor      m6, m6
  992.  
  993.     ; calculate DC
  994.     paddw     m0, [pw_4]
  995.     movd [blockq+32*0], m6
  996.     movd [blockq+32*1], m6
  997.     movd [blockq+32*2], m6
  998.     movd [blockq+32*3], m6
  999.     psraw     m0, 3
  1000.     psubw     m6, m0
  1001.     packuswb  m0, m0
  1002.     packuswb  m6, m6
  1003.     punpcklbw m0, m0 ; AABBCCDD
  1004.     punpcklbw m6, m6 ; AABBCCDD
  1005.     movq      m1, m0
  1006.     movq      m7, m6
  1007.     punpcklbw m0, m0 ; AAAABBBB
  1008.     punpckhbw m1, m1 ; CCCCDDDD
  1009.     punpcklbw m6, m6 ; AAAABBBB
  1010.     punpckhbw m7, m7 ; CCCCDDDD
  1011.  
  1012.     ; add DC
  1013.     DEFINE_ARGS dst1, dst2, stride
  1014.     lea    dst2q, [dst1q+strideq*2]
  1015.     ADD_DC    m0, m6, 0, mova
  1016.     ADD_DC    m1, m7, 8, mova
  1017.     RET
  1018. %endif
  1019.  
  1020. INIT_XMM sse2
  1021. cglobal vp8_idct_dc_add4y, 3, 3, 6, dst, block, stride
  1022.     ; load data
  1023.     movd      m0, [blockq+32*0] ; A
  1024.     movd      m1, [blockq+32*2] ; C
  1025.     punpcklwd m0, [blockq+32*1] ; A B
  1026.     punpcklwd m1, [blockq+32*3] ; C D
  1027.     punpckldq m0, m1        ; A B C D
  1028.     pxor      m1, m1
  1029.  
  1030.     ; calculate DC
  1031.     paddw     m0, [pw_4]
  1032.     movd [blockq+32*0], m1
  1033.     movd [blockq+32*1], m1
  1034.     movd [blockq+32*2], m1
  1035.     movd [blockq+32*3], m1
  1036.     psraw     m0, 3
  1037.     psubw     m1, m0
  1038.     packuswb  m0, m0
  1039.     packuswb  m1, m1
  1040.     punpcklbw m0, m0
  1041.     punpcklbw m1, m1
  1042.     punpcklbw m0, m0
  1043.     punpcklbw m1, m1
  1044.  
  1045.     ; add DC
  1046.     DEFINE_ARGS dst1, dst2, stride
  1047.     lea    dst2q, [dst1q+strideq*2]
  1048.     ADD_DC    m0, m1, 0, mova
  1049.     RET
  1050.  
  1051. ;-----------------------------------------------------------------------------
  1052. ; void vp8_idct_dc_add4uv_<opt>(uint8_t *dst, int16_t block[4][16], int stride);
  1053. ;-----------------------------------------------------------------------------
  1054.  
  1055. INIT_MMX mmx
  1056. cglobal vp8_idct_dc_add4uv, 3, 3, 0, dst, block, stride
  1057.     ; load data
  1058.     movd      m0, [blockq+32*0] ; A
  1059.     movd      m1, [blockq+32*2] ; C
  1060.     punpcklwd m0, [blockq+32*1] ; A B
  1061.     punpcklwd m1, [blockq+32*3] ; C D
  1062.     punpckldq m0, m1        ; A B C D
  1063.     pxor      m6, m6
  1064.  
  1065.     ; calculate DC
  1066.     paddw     m0, [pw_4]
  1067.     movd [blockq+32*0], m6
  1068.     movd [blockq+32*1], m6
  1069.     movd [blockq+32*2], m6
  1070.     movd [blockq+32*3], m6
  1071.     psraw     m0, 3
  1072.     psubw     m6, m0
  1073.     packuswb  m0, m0
  1074.     packuswb  m6, m6
  1075.     punpcklbw m0, m0 ; AABBCCDD
  1076.     punpcklbw m6, m6 ; AABBCCDD
  1077.     movq      m1, m0
  1078.     movq      m7, m6
  1079.     punpcklbw m0, m0 ; AAAABBBB
  1080.     punpckhbw m1, m1 ; CCCCDDDD
  1081.     punpcklbw m6, m6 ; AAAABBBB
  1082.     punpckhbw m7, m7 ; CCCCDDDD
  1083.  
  1084.     ; add DC
  1085.     DEFINE_ARGS dst1, dst2, stride
  1086.     lea    dst2q, [dst1q+strideq*2]
  1087.     ADD_DC    m0, m6, 0, mova
  1088.     lea    dst1q, [dst1q+strideq*4]
  1089.     lea    dst2q, [dst2q+strideq*4]
  1090.     ADD_DC    m1, m7, 0, mova
  1091.     RET
  1092.  
  1093. ;-----------------------------------------------------------------------------
  1094. ; void vp8_idct_add_<opt>(uint8_t *dst, int16_t block[16], int stride);
  1095. ;-----------------------------------------------------------------------------
  1096.  
  1097. ; calculate %1=mul_35468(%1)-mul_20091(%2); %2=mul_20091(%1)+mul_35468(%2)
  1098. ;           this macro assumes that m6/m7 have words for 20091/17734 loaded
  1099. %macro VP8_MULTIPLY_SUMSUB 4
  1100.     mova      %3, %1
  1101.     mova      %4, %2
  1102.     pmulhw    %3, m6 ;20091(1)
  1103.     pmulhw    %4, m6 ;20091(2)
  1104.     paddw     %3, %1
  1105.     paddw     %4, %2
  1106.     paddw     %1, %1
  1107.     paddw     %2, %2
  1108.     pmulhw    %1, m7 ;35468(1)
  1109.     pmulhw    %2, m7 ;35468(2)
  1110.     psubw     %1, %4
  1111.     paddw     %2, %3
  1112. %endmacro
  1113.  
  1114. ; calculate x0=%1+%3; x1=%1-%3
  1115. ;           x2=mul_35468(%2)-mul_20091(%4); x3=mul_20091(%2)+mul_35468(%4)
  1116. ;           %1=x0+x3 (tmp0); %2=x1+x2 (tmp1); %3=x1-x2 (tmp2); %4=x0-x3 (tmp3)
  1117. ;           %5/%6 are temporary registers
  1118. ;           we assume m6/m7 have constant words 20091/17734 loaded in them
  1119. %macro VP8_IDCT_TRANSFORM4x4_1D 6
  1120.     SUMSUB_BA         w, %3,  %1,  %5     ;t0, t1
  1121.     VP8_MULTIPLY_SUMSUB m%2, m%4, m%5,m%6 ;t2, t3
  1122.     SUMSUB_BA         w, %4,  %3,  %5     ;tmp0, tmp3
  1123.     SUMSUB_BA         w, %2,  %1,  %5     ;tmp1, tmp2
  1124.     SWAP                 %4,  %1
  1125.     SWAP                 %4,  %3
  1126. %endmacro
  1127.  
  1128. %macro VP8_IDCT_ADD 0
  1129. cglobal vp8_idct_add, 3, 3, 0, dst, block, stride
  1130.     ; load block data
  1131.     movq         m0, [blockq+ 0]
  1132.     movq         m1, [blockq+ 8]
  1133.     movq         m2, [blockq+16]
  1134.     movq         m3, [blockq+24]
  1135.     movq         m6, [pw_20091]
  1136.     movq         m7, [pw_17734]
  1137. %if cpuflag(sse)
  1138.     xorps      xmm0, xmm0
  1139.     movaps [blockq+ 0], xmm0
  1140.     movaps [blockq+16], xmm0
  1141. %else
  1142.     pxor         m4, m4
  1143.     movq [blockq+ 0], m4
  1144.     movq [blockq+ 8], m4
  1145.     movq [blockq+16], m4
  1146.     movq [blockq+24], m4
  1147. %endif
  1148.  
  1149.     ; actual IDCT
  1150.     VP8_IDCT_TRANSFORM4x4_1D 0, 1, 2, 3, 4, 5
  1151.     TRANSPOSE4x4W            0, 1, 2, 3, 4
  1152.     paddw        m0, [pw_4]
  1153.     VP8_IDCT_TRANSFORM4x4_1D 0, 1, 2, 3, 4, 5
  1154.     TRANSPOSE4x4W            0, 1, 2, 3, 4
  1155.  
  1156.     ; store
  1157.     pxor         m4, m4
  1158.     DEFINE_ARGS dst1, dst2, stride
  1159.     lea       dst2q, [dst1q+2*strideq]
  1160.     STORE_DIFFx2 m0, m1, m6, m7, m4, 3, dst1q, strideq
  1161.     STORE_DIFFx2 m2, m3, m6, m7, m4, 3, dst2q, strideq
  1162.  
  1163.     RET
  1164. %endmacro
  1165.  
  1166. %if ARCH_X86_32
  1167. INIT_MMX mmx
  1168. VP8_IDCT_ADD
  1169. %endif
  1170. INIT_MMX sse
  1171. VP8_IDCT_ADD
  1172.  
  1173. ;-----------------------------------------------------------------------------
  1174. ; void vp8_luma_dc_wht_mmxext(int16_t block[4][4][16], int16_t dc[16])
  1175. ;-----------------------------------------------------------------------------
  1176.  
  1177. %macro SCATTER_WHT 3
  1178.     movd dc1d, m%1
  1179.     movd dc2d, m%2
  1180.     mov [blockq+2*16*(0+%3)], dc1w
  1181.     mov [blockq+2*16*(1+%3)], dc2w
  1182.     shr  dc1d, 16
  1183.     shr  dc2d, 16
  1184.     psrlq m%1, 32
  1185.     psrlq m%2, 32
  1186.     mov [blockq+2*16*(4+%3)], dc1w
  1187.     mov [blockq+2*16*(5+%3)], dc2w
  1188.     movd dc1d, m%1
  1189.     movd dc2d, m%2
  1190.     mov [blockq+2*16*(8+%3)], dc1w
  1191.     mov [blockq+2*16*(9+%3)], dc2w
  1192.     shr  dc1d, 16
  1193.     shr  dc2d, 16
  1194.     mov [blockq+2*16*(12+%3)], dc1w
  1195.     mov [blockq+2*16*(13+%3)], dc2w
  1196. %endmacro
  1197.  
  1198. %macro HADAMARD4_1D 4
  1199.     SUMSUB_BADC w, %2, %1, %4, %3
  1200.     SUMSUB_BADC w, %4, %2, %3, %1
  1201.     SWAP %1, %4, %3
  1202. %endmacro
  1203.  
  1204. %macro VP8_DC_WHT 0
  1205. cglobal vp8_luma_dc_wht, 2, 3, 0, block, dc1, dc2
  1206.     movq          m0, [dc1q]
  1207.     movq          m1, [dc1q+8]
  1208.     movq          m2, [dc1q+16]
  1209.     movq          m3, [dc1q+24]
  1210. %if cpuflag(sse)
  1211.     xorps      xmm0, xmm0
  1212.     movaps [dc1q+ 0], xmm0
  1213.     movaps [dc1q+16], xmm0
  1214. %else
  1215.     pxor         m4, m4
  1216.     movq  [dc1q+ 0], m4
  1217.     movq  [dc1q+ 8], m4
  1218.     movq  [dc1q+16], m4
  1219.     movq  [dc1q+24], m4
  1220. %endif
  1221.     HADAMARD4_1D  0, 1, 2, 3
  1222.     TRANSPOSE4x4W 0, 1, 2, 3, 4
  1223.     paddw         m0, [pw_3]
  1224.     HADAMARD4_1D  0, 1, 2, 3
  1225.     psraw         m0, 3
  1226.     psraw         m1, 3
  1227.     psraw         m2, 3
  1228.     psraw         m3, 3
  1229.     SCATTER_WHT   0, 1, 0
  1230.     SCATTER_WHT   2, 3, 2
  1231.     RET
  1232. %endmacro
  1233.  
  1234. %if ARCH_X86_32
  1235. INIT_MMX mmx
  1236. VP8_DC_WHT
  1237. %endif
  1238. INIT_MMX sse
  1239. VP8_DC_WHT
  1240.  
  1241. ;-----------------------------------------------------------------------------
  1242. ; void vp8_h/v_loop_filter_simple_<opt>(uint8_t *dst, int stride, int flim);
  1243. ;-----------------------------------------------------------------------------
  1244.  
  1245. ; macro called with 7 mm register indexes as argument, and 4 regular registers
  1246. ;
  1247. ; first 4 mm registers will carry the transposed pixel data
  1248. ; the other three are scratchspace (one would be sufficient, but this allows
  1249. ; for more spreading/pipelining and thus faster execution on OOE CPUs)
  1250. ;
  1251. ; first two regular registers are buf+4*stride and buf+5*stride
  1252. ; third is -stride, fourth is +stride
  1253. %macro READ_8x4_INTERLEAVED 11
  1254.     ; interleave 8 (A-H) rows of 4 pixels each
  1255.     movd          m%1, [%8+%10*4]   ; A0-3
  1256.     movd          m%5, [%9+%10*4]   ; B0-3
  1257.     movd          m%2, [%8+%10*2]   ; C0-3
  1258.     movd          m%6, [%8+%10]     ; D0-3
  1259.     movd          m%3, [%8]         ; E0-3
  1260.     movd          m%7, [%9]         ; F0-3
  1261.     movd          m%4, [%9+%11]     ; G0-3
  1262.     punpcklbw     m%1, m%5          ; A/B interleaved
  1263.     movd          m%5, [%9+%11*2]   ; H0-3
  1264.     punpcklbw     m%2, m%6          ; C/D interleaved
  1265.     punpcklbw     m%3, m%7          ; E/F interleaved
  1266.     punpcklbw     m%4, m%5          ; G/H interleaved
  1267. %endmacro
  1268.  
  1269. ; macro called with 7 mm register indexes as argument, and 5 regular registers
  1270. ; first 11 mean the same as READ_8x4_TRANSPOSED above
  1271. ; fifth regular register is scratchspace to reach the bottom 8 rows, it
  1272. ; will be set to second regular register + 8*stride at the end
  1273. %macro READ_16x4_INTERLEAVED 12
  1274.     ; transpose 16 (A-P) rows of 4 pixels each
  1275.     lea           %12, [r0+8*r2]
  1276.  
  1277.     ; read (and interleave) those addressable by %8 (=r0), A/C/D/E/I/K/L/M
  1278.     movd          m%1, [%8+%10*4]   ; A0-3
  1279.     movd          m%3, [%12+%10*4]  ; I0-3
  1280.     movd          m%2, [%8+%10*2]   ; C0-3
  1281.     movd          m%4, [%12+%10*2]  ; K0-3
  1282.     movd          m%6, [%8+%10]     ; D0-3
  1283.     movd          m%5, [%12+%10]    ; L0-3
  1284.     movd          m%7, [%12]        ; M0-3
  1285.     add           %12, %11
  1286.     punpcklbw     m%1, m%3          ; A/I
  1287.     movd          m%3, [%8]         ; E0-3
  1288.     punpcklbw     m%2, m%4          ; C/K
  1289.     punpcklbw     m%6, m%5          ; D/L
  1290.     punpcklbw     m%3, m%7          ; E/M
  1291.     punpcklbw     m%2, m%6          ; C/D/K/L interleaved
  1292.  
  1293.     ; read (and interleave) those addressable by %9 (=r4), B/F/G/H/J/N/O/P
  1294.     movd         m%5, [%9+%10*4]   ; B0-3
  1295.     movd         m%4, [%12+%10*4]  ; J0-3
  1296.     movd         m%7, [%9]         ; F0-3
  1297.     movd         m%6, [%12]        ; N0-3
  1298.     punpcklbw    m%5, m%4          ; B/J
  1299.     punpcklbw    m%7, m%6          ; F/N
  1300.     punpcklbw    m%1, m%5          ; A/B/I/J interleaved
  1301.     punpcklbw    m%3, m%7          ; E/F/M/N interleaved
  1302.     movd         m%4, [%9+%11]     ; G0-3
  1303.     movd         m%6, [%12+%11]    ; O0-3
  1304.     movd         m%5, [%9+%11*2]   ; H0-3
  1305.     movd         m%7, [%12+%11*2]  ; P0-3
  1306.     punpcklbw    m%4, m%6          ; G/O
  1307.     punpcklbw    m%5, m%7          ; H/P
  1308.     punpcklbw    m%4, m%5          ; G/H/O/P interleaved
  1309. %endmacro
  1310.  
  1311. ; write 4 mm registers of 2 dwords each
  1312. ; first four arguments are mm register indexes containing source data
  1313. ; last four are registers containing buf+4*stride, buf+5*stride,
  1314. ; -stride and +stride
  1315. %macro WRITE_4x2D 8
  1316.     ; write out (2 dwords per register)
  1317.     movd    [%5+%7*4], m%1
  1318.     movd    [%5+%7*2], m%2
  1319.     movd         [%5], m%3
  1320.     movd      [%6+%8], m%4
  1321.     punpckhdq     m%1, m%1
  1322.     punpckhdq     m%2, m%2
  1323.     punpckhdq     m%3, m%3
  1324.     punpckhdq     m%4, m%4
  1325.     movd    [%6+%7*4], m%1
  1326.     movd      [%5+%7], m%2
  1327.     movd         [%6], m%3
  1328.     movd    [%6+%8*2], m%4
  1329. %endmacro
  1330.  
  1331. ; write 4 xmm registers of 4 dwords each
  1332. ; arguments same as WRITE_2x4D, but with an extra register, so that the 5 regular
  1333. ; registers contain buf+4*stride, buf+5*stride, buf+12*stride, -stride and +stride
  1334. ; we add 1*stride to the third regular registry in the process
  1335. ; the 10th argument is 16 if it's a Y filter (i.e. all regular registers cover the
  1336. ; same memory region), or 8 if they cover two separate buffers (third one points to
  1337. ; a different memory region than the first two), allowing for more optimal code for
  1338. ; the 16-width case
  1339. %macro WRITE_4x4D 10
  1340.     ; write out (4 dwords per register), start with dwords zero
  1341.     movd    [%5+%8*4], m%1
  1342.     movd         [%5], m%2
  1343.     movd    [%7+%8*4], m%3
  1344.     movd         [%7], m%4
  1345.  
  1346.     ; store dwords 1
  1347.     psrldq        m%1, 4
  1348.     psrldq        m%2, 4
  1349.     psrldq        m%3, 4
  1350.     psrldq        m%4, 4
  1351.     movd    [%6+%8*4], m%1
  1352.     movd         [%6], m%2
  1353. %if %10 == 16
  1354.     movd    [%6+%9*4], m%3
  1355. %endif
  1356.     movd      [%7+%9], m%4
  1357.  
  1358.     ; write dwords 2
  1359.     psrldq        m%1, 4
  1360.     psrldq        m%2, 4
  1361. %if %10 == 8
  1362.     movd    [%5+%8*2], m%1
  1363.     movd          %5d, m%3
  1364. %endif
  1365.     psrldq        m%3, 4
  1366.     psrldq        m%4, 4
  1367. %if %10 == 16
  1368.     movd    [%5+%8*2], m%1
  1369. %endif
  1370.     movd      [%6+%9], m%2
  1371.     movd    [%7+%8*2], m%3
  1372.     movd    [%7+%9*2], m%4
  1373.     add            %7, %9
  1374.  
  1375.     ; store dwords 3
  1376.     psrldq        m%1, 4
  1377.     psrldq        m%2, 4
  1378.     psrldq        m%3, 4
  1379.     psrldq        m%4, 4
  1380. %if %10 == 8
  1381.     mov     [%7+%8*4], %5d
  1382.     movd    [%6+%8*2], m%1
  1383. %else
  1384.     movd      [%5+%8], m%1
  1385. %endif
  1386.     movd    [%6+%9*2], m%2
  1387.     movd    [%7+%8*2], m%3
  1388.     movd    [%7+%9*2], m%4
  1389. %endmacro
  1390.  
  1391. ; write 4 or 8 words in the mmx/xmm registers as 8 lines
  1392. ; 1 and 2 are the registers to write, this can be the same (for SSE2)
  1393. ; for pre-SSE4:
  1394. ; 3 is a general-purpose register that we will clobber
  1395. ; for SSE4:
  1396. ; 3 is a pointer to the destination's 5th line
  1397. ; 4 is a pointer to the destination's 4th line
  1398. ; 5/6 is -stride and +stride
  1399. %macro WRITE_2x4W 6
  1400.     movd            %3d, %1
  1401.     punpckhdq        %1, %1
  1402.     mov       [%4+%5*4], %3w
  1403.     shr              %3, 16
  1404.     add              %4, %6
  1405.     mov       [%4+%5*4], %3w
  1406.  
  1407.     movd            %3d, %1
  1408.     add              %4, %5
  1409.     mov       [%4+%5*2], %3w
  1410.     shr              %3, 16
  1411.     mov       [%4+%5  ], %3w
  1412.  
  1413.     movd            %3d, %2
  1414.     punpckhdq        %2, %2
  1415.     mov       [%4     ], %3w
  1416.     shr              %3, 16
  1417.     mov       [%4+%6  ], %3w
  1418.  
  1419.     movd            %3d, %2
  1420.     add              %4, %6
  1421.     mov       [%4+%6  ], %3w
  1422.     shr              %3, 16
  1423.     mov       [%4+%6*2], %3w
  1424.     add              %4, %5
  1425. %endmacro
  1426.  
  1427. %macro WRITE_8W 5
  1428. %if cpuflag(sse4)
  1429.     pextrw    [%3+%4*4], %1, 0
  1430.     pextrw    [%2+%4*4], %1, 1
  1431.     pextrw    [%3+%4*2], %1, 2
  1432.     pextrw    [%3+%4  ], %1, 3
  1433.     pextrw    [%3     ], %1, 4
  1434.     pextrw    [%2     ], %1, 5
  1435.     pextrw    [%2+%5  ], %1, 6
  1436.     pextrw    [%2+%5*2], %1, 7
  1437. %else
  1438.     movd            %2d, %1
  1439.     psrldq           %1, 4
  1440.     mov       [%3+%4*4], %2w
  1441.     shr              %2, 16
  1442.     add              %3, %5
  1443.     mov       [%3+%4*4], %2w
  1444.  
  1445.     movd            %2d, %1
  1446.     psrldq           %1, 4
  1447.     add              %3, %4
  1448.     mov       [%3+%4*2], %2w
  1449.     shr              %2, 16
  1450.     mov       [%3+%4  ], %2w
  1451.  
  1452.     movd            %2d, %1
  1453.     psrldq           %1, 4
  1454.     mov       [%3     ], %2w
  1455.     shr              %2, 16
  1456.     mov       [%3+%5  ], %2w
  1457.  
  1458.     movd            %2d, %1
  1459.     add              %3, %5
  1460.     mov       [%3+%5  ], %2w
  1461.     shr              %2, 16
  1462.     mov       [%3+%5*2], %2w
  1463. %endif
  1464. %endmacro
  1465.  
  1466. %macro SIMPLE_LOOPFILTER 2
  1467. cglobal vp8_%1_loop_filter_simple, 3, %2, 8, dst, stride, flim, cntr
  1468. %if mmsize == 8 ; mmx/mmxext
  1469.     mov         cntrq, 2
  1470. %endif
  1471. %if cpuflag(ssse3)
  1472.     pxor           m0, m0
  1473. %endif
  1474.     SPLATB_REG     m7, flim, m0     ; splat "flim" into register
  1475.  
  1476.     ; set up indexes to address 4 rows
  1477. %if mmsize == 8
  1478.     DEFINE_ARGS dst1, mstride, stride, cntr, dst2
  1479. %else
  1480.     DEFINE_ARGS dst1, mstride, stride, dst3, dst2
  1481. %endif
  1482.     mov       strideq, mstrideq
  1483.     neg      mstrideq
  1484. %ifidn %1, h
  1485.     lea         dst1q, [dst1q+4*strideq-2]
  1486. %endif
  1487.  
  1488. %if mmsize == 8 ; mmx / mmxext
  1489. .next8px:
  1490. %endif
  1491. %ifidn %1, v
  1492.     ; read 4 half/full rows of pixels
  1493.     mova           m0, [dst1q+mstrideq*2]    ; p1
  1494.     mova           m1, [dst1q+mstrideq]      ; p0
  1495.     mova           m2, [dst1q]               ; q0
  1496.     mova           m3, [dst1q+ strideq]      ; q1
  1497. %else ; h
  1498.     lea         dst2q, [dst1q+ strideq]
  1499.  
  1500. %if mmsize == 8 ; mmx/mmxext
  1501.     READ_8x4_INTERLEAVED  0, 1, 2, 3, 4, 5, 6, dst1q, dst2q, mstrideq, strideq
  1502. %else ; sse2
  1503.     READ_16x4_INTERLEAVED 0, 1, 2, 3, 4, 5, 6, dst1q, dst2q, mstrideq, strideq, dst3q
  1504. %endif
  1505.     TRANSPOSE4x4W         0, 1, 2, 3, 4
  1506. %endif
  1507.  
  1508.     ; simple_limit
  1509.     mova           m5, m2           ; m5=backup of q0
  1510.     mova           m6, m1           ; m6=backup of p0
  1511.     psubusb        m1, m2           ; p0-q0
  1512.     psubusb        m2, m6           ; q0-p0
  1513.     por            m1, m2           ; FFABS(p0-q0)
  1514.     paddusb        m1, m1           ; m1=FFABS(p0-q0)*2
  1515.  
  1516.     mova           m4, m3
  1517.     mova           m2, m0
  1518.     psubusb        m3, m0           ; q1-p1
  1519.     psubusb        m0, m4           ; p1-q1
  1520.     por            m3, m0           ; FFABS(p1-q1)
  1521.     mova           m0, [pb_80]
  1522.     pxor           m2, m0
  1523.     pxor           m4, m0
  1524.     psubsb         m2, m4           ; m2=p1-q1 (signed) backup for below
  1525.     pand           m3, [pb_FE]
  1526.     psrlq          m3, 1            ; m3=FFABS(p1-q1)/2, this can be used signed
  1527.     paddusb        m3, m1
  1528.     psubusb        m3, m7
  1529.     pxor           m1, m1
  1530.     pcmpeqb        m3, m1           ; abs(p0-q0)*2+abs(p1-q1)/2<=flim mask(0xff/0x0)
  1531.  
  1532.     ; filter_common (use m2/p1-q1, m4=q0, m6=p0, m5/q0-p0 and m3/mask)
  1533.     mova           m4, m5
  1534.     pxor           m5, m0
  1535.     pxor           m0, m6
  1536.     psubsb         m5, m0           ; q0-p0 (signed)
  1537.     paddsb         m2, m5
  1538.     paddsb         m2, m5
  1539.     paddsb         m2, m5           ; a=(p1-q1) + 3*(q0-p0)
  1540.     pand           m2, m3           ; apply filter mask (m3)
  1541.  
  1542.     mova           m3, [pb_F8]
  1543.     mova           m1, m2
  1544.     paddsb         m2, [pb_4]       ; f1<<3=a+4
  1545.     paddsb         m1, [pb_3]       ; f2<<3=a+3
  1546.     pand           m2, m3
  1547.     pand           m1, m3           ; cache f2<<3
  1548.  
  1549.     pxor           m0, m0
  1550.     pxor           m3, m3
  1551.     pcmpgtb        m0, m2           ; which values are <0?
  1552.     psubb          m3, m2           ; -f1<<3
  1553.     psrlq          m2, 3            ; +f1
  1554.     psrlq          m3, 3            ; -f1
  1555.     pand           m3, m0
  1556.     pandn          m0, m2
  1557.     psubusb        m4, m0
  1558.     paddusb        m4, m3           ; q0-f1
  1559.  
  1560.     pxor           m0, m0
  1561.     pxor           m3, m3
  1562.     pcmpgtb        m0, m1           ; which values are <0?
  1563.     psubb          m3, m1           ; -f2<<3
  1564.     psrlq          m1, 3            ; +f2
  1565.     psrlq          m3, 3            ; -f2
  1566.     pand           m3, m0
  1567.     pandn          m0, m1
  1568.     paddusb        m6, m0
  1569.     psubusb        m6, m3           ; p0+f2
  1570.  
  1571.     ; store
  1572. %ifidn %1, v
  1573.     mova      [dst1q], m4
  1574.     mova [dst1q+mstrideq], m6
  1575. %else ; h
  1576.     inc        dst1q
  1577.     SBUTTERFLY    bw, 6, 4, 0
  1578.  
  1579. %if mmsize == 16 ; sse2
  1580. %if cpuflag(sse4)
  1581.     inc         dst2q
  1582. %endif
  1583.     WRITE_8W       m6, dst2q, dst1q, mstrideq, strideq
  1584.     lea         dst2q, [dst3q+mstrideq+1]
  1585. %if cpuflag(sse4)
  1586.     inc         dst3q
  1587. %endif
  1588.     WRITE_8W       m4, dst3q, dst2q, mstrideq, strideq
  1589. %else ; mmx/mmxext
  1590.     WRITE_2x4W     m6, m4, dst2q, dst1q, mstrideq, strideq
  1591. %endif
  1592. %endif
  1593.  
  1594. %if mmsize == 8 ; mmx/mmxext
  1595.     ; next 8 pixels
  1596. %ifidn %1, v
  1597.     add         dst1q, 8            ; advance 8 cols = pixels
  1598. %else ; h
  1599.     lea         dst1q, [dst1q+strideq*8-1]  ; advance 8 rows = lines
  1600. %endif
  1601.     dec         cntrq
  1602.     jg .next8px
  1603.     REP_RET
  1604. %else ; sse2
  1605.     RET
  1606. %endif
  1607. %endmacro
  1608.  
  1609. %if ARCH_X86_32
  1610. INIT_MMX mmx
  1611. SIMPLE_LOOPFILTER v, 4
  1612. SIMPLE_LOOPFILTER h, 5
  1613. INIT_MMX mmxext
  1614. SIMPLE_LOOPFILTER v, 4
  1615. SIMPLE_LOOPFILTER h, 5
  1616. %endif
  1617.  
  1618. INIT_XMM sse2
  1619. SIMPLE_LOOPFILTER v, 3
  1620. SIMPLE_LOOPFILTER h, 5
  1621. INIT_XMM ssse3
  1622. SIMPLE_LOOPFILTER v, 3
  1623. SIMPLE_LOOPFILTER h, 5
  1624. INIT_XMM sse4
  1625. SIMPLE_LOOPFILTER h, 5
  1626.  
  1627. ;-----------------------------------------------------------------------------
  1628. ; void vp8_h/v_loop_filter<size>_inner_<opt>(uint8_t *dst, [uint8_t *v,] int stride,
  1629. ;                                            int flimE, int flimI, int hev_thr);
  1630. ;-----------------------------------------------------------------------------
  1631.  
  1632. %macro INNER_LOOPFILTER 2
  1633. %define stack_size 0
  1634. %ifndef m8   ; stack layout: [0]=E, [1]=I, [2]=hev_thr
  1635. %ifidn %1, v ;               [3]=hev() result
  1636. %define stack_size mmsize * -4
  1637. %else ; h    ; extra storage space for transposes
  1638. %define stack_size mmsize * -5
  1639. %endif
  1640. %endif
  1641.  
  1642. %if %2 == 8 ; chroma
  1643. cglobal vp8_%1_loop_filter8uv_inner, 6, 6, 13, stack_size, dst, dst8, stride, flimE, flimI, hevthr
  1644. %else ; luma
  1645. cglobal vp8_%1_loop_filter16y_inner, 5, 5, 13, stack_size, dst, stride, flimE, flimI, hevthr
  1646. %endif
  1647.  
  1648. %if cpuflag(ssse3)
  1649.     pxor             m7, m7
  1650. %endif
  1651.  
  1652. %ifndef m8
  1653.     ; splat function arguments
  1654.     SPLATB_REG       m0, flimEq, m7   ; E
  1655.     SPLATB_REG       m1, flimIq, m7   ; I
  1656.     SPLATB_REG       m2, hevthrq, m7  ; hev_thresh
  1657.  
  1658. %define m_flimE    [rsp]
  1659. %define m_flimI    [rsp+mmsize]
  1660. %define m_hevthr   [rsp+mmsize*2]
  1661. %define m_maskres  [rsp+mmsize*3]
  1662. %define m_p0backup [rsp+mmsize*3]
  1663. %define m_q0backup [rsp+mmsize*4]
  1664.  
  1665.     mova        m_flimE, m0
  1666.     mova        m_flimI, m1
  1667.     mova       m_hevthr, m2
  1668. %else
  1669. %define m_flimE    m9
  1670. %define m_flimI    m10
  1671. %define m_hevthr   m11
  1672. %define m_maskres  m12
  1673. %define m_p0backup m12
  1674. %define m_q0backup m8
  1675.  
  1676.     ; splat function arguments
  1677.     SPLATB_REG  m_flimE, flimEq, m7   ; E
  1678.     SPLATB_REG  m_flimI, flimIq, m7   ; I
  1679.     SPLATB_REG m_hevthr, hevthrq, m7  ; hev_thresh
  1680. %endif
  1681.  
  1682. %if %2 == 8 ; chroma
  1683.     DEFINE_ARGS dst1, dst8, mstride, stride, dst2
  1684. %elif mmsize == 8
  1685.     DEFINE_ARGS dst1, mstride, stride, dst2, cntr
  1686.     mov           cntrq, 2
  1687. %else
  1688.     DEFINE_ARGS dst1, mstride, stride, dst2, dst8
  1689. %endif
  1690.     mov         strideq, mstrideq
  1691.     neg        mstrideq
  1692. %ifidn %1, h
  1693.     lea           dst1q, [dst1q+strideq*4-4]
  1694. %if %2 == 8 ; chroma
  1695.     lea           dst8q, [dst8q+strideq*4-4]
  1696. %endif
  1697. %endif
  1698.  
  1699. %if mmsize == 8
  1700. .next8px:
  1701. %endif
  1702.     ; read
  1703.     lea           dst2q, [dst1q+strideq]
  1704. %ifidn %1, v
  1705. %if %2 == 8 && mmsize == 16
  1706. %define movrow movh
  1707. %else
  1708. %define movrow mova
  1709. %endif
  1710.     movrow           m0, [dst1q+mstrideq*4] ; p3
  1711.     movrow           m1, [dst2q+mstrideq*4] ; p2
  1712.     movrow           m2, [dst1q+mstrideq*2] ; p1
  1713.     movrow           m5, [dst2q]            ; q1
  1714.     movrow           m6, [dst2q+ strideq*1] ; q2
  1715.     movrow           m7, [dst2q+ strideq*2] ; q3
  1716. %if mmsize == 16 && %2 == 8
  1717.     movhps           m0, [dst8q+mstrideq*4]
  1718.     movhps           m2, [dst8q+mstrideq*2]
  1719.     add           dst8q, strideq
  1720.     movhps           m1, [dst8q+mstrideq*4]
  1721.     movhps           m5, [dst8q]
  1722.     movhps           m6, [dst8q+ strideq  ]
  1723.     movhps           m7, [dst8q+ strideq*2]
  1724.     add           dst8q, mstrideq
  1725. %endif
  1726. %elif mmsize == 8 ; mmx/mmxext (h)
  1727.     ; read 8 rows of 8px each
  1728.     movu             m0, [dst1q+mstrideq*4]
  1729.     movu             m1, [dst2q+mstrideq*4]
  1730.     movu             m2, [dst1q+mstrideq*2]
  1731.     movu             m3, [dst1q+mstrideq  ]
  1732.     movu             m4, [dst1q]
  1733.     movu             m5, [dst2q]
  1734.     movu             m6, [dst2q+ strideq  ]
  1735.  
  1736.     ; 8x8 transpose
  1737.     TRANSPOSE4x4B     0, 1, 2, 3, 7
  1738.     mova     m_q0backup, m1
  1739.     movu             m7, [dst2q+ strideq*2]
  1740.     TRANSPOSE4x4B     4, 5, 6, 7, 1
  1741.     SBUTTERFLY       dq, 0, 4, 1     ; p3/p2
  1742.     SBUTTERFLY       dq, 2, 6, 1     ; q0/q1
  1743.     SBUTTERFLY       dq, 3, 7, 1     ; q2/q3
  1744.     mova             m1, m_q0backup
  1745.     mova     m_q0backup, m2          ; store q0
  1746.     SBUTTERFLY       dq, 1, 5, 2     ; p1/p0
  1747.     mova     m_p0backup, m5          ; store p0
  1748.     SWAP              1, 4
  1749.     SWAP              2, 4
  1750.     SWAP              6, 3
  1751.     SWAP              5, 3
  1752. %else ; sse2 (h)
  1753. %if %2 == 16
  1754.     lea           dst8q, [dst1q+ strideq*8]
  1755. %endif
  1756.  
  1757.     ; read 16 rows of 8px each, interleave
  1758.     movh             m0, [dst1q+mstrideq*4]
  1759.     movh             m1, [dst8q+mstrideq*4]
  1760.     movh             m2, [dst1q+mstrideq*2]
  1761.     movh             m5, [dst8q+mstrideq*2]
  1762.     movh             m3, [dst1q+mstrideq  ]
  1763.     movh             m6, [dst8q+mstrideq  ]
  1764.     movh             m4, [dst1q]
  1765.     movh             m7, [dst8q]
  1766.     punpcklbw        m0, m1          ; A/I
  1767.     punpcklbw        m2, m5          ; C/K
  1768.     punpcklbw        m3, m6          ; D/L
  1769.     punpcklbw        m4, m7          ; E/M
  1770.  
  1771.     add           dst8q, strideq
  1772.     movh             m1, [dst2q+mstrideq*4]
  1773.     movh             m6, [dst8q+mstrideq*4]
  1774.     movh             m5, [dst2q]
  1775.     movh             m7, [dst8q]
  1776.     punpcklbw        m1, m6          ; B/J
  1777.     punpcklbw        m5, m7          ; F/N
  1778.     movh             m6, [dst2q+ strideq  ]
  1779.     movh             m7, [dst8q+ strideq  ]
  1780.     punpcklbw        m6, m7          ; G/O
  1781.  
  1782.     ; 8x16 transpose
  1783.     TRANSPOSE4x4B     0, 1, 2, 3, 7
  1784. %ifdef m8
  1785.     SWAP              1, 8
  1786. %else
  1787.     mova     m_q0backup, m1
  1788. %endif
  1789.     movh             m7, [dst2q+ strideq*2]
  1790.     movh             m1, [dst8q+ strideq*2]
  1791.     punpcklbw        m7, m1          ; H/P
  1792.     TRANSPOSE4x4B     4, 5, 6, 7, 1
  1793.     SBUTTERFLY       dq, 0, 4, 1     ; p3/p2
  1794.     SBUTTERFLY       dq, 2, 6, 1     ; q0/q1
  1795.     SBUTTERFLY       dq, 3, 7, 1     ; q2/q3
  1796. %ifdef m8
  1797.     SWAP              1, 8
  1798.     SWAP              2, 8
  1799. %else
  1800.     mova             m1, m_q0backup
  1801.     mova     m_q0backup, m2          ; store q0
  1802. %endif
  1803.     SBUTTERFLY       dq, 1, 5, 2     ; p1/p0
  1804. %ifdef m12
  1805.     SWAP              5, 12
  1806. %else
  1807.     mova     m_p0backup, m5          ; store p0
  1808. %endif
  1809.     SWAP              1, 4
  1810.     SWAP              2, 4
  1811.     SWAP              6, 3
  1812.     SWAP              5, 3
  1813. %endif
  1814.  
  1815.     ; normal_limit for p3-p2, p2-p1, q3-q2 and q2-q1
  1816.     mova             m4, m1
  1817.     SWAP              4, 1
  1818.     psubusb          m4, m0          ; p2-p3
  1819.     psubusb          m0, m1          ; p3-p2
  1820.     por              m0, m4          ; abs(p3-p2)
  1821.  
  1822.     mova             m4, m2
  1823.     SWAP              4, 2
  1824.     psubusb          m4, m1          ; p1-p2
  1825.     psubusb          m1, m2          ; p2-p1
  1826.     por              m1, m4          ; abs(p2-p1)
  1827.  
  1828.     mova             m4, m6
  1829.     SWAP              4, 6
  1830.     psubusb          m4, m7          ; q2-q3
  1831.     psubusb          m7, m6          ; q3-q2
  1832.     por              m7, m4          ; abs(q3-q2)
  1833.  
  1834.     mova             m4, m5
  1835.     SWAP              4, 5
  1836.     psubusb          m4, m6          ; q1-q2
  1837.     psubusb          m6, m5          ; q2-q1
  1838.     por              m6, m4          ; abs(q2-q1)
  1839.  
  1840. %if notcpuflag(mmxext)
  1841.     mova             m4, m_flimI
  1842.     pxor             m3, m3
  1843.     psubusb          m0, m4
  1844.     psubusb          m1, m4
  1845.     psubusb          m7, m4
  1846.     psubusb          m6, m4
  1847.     pcmpeqb          m0, m3          ; abs(p3-p2) <= I
  1848.     pcmpeqb          m1, m3          ; abs(p2-p1) <= I
  1849.     pcmpeqb          m7, m3          ; abs(q3-q2) <= I
  1850.     pcmpeqb          m6, m3          ; abs(q2-q1) <= I
  1851.     pand             m0, m1
  1852.     pand             m7, m6
  1853.     pand             m0, m7
  1854. %else ; mmxext/sse2
  1855.     pmaxub           m0, m1
  1856.     pmaxub           m6, m7
  1857.     pmaxub           m0, m6
  1858. %endif
  1859.  
  1860.     ; normal_limit and high_edge_variance for p1-p0, q1-q0
  1861.     SWAP              7, 3           ; now m7 is zero
  1862. %ifidn %1, v
  1863.     movrow           m3, [dst1q+mstrideq  ] ; p0
  1864. %if mmsize == 16 && %2 == 8
  1865.     movhps           m3, [dst8q+mstrideq  ]
  1866. %endif
  1867. %elifdef m12
  1868.     SWAP              3, 12
  1869. %else
  1870.     mova             m3, m_p0backup
  1871. %endif
  1872.  
  1873.     mova             m1, m2
  1874.     SWAP              1, 2
  1875.     mova             m6, m3
  1876.     SWAP              3, 6
  1877.     psubusb          m1, m3          ; p1-p0
  1878.     psubusb          m6, m2          ; p0-p1
  1879.     por              m1, m6          ; abs(p1-p0)
  1880. %if notcpuflag(mmxext)
  1881.     mova             m6, m1
  1882.     psubusb          m1, m4
  1883.     psubusb          m6, m_hevthr
  1884.     pcmpeqb          m1, m7          ; abs(p1-p0) <= I
  1885.     pcmpeqb          m6, m7          ; abs(p1-p0) <= hev_thresh
  1886.     pand             m0, m1
  1887.     mova      m_maskres, m6
  1888. %else ; mmxext/sse2
  1889.     pmaxub           m0, m1          ; max_I
  1890.     SWAP              1, 4           ; max_hev_thresh
  1891. %endif
  1892.  
  1893.     SWAP              6, 4           ; now m6 is I
  1894. %ifidn %1, v
  1895.     movrow           m4, [dst1q]     ; q0
  1896. %if mmsize == 16 && %2 == 8
  1897.     movhps           m4, [dst8q]
  1898. %endif
  1899. %elifdef m8
  1900.     SWAP              4, 8
  1901. %else
  1902.     mova             m4, m_q0backup
  1903. %endif
  1904.     mova             m1, m4
  1905.     SWAP              1, 4
  1906.     mova             m7, m5
  1907.     SWAP              7, 5
  1908.     psubusb          m1, m5          ; q0-q1
  1909.     psubusb          m7, m4          ; q1-q0
  1910.     por              m1, m7          ; abs(q1-q0)
  1911. %if notcpuflag(mmxext)
  1912.     mova             m7, m1
  1913.     psubusb          m1, m6
  1914.     psubusb          m7, m_hevthr
  1915.     pxor             m6, m6
  1916.     pcmpeqb          m1, m6          ; abs(q1-q0) <= I
  1917.     pcmpeqb          m7, m6          ; abs(q1-q0) <= hev_thresh
  1918.     mova             m6, m_maskres
  1919.     pand             m0, m1          ; abs([pq][321]-[pq][210]) <= I
  1920.     pand             m6, m7
  1921. %else ; mmxext/sse2
  1922.     pxor             m7, m7
  1923.     pmaxub           m0, m1
  1924.     pmaxub           m6, m1
  1925.     psubusb          m0, m_flimI
  1926.     psubusb          m6, m_hevthr
  1927.     pcmpeqb          m0, m7          ; max(abs(..)) <= I
  1928.     pcmpeqb          m6, m7          ; !(max(abs..) > thresh)
  1929. %endif
  1930. %ifdef m12
  1931.     SWAP              6, 12
  1932. %else
  1933.     mova      m_maskres, m6          ; !(abs(p1-p0) > hev_t || abs(q1-q0) > hev_t)
  1934. %endif
  1935.  
  1936.     ; simple_limit
  1937.     mova             m1, m3
  1938.     SWAP              1, 3
  1939.     mova             m6, m4          ; keep copies of p0/q0 around for later use
  1940.     SWAP              6, 4
  1941.     psubusb          m1, m4          ; p0-q0
  1942.     psubusb          m6, m3          ; q0-p0
  1943.     por              m1, m6          ; abs(q0-p0)
  1944.     paddusb          m1, m1          ; m1=2*abs(q0-p0)
  1945.  
  1946.     mova             m7, m2
  1947.     SWAP              7, 2
  1948.     mova             m6, m5
  1949.     SWAP              6, 5
  1950.     psubusb          m7, m5          ; p1-q1
  1951.     psubusb          m6, m2          ; q1-p1
  1952.     por              m7, m6          ; abs(q1-p1)
  1953.     pxor             m6, m6
  1954.     pand             m7, [pb_FE]
  1955.     psrlq            m7, 1           ; abs(q1-p1)/2
  1956.     paddusb          m7, m1          ; abs(q0-p0)*2+abs(q1-p1)/2
  1957.     psubusb          m7, m_flimE
  1958.     pcmpeqb          m7, m6          ; abs(q0-p0)*2+abs(q1-p1)/2 <= E
  1959.     pand             m0, m7          ; normal_limit result
  1960.  
  1961.     ; filter_common; at this point, m2-m5=p1-q1 and m0 is filter_mask
  1962. %ifdef m8 ; x86-64 && sse2
  1963.     mova             m8, [pb_80]
  1964. %define m_pb_80 m8
  1965. %else ; x86-32 or mmx/mmxext
  1966. %define m_pb_80 [pb_80]
  1967. %endif
  1968.     mova             m1, m4
  1969.     mova             m7, m3
  1970.     pxor             m1, m_pb_80
  1971.     pxor             m7, m_pb_80
  1972.     psubsb           m1, m7          ; (signed) q0-p0
  1973.     mova             m6, m2
  1974.     mova             m7, m5
  1975.     pxor             m6, m_pb_80
  1976.     pxor             m7, m_pb_80
  1977.     psubsb           m6, m7          ; (signed) p1-q1
  1978.     mova             m7, m_maskres
  1979.     pandn            m7, m6
  1980.     paddsb           m7, m1
  1981.     paddsb           m7, m1
  1982.     paddsb           m7, m1          ; 3*(q0-p0)+is4tap?(p1-q1)
  1983.  
  1984.     pand             m7, m0
  1985.     mova             m1, [pb_F8]
  1986.     mova             m6, m7
  1987.     paddsb           m7, [pb_3]
  1988.     paddsb           m6, [pb_4]
  1989.     pand             m7, m1
  1990.     pand             m6, m1
  1991.  
  1992.     pxor             m1, m1
  1993.     pxor             m0, m0
  1994.     pcmpgtb          m1, m7
  1995.     psubb            m0, m7
  1996.     psrlq            m7, 3           ; +f2
  1997.     psrlq            m0, 3           ; -f2
  1998.     pand             m0, m1
  1999.     pandn            m1, m7
  2000.     psubusb          m3, m0
  2001.     paddusb          m3, m1          ; p0+f2
  2002.  
  2003.     pxor             m1, m1
  2004.     pxor             m0, m0
  2005.     pcmpgtb          m0, m6
  2006.     psubb            m1, m6
  2007.     psrlq            m6, 3           ; +f1
  2008.     psrlq            m1, 3           ; -f1
  2009.     pand             m1, m0
  2010.     pandn            m0, m6
  2011.     psubusb          m4, m0
  2012.     paddusb          m4, m1          ; q0-f1
  2013.  
  2014. %ifdef m12
  2015.     SWAP              6, 12
  2016. %else
  2017.     mova             m6, m_maskres
  2018. %endif
  2019. %if notcpuflag(mmxext)
  2020.     mova             m7, [pb_1]
  2021. %else ; mmxext/sse2
  2022.     pxor             m7, m7
  2023. %endif
  2024.     pand             m0, m6
  2025.     pand             m1, m6
  2026. %if notcpuflag(mmxext)
  2027.     paddusb          m0, m7
  2028.     pand             m1, [pb_FE]
  2029.     pandn            m7, m0
  2030.     psrlq            m1, 1
  2031.     psrlq            m7, 1
  2032.     SWAP              0, 7
  2033. %else ; mmxext/sse2
  2034.     psubusb          m1, [pb_1]
  2035.     pavgb            m0, m7          ; a
  2036.     pavgb            m1, m7          ; -a
  2037. %endif
  2038.     psubusb          m5, m0
  2039.     psubusb          m2, m1
  2040.     paddusb          m5, m1          ; q1-a
  2041.     paddusb          m2, m0          ; p1+a
  2042.  
  2043.     ; store
  2044. %ifidn %1, v
  2045.     movrow [dst1q+mstrideq*2], m2
  2046.     movrow [dst1q+mstrideq  ], m3
  2047.     movrow      [dst1q], m4
  2048.     movrow [dst1q+ strideq  ], m5
  2049. %if mmsize == 16 && %2 == 8
  2050.     movhps [dst8q+mstrideq*2], m2
  2051.     movhps [dst8q+mstrideq  ], m3
  2052.     movhps      [dst8q], m4
  2053.     movhps [dst8q+ strideq  ], m5
  2054. %endif
  2055. %else ; h
  2056.     add           dst1q, 2
  2057.     add           dst2q, 2
  2058.  
  2059.     ; 4x8/16 transpose
  2060.     TRANSPOSE4x4B     2, 3, 4, 5, 6
  2061.  
  2062. %if mmsize == 8 ; mmx/mmxext (h)
  2063.     WRITE_4x2D        2, 3, 4, 5, dst1q, dst2q, mstrideq, strideq
  2064. %else ; sse2 (h)
  2065.     lea           dst8q, [dst8q+mstrideq  +2]
  2066.     WRITE_4x4D        2, 3, 4, 5, dst1q, dst2q, dst8q, mstrideq, strideq, %2
  2067. %endif
  2068. %endif
  2069.  
  2070. %if mmsize == 8
  2071. %if %2 == 8 ; chroma
  2072. %ifidn %1, h
  2073.     sub           dst1q, 2
  2074. %endif
  2075.     cmp           dst1q, dst8q
  2076.     mov           dst1q, dst8q
  2077.     jnz .next8px
  2078. %else
  2079. %ifidn %1, h
  2080.     lea           dst1q, [dst1q+ strideq*8-2]
  2081. %else ; v
  2082.     add           dst1q, 8
  2083. %endif
  2084.     dec           cntrq
  2085.     jg .next8px
  2086. %endif
  2087.     REP_RET
  2088. %else ; mmsize == 16
  2089.     RET
  2090. %endif
  2091. %endmacro
  2092.  
  2093. %if ARCH_X86_32
  2094. INIT_MMX mmx
  2095. INNER_LOOPFILTER v, 16
  2096. INNER_LOOPFILTER h, 16
  2097. INNER_LOOPFILTER v,  8
  2098. INNER_LOOPFILTER h,  8
  2099.  
  2100. INIT_MMX mmxext
  2101. INNER_LOOPFILTER v, 16
  2102. INNER_LOOPFILTER h, 16
  2103. INNER_LOOPFILTER v,  8
  2104. INNER_LOOPFILTER h,  8
  2105. %endif
  2106.  
  2107. INIT_XMM sse2
  2108. INNER_LOOPFILTER v, 16
  2109. INNER_LOOPFILTER h, 16
  2110. INNER_LOOPFILTER v,  8
  2111. INNER_LOOPFILTER h,  8
  2112.  
  2113. INIT_XMM ssse3
  2114. INNER_LOOPFILTER v, 16
  2115. INNER_LOOPFILTER h, 16
  2116. INNER_LOOPFILTER v,  8
  2117. INNER_LOOPFILTER h,  8
  2118.  
  2119. ;-----------------------------------------------------------------------------
  2120. ; void vp8_h/v_loop_filter<size>_mbedge_<opt>(uint8_t *dst, [uint8_t *v,] int stride,
  2121. ;                                            int flimE, int flimI, int hev_thr);
  2122. ;-----------------------------------------------------------------------------
  2123.  
  2124. %macro MBEDGE_LOOPFILTER 2
  2125. %define stack_size 0
  2126. %ifndef m8       ; stack layout: [0]=E, [1]=I, [2]=hev_thr
  2127. %if mmsize == 16 ;               [3]=hev() result
  2128.                  ;               [4]=filter tmp result
  2129.                  ;               [5]/[6] = p2/q2 backup
  2130.                  ;               [7]=lim_res sign result
  2131. %define stack_size mmsize * -7
  2132. %else ; 8        ; extra storage space for transposes
  2133. %define stack_size mmsize * -8
  2134. %endif
  2135. %endif
  2136.  
  2137. %if %2 == 8 ; chroma
  2138. cglobal vp8_%1_loop_filter8uv_mbedge, 6, 6, 15, stack_size, dst1, dst8, stride, flimE, flimI, hevthr
  2139. %else ; luma
  2140. cglobal vp8_%1_loop_filter16y_mbedge, 5, 5, 15, stack_size, dst1, stride, flimE, flimI, hevthr
  2141. %endif
  2142.  
  2143. %if cpuflag(ssse3)
  2144.     pxor             m7, m7
  2145. %endif
  2146.  
  2147. %ifndef m8
  2148.     ; splat function arguments
  2149.     SPLATB_REG       m0, flimEq, m7   ; E
  2150.     SPLATB_REG       m1, flimIq, m7   ; I
  2151.     SPLATB_REG       m2, hevthrq, m7  ; hev_thresh
  2152.  
  2153. %define m_flimE    [rsp]
  2154. %define m_flimI    [rsp+mmsize]
  2155. %define m_hevthr   [rsp+mmsize*2]
  2156. %define m_maskres  [rsp+mmsize*3]
  2157. %define m_limres   [rsp+mmsize*4]
  2158. %define m_p0backup [rsp+mmsize*3]
  2159. %define m_q0backup [rsp+mmsize*4]
  2160. %define m_p2backup [rsp+mmsize*5]
  2161. %define m_q2backup [rsp+mmsize*6]
  2162. %if mmsize == 16
  2163. %define m_limsign  [rsp]
  2164. %else
  2165. %define m_limsign  [rsp+mmsize*7]
  2166. %endif
  2167.  
  2168.     mova        m_flimE, m0
  2169.     mova        m_flimI, m1
  2170.     mova       m_hevthr, m2
  2171. %else ; sse2 on x86-64
  2172. %define m_flimE    m9
  2173. %define m_flimI    m10
  2174. %define m_hevthr   m11
  2175. %define m_maskres  m12
  2176. %define m_limres   m8
  2177. %define m_p0backup m12
  2178. %define m_q0backup m8
  2179. %define m_p2backup m13
  2180. %define m_q2backup m14
  2181. %define m_limsign  m9
  2182.  
  2183.     ; splat function arguments
  2184.     SPLATB_REG  m_flimE, flimEq, m7   ; E
  2185.     SPLATB_REG  m_flimI, flimIq, m7   ; I
  2186.     SPLATB_REG m_hevthr, hevthrq, m7  ; hev_thresh
  2187. %endif
  2188.  
  2189. %if %2 == 8 ; chroma
  2190.     DEFINE_ARGS dst1, dst8, mstride, stride, dst2
  2191. %elif mmsize == 8
  2192.     DEFINE_ARGS dst1, mstride, stride, dst2, cntr
  2193.     mov           cntrq, 2
  2194. %else
  2195.     DEFINE_ARGS dst1, mstride, stride, dst2, dst8
  2196. %endif
  2197.     mov         strideq, mstrideq
  2198.     neg        mstrideq
  2199. %ifidn %1, h
  2200.     lea           dst1q, [dst1q+strideq*4-4]
  2201. %if %2 == 8 ; chroma
  2202.     lea           dst8q, [dst8q+strideq*4-4]
  2203. %endif
  2204. %endif
  2205.  
  2206. %if mmsize == 8
  2207. .next8px:
  2208. %endif
  2209.     ; read
  2210.     lea           dst2q, [dst1q+ strideq  ]
  2211. %ifidn %1, v
  2212. %if %2 == 8 && mmsize == 16
  2213. %define movrow movh
  2214. %else
  2215. %define movrow mova
  2216. %endif
  2217.     movrow           m0, [dst1q+mstrideq*4] ; p3
  2218.     movrow           m1, [dst2q+mstrideq*4] ; p2
  2219.     movrow           m2, [dst1q+mstrideq*2] ; p1
  2220.     movrow           m5, [dst2q]            ; q1
  2221.     movrow           m6, [dst2q+ strideq  ] ; q2
  2222.     movrow           m7, [dst2q+ strideq*2] ; q3
  2223. %if mmsize == 16 && %2 == 8
  2224.     movhps           m0, [dst8q+mstrideq*4]
  2225.     movhps           m2, [dst8q+mstrideq*2]
  2226.     add           dst8q, strideq
  2227.     movhps           m1, [dst8q+mstrideq*4]
  2228.     movhps           m5, [dst8q]
  2229.     movhps           m6, [dst8q+ strideq  ]
  2230.     movhps           m7, [dst8q+ strideq*2]
  2231.     add           dst8q, mstrideq
  2232. %endif
  2233. %elif mmsize == 8 ; mmx/mmxext (h)
  2234.     ; read 8 rows of 8px each
  2235.     movu             m0, [dst1q+mstrideq*4]
  2236.     movu             m1, [dst2q+mstrideq*4]
  2237.     movu             m2, [dst1q+mstrideq*2]
  2238.     movu             m3, [dst1q+mstrideq  ]
  2239.     movu             m4, [dst1q]
  2240.     movu             m5, [dst2q]
  2241.     movu             m6, [dst2q+ strideq  ]
  2242.  
  2243.     ; 8x8 transpose
  2244.     TRANSPOSE4x4B     0, 1, 2, 3, 7
  2245.     mova     m_q0backup, m1
  2246.     movu             m7, [dst2q+ strideq*2]
  2247.     TRANSPOSE4x4B     4, 5, 6, 7, 1
  2248.     SBUTTERFLY       dq, 0, 4, 1     ; p3/p2
  2249.     SBUTTERFLY       dq, 2, 6, 1     ; q0/q1
  2250.     SBUTTERFLY       dq, 3, 7, 1     ; q2/q3
  2251.     mova             m1, m_q0backup
  2252.     mova     m_q0backup, m2          ; store q0
  2253.     SBUTTERFLY       dq, 1, 5, 2     ; p1/p0
  2254.     mova     m_p0backup, m5          ; store p0
  2255.     SWAP              1, 4
  2256.     SWAP              2, 4
  2257.     SWAP              6, 3
  2258.     SWAP              5, 3
  2259. %else ; sse2 (h)
  2260. %if %2 == 16
  2261.     lea           dst8q, [dst1q+ strideq*8  ]
  2262. %endif
  2263.  
  2264.     ; read 16 rows of 8px each, interleave
  2265.     movh             m0, [dst1q+mstrideq*4]
  2266.     movh             m1, [dst8q+mstrideq*4]
  2267.     movh             m2, [dst1q+mstrideq*2]
  2268.     movh             m5, [dst8q+mstrideq*2]
  2269.     movh             m3, [dst1q+mstrideq  ]
  2270.     movh             m6, [dst8q+mstrideq  ]
  2271.     movh             m4, [dst1q]
  2272.     movh             m7, [dst8q]
  2273.     punpcklbw        m0, m1          ; A/I
  2274.     punpcklbw        m2, m5          ; C/K
  2275.     punpcklbw        m3, m6          ; D/L
  2276.     punpcklbw        m4, m7          ; E/M
  2277.  
  2278.     add           dst8q, strideq
  2279.     movh             m1, [dst2q+mstrideq*4]
  2280.     movh             m6, [dst8q+mstrideq*4]
  2281.     movh             m5, [dst2q]
  2282.     movh             m7, [dst8q]
  2283.     punpcklbw        m1, m6          ; B/J
  2284.     punpcklbw        m5, m7          ; F/N
  2285.     movh             m6, [dst2q+ strideq  ]
  2286.     movh             m7, [dst8q+ strideq  ]
  2287.     punpcklbw        m6, m7          ; G/O
  2288.  
  2289.     ; 8x16 transpose
  2290.     TRANSPOSE4x4B     0, 1, 2, 3, 7
  2291. %ifdef m8
  2292.     SWAP              1, 8
  2293. %else
  2294.     mova     m_q0backup, m1
  2295. %endif
  2296.     movh             m7, [dst2q+ strideq*2]
  2297.     movh             m1, [dst8q+ strideq*2]
  2298.     punpcklbw        m7, m1          ; H/P
  2299.     TRANSPOSE4x4B     4, 5, 6, 7, 1
  2300.     SBUTTERFLY       dq, 0, 4, 1     ; p3/p2
  2301.     SBUTTERFLY       dq, 2, 6, 1     ; q0/q1
  2302.     SBUTTERFLY       dq, 3, 7, 1     ; q2/q3
  2303. %ifdef m8
  2304.     SWAP              1, 8
  2305.     SWAP              2, 8
  2306. %else
  2307.     mova             m1, m_q0backup
  2308.     mova     m_q0backup, m2          ; store q0
  2309. %endif
  2310.     SBUTTERFLY       dq, 1, 5, 2     ; p1/p0
  2311. %ifdef m12
  2312.     SWAP              5, 12
  2313. %else
  2314.     mova     m_p0backup, m5          ; store p0
  2315. %endif
  2316.     SWAP              1, 4
  2317.     SWAP              2, 4
  2318.     SWAP              6, 3
  2319.     SWAP              5, 3
  2320. %endif
  2321.  
  2322.     ; normal_limit for p3-p2, p2-p1, q3-q2 and q2-q1
  2323.     mova             m4, m1
  2324.     SWAP              4, 1
  2325.     psubusb          m4, m0          ; p2-p3
  2326.     psubusb          m0, m1          ; p3-p2
  2327.     por              m0, m4          ; abs(p3-p2)
  2328.  
  2329.     mova             m4, m2
  2330.     SWAP              4, 2
  2331.     psubusb          m4, m1          ; p1-p2
  2332.     mova     m_p2backup, m1
  2333.     psubusb          m1, m2          ; p2-p1
  2334.     por              m1, m4          ; abs(p2-p1)
  2335.  
  2336.     mova             m4, m6
  2337.     SWAP              4, 6
  2338.     psubusb          m4, m7          ; q2-q3
  2339.     psubusb          m7, m6          ; q3-q2
  2340.     por              m7, m4          ; abs(q3-q2)
  2341.  
  2342.     mova             m4, m5
  2343.     SWAP              4, 5
  2344.     psubusb          m4, m6          ; q1-q2
  2345.     mova     m_q2backup, m6
  2346.     psubusb          m6, m5          ; q2-q1
  2347.     por              m6, m4          ; abs(q2-q1)
  2348.  
  2349. %if notcpuflag(mmxext)
  2350.     mova             m4, m_flimI
  2351.     pxor             m3, m3
  2352.     psubusb          m0, m4
  2353.     psubusb          m1, m4
  2354.     psubusb          m7, m4
  2355.     psubusb          m6, m4
  2356.     pcmpeqb          m0, m3          ; abs(p3-p2) <= I
  2357.     pcmpeqb          m1, m3          ; abs(p2-p1) <= I
  2358.     pcmpeqb          m7, m3          ; abs(q3-q2) <= I
  2359.     pcmpeqb          m6, m3          ; abs(q2-q1) <= I
  2360.     pand             m0, m1
  2361.     pand             m7, m6
  2362.     pand             m0, m7
  2363. %else ; mmxext/sse2
  2364.     pmaxub           m0, m1
  2365.     pmaxub           m6, m7
  2366.     pmaxub           m0, m6
  2367. %endif
  2368.  
  2369.     ; normal_limit and high_edge_variance for p1-p0, q1-q0
  2370.     SWAP              7, 3           ; now m7 is zero
  2371. %ifidn %1, v
  2372.     movrow           m3, [dst1q+mstrideq  ] ; p0
  2373. %if mmsize == 16 && %2 == 8
  2374.     movhps           m3, [dst8q+mstrideq  ]
  2375. %endif
  2376. %elifdef m12
  2377.     SWAP              3, 12
  2378. %else
  2379.     mova             m3, m_p0backup
  2380. %endif
  2381.  
  2382.     mova             m1, m2
  2383.     SWAP              1, 2
  2384.     mova             m6, m3
  2385.     SWAP              3, 6
  2386.     psubusb          m1, m3          ; p1-p0
  2387.     psubusb          m6, m2          ; p0-p1
  2388.     por              m1, m6          ; abs(p1-p0)
  2389. %if notcpuflag(mmxext)
  2390.     mova             m6, m1
  2391.     psubusb          m1, m4
  2392.     psubusb          m6, m_hevthr
  2393.     pcmpeqb          m1, m7          ; abs(p1-p0) <= I
  2394.     pcmpeqb          m6, m7          ; abs(p1-p0) <= hev_thresh
  2395.     pand             m0, m1
  2396.     mova      m_maskres, m6
  2397. %else ; mmxext/sse2
  2398.     pmaxub           m0, m1          ; max_I
  2399.     SWAP              1, 4           ; max_hev_thresh
  2400. %endif
  2401.  
  2402.     SWAP              6, 4           ; now m6 is I
  2403. %ifidn %1, v
  2404.     movrow           m4, [dst1q]     ; q0
  2405. %if mmsize == 16 && %2 == 8
  2406.     movhps           m4, [dst8q]
  2407. %endif
  2408. %elifdef m8
  2409.     SWAP              4, 8
  2410. %else
  2411.     mova             m4, m_q0backup
  2412. %endif
  2413.     mova             m1, m4
  2414.     SWAP              1, 4
  2415.     mova             m7, m5
  2416.     SWAP              7, 5
  2417.     psubusb          m1, m5          ; q0-q1
  2418.     psubusb          m7, m4          ; q1-q0
  2419.     por              m1, m7          ; abs(q1-q0)
  2420. %if notcpuflag(mmxext)
  2421.     mova             m7, m1
  2422.     psubusb          m1, m6
  2423.     psubusb          m7, m_hevthr
  2424.     pxor             m6, m6
  2425.     pcmpeqb          m1, m6          ; abs(q1-q0) <= I
  2426.     pcmpeqb          m7, m6          ; abs(q1-q0) <= hev_thresh
  2427.     mova             m6, m_maskres
  2428.     pand             m0, m1          ; abs([pq][321]-[pq][210]) <= I
  2429.     pand             m6, m7
  2430. %else ; mmxext/sse2
  2431.     pxor             m7, m7
  2432.     pmaxub           m0, m1
  2433.     pmaxub           m6, m1
  2434.     psubusb          m0, m_flimI
  2435.     psubusb          m6, m_hevthr
  2436.     pcmpeqb          m0, m7          ; max(abs(..)) <= I
  2437.     pcmpeqb          m6, m7          ; !(max(abs..) > thresh)
  2438. %endif
  2439. %ifdef m12
  2440.     SWAP              6, 12
  2441. %else
  2442.     mova      m_maskres, m6          ; !(abs(p1-p0) > hev_t || abs(q1-q0) > hev_t)
  2443. %endif
  2444.  
  2445.     ; simple_limit
  2446.     mova             m1, m3
  2447.     SWAP              1, 3
  2448.     mova             m6, m4          ; keep copies of p0/q0 around for later use
  2449.     SWAP              6, 4
  2450.     psubusb          m1, m4          ; p0-q0
  2451.     psubusb          m6, m3          ; q0-p0
  2452.     por              m1, m6          ; abs(q0-p0)
  2453.     paddusb          m1, m1          ; m1=2*abs(q0-p0)
  2454.  
  2455.     mova             m7, m2
  2456.     SWAP              7, 2
  2457.     mova             m6, m5
  2458.     SWAP              6, 5
  2459.     psubusb          m7, m5          ; p1-q1
  2460.     psubusb          m6, m2          ; q1-p1
  2461.     por              m7, m6          ; abs(q1-p1)
  2462.     pxor             m6, m6
  2463.     pand             m7, [pb_FE]
  2464.     psrlq            m7, 1           ; abs(q1-p1)/2
  2465.     paddusb          m7, m1          ; abs(q0-p0)*2+abs(q1-p1)/2
  2466.     psubusb          m7, m_flimE
  2467.     pcmpeqb          m7, m6          ; abs(q0-p0)*2+abs(q1-p1)/2 <= E
  2468.     pand             m0, m7          ; normal_limit result
  2469.  
  2470.     ; filter_common; at this point, m2-m5=p1-q1 and m0 is filter_mask
  2471. %ifdef m8 ; x86-64 && sse2
  2472.     mova             m8, [pb_80]
  2473. %define m_pb_80 m8
  2474. %else ; x86-32 or mmx/mmxext
  2475. %define m_pb_80 [pb_80]
  2476. %endif
  2477.     mova             m1, m4
  2478.     mova             m7, m3
  2479.     pxor             m1, m_pb_80
  2480.     pxor             m7, m_pb_80
  2481.     psubsb           m1, m7          ; (signed) q0-p0
  2482.     mova             m6, m2
  2483.     mova             m7, m5
  2484.     pxor             m6, m_pb_80
  2485.     pxor             m7, m_pb_80
  2486.     psubsb           m6, m7          ; (signed) p1-q1
  2487.     mova             m7, m_maskres
  2488.     paddsb           m6, m1
  2489.     paddsb           m6, m1
  2490.     paddsb           m6, m1
  2491.     pand             m6, m0
  2492. %ifdef m8
  2493.     mova       m_limres, m6          ; 3*(qp-p0)+(p1-q1) masked for filter_mbedge
  2494.     pand       m_limres, m7
  2495. %else
  2496.     mova             m0, m6
  2497.     pand             m0, m7
  2498.     mova       m_limres, m0
  2499. %endif
  2500.     pandn            m7, m6          ; 3*(q0-p0)+(p1-q1) masked for filter_common
  2501.  
  2502.     mova             m1, [pb_F8]
  2503.     mova             m6, m7
  2504.     paddsb           m7, [pb_3]
  2505.     paddsb           m6, [pb_4]
  2506.     pand             m7, m1
  2507.     pand             m6, m1
  2508.  
  2509.     pxor             m1, m1
  2510.     pxor             m0, m0
  2511.     pcmpgtb          m1, m7
  2512.     psubb            m0, m7
  2513.     psrlq            m7, 3           ; +f2
  2514.     psrlq            m0, 3           ; -f2
  2515.     pand             m0, m1
  2516.     pandn            m1, m7
  2517.     psubusb          m3, m0
  2518.     paddusb          m3, m1          ; p0+f2
  2519.  
  2520.     pxor             m1, m1
  2521.     pxor             m0, m0
  2522.     pcmpgtb          m0, m6
  2523.     psubb            m1, m6
  2524.     psrlq            m6, 3           ; +f1
  2525.     psrlq            m1, 3           ; -f1
  2526.     pand             m1, m0
  2527.     pandn            m0, m6
  2528.     psubusb          m4, m0
  2529.     paddusb          m4, m1          ; q0-f1
  2530.  
  2531.     ; filter_mbedge (m2-m5 = p1-q1; lim_res carries w)
  2532. %if cpuflag(ssse3)
  2533.     mova             m7, [pb_1]
  2534. %else
  2535.     mova             m7, [pw_63]
  2536. %endif
  2537. %ifdef m8
  2538.     SWAP              1, 8
  2539. %else
  2540.     mova             m1, m_limres
  2541. %endif
  2542.     pxor             m0, m0
  2543.     mova             m6, m1
  2544.     pcmpgtb          m0, m1         ; which are negative
  2545. %if cpuflag(ssse3)
  2546.     punpcklbw        m6, m7         ; interleave with "1" for rounding
  2547.     punpckhbw        m1, m7
  2548. %else
  2549.     punpcklbw        m6, m0         ; signed byte->word
  2550.     punpckhbw        m1, m0
  2551. %endif
  2552.     mova      m_limsign, m0
  2553. %if cpuflag(ssse3)
  2554.     mova             m7, [pb_27_63]
  2555. %ifndef m8
  2556.     mova       m_limres, m1
  2557. %endif
  2558. %ifdef m10
  2559.     SWAP              0, 10         ; don't lose lim_sign copy
  2560. %endif
  2561.     mova             m0, m7
  2562.     pmaddubsw        m7, m6
  2563.     SWAP              6, 7
  2564.     pmaddubsw        m0, m1
  2565.     SWAP              1, 0
  2566. %ifdef m10
  2567.     SWAP              0, 10
  2568. %else
  2569.     mova             m0, m_limsign
  2570. %endif
  2571. %else
  2572.     mova      m_maskres, m6         ; backup for later in filter
  2573.     mova       m_limres, m1
  2574.     pmullw          m6, [pw_27]
  2575.     pmullw          m1, [pw_27]
  2576.     paddw           m6, m7
  2577.     paddw           m1, m7
  2578. %endif
  2579.     psraw           m6, 7
  2580.     psraw           m1, 7
  2581.     packsswb        m6, m1          ; a0
  2582.     pxor            m1, m1
  2583.     psubb           m1, m6
  2584.     pand            m1, m0          ; -a0
  2585.     pandn           m0, m6          ; +a0
  2586. %if cpuflag(ssse3)
  2587.     mova            m6, [pb_18_63]  ; pipelining
  2588. %endif
  2589.     psubusb         m3, m1
  2590.     paddusb         m4, m1
  2591.     paddusb         m3, m0          ; p0+a0
  2592.     psubusb         m4, m0          ; q0-a0
  2593.  
  2594. %if cpuflag(ssse3)
  2595.     SWAP             6, 7
  2596. %ifdef m10
  2597.     SWAP             1, 10
  2598. %else
  2599.     mova            m1, m_limres
  2600. %endif
  2601.     mova            m0, m7
  2602.     pmaddubsw       m7, m6
  2603.     SWAP             6, 7
  2604.     pmaddubsw       m0, m1
  2605.     SWAP             1, 0
  2606. %ifdef m10
  2607.     SWAP             0, 10
  2608. %endif
  2609.     mova            m0, m_limsign
  2610. %else
  2611.     mova            m6, m_maskres
  2612.     mova            m1, m_limres
  2613.     pmullw          m6, [pw_18]
  2614.     pmullw          m1, [pw_18]
  2615.     paddw           m6, m7
  2616.     paddw           m1, m7
  2617. %endif
  2618.     mova            m0, m_limsign
  2619.     psraw           m6, 7
  2620.     psraw           m1, 7
  2621.     packsswb        m6, m1          ; a1
  2622.     pxor            m1, m1
  2623.     psubb           m1, m6
  2624.     pand            m1, m0          ; -a1
  2625.     pandn           m0, m6          ; +a1
  2626. %if cpuflag(ssse3)
  2627.     mova            m6, [pb_9_63]
  2628. %endif
  2629.     psubusb         m2, m1
  2630.     paddusb         m5, m1
  2631.     paddusb         m2, m0          ; p1+a1
  2632.     psubusb         m5, m0          ; q1-a1
  2633.  
  2634. %if cpuflag(ssse3)
  2635.     SWAP             6, 7
  2636. %ifdef m10
  2637.     SWAP             1, 10
  2638. %else
  2639.     mova            m1, m_limres
  2640. %endif
  2641.     mova            m0, m7
  2642.     pmaddubsw       m7, m6
  2643.     SWAP             6, 7
  2644.     pmaddubsw       m0, m1
  2645.     SWAP             1, 0
  2646. %else
  2647. %ifdef m8
  2648.     SWAP             6, 12
  2649.     SWAP             1, 8
  2650. %else
  2651.     mova            m6, m_maskres
  2652.     mova            m1, m_limres
  2653. %endif
  2654.     pmullw          m6, [pw_9]
  2655.     pmullw          m1, [pw_9]
  2656.     paddw           m6, m7
  2657.     paddw           m1, m7
  2658. %endif
  2659. %ifdef m9
  2660.     SWAP             7, 9
  2661. %else
  2662.     mova            m7, m_limsign
  2663. %endif
  2664.     psraw           m6, 7
  2665.     psraw           m1, 7
  2666.     packsswb        m6, m1          ; a1
  2667.     pxor            m0, m0
  2668.     psubb           m0, m6
  2669.     pand            m0, m7          ; -a1
  2670.     pandn           m7, m6          ; +a1
  2671. %ifdef m8
  2672.     SWAP             1, 13
  2673.     SWAP             6, 14
  2674. %else
  2675.     mova            m1, m_p2backup
  2676.     mova            m6, m_q2backup
  2677. %endif
  2678.     psubusb         m1, m0
  2679.     paddusb         m6, m0
  2680.     paddusb         m1, m7          ; p1+a1
  2681.     psubusb         m6, m7          ; q1-a1
  2682.  
  2683.     ; store
  2684. %ifidn %1, v
  2685.     movrow [dst2q+mstrideq*4], m1
  2686.     movrow [dst1q+mstrideq*2], m2
  2687.     movrow [dst1q+mstrideq  ], m3
  2688.     movrow     [dst1q], m4
  2689.     movrow     [dst2q], m5
  2690.     movrow [dst2q+ strideq  ], m6
  2691. %if mmsize == 16 && %2 == 8
  2692.     add           dst8q, mstrideq
  2693.     movhps [dst8q+mstrideq*2], m1
  2694.     movhps [dst8q+mstrideq  ], m2
  2695.     movhps     [dst8q], m3
  2696.     add          dst8q, strideq
  2697.     movhps     [dst8q], m4
  2698.     movhps [dst8q+ strideq  ], m5
  2699.     movhps [dst8q+ strideq*2], m6
  2700. %endif
  2701. %else ; h
  2702.     inc          dst1q
  2703.     inc          dst2q
  2704.  
  2705.     ; 4x8/16 transpose
  2706.     TRANSPOSE4x4B    1, 2, 3, 4, 0
  2707.     SBUTTERFLY      bw, 5, 6, 0
  2708.  
  2709. %if mmsize == 8 ; mmx/mmxext (h)
  2710.     WRITE_4x2D       1, 2, 3, 4, dst1q, dst2q, mstrideq, strideq
  2711.     add          dst1q, 4
  2712.     WRITE_2x4W      m5, m6, dst2q, dst1q, mstrideq, strideq
  2713. %else ; sse2 (h)
  2714.     lea          dst8q, [dst8q+mstrideq+1]
  2715.     WRITE_4x4D       1, 2, 3, 4, dst1q, dst2q, dst8q, mstrideq, strideq, %2
  2716.     lea          dst1q, [dst2q+mstrideq+4]
  2717.     lea          dst8q, [dst8q+mstrideq+4]
  2718. %if cpuflag(sse4)
  2719.     add          dst2q, 4
  2720. %endif
  2721.     WRITE_8W        m5, dst2q, dst1q,  mstrideq, strideq
  2722. %if cpuflag(sse4)
  2723.     lea          dst2q, [dst8q+ strideq  ]
  2724. %endif
  2725.     WRITE_8W        m6, dst2q, dst8q, mstrideq, strideq
  2726. %endif
  2727. %endif
  2728.  
  2729. %if mmsize == 8
  2730. %if %2 == 8 ; chroma
  2731. %ifidn %1, h
  2732.     sub          dst1q, 5
  2733. %endif
  2734.     cmp          dst1q, dst8q
  2735.     mov          dst1q, dst8q
  2736.     jnz .next8px
  2737. %else
  2738. %ifidn %1, h
  2739.     lea          dst1q, [dst1q+ strideq*8-5]
  2740. %else ; v
  2741.     add          dst1q, 8
  2742. %endif
  2743.     dec          cntrq
  2744.     jg .next8px
  2745. %endif
  2746.     REP_RET
  2747. %else ; mmsize == 16
  2748.     RET
  2749. %endif
  2750. %endmacro
  2751.  
  2752. %if ARCH_X86_32
  2753. INIT_MMX mmx
  2754. MBEDGE_LOOPFILTER v, 16
  2755. MBEDGE_LOOPFILTER h, 16
  2756. MBEDGE_LOOPFILTER v,  8
  2757. MBEDGE_LOOPFILTER h,  8
  2758.  
  2759. INIT_MMX mmxext
  2760. MBEDGE_LOOPFILTER v, 16
  2761. MBEDGE_LOOPFILTER h, 16
  2762. MBEDGE_LOOPFILTER v,  8
  2763. MBEDGE_LOOPFILTER h,  8
  2764. %endif
  2765.  
  2766. INIT_XMM sse2
  2767. MBEDGE_LOOPFILTER v, 16
  2768. MBEDGE_LOOPFILTER h, 16
  2769. MBEDGE_LOOPFILTER v,  8
  2770. MBEDGE_LOOPFILTER h,  8
  2771.  
  2772. INIT_XMM ssse3
  2773. MBEDGE_LOOPFILTER v, 16
  2774. MBEDGE_LOOPFILTER h, 16
  2775. MBEDGE_LOOPFILTER v,  8
  2776. MBEDGE_LOOPFILTER h,  8
  2777.  
  2778. INIT_XMM sse4
  2779. MBEDGE_LOOPFILTER h, 16
  2780. MBEDGE_LOOPFILTER h,  8
  2781.