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 result)19   public static void assertIntEquals(int expected, int result) {
20     if (expected != result) {
21       throw new Error("Expected: " + expected + ", found: " + result);
22     }
23   }
24 
assertLongEquals(long expected, long result)25   public static void assertLongEquals(long expected, long result) {
26     if (expected != result) {
27       throw new Error("Expected: " + expected + ", found: " + result);
28     }
29   }
30 
31   /// CHECK-START-ARM: int Main.and254(int) disassembly (after)
32   /// CHECK-NOT:            movs {{r\d+}}, #254
33   /// CHECK:                and {{r\d+}}, {{r\d+}}, #0xfe
34 
and254(int arg)35   public static int and254(int arg) {
36     return arg & 254;
37   }
38 
39   /// CHECK-START-ARM: int Main.and255(int) disassembly (after)
40   /// CHECK-NOT:            movs {{r\d+}}, #255
41   /// CHECK:                ubfx {{r\d+}}, {{r\d+}}, #0, #8
42 
and255(int arg)43   public static int and255(int arg) {
44     return arg & 255;
45   }
46 
47   /// CHECK-START-ARM: int Main.and511(int) disassembly (after)
48   /// CHECK:                ubfx {{r\d+}}, {{r\d+}}, #0, #9
49 
and511(int arg)50   public static int and511(int arg) {
51     return arg & 511;
52   }
53 
54   /// CHECK-START-ARM: int Main.andF00D(int) disassembly (after)
55   /// CHECK:                mov {{r\d+}}, #61453
56   /// CHECK:                and{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}}
57 
andF00D(int arg)58   public static int andF00D(int arg) {
59     return arg & 0xF00D;
60   }
61 
62   /// CHECK-START-ARM: int Main.andNot15(int) disassembly (after)
63   /// CHECK-NOT:            mvn {{r\d+}}, #15
64   /// CHECK:                bic {{r\d+}}, {{r\d+}}, #0xf
65 
andNot15(int arg)66   public static int andNot15(int arg) {
67     return arg & ~15;
68   }
69 
70   /// CHECK-START-ARM: int Main.or255(int) disassembly (after)
71   /// CHECK-NOT:            movs {{r\d+}}, #255
72   /// CHECK:                orr {{r\d+}}, {{r\d+}}, #0xff
73 
or255(int arg)74   public static int or255(int arg) {
75     return arg | 255;
76   }
77 
78   /// CHECK-START-ARM: int Main.or511(int) disassembly (after)
79   /// CHECK:                mov {{r\d+}}, #511
80   /// CHECK:                orr{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}}
81 
or511(int arg)82   public static int or511(int arg) {
83     return arg | 511;
84   }
85 
86   /// CHECK-START-ARM: int Main.orNot15(int) disassembly (after)
87   /// CHECK-NOT:            mvn {{r\d+}}, #15
88   /// CHECK:                orn {{r\d+}}, {{r\d+}}, #0xf
89 
orNot15(int arg)90   public static int orNot15(int arg) {
91     return arg | ~15;
92   }
93 
94   /// CHECK-START-ARM: int Main.xor255(int) disassembly (after)
95   /// CHECK-NOT:            movs {{r\d+}}, #255
96   /// CHECK:                eor {{r\d+}}, {{r\d+}}, #0xff
97 
xor255(int arg)98   public static int xor255(int arg) {
99     return arg ^ 255;
100   }
101 
102   /// CHECK-START-ARM: int Main.xor511(int) disassembly (after)
103   /// CHECK:                mov {{r\d+}}, #511
104   /// CHECK:                eor{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}}
105 
xor511(int arg)106   public static int xor511(int arg) {
107     return arg ^ 511;
108   }
109 
110   /// CHECK-START-ARM: int Main.xorNot15(int) disassembly (after)
111   /// CHECK:                mvn {{r\d+}}, #15
112   /// CHECK:                eor{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}}
113 
xorNot15(int arg)114   public static int xorNot15(int arg) {
115     return arg ^ ~15;
116   }
117 
118   /// CHECK-START-ARM: long Main.and255(long) disassembly (after)
119   /// CHECK-NOT:            movs {{r\d+}}, #255
120   /// CHECK-NOT:            and{{(\.w)?}}
121   /// CHECK-NOT:            bic{{(\.w)?}}
122   /// CHECK-DAG:            and {{r\d+}}, {{r\d+}}, #0xff
123   /// CHECK-DAG:            mov{{s?}} {{r\d+}}, #0
124   /// CHECK-NOT:            and{{(\.w)?}}
125   /// CHECK-NOT:            bic{{(\.w)?}}
126 
and255(long arg)127   public static long and255(long arg) {
128     return arg & 255L;
129   }
130 
131   /// CHECK-START-ARM: long Main.and511(long) disassembly (after)
132   /// CHECK:                ubfx {{r\d+}}, {{r\d+}}, #0, #9
133   /// CHECK-NEXT:           mov{{s?}} {{r\d+}}, #0
134   /// CHECK-NOT:            and{{(\.w)?}}
135   /// CHECK-NOT:            bic{{(\.w)?}}
136 
and511(long arg)137   public static long and511(long arg) {
138     return arg & 511L;
139   }
140 
141   /// CHECK-START-ARM: long Main.andF00D(long) disassembly (after)
142   /// CHECK:                mov {{r\d+}}, #61453
143   /// CHECK-NEXT:           mov{{s?}} {{r\d+}}, #0
144   /// CHECK-NOT:            and{{(\.w)?}}
145   /// CHECK-NOT:            bic{{(\.w)?}}
146   /// CHECK-NOT:            ubfx
147   /// CHECK:                and{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}}
148   /// CHECK-NEXT:           and{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}}
149   /// CHECK-NOT:            and{{(\.w)?}}
150   /// CHECK-NOT:            bic{{(\.w)?}}
151   /// CHECK-NOT:            ubfx
152 
andF00D(long arg)153   public static long andF00D(long arg) {
154     return arg & 0xF00DL;
155   }
156 
157   /// CHECK-START-ARM: long Main.andNot15(long) disassembly (after)
158   /// CHECK-NOT:            mvn {{r\d+}}, #15
159   /// CHECK-NOT:            and{{(\.w)?}}
160   /// CHECK-NOT:            bic{{(\.w)?}}
161   /// CHECK:                bic {{r\d+}}, {{r\d+}}, #0xf
162   /// CHECK-NOT:            and{{(\.w)?}}
163   /// CHECK-NOT:            bic{{(\.w)?}}
164 
andNot15(long arg)165   public static long andNot15(long arg) {
166     return arg & ~15L;
167   }
168 
169   /// CHECK-START-ARM: long Main.and0xfffffff00000000f(long) disassembly (after)
170   /// CHECK-NOT:            movs {{r\d+}}, #15
171   /// CHECK-NOT:            mvn {{r\d+}}, #15
172   /// CHECK-NOT:            and{{(\.w)?}}
173   /// CHECK-NOT:            bic{{(\.w)?}}
174   /// CHECK-DAG:            and {{r\d+}}, {{r\d+}}, #0xf
175   /// CHECK-DAG:            bic {{r\d+}}, {{r\d+}}, #0xf
176   /// CHECK-NOT:            and{{(\.w)?}}
177   /// CHECK-NOT:            bic{{(\.w)?}}
178 
and0xfffffff00000000f(long arg)179   public static long and0xfffffff00000000f(long arg) {
180     return arg & 0xfffffff00000000fL;
181   }
182 
183   /// CHECK-START-ARM: long Main.or255(long) disassembly (after)
184   /// CHECK-NOT:            movs {{r\d+}}, #255
185   /// CHECK-NOT:            orr{{(\.w)?}}
186   /// CHECK-NOT:            orn
187   /// CHECK:                orr {{r\d+}}, {{r\d+}}, #0xff
188   /// CHECK-NOT:            orr{{(\.w)?}}
189   /// CHECK-NOT:            orn
190 
or255(long arg)191   public static long or255(long arg) {
192     return arg | 255L;
193   }
194 
195   /// CHECK-START-ARM: long Main.or511(long) disassembly (after)
196   /// CHECK:                mov {{r\d+}}, #511
197   /// CHECK-NEXT:           mov{{s?}} {{r\d+}}, #0
198   /// CHECK-NOT:            orr{{(\.w)?}}
199   /// CHECK-NOT:            orn
200   /// CHECK:                orr{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}}
201   /// CHECK-NEXT:           orr{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}}
202   /// CHECK-NOT:            orr{{(\.w)?}}
203   /// CHECK-NOT:            orn
204 
or511(long arg)205   public static long or511(long arg) {
206     return arg | 511L;
207   }
208 
209   /// CHECK-START-ARM: long Main.orNot15(long) disassembly (after)
210   /// CHECK-NOT:            mvn {{r\d+}}, #15
211   /// CHECK-NOT:            orr{{(\.w)?}}
212   /// CHECK-NOT:            orn
213   /// CHECK-DAG:            orn {{r\d+}}, {{r\d+}}, #0xf
214   /// CHECK-DAG:            mvn {{r\d+}}, #0
215   /// CHECK-NOT:            orr{{(\.w)?}}
216   /// CHECK-NOT:            orn
217 
orNot15(long arg)218   public static long orNot15(long arg) {
219     return arg | ~15L;
220   }
221 
222   /// CHECK-START-ARM: long Main.or0xfffffff00000000f(long) disassembly (after)
223   /// CHECK-NOT:            movs {{r\d+}}, #15
224   /// CHECK-NOT:            mvn {{r\d+}}, #15
225   /// CHECK-NOT:            orr{{(\.w)?}}
226   /// CHECK-NOT:            orn
227   /// CHECK-DAG:            orr {{r\d+}}, {{r\d+}}, #0xf
228   /// CHECK-DAG:            orn {{r\d+}}, {{r\d+}}, #0xf
229   /// CHECK-NOT:            orr{{(\.w)?}}
230   /// CHECK-NOT:            orn
231 
or0xfffffff00000000f(long arg)232   public static long or0xfffffff00000000f(long arg) {
233     return arg | 0xfffffff00000000fL;
234   }
235 
236   /// CHECK-START-ARM: long Main.xor255(long) disassembly (after)
237   /// CHECK-NOT:            movs {{r\d+}}, #255
238   /// CHECK-NOT:            eor{{(\.w)?}}
239   /// CHECK:                eor {{r\d+}}, {{r\d+}}, #0xff
240   /// CHECK-NOT:            eor{{(\.w)?}}
241 
xor255(long arg)242   public static long xor255(long arg) {
243     return arg ^ 255L;
244   }
245 
246   /// CHECK-START-ARM: long Main.xor511(long) disassembly (after)
247   /// CHECK:                mov {{r\d+}}, #511
248   /// CHECK-NEXT:           mov{{s?}} {{r\d+}}, #0
249   /// CHECK-NOT:            eor{{(\.w)?}}
250   /// CHECK:                eor{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}}
251   /// CHECK-NEXT:           eor{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}}
252   /// CHECK-NOT:            eor{{(\.w)?}}
253 
xor511(long arg)254   public static long xor511(long arg) {
255     return arg ^ 511L;
256   }
257 
258   /// CHECK-START-ARM: long Main.xorNot15(long) disassembly (after)
259   /// CHECK-DAG:            mvn {{r\d+}}, #15
260   /// CHECK-DAG:            mov {{r\d+}}, #4294967295
261   /// CHECK-NOT:            eor{{(\.w)?}}
262   /// CHECK-DAG:            eor{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}}
263   /// CHECK-DAG:            eor{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}}
264   /// CHECK-NOT:            eor{{(\.w)?}}
265 
xorNot15(long arg)266   public static long xorNot15(long arg) {
267     return arg ^ ~15L;
268   }
269 
270   // Note: No support for partial long constant embedding.
271   /// CHECK-START-ARM: long Main.xor0xfffffff00000000f(long) disassembly (after)
272   /// CHECK-DAG:            mov{{s?}} {{r\d+}}, #15
273   /// CHECK-DAG:            mvn {{r\d+}}, #15
274   /// CHECK-NOT:            eor{{(\.w)?}}
275   /// CHECK-DAG:            eor{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}}
276   /// CHECK-DAG:            eor{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}}
277   /// CHECK-NOT:            eor{{(\.w)?}}
278 
xor0xfffffff00000000f(long arg)279   public static long xor0xfffffff00000000f(long arg) {
280     return arg ^ 0xfffffff00000000fL;
281   }
282 
283   /// CHECK-START-ARM: long Main.xor0xf00000000000000f(long) disassembly (after)
284   /// CHECK-NOT:            movs {{r\d+}}, #15
285   /// CHECK-NOT:            mov.w {{r\d+}}, #-268435456
286   /// CHECK-NOT:            eor{{(\.w)?}}
287   /// CHECK-DAG:            eor {{r\d+}}, {{r\d+}}, #0xf
288   /// CHECK-DAG:            eor {{r\d+}}, {{r\d+}}, #0xf0000000
289   /// CHECK-NOT:            eor{{(\.w)?}}
290 
xor0xf00000000000000f(long arg)291   public static long xor0xf00000000000000f(long arg) {
292     return arg ^ 0xf00000000000000fL;
293   }
294 
295   /// CHECK-START-ARM: long Main.shl1(long) disassembly (after)
296   /// CHECK:                lsls{{(\.w)?}} {{r\d+}}, {{r\d+}}, #1
297   /// CHECK:                adc{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}}
298 
299   /// CHECK-START-ARM: long Main.shl1(long) disassembly (after)
300   /// CHECK-NOT:            lsl{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}}
301 
302   /// CHECK-START-X86: long Main.shl1(long) disassembly (after)
303   /// CHECK:                add
304   /// CHECK:                adc
305 
306   /// CHECK-START-X86: long Main.shl1(long) disassembly (after)
307   /// CHECK-NOT:            shl
308 
shl1(long arg)309   public static long shl1(long arg) {
310     return arg << 1;
311   }
312 
313   /// CHECK-START-ARM: long Main.shl2(long) disassembly (after)
314   /// CHECK:                lsl{{s?|\.w}} <<oh:r\d+>>, {{r\d+}}, #2
315   /// CHECK:                orr <<oh>>, <<low:r\d+>>, lsr #30
316   /// CHECK:                lsl{{s?|\.w}} {{r\d+}}, <<low>>, #2
317 
318   /// CHECK-START-ARM: long Main.shl2(long) disassembly (after)
319   /// CHECK-NOT:            lsl{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}}
320 
shl2(long arg)321   public static long shl2(long arg) {
322     return arg << 2;
323   }
324 
325   /// CHECK-START-ARM: long Main.shl31(long) disassembly (after)
326   /// CHECK:                lsl{{s?|\.w}} <<oh:r\d+>>, {{r\d+}}, #31
327   /// CHECK:                orr <<oh>>, <<low:r\d+>>, lsr #1
328   /// CHECK:                lsl{{s?|\.w}} {{r\d+}}, <<low>>, #31
329 
330   /// CHECK-START-ARM: long Main.shl31(long) disassembly (after)
331   /// CHECK-NOT:            lsl{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}}
332 
shl31(long arg)333   public static long shl31(long arg) {
334     return arg << 31;
335   }
336 
337   /// CHECK-START-ARM: long Main.shl32(long) disassembly (after)
338   /// CHECK-DAG:            mov{{s?}} {{r\d+}}, {{r\d+}}
339   /// CHECK-DAG:            mov{{s?|\.w}} {{r\d+}}, #0
340 
341   /// CHECK-START-ARM: long Main.shl32(long) disassembly (after)
342   /// CHECK-NOT:            lsl{{s?|\.w}}
343 
shl32(long arg)344   public static long shl32(long arg) {
345     return arg << 32;
346   }
347 
348   /// CHECK-START-ARM: long Main.shl33(long) disassembly (after)
349   /// CHECK-DAG:            lsl{{s?|\.w}} {{r\d+}}, <<high:r\d+>>, #1
350   /// CHECK-DAG:            mov{{s?|\.w}} {{r\d+}}, #0
351 
352   /// CHECK-START-ARM: long Main.shl33(long) disassembly (after)
353   /// CHECK-NOT:            lsl{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}}
354 
shl33(long arg)355   public static long shl33(long arg) {
356     return arg << 33;
357   }
358 
359   /// CHECK-START-ARM: long Main.shl63(long) disassembly (after)
360   /// CHECK-DAG:            lsl{{s?|\.w}} {{r\d+}}, <<high:r\d+>>, #31
361   /// CHECK-DAG:            mov{{s?|\.w}} {{r\d+}}, #0
362 
363   /// CHECK-START-ARM: long Main.shl63(long) disassembly (after)
364   /// CHECK-NOT:            lsl{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}}
365 
shl63(long arg)366   public static long shl63(long arg) {
367     return arg << 63;
368   }
369 
370   /// CHECK-START-ARM: long Main.shr1(long) disassembly (after)
371   /// CHECK:                asrs{{(\.w)?}} {{r\d+}}, {{r\d+}}, #1
372   /// CHECK:                rrx {{r\d+}}, {{r\d+}}
373 
374   /// CHECK-START-ARM: long Main.shr1(long) disassembly (after)
375   /// CHECK-NOT:            asr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}}
376 
shr1(long arg)377   public static long shr1(long arg) {
378     return arg >> 1;
379   }
380 
381   /// CHECK-START-ARM: long Main.shr2(long) disassembly (after)
382   /// CHECK:                lsr{{s?|\.w}} <<ol:r\d+>>, {{r\d+}}, #2
383   /// CHECK:                orr <<ol>>, <<high:r\d+>>, lsl #30
384   /// CHECK-DAG:            asr{{s?|\.w}} {{r\d+}}, <<high>>, #2
385 
386   /// CHECK-START-ARM: long Main.shr2(long) disassembly (after)
387   /// CHECK-NOT:            asr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}}
388 
shr2(long arg)389   public static long shr2(long arg) {
390     return arg >> 2;
391   }
392 
393   /// CHECK-START-ARM: long Main.shr31(long) disassembly (after)
394   /// CHECK:                lsr{{s?|\.w}} <<ol:r\d+>>, {{r\d+}}, #31
395   /// CHECK:                orr <<ol>>, <<high:r\d+>>, lsl #1
396   /// CHECK:                asr{{s?|\.w}} {{r\d+}}, <<high>>, #31
397 
398   /// CHECK-START-ARM: long Main.shr31(long) disassembly (after)
399   /// CHECK-NOT:            asr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}}
400 
shr31(long arg)401   public static long shr31(long arg) {
402     return arg >> 31;
403   }
404 
405   /// CHECK-START-ARM: long Main.shr32(long) disassembly (after)
406   /// CHECK-DAG:            asr{{s?|\.w}} {{r\d+}}, <<high:r\d+>>, #31
407   /// CHECK-DAG:            mov{{s?}} {{r\d+}}, <<high>>
408 
409   /// CHECK-START-ARM: long Main.shr32(long) disassembly (after)
410   /// CHECK-NOT:            asr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}}
411   /// CHECK-NOT:            lsr{{s?|\.w}}
412 
shr32(long arg)413   public static long shr32(long arg) {
414     return arg >> 32;
415   }
416 
417   /// CHECK-START-ARM: long Main.shr33(long) disassembly (after)
418   /// CHECK-DAG:            asr{{s?|\.w}} {{r\d+}}, <<high:r\d+>>, #1
419   /// CHECK-DAG:            asr{{s?|\.w}} {{r\d+}}, <<high>>, #31
420 
421   /// CHECK-START-ARM: long Main.shr33(long) disassembly (after)
422   /// CHECK-NOT:            asr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}}
423 
shr33(long arg)424   public static long shr33(long arg) {
425     return arg >> 33;
426   }
427 
428   /// CHECK-START-ARM: long Main.shr63(long) disassembly (after)
429   /// CHECK-DAG:            asr{{s?|\.w}} {{r\d+}}, <<high:r\d+>>, #31
430   /// CHECK-DAG:            asr{{s?|\.w}} {{r\d+}}, <<high>>, #31
431 
432   /// CHECK-START-ARM: long Main.shr63(long) disassembly (after)
433   /// CHECK-NOT:            asr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}}
434 
shr63(long arg)435   public static long shr63(long arg) {
436     return arg >> 63;
437   }
438 
439   /// CHECK-START-ARM: long Main.ushr1(long) disassembly (after)
440   /// CHECK:                lsrs{{|.w}} {{r\d+}}, {{r\d+}}, #1
441   /// CHECK:                rrx {{r\d+}}, {{r\d+}}
442 
443   /// CHECK-START-ARM: long Main.ushr1(long) disassembly (after)
444   /// CHECK-NOT:            lsr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}}
445 
ushr1(long arg)446   public static long ushr1(long arg) {
447     return arg >>> 1;
448   }
449 
450   /// CHECK-START-ARM: long Main.ushr2(long) disassembly (after)
451   /// CHECK:                lsr{{s?|\.w}} <<ol:r\d+>>, {{r\d+}}, #2
452   /// CHECK:                orr <<ol>>, <<high:r\d+>>, lsl #30
453   /// CHECK-DAG:            lsr{{s?|\.w}} {{r\d+}}, <<high>>, #2
454 
455   /// CHECK-START-ARM: long Main.ushr2(long) disassembly (after)
456   /// CHECK-NOT:            lsr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}}
457 
ushr2(long arg)458   public static long ushr2(long arg) {
459     return arg >>> 2;
460   }
461 
462   /// CHECK-START-ARM: long Main.ushr31(long) disassembly (after)
463   /// CHECK:                lsr{{s?|\.w}} <<ol:r\d+>>, {{r\d+}}, #31
464   /// CHECK:                orr <<ol>>, <<high:r\d+>>, lsl #1
465   /// CHECK:                lsr{{s?|\.w}} {{r\d+}}, <<high>>, #31
466 
467   /// CHECK-START-ARM: long Main.ushr31(long) disassembly (after)
468   /// CHECK-NOT:            lsr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}}
469 
ushr31(long arg)470   public static long ushr31(long arg) {
471     return arg >>> 31;
472   }
473 
474   /// CHECK-START-ARM: long Main.ushr32(long) disassembly (after)
475   /// CHECK-DAG:            mov{{s?}} {{r\d+}}, {{r\d+}}
476   /// CHECK-DAG:            mov{{s?|\.w}} {{r\d+}}, #0
477 
478   /// CHECK-START-ARM: long Main.ushr32(long) disassembly (after)
479   /// CHECK-NOT:            lsr{{s?|\.w}}
480 
ushr32(long arg)481   public static long ushr32(long arg) {
482     return arg >>> 32;
483   }
484 
485   /// CHECK-START-ARM: long Main.ushr33(long) disassembly (after)
486   /// CHECK-DAG:            lsr{{s?|\.w}} {{r\d+}}, {{r\d+}}, #1
487   /// CHECK-DAG:            mov{{s?|\.w}} {{r\d+}}, #0
488 
489   /// CHECK-START-ARM: long Main.ushr33(long) disassembly (after)
490   /// CHECK-NOT:            lsr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}}
491 
ushr33(long arg)492   public static long ushr33(long arg) {
493     return arg >>> 33;
494   }
495 
496   /// CHECK-START-ARM: long Main.ushr63(long) disassembly (after)
497   /// CHECK-DAG:            lsr{{s?|\.w}} {{r\d+}}, {{r\d+}}, #31
498   /// CHECK-DAG:            mov{{s?|\.w}} {{r\d+}}, #0
499 
500   /// CHECK-START-ARM: long Main.ushr63(long) disassembly (after)
501   /// CHECK-NOT:            lsr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}}
502 
ushr63(long arg)503   public static long ushr63(long arg) {
504     return arg >>> 63;
505   }
506 
507   /**
508    * ARM/ARM64: Test that the `-1` constant is not synthesized in a register and that we
509    * instead simply switch between `add` and `sub` instructions with the
510    * constant embedded.
511    * We need two uses (or more) of the constant because the compiler always
512    * defers to immediate value handling to VIXL when it has only one use.
513    */
514 
515   /// CHECK-START-ARM64: long Main.addM1(long) register (after)
516   /// CHECK:     <<Arg:j\d+>>       ParameterValue
517   /// CHECK:     <<ConstM1:j\d+>>   LongConstant -1
518   /// CHECK-NOT:                    ParallelMove
519   /// CHECK:                        Add [<<Arg>>,<<ConstM1>>]
520   /// CHECK:                        Sub [<<Arg>>,<<ConstM1>>]
521 
522   /// CHECK-START-ARM64: long Main.addM1(long) disassembly (after)
523   /// CHECK:                        sub x{{\d+}}, x{{\d+}}, #0x1
524   /// CHECK:                        add x{{\d+}}, x{{\d+}}, #0x1
525 
526   /// CHECK-START-ARM: long Main.addM1(long) register (after)
527   /// CHECK:     <<Arg:j\d+>>       ParameterValue
528   /// CHECK:     <<ConstM1:j\d+>>   LongConstant -1
529   /// CHECK-NOT:                    ParallelMove
530   /// CHECK:                        Add [<<Arg>>,<<ConstM1>>]
531   /// CHECK:                        Sub [<<Arg>>,<<ConstM1>>]
532 
533   /// CHECK-START-ARM: long Main.addM1(long) disassembly (after)
534   /// CHECK:     <<Arg:j\d+>>       ParameterValue
535   /// CHECK:     <<ConstM1:j\d+>>   LongConstant -1
536   /// CHECK:                        Add [<<Arg>>,<<ConstM1>>]
537   /// CHECK-NEXT:                   {{adds|subs}} r{{\d+}}, #{{4294967295|1}}
538   /// CHECK-NEXT:                   adc r{{\d+}}, r{{\d+}}, #4294967295
539   /// CHECK:                        Sub [<<Arg>>,<<ConstM1>>]
540   /// CHECK-NEXT:                   adds r{{\d+}}, #1
541   /// CHECK-NEXT:                   adc r{{\d+}}, #0
542 
addM1(long arg)543   public static long addM1(long arg) {
544     return (arg + (-1)) | (arg - (-1));
545   }
546 
547   /**
548    * ARM: Test that some long constants are not synthesized in a register for add-long.
549    * Also test some negative cases where we do synthetize constants in registers.
550    */
551 
552   /// CHECK-START-ARM: long Main.addLongConstants(long) disassembly (after)
553   /// CHECK:     <<Arg:j\d+>>       ParameterValue
554   /// CHECK-DAG: <<ConstA:j\d+>>    LongConstant 4486007727657233
555   /// CHECK-DAG: <<ConstB:j\d+>>    LongConstant 4486011735248896
556   /// CHECK-DAG: <<ConstC:j\d+>>    LongConstant -1071856711330889728
557   /// CHECK-DAG: <<ConstD:j\d+>>    LongConstant 17587891077120
558   /// CHECK-DAG: <<ConstE:j\d+>>    LongConstant -8808977924096
559   /// CHECK-DAG: <<ConstF:j\d+>>    LongConstant 17587891077121
560   /// CHECK-DAG: <<ConstG:j\d+>>    LongConstant 4095
561   /// CHECK:                        Add [<<Arg>>,<<ConstA>>]
562   /// CHECK-NEXT:                   adds r{{\d+}}, r{{\d+}}, #286331153
563   /// CHECK-NEXT:                   adc r{{\d+}}, r{{\d+}}, #1044480
564   /// CHECK:                        Add [<<Arg>>,<<ConstB>>]
565   /// CHECK-NEXT:                   subs r{{\d+}}, r{{\d+}}, #1044480
566   /// CHECK-NEXT:                   adc r{{\d+}}, r{{\d+}}, #1044480
567   /// CHECK:                        Add [<<Arg>>,<<ConstC>>]
568   /// CHECK-NEXT:                   subs r{{\d+}}, r{{\d+}}, #16711680
569   /// CHECK-NEXT:                   sbc r{{\d+}}, r{{\d+}}, #249561088
570   /// CHECK:                        Add [<<Arg>>,<<ConstD>>]
571   // There may or may not be a MOV here.
572   /// CHECK:                        add r{{\d+}}, r{{\d+}}, #4095
573   /// CHECK:                        Add [<<Arg>>,<<ConstE>>]
574   // There may or may not be a MOV here.
575   /// CHECK:                        sub r{{\d+}}, r{{\d+}}, #2051
576   /// CHECK:                        Add [<<Arg>>,<<ConstF>>]
577   /// CHECK-NEXT:                   adds{{(\.w)?}} r{{\d+}}, r{{\d+}}, r{{\d+}}
578   /// CHECK-NEXT:                   adc{{(\.w)?}} r{{\d+}}, r{{\d+}}, r{{\d+}}
579   /// CHECK:                        Add [<<Arg>>,<<ConstG>>]
580   /// CHECK-NEXT:                   adds{{(\.w)?}} r{{\d+}}, r{{\d+}}, r{{\d+}}
581   /// CHECK-NEXT:                   adc{{(\.w)?}} r{{\d+}}, r{{\d+}}, r{{\d+}}
582 
addLongConstants(long arg)583   public static long addLongConstants(long arg) {
584     return
585         // Modified immediates.
586         (arg + 0x000ff00011111111L) ^  // 4486007727657233
587         // Modified immediates high and -low.
588         (arg + 0x000ff000fff01000L) ^  // 4486011735248896
589         // Modified immediates ~high and -low.
590         (arg + 0xf11fffffff010000L) ^  // -1071856711330889728
591         // Low word 0 (no carry), high is imm12.
592         (arg + 0x00000fff00000000L) ^  // 17587891077120
593         // Low word 0 (no carry), -high is imm12.
594         (arg + 0xfffff7fd00000000L) ^  // -8808977924096
595         // Cannot embed imm12 in ADC/SBC for high word.
596         (arg + 0x00000fff00000001L) ^  // 17587891077121
597         // Cannot embed imm12 in ADDS/SUBS for low word (need to set flags).
598         (arg + 0x0000000000000fffL) ^  // 4095
599         arg;
600   }
601 
602   /**
603    * ARM: Test that some long constants are not synthesized in a register for add-long.
604    * Also test some negative cases where we do synthetize constants in registers.
605    */
606 
607   /// CHECK-START-ARM: long Main.subLongConstants(long) disassembly (after)
608   /// CHECK:     <<Arg:j\d+>>       ParameterValue
609   /// CHECK-DAG: <<ConstA:j\d+>>    LongConstant 4486007727657233
610   /// CHECK-DAG: <<ConstB:j\d+>>    LongConstant 4486011735248896
611   /// CHECK-DAG: <<ConstC:j\d+>>    LongConstant -1071856711330889728
612   /// CHECK-DAG: <<ConstD:j\d+>>    LongConstant 17587891077120
613   /// CHECK-DAG: <<ConstE:j\d+>>    LongConstant -8808977924096
614   /// CHECK-DAG: <<ConstF:j\d+>>    LongConstant 17587891077121
615   /// CHECK-DAG: <<ConstG:j\d+>>    LongConstant 4095
616   /// CHECK:                        Sub [<<Arg>>,<<ConstA>>]
617   /// CHECK-NEXT:                   subs r{{\d+}}, r{{\d+}}, #286331153
618   /// CHECK-NEXT:                   sbc r{{\d+}}, r{{\d+}}, #1044480
619   /// CHECK:                        Sub [<<Arg>>,<<ConstB>>]
620   /// CHECK-NEXT:                   adds r{{\d+}}, r{{\d+}}, #1044480
621   /// CHECK-NEXT:                   sbc r{{\d+}}, r{{\d+}}, #1044480
622   /// CHECK:                        Sub [<<Arg>>,<<ConstC>>]
623   /// CHECK-NEXT:                   adds r{{\d+}}, r{{\d+}}, #16711680
624   /// CHECK-NEXT:                   adc r{{\d+}}, r{{\d+}}, #249561088
625   /// CHECK:                        Sub [<<Arg>>,<<ConstD>>]
626   // There may or may not be a MOV here.
627   /// CHECK:                        sub r{{\d+}}, r{{\d+}}, #4095
628   /// CHECK:                        Sub [<<Arg>>,<<ConstE>>]
629   // There may or may not be a MOV here.
630   /// CHECK:                        add r{{\d+}}, r{{\d+}}, #2051
631   /// CHECK:                        Sub [<<Arg>>,<<ConstF>>]
632   /// CHECK-NEXT:                   subs{{(\.w)?}} r{{\d+}}, r{{\d+}}, r{{\d+}}
633   /// CHECK-NEXT:                   sbc{{(\.w)?}} r{{\d+}}, r{{\d+}}, r{{\d+}}
634   /// CHECK:                        Sub [<<Arg>>,<<ConstG>>]
635   /// CHECK-NEXT:                   subs{{(\.w)?}} r{{\d+}}, r{{\d+}}, r{{\d+}}
636   /// CHECK-NEXT:                   sbc{{(\.w)?}} r{{\d+}}, r{{\d+}}, r{{\d+}}
637 
subLongConstants(long arg)638   public static long subLongConstants(long arg) {
639     return
640         // Modified immediates.
641         (arg - 0x000ff00011111111L) ^  // 4486007727657233
642         // Modified immediates high and -low.
643         (arg - 0x000ff000fff01000L) ^  // 4486011735248896
644         // Modified immediates ~high and -low.
645         (arg - 0xf11fffffff010000L) ^  // -1071856711330889728
646         // Low word 0 (no carry), high is imm12.
647         (arg - 0x00000fff00000000L) ^  // 17587891077120
648         // Low word 0 (no carry), -high is imm12.
649         (arg - 0xfffff7fd00000000L) ^  // -8808977924096
650         // Cannot embed imm12 in ADC/SBC for high word.
651         (arg - 0x00000fff00000001L) ^  // 17587891077121
652         // Cannot embed imm12 in ADDS/SUBS for low word (need to set flags).
653         (arg - 0x0000000000000fffL) ^  // 4095
654         arg;
655   }
656 
main(String[] args)657   public static void main(String[] args) {
658     int arg = 0x87654321;
659     assertIntEquals(and254(arg), 0x20);
660     assertIntEquals(and255(arg), 0x21);
661     assertIntEquals(and511(arg), 0x121);
662     assertIntEquals(andF00D(arg), 0x4001);
663     assertIntEquals(andNot15(arg), 0x87654320);
664     assertIntEquals(or255(arg), 0x876543ff);
665     assertIntEquals(or511(arg), 0x876543ff);
666     assertIntEquals(orNot15(arg), 0xfffffff1);
667     assertIntEquals(xor255(arg), 0x876543de);
668     assertIntEquals(xor511(arg), 0x876542de);
669     assertIntEquals(xorNot15(arg), 0x789abcd1);
670 
671     long longArg = 0x1234567887654321L;
672     assertLongEquals(and255(longArg), 0x21L);
673     assertLongEquals(and511(longArg), 0x121L);
674     assertLongEquals(andF00D(longArg), 0x4001L);
675     assertLongEquals(andNot15(longArg), 0x1234567887654320L);
676     assertLongEquals(and0xfffffff00000000f(longArg), 0x1234567000000001L);
677     assertLongEquals(or255(longArg), 0x12345678876543ffL);
678     assertLongEquals(or511(longArg), 0x12345678876543ffL);
679     assertLongEquals(orNot15(longArg), 0xfffffffffffffff1L);
680     assertLongEquals(or0xfffffff00000000f(longArg), 0xfffffff88765432fL);
681     assertLongEquals(xor255(longArg), 0x12345678876543deL);
682     assertLongEquals(xor511(longArg), 0x12345678876542deL);
683     assertLongEquals(xorNot15(longArg), 0xedcba987789abcd1L);
684     assertLongEquals(xor0xfffffff00000000f(longArg), 0xedcba9888765432eL);
685     assertLongEquals(xor0xf00000000000000f(longArg), 0xe23456788765432eL);
686 
687     assertLongEquals(14L, addM1(7));
688 
689     assertLongEquals(shl1(longArg), 0x2468acf10eca8642L);
690     assertLongEquals(shl2(longArg), 0x48d159e21d950c84L);
691     assertLongEquals(shl31(longArg), 0x43b2a19080000000L);
692     assertLongEquals(shl32(longArg), 0x8765432100000000L);
693     assertLongEquals(shl33(longArg), 0x0eca864200000000L);
694     assertLongEquals(shl63(longArg), 0x8000000000000000L);
695     assertLongEquals(shl1(~longArg), 0xdb97530ef13579bcL);
696     assertLongEquals(shl2(~longArg), 0xb72ea61de26af378L);
697     assertLongEquals(shl31(~longArg), 0xbc4d5e6f00000000L);
698     assertLongEquals(shl32(~longArg), 0x789abcde00000000L);
699     assertLongEquals(shl33(~longArg), 0xf13579bc00000000L);
700     assertLongEquals(shl63(~longArg), 0x0000000000000000L);
701 
702     assertLongEquals(shr1(longArg), 0x091a2b3c43b2a190L);
703     assertLongEquals(shr2(longArg), 0x048d159e21d950c8L);
704     assertLongEquals(shr31(longArg), 0x000000002468acf1L);
705     assertLongEquals(shr32(longArg), 0x0000000012345678L);
706     assertLongEquals(shr33(longArg), 0x00000000091a2b3cL);
707     assertLongEquals(shr63(longArg), 0x0000000000000000L);
708     assertLongEquals(shr1(~longArg), 0xf6e5d4c3bc4d5e6fL);
709     assertLongEquals(shr2(~longArg), 0xfb72ea61de26af37L);
710     assertLongEquals(shr31(~longArg), 0xffffffffdb97530eL);
711     assertLongEquals(shr32(~longArg), 0xffffffffedcba987L);
712     assertLongEquals(shr33(~longArg), 0xfffffffff6e5d4c3L);
713     assertLongEquals(shr63(~longArg), 0xffffffffffffffffL);
714 
715     assertLongEquals(ushr1(longArg), 0x091a2b3c43b2a190L);
716     assertLongEquals(ushr2(longArg), 0x048d159e21d950c8L);
717     assertLongEquals(ushr31(longArg), 0x000000002468acf1L);
718     assertLongEquals(ushr32(longArg), 0x0000000012345678L);
719     assertLongEquals(ushr33(longArg), 0x00000000091a2b3cL);
720     assertLongEquals(ushr63(longArg), 0x0000000000000000L);
721     assertLongEquals(ushr1(~longArg), 0x76e5d4c3bc4d5e6fL);
722     assertLongEquals(ushr2(~longArg), 0x3b72ea61de26af37L);
723     assertLongEquals(ushr31(~longArg), 0x00000001db97530eL);
724     assertLongEquals(ushr32(~longArg), 0x00000000edcba987L);
725     assertLongEquals(ushr33(~longArg), 0x0000000076e5d4c3L);
726     assertLongEquals(ushr63(~longArg), 0x0000000000000001L);
727 
728     // Test -1, 0, +1 and arbitrary constants just before and after overflow
729     // on low word in subexpressions of addLongConstants()/subLongConstants(),
730     // so that we check that we carry the overflow correctly to the high word.
731     // For example
732     //    0x111eeeeeeee+0x000ff00011111111 = 0x000ff111ffffffff (carry=0),
733     //    0x111eeeeeeef+0x000ff00011111111 = 0x000ff11200000000 (carry=1).
734     assertLongEquals(0xf11ff7fdee1e1111L, addLongConstants(0xffffffffffffffffL));
735     assertLongEquals(0xee0080211e00eefL, addLongConstants(0x0L));
736     assertLongEquals(0xee0080211e01111L, addLongConstants(0x1L));
737     assertLongEquals(0xedff81c12201113L, addLongConstants(0x111eeeeeeeeL));
738     assertLongEquals(0xedff81feddfeef1L, addLongConstants(0x111eeeeeeefL));
739     assertLongEquals(0xedff83e11c1f111L, addLongConstants(0x222000fefffL));
740     assertLongEquals(0xedff83fee3e0eefL, addLongConstants(0x222000ff000L));
741     assertLongEquals(0xedff805edfe1111L, addLongConstants(0x33300feffffL));
742     assertLongEquals(0xedff80412000eefL, addLongConstants(0x33300ff0000L));
743     assertLongEquals(0xee0080211e00eefL, subLongConstants(0xffffffffffffffffL));
744     assertLongEquals(0xf11ff7fdee1e1111L, subLongConstants(0x0L));
745     assertLongEquals(0xf11ff7fc11e1eef3L, subLongConstants(0x1L));
746     assertLongEquals(0xee0080412201113L, subLongConstants(0x44411111111L));
747     assertLongEquals(0xee0080412201111L, subLongConstants(0x44411111112L));
748     assertLongEquals(0xee0080e11c1f111L, subLongConstants(0x555fff01000L));
749     assertLongEquals(0xee0080e11c1eef3L, subLongConstants(0x555fff01001L));
750     assertLongEquals(0xee0080dedfe1111L, subLongConstants(0x666ff010000L));
751     assertLongEquals(0xee0080dedffeef3L, subLongConstants(0x666ff010001L));
752   }
753 }
754