diff --git a/common/dct.c b/common/dct.c
index 5e6f798..40f389f 100644
--- a/common/dct.c
+++ b/common/dct.c
@@ -564,6 +564,12 @@ void x264_zigzag_init( int cpu, x264_zigzag_function_t *pf, int b_interlaced )
 #ifdef HAVE_MMX
         if( cpu&X264_CPU_MMXEXT )
             pf->scan_4x4 = x264_zigzag_scan_4x4_field_mmxext;
+	if( cpu&X264_CPU_SSE2 )
+	{
+	    pf->scan_4x4 = x264_zigzag_scan_4x4_field_sse2;
+	    pf->scan_8x8 = x264_zigzag_scan_8x8_field_sse2;
+            pf->sub_4x4 = x264_zigzag_sub_4x4_field_sse2;
+	}
 #endif
 
 #ifdef ARCH_PPC
@@ -577,6 +583,12 @@ void x264_zigzag_init( int cpu, x264_zigzag_function_t *pf, int b_interlaced )
         pf->scan_4x4   = zigzag_scan_4x4_frame;
         pf->sub_4x4    = zigzag_sub_4x4_frame;
 #ifdef HAVE_MMX
+	if( cpu&X264_CPU_SSE2 )
+	{
+	    pf->scan_8x8 = x264_zigzag_scan_8x8_frame_sse2;
+	    pf->scan_4x4 = x264_zigzag_scan_4x4_frame_sse2;
+            pf->sub_4x4 = x264_zigzag_sub_4x4_frame_sse2;
+	}
         if( cpu&X264_CPU_SSSE3 )
             pf->sub_4x4 = x264_zigzag_sub_4x4_frame_ssse3;
 #endif
diff --git a/common/x86/dct-a.asm b/common/x86/dct-a.asm
index 59fa6ff..04b833b 100644
--- a/common/x86/dct-a.asm
+++ b/common/x86/dct-a.asm
@@ -276,6 +276,286 @@ cglobal x264_zigzag_scan_4x4_field_mmxext, 2,3
     mov    [r0+12], r2d
     RET
 
