Home | History | Annotate | Download | only in mjsunit
      1 // 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 const SMI_MAX = (1 << 29) - 1 + (1 << 29);  // Create without overflowing.
     29 const SMI_MIN = -SMI_MAX - 1;  // Create without overflowing.
     30 const ONE = 1;
     31 const ONE_HUNDRED = 100;
     32 
     33 const OBJ_42 = new (function() {
     34   this.valueOf = function() { return 42; };
     35 })();
     36 
     37 assertEquals(42, OBJ_42.valueOf());
     38 
     39 
     40 function Add1(x) {
     41   return x + 1;
     42 }
     43 
     44 function Add100(x) {
     45   return x + 100;
     46 }
     47 
     48 function Add1Reversed(x) {
     49   return 1 + x;
     50 }
     51 
     52 function Add100Reversed(x) {
     53   return 100 + x;
     54 }
     55 
     56 
     57 assertEquals(1, Add1(0));  // fast case
     58 assertEquals(1, Add1Reversed(0));  // fast case
     59 assertEquals(SMI_MAX + ONE, Add1(SMI_MAX), "smimax + 1");
     60 assertEquals(SMI_MAX + ONE, Add1Reversed(SMI_MAX), "1 + smimax");
     61 assertEquals(42 + ONE, Add1(OBJ_42));  // non-smi
     62 assertEquals(42 + ONE, Add1Reversed(OBJ_42));  // non-smi
     63 
     64 assertEquals(100, Add100(0));  // fast case
     65 assertEquals(100, Add100Reversed(0));  // fast case
     66 assertEquals(SMI_MAX + ONE_HUNDRED, Add100(SMI_MAX), "smimax + 100");
     67 assertEquals(SMI_MAX + ONE_HUNDRED, Add100Reversed(SMI_MAX), " 100 + smimax");
     68 assertEquals(42 + ONE_HUNDRED, Add100(OBJ_42));  // non-smi
     69 assertEquals(42 + ONE_HUNDRED, Add100Reversed(OBJ_42));  // non-smi
     70 
     71 
     72 
     73 function Sub1(x) {
     74   return x - 1;
     75 }
     76 
     77 function Sub100(x) {
     78   return x - 100;
     79 }
     80 
     81 function Sub1Reversed(x) {
     82   return 1 - x;
     83 }
     84 
     85 function Sub100Reversed(x) {
     86   return 100 - x;
     87 }
     88 
     89 
     90 assertEquals(0, Sub1(1));  // fast case
     91 assertEquals(-1, Sub1Reversed(2));  // fast case
     92 assertEquals(SMI_MIN - ONE, Sub1(SMI_MIN));  // overflow
     93 assertEquals(ONE - SMI_MIN, Sub1Reversed(SMI_MIN));  // overflow
     94 assertEquals(42 - ONE, Sub1(OBJ_42));  // non-smi
     95 assertEquals(ONE - 42, Sub1Reversed(OBJ_42));  // non-smi
     96 
     97 assertEquals(0, Sub100(100));  // fast case
     98 assertEquals(1, Sub100Reversed(99));  // fast case
     99 assertEquals(SMI_MIN - ONE_HUNDRED, Sub100(SMI_MIN));  // overflow
    100 assertEquals(ONE_HUNDRED - SMI_MIN, Sub100Reversed(SMI_MIN));  // overflow
    101 assertEquals(42 - ONE_HUNDRED, Sub100(OBJ_42));  // non-smi
    102 assertEquals(ONE_HUNDRED - 42, Sub100Reversed(OBJ_42));  // non-smi
    103 
    104 
    105 function Shr1(x) {
    106   return x >>> 1;
    107 }
    108 
    109 function Shr100(x) {
    110   return x >>> 100;
    111 }
    112 
    113 function Shr1Reversed(x) {
    114   return 1 >>> x;
    115 }
    116 
    117 function Shr100Reversed(x) {
    118   return 100 >>> x;
    119 }
    120 
    121 function Sar1(x) {
    122   return x >> 1;
    123 }
    124 
    125 function Sar100(x) {
    126   return x >> 100;
    127 }
    128 
    129 function Sar1Reversed(x) {
    130   return 1 >> x;
    131 }
    132 
    133 function Sar100Reversed(x) {
    134   return 100 >> x;
    135 }
    136 
    137 
    138 assertEquals(0, Shr1(1));
    139 assertEquals(0, Sar1(1));
    140 assertEquals(0, Shr1Reversed(2));
    141 assertEquals(0, Sar1Reversed(2));
    142 assertEquals(1610612736, Shr1(SMI_MIN));
    143 assertEquals(-536870912, Sar1(SMI_MIN));
    144 assertEquals(1, Shr1Reversed(SMI_MIN));
    145 assertEquals(1, Sar1Reversed(SMI_MIN));
    146 assertEquals(21, Shr1(OBJ_42));
    147 assertEquals(21, Sar1(OBJ_42));
    148 assertEquals(0, Shr1Reversed(OBJ_42));
    149 assertEquals(0, Sar1Reversed(OBJ_42));
    150 
    151 assertEquals(6, Shr100(100), "100 >>> 100");
    152 assertEquals(6, Sar100(100), "100 >> 100");
    153 assertEquals(12, Shr100Reversed(99));
    154 assertEquals(12, Sar100Reversed(99));
    155 assertEquals(201326592, Shr100(SMI_MIN));
    156 assertEquals(-67108864, Sar100(SMI_MIN));
    157 assertEquals(100, Shr100Reversed(SMI_MIN));
    158 assertEquals(100, Sar100Reversed(SMI_MIN));
    159 assertEquals(2, Shr100(OBJ_42));
    160 assertEquals(2, Sar100(OBJ_42));
    161 assertEquals(0, Shr100Reversed(OBJ_42));
    162 assertEquals(0, Sar100Reversed(OBJ_42));
    163 
    164 
    165 function Xor1(x) {
    166   return x ^ 1;
    167 }
    168 
    169 function Xor100(x) {
    170   return x ^ 100;
    171 }
    172 
    173 function Xor1Reversed(x) {
    174   return 1 ^ x;
    175 }
    176 
    177 function Xor100Reversed(x) {
    178   return 100 ^ x;
    179 }
    180 
    181 
    182 assertEquals(0, Xor1(1));
    183 assertEquals(3, Xor1Reversed(2));
    184 assertEquals(SMI_MIN + 1, Xor1(SMI_MIN));
    185 assertEquals(SMI_MIN + 1, Xor1Reversed(SMI_MIN));
    186 assertEquals(43, Xor1(OBJ_42));
    187 assertEquals(43, Xor1Reversed(OBJ_42));
    188 
    189 assertEquals(0, Xor100(100));
    190 assertEquals(7, Xor100Reversed(99));
    191 assertEquals(-1073741724, Xor100(SMI_MIN));
    192 assertEquals(-1073741724, Xor100Reversed(SMI_MIN));
    193 assertEquals(78, Xor100(OBJ_42));
    194 assertEquals(78, Xor100Reversed(OBJ_42));
    195 
    196 var x = 0x23; var y = 0x35;
    197 assertEquals(0x16, x ^ y);
    198 
    199 
    200 // Bitwise not.
    201 var v = 0;
    202 assertEquals(-1, ~v);
    203 v = SMI_MIN;
    204 assertEquals(0x3fffffff, ~v, "~smimin");
    205 v = SMI_MAX;
    206 assertEquals(-0x40000000, ~v, "~smimax");
    207 
    208 // Overflowing ++ and --.
    209 v = SMI_MAX;
    210 v++;
    211 assertEquals(0x40000000, v, "smimax++");
    212 v = SMI_MIN;
    213 v--;
    214 assertEquals(-0x40000001, v, "smimin--");
    215 
    216 // Check that comparisons of numbers separated by MIN_SMI work.
    217 assertFalse(SMI_MIN > 0);
    218 assertFalse(SMI_MIN + 1 > 1);
    219 assertFalse(SMI_MIN + 1 > 2);
    220 assertFalse(SMI_MIN + 2 > 1);
    221 assertFalse(0 < SMI_MIN);
    222 assertTrue(-1 < SMI_MAX);
    223 assertFalse(SMI_MAX < -1);
    224 
    225 // Not actually Smi operations.
    226 // Check that relations on unary ops work.
    227 var v = -1.2;
    228 assertTrue(v == v);
    229 assertTrue(v === v);
    230 assertTrue(v <= v);
    231 assertTrue(v >= v);
    232 assertFalse(v < v);
    233 assertFalse(v > v);
    234 assertFalse(v != v);
    235 assertFalse(v !== v);
    236 
    237 // Right hand side of unary minus is overwritable.
    238 v = 1.5
    239 assertEquals(-2.25, -(v * v));
    240 
    241 // Smi input to bitop gives non-smi result where the rhs is a float that
    242 // can be overwritten.
    243 var x1 = 0x10000000;
    244 var x2 = 0x40000002;
    245 var x3 = 0x40000000;
    246 assertEquals(0x40000000, x1 << (x2 - x3), "0x10000000<<1(1)");
    247 
    248 // Smi input to bitop gives non-smi result where the rhs could be overwritten
    249 // if it were a float, but it isn't.
    250 x1 = 0x10000000
    251 x2 = 4
    252 x3 = 2
    253 assertEquals(0x40000000, x1 << (x2 - x3), "0x10000000<<2(2)");
    254 
    255 
    256 // Test shift operators on non-smi inputs, giving smi and non-smi results.
    257 function testShiftNonSmis() {
    258   var pos_non_smi = 2000000000;
    259   var neg_non_smi = -pos_non_smi;
    260   var pos_smi = 1000000000;
    261   var neg_smi = -pos_smi;
    262 
    263   // Begin block A
    264   assertEquals(pos_non_smi, (pos_non_smi) >> 0);
    265   assertEquals(pos_non_smi, (pos_non_smi) >>> 0);
    266   assertEquals(pos_non_smi, (pos_non_smi) << 0);
    267   assertEquals(neg_non_smi, (neg_non_smi) >> 0);
    268   assertEquals(neg_non_smi + 0x100000000, (neg_non_smi) >>> 0);
    269   assertEquals(neg_non_smi, (neg_non_smi) << 0);
    270   assertEquals(pos_smi, (pos_smi) >> 0, "possmi >> 0");
    271   assertEquals(pos_smi, (pos_smi) >>> 0, "possmi >>>0");
    272   assertEquals(pos_smi, (pos_smi) << 0, "possmi << 0");
    273   assertEquals(neg_smi, (neg_smi) >> 0, "negsmi >> 0");
    274   assertEquals(neg_smi + 0x100000000, (neg_smi) >>> 0, "negsmi >>> 0");
    275   assertEquals(neg_smi, (neg_smi) << 0), "negsmi << 0";
    276 
    277   assertEquals(pos_non_smi / 2, (pos_non_smi) >> 1);
    278   assertEquals(pos_non_smi / 2, (pos_non_smi) >>> 1);
    279   assertEquals(-0x1194D800, (pos_non_smi) << 1);
    280   assertEquals(pos_non_smi / 8, (pos_non_smi) >> 3);
    281   assertEquals(pos_non_smi / 8, (pos_non_smi) >>> 3);
    282   assertEquals(-0x46536000, (pos_non_smi) << 3);
    283   assertEquals(0x73594000, (pos_non_smi) << 4);
    284   assertEquals(pos_non_smi, (pos_non_smi + 0.5) >> 0);
    285   assertEquals(pos_non_smi, (pos_non_smi + 0.5) >>> 0);
    286   assertEquals(pos_non_smi, (pos_non_smi + 0.5) << 0);
    287   assertEquals(pos_non_smi / 2, (pos_non_smi + 0.5) >> 1);
    288   assertEquals(pos_non_smi / 2, (pos_non_smi + 0.5) >>> 1);
    289   assertEquals(-0x1194D800, (pos_non_smi + 0.5) << 1);
    290   assertEquals(pos_non_smi / 8, (pos_non_smi + 0.5) >> 3);
    291   assertEquals(pos_non_smi / 8, (pos_non_smi + 0.5) >>> 3);
    292   assertEquals(-0x46536000, (pos_non_smi + 0.5) << 3);
    293   assertEquals(0x73594000, (pos_non_smi + 0.5) << 4);
    294 
    295   assertEquals(neg_non_smi / 2, (neg_non_smi) >> 1, "negnonsmi >> 1");
    296 
    297   assertEquals(neg_non_smi / 2 + 0x100000000 / 2, (neg_non_smi) >>> 1,
    298                "negnonsmi >>> 1");
    299   assertEquals(0x1194D800, (neg_non_smi) << 1);
    300   assertEquals(neg_non_smi / 8, (neg_non_smi) >> 3);
    301   assertEquals(neg_non_smi / 8 + 0x100000000 / 8, (neg_non_smi) >>> 3);
    302   assertEquals(0x46536000, (neg_non_smi) << 3);
    303   assertEquals(-0x73594000, (neg_non_smi) << 4);
    304   assertEquals(neg_non_smi, (neg_non_smi - 0.5) >> 0);
    305   assertEquals(neg_non_smi + 0x100000000, (neg_non_smi - 0.5) >>> 0,
    306                "negnonsmi.5 >>> 0");
    307   assertEquals(neg_non_smi, (neg_non_smi - 0.5) << 0);
    308   assertEquals(neg_non_smi / 2, (neg_non_smi - 0.5) >> 1);
    309   assertEquals(neg_non_smi / 2 + 0x100000000 / 2, (neg_non_smi - 0.5) >>> 1,
    310                "negnonsmi.5 >>> 1");
    311   assertEquals(0x1194D800, (neg_non_smi - 0.5) << 1);
    312   assertEquals(neg_non_smi / 8, (neg_non_smi - 0.5) >> 3);
    313   assertEquals(neg_non_smi / 8 + 0x100000000 / 8, (neg_non_smi - 0.5) >>> 3);
    314   assertEquals(0x46536000, (neg_non_smi - 0.5) << 3);
    315   assertEquals(-0x73594000, (neg_non_smi - 0.5) << 4);
    316 
    317   assertEquals(pos_smi / 2, (pos_smi) >> 1);
    318   assertEquals(pos_smi / 2, (pos_smi) >>> 1);
    319   assertEquals(pos_non_smi, (pos_smi) << 1);
    320   assertEquals(pos_smi / 8, (pos_smi) >> 3);
    321   assertEquals(pos_smi / 8, (pos_smi) >>> 3);
    322   assertEquals(-0x2329b000, (pos_smi) << 3);
    323   assertEquals(0x73594000, (pos_smi) << 5);
    324   assertEquals(pos_smi, (pos_smi + 0.5) >> 0, "possmi.5 >> 0");
    325   assertEquals(pos_smi, (pos_smi + 0.5) >>> 0, "possmi.5 >>> 0");
    326   assertEquals(pos_smi, (pos_smi + 0.5) << 0, "possmi.5 << 0");
    327   assertEquals(pos_smi / 2, (pos_smi + 0.5) >> 1);
    328   assertEquals(pos_smi / 2, (pos_smi + 0.5) >>> 1);
    329   assertEquals(pos_non_smi, (pos_smi + 0.5) << 1);
    330   assertEquals(pos_smi / 8, (pos_smi + 0.5) >> 3);
    331   assertEquals(pos_smi / 8, (pos_smi + 0.5) >>> 3);
    332   assertEquals(-0x2329b000, (pos_smi + 0.5) << 3);
    333   assertEquals(0x73594000, (pos_smi + 0.5) << 5);
    334 
    335   assertEquals(neg_smi / 2, (neg_smi) >> 1);
    336   assertEquals(neg_smi / 2 + 0x100000000 / 2, (neg_smi) >>> 1);
    337   assertEquals(neg_non_smi, (neg_smi) << 1);
    338   assertEquals(neg_smi / 8, (neg_smi) >> 3);
    339   assertEquals(neg_smi / 8 + 0x100000000 / 8, (neg_smi) >>> 3);
    340   assertEquals(0x46536000, (neg_smi) << 4);
    341   assertEquals(-0x73594000, (neg_smi) << 5);
    342   assertEquals(neg_smi, (neg_smi - 0.5) >> 0, "negsmi.5 >> 0");
    343   assertEquals(neg_smi + 0x100000000, (neg_smi - 0.5) >>> 0, "negsmi.5 >>> 0");
    344   assertEquals(neg_smi, (neg_smi - 0.5) << 0, "negsmi.5 << 0");
    345   assertEquals(neg_smi / 2, (neg_smi - 0.5) >> 1);
    346   assertEquals(neg_smi / 2 + 0x100000000 / 2, (neg_smi - 0.5) >>> 1);
    347   assertEquals(neg_non_smi, (neg_smi - 0.5) << 1);
    348   assertEquals(neg_smi / 8, (neg_smi - 0.5) >> 3);
    349   assertEquals(neg_smi / 8 + 0x100000000 / 8, (neg_smi - 0.5) >>> 3);
    350   assertEquals(0x46536000, (neg_smi - 0.5) << 4);
    351   assertEquals(-0x73594000, (neg_smi - 0.5) << 5);
    352   // End block A
    353 
    354   // Repeat block A with 2^32 added to positive numbers and
    355   // 2^32 subtracted from negative numbers.
    356   // Begin block A repeat 1
    357   var two_32 = 0x100000000;
    358   var neg_32 = -two_32;
    359   assertEquals(pos_non_smi, (two_32 + pos_non_smi) >> 0);
    360   assertEquals(pos_non_smi, (two_32 + pos_non_smi) >>> 0);
    361   assertEquals(pos_non_smi, (two_32 + pos_non_smi) << 0);
    362   assertEquals(neg_non_smi, (neg_32 + neg_non_smi) >> 0);
    363   assertEquals(neg_non_smi + 0x100000000, (neg_32 + neg_non_smi) >>> 0);
    364   assertEquals(neg_non_smi, (neg_32 + neg_non_smi) << 0);
    365   assertEquals(pos_smi, (two_32 + pos_smi) >> 0, "2^32+possmi >> 0");
    366   assertEquals(pos_smi, (two_32 + pos_smi) >>> 0, "2^32+possmi >>> 0");
    367   assertEquals(pos_smi, (two_32 + pos_smi) << 0, "2^32+possmi << 0");
    368   assertEquals(neg_smi, (neg_32 + neg_smi) >> 0, "2^32+negsmi >> 0");
    369   assertEquals(neg_smi + 0x100000000, (neg_32 + neg_smi) >>> 0);
    370   assertEquals(neg_smi, (neg_32 + neg_smi) << 0, "2^32+negsmi << 0");
    371 
    372   assertEquals(pos_non_smi / 2, (two_32 + pos_non_smi) >> 1);
    373   assertEquals(pos_non_smi / 2, (two_32 + pos_non_smi) >>> 1);
    374   assertEquals(-0x1194D800, (two_32 + pos_non_smi) << 1);
    375   assertEquals(pos_non_smi / 8, (two_32 + pos_non_smi) >> 3);
    376   assertEquals(pos_non_smi / 8, (two_32 + pos_non_smi) >>> 3);
    377   assertEquals(-0x46536000, (two_32 + pos_non_smi) << 3);
    378   assertEquals(0x73594000, (two_32 + pos_non_smi) << 4);
    379   assertEquals(pos_non_smi, (two_32 + pos_non_smi + 0.5) >> 0);
    380   assertEquals(pos_non_smi, (two_32 + pos_non_smi + 0.5) >>> 0);
    381   assertEquals(pos_non_smi, (two_32 + pos_non_smi + 0.5) << 0);
    382   assertEquals(pos_non_smi / 2, (two_32 + pos_non_smi + 0.5) >> 1);
    383   assertEquals(pos_non_smi / 2, (two_32 + pos_non_smi + 0.5) >>> 1);
    384   assertEquals(-0x1194D800, (two_32 + pos_non_smi + 0.5) << 1);
    385   assertEquals(pos_non_smi / 8, (two_32 + pos_non_smi + 0.5) >> 3);
    386   assertEquals(pos_non_smi / 8, (two_32 + pos_non_smi + 0.5) >>> 3);
    387   assertEquals(-0x46536000, (two_32 + pos_non_smi + 0.5) << 3);
    388   assertEquals(0x73594000, (two_32 + pos_non_smi + 0.5) << 4);
    389 
    390   assertEquals(neg_non_smi / 2, (neg_32 + neg_non_smi) >> 1);
    391   assertEquals(neg_non_smi / 2 + 0x100000000 / 2, (neg_32 + neg_non_smi) >>> 1);
    392   assertEquals(0x1194D800, (neg_32 + neg_non_smi) << 1);
    393   assertEquals(neg_non_smi / 8, (neg_32 + neg_non_smi) >> 3);
    394   assertEquals(neg_non_smi / 8 + 0x100000000 / 8, (neg_32 + neg_non_smi) >>> 3);
    395   assertEquals(0x46536000, (neg_32 + neg_non_smi) << 3);
    396   assertEquals(-0x73594000, (neg_32 + neg_non_smi) << 4);
    397   assertEquals(neg_non_smi, (neg_32 + neg_non_smi - 0.5) >> 0);
    398   assertEquals(neg_non_smi + 0x100000000, (neg_32 + neg_non_smi - 0.5) >>> 0);
    399   assertEquals(neg_non_smi, (neg_32 + neg_non_smi - 0.5) << 0);
    400   assertEquals(neg_non_smi / 2, (neg_32 + neg_non_smi - 0.5) >> 1);
    401   assertEquals(neg_non_smi / 2 + 0x100000000 / 2, (neg_32 + neg_non_smi - 0.5)
    402                >>> 1);
    403   assertEquals(0x1194D800, (neg_32 + neg_non_smi - 0.5) << 1);
    404   assertEquals(neg_non_smi / 8, (neg_32 + neg_non_smi - 0.5) >> 3);
    405   assertEquals(neg_non_smi / 8 + 0x100000000 / 8, (neg_32 + neg_non_smi - 0.5)
    406                >>> 3);
    407   assertEquals(0x46536000, (neg_32 + neg_non_smi - 0.5) << 3);
    408   assertEquals(-0x73594000, (neg_32 + neg_non_smi - 0.5) << 4);
    409 
    410   assertEquals(pos_smi / 2, (two_32 + pos_smi) >> 1);
    411   assertEquals(pos_smi / 2, (two_32 + pos_smi) >>> 1);
    412   assertEquals(pos_non_smi, (two_32 + pos_smi) << 1);
    413   assertEquals(pos_smi / 8, (two_32 + pos_smi) >> 3);
    414   assertEquals(pos_smi / 8, (two_32 + pos_smi) >>> 3);
    415   assertEquals(-0x2329b000, (two_32 + pos_smi) << 3);
    416   assertEquals(0x73594000, (two_32 + pos_smi) << 5);
    417   assertEquals(pos_smi, (two_32 + pos_smi + 0.5) >> 0);
    418   assertEquals(pos_smi, (two_32 + pos_smi + 0.5) >>> 0);
    419   assertEquals(pos_smi, (two_32 + pos_smi + 0.5) << 0);
    420   assertEquals(pos_smi / 2, (two_32 + pos_smi + 0.5) >> 1);
    421   assertEquals(pos_smi / 2, (two_32 + pos_smi + 0.5) >>> 1);
    422   assertEquals(pos_non_smi, (two_32 + pos_smi + 0.5) << 1);
    423   assertEquals(pos_smi / 8, (two_32 + pos_smi + 0.5) >> 3);
    424   assertEquals(pos_smi / 8, (two_32 + pos_smi + 0.5) >>> 3);
    425   assertEquals(-0x2329b000, (two_32 + pos_smi + 0.5) << 3);
    426   assertEquals(0x73594000, (two_32 + pos_smi + 0.5) << 5);
    427 
    428   assertEquals(neg_smi / 2, (neg_32 + neg_smi) >> 1);
    429   assertEquals(neg_smi / 2 + 0x100000000 / 2, (neg_32 + neg_smi) >>> 1);
    430   assertEquals(neg_non_smi, (neg_32 + neg_smi) << 1);
    431   assertEquals(neg_smi / 8, (neg_32 + neg_smi) >> 3);
    432   assertEquals((neg_smi + 0x100000000) / 8, (neg_32 + neg_smi) >>> 3);
    433   assertEquals(0x46536000, (neg_32 + neg_smi) << 4);
    434   assertEquals(-0x73594000, (neg_32 + neg_smi) << 5);
    435   assertEquals(neg_smi, (neg_32 + neg_smi - 0.5) >> 0, "-2^32+negsmi.5 >> 0");
    436   assertEquals(neg_smi + 0x100000000, (neg_32 + neg_smi - 0.5) >>> 0);
    437   assertEquals(neg_smi, (neg_32 + neg_smi - 0.5) << 0, "-2^32+negsmi.5 << 0");
    438   assertEquals(neg_smi / 2, (neg_32 + neg_smi - 0.5) >> 1);
    439   assertEquals(neg_smi / 2 + 0x100000000 / 2, (neg_32 + neg_smi - 0.5) >>> 1);
    440   assertEquals(neg_non_smi, (neg_32 + neg_smi - 0.5) << 1);
    441   assertEquals(neg_smi / 8, (neg_32 + neg_smi - 0.5) >> 3);
    442   assertEquals(neg_smi / 8 + 0x100000000 / 8, (neg_32 + neg_smi - 0.5) >>> 3);
    443   assertEquals(0x46536000, (neg_32 + neg_smi - 0.5) << 4);
    444   assertEquals(-0x73594000, (neg_32 + neg_smi - 0.5) << 5);
    445   // End block A repeat 1
    446   // Repeat block A with shift amounts in variables intialized with
    447   // a constant.
    448   var zero = 0;
    449   var one = 1;
    450   var three = 3;
    451   var four = 4;
    452   var five = 5;
    453   // Begin block A repeat 2
    454   assertEquals(pos_non_smi, (pos_non_smi) >> zero);
    455   assertEquals(pos_non_smi, (pos_non_smi) >>> zero);
    456   assertEquals(pos_non_smi, (pos_non_smi) << zero);
    457   assertEquals(neg_non_smi, (neg_non_smi) >> zero);
    458   assertEquals(neg_non_smi + 0x100000000, (neg_non_smi) >>> zero);
    459   assertEquals(neg_non_smi, (neg_non_smi) << zero);
    460   assertEquals(pos_smi, (pos_smi) >> zero);
    461   assertEquals(pos_smi, (pos_smi) >>> zero);
    462   assertEquals(pos_smi, (pos_smi) << zero);
    463   assertEquals(neg_smi, (neg_smi) >> zero, "negsmi >> zero");
    464   assertEquals(neg_smi + 0x100000000, (neg_smi) >>> zero);
    465   assertEquals(neg_smi, (neg_smi) << zero, "negsmi << zero");
    466 
    467   assertEquals(pos_non_smi / 2, (pos_non_smi) >> one);
    468   assertEquals(pos_non_smi / 2, (pos_non_smi) >>> one);
    469   assertEquals(-0x1194D800, (pos_non_smi) << one);
    470   assertEquals(pos_non_smi / 8, (pos_non_smi) >> three);
    471   assertEquals(pos_non_smi / 8, (pos_non_smi) >>> three);
    472   assertEquals(-0x46536000, (pos_non_smi) << three);
    473   assertEquals(0x73594000, (pos_non_smi) << four);
    474   assertEquals(pos_non_smi, (pos_non_smi + 0.5) >> zero);
    475   assertEquals(pos_non_smi, (pos_non_smi + 0.5) >>> zero);
    476   assertEquals(pos_non_smi, (pos_non_smi + 0.5) << zero);
    477   assertEquals(pos_non_smi / 2, (pos_non_smi + 0.5) >> one);
    478   assertEquals(pos_non_smi / 2, (pos_non_smi + 0.5) >>> one);
    479   assertEquals(-0x1194D800, (pos_non_smi + 0.5) << one);
    480   assertEquals(pos_non_smi / 8, (pos_non_smi + 0.5) >> three);
    481   assertEquals(pos_non_smi / 8, (pos_non_smi + 0.5) >>> three);
    482   assertEquals(-0x46536000, (pos_non_smi + 0.5) << three);
    483   assertEquals(0x73594000, (pos_non_smi + 0.5) << four);
    484 
    485   assertEquals(neg_non_smi / 2, (neg_non_smi) >> one);
    486   assertEquals(neg_non_smi / 2 + 0x100000000 / 2, (neg_non_smi) >>> one);
    487   assertEquals(0x1194D800, (neg_non_smi) << one);
    488   assertEquals(neg_non_smi / 8, (neg_non_smi) >> three);
    489   assertEquals(neg_non_smi / 8 + 0x100000000 / 8, (neg_non_smi) >>> three);
    490   assertEquals(0x46536000, (neg_non_smi) << three);
    491   assertEquals(-0x73594000, (neg_non_smi) << four);
    492   assertEquals(neg_non_smi, (neg_non_smi - 0.5) >> zero);
    493   assertEquals(neg_non_smi + 0x100000000, (neg_non_smi - 0.5) >>> zero);
    494   assertEquals(neg_non_smi, (neg_non_smi - 0.5) << zero);
    495   assertEquals(neg_non_smi / 2, (neg_non_smi - 0.5) >> one);
    496   assertEquals(neg_non_smi / 2 + 0x100000000 / 2, (neg_non_smi - 0.5) >>> one);
    497   assertEquals(0x1194D800, (neg_non_smi - 0.5) << one);
    498   assertEquals(neg_non_smi / 8, (neg_non_smi - 0.5) >> three);
    499   assertEquals(neg_non_smi / 8 + 0x100000000 / 8, (neg_non_smi - 0.5)
    500       >>> three);
    501   assertEquals(0x46536000, (neg_non_smi - 0.5) << three);
    502   assertEquals(-0x73594000, (neg_non_smi - 0.5) << four);
    503 
    504   assertEquals(pos_smi / 2, (pos_smi) >> one);
    505   assertEquals(pos_smi / 2, (pos_smi) >>> one);
    506   assertEquals(pos_non_smi, (pos_smi) << one);
    507   assertEquals(pos_smi / 8, (pos_smi) >> three);
    508   assertEquals(pos_smi / 8, (pos_smi) >>> three);
    509   assertEquals(-0x2329b000, (pos_smi) << three);
    510   assertEquals(0x73594000, (pos_smi) << five);
    511   assertEquals(pos_smi, (pos_smi + 0.5) >> zero);
    512   assertEquals(pos_smi, (pos_smi + 0.5) >>> zero);
    513   assertEquals(pos_smi, (pos_smi + 0.5) << zero);
    514   assertEquals(pos_smi / 2, (pos_smi + 0.5) >> one);
    515   assertEquals(pos_smi / 2, (pos_smi + 0.5) >>> one);
    516   assertEquals(pos_non_smi, (pos_smi + 0.5) << one);
    517   assertEquals(pos_smi / 8, (pos_smi + 0.5) >> three);
    518   assertEquals(pos_smi / 8, (pos_smi + 0.5) >>> three);
    519   assertEquals(-0x2329b000, (pos_smi + 0.5) << three);
    520   assertEquals(0x73594000, (pos_smi + 0.5) << five);
    521 
    522   assertEquals(neg_smi / 2, (neg_smi) >> one);
    523   assertEquals(neg_smi / 2 + 0x100000000 / 2, (neg_smi) >>> one);
    524   assertEquals(neg_non_smi, (neg_smi) << one);
    525   assertEquals(neg_smi / 8, (neg_smi) >> three);
    526   assertEquals(neg_smi / 8 + 0x100000000 / 8, (neg_smi) >>> three);
    527   assertEquals(0x46536000, (neg_smi) << four);
    528   assertEquals(-0x73594000, (neg_smi) << five);
    529   assertEquals(neg_smi, (neg_smi - 0.5) >> zero);
    530   assertEquals(neg_smi + 0x100000000, (neg_smi - 0.5) >>> zero);
    531   assertEquals(neg_smi, (neg_smi - 0.5) << zero);
    532   assertEquals(neg_smi / 2, (neg_smi - 0.5) >> one);
    533   assertEquals(neg_smi / 2 + 0x100000000 / 2, (neg_smi - 0.5) >>> one);
    534   assertEquals(neg_non_smi, (neg_smi - 0.5) << one);
    535   assertEquals(neg_smi / 8, (neg_smi - 0.5) >> three);
    536   assertEquals(neg_smi / 8 + 0x100000000 / 8, (neg_smi - 0.5) >>> three);
    537   assertEquals(0x46536000, (neg_smi - 0.5) << four);
    538   assertEquals(-0x73594000, (neg_smi - 0.5) << five);
    539   // End block A repeat 2
    540 
    541   // Repeat previous block, with computed values in the shift variables.
    542   five = 0;
    543   while (five < 5 ) ++five;
    544   four = five - one;
    545   three = four - one;
    546   one = four - three;
    547   zero = one - one;
    548 
    549   // Begin block A repeat 3
    550   assertEquals(pos_non_smi, (pos_non_smi) >> zero);
    551   assertEquals(pos_non_smi, (pos_non_smi) >>> zero);
    552   assertEquals(pos_non_smi, (pos_non_smi) << zero);
    553   assertEquals(neg_non_smi, (neg_non_smi) >> zero);
    554   assertEquals(neg_non_smi + 0x100000000, (neg_non_smi) >>> zero);
    555   assertEquals(neg_non_smi, (neg_non_smi) << zero);
    556   assertEquals(pos_smi, (pos_smi) >> zero);
    557   assertEquals(pos_smi, (pos_smi) >>> zero);
    558   assertEquals(pos_smi, (pos_smi) << zero);
    559   assertEquals(neg_smi, (neg_smi) >> zero, "negsmi >> zero(2)");
    560   assertEquals(neg_smi + 0x100000000, (neg_smi) >>> zero);
    561   assertEquals(neg_smi, (neg_smi) << zero, "negsmi << zero(2)");
    562 
    563   assertEquals(pos_non_smi / 2, (pos_non_smi) >> one);
    564   assertEquals(pos_non_smi / 2, (pos_non_smi) >>> one);
    565   assertEquals(-0x1194D800, (pos_non_smi) << one);
    566   assertEquals(pos_non_smi / 8, (pos_non_smi) >> three);
    567   assertEquals(pos_non_smi / 8, (pos_non_smi) >>> three);
    568   assertEquals(-0x46536000, (pos_non_smi) << three);
    569   assertEquals(0x73594000, (pos_non_smi) << four);
    570   assertEquals(pos_non_smi, (pos_non_smi + 0.5) >> zero);
    571   assertEquals(pos_non_smi, (pos_non_smi + 0.5) >>> zero);
    572   assertEquals(pos_non_smi, (pos_non_smi + 0.5) << zero);
    573   assertEquals(pos_non_smi / 2, (pos_non_smi + 0.5) >> one);
    574   assertEquals(pos_non_smi / 2, (pos_non_smi + 0.5) >>> one);
    575   assertEquals(-0x1194D800, (pos_non_smi + 0.5) << one);
    576   assertEquals(pos_non_smi / 8, (pos_non_smi + 0.5) >> three);
    577   assertEquals(pos_non_smi / 8, (pos_non_smi + 0.5) >>> three);
    578   assertEquals(-0x46536000, (pos_non_smi + 0.5) << three);
    579   assertEquals(0x73594000, (pos_non_smi + 0.5) << four);
    580 
    581   assertEquals(neg_non_smi / 2, (neg_non_smi) >> one);
    582   assertEquals(neg_non_smi / 2 + 0x100000000 / 2, (neg_non_smi) >>> one);
    583   assertEquals(0x1194D800, (neg_non_smi) << one);
    584   assertEquals(neg_non_smi / 8, (neg_non_smi) >> three);
    585   assertEquals(neg_non_smi / 8 + 0x100000000 / 8, (neg_non_smi) >>> three);
    586   assertEquals(0x46536000, (neg_non_smi) << three);
    587   assertEquals(-0x73594000, (neg_non_smi) << four);
    588   assertEquals(neg_non_smi, (neg_non_smi - 0.5) >> zero);
    589   assertEquals(neg_non_smi + 0x100000000, (neg_non_smi - 0.5) >>> zero);
    590   assertEquals(neg_non_smi, (neg_non_smi - 0.5) << zero);
    591   assertEquals(neg_non_smi / 2, (neg_non_smi - 0.5) >> one);
    592   assertEquals(neg_non_smi / 2 + 0x100000000 / 2, (neg_non_smi - 0.5) >>> one);
    593   assertEquals(0x1194D800, (neg_non_smi - 0.5) << one);
    594   assertEquals(neg_non_smi / 8, (neg_non_smi - 0.5) >> three);
    595   assertEquals(neg_non_smi / 8 + 0x100000000 / 8, (neg_non_smi - 0.5)
    596       >>> three);
    597   assertEquals(0x46536000, (neg_non_smi - 0.5) << three);
    598   assertEquals(-0x73594000, (neg_non_smi - 0.5) << four);
    599 
    600   assertEquals(pos_smi / 2, (pos_smi) >> one);
    601   assertEquals(pos_smi / 2, (pos_smi) >>> one);
    602   assertEquals(pos_non_smi, (pos_smi) << one);
    603   assertEquals(pos_smi / 8, (pos_smi) >> three);
    604   assertEquals(pos_smi / 8, (pos_smi) >>> three);
    605   assertEquals(-0x2329b000, (pos_smi) << three);
    606   assertEquals(0x73594000, (pos_smi) << five);
    607   assertEquals(pos_smi, (pos_smi + 0.5) >> zero);
    608   assertEquals(pos_smi, (pos_smi + 0.5) >>> zero);
    609   assertEquals(pos_smi, (pos_smi + 0.5) << zero);
    610   assertEquals(pos_smi / 2, (pos_smi + 0.5) >> one);
    611   assertEquals(pos_smi / 2, (pos_smi + 0.5) >>> one);
    612   assertEquals(pos_non_smi, (pos_smi + 0.5) << one);
    613   assertEquals(pos_smi / 8, (pos_smi + 0.5) >> three);
    614   assertEquals(pos_smi / 8, (pos_smi + 0.5) >>> three);
    615   assertEquals(-0x2329b000, (pos_smi + 0.5) << three);
    616   assertEquals(0x73594000, (pos_smi + 0.5) << five);
    617 
    618   assertEquals(neg_smi / 2, (neg_smi) >> one);
    619   assertEquals(neg_smi / 2 + 0x100000000 / 2, (neg_smi) >>> one);
    620   assertEquals(neg_non_smi, (neg_smi) << one);
    621   assertEquals(neg_smi / 8, (neg_smi) >> three);
    622   assertEquals(neg_smi / 8 + 0x100000000 / 8, (neg_smi) >>> three);
    623   assertEquals(0x46536000, (neg_smi) << four);
    624   assertEquals(-0x73594000, (neg_smi) << five);
    625   assertEquals(neg_smi, (neg_smi - 0.5) >> zero, "negsmi.5 >> zero");
    626   assertEquals(neg_smi + 0x100000000, (neg_smi - 0.5) >>> zero);
    627   assertEquals(neg_smi, (neg_smi - 0.5) << zero, "negsmi.5 << zero");
    628   assertEquals(neg_smi / 2, (neg_smi - 0.5) >> one);
    629   assertEquals(neg_smi / 2 + 0x100000000 / 2, (neg_smi - 0.5) >>> one);
    630   assertEquals(neg_non_smi, (neg_smi - 0.5) << one);
    631   assertEquals(neg_smi / 8, (neg_smi - 0.5) >> three);
    632   assertEquals(neg_smi / 8 + 0x100000000 / 8, (neg_smi - 0.5) >>> three);
    633   assertEquals(0x46536000, (neg_smi - 0.5) << four);
    634   assertEquals(-0x73594000, (neg_smi - 0.5) << five);
    635   // End block A repeat 3
    636 
    637   // Test non-integer shift value
    638   assertEquals(5, 20.5 >> 2.4);
    639   assertEquals(5, 20.5 >> 2.7);
    640   var shift = 2.4;
    641   assertEquals(5, 20.5 >> shift);
    642   assertEquals(5, 20.5 >> shift + 0.3);
    643   shift = shift + zero;
    644   assertEquals(5, 20.5 >> shift);
    645   assertEquals(5, 20.5 >> shift + 0.3);
    646 }
    647 
    648 testShiftNonSmis();
    649 
    650 function intConversion() {
    651   function foo(x) {
    652     assertEquals(x, (x * 1.0000000001) | 0, "foo more " + x);
    653     assertEquals(x, x | 0, "foo " + x);
    654     if (x > 0) {
    655       assertEquals(x - 1, (x * 0.9999999999) | 0, "foo less " + x);
    656     } else {
    657       assertEquals(x + 1, (x * 0.9999999999) | 0, "foo less " + x);
    658     }
    659   }
    660   for (var i = 1; i < 0x80000000; i *= 2) {
    661     foo(i);
    662     foo(-i);
    663   }
    664   for (var i = 1; i < 1/0; i *= 2) {
    665     assertEquals(i | 0, (i * 1.0000000000000001) | 0, "b" + i);
    666     assertEquals(-i | 0, (i * -1.0000000000000001) | 0, "c" + i);
    667   }
    668   for (var i = 0.5; i > 0; i /= 2) {
    669     assertEquals(0, i | 0, "d" + i);
    670     assertEquals(0, -i | 0, "e" + i);
    671   }
    672 }
    673 
    674 intConversion();
    675 
    676 // Verify that we handle the (optimized) corner case of shifting by
    677 // zero even for non-smis.
    678 function shiftByZero(n) { return n << 0; }
    679 
    680 assertEquals(3, shiftByZero(3.1415));
    681 
    682 // Verify that the static type information of x >>> 32 is computed correctly.
    683 function LogicalShiftRightByMultipleOf32(x) {
    684   x = x >>> 32;
    685   return x + x;
    686 }
    687 
    688 assertEquals(4589934592, LogicalShiftRightByMultipleOf32(-2000000000));
    689 assertEquals(4589934592, LogicalShiftRightByMultipleOf32(-2000000000));
    690 
    691 // Verify that the shift amount is reduced modulo 32, not modulo 64.
    692 function LeftShiftThreeBy(x) {return 3 << x;}
    693 assertEquals(24, LeftShiftThreeBy(3));
    694 assertEquals(24, LeftShiftThreeBy(35));
    695 assertEquals(24, LeftShiftThreeBy(67));
    696 assertEquals(24, LeftShiftThreeBy(-29));
    697 
    698 // Regression test for a bug in the ARM code generator.  For some register
    699 // allocations we got the Smi overflow case wrong.
    700 function f(x, y) { return y +  ( 1 << (x & 31)); }
    701 assertEquals(-2147483647, f(31, 1));
    702 
    703 // Regression test for correct handling of overflow in smi comparison.
    704 assertTrue(-0x40000000 < 42);
    705