Commit df2926615e for ffmpeg

commit df2926615e0dcb75b0655e10b5615ae7ad968974
Author: Zuxy Meng <zuxy.meng@gmail.com>
Date:   Mon Oct 26 20:12:45 2026 -0700

    avcodec/x86/h264: convert qpel MMX to SSE2

    Convert the last MMX (mmxext) qpel functions, all 4-wide
    8-bit and 10-bit paths, to SSE2, following the 8x8_l2
    conversion: new symbols carry the sse2 suffix and dispatch
    moves from EXTERNAL_MMXEXT to EXTERNAL_SSE2.

    checkasm h264qpel passes. almost identical performance in most
    converted functions except for small regression caused by replacing
    MMX's memory operand with movq and reg-reg op.

diff --git a/libavcodec/x86/h264_qpel.c b/libavcodec/x86/h264_qpel.c
index 1f01583142..433d7a9c66 100644
--- a/libavcodec/x86/h264_qpel.c
+++ b/libavcodec/x86/h264_qpel.c
@@ -30,36 +30,36 @@
 #include "fpel.h"
 #include "qpel.h"

-void ff_avg_pixels4_mmxext(uint8_t *dst, const uint8_t *src, ptrdiff_t stride);
-void ff_put_pixels4x4_l2_mmxext(uint8_t *dst, const uint8_t *src1, const uint8_t *src2,
-                                ptrdiff_t stride);
-void ff_avg_pixels4x4_l2_mmxext(uint8_t *dst, const uint8_t *src1, const uint8_t *src2,
-                                ptrdiff_t stride);
-#define ff_put_pixels4x4_l2_mmxext(dst, src1, src2, dststride, src1stride) \
-    ff_put_pixels4x4_l2_mmxext((dst), (src1), (src2), (dststride))
-#define ff_avg_pixels4x4_l2_mmxext(dst, src1, src2, dststride, src1stride) \
-    ff_avg_pixels4x4_l2_mmxext((dst), (src1), (src2), (dststride))
+void ff_avg_pixels4_sse2(uint8_t *dst, const uint8_t *src, ptrdiff_t stride);
+void ff_put_pixels4x4_l2_sse2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2,
+                              ptrdiff_t stride);
+void ff_avg_pixels4x4_l2_sse2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2,
+                              ptrdiff_t stride);
+#define ff_put_pixels4x4_l2_sse2(dst, src1, src2, dststride, src1stride) \
+    ff_put_pixels4x4_l2_sse2((dst), (src1), (src2), (dststride))
+#define ff_avg_pixels4x4_l2_sse2(dst, src1, src2, dststride, src1stride) \
+    ff_avg_pixels4x4_l2_sse2((dst), (src1), (src2), (dststride))

 #define DEF_QPEL(OPNAME)\
-void ff_ ## OPNAME ## _h264_qpel4_h_lowpass_mmxext(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride);\
+void ff_ ## OPNAME ## _h264_qpel4_h_lowpass_sse2(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride);\
 void ff_ ## OPNAME ## _h264_qpel8_h_lowpass_ssse3(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride);\
-void ff_ ## OPNAME ## _h264_qpel4_h_lowpass_l2_mmxext(uint8_t *dst, const uint8_t *src, const uint8_t *src2, ptrdiff_t dstStride, ptrdiff_t src2Stride);\
+void ff_ ## OPNAME ## _h264_qpel4_h_lowpass_l2_sse2(uint8_t *dst, const uint8_t *src, const uint8_t *src2, ptrdiff_t dstStride, ptrdiff_t src2Stride);\
 void ff_ ## OPNAME ## _h264_qpel8_h_lowpass_l2_sse2(uint8_t *dst, const uint8_t *src, const uint8_t *src2, ptrdiff_t dstStride, ptrdiff_t src2Stride);\
 void ff_ ## OPNAME ## _h264_qpel16_h_lowpass_l2_sse2(uint8_t *dst, const uint8_t *src, const uint8_t *src2, ptrdiff_t dstStride, ptrdiff_t src2Stride);\
 void ff_ ## OPNAME ## _h264_qpel8_h_lowpass_l2_ssse3(uint8_t *dst, const uint8_t *src, const uint8_t *src2, ptrdiff_t dstStride, ptrdiff_t src2Stride);\
-void ff_ ## OPNAME ## _h264_qpel4_v_lowpass_mmxext(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride);\
+void ff_ ## OPNAME ## _h264_qpel4_v_lowpass_sse2(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride);\
 void ff_ ## OPNAME ## _h264_qpel8or16_v_lowpass_sse2(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride, int h);\
-void ff_ ## OPNAME ## _h264_qpel4_hv_lowpass_h_mmxext(int16_t *tmp, uint8_t *dst, ptrdiff_t dstStride);\
+void ff_ ## OPNAME ## _h264_qpel4_hv_lowpass_h_sse2(int16_t *tmp, uint8_t *dst, ptrdiff_t dstStride);\
 void ff_ ## OPNAME ## _h264_qpel8or16_hv1_lowpass_op_sse2(const uint8_t *src, int16_t *tmp, ptrdiff_t srcStride, int size);\
 void ff_ ## OPNAME ## _h264_qpel8_hv2_lowpass_sse2(uint8_t *dst, int16_t *tmp, ptrdiff_t dstStride);\
 void ff_ ## OPNAME ## _h264_qpel16_hv2_lowpass_sse2(uint8_t *dst, int16_t *tmp, ptrdiff_t dstStride);\
 void ff_ ## OPNAME ## _h264_qpel8_hv2_lowpass_ssse3(uint8_t *dst, int16_t *tmp, ptrdiff_t dstStride);\
 void ff_ ## OPNAME ## _h264_qpel16_hv2_lowpass_ssse3(uint8_t *dst, int16_t *tmp, ptrdiff_t dstStride);\
-void ff_ ## OPNAME ## _pixels4_l2_shift5_mmxext(uint8_t *dst, const int16_t *src16, const uint8_t *src8, ptrdiff_t dstStride);\
+void ff_ ## OPNAME ## _pixels4_l2_shift5_sse2(uint8_t *dst, const int16_t *src16, const uint8_t *src8, ptrdiff_t dstStride);\
 void ff_ ## OPNAME ## _pixels8_l2_shift5_sse2(uint8_t *dst, const int16_t *src16, const uint8_t *src8, ptrdiff_t dstStride);\
 void ff_ ## OPNAME ## _pixels16_l2_shift5_sse2(uint8_t *dst, const int16_t *src16, const uint8_t *src8, ptrdiff_t dstStride);\

-void ff_put_h264_qpel4_hv_lowpass_v_mmxext(const uint8_t *src, int16_t *tmp, ptrdiff_t srcStride);
+void ff_put_h264_qpel4_hv_lowpass_v_sse2(const uint8_t *src, int16_t *tmp, ptrdiff_t srcStride);

 DEF_QPEL(avg)
 DEF_QPEL(put)
