Merge "vp9/10: fix forced keyframes w/alt-refs enabled"
diff --git a/CHANGELOG b/CHANGELOG
index 7746cc6..7db420e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,7 @@
+Next Release
+  - Incompatible changes:
+    The VP9 encoder's default keyframe interval changed to 128 from 9999.
+
 2015-11-09 v1.5.0 "Javan Whistling Duck"
   This release improves upon the VP9 encoder and speeds up the encoding and
   decoding processes.
diff --git a/test/datarate_test.cc b/test/datarate_test.cc
index 9d5074e..e94df20 100644
--- a/test/datarate_test.cc
+++ b/test/datarate_test.cc
@@ -905,6 +905,9 @@
   svc_params_.scaling_factor_num[1] = 288;
   svc_params_.scaling_factor_den[1] = 288;
   cfg_.rc_dropframe_thresh = 10;
+  // TODO(marpan): another test should be added for default/small kf_max_dist
+  // once https://bugs.chromium.org/p/webm/issues/detail?id=1150 is fixed.
+  cfg_.kf_max_dist = 9999;
   ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
                                        30, 1, 0, 200);
   // TODO(wonkap/marpan): Check that effective_datarate for each layer hits the
diff --git a/test/lpf_8_test.cc b/test/lpf_8_test.cc
index b16f14c..778a36c 100644
--- a/test/lpf_8_test.cc
+++ b/test/lpf_8_test.cc
@@ -430,7 +430,7 @@
 
 using std::tr1::make_tuple;
 
