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 25 static boolean doThrow = false; 26 27 // This function always returns 1. 28 // We use 'throw' to prevent the function from being inlined. $opt$noinline$function_call(int arg)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 $opt$LiveInCall(int arg)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 main(String[] args)85 public static void main(String[] args) { 86 int arg = 123; 87 assertIntEquals($opt$LiveInCall(arg), arg); 88 } 89 } 90