|
|
Subscribe / Log in / New account

Little-endian PowerPC

By Jonathan Corbet
October 6, 2010
The PowerPC architecture is normally thought of as a big-endian domain - the most significant byte of multi-byte values comes first. Big-endian is consistent with a number of other architectures, but the fact that one obscure architecture - x86 - is little-endian means that the world as a whole tends toward the little-endian persuasion. As it happens, at least some PowerPC processors can optionally be run in a little-endian mode. Ian Munsie has posted a patch set which enables Linux to take advantage of that feature and run little-endian on suitably-equipped PowerPC processors.

The first question that came to the mind of a few reviewers was: "why?" PowerPC runs fine as a big-endian architecture, and there has been little clamor for little-endian support. Besides, endianness seems to be one of those things that users can feel strongly about; to at least some PowerPC users, little-endian apparently feels cheap, wrong, and PCish.

The answer, as expressed by Ben Herrenschmidt, appears to be graphics hardware. A number of GPUs, especially those aimed at embedded applications, only work in the little-endian mode. Carefully-written device drivers can work around that sort of limitation without too much trouble, but user-space code - which often ends up talking to graphics hardware - is another story. Fixing all of that code is not a task that anybody wants to take on. As a result, PowerPC processors will not be considered for situations where little-endian support is needed. Running the processor in little-endian mode will nicely overcome that obstacle.

That said, it will take a little while before this support is generally available. The kernel patches apparently look good, but there are toolchain changes required which are not, yet, generally available. Until that little issue is resolved, PowerPC will remain a club for big-endian users only.

Index entries for this article
KernelArchitectures


to post comments

Little-endian PowerPC