+%define SHUFFLE(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6))
+%define YX(y,x) (((y)+(x)*8)*2)
+;-----------------------------------------------------------------------------
+; void x264_zigzag_scan_8x8_frame_sse2( int16_t level[64], int16_t dct[8][8] )
+;-----------------------------------------------------------------------------
+cglobal x264_zigzag_scan_8x8_frame_sse2, 2,2,0
+    ;
+    movdqa xmm0, [r1+0*16]
+    pshuflw xmm4, [r1+5*16], SHUFFLE(0,2,1,3)
+    movdqa xmm3, [r1+3*16]
+    pshufhw xmm2, [r1+2*16], SHUFFLE(2,0,1,3)
+    movdqa xmm6, [r1+6*16]
+    pshufhw xmm1, xmm0, SHUFFLE(1,2,0,3)
+    movdqa xmm7, [r1+7*16]
+    punpcklwd xmm0, [r1+1*16]
+    movdqa xmm5, xmm4
+
+    punpckhwd xmm1, [r1+1*16]
+    punpckhwd xmm7, xmm6
+    pshufhw xmm0, xmm0, SHUFFLE(1,2,0,3)
+    punpckhwd xmm3, xmm2
+    pshufhw xmm1, xmm1, SHUFFLE(0,3,1,2)
+    pinsrw xmm0, [r1+YX(2,0)], 3
+    pshufhw xmm7, xmm7, SHUFFLE(1,0,3,2)
+    punpcklwd xmm2, [r1+3*16]
+    pshufhw xmm3, xmm3, SHUFFLE(3,2,0,1)
+    punpcklwd xmm6, [r1+7*16]
+    pshuflw xmm7, xmm7, SHUFFLE(1,2,0,3)
+    pshuflw xmm1, xmm1, SHUFFLE(0,2,3,1)
+    punpcklwd xmm4, [r1+4*16]
+    pinsrw xmm7, [r1+YX(3,7)], 1
+    pinsrw xmm0, [r1+YX(4,0)], 6
+    punpckhwd xmm5, [r1+4*16]
+    pshuflw xmm2, xmm2, SHUFFLE(3,0,1,2)
+    pshuflw xmm6, xmm6, SHUFFLE(1,2,1,2)
+
+    movq [r0+0*2], xmm0
+    pinsrw xmm7, [r1+YX(5,7)], 4
+    movhps [r0+8*2], xmm0
+    pshuflw xmm4, xmm4, SHUFFLE(1,0,1,0)
+    pinsrw xmm1, [r1+YX(4,2)], 3
+    pshuflw xmm5, xmm5, SHUFFLE(1,0,3,2)
+    pinsrw xmm2, [r1+YX(1,1)], 0
+    pshufhw xmm6, xmm6, SHUFFLE(0,0,1,1)
+    movq [r0+52*2], xmm7
+    pinsrw xmm1, [r1+YX(5,2)], 5
+    movhps [r0+60*2], xmm7
+    pshufhw xmm5, xmm5, SHUFFLE(0,3,2,1)
+    pinsrw xmm2, [r1+YX(1,4)], 4
+    pshufhw xmm4, xmm4, SHUFFLE(2,1,0,3)
+
+    pinsrw xmm3, [r1+YX(7,1)], 0
+    pinsrw xmm1, [r1+YX(4,3)], 4
+    pinsrw xmm5, [r1+YX(3,6)], 0
+    pinsrw xmm2, [r1+YX(4,1)], 7
+    pinsrw xmm4, [r1+YX(2,2)], 0
+    pinsrw xmm6, [r1+YX(2,5)], 2
+    movq [r0+20*2], xmm1
+    pinsrw xmm5, [r1+YX(6,3)], 3
+    movhps [r0+32*2], xmm1
+    pinsrw xmm3, [r1+YX(4,4)], 3
+    pinsrw xmm4, [r1+YX(1,3)], 1
+    movq [r0+4*2], xmm2
+    pinsrw xmm6, [r1+YX(3,4)], 3
+    movhps [r0+16*2], xmm2
+    pinsrw xmm5, [r1+YX(6,6)], 7
+    pinsrw xmm3, [r1+YX(6,4)], 6
+    pinsrw xmm4, [r1+YX(3,3)], 4
+    pinsrw xmm6, [r1+YX(3,5)], 4
+    movq [r0+44*2], xmm5
+    pinsrw xmm3, [r1+YX(5,5)], 7
+    movhps [r0+56*2], xmm5
+    pinsrw xmm4, [r1+YX(0,6)], 7
+    pinsrw xmm6, [r1+YX(1,7)], 6
+    movq [r0+36*2], xmm3
+    movhps [r0+48*2], xmm3
+    movq [r0+12*2], xmm4
+    movhps [r0+24*2], xmm4
+    movq [r0+28*2], xmm6
+    movhps [r0+40*2], xmm6
+
+    RET
+%undef YX
+
+%define YX(y,x) (((y)+(x)*8)*2)
+;-----------------------------------------------------------------------------
+; void x264_zigzag_scan_8x8_field_sse2( int16_t level[64], int16_t dct[8][8] )
+;-----------------------------------------------------------------------------
+cglobal x264_zigzag_scan_8x8_field_sse2, 2,2,0
+    pshufd xmm7, [r1+7*16], SHUFFLE(2,3,0,1)
+    movdqa xmm6, [r1+6*16]
+    pshufhw xmm0, [r1+0*16], SHUFFLE(0,3,1,2)
+    pshuflw xmm1, [r1+1*16], SHUFFLE(1,0,3,2)
+    pshuflw xmm2, [r1+2*16], SHUFFLE(0,2,1,3)
+    pshuflw xmm3, [r1+3*16], SHUFFLE(0,1,3,2)
+    pshuflw xmm4, [r1+4*16], SHUFFLE(0,1,3,2)
+    pshufhw xmm5, [r1+5*16], SHUFFLE(1,2,3,0)
+
+    pinsrw xmm0, [r1+YX(0,1)], 3
+    movq [r0+60*2], xmm7
+    punpckhdq xmm7, xmm6
+    pinsrw xmm1, [r1+YX(2,2)], 4
+    pinsrw xmm2, [r1+YX(4,1)], 1
+    pinsrw xmm3, [r1+YX(3,2)], 0
+    pinsrw xmm4, [r1+YX(3,3)], 0
+    pshufhw xmm7, xmm7, SHUFFLE(2,3,0,1)
+    pshuflw xmm5, xmm5, SHUFFLE(0,1,3,2)
+    pinsrw xmm0, [r1+YX(0,2)], 4
+    pinsrw xmm1, [r1+YX(3,0)], 1
+    movhps [r0+56*2], xmm7
+    pinsrw xmm3, [r1+YX(0,4)], 2
+    movq [r0+52*2], xmm7
+    pinsrw xmm4, [r1+YX(0,5)], 2
+    movq [r0+20*2], xmm3
+    pinsrw xmm0, [r1+YX(3,1)], 5
+    movhps [r0+32*2], xmm3
+    pinsrw xmm2, [r1+YX(7,0)], 0
+    movq [r0+0*2], xmm0
+    pinsrw xmm1, [r1+YX(4,0)], 2
+    movhps [r0+8*2], xmm0
+    pinsrw xmm5, [r1+YX(3,4)], 0
+    movhps [r0+16*2], xmm1
+    pinsrw xmm2, [r1+YX(0,3)], 3
+    movq [r0+4*2], xmm1
+    pinsrw xmm6, [r1+YX(3,5)], 0
+    movq [r0+12*2], xmm2
+    pinsrw xmm5, [r1+YX(0,6)], 2
+    movhps [r0+24*2], xmm2
+    pinsrw xmm6, [r1+YX(4,5)], 3
+    movhps [r0+40*2], xmm4
+    pinsrw xmm5, [r1+YX(3,6)], 7
+    movq [r0+28*2], xmm4
+    movq [r0+44*2], xmm6
+    movq [r0+36*2], xmm5
+    movhps [r0+48*2], xmm5
+    RET
+%undef YX
+
+;-----------------------------------------------------------------------------
+; void x264_zigzag_scan_4x4_field_sse2 ( int16_t level[16], int16_t dct[4][4] )
+;-----------------------------------------------------------------------------
+cglobal x264_zigzag_scan_4x4_field_sse2, 2,3,0
+    ;; *(uint32_t*)level = *(uint32_t*)dct;
+    ;; ZIG(2,0,1) ZIG(3,2,0) ZIG(4,3,0) ZIG(5,1,1)
+    ;; *(uint32_t*)(level+6) = *(uint32_t*)(*dct+6);
+    ;; *(uint64_t*)(level+8) = *(uint64_t*)(*dct+8);
+    ;; *(uint64_t*)(level+12) = *(uint64_t*)(*dct+12);
+    pshuflw xmm0, [r1+0], SHUFFLE(0,1,3,2)
+    movdqa xmm1, [r1+16]
+    pinsrw xmm0, [r1+4*2], 2
+    pinsrw xmm0, [r1+3*2], 4
+    movdqa [r0+16], xmm1
+    movdqa [r0+0], xmm0
+    RET
+
+%define YX(y,x) (((y)+(x)*4)*2)
+;-----------------------------------------------------------------------------
+; void x264_zigzag_scan_4x4_frame_sse2 ( int16_t level[16], int16_t dct[4][4] )
+;-----------------------------------------------------------------------------
+cglobal x264_zigzag_scan_4x4_frame_sse2, 2,2,0
+    ;
+    movq xmm2, [r1+8]
+    pshufhw xmm3, [r1+16], SHUFFLE(1,2,0,3)
+    pshuflw xmm0, [r1], SHUFFLE(0,3,1,2)
+    pshuflw xmm2, xmm2, SHUFFLE(1,0,2,3)
+    pinsrw xmm3, [r1+YX(3,2)], 6
+    punpcklwd xmm2, xmm3 
+    movhps [r0+12*2], xmm3
+    pinsrw xmm0, [r1+YX(0,1)], 1
+    pshufhw xmm1, xmm2, SHUFFLE(0,3,2,1)
+    movq [r0+0*2], xmm0
+    pinsrw xmm2, [r1+YX(0,3)], 2
+    movq [r0+4*2], xmm2
+    pinsrw xmm1, [r1+YX(3,0)], 5
+    movhps [r0+8*2], xmm1
+    RET
+%undef YX
+
+;-----------------------------------------------------------------------------
+; void x264_zigzag_sub_4x4_field_sse2( int16_t level[16], const uint8_t *src, uint8_t *dst )
+;-----------------------------------------------------------------------------
+cglobal x264_zigzag_sub_4x4_field_sse2, 3, 3, 0
+    ; 0, 2, 8,12  xmm0, xmm4
+    ; 1, 5, 9,13  xmm1, xmm5
+    ; 3, 6,10,14  xmm2, xmm6
+    ; 4, 7,11,15  xmm3, xmm7
+    ; xmm0: 0, 1, 2, 5, 8, 9,12,13
+    ; xmm2: 3, 4, 6, 7,10,11,14,15
+    movd xmm4, [r2+0*FDEC_STRIDE]
+    movd xmm5, [r2+1*FDEC_STRIDE]
+    movd xmm0, [r1+0*FENC_STRIDE]
+    movd xmm1, [r1+1*FENC_STRIDE]
+    movd xmm6, [r2+2*FDEC_STRIDE]
+    punpcklbw xmm4, xmm5
+    movd xmm2, [r1+2*FENC_STRIDE]
+    pxor xmm5, xmm5
+    movd xmm7, [r2+3*FDEC_STRIDE]
+    movd [r2+0*FDEC_STRIDE], xmm0
+    punpcklbw xmm0, xmm1
+    movd xmm3, [r1+3*FENC_STRIDE]
+    punpcklbw xmm4, xmm5
+    punpcklbw xmm0, xmm5
+    punpcklbw xmm6, xmm7
+    movd [r2+2*FDEC_STRIDE], xmm2
+    punpcklbw xmm2, xmm3
+    punpcklbw xmm6, xmm5
+    punpcklbw xmm2, xmm5
+    movd [r2+1*FDEC_STRIDE], xmm1
+    psubw xmm0, xmm4
+    psubw xmm2, xmm6
+    movdqa xmm7, xmm0
+    ; xmm0: 0, 1, 2, 5, 3, 4, 6, 7
+    punpcklqdq xmm0, xmm2
+    movd [r2+3*FDEC_STRIDE], xmm3
+    ; xmm0: ( 3, 4),( 2, 5),( 0, 1),( 6, 7)
+    pshufd xmm0, xmm0, SHUFFLE(2,1,0,3)
+    ; xmm7: 8, 9,10,11,12,13,14,15
+    punpckhdq xmm7, xmm2
+    ; xmm0: ( 2, 3),( 4, 5),( 0, 1),( 6, 7)
+    pshuflw xmm0, xmm0, SHUFFLE(2,0,1,3)
+    movdqa [r0+16], xmm7
+    ; xmm0: ( 0, 1),( 2, 3),( 4, 5),( 6, 7)
+    pshufd xmm0, xmm0, SHUFFLE(2,0,1,3)
+    movdqa [r0+0], xmm0
+    RET
+
+;-----------------------------------------------------------------------------
+; void x264_zigzag_sub_4x4_frame_sse2( int16_t level[16], const uint8_t *src, uint8_t *dst )
+;-----------------------------------------------------------------------------
+cglobal x264_zigzag_sub_4x4_frame_sse2, 3, 3, 0
+    ; 0, 1, 5, 6  xmm0, xmm4
+    ; 2, 4, 7,12  xmm1, xmm5
+    ; 3, 8,11,13  xmm2, xmm6
+    ; 9,10,14,15  xmm3, xmm7
+    ; xmm0: 0, 1, 5, 6, 9,10,14,15
+    ; xmm1: 2, 3, 4, 8, 7,11,12,13
+    movd xmm6, [r2+2*FDEC_STRIDE]
+    movd xmm5, [r2+1*FDEC_STRIDE]
+    movd xmm1, [r1+1*FENC_STRIDE]
+    movd xmm2, [r1+2*FENC_STRIDE]
+    movd xmm4, [r2+0*FDEC_STRIDE]
+    punpcklbw xmm5, xmm6
+    pxor xmm6, xmm6
+    movd [r2+1*FDEC_STRIDE], xmm1
+    punpcklbw xmm1, xmm2
+    movd xmm7, [r2+3*FDEC_STRIDE]
+    punpcklbw xmm5, xmm6
+    movd xmm0, [r1+0*FENC_STRIDE]
+    punpcklbw xmm1, xmm6
+    movd xmm3, [r1+3*FENC_STRIDE]
+    psubw xmm1, xmm5
+    punpckldq xmm4, xmm7
+    movd [r2+0*FDEC_STRIDE], xmm0
+    ; xmm1:  (4, 8), (7,11), (2, 3),(12,13)
+    pshufd xmm1, xmm1, SHUFFLE(1,2,0,3)
+    punpckldq xmm0, xmm3
+    punpcklbw xmm4, xmm6
+    punpcklbw xmm0, xmm6
+    ; xmm1:  (4, 7), (8,11), (2, 3),(12,13)
+    pshuflw xmm1, xmm1, SHUFFLE(0,2,1,3)
+    psubw xmm0, xmm4
+    ; xmm1:  (2, 3), (4, 7), (8,11),(12,13)
+    pshufd xmm1, xmm1, SHUFFLE(2,0,1,3)
+    movdqa xmm7, xmm0
+    movd [r2+3*FDEC_STRIDE], xmm3
+    ; xmm0: 0, 1, 2, 3, 5, 6, 4, 7
+    punpckldq xmm0, xmm1
+    ; xmm1: 8, 11, 9,10,12,13 14,15
+    movd [r2+2*FDEC_STRIDE], xmm2
+    punpckhdq xmm1, xmm7
+    movq [r0+0*8], xmm0
+    ; xmm2: 0, 1, 2, 3, 4, 5, 6, 7
+    pshufhw xmm2, xmm0, SHUFFLE(2,0,1,3)
+    movhps [r0+3*8], xmm1
+    ; xmm3: 8, 9,10,11,12,13 14,15
+    pshuflw xmm4, xmm1, SHUFFLE(0,2,3,1)
+    movhps [r0+1*8], xmm2
+    movq [r0+2*8], xmm4
+    RET
+
 ;-----------------------------------------------------------------------------
 ; void x264_zigzag_sub_4x4_frame_ssse3( int16_t level[16], const uint8_t *src, uint8_t *dst )
 ;-----------------------------------------------------------------------------
