1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2016 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 19*795d594fSAndroid Build Coastguard Worker // TODO: make something like this work when b/26700769 is done. 20*795d594fSAndroid Build Coastguard Worker // CHECK-START-X86_64: int Main.bits32(int) disassembly (after) 21*795d594fSAndroid Build Coastguard Worker // CHECK-DAG: popcnt 22*795d594fSAndroid Build Coastguard Worker 23*795d594fSAndroid Build Coastguard Worker 24*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$BitCountBoolean(boolean) builder (after) 25*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerBitCount 26*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Result>>] $noinline$BitCountBoolean(boolean x)27*795d594fSAndroid Build Coastguard Worker private static int $noinline$BitCountBoolean(boolean x) { 28*795d594fSAndroid Build Coastguard Worker return Integer.bitCount(x ? 1 : 0); 29*795d594fSAndroid Build Coastguard Worker } 30*795d594fSAndroid Build Coastguard Worker 31*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$BitCountByte(byte) builder (after) 32*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerBitCount 33*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Result>>] $noinline$BitCountByte(byte x)34*795d594fSAndroid Build Coastguard Worker private static int $noinline$BitCountByte(byte x) { 35*795d594fSAndroid Build Coastguard Worker return Integer.bitCount(x); 36*795d594fSAndroid Build Coastguard Worker } 37*795d594fSAndroid Build Coastguard Worker 38*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$BitCountShort(short) builder (after) 39*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerBitCount 40*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Result>>] $noinline$BitCountShort(short x)41*795d594fSAndroid Build Coastguard Worker private static int $noinline$BitCountShort(short x) { 42*795d594fSAndroid Build Coastguard Worker return Integer.bitCount(x); 43*795d594fSAndroid Build Coastguard Worker } 44*795d594fSAndroid Build Coastguard Worker 45*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$BitCountChar(char) builder (after) 46*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerBitCount 47*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Result>>] $noinline$BitCountChar(char x)48*795d594fSAndroid Build Coastguard Worker private static int $noinline$BitCountChar(char x) { 49*795d594fSAndroid Build Coastguard Worker return Integer.bitCount(x); 50*795d594fSAndroid Build Coastguard Worker } 51*795d594fSAndroid Build Coastguard Worker 52*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$BitCountInt(int) builder (after) 53*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerBitCount 54*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Result>>] $noinline$BitCountInt(int x)55*795d594fSAndroid Build Coastguard Worker private static int $noinline$BitCountInt(int x) { 56*795d594fSAndroid Build Coastguard Worker return Integer.bitCount(x); 57*795d594fSAndroid Build Coastguard Worker } 58*795d594fSAndroid Build Coastguard Worker 59*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$BitCountLong(long) builder (after) 60*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:LongBitCount 61*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Result>>] $noinline$BitCountLong(long x)62*795d594fSAndroid Build Coastguard Worker private static int $noinline$BitCountLong(long x) { 63*795d594fSAndroid Build Coastguard Worker return Long.bitCount(x); 64*795d594fSAndroid Build Coastguard Worker } 65*795d594fSAndroid Build Coastguard Worker testBitCountBoolean()66*795d594fSAndroid Build Coastguard Worker public static void testBitCountBoolean() { 67*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountBoolean(false), 0); 68*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountBoolean(true), 1); 69*795d594fSAndroid Build Coastguard Worker } 70*795d594fSAndroid Build Coastguard Worker testBitCountByte()71*795d594fSAndroid Build Coastguard Worker public static void testBitCountByte() { 72*795d594fSAndroid Build Coastguard Worker // Number of bits in an 32-bit integer representing the sign 73*795d594fSAndroid Build Coastguard Worker // extension of a byte value widened to an int. 74*795d594fSAndroid Build Coastguard Worker int signExtensionSize = Integer.SIZE - Byte.SIZE; 75*795d594fSAndroid Build Coastguard Worker // Sign bit position in a byte. 76*795d594fSAndroid Build Coastguard Worker int signBit = Byte.SIZE - 1; 77*795d594fSAndroid Build Coastguard Worker 78*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountByte((byte) 0x00), 0); 79*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountByte((byte) 0x01), 1); 80*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountByte((byte) 0x10), 1); 81*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountByte((byte) 0x11), 2); 82*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountByte((byte) 0x03), 2); 83*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountByte((byte) 0x70), 3); 84*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountByte((byte) 0xF0), 4 + signExtensionSize); 85*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountByte((byte) 0x0F), 4); 86*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountByte((byte) 0x12), 2); 87*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountByte((byte) 0x9A), 4 + signExtensionSize); 88*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountByte((byte) 0xFF), 8 + signExtensionSize); 89*795d594fSAndroid Build Coastguard Worker 90*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < Byte.SIZE; i++) { 91*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountByte((byte) (1 << i)), 92*795d594fSAndroid Build Coastguard Worker (i < signBit) ? 1 : 1 + signExtensionSize); 93*795d594fSAndroid Build Coastguard Worker } 94*795d594fSAndroid Build Coastguard Worker } 95*795d594fSAndroid Build Coastguard Worker 96*795d594fSAndroid Build Coastguard Worker public static void testBitCountShort() { 97*795d594fSAndroid Build Coastguard Worker // Number of bits in an 32-bit integer representing the sign 98*795d594fSAndroid Build Coastguard Worker // extension of a short value widened to an int. 99*795d594fSAndroid Build Coastguard Worker int signExtensionSize = Integer.SIZE - Short.SIZE; 100*795d594fSAndroid Build Coastguard Worker // Sign bit position in a short. 101*795d594fSAndroid Build Coastguard Worker int signBit = Short.SIZE - 1; 102*795d594fSAndroid Build Coastguard Worker 103*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountShort((short) 0x0000), 0); 104*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountShort((short) 0x0001), 1); 105*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountShort((short) 0x1000), 1); 106*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountShort((short) 0x1001), 2); 107*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountShort((short) 0x0003), 2); 108*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountShort((short) 0x7000), 3); 109*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountShort((short) 0x0F00), 4); 110*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountShort((short) 0x0011), 2); 111*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountShort((short) 0x1100), 2); 112*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountShort((short) 0x1111), 4); 113*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountShort((short) 0x1234), 5); 114*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountShort((short) 0x9ABC), 9 + signExtensionSize); 115*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountShort((short) 0xFFFF), 16 + signExtensionSize); 116*795d594fSAndroid Build Coastguard Worker 117*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < Short.SIZE; i++) { 118*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountShort((short) (1 << i)), 119*795d594fSAndroid Build Coastguard Worker (i < signBit) ? 1 : 1 + signExtensionSize); 120*795d594fSAndroid Build Coastguard Worker } 121*795d594fSAndroid Build Coastguard Worker } 122*795d594fSAndroid Build Coastguard Worker 123*795d594fSAndroid Build Coastguard Worker public static void testBitCountChar() { 124*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountChar((char) 0x0000), 0); 125*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountChar((char) 0x0001), 1); 126*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountChar((char) 0x1000), 1); 127*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountChar((char) 0x1001), 2); 128*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountChar((char) 0x0003), 2); 129*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountChar((char) 0x7000), 3); 130*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountChar((char) 0x0F00), 4); 131*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountChar((char) 0x0011), 2); 132*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountChar((char) 0x1100), 2); 133*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountChar((char) 0x1111), 4); 134*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountChar((char) 0x1234), 5); 135*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountChar((char) 0x9ABC), 9); 136*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountChar((char) 0xFFFF), 16); 137*795d594fSAndroid Build Coastguard Worker 138*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < Character.SIZE; i++) { 139*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountChar((char) (1 << i)), 1); 140*795d594fSAndroid Build Coastguard Worker } 141*795d594fSAndroid Build Coastguard Worker } 142*795d594fSAndroid Build Coastguard Worker 143*795d594fSAndroid Build Coastguard Worker public static void testBitCountInt() { 144*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountInt(0x00000000), 0); 145*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountInt(0x00000001), 1); 146*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountInt(0x10000000), 1); 147*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountInt(0x10000001), 2); 148*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountInt(0x00000003), 2); 149*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountInt(0x70000000), 3); 150*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountInt(0x000F0000), 4); 151*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountInt(0x00001111), 4); 152*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountInt(0x11110000), 4); 153*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountInt(0x11111111), 8); 154*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountInt(0x12345678), 13); 155*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountInt(0x9ABCDEF0), 19); 156*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountInt(0xFFFFFFFF), 32); 157*795d594fSAndroid Build Coastguard Worker 158*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < Integer.SIZE; i++) { 159*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountInt(1 << i), 1); 160*795d594fSAndroid Build Coastguard Worker } 161*795d594fSAndroid Build Coastguard Worker } 162*795d594fSAndroid Build Coastguard Worker 163*795d594fSAndroid Build Coastguard Worker public static void testBitCountLong() { 164*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountLong(0x0000000000000000L), 0); 165*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountLong(0x0000000000000001L), 1); 166*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountLong(0x1000000000000000L), 1); 167*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountLong(0x1000000000000001L), 2); 168*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountLong(0x0000000000000003L), 2); 169*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountLong(0x7000000000000000L), 3); 170*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountLong(0x000F000000000000L), 4); 171*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountLong(0x0000000011111111L), 8); 172*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountLong(0x1111111100000000L), 8); 173*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountLong(0x1111111111111111L), 16); 174*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountLong(0x123456789ABCDEF1L), 33); 175*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountLong(0xFFFFFFFFFFFFFFFFL), 64); 176*795d594fSAndroid Build Coastguard Worker 177*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < Long.SIZE; i++) { 178*795d594fSAndroid Build Coastguard Worker expectEqualsInt($noinline$BitCountLong(1L << i), 1); 179*795d594fSAndroid Build Coastguard Worker } 180*795d594fSAndroid Build Coastguard Worker } 181*795d594fSAndroid Build Coastguard Worker 182*795d594fSAndroid Build Coastguard Worker public static void main(String args[]) { 183*795d594fSAndroid Build Coastguard Worker testBitCountBoolean(); 184*795d594fSAndroid Build Coastguard Worker testBitCountByte(); 185*795d594fSAndroid Build Coastguard Worker testBitCountShort(); 186*795d594fSAndroid Build Coastguard Worker testBitCountChar(); 187*795d594fSAndroid Build Coastguard Worker testBitCountInt(); 188*795d594fSAndroid Build Coastguard Worker testBitCountLong(); 189*795d594fSAndroid Build Coastguard Worker 190*795d594fSAndroid Build Coastguard Worker System.out.println("passed"); 191*795d594fSAndroid Build Coastguard Worker } 192*795d594fSAndroid Build Coastguard Worker 193*795d594fSAndroid Build Coastguard Worker private static void expectEqualsInt(int expected, int result) { 194*795d594fSAndroid Build Coastguard Worker if (expected != result) { 195*795d594fSAndroid Build Coastguard Worker throw new Error("Expected: " + expected + ", found: " + result); 196*795d594fSAndroid Build Coastguard Worker } 197*795d594fSAndroid Build Coastguard Worker } 198*795d594fSAndroid Build Coastguard Worker } 199