-#if HAVE_MMX && !CONFIG_VP9_HIGHBITDEPTH
+#if HAVE_MMX && CONFIG_USE_X86INC && !CONFIG_VP9_HIGHBITDEPTH
 INSTANTIATE_TEST_CASE_P(
     MMX, Loop8Test6Param,
     ::testing::Values(
diff --git a/third_party/x86inc/README.libvpx b/third_party/x86inc/README.libvpx
index e91e305..8d3cd96 100644
--- a/third_party/x86inc/README.libvpx
+++ b/third_party/x86inc/README.libvpx
@@ -1,5 +1,5 @@
-URL: http://git.videolan.org/?p=x264.git
-Version: a95584945dd9ce3acc66c6cd8f6796bc4404d40d
+URL: https://git.videolan.org/git/x264.git
+Version: d23d18655249944c1ca894b451e2c82c7a584c62
 License: ISC
 License File: LICENSE
 
@@ -13,12 +13,8 @@
 Manage name mangling (prefixing with '_') manually because 'PREFIX' does not
   exist in libvpx.
 Expand PIC default to macho64 and respect CONFIG_PIC from libvpx
-Catch all elf formats for 'hidden' status and SECTION notes.
-Avoid 'amdnop' when building with nasm.
 Set 'private_extern' visibility for macho targets.
 Copy PIC 'GLOBAL' macros from x86_abi_support.asm
 Use .text instead of .rodata on macho to avoid broken tables in PIC mode.
 Use .text with no alignment for aout
 Only use 'hidden' visibility with Chromium
-Move '%use smartalign' for nasm out of 'INIT_CPUFLAGS' and before
-  'ALIGNMODE'.
diff --git a/third_party/x86inc/x86inc.asm b/third_party/x86inc/x86inc.asm
index e7d3fa5..fc65bd3 100644
--- a/third_party/x86inc/x86inc.asm
+++ b/third_party/x86inc/x86inc.asm
@@ -1,7 +1,7 @@
 ;*****************************************************************************
 ;* x86inc.asm: x264asm abstraction layer
 ;*****************************************************************************
-;* Copyright (C) 2005-2015 x264 project
+;* Copyright (C) 2005-2016 x264 project
 ;*
 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
 ;*          Anton Mitrofanov <BugMaster@narod.ru>
@@ -66,16 +66,35 @@
     %endif
 %endif
 
-%ifidn   __OUTPUT_FORMAT__,elf32
-    %define mangle(x) x
+%define FORMAT_ELF 0
+%ifidn __OUTPUT_FORMAT__,elf
+    %define FORMAT_ELF 1
+%elifidn __OUTPUT_FORMAT__,elf32
+    %define FORMAT_ELF 1
 %elifidn __OUTPUT_FORMAT__,elf64
-    %define mangle(x) x
-%elifidn __OUTPUT_FORMAT__,x64
-    %define mangle(x) x
-%elifidn __OUTPUT_FORMAT__,win64
-    %define mangle(x) x
+    %define FORMAT_ELF 1
+%endif
+
+%define FORMAT_MACHO 0
+%ifidn __OUTPUT_FORMAT__,macho32
+     %define FORMAT_MACHO 1
+%elifidn __OUTPUT_FORMAT__,macho64
+     %define FORMAT_MACHO 1
+%endif
+
+; Set PREFIX for libvpx builds.
+%if FORMAT_ELF
+    %undef PREFIX
+%elif WIN64
+    %undef PREFIX
 %else
+    %define PREFIX
+%endif
+
+%ifdef PREFIX
     %define mangle(x) _ %+ x
+%else
+    %define mangle(x) x
 %endif
 
 ; In some instances macho32 tables get misaligned when using .rodata.
@@ -94,14 +113,6 @@
     %endif
 %endmacro
 
-%macro SECTION_TEXT 0-1 16
-    %ifidn __OUTPUT_FORMAT__,aout
-        SECTION .text
-    %else
-        SECTION .text align=%1
-    %endif
-%endmacro
-
 ; PIC macros are copied from vpx_ports/x86_abi_support.asm. The "define PIC"
 ; from original code is added in for 64bit.
 %ifidn __OUTPUT_FORMAT__,elf32
@@ -190,6 +201,10 @@
 %endif
 ; Done with PIC macros
 
+%ifdef __NASM_VER__
+    %use smartalign
+%endif
+
 ; Macros to eliminate most code duplication between x86_32 and x86_64:
 ; Currently this works only for leaf functions which load all their arguments
 ; into registers at the start, and make no other use of the stack. Luckily that
@@ -237,6 +252,7 @@
     %define r%1w %2w
     %define r%1b %2b
     %define r%1h %2h
+    %define %2q %2
     %if %0 == 2
         %define r%1m  %2d
         %define r%1mp %2
@@ -261,9 +277,9 @@
     %define e%1h %3
     %define r%1b %2
     %define e%1b %2
-%if ARCH_X86_64 == 0
-    %define r%1  e%1
-%endif
+    %if ARCH_X86_64 == 0
+        %define r%1 e%1
+    %endif
 %endmacro
 
 DECLARE_REG_SIZE ax, al, ah
@@ -373,7 +389,7 @@
 
 %macro ASSERT 1
     %if (%1) == 0
-        %error assert failed
+        %error assertion ``%1'' failed
     %endif
 %endmacro
 
@@ -464,8 +480,10 @@
         %if %1 != 0 && required_stack_alignment > STACK_ALIGNMENT
             %if %1 > 0
                 %assign regs_used (regs_used + 1)
-            %elif ARCH_X86_64 && regs_used == num_args && num_args <= 4 + UNIX64 * 2
-                %warning "Stack pointer will overwrite register argument"
+            %endif
+            %if ARCH_X86_64 && regs_used < 5 + UNIX64 * 3
+                ; Ensure that we don't clobber any registers containing arguments
+                %assign regs_used 5 + UNIX64 * 3
             %endif
         %endif
     %endif
@@ -579,9 +597,9 @@
 %macro RET 0
     WIN64_RESTORE_XMM_INTERNAL rsp
     POP_IF_USED 14, 13, 12, 11, 10, 9, 8, 7
-%if mmsize == 32
-    vzeroupper
-%endif
+    %if mmsize == 32
+        vzeroupper
+    %endif
     AUTO_REP_RET
 %endmacro
 
@@ -618,17 +636,17 @@
 %define has_epilogue regs_used > 9 || mmsize == 32 || stack_size > 0
 
 %macro RET 0
-%if stack_size_padded > 0
-%if required_stack_alignment > STACK_ALIGNMENT
-    mov rsp, rstkm
-%else
-    add rsp, stack_size_padded
-%endif
-%endif
+    %if stack_size_padded > 0
+        %if required_stack_alignment > STACK_ALIGNMENT
+            mov rsp, rstkm
+        %else
+            add rsp, stack_size_padded
+        %endif
+    %endif
     POP_IF_USED 14, 13, 12, 11, 10, 9
-%if mmsize == 32
-    vzeroupper
-%endif
+    %if mmsize == 32
+        vzeroupper
+    %endif
     AUTO_REP_RET
 %endmacro
 
@@ -674,29 +692,29 @@
 %define has_epilogue regs_used > 3 || mmsize == 32 || stack_size > 0
 
 %macro RET 0
-%if stack_size_padded > 0
-%if required_stack_alignment > STACK_ALIGNMENT
-    mov rsp, rstkm
-%else
-    add rsp, stack_size_padded
-%endif
-%endif
+    %if stack_size_padded > 0
+        %if required_stack_alignment > STACK_ALIGNMENT
+            mov rsp, rstkm
+        %else
+            add rsp, stack_size_padded
+        %endif
+    %endif
     POP_IF_USED 6, 5, 4, 3
-%if mmsize == 32
-    vzeroupper
-%endif
+    %if mmsize == 32
+        vzeroupper
+    %endif
     AUTO_REP_RET
 %endmacro
 
 %endif ;======================================================================
 
 %if WIN64 == 0
-%macro WIN64_SPILL_XMM 1
-%endmacro
-%macro WIN64_RESTORE_XMM 1
-%endmacro
-%macro WIN64_PUSH_XMM 0
-%endmacro
+    %macro WIN64_SPILL_XMM 1
+    %endmacro
+    %macro WIN64_RESTORE_XMM 1
+    %endmacro
+    %macro WIN64_PUSH_XMM 0
+    %endmacro
 %endif
 
 ; On AMD cpus <=K10, an ordinary ret is slow if it immediately follows either
@@ -709,24 +727,26 @@
     %else
         rep ret
     %endif
+    annotate_function_size
 %endmacro
 
 %define last_branch_adr $$
 %macro AUTO_REP_RET 0
-    %ifndef cpuflags
-        times ((last_branch_adr-$)>>31)+1 rep ; times 1 iff $ != last_branch_adr.
-    %elif notcpuflag(ssse3)
-        times ((last_branch_adr-$)>>31)+1 rep
+    %if notcpuflag(ssse3)
+        times ((last_branch_adr-$)>>31)+1 rep ; times 1 iff $ == last_branch_adr.
     %endif
     ret
+    annotate_function_size
 %endmacro
 
 %macro BRANCH_INSTR 0-*
     %rep %0
         %macro %1 1-2 %1
             %2 %1
-            %%branch_instr:
-            %xdefine last_branch_adr %%branch_instr
+            %if notcpuflag(ssse3)
+                %%branch_instr equ $
+                %xdefine last_branch_adr %%branch_instr
+            %endif
         %endmacro
         %rotate 1
     %endrep
@@ -741,6 +761,7 @@
     %elif %2
         jmp %1
     %endif
+    annotate_function_size
 %endmacro
 
 ;=============================================================================
@@ -762,6 +783,7 @@
     cglobal_internal 0, %1 %+ SUFFIX, %2
 %endmacro
 %macro cglobal_internal 2-3+
+    annotate_function_size
     %if %1
         %xdefine %%FUNCTION_PREFIX private_prefix
         ; libvpx explicitly sets visibility in shared object builds. Avoid
@@ -782,17 +804,10 @@
         CAT_XDEFINE cglobaled_, %2, 1
     %endif
     %xdefine current_function %2
-    %ifidn __OUTPUT_FORMAT__,elf32
+    %xdefine current_function_section __SECT__
+    %if FORMAT_ELF
         global %2:function %%VISIBILITY
-    %elifidn __OUTPUT_FORMAT__,elf64
-        global %2:function %%VISIBILITY
-    %elifidn __OUTPUT_FORMAT__,macho32
-        %ifdef __NASM_VER__
-            global %2
-        %else
-            global %2:private_extern
-        %endif
-    %elifidn __OUTPUT_FORMAT__,macho64
+    %elif FORMAT_MACHO
         %ifdef __NASM_VER__
             global %2
         %else
@@ -822,16 +837,16 @@
 
 ; like cextern, but without the prefix
 %macro cextern_naked 1
-    %xdefine %1 mangle(%1)
+    %ifdef PREFIX
+        %xdefine %1 mangle(%1)
+    %endif
     CAT_XDEFINE cglobaled_, %1, 1
     extern %1
 %endmacro
 
 %macro const 1-2+
     %xdefine %1 mangle(private_prefix %+ _ %+ %1)
-    %ifidn __OUTPUT_FORMAT__,elf32
-        global %1:data hidden
-    %elifidn __OUTPUT_FORMAT__,elf64
+    %if FORMAT_ELF
         global %1:data hidden
     %else
         global %1
@@ -839,14 +854,29 @@
     %1: %2
 %endmacro
 
-; This is needed for ELF, otherwise the GNU linker assumes the stack is
-; executable by default.
-%ifidn __OUTPUT_FORMAT__,elf32
-SECTION .note.GNU-stack noalloc noexec nowrite progbits
-%elifidn __OUTPUT_FORMAT__,elf64
-SECTION .note.GNU-stack noalloc noexec nowrite progbits
+; This is needed for ELF, otherwise the GNU linker assumes the stack is executable by default.
+%if FORMAT_ELF
+    [SECTION .note.GNU-stack noalloc noexec nowrite progbits]
 %endif
 
+; Tell debuggers how large the function was.
+; This may be invoked multiple times per function; we rely on later instances overriding earlier ones.
+; This is invoked by RET and similar macros, and also cglobal does it for the previous function,
+; but if the last function in a source file doesn't use any of the standard macros for its epilogue,
+; then its size might be unspecified.
+%macro annotate_function_size 0
+    %ifdef __YASM_VER__
+        %ifdef current_function
+            %if FORMAT_ELF
+                current_function_section
+                %%ecf equ $
+                size current_function %%ecf - current_function
+                __SECT__
+            %endif
+        %endif
+    %endif
+%endmacro
+
 ; cpuflags
 
 %assign cpuflags_mmx      (1<<0)
@@ -875,12 +905,9 @@
 %assign cpuflags_bmi1     (1<<22)|cpuflags_lzcnt
 %assign cpuflags_bmi2     (1<<23)|cpuflags_bmi1
 
-%define    cpuflag(x) ((cpuflags & (cpuflags_ %+ x)) == (cpuflags_ %+ x))
-%define notcpuflag(x) ((cpuflags & (cpuflags_ %+ x)) != (cpuflags_ %+ x))
-
-%ifdef __NASM_VER__
-    %use smartalign
-%endif
+; Returns a boolean value expressing whether or not the specified cpuflag is enabled.
+%define    cpuflag(x) (((((cpuflags & (cpuflags_ %+ x)) ^ (cpuflags_ %+ x)) - 1) >> 31) & 1)
+%define notcpuflag(x) (cpuflag(x) ^ 1)
 
 ; Takes an arbitrary number of cpuflags from the above list.
 ; All subsequent functions (up to the next INIT_CPUFLAGS) is built for the specified cpu.
@@ -917,12 +944,18 @@
         %endif
     %endif
 
-    %ifdef __NASM_VER__
-        ALIGNMODE k7
-    %elif ARCH_X86_64 || cpuflag(sse2)
-        CPU amdnop
+    %if ARCH_X86_64 || cpuflag(sse2)
+        %ifdef __NASM_VER__
+            ALIGNMODE k8
+        %else
+            CPU amdnop
+        %endif
     %else
-        CPU basicnop
+        %ifdef __NASM_VER__
+            ALIGNMODE nop
+        %else
+            CPU basicnop
+        %endif
     %endif
 %endmacro
 
@@ -951,14 +984,14 @@
     %define movnta movntq
     %assign %%i 0
     %rep 8
-    CAT_XDEFINE m, %%i, mm %+ %%i
-    CAT_XDEFINE nnmm, %%i, %%i
-    %assign %%i %%i+1
+        CAT_XDEFINE m, %%i, mm %+ %%i
+        CAT_XDEFINE nnmm, %%i, %%i
+        %assign %%i %%i+1
     %endrep
     %rep 8
-    CAT_UNDEF m, %%i
-    CAT_UNDEF nnmm, %%i
-    %assign %%i %%i+1
+        CAT_UNDEF m, %%i
+        CAT_UNDEF nnmm, %%i
+        %assign %%i %%i+1
     %endrep
     INIT_CPUFLAGS %1
 %endmacro
@@ -969,7 +1002,7 @@
     %define mmsize 16
     %define num_mmregs 8
     %if ARCH_X86_64
-    %define num_mmregs 16
+        %define num_mmregs 16
     %endif
     %define mova movdqa
     %define movu movdqu
@@ -977,9 +1010,9 @@
     %define movnta movntdq
     %assign %%i 0
     %rep num_mmregs
-    CAT_XDEFINE m, %%i, xmm %+ %%i
-    CAT_XDEFINE nnxmm, %%i, %%i
-    %assign %%i %%i+1
+        CAT_XDEFINE m, %%i, xmm %+ %%i
+        CAT_XDEFINE nnxmm, %%i, %%i
+        %assign %%i %%i+1
     %endrep
     INIT_CPUFLAGS %1
 %endmacro
@@ -990,7 +1023,7 @@
     %define mmsize 32
     %define num_mmregs 8
     %if ARCH_X86_64
-    %define num_mmregs 16
+        %define num_mmregs 16
     %endif
     %define mova movdqa
     %define movu movdqu
@@ -998,9 +1031,9 @@
     %define movnta movntdq
     %assign %%i 0
     %rep num_mmregs
-    CAT_XDEFINE m, %%i, ymm %+ %%i
-    CAT_XDEFINE nnymm, %%i, %%i
-    %assign %%i %%i+1
+        CAT_XDEFINE m, %%i, ymm %+ %%i
+        CAT_XDEFINE nnymm, %%i, %%i
+        %assign %%i %%i+1
     %endrep
     INIT_CPUFLAGS %1
 %endmacro
@@ -1024,7 +1057,7 @@
 %assign i 0
 %rep 16
     DECLARE_MMCAST i
-%assign i i+1
+    %assign i i+1
 %endrep
 
 ; I often want to use macros that permute their arguments. e.g. there's no
@@ -1042,23 +1075,23 @@
 ; doesn't cost any cycles.
 
 %macro PERMUTE 2-* ; takes a list of pairs to swap
-%rep %0/2
-    %xdefine %%tmp%2 m%2
-    %rotate 2
-%endrep
-%rep %0/2
-    %xdefine m%1 %%tmp%2
-    CAT_XDEFINE nn, m%1, %1
-    %rotate 2
-%endrep
+    %rep %0/2
+        %xdefine %%tmp%2 m%2
+        %rotate 2
+    %endrep
+    %rep %0/2
+        %xdefine m%1 %%tmp%2
+        CAT_XDEFINE nn, m%1, %1
+        %rotate 2
+    %endrep
 %endmacro
 
 %macro SWAP 2+ ; swaps a single chain (sometimes more concise than pairs)
-%ifnum %1 ; SWAP 0, 1, ...
-    SWAP_INTERNAL_NUM %1, %2
-%else ; SWAP m0, m1, ...
-    SWAP_INTERNAL_NAME %1, %2
-%endif
+    %ifnum %1 ; SWAP 0, 1, ...
+        SWAP_INTERNAL_NUM %1, %2
+    %else ; SWAP m0, m1, ...
+        SWAP_INTERNAL_NAME %1, %2
+    %endif
 %endmacro
 
 %macro SWAP_INTERNAL_NUM 2-*
@@ -1068,7 +1101,7 @@
         %xdefine m%2 %%tmp
         CAT_XDEFINE nn, m%1, %1
         CAT_XDEFINE nn, m%2, %2
-    %rotate 1
+        %rotate 1
     %endrep
 %endmacro
 
@@ -1076,7 +1109,7 @@
     %xdefine %%args nn %+ %1
     %rep %0-1
         %xdefine %%args %%args, nn %+ %2
-    %rotate 1
+        %rotate 1
     %endrep
     SWAP_INTERNAL_NUM %%args
 %endmacro
@@ -1093,7 +1126,7 @@
     %assign %%i 0
     %rep num_mmregs
         CAT_XDEFINE %%f, %%i, m %+ %%i
-    %assign %%i %%i+1
+        %assign %%i %%i+1
     %endrep
 %endmacro
 
@@ -1103,20 +1136,20 @@
         %rep num_mmregs
             CAT_XDEFINE m, %%i, %1_m %+ %%i
             CAT_XDEFINE nn, m %+ %%i, %%i
-        %assign %%i %%i+1
+            %assign %%i %%i+1
         %endrep
     %endif
 %endmacro
 
 ; Append cpuflags to the callee's name iff the appended name is known and the plain name isn't
 %macro call 1
-    call_internal %1, %1 %+ SUFFIX
+    call_internal %1 %+ SUFFIX, %1
 %endmacro
 %macro call_internal 2
-    %xdefine %%i %1
-    %ifndef cglobaled_%1
-        %ifdef cglobaled_%2
-            %xdefine %%i %2
+    %xdefine %%i %2
+    %ifndef cglobaled_%2
+        %ifdef cglobaled_%1
+            %xdefine %%i %1
         %endif
     %endif
     call %%i
@@ -1159,7 +1192,7 @@
     %endif
     CAT_XDEFINE sizeofxmm, i, 16
     CAT_XDEFINE sizeofymm, i, 32
-%assign i i+1
+    %assign i i+1
 %endrep
 %undef i
 
@@ -1536,7 +1569,7 @@
     %else
         CAT_XDEFINE q, j, i
     %endif
-%assign i i+1
+    %assign i i+1
 %endrep
 %undef i
 %undef j
@@ -1559,55 +1592,54 @@
 FMA_INSTR pmacsdql,  pmuldq, paddq ; sse4 emulation
 FMA_INSTR pmadcswd, pmaddwd, paddd
 
-; convert FMA4 to FMA3 if possible
-%macro FMA4_INSTR 4
-    %macro %1 4-8 %1, %2, %3, %4
-        %if cpuflag(fma4)
-            v%5 %1, %2, %3, %4
-        %elifidn %1, %2
-            v%6 %1, %4, %3 ; %1 = %1 * %3 + %4
-        %elifidn %1, %3
-            v%7 %1, %2, %4 ; %1 = %2 * %1 + %4
-        %elifidn %1, %4
-            v%8 %1, %2, %3 ; %1 = %2 * %3 + %1
-        %else
-            %error fma3 emulation of ``%5 %1, %2, %3, %4'' is not supported
-        %endif
-    %endmacro
+; Macros for consolidating FMA3 and FMA4 using 4-operand (dst, src1, src2, src3) syntax.
+; FMA3 is only possible if dst is the same as one of the src registers.
+; Either src2 or src3 can be a memory operand.
+%macro FMA4_INSTR 2-*
+    %push fma4_instr
+    %xdefine %$prefix %1
+    %rep %0 - 1
+        %macro %$prefix%2 4-6 %$prefix, %2
+            %if notcpuflag(fma3) && notcpuflag(fma4)
+                %error use of ``%5%6'' fma instruction in cpuname function: current_function
+            %elif cpuflag(fma4)
+                v%5%6 %1, %2, %3, %4
+            %elifidn %1, %2
+                ; If %3 or %4 is a memory operand it needs to be encoded as the last operand.
+                %ifid %3
+                    v%{5}213%6 %2, %3, %4
+                %else
+                    v%{5}132%6 %2, %4, %3
+                %endif
+            %elifidn %1, %3
+                v%{5}213%6 %3, %2, %4
+            %elifidn %1, %4
+                v%{5}231%6 %4, %2, %3
+            %else
+                %error fma3 emulation of ``%5%6 %1, %2, %3, %4'' is not supported
+            %endif
+        %endmacro
+        %rotate 1
+    %endrep
+    %pop
 %endmacro
 
-FMA4_INSTR fmaddpd, fmadd132pd, fmadd213pd, fmadd231pd
-FMA4_INSTR fmaddps, fmadd132ps, fmadd213ps, fmadd231ps
-FMA4_INSTR fmaddsd, fmadd132sd, fmadd213sd, fmadd231sd
-FMA4_INSTR fmaddss, fmadd132ss, fmadd213ss, fmadd231ss
+FMA4_INSTR fmadd,    pd, ps, sd, ss
+FMA4_INSTR fmaddsub, pd, ps
+FMA4_INSTR fmsub,    pd, ps, sd, ss
+FMA4_INSTR fmsubadd, pd, ps
+FMA4_INSTR fnmadd,   pd, ps, sd, ss
+FMA4_INSTR fnmsub,   pd, ps, sd, ss
 
-FMA4_INSTR fmaddsubpd, fmaddsub132pd, fmaddsub213pd, fmaddsub231pd
-FMA4_INSTR fmaddsubps, fmaddsub132ps, fmaddsub213ps, fmaddsub231ps
-FMA4_INSTR fmsubaddpd, fmsubadd132pd, fmsubadd213pd, fmsubadd231pd
-FMA4_INSTR fmsubaddps, fmsubadd132ps, fmsubadd213ps, fmsubadd231ps
-
-FMA4_INSTR fmsubpd, fmsub132pd, fmsub213pd, fmsub231pd
-FMA4_INSTR fmsubps, fmsub132ps, fmsub213ps, fmsub231ps
-FMA4_INSTR fmsubsd, fmsub132sd, fmsub213sd, fmsub231sd
-FMA4_INSTR fmsubss, fmsub132ss, fmsub213ss, fmsub231ss
-
-FMA4_INSTR fnmaddpd, fnmadd132pd, fnmadd213pd, fnmadd231pd
-FMA4_INSTR fnmaddps, fnmadd132ps, fnmadd213ps, fnmadd231ps
-FMA4_INSTR fnmaddsd, fnmadd132sd, fnmadd213sd, fnmadd231sd
-FMA4_INSTR fnmaddss, fnmadd132ss, fnmadd213ss, fnmadd231ss
-
-FMA4_INSTR fnmsubpd, fnmsub132pd, fnmsub213pd, fnmsub231pd
-FMA4_INSTR fnmsubps, fnmsub132ps, fnmsub213ps, fnmsub231ps
-FMA4_INSTR fnmsubsd, fnmsub132sd, fnmsub213sd, fnmsub231sd
-FMA4_INSTR fnmsubss, fnmsub132ss, fnmsub213ss, fnmsub231ss
-
-; workaround: vpbroadcastq is broken in x86_32 due to a yasm bug
-%if ARCH_X86_64 == 0
-%macro vpbroadcastq 2
-%if sizeof%1 == 16
-    movddup %1, %2
-%else
-    vbroadcastsd %1, %2
-%endif
-%endmacro
+; workaround: vpbroadcastq is broken in x86_32 due to a yasm bug (fixed in 1.3.0)
+%ifdef __YASM_VER__
+    %if __YASM_VERSION_ID__ < 0x01030000 && ARCH_X86_64 == 0
+        %macro vpbroadcastq 2
+            %if sizeof%1 == 16
+                movddup %1, %2
+            %else
+                vbroadcastsd %1, %2
+            %endif
+        %endmacro
+    %endif
 %endif
diff --git a/vp9/decoder/vp9_decodeframe.c b/vp9/decoder/vp9_decodeframe.c
index 9ce137d..7fc5733 100644
--- a/vp9/decoder/vp9_decodeframe.c
+++ b/vp9/decoder/vp9_decodeframe.c
@@ -859,7 +859,7 @@
                          VPX_CODEC_CORRUPT_FRAME, "Invalid block size.");
   }
 
