diff --git a/common/x86/sad-a.asm b/common/x86/sad-a.asm
index 49db789..08ff274 100644
--- a/common/x86/sad-a.asm
+++ b/common/x86/sad-a.asm
@@ -32,197 +32,159 @@ sw_64: dd 64
 SECTION .text
 
 ;=============================================================================
-; SAD MMX
+; SAD MMX/SSE2/SSE3 
 ;=============================================================================
 
-%macro SAD_INC_2x16P 0
-    movq    mm1,    [r0]
-    movq    mm2,    [r0+8]
-    movq    mm3,    [r0+r1]
-    movq    mm4,    [r0+r1+8]
-    psadbw  mm1,    [r2]
-    psadbw  mm2,    [r2+8]
-    psadbw  mm3,    [r2+r3]
-    psadbw  mm4,    [r2+r3+8]
-    lea     r0,     [r0+2*r1]
-    paddw   mm1,    mm2
-    paddw   mm3,    mm4
-    lea     r2,     [r2+2*r3]
-    paddw   mm0,    mm1
-    paddw   mm0,    mm3
+; %1 current iteration, %2 max iteration,
+; %3 ptr, %4 index                      
+%macro SAD_INC_PTR 4
+%if %1 <> %2 -1
+    lea     %3,    [%3+2*%4]
+%endif
 %endmacro
 
-%macro SAD_INC_2x8P 0
-    movq    mm1,    [r0]
-    movq    mm2,    [r0+r1]
-    psadbw  mm1,    [r2]
-    psadbw  mm2,    [r2+r3]
-    lea     r0,     [r0+2*r1]
-    paddw   mm0,    mm1
-    paddw   mm0,    mm2
-    lea     r2,     [r2+2*r3]
+;; %1 current iteration, %2 dst, %3 src
+%macro SAD_ADD2_SUM 3
+%if %1 = 0
+    %ifnidn %2, %3
+        mova    %2, %3
+    %endif
+%else
+    paddw   %2,     %3
+%endif
 %endmacro
 
-%macro SAD_INC_2x4P 0
-    movd    mm1,    [r0]
-    movd    mm2,    [r2]
-    punpckldq mm1,  [r0+r1]
-    punpckldq mm2,  [r2+r3]
-    psadbw  mm1,    mm2
-    paddw   mm0,    mm1
-    lea     r0,     [r0+2*r1]
-    lea     r2,     [r2+2*r3]
+;; %1 current iteration, %2 max iteration,
+;; %3 <> 0 do haddw, %4 src reg
+%macro SAD_READ_SUM 4
+%if %1 = %2 - 1 
+%if mmsize = 16 && %3 <> 0
+    movhlps m1,     %4
+    movd    edx,    m1
+    movd    eax,    %4
+    add     eax,    edx
+%else
+    movd    eax,    %4
+%endif
+%endif
 %endmacro
 
-;-----------------------------------------------------------------------------
-; int x264_pixel_sad_16x16_mmxext (uint8_t *, int, uint8_t *, int )
-;-----------------------------------------------------------------------------
-%macro SAD 2
-cglobal x264_pixel_sad_%1x%2_mmxext, 4,4
-    pxor    mm0, mm0
-%rep %2/2
-    SAD_INC_2x%1P
-%endrep
-    movd    eax, mm0
-    RET
+; %1 current iteration, %2 max iteration,
+; r0+r1 % 16 == 0
+; %3-%6 numbers of registers use 
+%macro SAD_INC_P2x16 6
+%if mmsize=16
+    movu    m%3,    [r2]
+    movu    m%4,    [r2+r3]
+    psadbw  m%3,    [r0]
+    psadbw  m%4,    [r0+r1]
+    SAD_INC_PTR %1, %2, r2, r3
+    SAD_INC_PTR %1, %2, r0, r1
+    paddw   m%3,    m%4
+    SAD_ADD2_SUM %1, m0, m%3
+%else
+    movu    m%3,    [r0]
+    movu    m%4,    [r0+8]
+    movu    m%5,    [r0+r1]
+    movu    m%6,    [r0+r1+8]
+    psadbw  m%3,    [r2]
+    psadbw  m%4,    [r2+8]
+    psadbw  m%5,    [r2+r3]
+    psadbw  m%6,    [r2+r3+8]
+    SAD_INC_PTR %1, %2, r0, r1
+    SAD_INC_PTR %1, %2, r2, r3
+    paddw   m%3,    m%4
+    paddw   m%5,    m%6
+    paddw   m%3,    m%5
+    SAD_ADD2_SUM %1, m0, m%3
+%endif
+    SAD_READ_SUM %1, %2, 1, m0
 %endmacro
 