Posted Oct 7, 2010 5:22 UTC (Thu) by jengelh (guest, #33263) [Link] (10 responses)

>little-endian apparently feels cheap

Apparently, LE is anything but cheap, since LE archs have to byteswap all the fields in network packets. Costly, costly.

Little-endian PowerPC

Posted Oct 7, 2010 12:57 UTC (Thu) by etienne (guest, #25256) [Link] (7 responses)

> since LE archs have to byteswap all the fields in network packets.

Not all the fields, just the 32 bits fields - while the 16 bits fields have to be rotated by 8 and the bytes have to be left untouched.
What is costly is not the byteswapping, it is all the code to process fields length (each field length and position is only known in the protocol layer where the field is defined, you cannot do a big function messages_swap() at all).
I would like to have the attribute((big-endian)) in gcc, but I guess the market share of big endian processor no more worth the improvement...

Little-endian PowerPC

Posted Oct 7, 2010 13:11 UTC (Thu) by jengelh (guest, #33263) [Link] (6 responses)

>Not all the fields, just the 32 bits fields - while the 16 bits fields have to be rotated by 8

Well, for 32-bit fields you use "BSWAP reg32" instruction, for 16 bit you use "ROR reg16, 8", so for simplicity of the argument, it is equally costly.

But my point was that BE CPUs need not do either of these for most networking protocols.

Little-endian PowerPC

Posted Oct 7, 2010 14:21 UTC (Thu) by etienne (guest, #25256) [Link] (5 responses)

Last time I looked gcc was not able to generate (did not know about) the bswap instruction.
I do not think gcc knows about "load/store word with byte reversed" of PPC neither.
For BE CPU, you still need some assembly instuctions to cast the value 3 in a 16 bits word to the value 3 in a byte, and pass its address... at least in gcc you need an explicit temporary.
It is easy to assume (source of a lot of bugs) that when an constant integer contains the value 15 you can cast the address of that integer to a char or short pointer; to get rid of those bugs it seems people prefer little endian.
But basically your byte endianess is directly depending on the endianess of all the environment, not only the network interface.
The "best" I worked with was a big endian main processor connected to a little endian coprocessor connected to a big endian FPGA: at the time you know that the message in the coprocessor contains a 32 bits value and you should byte-swap it, you should byte-swap it back to write it to the FPGA... Basically do not byte-swap it at all but for display/debug.

Little-endian PowerPC

Posted Oct 7, 2010 14:47 UTC (Thu) by jengelh (guest, #33263) [Link] (1 responses)

>Last time I looked gcc was not able to generate (did not know about) the bswap instruction.

Perhaps you need to update from that ancient gcc version ;-)

int main(int argc, char **argv) { printf("%d\n", htonl(argc)); return 0; } compiled with gcc-4.5 -O3 -static on x86_64 gives me a bswap in objdump. bswap has been there since 80486.

>some assembly instuctions to cast the value 3 in a 16 bits word to the value 3 in a byte,

Well, wouldn't that be just AND r0, 0xFF.

Little-endian PowerPC

Posted Oct 7, 2010 15:38 UTC (Thu) by etienne (guest, #25256) [Link]

> Perhaps you need to update from that ancient gcc version ;-)

Still no GCC-4.5 here and on ia32, if your example no more calls the function "htonl" (which for GCC-4.4.5 is a library function written manually in assembler - I just checked the whole calling sequence by objdump), that is a very welcome improvement!

> Well, wouldn't that be just AND r0, 0xFF.

Unfortunately a register do not have an address to pass to a function, so you need to allocate some temporary space on the stack and copy your register there...

Little-endian PowerPC

Posted Oct 7, 2010 18:55 UTC (Thu) by daniel (guest, #3181) [Link] (2 responses)

<i>Last time I looked gcc was not able to generate (did not know about) the bswap instruction.</i>

I doubt that, however what GCC does need is support for endian variable attributes with appropriate code generation. Last I looked, GCC has no such feature.

Little-endian PowerPC

Posted Oct 8, 2010 14:25 UTC (Fri) by etienne (guest, #25256) [Link] (1 responses)

> I doubt that

GCC do know about the bswap instruction since 4.0 (I just checked the source), but I did not find a way to make GCC use it (i.e. either inline the bswap() or recognise the three shift sequence) on a i386 host...

Little-endian PowerPC

Posted Oct 8, 2010 15:29 UTC (Fri) by jengelh (guest, #33263) [Link]

>but I did not find a way to make GCC use it (i.e. either inline the bswap() or recognise the three shift sequence) on a i386 host...

Works here. Optimizer starts recognizing int s = ((((argc) & 0xff000000) >> 24) | (((argc) & 0x00ff0000) >> 8) | (((argc) & 0x0000ff00) << 8) | (((argc) & 0x000000ff) << 24)); on -O2 and issues a bswap for it.

Alternatively, you could use the same trick as glibc's htonl: int s = __bswap_32(argc). Or even directly __builtin_bswap32 as documented in gcc.info.

Little-endian PowerPC

Posted Oct 7, 2010 23:07 UTC (Thu) by jhhaller (guest, #56103) [Link] (1 responses)

Byte swapping is not a particularly expensive operation. Pulling the data from RAM is the biggest delay in modern CPU, with a minor component related to the extra instructions. Since the instructions tend to get into the cache, the extra instructions don't detract significantly from the speed. Memory access dominates program execution speed for many if not most programs. We got this result while comparing execution speed for software with and without byte-swapping instructions while evaluating how to port some big-endian software to a little-endian processor.

Little-endian PowerPC

Posted Oct 12, 2010 16:11 UTC (Tue) by jzbiciak (guest, #5246) [Link]

I came here to say this. You're tilting at windmills if you're worrying too much about the cycle cost of byte swapping on modern hardware in most situations. About the only place it matters deeply is if you have a huge amount of data in the non-native endian (as would be the case for a frame buffer, hence the motivation of LE PCC).

The real cost most of the time is making sure you've not introduced endian dependencies in your code unwittingly, and have managed them properly where you have introduced them. Correctness is the tricky part.

Little-endian PowerPC

Posted Oct 7, 2010 5:50 UTC (Thu) by ikm (guest, #493) [Link] (4 responses)

> the fact that one obscure architecture - x86 - is little-endian

Not to mention ARM. Those together hold a lion share, such big that endian-correctness in programs isn't too big a deal anymore.

Little-endian PowerPC

Posted Oct 7, 2010 8:55 UTC (Thu) by jond (subscriber, #37669) [Link] (3 responses)

ARM comes in both flavours. The Linksys NSLU2 is big-endian ARM, for example.

Little-endian PowerPC

Posted Oct 7, 2010 16:46 UTC (Thu) by linuxjacques (subscriber, #45768) [Link] (2 responses)

The NSLU2 (like most (all?)) ARMs can run either endian.

I've run my slugs both ways.

Little-endian PowerPC

Posted Oct 7, 2010 16:51 UTC (Thu) by linuxjacques (subscriber, #45768) [Link] (1 responses)

The NSLU2 SoC, an Intel IXP425 defaulted to BE because it's a
"network processor" and network byte order is BE.

There was a slight but measurable network throughput gain when
running in BE vs LE.

Little-endian PowerPC

Posted Oct 8, 2010 1:19 UTC (Fri) by busterb (subscriber, #560) [Link]

Also, the IXP425 has a proprietary firmware that runs on the microengines that drive the networking subsystem. These always run big-endian, so it makes sense to have the whole chip be big endian (the microengines are not byte-swappable like the ARM core is.)

I did a lot of coding for the IXP2855, which is the IXP425's discontinued big brother.

Little-endian PowerPC

Posted Oct 14, 2010 16:58 UTC (Thu) by mrpippy (guest, #57134) [Link]

As I remember, Virtual PC (emulating x86 on PowerPC Macs) used this feature as a core part of the emulation engine. This was a big problem when the PPC 970 (G5) came out without the little-endian mode


Copyright © 2010, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds