Christian Franke wrote:
Assembly code for grub_swap_bytes16 from Debian gcc 4.1.2-7:
Macro or Inline: 4 bytes (minus possible additional benefit from
register level optimizations)
66 c1 c0 08 rol $0x8,%ax
Function call: 11 bytes
0f b7 c0 movzwl %ax,%eax
e8 xx xx xx xx call grub_swap_bytes16
0f b7 c0 movzwl %ax,%eax
The break even is possibly at grub_swap_bytes64() :-)
I take that back. For i386, even grub_swap_bytes32() should possibly be
a function.
The attached script compares the sizes of 8 inline expansions of
grub_swap_bytesNN() vs. function calls.
Sample output (Debian gcc 4.1.2-7):
/* 16 bit: inline=88, function=128 */
/* 32 bit: inline=357, function=104 */
#define GRUB_DONT_INLINE_GRUB_SWAP_BYTES32 1
/* 64 bit: inline=2621, function=167 */
#define GRUB_DONT_INLINE_GRUB_SWAP_BYTES64 1
With old gcc versions without the "rol" optimization, even the 16 bit
swap should be a function:
(Cygwin gcc 3.4.4):
/* 16 bit: inline=148, function=116 */
#define GRUB_DONT_INLINE_GRUB_SWAP_BYTES16 1
/* 32 bit: inline=340, function=96 */
#define GRUB_DONT_INLINE_GRUB_SWAP_BYTES32 1
/* 64 bit: inline=2876, function=164 */
#define GRUB_DONT_INLINE_GRUB_SWAP_BYTES64 1
Interestingly, the 64bit inline result is much smaller if
'-fomit-frame-pointer' is added:
(Cygwin gcc 3.4.4):
/* 16 bit: inline=144, function=112 */
#define GRUB_DONT_INLINE_GRUB_SWAP_BYTES16 1
/* 32 bit: inline=336, function=92 */
#define GRUB_DONT_INLINE_GRUB_SWAP_BYTES32 1
/* 64 bit: inline=1372, function=160 */
#define GRUB_DONT_INLINE_GRUB_SWAP_BYTES64 1
Christian
#!/bin/sh
set -e
srcdir=..
cat <<EOF > test.c
#include <grub/types.h>
#ifdef extf
type extf(type);
#define func extf
#else
#define func inlf
#endif
extern type x1,x2,x3,x4;
type test(type x, type *p)
{
x4 = func(func(x1) + func(x2) + func(x3));
*p = func(func(*p) * 13);
return func(func(x) + 42);
}
EOF
CC="gcc -c -I. -Iinclude -I${srcdir}/include -Os -falign-jumps=1
-falign-loops=1 -falign-functions=1 -mregparm=3 -mrtd $*"
for bits in 16 32 64; do
${CC} -Dtype=grub_uint${bits}_t -Dinlf=grub_swap_bytes${bits} -o
test${bits}i.o test.c
si=$(size test${bits}i.o | sed -n '2s,^ *\([0-9]*\).*$,\1,p')
${CC} -Dtype=grub_uint${bits}_t -Dextf=grub_swap_bytes${bits}_f -o
test${bits}f.o test.c
sf=$(size test${bits}f.o | sed -n '2s,^ *\([0-9]*\).*$,\1,p')
echo "/* ${bits} bit: inline=$si, function=$sf */"
[ $si -gt $sf ] && echo "#define GRUB_DONT_INLINE_GRUB_SWAP_BYTES${bits} 1"
#rm -f test${bits}{i,f}.o
done
rm -f test.c
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel