1 /* { dg-do compile } */
2 /* { dg-options "-O3 -march=z10 -mzarch" } */
3
4 unsigned long
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
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
22 foo1b (unsigned long a, unsigned long b)
23 {
24 return (a << 5) | (b & 1);
25 }
26
27 unsigned long
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
36 foo1c (unsigned long a, unsigned long b)
37 {
38 return (a << 5) | (b & 127);
39 }
40
41 unsigned long
42 foo2c (unsigned long a, unsigned long b)
43 {
44 return (b << 5) | (a & 127);
45 }
46
47 unsigned long
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
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
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
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
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
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 */