1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2015 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker public class Main { 18*795d594fSAndroid Build Coastguard Worker assertIntEquals(int expected, int result)19*795d594fSAndroid Build Coastguard Worker public static void assertIntEquals(int expected, int result) { 20*795d594fSAndroid Build Coastguard Worker if (expected != result) { 21*795d594fSAndroid Build Coastguard Worker throw new Error("Expected: " + expected + ", found: " + result); 22*795d594fSAndroid Build Coastguard Worker } 23*795d594fSAndroid Build Coastguard Worker } 24*795d594fSAndroid Build Coastguard Worker 25*795d594fSAndroid Build Coastguard Worker // This function always returns 1. $opt$noinline$function_call(int arg)26*795d594fSAndroid Build Coastguard Worker public static int $opt$noinline$function_call(int arg) { 27*795d594fSAndroid Build Coastguard Worker return 1 % arg; 28*795d594fSAndroid Build Coastguard Worker } 29*795d594fSAndroid Build Coastguard Worker 30*795d594fSAndroid Build Coastguard Worker // | registers available to | regexp 31*795d594fSAndroid Build Coastguard Worker // | the register allocator | 32*795d594fSAndroid Build Coastguard Worker // ------------------------------|------------------------|----------------- 33*795d594fSAndroid Build Coastguard Worker // ARM64 callee-saved registers | [x20-x29] | x2[0-9] 34*795d594fSAndroid Build Coastguard Worker // ARM callee-saved registers | [r5-r8,r10,r11] | r([5-8]|10|11) 35*795d594fSAndroid Build Coastguard Worker // X86 callee-saved registers | [ebp,esi,edi] | e(bp|si|di) 36*795d594fSAndroid Build Coastguard Worker // X86_64 callee-saved registers | [rbx,rbp,r12-15] | r(bx|bp|1[2-5]) 37*795d594fSAndroid Build Coastguard Worker 38*795d594fSAndroid Build Coastguard Worker /** 39*795d594fSAndroid Build Coastguard Worker * Check that a value live across a function call is allocated in a callee 40*795d594fSAndroid Build Coastguard Worker * saved register. 41*795d594fSAndroid Build Coastguard Worker */ 42*795d594fSAndroid Build Coastguard Worker 43*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM: int Main.$opt$LiveInCall(int) register (after) 44*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 45*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 46*795d594fSAndroid Build Coastguard Worker /// CHECK: <<t1:i\d+>> Add [<<Arg>>,<<Const1>>] {{.*->r([5-8]|10|11)}} 47*795d594fSAndroid Build Coastguard Worker /// CHECK: <<t2:i\d+>> InvokeStaticOrDirect 48*795d594fSAndroid Build Coastguard Worker /// CHECK: Sub [<<t1>>,<<t2>>] 49*795d594fSAndroid Build Coastguard Worker /// CHECK: Return 50*795d594fSAndroid Build Coastguard Worker 51*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM64: int Main.$opt$LiveInCall(int) register (after) 52*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 53*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 54*795d594fSAndroid Build Coastguard Worker /// CHECK: <<t1:i\d+>> Add [<<Arg>>,<<Const1>>] {{.*->x2[0-9]}} 55*795d594fSAndroid Build Coastguard Worker /// CHECK: <<t2:i\d+>> InvokeStaticOrDirect 56*795d594fSAndroid Build Coastguard Worker /// CHECK: Sub [<<t1>>,<<t2>>] 57*795d594fSAndroid Build Coastguard Worker /// CHECK: Return 58*795d594fSAndroid Build Coastguard Worker 59*795d594fSAndroid Build Coastguard Worker /// CHECK-START-X86: int Main.$opt$LiveInCall(int) register (after) 60*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 61*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 62*795d594fSAndroid Build Coastguard Worker /// CHECK: <<t1:i\d+>> Add [<<Arg>>,<<Const1>>] {{.*->e(bp|si|di)}} 63*795d594fSAndroid Build Coastguard Worker /// CHECK: <<t2:i\d+>> InvokeStaticOrDirect 64*795d594fSAndroid Build Coastguard Worker /// CHECK: Sub [<<t1>>,<<t2>>] 65*795d594fSAndroid Build Coastguard Worker /// CHECK: Return 66*795d594fSAndroid Build Coastguard Worker 67*795d594fSAndroid Build Coastguard Worker /// CHECK-START-X86_64: int Main.$opt$LiveInCall(int) register (after) 68*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 69*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 70*795d594fSAndroid Build Coastguard Worker /// CHECK: <<t1:i\d+>> Add [<<Arg>>,<<Const1>>] {{.*->r(bx|bp|1[2-5])}} 71*795d594fSAndroid Build Coastguard Worker /// CHECK: <<t2:i\d+>> InvokeStaticOrDirect 72*795d594fSAndroid Build Coastguard Worker /// CHECK: Sub [<<t1>>,<<t2>>] 73*795d594fSAndroid Build Coastguard Worker /// CHECK: Return 74*795d594fSAndroid Build Coastguard Worker $opt$LiveInCall(int arg)75*795d594fSAndroid Build Coastguard Worker public static int $opt$LiveInCall(int arg) { 76*795d594fSAndroid Build Coastguard Worker int t1 = arg + 1; 77*795d594fSAndroid Build Coastguard Worker int t2 = $opt$noinline$function_call(arg); 78*795d594fSAndroid Build Coastguard Worker return t1 - t2; 79*795d594fSAndroid Build Coastguard Worker } 80*795d594fSAndroid Build Coastguard Worker main(String[] args)81*795d594fSAndroid Build Coastguard Worker public static void main(String[] args) { 82*795d594fSAndroid Build Coastguard Worker int arg = 123; 83*795d594fSAndroid Build Coastguard Worker assertIntEquals($opt$LiveInCall(arg), arg); 84*795d594fSAndroid Build Coastguard Worker } 85*795d594fSAndroid Build Coastguard Worker } 86