https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63259
--- Comment #18 from Oleg Endo <olegendo at gcc dot gnu.org> ---
(In reply to Oleg Endo from comment #17)
> (In reply to thopre01 from comment #16)
> >
> > Did we? All I can find is you and Andreas mentionning that it should work
> > because it will be sign extended to int when doing the bitwise AND with
> > 0xFF00.
> >
> > What did I miss?
>
> Ah sorry ... me bad. I haven't tried increasing the 'level' with the
> bswaphi expander pattern in place. Will do that later.
So I did. Increasing the limit to
limit += 2 + (int) ceil_log2 ...
works for me for the signed short case.
However, the following function from the CSiBE set:
void
_nrrdSwap32Endian(void *_data, size_t N) {
int *data, w, fix;
size_t I;
if (_data) {
data = (int *)_data;
for (I=0; I<N; I++) {
w = data[I];
fix = (w & 0x000000FF);
fix = ((w & 0x0000FF00) >> 0x08) | (fix << 0x08);
fix = ((w & 0x00FF0000) >> 0x10) | (fix << 0x08);
fix = ((w & 0xFF000000) >> 0x18) | (fix << 0x08);
data[I] = fix;
}
}
}
seems to require 'limit += 3 + (int) ...' for the bswap insn to be detected.
Then, this fine function (from the same set)
void
_nrrdSwap64Endian(void *_data, size_t N) {
airLLong *data, l, fix;
size_t I;
if (_data) {
data = (airLLong *)_data;
for (I=0; I<N; I++) {
l = data[I];
fix = (l & 0x00000000000000FF);
fix = ((l & 0x000000000000FF00) >> 0x08) | (fix << 0x08);
fix = ((l & 0x0000000000FF0000) >> 0x10) | (fix << 0x08);
fix = ((l & 0x00000000FF000000) >> 0x18) | (fix << 0x08);
#if defined(_WIN32)
fix = ((l & 0x000000FF00000000i64) >> 0x20) | (fix << 0x08);
fix = ((l & 0x0000FF0000000000i64) >> 0x28) | (fix << 0x08);
fix = ((l & 0x00FF000000000000i64) >> 0x30) | (fix << 0x08);
fix = ((l & 0xFF00000000000000i64) >> 0x38) | (fix << 0x08);
#else
fix = ((l & 0x000000FF00000000LL) >> 0x20) | (fix << 0x08);
fix = ((l & 0x0000FF0000000000LL) >> 0x28) | (fix << 0x08);
fix = ((l & 0x00FF000000000000LL) >> 0x30) | (fix << 0x08);
fix = ((l & 0xFF00000000000000LL) >> 0x38) | (fix << 0x08);
#endif
data[I] = fix;
}
}
}
requires 'limit += 6 + (int) ...'
(luckily, there's no _nrrdSwap128Endian in the set)