From: Loren Merritt Date: Fri, 6 Apr 2007 21:17:34 +0000 (+0000) Subject: workaround gcc's inability to align variables on the stack. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3e7b136c8525f73f6e01be260adbfc15c34503d7;p=libx264 workaround gcc's inability to align variables on the stack. this crash was introduced in r642, but only because previous versions didn't use sse2 on the stack. git-svn-id: svn://svn.videolan.org/x264/trunk@646 df754926-b1dd-0310-bc7b-ec298dee348c --- diff --git a/common/cpu.h b/common/cpu.h index 94101e52..586f5319 100644 --- a/common/cpu.h +++ b/common/cpu.h @@ -30,4 +30,18 @@ int x264_cpu_num_processors( void ); /* probably MMX(EXT) centric but .... */ void x264_cpu_restore( uint32_t cpu ); +/* kluge: + * 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. + * 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 + * also have ABIs that ensure aligned stack. */ +#ifdef ARCH_X86 +void x264_stack_align( void (*func)(x264_t*), x264_t *arg ); +#else +#define x264_stack_align(func,arg) func(arg) +#endif + #endif diff --git a/common/i386/cpu-a.asm b/common/i386/cpu-a.asm index 2b7b56f8..235acd4a 100644 --- a/common/i386/cpu-a.asm +++ b/common/i386/cpu-a.asm @@ -101,3 +101,19 @@ cglobal x264_emms emms ret +;----------------------------------------------------------------------------- +; void x264_stack_align( void (*func)(void*), void *arg ); +;----------------------------------------------------------------------------- +cglobal x264_stack_align + push ebp + mov ebp, esp + sub esp, 4 + and esp, ~15 + mov ecx, [ebp+8] + mov edx, [ebp+12] + mov [esp], edx + call ecx + mov esp, ebp + pop ebp + ret + diff --git a/encoder/encoder.c b/encoder/encoder.c index d76994cd..ddf843ab 100644 --- a/encoder/encoder.c +++ b/encoder/encoder.c @@ -1023,7 +1023,7 @@ static inline void x264_slice_init( x264_t *h, int i_nal_type, int i_global_qp ) x264_macroblock_slice_init( h ); } -static int x264_slice_write( x264_t *h ) +static void x264_slice_write( x264_t *h ) { int i_skip; int mb_xy; @@ -1183,8 +1183,6 @@ static int x264_slice_write( x264_t *h ) - h->stat.frame.i_itex_bits - h->stat.frame.i_ptex_bits - h->stat.frame.i_hdr_bits; - - return 0; } static void x264_thread_sync_context( x264_t *dst, x264_t *src ) @@ -1223,7 +1221,7 @@ static int x264_slices_write( x264_t *h ) x264_visualize_init( h ); #endif - x264_slice_write( h ); + x264_stack_align( x264_slice_write, h ); i_frame_size = h->out.nal[h->out.i_nal-1].i_payload; x264_fdec_filter_row( h, h->sps->i_mb_height );