1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 public class TestRotate {
18 
19   /// CHECK-START: int TestRotate.rotateLeftByte(byte, int) builder (after)
20   /// CHECK:         <<ArgVal:b\d+>>  ParameterValue
21   /// CHECK:         <<ArgDist:i\d+>> ParameterValue
22   /// CHECK-DAG:     <<NegDist:i\d+>> Neg [<<ArgDist>>]
23   /// CHECK-DAG:     <<Result:i\d+>>  Ror [<<ArgVal>>,<<NegDist>>]
24   /// CHECK-DAG:                      Return [<<Result>>]
25 
26   /// CHECK-START: int TestRotate.rotateLeftByte(byte, int) builder (after)
27   /// CHECK-NOT:                      InvokeStaticOrDirect
28 
rotateLeftByte(byte value, int distance)29   private static int rotateLeftByte(byte value, int distance) {
30     return Integer.rotateLeft(value, distance);
31   }
32 
33   /// CHECK-START: int TestRotate.rotateLeftShort(short, int) builder (after)
34   /// CHECK:         <<ArgVal:s\d+>>  ParameterValue
35   /// CHECK:         <<ArgDist:i\d+>> ParameterValue
36   /// CHECK-DAG:     <<NegDist:i\d+>> Neg [<<ArgDist>>]
37   /// CHECK-DAG:     <<Result:i\d+>>  Ror [<<ArgVal>>,<<NegDist>>]
38   /// CHECK-DAG:                      Return [<<Result>>]
39 
40   /// CHECK-START: int TestRotate.rotateLeftShort(short, int) builder (after)
41   /// CHECK-NOT:                      InvokeStaticOrDirect
42 
rotateLeftShort(short value, int distance)43   private static int rotateLeftShort(short value, int distance) {
44     return Integer.rotateLeft(value, distance);
45   }
46 
47   /// CHECK-START: int TestRotate.rotateLeftChar(char, int) builder (after)
48   /// CHECK:         <<ArgVal:c\d+>>  ParameterValue
49   /// CHECK:         <<ArgDist:i\d+>> ParameterValue
50   /// CHECK-DAG:     <<NegDist:i\d+>> Neg [<<ArgDist>>]
51   /// CHECK-DAG:     <<Result:i\d+>>  Ror [<<ArgVal>>,<<NegDist>>]
52   /// CHECK-DAG:                      Return [<<Result>>]
53 
54   /// CHECK-START: int TestRotate.rotateLeftChar(char, int) builder (after)
55   /// CHECK-NOT:                      InvokeStaticOrDirect
56 
rotateLeftChar(char value, int distance)57   private static int rotateLeftChar(char value, int distance) {
58     return Integer.rotateLeft(value, distance);
59   }
60 
61   /// CHECK-START: int TestRotate.rotateLeftInt(int, int) builder (after)
62   /// CHECK:         <<ArgVal:i\d+>>  ParameterValue
63   /// CHECK:         <<ArgDist:i\d+>> ParameterValue
64   /// CHECK-DAG:     <<NegDist:i\d+>> Neg [<<ArgDist>>]
65   /// CHECK-DAG:     <<Result:i\d+>>  Ror [<<ArgVal>>,<<NegDist>>]
66   /// CHECK-DAG:                      Return [<<Result>>]
67 
68   /// CHECK-START: int TestRotate.rotateLeftInt(int, int) builder (after)
69   /// CHECK-NOT:                      InvokeStaticOrDirect
70 
rotateLeftInt(int value, int distance)71   private static int rotateLeftInt(int value, int distance) {
72     return Integer.rotateLeft(value, distance);
73   }
74 
75   /// CHECK-START: long TestRotate.rotateLeftLong(long, int) builder (after)
76   /// CHECK:         <<ArgVal:j\d+>>  ParameterValue
77   /// CHECK:         <<ArgDist:i\d+>> ParameterValue
78   /// CHECK-DAG:     <<NegDist:i\d+>> Neg [<<ArgDist>>]
79   /// CHECK-DAG:     <<Result:j\d+>>  Ror [<<ArgVal>>,<<NegDist>>]
80   /// CHECK-DAG:                      Return [<<Result>>]
81 
82   /// CHECK-START: long TestRotate.rotateLeftLong(long, int) builder (after)
83   /// CHECK-NOT:                      InvokeStaticOrDirect
84 
rotateLeftLong(long value, int distance)85   private static long rotateLeftLong(long value, int distance) {
86     return Long.rotateLeft(value, distance);
87   }
88 
89   /// CHECK-START: int TestRotate.rotateRightByte(byte, int) builder (after)
90   /// CHECK:         <<ArgVal:b\d+>>  ParameterValue
91   /// CHECK:         <<ArgDist:i\d+>> ParameterValue
92   /// CHECK-DAG:     <<Result:i\d+>>  Ror [<<ArgVal>>,<<ArgDist>>]
93   /// CHECK-DAG:                      Return [<<Result>>]
94 
95   /// CHECK-START: int TestRotate.rotateRightByte(byte, int) builder (after)
96   /// CHECK-NOT:                      InvokeStaticOrDirect
97 
rotateRightByte(byte value, int distance)98   private static int rotateRightByte(byte value, int distance) {
99     return Integer.rotateRight(value, distance);
100   }
101 
102   /// CHECK-START: int TestRotate.rotateRightShort(short, int) builder (after)
103   /// CHECK:         <<ArgVal:s\d+>>  ParameterValue
104   /// CHECK:         <<ArgDist:i\d+>> ParameterValue
105   /// CHECK-DAG:     <<Result:i\d+>>  Ror [<<ArgVal>>,<<ArgDist>>]
106   /// CHECK-DAG:                      Return [<<Result>>]
107 
108   /// CHECK-START: int TestRotate.rotateRightShort(short, int) builder (after)
109   /// CHECK-NOT:                      InvokeStaticOrDirect
110 
rotateRightShort(short value, int distance)111   private static int rotateRightShort(short value, int distance) {
112     return Integer.rotateRight(value, distance);
113   }
114 
115   /// CHECK-START: int TestRotate.rotateRightChar(char, int) builder (after)
116   /// CHECK:         <<ArgVal:c\d+>>  ParameterValue
117   /// CHECK:         <<ArgDist:i\d+>> ParameterValue
118   /// CHECK-DAG:     <<Result:i\d+>>  Ror [<<ArgVal>>,<<ArgDist>>]
119   /// CHECK-DAG:                      Return [<<Result>>]
120 
121   /// CHECK-START: int TestRotate.rotateRightChar(char, int) builder (after)
122   /// CHECK-NOT:                      InvokeStaticOrDirect
123 
rotateRightChar(char value, int distance)124   private static int rotateRightChar(char value, int distance) {
125     return Integer.rotateRight(value, distance);
126   }
127 
128   /// CHECK-START: int TestRotate.rotateRightInt(int, int) builder (after)
129   /// CHECK:         <<ArgVal:i\d+>>  ParameterValue
130   /// CHECK:         <<ArgDist:i\d+>> ParameterValue
131   /// CHECK-DAG:     <<Result:i\d+>>  Ror [<<ArgVal>>,<<ArgDist>>]
132   /// CHECK-DAG:                      Return [<<Result>>]
133 
134   /// CHECK-START: int TestRotate.rotateRightInt(int, int) builder (after)
135   /// CHECK-NOT:                      InvokeStaticOrDirect
136 
rotateRightInt(int value, int distance)137   private static int rotateRightInt(int value, int distance) {
138     return Integer.rotateRight(value, distance);
139   }
140 
141   /// CHECK-START: long TestRotate.rotateRightLong(long, int) builder (after)
142   /// CHECK:         <<ArgVal:j\d+>>  ParameterValue
143   /// CHECK:         <<ArgDist:i\d+>> ParameterValue
144   /// CHECK-DAG:     <<Result:j\d+>>  Ror [<<ArgVal>>,<<ArgDist>>]
145   /// CHECK-DAG:                      Return [<<Result>>]
146 
147   /// CHECK-START: long TestRotate.rotateRightLong(long, int) builder (after)
148   /// CHECK-NOT:                      InvokeStaticOrDirect
149 
rotateRightLong(long value, int distance)150   private static long rotateRightLong(long value, int distance) {
151     return Long.rotateRight(value, distance);
152   }
153 
154 
155   /// CHECK-START: int TestRotate.rotateLeftIntWithByteDistance(int, byte) builder (after)
156   /// CHECK:         <<ArgVal:i\d+>>  ParameterValue
157   /// CHECK:         <<ArgDist:b\d+>> ParameterValue
158   /// CHECK-DAG:     <<NegDist:i\d+>> Neg [<<ArgDist>>]
159   /// CHECK-DAG:     <<Result:i\d+>>  Ror [<<ArgVal>>,<<NegDist>>]
160   /// CHECK-DAG:                      Return [<<Result>>]
161 
162   /// CHECK-START: int TestRotate.rotateLeftIntWithByteDistance(int, byte) builder (after)
163   /// CHECK-NOT:                      InvokeStaticOrDirect
164 
rotateLeftIntWithByteDistance(int value, byte distance)165   private static int rotateLeftIntWithByteDistance(int value, byte distance) {
166     return Integer.rotateLeft(value, distance);
167   }
168 
169   /// CHECK-START: int TestRotate.rotateRightIntWithByteDistance(int, byte) builder (after)
170   /// CHECK:         <<ArgVal:i\d+>>  ParameterValue
171   /// CHECK:         <<ArgDist:b\d+>> ParameterValue
172   /// CHECK-DAG:     <<Result:i\d+>>  Ror [<<ArgVal>>,<<ArgDist>>]
173   /// CHECK-DAG:                      Return [<<Result>>]
174 
175   /// CHECK-START: int TestRotate.rotateRightIntWithByteDistance(int, byte) builder (after)
176   /// CHECK-NOT:                      InvokeStaticOrDirect
177 
rotateRightIntWithByteDistance(int value, byte distance)178   private static int rotateRightIntWithByteDistance(int value, byte distance) {
179     return Integer.rotateRight(value, distance);
180   }
181 
182   /// CHECK-START: int TestRotate.rotateLeftBoolean(boolean, int) builder (after)
183   /// CHECK:         <<ArgVal:z\d+>>  ParameterValue
184   /// CHECK:         <<ArgDist:i\d+>> ParameterValue
185   /// CHECK-DAG:     <<Zero:i\d+>>    IntConstant 0
186   /// CHECK-DAG:     <<One:i\d+>>     IntConstant 1
187   /// CHECK-DAG:     <<Val:i\d+>>     Phi [<<One>>,<<Zero>>]
188   /// CHECK-DAG:     <<NegDist:i\d+>> Neg [<<ArgDist>>]
189   /// CHECK-DAG:     <<Result:i\d+>>  Ror [<<Val>>,<<NegDist>>]
190   /// CHECK-DAG:                      Return [<<Result>>]
191 
192   /// CHECK-START: int TestRotate.rotateLeftBoolean(boolean, int) builder (after)
193   /// CHECK-NOT:                      InvokeStaticOrDirect
194 
195   /// CHECK-START: int TestRotate.rotateLeftBoolean(boolean, int) select_generator (after)
196   /// CHECK:         <<ArgVal:z\d+>>  ParameterValue
197   /// CHECK:         <<ArgDist:i\d+>> ParameterValue
198   /// CHECK-DAG:     <<Zero:i\d+>>    IntConstant 0
199   /// CHECK-DAG:     <<One:i\d+>>     IntConstant 1
200   /// CHECK-DAG:     <<SelVal:i\d+>>  Select [<<Zero>>,<<One>>,<<ArgVal>>]
201   /// CHECK-DAG:     <<NegDist:i\d+>> Neg [<<ArgDist>>]
202   /// CHECK-DAG:     <<Result:i\d+>>  Ror [<<SelVal>>,<<NegDist>>]
203   /// CHECK-DAG:                      Return [<<Result>>]
204 
205   /// CHECK-START: int TestRotate.rotateLeftBoolean(boolean, int) select_generator (after)
206   /// CHECK-NOT:                      Phi
207 
208   /// CHECK-START: int TestRotate.rotateLeftBoolean(boolean, int) instruction_simplifier$after_bce (after)
209   /// CHECK:         <<ArgVal:z\d+>>  ParameterValue
210   /// CHECK:         <<ArgDist:i\d+>> ParameterValue
211   /// CHECK-DAG:     <<NegDist:i\d+>> Neg [<<ArgDist>>]
212   /// CHECK-DAG:     <<Result:i\d+>>  Ror [<<ArgVal>>,<<NegDist>>]
213   /// CHECK-DAG:                      Return [<<Result>>]
214 
215   /// CHECK-START: int TestRotate.rotateLeftBoolean(boolean, int) instruction_simplifier$after_bce (after)
216   /// CHECK-NOT:                      Select
217 
rotateLeftBoolean(boolean value, int distance)218   private static int rotateLeftBoolean(boolean value, int distance) {
219     // Note: D8 would replace the ternary expression `value ? 1 : 0` with `value`
220     // but explicit `if` is preserved.
221     int src;
222     if (value) {
223       src = 1;
224     } else {
225       src = 0;
226     }
227     return Integer.rotateLeft(src, distance);
228   }
229 
testRotateLeftBoolean()230   public static void testRotateLeftBoolean() {
231     for (int i = 0; i < 40; i++) {  // overshoot a bit
232       int j = i & 31;
233       expectEqualsInt(0, rotateLeftBoolean(false, i));
234       expectEqualsInt(1 << j, rotateLeftBoolean(true, i));
235     }
236   }
237 
testRotateLeftByte()238   public static void testRotateLeftByte() {
239     expectEqualsInt(0x00000001, rotateLeftByte((byte)0x01, 0));
240     expectEqualsInt(0x00000002, rotateLeftByte((byte)0x01, 1));
241     expectEqualsInt(0x80000000, rotateLeftByte((byte)0x01, 31));
242     expectEqualsInt(0x00000001, rotateLeftByte((byte)0x01, 32));  // overshoot
243     expectEqualsInt(0xFFFFFF03, rotateLeftByte((byte)0x81, 1));
244     expectEqualsInt(0xFFFFFE07, rotateLeftByte((byte)0x81, 2));
245     expectEqualsInt(0x00000120, rotateLeftByte((byte)0x12, 4));
246     expectEqualsInt(0xFFFF9AFF, rotateLeftByte((byte)0x9A, 8));
247     for (int i = 0; i < 40; i++) {  // overshoot a bit
248       int j = i & 31;
249       expectEqualsInt(0x00000000, rotateLeftByte((byte)0x0000, i));
250       expectEqualsInt(0xFFFFFFFF, rotateLeftByte((byte)0xFFFF, i));
251       expectEqualsInt((1 << j), rotateLeftByte((byte)0x0001, i));
252       expectEqualsInt((0x12 << j) | (0x12 >>> -j), rotateLeftByte((byte)0x12, i));
253     }
254   }
255 
testRotateLeftShort()256   public static void testRotateLeftShort() {
257     expectEqualsInt(0x00000001, rotateLeftShort((short)0x0001, 0));
258     expectEqualsInt(0x00000002, rotateLeftShort((short)0x0001, 1));
259     expectEqualsInt(0x80000000, rotateLeftShort((short)0x0001, 31));
260     expectEqualsInt(0x00000001, rotateLeftShort((short)0x0001, 32));  // overshoot
261     expectEqualsInt(0xFFFF0003, rotateLeftShort((short)0x8001, 1));
262     expectEqualsInt(0xFFFE0007, rotateLeftShort((short)0x8001, 2));
263     expectEqualsInt(0x00012340, rotateLeftShort((short)0x1234, 4));
264     expectEqualsInt(0xFF9ABCFF, rotateLeftShort((short)0x9ABC, 8));
265     for (int i = 0; i < 40; i++) {  // overshoot a bit
266       int j = i & 31;
267       expectEqualsInt(0x00000000, rotateLeftShort((short)0x0000, i));
268       expectEqualsInt(0xFFFFFFFF, rotateLeftShort((short)0xFFFF, i));
269       expectEqualsInt((1 << j), rotateLeftShort((short)0x0001, i));
270       expectEqualsInt((0x1234 << j) | (0x1234 >>> -j), rotateLeftShort((short)0x1234, i));
271     }
272   }
273 
testRotateLeftChar()274   public static void testRotateLeftChar() {
275     expectEqualsInt(0x00000001, rotateLeftChar((char)0x0001, 0));
276     expectEqualsInt(0x00000002, rotateLeftChar((char)0x0001, 1));
277     expectEqualsInt(0x80000000, rotateLeftChar((char)0x0001, 31));
278     expectEqualsInt(0x00000001, rotateLeftChar((char)0x0001, 32));  // overshoot
279     expectEqualsInt(0x00010002, rotateLeftChar((char)0x8001, 1));
280     expectEqualsInt(0x00020004, rotateLeftChar((char)0x8001, 2));
281     expectEqualsInt(0x00012340, rotateLeftChar((char)0x1234, 4));
282     expectEqualsInt(0x009ABC00, rotateLeftChar((char)0x9ABC, 8));
283     expectEqualsInt(0x00FF0000, rotateLeftChar((char)0xFF00, 8));
284     for (int i = 0; i < 40; i++) {  // overshoot a bit
285       int j = i & 31;
286       expectEqualsInt(0x00000000, rotateLeftChar((char)0x0000, i));
287       expectEqualsInt((1 << j), rotateLeftChar((char)0x0001, i));
288       expectEqualsInt((0x1234 << j) | (0x1234 >>> -j), rotateLeftChar((char)0x1234, i));
289     }
290   }
291 
testRotateLeftInt()292   public static void testRotateLeftInt() {
293     expectEqualsInt(0x00000001, rotateLeftInt(0x00000001, 0));
294     expectEqualsInt(0x00000002, rotateLeftInt(0x00000001, 1));
295     expectEqualsInt(0x80000000, rotateLeftInt(0x00000001, 31));
296     expectEqualsInt(0x00000001, rotateLeftInt(0x00000001, 32));  // overshoot
297     expectEqualsInt(0x00000003, rotateLeftInt(0x80000001, 1));
298     expectEqualsInt(0x00000006, rotateLeftInt(0x80000001, 2));
299     expectEqualsInt(0x23456781, rotateLeftInt(0x12345678, 4));
300     expectEqualsInt(0xBCDEF09A, rotateLeftInt(0x9ABCDEF0, 8));
301     for (int i = 0; i < 40; i++) {  // overshoot a bit
302       int j = i & 31;
303       expectEqualsInt(0x00000000, rotateLeftInt(0x00000000, i));
304       expectEqualsInt(0xFFFFFFFF, rotateLeftInt(0xFFFFFFFF, i));
305       expectEqualsInt(1 << j, rotateLeftInt(0x00000001, i));
306       expectEqualsInt((0x12345678 << j) | (0x12345678 >>> -j), rotateLeftInt(0x12345678, i));
307     }
308   }
309 
testRotateLeftLong()310   public static void testRotateLeftLong() {
311     expectEqualsLong(0x0000000000000001L, rotateLeftLong(0x0000000000000001L, 0));
312     expectEqualsLong(0x0000000000000002L, rotateLeftLong(0x0000000000000001L, 1));
313     expectEqualsLong(0x8000000000000000L, rotateLeftLong(0x0000000000000001L, 63));
314     expectEqualsLong(0x0000000000000001L, rotateLeftLong(0x0000000000000001L, 64));  // overshoot
315     expectEqualsLong(0x0000000000000003L, rotateLeftLong(0x8000000000000001L, 1));
316     expectEqualsLong(0x0000000000000006L, rotateLeftLong(0x8000000000000001L, 2));
317     expectEqualsLong(0x23456789ABCDEF01L, rotateLeftLong(0x123456789ABCDEF0L, 4));
318     expectEqualsLong(0x3456789ABCDEF012L, rotateLeftLong(0x123456789ABCDEF0L, 8));
319     for (int i = 0; i < 70; i++) {  // overshoot a bit
320       int j = i & 63;
321       expectEqualsLong(0x0000000000000000L, rotateLeftLong(0x0000000000000000L, i));
322       expectEqualsLong(0xFFFFFFFFFFFFFFFFL, rotateLeftLong(0xFFFFFFFFFFFFFFFFL, i));
323       expectEqualsLong(1L << j, rotateLeftLong(0x0000000000000001, i));
324       expectEqualsLong((0x123456789ABCDEF0L << j) | (0x123456789ABCDEF0L >>> -j),
325                        rotateLeftLong(0x123456789ABCDEF0L, i));
326     }
327   }
328 
329   /// CHECK-START: int TestRotate.rotateRightBoolean(boolean, int) builder (after)
330   /// CHECK:         <<ArgVal:z\d+>>  ParameterValue
331   /// CHECK:         <<ArgDist:i\d+>> ParameterValue
332   /// CHECK-DAG:     <<Zero:i\d+>>    IntConstant 0
333   /// CHECK-DAG:     <<One:i\d+>>     IntConstant 1
334   /// CHECK-DAG:     <<Val:i\d+>>     Phi [<<One>>,<<Zero>>]
335   /// CHECK-DAG:     <<Result:i\d+>>  Ror [<<Val>>,<<ArgDist>>]
336   /// CHECK-DAG:                      Return [<<Result>>]
337 
338   /// CHECK-START: int TestRotate.rotateRightBoolean(boolean, int) builder (after)
339   /// CHECK-NOT:                      InvokeStaticOrDirect
340 
341   /// CHECK-START: int TestRotate.rotateRightBoolean(boolean, int) select_generator (after)
342   /// CHECK:         <<ArgVal:z\d+>>  ParameterValue
343   /// CHECK:         <<ArgDist:i\d+>> ParameterValue
344   /// CHECK-DAG:     <<Zero:i\d+>>    IntConstant 0
345   /// CHECK-DAG:     <<One:i\d+>>     IntConstant 1
346   /// CHECK-DAG:     <<SelVal:i\d+>>  Select [<<Zero>>,<<One>>,<<ArgVal>>]
347   /// CHECK-DAG:     <<Result:i\d+>>  Ror [<<SelVal>>,<<ArgDist>>]
348   /// CHECK-DAG:                      Return [<<Result>>]
349 
350   /// CHECK-START: int TestRotate.rotateRightBoolean(boolean, int) select_generator (after)
351   /// CHECK-NOT:                     Phi
352 
353   /// CHECK-START: int TestRotate.rotateRightBoolean(boolean, int) instruction_simplifier$after_bce (after)
354   /// CHECK:         <<ArgVal:z\d+>>  ParameterValue
355   /// CHECK:         <<ArgDist:i\d+>> ParameterValue
356   /// CHECK-DAG:     <<Result:i\d+>>  Ror [<<ArgVal>>,<<ArgDist>>]
357   /// CHECK-DAG:                      Return [<<Result>>]
358 
359   /// CHECK-START: int TestRotate.rotateRightBoolean(boolean, int) instruction_simplifier$after_bce (after)
360   /// CHECK-NOT:                     Select
361 
rotateRightBoolean(boolean value, int distance)362   private static int rotateRightBoolean(boolean value, int distance) {
363     // Note: D8 would replace the ternary expression `value ? 1 : 0` with `value`
364     // but explicit `if` is preserved.
365     int src;
366     if (value) {
367       src = 1;
368     } else {
369       src = 0;
370     }
371     return Integer.rotateRight(src, distance);
372   }
373 
testRotateRightBoolean()374   public static void testRotateRightBoolean() {
375     for (int i = 0; i < 40; i++) {  // overshoot a bit
376       int j = (-i) & 31;
377       expectEqualsInt(0, rotateRightBoolean(false, i));
378       expectEqualsInt(1 << j, rotateRightBoolean(true, i));
379     }
380   }
381 
testRotateRightByte()382   public static void testRotateRightByte() {
383     expectEqualsInt(0xFFFFFF80, rotateRightByte((byte)0x80, 0));
384     expectEqualsInt(0x7FFFFFC0, rotateRightByte((byte)0x80, 1));
385     expectEqualsInt(0xFFFFFF01, rotateRightByte((byte)0x80, 31));
386     expectEqualsInt(0xFFFFFF80, rotateRightByte((byte)0x80, 32));  // overshoot
387     expectEqualsInt(0xFFFFFFC0, rotateRightByte((byte)0x81, 1));
388     expectEqualsInt(0x7FFFFFE0, rotateRightByte((byte)0x81, 2));
389     expectEqualsInt(0x20000001, rotateRightByte((byte)0x12, 4));
390     expectEqualsInt(0x9AFFFFFF, rotateRightByte((byte)0x9A, 8));
391     for (int i = 0; i < 40; i++) {  // overshoot a bit
392       int j = i & 31;
393       expectEqualsInt(0x00000000, rotateRightByte((byte)0x00, i));
394       expectEqualsInt(0xFFFFFFFF, rotateRightByte((byte)0xFF, i));
395       expectEqualsInt(1 << (32 - j), rotateRightByte((byte)0x01, i));
396       expectEqualsInt((0x12 >>> j) | (0x12 << -j), rotateRightByte((byte)0x12, i));
397     }
398   }
399 
testRotateRightShort()400   public static void testRotateRightShort() {
401     expectEqualsInt(0xFFFF8000, rotateRightShort((short)0x8000, 0));
402     expectEqualsInt(0x7FFFC000, rotateRightShort((short)0x8000, 1));
403     expectEqualsInt(0xFFFF0001, rotateRightShort((short)0x8000, 31));
404     expectEqualsInt(0xFFFF8000, rotateRightShort((short)0x8000, 32));  // overshoot
405     expectEqualsInt(0xFFFFC000, rotateRightShort((short)0x8001, 1));
406     expectEqualsInt(0x7FFFE000, rotateRightShort((short)0x8001, 2));
407     expectEqualsInt(0x40000123, rotateRightShort((short)0x1234, 4));
408     expectEqualsInt(0xBCFFFF9A, rotateRightShort((short)0x9ABC, 8));
409     for (int i = 0; i < 40; i++) {  // overshoot a bit
410       int j = i & 31;
411       expectEqualsInt(0x00000000, rotateRightShort((short)0x0000, i));
412       expectEqualsInt(0xFFFFFFFF, rotateRightShort((short)0xFFFF, i));
413       expectEqualsInt(1 << (32 - j), rotateRightShort((short)0x0001, i));
414       expectEqualsInt((0x1234 >>> j) | (0x1234 << -j), rotateRightShort((short)0x1234, i));
415     }
416   }
417 
testRotateRightChar()418   public static void testRotateRightChar() {
419     expectEqualsInt(0x00008000, rotateRightChar((char)0x8000, 0));
420     expectEqualsInt(0x00004000, rotateRightChar((char)0x8000, 1));
421     expectEqualsInt(0x00010000, rotateRightChar((char)0x8000, 31));
422     expectEqualsInt(0x00008000, rotateRightChar((char)0x8000, 32));  // overshoot
423     expectEqualsInt(0x80004000, rotateRightChar((char)0x8001, 1));
424     expectEqualsInt(0x40002000, rotateRightChar((char)0x8001, 2));
425     expectEqualsInt(0x40000123, rotateRightChar((char)0x1234, 4));
426     expectEqualsInt(0xBC00009A, rotateRightChar((char)0x9ABC, 8));
427     for (int i = 0; i < 40; i++) {  // overshoot a bit
428       int j = i & 31;
429       expectEqualsInt(0x00000000, rotateRightChar((char)0x0000, i));
430       expectEqualsInt(1 << (32 - j), rotateRightChar((char)0x0001, i));
431       expectEqualsInt((0x1234 >>> j) | (0x1234 << -j), rotateRightChar((char)0x1234, i));
432     }
433   }
434 
testRotateRightInt()435   public static void testRotateRightInt() {
436     expectEqualsInt(0x80000000, rotateRightInt(0x80000000, 0));
437     expectEqualsInt(0x40000000, rotateRightInt(0x80000000, 1));
438     expectEqualsInt(0x00000001, rotateRightInt(0x80000000, 31));
439     expectEqualsInt(0x80000000, rotateRightInt(0x80000000, 32));  // overshoot
440     expectEqualsInt(0xC0000000, rotateRightInt(0x80000001, 1));
441     expectEqualsInt(0x60000000, rotateRightInt(0x80000001, 2));
442     expectEqualsInt(0x81234567, rotateRightInt(0x12345678, 4));
443     expectEqualsInt(0xF09ABCDE, rotateRightInt(0x9ABCDEF0, 8));
444     for (int i = 0; i < 40; i++) {  // overshoot a bit
445       int j = i & 31;
446       expectEqualsInt(0x00000000, rotateRightInt(0x00000000, i));
447       expectEqualsInt(0xFFFFFFFF, rotateRightInt(0xFFFFFFFF, i));
448       expectEqualsInt(0x80000000 >>> j, rotateRightInt(0x80000000, i));
449       expectEqualsInt((0x12345678 >>> j) | (0x12345678 << -j), rotateRightInt(0x12345678, i));
450     }
451   }
452 
testRotateRightLong()453   public static void testRotateRightLong() {
454     expectEqualsLong(0x8000000000000000L, rotateRightLong(0x8000000000000000L, 0));
455     expectEqualsLong(0x4000000000000000L, rotateRightLong(0x8000000000000000L, 1));
456     expectEqualsLong(0x0000000000000001L, rotateRightLong(0x8000000000000000L, 63));
457     expectEqualsLong(0x8000000000000000L, rotateRightLong(0x8000000000000000L, 64));  // overshoot
458     expectEqualsLong(0xC000000000000000L, rotateRightLong(0x8000000000000001L, 1));
459     expectEqualsLong(0x6000000000000000L, rotateRightLong(0x8000000000000001L, 2));
460     expectEqualsLong(0x0123456789ABCDEFL, rotateRightLong(0x123456789ABCDEF0L, 4));
461     expectEqualsLong(0xF0123456789ABCDEL, rotateRightLong(0x123456789ABCDEF0L, 8));
462     for (int i = 0; i < 70; i++) {  // overshoot a bit
463       int j = i & 63;
464       expectEqualsLong(0x0000000000000000L, rotateRightLong(0x0000000000000000L, i));
465       expectEqualsLong(0xFFFFFFFFFFFFFFFFL, rotateRightLong(0xFFFFFFFFFFFFFFFFL, i));
466       expectEqualsLong(0x8000000000000000L >>> j, rotateRightLong(0x8000000000000000L, i));
467       expectEqualsLong((0x123456789ABCDEF0L >>> j) | (0x123456789ABCDEF0L << -j),
468                        rotateRightLong(0x123456789ABCDEF0L, i));
469     }
470   }
471 
472 
testRotateLeftIntWithByteDistance()473   public static void testRotateLeftIntWithByteDistance() {
474     expectEqualsInt(0x00000001, rotateLeftIntWithByteDistance(0x00000001, (byte)0));
475     expectEqualsInt(0x00000002, rotateLeftIntWithByteDistance(0x00000001, (byte)1));
476     expectEqualsInt(0x80000000, rotateLeftIntWithByteDistance(0x00000001, (byte)31));
477     expectEqualsInt(0x00000001, rotateLeftIntWithByteDistance(0x00000001, (byte)32));  // overshoot
478     expectEqualsInt(0x00000003, rotateLeftIntWithByteDistance(0x80000001, (byte)1));
479     expectEqualsInt(0x00000006, rotateLeftIntWithByteDistance(0x80000001, (byte)2));
480     expectEqualsInt(0x23456781, rotateLeftIntWithByteDistance(0x12345678, (byte)4));
481     expectEqualsInt(0xBCDEF09A, rotateLeftIntWithByteDistance(0x9ABCDEF0, (byte)8));
482     for (byte i = 0; i < 40; i++) {  // overshoot a bit
483       byte j = (byte)(i & 31);
484       expectEqualsInt(0x00000000, rotateLeftIntWithByteDistance(0x00000000, i));
485       expectEqualsInt(0xFFFFFFFF, rotateLeftIntWithByteDistance(0xFFFFFFFF, i));
486       expectEqualsInt(1 << j, rotateLeftIntWithByteDistance(0x00000001, i));
487       expectEqualsInt((0x12345678 << j) | (0x12345678 >>> -j),
488                       rotateLeftIntWithByteDistance(0x12345678, i));
489     }
490   }
491 
testRotateRightIntWithByteDistance()492   public static void testRotateRightIntWithByteDistance() {
493     expectEqualsInt(0x80000000, rotateRightIntWithByteDistance(0x80000000, (byte)0));
494     expectEqualsInt(0x40000000, rotateRightIntWithByteDistance(0x80000000, (byte)1));
495     expectEqualsInt(0x00000001, rotateRightIntWithByteDistance(0x80000000, (byte)31));
496     expectEqualsInt(0x80000000, rotateRightIntWithByteDistance(0x80000000, (byte)32));  // overshoot
497     expectEqualsInt(0xC0000000, rotateRightIntWithByteDistance(0x80000001, (byte)1));
498     expectEqualsInt(0x60000000, rotateRightIntWithByteDistance(0x80000001, (byte)2));
499     expectEqualsInt(0x81234567, rotateRightIntWithByteDistance(0x12345678, (byte)4));
500     expectEqualsInt(0xF09ABCDE, rotateRightIntWithByteDistance(0x9ABCDEF0, (byte)8));
501     for (byte i = 0; i < 40; i++) {  // overshoot a bit
502       byte j = (byte)(i & 31);
503       expectEqualsInt(0x00000000, rotateRightIntWithByteDistance(0x00000000, i));
504       expectEqualsInt(0xFFFFFFFF, rotateRightIntWithByteDistance(0xFFFFFFFF, i));
505       expectEqualsInt(0x80000000 >>> j, rotateRightIntWithByteDistance(0x80000000, i));
506       expectEqualsInt((0x12345678 >>> j) | (0x12345678 << -j),
507                       rotateRightIntWithByteDistance(0x12345678, i));
508     }
509   }
510 
511 
main()512   public static void main() {
513     testRotateLeftBoolean();
514     testRotateLeftByte();
515     testRotateLeftShort();
516     testRotateLeftChar();
517     testRotateLeftInt();
518     testRotateLeftLong();
519 
520     testRotateRightBoolean();
521     testRotateRightByte();
522     testRotateRightShort();
523     testRotateRightChar();
524     testRotateRightInt();
525     testRotateRightLong();
526 
527     // Also exercise distance values with types other than int.
528     testRotateLeftIntWithByteDistance();
529     testRotateRightIntWithByteDistance();
530 
531     System.out.println("TestRotate passed");
532   }
533 
534 
expectEqualsInt(int expected, int result)535   private static void expectEqualsInt(int expected, int result) {
536     if (expected != result) {
537       throw new Error("Expected: " + expected + ", found: " + result);
538     }
539   }
540 
expectEqualsLong(long expected, long result)541   private static void expectEqualsLong(long expected, long result) {
542     if (expected != result) {
543       throw new Error("Expected: " + expected + ", found: " + result);
544     }
545   }
546 }
547