cvs commit: src/sys/sparc64/include in_cksum.h

Christoph Mallon christoph.mallon at gmx.de
Sat Jun 28 12:08:13 UTC 2008


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


More information about the cvs-src mailing list