grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Endianness macros capitalization


From: Christian Franke
Subject: Re: Endianness macros capitalization
Date: Tue, 08 Jul 2008 20:04:34 +0200
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.11) Gecko/20071128 SeaMonkey/1.1.7

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


reply via email to

[Prev in Thread] Current Thread [Next in Thread]