-SAD 16, 16
-SAD 16,  8
-SAD  8, 16
-SAD  8,  8
-SAD  8,  4
-SAD  4,  8
-SAD  4,  4
-
-
-
-;=============================================================================
-; SAD XMM
-;=============================================================================
-
-%macro SAD_END_SSE2 0
-    movhlps xmm1, xmm0
-    paddw   xmm0, xmm1
-    movd    eax,  xmm0
-    RET
+;; %1 current iteration, %2 max iteration
+;; with mmsize=16 slower than with mmsize=8
+; %3-%6 numbers of registers use 
+%macro SAD_INC_P2x8 6
+%if mmsize <> 8
+    %error "SAD_INC_P2x8 works only for mmsize=8"
+%endif
+    movq    m%3,    [r0]
+    movq    m%4,    [r0+r1]
+    psadbw  m%3,    [r2]
+    psadbw  m%4,    [r2+r3]
+    SAD_INC_PTR %1, %2, r0, r1
+    SAD_INC_PTR %1, %2, r2, r3
+    paddw   m%3,    m%4
+    SAD_ADD2_SUM %1, m0, m%3
+    SAD_READ_SUM %1, %2, 0, m0
+%endmacro
+
+;; %1 current iteration, %2 max iteration
+;; works only with mmsize=8
+; %3-%6 numbers of registers use 
+%macro SAD_INC_P2x4 6
+%if mmsize <> 8
+    %error "SAD_INC_P2x4 works only for mmsize=8"
+%endif
+    movd    m%3,    [r0]
+    movd    m%4,    [r2]
+    punpckldq m%3,  [r0+r1]
+    SAD_INC_PTR %1, %2, r0, r1
+    punpckldq m%4,  [r2+r3]
+    SAD_INC_PTR %1, %2, r2, r3
+    psadbw  m%3,    m%4    
+    SAD_ADD2_SUM %1, m0, m%3
+    SAD_READ_SUM %1, %2, 0, m0
 %endmacro
 
-%macro SAD_W16 1
 ;-----------------------------------------------------------------------------
-; int x264_pixel_sad_16x16_sse2 (uint8_t *, int, uint8_t *, int )
+; int x264_pixel_sad_XXxYY_ZZ (uint8_t *, int, uint8_t *, int )
 ;-----------------------------------------------------------------------------
-cglobal x264_pixel_sad_16x16_%1, 4,4
-    movdqu  xmm0,   [r2]
-    movdqu  xmm1,   [r2+r3]
-    lea     r2,     [r2+2*r3]
-    movdqu  xmm2,   [r2]
-    movdqu  xmm3,   [r2+r3]
-    lea     r2,     [r2+2*r3]
-    psadbw  xmm0,   [r0]
-    psadbw  xmm1,   [r0+r1]
-    lea     r0,     [r0+2*r1]
-    movdqu  xmm4,   [r2]
-    paddw   xmm0,   xmm1
-    psadbw  xmm2,   [r0]
-    psadbw  xmm3,   [r0+r1]
-    lea     r0,     [r0+2*r1]
-    movdqu  xmm5,   [r2+r3]
-    lea     r2,     [r2+2*r3]
-    paddw   xmm2,   xmm3
-    movdqu  xmm6,   [r2]
-    movdqu  xmm7,   [r2+r3]
-    lea     r2,     [r2+2*r3]
-    paddw   xmm0,   xmm2
-    psadbw  xmm4,   [r0]
-    psadbw  xmm5,   [r0+r1]
-    lea     r0,     [r0+2*r1]
-    movdqu  xmm1,   [r2]
-    paddw   xmm4,   xmm5
-    psadbw  xmm6,   [r0]
-    psadbw  xmm7,   [r0+r1]
-    lea     r0,     [r0+2*r1]
-    movdqu  xmm2,   [r2+r3]
-    lea     r2,     [r2+2*r3]
-    paddw   xmm6,   xmm7
-    movdqu  xmm3,   [r2]
-    paddw   xmm0,   xmm4
-    movdqu  xmm4,   [r2+r3]
-    lea     r2,     [r2+2*r3]
-    paddw   xmm0,   xmm6
-    psadbw  xmm1,   [r0]
-    psadbw  xmm2,   [r0+r1]
-    lea     r0,     [r0+2*r1]
-    movdqu  xmm5,   [r2]
-    paddw   xmm1,   xmm2
-    psadbw  xmm3,   [r0]
-    psadbw  xmm4,   [r0+r1]
-    lea     r0,     [r0+2*r1]
-    movdqu  xmm6,   [r2+r3]
-    lea     r2,     [r2+2*r3]
-    paddw   xmm3,   xmm4
-    movdqu  xmm7,   [r2]
-    paddw   xmm0,   xmm1
-    movdqu  xmm1,   [r2+r3]
-    paddw   xmm0,   xmm3
-    psadbw  xmm5,   [r0]
-    psadbw  xmm6,   [r0+r1]
-    lea     r0,     [r0+2*r1]
-    paddw   xmm5,   xmm6
-    psadbw  xmm7,   [r0]
-    psadbw  xmm1,   [r0+r1]
-    paddw   xmm7,   xmm1
-    paddw   xmm0,   xmm5
-    paddw   xmm0,   xmm7
-    SAD_END_SSE2
+%macro SAD_SEL 3
+%assign %%i 0
+%assign %%n %2/2
+%assign %%t0 0
+%assign %%t1 1
+%assign %%t2 2
+%assign %%t3 3
+cglobal x264_pixel_sad_%1x%2_%3,4,4
+%rep %2/2
+    SAD_INC_P2x%1 %%i, %%n, %%t0, %%t1, %%t2, %%t3
+%if (%%i %% 3) = 0
+    %assign %%t0 1
+%else
+    %assign %%t0 %%t0+1
+%endif
+    %assign %%t1 %%t0+1
+    %assign %%t2 %%t0+2
+    %assign %%t3 %%t0+3
+    %assign %%i %%i+1
+%endrep    
+    RET
+%endmacro
 
