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

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. ;*****************************************************************************
  2. ;* mc-a.asm: h264 encoder library
  3. ;*****************************************************************************
  4. ;* Copyright (C) 2003-2008 x264 project
  5. ;*
  6. ;* Authors: Loren Merritt <lorenm@u.washington.edu>
  7. ;*          Jason Garrett-Glaser <darkshikari@gmail.com>
  8. ;*          Laurent Aimar <fenrir@via.ecp.fr>
  9. ;*          Min Chen <chenm001.163.com>
  10. ;*
  11. ;* This program is free software; you can redistribute it and/or modify
  12. ;* it under the terms of the GNU General Public License as published by
  13. ;* the Free Software Foundation; either version 2 of the License, or
  14. ;* (at your option) any later version.
  15. ;*
  16. ;* This program is distributed in the hope that it will be useful,
  17. ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19. ;* GNU General Public License for more details.
  20. ;*
  21. ;* You should have received a copy of the GNU General Public License
  22. ;* along with this program; if not, write to the Free Software
  23. ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
  24. ;*****************************************************************************
  25. %include "x86inc.asm"
  26. SECTION_RODATA 32
  27. ch_shuffle: db 0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,0,0
  28. pw_4:  times 8 dw  4
  29. pw_8:  times 8 dw  8
  30. pw_32: times 8 dw 32
  31. pw_64: times 8 dw 64
  32. sw_64: dd 64
  33. SECTION .text
  34. ;=============================================================================
  35. ; weighted prediction
  36. ;=============================================================================
  37. ; implicit bipred only:
  38. ; assumes log2_denom = 5, offset = 0, weight1 + weight2 = 64
  39. %ifdef ARCH_X86_64
  40.     DECLARE_REG_TMP 0,1,2,3,4,5,10,11
  41.     %macro AVG_START 0-1 0
  42.         PROLOGUE 6,7,%1
  43. %ifdef WIN64
  44.         movsxd r5, r5d
  45. %endif
  46.         .height_loop:
  47.     %endmacro
  48. %else
  49.     DECLARE_REG_TMP 1,2,3,4,5,6,1,2
  50.     %macro AVG_START 0-1 0
  51.         PROLOGUE 0,7,%1
  52.         mov t0, r0m
  53.         mov t1, r1m
  54.         mov t2, r2m
  55.         mov t3, r3m
  56.         mov t4, r4m
  57.         mov t5, r5m
  58.         .height_loop:
  59.     %endmacro
  60. %endif
  61. %macro SPLATW 2
  62. %if mmsize==16
  63.     pshuflw  %1, %2, 0
  64.     punpcklqdq %1, %1
  65. %else
  66.     pshufw   %1, %2, 0
  67. %endif
  68. %endmacro
  69. %macro BIWEIGHT_MMX 2
  70.     movh      m0, %1
  71.     movh      m1, %2
  72.     punpcklbw m0, m5
  73.     punpcklbw m1, m5
  74.     pmullw    m0, m2
  75.     pmullw    m1, m3
  76.     paddw     m0, m1
  77.     paddw     m0, m4
  78.     psraw     m0, 6
  79. %endmacro
  80. %macro BIWEIGHT_START_MMX 0
  81.     movd    m2, r6m
  82.     SPLATW  m2, m2   ; weight_dst
  83.     mova    m3, [pw_64 GLOBAL]
  84.     psubw   m3, m2   ; weight_src
  85.     mova    m4, [pw_32 GLOBAL] ; rounding
  86.     pxor    m5, m5
  87. %endmacro
  88. %macro BIWEIGHT_SSSE3 2
  89.     movh      m0, %1
  90.     movh      m1, %2
  91.     punpcklbw m0, m1
  92.     pmaddubsw m0, m3
  93.     paddw     m0, m4
  94.     psraw     m0, 6
  95. %endmacro
  96. %macro BIWEIGHT_START_SSSE3 0
  97.     movzx  t6d, byte r6m ; FIXME x86_64
  98.     mov    t7d, 64
  99.     sub    t7d, t6d
  100.     shl    t7d, 8
  101.     add    t6d, t7d
  102.     movd    m3, t6d
  103.     mova    m4, [pw_32 GLOBAL]
  104.     SPLATW  m3, m3   ; weight_dst,src
  105. %endmacro
  106. %macro BIWEIGHT_ROW 4
  107.     BIWEIGHT [%2], [%3]
  108. %if %4==mmsize/2
  109.     packuswb   m0, m0
  110.     movh     [%1], m0
  111. %else
  112.     SWAP 0, 6
  113.     BIWEIGHT [%2+mmsize/2], [%3+mmsize/2]
  114.     packuswb   m6, m0
  115.     mova     [%1], m6
  116. %endif
  117. %endmacro
  118. ;-----------------------------------------------------------------------------
  119. ; int x264_pixel_avg_weight_w16_mmxext( uint8_t *dst, int, uint8_t *src1, int, uint8_t *src2, int, int i_weight )
  120. ;-----------------------------------------------------------------------------
  121. %macro AVG_WEIGHT 2-3 0
  122. cglobal x264_pixel_avg_weight_w%2_%1
  123.     BIWEIGHT_START
  124.     AVG_START %3
  125. %if %2==8 && mmsize==16
  126.     BIWEIGHT [t2], [t4]
  127.     SWAP 0, 6
  128.     BIWEIGHT [t2+t3], [t4+t5]
  129.     packuswb m6, m0
  130.     movlps   [t0], m6
  131.     movhps   [t0+t1], m6
  132. %else
  133. %assign x 0
  134. %rep 1+%2/(mmsize*2)
  135.     BIWEIGHT_ROW t0+x,    t2+x,    t4+x,    %2
  136.     BIWEIGHT_ROW t0+x+t1, t2+x+t3, t4+x+t5, %2
  137. %assign x x+mmsize
  138. %endrep
  139. %endif
  140.     lea  t0, [t0+t1*2]
  141.     lea  t2, [t2+t3*2]
  142.     lea  t4, [t4+t5*2]
  143.     sub  eax, 2
  144.     jg   .height_loop
  145.     REP_RET
  146. %endmacro
  147. %define BIWEIGHT BIWEIGHT_MMX
  148. %define BIWEIGHT_START BIWEIGHT_START_MMX
  149. INIT_MMX
  150. AVG_WEIGHT mmxext, 4
  151. AVG_WEIGHT mmxext, 8
  152. AVG_WEIGHT mmxext, 16
  153. INIT_XMM
  154. %define x264_pixel_avg_weight_w4_sse2 x264_pixel_avg_weight_w4_mmxext
  155. AVG_WEIGHT sse2, 8,  7
  156. AVG_WEIGHT sse2, 16, 7
  157. %define BIWEIGHT BIWEIGHT_SSSE3
  158. %define BIWEIGHT_START BIWEIGHT_START_SSSE3
  159. INIT_MMX
  160. AVG_WEIGHT ssse3, 4
  161. INIT_XMM
  162. AVG_WEIGHT ssse3, 8,  7
  163. AVG_WEIGHT ssse3, 16, 7
  164. ;=============================================================================
  165. ; pixel avg
  166. ;=============================================================================
  167. ;-----------------------------------------------------------------------------
  168. ; void x264_pixel_avg_4x4_mmxext( uint8_t *dst, int dst_stride,
  169. ;                                 uint8_t *src1, int src1_stride, uint8_t *src2, int src2_stride, int weight );
  170. ;-----------------------------------------------------------------------------
  171. %macro AVGH 3
  172. cglobal x264_pixel_avg_%1x%2_%3
  173.     mov eax, %2
  174.     cmp dword r6m, 32
  175.     jne x264_pixel_avg_weight_w%1_%3
  176. %if mmsize == 16 && %1 == 16
  177.     test dword r4m, 15
  178.     jz x264_pixel_avg_w%1_sse2
  179. %endif
  180.     jmp x264_pixel_avg_w%1_mmxext
  181. %endmacro
  182. ;-----------------------------------------------------------------------------
  183. ; void x264_pixel_avg_w4_mmxext( uint8_t *dst, int dst_stride,
  184. ;                                uint8_t *src1, int src1_stride, uint8_t *src2, int src2_stride,
  185. ;                                int height, int weight );
  186. ;-----------------------------------------------------------------------------
  187. %macro AVG_END 0
  188.     sub    eax, 2
  189.     lea    t4, [t4+t5*2]
  190.     lea    t2, [t2+t3*2]
  191.     lea    t0, [t0+t1*2]
  192.     jg     .height_loop
  193.     REP_RET
  194. %endmacro
  195. %macro AVG_FUNC 3
  196. cglobal %1
  197.     AVG_START
  198.     %2     m0, [t2]
  199.     %2     m1, [t2+t3]
  200.     pavgb  m0, [t4]
  201.     pavgb  m1, [t4+t5]
  202.     %3     [t0], m0
  203.     %3     [t0+t1], m1
  204.     AVG_END
  205. %endmacro
  206. INIT_MMX
  207. AVG_FUNC x264_pixel_avg_w4_mmxext, movd, movd
  208. AVGH 4, 8, mmxext
  209. AVGH 4, 4, mmxext
  210. AVGH 4, 2, mmxext
  211. AVG_FUNC x264_pixel_avg_w8_mmxext, movq, movq
  212. AVGH 8, 16, mmxext
  213. AVGH 8, 8,  mmxext
  214. AVGH 8, 4,  mmxext
  215. cglobal x264_pixel_avg_w16_mmxext
  216.     AVG_START
  217.     movq   mm0, [t2  ]
  218.     movq   mm1, [t2+8]
  219.     movq   mm2, [t2+t3  ]
  220.     movq   mm3, [t2+t3+8]
  221.     pavgb  mm0, [t4  ]
  222.     pavgb  mm1, [t4+8]
  223.     pavgb  mm2, [t4+t5  ]
  224.     pavgb  mm3, [t4+t5+8]
  225.     movq   [t0  ], mm0
  226.     movq   [t0+8], mm1
  227.     movq   [t0+t1  ], mm2
  228.     movq   [t0+t1+8], mm3
  229.     AVG_END
  230. AVGH 16, 16, mmxext
  231. AVGH 16, 8,  mmxext
  232. INIT_XMM
  233. AVG_FUNC x264_pixel_avg_w16_sse2, movdqu, movdqa
  234. AVGH 16, 16, sse2
  235. AVGH 16,  8, sse2
  236. AVGH  8, 16, sse2
  237. AVGH  8,  8, sse2
  238. AVGH  8,  4, sse2
  239. AVGH 16, 16, ssse3
  240. AVGH 16,  8, ssse3
  241. AVGH  8, 16, ssse3
  242. AVGH  8,  8, ssse3
  243. AVGH  8,  4, ssse3
  244. INIT_MMX
  245. AVGH  4,  8, ssse3
  246. AVGH  4,  4, ssse3
  247. AVGH  4,  2, ssse3
  248. ;=============================================================================
  249. ; pixel avg2
  250. ;=============================================================================
  251. ;-----------------------------------------------------------------------------
  252. ; void x264_pixel_avg2_w4_mmxext( uint8_t *dst, int dst_stride,
  253. ;                                 uint8_t *src1, int src_stride,
  254. ;                                 uint8_t *src2, int height );
  255. ;-----------------------------------------------------------------------------
  256. %macro AVG2_W8 2
  257. cglobal x264_pixel_avg2_w%1_mmxext, 6,7
  258.     sub    r4, r2
  259.     lea    r6, [r4+r3]
  260. .height_loop:
  261.     %2     mm0, [r2]
  262.     %2     mm1, [r2+r3]
  263.     pavgb  mm0, [r2+r4]
  264.     pavgb  mm1, [r2+r6]
  265.     %2     [r0], mm0
  266.     %2     [r0+r1], mm1
  267.     sub    r5d, 2
  268.     lea    r2, [r2+r3*2]
  269.     lea    r0, [r0+r1*2]
  270.     jg     .height_loop
  271.     REP_RET
  272. %endmacro
  273. AVG2_W8 4, movd
  274. AVG2_W8 8, movq
  275. %macro AVG2_W16 2
  276. cglobal x264_pixel_avg2_w%1_mmxext, 6,7
  277.     sub    r4, r2
  278.     lea    r6, [r4+r3]
  279. .height_loop:
  280.     movq   mm0, [r2]
  281.     %2     mm1, [r2+8]
  282.     movq   mm2, [r2+r3]
  283.     %2     mm3, [r2+r3+8]
  284.     pavgb  mm0, [r2+r4]
  285.     pavgb  mm1, [r2+r4+8]
  286.     pavgb  mm2, [r2+r6]
  287.     pavgb  mm3, [r2+r6+8]
  288.     movq   [r0], mm0
  289.     %2     [r0+8], mm1
  290.     movq   [r0+r1], mm2
  291.     %2     [r0+r1+8], mm3
  292.     lea    r2, [r2+r3*2]
  293.     lea    r0, [r0+r1*2]
  294.     sub    r5d, 2
  295.     jg     .height_loop
  296.     REP_RET
  297. %endmacro
  298. AVG2_W16 12, movd
  299. AVG2_W16 16, movq
  300. cglobal x264_pixel_avg2_w20_mmxext, 6,7
  301.     sub    r4, r2
  302.     lea    r6, [r4+r3]
  303. .height_loop:
  304.     movq   mm0, [r2]
  305.     movq   mm1, [r2+8]
  306.     movd   mm2, [r2+16]
  307.     movq   mm3, [r2+r3]
  308.     movq   mm4, [r2+r3+8]
  309.     movd   mm5, [r2+r3+16]
  310.     pavgb  mm0, [r2+r4]
  311.     pavgb  mm1, [r2+r4+8]
  312.     pavgb  mm2, [r2+r4+16]
  313.     pavgb  mm3, [r2+r6]
  314.     pavgb  mm4, [r2+r6+8]
  315.     pavgb  mm5, [r2+r6+16]
  316.     movq   [r0], mm0
  317.     movq   [r0+8], mm1
  318.     movd   [r0+16], mm2
  319.     movq   [r0+r1], mm3
  320.     movq   [r0+r1+8], mm4
  321.     movd   [r0+r1+16], mm5
  322.     lea    r2, [r2+r3*2]
  323.     lea    r0, [r0+r1*2]
  324.     sub    r5d, 2
  325.     jg     .height_loop
  326.     REP_RET
  327. cglobal x264_pixel_avg2_w16_sse2, 6,7
  328.     sub    r4, r2
  329.     lea    r6, [r4+r3]
  330. .height_loop:
  331.     movdqu xmm0, [r2]
  332.     movdqu xmm2, [r2+r3]
  333.     movdqu xmm1, [r2+r4]
  334.     movdqu xmm3, [r2+r6]
  335.     pavgb  xmm0, xmm1
  336.     pavgb  xmm2, xmm3
  337.     movdqa [r0], xmm0
  338.     movdqa [r0+r1], xmm2
  339.     lea    r2, [r2+r3*2]
  340.     lea    r0, [r0+r1*2]
  341.     sub    r5d, 2
  342.     jg     .height_loop
  343.     REP_RET
  344. %macro AVG2_W20 1
  345. cglobal x264_pixel_avg2_w20_%1, 6,7
  346.     sub    r4, r2
  347.     lea    r6, [r4+r3]
  348. .height_loop:
  349.     movdqu xmm0, [r2]
  350.     movdqu xmm2, [r2+r3]
  351.     movd   mm4,  [r2+16]
  352.     movd   mm5,  [r2+r3+16]
  353. %ifidn %1, sse2_misalign
  354.     pavgb  xmm0, [r2+r4]
  355.     pavgb  xmm2, [r2+r6]
  356. %else
  357.     movdqu xmm1, [r2+r4]
  358.     movdqu xmm3, [r2+r6]
  359.     pavgb  xmm0, xmm1
  360.     pavgb  xmm2, xmm3
  361. %endif
  362.     pavgb  mm4,  [r2+r4+16]
  363.     pavgb  mm5,  [r2+r6+16]
  364.     movdqa [r0], xmm0
  365.     movd   [r0+16], mm4
  366.     movdqa [r0+r1], xmm2
  367.     movd   [r0+r1+16], mm5
  368.     lea    r2, [r2+r3*2]
  369.     lea    r0, [r0+r1*2]
  370.     sub    r5d, 2
  371.     jg     .height_loop
  372.     REP_RET
  373. %endmacro
  374. AVG2_W20 sse2
  375. AVG2_W20 sse2_misalign
  376. ; Cacheline split code for processors with high latencies for loads
  377. ; split over cache lines.  See sad-a.asm for a more detailed explanation.
  378. ; This particular instance is complicated by the fact that src1 and src2
  379. ; can have different alignments.  For simplicity and code size, only the
  380. ; MMX cacheline workaround is used.  As a result, in the case of SSE2
  381. ; pixel_avg, the cacheline check functions calls the SSE2 version if there
  382. ; is no cacheline split, and the MMX workaround if there is.
  383. %macro INIT_SHIFT 2
  384.     and    eax, 7
  385.     shl    eax, 3
  386.     movd   %1, [sw_64 GLOBAL]
  387.     movd   %2, eax
  388.     psubw  %1, %2
  389. %endmacro
  390. %macro AVG_CACHELINE_CHECK 3 ; width, cacheline, instruction set
  391. cglobal x264_pixel_avg2_w%1_cache%2_%3
  392.     mov    eax, r2m
  393.     and    eax, 0x1f|(%2>>1)
  394.     cmp    eax, (32-%1)|(%2>>1)
  395.     jle x264_pixel_avg2_w%1_%3
  396. ;w12 isn't needed because w16 is just as fast if there's no cacheline split
  397. %if %1 == 12
  398.     jmp x264_pixel_avg2_w16_cache_mmxext
  399. %else
  400.     jmp x264_pixel_avg2_w%1_cache_mmxext
  401. %endif
  402. %endmacro
  403. %macro AVG_CACHELINE_START 0
  404.     %assign stack_offset 0
  405.     INIT_SHIFT mm6, mm7
  406.     mov    eax, r4m
  407.     INIT_SHIFT mm4, mm5
  408.     PROLOGUE 6,6
  409.     and    r2, ~7
  410.     and    r4, ~7
  411.     sub    r4, r2
  412. .height_loop:
  413. %endmacro
  414. %macro AVG_CACHELINE_LOOP 2
  415.     movq   mm0, [r2+8+%1]
  416.     movq   mm1, [r2+%1]
  417.     movq   mm2, [r2+r4+8+%1]
  418.     movq   mm3, [r2+r4+%1]
  419.     psllq  mm0, mm6
  420.     psrlq  mm1, mm7
  421.     psllq  mm2, mm4
  422.     psrlq  mm3, mm5
  423.     por    mm0, mm1
  424.     por    mm2, mm3
  425.     pavgb  mm0, mm2
  426.     %2 [r0+%1], mm0
  427. %endmacro
  428. x264_pixel_avg2_w8_cache_mmxext:
  429.     AVG_CACHELINE_START
  430.     AVG_CACHELINE_LOOP 0, movq
  431.     add    r2, r3
  432.     add    r0, r1
  433.     dec    r5d
  434.     jg     .height_loop
  435.     REP_RET
  436. x264_pixel_avg2_w16_cache_mmxext:
  437.     AVG_CACHELINE_START
  438.     AVG_CACHELINE_LOOP 0, movq
  439.     AVG_CACHELINE_LOOP 8, movq
  440.     add    r2, r3
  441.     add    r0, r1
  442.     dec    r5d
  443.     jg .height_loop
  444.     REP_RET
  445. x264_pixel_avg2_w20_cache_mmxext:
  446.     AVG_CACHELINE_START
  447.     AVG_CACHELINE_LOOP 0, movq
  448.     AVG_CACHELINE_LOOP 8, movq
  449.     AVG_CACHELINE_LOOP 16, movd
  450.     add    r2, r3
  451.     add    r0, r1
  452.     dec    r5d
  453.     jg .height_loop
  454.     REP_RET
  455. %ifndef ARCH_X86_64
  456. AVG_CACHELINE_CHECK  8, 32, mmxext
  457. AVG_CACHELINE_CHECK 12, 32, mmxext
  458. AVG_CACHELINE_CHECK 16, 32, mmxext
  459. AVG_CACHELINE_CHECK 20, 32, mmxext
  460. AVG_CACHELINE_CHECK 16, 64, mmxext
  461. AVG_CACHELINE_CHECK 20, 64, mmxext
  462. %endif
  463. AVG_CACHELINE_CHECK  8, 64, mmxext
  464. AVG_CACHELINE_CHECK 12, 64, mmxext
  465. AVG_CACHELINE_CHECK 16, 64, sse2
  466. AVG_CACHELINE_CHECK 20, 64, sse2
  467. ; computed jump assumes this loop is exactly 48 bytes
  468. %macro AVG16_CACHELINE_LOOP_SSSE3 2 ; alignment
  469. ALIGN 16
  470. avg_w16_align%1_%2_ssse3:
  471. %if %2&15==0
  472.     movdqa  xmm1, [r2+16]
  473.     palignr xmm1, [r2], %1
  474.     pavgb   xmm1, [r2+r4]
  475. %else
  476.     movdqa  xmm1, [r2+16]
  477.     movdqa  xmm2, [r2+r4+16]
  478.     palignr xmm1, [r2], %1
  479.     palignr xmm2, [r2+r4], %2
  480.     pavgb   xmm1, xmm2
  481. %endif
  482.     movdqa  [r0], xmm1
  483.     add    r2, r3
  484.     add    r0, r1
  485.     dec    r5d
  486.     jg     avg_w16_align%1_%2_ssse3
  487.     rep ret
  488. %endmacro
  489. %assign j 1
  490. %assign k 2
  491. %rep 15
  492. AVG16_CACHELINE_LOOP_SSSE3 j, j
  493. AVG16_CACHELINE_LOOP_SSSE3 j, k
  494. %assign j j+1
  495. %assign k k+1
  496. %endrep
  497. cglobal x264_pixel_avg2_w16_cache64_ssse3
  498.     mov    eax, r2m
  499.     and    eax, 0x3f
  500.     cmp    eax, 0x30
  501.     jle x264_pixel_avg2_w16_sse2
  502.     PROLOGUE 6,7
  503.     lea    r6, [r4+r2]
  504.     and    r4, ~0xf
  505.     and    r6, 0x1f
  506.     and    r2, ~0xf
  507.     lea    r6, [r6*3]    ;(offset + align*2)*3
  508.     sub    r4, r2
  509.     shl    r6, 4         ;jump = (offset + align*2)*48
  510. %define avg_w16_addr avg_w16_align1_1_ssse3-(avg_w16_align2_2_ssse3-avg_w16_align1_1_ssse3)
  511. %ifdef PIC
  512.     lea   r11, [avg_w16_addr GLOBAL]
  513.     add    r6, r11
  514. %else
  515.     lea    r6, [avg_w16_addr + r6 GLOBAL]
  516. %endif
  517. %ifdef UNIX64
  518.     jmp    r6
  519. %else
  520.     call   r6
  521.     RET
  522. %endif
  523. ;=============================================================================
  524. ; pixel copy
  525. ;=============================================================================
  526. %macro COPY4 4
  527.     %2  m0, [r2]
  528.     %2  m1, [r2+r3]
  529.     %2  m2, [r2+r3*2]
  530.     %2  m3, [r2+%4]
  531.     %1  [r0],      m0
  532.     %1  [r0+r1],   m1
  533.     %1  [r0+r1*2], m2
  534.     %1  [r0+%3],   m3
  535. %endmacro
  536. INIT_MMX
  537. ;-----------------------------------------------------------------------------
  538. ; void x264_mc_copy_w4_mmx( uint8_t *dst, int i_dst_stride,
  539. ;                           uint8_t *src, int i_src_stride, int i_height )
  540. ;-----------------------------------------------------------------------------
  541. cglobal x264_mc_copy_w4_mmx, 4,6
  542.     cmp     dword r4m, 4
  543.     lea     r5, [r3*3]
  544.     lea     r4, [r1*3]
  545.     je .end
  546.     COPY4 movd, movd, r4, r5
  547.     lea     r2, [r2+r3*4]
  548.     lea     r0, [r0+r1*4]
  549. .end:
  550.     COPY4 movd, movd, r4, r5
  551.     RET
  552. cglobal x264_mc_copy_w8_mmx, 5,7
  553.     lea     r6, [r3*3]
  554.     lea     r5, [r1*3]
  555. .height_loop:
  556.     COPY4 movq, movq, r5, r6
  557.     lea     r2, [r2+r3*4]
  558.     lea     r0, [r0+r1*4]
  559.     sub     r4d, 4
  560.     jg      .height_loop
  561.     REP_RET
  562. cglobal x264_mc_copy_w16_mmx, 5,7
  563.     lea     r6, [r3*3]
  564.     lea     r5, [r1*3]
  565. .height_loop:
  566.     movq    mm0, [r2]
  567.     movq    mm1, [r2+8]
  568.     movq    mm2, [r2+r3]
  569.     movq    mm3, [r2+r3+8]
  570.     movq    mm4, [r2+r3*2]
  571.     movq    mm5, [r2+r3*2+8]
  572.     movq    mm6, [r2+r6]
  573.     movq    mm7, [r2+r6+8]
  574.     movq    [r0], mm0
  575.     movq    [r0+8], mm1
  576.     movq    [r0+r1], mm2
  577.     movq    [r0+r1+8], mm3
  578.     movq    [r0+r1*2], mm4
  579.     movq    [r0+r1*2+8], mm5
  580.     movq    [r0+r5], mm6
  581.     movq    [r0+r5+8], mm7
  582.     lea     r2, [r2+r3*4]
  583.     lea     r0, [r0+r1*4]
  584.     sub     r4d, 4
  585.     jg      .height_loop
  586.     REP_RET
  587. INIT_XMM
  588. %macro COPY_W16_SSE2 2
  589. cglobal %1, 5,7
  590.     lea     r6, [r3*3]
  591.     lea     r5, [r1*3]
  592. .height_loop:
  593.     COPY4 movdqa, %2, r5, r6
  594.     lea     r2, [r2+r3*4]
  595.     lea     r0, [r0+r1*4]
  596.     sub     r4d, 4
  597.     jg      .height_loop
  598.     REP_RET
  599. %endmacro
  600. COPY_W16_SSE2 x264_mc_copy_w16_sse2, movdqu
  601. ; cacheline split with mmx has too much overhead; the speed benefit is near-zero.
  602. ; but with SSE3 the overhead is zero, so there's no reason not to include it.
  603. COPY_W16_SSE2 x264_mc_copy_w16_sse3, lddqu
  604. COPY_W16_SSE2 x264_mc_copy_w16_aligned_sse2, movdqa
  605. ;=============================================================================
  606. ; prefetch
  607. ;=============================================================================
  608. ; FIXME assumes 64 byte cachelines
  609. ;-----------------------------------------------------------------------------
  610. ; void x264_prefetch_fenc_mmxext( uint8_t *pix_y, int stride_y,
  611. ;                                 uint8_t *pix_uv, int stride_uv, int mb_x )
  612. ;-----------------------------------------------------------------------------
  613. %ifdef ARCH_X86_64
  614. cglobal x264_prefetch_fenc_mmxext, 5,5
  615.     mov    eax, r4d
  616.     and    eax, 3
  617.     imul   eax, r1d
  618.     lea    r0,  [r0+rax*4+64]
  619.     prefetcht0  [r0]
  620.     prefetcht0  [r0+r1]
  621.     lea    r0,  [r0+r1*2]
  622.     prefetcht0  [r0]
  623.     prefetcht0  [r0+r1]
  624.     and    r4d, 6
  625.     imul   r4d, r3d
  626.     lea    r2,  [r2+r4+64]
  627.     prefetcht0  [r2]
  628.     prefetcht0  [r2+r3]
  629.     RET
  630. %else
  631. cglobal x264_prefetch_fenc_mmxext
  632.     mov    r2, [esp+20]
  633.     mov    r1, [esp+8]
  634.     mov    r0, [esp+4]
  635.     and    r2, 3
  636.     imul   r2, r1
  637.     lea    r0, [r0+r2*4+64]
  638.     prefetcht0 [r0]
  639.     prefetcht0 [r0+r1]
  640.     lea    r0, [r0+r1*2]
  641.     prefetcht0 [r0]
  642.     prefetcht0 [r0+r1]
  643.     mov    r2, [esp+20]
  644.     mov    r1, [esp+16]
  645.     mov    r0, [esp+12]
  646.     and    r2, 6
  647.     imul   r2, r1
  648.     lea    r0, [r0+r2+64]
  649.     prefetcht0 [r0]
  650.     prefetcht0 [r0+r1]
  651.     ret
  652. %endif ; ARCH_X86_64
  653. ;-----------------------------------------------------------------------------
  654. ; void x264_prefetch_ref_mmxext( uint8_t *pix, int stride, int parity )
  655. ;-----------------------------------------------------------------------------
  656. cglobal x264_prefetch_ref_mmxext, 3,3
  657.     dec    r2d
  658.     and    r2d, r1d
  659.     lea    r0,  [r0+r2*8+64]
  660.     lea    r2,  [r1*3]
  661.     prefetcht0  [r0]
  662.     prefetcht0  [r0+r1]
  663.     prefetcht0  [r0+r1*2]
  664.     prefetcht0  [r0+r2]
  665.     lea    r0,  [r0+r1*4]
  666.     prefetcht0  [r0]
  667.     prefetcht0  [r0+r1]
  668.     prefetcht0  [r0+r1*2]
  669.     prefetcht0  [r0+r2]
  670.     RET
  671. ;=============================================================================
  672. ; chroma MC
  673. ;=============================================================================
  674.     %define t0 rax
  675. %ifdef ARCH_X86_64
  676.     %define t1 r10
  677. %else
  678.     %define t1 r1
  679. %endif
  680. %macro MC_CHROMA_START 0
  681.     movifnidn r2,  r2mp
  682.     movifnidn r3d, r3m
  683.     movifnidn r4d, r4m
  684.     movifnidn r5d, r5m
  685.     mov       t0d, r5d
  686.     mov       t1d, r4d
  687.     sar       t0d, 3
  688.     sar       t1d, 3
  689.     imul      t0d, r3d
  690.     add       t0d, t1d
  691.     movsxdifnidn t0, t0d
  692.     add       r2,  t0            ; src += (dx>>3) + (dy>>3) * src_stride
  693. %endmacro
  694. ;-----------------------------------------------------------------------------
  695. ; void x264_mc_chroma_mmxext( uint8_t *dst, int dst_stride,
  696. ;                             uint8_t *src, int src_stride,
  697. ;                             int dx, int dy,
  698. ;                             int width, int height )
  699. ;-----------------------------------------------------------------------------
  700. %macro MC_CHROMA 1-2 0
  701. cglobal x264_mc_chroma_%1
  702. %if mmsize == 16
  703.     cmp dword r6m, 4
  704.     jle x264_mc_chroma_mmxext
  705. %endif
  706.     PROLOGUE 0,6,%2
  707.     MC_CHROMA_START
  708.     pxor       m3, m3
  709.     and       r4d, 7         ; dx &= 7
  710.     jz .mc1dy
  711.     and       r5d, 7         ; dy &= 7
  712.     jz .mc1dx
  713.     movd       m5, r4d
  714.     movd       m6, r5d
  715.     SPLATW     m5, m5        ; m5 = dx
  716.     SPLATW     m6, m6        ; m6 = dy
  717.     mova       m4, [pw_8 GLOBAL]
  718.     mova       m0, m4
  719.     psubw      m4, m5        ; m4 = 8-dx
  720.     psubw      m0, m6        ; m0 = 8-dy
  721.     mova       m7, m5
  722.     pmullw     m5, m0        ; m5 = dx*(8-dy) =     cB
  723.     pmullw     m7, m6        ; m7 = dx*dy =         cD
  724.     pmullw     m6, m4        ; m6 = (8-dx)*dy =     cC
  725.     pmullw     m4, m0        ; m4 = (8-dx)*(8-dy) = cA
  726.     mov       r4d, r7m
  727. %ifdef ARCH_X86_64
  728.     mov       r10, r0
  729.     mov       r11, r2
  730. %else
  731.     mov        r0, r0mp
  732.     mov        r1, r1m
  733.     mov        r5, r2
  734. %endif
  735. .loop2d:
  736.     movh       m1, [r2+r3]
  737.     movh       m0, [r2]
  738.     punpcklbw  m1, m3        ; 00 px1 | 00 px2 | 00 px3 | 00 px4
  739.     punpcklbw  m0, m3
  740.     pmullw     m1, m6        ; 2nd line * cC
  741.     pmullw     m0, m4        ; 1st line * cA
  742.     paddw      m0, m1        ; m0 <- result
  743.     movh       m2, [r2+1]
  744.     movh       m1, [r2+r3+1]
  745.     punpcklbw  m2, m3
  746.     punpcklbw  m1, m3
  747.     paddw      m0, [pw_32 GLOBAL]
  748.     pmullw     m2, m5        ; line * cB
  749.     pmullw     m1, m7        ; line * cD
  750.     paddw      m0, m2
  751.     paddw      m0, m1
  752.     psrlw      m0, 6
  753.     packuswb m0, m3          ; 00 00 00 00 px1 px2 px3 px4
  754.     movh       [r0], m0
  755.     add        r2,  r3
  756.     add        r0,  r1       ; dst_stride
  757.     dec        r4d
  758.     jnz .loop2d
  759. %if mmsize == 8
  760.     sub dword r6m, 8
  761.     jnz .finish              ; width != 8 so assume 4
  762. %ifdef ARCH_X86_64
  763.     lea        r0, [r10+4]   ; dst
  764.     lea        r2, [r11+4]   ; src
  765. %else
  766.     mov        r0, r0mp
  767.     lea        r2, [r5+4]
  768.     add        r0, 4
  769. %endif
  770.     mov       r4d, r7m       ; height
  771.     jmp .loop2d
  772. %else
  773.     REP_RET
  774. %endif ; mmsize
  775. .mc1dy:
  776.     and       r5d, 7
  777.     movd       m6, r5d
  778.     mov        r5, r3        ; pel_offset = dx ? 1 : src_stride
  779.     jmp .mc1d
  780. .mc1dx:
  781.     movd       m6, r4d
  782.     mov       r5d, 1
  783. .mc1d:
  784.     mova       m5, [pw_8 GLOBAL]
  785.     SPLATW     m6, m6
  786.     mova       m7, [pw_4 GLOBAL]
  787.     psubw      m5, m6
  788.     movifnidn r0,  r0mp
  789.     movifnidn r1d, r1m
  790.     mov       r4d, r7m
  791. %if mmsize == 8
  792.     cmp dword r6m, 8
  793.     je .loop1d_w8
  794. %endif
  795. .loop1d_w4:
  796.     movh       m0, [r2+r5]
  797.     movh       m1, [r2]
  798.     punpcklbw  m0, m3
  799.     punpcklbw  m1, m3
  800.     pmullw     m0, m6
  801.     pmullw     m1, m5
  802.     paddw      m0, m7
  803.     paddw      m0, m1
  804.     psrlw      m0, 3
  805.     packuswb   m0, m3
  806.     movh     [r0], m0
  807.     add        r2, r3
  808.     add        r0, r1
  809.     dec        r4d
  810.     jnz .loop1d_w4
  811. .finish:
  812.     REP_RET
  813. %if mmsize == 8
  814. .loop1d_w8:
  815.     movu       m0, [r2+r5]
  816.     mova       m1, [r2]
  817.     mova       m2, m0
  818.     mova       m4, m1
  819.     punpcklbw  m0, m3
  820.     punpcklbw  m1, m3
  821.     punpckhbw  m2, m3
  822.     punpckhbw  m4, m3
  823.     pmullw     m0, m6
  824.     pmullw     m1, m5
  825.     pmullw     m2, m6
  826.     pmullw     m4, m5
  827.     paddw      m0, m7
  828.     paddw      m2, m7
  829.     paddw      m0, m1
  830.     paddw      m2, m4
  831.     psrlw      m0, 3
  832.     psrlw      m2, 3
  833.     packuswb   m0, m2
  834.     mova     [r0], m0
  835.     add        r2, r3
  836.     add        r0, r1
  837.     dec        r4d
  838.     jnz .loop1d_w8
  839.     REP_RET
  840. %endif ; mmsize
  841. %endmacro ; MC_CHROMA
  842. INIT_MMX
  843. MC_CHROMA mmxext
  844. INIT_XMM
  845. MC_CHROMA sse2, 8
  846. %macro MC_CHROMA_SSSE3 2
  847. INIT_MMX
  848. cglobal x264_mc_chroma_ssse3%1, 0,6,%2
  849.     MC_CHROMA_START
  850.     and       r4d, 7
  851.     and       r5d, 7
  852.     mov       t0d, r4d
  853.     shl       t0d, 8
  854.     sub       t0d, r4d
  855.     mov       r4d, 8
  856.     add       t0d, 8
  857.     sub       r4d, r5d
  858.     imul      r5d, t0d ; (x*255+8)*y
  859.     imul      r4d, t0d ; (x*255+8)*(8-y)
  860.     cmp dword r6m, 4
  861.     jg .width8
  862.     mova       m5, [pw_32 GLOBAL]
  863.     movd       m6, r5d
  864.     movd       m7, r4d
  865.     movifnidn  r0, r0mp
  866.     movifnidn r1d, r1m
  867.     movifnidn r4d, r7m
  868.     SPLATW     m6, m6
  869.     SPLATW     m7, m7
  870.     movh       m0, [r2]
  871.     punpcklbw  m0, [r2+1]
  872.     add r2, r3
  873. .loop4:
  874.     movh       m1, [r2]
  875.     movh       m3, [r2+r3]
  876.     punpcklbw  m1, [r2+1]
  877.     punpcklbw  m3, [r2+r3+1]
  878.     lea        r2, [r2+2*r3]
  879.     mova       m2, m1
  880.     mova       m4, m3
  881.     pmaddubsw  m0, m7
  882.     pmaddubsw  m1, m6
  883.     pmaddubsw  m2, m7
  884.     pmaddubsw  m3, m6
  885.     paddw      m0, m5
  886.     paddw      m2, m5
  887.     paddw      m1, m0
  888.     paddw      m3, m2
  889.     mova       m0, m4
  890.     psrlw      m1, 6
  891.     psrlw      m3, 6
  892.     packuswb   m1, m1
  893.     packuswb   m3, m3
  894.     movh     [r0], m1
  895.     movh  [r0+r1], m3
  896.     sub       r4d, 2
  897.     lea        r0, [r0+2*r1]
  898.     jg .loop4
  899.     REP_RET
  900. INIT_XMM
  901. .width8:
  902.     movd       m6, r5d
  903.     movd       m7, r4d
  904.     movifnidn  r0, r0mp
  905.     movifnidn r1d, r1m
  906.     movifnidn r4d, r7m
  907.     SPLATW     m6, m6
  908.     SPLATW     m7, m7
  909. %ifidn %1, _cache64
  910.     mov        r5, r2
  911.     and        r5, 0x3f
  912.     cmp        r5, 0x38
  913.     jge .split
  914. %endif
  915.     mova       m5, [pw_32 GLOBAL]
  916.     movh       m0, [r2]
  917.     movh       m1, [r2+1]
  918.     punpcklbw  m0, m1
  919. .loop8:
  920.     movh       m1, [r2+1*r3]
  921.     movh       m2, [r2+1*r3+1]
  922.     movh       m3, [r2+2*r3]
  923.     movh       m4, [r2+2*r3+1]
  924.     punpcklbw  m1, m2
  925.     punpcklbw  m3, m4
  926.     lea        r2, [r2+2*r3]
  927.     mova       m2, m1
  928.     mova       m4, m3
  929.     pmaddubsw  m0, m7
  930.     pmaddubsw  m1, m6
  931.     pmaddubsw  m2, m7
  932.     pmaddubsw  m3, m6
  933.     paddw      m0, m5
  934.     paddw      m2, m5
  935.     paddw      m1, m0
  936.     paddw      m3, m2
  937.     mova       m0, m4
  938.     psrlw      m1, 6
  939.     psrlw      m3, 6
  940.     packuswb   m1, m3
  941.     movh     [r0], m1
  942.     movhps [r0+r1], m1
  943.     sub       r4d, 2
  944.     lea        r0, [r0+2*r1]
  945.     jg .loop8
  946.     REP_RET
  947. %ifidn %1, _cache64
  948. .split:
  949.     and        r2, ~7
  950.     and        r5, 7
  951. %ifdef PIC
  952.     lea       r11, [ch_shuffle GLOBAL]
  953.     movu       m5, [r11 + r5*2]
  954. %else
  955.     movu       m5, [ch_shuffle + r5*2 GLOBAL]
  956. %endif
  957.     movu       m0, [r2]
  958.     pshufb     m0, m5
  959. %ifdef ARCH_X86_64
  960.     mova       m8, [pw_32 GLOBAL]
  961.     %define round m8
  962. %else
  963.     %define round [pw_32 GLOBAL]
  964. %endif
  965. .splitloop8:
  966.     movu       m1, [r2+r3]
  967.     pshufb     m1, m5
  968.     movu       m3, [r2+2*r3]
  969.     pshufb     m3, m5
  970.     lea        r2, [r2+2*r3]
  971.     mova       m2, m1
  972.     mova       m4, m3
  973.     pmaddubsw  m0, m7
  974.     pmaddubsw  m1, m6
  975.     pmaddubsw  m2, m7
  976.     pmaddubsw  m3, m6
  977.     paddw      m0, round
  978.     paddw      m2, round
  979.     paddw      m1, m0
  980.     paddw      m3, m2
  981.     mova       m0, m4
  982.     psrlw      m1, 6
  983.     psrlw      m3, 6
  984.     packuswb   m1, m3
  985.     movh     [r0], m1
  986.     movhps [r0+r1], m1
  987.     sub       r4d, 2
  988.     lea        r0, [r0+2*r1]
  989.     jg .splitloop8
  990.     REP_RET
  991. %endif
  992. ; mc_chroma 1d ssse3 is negligibly faster, and definitely not worth the extra code size
  993. %endmacro
  994. MC_CHROMA_SSSE3 , 8
  995. MC_CHROMA_SSSE3 _cache64, 9