PR #24346 opened by zuxy
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24346
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24346.patch

Deprecate use of MMX registers in h264's weight/bi-weight prediction




>From 995aa0dedf238d7ec10abbca8f2be992a5fabbb4 Mon Sep 17 00:00:00 2001
From: Zuxy Meng <[email protected]>
Date: Fri, 21 Aug 2026 22:04:57 -0700
Subject: [PATCH 1/2] avcodec/x86/h264_weight: Remove MMX

SSE2/SSSE3 impl. of MMX weight/bi-weight functions. Identical or
slightly better performance:

  biweight_4x16_8_mmxext:                          26.3 ( 2.37x)
  biweight_4x16_8_sse2:                            24.4 ( 2.54x)
  biweight_4x16_8_ssse3:                           19.7 ( 3.13x)
  weight_4x16_8_mmxext:                            20.0 ( 2.34x)
  weight_4x16_8_sse2:                              19.5 ( 2.33x)

Signed-off-by: Zuxy Meng <[email protected]>
---
 libavcodec/x86/h264_weight.asm | 79 ++++++++++++++++++++--------------
 libavcodec/x86/h264dsp_init.c  | 13 ++----
 tests/checkasm/h264dsp.c       |  9 ++--
 3 files changed, 55 insertions(+), 46 deletions(-)

diff --git a/libavcodec/x86/h264_weight.asm b/libavcodec/x86/h264_weight.asm
index 5524f3e28c..acd6cfbfdd 100644
--- a/libavcodec/x86/h264_weight.asm
+++ b/libavcodec/x86/h264_weight.asm
@@ -44,21 +44,21 @@ SECTION .text
     movd       m6, r3d
     pslld      m5, m6
     psrld      m5, 1
-%if mmsize == 16
     pshuflw    m3, m3, 0
     pshuflw    m5, m5, 0
     punpcklqdq m3, m3
     punpcklqdq m5, m5
-%else
-    pshufw     m3, m3, 0
-    pshufw     m5, m5, 0
-%endif
     pxor       m7, m7
 %endmacro
 
-%macro WEIGHT_OP 2
+%macro WEIGHT_OP 3
+%if %3 == 4
+    movd          m0, [r0+%1]
+    movd          m1, [r0+%2]
+%else
     movh          m0, [r0+%1]
     movh          m1, [r0+%2]
+%endif
     punpcklbw     m0, m7
     punpcklbw     m1, m7
     pmullw        m0, m3
@@ -70,11 +70,11 @@ SECTION .text
     packuswb      m0, m1
 %endmacro
 
-%macro WEIGHT_FUNC_MM 2
-cglobal h264_weight_%1, 6, 6, %2
+%macro WEIGHT_FUNC_MM 1
+cglobal h264_weight_%1, 6, 6, 8
     WEIGHT_SETUP
 .nextrow:
-    WEIGHT_OP 0, mmsize/2
+    WEIGHT_OP 0, mmsize/2, %1
     mova     [r0], m0
     add        r0, r1
     dec        r2d
@@ -83,21 +83,22 @@ cglobal h264_weight_%1, 6, 6, %2
 %endmacro
 
 INIT_XMM sse2
-WEIGHT_FUNC_MM 16, 8
+WEIGHT_FUNC_MM 16
 
-%macro WEIGHT_FUNC_HALF_MM 2
-cglobal h264_weight_%1, 6, 6, %2
+%macro WEIGHT_FUNC_HALF_MM 1
+cglobal h264_weight_%1, 6, 6, 8
     WEIGHT_SETUP
     sar       r2d, 1
     lea        r3, [r1*2]
 .nextrow:
-    WEIGHT_OP 0, r1
+    WEIGHT_OP 0, r1, %1
+%if %1 > 4
     movh     [r0], m0
-%if mmsize == 16
     movhps   [r0+r1], m0
 %else
-    psrlq      m0, 32
-    movh     [r0+r1], m0
+    movd     [r0], m0
+    psrldq     m0, 8
+    movd     [r0+r1], m0
 %endif
     add        r0, r3
     dec        r2d
