www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1998/01/13/12:24:58

Message-ID: <19980112231700.01629@cerebro.laendle>
Date: Mon, 12 Jan 1998 23:17:00 +0100
From: Marc Lehmann <pcg AT goof DOT com>
To: djgpp-workers AT delorie DOT com
Cc: Andrew Crabtree <andrewc AT rosemail DOT rose DOT hp DOT com>
Subject: stack alignment options
Mime-Version: 1.0

I was asked to sent an explanation of the options pgcc (and egcs sometime
in the future) uses to ensure an 8 byte alignment of doubles, how it is
achieved and what breaks.

pgcc has three switches:

-malign-double		this is old, even gcc-2.7.2 has it
-mstack-align-double	this aligns the stack to an 8 byte boundary
-marg-align-double	this aligns function arguments to an 8 byte boundary


-malign-double is used to align doubles in structs to an 8 byte boundary, i.e.
struct		offset with	/without switch
int i		0		0
double j	4		8
int k		12		16

this (obiously) breaks the published sysv x86 ABI, since code compiled with
and without this option is incompatible when doubles in struct's are used
without proper alignment.


-mstack-align-double assumes that the stack is suitably aligned
i.e. on an 8 byte boundary before the function call, and will
ensure that spill/frame slots containing doubles will be correctly
aligned (i.e. auto variables).

This does NOT break the ABI, since auto variables are function-private, the
call protocol is not being changed. This means that arguments to function
might still be misaligned (and are copied into aligned stack slots upon
function entry).

gcc assumes that the stack is aligned AT the function call, i.e. BEFORE the
call instruction is executed, or AFTER the function prologue has executed,
NOT upon function entry, since gcc generally doesn't know about prologue
code:

code		%esp (hex) _before_ insn.
movl $1,%eax	1f00c
pushl %eax      1f00c
call fun	1f008

fun:		1f004
pushl %ebx	1f004
nop		1f000
...

the stack itself must already be aligned by the startup code upon entry to
main(). linux uses a code equivalent to this (taken from glibc2.0.6):

	/* Before pushing the arguments align the stack to a double word
	   boundary to avoid penalties from misaligned accesses.  Thanks
	   to Edward Seidl <seidl AT janed DOT com> for pointing this out.  */
	andl $0xfffffff8, %esp
	pushl %eax		/* Push garbage because we allocate
				   twelve more bytes.  */

	pushl %eax		/* Push third argument: envp.  */
	pushl %edx		/* Push second argument: argv.  */
	pushl %esi		/* Push first argument: argc.  */

	/* Call the user's main function, and exit with its value.  */
	call main
	pushl %eax
	call exit
	hlt			/* Crash if somehow `exit' does return.  */


to be effective, all code execution passes thru must be compiled with
-mstack-align-double, to the minimum all code that's executed before entry
to main(), i.e. the startup code. -mstack-align-double also imposes a small
integer penalty because the alignment has to be enforced with additional
push insns. also, function like qsort() possibly destroys the alignment
(although these libc functions are rare).

it's IMHO best only to align the actual call to main and not compile anything
with this switch (even more since this switch isn't available in every
gcc version).


-marg-align-double will align doubles in argument slots (parameters
to function calls) to an 8 byte boundary. This DOES break the ABI and makes
the same assumptions about alignment as -mstack-align-double.

Due to a bug in gcc, this currently only works with -mamdk6 (the amd
doesn't use pushes) anyway.


I hope this clarifies the issue a bit... If I forgot sth. or was unclear,
don't hesitate to ask me!

      -----==-                                              |
      ----==-- _                                            |
      ---==---(_)__  __ ____  __       Marc Lehmann       +--
      --==---/ / _ \/ // /\ \/ /       pcg AT goof DOT com       |e|
      -=====/_/_//_/\_,_/ /_/\_\                          --+
    The choice of a GNU generation                        |
                                                          |

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019