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