On Tue, Oct 16, 2007 at 12:53:13AM +0200, Andi Kleen wrote:
> > Actually no.  In 32-bit mode, double is aligned on a 4 byte boundary, not 
> > an 8
> > byte boundary, unless you use -malign-double, which breaks the ABI.  This 
> > has
> > been a 'feature' of the original AT&T 386 System V ABI that Linux uses for
> > 32-bit x86 processors.  With the SCO mess, it may be hard to ever change 
> > that
> > ABI....
> 
> My gcc doesn't agree with you (I actually checked before posting)
> 
> ~> cat t.c
> 
> int main(void)
> {
>         double x;
>         printf("%d\n", __alignof__(x));
>         return 0;
> }
> ~> gcc -m32 -o t t.c
> t.c: In function ‘main’:
> t.c:5: warning: incompatible implicit declaration of built-in function 
> ‘printf’
> ~> ./t
> 8
> ~> 
> 

Doubles that are scalar variables are aligned on a 64-bit boundary, but doubles
that are within structures are only aligned to a 32-bit boundary, which comes
from the published i386 ABI from System V.  Here is the code in question from
gcc/config/i386/i386.h:

        /* The published ABIs say that doubles should be aligned on word
           boundaries, so lower the alignment for structure fields unless
           -malign-double is set.  */

        /* ??? Blah -- this macro is used directly by libobjc.  Since it
           supports no vector modes, cut out the complexity and fall back
           on BIGGEST_FIELD_ALIGNMENT.  */
        #ifdef IN_TARGET_LIBS
        #ifdef __x86_64__
        #define BIGGEST_FIELD_ALIGNMENT 128
        #else
        #define BIGGEST_FIELD_ALIGNMENT 32
        #endif
        #else
        #define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
           x86_field_alignment (FIELD, COMPUTED)
        #endif

And this is where we recompute the alignment in i386.c:

        int
        x86_field_alignment (tree field, int computed)
        {
          enum machine_mode mode;
          tree type = TREE_TYPE (field);

          if (TARGET_64BIT || TARGET_ALIGN_DOUBLE)
            return computed;
          mode = TYPE_MODE (TREE_CODE (type) == ARRAY_TYPE
                            ? get_inner_array_type (type) : type);
          if (mode == DFmode || mode == DCmode
              || GET_MODE_CLASS (mode) == MODE_INT
              || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT)
            return MIN (32, computed);
          return computed;
        }


-- 
Michael Meissner, AMD
90 Central Street, MS 83-29, Boxborough, MA, 01719, USA
[EMAIL PROTECTED]


Reply via email to