--- /dev/null
+/* PR middle-end/113722 */
+/* { dg-do run { target int128 } } */
+/* { dg-options "-O2" } */
+
+int
+main ()
+{
+ unsigned __int128 a = __builtin_bswap128 ((unsigned __int128) 2);
+ if (a != ((unsigned __int128) 2) << 120)
+ __builtin_abort ();
+ a = __builtin_bswap128 ((unsigned __int128) 0xdeadbeefULL);
+ if (a != ((unsigned __int128) 0xefbeaddeULL) << 96)
+ __builtin_abort ();
+ a = __builtin_bswap128 (((unsigned __int128) 0xdeadbeefULL) << 64);
+ if (a != ((unsigned __int128) 0xefbeaddeULL) << 32)
+ __builtin_abort ();
+ a = __builtin_bswap128 ((((unsigned __int128) 0xdeadbeefULL) << 64)
+ | 0xcafed00dfeedbac1ULL);
+ if (a != ((((unsigned __int128) 0xc1baedfe0dd0fecaULL) << 64)
+ | (((unsigned __int128) 0xefbeaddeULL) << 32)))
+ __builtin_abort ();
+}
}
}
-/* Byte swap the integer represented by XVAL and LEN into VAL. Return
+/* Byte swap the integer represented by XVAL and XLEN into VAL. Return
the number of blocks in VAL. Both XVAL and VAL have PRECISION bits. */
unsigned int
wi::bswap_large (HOST_WIDE_INT *val, const HOST_WIDE_INT *xval,
- unsigned int len, unsigned int precision)
+ unsigned int xlen, unsigned int precision)
{
- unsigned int i, s;
+ unsigned int s, len = BLOCKS_NEEDED (precision);
/* This is not a well defined operation if the precision is not a
multiple of 8. */
gcc_assert ((precision & 0x7) == 0);
- for (i = 0; i < len; i++)
- val[i] = 0;
+ memset (val, 0, sizeof (unsigned HOST_WIDE_INT) * len);
/* Only swap the bytes that are not the padding. */
for (s = 0; s < precision; s += 8)
unsigned int block = s / HOST_BITS_PER_WIDE_INT;
unsigned int offset = s & (HOST_BITS_PER_WIDE_INT - 1);
- byte = (safe_uhwi (xval, len, block) >> offset) & 0xff;
+ byte = (safe_uhwi (xval, xlen, block) >> offset) & 0xff;
block = d / HOST_BITS_PER_WIDE_INT;
offset = d & (HOST_BITS_PER_WIDE_INT - 1);