Fix crash when using libx264.dll compiled with ICL for X86_64
authorAnton Mitrofanov <BugMaster@narod.ru>
Sat, 10 Nov 2012 23:44:02 +0000 (03:44 +0400)
committerFiona Glaser <fiona@x264.com>
Mon, 12 Nov 2012 19:07:13 +0000 (11:07 -0800)
common/cpu.h
common/osdep.c
common/x86/cpu-a.asm

index c92f93e..ed1a8bc 100644 (file)
@@ -46,6 +46,7 @@ void     x264_cpu_sfence( void );
 #endif
 #define x264_sfence x264_cpu_sfence
 void     x264_cpu_mask_misalign_sse( void );
+void     x264_safe_intel_cpu_indicator_init( void );
 
 /* kluge:
  * gcc can't give variables any greater alignment than the stack frame has.
index 0a97bc7..97911d0 100644 (file)
@@ -90,6 +90,7 @@ int x264_threading_init( void )
 }
 #endif
 
+#if HAVE_MMX
 #ifdef __INTEL_COMPILER
 /* Agner's patch to Intel's CPU dispatcher from pages 131-132 of
  * http://agner.org/optimize/optimizing_cpp.pdf (2011-01-30)
@@ -98,7 +99,7 @@ int x264_threading_init( void )
 // Global variable indicating cpu
 int __intel_cpu_indicator = 0;
 // CPU dispatcher function
-void __intel_cpu_indicator_init( void )
+void x264_intel_cpu_indicator_init( void )
 {
     unsigned int cpu = x264_cpu_detect();
     if( cpu&X264_CPU_AVX )
@@ -120,4 +121,16 @@ void __intel_cpu_indicator_init( void )
     else
         __intel_cpu_indicator = 1;
 }
+
+/* __intel_cpu_indicator_init appears to have a non-standard calling convention that
+ * assumes certain registers aren't preserved, so we'll route it through a function
+ * that backs up all the registers. */
+void __intel_cpu_indicator_init( void )
+{
+    x264_safe_intel_cpu_indicator_init();
+}
+#else
+void x264_intel_cpu_indicator_init( void )
+{}
+#endif
 #endif
index fcc4e51..9babccb 100644 (file)
@@ -139,3 +139,50 @@ cglobal cpu_mask_misalign_sse
     ldmxcsr [rsp]
     add   rsp, 4
     ret
+
+cextern intel_cpu_indicator_init
+
+;-----------------------------------------------------------------------------
+; void safe_intel_cpu_indicator_init( void );
+;-----------------------------------------------------------------------------
+cglobal safe_intel_cpu_indicator_init
+    push r0
+    push r1
+    push r2
+    push r3
+    push r4
+    push r5
+    push r6
+%if ARCH_X86_64
+    push r7
+    push r8
+    push r9
+    push r10
+    push r11
+    push r12
+    push r13
+    push r14
+%endif
+    push rbp
+    mov  rbp, rsp
+    and  rsp, ~15
+    call intel_cpu_indicator_init
+    leave
+%if ARCH_X86_64
+    pop r14
+    pop r13
+    pop r12
+    pop r11
+    pop r10
+    pop r9
+    pop r8
+    pop r7
+%endif
+    pop r6
+    pop r5
+    pop r4
+    pop r3
+    pop r2
+    pop r1
+    pop r0
+    ret