diff --git a/common/x86/dct.h b/common/x86/dct.h
index b7370d6..69743bd 100644
--- a/common/x86/dct.h
+++ b/common/x86/dct.h
@@ -50,6 +50,12 @@ void x264_add8x8_idct8_sse2( uint8_t *dst, int16_t dct[8][8] );
 void x264_add16x16_idct8_sse2( uint8_t *dst, int16_t dct[4][8][8] );
 
 void x264_zigzag_scan_4x4_field_mmxext( int16_t level[16], int16_t dct[4][4] );
+void x264_zigzag_scan_4x4_field_sse2( int16_t level[16], int16_t dct[4][4] );
+void x264_zigzag_scan_8x8_field_sse2( int16_t level[64], int16_t dct[8][8] );
+void x264_zigzag_sub_4x4_field_sse2( int16_t level[16], const uint8_t *src, uint8_t *dst );
+void x264_zigzag_scan_4x4_frame_sse2( int16_t level[16], int16_t dct[4][4] );
+void x264_zigzag_scan_8x8_frame_sse2( int16_t level[64], int16_t dct[8][8] );
+void x264_zigzag_sub_4x4_frame_sse2( int16_t level[16], const uint8_t *src, uint8_t *dst );
 void x264_zigzag_sub_4x4_frame_ssse3( int16_t level[16], const uint8_t *src, uint8_t *dst );
 
 #endif
