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