Hi Juha,
I also get 0x49f00 with the code generated by gcc. But in my opinion, the compiler does what you asked. The instructions you wrote are right but there is a problem with the use of inline asm (that is error-prone) and how parameters are declared.
At each line, you ask to apply an operation on "ret" with "val" as input but ... nothing says that "ret" is the previously modified "ret" to be reused!
By chance with MW, it does not use an additional register, so luckily reuses the same destination register on the third instruction.
For me, that works with the following code, that says "ret" is modified (what prevents it to be trashed):
static unsigned int u32SwapEndianness(register unsigned int val)
{
register unsigned int ret = 0;
asm volatile("rlwinm %0, %1, 24, 0, 31" : "=r"(ret) : "r"(val));
asm volatile("rlwimi %0, %1, 8, 8, 15" : "+r"(ret) : "r"(val));
asm volatile("rlwimi %0, %1, 8, 24, 31" : "+r"(ret) : "r"(val));
return ret;
}
But the generated code is not very good and that is not good either to write independent asm lines like that. So to be cleaner (even if, again, it is difficult with inline asm code), the code should be written in a single block:
static unsigned int u32SwapEndianness(register unsigned int val)
{
register unsigned int ret = 0;
asm volatile("rlwinm %0, %1, 24, 0, 31 \n\t"
"rlwimi %0, %1, 8, 8, 15 \n\t"
"rlwimi %0, %1, 8, 24, 31 \n\t" : "+r"(ret) : "r"(val));
return ret;
}
That gives something like that:
mr r10,r3
li r31,0
mr r9,r31
rotrwi r9,r10,24
rlwimi r9,r10,8,8,15
inslwi r9,r10,8,24
mr r31,r9
mr r9,r31
mr r3,r9
And these days (and with this CPU architecture), I think using the keyword is quite useless. And here, it is even worst because it forces to use registers and adds an overhead. Removing these keywords, the code looks like:
li r9,0
rotrwi r9,r10,24
rlwimi r9,r10,8,8,15
inslwi r9,r10,8,24
mr r3,r9
Mathias