1// Copyright 2012 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6//     * Redistributions of source code must retain the above copyright
7//       notice, this list of conditions and the following disclaimer.
8//     * Redistributions in binary form must reproduce the above
9//       copyright notice, this list of conditions and the following
10//       disclaimer in the documentation and/or other materials provided
11//       with the distribution.
12//     * Neither the name of Google Inc. nor the names of its
13//       contributors may be used to endorse or promote products derived
14//       from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28// Flags: --allow-natives-syntax --expose-gc
29
30// Test shift operations that can be replaced by rotate operation.
31
32function SideEffect() {
33  with ({}) { }  // not inlinable
34}
35
36function Twenty() {
37  SideEffect();
38  return 20;
39}
40
41function Twelve() {
42  SideEffect();
43  return 12;
44}
45
46
47function ROR(x, sa) {
48  return (x >>> sa) | (x << (32 - sa));
49}
50
51function ROR1(x, sa) {
52  return (x >>> sa) | (x << (32 - sa));
53}
54
55function ROR2(x, sa) {
56  return (x >>> (32 - sa)) | (x << (sa));
57}
58
59function ROR3(x, sa) {
60  return (x << (32 - sa)) | (x >>> sa);
61}
62
63function ROR4(x, sa) {
64  return (x << (sa)) | (x >>> (32 - sa));
65}
66
67assertEquals(1 << ((2 % 32)), ROR(1, 30));
68assertEquals(1 << ((2 % 32)), ROR(1, 30));
69%OptimizeFunctionOnNextCall(ROR);
70assertEquals(1 << ((2 % 32)), ROR(1, 30));
71
72assertEquals(0xF0000FFF | 0, ROR1(0x0000FFFF, 4));
73assertEquals(0xF0000FFF | 0, ROR1(0x0000FFFF, 4));
74%OptimizeFunctionOnNextCall(ROR1);
75assertEquals(0xF0000FFF | 0, ROR1(0x0000FFFF, 4));
76
77assertEquals(0x0FFFF000 | 0, ROR1(0x0000FFFF, 20));
78assertEquals(0x0FFFF000 | 0, ROR1(0x0000FFFF, 20));
79%OptimizeFunctionOnNextCall(ROR1);
80assertEquals(0x0FFFF000 | 0, ROR1(0x0000FFFF, 20));
81
82assertEquals(0x0FFFF000 | 0, ROR1(0x0000FFFF, Twenty()));
83assertEquals(0x0FFFF000 | 0, ROR1(0x0000FFFF, Twenty()));
84%OptimizeFunctionOnNextCall(ROR1);
85assertEquals(0x0FFFF000 | 0, ROR1(0x0000FFFF, Twenty()));
86
87for (var i = 0; i <= 100; i++) {
88  assertEquals(0xFFFFFFFF | 0, ROR1(0xFFFFFFFF, i));
89  assertEquals(0xFFFFFFFF | 0, ROR1(0xFFFFFFFF, i));
90  %OptimizeFunctionOnNextCall(ROR1);
91  assertEquals(0xFFFFFFFF | 0, ROR1(0xFFFFFFFF, i));
92}
93
94for (var i = 0; i <= 100; i++) {
95  assertEquals(-1, ROR1(-1, i));
96  assertEquals(-1, ROR1(-1, i));
97  %OptimizeFunctionOnNextCall(ROR1);
98  assertEquals(-1, ROR1(-1, i));
99}
100
101for (var i = 0; i <= 100; i++) {
102  assertEquals(1 << (32 - (i % 32)), ROR1(1, i));
103  assertEquals(1 << (32 - (i % 32)), ROR1(1, i));
104  %OptimizeFunctionOnNextCall(ROR1);
105  assertEquals(1 << (32 - (i % 32)), ROR1(1, i));
106}
107
108for (var i = 0; i <= 100; i++) {
109  assertEquals(1 << (32 - (i % 32)), ROR1(1.4, i));
110  assertEquals(1 << (32 - (i % 32)), ROR1(1.4, i));
111  %OptimizeFunctionOnNextCall(ROR1);
112  assertEquals(1 << (32 - (i % 32)), ROR1(1.4, i));
113}
114
115
116
117assertEquals(0xF0000FFF | 0, ROR2(0x0000FFFF, 28));
118assertEquals(0xF0000FFF | 0, ROR2(0x0000FFFF, 28));
119%OptimizeFunctionOnNextCall(ROR2);
120assertEquals(0xF0000FFF | 0, ROR2(0x0000FFFF, 28));
121
122assertEquals(0x0FFFF000 | 0, ROR2(0x0000FFFF, 12));
123assertEquals(0x0FFFF000 | 0, ROR2(0x0000FFFF, 12));
124%OptimizeFunctionOnNextCall(ROR2);
125assertEquals(0x0FFFF000 | 0, ROR2(0x0000FFFF, 12));
126
127assertEquals(0x0FFFF000 | 0, ROR2(0x0000FFFF, Twelve()));
128assertEquals(0x0FFFF000 | 0, ROR2(0x0000FFFF, Twelve()));
129%OptimizeFunctionOnNextCall(ROR2);
130assertEquals(0x0FFFF000 | 0, ROR2(0x0000FFFF, Twelve()));
131
132for (var i = 0; i <= 100; i++) {
133  assertEquals(0xFFFFFFFF | 0, ROR2(0xFFFFFFFF, i));
134  assertEquals(0xFFFFFFFF | 0, ROR2(0xFFFFFFFF, i));
135  %OptimizeFunctionOnNextCall(ROR2);
136  assertEquals(0xFFFFFFFF | 0, ROR2(0xFFFFFFFF, i));
137}
138
139for (var i = 0; i <= 100; i++) {
140  assertEquals(-1, ROR2(-1, i));
141  assertEquals(-1, ROR2(-1, i));
142  %OptimizeFunctionOnNextCall(ROR2);
143  assertEquals(-1, ROR2(-1, i));
144}
145
146for (var i = 0; i <= 100; i++) {
147  assertEquals(1 << ((i % 32)), ROR2(1, i));
148  assertEquals(1 << ((i % 32)), ROR2(1, i));
149  %OptimizeFunctionOnNextCall(ROR2);
150  assertEquals(1 << ((i % 32)), ROR2(1, i));
151}
152
153assertEquals(0xF0000FFF | 0, ROR3(0x0000FFFF, 4));
154assertEquals(0xF0000FFF | 0, ROR3(0x0000FFFF, 4));
155%OptimizeFunctionOnNextCall(ROR3);
156assertEquals(0xF0000FFF | 0, ROR3(0x0000FFFF, 4));
157
158assertEquals(0x0FFFF000 | 0, ROR3(0x0000FFFF, 20));
159assertEquals(0x0FFFF000 | 0, ROR3(0x0000FFFF, 20));
160%OptimizeFunctionOnNextCall(ROR3);
161assertEquals(0x0FFFF000 | 0, ROR3(0x0000FFFF, 20));
162
163assertEquals(0x0FFFF000 | 0, ROR3(0x0000FFFF, Twenty()));
164assertEquals(0x0FFFF000 | 0, ROR3(0x0000FFFF, Twenty()));
165%OptimizeFunctionOnNextCall(ROR3);
166assertEquals(0x0FFFF000 | 0, ROR3(0x0000FFFF, Twenty()));
167
168for (var i = 0; i <= 100; i++) {
169  assertEquals(0xFFFFFFFF | 0, ROR3(0xFFFFFFFF, i));
170  assertEquals(0xFFFFFFFF | 0, ROR3(0xFFFFFFFF, i));
171  %OptimizeFunctionOnNextCall(ROR3);
172  assertEquals(0xFFFFFFFF | 0, ROR3(0xFFFFFFFF, i));
173}
174
175for (var i = 0; i <= 100; i++) {
176  assertEquals(-1, ROR3(-1, i));
177  assertEquals(-1, ROR3(-1, i));
178  %OptimizeFunctionOnNextCall(ROR3);
179  assertEquals(-1, ROR3(-1, i));
180}
181
182for (var i = 0; i <= 100; i++) {
183  assertEquals(1 << (32 - (i % 32)), ROR3(1, i));
184  assertEquals(1 << (32 - (i % 32)), ROR3(1, i));
185  %OptimizeFunctionOnNextCall(ROR3);
186  assertEquals(1 << (32 - (i % 32)), ROR3(1, i));
187}
188
189assertEquals(0xF0000FFF | 0, ROR4(0x0000FFFF, 28));
190assertEquals(0xF0000FFF | 0, ROR4(0x0000FFFF, 28));
191%OptimizeFunctionOnNextCall(ROR4);
192assertEquals(0xF0000FFF | 0, ROR4(0x0000FFFF, 28));
193
194assertEquals(0x0FFFF000 | 0, ROR4(0x0000FFFF, 12));
195assertEquals(0x0FFFF000 | 0, ROR4(0x0000FFFF, 12));
196%OptimizeFunctionOnNextCall(ROR4);
197assertEquals(0x0FFFF000 | 0, ROR4(0x0000FFFF, 12));
198
199assertEquals(0x0FFFF000 | 0, ROR4(0x0000FFFF, Twelve()));
200assertEquals(0x0FFFF000 | 0, ROR4(0x0000FFFF, Twelve()));
201%OptimizeFunctionOnNextCall(ROR4);
202assertEquals(0x0FFFF000 | 0, ROR4(0x0000FFFF, Twelve()));
203
204for (var i = 0; i <= 100; i++) {
205  assertEquals(0xFFFFFFFF | 0, ROR4(0xFFFFFFFF, i));
206  assertEquals(0xFFFFFFFF | 0, ROR4(0xFFFFFFFF, i));
207  %OptimizeFunctionOnNextCall(ROR4);
208  assertEquals(0xFFFFFFFF | 0, ROR4(0xFFFFFFFF, i));
209}
210
211for (var i = 0; i <= 100; i++) {
212  assertEquals(-1, ROR4(-1, i));
213  assertEquals(-1, ROR4(-1, i));
214  %OptimizeFunctionOnNextCall(ROR4);
215  assertEquals(-1, ROR4(-1, i));
216}
217
218for (var i = 0; i <= 100; i++) {
219  assertEquals(1 << ((i % 32)), ROR4(1, i));
220  assertEquals(1 << ((i % 32)), ROR4(1, i));
221  %OptimizeFunctionOnNextCall(ROR4);
222  assertEquals(1 << ((i % 32)), ROR4(1, i));
223}
224
225//---------------------------------------------------------
226// add test cases for constant operand
227//---------------------------------------------------------
228// constant operand: 20
229function ROR1_sa20(x) {
230  return (x >>> 20) | (x << 12);
231}
232
233function ROR2_sa20(x) {
234  return (x >>> 12) | (x << 20);
235}
236
237function ROR3_sa20(x, sa) {
238  return (x << 12) | (x >>> 20);
239}
240
241function ROR4_sa20(x) {
242  return (x << 20) | (x >>> 12);
243}
244
245// constant operand: 40
246function ROR1_sa40(x) {
247  return (x >>> 40) | (x << -8);
248}
249
250function ROR2_sa40(x) {
251  return (x >>> -8) | (x << 40);
252}
253
254function ROR3_sa40(x, sa) {
255  return (x << -8) | (x >>> 40);
256}
257
258function ROR4_sa40(x) {
259  return (x << 40) | (x >>> -8);
260}
261
262// ROR1_sa20
263assertEquals(ROR1(0x0000FFFF, 20), ROR1_sa20(0x0000FFFF));
264assertEquals(ROR1(0x0000FFFF, 20), ROR1_sa20(0x0000FFFF));
265%OptimizeFunctionOnNextCall(ROR1_sa20);
266assertEquals(ROR1(0x0000FFFF, 20), ROR1_sa20(0x0000FFFF));
267
268// ROR1_sa40
269assertEquals(ROR1(0x0000FFFF, 40), ROR1_sa40(0x0000FFFF));
270assertEquals(ROR1(0x0000FFFF, 40), ROR1_sa40(0x0000FFFF));
271%OptimizeFunctionOnNextCall(ROR1_sa40);
272assertEquals(ROR1(0x0000FFFF, 40), ROR1_sa40(0x0000FFFF));
273
274// ROR2_sa20
275assertEquals(ROR2(0xFFFFFFFF, 20), ROR2_sa20(0xFFFFFFFF));
276assertEquals(ROR2(0xFFFFFFFF, 20), ROR2_sa20(0xFFFFFFFF));
277%OptimizeFunctionOnNextCall(ROR2_sa20);
278assertEquals(ROR2(0xFFFFFFFF, 20), ROR2_sa20(0xFFFFFFFF));
279
280// ROR2_sa40
281assertEquals(ROR2(0x0000FFFF, 40), ROR2_sa40(0x0000FFFF));
282assertEquals(ROR2(0x0000FFFF, 40), ROR2_sa40(0x0000FFFF));
283%OptimizeFunctionOnNextCall(ROR2_sa40);
284assertEquals(ROR2(0x0000FFFF, 40), ROR2_sa40(0x0000FFFF));
285
286// ROR3_sa20
287assertEquals(ROR3(0x0000FFFF, 20), ROR3_sa20(0x0000FFFF));
288assertEquals(ROR3(0x0000FFFF, 20), ROR3_sa20(0x0000FFFF));
289%OptimizeFunctionOnNextCall(ROR3_sa20);
290assertEquals(ROR3(0x0000FFFF, 20), ROR3_sa20(0x0000FFFF));
291
292// ROR3_sa40
293assertEquals(ROR3(0x0000FFFF, 40), ROR3_sa40(0x0000FFFF));
294assertEquals(ROR3(0x0000FFFF, 40), ROR3_sa40(0x0000FFFF));
295%OptimizeFunctionOnNextCall(ROR3_sa40);
296assertEquals(ROR3(0x0000FFFF, 40), ROR3_sa40(0x0000FFFF));
297
298// ROR4_sa20
299assertEquals(ROR4(0x0000FFFF, 20), ROR4_sa20(0x0000FFFF));
300assertEquals(ROR4(0x0000FFFF, 20), ROR4_sa20(0x0000FFFF));
301%OptimizeFunctionOnNextCall(ROR4_sa20);
302assertEquals(ROR4(0x0000FFFF, 20), ROR4_sa20(0x0000FFFF));
303
304// ROR4_sa40
305assertEquals(ROR4(0xFFFFFFFF, 40), ROR4_sa40(0xFFFFFFFF));
306assertEquals(ROR4(0xFFFFFFFF, 40), ROR4_sa40(0xFFFFFFFF));
307%OptimizeFunctionOnNextCall(ROR4_sa40);
308assertEquals(ROR4(0xFFFFFFFF, 40), ROR4_sa40(0xFFFFFFFF));
309