Subversion Repositories Kolibri OS

Rev

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

  1. ;******************************************************************************
  2. ;* H.264 intra prediction asm optimizations
  3. ;* Copyright (c) 2010 Jason Garrett-Glaser
  4. ;* Copyright (c) 2010 Holger Lubitz
  5. ;* Copyright (c) 2010 Loren Merritt
  6. ;* Copyright (c) 2010 Ronald S. Bultje
  7. ;*
  8. ;* This file is part of FFmpeg.
  9. ;*
  10. ;* FFmpeg is free software; you can redistribute it and/or
  11. ;* modify it under the terms of the GNU Lesser General Public
  12. ;* License as published by the Free Software Foundation; either
  13. ;* version 2.1 of the License, or (at your option) any later version.
  14. ;*
  15. ;* FFmpeg is distributed in the hope that it will be useful,
  16. ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  18. ;* Lesser General Public License for more details.
  19. ;*
  20. ;* You should have received a copy of the GNU Lesser General Public
  21. ;* License along with FFmpeg; if not, write to the Free Software
  22. ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  23. ;******************************************************************************
  24.  
  25. %include "libavutil/x86/x86util.asm"
  26.  
  27. SECTION_RODATA
  28.  
  29. tm_shuf: times 8 db 0x03, 0x80
  30. pw_ff00: times 8 dw 0xff00
  31. plane_shuf:  db -8, -7, -6, -5, -4, -3, -2, -1
  32.              db  1,  2,  3,  4,  5,  6,  7,  8
  33. plane8_shuf: db -4, -3, -2, -1,  0,  0,  0,  0
  34.              db  1,  2,  3,  4,  0,  0,  0,  0
  35. pw_0to7:     dw  0,  1,  2,  3,  4,  5,  6,  7
  36. pw_1to8:     dw  1,  2,  3,  4,  5,  6,  7,  8
  37. pw_m8tom1:   dw -8, -7, -6, -5, -4, -3, -2, -1
  38. pw_m4to4:    dw -4, -3, -2, -1,  1,  2,  3,  4
  39.  
  40. SECTION .text
  41.  
  42. cextern pb_1
  43. cextern pb_3
  44. cextern pw_4
  45. cextern pw_5
  46. cextern pw_8
  47. cextern pw_16
  48. cextern pw_17
  49. cextern pw_32
  50.  
  51. ;-----------------------------------------------------------------------------
  52. ; void pred16x16_vertical_8(uint8_t *src, int stride)
  53. ;-----------------------------------------------------------------------------
  54.  
  55. INIT_MMX mmx
  56. cglobal pred16x16_vertical_8, 2,3
  57.     sub   r0, r1
  58.     mov   r2, 8
  59.     movq mm0, [r0+0]
  60.     movq mm1, [r0+8]
  61. .loop:
  62.     movq [r0+r1*1+0], mm0
  63.     movq [r0+r1*1+8], mm1
  64.     movq [r0+r1*2+0], mm0
  65.     movq [r0+r1*2+8], mm1
  66.     lea   r0, [r0+r1*2]
  67.     dec   r2
  68.     jg .loop
  69.     REP_RET
  70.  
  71. INIT_XMM sse
  72. cglobal pred16x16_vertical_8, 2,3
  73.     sub   r0, r1
  74.     mov   r2, 4
  75.     movaps xmm0, [r0]
  76. .loop:
  77.     movaps [r0+r1*1], xmm0
  78.     movaps [r0+r1*2], xmm0
  79.     lea   r0, [r0+r1*2]
  80.     movaps [r0+r1*1], xmm0
  81.     movaps [r0+r1*2], xmm0
  82.     lea   r0, [r0+r1*2]
  83.     dec   r2
  84.     jg .loop
  85.     REP_RET
  86.  
  87. ;-----------------------------------------------------------------------------
  88. ; void pred16x16_horizontal_8(uint8_t *src, int stride)
  89. ;-----------------------------------------------------------------------------
  90.  
  91. %macro PRED16x16_H 0
  92. cglobal pred16x16_horizontal_8, 2,3
  93.     mov       r2, 8
  94. %if cpuflag(ssse3)
  95.     mova      m2, [pb_3]
  96. %endif
  97. .loop:
  98.     movd      m0, [r0+r1*0-4]
  99.     movd      m1, [r0+r1*1-4]
  100.  
  101. %if cpuflag(ssse3)
  102.     pshufb    m0, m2
  103.     pshufb    m1, m2
  104. %else
  105.     punpcklbw m0, m0
  106.     punpcklbw m1, m1
  107.     SPLATW    m0, m0, 3
  108.     SPLATW    m1, m1, 3
  109.     mova [r0+r1*0+8], m0
  110.     mova [r0+r1*1+8], m1
  111. %endif
  112.  
  113.     mova [r0+r1*0], m0
  114.     mova [r0+r1*1], m1
  115.     lea       r0, [r0+r1*2]
  116.     dec       r2
  117.     jg .loop
  118.     REP_RET
  119. %endmacro
  120.  
  121. INIT_MMX mmx
  122. PRED16x16_H
  123. INIT_MMX mmxext
  124. PRED16x16_H
  125. INIT_XMM ssse3
  126. PRED16x16_H
  127.  
  128. ;-----------------------------------------------------------------------------
  129. ; void pred16x16_dc_8(uint8_t *src, int stride)
  130. ;-----------------------------------------------------------------------------
  131.  
  132. %macro PRED16x16_DC 0
  133. cglobal pred16x16_dc_8, 2,7
  134.     mov       r4, r0
  135.     sub       r0, r1
  136.     pxor      mm0, mm0
  137.     pxor      mm1, mm1
  138.     psadbw    mm0, [r0+0]
  139.     psadbw    mm1, [r0+8]
  140.     dec        r0
  141.     movzx     r5d, byte [r0+r1*1]
  142.     paddw     mm0, mm1
  143.     movd      r6d, mm0
  144.     lea        r0, [r0+r1*2]
  145. %rep 7
  146.     movzx     r2d, byte [r0+r1*0]
  147.     movzx     r3d, byte [r0+r1*1]
  148.     add       r5d, r2d
  149.     add       r6d, r3d
  150.     lea        r0, [r0+r1*2]
  151. %endrep
  152.     movzx     r2d, byte [r0+r1*0]
  153.     add       r5d, r6d
  154.     lea       r2d, [r2+r5+16]
  155.     shr       r2d, 5
  156. %if cpuflag(ssse3)
  157.     pxor       m1, m1
  158. %endif
  159.     SPLATB_REG m0, r2, m1
  160.  
  161. %if mmsize==8
  162.     mov       r3d, 8
  163. .loop:
  164.     mova [r4+r1*0+0], m0
  165.     mova [r4+r1*0+8], m0
  166.     mova [r4+r1*1+0], m0
  167.     mova [r4+r1*1+8], m0
  168. %else
  169.     mov       r3d, 4
  170. .loop:
  171.     mova [r4+r1*0], m0
  172.     mova [r4+r1*1], m0
  173.     lea   r4, [r4+r1*2]
  174.     mova [r4+r1*0], m0
  175.     mova [r4+r1*1], m0
  176. %endif
  177.     lea   r4, [r4+r1*2]
  178.     dec   r3d
  179.     jg .loop
  180.     REP_RET
  181. %endmacro
  182.  
  183. INIT_MMX mmxext
  184. PRED16x16_DC
  185. INIT_XMM sse2
  186. PRED16x16_DC
  187. INIT_XMM ssse3
  188. PRED16x16_DC
  189.  
  190. ;-----------------------------------------------------------------------------
  191. ; void pred16x16_tm_vp8_8(uint8_t *src, int stride)
  192. ;-----------------------------------------------------------------------------
  193.  
  194. %macro PRED16x16_TM 0
  195. cglobal pred16x16_tm_vp8_8, 2,5
  196.     sub        r0, r1
  197.     pxor      mm7, mm7
  198.     movq      mm0, [r0+0]
  199.     movq      mm2, [r0+8]
  200.     movq      mm1, mm0
  201.     movq      mm3, mm2
  202.     punpcklbw mm0, mm7
  203.     punpckhbw mm1, mm7
  204.     punpcklbw mm2, mm7
  205.     punpckhbw mm3, mm7
  206.     movzx     r3d, byte [r0-1]
  207.     mov       r4d, 16
  208. .loop:
  209.     movzx     r2d, byte [r0+r1-1]
  210.     sub       r2d, r3d
  211.     movd      mm4, r2d
  212.     SPLATW    mm4, mm4, 0
  213.     movq      mm5, mm4
  214.     movq      mm6, mm4
  215.     movq      mm7, mm4
  216.     paddw     mm4, mm0
  217.     paddw     mm5, mm1
  218.     paddw     mm6, mm2
  219.     paddw     mm7, mm3
  220.     packuswb  mm4, mm5
  221.     packuswb  mm6, mm7
  222.     movq [r0+r1+0], mm4
  223.     movq [r0+r1+8], mm6
  224.     add        r0, r1
  225.     dec       r4d
  226.     jg .loop
  227.     REP_RET
  228. %endmacro
  229.  
  230. INIT_MMX mmx
  231. PRED16x16_TM
  232. INIT_MMX mmxext
  233. PRED16x16_TM
  234.  
  235. INIT_XMM sse2
  236. cglobal pred16x16_tm_vp8_8, 2,6,6
  237.     sub          r0, r1
  238.     pxor       xmm2, xmm2
  239.     movdqa     xmm0, [r0]
  240.     movdqa     xmm1, xmm0
  241.     punpcklbw  xmm0, xmm2
  242.     punpckhbw  xmm1, xmm2
  243.     movzx       r4d, byte [r0-1]
  244.     mov         r5d, 8
  245. .loop:
  246.     movzx       r2d, byte [r0+r1*1-1]
  247.     movzx       r3d, byte [r0+r1*2-1]
  248.     sub         r2d, r4d
  249.     sub         r3d, r4d
  250.     movd       xmm2, r2d
  251.     movd       xmm4, r3d
  252.     pshuflw    xmm2, xmm2, 0
  253.     pshuflw    xmm4, xmm4, 0
  254.     punpcklqdq xmm2, xmm2
  255.     punpcklqdq xmm4, xmm4
  256.     movdqa     xmm3, xmm2
  257.     movdqa     xmm5, xmm4
  258.     paddw      xmm2, xmm0
  259.     paddw      xmm3, xmm1
  260.     paddw      xmm4, xmm0
  261.     paddw      xmm5, xmm1
  262.     packuswb   xmm2, xmm3
  263.     packuswb   xmm4, xmm5
  264.     movdqa [r0+r1*1], xmm2
  265.     movdqa [r0+r1*2], xmm4
  266.     lea          r0, [r0+r1*2]
  267.     dec         r5d
  268.     jg .loop
  269.     REP_RET
  270.  
  271. ;-----------------------------------------------------------------------------
  272. ; void pred16x16_plane_*_8(uint8_t *src, int stride)
  273. ;-----------------------------------------------------------------------------
  274.  
  275. %macro H264_PRED16x16_PLANE 1
  276. cglobal pred16x16_plane_%1_8, 2,9,7
  277.     mov          r2, r1           ; +stride
  278.     neg          r1               ; -stride
  279.  
  280.     movh         m0, [r0+r1  -1]
  281. %if mmsize == 8
  282.     pxor         m4, m4
  283.     movh         m1, [r0+r1  +3 ]
  284.     movh         m2, [r0+r1  +8 ]
  285.     movh         m3, [r0+r1  +12]
  286.     punpcklbw    m0, m4
  287.     punpcklbw    m1, m4
  288.     punpcklbw    m2, m4
  289.     punpcklbw    m3, m4
  290.     pmullw       m0, [pw_m8tom1  ]
  291.     pmullw       m1, [pw_m8tom1+8]
  292.     pmullw       m2, [pw_1to8    ]
  293.     pmullw       m3, [pw_1to8  +8]
  294.     paddw        m0, m2
  295.     paddw        m1, m3
  296. %else ; mmsize == 16
  297. %if cpuflag(ssse3)
  298.     movhps       m0, [r0+r1  +8]
  299.     pmaddubsw    m0, [plane_shuf] ; H coefficients
  300. %else ; sse2
  301.     pxor         m2, m2
  302.     movh         m1, [r0+r1  +8]
  303.     punpcklbw    m0, m2
  304.     punpcklbw    m1, m2
  305.     pmullw       m0, [pw_m8tom1]
  306.     pmullw       m1, [pw_1to8]
  307.     paddw        m0, m1
  308. %endif
  309.     movhlps      m1, m0
  310. %endif
  311.     paddw        m0, m1
  312. %if cpuflag(mmxext)
  313.     PSHUFLW      m1, m0, 0xE
  314. %elif cpuflag(mmx)
  315.     mova         m1, m0
  316.     psrlq        m1, 32
  317. %endif
  318.     paddw        m0, m1
  319. %if cpuflag(mmxext)
  320.     PSHUFLW      m1, m0, 0x1
  321. %elif cpuflag(mmx)
  322.     mova         m1, m0
  323.     psrlq        m1, 16
  324. %endif
  325.     paddw        m0, m1           ; sum of H coefficients
  326.  
  327.     lea          r4, [r0+r2*8-1]
  328.     lea          r3, [r0+r2*4-1]
  329.     add          r4, r2
  330.  
  331. %if ARCH_X86_64
  332. %define e_reg r8
  333. %else
  334. %define e_reg r0
  335. %endif
  336.  
  337.     movzx     e_reg, byte [r3+r2*2   ]
  338.     movzx        r5, byte [r4+r1     ]
  339.     sub          r5, e_reg
  340.  
  341.     movzx     e_reg, byte [r3+r2     ]
  342.     movzx        r6, byte [r4        ]
  343.     sub          r6, e_reg
  344.     lea          r5, [r5+r6*2]
  345.  
  346.     movzx     e_reg, byte [r3+r1     ]
  347.     movzx        r6, byte [r4+r2*2   ]
  348.     sub          r6, e_reg
  349.     lea          r5, [r5+r6*4]
  350.  
  351.     movzx     e_reg, byte [r3        ]
  352. %if ARCH_X86_64
  353.     movzx        r7, byte [r4+r2     ]
  354.     sub          r7, e_reg
  355. %else
  356.     movzx        r6, byte [r4+r2     ]
  357.     sub          r6, e_reg
  358.     lea          r5, [r5+r6*4]
  359.     sub          r5, r6
  360. %endif
  361.  
  362.     lea       e_reg, [r3+r1*4]
  363.     lea          r3, [r4+r2*4]
  364.  
  365.     movzx        r4, byte [e_reg+r2  ]
  366.     movzx        r6, byte [r3        ]
  367.     sub          r6, r4
  368. %if ARCH_X86_64
  369.     lea          r6, [r7+r6*2]
  370.     lea          r5, [r5+r6*2]
  371.     add          r5, r6
  372. %else
  373.     lea          r5, [r5+r6*4]
  374.     lea          r5, [r5+r6*2]
  375. %endif
  376.  
  377.     movzx        r4, byte [e_reg     ]
  378. %if ARCH_X86_64
  379.     movzx        r7, byte [r3   +r2  ]
  380.     sub          r7, r4
  381.     sub          r5, r7
  382. %else
  383.     movzx        r6, byte [r3   +r2  ]
  384.     sub          r6, r4
  385.     lea          r5, [r5+r6*8]
  386.     sub          r5, r6
  387. %endif
  388.  
  389.     movzx        r4, byte [e_reg+r1  ]
  390.     movzx        r6, byte [r3   +r2*2]
  391.     sub          r6, r4
  392. %if ARCH_X86_64
  393.     add          r6, r7
  394. %endif
  395.     lea          r5, [r5+r6*8]
  396.  
  397.     movzx        r4, byte [e_reg+r2*2]
  398.     movzx        r6, byte [r3   +r1  ]
  399.     sub          r6, r4
  400.     lea          r5, [r5+r6*4]
  401.     add          r5, r6           ; sum of V coefficients
  402.  
  403. %if ARCH_X86_64 == 0
  404.     mov          r0, r0m
  405. %endif
  406.  
  407. %ifidn %1, h264
  408.     lea          r5, [r5*5+32]
  409.     sar          r5, 6
  410. %elifidn %1, rv40
  411.     lea          r5, [r5*5]
  412.     sar          r5, 6
  413. %elifidn %1, svq3
  414.     test         r5, r5
  415.     lea          r6, [r5+3]
  416.     cmovs        r5, r6
  417.     sar          r5, 2            ; V/4
  418.     lea          r5, [r5*5]       ; 5*(V/4)
  419.     test         r5, r5
  420.     lea          r6, [r5+15]
  421.     cmovs        r5, r6
  422.     sar          r5, 4            ; (5*(V/4))/16
  423. %endif
  424.  
  425.     movzx        r4, byte [r0+r1  +15]
  426.     movzx        r3, byte [r3+r2*2   ]
  427.     lea          r3, [r3+r4+1]
  428.     shl          r3, 4
  429.  
  430.     movd        r1d, m0
  431.     movsx       r1d, r1w
  432. %ifnidn %1, svq3
  433. %ifidn %1, h264
  434.     lea         r1d, [r1d*5+32]
  435. %else ; rv40
  436.     lea         r1d, [r1d*5]
  437. %endif
  438.     sar         r1d, 6
  439. %else ; svq3
  440.     test        r1d, r1d
  441.     lea         r4d, [r1d+3]
  442.     cmovs       r1d, r4d
  443.     sar         r1d, 2           ; H/4
  444.     lea         r1d, [r1d*5]     ; 5*(H/4)
  445.     test        r1d, r1d
  446.     lea         r4d, [r1d+15]
  447.     cmovs       r1d, r4d
  448.     sar         r1d, 4           ; (5*(H/4))/16
  449. %endif
  450.     movd         m0, r1d
  451.  
  452.     add         r1d, r5d
  453.     add         r3d, r1d
  454.     shl         r1d, 3
  455.     sub         r3d, r1d          ; a
  456.  
  457.     movd         m1, r5d
  458.     movd         m3, r3d
  459.     SPLATW       m0, m0, 0        ; H
  460.     SPLATW       m1, m1, 0        ; V
  461.     SPLATW       m3, m3, 0        ; a
  462. %ifidn %1, svq3
  463.     SWAP          0, 1
  464. %endif
  465.     mova         m2, m0
  466. %if mmsize == 8
  467.     mova         m5, m0
  468. %endif
  469.     pmullw       m0, [pw_0to7]    ; 0*H, 1*H, ..., 7*H  (words)
  470. %if mmsize == 16
  471.     psllw        m2, 3
  472. %else
  473.     psllw        m5, 3
  474.     psllw        m2, 2
  475.     mova         m6, m5
  476.     paddw        m6, m2
  477. %endif
  478.     paddw        m0, m3           ; a + {0,1,2,3,4,5,6,7}*H
  479.     paddw        m2, m0           ; a + {8,9,10,11,12,13,14,15}*H
  480. %if mmsize == 8
  481.     paddw        m5, m0           ; a + {8,9,10,11}*H
  482.     paddw        m6, m0           ; a + {12,13,14,15}*H
  483. %endif
  484.  
  485.     mov          r4, 8
  486. .loop:
  487.     mova         m3, m0           ; b[0..7]
  488.     mova         m4, m2           ; b[8..15]
  489.     psraw        m3, 5
  490.     psraw        m4, 5
  491.     packuswb     m3, m4
  492.     mova       [r0], m3
  493. %if mmsize == 8
  494.     mova         m3, m5           ; b[8..11]
  495.     mova         m4, m6           ; b[12..15]
  496.     psraw        m3, 5
  497.     psraw        m4, 5
  498.     packuswb     m3, m4
  499.     mova     [r0+8], m3
  500. %endif
  501.     paddw        m0, m1
  502.     paddw        m2, m1
  503. %if mmsize == 8
  504.     paddw        m5, m1
  505.     paddw        m6, m1
  506. %endif
  507.  
  508.     mova         m3, m0           ; b[0..7]
  509.     mova         m4, m2           ; b[8..15]
  510.     psraw        m3, 5
  511.     psraw        m4, 5
  512.     packuswb     m3, m4
  513.     mova    [r0+r2], m3
  514. %if mmsize == 8
  515.     mova         m3, m5           ; b[8..11]
  516.     mova         m4, m6           ; b[12..15]
  517.     psraw        m3, 5
  518.     psraw        m4, 5
  519.     packuswb     m3, m4
  520.     mova  [r0+r2+8], m3
  521. %endif
  522.     paddw        m0, m1
  523.     paddw        m2, m1
  524. %if mmsize == 8
  525.     paddw        m5, m1
  526.     paddw        m6, m1
  527. %endif
  528.  
  529.     lea          r0, [r0+r2*2]
  530.     dec          r4
  531.     jg .loop
  532.     REP_RET
  533. %endmacro
  534.  
  535. INIT_MMX mmx
  536. H264_PRED16x16_PLANE h264
  537. H264_PRED16x16_PLANE rv40
  538. H264_PRED16x16_PLANE svq3
  539. INIT_MMX mmxext
  540. H264_PRED16x16_PLANE h264
  541. H264_PRED16x16_PLANE rv40
  542. H264_PRED16x16_PLANE svq3
  543. INIT_XMM sse2
  544. H264_PRED16x16_PLANE h264
  545. H264_PRED16x16_PLANE rv40
  546. H264_PRED16x16_PLANE svq3
  547. INIT_XMM ssse3
  548. H264_PRED16x16_PLANE h264
  549. H264_PRED16x16_PLANE rv40
  550. H264_PRED16x16_PLANE svq3
  551.  
  552. ;-----------------------------------------------------------------------------
  553. ; void pred8x8_plane_8(uint8_t *src, int stride)
  554. ;-----------------------------------------------------------------------------
  555.  
  556. %macro H264_PRED8x8_PLANE 0
  557. cglobal pred8x8_plane_8, 2,9,7
  558.     mov          r2, r1           ; +stride
  559.     neg          r1               ; -stride
  560.  
  561.     movd         m0, [r0+r1  -1]
  562. %if mmsize == 8
  563.     pxor         m2, m2
  564.     movh         m1, [r0+r1  +4 ]
  565.     punpcklbw    m0, m2
  566.     punpcklbw    m1, m2
  567.     pmullw       m0, [pw_m4to4]
  568.     pmullw       m1, [pw_m4to4+8]
  569. %else ; mmsize == 16
  570. %if cpuflag(ssse3)
  571.     movhps       m0, [r0+r1  +4]   ; this reads 4 bytes more than necessary
  572.     pmaddubsw    m0, [plane8_shuf] ; H coefficients
  573. %else ; sse2
  574.     pxor         m2, m2
  575.     movd         m1, [r0+r1  +4]
  576.     punpckldq    m0, m1
  577.     punpcklbw    m0, m2
  578.     pmullw       m0, [pw_m4to4]
  579. %endif
  580.     movhlps      m1, m0
  581. %endif
  582.     paddw        m0, m1
  583.  
  584. %if notcpuflag(ssse3)
  585. %if cpuflag(mmxext)
  586.     PSHUFLW      m1, m0, 0xE
  587. %elif cpuflag(mmx)
  588.     mova         m1, m0
  589.     psrlq        m1, 32
  590. %endif
  591.     paddw        m0, m1
  592. %endif ; !ssse3
  593.  
  594. %if cpuflag(mmxext)
  595.     PSHUFLW      m1, m0, 0x1
  596. %elif cpuflag(mmx)
  597.     mova         m1, m0
  598.     psrlq        m1, 16
  599. %endif
  600.     paddw        m0, m1           ; sum of H coefficients
  601.  
  602.     lea          r4, [r0+r2*4-1]
  603.     lea          r3, [r0     -1]
  604.     add          r4, r2
  605.  
  606. %if ARCH_X86_64
  607. %define e_reg r8
  608. %else
  609. %define e_reg r0
  610. %endif
  611.  
  612.     movzx     e_reg, byte [r3+r2*2   ]
  613.     movzx        r5, byte [r4+r1     ]
  614.     sub          r5, e_reg
  615.  
  616.     movzx     e_reg, byte [r3        ]
  617. %if ARCH_X86_64
  618.     movzx        r7, byte [r4+r2     ]
  619.     sub          r7, e_reg
  620.     sub          r5, r7
  621. %else
  622.     movzx        r6, byte [r4+r2     ]
  623.     sub          r6, e_reg
  624.     lea          r5, [r5+r6*4]
  625.     sub          r5, r6
  626. %endif
  627.  
  628.     movzx     e_reg, byte [r3+r1     ]
  629.     movzx        r6, byte [r4+r2*2   ]
  630.     sub          r6, e_reg
  631. %if ARCH_X86_64
  632.     add          r6, r7
  633. %endif
  634.     lea          r5, [r5+r6*4]
  635.  
  636.     movzx     e_reg, byte [r3+r2     ]
  637.     movzx        r6, byte [r4        ]
  638.     sub          r6, e_reg
  639.     lea          r6, [r5+r6*2]
  640.  
  641.     lea          r5, [r6*9+16]
  642.     lea          r5, [r5+r6*8]
  643.     sar          r5, 5
  644.  
  645. %if ARCH_X86_64 == 0
  646.     mov          r0, r0m
  647. %endif
  648.  
  649.     movzx        r3, byte [r4+r2*2  ]
  650.     movzx        r4, byte [r0+r1  +7]
  651.     lea          r3, [r3+r4+1]
  652.     shl          r3, 4
  653.     movd        r1d, m0
  654.     movsx       r1d, r1w
  655.     imul        r1d, 17
  656.     add         r1d, 16
  657.     sar         r1d, 5
  658.     movd         m0, r1d
  659.     add         r1d, r5d
  660.     sub         r3d, r1d
  661.     add         r1d, r1d
  662.     sub         r3d, r1d          ; a
  663.  
  664.     movd         m1, r5d
  665.     movd         m3, r3d
  666.     SPLATW       m0, m0, 0        ; H
  667.     SPLATW       m1, m1, 0        ; V
  668.     SPLATW       m3, m3, 0        ; a
  669. %if mmsize == 8
  670.     mova         m2, m0
  671. %endif
  672.     pmullw       m0, [pw_0to7]    ; 0*H, 1*H, ..., 7*H  (words)
  673.     paddw        m0, m3           ; a + {0,1,2,3,4,5,6,7}*H
  674. %if mmsize == 8
  675.     psllw        m2, 2
  676.     paddw        m2, m0           ; a + {4,5,6,7}*H
  677. %endif
  678.  
  679.     mov          r4, 4
  680. ALIGN 16
  681. .loop:
  682. %if mmsize == 16
  683.     mova         m3, m0           ; b[0..7]
  684.     paddw        m0, m1
  685.     psraw        m3, 5
  686.     mova         m4, m0           ; V+b[0..7]
  687.     paddw        m0, m1
  688.     psraw        m4, 5
  689.     packuswb     m3, m4
  690.     movh       [r0], m3
  691.     movhps  [r0+r2], m3
  692. %else ; mmsize == 8
  693.     mova         m3, m0           ; b[0..3]
  694.     mova         m4, m2           ; b[4..7]
  695.     paddw        m0, m1
  696.     paddw        m2, m1
  697.     psraw        m3, 5
  698.     psraw        m4, 5
  699.     mova         m5, m0           ; V+b[0..3]
  700.     mova         m6, m2           ; V+b[4..7]
  701.     paddw        m0, m1
  702.     paddw        m2, m1
  703.     psraw        m5, 5
  704.     psraw        m6, 5
  705.     packuswb     m3, m4
  706.     packuswb     m5, m6
  707.     mova       [r0], m3
  708.     mova    [r0+r2], m5
  709. %endif
  710.  
  711.     lea          r0, [r0+r2*2]
  712.     dec          r4
  713.     jg .loop
  714.     REP_RET
  715. %endmacro
  716.  
  717. INIT_MMX mmx
  718. H264_PRED8x8_PLANE
  719. INIT_MMX mmxext
  720. H264_PRED8x8_PLANE
  721. INIT_XMM sse2
  722. H264_PRED8x8_PLANE
  723. INIT_XMM ssse3
  724. H264_PRED8x8_PLANE
  725.  
  726. ;-----------------------------------------------------------------------------
  727. ; void pred8x8_vertical_8(uint8_t *src, int stride)
  728. ;-----------------------------------------------------------------------------
  729.  
  730. INIT_MMX mmx
  731. cglobal pred8x8_vertical_8, 2,2
  732.     sub    r0, r1
  733.     movq  mm0, [r0]
  734. %rep 3
  735.     movq [r0+r1*1], mm0
  736.     movq [r0+r1*2], mm0
  737.     lea    r0, [r0+r1*2]
  738. %endrep
  739.     movq [r0+r1*1], mm0
  740.     movq [r0+r1*2], mm0
  741.     RET
  742.  
  743. ;-----------------------------------------------------------------------------
  744. ; void pred8x8_horizontal_8(uint8_t *src, int stride)
  745. ;-----------------------------------------------------------------------------
  746.  
  747. %macro PRED8x8_H 0
  748. cglobal pred8x8_horizontal_8, 2,3
  749.     mov       r2, 4
  750. %if cpuflag(ssse3)
  751.     mova      m2, [pb_3]
  752. %endif
  753. .loop:
  754.     SPLATB_LOAD m0, r0+r1*0-1, m2
  755.     SPLATB_LOAD m1, r0+r1*1-1, m2
  756.     mova [r0+r1*0], m0
  757.     mova [r0+r1*1], m1
  758.     lea       r0, [r0+r1*2]
  759.     dec       r2
  760.     jg .loop
  761.     REP_RET
  762. %endmacro
  763.  
  764. INIT_MMX mmx
  765. PRED8x8_H
  766. INIT_MMX mmxext
  767. PRED8x8_H
  768. INIT_MMX ssse3
  769. PRED8x8_H
  770.  
  771. ;-----------------------------------------------------------------------------
  772. ; void pred8x8_top_dc_8_mmxext(uint8_t *src, int stride)
  773. ;-----------------------------------------------------------------------------
  774. INIT_MMX mmxext
  775. cglobal pred8x8_top_dc_8, 2,5
  776.     sub         r0, r1
  777.     movq       mm0, [r0]
  778.     pxor       mm1, mm1
  779.     pxor       mm2, mm2
  780.     lea         r2, [r0+r1*2]
  781.     punpckhbw  mm1, mm0
  782.     punpcklbw  mm0, mm2
  783.     psadbw     mm1, mm2        ; s1
  784.     lea         r3, [r2+r1*2]
  785.     psadbw     mm0, mm2        ; s0
  786.     psrlw      mm1, 1
  787.     psrlw      mm0, 1
  788.     pavgw      mm1, mm2
  789.     lea         r4, [r3+r1*2]
  790.     pavgw      mm0, mm2
  791.     pshufw     mm1, mm1, 0
  792.     pshufw     mm0, mm0, 0     ; dc0 (w)
  793.     packuswb   mm0, mm1        ; dc0,dc1 (b)
  794.     movq [r0+r1*1], mm0
  795.     movq [r0+r1*2], mm0
  796.     lea         r0, [r3+r1*2]
  797.     movq [r2+r1*1], mm0
  798.     movq [r2+r1*2], mm0
  799.     movq [r3+r1*1], mm0
  800.     movq [r3+r1*2], mm0
  801.     movq [r0+r1*1], mm0
  802.     movq [r0+r1*2], mm0
  803.     RET
  804.  
  805. ;-----------------------------------------------------------------------------
  806. ; void pred8x8_dc_8_mmxext(uint8_t *src, int stride)
  807. ;-----------------------------------------------------------------------------
  808.  
  809. INIT_MMX mmxext
  810. cglobal pred8x8_dc_8, 2,5
  811.     sub       r0, r1
  812.     pxor      m7, m7
  813.     movd      m0, [r0+0]
  814.     movd      m1, [r0+4]
  815.     psadbw    m0, m7            ; s0
  816.     mov       r4, r0
  817.     psadbw    m1, m7            ; s1
  818.  
  819.     movzx    r2d, byte [r0+r1*1-1]
  820.     movzx    r3d, byte [r0+r1*2-1]
  821.     lea       r0, [r0+r1*2]
  822.     add      r2d, r3d
  823.     movzx    r3d, byte [r0+r1*1-1]
  824.     add      r2d, r3d
  825.     movzx    r3d, byte [r0+r1*2-1]
  826.     add      r2d, r3d
  827.     lea       r0, [r0+r1*2]
  828.     movd      m2, r2d            ; s2
  829.     movzx    r2d, byte [r0+r1*1-1]
  830.     movzx    r3d, byte [r0+r1*2-1]
  831.     lea       r0, [r0+r1*2]
  832.     add      r2d, r3d
  833.     movzx    r3d, byte [r0+r1*1-1]
  834.     add      r2d, r3d
  835.     movzx    r3d, byte [r0+r1*2-1]
  836.     add      r2d, r3d
  837.     movd      m3, r2d            ; s3
  838.  
  839.     punpcklwd m0, m1
  840.     mov       r0, r4
  841.     punpcklwd m2, m3
  842.     punpckldq m0, m2            ; s0, s1, s2, s3
  843.     pshufw    m3, m0, 11110110b ; s2, s1, s3, s3
  844.     lea       r2, [r0+r1*2]
  845.     pshufw    m0, m0, 01110100b ; s0, s1, s3, s1
  846.     paddw     m0, m3
  847.     lea       r3, [r2+r1*2]
  848.     psrlw     m0, 2
  849.     pavgw     m0, m7            ; s0+s2, s1, s3, s1+s3
  850.     lea       r4, [r3+r1*2]
  851.     packuswb  m0, m0
  852.     punpcklbw m0, m0
  853.     movq      m1, m0
  854.     punpcklbw m0, m0
  855.     punpckhbw m1, m1
  856.     movq [r0+r1*1], m0
  857.     movq [r0+r1*2], m0
  858.     movq [r2+r1*1], m0
  859.     movq [r2+r1*2], m0
  860.     movq [r3+r1*1], m1
  861.     movq [r3+r1*2], m1
  862.     movq [r4+r1*1], m1
  863.     movq [r4+r1*2], m1
  864.     RET
  865.  
  866. ;-----------------------------------------------------------------------------
  867. ; void pred8x8_dc_rv40_8(uint8_t *src, int stride)
  868. ;-----------------------------------------------------------------------------
  869.  
  870. INIT_MMX mmxext
  871. cglobal pred8x8_dc_rv40_8, 2,7
  872.     mov       r4, r0
  873.     sub       r0, r1
  874.     pxor      mm0, mm0
  875.     psadbw    mm0, [r0]
  876.     dec        r0
  877.     movzx     r5d, byte [r0+r1*1]
  878.     movd      r6d, mm0
  879.     lea        r0, [r0+r1*2]
  880. %rep 3
  881.     movzx     r2d, byte [r0+r1*0]
  882.     movzx     r3d, byte [r0+r1*1]
  883.     add       r5d, r2d
  884.     add       r6d, r3d
  885.     lea        r0, [r0+r1*2]
  886. %endrep
  887.     movzx     r2d, byte [r0+r1*0]
  888.     add       r5d, r6d
  889.     lea       r2d, [r2+r5+8]
  890.     shr       r2d, 4
  891.     movd      mm0, r2d
  892.     punpcklbw mm0, mm0
  893.     pshufw    mm0, mm0, 0
  894.     mov       r3d, 4
  895. .loop:
  896.     movq [r4+r1*0], mm0
  897.     movq [r4+r1*1], mm0
  898.     lea   r4, [r4+r1*2]
  899.     dec   r3d
  900.     jg .loop
  901.     REP_RET
  902.  
  903. ;-----------------------------------------------------------------------------
  904. ; void pred8x8_tm_vp8_8(uint8_t *src, int stride)
  905. ;-----------------------------------------------------------------------------
  906.  
  907. %macro PRED8x8_TM 0
  908. cglobal pred8x8_tm_vp8_8, 2,6
  909.     sub        r0, r1
  910.     pxor      mm7, mm7
  911.     movq      mm0, [r0]
  912.     movq      mm1, mm0
  913.     punpcklbw mm0, mm7
  914.     punpckhbw mm1, mm7
  915.     movzx     r4d, byte [r0-1]
  916.     mov       r5d, 4
  917. .loop:
  918.     movzx     r2d, byte [r0+r1*1-1]
  919.     movzx     r3d, byte [r0+r1*2-1]
  920.     sub       r2d, r4d
  921.     sub       r3d, r4d
  922.     movd      mm2, r2d
  923.     movd      mm4, r3d
  924.     SPLATW    mm2, mm2, 0
  925.     SPLATW    mm4, mm4, 0
  926.     movq      mm3, mm2
  927.     movq      mm5, mm4
  928.     paddw     mm2, mm0
  929.     paddw     mm3, mm1
  930.     paddw     mm4, mm0
  931.     paddw     mm5, mm1
  932.     packuswb  mm2, mm3
  933.     packuswb  mm4, mm5
  934.     movq [r0+r1*1], mm2
  935.     movq [r0+r1*2], mm4
  936.     lea        r0, [r0+r1*2]
  937.     dec       r5d
  938.     jg .loop
  939.     REP_RET
  940. %endmacro
  941.  
  942. INIT_MMX mmx
  943. PRED8x8_TM
  944. INIT_MMX mmxext
  945. PRED8x8_TM
  946.  
  947. INIT_XMM sse2
  948. cglobal pred8x8_tm_vp8_8, 2,6,4
  949.     sub          r0, r1
  950.     pxor       xmm1, xmm1
  951.     movq       xmm0, [r0]
  952.     punpcklbw  xmm0, xmm1
  953.     movzx       r4d, byte [r0-1]
  954.     mov         r5d, 4
  955. .loop:
  956.     movzx       r2d, byte [r0+r1*1-1]
  957.     movzx       r3d, byte [r0+r1*2-1]
  958.     sub         r2d, r4d
  959.     sub         r3d, r4d
  960.     movd       xmm2, r2d
  961.     movd       xmm3, r3d
  962.     pshuflw    xmm2, xmm2, 0
  963.     pshuflw    xmm3, xmm3, 0
  964.     punpcklqdq xmm2, xmm2
  965.     punpcklqdq xmm3, xmm3
  966.     paddw      xmm2, xmm0
  967.     paddw      xmm3, xmm0
  968.     packuswb   xmm2, xmm3
  969.     movq   [r0+r1*1], xmm2
  970.     movhps [r0+r1*2], xmm2
  971.     lea          r0, [r0+r1*2]
  972.     dec         r5d
  973.     jg .loop
  974.     REP_RET
  975.  
  976. INIT_XMM ssse3
  977. cglobal pred8x8_tm_vp8_8, 2,3,6
  978.     sub          r0, r1
  979.     movdqa     xmm4, [tm_shuf]
  980.     pxor       xmm1, xmm1
  981.     movq       xmm0, [r0]
  982.     punpcklbw  xmm0, xmm1
  983.     movd       xmm5, [r0-4]
  984.     pshufb     xmm5, xmm4
  985.     mov         r2d, 4
  986. .loop:
  987.     movd       xmm2, [r0+r1*1-4]
  988.     movd       xmm3, [r0+r1*2-4]
  989.     pshufb     xmm2, xmm4
  990.     pshufb     xmm3, xmm4
  991.     psubw      xmm2, xmm5
  992.     psubw      xmm3, xmm5
  993.     paddw      xmm2, xmm0
  994.     paddw      xmm3, xmm0
  995.     packuswb   xmm2, xmm3
  996.     movq   [r0+r1*1], xmm2
  997.     movhps [r0+r1*2], xmm2
  998.     lea          r0, [r0+r1*2]
  999.     dec         r2d
  1000.     jg .loop
  1001.     REP_RET
  1002.  
  1003. ; dest, left, right, src, tmp
  1004. ; output: %1 = (t[n-1] + t[n]*2 + t[n+1] + 2) >> 2
  1005. %macro PRED4x4_LOWPASS 5
  1006.     mova    %5, %2
  1007.     pavgb   %2, %3
  1008.     pxor    %3, %5
  1009.     mova    %1, %4
  1010.     pand    %3, [pb_1]
  1011.     psubusb %2, %3
  1012.     pavgb   %1, %2
  1013. %endmacro
  1014.  
  1015. ;-----------------------------------------------------------------------------
  1016. ; void pred8x8l_top_dc_8(uint8_t *src, int has_topleft, int has_topright, int stride)
  1017. ;-----------------------------------------------------------------------------
  1018. %macro PRED8x8L_TOP_DC 0
  1019. cglobal pred8x8l_top_dc_8, 4,4
  1020.     sub          r0, r3
  1021.     pxor        mm7, mm7
  1022.     movq        mm0, [r0-8]
  1023.     movq        mm3, [r0]
  1024.     movq        mm1, [r0+8]
  1025.     movq        mm2, mm3
  1026.     movq        mm4, mm3
  1027.     PALIGNR     mm2, mm0, 7, mm0
  1028.     PALIGNR     mm1, mm4, 1, mm4
  1029.     test         r1, r1 ; top_left
  1030.     jz .fix_lt_2
  1031.     test         r2, r2 ; top_right
  1032.     jz .fix_tr_1
  1033.     jmp .body
  1034. .fix_lt_2:
  1035.     movq        mm5, mm3
  1036.     pxor        mm5, mm2
  1037.     psllq       mm5, 56
  1038.     psrlq       mm5, 56
  1039.     pxor        mm2, mm5
  1040.     test         r2, r2 ; top_right
  1041.     jnz .body
  1042. .fix_tr_1:
  1043.     movq        mm5, mm3
  1044.     pxor        mm5, mm1
  1045.     psrlq       mm5, 56
  1046.     psllq       mm5, 56
  1047.     pxor        mm1, mm5
  1048. .body:
  1049.     PRED4x4_LOWPASS mm0, mm2, mm1, mm3, mm5
  1050.     psadbw   mm7, mm0
  1051.     paddw    mm7, [pw_4]
  1052.     psrlw    mm7, 3
  1053.     pshufw   mm7, mm7, 0
  1054.     packuswb mm7, mm7
  1055. %rep 3
  1056.     movq [r0+r3*1], mm7
  1057.     movq [r0+r3*2], mm7
  1058.     lea    r0, [r0+r3*2]
  1059. %endrep
  1060.     movq [r0+r3*1], mm7
  1061.     movq [r0+r3*2], mm7
  1062.     RET
  1063. %endmacro
  1064.  
  1065. INIT_MMX mmxext
  1066. PRED8x8L_TOP_DC
  1067. INIT_MMX ssse3
  1068. PRED8x8L_TOP_DC
  1069.  
  1070. ;-----------------------------------------------------------------------------
  1071. ;void pred8x8l_dc_8(uint8_t *src, int has_topleft, int has_topright, int stride)
  1072. ;-----------------------------------------------------------------------------
  1073.  
  1074. %macro PRED8x8L_DC 0
  1075. cglobal pred8x8l_dc_8, 4,5
  1076.     sub          r0, r3
  1077.     lea          r4, [r0+r3*2]
  1078.     movq        mm0, [r0+r3*1-8]
  1079.     punpckhbw   mm0, [r0+r3*0-8]
  1080.     movq        mm1, [r4+r3*1-8]
  1081.     punpckhbw   mm1, [r0+r3*2-8]
  1082.     mov          r4, r0
  1083.     punpckhwd   mm1, mm0
  1084.     lea          r0, [r0+r3*4]
  1085.     movq        mm2, [r0+r3*1-8]
  1086.     punpckhbw   mm2, [r0+r3*0-8]
  1087.     lea          r0, [r0+r3*2]
  1088.     movq        mm3, [r0+r3*1-8]
  1089.     punpckhbw   mm3, [r0+r3*0-8]
  1090.     punpckhwd   mm3, mm2
  1091.     punpckhdq   mm3, mm1
  1092.     lea          r0, [r0+r3*2]
  1093.     movq        mm0, [r0+r3*0-8]
  1094.     movq        mm1, [r4]
  1095.     mov          r0, r4
  1096.     movq        mm4, mm3
  1097.     movq        mm2, mm3
  1098.     PALIGNR     mm4, mm0, 7, mm0
  1099.     PALIGNR     mm1, mm2, 1, mm2
  1100.     test        r1, r1
  1101.     jnz .do_left
  1102. .fix_lt_1:
  1103.     movq        mm5, mm3
  1104.     pxor        mm5, mm4
  1105.     psrlq       mm5, 56
  1106.     psllq       mm5, 48
  1107.     pxor        mm1, mm5
  1108.     jmp .do_left
  1109. .fix_lt_2:
  1110.     movq        mm5, mm3
  1111.     pxor        mm5, mm2
  1112.     psllq       mm5, 56
  1113.     psrlq       mm5, 56
  1114.     pxor        mm2, mm5
  1115.     test         r2, r2
  1116.     jnz .body
  1117. .fix_tr_1:
  1118.     movq        mm5, mm3
  1119.     pxor        mm5, mm1
  1120.     psrlq       mm5, 56
  1121.     psllq       mm5, 56
  1122.     pxor        mm1, mm5
  1123.     jmp .body
  1124. .do_left:
  1125.     movq        mm0, mm4
  1126.     PRED4x4_LOWPASS mm2, mm1, mm4, mm3, mm5
  1127.     movq        mm4, mm0
  1128.     movq        mm7, mm2
  1129.     PRED4x4_LOWPASS mm1, mm3, mm0, mm4, mm5
  1130.     psllq       mm1, 56
  1131.     PALIGNR     mm7, mm1, 7, mm3
  1132.     movq        mm0, [r0-8]
  1133.     movq        mm3, [r0]
  1134.     movq        mm1, [r0+8]
  1135.     movq        mm2, mm3
  1136.     movq        mm4, mm3
  1137.     PALIGNR     mm2, mm0, 7, mm0
  1138.     PALIGNR     mm1, mm4, 1, mm4
  1139.     test         r1, r1
  1140.     jz .fix_lt_2
  1141.     test         r2, r2
  1142.     jz .fix_tr_1
  1143. .body:
  1144.     lea          r1, [r0+r3*2]
  1145.     PRED4x4_LOWPASS mm6, mm2, mm1, mm3, mm5
  1146.     pxor        mm0, mm0
  1147.     pxor        mm1, mm1
  1148.     lea          r2, [r1+r3*2]
  1149.     psadbw      mm0, mm7
  1150.     psadbw      mm1, mm6
  1151.     paddw       mm0, [pw_8]
  1152.     paddw       mm0, mm1
  1153.     lea          r4, [r2+r3*2]
  1154.     psrlw       mm0, 4
  1155.     pshufw      mm0, mm0, 0
  1156.     packuswb    mm0, mm0
  1157.     movq [r0+r3*1], mm0
  1158.     movq [r0+r3*2], mm0
  1159.     movq [r1+r3*1], mm0
  1160.     movq [r1+r3*2], mm0
  1161.     movq [r2+r3*1], mm0
  1162.     movq [r2+r3*2], mm0
  1163.     movq [r4+r3*1], mm0
  1164.     movq [r4+r3*2], mm0
  1165.     RET
  1166. %endmacro
  1167.  
  1168. INIT_MMX mmxext
  1169. PRED8x8L_DC
  1170. INIT_MMX ssse3
  1171. PRED8x8L_DC
  1172.  
  1173. ;-----------------------------------------------------------------------------
  1174. ; void pred8x8l_horizontal_8(uint8_t *src, int has_topleft, int has_topright, int stride)
  1175. ;-----------------------------------------------------------------------------
  1176.  
  1177. %macro PRED8x8L_HORIZONTAL 0
  1178. cglobal pred8x8l_horizontal_8, 4,4
  1179.     sub          r0, r3
  1180.     lea          r2, [r0+r3*2]
  1181.     movq        mm0, [r0+r3*1-8]
  1182.     test         r1, r1
  1183.     lea          r1, [r0+r3]
  1184.     cmovnz       r1, r0
  1185.     punpckhbw   mm0, [r1+r3*0-8]
  1186.     movq        mm1, [r2+r3*1-8]
  1187.     punpckhbw   mm1, [r0+r3*2-8]
  1188.     mov          r2, r0
  1189.     punpckhwd   mm1, mm0
  1190.     lea          r0, [r0+r3*4]
  1191.     movq        mm2, [r0+r3*1-8]
  1192.     punpckhbw   mm2, [r0+r3*0-8]
  1193.     lea          r0, [r0+r3*2]
  1194.     movq        mm3, [r0+r3*1-8]
  1195.     punpckhbw   mm3, [r0+r3*0-8]
  1196.     punpckhwd   mm3, mm2
  1197.     punpckhdq   mm3, mm1
  1198.     lea          r0, [r0+r3*2]
  1199.     movq        mm0, [r0+r3*0-8]
  1200.     movq        mm1, [r1+r3*0-8]
  1201.     mov          r0, r2
  1202.     movq        mm4, mm3
  1203.     movq        mm2, mm3
  1204.     PALIGNR     mm4, mm0, 7, mm0
  1205.     PALIGNR     mm1, mm2, 1, mm2
  1206.     movq        mm0, mm4
  1207.     PRED4x4_LOWPASS mm2, mm1, mm4, mm3, mm5
  1208.     movq        mm4, mm0
  1209.     movq        mm7, mm2
  1210.     PRED4x4_LOWPASS mm1, mm3, mm0, mm4, mm5
  1211.     psllq       mm1, 56
  1212.     PALIGNR     mm7, mm1, 7, mm3
  1213.     movq        mm3, mm7
  1214.     lea         r1, [r0+r3*2]
  1215.     movq       mm7, mm3
  1216.     punpckhbw  mm3, mm3
  1217.     punpcklbw  mm7, mm7
  1218.     pshufw     mm0, mm3, 0xff
  1219.     pshufw     mm1, mm3, 0xaa
  1220.     lea         r2, [r1+r3*2]
  1221.     pshufw     mm2, mm3, 0x55
  1222.     pshufw     mm3, mm3, 0x00
  1223.     pshufw     mm4, mm7, 0xff
  1224.     pshufw     mm5, mm7, 0xaa
  1225.     pshufw     mm6, mm7, 0x55
  1226.     pshufw     mm7, mm7, 0x00
  1227.     movq [r0+r3*1], mm0
  1228.     movq [r0+r3*2], mm1
  1229.     movq [r1+r3*1], mm2
  1230.     movq [r1+r3*2], mm3
  1231.     movq [r2+r3*1], mm4
  1232.     movq [r2+r3*2], mm5
  1233.     lea         r0, [r2+r3*2]
  1234.     movq [r0+r3*1], mm6
  1235.     movq [r0+r3*2], mm7
  1236.     RET
  1237. %endmacro
  1238.  
  1239. INIT_MMX mmxext
  1240. PRED8x8L_HORIZONTAL
  1241. INIT_MMX ssse3
  1242. PRED8x8L_HORIZONTAL
  1243.  
  1244. ;-----------------------------------------------------------------------------
  1245. ; void pred8x8l_vertical_8(uint8_t *src, int has_topleft, int has_topright, int stride)
  1246. ;-----------------------------------------------------------------------------
  1247.  
  1248. %macro PRED8x8L_VERTICAL 0
  1249. cglobal pred8x8l_vertical_8, 4,4
  1250.     sub          r0, r3
  1251.     movq        mm0, [r0-8]
  1252.     movq        mm3, [r0]
  1253.     movq        mm1, [r0+8]
  1254.     movq        mm2, mm3
  1255.     movq        mm4, mm3
  1256.     PALIGNR     mm2, mm0, 7, mm0
  1257.     PALIGNR     mm1, mm4, 1, mm4
  1258.     test         r1, r1 ; top_left
  1259.     jz .fix_lt_2
  1260.     test         r2, r2 ; top_right
  1261.     jz .fix_tr_1
  1262.     jmp .body
  1263. .fix_lt_2:
  1264.     movq        mm5, mm3
  1265.     pxor        mm5, mm2
  1266.     psllq       mm5, 56
  1267.     psrlq       mm5, 56
  1268.     pxor        mm2, mm5
  1269.     test         r2, r2 ; top_right
  1270.     jnz .body
  1271. .fix_tr_1:
  1272.     movq        mm5, mm3
  1273.     pxor        mm5, mm1
  1274.     psrlq       mm5, 56
  1275.     psllq       mm5, 56
  1276.     pxor        mm1, mm5
  1277. .body:
  1278.     PRED4x4_LOWPASS mm0, mm2, mm1, mm3, mm5
  1279. %rep 3
  1280.     movq [r0+r3*1], mm0
  1281.     movq [r0+r3*2], mm0
  1282.     lea    r0, [r0+r3*2]
  1283. %endrep
  1284.     movq [r0+r3*1], mm0
  1285.     movq [r0+r3*2], mm0
  1286.     RET
  1287. %endmacro
  1288.  
  1289. INIT_MMX mmxext
  1290. PRED8x8L_VERTICAL
  1291. INIT_MMX ssse3
  1292. PRED8x8L_VERTICAL
  1293.  
  1294. ;-----------------------------------------------------------------------------
  1295. ;void pred8x8l_down_left_8(uint8_t *src, int has_topleft, int has_topright, int stride)
  1296. ;-----------------------------------------------------------------------------
  1297.  
  1298. INIT_MMX mmxext
  1299. cglobal pred8x8l_down_left_8, 4,5
  1300.     sub          r0, r3
  1301.     movq        mm0, [r0-8]
  1302.     movq        mm3, [r0]
  1303.     movq        mm1, [r0+8]
  1304.     movq        mm2, mm3
  1305.     movq        mm4, mm3
  1306.     PALIGNR     mm2, mm0, 7, mm0
  1307.     PALIGNR     mm1, mm4, 1, mm4
  1308.     test         r1, r1
  1309.     jz .fix_lt_2
  1310.     test         r2, r2
  1311.     jz .fix_tr_1
  1312.     jmp .do_top
  1313. .fix_lt_2:
  1314.     movq        mm5, mm3
  1315.     pxor        mm5, mm2
  1316.     psllq       mm5, 56
  1317.     psrlq       mm5, 56
  1318.     pxor        mm2, mm5
  1319.     test         r2, r2
  1320.     jnz .do_top
  1321. .fix_tr_1:
  1322.     movq        mm5, mm3
  1323.     pxor        mm5, mm1
  1324.     psrlq       mm5, 56
  1325.     psllq       mm5, 56
  1326.     pxor        mm1, mm5
  1327.     jmp .do_top
  1328. .fix_tr_2:
  1329.     punpckhbw   mm3, mm3
  1330.     pshufw      mm1, mm3, 0xFF
  1331.     jmp .do_topright
  1332. .do_top:
  1333.     PRED4x4_LOWPASS mm4, mm2, mm1, mm3, mm5
  1334.     movq        mm7, mm4
  1335.     test         r2, r2
  1336.     jz .fix_tr_2
  1337.     movq        mm0, [r0+8]
  1338.     movq        mm5, mm0
  1339.     movq        mm2, mm0
  1340.     movq        mm4, mm0
  1341.     psrlq       mm5, 56
  1342.     PALIGNR     mm2, mm3, 7, mm3
  1343.     PALIGNR     mm5, mm4, 1, mm4
  1344.     PRED4x4_LOWPASS mm1, mm2, mm5, mm0, mm4
  1345. .do_topright:
  1346.     lea          r1, [r0+r3*2]
  1347.     movq        mm6, mm1
  1348.     psrlq       mm1, 56
  1349.     movq        mm4, mm1
  1350.     lea          r2, [r1+r3*2]
  1351.     movq        mm2, mm6
  1352.     PALIGNR     mm2, mm7, 1, mm0
  1353.     movq        mm3, mm6
  1354.     PALIGNR     mm3, mm7, 7, mm0
  1355.     PALIGNR     mm4, mm6, 1, mm0
  1356.     movq        mm5, mm7
  1357.     movq        mm1, mm7
  1358.     movq        mm7, mm6
  1359.     lea          r4, [r2+r3*2]
  1360.     psllq       mm1, 8
  1361.     PRED4x4_LOWPASS mm0, mm1, mm2, mm5, mm6
  1362.     PRED4x4_LOWPASS mm1, mm3, mm4, mm7, mm6
  1363.     movq  [r4+r3*2], mm1
  1364.     movq        mm2, mm0
  1365.     psllq       mm1, 8
  1366.     psrlq       mm2, 56
  1367.     psllq       mm0, 8
  1368.     por         mm1, mm2
  1369.     movq  [r4+r3*1], mm1
  1370.     movq        mm2, mm0
  1371.     psllq       mm1, 8
  1372.     psrlq       mm2, 56
  1373.     psllq       mm0, 8
  1374.     por         mm1, mm2
  1375.     movq  [r2+r3*2], mm1
  1376.     movq        mm2, mm0
  1377.     psllq       mm1, 8
  1378.     psrlq       mm2, 56
  1379.     psllq       mm0, 8
  1380.     por         mm1, mm2
  1381.     movq  [r2+r3*1], mm1
  1382.     movq        mm2, mm0
  1383.     psllq       mm1, 8
  1384.     psrlq       mm2, 56
  1385.     psllq       mm0, 8
  1386.     por         mm1, mm2
  1387.     movq  [r1+r3*2], mm1
  1388.     movq        mm2, mm0
  1389.     psllq       mm1, 8
  1390.     psrlq       mm2, 56
  1391.     psllq       mm0, 8
  1392.     por         mm1, mm2
  1393.     movq  [r1+r3*1], mm1
  1394.     movq        mm2, mm0
  1395.     psllq       mm1, 8
  1396.     psrlq       mm2, 56
  1397.     psllq       mm0, 8
  1398.     por         mm1, mm2
  1399.     movq  [r0+r3*2], mm1
  1400.     psllq       mm1, 8
  1401.     psrlq       mm0, 56
  1402.     por         mm1, mm0
  1403.     movq  [r0+r3*1], mm1
  1404.     RET
  1405.  
  1406. %macro PRED8x8L_DOWN_LEFT 0
  1407. cglobal pred8x8l_down_left_8, 4,4
  1408.     sub          r0, r3
  1409.     movq        mm0, [r0-8]
  1410.     movq        mm3, [r0]
  1411.     movq        mm1, [r0+8]
  1412.     movq        mm2, mm3
  1413.     movq        mm4, mm3
  1414.     PALIGNR     mm2, mm0, 7, mm0
  1415.     PALIGNR     mm1, mm4, 1, mm4
  1416.     test         r1, r1 ; top_left
  1417.     jz .fix_lt_2
  1418.     test         r2, r2 ; top_right
  1419.     jz .fix_tr_1
  1420.     jmp .do_top
  1421. .fix_lt_2:
  1422.     movq        mm5, mm3
  1423.     pxor        mm5, mm2
  1424.     psllq       mm5, 56
  1425.     psrlq       mm5, 56
  1426.     pxor        mm2, mm5
  1427.     test         r2, r2 ; top_right
  1428.     jnz .do_top
  1429. .fix_tr_1:
  1430.     movq        mm5, mm3
  1431.     pxor        mm5, mm1
  1432.     psrlq       mm5, 56
  1433.     psllq       mm5, 56
  1434.     pxor        mm1, mm5
  1435.     jmp .do_top
  1436. .fix_tr_2:
  1437.     punpckhbw   mm3, mm3
  1438.     pshufw      mm1, mm3, 0xFF
  1439.     jmp .do_topright
  1440. .do_top:
  1441.     PRED4x4_LOWPASS mm4, mm2, mm1, mm3, mm5
  1442.     movq2dq    xmm3, mm4
  1443.     test         r2, r2 ; top_right
  1444.     jz .fix_tr_2
  1445.     movq        mm0, [r0+8]
  1446.     movq        mm5, mm0
  1447.     movq        mm2, mm0
  1448.     movq        mm4, mm0
  1449.     psrlq       mm5, 56
  1450.     PALIGNR     mm2, mm3, 7, mm3
  1451.     PALIGNR     mm5, mm4, 1, mm4
  1452.     PRED4x4_LOWPASS mm1, mm2, mm5, mm0, mm4
  1453. .do_topright:
  1454.     movq2dq    xmm4, mm1
  1455.     psrlq       mm1, 56
  1456.     movq2dq    xmm5, mm1
  1457.     lea         r1, [r0+r3*2]
  1458.     pslldq    xmm4, 8
  1459.     por       xmm3, xmm4
  1460.     movdqa    xmm2, xmm3
  1461.     psrldq    xmm2, 1
  1462.     pslldq    xmm5, 15
  1463.     por       xmm2, xmm5
  1464.     lea         r2, [r1+r3*2]
  1465.     movdqa    xmm1, xmm3
  1466.     pslldq    xmm1, 1
  1467. INIT_XMM cpuname
  1468.     PRED4x4_LOWPASS xmm0, xmm1, xmm2, xmm3, xmm4
  1469.     psrldq    xmm0, 1
  1470.     movq [r0+r3*1], xmm0
  1471.     psrldq    xmm0, 1
  1472.     movq [r0+r3*2], xmm0
  1473.     psrldq    xmm0, 1
  1474.     lea         r0, [r2+r3*2]
  1475.     movq [r1+r3*1], xmm0
  1476.     psrldq    xmm0, 1
  1477.     movq [r1+r3*2], xmm0
  1478.     psrldq    xmm0, 1
  1479.     movq [r2+r3*1], xmm0
  1480.     psrldq    xmm0, 1
  1481.     movq [r2+r3*2], xmm0
  1482.     psrldq    xmm0, 1
  1483.     movq [r0+r3*1], xmm0
  1484.     psrldq    xmm0, 1
  1485.     movq [r0+r3*2], xmm0
  1486.     RET
  1487. %endmacro
  1488.  
  1489. INIT_MMX sse2
  1490. PRED8x8L_DOWN_LEFT
  1491. INIT_MMX ssse3
  1492. PRED8x8L_DOWN_LEFT
  1493.  
  1494. ;-----------------------------------------------------------------------------
  1495. ;void pred8x8l_down_right_8_mmxext(uint8_t *src, int has_topleft, int has_topright, int stride)
  1496. ;-----------------------------------------------------------------------------
  1497.  
  1498. INIT_MMX mmxext
  1499. cglobal pred8x8l_down_right_8, 4,5
  1500.     sub          r0, r3
  1501.     lea          r4, [r0+r3*2]
  1502.     movq        mm0, [r0+r3*1-8]
  1503.     punpckhbw   mm0, [r0+r3*0-8]
  1504.     movq        mm1, [r4+r3*1-8]
  1505.     punpckhbw   mm1, [r0+r3*2-8]
  1506.     mov          r4, r0
  1507.     punpckhwd   mm1, mm0
  1508.     lea          r0, [r0+r3*4]
  1509.     movq        mm2, [r0+r3*1-8]
  1510.     punpckhbw   mm2, [r0+r3*0-8]
  1511.     lea          r0, [r0+r3*2]
  1512.     movq        mm3, [r0+r3*1-8]
  1513.     punpckhbw   mm3, [r0+r3*0-8]
  1514.     punpckhwd   mm3, mm2
  1515.     punpckhdq   mm3, mm1
  1516.     lea          r0, [r0+r3*2]
  1517.     movq        mm0, [r0+r3*0-8]
  1518.     movq        mm1, [r4]
  1519.     mov          r0, r4
  1520.     movq        mm4, mm3
  1521.     movq        mm2, mm3
  1522.     PALIGNR     mm4, mm0, 7, mm0
  1523.     PALIGNR     mm1, mm2, 1, mm2
  1524.     test        r1, r1 ; top_left
  1525.     jz .fix_lt_1
  1526. .do_left:
  1527.     movq        mm0, mm4
  1528.     PRED4x4_LOWPASS mm2, mm1, mm4, mm3, mm5
  1529.     movq        mm4, mm0
  1530.     movq        mm7, mm2
  1531.     movq        mm6, mm2
  1532.     PRED4x4_LOWPASS mm1, mm3, mm0, mm4, mm5
  1533.     psllq       mm1, 56
  1534.     PALIGNR     mm7, mm1, 7, mm3
  1535.     movq        mm0, [r0-8]
  1536.     movq        mm3, [r0]
  1537.     movq        mm1, [r0+8]
  1538.     movq        mm2, mm3
  1539.     movq        mm4, mm3
  1540.     PALIGNR     mm2, mm0, 7, mm0
  1541.     PALIGNR     mm1, mm4, 1, mm4
  1542.     test         r1, r1 ; top_left
  1543.     jz .fix_lt_2
  1544.     test         r2, r2 ; top_right
  1545.     jz .fix_tr_1
  1546. .do_top:
  1547.     PRED4x4_LOWPASS mm4, mm2, mm1, mm3, mm5
  1548.     movq        mm5, mm4
  1549.     jmp .body
  1550. .fix_lt_1:
  1551.     movq        mm5, mm3
  1552.     pxor        mm5, mm4
  1553.     psrlq       mm5, 56
  1554.     psllq       mm5, 48
  1555.     pxor        mm1, mm5
  1556.     jmp .do_left
  1557. .fix_lt_2:
  1558.     movq        mm5, mm3
  1559.     pxor        mm5, mm2
  1560.     psllq       mm5, 56
  1561.     psrlq       mm5, 56
  1562.     pxor        mm2, mm5
  1563.     test         r2, r2 ; top_right
  1564.     jnz .do_top
  1565. .fix_tr_1:
  1566.     movq        mm5, mm3
  1567.     pxor        mm5, mm1
  1568.     psrlq       mm5, 56
  1569.     psllq       mm5, 56
  1570.     pxor        mm1, mm5
  1571.     jmp .do_top
  1572. .body:
  1573.     lea         r1, [r0+r3*2]
  1574.     movq       mm1, mm7
  1575.     movq       mm7, mm5
  1576.     movq       mm5, mm6
  1577.     movq       mm2, mm7
  1578.     lea         r2, [r1+r3*2]
  1579.     PALIGNR    mm2, mm6, 1, mm0
  1580.     movq       mm3, mm7
  1581.     PALIGNR    mm3, mm6, 7, mm0
  1582.     movq       mm4, mm7
  1583.     lea         r4, [r2+r3*2]
  1584.     psrlq      mm4, 8
  1585.     PRED4x4_LOWPASS mm0, mm1, mm2, mm5, mm6
  1586.     PRED4x4_LOWPASS mm1, mm3, mm4, mm7, mm6
  1587.     movq [r4+r3*2], mm0
  1588.     movq       mm2, mm1
  1589.     psrlq      mm0, 8
  1590.     psllq      mm2, 56
  1591.     psrlq      mm1, 8
  1592.     por        mm0, mm2
  1593.     movq [r4+r3*1], mm0
  1594.     movq       mm2, mm1
  1595.     psrlq      mm0, 8
  1596.     psllq      mm2, 56
  1597.     psrlq      mm1, 8
  1598.     por        mm0, mm2
  1599.     movq [r2+r3*2], mm0
  1600.     movq       mm2, mm1
  1601.     psrlq      mm0, 8
  1602.     psllq      mm2, 56
  1603.     psrlq      mm1, 8
  1604.     por        mm0, mm2
  1605.     movq [r2+r3*1], mm0
  1606.     movq       mm2, mm1
  1607.     psrlq      mm0, 8
  1608.     psllq      mm2, 56
  1609.     psrlq      mm1, 8
  1610.     por        mm0, mm2
  1611.     movq [r1+r3*2], mm0
  1612.     movq       mm2, mm1
  1613.     psrlq      mm0, 8
  1614.     psllq      mm2, 56
  1615.     psrlq      mm1, 8
  1616.     por        mm0, mm2
  1617.     movq [r1+r3*1], mm0
  1618.     movq       mm2, mm1
  1619.     psrlq      mm0, 8
  1620.     psllq      mm2, 56
  1621.     psrlq      mm1, 8
  1622.     por        mm0, mm2
  1623.     movq [r0+r3*2], mm0
  1624.     psrlq      mm0, 8
  1625.     psllq      mm1, 56
  1626.     por        mm0, mm1
  1627.     movq [r0+r3*1], mm0
  1628.     RET
  1629.  
  1630. %macro PRED8x8L_DOWN_RIGHT 0
  1631. cglobal pred8x8l_down_right_8, 4,5
  1632.     sub          r0, r3
  1633.     lea          r4, [r0+r3*2]
  1634.     movq        mm0, [r0+r3*1-8]
  1635.     punpckhbw   mm0, [r0+r3*0-8]
  1636.     movq        mm1, [r4+r3*1-8]
  1637.     punpckhbw   mm1, [r0+r3*2-8]
  1638.     mov          r4, r0
  1639.     punpckhwd   mm1, mm0
  1640.     lea          r0, [r0+r3*4]
  1641.     movq        mm2, [r0+r3*1-8]
  1642.     punpckhbw   mm2, [r0+r3*0-8]
  1643.     lea          r0, [r0+r3*2]
  1644.     movq        mm3, [r0+r3*1-8]
  1645.     punpckhbw   mm3, [r0+r3*0-8]
  1646.     punpckhwd   mm3, mm2
  1647.     punpckhdq   mm3, mm1
  1648.     lea          r0, [r0+r3*2]
  1649.     movq        mm0, [r0+r3*0-8]
  1650.     movq        mm1, [r4]
  1651.     mov          r0, r4
  1652.     movq        mm4, mm3
  1653.     movq        mm2, mm3
  1654.     PALIGNR     mm4, mm0, 7, mm0
  1655.     PALIGNR     mm1, mm2, 1, mm2
  1656.     test        r1, r1
  1657.     jz .fix_lt_1
  1658.     jmp .do_left
  1659. .fix_lt_1:
  1660.     movq        mm5, mm3
  1661.     pxor        mm5, mm4
  1662.     psrlq       mm5, 56
  1663.     psllq       mm5, 48
  1664.     pxor        mm1, mm5
  1665.     jmp .do_left
  1666. .fix_lt_2:
  1667.     movq        mm5, mm3
  1668.     pxor        mm5, mm2
  1669.     psllq       mm5, 56
  1670.     psrlq       mm5, 56
  1671.     pxor        mm2, mm5
  1672.     test         r2, r2
  1673.     jnz .do_top
  1674. .fix_tr_1:
  1675.     movq        mm5, mm3
  1676.     pxor        mm5, mm1
  1677.     psrlq       mm5, 56
  1678.     psllq       mm5, 56
  1679.     pxor        mm1, mm5
  1680.     jmp .do_top
  1681. .do_left:
  1682.     movq        mm0, mm4
  1683.     PRED4x4_LOWPASS mm2, mm1, mm4, mm3, mm5
  1684.     movq        mm4, mm0
  1685.     movq        mm7, mm2
  1686.     movq2dq    xmm3, mm2
  1687.     PRED4x4_LOWPASS mm1, mm3, mm0, mm4, mm5
  1688.     psllq       mm1, 56
  1689.     PALIGNR     mm7, mm1, 7, mm3
  1690.     movq2dq    xmm1, mm7
  1691.     movq        mm0, [r0-8]
  1692.     movq        mm3, [r0]
  1693.     movq        mm1, [r0+8]
  1694.     movq        mm2, mm3
  1695.     movq        mm4, mm3
  1696.     PALIGNR     mm2, mm0, 7, mm0
  1697.     PALIGNR     mm1, mm4, 1, mm4
  1698.     test         r1, r1
  1699.     jz .fix_lt_2
  1700.     test         r2, r2
  1701.     jz .fix_tr_1
  1702. .do_top:
  1703.     PRED4x4_LOWPASS mm4, mm2, mm1, mm3, mm5
  1704.     movq2dq   xmm4, mm4
  1705.     lea         r1, [r0+r3*2]
  1706.     movdqa    xmm0, xmm3
  1707.     pslldq    xmm4, 8
  1708.     por       xmm3, xmm4
  1709.     lea         r2, [r1+r3*2]
  1710.     pslldq    xmm4, 1
  1711.     por       xmm1, xmm4
  1712.     psrldq    xmm0, 7
  1713.     pslldq    xmm0, 15
  1714.     psrldq    xmm0, 7
  1715.     por       xmm1, xmm0
  1716.     lea         r0, [r2+r3*2]
  1717.     movdqa    xmm2, xmm3
  1718.     psrldq    xmm2, 1
  1719. INIT_XMM cpuname
  1720.     PRED4x4_LOWPASS xmm0, xmm1, xmm2, xmm3, xmm4
  1721.     movdqa    xmm1, xmm0
  1722.     psrldq    xmm1, 1
  1723.     movq [r0+r3*2], xmm0
  1724.     movq [r0+r3*1], xmm1
  1725.     psrldq    xmm0, 2
  1726.     psrldq    xmm1, 2
  1727.     movq [r2+r3*2], xmm0
  1728.     movq [r2+r3*1], xmm1
  1729.     psrldq    xmm0, 2
  1730.     psrldq    xmm1, 2
  1731.     movq [r1+r3*2], xmm0
  1732.     movq [r1+r3*1], xmm1
  1733.     psrldq    xmm0, 2
  1734.     psrldq    xmm1, 2
  1735.     movq [r4+r3*2], xmm0
  1736.     movq [r4+r3*1], xmm1
  1737.     RET
  1738. %endmacro
  1739.  
  1740. INIT_MMX sse2
  1741. PRED8x8L_DOWN_RIGHT
  1742. INIT_MMX ssse3
  1743. PRED8x8L_DOWN_RIGHT
  1744.  
  1745. ;-----------------------------------------------------------------------------
  1746. ; void pred8x8l_vertical_right_8(uint8_t *src, int has_topleft, int has_topright, int stride)
  1747. ;-----------------------------------------------------------------------------
  1748.  
  1749. INIT_MMX mmxext
  1750. cglobal pred8x8l_vertical_right_8, 4,5
  1751.     sub          r0, r3
  1752.     lea          r4, [r0+r3*2]
  1753.     movq        mm0, [r0+r3*1-8]
  1754.     punpckhbw   mm0, [r0+r3*0-8]
  1755.     movq        mm1, [r4+r3*1-8]
  1756.     punpckhbw   mm1, [r0+r3*2-8]
  1757.     mov          r4, r0
  1758.     punpckhwd   mm1, mm0
  1759.     lea          r0, [r0+r3*4]
  1760.     movq        mm2, [r0+r3*1-8]
  1761.     punpckhbw   mm2, [r0+r3*0-8]
  1762.     lea          r0, [r0+r3*2]
  1763.     movq        mm3, [r0+r3*1-8]
  1764.     punpckhbw   mm3, [r0+r3*0-8]
  1765.     punpckhwd   mm3, mm2
  1766.     punpckhdq   mm3, mm1
  1767.     lea          r0, [r0+r3*2]
  1768.     movq        mm0, [r0+r3*0-8]
  1769.     movq        mm1, [r4]
  1770.     mov          r0, r4
  1771.     movq        mm4, mm3
  1772.     movq        mm2, mm3
  1773.     PALIGNR     mm4, mm0, 7, mm0
  1774.     PALIGNR     mm1, mm2, 1, mm2
  1775.     test        r1, r1
  1776.     jz .fix_lt_1
  1777.     jmp .do_left
  1778. .fix_lt_1:
  1779.     movq        mm5, mm3
  1780.     pxor        mm5, mm4
  1781.     psrlq       mm5, 56
  1782.     psllq       mm5, 48
  1783.     pxor        mm1, mm5
  1784.     jmp .do_left
  1785. .fix_lt_2:
  1786.     movq        mm5, mm3
  1787.     pxor        mm5, mm2
  1788.     psllq       mm5, 56
  1789.     psrlq       mm5, 56
  1790.     pxor        mm2, mm5
  1791.     test         r2, r2
  1792.     jnz .do_top
  1793. .fix_tr_1:
  1794.     movq        mm5, mm3
  1795.     pxor        mm5, mm1
  1796.     psrlq       mm5, 56
  1797.     psllq       mm5, 56
  1798.     pxor        mm1, mm5
  1799.     jmp .do_top
  1800. .do_left:
  1801.     movq        mm0, mm4
  1802.     PRED4x4_LOWPASS mm2, mm1, mm4, mm3, mm5
  1803.     movq        mm7, mm2
  1804.     movq        mm0, [r0-8]
  1805.     movq        mm3, [r0]
  1806.     movq        mm1, [r0+8]
  1807.     movq        mm2, mm3
  1808.     movq        mm4, mm3
  1809.     PALIGNR     mm2, mm0, 7, mm0
  1810.     PALIGNR     mm1, mm4, 1, mm4
  1811.     test         r1, r1
  1812.     jz .fix_lt_2
  1813.     test         r2, r2
  1814.     jz .fix_tr_1
  1815. .do_top:
  1816.     PRED4x4_LOWPASS mm6, mm2, mm1, mm3, mm5
  1817.     lea         r1, [r0+r3*2]
  1818.     movq       mm2, mm6
  1819.     movq       mm3, mm6
  1820.     PALIGNR    mm3, mm7, 7, mm0
  1821.     PALIGNR    mm6, mm7, 6, mm1
  1822.     movq       mm4, mm3
  1823.     pavgb      mm3, mm2
  1824.     lea         r2, [r1+r3*2]
  1825.     PRED4x4_LOWPASS mm0, mm6, mm2, mm4, mm5
  1826.     movq [r0+r3*1], mm3
  1827.     movq [r0+r3*2], mm0
  1828.     movq       mm5, mm0
  1829.     movq       mm6, mm3
  1830.     movq       mm1, mm7
  1831.     movq       mm2, mm1
  1832.     psllq      mm2, 8
  1833.     movq       mm3, mm1
  1834.     psllq      mm3, 16
  1835.     lea         r4, [r2+r3*2]
  1836.     PRED4x4_LOWPASS mm0, mm1, mm3, mm2, mm4
  1837.     PALIGNR    mm6, mm0, 7, mm2
  1838.     movq [r1+r3*1], mm6
  1839.     psllq      mm0, 8
  1840.     PALIGNR    mm5, mm0, 7, mm1
  1841.     movq [r1+r3*2], mm5
  1842.     psllq      mm0, 8
  1843.     PALIGNR    mm6, mm0, 7, mm2
  1844.     movq [r2+r3*1], mm6
  1845.     psllq      mm0, 8
  1846.     PALIGNR    mm5, mm0, 7, mm1
  1847.     movq [r2+r3*2], mm5
  1848.     psllq      mm0, 8
  1849.     PALIGNR    mm6, mm0, 7, mm2
  1850.     movq [r4+r3*1], mm6
  1851.     psllq      mm0, 8
  1852.     PALIGNR    mm5, mm0, 7, mm1
  1853.     movq [r4+r3*2], mm5
  1854.     RET
  1855.  
  1856. %macro PRED8x8L_VERTICAL_RIGHT 0
  1857. cglobal pred8x8l_vertical_right_8, 4,5,7
  1858.     ; manually spill XMM registers for Win64 because
  1859.     ; the code here is initialized with INIT_MMX
  1860.     WIN64_SPILL_XMM 7
  1861.     sub          r0, r3
  1862.     lea          r4, [r0+r3*2]
  1863.     movq        mm0, [r0+r3*1-8]
  1864.     punpckhbw   mm0, [r0+r3*0-8]
  1865.     movq        mm1, [r4+r3*1-8]
  1866.     punpckhbw   mm1, [r0+r3*2-8]
  1867.     mov          r4, r0
  1868.     punpckhwd   mm1, mm0
  1869.     lea          r0, [r0+r3*4]
  1870.     movq        mm2, [r0+r3*1-8]
  1871.     punpckhbw   mm2, [r0+r3*0-8]
  1872.     lea          r0, [r0+r3*2]
  1873.     movq        mm3, [r0+r3*1-8]
  1874.     punpckhbw   mm3, [r0+r3*0-8]
  1875.     punpckhwd   mm3, mm2
  1876.     punpckhdq   mm3, mm1
  1877.     lea          r0, [r0+r3*2]
  1878.     movq        mm0, [r0+r3*0-8]
  1879.     movq        mm1, [r4]
  1880.     mov          r0, r4
  1881.     movq        mm4, mm3
  1882.     movq        mm2, mm3
  1883.     PALIGNR     mm4, mm0, 7, mm0
  1884.     PALIGNR     mm1, mm2, 1, mm2
  1885.     test        r1, r1
  1886.     jnz .do_left
  1887. .fix_lt_1:
  1888.     movq        mm5, mm3
  1889.     pxor        mm5, mm4
  1890.     psrlq       mm5, 56
  1891.     psllq       mm5, 48
  1892.     pxor        mm1, mm5
  1893.     jmp .do_left
  1894. .fix_lt_2:
  1895.     movq        mm5, mm3
  1896.     pxor        mm5, mm2
  1897.     psllq       mm5, 56
  1898.     psrlq       mm5, 56
  1899.     pxor        mm2, mm5
  1900.     test         r2, r2
  1901.     jnz .do_top
  1902. .fix_tr_1:
  1903.     movq        mm5, mm3
  1904.     pxor        mm5, mm1
  1905.     psrlq       mm5, 56
  1906.     psllq       mm5, 56
  1907.     pxor        mm1, mm5
  1908.     jmp .do_top
  1909. .do_left:
  1910.     movq        mm0, mm4
  1911.     PRED4x4_LOWPASS mm2, mm1, mm4, mm3, mm5
  1912.     movq2dq    xmm0, mm2
  1913.     movq        mm0, [r0-8]
  1914.     movq        mm3, [r0]
  1915.     movq        mm1, [r0+8]
  1916.     movq        mm2, mm3
  1917.     movq        mm4, mm3
  1918.     PALIGNR     mm2, mm0, 7, mm0
  1919.     PALIGNR     mm1, mm4, 1, mm4
  1920.     test         r1, r1
  1921.     jz .fix_lt_2
  1922.     test         r2, r2
  1923.     jz .fix_tr_1
  1924. .do_top:
  1925.     PRED4x4_LOWPASS mm6, mm2, mm1, mm3, mm5
  1926.     lea           r1, [r0+r3*2]
  1927.     movq2dq     xmm4, mm6
  1928.     pslldq      xmm4, 8
  1929.     por         xmm0, xmm4
  1930.     movdqa      xmm6, [pw_ff00]
  1931.     movdqa      xmm1, xmm0
  1932.     lea           r2, [r1+r3*2]
  1933.     movdqa      xmm2, xmm0
  1934.     movdqa      xmm3, xmm0
  1935.     pslldq      xmm0, 1
  1936.     pslldq      xmm1, 2
  1937.     pavgb       xmm2, xmm0
  1938. INIT_XMM cpuname
  1939.     PRED4x4_LOWPASS xmm4, xmm3, xmm1, xmm0, xmm5
  1940.     pandn       xmm6, xmm4
  1941.     movdqa      xmm5, xmm4
  1942.     psrlw       xmm4, 8
  1943.     packuswb    xmm6, xmm4
  1944.     movhlps     xmm4, xmm6
  1945.     movhps [r0+r3*2], xmm5
  1946.     movhps [r0+r3*1], xmm2
  1947.     psrldq      xmm5, 4
  1948.     movss       xmm5, xmm6
  1949.     psrldq      xmm2, 4
  1950.     movss       xmm2, xmm4
  1951.     lea           r0, [r2+r3*2]
  1952.     psrldq      xmm5, 1
  1953.     psrldq      xmm2, 1
  1954.     movq        [r0+r3*2], xmm5
  1955.     movq        [r0+r3*1], xmm2
  1956.     psrldq      xmm5, 1
  1957.     psrldq      xmm2, 1
  1958.     movq        [r2+r3*2], xmm5
  1959.     movq        [r2+r3*1], xmm2
  1960.     psrldq      xmm5, 1
  1961.     psrldq      xmm2, 1
  1962.     movq        [r1+r3*2], xmm5
  1963.     movq        [r1+r3*1], xmm2
  1964.     RET
  1965. %endmacro
  1966.  
  1967. INIT_MMX sse2
  1968. PRED8x8L_VERTICAL_RIGHT
  1969. INIT_MMX ssse3
  1970. PRED8x8L_VERTICAL_RIGHT
  1971.  
  1972. ;-----------------------------------------------------------------------------
  1973. ;void pred8x8l_vertical_left_8(uint8_t *src, int has_topleft, int has_topright, int stride)
  1974. ;-----------------------------------------------------------------------------
  1975.  
  1976. %macro PRED8x8L_VERTICAL_LEFT 0
  1977. cglobal pred8x8l_vertical_left_8, 4,4
  1978.     sub          r0, r3
  1979.     movq        mm0, [r0-8]
  1980.     movq        mm3, [r0]
  1981.     movq        mm1, [r0+8]
  1982.     movq        mm2, mm3
  1983.     movq        mm4, mm3
  1984.     PALIGNR     mm2, mm0, 7, mm0
  1985.     PALIGNR     mm1, mm4, 1, mm4
  1986.     test         r1, r1
  1987.     jz .fix_lt_2
  1988.     test         r2, r2
  1989.     jz .fix_tr_1
  1990.     jmp .do_top
  1991. .fix_lt_2:
  1992.     movq        mm5, mm3
  1993.     pxor        mm5, mm2
  1994.     psllq       mm5, 56
  1995.     psrlq       mm5, 56
  1996.     pxor        mm2, mm5
  1997.     test         r2, r2
  1998.     jnz .do_top
  1999. .fix_tr_1:
  2000.     movq        mm5, mm3
  2001.     pxor        mm5, mm1
  2002.     psrlq       mm5, 56
  2003.     psllq       mm5, 56
  2004.     pxor        mm1, mm5
  2005.     jmp .do_top
  2006. .fix_tr_2:
  2007.     punpckhbw   mm3, mm3
  2008.     pshufw      mm1, mm3, 0xFF
  2009.     jmp .do_topright
  2010. .do_top:
  2011.     PRED4x4_LOWPASS mm4, mm2, mm1, mm3, mm5
  2012.     movq2dq    xmm4, mm4
  2013.     test         r2, r2
  2014.     jz .fix_tr_2
  2015.     movq        mm0, [r0+8]
  2016.     movq        mm5, mm0
  2017.     movq        mm2, mm0
  2018.     movq        mm4, mm0
  2019.     psrlq       mm5, 56
  2020.     PALIGNR     mm2, mm3, 7, mm3
  2021.     PALIGNR     mm5, mm4, 1, mm4
  2022.     PRED4x4_LOWPASS mm1, mm2, mm5, mm0, mm4
  2023. .do_topright:
  2024.     movq2dq   xmm3, mm1
  2025.     lea         r1, [r0+r3*2]
  2026.     pslldq    xmm3, 8
  2027.     por       xmm4, xmm3
  2028.     movdqa    xmm2, xmm4
  2029.     movdqa    xmm1, xmm4
  2030.     movdqa    xmm3, xmm4
  2031.     psrldq    xmm2, 1
  2032.     pslldq    xmm1, 1
  2033.     pavgb     xmm3, xmm2
  2034.     lea         r2, [r1+r3*2]
  2035. INIT_XMM cpuname
  2036.     PRED4x4_LOWPASS xmm0, xmm1, xmm2, xmm4, xmm5
  2037.     psrldq    xmm0, 1
  2038.     movq [r0+r3*1], xmm3
  2039.     movq [r0+r3*2], xmm0
  2040.     lea         r0, [r2+r3*2]
  2041.     psrldq    xmm3, 1
  2042.     psrldq    xmm0, 1
  2043.     movq [r1+r3*1], xmm3
  2044.     movq [r1+r3*2], xmm0
  2045.     psrldq    xmm3, 1
  2046.     psrldq    xmm0, 1
  2047.     movq [r2+r3*1], xmm3
  2048.     movq [r2+r3*2], xmm0
  2049.     psrldq    xmm3, 1
  2050.     psrldq    xmm0, 1
  2051.     movq [r0+r3*1], xmm3
  2052.     movq [r0+r3*2], xmm0
  2053.     RET
  2054. %endmacro
  2055.  
  2056. INIT_MMX sse2
  2057. PRED8x8L_VERTICAL_LEFT
  2058. INIT_MMX ssse3
  2059. PRED8x8L_VERTICAL_LEFT
  2060.  
  2061. ;-----------------------------------------------------------------------------
  2062. ; void pred8x8l_horizontal_up_8(uint8_t *src, int has_topleft, int has_topright, int stride)
  2063. ;-----------------------------------------------------------------------------
  2064.  
  2065. %macro PRED8x8L_HORIZONTAL_UP 0
  2066. cglobal pred8x8l_horizontal_up_8, 4,4
  2067.     sub          r0, r3
  2068.     lea          r2, [r0+r3*2]
  2069.     movq        mm0, [r0+r3*1-8]
  2070.     test         r1, r1
  2071.     lea          r1, [r0+r3]
  2072.     cmovnz       r1, r0
  2073.     punpckhbw   mm0, [r1+r3*0-8]
  2074.     movq        mm1, [r2+r3*1-8]
  2075.     punpckhbw   mm1, [r0+r3*2-8]
  2076.     mov          r2, r0
  2077.     punpckhwd   mm1, mm0
  2078.     lea          r0, [r0+r3*4]
  2079.     movq        mm2, [r0+r3*1-8]
  2080.     punpckhbw   mm2, [r0+r3*0-8]
  2081.     lea          r0, [r0+r3*2]
  2082.     movq        mm3, [r0+r3*1-8]
  2083.     punpckhbw   mm3, [r0+r3*0-8]
  2084.     punpckhwd   mm3, mm2
  2085.     punpckhdq   mm3, mm1
  2086.     lea          r0, [r0+r3*2]
  2087.     movq        mm0, [r0+r3*0-8]
  2088.     movq        mm1, [r1+r3*0-8]
  2089.     mov          r0, r2
  2090.     movq        mm4, mm3
  2091.     movq        mm2, mm3
  2092.     PALIGNR     mm4, mm0, 7, mm0
  2093.     PALIGNR     mm1, mm2, 1, mm2
  2094.     movq       mm0, mm4
  2095.     PRED4x4_LOWPASS mm2, mm1, mm4, mm3, mm5
  2096.     movq       mm4, mm0
  2097.     movq       mm7, mm2
  2098.     PRED4x4_LOWPASS mm1, mm3, mm0, mm4, mm5
  2099.     psllq      mm1, 56
  2100.     PALIGNR    mm7, mm1, 7, mm3
  2101.     lea         r1, [r0+r3*2]
  2102.     pshufw     mm0, mm7, 00011011b ; l6 l7 l4 l5 l2 l3 l0 l1
  2103.     psllq      mm7, 56             ; l7 .. .. .. .. .. .. ..
  2104.     movq       mm2, mm0
  2105.     psllw      mm0, 8
  2106.     psrlw      mm2, 8
  2107.     por        mm2, mm0            ; l7 l6 l5 l4 l3 l2 l1 l0
  2108.     movq       mm3, mm2
  2109.     movq       mm4, mm2
  2110.     movq       mm5, mm2
  2111.     psrlq      mm2, 8
  2112.     psrlq      mm3, 16
  2113.     lea         r2, [r1+r3*2]
  2114.     por        mm2, mm7            ; l7 l7 l6 l5 l4 l3 l2 l1
  2115.     punpckhbw  mm7, mm7
  2116.     por        mm3, mm7            ; l7 l7 l7 l6 l5 l4 l3 l2
  2117.     pavgb      mm4, mm2
  2118.     PRED4x4_LOWPASS mm1, mm3, mm5, mm2, mm6
  2119.     movq       mm5, mm4
  2120.     punpcklbw  mm4, mm1            ; p4 p3 p2 p1
  2121.     punpckhbw  mm5, mm1            ; p8 p7 p6 p5
  2122.     movq       mm6, mm5
  2123.     movq       mm7, mm5
  2124.     movq       mm0, mm5
  2125.     PALIGNR    mm5, mm4, 2, mm1
  2126.     pshufw     mm1, mm6, 11111001b
  2127.     PALIGNR    mm6, mm4, 4, mm2
  2128.     pshufw     mm2, mm7, 11111110b
  2129.     PALIGNR    mm7, mm4, 6, mm3
  2130.     pshufw     mm3, mm0, 11111111b
  2131.     movq [r0+r3*1], mm4
  2132.     movq [r0+r3*2], mm5
  2133.     lea         r0, [r2+r3*2]
  2134.     movq [r1+r3*1], mm6
  2135.     movq [r1+r3*2], mm7
  2136.     movq [r2+r3*1], mm0
  2137.     movq [r2+r3*2], mm1
  2138.     movq [r0+r3*1], mm2
  2139.     movq [r0+r3*2], mm3
  2140.     RET
  2141. %endmacro
  2142.  
  2143. INIT_MMX mmxext
  2144. PRED8x8L_HORIZONTAL_UP
  2145. INIT_MMX ssse3
  2146. PRED8x8L_HORIZONTAL_UP
  2147.  
  2148. ;-----------------------------------------------------------------------------
  2149. ;void pred8x8l_horizontal_down_8(uint8_t *src, int has_topleft, int has_topright, int stride)
  2150. ;-----------------------------------------------------------------------------
  2151.  
  2152. INIT_MMX mmxext
  2153. cglobal pred8x8l_horizontal_down_8, 4,5
  2154.     sub          r0, r3
  2155.     lea          r4, [r0+r3*2]
  2156.     movq        mm0, [r0+r3*1-8]
  2157.     punpckhbw   mm0, [r0+r3*0-8]
  2158.     movq        mm1, [r4+r3*1-8]
  2159.     punpckhbw   mm1, [r0+r3*2-8]
  2160.     mov          r4, r0
  2161.     punpckhwd   mm1, mm0
  2162.     lea          r0, [r0+r3*4]
  2163.     movq        mm2, [r0+r3*1-8]
  2164.     punpckhbw   mm2, [r0+r3*0-8]
  2165.     lea          r0, [r0+r3*2]
  2166.     movq        mm3, [r0+r3*1-8]
  2167.     punpckhbw   mm3, [r0+r3*0-8]
  2168.     punpckhwd   mm3, mm2
  2169.     punpckhdq   mm3, mm1
  2170.     lea          r0, [r0+r3*2]
  2171.     movq        mm0, [r0+r3*0-8]
  2172.     movq        mm1, [r4]
  2173.     mov          r0, r4
  2174.     movq        mm4, mm3
  2175.     movq        mm2, mm3
  2176.     PALIGNR     mm4, mm0, 7, mm0
  2177.     PALIGNR     mm1, mm2, 1, mm2
  2178.     test        r1, r1
  2179.     jnz .do_left
  2180. .fix_lt_1:
  2181.     movq        mm5, mm3
  2182.     pxor        mm5, mm4
  2183.     psrlq       mm5, 56
  2184.     psllq       mm5, 48
  2185.     pxor        mm1, mm5
  2186.     jmp .do_left
  2187. .fix_lt_2:
  2188.     movq        mm5, mm3
  2189.     pxor        mm5, mm2
  2190.     psllq       mm5, 56
  2191.     psrlq       mm5, 56
  2192.     pxor        mm2, mm5
  2193.     test         r2, r2
  2194.     jnz .do_top
  2195. .fix_tr_1:
  2196.     movq        mm5, mm3
  2197.     pxor        mm5, mm1
  2198.     psrlq       mm5, 56
  2199.     psllq       mm5, 56
  2200.     pxor        mm1, mm5
  2201.     jmp .do_top
  2202. .do_left:
  2203.     movq        mm0, mm4
  2204.     PRED4x4_LOWPASS mm2, mm1, mm4, mm3, mm5
  2205.     movq        mm4, mm0
  2206.     movq        mm7, mm2
  2207.     movq        mm6, mm2
  2208.     PRED4x4_LOWPASS mm1, mm3, mm0, mm4, mm5
  2209.     psllq       mm1, 56
  2210.     PALIGNR     mm7, mm1, 7, mm3
  2211.     movq        mm0, [r0-8]
  2212.     movq        mm3, [r0]
  2213.     movq        mm1, [r0+8]
  2214.     movq        mm2, mm3
  2215.     movq        mm4, mm3
  2216.     PALIGNR     mm2, mm0, 7, mm0
  2217.     PALIGNR     mm1, mm4, 1, mm4
  2218.     test         r1, r1
  2219.     jz .fix_lt_2
  2220.     test         r2, r2
  2221.     jz .fix_tr_1
  2222. .do_top:
  2223.     PRED4x4_LOWPASS mm4, mm2, mm1, mm3, mm5
  2224.     movq       mm5, mm4
  2225.     lea         r1, [r0+r3*2]
  2226.     psllq      mm7, 56
  2227.     movq       mm2, mm5
  2228.     movq       mm3, mm6
  2229.     movq       mm4, mm2
  2230.     PALIGNR    mm2, mm6, 7, mm5
  2231.     PALIGNR    mm6, mm7, 7, mm0
  2232.     lea         r2, [r1+r3*2]
  2233.     PALIGNR    mm4, mm3, 1, mm7
  2234.     movq       mm5, mm3
  2235.     pavgb      mm3, mm6
  2236.     PRED4x4_LOWPASS mm0, mm4, mm6, mm5, mm7
  2237.     movq       mm4, mm2
  2238.     movq       mm1, mm2
  2239.     lea         r4, [r2+r3*2]
  2240.     psrlq      mm4, 16
  2241.     psrlq      mm1, 8
  2242.     PRED4x4_LOWPASS mm6, mm4, mm2, mm1, mm5
  2243.     movq       mm7, mm3
  2244.     punpcklbw  mm3, mm0
  2245.     punpckhbw  mm7, mm0
  2246.     movq       mm1, mm7
  2247.     movq       mm0, mm7
  2248.     movq       mm4, mm7
  2249.     movq [r4+r3*2], mm3
  2250.     PALIGNR    mm7, mm3, 2, mm5
  2251.     movq [r4+r3*1], mm7
  2252.     PALIGNR    mm1, mm3, 4, mm5
  2253.     movq [r2+r3*2], mm1
  2254.     PALIGNR    mm0, mm3, 6, mm3
  2255.     movq [r2+r3*1], mm0
  2256.     movq       mm2, mm6
  2257.     movq       mm3, mm6
  2258.     movq [r1+r3*2], mm4
  2259.     PALIGNR    mm6, mm4, 2, mm5
  2260.     movq [r1+r3*1], mm6
  2261.     PALIGNR    mm2, mm4, 4, mm5
  2262.     movq [r0+r3*2], mm2
  2263.     PALIGNR    mm3, mm4, 6, mm4
  2264.     movq [r0+r3*1], mm3
  2265.     RET
  2266.  
  2267. %macro PRED8x8L_HORIZONTAL_DOWN 0
  2268. cglobal pred8x8l_horizontal_down_8, 4,5
  2269.     sub          r0, r3
  2270.     lea          r4, [r0+r3*2]
  2271.     movq        mm0, [r0+r3*1-8]
  2272.     punpckhbw   mm0, [r0+r3*0-8]
  2273.     movq        mm1, [r4+r3*1-8]
  2274.     punpckhbw   mm1, [r0+r3*2-8]
  2275.     mov          r4, r0
  2276.     punpckhwd   mm1, mm0
  2277.     lea          r0, [r0+r3*4]
  2278.     movq        mm2, [r0+r3*1-8]
  2279.     punpckhbw   mm2, [r0+r3*0-8]
  2280.     lea          r0, [r0+r3*2]
  2281.     movq        mm3, [r0+r3*1-8]
  2282.     punpckhbw   mm3, [r0+r3*0-8]
  2283.     punpckhwd   mm3, mm2
  2284.     punpckhdq   mm3, mm1
  2285.     lea          r0, [r0+r3*2]
  2286.     movq        mm0, [r0+r3*0-8]
  2287.     movq        mm1, [r4]
  2288.     mov          r0, r4
  2289.     movq        mm4, mm3
  2290.     movq        mm2, mm3
  2291.     PALIGNR     mm4, mm0, 7, mm0
  2292.     PALIGNR     mm1, mm2, 1, mm2
  2293.     test        r1, r1
  2294.     jnz .do_left
  2295. .fix_lt_1:
  2296.     movq        mm5, mm3
  2297.     pxor        mm5, mm4
  2298.     psrlq       mm5, 56
  2299.     psllq       mm5, 48
  2300.     pxor        mm1, mm5
  2301.     jmp .do_left
  2302. .fix_lt_2:
  2303.     movq        mm5, mm3
  2304.     pxor        mm5, mm2
  2305.     psllq       mm5, 56
  2306.     psrlq       mm5, 56
  2307.     pxor        mm2, mm5
  2308.     test         r2, r2
  2309.     jnz .do_top
  2310. .fix_tr_1:
  2311.     movq        mm5, mm3
  2312.     pxor        mm5, mm1
  2313.     psrlq       mm5, 56
  2314.     psllq       mm5, 56
  2315.     pxor        mm1, mm5
  2316.     jmp .do_top
  2317. .fix_tr_2:
  2318.     punpckhbw   mm3, mm3
  2319.     pshufw      mm1, mm3, 0xFF
  2320.     jmp .do_topright
  2321. .do_left:
  2322.     movq        mm0, mm4
  2323.     PRED4x4_LOWPASS mm2, mm1, mm4, mm3, mm5
  2324.     movq2dq    xmm0, mm2
  2325.     pslldq     xmm0, 8
  2326.     movq        mm4, mm0
  2327.     PRED4x4_LOWPASS mm1, mm3, mm0, mm4, mm5
  2328.     movq2dq    xmm2, mm1
  2329.     pslldq     xmm2, 15
  2330.     psrldq     xmm2, 8
  2331.     por        xmm0, xmm2
  2332.     movq        mm0, [r0-8]
  2333.     movq        mm3, [r0]
  2334.     movq        mm1, [r0+8]
  2335.     movq        mm2, mm3
  2336.     movq        mm4, mm3
  2337.     PALIGNR     mm2, mm0, 7, mm0
  2338.     PALIGNR     mm1, mm4, 1, mm4
  2339.     test         r1, r1
  2340.     jz .fix_lt_2
  2341.     test         r2, r2
  2342.     jz .fix_tr_1
  2343. .do_top:
  2344.     PRED4x4_LOWPASS mm4, mm2, mm1, mm3, mm5
  2345.     movq2dq    xmm1, mm4
  2346.     test         r2, r2
  2347.     jz .fix_tr_2
  2348.     movq        mm0, [r0+8]
  2349.     movq        mm5, mm0
  2350.     movq        mm2, mm0
  2351.     movq        mm4, mm0
  2352.     psrlq       mm5, 56
  2353.     PALIGNR     mm2, mm3, 7, mm3
  2354.     PALIGNR     mm5, mm4, 1, mm4
  2355.     PRED4x4_LOWPASS mm1, mm2, mm5, mm0, mm4
  2356. .do_topright:
  2357.     movq2dq    xmm5, mm1
  2358.     pslldq     xmm5, 8
  2359.     por        xmm1, xmm5
  2360. INIT_XMM cpuname
  2361.     lea         r2, [r4+r3*2]
  2362.     movdqa    xmm2, xmm1
  2363.     movdqa    xmm3, xmm1
  2364.     PALIGNR   xmm1, xmm0, 7, xmm4
  2365.     PALIGNR   xmm2, xmm0, 9, xmm5
  2366.     lea         r1, [r2+r3*2]
  2367.     PALIGNR   xmm3, xmm0, 8, xmm0
  2368.     movdqa    xmm4, xmm1
  2369.     pavgb     xmm4, xmm3
  2370.     lea         r0, [r1+r3*2]
  2371.     PRED4x4_LOWPASS xmm0, xmm1, xmm2, xmm3, xmm5
  2372.     punpcklbw xmm4, xmm0
  2373.     movhlps   xmm0, xmm4
  2374.     movq   [r0+r3*2], xmm4
  2375.     movq   [r2+r3*2], xmm0
  2376.     psrldq xmm4, 2
  2377.     psrldq xmm0, 2
  2378.     movq   [r0+r3*1], xmm4
  2379.     movq   [r2+r3*1], xmm0
  2380.     psrldq xmm4, 2
  2381.     psrldq xmm0, 2
  2382.     movq   [r1+r3*2], xmm4
  2383.     movq   [r4+r3*2], xmm0
  2384.     psrldq xmm4, 2
  2385.     psrldq xmm0, 2
  2386.     movq   [r1+r3*1], xmm4
  2387.     movq   [r4+r3*1], xmm0
  2388.     RET
  2389. %endmacro
  2390.  
  2391. INIT_MMX sse2
  2392. PRED8x8L_HORIZONTAL_DOWN
  2393. INIT_MMX ssse3
  2394. PRED8x8L_HORIZONTAL_DOWN
  2395.  
  2396. ;-----------------------------------------------------------------------------
  2397. ; void pred4x4_dc_8_mmxext(uint8_t *src, const uint8_t *topright, int stride)
  2398. ;-----------------------------------------------------------------------------
  2399.  
  2400. INIT_MMX mmxext
  2401. cglobal pred4x4_dc_8, 3,5
  2402.     pxor   mm7, mm7
  2403.     mov     r4, r0
  2404.     sub     r0, r2
  2405.     movd   mm0, [r0]
  2406.     psadbw mm0, mm7
  2407.     movzx  r1d, byte [r0+r2*1-1]
  2408.     movd   r3d, mm0
  2409.     add    r3d, r1d
  2410.     movzx  r1d, byte [r0+r2*2-1]
  2411.     lea     r0, [r0+r2*2]
  2412.     add    r3d, r1d
  2413.     movzx  r1d, byte [r0+r2*1-1]
  2414.     add    r3d, r1d
  2415.     movzx  r1d, byte [r0+r2*2-1]
  2416.     add    r3d, r1d
  2417.     add    r3d, 4
  2418.     shr    r3d, 3
  2419.     imul   r3d, 0x01010101
  2420.     mov   [r4+r2*0], r3d
  2421.     mov   [r0+r2*0], r3d
  2422.     mov   [r0+r2*1], r3d
  2423.     mov   [r0+r2*2], r3d
  2424.     RET
  2425.  
  2426. ;-----------------------------------------------------------------------------
  2427. ; void pred4x4_tm_vp8_8_mmxext(uint8_t *src, const uint8_t *topright, int stride)
  2428. ;-----------------------------------------------------------------------------
  2429.  
  2430. %macro PRED4x4_TM 0
  2431. cglobal pred4x4_tm_vp8_8, 3,6
  2432.     sub        r0, r2
  2433.     pxor      mm7, mm7
  2434.     movd      mm0, [r0]
  2435.     punpcklbw mm0, mm7
  2436.     movzx     r4d, byte [r0-1]
  2437.     mov       r5d, 2
  2438. .loop:
  2439.     movzx     r1d, byte [r0+r2*1-1]
  2440.     movzx     r3d, byte [r0+r2*2-1]
  2441.     sub       r1d, r4d
  2442.     sub       r3d, r4d
  2443.     movd      mm2, r1d
  2444.     movd      mm4, r3d
  2445. %if cpuflag(mmxext)
  2446.     pshufw    mm2, mm2, 0
  2447.     pshufw    mm4, mm4, 0
  2448. %else
  2449.     punpcklwd mm2, mm2
  2450.     punpcklwd mm4, mm4
  2451.     punpckldq mm2, mm2
  2452.     punpckldq mm4, mm4
  2453. %endif
  2454.     paddw     mm2, mm0
  2455.     paddw     mm4, mm0
  2456.     packuswb  mm2, mm2
  2457.     packuswb  mm4, mm4
  2458.     movd [r0+r2*1], mm2
  2459.     movd [r0+r2*2], mm4
  2460.     lea        r0, [r0+r2*2]
  2461.     dec       r5d
  2462.     jg .loop
  2463.     REP_RET
  2464. %endmacro
  2465.  
  2466. INIT_MMX mmx
  2467. PRED4x4_TM
  2468. INIT_MMX mmxext
  2469. PRED4x4_TM
  2470.  
  2471. INIT_XMM ssse3
  2472. cglobal pred4x4_tm_vp8_8, 3,3
  2473.     sub         r0, r2
  2474.     movq       mm6, [tm_shuf]
  2475.     pxor       mm1, mm1
  2476.     movd       mm0, [r0]
  2477.     punpcklbw  mm0, mm1
  2478.     movd       mm7, [r0-4]
  2479.     pshufb     mm7, mm6
  2480.     lea         r1, [r0+r2*2]
  2481.     movd       mm2, [r0+r2*1-4]
  2482.     movd       mm3, [r0+r2*2-4]
  2483.     movd       mm4, [r1+r2*1-4]
  2484.     movd       mm5, [r1+r2*2-4]
  2485.     pshufb     mm2, mm6
  2486.     pshufb     mm3, mm6
  2487.     pshufb     mm4, mm6
  2488.     pshufb     mm5, mm6
  2489.     psubw      mm2, mm7
  2490.     psubw      mm3, mm7
  2491.     psubw      mm4, mm7
  2492.     psubw      mm5, mm7
  2493.     paddw      mm2, mm0
  2494.     paddw      mm3, mm0
  2495.     paddw      mm4, mm0
  2496.     paddw      mm5, mm0
  2497.     packuswb   mm2, mm2
  2498.     packuswb   mm3, mm3
  2499.     packuswb   mm4, mm4
  2500.     packuswb   mm5, mm5
  2501.     movd [r0+r2*1], mm2
  2502.     movd [r0+r2*2], mm3
  2503.     movd [r1+r2*1], mm4
  2504.     movd [r1+r2*2], mm5
  2505.     RET
  2506.  
  2507. ;-----------------------------------------------------------------------------
  2508. ; void pred4x4_vertical_vp8_8_mmxext(uint8_t *src, const uint8_t *topright, int stride)
  2509. ;-----------------------------------------------------------------------------
  2510.  
  2511. INIT_MMX mmxext
  2512. cglobal pred4x4_vertical_vp8_8, 3,3
  2513.     sub       r0, r2
  2514.     movd      m1, [r0-1]
  2515.     movd      m0, [r0]
  2516.     mova      m2, m0   ;t0 t1 t2 t3
  2517.     punpckldq m0, [r1] ;t0 t1 t2 t3 t4 t5 t6 t7
  2518.     lea       r1, [r0+r2*2]
  2519.     psrlq     m0, 8    ;t1 t2 t3 t4
  2520.     PRED4x4_LOWPASS m3, m1, m0, m2, m4
  2521.     movd [r0+r2*1], m3
  2522.     movd [r0+r2*2], m3
  2523.     movd [r1+r2*1], m3
  2524.     movd [r1+r2*2], m3
  2525.     RET
  2526.  
  2527. ;-----------------------------------------------------------------------------
  2528. ; void pred4x4_down_left_8_mmxext(uint8_t *src, const uint8_t *topright, int stride)
  2529. ;-----------------------------------------------------------------------------
  2530. INIT_MMX mmxext
  2531. cglobal pred4x4_down_left_8, 3,3
  2532.     sub       r0, r2
  2533.     movq      m1, [r0]
  2534.     punpckldq m1, [r1]
  2535.     movq      m2, m1
  2536.     movq      m3, m1
  2537.     psllq     m1, 8
  2538.     pxor      m2, m1
  2539.     psrlq     m2, 8
  2540.     pxor      m2, m3
  2541.     PRED4x4_LOWPASS m0, m1, m2, m3, m4
  2542.     lea       r1, [r0+r2*2]
  2543.     psrlq     m0, 8
  2544.     movd      [r0+r2*1], m0
  2545.     psrlq     m0, 8
  2546.     movd      [r0+r2*2], m0
  2547.     psrlq     m0, 8
  2548.     movd      [r1+r2*1], m0
  2549.     psrlq     m0, 8
  2550.     movd      [r1+r2*2], m0
  2551.     RET
  2552.  
  2553. ;-----------------------------------------------------------------------------
  2554. ; void pred4x4_vertical_left_8_mmxext(uint8_t *src, const uint8_t *topright, int stride)
  2555. ;-----------------------------------------------------------------------------
  2556.  
  2557. INIT_MMX mmxext
  2558. cglobal pred4x4_vertical_left_8, 3,3
  2559.     sub       r0, r2
  2560.     movq      m1, [r0]
  2561.     punpckldq m1, [r1]
  2562.     movq      m3, m1
  2563.     movq      m2, m1
  2564.     psrlq     m3, 8
  2565.     psrlq     m2, 16
  2566.     movq      m4, m3
  2567.     pavgb     m4, m1
  2568.     PRED4x4_LOWPASS m0, m1, m2, m3, m5
  2569.     lea       r1, [r0+r2*2]
  2570.     movh      [r0+r2*1], m4
  2571.     movh      [r0+r2*2], m0
  2572.     psrlq     m4, 8
  2573.     psrlq     m0, 8
  2574.     movh      [r1+r2*1], m4
  2575.     movh      [r1+r2*2], m0
  2576.     RET
  2577.  
  2578. ;-----------------------------------------------------------------------------
  2579. ; void pred4x4_horizontal_up_8_mmxext(uint8_t *src, const uint8_t *topright, int stride)
  2580. ;-----------------------------------------------------------------------------
  2581.  
  2582. INIT_MMX mmxext
  2583. cglobal pred4x4_horizontal_up_8, 3,3
  2584.     sub       r0, r2
  2585.     lea       r1, [r0+r2*2]
  2586.     movd      m0, [r0+r2*1-4]
  2587.     punpcklbw m0, [r0+r2*2-4]
  2588.     movd      m1, [r1+r2*1-4]
  2589.     punpcklbw m1, [r1+r2*2-4]
  2590.     punpckhwd m0, m1
  2591.     movq      m1, m0
  2592.     punpckhbw m1, m1
  2593.     pshufw    m1, m1, 0xFF
  2594.     punpckhdq m0, m1
  2595.     movq      m2, m0
  2596.     movq      m3, m0
  2597.     movq      m7, m0
  2598.     psrlq     m2, 16
  2599.     psrlq     m3, 8
  2600.     pavgb     m7, m3
  2601.     PRED4x4_LOWPASS m4, m0, m2, m3, m5
  2602.     punpcklbw m7, m4
  2603.     movd    [r0+r2*1], m7
  2604.     psrlq    m7, 16
  2605.     movd    [r0+r2*2], m7
  2606.     psrlq    m7, 16
  2607.     movd    [r1+r2*1], m7
  2608.     movd    [r1+r2*2], m1
  2609.     RET
  2610.  
  2611. ;-----------------------------------------------------------------------------
  2612. ; void pred4x4_horizontal_down_8_mmxext(uint8_t *src, const uint8_t *topright, int stride)
  2613. ;-----------------------------------------------------------------------------
  2614.  
  2615. INIT_MMX mmxext
  2616. cglobal pred4x4_horizontal_down_8, 3,3
  2617.     sub       r0, r2
  2618.     lea       r1, [r0+r2*2]
  2619.     movh      m0, [r0-4]      ; lt ..
  2620.     punpckldq m0, [r0]        ; t3 t2 t1 t0 lt .. .. ..
  2621.     psllq     m0, 8           ; t2 t1 t0 lt .. .. .. ..
  2622.     movd      m1, [r1+r2*2-4] ; l3
  2623.     punpcklbw m1, [r1+r2*1-4] ; l2 l3
  2624.     movd      m2, [r0+r2*2-4] ; l1
  2625.     punpcklbw m2, [r0+r2*1-4] ; l0 l1
  2626.     punpckhwd m1, m2          ; l0 l1 l2 l3
  2627.     punpckhdq m1, m0          ; t2 t1 t0 lt l0 l1 l2 l3
  2628.     movq      m0, m1
  2629.     movq      m2, m1
  2630.     movq      m5, m1
  2631.     psrlq     m0, 16          ; .. .. t2 t1 t0 lt l0 l1
  2632.     psrlq     m2, 8           ; .. t2 t1 t0 lt l0 l1 l2
  2633.     pavgb     m5, m2
  2634.     PRED4x4_LOWPASS m3, m1, m0, m2, m4
  2635.     punpcklbw m5, m3
  2636.     psrlq     m3, 32
  2637.     PALIGNR   m3, m5, 6, m4
  2638.     movh      [r1+r2*2], m5
  2639.     psrlq     m5, 16
  2640.     movh      [r1+r2*1], m5
  2641.     psrlq     m5, 16
  2642.     movh      [r0+r2*2], m5
  2643.     movh      [r0+r2*1], m3
  2644.     RET
  2645.  
  2646. ;-----------------------------------------------------------------------------
  2647. ; void pred4x4_vertical_right_8_mmxext(uint8_t *src, const uint8_t *topright, int stride)
  2648. ;-----------------------------------------------------------------------------
  2649.  
  2650. INIT_MMX mmxext
  2651. cglobal pred4x4_vertical_right_8, 3,3
  2652.     sub     r0, r2
  2653.     lea     r1, [r0+r2*2]
  2654.     movh    m0, [r0]                    ; ........t3t2t1t0
  2655.     movq    m5, m0
  2656.     PALIGNR m0, [r0-8], 7, m1           ; ......t3t2t1t0lt
  2657.     pavgb   m5, m0
  2658.     PALIGNR m0, [r0+r2*1-8], 7, m1      ; ....t3t2t1t0ltl0
  2659.     movq    m1, m0
  2660.     PALIGNR m0, [r0+r2*2-8], 7, m2      ; ..t3t2t1t0ltl0l1
  2661.     movq    m2, m0
  2662.     PALIGNR m0, [r1+r2*1-8], 7, m3      ; t3t2t1t0ltl0l1l2
  2663.     PRED4x4_LOWPASS m3, m1, m0, m2, m4
  2664.     movq    m1, m3
  2665.     psrlq   m3, 16
  2666.     psllq   m1, 48
  2667.     movh    [r0+r2*1], m5
  2668.     movh    [r0+r2*2], m3
  2669.     PALIGNR m5, m1, 7, m2
  2670.     psllq   m1, 8
  2671.     movh    [r1+r2*1], m5
  2672.     PALIGNR m3, m1, 7, m1
  2673.     movh    [r1+r2*2], m3
  2674.     RET
  2675.  
  2676. ;-----------------------------------------------------------------------------
  2677. ; void pred4x4_down_right_8_mmxext(uint8_t *src, const uint8_t *topright, int stride)
  2678. ;-----------------------------------------------------------------------------
  2679.  
  2680. INIT_MMX mmxext
  2681. cglobal pred4x4_down_right_8, 3,3
  2682.     sub       r0, r2
  2683.     lea       r1, [r0+r2*2]
  2684.     movq      m1, [r1-8]
  2685.     movq      m2, [r0+r2*1-8]
  2686.     punpckhbw m2, [r0-8]
  2687.     movh      m3, [r0]
  2688.     punpckhwd m1, m2
  2689.     PALIGNR   m3, m1, 5, m1
  2690.     movq      m1, m3
  2691.     PALIGNR   m3, [r1+r2*1-8], 7, m4
  2692.     movq      m2, m3
  2693.     PALIGNR   m3, [r1+r2*2-8], 7, m4
  2694.     PRED4x4_LOWPASS m0, m3, m1, m2, m4
  2695.     movh      [r1+r2*2], m0
  2696.     psrlq     m0, 8
  2697.     movh      [r1+r2*1], m0
  2698.     psrlq     m0, 8
  2699.     movh      [r0+r2*2], m0
  2700.     psrlq     m0, 8
  2701.     movh      [r0+r2*1], m0
  2702.     RET
  2703.