#define NIPQUAD(addr) \
(int)(((addr) >> 0) & 0xff), \
(int)(((addr) >> 8) & 0xff), \
(int)(((addr) >> 16) & 0xff), \
(int)(((addr) >> 24) & 0xff)
#define NIPQUADok(addr) \
((unsigned char *)&addr)[0], \
((unsigned char *)&addr)[1], \
((unsigned char *)&addr)[2], \
((unsigned char *)&addr)[3]
main()
{
unsigned int theaddr=*(int*)"\x01\x02\x03\x04";
printf("addr=%d.%d.%d.%d\n",NIPQUAD(theaddr));
printf("addr=%d.%d.%d.%d\n",NIPQUADok(theaddr));
}
When run on a big endian machine (PPC) this program prints :
addr=4.3.2.1
addr=1.2.3.4
and on a little endian machine (intel) :
addr=1.2.3.4
addr=1.2.3.4
This shows that NIPQUAD is really broken for big endian, and also when
looking at the assembly level produced (using -O3) on the intel machine :
#
# code generated by the current macro
#
movl %edx,%eax
shrl $24,%eax
pushl %eax
movl %edx,%eax
shrl $16,%eax
andl $255,%eax
pushl %eax
movl %edx,%eax
shrl $8,%eax
andl $255,%eax
pushl %eax
movzbl %dl,%edx
pushl %edx
pushl $.LC1
call printf
#
# code generated by the new macro
#
movzbl -1(%ebp),%eax
pushl %eax
movzbl -2(%ebp),%eax
pushl %eax
movzbl -3(%ebp),%eax
pushl %eax
movzbl -4(%ebp),%eax
pushl %eax
pushl $.LC1
call printf
This shows that the new macro is also better when looking at the generated
code. This is also the case on a PPC machine. The only case where the old
macro was better is when the addr to be printed is a litteral because the
optimizer is able to do the shift calculation on the constant; but this is
not usefull at all because litteral addr are never use in real code.
I hope this will be included in the next kernel sub-release (as I am a new
Linux user/developper, I don't know if I must submit this code in an other
way in order to get it in the mainstream code source).
Regards,
------------------------------------------------
Alain RICHARD <mailto:alain_richard@equation.fr>
EQUATION SA <http://www.equation.fr>
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/