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

Audio

开发平台:

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. ;*          Laurent Aimar <fenrir@via.ecp.fr>
  8. ;*          Jason Garrett-Glaser <darkshikari@gmail.com>
  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
  27. pw_4:  times 8 dw  4
  28. pw_8:  times 8 dw  8
  29. pw_32: times 8 dw 32
  30. pw_64: times 8 dw 64
  31. sw_64: dd 64
  32. SECTION .text
  33. ;=============================================================================
  34. ; pixel avg
  35. ;=============================================================================
  36. ;-----------------------------------------------------------------------------
  37. ; void x264_pixel_avg_4x4_mmxext( uint8_t *dst, int dst_stride,
  38. ;                                 uint8_t *src, int src_stride );
  39. ;-----------------------------------------------------------------------------
  40. %macro AVGH 3
  41. %assign function_align 8 ; the whole function fits in 8 bytes, so a larger align just wastes space
  42. cglobal x264_pixel_avg_%1x%2_%3
  43.     mov eax, %2
  44.     jmp x264_pixel_avg_w%1_%3
  45. %assign function_align 16
  46. %endmacro
  47. ;-----------------------------------------------------------------------------
  48. ; void x264_pixel_avg_w4_mmxext( uint8_t *dst, int dst_stride,
  49. ;                                uint8_t *src, int src_stride,
  50. ;                                int height );
  51. ;-----------------------------------------------------------------------------
  52. %ifdef ARCH_X86_64
  53.     %define t0 r0
  54.     %define t1 r1
  55.     %define t2 r2
  56.     %define t3 r3
  57.     %macro AVG_START 1
  58.         cglobal %1, 4,5
  59.         .height_loop:
  60.     %endmacro
  61. %else
  62.     %define t0 r1
  63.     %define t1 r2
  64.     %define t2 r3
  65.     %define t3 r4
  66.     %macro AVG_START 1
  67.         cglobal %1, 0,5
  68.         mov t0, r0m
  69.         mov t1, r1m
  70.         mov t2, r2m
  71.         mov t3, r3m
  72.         .height_loop:
  73.     %endmacro
  74. %endif
  75. %macro AVG_END 0
  76.     sub    eax, 2
  77.     lea    t2, [t2+t3*2]
  78.     lea    t0, [t0+t1*2]
  79.     jg     .height_loop
  80.     REP_RET
  81. %endmacro
  82. AVG_START x264_pixel_avg_w4_mmxext
  83.     movd   mm0, [t2]
  84.     movd   mm1, [t2+t3]
  85.     pavgb  mm0, [t0]
  86.     pavgb  mm1, [t0+t1]
  87.     movd   [t0], mm0
  88.     movd   [t0+t1], mm1
  89. AVG_END
  90. AVGH 4, 8, mmxext
  91. AVGH 4, 4, mmxext
  92. AVGH 4, 2, mmxext
  93. AVG_START x264_pixel_avg_w8_mmxext
  94.     movq   mm0, [t2]
  95.     movq   mm1, [t2+t3]
  96.     pavgb  mm0, [t0]
  97.     pavgb  mm1, [t0+t1]
  98.     movq   [t0], mm0
  99.     movq   [t0+t1], mm1
  100. AVG_END
  101. AVGH 8, 16, mmxext
  102. AVGH 8, 8,  mmxext
  103. AVGH 8, 4,  mmxext
  104. AVG_START x264_pixel_avg_w16_mmxext
  105.     movq   mm0, [t2  ]
  106.     movq   mm1, [t2+8]
  107.     movq   mm2, [t2+t3  ]
  108.     movq   mm3, [t2+t3+8]
  109.     pavgb  mm0, [t0  ]
  110.     pavgb  mm1, [t0+8]
  111.     pavgb  mm2, [t0+t1  ]
  112.     pavgb  mm3, [t0+t1+8]
  113.     movq   [t0  ], mm0
  114.     movq   [t0+8], mm1
  115.     movq   [t0+t1  ], mm2
  116.     movq   [t0+t1+8], mm3
  117. AVG_END
  118. AVGH 16, 16, mmxext
  119. AVGH 16, 8,  mmxext
  120. AVG_START x264_pixel_avg_w16_sse2
  121.     movdqu xmm0, [t2]
  122.     movdqu xmm1, [t2+t3]
  123.     pavgb  xmm0, [t0]
  124.     pavgb  xmm1, [t0+t1]
  125.     movdqa [t0], xmm0
  126.     movdqa [t0+t1], xmm1
  127. AVG_END
  128. AVGH 16, 16, sse2
  129. AVGH 16, 8,  sse2
  130. ;=============================================================================
  131. ; pixel avg2
  132. ;=============================================================================
  133. ;-----------------------------------------------------------------------------
  134. ; void x264_pixel_avg2_w4_mmxext( uint8_t *dst, int dst_stride,
  135. ;                                 uint8_t *src1, int src_stride,
  136. ;                                 uint8_t *src2, int height );
  137. ;-----------------------------------------------------------------------------
  138. %macro AVG2_W8 2
  139. cglobal x264_pixel_avg2_w%1_mmxext, 6,7
  140.     sub    r4, r2
  141.     lea    r6, [r4+r3]
  142. .height_loop:
  143.     %2     mm0, [r2]
  144.     %2     mm1, [r2+r3]
  145.     pavgb  mm0, [r2+r4]
  146.     pavgb  mm1, [r2+r6]
  147.     %2     [r0], mm0
  148.     %2     [r0+r1], mm1
  149.     sub    r5d, 2
  150.     lea    r2, [r2+r3*2]
  151.     lea    r0, [r0+r1*2]
  152.     jg     .height_loop
  153.     REP_RET
  154. %endmacro
  155. AVG2_W8 4, movd
  156. AVG2_W8 8, movq
  157. %macro AVG2_W16 2
  158. cglobal x264_pixel_avg2_w%1_mmxext, 6,7
  159.     sub    r4, r2
  160.     lea    r6, [r4+r3]
  161. .height_loop:
  162.     movq   mm0, [r2]
  163.     %2     mm1, [r2+8]
  164.     movq   mm2, [r2+r3]
  165.     %2     mm3, [r2+r3+8]
  166.     pavgb  mm0, [r2+r4]
  167.     pavgb  mm1, [r2+r4+8]
  168.     pavgb  mm2, [r2+r6]
  169.     pavgb  mm3, [r2+r6+8]
  170.     movq   [r0], mm0
  171.     %2     [r0+8], mm1
  172.     movq   [r0+r1], mm2
  173.     %2     [r0+r1+8], mm3
  174.     lea    r2, [r2+r3*2]
  175.     lea    r0, [r0+r1*2]
  176.     sub    r5d, 2
  177.     jg     .height_loop
  178.     REP_RET
  179. %endmacro
  180. AVG2_W16 12, movd
  181. AVG2_W16 16, movq
  182. cglobal x264_pixel_avg2_w20_mmxext, 6,7
  183.     sub    r4, r2
  184.     lea    r6, [r4+r3]
  185. .height_loop:
  186.     movq   mm0, [r2]
  187.     movq   mm1, [r2+8]
  188.     movd   mm2, [r2+16]
  189.     movq   mm3, [r2+r3]
  190.     movq   mm4, [r2+r3+8]
  191.     movd   mm5, [r2+r3+16]
  192.     pavgb  mm0, [r2+r4]
  193.     pavgb  mm1, [r2+r4+8]
  194.     pavgb  mm2, [r2+r4+16]
  195.     pavgb  mm3, [r2+r6]
  196.     pavgb  mm4, [r2+r6+8]
  197.     pavgb  mm5, [r2+r6+16]
  198.     movq   [r0], mm0
  199.     movq   [r0+8], mm1
  200.     movd   [r0+16], mm2
  201.     movq   [r0+r1], mm3
  202.     movq   [r0+r1+8], mm4
  203.     movd   [r0+r1+16], mm5
  204.     lea    r2, [r2+r3*2]
  205.     lea    r0, [r0+r1*2]
  206.     sub    r5d, 2
  207.     jg     .height_loop
  208.     REP_RET
  209. cglobal x264_pixel_avg2_w16_sse2, 6,7
  210.     sub    r4, r2
  211.     lea    r6, [r4+r3]
  212. .height_loop:
  213.     movdqu xmm0, [r2]
  214.     movdqu xmm2, [r2+r3]
  215.     movdqu xmm1, [r2+r4]
  216.     movdqu xmm3, [r2+r6]
  217.     pavgb  xmm0, xmm1
  218.     pavgb  xmm2, xmm3
  219.     movdqa [r0], xmm0
  220.     movdqa [r0+r1], xmm2
  221.     lea    r2, [r2+r3*2]
  222.     lea    r0, [r0+r1*2]
  223.     sub    r5d, 2
  224.     jg     .height_loop
  225.     REP_RET
  226. cglobal x264_pixel_avg2_w20_sse2, 6,7
  227.     sub    r4, r2
  228.     lea    r6, [r4+r3]
  229. .height_loop:
  230.     movdqu xmm0, [r2]
  231.     movdqu xmm2, [r2+r3]
  232.     movdqu xmm1, [r2+r4]
  233.     movdqu xmm3, [r2+r6]
  234.     movd   mm4,  [r2+16]
  235.     movd   mm5,  [r2+r3+16]
  236.     pavgb  xmm0, xmm1
  237.     pavgb  xmm2, xmm3
  238.     pavgb  mm4,  [r2+r4+16]
  239.     pavgb  mm5,  [r2+r6+16]
  240.     movdqa [r0], xmm0
  241.     movd   [r0+16], mm4
  242.     movdqa [r0+r1], xmm2
  243.     movd   [r0+r1+16], mm5
  244.     lea    r2, [r2+r3*2]
  245.     lea    r0, [r0+r1*2]
  246.     sub    r5d, 2
  247.     jg     .height_loop
  248.     REP_RET
  249. ; Cacheline split code for processors with high latencies for loads
  250. ; split over cache lines.  See sad-a.asm for a more detailed explanation.
  251. ; This particular instance is complicated by the fact that src1 and src2
  252. ; can have different alignments.  For simplicity and code size, only the
  253. ; MMX cacheline workaround is used.  As a result, in the case of SSE2
  254. ; pixel_avg, the cacheline check functions calls the SSE2 version if there
  255. ; is no cacheline split, and the MMX workaround if there is.
  256. %macro INIT_SHIFT 2
  257.     and    eax, 7
  258.     shl    eax, 3
  259.     movd   %1, [sw_64 GLOBAL]
  260.     movd   %2, eax
  261.     psubw  %1, %2
  262. %endmacro
  263. %macro AVG_CACHELINE_CHECK 3 ; width, cacheline, instruction set
  264. cglobal x264_pixel_avg2_w%1_cache%2_%3, 0,0
  265.     mov    eax, r2m
  266.     and    eax, 0x1f|(%2>>1)
  267.     cmp    eax, (32-%1)|(%2>>1)
  268.     jle x264_pixel_avg2_w%1_%3
  269. ;w12 isn't needed because w16 is just as fast if there's no cacheline split
  270. %if %1 == 12
  271.     jmp x264_pixel_avg2_w16_cache_mmxext
  272. %else
  273.     jmp x264_pixel_avg2_w%1_cache_mmxext
  274. %endif
  275. %endmacro
  276. %macro AVG_CACHELINE_START 0
  277.     %assign stack_offset 0
  278.     INIT_SHIFT mm6, mm7
  279.     mov    eax, r4m
  280.     INIT_SHIFT mm4, mm5
  281.     PROLOGUE 6,6
  282.     and    r2, ~7
  283.     and    r4, ~7
  284.     sub    r4, r2
  285. .height_loop:
  286. %endmacro
  287. %macro AVG_CACHELINE_LOOP 2
  288.     movq   mm0, [r2+8+%1]
  289.     movq   mm1, [r2+%1]
  290.     movq   mm2, [r2+r4+8+%1]
  291.     movq   mm3, [r2+r4+%1]
  292.     psllq  mm0, mm6
  293.     psrlq  mm1, mm7
  294.     psllq  mm2, mm4
  295.     psrlq  mm3, mm5
  296.     por    mm0, mm1
  297.     por    mm2, mm3
  298.     pavgb  mm0, mm2
  299.     %2 [r0+%1], mm0
  300. %endmacro
  301. x264_pixel_avg2_w8_cache_mmxext:
  302.     AVG_CACHELINE_START
  303.     AVG_CACHELINE_LOOP 0, movq
  304.     add    r2, r3
  305.     add    r0, r1
  306.     dec    r5d
  307.     jg     .height_loop
  308.     RET
  309. x264_pixel_avg2_w16_cache_mmxext:
  310.     AVG_CACHELINE_START
  311.     AVG_CACHELINE_LOOP 0, movq
  312.     AVG_CACHELINE_LOOP 8, movq
  313.     add    r2, r3
  314.     add    r0, r1
  315.     dec    r5d
  316.     jg .height_loop
  317.     RET
  318. x264_pixel_avg2_w20_cache_mmxext:
  319.     AVG_CACHELINE_START
  320.     AVG_CACHELINE_LOOP 0, movq
  321.     AVG_CACHELINE_LOOP 8, movq
  322.     AVG_CACHELINE_LOOP 16, movd
  323.     add    r2, r3
  324.     add    r0, r1
  325.     dec    r5d
  326.     jg .height_loop
  327.     RET
  328. %ifndef ARCH_X86_64
  329. AVG_CACHELINE_CHECK  8, 32, mmxext
  330. AVG_CACHELINE_CHECK 12, 32, mmxext
  331. AVG_CACHELINE_CHECK 16, 32, mmxext
  332. AVG_CACHELINE_CHECK 20, 32, mmxext
  333. AVG_CACHELINE_CHECK 16, 64, mmxext
  334. AVG_CACHELINE_CHECK 20, 64, mmxext
  335. %endif
  336. AVG_CACHELINE_CHECK  8, 64, mmxext
  337. AVG_CACHELINE_CHECK 12, 64, mmxext
  338. AVG_CACHELINE_CHECK 16, 64, sse2
  339. AVG_CACHELINE_CHECK 20, 64, sse2
  340. ;=============================================================================
  341. ; pixel copy
  342. ;=============================================================================
  343. %macro COPY4 4
  344.     %2  m0, [r2]
  345.     %2  m1, [r2+r3]
  346.     %2  m2, [r2+r3*2]
  347.     %2  m3, [r2+%4]
  348.     %1  [r0],      m0
  349.     %1  [r0+r1],   m1
  350.     %1  [r0+r1*2], m2
  351.     %1  [r0+%3],   m3
  352. %endmacro
  353. INIT_MMX
  354. ;-----------------------------------------------------------------------------
  355. ; void x264_mc_copy_w4_mmx( uint8_t *dst, int i_dst_stride,
  356. ;                           uint8_t *src, int i_src_stride, int i_height )
  357. ;-----------------------------------------------------------------------------
  358. cglobal x264_mc_copy_w4_mmx, 4,6
  359.     cmp     dword r4m, 4
  360.     lea     r5, [r3*3]
  361.     lea     r4, [r1*3]
  362.     je .end
  363.     COPY4 movd, movd, r4, r5
  364.     lea     r2, [r2+r3*4]
  365.     lea     r0, [r0+r1*4]
  366. .end:
  367.     COPY4 movd, movd, r4, r5
  368.     RET
  369. cglobal x264_mc_copy_w8_mmx, 5,7
  370.     lea     r6, [r3*3]
  371.     lea     r5, [r1*3]
  372. .height_loop:
  373.     COPY4 movq, movq, r5, r6
  374.     lea     r2, [r2+r3*4]
  375.     lea     r0, [r0+r1*4]
  376.     sub     r4d, 4
  377.     jg      .height_loop
  378.     REP_RET
  379. cglobal x264_mc_copy_w16_mmx, 5,7
  380.     lea     r6, [r3*3]
  381.     lea     r5, [r1*3]
  382. .height_loop:
  383.     movq    mm0, [r2]
  384.     movq    mm1, [r2+8]
  385.     movq    mm2, [r2+r3]
  386.     movq    mm3, [r2+r3+8]
  387.     movq    mm4, [r2+r3*2]
  388.     movq    mm5, [r2+r3*2+8]
  389.     movq    mm6, [r2+r6]
  390.     movq    mm7, [r2+r6+8]
  391.     movq    [r0], mm0
  392.     movq    [r0+8], mm1
  393.     movq    [r0+r1], mm2
  394.     movq    [r0+r1+8], mm3
  395.     movq    [r0+r1*2], mm4
  396.     movq    [r0+r1*2+8], mm5
  397.     movq    [r0+r5], mm6
  398.     movq    [r0+r5+8], mm7
  399.     lea     r2, [r2+r3*4]
  400.     lea     r0, [r0+r1*4]
  401.     sub     r4d, 4
  402.     jg      .height_loop
  403.     REP_RET
  404. INIT_XMM
  405. %macro COPY_W16_SSE2 2
  406. cglobal %1, 5,7
  407.     lea     r6, [r3*3]
  408.     lea     r5, [r1*3]
  409. .height_loop:
  410.     COPY4 movdqa, %2, r5, r6
  411.     lea     r2, [r2+r3*4]
  412.     lea     r0, [r0+r1*4]
  413.     sub     r4d, 4
  414.     jg      .height_loop
  415.     REP_RET
  416. %endmacro
  417. COPY_W16_SSE2 x264_mc_copy_w16_sse2, movdqu
  418. ; cacheline split with mmx has too much overhead; the speed benefit is near-zero.
  419. ; but with SSE3 the overhead is zero, so there's no reason not to include it.
  420. COPY_W16_SSE2 x264_mc_copy_w16_sse3, lddqu
  421. COPY_W16_SSE2 x264_mc_copy_w16_aligned_sse2, movdqa
  422. ;=============================================================================
  423. ; weighted prediction
  424. ;=============================================================================
  425. ; implicit bipred only:
  426. ; assumes log2_denom = 5, offset = 0, weight1 + weight2 = 64
  427. %macro SPLATW 2
  428. %if mmsize==16
  429.     pshuflw  %1, %2, 0
  430.     movlhps  %1, %1
  431. %else
  432.     pshufw   %1, %2, 0
  433. %endif
  434. %endmacro
  435. %macro BIWEIGHT 2
  436.     movh      m0, %1
  437.     movh      m1, %2
  438.     punpcklbw m0, m7
  439.     punpcklbw m1, m7
  440.     pmullw    m0, m4
  441.     pmullw    m1, m5
  442.     paddw     m0, m1
  443.     paddw     m0, m6
  444.     psraw     m0, 6
  445.     pmaxsw    m0, m7
  446.     packuswb  m0, m0
  447.     movh      %1,  m0
  448. %endmacro
  449. %macro BIWEIGHT_START 1
  450. %ifidn r4m, r4d
  451.     movd    m4, r4m
  452.     SPLATW  m4, m4   ; weight_dst
  453. %else
  454.     SPLATW  m4, r4m
  455. %endif
  456.     mova    m5, [pw_64 GLOBAL]
  457.     psubw   m5, m4      ; weight_src
  458.     mova    m6, [pw_32 GLOBAL] ; rounding
  459.     pxor    m7, m7
  460. %if %1
  461. %ifidn r5m, r5d
  462.     %define t0 r5d
  463. %else
  464.     %define t0 r4d
  465.     mov  r4d, r5m
  466. %endif
  467. %endif
  468. .height_loop:
  469. %endmacro
  470. INIT_MMX
  471. ;-----------------------------------------------------------------------------
  472. ; int x264_pixel_avg_weight_w16_mmxext( uint8_t *dst, int, uint8_t *src, int, int i_weight, int )
  473. ;-----------------------------------------------------------------------------
  474. cglobal x264_pixel_avg_weight_4x4_mmxext, 4,4
  475.     BIWEIGHT_START 0
  476.     BIWEIGHT  [r0     ], [r2     ]
  477.     BIWEIGHT  [r0+r1  ], [r2+r3  ]
  478.     BIWEIGHT  [r0+r1*2], [r2+r3*2]
  479.     add  r0, r1
  480.     add  r2, r3
  481.     BIWEIGHT  [r0+r1*2], [r2+r3*2]
  482.     RET
  483. %macro AVG_WEIGHT 2
  484. cglobal x264_pixel_avg_weight_w%2_%1, 4,5
  485.     BIWEIGHT_START 1
  486. %assign x 0
  487. %rep %2*2/mmsize
  488.     BIWEIGHT  [r0+x], [r2+x]
  489.     BIWEIGHT  [r0+x+r1], [r2+x+r3]
  490. %assign x x+mmsize/2
  491. %endrep
  492.     lea  r0, [r0+r1*2]
  493.     lea  r2, [r2+r3*2]
  494.     sub  t0, 2
  495.     jg   .height_loop
  496.     REP_RET
  497. %endmacro
  498. AVG_WEIGHT mmxext, 8
  499. AVG_WEIGHT mmxext, 16
  500. INIT_XMM
  501. AVG_WEIGHT sse2, 8
  502. AVG_WEIGHT sse2, 16
  503. ;=============================================================================
  504. ; prefetch
  505. ;=============================================================================
  506. ; FIXME assumes 64 byte cachelines
  507. ;-----------------------------------------------------------------------------
  508. ; void x264_prefetch_fenc_mmxext( uint8_t *pix_y, int stride_y,
  509. ;                                 uint8_t *pix_uv, int stride_uv, int mb_x )
  510. ;-----------------------------------------------------------------------------
  511. %ifdef ARCH_X86_64
  512. cglobal x264_prefetch_fenc_mmxext, 5,5
  513.     mov    eax, r4d
  514.     and    eax, 3
  515.     imul   eax, r1d
  516.     lea    r0,  [r0+rax*4+64]
  517.     prefetcht0  [r0]
  518.     prefetcht0  [r0+r1]
  519.     lea    r0,  [r0+r1*2]
  520.     prefetcht0  [r0]
  521.     prefetcht0  [r0+r1]
  522.     and    r4d, 6
  523.     imul   r4d, r3d
  524.     lea    r2,  [r2+r4+64]
  525.     prefetcht0  [r2]
  526.     prefetcht0  [r2+r3]
  527.     ret
  528. %else
  529. cglobal x264_prefetch_fenc_mmxext
  530.     mov    r2, [esp+20]
  531.     mov    r1, [esp+8]
  532.     mov    r0, [esp+4]
  533.     and    r2, 3
  534.     imul   r2, r1
  535.     lea    r0, [r0+r2*4+64]
  536.     prefetcht0 [r0]
  537.     prefetcht0 [r0+r1]
  538.     lea    r0, [r0+r1*2]
  539.     prefetcht0 [r0]
  540.     prefetcht0 [r0+r1]
  541.     mov    r2, [esp+20]
  542.     mov    r1, [esp+16]
  543.     mov    r0, [esp+12]
  544.     and    r2, 6
  545.     imul   r2, r1
  546.     lea    r0, [r0+r2+64]
  547.     prefetcht0 [r0]
  548.     prefetcht0 [r0+r1]
  549.     ret
  550. %endif ; ARCH_X86_64
  551. ;-----------------------------------------------------------------------------
  552. ; void x264_prefetch_ref_mmxext( uint8_t *pix, int stride, int parity )
  553. ;-----------------------------------------------------------------------------
  554. cglobal x264_prefetch_ref_mmxext, 3,3
  555.     dec    r2d
  556.     and    r2d, r1d
  557.     lea    r0,  [r0+r2*8+64]
  558.     lea    r2,  [r1*3]
  559.     prefetcht0  [r0]
  560.     prefetcht0  [r0+r1]
  561.     prefetcht0  [r0+r1*2]
  562.     prefetcht0  [r0+r2]
  563.     lea    r0,  [r0+r1*4]
  564.     prefetcht0  [r0]
  565.     prefetcht0  [r0+r1]
  566.     prefetcht0  [r0+r1*2]
  567.     prefetcht0  [r0+r2]
  568.     ret
  569. ;=============================================================================
  570. ; chroma MC
  571. ;=============================================================================
  572.     %define t0d  eax
  573.     %define t0   rax
  574. %ifdef ARCH_X86_64
  575.     %define t1d  r10d
  576. %else
  577.     %define t1d  r1d
  578. %endif
  579. %macro MC_CHROMA_START 0
  580.     movifnidn r2d, r2m
  581.     movifnidn r3d, r3m
  582.     movifnidn r4d, r4m
  583.     movifnidn r5d, r5m
  584.     mov       t0d, r5d
  585.     mov       t1d, r4d
  586.     sar       t0d, 3
  587.     sar       t1d, 3
  588.     imul      t0d, r3d
  589.     add       t0d, t1d
  590.     movsxdifnidn t0, t0d
  591.     add       r2,  t0            ; src += (dx>>3) + (dy>>3) * src_stride
  592. %endmacro
  593. ;-----------------------------------------------------------------------------
  594. ; void x264_mc_chroma_mmxext( uint8_t *dst, int dst_stride,
  595. ;                             uint8_t *src, int src_stride,
  596. ;                             int dx, int dy,
  597. ;                             int width, int height )
  598. ;-----------------------------------------------------------------------------
  599. %macro MC_CHROMA 1
  600. cglobal x264_mc_chroma_%1, 0,6
  601. %if mmsize == 16
  602.     cmp dword r6m, 4
  603.     jle x264_mc_chroma_mmxext %+ .skip_prologue
  604. %endif
  605. .skip_prologue:
  606.     MC_CHROMA_START
  607.     pxor       m3, m3
  608.     and       r4d, 7         ; dx &= 7
  609.     jz .mc1dy
  610.     and       r5d, 7         ; dy &= 7
  611.     jz .mc1dx
  612.     movd       m5, r4d
  613.     movd       m6, r5d
  614.     SPLATW     m5, m5        ; m5 = dx
  615.     SPLATW     m6, m6        ; m6 = dy
  616.     mova       m4, [pw_8 GLOBAL]
  617.     mova       m0, m4
  618.     psubw      m4, m5        ; m4 = 8-dx
  619.     psubw      m0, m6        ; m0 = 8-dy
  620.     mova       m7, m5
  621.     pmullw     m5, m0        ; m5 = dx*(8-dy) =     cB
  622.     pmullw     m7, m6        ; m7 = dx*dy =         cD
  623.     pmullw     m6, m4        ; m6 = (8-dx)*dy =     cC
  624.     pmullw     m4, m0        ; m4 = (8-dx)*(8-dy) = cA
  625.     mov       r4d, r7m
  626. %ifdef ARCH_X86_64
  627.     mov       r10, r0
  628.     mov       r11, r2
  629. %else
  630.     mov        r0, r0m
  631.     mov        r1, r1m
  632.     mov        r5, r2
  633. %endif
  634. .loop2d:
  635.     movh       m1, [r2+r3]
  636.     movh       m0, [r2]
  637.     punpcklbw  m1, m3        ; 00 px1 | 00 px2 | 00 px3 | 00 px4
  638.     punpcklbw  m0, m3
  639.     pmullw     m1, m6        ; 2nd line * cC
  640.     pmullw     m0, m4        ; 1st line * cA
  641.     paddw      m0, m1        ; m0 <- result
  642.     movh       m2, [r2+1]
  643.     movh       m1, [r2+r3+1]
  644.     punpcklbw  m2, m3
  645.     punpcklbw  m1, m3
  646.     paddw      m0, [pw_32 GLOBAL]
  647.     pmullw     m2, m5        ; line * cB
  648.     pmullw     m1, m7        ; line * cD
  649.     paddw      m0, m2
  650.     paddw      m0, m1
  651.     psrlw      m0, 6
  652.     packuswb m0, m3          ; 00 00 00 00 px1 px2 px3 px4
  653.     movh       [r0], m0
  654.     add        r2,  r3
  655.     add        r0,  r1       ; dst_stride
  656.     dec        r4d
  657.     jnz .loop2d
  658. %if mmsize == 8
  659.     sub dword r6m, 8
  660.     jnz .finish              ; width != 8 so assume 4
  661. %ifdef ARCH_X86_64
  662.     lea        r0, [r10+4]   ; dst
  663.     lea        r2, [r11+4]   ; src
  664. %else
  665.     mov        r0,  r0m
  666.     lea        r2, [r5+4]
  667.     add        r0,  4
  668. %endif
  669.     mov       r4d, r7m       ; height
  670.     jmp .loop2d
  671. %else
  672.     REP_RET
  673. %endif ; mmsize
  674. .mc1dy:
  675.     and       r5d, 7
  676.     movd       m6, r5d
  677.     mov        r5, r3        ; pel_offset = dx ? 1 : src_stride
  678.     jmp .mc1d
  679. .mc1dx:
  680.     movd       m6, r4d
  681.     mov       r5d, 1
  682. .mc1d:
  683.     mova       m5, [pw_8 GLOBAL]
  684.     SPLATW     m6, m6
  685.     mova       m7, [pw_4 GLOBAL]
  686.     psubw      m5, m6
  687.     movifnidn r0d, r0m
  688.     movifnidn r1d, r1m
  689.     mov       r4d, r7m
  690. %if mmsize == 8
  691.     cmp dword r6m, 8
  692.     je .loop1d_w8
  693. %endif
  694. .loop1d_w4:
  695.     movh       m0, [r2+r5]
  696.     movh       m1, [r2]
  697.     punpcklbw  m0, m3
  698.     punpcklbw  m1, m3
  699.     pmullw     m0, m6
  700.     pmullw     m1, m5
  701.     paddw      m0, m7
  702.     paddw      m0, m1
  703.     psrlw      m0, 3
  704.     packuswb   m0, m3
  705.     movh     [r0], m0
  706.     add        r2, r3
  707.     add        r0, r1
  708.     dec        r4d
  709.     jnz .loop1d_w4
  710. .finish:
  711.     REP_RET
  712. %if mmsize == 8
  713. .loop1d_w8:
  714.     movu       m0, [r2+r5]
  715.     mova       m1, [r2]
  716.     mova       m2, m0
  717.     mova       m4, m1
  718.     punpcklbw  m0, m3
  719.     punpcklbw  m1, m3
  720.     punpckhbw  m2, m3
  721.     punpckhbw  m4, m3
  722.     pmullw     m0, m6
  723.     pmullw     m1, m5
  724.     pmullw     m2, m6
  725.     pmullw     m4, m5
  726.     paddw      m0, m7
  727.     paddw      m2, m7
  728.     paddw      m0, m1
  729.     paddw      m2, m4
  730.     psrlw      m0, 3
  731.     psrlw      m2, 3
  732.     packuswb   m0, m2
  733.     mova     [r0], m0
  734.     add        r2, r3
  735.     add        r0, r1
  736.     dec        r4d
  737.     jnz .loop1d_w8
  738.     REP_RET
  739. %endif ; mmsize
  740. %endmacro ; MC_CHROMA
  741. INIT_MMX
  742. MC_CHROMA mmxext
  743. INIT_XMM
  744. MC_CHROMA sse2
  745. INIT_MMX
  746. cglobal x264_mc_chroma_ssse3, 0,6
  747.     MC_CHROMA_START
  748.     and       r4d, 7
  749.     and       r5d, 7
  750.     mov       t0d, r4d
  751.     shl       t0d, 8
  752.     sub       t0d, r4d
  753.     mov       r4d, 8
  754.     add       t0d, 8
  755.     sub       r4d, r5d
  756.     imul      r5d, t0d ; (x*255+8)*y
  757.     imul      r4d, t0d ; (x*255+8)*(8-y)
  758.     cmp dword r6m, 4
  759.     jg .width8
  760.     mova       m5, [pw_32 GLOBAL]
  761.     movd       m6, r5d
  762.     movd       m7, r4d
  763.     movifnidn r0d, r0m
  764.     movifnidn r1d, r1m
  765.     movifnidn r4d, r7m
  766.     SPLATW     m6, m6
  767.     SPLATW     m7, m7
  768.     movh       m0, [r2]
  769.     punpcklbw  m0, [r2+1]
  770.     add r2, r3
  771. .loop4:
  772.     movh       m1, [r2]
  773.     movh       m3, [r2+r3]
  774.     punpcklbw  m1, [r2+1]
  775.     punpcklbw  m3, [r2+r3+1]
  776.     lea        r2, [r2+2*r3]
  777.     mova       m2, m1
  778.     mova       m4, m3
  779.     pmaddubsw  m0, m7
  780.     pmaddubsw  m1, m6
  781.     pmaddubsw  m2, m7
  782.     pmaddubsw  m3, m6
  783.     paddw      m0, m5
  784.     paddw      m2, m5
  785.     paddw      m1, m0
  786.     paddw      m3, m2
  787.     mova       m0, m4
  788.     psrlw      m1, 6
  789.     psrlw      m3, 6
  790.     packuswb   m1, m1
  791.     packuswb   m3, m3
  792.     movh     [r0], m1
  793.     movh  [r0+r1], m3
  794.     sub       r4d, 2
  795.     lea        r0, [r0+2*r1]
  796.     jg .loop4
  797.     REP_RET
  798. INIT_XMM
  799. .width8:
  800.     mova       m5, [pw_32 GLOBAL]
  801.     movd       m6, r5d
  802.     movd       m7, r4d
  803.     movifnidn r0d, r0m
  804.     movifnidn r1d, r1m
  805.     movifnidn r4d, r7m
  806.     SPLATW     m6, m6
  807.     SPLATW     m7, m7
  808.     movh       m0, [r2]
  809.     movh       m1, [r2+1]
  810.     punpcklbw  m0, m1
  811.     add r2, r3
  812. .loop8:
  813.     movh       m1, [r2]
  814.     movh       m2, [r2+1]
  815.     movh       m3, [r2+r3]
  816.     movh       m4, [r2+r3+1]
  817.     punpcklbw  m1, m2
  818.     punpcklbw  m3, m4
  819.     lea        r2, [r2+2*r3]
  820.     mova       m2, m1
  821.     mova       m4, m3
  822.     pmaddubsw  m0, m7
  823.     pmaddubsw  m1, m6
  824.     pmaddubsw  m2, m7
  825.     pmaddubsw  m3, m6
  826.     paddw      m0, m5
  827.     paddw      m2, m5
  828.     paddw      m1, m0
  829.     paddw      m3, m2
  830.     mova       m0, m4
  831.     psrlw      m1, 6
  832.     psrlw      m3, 6
  833.     packuswb   m1, m3
  834.     movh     [r0], m1
  835.     movhps [r0+r1], m1
  836.     sub       r4d, 2
  837.     lea        r0, [r0+2*r1]
  838.     jg .loop8
  839.     REP_RET
  840. ; mc_chroma 1d ssse3 is negligibly faster, and definitely not worth the extra code size