BITS_BIG_ENDIAN in llvm-gcc

There are various functions in llvm-convert.cpp that depend on BITS_BIG_ENDIAN:

TreeToLLVM::EmitLoadOfLValue()
TreeToLLVM::EmitMODIFY_EXPR()
InsertBitFieldValue()
ProcessBitFieldInitialization()

The comments say things like:

    // If this target has bitfields laid out in big-endian order, invert the bit
    // in the word if needed.

        // If this is a big-endian bit-field, take the top NumBitsToInsert
        // bits from the bitfield value.

        // If this is little-endian bit-field, take the bottom NumBitsToInsert
        // bits from the bitfield value.

But as I understand it in GCC, BITS_BIG_ENDIAN has nothing to do with
the way bit-fields are laid out. All it affects is how the operands of
the sign_extract and zero_extract RTXs are interpreted. This is what
the GCC internals manual says, and I believe it's true from looking at
the GCC source code.

So can anyone explain why llvm-gcc depends on BITS_BIG_ENDIAN in this way?

Thanks,
Jay.

Hi,

But as I understand it in GCC, BITS_BIG_ENDIAN has nothing to do with
the way bit-fields are laid out. All it affects is how the operands of
the sign_extract and zero_extract RTXs are interpreted. This is what
the GCC internals manual says, and I believe it's true from looking at
the GCC source code.

So can anyone explain why llvm-gcc depends on BITS_BIG_ENDIAN in this way?

according to doc/tm.texi:

@defmac BITS_BIG_ENDIAN
Define this macro to have the value 1 if the most significant bit in a
byte has the lowest number; otherwise define it to have the value zero.
This means that bit-field instructions count from the most significant
bit. If the machine has no bit-field instructions, then this must still
be defined, but it doesn't matter which value it is defined to. This
macro need not be a constant.

This macro does not affect the way structure fields are packed into
bytes or words; that is controlled by @code{BYTES_BIG_ENDIAN}.
@end defmac

In expmed.c you can see code like this:

      /* On big-endian machines, we count bits from the most significant.
         If the bit field insn does not, we must invert. */

      if (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
        xbitpos = unit - bitsize - xbitpos;

This is similar to what is done in llvm-gcc, except that in llvm-convert
the check is on BITS_BIG_ENDIAN directly, not on whether it differs from
BYTES_BIG_ENDIAN. Maybe llvm-gcc is wrong - not clear without analysing
the code.

I think the idea is, that if you talk about bits 0 to 3 in a bit, does
this mean the low 4 bits or the high four bits?

Ciao,

Duncan.

So can anyone explain why llvm-gcc depends on BITS_BIG_ENDIAN in this way?

I've raised bug 2724 on this, with an example of an actual problem that is
caused by this.

Thanks,
Jay.