@@ -105,10 +106,10 @@ cglobal h264_weight_%1, 6, 6, %2
     RET
 %endmacro
 
-INIT_MMX mmxext
-WEIGHT_FUNC_HALF_MM 4, 0
 INIT_XMM sse2
-WEIGHT_FUNC_HALF_MM 8, 8
+WEIGHT_FUNC_HALF_MM 4
+INIT_XMM sse2
+WEIGHT_FUNC_HALF_MM 8
 
 %macro BIWEIGHT_SETUP 0
 %if ARCH_X86_64
@@ -149,18 +150,12 @@ WEIGHT_FUNC_HALF_MM 8, 8
     punpcklqdq m5, m5
 
 %else
-%if mmsize == 16
     pshuflw    m3, m3, 0
     pshuflw    m4, m4, 0
     pshuflw    m5, m5, 0
     punpcklqdq m3, m3
     punpcklqdq m4, m4
     punpcklqdq m5, m5
-%else
-    pshufw     m3, m3, 0
-    pshufw     m4, m4, 0
-    pshufw     m5, m5, 0
-%endif
     pxor       m7, m7
 %endif
 %endmacro
@@ -206,6 +201,28 @@ BIWEIGHT_FUNC_MM 16, 8
 cglobal h264_biweight_%1, 7, 8, %2
     BIWEIGHT_SETUP
     movifnidn r3d, r3m
+%if %1 == 4
+    ; for 4 with sse2, process 1 row at a time
+.nextrow:
+    movd       m0, [r0]
+    movd       m1, [r1]
+%if cpuflag(ssse3)
+    punpcklbw  m0, m1
+    pmaddubsw  m0, m4
+%else
+    punpcklbw  m0, m7
+    punpcklbw  m1, m7
+    pmullw     m0, m3
+    pmullw     m1, m4
+    paddsw     m0, m1
+%endif
+    paddsw     m0, m5
+    psraw      m0, m6
+    packuswb   m0, m0
+    movd       [r0], m0
+    add        r0, r2
+    add        r1, r2
+%else
     sar       r3d, 1
     lea        r4, [r2*2]
 .nextrow:
@@ -213,21 +230,19 @@ cglobal h264_biweight_%1, 7, 8, %2
     BIWEIGHT_STEPA 1, 2, r2
     BIWEIGHT_STEPB
     movh       [r0], m0
-%if mmsize == 16
     movhps     [r0+r2], m0
-%else
-    psrlq      m0, 32
-    movh       [r0+r2], m0
-%endif
     add        r0, r4
     add        r1, r4
+%endif
     dec        r3d
     jnz .nextrow
     RET
 %endmacro
 
-INIT_MMX mmxext
-BIWEIGHT_FUNC_HALF_MM 4, 0
+INIT_XMM sse2
+BIWEIGHT_FUNC_HALF_MM 4, 8
+INIT_XMM ssse3
+BIWEIGHT_FUNC_HALF_MM 4, 7
 INIT_XMM sse2
 BIWEIGHT_FUNC_HALF_MM 8, 8
 
diff --git a/libavcodec/x86/h264dsp_init.c b/libavcodec/x86/h264dsp_init.c
index d853219fb1..654316c2af 100644
--- a/libavcodec/x86/h264dsp_init.c
+++ b/libavcodec/x86/h264dsp_init.c
@@ -140,10 +140,6 @@ void ff_h264_biweight_ ## W ## _ ## OPT(uint8_t *dst, 
uint8_t *src,     \
                                         int log2_denom, int weightd,    \
                                         int weights, int offset);
 
-#define H264_BIWEIGHT_MMX(W)                    \
-    H264_WEIGHT(W, mmxext)                      \
-    H264_BIWEIGHT(W, mmxext)
-
 #define H264_BIWEIGHT_SSE(W)                    \
     H264_WEIGHT(W, sse2)                        \
     H264_BIWEIGHT(W, sse2)                      \
