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 actual)19*795d594fSAndroid Build Coastguard Worker public static void assertIntEquals(int expected, int actual) { 20*795d594fSAndroid Build Coastguard Worker if (expected != actual) { 21*795d594fSAndroid Build Coastguard Worker throw new Error("Expected: " + expected + ", found: " + actual); 22*795d594fSAndroid Build Coastguard Worker } 23*795d594fSAndroid Build Coastguard Worker } 24*795d594fSAndroid Build Coastguard Worker assertLongEquals(long expected, long actual)25*795d594fSAndroid Build Coastguard Worker public static void assertLongEquals(long expected, long actual) { 26*795d594fSAndroid Build Coastguard Worker if (expected != actual) { 27*795d594fSAndroid Build Coastguard Worker throw new Error("Expected: " + expected + ", found: " + actual); 28*795d594fSAndroid Build Coastguard Worker } 29*795d594fSAndroid Build Coastguard Worker } 30*795d594fSAndroid Build Coastguard Worker 31*795d594fSAndroid Build Coastguard Worker // (i >>> #distance) | (i << #(reg_bits - distance)) 32*795d594fSAndroid Build Coastguard Worker 33*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.ror_int_constant_c_c(int) instruction_simplifier (before) 34*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:i\d+>> ParameterValue 35*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const2:i\d+>> IntConstant 2 36*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const30:i\d+>> IntConstant 30 37*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<Const2>>] 38*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<Const30>>] 39*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] 40*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Or>>] 41*795d594fSAndroid Build Coastguard Worker 42*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.ror_int_constant_c_c(int) instruction_simplifier (after) 43*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:i\d+>> ParameterValue 44*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const2:i\d+>> IntConstant 2 45*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<Const2>>] 46*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Ror>>] 47*795d594fSAndroid Build Coastguard Worker 48*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.ror_int_constant_c_c(int) instruction_simplifier (after) 49*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: UShr 50*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Shl ror_int_constant_c_c(int value)51*795d594fSAndroid Build Coastguard Worker public static int ror_int_constant_c_c(int value) { 52*795d594fSAndroid Build Coastguard Worker return (value >>> 2) | (value << 30); 53*795d594fSAndroid Build Coastguard Worker } 54*795d594fSAndroid Build Coastguard Worker 55*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.ror_int_constant_c_c_0(int) instruction_simplifier (after) 56*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:i\d+>> ParameterValue 57*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const2:i\d+>> IntConstant 2 58*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<Const2>>] 59*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Ror>>] 60*795d594fSAndroid Build Coastguard Worker 61*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.ror_int_constant_c_c_0(int) instruction_simplifier (after) 62*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: UShr 63*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Shl ror_int_constant_c_c_0(int value)64*795d594fSAndroid Build Coastguard Worker public static int ror_int_constant_c_c_0(int value) { 65*795d594fSAndroid Build Coastguard Worker return (value >>> 2) | (value << 62); 66*795d594fSAndroid Build Coastguard Worker } 67*795d594fSAndroid Build Coastguard Worker 68*795d594fSAndroid Build Coastguard Worker // (j >>> #distance) | (j << #(reg_bits - distance)) 69*795d594fSAndroid Build Coastguard Worker 70*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.ror_long_constant_c_c(long) instruction_simplifier (before) 71*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:j\d+>> ParameterValue 72*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const2:i\d+>> IntConstant 2 73*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const62:i\d+>> IntConstant 62 74*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<Const2>>] 75*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<Const62>>] 76*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Or:j\d+>> Or [<<UShr>>,<<Shl>>] 77*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Or>>] 78*795d594fSAndroid Build Coastguard Worker 79*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.ror_long_constant_c_c(long) instruction_simplifier (after) 80*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:j\d+>> ParameterValue 81*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const2:i\d+>> IntConstant 2 82*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<Const2>>] 83*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Ror>>] 84*795d594fSAndroid Build Coastguard Worker 85*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.ror_long_constant_c_c(long) instruction_simplifier (after) 86*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: UShr 87*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Shl ror_long_constant_c_c(long value)88*795d594fSAndroid Build Coastguard Worker public static long ror_long_constant_c_c(long value) { 89*795d594fSAndroid Build Coastguard Worker return (value >>> 2) | (value << 62); 90*795d594fSAndroid Build Coastguard Worker } 91*795d594fSAndroid Build Coastguard Worker 92*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.ror_long_constant_c_c_0(long) instruction_simplifier (after) 93*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Ror ror_long_constant_c_c_0(long value)94*795d594fSAndroid Build Coastguard Worker public static long ror_long_constant_c_c_0(long value) { 95*795d594fSAndroid Build Coastguard Worker return (value >>> 2) | (value << 30); 96*795d594fSAndroid Build Coastguard Worker } 97*795d594fSAndroid Build Coastguard Worker 98*795d594fSAndroid Build Coastguard Worker // (i >>> #distance) | (i << #-distance) 99*795d594fSAndroid Build Coastguard Worker 100*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.ror_int_constant_c_negc(int) instruction_simplifier$after_inlining (before) 101*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:i\d+>> ParameterValue 102*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const2:i\d+>> IntConstant 2 103*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ConstNeg2:i\d+>> IntConstant -2 104*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<Const2>>] 105*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<ConstNeg2>>] 106*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] 107*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Or>>] 108*795d594fSAndroid Build Coastguard Worker 109*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.ror_int_constant_c_negc(int) instruction_simplifier$after_inlining (after) 110*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:i\d+>> ParameterValue 111*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const2:i\d+>> IntConstant 2 112*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<Const2>>] 113*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Ror>>] 114*795d594fSAndroid Build Coastguard Worker 115*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.ror_int_constant_c_negc(int) instruction_simplifier$after_inlining (after) 116*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: UShr 117*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Shl ror_int_constant_c_negc(int value)118*795d594fSAndroid Build Coastguard Worker public static int ror_int_constant_c_negc(int value) { 119*795d594fSAndroid Build Coastguard Worker return (value >>> 2) | (value << $opt$inline$IntConstantM2()); 120*795d594fSAndroid Build Coastguard Worker } 121*795d594fSAndroid Build Coastguard Worker 122*795d594fSAndroid Build Coastguard Worker // Hiding constants outside the range [0, 32) used for int shifts from Jack. 123*795d594fSAndroid Build Coastguard Worker // (Jack extracts only the low 5 bits.) $opt$inline$IntConstantM2()124*795d594fSAndroid Build Coastguard Worker public static int $opt$inline$IntConstantM2() { return -2; } 125*795d594fSAndroid Build Coastguard Worker 126*795d594fSAndroid Build Coastguard Worker // (j >>> #distance) | (j << #-distance) 127*795d594fSAndroid Build Coastguard Worker 128*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.ror_long_constant_c_negc(long) instruction_simplifier (before) 129*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:j\d+>> ParameterValue 130*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const2:i\d+>> IntConstant 2 131*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ConstNeg2:i\d+>> IntConstant -2 132*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<Const2>>] 133*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<ConstNeg2>>] 134*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Or:j\d+>> Or [<<UShr>>,<<Shl>>] 135*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Or>>] 136*795d594fSAndroid Build Coastguard Worker 137*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.ror_long_constant_c_negc(long) instruction_simplifier (after) 138*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:j\d+>> ParameterValue 139*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const2:i\d+>> IntConstant 2 140*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<Const2>>] 141*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Ror>>] 142*795d594fSAndroid Build Coastguard Worker 143*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.ror_long_constant_c_negc(long) instruction_simplifier (after) 144*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: UShr 145*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Shl ror_long_constant_c_negc(long value)146*795d594fSAndroid Build Coastguard Worker public static long ror_long_constant_c_negc(long value) { 147*795d594fSAndroid Build Coastguard Worker return (value >>> 2) | (value << -2); 148*795d594fSAndroid Build Coastguard Worker } 149*795d594fSAndroid Build Coastguard Worker 150*795d594fSAndroid Build Coastguard Worker // (i >>> distance) | (i << (#reg_bits - distance) 151*795d594fSAndroid Build Coastguard Worker 152*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.ror_int_reg_v_csubv(int, int) instruction_simplifier (before) 153*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:i\d+>> ParameterValue 154*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgDistance:i\d+>> ParameterValue 155*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const32:i\d+>> IntConstant 32 156*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<ArgDistance>>] 157*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Const32>>,<<ArgDistance>>] 158*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<Sub>>] 159*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] 160*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Or>>] 161*795d594fSAndroid Build Coastguard Worker 162*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.ror_int_reg_v_csubv(int, int) instruction_simplifier (after) 163*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:i\d+>> ParameterValue 164*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgDistance:i\d+>> ParameterValue 165*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<ArgDistance>>] 166*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Ror>>] 167*795d594fSAndroid Build Coastguard Worker 168*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.ror_int_reg_v_csubv(int, int) instruction_simplifier (after) 169*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: UShr 170*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Shl 171*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Sub ror_int_reg_v_csubv(int value, int distance)172*795d594fSAndroid Build Coastguard Worker public static int ror_int_reg_v_csubv(int value, int distance) { 173*795d594fSAndroid Build Coastguard Worker return (value >>> distance) | (value << (32 - distance)); 174*795d594fSAndroid Build Coastguard Worker } 175*795d594fSAndroid Build Coastguard Worker 176*795d594fSAndroid Build Coastguard Worker // (distance = x - y) 177*795d594fSAndroid Build Coastguard Worker // (i >>> distance) | (i << (#reg_bits - distance) 178*795d594fSAndroid Build Coastguard Worker 179*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.ror_int_subv_csubv(int, int, int) instruction_simplifier (before) 180*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:i\d+>> ParameterValue 181*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgX:i\d+>> ParameterValue 182*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgY:i\d+>> ParameterValue 183*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const32:i\d+>> IntConstant 32 184*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<SubDistance:i\d+>> Sub [<<ArgX>>,<<ArgY>>] 185*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Sub32:i\d+>> Sub [<<Const32>>,<<SubDistance>>] 186*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<Sub32>>] 187*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<SubDistance>>] 188*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] 189*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Or>>] 190*795d594fSAndroid Build Coastguard Worker 191*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.ror_int_subv_csubv(int, int, int) instruction_simplifier (after) 192*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:i\d+>> ParameterValue 193*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgX:i\d+>> ParameterValue 194*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgY:i\d+>> ParameterValue 195*795d594fSAndroid Build Coastguard Worker /// CHECK: <<SubDistance:i\d+>> Sub [<<ArgX>>,<<ArgY>>] 196*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<SubDistance>>] 197*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Ror>>] 198*795d594fSAndroid Build Coastguard Worker 199*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.ror_int_subv_csubv(int, int, int) instruction_simplifier (after) 200*795d594fSAndroid Build Coastguard Worker /// CHECK: Sub 201*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Sub 202*795d594fSAndroid Build Coastguard Worker 203*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.ror_int_subv_csubv(int, int, int) instruction_simplifier (after) 204*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: UShr 205*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Shl ror_int_subv_csubv(int value, int x, int y)206*795d594fSAndroid Build Coastguard Worker public static int ror_int_subv_csubv(int value, int x, int y) { 207*795d594fSAndroid Build Coastguard Worker int distance = x - y; 208*795d594fSAndroid Build Coastguard Worker return (value >>> distance) | (value << (32 - distance)); 209*795d594fSAndroid Build Coastguard Worker } 210*795d594fSAndroid Build Coastguard Worker 211*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.ror_int_subv_csubv_env(int, int, int) instruction_simplifier (before) 212*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:i\d+>> ParameterValue 213*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgX:i\d+>> ParameterValue 214*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgY:i\d+>> ParameterValue 215*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const32:i\d+>> IntConstant 32 216*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<SubDistance:i\d+>> Sub [<<ArgX>>,<<ArgY>>] 217*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Sub32:i\d+>> Sub [<<Const32>>,<<SubDistance>>] 218*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<SubDistance>>] 219*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<Sub32>>] 220*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] 221*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Add:i\d+>> Add [<<Or>>,<<Sub32>>] 222*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Add>>] 223*795d594fSAndroid Build Coastguard Worker 224*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.ror_int_subv_csubv_env(int, int, int) instruction_simplifier (after) 225*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:i\d+>> ParameterValue 226*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgX:i\d+>> ParameterValue 227*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgY:i\d+>> ParameterValue 228*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const32:i\d+>> IntConstant 32 229*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<SubDistance:i\d+>> Sub [<<ArgX>>,<<ArgY>>] 230*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Sub32:i\d+>> Sub [<<Const32>>,<<SubDistance>>] 231*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<SubDistance>>] 232*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Add:i\d+>> Add [<<Ror>>,<<Sub32>>] 233*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Add>>] 234*795d594fSAndroid Build Coastguard Worker 235*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.ror_int_subv_csubv_env(int, int, int) instruction_simplifier (after) 236*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: UShr 237*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Shl ror_int_subv_csubv_env(int value, int x, int y)238*795d594fSAndroid Build Coastguard Worker public static int ror_int_subv_csubv_env(int value, int x, int y) { 239*795d594fSAndroid Build Coastguard Worker int distance = x - y; 240*795d594fSAndroid Build Coastguard Worker int bits_minus_dist = 32 - distance; 241*795d594fSAndroid Build Coastguard Worker return ((value >>> distance) | (value << bits_minus_dist)) + bits_minus_dist; 242*795d594fSAndroid Build Coastguard Worker } 243*795d594fSAndroid Build Coastguard Worker 244*795d594fSAndroid Build Coastguard Worker // (j >>> distance) | (j << (#reg_bits - distance) 245*795d594fSAndroid Build Coastguard Worker 246*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.ror_long_reg_v_csubv(long, int) instruction_simplifier (before) 247*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:j\d+>> ParameterValue 248*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgDistance:i\d+>> ParameterValue 249*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const64:i\d+>> IntConstant 64 250*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<ArgDistance>>] 251*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Const64>>,<<ArgDistance>>] 252*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<Sub>>] 253*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Or:j\d+>> Or [<<UShr>>,<<Shl>>] 254*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Or>>] 255*795d594fSAndroid Build Coastguard Worker 256*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.ror_long_reg_v_csubv(long, int) instruction_simplifier (after) 257*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:j\d+>> ParameterValue 258*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgDistance:i\d+>> ParameterValue 259*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<ArgDistance>>] 260*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Ror>>] 261*795d594fSAndroid Build Coastguard Worker 262*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.ror_long_reg_v_csubv(long, int) instruction_simplifier (after) 263*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: UShr 264*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Shl 265*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Sub ror_long_reg_v_csubv(long value, int distance)266*795d594fSAndroid Build Coastguard Worker public static long ror_long_reg_v_csubv(long value, int distance) { 267*795d594fSAndroid Build Coastguard Worker return (value >>> distance) | (value << (64 - distance)); 268*795d594fSAndroid Build Coastguard Worker } 269*795d594fSAndroid Build Coastguard Worker 270*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.ror_long_reg_v_csubv_0(long, int) instruction_simplifier (after) 271*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Ror ror_long_reg_v_csubv_0(long value, int distance)272*795d594fSAndroid Build Coastguard Worker public static long ror_long_reg_v_csubv_0(long value, int distance) { 273*795d594fSAndroid Build Coastguard Worker return (value >>> distance) | (value << (32 - distance)); 274*795d594fSAndroid Build Coastguard Worker } 275*795d594fSAndroid Build Coastguard Worker 276*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.ror_long_subv_csubv_0(long, int, int) instruction_simplifier (after) 277*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Ror ror_long_subv_csubv_0(long value, int x, int y)278*795d594fSAndroid Build Coastguard Worker public static long ror_long_subv_csubv_0(long value, int x, int y) { 279*795d594fSAndroid Build Coastguard Worker int distance = x - y; 280*795d594fSAndroid Build Coastguard Worker return (value >>> distance) | (value << (32 - distance)); 281*795d594fSAndroid Build Coastguard Worker } 282*795d594fSAndroid Build Coastguard Worker 283*795d594fSAndroid Build Coastguard Worker // (i >>> (#reg_bits - distance)) | (i << distance) 284*795d594fSAndroid Build Coastguard Worker 285*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.rol_int_reg_csubv_v(int, int) instruction_simplifier (before) 286*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:i\d+>> ParameterValue 287*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgDistance:i\d+>> ParameterValue 288*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const32:i\d+>> IntConstant 32 289*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Const32>>,<<ArgDistance>>] 290*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<Sub>>] 291*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<ArgDistance>>] 292*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] 293*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Or>>] 294*795d594fSAndroid Build Coastguard Worker 295*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.rol_int_reg_csubv_v(int, int) instruction_simplifier (after) 296*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:i\d+>> ParameterValue 297*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgDistance:i\d+>> ParameterValue 298*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const32:i\d+>> IntConstant 32 299*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Sub:i\d+>> Sub [<<Const32>>,<<ArgDistance>>] 300*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<Sub>>] 301*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Ror>>] 302*795d594fSAndroid Build Coastguard Worker 303*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.rol_int_reg_csubv_v(int, int) instruction_simplifier (after) 304*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: UShr 305*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Shl rol_int_reg_csubv_v(int value, int distance)306*795d594fSAndroid Build Coastguard Worker public static int rol_int_reg_csubv_v(int value, int distance) { 307*795d594fSAndroid Build Coastguard Worker return (value >>> (32 - distance)) | (value << distance); 308*795d594fSAndroid Build Coastguard Worker } 309*795d594fSAndroid Build Coastguard Worker 310*795d594fSAndroid Build Coastguard Worker // (distance = x - y) 311*795d594fSAndroid Build Coastguard Worker // (i >>> (#reg_bits - distance)) | (i << distance) 312*795d594fSAndroid Build Coastguard Worker 313*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.rol_int_csubv_subv(int, int, int) instruction_simplifier (before) 314*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:i\d+>> ParameterValue 315*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgX:i\d+>> ParameterValue 316*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgY:i\d+>> ParameterValue 317*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const32:i\d+>> IntConstant 32 318*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<SubDistance:i\d+>> Sub [<<ArgX>>,<<ArgY>>] 319*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Sub32:i\d+>> Sub [<<Const32>>,<<SubDistance>>] 320*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<SubDistance>>] 321*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<Sub32>>] 322*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] 323*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Or>>] 324*795d594fSAndroid Build Coastguard Worker 325*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.rol_int_csubv_subv(int, int, int) instruction_simplifier (after) 326*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:i\d+>> ParameterValue 327*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgX:i\d+>> ParameterValue 328*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgY:i\d+>> ParameterValue 329*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const32:i\d+>> IntConstant 32 330*795d594fSAndroid Build Coastguard Worker /// CHECK: <<SubDistance:i\d+>> Sub [<<ArgX>>,<<ArgY>>] 331*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Sub:i\d+>> Sub [<<Const32>>,<<SubDistance>>] 332*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<Sub>>] 333*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Ror>>] 334*795d594fSAndroid Build Coastguard Worker 335*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.rol_int_csubv_subv(int, int, int) instruction_simplifier (after) 336*795d594fSAndroid Build Coastguard Worker /// CHECK: Sub 337*795d594fSAndroid Build Coastguard Worker /// CHECK: Sub 338*795d594fSAndroid Build Coastguard Worker 339*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.rol_int_csubv_subv(int, int, int) instruction_simplifier (after) 340*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: UShr 341*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Shl rol_int_csubv_subv(int value, int x, int y)342*795d594fSAndroid Build Coastguard Worker public static int rol_int_csubv_subv(int value, int x, int y) { 343*795d594fSAndroid Build Coastguard Worker int distance = x - y; 344*795d594fSAndroid Build Coastguard Worker return (value >>> (32 - distance)) | (value << distance); 345*795d594fSAndroid Build Coastguard Worker } 346*795d594fSAndroid Build Coastguard Worker 347*795d594fSAndroid Build Coastguard Worker // (j >>> (#reg_bits - distance)) | (j << distance) 348*795d594fSAndroid Build Coastguard Worker 349*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.rol_long_reg_csubv_v(long, int) instruction_simplifier (before) 350*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:j\d+>> ParameterValue 351*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgDistance:i\d+>> ParameterValue 352*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const64:i\d+>> IntConstant 64 353*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Const64>>,<<ArgDistance>>] 354*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<Sub>>] 355*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<ArgDistance>>] 356*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Or:j\d+>> Or [<<UShr>>,<<Shl>>] 357*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Or>>] 358*795d594fSAndroid Build Coastguard Worker 359*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.rol_long_reg_csubv_v(long, int) instruction_simplifier (after) 360*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:j\d+>> ParameterValue 361*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgDistance:i\d+>> ParameterValue 362*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const64:i\d+>> IntConstant 64 363*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Sub:i\d+>> Sub [<<Const64>>,<<ArgDistance>>] 364*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<Sub>>] 365*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Ror>>] 366*795d594fSAndroid Build Coastguard Worker 367*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.rol_long_reg_csubv_v(long, int) instruction_simplifier (after) 368*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: UShr 369*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Shl rol_long_reg_csubv_v(long value, int distance)370*795d594fSAndroid Build Coastguard Worker public static long rol_long_reg_csubv_v(long value, int distance) { 371*795d594fSAndroid Build Coastguard Worker return (value >>> (64 - distance)) | (value << distance); 372*795d594fSAndroid Build Coastguard Worker } 373*795d594fSAndroid Build Coastguard Worker 374*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.rol_long_reg_csubv_v_0(long, int) instruction_simplifier (after) 375*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Ror rol_long_reg_csubv_v_0(long value, int distance)376*795d594fSAndroid Build Coastguard Worker public static long rol_long_reg_csubv_v_0(long value, int distance) { 377*795d594fSAndroid Build Coastguard Worker return (value >>> (32 - distance)) | (value << distance); 378*795d594fSAndroid Build Coastguard Worker } 379*795d594fSAndroid Build Coastguard Worker 380*795d594fSAndroid Build Coastguard Worker // (i >>> distance) | (i << -distance) (i.e. libcore's Integer.rotateRight) 381*795d594fSAndroid Build Coastguard Worker 382*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.ror_int_reg_v_negv(int, int) instruction_simplifier (before) 383*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:i\d+>> ParameterValue 384*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgDistance:i\d+>> ParameterValue 385*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<ArgDistance>>] 386*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] 387*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<Neg>>] 388*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] 389*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Or>>] 390*795d594fSAndroid Build Coastguard Worker 391*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.ror_int_reg_v_negv(int, int) instruction_simplifier (after) 392*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:i\d+>> ParameterValue 393*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgDistance:i\d+>> ParameterValue 394*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<ArgDistance>>] 395*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Ror>>] 396*795d594fSAndroid Build Coastguard Worker 397*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.ror_int_reg_v_negv(int, int) instruction_simplifier (after) 398*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: UShr 399*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Shl 400*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Neg ror_int_reg_v_negv(int value, int distance)401*795d594fSAndroid Build Coastguard Worker public static int ror_int_reg_v_negv(int value, int distance) { 402*795d594fSAndroid Build Coastguard Worker return (value >>> distance) | (value << -distance); 403*795d594fSAndroid Build Coastguard Worker } 404*795d594fSAndroid Build Coastguard Worker 405*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.ror_int_reg_v_negv_env(int, int) instruction_simplifier (before) 406*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:i\d+>> ParameterValue 407*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgDistance:i\d+>> ParameterValue 408*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] 409*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<ArgDistance>>] 410*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<Neg>>] 411*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] 412*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Add:i\d+>> Add [<<Or>>,<<Neg>>] 413*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Add>>] 414*795d594fSAndroid Build Coastguard Worker 415*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.ror_int_reg_v_negv_env(int, int) instruction_simplifier (after) 416*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:i\d+>> ParameterValue 417*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgDistance:i\d+>> ParameterValue 418*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<ArgDistance>>] 419*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Sub:i\d+>> Sub [<<Ror>>,<<ArgDistance>>] 420*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Sub>>] 421*795d594fSAndroid Build Coastguard Worker 422*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.ror_int_reg_v_negv_env(int, int) instruction_simplifier (after) 423*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: UShr 424*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Shl ror_int_reg_v_negv_env(int value, int distance)425*795d594fSAndroid Build Coastguard Worker public static int ror_int_reg_v_negv_env(int value, int distance) { 426*795d594fSAndroid Build Coastguard Worker int neg_distance = -distance; 427*795d594fSAndroid Build Coastguard Worker return ((value >>> distance) | (value << neg_distance)) + neg_distance; 428*795d594fSAndroid Build Coastguard Worker } 429*795d594fSAndroid Build Coastguard Worker 430*795d594fSAndroid Build Coastguard Worker // (j >>> distance) | (j << -distance) (i.e. libcore's Long.rotateRight) 431*795d594fSAndroid Build Coastguard Worker 432*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.ror_long_reg_v_negv(long, int) instruction_simplifier (before) 433*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:j\d+>> ParameterValue 434*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgDistance:i\d+>> ParameterValue 435*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<ArgDistance>>] 436*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] 437*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<Neg>>] 438*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Or:j\d+>> Or [<<UShr>>,<<Shl>>] 439*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Or>>] 440*795d594fSAndroid Build Coastguard Worker 441*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.ror_long_reg_v_negv(long, int) instruction_simplifier (after) 442*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:j\d+>> ParameterValue 443*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgDistance:i\d+>> ParameterValue 444*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<ArgDistance>>] 445*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Ror>>] 446*795d594fSAndroid Build Coastguard Worker 447*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.ror_long_reg_v_negv(long, int) instruction_simplifier (after) 448*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: UShr 449*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Shl 450*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Neg ror_long_reg_v_negv(long value, int distance)451*795d594fSAndroid Build Coastguard Worker public static long ror_long_reg_v_negv(long value, int distance) { 452*795d594fSAndroid Build Coastguard Worker return (value >>> distance) | (value << -distance); 453*795d594fSAndroid Build Coastguard Worker } 454*795d594fSAndroid Build Coastguard Worker 455*795d594fSAndroid Build Coastguard Worker // (i << distance) | (i >>> -distance) (i.e. libcore's Integer.rotateLeft) 456*795d594fSAndroid Build Coastguard Worker 457*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.rol_int_reg_negv_v(int, int) instruction_simplifier (before) 458*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:i\d+>> ParameterValue 459*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgDistance:i\d+>> ParameterValue 460*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] 461*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<Neg>>] 462*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<ArgDistance>>] 463*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Or:i\d+>> Or [<<Shl>>,<<UShr>>] 464*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Or>>] 465*795d594fSAndroid Build Coastguard Worker 466*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.rol_int_reg_negv_v(int, int) instruction_simplifier (after) 467*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:i\d+>> ParameterValue 468*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgDistance:i\d+>> ParameterValue 469*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Neg:i\d+>> Neg [<<ArgDistance>>] 470*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<Neg>>] 471*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Ror>>] 472*795d594fSAndroid Build Coastguard Worker 473*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.rol_int_reg_negv_v(int, int) instruction_simplifier (after) 474*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: UShr 475*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Shl rol_int_reg_negv_v(int value, int distance)476*795d594fSAndroid Build Coastguard Worker public static int rol_int_reg_negv_v(int value, int distance) { 477*795d594fSAndroid Build Coastguard Worker return (value << distance) | (value >>> -distance); 478*795d594fSAndroid Build Coastguard Worker } 479*795d594fSAndroid Build Coastguard Worker 480*795d594fSAndroid Build Coastguard Worker // (j << distance) | (j >>> -distance) (i.e. libcore's Long.rotateLeft) 481*795d594fSAndroid Build Coastguard Worker 482*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.rol_long_reg_negv_v(long, int) instruction_simplifier (before) 483*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:j\d+>> ParameterValue 484*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgDistance:i\d+>> ParameterValue 485*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] 486*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<Neg>>] 487*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<ArgDistance>>] 488*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Or:j\d+>> Or [<<Shl>>,<<UShr>>] 489*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Or>>] 490*795d594fSAndroid Build Coastguard Worker 491*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.rol_long_reg_negv_v(long, int) instruction_simplifier (after) 492*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:j\d+>> ParameterValue 493*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgDistance:i\d+>> ParameterValue 494*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Neg:i\d+>> Neg [<<ArgDistance>>] 495*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<Neg>>] 496*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Ror>>] 497*795d594fSAndroid Build Coastguard Worker 498*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.rol_long_reg_negv_v(long, int) instruction_simplifier (after) 499*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: UShr 500*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Shl rol_long_reg_negv_v(long value, int distance)501*795d594fSAndroid Build Coastguard Worker public static long rol_long_reg_negv_v(long value, int distance) { 502*795d594fSAndroid Build Coastguard Worker return (value << distance) | (value >>> -distance); 503*795d594fSAndroid Build Coastguard Worker } 504*795d594fSAndroid Build Coastguard Worker 505*795d594fSAndroid Build Coastguard Worker // (j << distance) + (j >>> -distance) 506*795d594fSAndroid Build Coastguard Worker // We can't perform the optimization as distance might be `0`, resulting in the wrong value. 507*795d594fSAndroid Build Coastguard Worker 508*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.rol_long_reg_v_negv_add(long, int) instruction_simplifier (before) 509*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:j\d+>> ParameterValue 510*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgDistance:i\d+>> ParameterValue 511*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] 512*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<Neg>>] 513*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<ArgDistance>>] 514*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Add:j\d+>> Add [<<Shl>>,<<UShr>>] 515*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Add>>] 516*795d594fSAndroid Build Coastguard Worker 517*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.rol_long_reg_v_negv_add(long, int) instruction_simplifier (after) 518*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:j\d+>> ParameterValue 519*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgDistance:i\d+>> ParameterValue 520*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] 521*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<Neg>>] 522*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<ArgDistance>>] 523*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Add:j\d+>> Add [<<Shl>>,<<UShr>>] 524*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Add>>] rol_long_reg_v_negv_add(long value, int distance)525*795d594fSAndroid Build Coastguard Worker public static long rol_long_reg_v_negv_add(long value, int distance) { 526*795d594fSAndroid Build Coastguard Worker return (value << distance) + (value >>> -distance); 527*795d594fSAndroid Build Coastguard Worker } 528*795d594fSAndroid Build Coastguard Worker 529*795d594fSAndroid Build Coastguard Worker // (j << distance) ^ (j >>> -distance) 530*795d594fSAndroid Build Coastguard Worker // We can't perform the optimization as distance might be `0`, resulting in the wrong value. 531*795d594fSAndroid Build Coastguard Worker 532*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.rol_long_reg_v_negv_xor(long, int) instruction_simplifier (before) 533*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:j\d+>> ParameterValue 534*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgDistance:i\d+>> ParameterValue 535*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] 536*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<Neg>>] 537*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<ArgDistance>>] 538*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Xor:j\d+>> Xor [<<Shl>>,<<UShr>>] 539*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Xor>>] 540*795d594fSAndroid Build Coastguard Worker 541*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.rol_long_reg_v_negv_xor(long, int) instruction_simplifier (after) 542*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgValue:j\d+>> ParameterValue 543*795d594fSAndroid Build Coastguard Worker /// CHECK: <<ArgDistance:i\d+>> ParameterValue 544*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] 545*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<Neg>>] 546*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<ArgDistance>>] 547*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Xor:j\d+>> Xor [<<Shl>>,<<UShr>>] 548*795d594fSAndroid Build Coastguard Worker /// CHECK: Return [<<Xor>>] 549*795d594fSAndroid Build Coastguard Worker rol_long_reg_v_negv_xor(long value, int distance)550*795d594fSAndroid Build Coastguard Worker public static long rol_long_reg_v_negv_xor(long value, int distance) { 551*795d594fSAndroid Build Coastguard Worker return (value << distance) ^ (value >>> -distance); 552*795d594fSAndroid Build Coastguard Worker } 553*795d594fSAndroid Build Coastguard Worker 554*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.$noinline$testDontOptimizeAddIntoRotate_Int() disassembly (after) 555*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Ror $noinline$testDontOptimizeAddIntoRotate_Int()556*795d594fSAndroid Build Coastguard Worker public static void $noinline$testDontOptimizeAddIntoRotate_Int() { 557*795d594fSAndroid Build Coastguard Worker int distance = returnFalse() ? 1 : 0; 558*795d594fSAndroid Build Coastguard Worker int value = -512667375; 559*795d594fSAndroid Build Coastguard Worker int expected_result = 2 * value; 560*795d594fSAndroid Build Coastguard Worker int result = (value >>> distance) + (value << -distance); 561*795d594fSAndroid Build Coastguard Worker assertIntEquals(expected_result, result); 562*795d594fSAndroid Build Coastguard Worker } 563*795d594fSAndroid Build Coastguard Worker 564*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.$noinline$testDontOptimizeAddIntoRotate_Long() disassembly (after) 565*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Ror $noinline$testDontOptimizeAddIntoRotate_Long()566*795d594fSAndroid Build Coastguard Worker public static void $noinline$testDontOptimizeAddIntoRotate_Long() { 567*795d594fSAndroid Build Coastguard Worker int distance = returnFalse() ? 1 : 0; 568*795d594fSAndroid Build Coastguard Worker long value = -512667375L; 569*795d594fSAndroid Build Coastguard Worker long expected_result = 2L * value; 570*795d594fSAndroid Build Coastguard Worker long result = (value >>> distance) + (value << -distance); 571*795d594fSAndroid Build Coastguard Worker assertLongEquals(expected_result, result); 572*795d594fSAndroid Build Coastguard Worker } 573*795d594fSAndroid Build Coastguard Worker 574*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.$noinline$testDontOptimizeXorIntoRotate_Int() disassembly (after) 575*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Ror $noinline$testDontOptimizeXorIntoRotate_Int()576*795d594fSAndroid Build Coastguard Worker public static void $noinline$testDontOptimizeXorIntoRotate_Int() { 577*795d594fSAndroid Build Coastguard Worker int distance = returnFalse() ? 1 : 0; 578*795d594fSAndroid Build Coastguard Worker int value = -512667375; 579*795d594fSAndroid Build Coastguard Worker int expected_result = 0; 580*795d594fSAndroid Build Coastguard Worker int result = (value >>> distance) ^ (value << -distance); 581*795d594fSAndroid Build Coastguard Worker assertIntEquals(expected_result, result); 582*795d594fSAndroid Build Coastguard Worker } 583*795d594fSAndroid Build Coastguard Worker 584*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.$noinline$testDontOptimizeXorIntoRotate_Long() disassembly (after) 585*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Ror $noinline$testDontOptimizeXorIntoRotate_Long()586*795d594fSAndroid Build Coastguard Worker public static void $noinline$testDontOptimizeXorIntoRotate_Long() { 587*795d594fSAndroid Build Coastguard Worker int distance = returnFalse() ? 1 : 0; 588*795d594fSAndroid Build Coastguard Worker long value = -512667375L; 589*795d594fSAndroid Build Coastguard Worker long expected_result = 0; 590*795d594fSAndroid Build Coastguard Worker long result = (value >>> distance) ^ (value << -distance); 591*795d594fSAndroid Build Coastguard Worker assertLongEquals(expected_result, result); 592*795d594fSAndroid Build Coastguard Worker } 593*795d594fSAndroid Build Coastguard Worker returnFalse()594*795d594fSAndroid Build Coastguard Worker static boolean returnFalse() { 595*795d594fSAndroid Build Coastguard Worker return false; 596*795d594fSAndroid Build Coastguard Worker } 597*795d594fSAndroid Build Coastguard Worker main(String[] args)598*795d594fSAndroid Build Coastguard Worker public static void main(String[] args) { 599*795d594fSAndroid Build Coastguard Worker assertIntEquals(2, ror_int_constant_c_c(8)); 600*795d594fSAndroid Build Coastguard Worker assertIntEquals(2, ror_int_constant_c_c_0(8)); 601*795d594fSAndroid Build Coastguard Worker assertLongEquals(2L, ror_long_constant_c_c(8L)); 602*795d594fSAndroid Build Coastguard Worker 603*795d594fSAndroid Build Coastguard Worker assertIntEquals(2, ror_int_constant_c_negc(8)); 604*795d594fSAndroid Build Coastguard Worker assertLongEquals(2L, ror_long_constant_c_negc(8L)); 605*795d594fSAndroid Build Coastguard Worker 606*795d594fSAndroid Build Coastguard Worker assertIntEquals(2, ror_int_reg_v_csubv(8, 2)); 607*795d594fSAndroid Build Coastguard Worker assertLongEquals(2L, ror_long_reg_v_csubv(8L, 2)); 608*795d594fSAndroid Build Coastguard Worker 609*795d594fSAndroid Build Coastguard Worker assertIntEquals(2, ror_int_subv_csubv(8, 2, 0)); 610*795d594fSAndroid Build Coastguard Worker assertIntEquals(32, ror_int_subv_csubv_env(8, 2, 0)); 611*795d594fSAndroid Build Coastguard Worker assertIntEquals(32, rol_int_csubv_subv(8, 2, 0)); 612*795d594fSAndroid Build Coastguard Worker 613*795d594fSAndroid Build Coastguard Worker assertIntEquals(32, rol_int_reg_csubv_v(8, 2)); 614*795d594fSAndroid Build Coastguard Worker assertLongEquals(32L, rol_long_reg_csubv_v(8L, 2)); 615*795d594fSAndroid Build Coastguard Worker 616*795d594fSAndroid Build Coastguard Worker assertIntEquals(2, ror_int_reg_v_negv(8, 2)); 617*795d594fSAndroid Build Coastguard Worker assertIntEquals(0, ror_int_reg_v_negv_env(8, 2)); 618*795d594fSAndroid Build Coastguard Worker assertLongEquals(2L, ror_long_reg_v_negv(8L, 2)); 619*795d594fSAndroid Build Coastguard Worker 620*795d594fSAndroid Build Coastguard Worker assertIntEquals(32, rol_int_reg_negv_v(8, 2)); 621*795d594fSAndroid Build Coastguard Worker assertLongEquals(32L, rol_long_reg_negv_v(8L, 2)); 622*795d594fSAndroid Build Coastguard Worker 623*795d594fSAndroid Build Coastguard Worker assertLongEquals(32L, rol_long_reg_v_negv_add(8L, 2)); 624*795d594fSAndroid Build Coastguard Worker assertLongEquals(32L, rol_long_reg_v_negv_xor(8L, 2)); 625*795d594fSAndroid Build Coastguard Worker 626*795d594fSAndroid Build Coastguard Worker $noinline$testDontOptimizeAddIntoRotate_Int(); 627*795d594fSAndroid Build Coastguard Worker $noinline$testDontOptimizeAddIntoRotate_Long(); 628*795d594fSAndroid Build Coastguard Worker 629*795d594fSAndroid Build Coastguard Worker $noinline$testDontOptimizeXorIntoRotate_Int(); 630*795d594fSAndroid Build Coastguard Worker $noinline$testDontOptimizeXorIntoRotate_Long(); 631*795d594fSAndroid Build Coastguard Worker } 632*795d594fSAndroid Build Coastguard Worker } 633