-  vpx_read_mode_info(pbi, xd, mi_row, mi_col, r, x_mis, y_mis);
+  vp9_read_mode_info(pbi, xd, mi_row, mi_col, r, x_mis, y_mis);
 
   if (mi->skip) {
     dec_reset_skip_context(xd);
diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c
index 8604420..3bd42ec 100644
--- a/vp9/decoder/vp9_decodemv.c
+++ b/vp9/decoder/vp9_decodemv.c
@@ -149,17 +149,12 @@
 }
 
 static int read_inter_segment_id(VP9_COMMON *const cm, MACROBLOCKD *const xd,
-                                 int mi_row, int mi_col, vpx_reader *r) {
+                                 int mi_row, int mi_col, vpx_reader *r,
+                                 int x_mis, int y_mis) {
   struct segmentation *const seg = &cm->seg;
   MODE_INFO *const mi = xd->mi[0];
   int predicted_segment_id, segment_id;
   const int mi_offset = mi_row * cm->mi_cols + mi_col;
-  const int bw = xd->plane[0].n4_w >> 1;
-  const int bh = xd->plane[0].n4_h >> 1;
-
-  // TODO(slavarnway): move x_mis, y_mis into xd ?????
-  const int x_mis = VPXMIN(cm->mi_cols - mi_col, bw);
-  const int y_mis = VPXMIN(cm->mi_rows - mi_row, bh);
 
   if (!seg->enabled)
     return 0;  // Default for disabled segmentation
@@ -202,19 +197,14 @@
 
 static void read_intra_frame_mode_info(VP9_COMMON *const cm,
                                        MACROBLOCKD *const xd,
-                                       int mi_row, int mi_col, vpx_reader *r) {
+                                       int mi_row, int mi_col, vpx_reader *r,
+                                       int x_mis, int y_mis) {
   MODE_INFO *const mi = xd->mi[0];
   const MODE_INFO *above_mi = xd->above_mi;
   const MODE_INFO *left_mi  = xd->left_mi;
   const BLOCK_SIZE bsize = mi->sb_type;
   int i;
   const int mi_offset = mi_row * cm->mi_cols + mi_col;
-  const int bw = xd->plane[0].n4_w >> 1;
-  const int bh = xd->plane[0].n4_h >> 1;
-
-  // TODO(slavarnway): move x_mis, y_mis into xd ?????
-  const int x_mis = VPXMIN(cm->mi_cols - mi_col, bw);
-  const int y_mis = VPXMIN(cm->mi_rows - mi_row, bh);
 
   mi->segment_id = read_intra_segment_id(cm, mi_offset, x_mis, y_mis, r);
   mi->skip = read_skip(cm, xd, mi->segment_id, r);
@@ -839,12 +829,14 @@
 
 static void read_inter_frame_mode_info(VP9Decoder *const pbi,
                                        MACROBLOCKD *const xd,
-                                       int mi_row, int mi_col, vpx_reader *r) {
+                                       int mi_row, int mi_col, vpx_reader *r,
+                                       int x_mis, int y_mis) {
   VP9_COMMON *const cm = &pbi->common;
   MODE_INFO *const mi = xd->mi[0];
   int inter_block;
 
-  mi->segment_id = read_inter_segment_id(cm, xd, mi_row, mi_col, r);
+  mi->segment_id = read_inter_segment_id(cm, xd, mi_row, mi_col, r, x_mis,
+                                         y_mis);
   mi->skip = read_skip(cm, xd, mi->segment_id, r);
   inter_block = read_is_inter_block(cm, xd, mi->segment_id, r);
   mi->tx_size = read_tx_size(cm, xd, !mi->skip || !inter_block, r);
@@ -860,7 +852,7 @@
   memcpy(dst, src, sizeof(*dst) * 2);
 }
 
-void vpx_read_mode_info(VP9Decoder *const pbi, MACROBLOCKD *xd,
+void vp9_read_mode_info(VP9Decoder *const pbi, MACROBLOCKD *xd,
                         int mi_row, int mi_col, vpx_reader *r,
                         int x_mis, int y_mis) {
   VP9_COMMON *const cm = &pbi->common;
@@ -869,9 +861,9 @@
   int w, h;
 
   if (frame_is_intra_only(cm)) {
-    read_intra_frame_mode_info(cm, xd, mi_row, mi_col, r);
+    read_intra_frame_mode_info(cm, xd, mi_row, mi_col, r, x_mis, y_mis);
   } else {
-    read_inter_frame_mode_info(pbi, xd, mi_row, mi_col, r);
+    read_inter_frame_mode_info(pbi, xd, mi_row, mi_col, r, x_mis, y_mis);
 
     for (h = 0; h < y_mis; ++h) {
       for (w = 0; w < x_mis; ++w) {
diff --git a/vp9/decoder/vp9_decodemv.h b/vp9/decoder/vp9_decodemv.h
index 75f568c..45569ec 100644
--- a/vp9/decoder/vp9_decodemv.h
+++ b/vp9/decoder/vp9_decodemv.h
@@ -19,7 +19,7 @@
 extern "C" {
 #endif
 
-void vpx_read_mode_info(VP9Decoder *const pbi, MACROBLOCKD *xd,
+void vp9_read_mode_info(VP9Decoder *const pbi, MACROBLOCKD *xd,
                         int mi_row, int mi_col, vpx_reader *r,
                         int x_mis, int y_mis);
 
diff --git a/vp9/encoder/vp9_aq_cyclicrefresh.c b/vp9/encoder/vp9_aq_cyclicrefresh.c
index 0a02bde..c2ba276 100644
--- a/vp9/encoder/vp9_aq_cyclicrefresh.c
+++ b/vp9/encoder/vp9_aq_cyclicrefresh.c
@@ -198,6 +198,9 @@
       refresh_this_block = 1;
   }
 
+  if (cpi->oxcf.rc_mode == VPX_VBR && mi->ref_frame[0] == GOLDEN_FRAME)
+    refresh_this_block = 0;
+
   // If this block is labeled for refresh, check if we should reset the
   // segment_id.
   if (cyclic_refresh_segment_id_boosted(mi->segment_id)) {
@@ -305,6 +308,8 @@
     rc->baseline_gf_interval = VPXMIN(4 * (100 / cr->percent_refresh), 40);
   else
     rc->baseline_gf_interval = 40;
+  if (cpi->oxcf.rc_mode == VPX_VBR)
+    rc->baseline_gf_interval = 20;
 }
 
 // Update some encoding stats (from the just encoded frame). If this frame's
@@ -504,6 +509,18 @@
     cr->motion_thresh = 4;
     cr->rate_boost_fac = 12;
   }
+  if (cpi->oxcf.rc_mode == VPX_VBR) {
+    // To be adjusted for VBR mode, e.g., based on gf period and boost.
+    // For now use smaller qp-delta (than CBR), no second boosted seg, and
+    // turn-off (no refresh) on golden refresh (since it's already boosted).
+    cr->percent_refresh = 10;
+    cr->rate_ratio_qdelta = 1.5;
+    cr->rate_boost_fac = 10;
+    if (cpi->refresh_golden_frame == 1) {
+      cr->percent_refresh = 0;
+      cr->rate_ratio_qdelta = 1.0;
+    }
+  }
 }
 
 // Setup cyclic background refresh: set delta q and segmentation map.
diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c
index 06d245e..f8f681a 100644
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -3363,11 +3363,13 @@
                                       (cpi->oxcf.pass == 0));
 
   // Avoid scaling last_source unless its needed.
-  // Last source is currently only used for screen-content mode,
-  // if partition_search_type == SOURCE_VAR_BASED_PARTITION, or if noise
+  // Last source is needed if vp9_avg_source_sad() is used, or if
+  // partition_search_type == SOURCE_VAR_BASED_PARTITION, or if noise
   // estimation is enabled.
   if (cpi->unscaled_last_source != NULL &&
       (cpi->oxcf.content == VP9E_CONTENT_SCREEN ||
+      (cpi->oxcf.pass == 0 && cpi->oxcf.rc_mode == VPX_VBR &&
+      cpi->oxcf.mode == REALTIME && cpi->oxcf.speed >= 5) ||
       cpi->sf.partition_search_type == SOURCE_VAR_BASED_PARTITION ||
       cpi->noise_estimate.enabled))
     cpi->Last_Source = vp9_scale_if_required(cm,
@@ -3377,10 +3379,12 @@
   vp9_update_noise_estimate(cpi);
 
   if (cpi->oxcf.pass == 0 &&
-      cpi->oxcf.rc_mode == VPX_CBR &&
+      cpi->oxcf.mode == REALTIME &&
+      cpi->oxcf.speed >= 5 &&
       cpi->resize_state == 0 &&
       cm->frame_type != KEY_FRAME &&
-      cpi->oxcf.content == VP9E_CONTENT_SCREEN)
+      (cpi->oxcf.content == VP9E_CONTENT_SCREEN ||
+       cpi->oxcf.rc_mode == VPX_VBR))
     vp9_avg_source_sad(cpi);
 
   // TODO(wonkap/marpan): For 1 pass SVC, since only ZERMOV is allowed for
diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c
index 5df2909..d64b5c5 100644
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -1469,7 +1469,12 @@
     cm->frame_type = INTER_FRAME;
   }
   if (rc->frames_till_gf_update_due == 0) {
-    rc->baseline_gf_interval = (rc->min_gf_interval + rc->max_gf_interval) / 2;
+    if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cpi->oxcf.pass == 0) {
+      vp9_cyclic_refresh_set_golden_update(cpi);
+    } else {
+      rc->baseline_gf_interval =
+          (rc->min_gf_interval + rc->max_gf_interval) / 2;
+    }
     rc->frames_till_gf_update_due = rc->baseline_gf_interval;
     // NOTE: frames_till_gf_update_due must be <= frames_to_key.
     if (rc->frames_till_gf_update_due > rc->frames_to_key) {
@@ -1487,6 +1492,8 @@
   else
     target = calc_pframe_target_size_one_pass_vbr(cpi);
   vp9_rc_set_frame_target(cpi, target);
+  if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cpi->oxcf.pass == 0)
+    vp9_cyclic_refresh_update_parameters(cpi);
 }
 
 static int calc_pframe_target_size_one_pass_cbr(const VP9_COMP *cpi) {
@@ -2010,13 +2017,17 @@
   VP9_COMMON * const cm = &cpi->common;
   RATE_CONTROL *const rc = &cpi->rc;
   rc->high_source_sad = 0;
-  if (cpi->Last_Source != NULL) {
+  if (cpi->Last_Source != NULL &&
+      cpi->Last_Source->y_width == cm->width &&
+      cpi->Last_Source->y_height == cm->height) {
     const uint8_t *src_y = cpi->Source->y_buffer;
     const int src_ystride = cpi->Source->y_stride;
     const uint8_t *last_src_y = cpi->Last_Source->y_buffer;
     const int last_src_ystride = cpi->Last_Source->y_stride;
     int sbi_row, sbi_col;
     const BLOCK_SIZE bsize = BLOCK_64X64;
+    uint32_t min_thresh = 4000;
+    float thresh = 8.0f;
     // Loop over sub-sample of frame, and compute average sad over 64x64 blocks.
     uint64_t avg_sad = 0;
     int num_samples = 0;
@@ -2047,12 +2058,32 @@
     // between current and the previous frame value(s). Use a minimum threshold
     // for cases where there is small change from content that is completely
     // static.
-    if (avg_sad > VPXMAX(4000, (rc->avg_source_sad << 3)) &&
+    if (cpi->oxcf.rc_mode == VPX_VBR) {
+      min_thresh = 20000;
+      thresh = 2.0f;
+    }
+    if (avg_sad >
+        VPXMAX(min_thresh, (unsigned int)(rc->avg_source_sad  * thresh)) &&
         rc->frames_since_key > 1)
       rc->high_source_sad = 1;
     else
       rc->high_source_sad = 0;
-    rc->avg_source_sad = (rc->avg_source_sad + avg_sad) >> 1;
+    if (avg_sad > 0)
+      rc->avg_source_sad = (rc->avg_source_sad + avg_sad) >> 1;
+    // For VBR, under scene change/high content change, force golden refresh.
+    if (cpi->oxcf.rc_mode == VPX_VBR &&
+        rc->high_source_sad &&
+        cpi->refresh_golden_frame == 0 &&
+        cpi->ext_refresh_frame_flags_pending == 0) {
+      int target;
+      cpi->refresh_golden_frame = 1;
+      rc->frames_till_gf_update_due = rc->baseline_gf_interval >> 1;
+      if (rc->frames_till_gf_update_due > rc->frames_to_key)
+        rc->frames_till_gf_update_due = rc->frames_to_key;
+      rc->gfu_boost = DEFAULT_GF_BOOST;
+      target = calc_pframe_target_size_one_pass_vbr(cpi);
+      vp9_rc_set_frame_target(cpi, target);
+    }
   }
 }
 
diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c
index 11df1e4..624d5c9 100644
--- a/vp9/vp9_cx_iface.c
+++ b/vp9/vp9_cx_iface.c
@@ -1566,7 +1566,7 @@
       // keyframing settings (kf)
       VPX_KF_AUTO,        // g_kfmode
       0,                  // kf_min_dist
-      9999,               // kf_max_dist
+      128,                // kf_max_dist
 
       VPX_SS_DEFAULT_LAYERS,  // ss_number_layers
       {0},
diff --git a/vpx_dsp/vpx_dsp.mk b/vpx_dsp/vpx_dsp.mk
index e394688..581ec3a 100644
--- a/vpx_dsp/vpx_dsp.mk
+++ b/vpx_dsp/vpx_dsp.mk
@@ -39,6 +39,7 @@
 DSP_SRCS-yes += intrapred.c
 
 ifeq ($(CONFIG_USE_X86INC),yes)
+DSP_SRCS-$(HAVE_MMX) += x86/loopfilter_mmx.asm
 DSP_SRCS-$(HAVE_SSE) += x86/intrapred_sse2.asm
 DSP_SRCS-$(HAVE_SSE2) += x86/intrapred_sse2.asm
 DSP_SRCS-$(HAVE_SSSE3) += x86/intrapred_ssse3.asm
@@ -128,7 +129,6 @@
 
 DSP_SRCS-$(ARCH_X86)$(ARCH_X86_64)   += x86/loopfilter_sse2.c
 DSP_SRCS-$(HAVE_AVX2)                += x86/loopfilter_avx2.c
-DSP_SRCS-$(HAVE_MMX)                 += x86/loopfilter_mmx.asm
 
 DSP_SRCS-$(HAVE_NEON)   += arm/loopfilter_neon.c
 ifeq ($(HAVE_NEON_ASM),yes)
diff --git a/vpx_dsp/vpx_dsp_rtcd_defs.pl b/vpx_dsp/vpx_dsp_rtcd_defs.pl
index d7835f4..34dd0bc 100644
--- a/vpx_dsp/vpx_dsp_rtcd_defs.pl
+++ b/vpx_dsp/vpx_dsp_rtcd_defs.pl
@@ -543,7 +543,7 @@
 $vpx_lpf_vertical_8_dual_neon_asm=vpx_lpf_vertical_8_dual_neon;
 
 add_proto qw/void vpx_lpf_vertical_4/, "uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh";
-specialize qw/vpx_lpf_vertical_4 mmx neon dspr2 msa/;
+specialize qw/vpx_lpf_vertical_4 neon dspr2 msa/, "$mmx_x86inc";
 
 add_proto qw/void vpx_lpf_vertical_4_dual/, "uint8_t *s, int pitch, const uint8_t *blimit0, const uint8_t *limit0, const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, const uint8_t *thresh1";
 specialize qw/vpx_lpf_vertical_4_dual sse2 neon dspr2 msa/;
@@ -564,7 +564,7 @@
 $vpx_lpf_horizontal_8_dual_neon_asm=vpx_lpf_horizontal_8_dual_neon;
 
 add_proto qw/void vpx_lpf_horizontal_4/, "uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh";
-specialize qw/vpx_lpf_horizontal_4 mmx neon dspr2 msa/;
+specialize qw/vpx_lpf_horizontal_4 neon dspr2 msa/, "$mmx_x86inc";
 
 add_proto qw/void vpx_lpf_horizontal_4_dual/, "uint8_t *s, int pitch, const uint8_t *blimit0, const uint8_t *limit0, const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, const uint8_t *thresh1";
 specialize qw/vpx_lpf_horizontal_4_dual sse2 neon dspr2 msa/;
diff --git a/vpx_dsp/x86/loopfilter_mmx.asm b/vpx_dsp/x86/loopfilter_mmx.asm
index 15105e3..3c4c8a5 100644
--- a/vpx_dsp/x86/loopfilter_mmx.asm
+++ b/vpx_dsp/x86/loopfilter_mmx.asm
@@ -1,5 +1,5 @@
 ;
-;  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+;  Copyright (c) 2016 The WebM project authors. All Rights Reserved.
 ;
 ;  Use of this source code is governed by a BSD-style license
 ;  that can be found in the LICENSE file in the root of the source
@@ -8,589 +8,425 @@
 ;  be found in the AUTHORS file in the root of the source tree.
 ;
 
-
-%include "vpx_ports/x86_abi_support.asm"
-
-
-;void vpx_lpf_horizontal_4_mmx
-;(
-;    unsigned char *src_ptr,
-;    int src_pixel_step,
-;    const char *blimit,
-;    const char *limit,
-;    const char *thresh
-;)
-global sym(vpx_lpf_horizontal_4_mmx) PRIVATE
-sym(vpx_lpf_horizontal_4_mmx):
-    push        rbp
-    mov         rbp, rsp
-    SHADOW_ARGS_TO_STACK 5
-    GET_GOT     rbx
-    push        rsi
-    push        rdi
-    ; end prolog
-
-    ALIGN_STACK 16, rax
-    sub         rsp, 32                         ; reserve 32 bytes
-    %define t0 [rsp + 0]    ;__declspec(align(16)) char t0[8];
-    %define t1 [rsp + 16]   ;__declspec(align(16)) char t1[8];
-
-        mov         rsi, arg(0) ;src_ptr
-        movsxd      rax, dword ptr arg(1) ;src_pixel_step     ; destination pitch?
-
-        mov         rdx, arg(3) ;limit
-        movq        mm7, [rdx]
-        mov         rdi, rsi              ; rdi points to row +1 for indirect addressing
-        add         rdi, rax
-
-        ; calculate breakout conditions
-        movq        mm2, [rdi+2*rax]      ; q3
-        movq        mm1, [rsi+2*rax]      ; q2
-        movq        mm6, mm1              ; q2
-        psubusb     mm1, mm2              ; q2-=q3
-        psubusb     mm2, mm6              ; q3-=q2
-        por         mm1, mm2              ; abs(q3-q2)
-        psubusb     mm1, mm7              ;
-
-
-        movq        mm4, [rsi+rax]        ; q1
-        movq        mm3, mm4              ; q1
-        psubusb     mm4, mm6              ; q1-=q2
-        psubusb     mm6, mm3              ; q2-=q1
-        por         mm4, mm6              ; abs(q2-q1)
-
-        psubusb     mm4, mm7
-        por        mm1, mm4
-
-        movq        mm4, [rsi]            ; q0
-        movq        mm0, mm4              ; q0
-        psubusb     mm4, mm3              ; q0-=q1
-        psubusb     mm3, mm0              ; q1-=q0
-        por         mm4, mm3              ; abs(q0-q1)
-        movq        t0, mm4               ; save to t0
-        psubusb     mm4, mm7
-        por        mm1, mm4
-
-
-        neg         rax                   ; negate pitch to deal with above border
-
-        movq        mm2, [rsi+4*rax]      ; p3
-        movq        mm4, [rdi+4*rax]      ; p2
-        movq        mm5, mm4              ; p2
-        psubusb     mm4, mm2              ; p2-=p3
-        psubusb     mm2, mm5              ; p3-=p2
-        por         mm4, mm2              ; abs(p3 - p2)
-        psubusb     mm4, mm7
-        por        mm1, mm4
-
-
-        movq        mm4, [rsi+2*rax]      ; p1
-        movq        mm3, mm4              ; p1
-        psubusb     mm4, mm5              ; p1-=p2
-        psubusb     mm5, mm3              ; p2-=p1
-        por         mm4, mm5              ; abs(p2 - p1)
-        psubusb     mm4, mm7
-        por        mm1, mm4
-
-        movq        mm2, mm3              ; p1
-
-        movq        mm4, [rsi+rax]        ; p0
-        movq        mm5, mm4              ; p0
-        psubusb     mm4, mm3              ; p0-=p1
-        psubusb     mm3, mm5              ; p1-=p0
-        por         mm4, mm3              ; abs(p1 - p0)
-        movq        t1, mm4               ; save to t1
-        psubusb     mm4, mm7
-        por        mm1, mm4
-
-        movq        mm3, [rdi]            ; q1
-        movq        mm4, mm3              ; q1
-        psubusb     mm3, mm2              ; q1-=p1
-        psubusb     mm2, mm4              ; p1-=q1
-        por         mm2, mm3              ; abs(p1-q1)
-        pand        mm2, [GLOBAL(tfe)]    ; set lsb of each byte to zero
-        psrlw       mm2, 1                ; abs(p1-q1)/2
-
-        movq        mm6, mm5              ; p0
-        movq        mm3, [rsi]            ; q0
-        psubusb     mm5, mm3              ; p0-=q0
-        psubusb     mm3, mm6              ; q0-=p0
-        por         mm5, mm3              ; abs(p0 - q0)
-        paddusb     mm5, mm5              ; abs(p0-q0)*2
-        paddusb     mm5, mm2              ; abs (p0 - q0) *2 + abs(p1-q1)/2
-
-        mov         rdx, arg(2) ;blimit           ; get blimit
-        movq        mm7, [rdx]            ; blimit
-
-        psubusb     mm5,    mm7           ; abs (p0 - q0) *2 + abs(p1-q1)/2  > blimit
-        por         mm1,    mm5
-        pxor        mm5,    mm5
-        pcmpeqb     mm1,    mm5           ; mask mm1
-
-        ; calculate high edge variance
-        mov         rdx, arg(4) ;thresh           ; get thresh
-        movq        mm7, [rdx]            ;
-        movq        mm4, t0               ; get abs (q1 - q0)
-        psubusb     mm4, mm7
-        movq        mm3, t1               ; get abs (p1 - p0)
-        psubusb     mm3, mm7
-        paddb       mm4, mm3              ; abs(q1 - q0) > thresh || abs(p1 - p0) > thresh
-
-        pcmpeqb     mm4,        mm5
-
-        pcmpeqb     mm5,        mm5
-        pxor        mm4,        mm5
-
-
-        ; start work on filters
-        movq        mm2, [rsi+2*rax]      ; p1
-        movq        mm7, [rdi]            ; q1
-        pxor        mm2, [GLOBAL(t80)]    ; p1 offset to convert to signed values
-        pxor        mm7, [GLOBAL(t80)]    ; q1 offset to convert to signed values
-        psubsb      mm2, mm7              ; p1 - q1
-        pand        mm2, mm4              ; high var mask (hvm)(p1 - q1)
-        pxor        mm6, [GLOBAL(t80)]    ; offset to convert to signed values
-        pxor        mm0, [GLOBAL(t80)]    ; offset to convert to signed values
-        movq        mm3, mm0              ; q0
-        psubsb      mm0, mm6              ; q0 - p0
-        paddsb      mm2, mm0              ; 1 * (q0 - p0) + hvm(p1 - q1)
-        paddsb      mm2, mm0              ; 2 * (q0 - p0) + hvm(p1 - q1)
-        paddsb      mm2, mm0              ; 3 * (q0 - p0) + hvm(p1 - q1)
-        pand        mm1, mm2                  ; mask filter values we don't care about
-        movq        mm2, mm1
-        paddsb      mm1, [GLOBAL(t4)]     ; 3* (q0 - p0) + hvm(p1 - q1) + 4
-        paddsb      mm2, [GLOBAL(t3)]     ; 3* (q0 - p0) + hvm(p1 - q1) + 3
-
-        pxor        mm0, mm0             ;
-        pxor        mm5, mm5
-        punpcklbw   mm0, mm2            ;
-        punpckhbw   mm5, mm2            ;
-        psraw       mm0, 11             ;
-        psraw       mm5, 11
-        packsswb    mm0, mm5
-        movq        mm2, mm0            ;  (3* (q0 - p0) + hvm(p1 - q1) + 3) >> 3;
-
-        pxor        mm0, mm0              ; 0
-        movq        mm5, mm1              ; abcdefgh
-        punpcklbw   mm0, mm1              ; e0f0g0h0
-        psraw       mm0, 11               ; sign extended shift right by 3
-        pxor        mm1, mm1              ; 0
-        punpckhbw   mm1, mm5              ; a0b0c0d0
-        psraw       mm1, 11               ; sign extended shift right by 3
-        movq        mm5, mm0              ; save results
-
-        packsswb    mm0, mm1              ; (3* (q0 - p0) + hvm(p1 - q1) + 4) >>3
-        paddsw      mm5, [GLOBAL(ones)]
-        paddsw      mm1, [GLOBAL(ones)]
-        psraw       mm5, 1                ; partial shifted one more time for 2nd tap
-        psraw       mm1, 1                ; partial shifted one more time for 2nd tap
-        packsswb    mm5, mm1              ; (3* (q0 - p0) + hvm(p1 - q1) + 4) >>4
-        pandn       mm4, mm5              ; high edge variance additive
-
-        paddsb      mm6, mm2              ; p0+= p0 add
-        pxor        mm6, [GLOBAL(t80)]    ; unoffset
-        movq        [rsi+rax], mm6        ; write back
-
-        movq        mm6, [rsi+2*rax]      ; p1
-        pxor        mm6, [GLOBAL(t80)]    ; reoffset
-        paddsb      mm6, mm4              ; p1+= p1 add
-        pxor        mm6, [GLOBAL(t80)]    ; unoffset
-        movq        [rsi+2*rax], mm6      ; write back
-
-        psubsb      mm3, mm0              ; q0-= q0 add
-        pxor        mm3, [GLOBAL(t80)]    ; unoffset
-        movq        [rsi], mm3            ; write back
-
-        psubsb      mm7, mm4              ; q1-= q1 add
-        pxor        mm7, [GLOBAL(t80)]    ; unoffset
-        movq        [rdi], mm7            ; write back
-
-    add rsp, 32
-    pop rsp
-    ; begin epilog
-    pop rdi
-    pop rsi
-    RESTORE_GOT
-    UNSHADOW_ARGS
-    pop         rbp
-    ret
-
-
-;void vpx_lpf_vertical_4_mmx
-;(
-;    unsigned char *src_ptr,
-;    int  src_pixel_step,
-;    const char *blimit,
-;    const char *limit,
-;    const char *thresh
-;)
-global sym(vpx_lpf_vertical_4_mmx) PRIVATE
-sym(vpx_lpf_vertical_4_mmx):
-    push        rbp
-    mov         rbp, rsp
-    SHADOW_ARGS_TO_STACK 5
-    GET_GOT     rbx
-    push        rsi
-    push        rdi
-    ; end prolog
-
-    ALIGN_STACK 16, rax
-    sub          rsp, 64      ; reserve 64 bytes
-    %define t0   [rsp + 0]    ;__declspec(align(16)) char t0[8];
-    %define t1   [rsp + 16]   ;__declspec(align(16)) char t1[8];
-    %define srct [rsp + 32]   ;__declspec(align(16)) char srct[32];
-
-        mov         rsi,        arg(0) ;src_ptr
-        movsxd      rax,        dword ptr arg(1) ;src_pixel_step     ; destination pitch?
-
-        lea         rsi,        [rsi + rax*4 - 4]
-
-        mov         rdi,        rsi           ; rdi points to row +1 for indirect addressing
-        add         rdi,        rax
-
-
-        ;transpose
-        movq        mm6,        [rsi+2*rax]                 ; 67 66 65 64 63 62 61 60
-        movq        mm7,        mm6                         ; 77 76 75 74 73 72 71 70
-
-        punpckhbw   mm7,        [rdi+2*rax]                 ; 77 67 76 66 75 65 74 64
-        punpcklbw   mm6,        [rdi+2*rax]                 ; 73 63 72 62 71 61 70 60
-
-        movq        mm4,        [rsi]                       ; 47 46 45 44 43 42 41 40
-        movq        mm5,        mm4                         ; 47 46 45 44 43 42 41 40
-
-        punpckhbw   mm5,        [rsi+rax]                   ; 57 47 56 46 55 45 54 44
-        punpcklbw   mm4,        [rsi+rax]                   ; 53 43 52 42 51 41 50 40
-
-        movq        mm3,        mm5                         ; 57 47 56 46 55 45 54 44
-        punpckhwd   mm5,        mm7                         ; 77 67 57 47 76 66 56 46
-
-        punpcklwd   mm3,        mm7                         ; 75 65 55 45 74 64 54 44
-        movq        mm2,        mm4                         ; 53 43 52 42 51 41 50 40
-
-        punpckhwd   mm4,        mm6                         ; 73 63 53 43 72 62 52 42
-        punpcklwd   mm2,        mm6                         ; 71 61 51 41 70 60 50 40
-
-        neg         rax
-        movq        mm6,        [rsi+rax*2]                 ; 27 26 25 24 23 22 21 20
-
-        movq        mm1,        mm6                         ; 27 26 25 24 23 22 21 20
-        punpckhbw   mm6,        [rsi+rax]                   ; 37 27 36 36 35 25 34 24
-
-        punpcklbw   mm1,        [rsi+rax]                   ; 33 23 32 22 31 21 30 20
-        movq        mm7,        [rsi+rax*4];                ; 07 06 05 04 03 02 01 00
-
-        punpckhbw   mm7,        [rdi+rax*4]                 ; 17 07 16 06 15 05 14 04
-        movq        mm0,        mm7                         ; 17 07 16 06 15 05 14 04
-
-        punpckhwd   mm7,        mm6                         ; 37 27 17 07 36 26 16 06
-        punpcklwd   mm0,        mm6                         ; 35 25 15 05 34 24 14 04
-
-        movq        mm6,        mm7                         ; 37 27 17 07 36 26 16 06
-        punpckhdq   mm7,        mm5                         ; 77 67 57 47 37 27 17 07  = q3
-
-        punpckldq   mm6,        mm5                         ; 76 66 56 46 36 26 16 06  = q2
-
-        movq        mm5,        mm6                         ; 76 66 56 46 36 26 16 06
-        psubusb     mm5,        mm7                         ; q2-q3
-
-        psubusb     mm7,        mm6                         ; q3-q2
-        por         mm7,        mm5;                        ; mm7=abs (q3-q2)
-
-        movq        mm5,        mm0                         ; 35 25 15 05 34 24 14 04
-        punpckhdq   mm5,        mm3                         ; 75 65 55 45 35 25 15 05 = q1
-
-        punpckldq   mm0,        mm3                         ; 74 64 54 44 34 24 15 04 = q0
-        movq        mm3,        mm5                         ; 75 65 55 45 35 25 15 05 = q1
-
-        psubusb     mm3,        mm6                         ; q1-q2
-        psubusb     mm6,        mm5                         ; q2-q1
-
-        por         mm6,        mm3                         ; mm6=abs(q2-q1)
-        lea         rdx,        srct
-
-        movq        [rdx+24],   mm5                         ; save q1
-        movq        [rdx+16],   mm0                         ; save q0
-
-        movq        mm3,        [rsi+rax*4]                 ; 07 06 05 04 03 02 01 00
-        punpcklbw   mm3,        [rdi+rax*4]                 ; 13 03 12 02 11 01 10 00
-
-        movq        mm0,        mm3                         ; 13 03 12 02 11 01 10 00
-        punpcklwd   mm0,        mm1                         ; 31 21 11 01 30 20 10 00
-
-        punpckhwd   mm3,        mm1                         ; 33 23 13 03 32 22 12 02
-        movq        mm1,        mm0                         ; 31 21 11 01 30 20 10 00
-
-        punpckldq   mm0,        mm2                         ; 70 60 50 40 30 20 10 00  =p3
-        punpckhdq   mm1,        mm2                         ; 71 61 51 41 31 21 11 01  =p2
-
-        movq        mm2,        mm1                         ; 71 61 51 41 31 21 11 01  =p2
-        psubusb     mm2,        mm0                         ; p2-p3
-
-        psubusb     mm0,        mm1                         ; p3-p2
-        por         mm0,        mm2                         ; mm0=abs(p3-p2)
-
-        movq        mm2,        mm3                         ; 33 23 13 03 32 22 12 02
-        punpckldq   mm2,        mm4                         ; 72 62 52 42 32 22 12 02 = p1
-
-        punpckhdq   mm3,        mm4                         ; 73 63 53 43 33 23 13 03 = p0
-        movq        [rdx+8],    mm3                         ; save p0
-
-        movq        [rdx],      mm2                         ; save p1
-        movq        mm5,        mm2                         ; mm5 = p1
-
-        psubusb     mm2,        mm1                         ; p1-p2
-        psubusb     mm1,        mm5                         ; p2-p1
-
-        por         mm1,        mm2                         ; mm1=abs(p2-p1)
-        mov         rdx,        arg(3) ;limit
-
-        movq        mm4,        [rdx]                       ; mm4 = limit
-        psubusb     mm7,        mm4
-
-        psubusb     mm0,        mm4
-        psubusb     mm1,        mm4
-
-        psubusb     mm6,        mm4
-        por         mm7,        mm6
-
-        por         mm0,        mm1
-        por         mm0,        mm7                         ;   abs(q3-q2) > limit || abs(p3-p2) > limit ||abs(p2-p1) > limit || abs(q2-q1) > limit
-
-        movq        mm1,        mm5                         ; p1
-
-        movq        mm7,        mm3                         ; mm3=mm7=p0
-        psubusb     mm7,        mm5                         ; p0 - p1
-
-        psubusb     mm5,        mm3                         ; p1 - p0
-        por         mm5,        mm7                         ; abs(p1-p0)
-
-        movq        t0,         mm5                         ; save abs(p1-p0)
-        lea         rdx,        srct
-
-        psubusb     mm5,        mm4
-        por         mm0,        mm5                         ; mm0=mask
-
-        movq        mm5,        [rdx+16]                    ; mm5=q0
-        movq        mm7,        [rdx+24]                    ; mm7=q1
-
-        movq        mm6,        mm5                         ; mm6=q0
-        movq        mm2,        mm7                         ; q1
-        psubusb     mm5,        mm7                         ; q0-q1
-
-        psubusb     mm7,        mm6                         ; q1-q0
-        por         mm7,        mm5                         ; abs(q1-q0)
-
-        movq        t1,         mm7                         ; save abs(q1-q0)
-        psubusb     mm7,        mm4
-
-        por         mm0,        mm7                         ; mask
-
-        movq        mm5,        mm2                         ; q1
-        psubusb     mm5,        mm1                         ; q1-=p1
-        psubusb     mm1,        mm2                         ; p1-=q1
-        por         mm5,        mm1                         ; abs(p1-q1)
-        pand        mm5,        [GLOBAL(tfe)]               ; set lsb of each byte to zero
-        psrlw       mm5,        1                           ; abs(p1-q1)/2
-
-        mov         rdx,        arg(2) ;blimit                      ;
-
-        movq        mm4,        [rdx]                       ;blimit
-        movq        mm1,        mm3                         ; mm1=mm3=p0
-
-        movq        mm7,        mm6                         ; mm7=mm6=q0
-        psubusb     mm1,        mm7                         ; p0-q0
-
-        psubusb     mm7,        mm3                         ; q0-p0
-        por         mm1,        mm7                         ; abs(q0-p0)
-        paddusb     mm1,        mm1                         ; abs(q0-p0)*2
-        paddusb     mm1,        mm5                         ; abs (p0 - q0) *2 + abs(p1-q1)/2
-
-        psubusb     mm1,        mm4                         ; abs (p0 - q0) *2 + abs(p1-q1)/2  > blimit
-        por         mm1,        mm0;                        ; mask
-
-        pxor        mm0,        mm0
-        pcmpeqb     mm1,        mm0
-
-        ; calculate high edge variance
-        mov         rdx,        arg(4) ;thresh            ; get thresh
-        movq        mm7,        [rdx]
-        ;
-        movq        mm4,        t0              ; get abs (q1 - q0)
-        psubusb     mm4,        mm7
-
-        movq        mm3,        t1              ; get abs (p1 - p0)
-        psubusb     mm3,        mm7
-
-        por         mm4,        mm3             ; abs(q1 - q0) > thresh || abs(p1 - p0) > thresh
-        pcmpeqb     mm4,        mm0
-
-        pcmpeqb     mm0,        mm0
-        pxor        mm4,        mm0
-
-
-
-        ; start work on filters
-        lea         rdx,        srct
-
-        movq        mm2,        [rdx]           ; p1
-        movq        mm7,        [rdx+24]        ; q1
-
-        movq        mm6,        [rdx+8]         ; p0
-        movq        mm0,        [rdx+16]        ; q0
-
-        pxor        mm2,        [GLOBAL(t80)]   ; p1 offset to convert to signed values
-        pxor        mm7,        [GLOBAL(t80)]   ; q1 offset to convert to signed values
-
-        psubsb      mm2,        mm7             ; p1 - q1
-        pand        mm2,        mm4             ; high var mask (hvm)(p1 - q1)
-
-        pxor        mm6,        [GLOBAL(t80)]   ; offset to convert to signed values
-        pxor        mm0,        [GLOBAL(t80)]   ; offset to convert to signed values
-
-        movq        mm3,        mm0             ; q0
-        psubsb      mm0,        mm6             ; q0 - p0
-
-        paddsb      mm2,        mm0             ; 1 * (q0 - p0) + hvm(p1 - q1)
-        paddsb      mm2,        mm0             ; 2 * (q0 - p0) + hvm(p1 - q1)
-
-        paddsb      mm2,        mm0             ; 3 * (q0 - p0) + hvm(p1 - q1)
-        pand       mm1,        mm2              ; mask filter values we don't care about
-
-        movq        mm2,        mm1
-        paddsb      mm1,        [GLOBAL(t4)]      ; 3* (q0 - p0) + hvm(p1 - q1) + 4
-
-        paddsb      mm2,        [GLOBAL(t3)]      ; 3* (q0 - p0) + hvm(p1 - q1) + 3
-        pxor        mm0,        mm0          ;
-
-        pxor        mm5,        mm5
-        punpcklbw   mm0,        mm2         ;
-
-        punpckhbw   mm5,        mm2         ;
-        psraw       mm0,        11              ;
-
-        psraw       mm5,        11
-        packsswb    mm0,        mm5
-
-        movq        mm2,        mm0         ;  (3* (q0 - p0) + hvm(p1 - q1) + 3) >> 3;
-
-        pxor        mm0,        mm0           ; 0
-        movq        mm5,        mm1           ; abcdefgh
-
-        punpcklbw   mm0,        mm1           ; e0f0g0h0
-        psraw       mm0,        11                ; sign extended shift right by 3
-
-        pxor        mm1,        mm1           ; 0
-        punpckhbw   mm1,        mm5           ; a0b0c0d0
-
-        psraw       mm1,        11                ; sign extended shift right by 3
-        movq        mm5,        mm0              ; save results
-
-        packsswb    mm0,        mm1           ; (3* (q0 - p0) + hvm(p1 - q1) + 4) >>3
-        paddsw      mm5,        [GLOBAL(ones)]
-
-        paddsw      mm1,        [GLOBAL(ones)]
-        psraw       mm5,        1                 ; partial shifted one more time for 2nd tap
-
-        psraw       mm1,        1                 ; partial shifted one more time for 2nd tap
-        packsswb    mm5,        mm1           ; (3* (q0 - p0) + hvm(p1 - q1) + 4) >>4
-
-        pandn       mm4,        mm5             ; high edge variance additive
-
-        paddsb      mm6,        mm2             ; p0+= p0 add
-        pxor        mm6,        [GLOBAL(t80)]   ; unoffset
-
-        ; mm6=p0                               ;
-        movq        mm1,        [rdx]           ; p1
-        pxor        mm1,        [GLOBAL(t80)]   ; reoffset
-
-        paddsb      mm1,        mm4                 ; p1+= p1 add
-        pxor        mm1,        [GLOBAL(t80)]       ; unoffset
-        ; mm6 = p0 mm1 = p1
-
-        psubsb      mm3,        mm0                 ; q0-= q0 add
-        pxor        mm3,        [GLOBAL(t80)]       ; unoffset
-
-        ; mm3 = q0
-        psubsb      mm7,        mm4                 ; q1-= q1 add
-        pxor        mm7,        [GLOBAL(t80)]       ; unoffset
-        ; mm7 = q1
-
-        ; transpose and write back
-        ; mm1 =    72 62 52 42 32 22 12 02
-        ; mm6 =    73 63 53 43 33 23 13 03
-        ; mm3 =    74 64 54 44 34 24 14 04
-        ; mm7 =    75 65 55 45 35 25 15 05
-
-        movq        mm2,        mm1             ; 72 62 52 42 32 22 12 02
-        punpcklbw   mm2,        mm6             ; 33 32 23 22 13 12 03 02
-
-        movq        mm4,        mm3             ; 74 64 54 44 34 24 14 04
-        punpckhbw   mm1,        mm6             ; 73 72 63 62 53 52 43 42
-
-        punpcklbw   mm4,        mm7             ; 35 34 25 24 15 14 05 04
-        punpckhbw   mm3,        mm7             ; 75 74 65 64 55 54 45 44
-
-        movq        mm6,        mm2             ; 33 32 23 22 13 12 03 02
-        punpcklwd   mm2,        mm4             ; 15 14 13 12 05 04 03 02
-
-        punpckhwd   mm6,        mm4             ; 35 34 33 32 25 24 23 22
-        movq        mm5,        mm1             ; 73 72 63 62 53 52 43 42
-
-        punpcklwd   mm1,        mm3             ; 55 54 53 52 45 44 43 42
-        punpckhwd   mm5,        mm3             ; 75 74 73 72 65 64 63 62
-
-
-        ; mm2 = 15 14 13 12 05 04 03 02
-        ; mm6 = 35 34 33 32 25 24 23 22
-        ; mm5 = 55 54 53 52 45 44 43 42
-        ; mm1 = 75 74 73 72 65 64 63 62
-
-
-
-        movd        [rsi+rax*4+2], mm2
-        psrlq       mm2,        32
-
-        movd        [rdi+rax*4+2], mm2
-        movd        [rsi+rax*2+2], mm6
-
-        psrlq       mm6,        32
-        movd        [rsi+rax+2],mm6
-
-        movd        [rsi+2],    mm1
-        psrlq       mm1,        32
-
-        movd        [rdi+2],    mm1
-        neg         rax
-
-        movd        [rdi+rax+2],mm5
-        psrlq       mm5,        32
-
-        movd        [rdi+rax*2+2], mm5
-
-    add rsp, 64
-    pop rsp
-    ; begin epilog
-    pop rdi
-    pop rsi
-    RESTORE_GOT
-    UNSHADOW_ARGS
-    pop         rbp
-    ret
+%include "third_party/x86inc/x86inc.asm"
 
 SECTION_RODATA
 align 16
 tfe:
     times 8 db 0xfe
-align 16
 t80:
     times 8 db 0x80
-align 16
 t3:
     times 8 db 0x03
-align 16
 t4:
     times 8 db 0x04
-align 16
 ones:
     times 4 dw 0x0001
+
+SECTION .text
+
+%define stkreg rsp
+
+%define t0                  0
+%define t1            t0 + 16
+%define p1            t1 + 16
+%define p0            p1 + 16
+%define q0            p0 + 16
+%define q1            q0 + 16
+%define lstacksize    q1 + 16
+
+%define goffsetq _limitq
+
+;void vpx_lpf_horizontal_4_mmx(unsigned char *src_ptr, int  src_pixel_step,
+;                              const char *blimit, const char *limit,
+;                              const char *thresh);
+INIT_MMX mmx
+cglobal lpf_horizontal_4, 5, 6, 8, 0 - lstacksize, \
+                                s, p, _blimit, _limit, _thresh, s1
+    movq                  m7, [_limitq]
+    GET_GOT         goffsetq
+    lea                  s1q, [sq + pq]       ; s1q points to row +1
+
+    ; calculate breakout conditions
+    movq                  m2, [s1q + 2 * pq]  ; q3
+    movq                  m1, [ sq + 2 * pq]  ; q2
+    movq                  m6, m1              ; q2
+    psubusb               m1, m2              ; q2-=q3
+    psubusb               m2, m6              ; q3-=q2
+    por                   m1, m2              ; abs(q3-q2)
+    psubusb               m1, m7
+    movq                  m4, [sq + pq]       ; q1
+    movq                  m3, m4              ; q1
+    psubusb               m4, m6              ; q1-=q2
+    psubusb               m6, m3              ; q2-=q1
+    por                   m4, m6              ; abs(q2-q1)
+    psubusb               m4, m7
+    por                   m1, m4
+    movq                  m4, [sq]            ; q0
+    movq                  m0, m4              ; q0
+    psubusb               m4, m3              ; q0-=q1
+    psubusb               m3, m0              ; q1-=q0
+    por                   m4, m3              ; abs(q0-q1)
+    movq       [stkreg + t0], m4              ; save to t0
+    psubusb               m4, m7
+    por                   m1, m4
+    neg                   pq                  ; negate pitch to deal with
+                                              ; above border
+    movq                  m2, [ sq + 4 * pq]  ; p3
+    movq                  m4, [s1q + 4 * pq]  ; p2
+    movq                  m5, m4              ; p2
+    psubusb               m4, m2              ; p2-=p3
+    psubusb               m2, m5              ; p3-=p2
+    por                   m4, m2              ; abs(p3 - p2)
+    psubusb               m4, m7
+    por                   m1, m4
+    movq                  m4, [sq + 2 * pq]   ; p1
+    movq                  m3, m4              ; p1
+    psubusb               m4, m5              ; p1-=p2
+    psubusb               m5, m3              ; p2-=p1
+    por                   m4, m5              ; abs(p2 - p1)
+    psubusb               m4, m7
+    por                   m1, m4
+    movq                  m2, m3              ; p1
+    movq                  m4, [sq + pq]       ; p0
+    movq                  m5, m4              ; p0
+    psubusb               m4, m3              ; p0-=p1
+    psubusb               m3, m5              ; p1-=p0
+    por                   m4, m3              ; abs(p1 - p0)
+    movq       [stkreg + t1], m4              ; save to t1
+    psubusb               m4, m7
+    por                   m1, m4
+    movq                  m3, [s1q]           ; q1
+    movq                  m4, m3              ; q1
+    psubusb               m3, m2              ; q1-=p1
+    psubusb               m2, m4              ; p1-=q1
+    por                   m2, m3              ; abs(p1-q1)
+    pand                  m2, [GLOBAL(tfe)]   ; set lsb of each byte to zero
+    psrlw                 m2, 1               ; abs(p1-q1)/2
+    movq                  m6, m5              ; p0
+    movq                  m3, [sq]            ; q0
+    psubusb               m5, m3              ; p0-=q0
+    psubusb               m3, m6              ; q0-=p0
+    por                   m5, m3              ; abs(p0 - q0)
+    paddusb               m5, m5              ; abs(p0-q0)*2
+    paddusb               m5, m2              ; abs (p0 - q0) * 2 + abs(p1-q1)/2
+    movq                  m7, [_blimitq]            ; blimit
+    psubusb               m5, m7              ; abs (p0 - q0) * 2 +
+                                              ; abs(p1-q1)/2  > blimit
+    por                   m1, m5
+    pxor                  m5, m5
+    pcmpeqb               m1, m5              ; mask m1
+
+    ; calculate high edge variance
+    movq                  m7, [_threshq]
+    movq                  m4, [stkreg + t0]   ; get abs (q1 - q0)
+    psubusb               m4, m7
+    movq                  m3, [stkreg + t1]   ; get abs (p1 - p0)
+    psubusb               m3, m7
+    paddb                 m4, m3              ; abs(q1 - q0) > thresh ||
+                                              ; abs(p1 - p0) > thresh
+    pcmpeqb               m4, m5
+    pcmpeqb               m5, m5
+    movq                  m3, [GLOBAL(t80)]
+    pxor                  m4, m5
+
+    ; start work on filters
+    movq                  m2, [sq + 2 * pq]   ; p1
+    movq                  m7, [s1q]           ; q1
+    pxor                  m2, m3              ; p1 converted to signed values
+    pxor                  m7, m3              ; q1 converted to signed values
+    psubsb                m2, m7              ; p1 - q1
+    pand                  m2, m4              ; high var mask (hvm)(p1 - q1)
+    pxor                  m6, m3              ; p0 converted to signed values
+    pxor                  m0, m3              ; q0 converted to signed values
+    movq                  m3, m0              ; q0
+    psubsb                m0, m6              ; q0 - p0
+    paddsb                m2, m0              ; 1 * (q0 - p0) + hvm(p1 - q1)
+    paddsb                m2, m0              ; 2 * (q0 - p0) + hvm(p1 - q1)
+    paddsb                m2, m0              ; 3 * (q0 - p0) + hvm(p1 - q1)
+    pand                  m1, m2              ; mask filter values we don't
+                                              ; care about
+    movq                  m2, m1
+    paddsb                m1, [GLOBAL(t4)]    ; 3* (q0 - p0) + hvm(p1 - q1) + 4
+    paddsb                m2, [GLOBAL(t3)]    ; 3* (q0 - p0) + hvm(p1 - q1) + 3
+
+    pxor                  m0, m0
+    pxor                  m5, m5
+    punpcklbw             m0, m2
+    punpckhbw             m5, m2
+    psraw                 m0, 11
+    psraw                 m5, 11
+    packsswb              m0, m5
+    movq                  m2, m0              ; (3* (q0 - p0) + hvm(p1 - q1)
+                                              ; + 3) >> 3;
+    pxor                  m0, m0
+    movq                  m5, m1              ; abcdefgh
+    punpcklbw             m0, m1              ; e0f0g0h0
+    psraw                 m0, 11              ; sign extended shift right by 3
+    pxor                  m1, m1
+    punpckhbw             m1, m5              ; a0b0c0d0
+    psraw                 m1, 11              ; sign extended shift right by 3
+    movq                  m5, m0              ; save results
+
+    packsswb              m0, m1              ; (3* (q0 - p0) + hvm(p1 - q1)
+                                              ; + 4) >>3
+    paddsw                m5, [GLOBAL(ones)]
+    paddsw                m1, [GLOBAL(ones)]
+    psraw                 m5, 1
+    psraw                 m1, 1
+    packsswb              m5, m1              ; (3* (q0 - p0) + hvm(p1 - q1)
+                                              ; + 4) >>4
+    movq                  m1, [GLOBAL(t80)]
+    pandn                 m4, m5              ; high edge variance additive
+    paddsb                m6, m2              ; p0+= p0 add
+    pxor                  m6, m1              ; unoffset
+    movq           [sq + pq], m6              ; write back
+    movq                  m6, [sq + 2 * pq]   ; p1
+    pxor                  m6, m1              ; reoffset
+    paddsb                m6, m4              ; p1+= p1 add
+    pxor                  m6, m1              ; unoffset
+    movq       [sq + 2 * pq], m6              ; write back
+    psubsb                m3, m0              ; q0-= q0 add
+    pxor                  m3, m1              ; unoffset
+    movq                [sq], m3              ; write back
+    psubsb                m7, m4              ; q1-= q1 add
+    pxor                  m7, m1              ; unoffset
+    movq               [s1q], m7              ; write back
+    RESTORE_GOT
+    RET
+
+;void vpx_lpf_vertical_4_mmx(unsigned char *src_ptr, int  src_pixel_step,
+;                            const char *blimit, const char *limit,
+;                            const char *thresh);
+INIT_MMX mmx
+cglobal lpf_vertical_4, 5, 6, 8, 0 - lstacksize, \
+                              s, p, _blimit, _limit, _thresh, s1
+    lea                   sq, [sq + pq * 4 - 4]
+    lea                  s1q, [sq + pq]       ; s1q points to row +1
+    ;transpose
+    movq                  m6, [ sq + 2 * pq]  ; 67 66 65 64 63 62 61 60
+    movq                  m7, m6              ; 77 76 75 74 73 72 71 70
+    punpckhbw             m7, [s1q + 2 * pq]  ; 77 67 76 66 75 65 74 64
+    punpcklbw             m6, [s1q + 2 * pq]  ; 73 63 72 62 71 61 70 60
+    movq                  m4, [sq]            ; 47 46 45 44 43 42 41 40
+    movq                  m5, m4              ; 47 46 45 44 43 42 41 40
+    punpckhbw             m5, [sq + pq]       ; 57 47 56 46 55 45 54 44
+    punpcklbw             m4, [sq + pq]       ; 53 43 52 42 51 41 50 40
+    movq                  m3, m5              ; 57 47 56 46 55 45 54 44
+    punpckhwd             m5, m7              ; 77 67 57 47 76 66 56 46
+    punpcklwd             m3, m7              ; 75 65 55 45 74 64 54 44
+    movq                  m2, m4              ; 53 43 52 42 51 41 50 40
+    punpckhwd             m4, m6              ; 73 63 53 43 72 62 52 42
+    punpcklwd             m2, m6              ; 71 61 51 41 70 60 50 40
+    neg                   pq
+    movq                  m6, [ sq + pq * 2]  ; 27 26 25 24 23 22 21 20
+    movq                  m1, m6              ; 27 26 25 24 23 22 21 20
+    punpckhbw             m6, [ sq + pq    ]  ; 37 27 36 36 35 25 34 24
+    punpcklbw             m1, [ sq + pq    ]  ; 33 23 32 22 31 21 30 20
+    movq                  m7, [ sq + pq * 4]; ; 07 06 05 04 03 02 01 00
+    punpckhbw             m7, [s1q + pq * 4]  ; 17 07 16 06 15 05 14 04
+    movq                  m0, m7              ; 17 07 16 06 15 05 14 04
+    punpckhwd             m7, m6              ; 37 27 17 07 36 26 16 06
+    punpcklwd             m0, m6              ; 35 25 15 05 34 24 14 04
+    movq                  m6, m7              ; 37 27 17 07 36 26 16 06
+    punpckhdq             m7, m5              ; 77 67 57 47 37 27 17 07  = q3
+    punpckldq             m6, m5              ; 76 66 56 46 36 26 16 06  = q2
+    movq                  m5, m6              ; 76 66 56 46 36 26 16 06
+    psubusb               m5, m7              ; q2-q3
+    psubusb               m7, m6              ; q3-q2
+    por                   m7, m5;             ; m7=abs (q3-q2)
+    movq                  m5, m0              ; 35 25 15 05 34 24 14 04
+    punpckhdq             m5, m3              ; 75 65 55 45 35 25 15 05 = q1
+    punpckldq             m0, m3              ; 74 64 54 44 34 24 15 04 = q0
+    movq                  m3, m5              ; 75 65 55 45 35 25 15 05 = q1
+    psubusb               m3, m6              ; q1-q2
+    psubusb               m6, m5              ; q2-q1
+    por                   m6, m3              ; m6=abs(q2-q1)
+
+    movq       [stkreg + q1], m5              ; save q1
+    movq       [stkreg + q0], m0              ; save q0
+
+    movq                  m3, [ sq + pq * 4]  ; 07 06 05 04 03 02 01 00
+    punpcklbw             m3, [s1q + pq * 4]  ; 13 03 12 02 11 01 10 00
+    movq                  m0, m3              ; 13 03 12 02 11 01 10 00
+    punpcklwd             m0, m1              ; 31 21 11 01 30 20 10 00
+    punpckhwd             m3, m1              ; 33 23 13 03 32 22 12 02
+    movq                  m1, m0              ; 31 21 11 01 30 20 10 00
+    punpckldq             m0, m2              ; 70 60 50 40 30 20 10 00  =p3
+    punpckhdq             m1, m2              ; 71 61 51 41 31 21 11 01  =p2
+    movq                  m2, m1              ; 71 61 51 41 31 21 11 01  =p2
+    psubusb               m2, m0              ; p2-p3
+    psubusb               m0, m1              ; p3-p2
+    por                   m0, m2              ; m0=abs(p3-p2)
+    movq                  m2, m3              ; 33 23 13 03 32 22 12 02
+    punpckldq             m2, m4              ; 72 62 52 42 32 22 12 02 = p1
+    punpckhdq             m3, m4              ; 73 63 53 43 33 23 13 03 = p0
+
+    movq       [stkreg + p0], m3              ; save p0
+    movq       [stkreg + p1], m2              ; save p1
+    movq                  m5, m2              ; m5 = p1
+    psubusb               m2, m1              ; p1-p2
+    psubusb               m1, m5              ; p2-p1
+    por                   m1, m2              ; m1=abs(p2-p1)
+    movq                  m4, [_limitq]
+    GET_GOT         goffsetq
+    psubusb               m7, m4
+    psubusb               m0, m4
+    psubusb               m1, m4
+    psubusb               m6, m4
+    por                   m7, m6
+    por                   m0, m1
+    por                   m0, m7              ; abs(q3-q2) > limit ||
+                                              ; abs(p3-p2) > limit ||
+                                              ; abs(p2-p1) > limit ||
+                                              ; abs(q2-q1) > limit
+    movq                  m1, m5              ; p1
+    movq                  m7, m3              ; m3=m7=p0
+    psubusb               m7, m5              ; p0 - p1
+    psubusb               m5, m3              ; p1 - p0
+    por                   m5, m7              ; abs(p1-p0)
+    movq       [stkreg + t0], m5              ; save abs(p1-p0)
+    psubusb               m5, m4
+    por                   m0, m5              ; m0=mask
+    movq                  m5, [stkreg + q0]   ; m5=q0
+    movq                  m7, [stkreg + q1]   ; m7=q1
+    movq                  m6, m5              ; m6=q0
+    movq                  m2, m7              ; q1
+    psubusb               m5, m7              ; q0-q1
+    psubusb               m7, m6              ; q1-q0
+    por                   m7, m5              ; abs(q1-q0)
+    movq       [stkreg + t1], m7              ; save abs(q1-q0)
+    psubusb               m7, m4
+    por                   m0, m7              ; mask
+    movq                  m5, m2              ; q1
+    psubusb               m5, m1              ; q1-=p1
+    psubusb               m1, m2              ; p1-=q1
+    por                   m5, m1              ; abs(p1-q1)
+    pand                  m5, [GLOBAL(tfe)]   ; set lsb of each byte to zero
+    psrlw                 m5, 1               ; abs(p1-q1)/2
+    movq                  m4, [_blimitq]
+    movq                  m1, m3              ; m1=m3=p0
+    movq                  m7, m6              ; m7=m6=q0
+    psubusb               m1, m7              ; p0-q0
+    psubusb               m7, m3              ; q0-p0
+    por                   m1, m7              ; abs(q0-p0)
+    paddusb               m1, m1              ; abs(q0-p0)*2
+    paddusb               m1, m5              ; abs(p0 - q0)*2 + abs(p1-q1)/2
+    psubusb               m1, m4              ; abs(p0 - q0)*2 + abs(p1-q1)/2
+                                              ; > blimit
+    por                   m1, m0;             ; mask
+    pxor                  m0, m0
+    pcmpeqb               m1, m0
+
+    ; calculate high edge variance
+    movq                  m7, [_threshq]
+    movq                  m4, [stkreg + t0]   ; get abs (q1 - q0)
+    psubusb               m4, m7
+    movq                  m3, [stkreg + t1]   ; get abs (p1 - p0)
+    psubusb               m3, m7
+    por                   m4, m3              ; abs(q1 - q0) > thresh ||
+                                              ; abs(p1 - p0) > thresh
+    pcmpeqb               m4, m0
+    pcmpeqb               m0, m0
+    movq                  m3, [GLOBAL(t80)]
+    pxor                  m4, m0
+
+    ; start work on filters
+    movq                  m2, [stkreg + p1]
+    movq                  m7, [stkreg + q1]
+    movq                  m6, [stkreg + p0]
+    movq                  m0, [stkreg + q0]
+    pxor                  m2, m3
+    pxor                  m7, m3
+    psubsb                m2, m7              ; p1 - q1
+    pand                  m2, m4              ; high var mask (hvm)(p1 - q1)
+    pxor                  m6, m3
+    pxor                  m0, m3
+    movq                  m3, m0              ; q0
+    psubsb                m0, m6              ; q0 - p0
+    paddsb                m2, m0              ; 1 * (q0 - p0) + hvm(p1 - q1)
+    paddsb                m2, m0              ; 2 * (q0 - p0) + hvm(p1 - q1)
+    paddsb                m2, m0              ; 3 * (q0 - p0) + hvm(p1 - q1)
+    pand                  m1, m2              ; mask filter values we don't
+                                              ; care about
+    movq                  m2, m1
+    paddsb                m1, [GLOBAL(t4)]    ; 3*(q0 - p0) + hvm(p1 - q1) + 4
+    paddsb                m2, [GLOBAL(t3)]    ; 3*(q0 - p0) + hvm(p1 - q1) + 3
+    pxor                  m0, m0
+    pxor                  m5, m5
+    punpcklbw             m0, m2
+    punpckhbw             m5, m2
+    psraw                 m0, 11
+    psraw                 m5, 11
+    packsswb              m0, m5
+    movq                  m2, m0              ; (3*(q0 - p0) + hvm(p1 - q1)
+                                              ; + 3) >> 3;
+    pxor                  m0, m0
+    movq                  m5, m1              ; abcdefgh
+    punpcklbw             m0, m1              ; e0f0g0h0
+    psraw                 m0, 11              ; sign extended shift right by 3
+    pxor                  m1, m1
+    punpckhbw             m1, m5              ; a0b0c0d0
+    psraw                 m1, 11              ; sign extended shift right by 3
+    movq                  m5, m0              ; save results
+    packsswb              m0, m1              ; (3*(q0 - p0) + hvm(p1 - q1)
+                                              ; + 4) >>3
+    paddsw                m5, [GLOBAL(ones)]
+    paddsw                m1, [GLOBAL(ones)]
+    psraw                 m5, 1
+    psraw                 m1, 1
+    packsswb              m5, m1              ; (3* (q0 - p0) + hvm(p1 - q1)
+                                              ; + 4) >>4
+    pandn                 m4, m5              ; high edge variance additive
+    movq                  m5, [GLOBAL(t80)]
+    paddsb                m6, m2              ; p0+= p0 add
+    pxor                  m6, m5              ; unoffset
+    ; m6=p0
+    movq                  m1, [stkreg + p1]
+    pxor                  m1, m5              ; reoffset
+    paddsb                m1, m4              ; p1+= p1 add
+    pxor                  m1, m5              ; unoffset
+    ; m6 = p0 m1 = p1
+    psubsb                m3, m0              ; q0-= q0 add
+    pxor                  m3, m5              ; unoffset
+    ; m3 = q0
+    psubsb                m7, m4              ; q1-= q1 add
+    pxor                  m7, m5              ; unoffset
+    ; m7 = q1
+    ; transpose and write back
+    ; m1 =    72 62 52 42 32 22 12 02
+    ; m6 =    73 63 53 43 33 23 13 03
+    ; m3 =    74 64 54 44 34 24 14 04
+    ; m7 =    75 65 55 45 35 25 15 05
+    movq                  m2, m1              ; 72 62 52 42 32 22 12 02
+    punpcklbw             m2, m6              ; 33 32 23 22 13 12 03 02
+    movq                  m4, m3              ; 74 64 54 44 34 24 14 04
+    punpckhbw             m1, m6              ; 73 72 63 62 53 52 43 42
+    punpcklbw             m4, m7              ; 35 34 25 24 15 14 05 04
+    punpckhbw             m3, m7              ; 75 74 65 64 55 54 45 44
+    movq                  m6, m2              ; 33 32 23 22 13 12 03 02
+    punpcklwd             m2, m4              ; 15 14 13 12 05 04 03 02
+    punpckhwd             m6, m4              ; 35 34 33 32 25 24 23 22
+    movq                  m5, m1              ; 73 72 63 62 53 52 43 42
+    punpcklwd             m1, m3              ; 55 54 53 52 45 44 43 42
+    punpckhwd             m5, m3              ; 75 74 73 72 65 64 63 62
+
+    ; m2 = 15 14 13 12 05 04 03 02
+    ; m6 = 35 34 33 32 25 24 23 22
+    ; m5 = 55 54 53 52 45 44 43 42
+    ; m1 = 75 74 73 72 65 64 63 62
+    movd   [sq + pq * 4 + 2], m2
+    psrlq                 m2, 32
+    movd  [s1q + pq * 4 + 2], m2
+    movd   [sq + pq * 2 + 2], m6
+    psrlq                 m6, 32
+    movd       [sq + pq + 2], m6
+    movd            [sq + 2], m1
+    psrlq                 m1, 32
+    movd           [s1q + 2], m1
+    neg                   pq
+    movd      [s1q + pq + 2], m5
+    psrlq                 m5, 32
+    movd  [s1q + pq * 2 + 2], m5
+    RESTORE_GOT
+    RET
diff --git a/vpx_dsp/x86/vpx_subpixel_8t_ssse3.asm b/vpx_dsp/x86/vpx_subpixel_8t_ssse3.asm
index 3fbaa27..b0e99ed 100644
--- a/vpx_dsp/x86/vpx_subpixel_8t_ssse3.asm
+++ b/vpx_dsp/x86/vpx_subpixel_8t_ssse3.asm
@@ -538,11 +538,11 @@
     movx         m1, [srcq + sstrideq     ]     ;B
     movx         m6, [srcq + sstride6q    ]     ;G
     punpcklbw    m0, m1                         ;A B
-    movx         m7, [rax + sstride6q     ]     ;H
+    movx         m7, [src1q + sstride6q   ]     ;H
     pmaddubsw    m0, k0k1
     movx         m2, [srcq + sstrideq * 2 ]     ;C
     punpcklbw    m6, m7                         ;G H
-    movx         m3, [rax + sstrideq * 2  ]     ;D
+    movx         m3, [src1q + sstrideq * 2]     ;D
     pmaddubsw    m6, k6k7
     movx         m4, [srcq + sstrideq * 4 ]     ;E
     punpcklbw    m2, m3                         ;C D
diff --git a/vpxenc.c b/vpxenc.c
index f14470a..f24b180 100644
--- a/vpxenc.c
+++ b/vpxenc.c
@@ -804,7 +804,6 @@
   int                       arg_ctrls[ARG_CTRL_CNT_MAX][2];
   int                       arg_ctrl_cnt;
   int                       write_webm;
-  int                       have_kf_max_dist;
 #if CONFIG_VP9_HIGHBITDEPTH
   // whether to use 16bit internal buffers
   int                       use_16bit_internal;
@@ -1224,7 +1223,6 @@
       config->cfg.kf_min_dist = arg_parse_uint(&arg);
     } else if (arg_match(&arg, &kf_max_dist, argi)) {
       config->cfg.kf_max_dist = arg_parse_uint(&arg);
-      config->have_kf_max_dist = 1;
     } else if (arg_match(&arg, &kf_disabled, argi)) {
       config->cfg.kf_mode = VPX_KF_DISABLED;
 #if CONFIG_VP9_HIGHBITDEPTH
@@ -1352,19 +1350,6 @@
   }
 }
 
-
-static void set_default_kf_interval(struct stream_state *stream,
-                                    struct VpxEncoderConfig *global) {
-  /* Use a max keyframe interval of 5 seconds, if none was
-   * specified on the command line.
-   */
-  if (!stream->config.have_kf_max_dist) {
-    double framerate = (double)global->framerate.num / global->framerate.den;
-    if (framerate > 0.0)
-      stream->config.cfg.kf_max_dist = (unsigned int)(5.0 * framerate);
-  }
-}
-
 static const char* file_type_to_string(enum VideoFileType t) {
   switch (t) {
     case FILE_TYPE_RAW: return "RAW";
@@ -2086,8 +2071,6 @@
                      stream->config.cfg.g_timebase.num = global.framerate.den);
     }
 
-    FOREACH_STREAM(set_default_kf_interval(stream, &global));
-
     /* Show configuration */
     if (global.verbose && pass == 0)
       FOREACH_STREAM(show_stream_config(stream, &global, &input));