1/*
2 * Copyright (C) 2015 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
17public class Main {
18
19  public static void assertIntEquals(int expected, int actual) {
20    if (expected != actual) {
21      throw new Error("Expected: " + expected + ", found: " + actual);
22    }
23  }
24
25  public static void assertLongEquals(long expected, long actual) {
26    if (expected != actual) {
27      throw new Error("Expected: " + expected + ", found: " + actual);
28    }
29  }
30
31  /// CHECK-START: int Main.rotateIntegerRight(int, int) instruction_simplifier (before)
32  /// CHECK:          <<ArgValue:i\d+>>     ParameterValue
33  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
34  /// CHECK:          <<Invoke:i\d+>>       InvokeStaticOrDirect intrinsic:IntegerRotateRight
35
36  /// CHECK-START: int Main.rotateIntegerRight(int, int) instruction_simplifier (after)
37  /// CHECK:          <<ArgValue:i\d+>>     ParameterValue
38  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
39  /// CHECK:          <<Ror:i\d+>>          Ror [<<ArgValue>>,<<ArgDistance>>]
40  /// CHECK:                                Return [<<Ror>>]
41
42  /// CHECK-START: int Main.rotateIntegerRight(int, int) instruction_simplifier (after)
43  /// CHECK-NOT:      LoadClass
44  /// CHECK-NOT:      ClinitCheck
45  /// CHECK-NOT:      InvokeStaticOrDirect
46  public static int rotateIntegerRight(int value, int distance) {
47    return java.lang.Integer.rotateRight(value, distance);
48  }
49
50  /// CHECK-START: int Main.rotateIntegerLeft(int, int) instruction_simplifier (before)
51  /// CHECK:          <<ArgValue:i\d+>>     ParameterValue
52  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
53  /// CHECK:          <<Invoke:i\d+>>       InvokeStaticOrDirect intrinsic:IntegerRotateLeft
54
55  /// CHECK-START: int Main.rotateIntegerLeft(int, int) instruction_simplifier (after)
56  /// CHECK:          <<ArgValue:i\d+>>     ParameterValue
57  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
58  /// CHECK:          <<Neg:i\d+>>          Neg [<<ArgDistance>>]
59  /// CHECK:          <<Ror:i\d+>>          Ror [<<ArgValue>>,<<Neg>>]
60  /// CHECK:                                Return [<<Ror>>]
61
62  /// CHECK-START: int Main.rotateIntegerLeft(int, int) instruction_simplifier (after)
63  /// CHECK-NOT:      LoadClass
64  /// CHECK-NOT:      ClinitCheck
65  /// CHECK-NOT:      InvokeStaticOrDirect
66  public static int rotateIntegerLeft(int value, int distance) {
67    return java.lang.Integer.rotateLeft(value, distance);
68  }
69
70  /// CHECK-START: long Main.rotateLongRight(long, int) instruction_simplifier (before)
71  /// CHECK:          <<ArgValue:j\d+>>     ParameterValue
72  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
73  /// CHECK:          <<Invoke:j\d+>>       InvokeStaticOrDirect intrinsic:LongRotateRight
74
75  /// CHECK-START: long Main.rotateLongRight(long, int) instruction_simplifier (after)
76  /// CHECK:          <<ArgValue:j\d+>>     ParameterValue
77  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
78  /// CHECK:          <<Ror:j\d+>>          Ror [<<ArgValue>>,<<ArgDistance>>]
79  /// CHECK:                                Return [<<Ror>>]
80
81  /// CHECK-START: long Main.rotateLongRight(long, int) instruction_simplifier (after)
82  /// CHECK-NOT:      LoadClass
83  /// CHECK-NOT:      ClinitCheck
84  /// CHECK-NOT:      InvokeStaticOrDirect
85  public static long rotateLongRight(long value, int distance) {
86    return java.lang.Long.rotateRight(value, distance);
87  }
88
89  /// CHECK-START: long Main.rotateLongLeft(long, int) instruction_simplifier (before)
90  /// CHECK:          <<ArgValue:j\d+>>     ParameterValue
91  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
92  /// CHECK:          <<Invoke:j\d+>>       InvokeStaticOrDirect intrinsic:LongRotateLeft
93
94  /// CHECK-START: long Main.rotateLongLeft(long, int) instruction_simplifier (after)
95  /// CHECK:          <<ArgValue:j\d+>>     ParameterValue
96  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
97  /// CHECK:          <<Neg:i\d+>>          Neg [<<ArgDistance>>]
98  /// CHECK:          <<Ror:j\d+>>          Ror [<<ArgValue>>,<<Neg>>]
99  /// CHECK:                                Return [<<Ror>>]
100
101  /// CHECK-START: long Main.rotateLongLeft(long, int) instruction_simplifier (after)
102  /// CHECK-NOT:      LoadClass
103  /// CHECK-NOT:      ClinitCheck
104  /// CHECK-NOT:      InvokeStaticOrDirect
105  public static long rotateLongLeft(long value, int distance) {
106    return java.lang.Long.rotateLeft(value, distance);
107  }
108
109  //  (i >>> #distance) | (i << #(reg_bits - distance))
110
111  /// CHECK-START: int Main.ror_int_constant_c_c(int) instruction_simplifier (before)
112  /// CHECK:          <<ArgValue:i\d+>>     ParameterValue
113  /// CHECK:          <<Const2:i\d+>>       IntConstant 2
114  /// CHECK:          <<Const30:i\d+>>      IntConstant 30
115  /// CHECK-DAG:      <<UShr:i\d+>>         UShr [<<ArgValue>>,<<Const2>>]
116  /// CHECK-DAG:      <<Shl:i\d+>>          Shl [<<ArgValue>>,<<Const30>>]
117  /// CHECK:          <<Or:i\d+>>           Or [<<UShr>>,<<Shl>>]
118  /// CHECK:                                Return [<<Or>>]
119
120  /// CHECK-START: int Main.ror_int_constant_c_c(int) instruction_simplifier (after)
121  /// CHECK:          <<ArgValue:i\d+>>     ParameterValue
122  /// CHECK:          <<Const2:i\d+>>       IntConstant 2
123  /// CHECK:          <<Ror:i\d+>>          Ror [<<ArgValue>>,<<Const2>>]
124  /// CHECK:                                Return [<<Ror>>]
125
126  /// CHECK-START: int Main.ror_int_constant_c_c(int) instruction_simplifier (after)
127  /// CHECK-NOT:      UShr
128  /// CHECK-NOT:      Shl
129  public static int ror_int_constant_c_c(int value) {
130    return (value >>> 2) | (value << 30);
131  }
132
133  /// CHECK-START: int Main.ror_int_constant_c_c_0(int) instruction_simplifier (after)
134  /// CHECK:          <<ArgValue:i\d+>>     ParameterValue
135  /// CHECK:          <<Const2:i\d+>>       IntConstant 2
136  /// CHECK:          <<Ror:i\d+>>          Ror [<<ArgValue>>,<<Const2>>]
137  /// CHECK:                                Return [<<Ror>>]
138
139  /// CHECK-START: int Main.ror_int_constant_c_c_0(int) instruction_simplifier (after)
140  /// CHECK-NOT:      UShr
141  /// CHECK-NOT:      Shl
142  public static int ror_int_constant_c_c_0(int value) {
143    return (value >>> 2) | (value << 62);
144  }
145
146  //  (j >>> #distance) | (j << #(reg_bits - distance))
147
148  /// CHECK-START: long Main.ror_long_constant_c_c(long) instruction_simplifier (before)
149  /// CHECK:          <<ArgValue:j\d+>>     ParameterValue
150  /// CHECK:          <<Const2:i\d+>>       IntConstant 2
151  /// CHECK:          <<Const62:i\d+>>      IntConstant 62
152  /// CHECK-DAG:      <<UShr:j\d+>>         UShr [<<ArgValue>>,<<Const2>>]
153  /// CHECK-DAG:      <<Shl:j\d+>>          Shl [<<ArgValue>>,<<Const62>>]
154  /// CHECK:          <<Or:j\d+>>           Or [<<UShr>>,<<Shl>>]
155  /// CHECK:                                Return [<<Or>>]
156
157  /// CHECK-START: long Main.ror_long_constant_c_c(long) instruction_simplifier (after)
158  /// CHECK:          <<ArgValue:j\d+>>     ParameterValue
159  /// CHECK:          <<Const2:i\d+>>       IntConstant 2
160  /// CHECK:          <<Ror:j\d+>>          Ror [<<ArgValue>>,<<Const2>>]
161  /// CHECK:                                Return [<<Ror>>]
162
163  /// CHECK-START: long Main.ror_long_constant_c_c(long) instruction_simplifier (after)
164  /// CHECK-NOT:      UShr
165  /// CHECK-NOT:      Shl
166  public static long ror_long_constant_c_c(long value) {
167    return (value >>> 2) | (value << 62);
168  }
169
170  /// CHECK-START: long Main.ror_long_constant_c_c_0(long) instruction_simplifier (after)
171  /// CHECK-NOT:      Ror
172  public static long ror_long_constant_c_c_0(long value) {
173    return (value >>> 2) | (value << 30);
174  }
175
176  //  (i >>> #distance) | (i << #-distance)
177
178  /// CHECK-START: int Main.ror_int_constant_c_negc(int) instruction_simplifier$after_inlining (before)
179  /// CHECK:          <<ArgValue:i\d+>>     ParameterValue
180  /// CHECK:          <<Const2:i\d+>>       IntConstant 2
181  /// CHECK:          <<ConstNeg2:i\d+>>    IntConstant -2
182  /// CHECK-DAG:      <<UShr:i\d+>>         UShr [<<ArgValue>>,<<Const2>>]
183  /// CHECK-DAG:      <<Shl:i\d+>>          Shl [<<ArgValue>>,<<ConstNeg2>>]
184  /// CHECK:          <<Or:i\d+>>           Or [<<UShr>>,<<Shl>>]
185  /// CHECK:                                Return [<<Or>>]
186
187  /// CHECK-START: int Main.ror_int_constant_c_negc(int) instruction_simplifier$after_inlining (after)
188  /// CHECK:          <<ArgValue:i\d+>>     ParameterValue
189  /// CHECK:          <<Const2:i\d+>>       IntConstant 2
190  /// CHECK:          <<Ror:i\d+>>          Ror [<<ArgValue>>,<<Const2>>]
191  /// CHECK:                                Return [<<Ror>>]
192
193  /// CHECK-START: int Main.ror_int_constant_c_negc(int) instruction_simplifier$after_inlining (after)
194  /// CHECK-NOT:      UShr
195  /// CHECK-NOT:      Shl
196  public static int ror_int_constant_c_negc(int value) {
197    return (value >>> 2) | (value << $opt$inline$IntConstantM2());
198  }
199
200  // Hiding constants outside the range [0, 32) used for int shifts from Jack.
201  // (Jack extracts only the low 5 bits.)
202  public static int $opt$inline$IntConstantM2() { return -2; }
203
204  //  (j >>> #distance) | (j << #-distance)
205
206  /// CHECK-START: long Main.ror_long_constant_c_negc(long) instruction_simplifier (before)
207  /// CHECK:          <<ArgValue:j\d+>>     ParameterValue
208  /// CHECK:          <<Const2:i\d+>>       IntConstant 2
209  /// CHECK:          <<ConstNeg2:i\d+>>    IntConstant -2
210  /// CHECK-DAG:      <<UShr:j\d+>>         UShr [<<ArgValue>>,<<Const2>>]
211  /// CHECK-DAG:      <<Shl:j\d+>>          Shl [<<ArgValue>>,<<ConstNeg2>>]
212  /// CHECK:          <<Or:j\d+>>           Or [<<UShr>>,<<Shl>>]
213  /// CHECK:                                Return [<<Or>>]
214
215  /// CHECK-START: long Main.ror_long_constant_c_negc(long) instruction_simplifier (after)
216  /// CHECK:          <<ArgValue:j\d+>>     ParameterValue
217  /// CHECK:          <<Const2:i\d+>>       IntConstant 2
218  /// CHECK:          <<Ror:j\d+>>          Ror [<<ArgValue>>,<<Const2>>]
219  /// CHECK:                                Return [<<Ror>>]
220
221  /// CHECK-START: long Main.ror_long_constant_c_negc(long) instruction_simplifier (after)
222  /// CHECK-NOT:      UShr
223  /// CHECK-NOT:      Shl
224  public static long ror_long_constant_c_negc(long value) {
225    return (value >>> 2) | (value << -2);
226  }
227
228  //  (i >>> distance) | (i << (#reg_bits - distance)
229
230  /// CHECK-START: int Main.ror_int_reg_v_csubv(int, int) instruction_simplifier (before)
231  /// CHECK:          <<ArgValue:i\d+>>     ParameterValue
232  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
233  /// CHECK:          <<Const32:i\d+>>      IntConstant 32
234  /// CHECK-DAG:      <<UShr:i\d+>>         UShr [<<ArgValue>>,<<ArgDistance>>]
235  /// CHECK-DAG:      <<Sub:i\d+>>          Sub [<<Const32>>,<<ArgDistance>>]
236  /// CHECK-DAG:      <<Shl:i\d+>>          Shl [<<ArgValue>>,<<Sub>>]
237  /// CHECK:          <<Or:i\d+>>           Or [<<UShr>>,<<Shl>>]
238  /// CHECK:                                Return [<<Or>>]
239
240  /// CHECK-START: int Main.ror_int_reg_v_csubv(int, int) instruction_simplifier (after)
241  /// CHECK:          <<ArgValue:i\d+>>     ParameterValue
242  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
243  /// CHECK:          <<Ror:i\d+>>          Ror [<<ArgValue>>,<<ArgDistance>>]
244  /// CHECK:                                Return [<<Ror>>]
245
246  /// CHECK-START: int Main.ror_int_reg_v_csubv(int, int) instruction_simplifier (after)
247  /// CHECK-NOT:      UShr
248  /// CHECK-NOT:      Shl
249  /// CHECK-NOT:      Sub
250  public static int ror_int_reg_v_csubv(int value, int distance) {
251    return (value >>> distance) | (value << (32 - distance));
252  }
253
254  //  (distance = x - y)
255  //  (i >>> distance) | (i << (#reg_bits - distance)
256
257  /// CHECK-START: int Main.ror_int_subv_csubv(int, int, int) instruction_simplifier (before)
258  /// CHECK:          <<ArgValue:i\d+>>     ParameterValue
259  /// CHECK:          <<ArgX:i\d+>>         ParameterValue
260  /// CHECK:          <<ArgY:i\d+>>         ParameterValue
261  /// CHECK:          <<Const32:i\d+>>      IntConstant 32
262  /// CHECK-DAG:      <<SubDistance:i\d+>>  Sub [<<ArgX>>,<<ArgY>>]
263  /// CHECK-DAG:      <<Sub32:i\d+>>        Sub [<<Const32>>,<<SubDistance>>]
264  /// CHECK-DAG:      <<Shl:i\d+>>          Shl [<<ArgValue>>,<<Sub32>>]
265  /// CHECK-DAG:      <<UShr:i\d+>>         UShr [<<ArgValue>>,<<SubDistance>>]
266  /// CHECK:          <<Or:i\d+>>           Or [<<UShr>>,<<Shl>>]
267  /// CHECK:                                Return [<<Or>>]
268
269  /// CHECK-START: int Main.ror_int_subv_csubv(int, int, int) instruction_simplifier (after)
270  /// CHECK:          <<ArgValue:i\d+>>     ParameterValue
271  /// CHECK:          <<ArgX:i\d+>>         ParameterValue
272  /// CHECK:          <<ArgY:i\d+>>         ParameterValue
273  /// CHECK:          <<SubDistance:i\d+>>  Sub [<<ArgX>>,<<ArgY>>]
274  /// CHECK:          <<Ror:i\d+>>          Ror [<<ArgValue>>,<<SubDistance>>]
275  /// CHECK:                                Return [<<Ror>>]
276
277  /// CHECK-START: int Main.ror_int_subv_csubv(int, int, int) instruction_simplifier (after)
278  /// CHECK:          Sub
279  /// CHECK-NOT:      Sub
280
281  /// CHECK-START: int Main.ror_int_subv_csubv(int, int, int) instruction_simplifier (after)
282  /// CHECK-NOT:      UShr
283  /// CHECK-NOT:      Shl
284  public static int ror_int_subv_csubv(int value, int x, int y) {
285    int distance = x - y;
286    return (value >>> distance) | (value << (32 - distance));
287  }
288
289  /// CHECK-START: int Main.ror_int_subv_csubv_env(int, int, int) instruction_simplifier (before)
290  /// CHECK:          <<ArgValue:i\d+>>     ParameterValue
291  /// CHECK:          <<ArgX:i\d+>>         ParameterValue
292  /// CHECK:          <<ArgY:i\d+>>         ParameterValue
293  /// CHECK:          <<Const32:i\d+>>      IntConstant 32
294  /// CHECK-DAG:      <<SubDistance:i\d+>>  Sub [<<ArgX>>,<<ArgY>>]
295  /// CHECK-DAG:      <<Sub32:i\d+>>        Sub [<<Const32>>,<<SubDistance>>]
296  /// CHECK-DAG:      <<UShr:i\d+>>         UShr [<<ArgValue>>,<<SubDistance>>]
297  /// CHECK-DAG:      <<Shl:i\d+>>          Shl [<<ArgValue>>,<<Sub32>>]
298  /// CHECK:          <<Or:i\d+>>           Or [<<UShr>>,<<Shl>>]
299  /// CHECK:          <<Add:i\d+>>          Add [<<Or>>,<<Sub32>>]
300  /// CHECK:                                Return [<<Add>>]
301
302  /// CHECK-START: int Main.ror_int_subv_csubv_env(int, int, int) instruction_simplifier (after)
303  /// CHECK:          <<ArgValue:i\d+>>     ParameterValue
304  /// CHECK:          <<ArgX:i\d+>>         ParameterValue
305  /// CHECK:          <<ArgY:i\d+>>         ParameterValue
306  /// CHECK:          <<Const32:i\d+>>      IntConstant 32
307  /// CHECK-DAG:      <<SubDistance:i\d+>>  Sub [<<ArgX>>,<<ArgY>>]
308  /// CHECK-DAG:      <<Sub32:i\d+>>        Sub [<<Const32>>,<<SubDistance>>]
309  /// CHECK:          <<Ror:i\d+>>          Ror [<<ArgValue>>,<<SubDistance>>]
310  /// CHECK:          <<Add:i\d+>>          Add [<<Ror>>,<<Sub32>>]
311  /// CHECK:                                Return [<<Add>>]
312
313  /// CHECK-START: int Main.ror_int_subv_csubv_env(int, int, int) instruction_simplifier (after)
314  /// CHECK-NOT:      UShr
315  /// CHECK-NOT:      Shl
316  public static int ror_int_subv_csubv_env(int value, int x, int y) {
317    int distance = x - y;
318    int bits_minus_dist = 32 - distance;
319    return ((value >>> distance) | (value << bits_minus_dist)) + bits_minus_dist;
320  }
321
322  //  (j >>> distance) | (j << (#reg_bits - distance)
323
324  /// CHECK-START: long Main.ror_long_reg_v_csubv(long, int) instruction_simplifier (before)
325  /// CHECK:          <<ArgValue:j\d+>>     ParameterValue
326  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
327  /// CHECK:          <<Const64:i\d+>>      IntConstant 64
328  /// CHECK-DAG:      <<UShr:j\d+>>         UShr [<<ArgValue>>,<<ArgDistance>>]
329  /// CHECK-DAG:      <<Sub:i\d+>>          Sub [<<Const64>>,<<ArgDistance>>]
330  /// CHECK-DAG:      <<Shl:j\d+>>          Shl [<<ArgValue>>,<<Sub>>]
331  /// CHECK:          <<Or:j\d+>>           Or [<<UShr>>,<<Shl>>]
332  /// CHECK:                                Return [<<Or>>]
333
334  /// CHECK-START: long Main.ror_long_reg_v_csubv(long, int) instruction_simplifier (after)
335  /// CHECK:          <<ArgValue:j\d+>>     ParameterValue
336  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
337  /// CHECK:          <<Ror:j\d+>>          Ror [<<ArgValue>>,<<ArgDistance>>]
338  /// CHECK:                                Return [<<Ror>>]
339
340  /// CHECK-START: long Main.ror_long_reg_v_csubv(long, int) instruction_simplifier (after)
341  /// CHECK-NOT:      UShr
342  /// CHECK-NOT:      Shl
343  /// CHECK-NOT:      Sub
344  public static long ror_long_reg_v_csubv(long value, int distance) {
345    return (value >>> distance) | (value << (64 - distance));
346  }
347
348  /// CHECK-START: long Main.ror_long_reg_v_csubv_0(long, int) instruction_simplifier (after)
349  /// CHECK-NOT:      Ror
350  public static long ror_long_reg_v_csubv_0(long value, int distance) {
351    return (value >>> distance) | (value << (32 - distance));
352  }
353
354  /// CHECK-START: long Main.ror_long_subv_csubv_0(long, int, int) instruction_simplifier (after)
355  /// CHECK-NOT:      Ror
356  public static long ror_long_subv_csubv_0(long value, int x, int y) {
357    int distance = x - y;
358    return (value >>> distance) | (value << (32 - distance));
359  }
360
361  //  (i >>> (#reg_bits - distance)) | (i << distance)
362
363  /// CHECK-START: int Main.rol_int_reg_csubv_v(int, int) instruction_simplifier (before)
364  /// CHECK:          <<ArgValue:i\d+>>     ParameterValue
365  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
366  /// CHECK:          <<Const32:i\d+>>      IntConstant 32
367  /// CHECK-DAG:      <<Sub:i\d+>>          Sub [<<Const32>>,<<ArgDistance>>]
368  /// CHECK-DAG:      <<UShr:i\d+>>         UShr [<<ArgValue>>,<<Sub>>]
369  /// CHECK-DAG:      <<Shl:i\d+>>          Shl [<<ArgValue>>,<<ArgDistance>>]
370  /// CHECK:          <<Or:i\d+>>           Or [<<UShr>>,<<Shl>>]
371  /// CHECK:                                Return [<<Or>>]
372
373  /// CHECK-START: int Main.rol_int_reg_csubv_v(int, int) instruction_simplifier (after)
374  /// CHECK:          <<ArgValue:i\d+>>     ParameterValue
375  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
376  /// CHECK:          <<Const32:i\d+>>      IntConstant 32
377  /// CHECK:          <<Sub:i\d+>>          Sub [<<Const32>>,<<ArgDistance>>]
378  /// CHECK:          <<Ror:i\d+>>          Ror [<<ArgValue>>,<<Sub>>]
379  /// CHECK:                                Return [<<Ror>>]
380
381  /// CHECK-START: int Main.rol_int_reg_csubv_v(int, int) instruction_simplifier (after)
382  /// CHECK-NOT:      UShr
383  /// CHECK-NOT:      Shl
384  public static int rol_int_reg_csubv_v(int value, int distance) {
385    return (value >>> (32 - distance)) | (value << distance);
386  }
387
388  //  (distance = x - y)
389  //  (i >>> (#reg_bits - distance)) | (i << distance)
390
391  /// CHECK-START: int Main.rol_int_csubv_subv(int, int, int) instruction_simplifier (before)
392  /// CHECK:          <<ArgValue:i\d+>>     ParameterValue
393  /// CHECK:          <<ArgX:i\d+>>         ParameterValue
394  /// CHECK:          <<ArgY:i\d+>>         ParameterValue
395  /// CHECK:          <<Const32:i\d+>>      IntConstant 32
396  /// CHECK-DAG:      <<SubDistance:i\d+>>  Sub [<<ArgX>>,<<ArgY>>]
397  /// CHECK-DAG:      <<Sub32:i\d+>>        Sub [<<Const32>>,<<SubDistance>>]
398  /// CHECK-DAG:      <<Shl:i\d+>>          Shl [<<ArgValue>>,<<SubDistance>>]
399  /// CHECK-DAG:      <<UShr:i\d+>>         UShr [<<ArgValue>>,<<Sub32>>]
400  /// CHECK:          <<Or:i\d+>>           Or [<<UShr>>,<<Shl>>]
401  /// CHECK:                                Return [<<Or>>]
402
403  /// CHECK-START: int Main.rol_int_csubv_subv(int, int, int) instruction_simplifier (after)
404  /// CHECK:          <<ArgValue:i\d+>>     ParameterValue
405  /// CHECK:          <<ArgX:i\d+>>         ParameterValue
406  /// CHECK:          <<ArgY:i\d+>>         ParameterValue
407  /// CHECK:          <<Const32:i\d+>>      IntConstant 32
408  /// CHECK:          <<SubDistance:i\d+>>  Sub [<<ArgX>>,<<ArgY>>]
409  /// CHECK:          <<Sub:i\d+>>          Sub [<<Const32>>,<<SubDistance>>]
410  /// CHECK:          <<Ror:i\d+>>          Ror [<<ArgValue>>,<<Sub>>]
411  /// CHECK:                                Return [<<Ror>>]
412
413  /// CHECK-START: int Main.rol_int_csubv_subv(int, int, int) instruction_simplifier (after)
414  /// CHECK:          Sub
415  /// CHECK:          Sub
416
417  /// CHECK-START: int Main.rol_int_csubv_subv(int, int, int) instruction_simplifier (after)
418  /// CHECK-NOT:      UShr
419  /// CHECK-NOT:      Shl
420  public static int rol_int_csubv_subv(int value, int x, int y) {
421    int distance = x - y;
422    return (value >>> (32 - distance)) | (value << distance);
423  }
424
425  //  (j >>> (#reg_bits - distance)) | (j << distance)
426
427  /// CHECK-START: long Main.rol_long_reg_csubv_v(long, int) instruction_simplifier (before)
428  /// CHECK:          <<ArgValue:j\d+>>     ParameterValue
429  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
430  /// CHECK:          <<Const64:i\d+>>      IntConstant 64
431  /// CHECK-DAG:      <<Sub:i\d+>>          Sub [<<Const64>>,<<ArgDistance>>]
432  /// CHECK-DAG:      <<UShr:j\d+>>         UShr [<<ArgValue>>,<<Sub>>]
433  /// CHECK-DAG:      <<Shl:j\d+>>          Shl [<<ArgValue>>,<<ArgDistance>>]
434  /// CHECK:          <<Or:j\d+>>           Or [<<UShr>>,<<Shl>>]
435  /// CHECK:                                Return [<<Or>>]
436
437  /// CHECK-START: long Main.rol_long_reg_csubv_v(long, int) instruction_simplifier (after)
438  /// CHECK:          <<ArgValue:j\d+>>     ParameterValue
439  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
440  /// CHECK:          <<Const64:i\d+>>      IntConstant 64
441  /// CHECK:          <<Sub:i\d+>>          Sub [<<Const64>>,<<ArgDistance>>]
442  /// CHECK:          <<Ror:j\d+>>          Ror [<<ArgValue>>,<<Sub>>]
443  /// CHECK:                                Return [<<Ror>>]
444
445  /// CHECK-START: long Main.rol_long_reg_csubv_v(long, int) instruction_simplifier (after)
446  /// CHECK-NOT:      UShr
447  /// CHECK-NOT:      Shl
448  public static long rol_long_reg_csubv_v(long value, int distance) {
449    return (value >>> (64 - distance)) | (value << distance);
450  }
451
452  /// CHECK-START: long Main.rol_long_reg_csubv_v_0(long, int) instruction_simplifier (after)
453  /// CHECK-NOT:      Ror
454  public static long rol_long_reg_csubv_v_0(long value, int distance) {
455    return (value >>> (32 - distance)) | (value << distance);
456  }
457
458  //  (i >>> distance) | (i << -distance) (i.e. libcore's Integer.rotateRight)
459
460  /// CHECK-START: int Main.ror_int_reg_v_negv(int, int) instruction_simplifier (before)
461  /// CHECK:          <<ArgValue:i\d+>>     ParameterValue
462  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
463  /// CHECK-DAG:      <<UShr:i\d+>>         UShr [<<ArgValue>>,<<ArgDistance>>]
464  /// CHECK-DAG:      <<Neg:i\d+>>          Neg [<<ArgDistance>>]
465  /// CHECK-DAG:      <<Shl:i\d+>>          Shl [<<ArgValue>>,<<Neg>>]
466  /// CHECK:          <<Or:i\d+>>           Or [<<UShr>>,<<Shl>>]
467  /// CHECK:                                Return [<<Or>>]
468
469  /// CHECK-START: int Main.ror_int_reg_v_negv(int, int) instruction_simplifier (after)
470  /// CHECK:          <<ArgValue:i\d+>>     ParameterValue
471  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
472  /// CHECK:          <<Ror:i\d+>>          Ror [<<ArgValue>>,<<ArgDistance>>]
473  /// CHECK:                                Return [<<Ror>>]
474
475  /// CHECK-START: int Main.ror_int_reg_v_negv(int, int) instruction_simplifier (after)
476  /// CHECK-NOT:      UShr
477  /// CHECK-NOT:      Shl
478  /// CHECK-NOT:      Neg
479  public static int ror_int_reg_v_negv(int value, int distance) {
480    return (value >>> distance) | (value << -distance);
481  }
482
483  /// CHECK-START: int Main.ror_int_reg_v_negv_env(int, int) instruction_simplifier (before)
484  /// CHECK:          <<ArgValue:i\d+>>     ParameterValue
485  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
486  /// CHECK-DAG:      <<Neg:i\d+>>          Neg [<<ArgDistance>>]
487  /// CHECK-DAG:      <<UShr:i\d+>>         UShr [<<ArgValue>>,<<ArgDistance>>]
488  /// CHECK-DAG:      <<Shl:i\d+>>          Shl [<<ArgValue>>,<<Neg>>]
489  /// CHECK:          <<Or:i\d+>>           Or [<<UShr>>,<<Shl>>]
490  /// CHECK:          <<Add:i\d+>>          Add [<<Or>>,<<Neg>>]
491  /// CHECK:                                Return [<<Add>>]
492
493  /// CHECK-START: int Main.ror_int_reg_v_negv_env(int, int) instruction_simplifier (after)
494  /// CHECK:          <<ArgValue:i\d+>>     ParameterValue
495  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
496  /// CHECK:          <<Ror:i\d+>>          Ror [<<ArgValue>>,<<ArgDistance>>]
497  /// CHECK:          <<Sub:i\d+>>          Sub [<<Ror>>,<<ArgDistance>>]
498  /// CHECK:                                Return [<<Sub>>]
499
500  /// CHECK-START: int Main.ror_int_reg_v_negv_env(int, int) instruction_simplifier (after)
501  /// CHECK-NOT:      UShr
502  /// CHECK-NOT:      Shl
503  public static int ror_int_reg_v_negv_env(int value, int distance) {
504    int neg_distance = -distance;
505    return ((value >>> distance) | (value << neg_distance)) + neg_distance;
506  }
507
508  //  (j >>> distance) | (j << -distance) (i.e. libcore's Long.rotateRight)
509
510  /// CHECK-START: long Main.ror_long_reg_v_negv(long, int) instruction_simplifier (before)
511  /// CHECK:          <<ArgValue:j\d+>>     ParameterValue
512  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
513  /// CHECK-DAG:      <<UShr:j\d+>>         UShr [<<ArgValue>>,<<ArgDistance>>]
514  /// CHECK-DAG:      <<Neg:i\d+>>          Neg [<<ArgDistance>>]
515  /// CHECK-DAG:      <<Shl:j\d+>>          Shl [<<ArgValue>>,<<Neg>>]
516  /// CHECK:          <<Or:j\d+>>           Or [<<UShr>>,<<Shl>>]
517  /// CHECK:                                Return [<<Or>>]
518
519  /// CHECK-START: long Main.ror_long_reg_v_negv(long, int) instruction_simplifier (after)
520  /// CHECK:          <<ArgValue:j\d+>>     ParameterValue
521  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
522  /// CHECK:          <<Ror:j\d+>>          Ror [<<ArgValue>>,<<ArgDistance>>]
523  /// CHECK:                                Return [<<Ror>>]
524
525  /// CHECK-START: long Main.ror_long_reg_v_negv(long, int) instruction_simplifier (after)
526  /// CHECK-NOT:      UShr
527  /// CHECK-NOT:      Shl
528  /// CHECK-NOT:      Neg
529  public static long ror_long_reg_v_negv(long value, int distance) {
530    return (value >>> distance) | (value << -distance);
531  }
532
533  //  (i << distance) | (i >>> -distance) (i.e. libcore's Integer.rotateLeft)
534
535  /// CHECK-START: int Main.rol_int_reg_negv_v(int, int) instruction_simplifier (before)
536  /// CHECK:          <<ArgValue:i\d+>>     ParameterValue
537  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
538  /// CHECK-DAG:      <<Neg:i\d+>>          Neg [<<ArgDistance>>]
539  /// CHECK-DAG:      <<UShr:i\d+>>         UShr [<<ArgValue>>,<<Neg>>]
540  /// CHECK-DAG:      <<Shl:i\d+>>          Shl [<<ArgValue>>,<<ArgDistance>>]
541  /// CHECK:          <<Or:i\d+>>           Or [<<Shl>>,<<UShr>>]
542  /// CHECK:                                Return [<<Or>>]
543
544  /// CHECK-START: int Main.rol_int_reg_negv_v(int, int) instruction_simplifier (after)
545  /// CHECK:          <<ArgValue:i\d+>>     ParameterValue
546  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
547  /// CHECK:          <<Neg:i\d+>>          Neg [<<ArgDistance>>]
548  /// CHECK:          <<Ror:i\d+>>          Ror [<<ArgValue>>,<<Neg>>]
549  /// CHECK:                                Return [<<Ror>>]
550
551  /// CHECK-START: int Main.rol_int_reg_negv_v(int, int) instruction_simplifier (after)
552  /// CHECK-NOT:      UShr
553  /// CHECK-NOT:      Shl
554  public static int rol_int_reg_negv_v(int value, int distance) {
555    return (value << distance) | (value >>> -distance);
556  }
557
558  //  (j << distance) | (j >>> -distance) (i.e. libcore's Long.rotateLeft)
559
560  /// CHECK-START: long Main.rol_long_reg_negv_v(long, int) instruction_simplifier (before)
561  /// CHECK:          <<ArgValue:j\d+>>     ParameterValue
562  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
563  /// CHECK-DAG:      <<Neg:i\d+>>          Neg [<<ArgDistance>>]
564  /// CHECK-DAG:      <<UShr:j\d+>>         UShr [<<ArgValue>>,<<Neg>>]
565  /// CHECK-DAG:      <<Shl:j\d+>>          Shl [<<ArgValue>>,<<ArgDistance>>]
566  /// CHECK:          <<Or:j\d+>>           Or [<<Shl>>,<<UShr>>]
567  /// CHECK:                                Return [<<Or>>]
568
569  /// CHECK-START: long Main.rol_long_reg_negv_v(long, int) instruction_simplifier (after)
570  /// CHECK:          <<ArgValue:j\d+>>     ParameterValue
571  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
572  /// CHECK:          <<Neg:i\d+>>          Neg [<<ArgDistance>>]
573  /// CHECK:          <<Ror:j\d+>>          Ror [<<ArgValue>>,<<Neg>>]
574  /// CHECK:                                Return [<<Ror>>]
575
576  /// CHECK-START: long Main.rol_long_reg_negv_v(long, int) instruction_simplifier (after)
577  /// CHECK-NOT:      UShr
578  /// CHECK-NOT:      Shl
579  public static long rol_long_reg_negv_v(long value, int distance) {
580    return (value << distance) | (value >>> -distance);
581  }
582
583  //  (j << distance) + (j >>> -distance)
584
585  /// CHECK-START: long Main.rol_long_reg_v_negv_add(long, int) instruction_simplifier (before)
586  /// CHECK:          <<ArgValue:j\d+>>     ParameterValue
587  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
588  /// CHECK-DAG:      <<Neg:i\d+>>          Neg [<<ArgDistance>>]
589  /// CHECK-DAG:      <<UShr:j\d+>>         UShr [<<ArgValue>>,<<Neg>>]
590  /// CHECK-DAG:      <<Shl:j\d+>>          Shl [<<ArgValue>>,<<ArgDistance>>]
591  /// CHECK:          <<Add:j\d+>>          Add [<<Shl>>,<<UShr>>]
592  /// CHECK:                                Return [<<Add>>]
593
594  /// CHECK-START: long Main.rol_long_reg_v_negv_add(long, int) instruction_simplifier (after)
595  /// CHECK:          <<ArgValue:j\d+>>     ParameterValue
596  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
597  /// CHECK:          <<Neg:i\d+>>          Neg [<<ArgDistance>>]
598  /// CHECK:          <<Ror:j\d+>>          Ror [<<ArgValue>>,<<Neg>>]
599  /// CHECK:                                Return [<<Ror>>]
600
601  /// CHECK-START: long Main.rol_long_reg_v_negv_add(long, int) instruction_simplifier (after)
602  /// CHECK-NOT:  Add
603  /// CHECK-NOT:  Shl
604  /// CHECK-NOT:  UShr
605  public static long rol_long_reg_v_negv_add(long value, int distance) {
606    return (value << distance) + (value >>> -distance);
607  }
608
609  //  (j << distance) ^ (j >>> -distance)
610
611  /// CHECK-START: long Main.rol_long_reg_v_negv_xor(long, int) instruction_simplifier (before)
612  /// CHECK:          <<ArgValue:j\d+>>     ParameterValue
613  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
614  /// CHECK-DAG:      <<Neg:i\d+>>          Neg [<<ArgDistance>>]
615  /// CHECK-DAG:      <<UShr:j\d+>>         UShr [<<ArgValue>>,<<Neg>>]
616  /// CHECK-DAG:      <<Shl:j\d+>>          Shl [<<ArgValue>>,<<ArgDistance>>]
617  /// CHECK:          <<Xor:j\d+>>          Xor [<<Shl>>,<<UShr>>]
618  /// CHECK:                                Return [<<Xor>>]
619
620  /// CHECK-START: long Main.rol_long_reg_v_negv_xor(long, int) instruction_simplifier (after)
621  /// CHECK:          <<ArgValue:j\d+>>     ParameterValue
622  /// CHECK:          <<ArgDistance:i\d+>>  ParameterValue
623  /// CHECK:          <<Neg:i\d+>>          Neg [<<ArgDistance>>]
624  /// CHECK:          <<Ror:j\d+>>          Ror [<<ArgValue>>,<<Neg>>]
625  /// CHECK:                                Return [<<Ror>>]
626
627  /// CHECK-START: long Main.rol_long_reg_v_negv_xor(long, int) instruction_simplifier (after)
628  /// CHECK-NOT:  Xor
629  /// CHECK-NOT:  Shl
630  /// CHECK-NOT:  UShr
631  public static long rol_long_reg_v_negv_xor(long value, int distance) {
632    return (value << distance) ^ (value >>> -distance);
633  }
634
635  public static void main(String[] args) {
636    assertIntEquals(2, ror_int_constant_c_c(8));
637    assertIntEquals(2, ror_int_constant_c_c_0(8));
638    assertLongEquals(2L, ror_long_constant_c_c(8L));
639
640    assertIntEquals(2, ror_int_constant_c_negc(8));
641    assertLongEquals(2L, ror_long_constant_c_negc(8L));
642
643    assertIntEquals(2, ror_int_reg_v_csubv(8, 2));
644    assertLongEquals(2L, ror_long_reg_v_csubv(8L, 2));
645
646    assertIntEquals(2, ror_int_subv_csubv(8, 2, 0));
647    assertIntEquals(32, ror_int_subv_csubv_env(8, 2, 0));
648    assertIntEquals(32, rol_int_csubv_subv(8, 2, 0));
649
650    assertIntEquals(32, rol_int_reg_csubv_v(8, 2));
651    assertLongEquals(32L, rol_long_reg_csubv_v(8L, 2));
652
653    assertIntEquals(2, ror_int_reg_v_negv(8, 2));
654    assertIntEquals(0, ror_int_reg_v_negv_env(8, 2));
655    assertLongEquals(2L, ror_long_reg_v_negv(8L, 2));
656
657    assertIntEquals(32, rol_int_reg_negv_v(8, 2));
658    assertLongEquals(32L, rol_long_reg_negv_v(8L, 2));
659
660    assertLongEquals(32L, rol_long_reg_v_negv_add(8L, 2));
661    assertLongEquals(32L, rol_long_reg_v_negv_xor(8L, 2));
662  }
663}
664