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)

Reply via email to