OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 // Dart test for testing bitwise operations. | |
5 // VMOptions=--optimization-counter-threshold=10 --no-use-osr --no-background-co
mpilation --enable-inlining-annotations | |
6 | |
7 import "package:expect/expect.dart"; | |
8 | |
9 const neverInline = "NeverInline"; | |
10 | |
11 void main() { | |
12 for (int i = 0; i < 4; i++) { | |
13 test(); | |
14 } | |
15 } | |
16 | |
17 void test() { | |
18 Expect.equals(3, (3 & 7)); | |
19 Expect.equals(7, (3 | 7)); | |
20 Expect.equals(4, (3 ^ 7)); | |
21 Expect.equals(25, (100 >> 2)); | |
22 Expect.equals(400, (100 << 2)); | |
23 Expect.equals(-25, (-100 >> 2)); | |
24 Expect.equals(-101, ~100); | |
25 Expect.equals(0x10000000000000000, 1 << 64); | |
26 Expect.equals(-0x10000000000000000, -1 << 64); | |
27 Expect.equals(0x40000000, 0x04000000 << 4); | |
28 Expect.equals(0x4000000000000000, 0x0400000000000000 << 4); | |
29 Expect.equals(0, ~ -1); | |
30 Expect.equals(-1, ~0); | |
31 | |
32 Expect.equals(0, 1 >> 160); | |
33 Expect.equals(-1, -1 >> 160); | |
34 | |
35 Expect.equals( | |
36 0x100000000000000001, 0x100000000000000001 & 0x100000100F00000001); | |
37 Expect.equals(0x1, 0x1 & 0x100000100F00000001); | |
38 Expect.equals(0x1, 0x100000100F00000001 & 0x1); | |
39 | |
40 Expect.equals( | |
41 0x100000100F00000001, 0x100000000000000001 | 0x100000100F00000001); | |
42 Expect.equals(0x100000100F00000011, 0x11 | 0x100000100F00000001); | |
43 Expect.equals(0x100000100F00000011, 0x100000100F00000001 | 0x11); | |
44 | |
45 Expect.equals( | |
46 0x0F000F00000000000000, 0x0F00F00000000000001 ^ 0xFF00000000000000001); | |
47 Expect.equals(0x31, 0xF00F00000000000001 ^ 0xF00F00000000000030); | |
48 Expect.equals(0xF00F00000000000031, 0xF00F00000000000001 ^ 0x30); | |
49 Expect.equals(0xF00F00000000000031, 0x30 ^ 0xF00F00000000000001); | |
50 | |
51 Expect.equals(0xF0000000000000000F, 0xF0000000000000000F7 >> 4); | |
52 Expect.equals(15, 0xF00000000 >> 32); | |
53 Expect.equals(1030792151040, 16492674416655 >> 4); | |
54 | |
55 Expect.equals(0xF0000000000000000F0, 0xF0000000000000000F << 4); | |
56 Expect.equals(0xF00000000, 15 << 32); | |
57 | |
58 testNegativeValueShifts(); | |
59 testPositiveValueShifts(); | |
60 testNoMaskingOfShiftCount(); | |
61 testNegativeCountShifts(); | |
62 for (int i = 0; i < 20; i++) { | |
63 testCornerCasesRightShifts(); | |
64 testRightShift64Bit(); | |
65 testLeftShift64Bit(); | |
66 testLeftShift64BitWithOverflow1(); | |
67 testLeftShift64BitWithOverflow2(); | |
68 testLeftShift64BitWithOverflow3(); | |
69 } | |
70 | |
71 // Test precedence. | |
72 testPrecedence(4, 5, 3, 1); | |
73 testPrecedence(3, 4, 5, 9); | |
74 testPrecedence(0x5c71, 0x6b92, 0x7654, 0x7d28); | |
75 | |
76 // Test more special cases. | |
77 testRightShift65(); | |
78 } | |
79 | |
80 void testCornerCasesRightShifts() { | |
81 var v32 = 0xFF000000; | |
82 var v64 = 0xFF00000000000000; | |
83 Expect.equals(0x3, v32 >> 0x1E); | |
84 Expect.equals(0x1, v32 >> 0x1F); | |
85 Expect.equals(0x0, v32 >> 0x20); | |
86 Expect.equals(0x3, v64 >> 0x3E); | |
87 Expect.equals(0x1, v64 >> 0x3F); | |
88 Expect.equals(0x0, v64 >> 0x40); | |
89 } | |
90 | |
91 void testRightShift64Bit() { | |
92 var t = 0x1ffffffff; | |
93 Expect.equals(0xffffffff, t >> 1); | |
94 } | |
95 | |
96 void testLeftShift64Bit() { | |
97 var t = 0xffffffff; | |
98 Expect.equals(0xffffffff, t << 0); | |
99 Expect.equals(0x1fffffffe, t << 1); | |
100 Expect.equals(0x7fffffff80000000, t << 31); | |
101 Expect.equals(0x10000000000000000, 2*(t+1) << 31); //# 01: static type warning | |
102 Expect.equals(0x20000000000000000, 4*(t+1) << 31); //# 02: static type warning | |
103 Expect.equals(0x8000000000000000, (t + 1) << 31); | |
104 } | |
105 | |
106 void testLeftShift64BitWithOverflow1() { | |
107 var t = 0xffffffff; | |
108 Expect.equals(0x10000000000000000, 2*(t+1) << 31); //# 03: static type warning | |
109 } | |
110 | |
111 void testLeftShift64BitWithOverflow2() { | |
112 var t = 0xffffffff; | |
113 Expect.equals(0x20000000000000000, 4*(t+1) << 31); //# 04: static type warning | |
114 } | |
115 | |
116 void testLeftShift64BitWithOverflow3() { | |
117 var t = 0xffffffff; | |
118 Expect.equals(0x8000000000000000, (t + 1) << 31); | |
119 } | |
120 | |
121 void testNegativeCountShifts() { | |
122 bool throwOnLeft(a, b) { | |
123 try { | |
124 var x = a << b; | |
125 return false; | |
126 } catch (e) { | |
127 return true; | |
128 } | |
129 } | |
130 | |
131 bool throwOnRight(a, b) { | |
132 try { | |
133 var x = a >> b; | |
134 return false; | |
135 } catch (e) { | |
136 return true; | |
137 } | |
138 } | |
139 | |
140 Expect.isTrue(throwOnLeft(12, -3)); | |
141 Expect.isTrue(throwOnRight(12, -3)); | |
142 for (int i = 0; i < 20; i++) { | |
143 Expect.isFalse(throwOnLeft(12, 3)); | |
144 Expect.isFalse(throwOnRight(12, 3)); | |
145 } | |
146 } | |
147 | |
148 void testNegativeValueShifts() { | |
149 for (int value = 0; value > -100; value--) { | |
150 for (int i = 0; i < 300; i++) { | |
151 int b = (value << i) >> i; | |
152 Expect.equals(value, b); | |
153 } | |
154 } | |
155 } | |
156 | |
157 void testPositiveValueShifts() { | |
158 for (int value = 0; value < 100; value++) { | |
159 for (int i = 0; i < 300; i++) { | |
160 int b = (value << i) >> i; | |
161 Expect.equals(value, b); | |
162 } | |
163 } | |
164 } | |
165 | |
166 void testNoMaskingOfShiftCount() { | |
167 // Shifts which would behave differently if shift count was masked into a | |
168 // range. | |
169 Expect.equals(0, 0 >> 256); | |
170 Expect.equals(0, 1 >> 256); | |
171 Expect.equals(0, 2 >> 256); | |
172 Expect.equals(0, shiftRight(0, 256)); | |
173 Expect.equals(0, shiftRight(1, 256)); | |
174 Expect.equals(0, shiftRight(2, 256)); | |
175 | |
176 for (int shift = 1; shift <= 256; shift++) { | |
177 Expect.equals(0, shiftRight(1, shift)); | |
178 Expect.equals(-1, shiftRight(-1, shift)); | |
179 Expect.equals(true, shiftLeft(1, shift) > shiftLeft(1, shift - 1)); | |
180 } | |
181 } | |
182 | |
183 int shiftLeft(int a, int b) { | |
184 return a << b; | |
185 } | |
186 | |
187 int shiftRight(int a, int b) { | |
188 return a >> b; | |
189 } | |
190 | |
191 void testPrecedence(int a, int b, int c, int d) { | |
192 // & binds stronger than ^, which binds stronger than |. | |
193 int result = a & b ^ c | d & b ^ c; | |
194 Expect.equals(((a & b) ^ c) | ((d & b) ^ c), result); // &^| | |
195 Expect.notEquals((a & (b ^ c)) | (d & (b ^ c)), result); // ^&| | |
196 Expect.notEquals((a & b) ^ (c | (d & b)) ^ c, result); // &|^ | |
197 Expect.notEquals((a & b) ^ ((c | d) & b) ^ c, result); // |&^ | |
198 Expect.notEquals(a & (b ^ (c | d)) & (b ^ c), result); // |^& | |
199 Expect.notEquals(a & ((b ^ c) | d) & (b ^ c), result); // ^|& | |
200 // Binds stronger than relational operators. | |
201 Expect.equals((a & b) < (c & d), a & b < c & d); | |
202 // Binds weaker than shift operators. | |
203 Expect.equals((a & (b << c)) ^ d, a & b << c ^ d); | |
204 Expect.notEquals((a & b) << (c ^ d), a & b << c ^ d); | |
205 } | |
206 | |
207 @neverInline | |
208 rightShift65Noinline(a) => a >> 65; | |
209 | |
210 testRightShift65() { | |
211 var a = 0x5f22334455667788; | |
212 var b = -0x5f22334455667788; | |
213 | |
214 for (var i = 0; i < 20; ++i) { | |
215 Expect.equals(0, rightShift65Noinline(a)); | |
216 Expect.equals(-1, rightShift65Noinline(b)); | |
217 } | |
218 } | |
OLD | NEW |