Home | History | Annotate | Download | only in src
      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 
     19   public static void assertIntEquals(int expected, int result) {
     20     if (expected != result) {
     21       throw new Error("Expected: " + expected + ", found: " + result);
     22     }
     23   }
     24 
     25   static boolean doThrow = false;
     26 
     27   // This function always returns 1.
     28   // We use 'throw' to prevent the function from being inlined.
     29   public static int $opt$noinline$function_call(int arg) {
     30     if (doThrow) throw new Error();
     31     return 1 % arg;
     32   }
     33 
     34   //                               | registers available to | regexp
     35   //                               | the register allocator |
     36   // ------------------------------|------------------------|-----------------
     37   // ARM64 callee-saved registers  | [x20-x29]              | x2[0-9]
     38   // ARM callee-saved registers    | [r5-r8,r10,r11]        | r([5-8]|10|11)
     39   // X86 callee-saved registers    | [ebp,esi,edi]          | e(bp|si|di)
     40   // X86_64 callee-saved registers | [rbx,rbp,r12-15]       | r(bx|bp|1[2-5])
     41 
     42   /**
     43    * Check that a value live across a function call is allocated in a callee
     44    * saved register.
     45    */
     46 
     47   /// CHECK-START-ARM:   int Main.$opt$LiveInCall(int) register (after)
     48   /// CHECK-DAG:   <<Arg:i\d+>>     ParameterValue
     49   /// CHECK-DAG:   <<Const1:i\d+>>  IntConstant 1
     50   /// CHECK:       <<t1:i\d+>>      Add [<<Arg>>,<<Const1>>] {{.*->r([5-8]|10|11)}}
     51   /// CHECK:       <<t2:i\d+>>      InvokeStaticOrDirect
     52   /// CHECK:                        Sub [<<t1>>,<<t2>>]
     53   /// CHECK:                        Return
     54 
     55   /// CHECK-START-ARM64: int Main.$opt$LiveInCall(int) register (after)
     56   /// CHECK-DAG:   <<Arg:i\d+>>     ParameterValue
     57   /// CHECK-DAG:   <<Const1:i\d+>>  IntConstant 1
     58   /// CHECK:       <<t1:i\d+>>      Add [<<Arg>>,<<Const1>>] {{.*->x2[0-9]}}
     59   /// CHECK:       <<t2:i\d+>>      InvokeStaticOrDirect
     60   /// CHECK:                        Sub [<<t1>>,<<t2>>]
     61   /// CHECK:                        Return
     62 
     63   /// CHECK-START-X86: int Main.$opt$LiveInCall(int) register (after)
     64   /// CHECK-DAG:   <<Arg:i\d+>>     ParameterValue
     65   /// CHECK-DAG:   <<Const1:i\d+>>  IntConstant 1
     66   /// CHECK:       <<t1:i\d+>>      Add [<<Arg>>,<<Const1>>] {{.*->e(bp|si|di)}}
     67   /// CHECK:       <<t2:i\d+>>      InvokeStaticOrDirect
     68   /// CHECK:                        Sub [<<t1>>,<<t2>>]
     69   /// CHECK:                        Return
     70 
     71   /// CHECK-START-X86_64: int Main.$opt$LiveInCall(int) register (after)
     72   /// CHECK-DAG:   <<Arg:i\d+>>     ParameterValue
     73   /// CHECK-DAG:   <<Const1:i\d+>>  IntConstant 1
     74   /// CHECK:       <<t1:i\d+>>      Add [<<Arg>>,<<Const1>>] {{.*->r(bx|bp|1[2-5])}}
     75   /// CHECK:       <<t2:i\d+>>      InvokeStaticOrDirect
     76   /// CHECK:                        Sub [<<t1>>,<<t2>>]
     77   /// CHECK:                        Return
     78 
     79   public static int $opt$LiveInCall(int arg) {
     80     int t1 = arg + 1;
     81     int t2 = $opt$noinline$function_call(arg);
     82     return t1 - t2;
     83   }
     84 
     85   public static void main(String[] args) {
     86     int arg = 123;
     87     assertIntEquals($opt$LiveInCall(arg), arg);
     88   }
     89 }
     90