@@ -68,8 +68,8 @@ DEF_QPEL(put)
 static av_always_inline void OPNAME ## h264_qpel4_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride)\
 {\
     src -= 2*srcStride+2;\
-    ff_put_h264_qpel4_hv_lowpass_v_mmxext(src, tmp, srcStride);\
-    ff_ ## OPNAME ## h264_qpel4_hv_lowpass_h_mmxext(tmp, dst, dstStride);\
+    ff_put_h264_qpel4_hv_lowpass_v_ ## MMX(src, tmp, srcStride);\
+    ff_ ## OPNAME ## h264_qpel4_hv_lowpass_h_ ## MMX(tmp, dst, dstStride);\
 }\

 #define QPEL_H264_H16(OPNAME, EXT) \
@@ -270,8 +270,8 @@ QPEL(put_, 16,XMM, 16, SHIFT5_EXT)\
 QPEL(avg_, 8, XMM, 16, SHIFT5_EXT)\
 QPEL(avg_, 16,XMM, 16, SHIFT5_EXT)\

-QPEL_H264(put_, mmxext)
-QPEL_H264(avg_, mmxext)
+QPEL_H264(put_, sse2)
+QPEL_H264(avg_, sse2)
 QPEL_H264_V_XMM(put_, sse2, sse2)
 QPEL_H264_V_XMM(avg_, sse2, sse2)
 QPEL_H264_HV_XMM(put_, sse2)
@@ -282,7 +282,7 @@ QPEL_H264_V_XMM(put_, ssse3, sse2)
 QPEL_H264_HV_XMM(put_, ssse3)
 QPEL_H264_HV_XMM(avg_, ssse3)

-H264_MC(H264_MC_V_H_HV, 4, mmxext, 8, mmxext)
+H264_MC(H264_MC_V_H_HV, 4, sse2, 16, sse2)
 H264_MC_816(H264_MC_V, sse2, sse2)
 H264_MC_816(H264_MC_HV, sse2, sse2)
 H264_MC_816(H264_MC_H, ssse3, sse2)
@@ -304,22 +304,22 @@ void ff_ ## OP ## _h264_qpel ## NUM ## _ ## TYPE ## _ ## DEPTH ## _ ## OPT \
     LUMA_MC_OP(put, 16, DEPTH, TYPE, OPT) \
     LUMA_MC_OP(avg, 16, DEPTH, TYPE, OPT)

-LUMA_MC_4(10, mc00, mmxext)
-LUMA_MC_4(10, mc10, mmxext)
-LUMA_MC_4(10, mc20, mmxext)
-LUMA_MC_4(10, mc30, mmxext)
-LUMA_MC_4(10, mc01, mmxext)
-LUMA_MC_4(10, mc11, mmxext)
-LUMA_MC_4(10, mc21, mmxext)
-LUMA_MC_4(10, mc31, mmxext)
-LUMA_MC_4(10, mc02, mmxext)
-LUMA_MC_4(10, mc12, mmxext)
-LUMA_MC_4(10, mc22, mmxext)
-LUMA_MC_4(10, mc32, mmxext)
-LUMA_MC_4(10, mc03, mmxext)
-LUMA_MC_4(10, mc13, mmxext)
-LUMA_MC_4(10, mc23, mmxext)
-LUMA_MC_4(10, mc33, mmxext)
+LUMA_MC_4(10, mc00, sse2)
+LUMA_MC_4(10, mc10, sse2)
+LUMA_MC_4(10, mc20, sse2)
+LUMA_MC_4(10, mc30, sse2)
+LUMA_MC_4(10, mc01, sse2)
+LUMA_MC_4(10, mc11, sse2)
+LUMA_MC_4(10, mc21, sse2)
+LUMA_MC_4(10, mc31, sse2)
+LUMA_MC_4(10, mc02, sse2)
+LUMA_MC_4(10, mc12, sse2)
+LUMA_MC_4(10, mc22, sse2)
+LUMA_MC_4(10, mc32, sse2)
+LUMA_MC_4(10, mc03, sse2)
+LUMA_MC_4(10, mc13, sse2)
+LUMA_MC_4(10, mc23, sse2)
+LUMA_MC_4(10, mc33, sse2)

 LUMA_MC_816(10, mc00, sse2)
 LUMA_MC_816(10, mc10, sse2)
@@ -386,19 +386,11 @@ av_cold void ff_h264qpel_init_x86(H264QpelContext *c, int bit_depth)
     int high_bit_depth = bit_depth > 8;
     int cpu_flags = av_get_cpu_flags();

