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