This is the mail archive of the gcc@gcc.gnu.org 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 12/09/17 16:15, Paul.Koning@dell.com wrote:
> 
>> On Sep 12, 2017, at 5:32 AM, Jürg Billeter <juerg.billeter@codethink.co.uk> 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:

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.

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;
	...
    }
}

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


David

	


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