This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Byte swapping support

On Tue, Sep 12, 2017 at 05:26:29PM +0200, David Brown wrote:
> On 12/09/17 16:15, wrote:
> > 
> >> On Sep 12, 2017, at 5:32 AM, Jürg Billeter <> wrote:
> >>
> >> Hi,
> >>
> >> To support applications that assume big-endian memory layout on little-
> >> endian systems, I'm considering adding support for reversing the
> >> storage order to GCC. In contrast to the existing scalar storage order
> >> support for structs, the goal is to reverse the storage order for all
> >> memory operations to achieve maximum compatibility with the behavior on
> >> big-endian systems, as far as observable by the application.
> > 
> > I've done this in the past by C++ type magic. As a general setting
> > it doesn't make sense that I can see. As an attribute applied to a
> > particular data item, it does. But I'm not sure why you'd put this in
> > the compiler when programmers can do it easily enough by defining a "big
> > endian int32" class, etc.
> > 
> Some people use the compiler for C rather than C++ ...
> If someone wants to improve on the endianness support in gcc, I can
> think of a few ideas that /I/ think might be useful.  I have no idea how
> difficult they might be to put in practice, and can't say if they would
> be of interest to others.
> First, I would like to see endianness given as a named address space,
> rather than as a type attribute.  A key point here is that named address
> spaces are effectively qualifiers, like "const" and "volatile" - and you
> can then use them in pointers:

When I gave the talk at the 2009 GCC summit on the named address support, I
thought that it could be used to add endianess support.  In fact at one time, I
had a trial PowerPC compiler that added endianess support.  Unfortunately, that
was in 2009, and I lost the directory of the work.  I tried again a few years
ago, but I didn't get far enough into it to get a working compiler before being
pulled back into work.

Back when I worked at Cygnus Solutions, we used to get requests to add endian
support every so often, but nobody wanted to pay the cost that we were then
quoting to add the support.  Now that named address support is in, it could be
done better.

I suspect however, you want to do this at the higher tree level, adding in the
endianess bits in a separate area than the named address support.  Or perhaps,
growing the named address support, and adding several standard named addresses.

The paper where I talked about the named address support was from the 2009 GCC
summit.  You can download the proceedings of the 2009 summit from here (my
paper is pages 67-74):

> big_endian uint32_t be_buffer[20];
> little_endian uint32_t le_buffer[20];
> void copy_buffers(const big_endian uint32_t * src,
> 			little_endian uint32_t * dest)
> {
> 	for (int i = 0; i < 20; i++) {
> 		dest[i] = src[i];	// Swaps endianness on copy
> 	}
> }
> That would also let you use them for scaler types, not just structs, and
> you could use typedefs:
> 	typedef big_endian uint32_t be_uint32_t;
> Secondly, I would add more endian types.  As well as big_endian and
> little_endian, I would add native_endian and reverse_endian.  These
> could let you write a little clearer definitions sometimes.  And ideally
> I would like mixed endian with big-endian 16-bit ordering and
> little-endian ordering for bigger types (i.e., 0x87654321 would be
> stored 0x43, 0x21, 0x87, 0x65).  That order matches some protocols, such
> as Modbus.

It depends, you can add so many different combinations, that in the end you
don't add the support you want because of th 53 other variants.

Note, if you use it in named addresses, you are currently limited to 15 new
keywords for adding named address support.  This can be grown, but you should
know about the limit ahead of time.  Of course if you add it in a parallel,
machine independent version, then you don't have to worry about the existing

As I write this, another usage for named addresses occurs to me -- and that is
restricting addressing for memory mapped I/O regions that don't allow certain
types of accesses.

> Third, I'd like to be able to attach the attribute to particular
> variables and to scalers, not just struct and union types.
> Forth, I would like type-punning through unions with different ordering
> to be allowed.  I'd like to be able to define:
> union U {
>     __attribute__((scalar_storage_order("big-endian"))) uint16_t
>  		protocol[32];
>     __attribute__((scalar_storage_order("little-endian"))) struct {
> 	uint32_t id;
> 	uint16_t command;
> 	uint16_t param1;
> 	...
>     }
> }

This definately requires support at the higher levels of the compiler.

> and then I could access data in little ordering in the structures, then
> in 16-bit big-endian lumps via the "protocol" array.

One of the things you have to do is be prepared to do a full sweep of your
backend to make sure you only used the named address memory functions and don't
use the traditional functions that pass 0 for the named address.

Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email:, phone: +1 (978) 899-4797

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]