@@ -151,7 +147,7 @@ void ff_h264_biweight_ ## W ## _ ## OPT(uint8_t *dst, 
uint8_t *src,     \
 
 H264_BIWEIGHT_SSE(16)
 H264_BIWEIGHT_SSE(8)
-H264_BIWEIGHT_MMX(4)
+H264_BIWEIGHT_SSE(4)
 
 #define H264_WEIGHT_10(W, DEPTH, OPT)                                   \
 void ff_h264_weight_ ## W ## _ ## DEPTH ## _ ## OPT(uint8_t *dst,       \
@@ -198,10 +194,6 @@ av_cold void ff_h264dsp_init_x86(H264DSPContext *c, const 
int bit_depth,
         }
         if (EXTERNAL_MMXEXT(cpu_flags)) {
             c->idct8_dc_add = ff_h264_idct8_dc_add_8_mmxext;
-
-            c->weight_pixels_tab[2] = ff_h264_weight_4_mmxext;
-
-            c->biweight_pixels_tab[2] = ff_h264_biweight_4_mmxext;
         }
         if (EXTERNAL_SSE2(cpu_flags)) {
             c->idct8_add  = ff_h264_idct8_add_8_sse2;
@@ -215,9 +207,11 @@ av_cold void ff_h264dsp_init_x86(H264DSPContext *c, const 
int bit_depth,
 
             c->weight_pixels_tab[0] = ff_h264_weight_16_sse2;
             c->weight_pixels_tab[1] = ff_h264_weight_8_sse2;
+            c->weight_pixels_tab[2] = ff_h264_weight_4_sse2;
 
             c->biweight_pixels_tab[0] = ff_h264_biweight_16_sse2;
             c->biweight_pixels_tab[1] = ff_h264_biweight_8_sse2;
+            c->biweight_pixels_tab[2] = ff_h264_biweight_4_sse2;
 
             c->v_loop_filter_luma       = ff_deblock_v_luma_8_sse2;
             c->h_loop_filter_luma       = ff_deblock_h_luma_8_sse2;
@@ -244,6 +238,7 @@ av_cold void ff_h264dsp_init_x86(H264DSPContext *c, const 
int bit_depth,
         if (EXTERNAL_SSSE3(cpu_flags)) {
             c->biweight_pixels_tab[0] = ff_h264_biweight_16_ssse3;
             c->biweight_pixels_tab[1] = ff_h264_biweight_8_ssse3;
+            c->biweight_pixels_tab[2] = ff_h264_biweight_4_ssse3;
         }
         if (EXTERNAL_AVX(cpu_flags)) {
             c->v_loop_filter_luma       = ff_deblock_v_luma_8_avx;
diff --git a/tests/checkasm/h264dsp.c b/tests/checkasm/h264dsp.c
index cc2d7524da..30478f2956 100644
--- a/tests/checkasm/h264dsp.c
+++ b/tests/checkasm/h264dsp.c
@@ -510,8 +510,8 @@ static void check_weight(void)
     LOCAL_ALIGNED_16(uint8_t, dst0, [32 * 32 * 2]);
     LOCAL_ALIGNED_16(uint8_t, dst1, [32 * 32 * 2]);
     H264DSPContext h;
-    declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, ptrdiff_t stride,
-                      int height, int log2_denom, int weight, int offset);
+    declare_func(void, uint8_t *dst, ptrdiff_t stride, int height,
+                 int log2_denom, int weight, int offset);
 
     for (int bit_depth = 8; bit_depth <= 10; bit_depth += 2) {
         ff_h264dsp_init(&h, bit_depth, 1);
@@ -562,9 +562,8 @@ static void check_biweight(void)
     LOCAL_ALIGNED_16(uint8_t, src0, [32 * 32 * 2]);
     LOCAL_ALIGNED_16(uint8_t, src1, [32 * 32 * 2]);
     H264DSPContext h;
-    declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, uint8_t *src,
-                      ptrdiff_t stride, int height, int log2_denom,
-                      int weightd, int weights, int offset);
+    declare_func(void, uint8_t *dst, uint8_t *src, ptrdiff_t stride, int 
height,
+                 int log2_denom, int weightd, int weights, int offset);
 
     for (int bit_depth = 8; bit_depth <= 10; bit_depth += 2) {
         uint32_t mask = pixel_mask[bit_depth - 8];
-- 
2.52.0


>From 03c738adaa5d86560e548b292bfdafd4c2aab987 Mon Sep 17 00:00:00 2001
From: Zuxy Meng <[email protected]>
Date: Sat, 22 Aug 2026 17:58:36 -0700
Subject: [PATCH 2/2] avcodec/x86/h264_weight: less callee saved XMM registers
 in Windows

Tweak usage of XMM regisers so that Windows can save less upon function
entry.

Signed-off-by: Zuxy Meng <[email protected]>
---
 libavcodec/x86/h264_weight.asm       | 80 ++++++++++++++--------------
 libavcodec/x86/h264_weight_10bit.asm | 28 ++++++----
 2 files changed, 58 insertions(+), 50 deletions(-)

diff --git a/libavcodec/x86/h264_weight.asm b/libavcodec/x86/h264_weight.asm
index acd6cfbfdd..751c910b71 100644
--- a/libavcodec/x86/h264_weight.asm
+++ b/libavcodec/x86/h264_weight.asm
@@ -41,14 +41,14 @@ SECTION .text
     inc        r5
     movd       m3, r4d
     movd       m5, r5d
-    movd       m6, r3d
-    pslld      m5, m6
+    movd       m2, r3d
+    pslld      m5, m2
     psrld      m5, 1
     pshuflw    m3, m3, 0
     pshuflw    m5, m5, 0
     punpcklqdq m3, m3
     punpcklqdq m5, m5
-    pxor       m7, m7
+    pxor       m4, m4
 %endmacro
 
 %macro WEIGHT_OP 3
@@ -59,19 +59,19 @@ SECTION .text
     movh          m0, [r0+%1]
     movh          m1, [r0+%2]
 %endif
-    punpcklbw     m0, m7
-    punpcklbw     m1, m7
+    punpcklbw     m0, m4
+    punpcklbw     m1, m4
     pmullw        m0, m3
     pmullw        m1, m3
     paddsw        m0, m5
     paddsw        m1, m5
-    psraw         m0, m6
-    psraw         m1, m6
+    psraw         m0, m2
+    psraw         m1, m2
     packuswb      m0, m1
 %endmacro
 
 %macro WEIGHT_FUNC_MM 1
-cglobal h264_weight_%1, 6, 6, 8
+cglobal h264_weight_%1, 6, 6, 6
     WEIGHT_SETUP
 .nextrow:
     WEIGHT_OP 0, mmsize/2, %1
@@ -86,7 +86,7 @@ INIT_XMM sse2
 WEIGHT_FUNC_MM 16
 
 %macro WEIGHT_FUNC_HALF_MM 1
-cglobal h264_weight_%1, 6, 6, 8
+cglobal h264_weight_%1, 6, 6, 6
     WEIGHT_SETUP
     sar       r2d, 1
     lea        r3, [r1*2]
@@ -135,12 +135,12 @@ WEIGHT_FUNC_HALF_MM 8
     movd       m4, r5d
     movd       m0, r6d
 %else
-    movd       m3, r5d
+    movd       m6, r5d
     movd       m4, r6d
 %endif
     movd       m5, off_regd
-    movd       m6, r4d
-    pslld      m5, m6
+    movd       m3, r4d
+    pslld      m5, m3
     psrld      m5, 1
 %if cpuflag(ssse3)
     punpcklbw  m4, m0
@@ -150,22 +150,22 @@ WEIGHT_FUNC_HALF_MM 8
     punpcklqdq m5, m5
 
 %else
-    pshuflw    m3, m3, 0
+    pshuflw    m6, m6, 0
     pshuflw    m4, m4, 0
     pshuflw    m5, m5, 0
-    punpcklqdq m3, m3
+    punpcklqdq m6, m6
     punpcklqdq m4, m4
     punpcklqdq m5, m5
-    pxor       m7, m7
+    pxor       m2, m2
 %endif
 %endmacro
 
 %macro BIWEIGHT_STEPA 3
     movh       m%1, [r0+%3]
     movh       m%2, [r1+%3]
-    punpcklbw  m%1, m7
-    punpcklbw  m%2, m7
-    pmullw     m%1, m3
+    punpcklbw  m%1, m2
+    punpcklbw  m%2, m2
+    pmullw     m%1, m6
     pmullw     m%2, m4
     paddsw     m%1, m%2
 %endmacro
@@ -173,18 +173,18 @@ WEIGHT_FUNC_HALF_MM 8
 %macro BIWEIGHT_STEPB 0
     paddsw     m0, m5
     paddsw     m1, m5
-    psraw      m0, m6
-    psraw      m1, m6
+    psraw      m0, m3
+    psraw      m1, m3
     packuswb   m0, m1
 %endmacro
 
-%macro BIWEIGHT_FUNC_MM 2
-cglobal h264_biweight_%1, 7, 8, %2
+%macro BIWEIGHT_FUNC_MM 1
+cglobal h264_biweight_%1, 7, 8, 8
     BIWEIGHT_SETUP
     movifnidn r3d, r3m
 .nextrow:
     BIWEIGHT_STEPA 0, 1, 0
-    BIWEIGHT_STEPA 1, 2, mmsize/2
+    BIWEIGHT_STEPA 1, 7, mmsize/2
     BIWEIGHT_STEPB
     mova       [r0], m0
     add        r0, r2
@@ -195,7 +195,7 @@ cglobal h264_biweight_%1, 7, 8, %2
 %endmacro
 
 INIT_XMM sse2
-BIWEIGHT_FUNC_MM 16, 8
+BIWEIGHT_FUNC_MM 16
 
 %macro BIWEIGHT_FUNC_HALF_MM 2
 cglobal h264_biweight_%1, 7, 8, %2
@@ -210,14 +210,14 @@ cglobal h264_biweight_%1, 7, 8, %2
     punpcklbw  m0, m1
     pmaddubsw  m0, m4
 %else
-    punpcklbw  m0, m7
-    punpcklbw  m1, m7
-    pmullw     m0, m3
+    punpcklbw  m0, m2
+    punpcklbw  m1, m2
+    pmullw     m0, m6
     pmullw     m1, m4
     paddsw     m0, m1
 %endif
     paddsw     m0, m5
-    psraw      m0, m6
+    psraw      m0, m3
     packuswb   m0, m0
     movd       [r0], m0
     add        r0, r2
@@ -227,7 +227,7 @@ cglobal h264_biweight_%1, 7, 8, %2
     lea        r4, [r2*2]
 .nextrow:
     BIWEIGHT_STEPA 0, 1, 0
-    BIWEIGHT_STEPA 1, 2, r2
+    BIWEIGHT_STEPA 1, 7, r2
     BIWEIGHT_STEPB
     movh       [r0], m0
     movhps     [r0+r2], m0
@@ -240,9 +240,9 @@ cglobal h264_biweight_%1, 7, 8, %2
 %endmacro
 
 INIT_XMM sse2
-BIWEIGHT_FUNC_HALF_MM 4, 8
-INIT_XMM ssse3
 BIWEIGHT_FUNC_HALF_MM 4, 7
+INIT_XMM ssse3
+BIWEIGHT_FUNC_HALF_MM 4, 6
 INIT_XMM sse2
 BIWEIGHT_FUNC_HALF_MM 8, 8
 
@@ -251,22 +251,22 @@ BIWEIGHT_FUNC_HALF_MM 8, 8
     pmaddubsw  m2, m4
     paddsw     m0, m5
     paddsw     m2, m5
-    psraw      m0, m6
-    psraw      m2, m6
+    psraw      m0, m3
+    psraw      m2, m3
     packuswb   m0, m2
 %endmacro
 
 INIT_XMM ssse3
-cglobal h264_biweight_16, 7, 8, 8
+cglobal h264_biweight_16, 7, 8, 6
     BIWEIGHT_SETUP
     movifnidn r3d, r3m
 
 .nextrow:
     movh       m0, [r0]
     movh       m2, [r0+8]
-    movh       m3, [r1+8]
+    movh       m1, [r1+8]
     punpcklbw  m0, [r1]
-    punpcklbw  m2, m3
+    punpcklbw  m2, m1
     BIWEIGHT_SSSE3_OP
     mova       [r0], m0
     add        r0, r2
@@ -276,7 +276,7 @@ cglobal h264_biweight_16, 7, 8, 8
     RET
 
 INIT_XMM ssse3
-cglobal h264_biweight_8, 7, 8, 8
+cglobal h264_biweight_8, 7, 8, 6
     BIWEIGHT_SETUP
     movifnidn r3d, r3m
     sar       r3d, 1
@@ -285,10 +285,10 @@ cglobal h264_biweight_8, 7, 8, 8
 .nextrow:
     movh       m0, [r0]
     movh       m1, [r1]
-    movh       m2, [r0+r2]
-    movh       m3, [r1+r2]
     punpcklbw  m0, m1
-    punpcklbw  m2, m3
+    movh       m2, [r0+r2]
+    movh       m1, [r1+r2]
+    punpcklbw  m2, m1
     BIWEIGHT_SSSE3_OP
     movh       [r0], m0
     movhps     [r0+r2], m0
diff --git a/libavcodec/x86/h264_weight_10bit.asm 
b/libavcodec/x86/h264_weight_10bit.asm
index 7b7e367c9d..2044da7489 100644
--- a/libavcodec/x86/h264_weight_10bit.asm
+++ b/libavcodec/x86/h264_weight_10bit.asm
@@ -41,7 +41,11 @@ SECTION .text
 ;-----------------------------------------------------------------------------
 %macro WEIGHT_PROLOGUE 0
 .prologue:
-    PROLOGUE 0,6,8
+%if cpuflag(sse4)
+    PROLOGUE 0,6,6
+%else
+    PROLOGUE 0,6,7
+%endif
     movifnidn  r0, r0mp
     movifnidn r1d, r1m
     movifnidn r2d, r2m
@@ -63,31 +67,31 @@ SECTION .text
     mova       m4, [pw_pixel_max]
     paddw      m2, [sq_1]   ; log2_denom+1
 %if notcpuflag(sse4)
-    pxor       m7, m7
+    pxor       m6, m6
 %endif
 %endmacro
 
 %macro WEIGHT_OP 1-2
 %if %0==1
     mova        m5, [r0+%1]
-    punpckhwd   m6, m5, m0
+    punpckhwd   m1, m5, m0
     punpcklwd   m5, m0
 %else
     movq        m5, [r0+%1]
-    movq        m6, [r0+%2]
+    movq        m1, [r0+%2]
     punpcklwd   m5, m0
-    punpcklwd   m6, m0
+    punpcklwd   m1, m0
 %endif
     pmaddwd     m5, m3
-    pmaddwd     m6, m3
+    pmaddwd     m1, m3
     psrad       m5, m2
-    psrad       m6, m2
+    psrad       m1, m2
 %if cpuflag(sse4)
-    packusdw    m5, m6
+    packusdw    m5, m1
     pminuw      m5, m4
 %else
-    packssdw    m5, m6
-    CLIPW       m5, m7, m4
+    packssdw    m5, m1
+    CLIPW       m5, m6, m4
 %endif
 %endmacro
 
@@ -166,7 +170,11 @@ DECLARE_REG_TMP 7
 
 %macro BIWEIGHT_PROLOGUE 0
 .prologue:
+%if cpuflag(sse4)
+    PROLOGUE 0,8,7
+%else
     PROLOGUE 0,8,8
+%endif
     movifnidn  r0, r0mp
     movifnidn  r1, r1mp
     movifnidn r2d, r2m
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to