Marius Strobl wrote:
On a related note: Is inline assembler really necessary here? For example couldn't in_addword() be written as
static __inline u_short
in_addword(u_short const sum, u_short const b)
{
    u_int const t = sum + b;
    return t + (t >> 16);
} ?
This should at least produce equally good code and because the compiler has more knowledge about it than an assembler block, it potentially leads to better code. I have no SPARC compiler at hand, though.

With GCC 4.2.1 at -O2 the code generated for the above C version
takes on more instruction than the inline assembler so if one

On SPARC?  What code does it produce? I have not SPARC compiler at hand.
Even if it is one more instruction, I think the reduced register pressure makes more than up for it.

wants to go for micro-optimizing one should certainly prefer the
inline assembler version.

As a compiler construction I can tell you, that regarding optimisation there is no such thing as "certainty". The worst part about inline assembler is, that the compiler knows nothing about the instructions in there and has to copy them verbatim. For example it can not do any clever things with the two shifts at the beginning of the inline assembler block of in_addword().

In fact the in/out specification for this asm block looks rather bad:
"=&r" (__ret), "=&r" (__tmp) : "r" (sum), "r" (b) : "cc");
The "&"-modifiers (do not use the same registers as for any input operand value) force the compiler to use 4 (!) register in total for this asm block. It could be done with 2 registers if a proper in/out specification was used. At the very least the in/out specification can be improved, but I suspect using plain C is the better choice.


The "&"-modifiers are necessary as the inline assembler in
question consumes output operands before all input operands
are consumed. Omitting them caused GCC to generate broken
code in the past.

This should work fine and only use two registers (though the compiler can choose to use three, if it deems it beneficial):

static __inline u_short
in_addword(u_short const sum, u_short const b)
{
  u_long const sum16 = sum << 16;
  u_long const b16   = b   << 16;
  u_long       ret;

  __asm(
    "addcc %1, %2, %0\n\t"
    "srl   %0, 16, %0\n\t"
    "addc  %0,  0, %0\n"
    : "=r" (ret) : "r" (sum16), "r" (b16) : "cc");

  return (ret);
}

But I still prefer the C version.


Regards
        Christoph
_______________________________________________
cvs-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/cvs-all
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to