-    if (EXTERNAL_MMXEXT(cpu_flags)) {
-        if (!high_bit_depth) {
-            SET_QPEL_FUNCS_1PP(put_h264_qpel, 2,  4, mmxext, );
-            SET_QPEL_FUNCS_1PP(avg_h264_qpel, 2,  4, mmxext, );
-            c->avg_h264_qpel_pixels_tab[2][0] = ff_avg_pixels4_mmxext;
-        } else if (bit_depth == 10) {
-            SET_QPEL_FUNCS(put_h264_qpel, 2, 4,  10_mmxext, ff_);
-            SET_QPEL_FUNCS(avg_h264_qpel, 2, 4,  10_mmxext, ff_);
-        }
-    }
-
     if (EXTERNAL_SSE2(cpu_flags)) {
         if (!high_bit_depth) {
+            SET_QPEL_FUNCS_1PP(put_h264_qpel, 2,  4, sse2, );
+            SET_QPEL_FUNCS_1PP(avg_h264_qpel, 2,  4, sse2, );
+            c->avg_h264_qpel_pixels_tab[2][0] = ff_avg_pixels4_sse2;
             H264_QPEL_FUNCS(0, 1, sse2);
             H264_QPEL_FUNCS(0, 2, sse2);
             H264_QPEL_FUNCS(0, 3, sse2);
@@ -419,8 +411,10 @@ av_cold void ff_h264qpel_init_x86(H264QpelContext *c, int bit_depth)
         if (bit_depth == 10) {
             SET_QPEL_FUNCS(put_h264_qpel, 0, 16, 10_sse2, ff_);
             SET_QPEL_FUNCS(put_h264_qpel, 1,  8, 10_sse2, ff_);
+            SET_QPEL_FUNCS(put_h264_qpel, 2,  4, 10_sse2, ff_);
             SET_QPEL_FUNCS(avg_h264_qpel, 0, 16, 10_sse2, ff_);
             SET_QPEL_FUNCS(avg_h264_qpel, 1,  8, 10_sse2, ff_);
+            SET_QPEL_FUNCS(avg_h264_qpel, 2,  4, 10_sse2, ff_);
             H264_QPEL_FUNCS_10(1, 0, sse2);
             H264_QPEL_FUNCS_10(2, 0, sse2);
             H264_QPEL_FUNCS_10(3, 0, sse2);
diff --git a/libavcodec/x86/h264_qpel_10bit.asm b/libavcodec/x86/h264_qpel_10bit.asm
index bad2d386eb..31497da345 100644
--- a/libavcodec/x86/h264_qpel_10bit.asm
+++ b/libavcodec/x86/h264_qpel_10bit.asm
@@ -1,5 +1,5 @@
 ;*****************************************************************************
-;* MMX/SSE2/AVX-optimized 10-bit H.264 qpel code
+;* SSE2/AVX-optimized 10-bit H.264 qpel code
 ;*****************************************************************************
 ;* Copyright (C) 2011 x264 project
 ;*
@@ -52,13 +52,26 @@ SECTION .text
     mova  %1, %2
 %endmacro

-%macro ADDW 3
-%if mmsize == 8
-    paddw %1, %2
-%else
-    movu  %3, %2
+; 4-wide (8-byte row) avg store: exact 8-byte traffic via movq, so no
+; 16-byte alignment is required of dst. m6 is free at all use sites.
+%macro AVG_MOVQ 2
+    movq m6, %1
+    pavgw %2, m6
+    movq %1, %2
+%endmacro
+
+; MC00 4-wide avg uses only m0, so scratch in m1 keeps its count at 2.
+%macro AVG_MOVQ1 2
+    movq m1, %1
+    pavgw %2, m1
+    movq %1, %2
+%endmacro
+
+; %4 selects the temp load width: movu for 8-wide rows, movq for
+; 4-wide 10-bit rows (8 bytes)
+%macro ADDW 3-4 movu
+    %4  %3, %2
     paddw %1, %3
-%endif
 %endmacro

 %macro FILT_H 4
@@ -74,17 +87,17 @@ SECTION .text
 %macro PRELOAD_V 0
     lea      r3, [r2*3]
     sub      r1, r3
-    movu     m0, [r1+r2]
-    movu     m1, [r1+r2*2]
+    OP_LOAD  m0, [r1+r2]
+    OP_LOAD  m1, [r1+r2*2]
     add      r1, r3
-    movu     m2, [r1]
-    movu     m3, [r1+r2]
-    movu     m4, [r1+r2*2]
+    OP_LOAD  m2, [r1]
+    OP_LOAD  m3, [r1+r2]
+    OP_LOAD  m4, [r1+r2*2]
     add      r1, r3
 %endmacro

 %macro FILT_V 8
-    movu     %6, [r1]
+    OP_LOAD  %6, [r1]
     paddw    %1, %6
     mova     %7, %2
     paddw    %7, %5
@@ -96,16 +109,19 @@ SECTION .text
 %endmacro

 %macro MC 1
-%define OP_MOV mova
-INIT_MMX mmxext
-%1 put, 4
 INIT_XMM sse2
+%define OP_MOV movq
+%define OP_LOAD movq
+%1 put, 4
+%define OP_MOV mova
+%define OP_LOAD movu
 %1 put, 8

-%define OP_MOV AVG_MOV
-INIT_MMX mmxext
+%define OP_MOV AVG_MOVQ
+%define OP_LOAD movq
 %1 avg, 4
-INIT_XMM sse2
+%define OP_MOV AVG_MOV
+%define OP_LOAD movu
 %1 avg, 8
 %endmacro

@@ -153,7 +169,7 @@ cglobal %1_h264_qpel%4_%2_10, %5,%6 + 2,%7
 ;cpu, put/avg, mc, 4/8, ...
 %macro cglobal_mc 6
 %assign i %3*2
-%if cpuflag(sse2)
+%if %3 == 8
 MCAxA_OP %1, %2, %3, i, %4,%5,%6
 %endif

@@ -170,25 +186,37 @@ stub_%1_h264_qpel%3_%2_10 %+ SUFFIX:
 ; void ff_h264_qpel_mc00(uint8_t *dst, uint8_t *src, int stride)
 ;-----------------------------------------------------------------------------
 %macro COPY4 0
-    movu          m0, [r1     ]
+    OP_LOAD       m0, [r1     ]
     OP_MOV [r0     ], m0
-    movu          m0, [r1+r2  ]
+    OP_LOAD       m0, [r1+r2  ]
     OP_MOV [r0+r2  ], m0
-    movu          m0, [r1+r2*2]
+    OP_LOAD       m0, [r1+r2*2]
     OP_MOV [r0+r2*2], m0
-    movu          m0, [r1+r3  ]
+    OP_LOAD       m0, [r1+r3  ]
     OP_MOV [r0+r3  ], m0
 %endmacro

 %macro MC00 1
-INIT_MMX mmxext
-cglobal_mc %1, mc00, 4, 3,4,0
+INIT_XMM sse2
+%define OP_LOAD4 movq
+%define OP_LOAD8 movu
+%ifidn %1, put
+%define OP_MOV4 movq
+%define OP_MOV8 mova
+%else
+%define OP_MOV4 AVG_MOVQ1
+%define OP_MOV8 AVG_MOV
+%endif
+cglobal_mc %1, mc00, 4, 3,4,2
     lea           r3, [r2*3]
+%define OP_MOV OP_MOV4
+%define OP_LOAD OP_LOAD4
     COPY4
     ret

-INIT_XMM sse2
 cglobal %1_h264_qpel8_mc00_10, 3,4
+%define OP_MOV OP_MOV8
+%define OP_LOAD OP_LOAD8
     lea  r3, [r2*3]
     COPY4
     lea  r0, [r0+r2*4]
@@ -214,28 +242,31 @@ cglobal %1_h264_qpel16_mc00_10, 3,4
     RET
 %endmacro

-%define OP_MOV mova
 MC00 put

-%define OP_MOV AVG_MOV
 MC00 avg

 ;-----------------------------------------------------------------------------
 ; void ff_h264_qpel_mc20(uint8_t *dst, uint8_t *src, int stride)
 ;-----------------------------------------------------------------------------
 %macro MC_CACHE 1
-%define OP_MOV mova
-INIT_MMX mmxext
+INIT_XMM sse2
+%define OP_MOV movq
+%define OP_LOAD movq
 %1 put, 4
 INIT_XMM ssse3, cache64
+%define OP_MOV mova
+%define OP_LOAD movu
 %1 put, 8
 INIT_XMM sse2
 %1 put, 8

-%define OP_MOV AVG_MOV
-INIT_MMX mmxext
+%define OP_MOV AVG_MOVQ
+%define OP_LOAD movq
 %1 avg, 4
 INIT_XMM ssse3, cache64
+%define OP_MOV AVG_MOV
+%define OP_LOAD movu
 %1 avg, 8
 INIT_XMM sse2
 %1 avg, 8
@@ -252,15 +283,14 @@ cglobal_mc %1, mc20, %2, 3,4,9
     %define p16 [pw_16]
 %endif
 .nextrow:
-%if %0 == 4
-    movu     m2, [r1-4]
-    movu     m3, [r1-2]
-    movu     m4, [r1+0]
-    ADDW     m2, [r1+6], m5
-    ADDW     m3, [r1+4], m5
-    ADDW     m4, [r1+2], m5
+%if %2 == 4
+    movq     m2, [r1-4]
+    movq     m3, [r1-2]
+    movq     m4, [r1+0]
+    ADDW     m2, [r1+6], m5, movq
+    ADDW     m3, [r1+4], m5, movq
+    ADDW     m4, [r1+2], m5, movq
 %else ; movu is slow on these processors
-%if mmsize==16
     movu     m2, [r1-4]
     movu     m0, [r1+6]
     mova     m6, m0
@@ -274,16 +304,6 @@ cglobal_mc %1, mc20, %2, 3,4,9
     PALIGNR  m7, m0, m2, 6, m5
     paddw    m4, m7
     SWAP      2, 6
-%else
-    movu     m2, [r1-4]
-    movu     m6, [r1+4]
-    PALIGNR  m3, m6, m2, 2, m5
-    paddw    m3, m6
-    PALIGNR  m4, m6, m2, 4, m5
-    PALIGNR  m7, m6, m2, 6, m5
-    paddw    m4, m7
-    paddw    m2, [r1+6]
-%endif
 %endif

     FILT_H   m2, m3, m4, p16
@@ -327,15 +347,14 @@ cglobal_mc %1, mc10, %2, 3,5,9
     %define p16 [pw_16]
 %endif
 .nextrow:
-%if %0 == 4
-    movu     m2, [r1-4]
-    movu     m3, [r1-2]
-    movu     m4, [r1+0]
-    ADDW     m2, [r1+6], m5
-    ADDW     m3, [r1+4], m5
-    ADDW     m4, [r1+2], m5
+%if %2 == 4
+    movq     m2, [r1-4]
+    movq     m3, [r1-2]
+    movq     m4, [r1+0]
+    ADDW     m2, [r1+6], m5, movq
+    ADDW     m3, [r1+4], m5, movq
+    ADDW     m4, [r1+2], m5, movq
 %else ; movu is slow on these processors
-%if mmsize==16
     movu     m2, [r1-4]
     movu     m0, [r1+6]
     mova     m6, m0
@@ -349,23 +368,13 @@ cglobal_mc %1, mc10, %2, 3,5,9
     PALIGNR  m7, m0, m2, 6, m5
     paddw    m4, m7
     SWAP      2, 6
-%else
-    movu     m2, [r1-4]
-    movu     m6, [r1+4]
-    PALIGNR  m3, m6, m2, 2, m5
-    paddw    m3, m6
-    PALIGNR  m4, m6, m2, 4, m5
-    PALIGNR  m7, m6, m2, 6, m5
-    paddw    m4, m7
-    paddw    m2, [r1+6]
-%endif
 %endif

     FILT_H   m2, m3, m4, p16
     psraw    m2, 1
     pxor     m0, m0
     CLIPW    m2, m0, m1
-    movu     m3, [r4]
+    OP_LOAD  m3, [r4]
     pavgw    m2, m3
     OP_MOV [r0], m2
     add      r0, r2
@@ -391,8 +400,9 @@ v_filt%9_%10_10:
     ret
 %endmacro

-INIT_MMX mmxext
+INIT_XMM sse2
 RESET_MM_PERMUTATION
+%define OP_LOAD movq
 %assign i 0
 %rep 4
 V_FILT m0, m1, m2, m3, m4, m5, m6, m7, 4, i
@@ -402,6 +412,7 @@ SWAP 0,1,2,3,4,5

 INIT_XMM sse2
 RESET_MM_PERMUTATION
+%define OP_LOAD movu
 %assign i 0
 %rep 6
 V_FILT m0, m1, m2, m3, m4, m5, m6, m7, 8, i
@@ -442,7 +453,7 @@ cglobal_mc %1, mc01, %2, 3,5,8
 %rep %2
     %assign i (j % 6)
     call v_filt%2_ %+ i %+ _10
-    movu     m7, [r4]
+    OP_LOAD  m7, [r4]
     pavgw    m0, m7
     OP_MOV [r0], m0
     SWAP 0,1,2,3,4,5
@@ -472,16 +483,21 @@ h_filt%1_%2_10:
 ;FILT_H with fewer registers and averaged with the FILT_V result
 ;m6,m7 are tmp registers, m0 is the FILT_V result, the rest are to be used next in the next iteration
 ;unfortunately I need three registers, so m5 will have to be re-read from memory
-    movu     m5, [r4-4]
-    ADDW     m5, [r4+6], m7
-    movu     m6, [r4-2]
-    ADDW     m6, [r4+4], m7
+%if %1 == 4
+%define HROW movq
+%else
+%define HROW movu
+%endif
+    HROW     m5, [r4-4]
+    ADDW     m5, [r4+6], m7, HROW
+    HROW     m6, [r4-2]
+    ADDW     m6, [r4+4], m7, HROW
     paddw    m5, [pw_16]
     psubw    m5, m6  ; a-b
     psraw    m5, 2   ; (a-b)/4
     psubw    m5, m6  ; (a-b)/4-b
-    movu     m6, [r4+0]
-    ADDW     m6, [r4+2], m7
+    HROW     m6, [r4+0]
+    ADDW     m6, [r4+2], m7, HROW
     paddw    m5, m6  ; (a-b)/4-b+c
     psraw    m5, 2   ; ((a-b)/4-b+c)/4
     paddw    m5, m6  ; ((a-b)/4-b+c)/4+c = (a-5*b+20*c)/16
@@ -490,12 +506,12 @@ h_filt%1_%2_10:
 ;avg FILT_V, FILT_H
     pavgw    m0, m5
 %if %0!=4
-    movu     m5, [r1+r5]
+    HROW     m5, [r1+r5]
 %endif
     ret
 %endmacro

-INIT_MMX mmxext
+INIT_XMM sse2
 RESET_MM_PERMUTATION
 %assign i 0
 %rep 3
@@ -594,7 +610,7 @@ MC MC33
 %endmacro

 %macro FILT_VNRD 8
-    movu     %6, [r1]
+    ROWMOV   %6, [r1]
     paddw    %1, %6
     mova     %7, %2
     paddw    %7, %5
@@ -604,43 +620,47 @@ MC MC33
 %endmacro

 %macro HV 1
-%if mmsize==16
-%define PAD 12
-%define COUNT 2
+%if %1 == 8
+%assign ROWHV mmsize
+%assign PAD 12
+%assign COUNT 2
+%define ROWMOV movu
 %else
-%define PAD 4
-%define COUNT 3
+%assign ROWHV 8
+%assign PAD 4
+%assign COUNT 3
+%define ROWMOV movq
 %endif
 put_hv%1_10:
     neg      r2           ; This actually saves instructions
-    lea      r1, [r1+r2*2-mmsize+PAD]
+    lea      r1, [r1+r2*2-ROWHV+PAD]
     lea      r4, [rsp+PAD+gprsize]
     mov     r3d, COUNT
 .v_loop:
-    movu     m0, [r1]
+    ROWMOV   m0, [r1]
     sub      r1, r2
-    movu     m1, [r1]
+    ROWMOV   m1, [r1]
     sub      r1, r2
-    movu     m2, [r1]
+    ROWMOV   m2, [r1]
     sub      r1, r2
-    movu     m3, [r1]
+    ROWMOV   m3, [r1]
     sub      r1, r2
-    movu     m4, [r1]
+    ROWMOV   m4, [r1]
     sub      r1, r2
 %assign i 0
 %rep %1-1
     FILT_VNRD m0, m1, m2, m3, m4, m5, m6, m7
     psubw    m0, [pad20]
-    movu     [r4+i*mmsize*3], m0
+    ROWMOV   [r4+i*ROWHV*3], m0
     sub      r1, r2
     SWAP 0,1,2,3,4,5
 %assign i i+1
 %endrep
     FILT_VNRD m0, m1, m2, m3, m4, m5, m6, m7
     psubw    m0, [pad20]
-    movu     [r4+i*mmsize*3], m0
-    add      r4, mmsize
-    lea      r1, [r1+r2*8+mmsize]
+    ROWMOV   [r4+i*ROWHV*3], m0
+    add      r4, ROWHV
+    lea      r1, [r1+r2*8+ROWHV]
 %if %1==8
     lea      r1, [r1+r2*4]
 %endif
@@ -650,9 +670,8 @@ put_hv%1_10:
     ret
 %endmacro

-INIT_MMX mmxext
-HV 4
 INIT_XMM sse2
+HV 4
 HV 8

 %macro H_LOOP 1
@@ -667,13 +686,20 @@ HV 8
     %define s3 [tap3]
     %define d1 [depad]
 %endif
+%if %1 == 4
+%assign ROWHL 8
+%define ROWMOV movq
+%else
+%assign ROWHL mmsize
+%define ROWMOV movu
+%endif
 h%1_loop_op:
-    movu       m1, [r1+mmsize-4]
-    movu       m2, [r1+mmsize-2]
-    mova       m3, [r1+mmsize+0]
-    movu       m4, [r1+mmsize+2]
-    movu       m5, [r1+mmsize+4]
-    movu       m6, [r1+mmsize+6]
+    ROWMOV     m1, [r1+ROWHL-4]
+    ROWMOV     m2, [r1+ROWHL-2]
+    ROWMOV     m3, [r1+ROWHL+0]
+    ROWMOV     m4, [r1+ROWHL+2]
+    ROWMOV     m5, [r1+ROWHL+4]
+    ROWMOV     m6, [r1+ROWHL+6]
 %if num_mmregs > 8
     pmaddwd    m1, s1
     pmaddwd    m2, s1
@@ -710,18 +736,22 @@ h%1_loop_op:
     pxor       m0, m0
 %endif
     CLIPW      m1, m0, m7
-    add        r1, mmsize*3
+    add        r1, ROWHL*3
     ret
 %endmacro

-INIT_MMX mmxext
-H_LOOP 4
 INIT_XMM sse2
+H_LOOP 4
 H_LOOP 8

 %macro MC22 2
 cglobal_mc %1, mc22, %2, 3,7,12
-%define PAD mmsize*8*4*2      ; SIZE*16*4*sizeof(pixel)
+%if %2 == 4
+%assign PADMC22 8*8*4*2       ; SIZE*16*4*sizeof(pixel)
+%else
+%assign PADMC22 mmsize*8*4*2  ; SIZE*16*4*sizeof(pixel)
+%endif
+%define PAD PADMC22
     mov      r6, rsp          ; backup stack pointer
     and     rsp, ~(mmsize-1)  ; align stack
     sub     rsp, PAD
@@ -757,7 +787,16 @@ MC MC22
 ;-----------------------------------------------------------------------------
 %macro MC12 2
 cglobal_mc %1, mc12, %2, 3,7,12
-%define PAD mmsize*8*4*2        ; SIZE*16*4*sizeof(pixel)
+%if %2 == 4
+%assign RBMC12 8
+%assign PADMC12 8*8*4*2        ; SIZE*16*4*sizeof(pixel)
+%define ROWMOV movq
+%else
+%assign RBMC12 mmsize
+%assign PADMC12 mmsize*8*4*2   ; SIZE*16*4*sizeof(pixel)
+%define ROWMOV movu
+%endif
+%define PAD PADMC12
     mov        r6, rsp          ; backup stack pointer
     and       rsp, ~(mmsize-1)  ; align stack
     sub       rsp, PAD
@@ -779,7 +818,7 @@ cglobal_mc %1, mc12, %2, 3,7,12
 .h_loop:
     call h%2_loop_op

-    movu       m3, [r1+r4-2*mmsize] ; movu needed for mc32, etc
+    ROWMOV     m3, [r1+r4-2*RBMC12] ; movu needed for mc32, etc
     paddw      m3, [depad2]
     psrlw      m3, 5
     psubw      m3, [unpad]
@@ -819,23 +858,30 @@ MC MC32
 ; void ff_h264_qpel_mc21(uint8_t *dst, uint8_t *src, int stride)
 ;-----------------------------------------------------------------------------
 %macro H_NRD 1
+%if %1 == 4
+%assign ROWHN 8
+%define ROWMOV movq
+%else
+%assign ROWHN mmsize
+%define ROWMOV movu
+%endif
 put_h%1_10:
     add       rsp, gprsize
     mov       r3d, %1
     xor       r4d, r4d
     mova       m6, [pad20]
 .nextrow:
-    movu       m2, [r5-4]
-    movu       m3, [r5-2]
-    movu       m4, [r5+0]
-    ADDW       m2, [r5+6], m5
-    ADDW       m3, [r5+4], m5
-    ADDW       m4, [r5+2], m5
+    ROWMOV     m2, [r5-4]
+    ROWMOV     m3, [r5-2]
+    ROWMOV     m4, [r5+0]
+    ADDW       m2, [r5+6], m5, ROWMOV
+    ADDW       m3, [r5+4], m5, ROWMOV
+    ADDW       m4, [r5+2], m5, ROWMOV

     FILT_H2    m2, m3, m4
     psubw      m2, m6
-    mova [rsp+r4], m2
-    add       r4d, mmsize*3
+    ROWMOV [rsp+r4], m2
+    add       r4d, ROWHN*3
     add        r5, r2
     dec       r3d
     jg .nextrow
@@ -843,26 +889,31 @@ put_h%1_10:
     ret
 %endmacro

-INIT_MMX mmxext
-H_NRD 4
 INIT_XMM sse2
+H_NRD 4
 H_NRD 8

 %macro MC21 2
 cglobal_mc %1, mc21, %2, 3,7,12
     mov   r5, r1
 .body:
-%define PAD mmsize*8*3*2   ; SIZE*16*4*sizeof(pixel)
+%if %2 == 4
+%assign RBMC21 8
+%assign PADMC21 8*8*3*2     ; SIZE*16*4*sizeof(pixel)
+%else
+%assign RBMC21 mmsize
+%assign PADMC21 mmsize*8*3*2 ; SIZE*16*4*sizeof(pixel)
+%endif
     mov   r6, rsp          ; backup stack pointer
     and  rsp, ~(mmsize-1)  ; align stack

-    sub  rsp, PAD
+    sub  rsp, PADMC21
     call put_h%2_10

-    sub  rsp, PAD
+    sub  rsp, PADMC21
     call put_hv%2_10

-    mov r4d, PAD-mmsize    ; H buffer
+    mov r4d, PADMC21-RBMC21 ; H buffer
     jmp stub_%1_h264_qpel%2_mc12_10 %+ SUFFIX %+ .body
 %endmacro

diff --git a/libavcodec/x86/h264_qpel_8bit.asm b/libavcodec/x86/h264_qpel_8bit.asm
index 2bfe6042a1..4335cf0290 100644
--- a/libavcodec/x86/h264_qpel_8bit.asm
+++ b/libavcodec/x86/h264_qpel_8bit.asm
@@ -1,5 +1,5 @@
 ;*****************************************************************************
-;* MMX/SSE2/SSSE3-optimized H.264 QPEL code
+;* SSE2/SSSE3-optimized H.264 QPEL code
 ;*****************************************************************************
 ;* Copyright (c) 2004-2005 Michael Niedermayer, Loren Merritt
 ;* Copyright (C) 2012 Daniel Kang
@@ -31,23 +31,27 @@ cextern pb_0

 SECTION .text

-; void ff_avg_pixels4_mmxext(uint8_t *block, const uint8_t *pixels,
-;                            ptrdiff_t line_size)
-INIT_MMX mmxext
-cglobal avg_pixels4, 3,4
+; void ff_avg_pixels4_sse2(uint8_t *block, const uint8_t *pixels,
+;                         ptrdiff_t line_size)
+INIT_XMM sse2
+cglobal avg_pixels4, 3,4,5
     lea          r3, [r2*3]
-    movh         m0, [r1]
-    movh         m1, [r1+r2]
-    movh         m2, [r1+r2*2]
-    movh         m3, [r1+r3]
-    pavgb        m0, [r0]
-    pavgb        m1, [r0+r2]
-    pavgb        m2, [r0+r2*2]
-    pavgb        m3, [r0+r3]
-    movh       [r0], m0
-    movh    [r0+r2], m1
-    movh  [r0+r2*2], m2
-    movh    [r0+r3], m3
+    movd         m0, [r1]
+    movd         m1, [r1+r2]
+    movd         m2, [r1+r2*2]
+    movd         m3, [r1+r3]
+    movd         m4, [r0]
+    pavgb        m0, m4
+    movd         m4, [r0+r2]
+    pavgb        m1, m4
+    movd         m4, [r0+r2*2]
+    pavgb        m2, m4
+    movd         m4, [r0+r3]
+    pavgb        m3, m4
+    movd       [r0], m0
+    movd    [r0+r2], m1
+    movd  [r0+r2*2], m2
+    movd    [r0+r3], m3
     RET

 %macro op_avgh 3
@@ -65,57 +69,73 @@ cglobal avg_pixels4, 3,4
     movh   %2, %1
 %endmacro

+; 4-wide rows are 4 bytes: movh (movq under XMM) would read 4 extra
+; bytes per row, so these use movd. op_*h stays for 8-wide rows.
+%macro op_avgf 3
+    movd   %3, %2
+    pavgb  %1, %3
+    movd   %2, %1
+%endmacro
+
+%macro op_putf 2-3
+    movd   %2, %1
+%endmacro
+
 %macro op_put 2-3
     mova   %2, %1
 %endmacro

-; void ff_put/avg_pixels4x4_l2_mmxext(uint8_t *dst, const uint8_t *src1, const uint8_t *src2,
-;                                     ptrdiff_t stride)
+; void ff_put/avg_pixels4x4_l2_sse2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2,
+;                                  ptrdiff_t stride)
 %macro PIXELS4_L2 1
-%define OP op_%1h
-cglobal %1_pixels4x4_l2, 4,4
-    mova         m0, [r1]
-    mova         m1, [r1+r3]
+%define OP op_%1f
+cglobal %1_pixels4x4_l2, 4,4,4
+    movh         m0, [r1]
+    movh         m1, [r1+r3]
     lea          r1, [r1+2*r3]
-    pavgb        m0, [r2]
-    pavgb        m1, [r2+4]
+    movh         m3, [r2]
+    pavgb        m0, m3
+    movh         m3, [r2+4]
+    pavgb        m1, m3
     OP           m0, [r0], m3
     OP           m1, [r0+r3], m3
     lea          r0, [r0+2*r3]
-    mova         m0, [r1]
-    mova         m1, [r1+r3]
-    pavgb        m0, [r2+8]
-    pavgb        m1, [r2+12]
+    movh         m0, [r1]
+    movh         m1, [r1+r3]
+    movh         m3, [r2+8]
+    pavgb        m0, m3
+    movh         m3, [r2+12]
+    pavgb        m1, m3
     OP           m0, [r0], m3
     OP           m1, [r0+r3], m3
     RET
 %endmacro

-INIT_MMX mmxext
+INIT_XMM sse2
 PIXELS4_L2 put
 PIXELS4_L2 avg

 %macro QPEL4_H_LOWPASS_OP 1
-cglobal %1_h264_qpel4_h_lowpass, 4,5 ; dst, src, dstStride, srcStride
-    pxor          m7, m7
+cglobal %1_h264_qpel4_h_lowpass, 4,5,7 ; dst, src, dstStride, srcStride
+    pxor          m6, m6
     mova          m4, [pw_5]
     mova          m5, [pw_16]
     mov          r4d, 4
 .loop:
-    movh          m1, [r1-1]
-    movh          m2, [r1+0]
-    movh          m3, [r1+1]
-    movh          m0, [r1+2]
-    punpcklbw     m1, m7
-    punpcklbw     m2, m7
-    punpcklbw     m3, m7
-    punpcklbw     m0, m7
+    movd          m1, [r1-1]
+    movd          m2, [r1+0]
+    movd          m3, [r1+1]
+    movd          m0, [r1+2]
+    punpcklbw     m1, m6
+    punpcklbw     m2, m6
+    punpcklbw     m3, m6
+    punpcklbw     m0, m6
     paddw         m1, m0
     paddw         m2, m3
-    movh          m0, [r1-2]
-    movh          m3, [r1+3]
-    punpcklbw     m0, m7
-    punpcklbw     m3, m7
+    movd          m0, [r1-2]
+    movd          m3, [r1+3]
+    punpcklbw     m0, m6
+    punpcklbw     m3, m6
     paddw         m0, m3
     psllw         m2, 2
     psubw         m2, m1
@@ -124,7 +144,7 @@ cglobal %1_h264_qpel4_h_lowpass, 4,5 ; dst, src, dstStride, srcStride
     paddw         m0, m2
     psraw         m0, 5
     packuswb      m0, m0
-    op_%1h        m0, [r0], m6
+    op_%1f        m0, [r0], m1
     add           r0, r2
     add           r1, r3
     dec          r4d
@@ -132,7 +152,7 @@ cglobal %1_h264_qpel4_h_lowpass, 4,5 ; dst, src, dstStride, srcStride
     RET
 %endmacro

-INIT_MMX mmxext
+INIT_XMM sse2
 QPEL4_H_LOWPASS_OP put
 QPEL4_H_LOWPASS_OP avg

@@ -179,37 +199,37 @@ QPEL8_H_LOWPASS_OP_XMM avg


 %macro QPEL4_H_LOWPASS_L2_OP 1
-cglobal %1_h264_qpel4_h_lowpass_l2, 5,6 ; dst, src, src2, dstStride, srcStride
-    pxor          m7, m7
+cglobal %1_h264_qpel4_h_lowpass_l2, 5,6,7 ; dst, src, src2, dstStride, srcStride
+    pxor          m6, m6
     mova          m4, [pw_5]
     mova          m5, [pw_16]
     mov          r5d, 4
 .loop:
-    movh          m1, [r1-1]
-    movh          m2, [r1+0]
-    movh          m3, [r1+1]
-    movh          m0, [r1+2]
-    punpcklbw     m1, m7
-    punpcklbw     m2, m7
-    punpcklbw     m3, m7
-    punpcklbw     m0, m7
+    movd          m1, [r1-1]
+    movd          m2, [r1+0]
+    movd          m3, [r1+1]
+    movd          m0, [r1+2]
+    punpcklbw     m1, m6
+    punpcklbw     m2, m6
+    punpcklbw     m3, m6
+    punpcklbw     m0, m6
     paddw         m1, m0
     paddw         m2, m3
-    movh          m0, [r1-2]
-    movh          m3, [r1+3]
-    punpcklbw     m0, m7
-    punpcklbw     m3, m7
+    movd          m0, [r1-2]
+    movd          m3, [r1+3]
+    punpcklbw     m0, m6
+    punpcklbw     m3, m6
     paddw         m0, m3
     psllw         m2, 2
     psubw         m2, m1
     pmullw        m2, m4
     paddw         m0, m5
     paddw         m0, m2
-    movh          m3, [r2]
+    movd          m3, [r2]
     psraw         m0, 5
     packuswb      m0, m0
     pavgb         m0, m3
-    op_%1h        m0, [r0], m6
+    op_%1f        m0, [r0], m1
     add           r0, r3
     add           r1, r3
     add           r2, r4
@@ -218,7 +238,7 @@ cglobal %1_h264_qpel4_h_lowpass_l2, 5,6 ; dst, src, src2, dstStride, srcStride
     RET
 %endmacro

-INIT_MMX mmxext
+INIT_XMM sse2
 QPEL4_H_LOWPASS_L2_OP put
 QPEL4_H_LOWPASS_L2_OP avg

@@ -387,13 +407,15 @@ QPEL8_H_LOWPASS_L2_OP_XMM avg

 ; All functions that call this are required to have function arguments of
 ; dst, src, dstStride, srcStride
+; %1 is the full store op (op_puth/op_avgh for 8-wide rows,
+; op_putf/op_avgf for 4-wide rows)
 %macro FILT_V 1-2
 %ifnidn %2, last
     mova      m6, m2
 %else
     SWAP       6, 2
 %endif
-    movh      m5, [r1]
+    OP_LOAD   m5, [r1]
     paddw     m6, m3
     psllw     m6, 2
     psubw     m6, m1
@@ -406,7 +428,7 @@ QPEL8_H_LOWPASS_L2_OP_XMM avg
     paddw     m6, m0
     psraw     m6, 5
     packuswb  m6, m6
-    op_%1h    m6, [r0], m0 ; 1
+    %1        m6, [r0], m0 ; 1
 %ifnidn %2, last
     add       r0, r2
 %endif
@@ -414,31 +436,32 @@ QPEL8_H_LOWPASS_L2_OP_XMM avg
 %endmacro

 %macro QPEL4_V_LOWPASS_OP 1
-cglobal %1_h264_qpel4_v_lowpass, 4,4 ; dst, src, dstStride, srcStride
+cglobal %1_h264_qpel4_v_lowpass, 4,4,8 ; dst, src, dstStride, srcStride
     sub           r1, r3
     sub           r1, r3
     pxor          m7, m7
-    movh          m0, [r1]
-    movh          m1, [r1+r3]
+    movd          m0, [r1]
+    movd          m1, [r1+r3]
     lea           r1, [r1+2*r3]
-    movh          m2, [r1]
-    movh          m3, [r1+r3]
+    movd          m2, [r1]
+    movd          m3, [r1+r3]
     lea           r1, [r1+2*r3]
-    movh          m4, [r1]
+    movd          m4, [r1]
     add           r1, r3
     punpcklbw     m0, m7
     punpcklbw     m1, m7
     punpcklbw     m2, m7
     punpcklbw     m3, m7
     punpcklbw     m4, m7
-    FILT_V        %1
-    FILT_V        %1
-    FILT_V        %1
-    FILT_V        %1, last
+    FILT_V        op_%1f
+    FILT_V        op_%1f
+    FILT_V        op_%1f
+    FILT_V        op_%1f, last
     RET
 %endmacro

-INIT_MMX mmxext
+%define OP_LOAD movd
+INIT_XMM sse2
 QPEL4_V_LOWPASS_OP put
 QPEL4_V_LOWPASS_OP avg

@@ -462,28 +485,29 @@ cglobal %1_h264_qpel8or16_v_lowpass, 5,5,8 ; dst, src, dstStride, srcStride, h
     punpcklbw     m2, m7
     punpcklbw     m3, m7
     punpcklbw     m4, m7
-    FILT_V        %1
-    FILT_V        %1
-    FILT_V        %1
-    FILT_V        %1
-    FILT_V        %1
-    FILT_V        %1
-    FILT_V        %1
-    FILT_V        %1
+    FILT_V        op_%1h
+    FILT_V        op_%1h
+    FILT_V        op_%1h
+    FILT_V        op_%1h
+    FILT_V        op_%1h
+    FILT_V        op_%1h
+    FILT_V        op_%1h
+    FILT_V        op_%1h
     cmp          r4d, 16
     jne         .end
-    FILT_V        %1
-    FILT_V        %1
-    FILT_V        %1
-    FILT_V        %1
-    FILT_V        %1
-    FILT_V        %1
-    FILT_V        %1
-    FILT_V        %1, last
+    FILT_V        op_%1h
+    FILT_V        op_%1h
+    FILT_V        op_%1h
+    FILT_V        op_%1h
+    FILT_V        op_%1h
+    FILT_V        op_%1h
+    FILT_V        op_%1h
+    FILT_V        op_%1h, last
 .end:
     RET
 %endmacro

+%define OP_LOAD movh
 INIT_XMM sse2
 QPEL8OR16_V_LOWPASS_OP put
 QPEL8OR16_V_LOWPASS_OP avg
@@ -491,13 +515,15 @@ QPEL8OR16_V_LOWPASS_OP avg

 ; All functions that use this are required to have args:
 ; src, tmp, srcSize
+; HV_STORE selects the 8-byte (movq, 4-wide) or 16-byte (mova, 8/16-wide)
+; tmp row store; set it before instantiating.
 %macro FILT_HV 1-2 ; offset, last
 %ifnidn %2, last
     mova           m6, m2
 %else
     SWAP            2, 6
 %endif
-    movh           m5, [r0]
+    OP_LOAD        m5, [r0]
     paddw          m6, m3
     psllw          m6, 2
     paddw          m0, [pw_16]
@@ -510,23 +536,25 @@ QPEL8OR16_V_LOWPASS_OP avg
     add            r0, r2
 %endif
     paddw          m6, m0
-    mova      [r1+%1], m6
+    HV_STORE  [r1+%1], m6
     SWAP            0, 1, 2, 3, 4, 5
 %endmacro

-INIT_MMX mmxext
-cglobal put_h264_qpel4_hv_lowpass_v, 3,5 ; src, tmp, srcStride
+%define HV_STORE movq
+%define OP_LOAD movd
+INIT_XMM sse2
+cglobal put_h264_qpel4_hv_lowpass_v, 3,5,8 ; src, tmp, srcStride
     mov          r4d, 3
     mov           r3, r0
     pxor          m7, m7
 .loop:
-    movh          m0, [r0]
-    movh          m1, [r0+r2]
+    movd          m0, [r0]
+    movd          m1, [r0+r2]
     lea           r0, [r0+2*r2]
-    movh          m2, [r0]
-    movh          m3, [r0+r2]
+    movd          m2, [r0]
+    movd          m3, [r0+r2]
     lea           r0, [r0+2*r2]
-    movh          m4, [r0]
+    movd          m4, [r0]
     add           r0, r2
     punpcklbw     m0, m7
     punpcklbw     m1, m7
@@ -544,16 +572,21 @@ cglobal put_h264_qpel4_hv_lowpass_v, 3,5 ; src, tmp, srcStride
     jnz        .loop
     RET

+%define HV_STORE mova
+%define OP_LOAD movh
 %macro QPEL4_HV1_LOWPASS_OP 1
-cglobal %1_h264_qpel4_hv_lowpass_h, 3,4 ; tmp, dst, dstStride
+cglobal %1_h264_qpel4_hv_lowpass_h, 3,4,5 ; tmp, dst, dstStride
     mov          r3d, 4
 .loop:
-    mova          m0, [r0]
-    paddw         m0, [r0+10]
-    mova          m1, [r0+2]
-    paddw         m1, [r0+8]
-    mova          m2, [r0+4]
-    paddw         m2, [r0+6]
+    movq          m0, [r0]
+    movq          m3, [r0+10]
+    paddw         m0, m3
+    movq          m1, [r0+2]
+    movq          m3, [r0+8]
+    paddw         m1, m3
+    movq          m2, [r0+4]
+    movq          m3, [r0+6]
+    paddw         m2, m3
     psubw         m0, m1
     psraw         m0, 2
     psubw         m0, m1
@@ -562,7 +595,7 @@ cglobal %1_h264_qpel4_hv_lowpass_h, 3,4 ; tmp, dst, dstStride
     paddw         m0, m2
     psraw         m0, 6
     packuswb      m0, m0
-    op_%1h        m0, [r1], m7
+    op_%1f        m0, [r1], m4
     add           r0, 24
     add           r1, r2
     dec          r3d
@@ -570,7 +603,7 @@ cglobal %1_h264_qpel4_hv_lowpass_h, 3,4 ; tmp, dst, dstStride
     RET
 %endmacro

-INIT_MMX mmxext
+INIT_XMM sse2
 QPEL4_HV1_LOWPASS_OP put
 QPEL4_HV1_LOWPASS_OP avg

@@ -753,32 +786,36 @@ QPEL8OR16_HV2_LOWPASS_OP_XMM avg


 %macro PIXELS4_L2_SHIFT5 1
-cglobal %1_pixels4_l2_shift5,4,4 ; dst, src16, src8, dstStride
-    mova          m0, [r1]
-    mova          m1, [r1+24]
+cglobal %1_pixels4_l2_shift5,4,4,6 ; dst, src16, src8, dstStride
+    movh          m0, [r1]
+    movh          m1, [r1+24]
     psraw         m0, 5
     psraw         m1, 5
     packuswb      m0, m0
     packuswb      m1, m1
-    pavgb         m0, [r2]
-    pavgb         m1, [r2+4]
-    op_%1h        m0, [r0], m4
-    op_%1h        m1, [r0+r3], m5
+    movh          m2, [r2]
+    pavgb         m0, m2
+    movh          m2, [r2+4]
+    pavgb         m1, m2
+    op_%1f        m0, [r0], m4
+    op_%1f        m1, [r0+r3], m5
     lea           r0, [r0+r3*2]
-    mova          m0, [r1+48]
-    mova          m1, [r1+72]
+    movh          m0, [r1+48]
+    movh          m1, [r1+72]
     psraw         m0, 5
     psraw         m1, 5
     packuswb      m0, m0
     packuswb      m1, m1
-    pavgb         m0, [r2+2*4]
-    pavgb         m1, [r2+3*4]
-    op_%1h        m0, [r0], m4
-    op_%1h        m1, [r0+r3], m5
+    movh          m2, [r2+2*4]
+    pavgb         m0, m2
+    movh          m2, [r2+3*4]
+    pavgb         m1, m2
+    op_%1f        m0, [r0], m4
+    op_%1f        m1, [r0+r3], m5
     RET
 %endmacro

-INIT_MMX mmxext
+INIT_XMM sse2
 PIXELS4_L2_SHIFT5 put
 PIXELS4_L2_SHIFT5 avg

diff --git a/tests/checkasm/h264qpel.c b/tests/checkasm/h264qpel.c
index 96e781f78e..1e28eb95a6 100644
--- a/tests/checkasm/h264qpel.c
+++ b/tests/checkasm/h264qpel.c
@@ -74,7 +74,7 @@ void checkasm_check_h264qpel(void)
     LOCAL_ALIGNED_16(uint8_t, dst1, [BUF_SIZE]);
     H264QpelContext h;
     int op, bit_depth, i, j;
-    declare_func_emms(AV_CPU_FLAG_MMX | AV_CPU_FLAG_MMXEXT, void, uint8_t *dst, const uint8_t *src, ptrdiff_t stride);
+    declare_func(void, uint8_t *dst, const uint8_t *src, ptrdiff_t stride);

     for (op = 0; op < 2; op++) {
         qpel_mc_func (*tab)[16] = op ? h.avg_h264_qpel_pixels_tab : h.put_h264_qpel_pixels_tab;