blob: 6d8b74d1eca645c52520677255b9e475d2a81640 [file] [log] [blame]
Scott Wakeling40a04bf2015-12-11 09:50:36 +00001/*
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
Vladimir Marko5bc80b92016-04-26 17:55:55 +0100178 /// CHECK-START: int Main.ror_int_constant_c_negc(int) instruction_simplifier_after_bce (before)
Scott Wakeling40a04bf2015-12-11 09:50:36 +0000179 /// CHECK: <<ArgValue:i\d+>> ParameterValue
180 /// CHECK: <<Const2:i\d+>> IntConstant 2
Vladimir Marko5bc80b92016-04-26 17:55:55 +0100181 /// CHECK: <<ConstNeg2:i\d+>> IntConstant -2
Scott Wakeling40a04bf2015-12-11 09:50:36 +0000182 /// 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
Vladimir Marko5bc80b92016-04-26 17:55:55 +0100187 /// CHECK-START: int Main.ror_int_constant_c_negc(int) instruction_simplifier_after_bce (after)
Scott Wakeling40a04bf2015-12-11 09:50:36 +0000188 /// 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
Vladimir Marko5bc80b92016-04-26 17:55:55 +0100193 /// CHECK-START: int Main.ror_int_constant_c_negc(int) instruction_simplifier_after_bce (after)
Scott Wakeling40a04bf2015-12-11 09:50:36 +0000194 /// CHECK-NOT: UShr
195 /// CHECK-NOT: Shl
196 public static int ror_int_constant_c_negc(int value) {
Vladimir Marko5bc80b92016-04-26 17:55:55 +0100197 return (value >>> 2) | (value << $opt$inline$IntConstantM2());
Scott Wakeling40a04bf2015-12-11 09:50:36 +0000198 }
199
Vladimir Marko5bc80b92016-04-26 17:55:55 +0100200 // 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
Scott Wakeling40a04bf2015-12-11 09:50:36 +0000204 // (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}