blob: afc6cc0765553a253b1de4868023d0de54975cff [file] [log] [blame]
Ben Murdochb0fe1622011-05-05 13:52:32 +01001// Copyright 2010 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28// Flags: --always-inline-smi-code
29
30const SMI_MAX = (1 << 30) - 1;
31const SMI_MIN = -(1 << 30);
32const ONE = 1;
33const ONE_HUNDRED = 100;
34
35const OBJ_42 = new (function() {
36 this.valueOf = function() { return 42; };
37})();
38
39assertEquals(42, OBJ_42.valueOf());
40
41
42function Add1(x) {
43 return x + 1;
44}
45
46function Add100(x) {
47 return x + 100;
48}
49
50function Add1Reversed(x) {
51 return 1 + x;
52}
53
54function Add100Reversed(x) {
55 return 100 + x;
56}
57
58
59assertEquals(1, Add1(0)); // fast case
60assertEquals(1, Add1Reversed(0)); // fast case
61assertEquals(SMI_MAX + ONE, Add1(SMI_MAX), "smimax + 1");
62assertEquals(SMI_MAX + ONE, Add1Reversed(SMI_MAX), "1 + smimax");
63assertEquals(42 + ONE, Add1(OBJ_42)); // non-smi
64assertEquals(42 + ONE, Add1Reversed(OBJ_42)); // non-smi
65
66assertEquals(100, Add100(0)); // fast case
67assertEquals(100, Add100Reversed(0)); // fast case
68assertEquals(SMI_MAX + ONE_HUNDRED, Add100(SMI_MAX), "smimax + 100");
69assertEquals(SMI_MAX + ONE_HUNDRED, Add100Reversed(SMI_MAX), " 100 + smimax");
70assertEquals(42 + ONE_HUNDRED, Add100(OBJ_42)); // non-smi
71assertEquals(42 + ONE_HUNDRED, Add100Reversed(OBJ_42)); // non-smi
72
73
74
75function Sub1(x) {
76 return x - 1;
77}
78
79function Sub100(x) {
80 return x - 100;
81}
82
83function Sub1Reversed(x) {
84 return 1 - x;
85}
86
87function Sub100Reversed(x) {
88 return 100 - x;
89}
90
91
92assertEquals(0, Sub1(1)); // fast case
93assertEquals(-1, Sub1Reversed(2)); // fast case
94assertEquals(SMI_MIN - ONE, Sub1(SMI_MIN)); // overflow
95assertEquals(ONE - SMI_MIN, Sub1Reversed(SMI_MIN)); // overflow
96assertEquals(42 - ONE, Sub1(OBJ_42)); // non-smi
97assertEquals(ONE - 42, Sub1Reversed(OBJ_42)); // non-smi
98
99assertEquals(0, Sub100(100)); // fast case
100assertEquals(1, Sub100Reversed(99)); // fast case
101assertEquals(SMI_MIN - ONE_HUNDRED, Sub100(SMI_MIN)); // overflow
102assertEquals(ONE_HUNDRED - SMI_MIN, Sub100Reversed(SMI_MIN)); // overflow
103assertEquals(42 - ONE_HUNDRED, Sub100(OBJ_42)); // non-smi
104assertEquals(ONE_HUNDRED - 42, Sub100Reversed(OBJ_42)); // non-smi
105
106
107function Shr1(x) {
108 return x >>> 1;
109}
110
111function Shr100(x) {
112 return x >>> 100;
113}
114
115function Shr1Reversed(x) {
116 return 1 >>> x;
117}
118
119function Shr100Reversed(x) {
120 return 100 >>> x;
121}
122
123function Sar1(x) {
124 return x >> 1;
125}
126
127function Sar100(x) {
128 return x >> 100;
129}
130
131function Sar1Reversed(x) {
132 return 1 >> x;
133}
134
135function Sar100Reversed(x) {
136 return 100 >> x;
137}
138
139
140assertEquals(0, Shr1(1));
141assertEquals(0, Sar1(1));
142assertEquals(0, Shr1Reversed(2));
143assertEquals(0, Sar1Reversed(2));
144assertEquals(1610612736, Shr1(SMI_MIN));
145assertEquals(-536870912, Sar1(SMI_MIN));
146assertEquals(1, Shr1Reversed(SMI_MIN));
147assertEquals(1, Sar1Reversed(SMI_MIN));
148assertEquals(21, Shr1(OBJ_42));
149assertEquals(21, Sar1(OBJ_42));
150assertEquals(0, Shr1Reversed(OBJ_42));
151assertEquals(0, Sar1Reversed(OBJ_42));
152
153assertEquals(6, Shr100(100), "100 >>> 100");
154assertEquals(6, Sar100(100), "100 >> 100");
155assertEquals(12, Shr100Reversed(99));
156assertEquals(12, Sar100Reversed(99));
157assertEquals(201326592, Shr100(SMI_MIN));
158assertEquals(-67108864, Sar100(SMI_MIN));
159assertEquals(100, Shr100Reversed(SMI_MIN));
160assertEquals(100, Sar100Reversed(SMI_MIN));
161assertEquals(2, Shr100(OBJ_42));
162assertEquals(2, Sar100(OBJ_42));
163assertEquals(0, Shr100Reversed(OBJ_42));
164assertEquals(0, Sar100Reversed(OBJ_42));
165
166
167function Xor1(x) {
168 return x ^ 1;
169}
170
171function Xor100(x) {
172 return x ^ 100;
173}
174
175function Xor1Reversed(x) {
176 return 1 ^ x;
177}
178
179function Xor100Reversed(x) {
180 return 100 ^ x;
181}
182
183
184assertEquals(0, Xor1(1));
185assertEquals(3, Xor1Reversed(2));
186assertEquals(SMI_MIN + 1, Xor1(SMI_MIN));
187assertEquals(SMI_MIN + 1, Xor1Reversed(SMI_MIN));
188assertEquals(43, Xor1(OBJ_42));
189assertEquals(43, Xor1Reversed(OBJ_42));
190
191assertEquals(0, Xor100(100));
192assertEquals(7, Xor100Reversed(99));
193assertEquals(-1073741724, Xor100(SMI_MIN));
194assertEquals(-1073741724, Xor100Reversed(SMI_MIN));
195assertEquals(78, Xor100(OBJ_42));
196assertEquals(78, Xor100Reversed(OBJ_42));
197
198var x = 0x23; var y = 0x35;
199assertEquals(0x16, x ^ y);
200
201
202// Bitwise not.
203var v = 0;
204assertEquals(-1, ~v);
205v = SMI_MIN;
206assertEquals(0x3fffffff, ~v, "~smimin");
207v = SMI_MAX;
208assertEquals(-0x40000000, ~v, "~smimax");
209
210// Overflowing ++ and --.
211v = SMI_MAX;
212v++;
213assertEquals(0x40000000, v, "smimax++");
214v = SMI_MIN;
215v--;
216assertEquals(-0x40000001, v, "smimin--");
217
218// Not actually Smi operations.
219// Check that relations on unary ops work.
220var v = -1.2;
221assertTrue(v == v);
222assertTrue(v === v);
223assertTrue(v <= v);
224assertTrue(v >= v);
225assertFalse(v < v);
226assertFalse(v > v);
227assertFalse(v != v);
228assertFalse(v !== v);
229
230// Right hand side of unary minus is overwritable.
231v = 1.5
232assertEquals(-2.25, -(v * v));
233
234// Smi input to bitop gives non-smi result where the rhs is a float that
235// can be overwritten.
236var x1 = 0x10000000;
237var x2 = 0x40000002;
238var x3 = 0x40000000;
239assertEquals(0x40000000, x1 << (x2 - x3), "0x10000000<<1(1)");
240
241// Smi input to bitop gives non-smi result where the rhs could be overwritten
242// if it were a float, but it isn't.
243x1 = 0x10000000
244x2 = 4
245x3 = 2
246assertEquals(0x40000000, x1 << (x2 - x3), "0x10000000<<2(2)");
247
248
249// Test shift operators on non-smi inputs, giving smi and non-smi results.
250function testShiftNonSmis() {
251 var pos_non_smi = 2000000000;
252 var neg_non_smi = -pos_non_smi;
253 var pos_smi = 1000000000;
254 var neg_smi = -pos_smi;
255
256 // Begin block A
257 assertEquals(pos_non_smi, (pos_non_smi) >> 0);
258 assertEquals(pos_non_smi, (pos_non_smi) >>> 0);
259 assertEquals(pos_non_smi, (pos_non_smi) << 0);
260 assertEquals(neg_non_smi, (neg_non_smi) >> 0);
261 assertEquals(neg_non_smi + 0x100000000, (neg_non_smi) >>> 0);
262 assertEquals(neg_non_smi, (neg_non_smi) << 0);
263 assertEquals(pos_smi, (pos_smi) >> 0, "possmi >> 0");
264 assertEquals(pos_smi, (pos_smi) >>> 0, "possmi >>>0");
265 assertEquals(pos_smi, (pos_smi) << 0, "possmi << 0");
266 assertEquals(neg_smi, (neg_smi) >> 0, "negsmi >> 0");
267 assertEquals(neg_smi + 0x100000000, (neg_smi) >>> 0, "negsmi >>> 0");
268 assertEquals(neg_smi, (neg_smi) << 0), "negsmi << 0";
269
270 assertEquals(pos_non_smi / 2, (pos_non_smi) >> 1);
271 assertEquals(pos_non_smi / 2, (pos_non_smi) >>> 1);
272 assertEquals(-0x1194D800, (pos_non_smi) << 1);
273 assertEquals(pos_non_smi / 8, (pos_non_smi) >> 3);
274 assertEquals(pos_non_smi / 8, (pos_non_smi) >>> 3);
275 assertEquals(-0x46536000, (pos_non_smi) << 3);
276 assertEquals(0x73594000, (pos_non_smi) << 4);
277 assertEquals(pos_non_smi, (pos_non_smi + 0.5) >> 0);
278 assertEquals(pos_non_smi, (pos_non_smi + 0.5) >>> 0);
279 assertEquals(pos_non_smi, (pos_non_smi + 0.5) << 0);
280 assertEquals(pos_non_smi / 2, (pos_non_smi + 0.5) >> 1);
281 assertEquals(pos_non_smi / 2, (pos_non_smi + 0.5) >>> 1);
282 assertEquals(-0x1194D800, (pos_non_smi + 0.5) << 1);
283 assertEquals(pos_non_smi / 8, (pos_non_smi + 0.5) >> 3);
284 assertEquals(pos_non_smi / 8, (pos_non_smi + 0.5) >>> 3);
285 assertEquals(-0x46536000, (pos_non_smi + 0.5) << 3);
286 assertEquals(0x73594000, (pos_non_smi + 0.5) << 4);
287
288 assertEquals(neg_non_smi / 2, (neg_non_smi) >> 1, "negnonsmi >> 1");
289
290 assertEquals(neg_non_smi / 2 + 0x100000000 / 2, (neg_non_smi) >>> 1,
291 "negnonsmi >>> 1");
292 assertEquals(0x1194D800, (neg_non_smi) << 1);
293 assertEquals(neg_non_smi / 8, (neg_non_smi) >> 3);
294 assertEquals(neg_non_smi / 8 + 0x100000000 / 8, (neg_non_smi) >>> 3);
295 assertEquals(0x46536000, (neg_non_smi) << 3);
296 assertEquals(-0x73594000, (neg_non_smi) << 4);
297 assertEquals(neg_non_smi, (neg_non_smi - 0.5) >> 0);
298 assertEquals(neg_non_smi + 0x100000000, (neg_non_smi - 0.5) >>> 0,
299 "negnonsmi.5 >>> 0");
300 assertEquals(neg_non_smi, (neg_non_smi - 0.5) << 0);
301 assertEquals(neg_non_smi / 2, (neg_non_smi - 0.5) >> 1);
302 assertEquals(neg_non_smi / 2 + 0x100000000 / 2, (neg_non_smi - 0.5) >>> 1,
303 "negnonsmi.5 >>> 1");
304 assertEquals(0x1194D800, (neg_non_smi - 0.5) << 1);
305 assertEquals(neg_non_smi / 8, (neg_non_smi - 0.5) >> 3);
306 assertEquals(neg_non_smi / 8 + 0x100000000 / 8, (neg_non_smi - 0.5) >>> 3);
307 assertEquals(0x46536000, (neg_non_smi - 0.5) << 3);
308 assertEquals(-0x73594000, (neg_non_smi - 0.5) << 4);
309
310 assertEquals(pos_smi / 2, (pos_smi) >> 1);
311 assertEquals(pos_smi / 2, (pos_smi) >>> 1);
312 assertEquals(pos_non_smi, (pos_smi) << 1);
313 assertEquals(pos_smi / 8, (pos_smi) >> 3);
314 assertEquals(pos_smi / 8, (pos_smi) >>> 3);
315 assertEquals(-0x2329b000, (pos_smi) << 3);
316 assertEquals(0x73594000, (pos_smi) << 5);
317 assertEquals(pos_smi, (pos_smi + 0.5) >> 0, "possmi.5 >> 0");
318 assertEquals(pos_smi, (pos_smi + 0.5) >>> 0, "possmi.5 >>> 0");
319 assertEquals(pos_smi, (pos_smi + 0.5) << 0, "possmi.5 << 0");
320 assertEquals(pos_smi / 2, (pos_smi + 0.5) >> 1);
321 assertEquals(pos_smi / 2, (pos_smi + 0.5) >>> 1);
322 assertEquals(pos_non_smi, (pos_smi + 0.5) << 1);
323 assertEquals(pos_smi / 8, (pos_smi + 0.5) >> 3);
324 assertEquals(pos_smi / 8, (pos_smi + 0.5) >>> 3);
325 assertEquals(-0x2329b000, (pos_smi + 0.5) << 3);
326 assertEquals(0x73594000, (pos_smi + 0.5) << 5);
327
328 assertEquals(neg_smi / 2, (neg_smi) >> 1);
329 assertEquals(neg_smi / 2 + 0x100000000 / 2, (neg_smi) >>> 1);
330 assertEquals(neg_non_smi, (neg_smi) << 1);
331 assertEquals(neg_smi / 8, (neg_smi) >> 3);
332 assertEquals(neg_smi / 8 + 0x100000000 / 8, (neg_smi) >>> 3);
333 assertEquals(0x46536000, (neg_smi) << 4);
334 assertEquals(-0x73594000, (neg_smi) << 5);
335 assertEquals(neg_smi, (neg_smi - 0.5) >> 0, "negsmi.5 >> 0");
336 assertEquals(neg_smi + 0x100000000, (neg_smi - 0.5) >>> 0, "negsmi.5 >>> 0");
337 assertEquals(neg_smi, (neg_smi - 0.5) << 0, "negsmi.5 << 0");
338 assertEquals(neg_smi / 2, (neg_smi - 0.5) >> 1);
339 assertEquals(neg_smi / 2 + 0x100000000 / 2, (neg_smi - 0.5) >>> 1);
340 assertEquals(neg_non_smi, (neg_smi - 0.5) << 1);
341 assertEquals(neg_smi / 8, (neg_smi - 0.5) >> 3);
342 assertEquals(neg_smi / 8 + 0x100000000 / 8, (neg_smi - 0.5) >>> 3);
343 assertEquals(0x46536000, (neg_smi - 0.5) << 4);
344 assertEquals(-0x73594000, (neg_smi - 0.5) << 5);
345 // End block A
346
347 // Repeat block A with 2^32 added to positive numbers and
348 // 2^32 subtracted from negative numbers.
349 // Begin block A repeat 1
350 var two_32 = 0x100000000;
351 var neg_32 = -two_32;
352 assertEquals(pos_non_smi, (two_32 + pos_non_smi) >> 0);
353 assertEquals(pos_non_smi, (two_32 + pos_non_smi) >>> 0);
354 assertEquals(pos_non_smi, (two_32 + pos_non_smi) << 0);
355 assertEquals(neg_non_smi, (neg_32 + neg_non_smi) >> 0);
356 assertEquals(neg_non_smi + 0x100000000, (neg_32 + neg_non_smi) >>> 0);
357 assertEquals(neg_non_smi, (neg_32 + neg_non_smi) << 0);
358 assertEquals(pos_smi, (two_32 + pos_smi) >> 0, "2^32+possmi >> 0");
359 assertEquals(pos_smi, (two_32 + pos_smi) >>> 0, "2^32+possmi >>> 0");
360 assertEquals(pos_smi, (two_32 + pos_smi) << 0, "2^32+possmi << 0");
361 assertEquals(neg_smi, (neg_32 + neg_smi) >> 0, "2^32+negsmi >> 0");
362 assertEquals(neg_smi + 0x100000000, (neg_32 + neg_smi) >>> 0);
363 assertEquals(neg_smi, (neg_32 + neg_smi) << 0, "2^32+negsmi << 0");
364
365 assertEquals(pos_non_smi / 2, (two_32 + pos_non_smi) >> 1);
366 assertEquals(pos_non_smi / 2, (two_32 + pos_non_smi) >>> 1);
367 assertEquals(-0x1194D800, (two_32 + pos_non_smi) << 1);
368 assertEquals(pos_non_smi / 8, (two_32 + pos_non_smi) >> 3);
369 assertEquals(pos_non_smi / 8, (two_32 + pos_non_smi) >>> 3);
370 assertEquals(-0x46536000, (two_32 + pos_non_smi) << 3);
371 assertEquals(0x73594000, (two_32 + pos_non_smi) << 4);
372 assertEquals(pos_non_smi, (two_32 + pos_non_smi + 0.5) >> 0);
373 assertEquals(pos_non_smi, (two_32 + pos_non_smi + 0.5) >>> 0);
374 assertEquals(pos_non_smi, (two_32 + pos_non_smi + 0.5) << 0);
375 assertEquals(pos_non_smi / 2, (two_32 + pos_non_smi + 0.5) >> 1);
376 assertEquals(pos_non_smi / 2, (two_32 + pos_non_smi + 0.5) >>> 1);
377 assertEquals(-0x1194D800, (two_32 + pos_non_smi + 0.5) << 1);
378 assertEquals(pos_non_smi / 8, (two_32 + pos_non_smi + 0.5) >> 3);
379 assertEquals(pos_non_smi / 8, (two_32 + pos_non_smi + 0.5) >>> 3);
380 assertEquals(-0x46536000, (two_32 + pos_non_smi + 0.5) << 3);
381 assertEquals(0x73594000, (two_32 + pos_non_smi + 0.5) << 4);
382
383 assertEquals(neg_non_smi / 2, (neg_32 + neg_non_smi) >> 1);
384 assertEquals(neg_non_smi / 2 + 0x100000000 / 2, (neg_32 + neg_non_smi) >>> 1);
385 assertEquals(0x1194D800, (neg_32 + neg_non_smi) << 1);
386 assertEquals(neg_non_smi / 8, (neg_32 + neg_non_smi) >> 3);
387 assertEquals(neg_non_smi / 8 + 0x100000000 / 8, (neg_32 + neg_non_smi) >>> 3);
388 assertEquals(0x46536000, (neg_32 + neg_non_smi) << 3);
389 assertEquals(-0x73594000, (neg_32 + neg_non_smi) << 4);
390 assertEquals(neg_non_smi, (neg_32 + neg_non_smi - 0.5) >> 0);
391 assertEquals(neg_non_smi + 0x100000000, (neg_32 + neg_non_smi - 0.5) >>> 0);
392 assertEquals(neg_non_smi, (neg_32 + neg_non_smi - 0.5) << 0);
393 assertEquals(neg_non_smi / 2, (neg_32 + neg_non_smi - 0.5) >> 1);
394 assertEquals(neg_non_smi / 2 + 0x100000000 / 2, (neg_32 + neg_non_smi - 0.5)
395 >>> 1);
396 assertEquals(0x1194D800, (neg_32 + neg_non_smi - 0.5) << 1);
397 assertEquals(neg_non_smi / 8, (neg_32 + neg_non_smi - 0.5) >> 3);
398 assertEquals(neg_non_smi / 8 + 0x100000000 / 8, (neg_32 + neg_non_smi - 0.5)
399 >>> 3);
400 assertEquals(0x46536000, (neg_32 + neg_non_smi - 0.5) << 3);
401 assertEquals(-0x73594000, (neg_32 + neg_non_smi - 0.5) << 4);
402
403 assertEquals(pos_smi / 2, (two_32 + pos_smi) >> 1);
404 assertEquals(pos_smi / 2, (two_32 + pos_smi) >>> 1);
405 assertEquals(pos_non_smi, (two_32 + pos_smi) << 1);
406 assertEquals(pos_smi / 8, (two_32 + pos_smi) >> 3);
407 assertEquals(pos_smi / 8, (two_32 + pos_smi) >>> 3);
408 assertEquals(-0x2329b000, (two_32 + pos_smi) << 3);
409 assertEquals(0x73594000, (two_32 + pos_smi) << 5);
410 assertEquals(pos_smi, (two_32 + pos_smi + 0.5) >> 0);
411 assertEquals(pos_smi, (two_32 + pos_smi + 0.5) >>> 0);
412 assertEquals(pos_smi, (two_32 + pos_smi + 0.5) << 0);
413 assertEquals(pos_smi / 2, (two_32 + pos_smi + 0.5) >> 1);
414 assertEquals(pos_smi / 2, (two_32 + pos_smi + 0.5) >>> 1);
415 assertEquals(pos_non_smi, (two_32 + pos_smi + 0.5) << 1);
416 assertEquals(pos_smi / 8, (two_32 + pos_smi + 0.5) >> 3);
417 assertEquals(pos_smi / 8, (two_32 + pos_smi + 0.5) >>> 3);
418 assertEquals(-0x2329b000, (two_32 + pos_smi + 0.5) << 3);
419 assertEquals(0x73594000, (two_32 + pos_smi + 0.5) << 5);
420
421 assertEquals(neg_smi / 2, (neg_32 + neg_smi) >> 1);
422 assertEquals(neg_smi / 2 + 0x100000000 / 2, (neg_32 + neg_smi) >>> 1);
423 assertEquals(neg_non_smi, (neg_32 + neg_smi) << 1);
424 assertEquals(neg_smi / 8, (neg_32 + neg_smi) >> 3);
425 assertEquals((neg_smi + 0x100000000) / 8, (neg_32 + neg_smi) >>> 3);
426 assertEquals(0x46536000, (neg_32 + neg_smi) << 4);
427 assertEquals(-0x73594000, (neg_32 + neg_smi) << 5);
428 assertEquals(neg_smi, (neg_32 + neg_smi - 0.5) >> 0, "-2^32+negsmi.5 >> 0");
429 assertEquals(neg_smi + 0x100000000, (neg_32 + neg_smi - 0.5) >>> 0);
430 assertEquals(neg_smi, (neg_32 + neg_smi - 0.5) << 0, "-2^32+negsmi.5 << 0");
431 assertEquals(neg_smi / 2, (neg_32 + neg_smi - 0.5) >> 1);
432 assertEquals(neg_smi / 2 + 0x100000000 / 2, (neg_32 + neg_smi - 0.5) >>> 1);
433 assertEquals(neg_non_smi, (neg_32 + neg_smi - 0.5) << 1);
434 assertEquals(neg_smi / 8, (neg_32 + neg_smi - 0.5) >> 3);
435 assertEquals(neg_smi / 8 + 0x100000000 / 8, (neg_32 + neg_smi - 0.5) >>> 3);
436 assertEquals(0x46536000, (neg_32 + neg_smi - 0.5) << 4);
437 assertEquals(-0x73594000, (neg_32 + neg_smi - 0.5) << 5);
438 // End block A repeat 1
439 // Repeat block A with shift amounts in variables intialized with
440 // a constant.
441 var zero = 0;
442 var one = 1;
443 var three = 3;
444 var four = 4;
445 var five = 5;
446 // Begin block A repeat 2
447 assertEquals(pos_non_smi, (pos_non_smi) >> zero);
448 assertEquals(pos_non_smi, (pos_non_smi) >>> zero);
449 assertEquals(pos_non_smi, (pos_non_smi) << zero);
450 assertEquals(neg_non_smi, (neg_non_smi) >> zero);
451 assertEquals(neg_non_smi + 0x100000000, (neg_non_smi) >>> zero);
452 assertEquals(neg_non_smi, (neg_non_smi) << zero);
453 assertEquals(pos_smi, (pos_smi) >> zero);
454 assertEquals(pos_smi, (pos_smi) >>> zero);
455 assertEquals(pos_smi, (pos_smi) << zero);
456 assertEquals(neg_smi, (neg_smi) >> zero, "negsmi >> zero");
457 assertEquals(neg_smi + 0x100000000, (neg_smi) >>> zero);
458 assertEquals(neg_smi, (neg_smi) << zero, "negsmi << zero");
459
460 assertEquals(pos_non_smi / 2, (pos_non_smi) >> one);
461 assertEquals(pos_non_smi / 2, (pos_non_smi) >>> one);
462 assertEquals(-0x1194D800, (pos_non_smi) << one);
463 assertEquals(pos_non_smi / 8, (pos_non_smi) >> three);
464 assertEquals(pos_non_smi / 8, (pos_non_smi) >>> three);
465 assertEquals(-0x46536000, (pos_non_smi) << three);
466 assertEquals(0x73594000, (pos_non_smi) << four);
467 assertEquals(pos_non_smi, (pos_non_smi + 0.5) >> zero);
468 assertEquals(pos_non_smi, (pos_non_smi + 0.5) >>> zero);
469 assertEquals(pos_non_smi, (pos_non_smi + 0.5) << zero);
470 assertEquals(pos_non_smi / 2, (pos_non_smi + 0.5) >> one);
471 assertEquals(pos_non_smi / 2, (pos_non_smi + 0.5) >>> one);
472 assertEquals(-0x1194D800, (pos_non_smi + 0.5) << one);
473 assertEquals(pos_non_smi / 8, (pos_non_smi + 0.5) >> three);
474 assertEquals(pos_non_smi / 8, (pos_non_smi + 0.5) >>> three);
475 assertEquals(-0x46536000, (pos_non_smi + 0.5) << three);
476 assertEquals(0x73594000, (pos_non_smi + 0.5) << four);
477
478 assertEquals(neg_non_smi / 2, (neg_non_smi) >> one);
479 assertEquals(neg_non_smi / 2 + 0x100000000 / 2, (neg_non_smi) >>> one);
480 assertEquals(0x1194D800, (neg_non_smi) << one);
481 assertEquals(neg_non_smi / 8, (neg_non_smi) >> three);
482 assertEquals(neg_non_smi / 8 + 0x100000000 / 8, (neg_non_smi) >>> three);
483 assertEquals(0x46536000, (neg_non_smi) << three);
484 assertEquals(-0x73594000, (neg_non_smi) << four);
485 assertEquals(neg_non_smi, (neg_non_smi - 0.5) >> zero);
486 assertEquals(neg_non_smi + 0x100000000, (neg_non_smi - 0.5) >>> zero);
487 assertEquals(neg_non_smi, (neg_non_smi - 0.5) << zero);
488 assertEquals(neg_non_smi / 2, (neg_non_smi - 0.5) >> one);
489 assertEquals(neg_non_smi / 2 + 0x100000000 / 2, (neg_non_smi - 0.5) >>> one);
490 assertEquals(0x1194D800, (neg_non_smi - 0.5) << one);
491 assertEquals(neg_non_smi / 8, (neg_non_smi - 0.5) >> three);
492 assertEquals(neg_non_smi / 8 + 0x100000000 / 8, (neg_non_smi - 0.5)
493 >>> three);
494 assertEquals(0x46536000, (neg_non_smi - 0.5) << three);
495 assertEquals(-0x73594000, (neg_non_smi - 0.5) << four);
496
497 assertEquals(pos_smi / 2, (pos_smi) >> one);
498 assertEquals(pos_smi / 2, (pos_smi) >>> one);
499 assertEquals(pos_non_smi, (pos_smi) << one);
500 assertEquals(pos_smi / 8, (pos_smi) >> three);
501 assertEquals(pos_smi / 8, (pos_smi) >>> three);
502 assertEquals(-0x2329b000, (pos_smi) << three);
503 assertEquals(0x73594000, (pos_smi) << five);
504 assertEquals(pos_smi, (pos_smi + 0.5) >> zero);
505 assertEquals(pos_smi, (pos_smi + 0.5) >>> zero);
506 assertEquals(pos_smi, (pos_smi + 0.5) << zero);
507 assertEquals(pos_smi / 2, (pos_smi + 0.5) >> one);
508 assertEquals(pos_smi / 2, (pos_smi + 0.5) >>> one);
509 assertEquals(pos_non_smi, (pos_smi + 0.5) << one);
510 assertEquals(pos_smi / 8, (pos_smi + 0.5) >> three);
511 assertEquals(pos_smi / 8, (pos_smi + 0.5) >>> three);
512 assertEquals(-0x2329b000, (pos_smi + 0.5) << three);
513 assertEquals(0x73594000, (pos_smi + 0.5) << five);
514
515 assertEquals(neg_smi / 2, (neg_smi) >> one);
516 assertEquals(neg_smi / 2 + 0x100000000 / 2, (neg_smi) >>> one);
517 assertEquals(neg_non_smi, (neg_smi) << one);
518 assertEquals(neg_smi / 8, (neg_smi) >> three);
519 assertEquals(neg_smi / 8 + 0x100000000 / 8, (neg_smi) >>> three);
520 assertEquals(0x46536000, (neg_smi) << four);
521 assertEquals(-0x73594000, (neg_smi) << five);
522 assertEquals(neg_smi, (neg_smi - 0.5) >> zero);
523 assertEquals(neg_smi + 0x100000000, (neg_smi - 0.5) >>> zero);
524 assertEquals(neg_smi, (neg_smi - 0.5) << zero);
525 assertEquals(neg_smi / 2, (neg_smi - 0.5) >> one);
526 assertEquals(neg_smi / 2 + 0x100000000 / 2, (neg_smi - 0.5) >>> one);
527 assertEquals(neg_non_smi, (neg_smi - 0.5) << one);
528 assertEquals(neg_smi / 8, (neg_smi - 0.5) >> three);
529 assertEquals(neg_smi / 8 + 0x100000000 / 8, (neg_smi - 0.5) >>> three);
530 assertEquals(0x46536000, (neg_smi - 0.5) << four);
531 assertEquals(-0x73594000, (neg_smi - 0.5) << five);
532 // End block A repeat 2
533
534 // Repeat previous block, with computed values in the shift variables.
535 five = 0;
536 while (five < 5 ) ++five;
537 four = five - one;
538 three = four - one;
539 one = four - three;
540 zero = one - one;
541
542 // Begin block A repeat 3
543 assertEquals(pos_non_smi, (pos_non_smi) >> zero);
544 assertEquals(pos_non_smi, (pos_non_smi) >>> zero);
545 assertEquals(pos_non_smi, (pos_non_smi) << zero);
546 assertEquals(neg_non_smi, (neg_non_smi) >> zero);
547 assertEquals(neg_non_smi + 0x100000000, (neg_non_smi) >>> zero);
548 assertEquals(neg_non_smi, (neg_non_smi) << zero);
549 assertEquals(pos_smi, (pos_smi) >> zero);
550 assertEquals(pos_smi, (pos_smi) >>> zero);
551 assertEquals(pos_smi, (pos_smi) << zero);
552 assertEquals(neg_smi, (neg_smi) >> zero, "negsmi >> zero(2)");
553 assertEquals(neg_smi + 0x100000000, (neg_smi) >>> zero);
554 assertEquals(neg_smi, (neg_smi) << zero, "negsmi << zero(2)");
555
556 assertEquals(pos_non_smi / 2, (pos_non_smi) >> one);
557 assertEquals(pos_non_smi / 2, (pos_non_smi) >>> one);
558 assertEquals(-0x1194D800, (pos_non_smi) << one);
559 assertEquals(pos_non_smi / 8, (pos_non_smi) >> three);
560 assertEquals(pos_non_smi / 8, (pos_non_smi) >>> three);
561 assertEquals(-0x46536000, (pos_non_smi) << three);
562 assertEquals(0x73594000, (pos_non_smi) << four);
563 assertEquals(pos_non_smi, (pos_non_smi + 0.5) >> zero);
564 assertEquals(pos_non_smi, (pos_non_smi + 0.5) >>> zero);
565 assertEquals(pos_non_smi, (pos_non_smi + 0.5) << zero);
566 assertEquals(pos_non_smi / 2, (pos_non_smi + 0.5) >> one);
567 assertEquals(pos_non_smi / 2, (pos_non_smi + 0.5) >>> one);
568 assertEquals(-0x1194D800, (pos_non_smi + 0.5) << one);
569 assertEquals(pos_non_smi / 8, (pos_non_smi + 0.5) >> three);
570 assertEquals(pos_non_smi / 8, (pos_non_smi + 0.5) >>> three);
571 assertEquals(-0x46536000, (pos_non_smi + 0.5) << three);
572 assertEquals(0x73594000, (pos_non_smi + 0.5) << four);
573
574 assertEquals(neg_non_smi / 2, (neg_non_smi) >> one);
575 assertEquals(neg_non_smi / 2 + 0x100000000 / 2, (neg_non_smi) >>> one);
576 assertEquals(0x1194D800, (neg_non_smi) << one);
577 assertEquals(neg_non_smi / 8, (neg_non_smi) >> three);
578 assertEquals(neg_non_smi / 8 + 0x100000000 / 8, (neg_non_smi) >>> three);
579 assertEquals(0x46536000, (neg_non_smi) << three);
580 assertEquals(-0x73594000, (neg_non_smi) << four);
581 assertEquals(neg_non_smi, (neg_non_smi - 0.5) >> zero);
582 assertEquals(neg_non_smi + 0x100000000, (neg_non_smi - 0.5) >>> zero);
583 assertEquals(neg_non_smi, (neg_non_smi - 0.5) << zero);
584 assertEquals(neg_non_smi / 2, (neg_non_smi - 0.5) >> one);
585 assertEquals(neg_non_smi / 2 + 0x100000000 / 2, (neg_non_smi - 0.5) >>> one);
586 assertEquals(0x1194D800, (neg_non_smi - 0.5) << one);
587 assertEquals(neg_non_smi / 8, (neg_non_smi - 0.5) >> three);
588 assertEquals(neg_non_smi / 8 + 0x100000000 / 8, (neg_non_smi - 0.5)
589 >>> three);
590 assertEquals(0x46536000, (neg_non_smi - 0.5) << three);
591 assertEquals(-0x73594000, (neg_non_smi - 0.5) << four);
592
593 assertEquals(pos_smi / 2, (pos_smi) >> one);
594 assertEquals(pos_smi / 2, (pos_smi) >>> one);
595 assertEquals(pos_non_smi, (pos_smi) << one);
596 assertEquals(pos_smi / 8, (pos_smi) >> three);
597 assertEquals(pos_smi / 8, (pos_smi) >>> three);
598 assertEquals(-0x2329b000, (pos_smi) << three);
599 assertEquals(0x73594000, (pos_smi) << five);
600 assertEquals(pos_smi, (pos_smi + 0.5) >> zero);
601 assertEquals(pos_smi, (pos_smi + 0.5) >>> zero);
602 assertEquals(pos_smi, (pos_smi + 0.5) << zero);
603 assertEquals(pos_smi / 2, (pos_smi + 0.5) >> one);
604 assertEquals(pos_smi / 2, (pos_smi + 0.5) >>> one);
605 assertEquals(pos_non_smi, (pos_smi + 0.5) << one);
606 assertEquals(pos_smi / 8, (pos_smi + 0.5) >> three);
607 assertEquals(pos_smi / 8, (pos_smi + 0.5) >>> three);
608 assertEquals(-0x2329b000, (pos_smi + 0.5) << three);
609 assertEquals(0x73594000, (pos_smi + 0.5) << five);
610
611 assertEquals(neg_smi / 2, (neg_smi) >> one);
612 assertEquals(neg_smi / 2 + 0x100000000 / 2, (neg_smi) >>> one);
613 assertEquals(neg_non_smi, (neg_smi) << one);
614 assertEquals(neg_smi / 8, (neg_smi) >> three);
615 assertEquals(neg_smi / 8 + 0x100000000 / 8, (neg_smi) >>> three);
616 assertEquals(0x46536000, (neg_smi) << four);
617 assertEquals(-0x73594000, (neg_smi) << five);
618 assertEquals(neg_smi, (neg_smi - 0.5) >> zero, "negsmi.5 >> zero");
619 assertEquals(neg_smi + 0x100000000, (neg_smi - 0.5) >>> zero);
620 assertEquals(neg_smi, (neg_smi - 0.5) << zero, "negsmi.5 << zero");
621 assertEquals(neg_smi / 2, (neg_smi - 0.5) >> one);
622 assertEquals(neg_smi / 2 + 0x100000000 / 2, (neg_smi - 0.5) >>> one);
623 assertEquals(neg_non_smi, (neg_smi - 0.5) << one);
624 assertEquals(neg_smi / 8, (neg_smi - 0.5) >> three);
625 assertEquals(neg_smi / 8 + 0x100000000 / 8, (neg_smi - 0.5) >>> three);
626 assertEquals(0x46536000, (neg_smi - 0.5) << four);
627 assertEquals(-0x73594000, (neg_smi - 0.5) << five);
628 // End block A repeat 3
629
630 // Test non-integer shift value
631 assertEquals(5, 20.5 >> 2.4);
632 assertEquals(5, 20.5 >> 2.7);
633 var shift = 2.4;
634 assertEquals(5, 20.5 >> shift);
635 assertEquals(5, 20.5 >> shift + 0.3);
636 shift = shift + zero;
637 assertEquals(5, 20.5 >> shift);
638 assertEquals(5, 20.5 >> shift + 0.3);
639}
640
641testShiftNonSmis();
642
643function intConversion() {
644 function foo(x) {
645 assertEquals(x, (x * 1.0000000001) | 0, "foo more " + x);
646 assertEquals(x, x | 0, "foo " + x);
647 if (x > 0) {
648 assertEquals(x - 1, (x * 0.9999999999) | 0, "foo less " + x);
649 } else {
650 assertEquals(x + 1, (x * 0.9999999999) | 0, "foo less " + x);
651 }
652 }
653 for (var i = 1; i < 0x80000000; i *= 2) {
654 foo(i);
655 foo(-i);
656 }
657 for (var i = 1; i < 1/0; i *= 2) {
658 assertEquals(i | 0, (i * 1.0000000000000001) | 0, "b" + i);
659 assertEquals(-i | 0, (i * -1.0000000000000001) | 0, "c" + i);
660 }
661 for (var i = 0.5; i > 0; i /= 2) {
662 assertEquals(0, i | 0, "d" + i);
663 assertEquals(0, -i | 0, "e" + i);
664 }
665}
666
667intConversion();
668
669// Verify that we handle the (optimized) corner case of shifting by
670// zero even for non-smis.
671function shiftByZero(n) { return n << 0; }
672
673assertEquals(3, shiftByZero(3.1415));