]> git.sesse.net Git - x264/commitdiff
x86: 32-byte align the stack if possible
authorFiona Glaser <fiona@x264.com>
Fri, 3 May 2013 00:10:26 +0000 (17:10 -0700)
committerFiona Glaser <fiona@x264.com>
Mon, 20 May 2013 19:25:18 +0000 (12:25 -0700)
Avoids the need for manual 32 byte array alignment on compilers that support
-mpreferred-stack-boundary.

common/cpu.h
common/osdep.h
common/x86/cpu-a.asm
configure

index 7f76e435b050e6b357b1fda0acb569f1f6ee4869..27d133977ae5dcc776f5668809260aaf8403cbc7 100644 (file)
@@ -48,15 +48,17 @@ void     x264_cpu_sfence( void );
 void     x264_cpu_mask_misalign_sse( void );
 void     x264_safe_intel_cpu_indicator_init( void );
 
-/* kluge:
+/* kludge:
  * gcc can't give variables any greater alignment than the stack frame has.
- * We need 16 byte alignment for SSE2, so here we make sure that the stack is
- * aligned to 16 bytes.
+ * We need 32 byte alignment for AVX2, so here we make sure that the stack is
+ * aligned to 32 bytes.
  * gcc 4.2 introduced __attribute__((force_align_arg_pointer)) to fix this
  * problem, but I don't want to require such a new version.
- * This applies only to x86_32, since other architectures that need alignment
- * either have ABIs that ensure aligned stack, or don't support it at all. */
-#if ARCH_X86 && HAVE_MMX
+ * aligning to 32 bytes only works if the compiler supports keeping that
+ * alignment between functions (osdep.h handles manual alignment of arrays
+ * if it doesn't).
+ */
+#if (ARCH_X86 || HAVE_32B_STACK_ALIGNMENT) && HAVE_MMX
 int x264_stack_align( void (*func)(), ... );
 #define x264_stack_align(func,...) x264_stack_align((void (*)())func, __VA_ARGS__)
 #else
index e4b22f0cf2908d197fd045bc38670f4a231a5186..cdc0f61be640c6b02dfc1f04d387d344cc698366 100644 (file)
 
 #define EXPAND(x) x
 
+#if HAVE_32B_STACK_ALIGNMENT
+#define ALIGNED_ARRAY_32( type, name, sub1, ... )\
+    ALIGNED_32( type name sub1 __VA_ARGS__ )
+#else
 #define ALIGNED_ARRAY_32( ... ) EXPAND( ALIGNED_ARRAY_EMU( 31, __VA_ARGS__ ) )
+#endif
+
 #define ALIGNED_ARRAY_64( ... ) EXPAND( ALIGNED_ARRAY_EMU( 63, __VA_ARGS__ ) )
 
 /* For AVX2 */
index ea27158b4b71866afbf5fba9c586f23ad852f439..d059a9aae251fc698d81eceb427cd5c50dafc78c 100644 (file)
@@ -66,7 +66,27 @@ cglobal cpu_xgetbv, 3,7
     mov [r4], edx
     RET
 
-%if ARCH_X86_64 == 0
+%if ARCH_X86_64
+
+;-----------------------------------------------------------------------------
+; void stack_align( void (*func)(void*), void *arg );
+;-----------------------------------------------------------------------------
+cglobal stack_align
+    push rbp
+    mov  rbp, rsp
+%if WIN64
+    sub  rsp, 32 ; shadow space
+%endif
+    and  rsp, ~31
+    mov  rax, r0
+    mov   r0, r1
+    mov   r1, r2
+    mov   r2, r3
+    call rax
+    leave
+    ret
+
+%else
 
 ;-----------------------------------------------------------------------------
 ; int cpu_cpuid_test( void )
@@ -94,14 +114,11 @@ cglobal cpu_cpuid_test
     popfd
     ret
 
-;-----------------------------------------------------------------------------
-; void stack_align( void (*func)(void*), void *arg );
-;-----------------------------------------------------------------------------
 cglobal stack_align
     push ebp
     mov  ebp, esp
     sub  esp, 12
-    and  esp, ~15
+    and  esp, ~31
     mov  ecx, [ebp+8]
     mov  edx, [ebp+12]
     mov  [esp], edx
@@ -168,7 +185,7 @@ cglobal safe_intel_cpu_indicator_init
 %if WIN64
     sub  rsp, 32 ; shadow space
 %endif
-    and  rsp, ~15
+    and  rsp, ~31
     call intel_cpu_indicator_init
     leave
 %if ARCH_X86_64
index 7fea42154e905d4157109ae52c7695a14bbefc5d..3d14850909956cc16edebaabf206eeef41344b41 100755 (executable)
--- a/configure
+++ b/configure
@@ -717,6 +717,10 @@ if [ $asm = auto -a \( $ARCH = X86 -o $ARCH = X86_64 \) ] ; then
         exit 1
     fi
     define HAVE_MMX
+    if cc_check '' -mpreferred-stack-boundary=5 ; then
+        CFLAGS="$CFLAGS -mpreferred-stack-boundary=5"
+        define HAVE_32B_STACK_ALIGNMENT
+    fi
 fi
 
 if [ $asm = auto -a $ARCH = ARM ] ; then