1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 public class Main {
18 
19   public static boolean doThrow = false;
20 
$noinline$foo(int in_w1, int in_w2, int in_w3, int in_w4, int in_w5, int in_w6, int in_w7, int on_stack_int, long on_stack_long, float in_s0, float in_s1, float in_s2, float in_s3, float in_s4, float in_s5, float in_s6, float in_s7, float on_stack_float, double on_stack_double)21   public void $noinline$foo(int in_w1,
22                             int in_w2,
23                             int in_w3,
24                             int in_w4,
25                             int in_w5,
26                             int in_w6,
27                             int in_w7,
28                             int on_stack_int,
29                             long on_stack_long,
30                             float in_s0,
31                             float in_s1,
32                             float in_s2,
33                             float in_s3,
34                             float in_s4,
35                             float in_s5,
36                             float in_s6,
37                             float in_s7,
38                             float on_stack_float,
39                             double on_stack_double) {
40     if (doThrow) throw new Error();
41   }
42 
43   // We expect a parallel move that moves four times the zero constant to stack locations.
44   /// CHECK-START-ARM64: void Main.bar() register (after)
45   /// CHECK:             ParallelMove {{.*#0->[0-9x]+\(sp\).*#0->[0-9x]+\(sp\).*#0->[0-9x]+\(sp\).*#0->[0-9x]+\(sp\).*}}
46 
47   // Those four moves should generate four 'store' instructions using directly the zero register.
48   /// CHECK-START-ARM64: void Main.bar() disassembly (after)
49   /// CHECK-DAG:         {{(str|stur)}} wzr, [sp, #{{[0-9]+}}]
50   /// CHECK-DAG:         {{(str|stur)}} xzr, [sp, #{{[0-9]+}}]
51   /// CHECK-DAG:         {{(str|stur)}} wzr, [sp, #{{[0-9]+}}]
52   /// CHECK-DAG:         {{(str|stur)}} xzr, [sp, #{{[0-9]+}}]
53 
bar()54   public void bar() {
55     $noinline$foo(1, 2, 3, 4, 5, 6, 7,     // Integral values in registers.
56                   0, 0L,                   // Integral values on the stack.
57                   1, 2, 3, 4, 5, 6, 7, 8,  // Floating-point values in registers.
58                   0.0f, 0.0);              // Floating-point values on the stack.
59   }
60 
61   /// CHECK-START-ARM64: void Main.store_zero_to_static_byte_field() disassembly (after)
62   /// CHECK:             StaticFieldSet
63   /// CHECK-NEXT:        strb wzr, [x{{[0-9]+}}, #{{[0-9]+}}]
64 
65   public static byte static_byte_field;
66 
store_zero_to_static_byte_field()67   public void store_zero_to_static_byte_field() {
68     static_byte_field = 0;
69   }
70 
71   /// CHECK-START-ARM64: void Main.store_zero_to_static_char_field() disassembly (after)
72   /// CHECK:             StaticFieldSet
73   /// CHECK-NEXT:        strh wzr, [x{{[0-9]+}}, #{{[0-9]+}}]
74 
75   public static char static_char_field;
76 
store_zero_to_static_char_field()77   public void store_zero_to_static_char_field() {
78     static_char_field = 0;
79   }
80 
81   /// CHECK-START-ARM64: void Main.store_zero_to_static_short_field() disassembly (after)
82   /// CHECK:             StaticFieldSet
83   /// CHECK-NEXT:        strh wzr, [x{{[0-9]+}}, #{{[0-9]+}}]
84 
85   public static short static_short_field;
86 
store_zero_to_static_short_field()87   public void store_zero_to_static_short_field() {
88     static_short_field = 0;
89   }
90 
91   /// CHECK-START-ARM64: void Main.store_zero_to_static_int_field() disassembly (after)
92   /// CHECK:             StaticFieldSet
93   /// CHECK-NEXT:        str wzr, [x{{[0-9]+}}, #{{[0-9]+}}]
94 
95   public static int static_int_field;
96 
store_zero_to_static_int_field()97   public void store_zero_to_static_int_field() {
98     static_int_field = 0;
99   }
100 
101   /// CHECK-START-ARM64: void Main.store_zero_to_static_long_field() disassembly (after)
102   /// CHECK:             StaticFieldSet
103   /// CHECK-NEXT:        str xzr, [x{{[0-9]+}}, #{{[0-9]+}}]
104 
105   public static long static_long_field;
106 
store_zero_to_static_long_field()107   public void store_zero_to_static_long_field() {
108     static_long_field = 0;
109   }
110 
111   /// CHECK-START-ARM64: void Main.store_zero_to_static_float_field() disassembly (after)
112   /// CHECK:             StaticFieldSet
113   /// CHECK-NEXT:        str wzr, [x{{[0-9]+}}, #{{[0-9]+}}]
114 
115   public static float static_float_field;
116 
store_zero_to_static_float_field()117   public void store_zero_to_static_float_field() {
118     static_float_field = 0.0f;
119   }
120 
121   /// CHECK-START-ARM64: void Main.store_zero_to_static_double_field() disassembly (after)
122   /// CHECK:             StaticFieldSet
123   /// CHECK-NEXT:        str xzr, [x{{[0-9]+}}, #{{[0-9]+}}]
124 
125   public static double static_double_field;
126 
store_zero_to_static_double_field()127   public void store_zero_to_static_double_field() {
128     static_double_field = 0.0;
129   }
130 
131   /// CHECK-START-ARM64: void Main.store_zero_to_volatile_static_byte_field() disassembly (after)
132   /// CHECK:             StaticFieldSet
133   /// CHECK-NEXT:        add <<temp:x[0-9]+>>, x{{[0-9]+}}, #0x{{[0-9a-fA-F]+}}
134   /// CHECK-NEXT:        stlrb wzr, [<<temp>>]
135 
136   public static volatile byte volatile_static_byte_field;
137 
store_zero_to_volatile_static_byte_field()138   public void store_zero_to_volatile_static_byte_field() {
139     volatile_static_byte_field = 0;
140   }
141 
142   /// CHECK-START-ARM64: void Main.store_zero_to_volatile_static_char_field() disassembly (after)
143   /// CHECK:             StaticFieldSet
144   /// CHECK-NEXT:        add <<temp:x[0-9]+>>, x{{[0-9]+}}, #0x{{[0-9a-fA-F]+}}
145   /// CHECK-NEXT:        stlrh wzr, [<<temp>>]
146 
147   public static volatile char volatile_static_char_field;
148 
store_zero_to_volatile_static_char_field()149   public void store_zero_to_volatile_static_char_field() {
150     volatile_static_char_field = 0;
151   }
152 
153   /// CHECK-START-ARM64: void Main.store_zero_to_volatile_static_short_field() disassembly (after)
154   /// CHECK:             StaticFieldSet
155   /// CHECK-NEXT:        add <<temp:x[0-9]+>>, x{{[0-9]+}}, #0x{{[0-9a-fA-F]+}}
156   /// CHECK-NEXT:        stlrh wzr, [<<temp>>]
157 
158   public static volatile short volatile_static_short_field;
159 
store_zero_to_volatile_static_short_field()160   public void store_zero_to_volatile_static_short_field() {
161     volatile_static_short_field = 0;
162   }
163 
164   /// CHECK-START-ARM64: void Main.store_zero_to_volatile_static_int_field() disassembly (after)
165   /// CHECK:             StaticFieldSet
166   /// CHECK-NEXT:        add <<temp:x[0-9]+>>, x{{[0-9]+}}, #0x{{[0-9a-fA-F]+}}
167   /// CHECK-NEXT:        stlr wzr, [<<temp>>]
168 
169   public static volatile int volatile_static_int_field;
170 
store_zero_to_volatile_static_int_field()171   public void store_zero_to_volatile_static_int_field() {
172     volatile_static_int_field = 0;
173   }
174 
175   /// CHECK-START-ARM64: void Main.store_zero_to_volatile_static_long_field() disassembly (after)
176   /// CHECK:             StaticFieldSet
177   /// CHECK-NEXT:        add <<temp:x[0-9]+>>, x{{[0-9]+}}, #0x{{[0-9a-fA-F]+}}
178   /// CHECK-NEXT:        stlr xzr, [<<temp>>]
179 
180   public static volatile long volatile_static_long_field;
181 
store_zero_to_volatile_static_long_field()182   public void store_zero_to_volatile_static_long_field() {
183     volatile_static_long_field = 0;
184   }
185 
186   /// CHECK-START-ARM64: void Main.store_zero_to_volatile_static_float_field() disassembly (after)
187   /// CHECK:             StaticFieldSet
188   /// CHECK-NEXT:        add <<temp:x[0-9]+>>, x{{[0-9]+}}, #0x{{[0-9a-fA-F]+}}
189   /// CHECK-NEXT:        stlr wzr, [<<temp>>]
190 
191   public static volatile float volatile_static_float_field;
192 
store_zero_to_volatile_static_float_field()193   public void store_zero_to_volatile_static_float_field() {
194     volatile_static_float_field = 0.0f;
195   }
196 
197   /// CHECK-START-ARM64: void Main.store_zero_to_volatile_static_double_field() disassembly (after)
198   /// CHECK:             StaticFieldSet
199   /// CHECK-NEXT:        add <<temp:x[0-9]+>>, x{{[0-9]+}}, #0x{{[0-9a-fA-F]+}}
200   /// CHECK-NEXT:        stlr xzr, [<<temp>>]
201 
202   public static volatile double volatile_static_double_field;
203 
store_zero_to_volatile_static_double_field()204   public void store_zero_to_volatile_static_double_field() {
205     volatile_static_double_field = 0.0;
206   }
207 
208   /// CHECK-START-ARM64: void Main.store_zero_to_instance_byte_field() disassembly (after)
209   /// CHECK:             InstanceFieldSet
210   /// CHECK-NEXT:        strb wzr, [x{{[0-9]+}}, #{{[0-9]+}}]
211 
212   public byte instance_byte_field;
213 
store_zero_to_instance_byte_field()214   public void store_zero_to_instance_byte_field() {
215     instance_byte_field = 0;
216   }
217 
218   /// CHECK-START-ARM64: void Main.store_zero_to_instance_char_field() disassembly (after)
219   /// CHECK:             InstanceFieldSet
220   /// CHECK-NEXT:        strh wzr, [x{{[0-9]+}}, #{{[0-9]+}}]
221 
222   public char instance_char_field;
223 
store_zero_to_instance_char_field()224   public void store_zero_to_instance_char_field() {
225     instance_char_field = 0;
226   }
227 
228   /// CHECK-START-ARM64: void Main.store_zero_to_instance_short_field() disassembly (after)
229   /// CHECK:             InstanceFieldSet
230   /// CHECK-NEXT:        strh wzr, [x{{[0-9]+}}, #{{[0-9]+}}]
231 
232   public short instance_short_field;
233 
store_zero_to_instance_short_field()234   public void store_zero_to_instance_short_field() {
235     instance_short_field = 0;
236   }
237 
238   /// CHECK-START-ARM64: void Main.store_zero_to_instance_int_field() disassembly (after)
239   /// CHECK:             InstanceFieldSet
240   /// CHECK-NEXT:        str wzr, [x{{[0-9]+}}, #{{[0-9]+}}]
241 
242   public int instance_int_field;
243 
store_zero_to_instance_int_field()244   public void store_zero_to_instance_int_field() {
245     instance_int_field = 0;
246   }
247 
248   /// CHECK-START-ARM64: void Main.store_zero_to_instance_long_field() disassembly (after)
249   /// CHECK:             InstanceFieldSet
250   /// CHECK-NEXT:        str xzr, [x{{[0-9]+}}, #{{[0-9]+}}]
251 
252   public long instance_long_field;
253 
store_zero_to_instance_long_field()254   public void store_zero_to_instance_long_field() {
255     instance_long_field = 0;
256   }
257 
258   /// CHECK-START-ARM64: void Main.store_zero_to_instance_float_field() disassembly (after)
259   /// CHECK:             InstanceFieldSet
260   /// CHECK-NEXT:        str wzr, [x{{[0-9]+}}, #{{[0-9]+}}]
261 
262   public float instance_float_field;
263 
store_zero_to_instance_float_field()264   public void store_zero_to_instance_float_field() {
265     instance_float_field = 0.0f;
266   }
267 
268   /// CHECK-START-ARM64: void Main.store_zero_to_instance_double_field() disassembly (after)
269   /// CHECK:             InstanceFieldSet
270   /// CHECK-NEXT:        str xzr, [x{{[0-9]+}}, #{{[0-9]+}}]
271 
272   public double instance_double_field;
273 
store_zero_to_instance_double_field()274   public void store_zero_to_instance_double_field() {
275     instance_double_field = 0.0;
276   }
277 
278   /// CHECK-START-ARM64: void Main.store_zero_to_volatile_instance_byte_field() disassembly (after)
279   /// CHECK:             InstanceFieldSet
280   /// CHECK-NEXT:        add <<temp:x[0-9]+>>, x{{[0-9]+}}, #0x{{[0-9a-fA-F]+}}
281   /// CHECK-NEXT:        stlrb wzr, [<<temp>>]
282 
283   public volatile byte volatile_instance_byte_field;
284 
store_zero_to_volatile_instance_byte_field()285   public void store_zero_to_volatile_instance_byte_field() {
286     volatile_instance_byte_field = 0;
287   }
288 
289   /// CHECK-START-ARM64: void Main.store_zero_to_volatile_instance_char_field() disassembly (after)
290   /// CHECK:             InstanceFieldSet
291   /// CHECK-NEXT:        add <<temp:x[0-9]+>>, x{{[0-9]+}}, #0x{{[0-9a-fA-F]+}}
292   /// CHECK-NEXT:        stlrh wzr, [<<temp>>]
293 
294   public volatile char volatile_instance_char_field;
295 
store_zero_to_volatile_instance_char_field()296   public void store_zero_to_volatile_instance_char_field() {
297     volatile_instance_char_field = 0;
298   }
299 
300   /// CHECK-START-ARM64: void Main.store_zero_to_volatile_instance_short_field() disassembly (after)
301   /// CHECK:             InstanceFieldSet
302   /// CHECK-NEXT:        add <<temp:x[0-9]+>>, x{{[0-9]+}}, #0x{{[0-9a-fA-F]+}}
303   /// CHECK-NEXT:        stlrh wzr, [<<temp>>]
304 
305   public volatile short volatile_instance_short_field;
306 
store_zero_to_volatile_instance_short_field()307   public void store_zero_to_volatile_instance_short_field() {
308     volatile_instance_short_field = 0;
309   }
310 
311   /// CHECK-START-ARM64: void Main.store_zero_to_volatile_instance_int_field() disassembly (after)
312   /// CHECK:             InstanceFieldSet
313   /// CHECK-NEXT:        add <<temp:x[0-9]+>>, x{{[0-9]+}}, #0x{{[0-9a-fA-F]+}}
314   /// CHECK-NEXT:        stlr wzr, [<<temp>>]
315 
316   public volatile int volatile_instance_int_field;
317 
store_zero_to_volatile_instance_int_field()318   public void store_zero_to_volatile_instance_int_field() {
319     volatile_instance_int_field = 0;
320   }
321 
322   /// CHECK-START-ARM64: void Main.store_zero_to_volatile_instance_long_field() disassembly (after)
323   /// CHECK:             InstanceFieldSet
324   /// CHECK-NEXT:        add <<temp:x[0-9]+>>, x{{[0-9]+}}, #0x{{[0-9a-fA-F]+}}
325   /// CHECK-NEXT:        stlr xzr, [<<temp>>]
326 
327   public volatile long volatile_instance_long_field;
328 
store_zero_to_volatile_instance_long_field()329   public void store_zero_to_volatile_instance_long_field() {
330     volatile_instance_long_field = 0;
331   }
332 
333   /// CHECK-START-ARM64: void Main.store_zero_to_volatile_instance_float_field() disassembly (after)
334   /// CHECK:             InstanceFieldSet
335   /// CHECK-NEXT:        add <<temp:x[0-9]+>>, x{{[0-9]+}}, #0x{{[0-9a-fA-F]+}}
336   /// CHECK-NEXT:        stlr wzr, [<<temp>>]
337 
338   public volatile float volatile_instance_float_field;
339 
store_zero_to_volatile_instance_float_field()340   public void store_zero_to_volatile_instance_float_field() {
341     volatile_instance_float_field = 0.0f;
342   }
343 
344   /// CHECK-START-ARM64: void Main.store_zero_to_volatile_instance_double_field() disassembly (after)
345   /// CHECK:             InstanceFieldSet
346   /// CHECK-NEXT:        add <<temp:x[0-9]+>>, x{{[0-9]+}}, #0x{{[0-9a-fA-F]+}}
347   /// CHECK-NEXT:        stlr xzr, [<<temp>>]
348 
349   public volatile double volatile_instance_double_field;
350 
store_zero_to_volatile_instance_double_field()351   public void store_zero_to_volatile_instance_double_field() {
352     volatile_instance_double_field = 0.0;
353   }
354 
355   /// CHECK-START-ARM64: void Main.store_zero_to_array_byte() disassembly (after)
356   /// CHECK:             ArraySet
357   /// CHECK-NEXT:        strb wzr, [x{{[0-9]+}}, #{{[0-9]+}}]
358 
359   byte array_byte[];
360 
store_zero_to_array_byte()361   public void store_zero_to_array_byte() {
362     array_byte[0] = 0;
363   }
364 
365   /// CHECK-START-ARM64: void Main.store_zero_to_array_char() disassembly (after)
366   /// CHECK:             ArraySet
367   /// CHECK-NEXT:        strh wzr, [x{{[0-9]+}}, #{{[0-9]+}}]
368 
369   char array_char[];
370 
store_zero_to_array_char()371   public void store_zero_to_array_char() {
372     array_char[0] = 0;
373   }
374 
375   /// CHECK-START-ARM64: void Main.store_zero_to_array_short() disassembly (after)
376   /// CHECK:             ArraySet
377   /// CHECK-NEXT:        strh wzr, [x{{[0-9]+}}, #{{[0-9]+}}]
378 
379   short array_short[];
380 
store_zero_to_array_short()381   public void store_zero_to_array_short() {
382     array_short[0] = 0;
383   }
384 
385   /// CHECK-START-ARM64: void Main.store_zero_to_array_int() disassembly (after)
386   /// CHECK:             ArraySet
387   /// CHECK-NEXT:        str wzr, [x{{[0-9]+}}, #{{[0-9]+}}]
388 
389   int array_int[];
390 
store_zero_to_array_int()391   public void store_zero_to_array_int() {
392     array_int[0] = 0;
393   }
394 
395   /// CHECK-START-ARM64: void Main.store_zero_to_array_long() disassembly (after)
396   /// CHECK:             ArraySet
397   /// CHECK-NEXT:        str xzr, [x{{[0-9]+}}, #{{[0-9]+}}]
398 
399   long array_long[];
400 
store_zero_to_array_long()401   public void store_zero_to_array_long() {
402     array_long[0] = 0;
403   }
404 
405   /// CHECK-START-ARM64: void Main.store_zero_to_array_float() disassembly (after)
406   /// CHECK:             ArraySet
407   /// CHECK-NEXT:        str wzr, [x{{[0-9]+}}, #{{[0-9]+}}]
408 
409   float array_float[];
410 
store_zero_to_array_float()411   public void store_zero_to_array_float() {
412     array_float[0] = 0.0f;
413   }
414 
415   /// CHECK-START-ARM64: void Main.store_zero_to_array_double() disassembly (after)
416   /// CHECK:             ArraySet
417   /// CHECK-NEXT:        str xzr, [x{{[0-9]+}}, #{{[0-9]+}}]
418 
419   double array_double[];
420 
store_zero_to_array_double()421   public void store_zero_to_array_double() {
422     array_double[0] = 0.0;
423   }
424 
main(String args[])425   public static void main(String args[]) {
426     Main obj = new Main();
427     obj.array_byte = new byte[1];
428     obj.array_char = new char[1];
429     obj.array_short = new short[1];
430     obj.array_int = new int[1];
431     obj.array_long = new long[1];
432     obj.array_float = new float[1];
433     obj.array_double = new double[1];
434 
435     obj.bar();
436     obj.store_zero_to_static_byte_field();
437     obj.store_zero_to_static_char_field();
438     obj.store_zero_to_static_short_field();
439     obj.store_zero_to_static_int_field();
440     obj.store_zero_to_static_long_field();
441     obj.store_zero_to_static_float_field();
442     obj.store_zero_to_static_double_field();
443     obj.store_zero_to_volatile_static_byte_field();
444     obj.store_zero_to_volatile_static_char_field();
445     obj.store_zero_to_volatile_static_short_field();
446     obj.store_zero_to_volatile_static_int_field();
447     obj.store_zero_to_volatile_static_long_field();
448     obj.store_zero_to_volatile_static_float_field();
449     obj.store_zero_to_volatile_static_double_field();
450     obj.store_zero_to_instance_byte_field();
451     obj.store_zero_to_instance_char_field();
452     obj.store_zero_to_instance_short_field();
453     obj.store_zero_to_instance_int_field();
454     obj.store_zero_to_instance_long_field();
455     obj.store_zero_to_instance_float_field();
456     obj.store_zero_to_instance_double_field();
457     obj.store_zero_to_volatile_instance_byte_field();
458     obj.store_zero_to_volatile_instance_char_field();
459     obj.store_zero_to_volatile_instance_short_field();
460     obj.store_zero_to_volatile_instance_int_field();
461     obj.store_zero_to_volatile_instance_long_field();
462     obj.store_zero_to_volatile_instance_float_field();
463     obj.store_zero_to_volatile_instance_double_field();
464     obj.store_zero_to_array_byte();
465     obj.store_zero_to_array_char();
466     obj.store_zero_to_array_short();
467     obj.store_zero_to_array_int();
468     obj.store_zero_to_array_long();
469     obj.store_zero_to_array_float();
470     obj.store_zero_to_array_double();
471   }
472 }
473