119 lines
2.3 KiB
C
119 lines
2.3 KiB
C
/* { dg-do compile } */
|
|
/* { dg-options "-O3 -march=z10 -mzarch" } */
|
|
|
|
unsigned long
|
|
foo1 (unsigned long a, unsigned long b)
|
|
{
|
|
return (a << 5) | (b & (((1UL << 5) - 1)));
|
|
}
|
|
|
|
/* This generates very different RTX than foo1. The output reg (r2)
|
|
matches the unshifted argument. So it actually is a
|
|
(set (zero_extract a 59 0) b) */
|
|
unsigned long
|
|
foo2 (unsigned long a, unsigned long b)
|
|
{
|
|
return (b << 5) | (a & (((1UL << 5) - 1)));
|
|
}
|
|
|
|
/* risbg cannot be used when less bits are removed with the mask. */
|
|
|
|
unsigned long
|
|
foo1b (unsigned long a, unsigned long b)
|
|
{
|
|
return (a << 5) | (b & 1);
|
|
}
|
|
|
|
unsigned long
|
|
foo2b (unsigned long a, unsigned long b)
|
|
{
|
|
return (b << 5) | (a & 1);
|
|
}
|
|
|
|
/* risbg cannot be used when the masked bits would end up in the
|
|
result since a real OR is required then. */
|
|
unsigned long
|
|
foo1c (unsigned long a, unsigned long b)
|
|
{
|
|
return (a << 5) | (b & 127);
|
|
}
|
|
|
|
unsigned long
|
|
foo2c (unsigned long a, unsigned long b)
|
|
{
|
|
return (b << 5) | (a & 127);
|
|
}
|
|
|
|
unsigned long
|
|
foo3 (unsigned long a, unsigned long b)
|
|
{
|
|
#ifdef __s390x__
|
|
return (a << 5) | (b >> 59);
|
|
#else
|
|
return (a << 5) | (b >> 27);
|
|
#endif
|
|
}
|
|
|
|
unsigned long
|
|
foo4 (unsigned long a, unsigned long b)
|
|
{
|
|
#ifdef __s390x__
|
|
return (b << 5) | (a >> 59);
|
|
#else
|
|
return (b << 5) | (a >> 27);
|
|
#endif
|
|
}
|
|
|
|
/* risbg can be used also if there are some bits spared in the middle
|
|
of the two chunks. */
|
|
unsigned long
|
|
foo3b (unsigned long a, unsigned long b)
|
|
{
|
|
#ifdef __s390x__
|
|
return (a << 6) | (b >> 59);
|
|
#else
|
|
return (a << 6) | (b >> 27);
|
|
#endif
|
|
}
|
|
|
|
unsigned long
|
|
foo4b (unsigned long a, unsigned long b)
|
|
{
|
|
#ifdef __s390x__
|
|
return (b << 6) | (a >> 59);
|
|
#else
|
|
return (b << 6) | (a >> 27);
|
|
#endif
|
|
}
|
|
|
|
/* One bit of overlap so better don't use risbg. */
|
|
|
|
unsigned long
|
|
foo3c (unsigned long a, unsigned long b)
|
|
{
|
|
#ifdef __s390x__
|
|
return (a << 4) | (b >> 59);
|
|
#else
|
|
return (a << 4) | (b >> 27);
|
|
#endif
|
|
}
|
|
|
|
unsigned long
|
|
foo4c (unsigned long a, unsigned long b)
|
|
{
|
|
#ifdef __s390x__
|
|
return (b << 4) | (a >> 59);
|
|
#else
|
|
return (b << 4) | (a >> 27);
|
|
#endif
|
|
}
|
|
|
|
/* The functions foo3, foo4, foo3b, foo4b no longer use risbg but rosbg instead.
|
|
|
|
On 64 bit, four risbg go away and four new ones appear in other functions
|
|
{ dg-final { scan-assembler-times "risbg" 6 { target { lp64 } } } }
|
|
|
|
... but not on 31 bit.
|
|
{ dg-final { scan-assembler-times "risbg" 2 { target { ! lp64 } } } }
|
|
*/
|