svn commit: r233684 - head/sys/x86/include

Dimitry Andric dim at FreeBSD.org
Fri Mar 30 12:11:13 UTC 2012


On 2012-03-30 10:25, Andrey Chernov wrote:
> On Thu, Mar 29, 2012 at 11:31:48PM +0000, Dimitry Andric wrote:
>>    However, the arguments are not properly masked, which results in the
>>    wrong value being calculated in some instances.  For example,
>>    bswap32(0x12345678) returns 0x7c563412, and bswap64(0x123456789abcdef0)
>>    returns 0xfcdefc9a7c563412.
>
> Is sign extension considered in that place? Shifting any signed value to
> ">>" direction (char, short, int, etc.) replicates sign bit, so cast to
> corresponding unsigned value must be done first, which may take less
> instructions, than masking (I am not sure about this part, just
> guessing). Casting in that case applies to the argument (x) not to result
> (x>>  YY).

Yes, the arguments are all converted to unsigned types where necessary.
The __bswapXX_gen() macros are only used internally by the __bswapXX()
macros and the __bswapXX_var() inline functions.

In case of the __bswapXX() macros, you can see that the argument to
__bswapXX_gen() is first explicitly cast to an unsigned type, for
example with __bswap32():

#define __bswap32(x)                    \
         (__builtin_constant_p(x) ?      \
             __bswap32_gen((__uint32_t)(x)) : __bswap32_var(x))

Therefore, right shifting will not give any problems.  For the call to
__bswap32_var(), such casting is not needed, since the argument will be
implicitly converted to __uint32_t.

As Bruce has mentioned, you could add more explicit casts and additional
parentheses, but those would be superfluous.


More information about the svn-src-all mailing list