-;-----------------------------------------------------------------------------
-; int x264_pixel_sad_16x8_sse2 (uint8_t *, int, uint8_t *, int )
-;-----------------------------------------------------------------------------
-cglobal x264_pixel_sad_16x8_%1, 4,4
-    movdqu  xmm0,   [r2]
-    movdqu  xmm2,   [r2+r3]
-    lea     r2,     [r2+2*r3]
-    movdqu  xmm3,   [r2]
-    movdqu  xmm4,   [r2+r3]
-    psadbw  xmm0,   [r0]
-    psadbw  xmm2,   [r0+r1]
-    lea     r0,     [r0+2*r1]
-    psadbw  xmm3,   [r0]
-    psadbw  xmm4,   [r0+r1]
-    lea     r0,     [r0+2*r1]
-    lea     r2,     [r2+2*r3]
-    paddw   xmm0,   xmm2
-    paddw   xmm3,   xmm4
-    paddw   xmm0,   xmm3
-    movdqu  xmm1,   [r2]
-    movdqu  xmm2,   [r2+r3]
-    lea     r2,     [r2+2*r3]
-    movdqu  xmm3,   [r2]
-    movdqu  xmm4,   [r2+r3]
-    psadbw  xmm1,   [r0]
-    psadbw  xmm2,   [r0+r1]
-    lea     r0,     [r0+2*r1]
-    psadbw  xmm3,   [r0]
-    psadbw  xmm4,   [r0+r1]
-    lea     r0,     [r0+2*r1]
-    lea     r2,     [r2+2*r3]
-    paddw   xmm1,   xmm2
-    paddw   xmm3,   xmm4
-    paddw   xmm0,   xmm1
-    paddw   xmm0,   xmm3
-    SAD_END_SSE2
+%macro SAD_GEN 1
+%if mmsize=8
+    SAD_SEL  4,  4, %1
+    SAD_SEL  4,  8, %1
+    SAD_SEL  8,  4, %1
+    SAD_SEL  8,  8, %1
+    SAD_SEL  8, 16, %1
+%endif    
+    SAD_SEL 16,  8, %1
+    SAD_SEL 16, 16, %1
 %endmacro
 
-SAD_W16 sse2
+INIT_MMX
+SAD_GEN mmxext
+INIT_XMM
+SAD_GEN sse2
 %define movdqu lddqu
-SAD_W16 sse3
+SAD_GEN sse3
 %define movdqu movdqa
-SAD_W16 sse2_aligned
+SAD_GEN sse2_aligned
 %define movdqu movups
 
-
-
 ;-----------------------------------------------------------------------------
 ; void intra_sad_x3_16x16 ( uint8_t *fenc, uint8_t *fdec, int res[3] );
 ;-----------------------------------------------------------------------------
