1 /* { dg-do compile } */
2 /* { dg-options "-O3 -march=z10 -mzarch" } */
3 
4 unsigned long
foo1(unsigned long a,unsigned long b)5 foo1 (unsigned long a, unsigned long b)
6 {
7   return (a << 5) | (b & (((1UL << 5) - 1)));
8 }
9 
10 /* This generates very different RTX than foo1.  The output reg (r2)
11    matches the unshifted argument.  So it actually is a
12    (set (zero_extract a 59 0) b) */
13 unsigned long
foo2(unsigned long a,unsigned long b)14 foo2 (unsigned long a, unsigned long b)
15 {
16   return (b << 5) | (a & (((1UL << 5) - 1)));
17 }
18 
19 /* risbg cannot be used when less bits are removed with the mask.  */
20 
21 unsigned long
foo1b(unsigned long a,unsigned long b)22 foo1b (unsigned long a, unsigned long b)
23 {
24   return (a << 5) | (b & 1);
25 }
26 
27 unsigned long
foo2b(unsigned long a,unsigned long b)28 foo2b (unsigned long a, unsigned long b)
29 {
30   return (b << 5) | (a & 1);
31 }
32 
33 /* risbg cannot be used when the masked bits would end up in the
34    result since a real OR is required then.  */
35 unsigned long
foo1c(unsigned long a,unsigned long b)36 foo1c (unsigned long a, unsigned long b)
37 {
38   return (a << 5) | (b & 127);
39 }
40 
41 unsigned long
foo2c(unsigned long a,unsigned long b)42 foo2c (unsigned long a, unsigned long b)
43 {
44   return (b << 5) | (a & 127);
45 }
46 
47 unsigned long
foo3(unsigned long a,unsigned long b)48 foo3 (unsigned long a, unsigned long b)
49 {
50 #ifdef __s390x__
51   return (a << 5) | (b >> 59);
52 #else
53   return (a << 5) | (b >> 27);
54 #endif
55 }
56 
57 unsigned long
foo4(unsigned long a,unsigned long b)58 foo4 (unsigned long a, unsigned long b)
59 {
60 #ifdef __s390x__
61   return (b << 5) | (a >> 59);
62 #else
63   return (b << 5) | (a >> 27);
64 #endif
65 }
66 
67 /* risbg can be used also if there are some bits spared in the middle
68    of the two chunks.  */
69 unsigned long
foo3b(unsigned long a,unsigned long b)70 foo3b (unsigned long a, unsigned long b)
71 {
72 #ifdef __s390x__
73   return (a << 6) | (b >> 59);
74 #else
75   return (a << 6) | (b >> 27);
76 #endif
77 }
78 
79 unsigned long
foo4b(unsigned long a,unsigned long b)80 foo4b (unsigned long a, unsigned long b)
81 {
82 #ifdef __s390x__
83   return (b << 6) | (a >> 59);
84 #else
85   return (b << 6) | (a >> 27);
86 #endif
87 }
88 
89 /* One bit of overlap so better don't use risbg.  */
90 
91 unsigned long
foo3c(unsigned long a,unsigned long b)92 foo3c (unsigned long a, unsigned long b)
93 {
94 #ifdef __s390x__
95   return (a << 4) | (b >> 59);
96 #else
97   return (a << 4) | (b >> 27);
98 #endif
99 }
100 
101 unsigned long
foo4c(unsigned long a,unsigned long b)102 foo4c (unsigned long a, unsigned long b)
103 {
104 #ifdef __s390x__
105   return (b << 4) | (a >> 59);
106 #else
107   return (b << 4) | (a >> 27);
108 #endif
109 }
110 
111 /* The functions foo3, foo4, foo3b, foo4b no longer use risbg but rosbg instead.
112 
113    On 64 bit, four risbg go away and four new ones appear in other functions
114      { dg-final { scan-assembler-times "risbg" 6 { target { lp64 } } } }
115 
116    ... but not on 31 bit.
117      { dg-final { scan-assembler-times "risbg" 2 { target { ! lp64 } } } }
118 */
119