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 // Flags: --always-inline-smi-code
     29 
     30 const SMI_MAX = (1 << 30) - 1;
     31 const SMI_MIN = -(1 << 30);
     32 const ONE = 1;
     33 const ONE_HUNDRED = 100;
     34 
     35 const OBJ_42 = new (function() {
     36   this.valueOf = function() { return 42; };
     37 })();
     38 
     39 assertEquals(42, OBJ_42.valueOf());
     40 
     41 
     42 function Add1(x) {
     43   return x + 1;
     44 }
     45 
     46 function Add100(x) {
     47   return x + 100;
     48 }
     49 
     50 function Add1Reversed(x) {
     51   return 1 + x;
     52 }
     53 
     54 function Add100Reversed(x) {
     55   return 100 + x;
     56 }
     57 
     58 
     59 assertEquals(1, Add1(0));  // fast case
     60 assertEquals(1, Add1Reversed(0));  // fast case
     61 assertEquals(SMI_MAX + ONE, Add1(SMI_MAX), "smimax + 1");
     62 assertEquals(SMI_MAX + ONE, Add1Reversed(SMI_MAX), "1 + smimax");
     63 assertEquals(42 + ONE, Add1(OBJ_42));  // non-smi
     64 assertEquals(42 + ONE, Add1Reversed(OBJ_42));  // non-smi
     65 
     66 assertEquals(100, Add100(0));  // fast case
     67 assertEquals(100, Add100Reversed(0));  // fast case
     68 assertEquals(SMI_MAX + ONE_HUNDRED, Add100(SMI_MAX), "smimax + 100");
     69 assertEquals(SMI_MAX + ONE_HUNDRED, Add100Reversed(SMI_MAX), " 100 + smimax");
     70 assertEquals(42 + ONE_HUNDRED, Add100(OBJ_42));  // non-smi
     71 assertEquals(42 + ONE_HUNDRED, Add100Reversed(OBJ_42));  // non-smi
     72 
     73 
     74 
     75 function Sub1(x) {
     76   return x - 1;
     77 }
     78 
     79 function Sub100(x) {
     80   return x - 100;
     81 }
     82 
     83 function Sub1Reversed(x) {
     84   return 1 - x;
     85 }
     86 
     87 function Sub100Reversed(x) {
     88   return 100 - x;
     89 }
     90 
     91 
     92 assertEquals(0, Sub1(1));  // fast case
     93 assertEquals(-1, Sub1Reversed(2));  // fast case
     94 assertEquals(SMI_MIN - ONE, Sub1(SMI_MIN));  // overflow
     95 assertEquals(ONE - SMI_MIN, Sub1Reversed(SMI_MIN));  // overflow
     96 assertEquals(42 - ONE, Sub1(OBJ_42));  // non-smi
     97 assertEquals(ONE - 42, Sub1Reversed(OBJ_42));  // non-smi
     98 
     99 assertEquals(0, Sub100(100));  // fast case
    100 assertEquals(1, Sub100Reversed(99));  // fast case
    101 assertEquals(SMI_MIN - ONE_HUNDRED, Sub100(SMI_MIN));  // overflow
    102 assertEquals(ONE_HUNDRED - SMI_MIN, Sub100Reversed(SMI_MIN));  // overflow
    103 assertEquals(42 - ONE_HUNDRED, Sub100(OBJ_42));  // non-smi
    104 assertEquals(ONE_HUNDRED - 42, Sub100Reversed(OBJ_42));  // non-smi
    105 
    106 
    107 function Shr1(x) {
    108   return x >>> 1;
    109 }
    110 
    111 function Shr100(x) {
    112   return x >>> 100;
    113 }
    114 
    115 function Shr1Reversed(x) {
    116   return 1 >>> x;
    117 }
    118 
    119 function Shr100Reversed(x) {
    120   return 100 >>> x;
    121 }
    122 
    123 function Sar1(x) {
    124   return x >> 1;
    125 }
    126 
    127 function Sar100(x) {
    128   return x >> 100;
    129 }
    130 
    131 function Sar1Reversed(x) {
    132   return 1 >> x;
    133 }
    134 
    135 function Sar100Reversed(x) {
    136   return 100 >> x;
    137 }
    138 
    139 
    140 assertEquals(0, Shr1(1));
    141 assertEquals(0, Sar1(1));
    142 assertEquals(0, Shr1Reversed(2));
    143 assertEquals(0, Sar1Reversed(2));
    144 assertEquals(1610612736, Shr1(SMI_MIN));
    145 assertEquals(-536870912, Sar1(SMI_MIN));
    146 assertEquals(1, Shr1Reversed(SMI_MIN));
    147 assertEquals(1, Sar1Reversed(SMI_MIN));
    148 assertEquals(21, Shr1(OBJ_42));
    149 assertEquals(21, Sar1(OBJ_42));
    150 assertEquals(0, Shr1Reversed(OBJ_42));
    151 assertEquals(0, Sar1Reversed(OBJ_42));
    152 
    153 assertEquals(6, Shr100(100), "100 >>> 100");
    154 assertEquals(6, Sar100(100), "100 >> 100");
    155 assertEquals(12, Shr100Reversed(99));
    156 assertEquals(12, Sar100Reversed(99));
    157 assertEquals(201326592, Shr100(SMI_MIN));
    158 assertEquals(-67108864, Sar100(SMI_MIN));
    159 assertEquals(100, Shr100Reversed(SMI_MIN));
    160 assertEquals(100, Sar100Reversed(SMI_MIN));
    161 assertEquals(2, Shr100(OBJ_42));
    162 assertEquals(2, Sar100(OBJ_42));
    163 assertEquals(0, Shr100Reversed(OBJ_42));
    164 assertEquals(0, Sar100Reversed(OBJ_42));
    165 
    166 
    167 function Xor1(x) {
    168   return x ^ 1;
    169 }
    170 
    171 function Xor100(x) {
    172   return x ^ 100;
    173 }
    174 
    175 function Xor1Reversed(x) {
    176   return 1 ^ x;
    177 }
    178 
    179 function Xor100Reversed(x) {
    180   return 100 ^ x;
    181 }
    182 
    183 
    184 assertEquals(0, Xor1(1));
    185 assertEquals(3, Xor1Reversed(2));
    186 assertEquals(SMI_MIN + 1, Xor1(SMI_MIN));
    187 assertEquals(SMI_MIN + 1, Xor1Reversed(SMI_MIN));
    188 assertEquals(43, Xor1(OBJ_42));
    189 assertEquals(43, Xor1Reversed(OBJ_42));
    190 
    191 assertEquals(0, Xor100(100));
    192 assertEquals(7, Xor100Reversed(99));
    193 assertEquals(-1073741724, Xor100(SMI_MIN));
    194 assertEquals(-1073741724, Xor100Reversed(SMI_MIN));
    195 assertEquals(78, Xor100(OBJ_42));
    196 assertEquals(78, Xor100Reversed(OBJ_42));
    197 
    198 var x = 0x23; var y = 0x35;
    199 assertEquals(0x16, x ^ y);
    200 
    201 
    202 // Bitwise not.
    203 var v = 0;
    204 assertEquals(-1, ~v);
    205 v = SMI_MIN;
    206 assertEquals(0x3fffffff, ~v, "~smimin");
    207 v = SMI_MAX;
    208 assertEquals(-0x40000000, ~v, "~smimax");
    209 
    210 // Overflowing ++ and --.
    211 v = SMI_MAX;
    212 v++;
    213 assertEquals(0x40000000, v, "smimax++");
    214 v = SMI_MIN;
    215 v--;
    216 assertEquals(-0x40000001, v, "smimin--");
    217 
    218 // Not actually Smi operations.
    219 // Check that relations on unary ops work.
    220 var v = -1.2;
    221 assertTrue(v == v);
    222 assertTrue(v === v);
    223 assertTrue(v <= v);
    224 assertTrue(v >= v);
    225 assertFalse(v < v);
    226 assertFalse(v > v);
    227 assertFalse(v != v);
    228 assertFalse(v !== v);
    229 
    230 // Right hand side of unary minus is overwritable.
    231 v = 1.5
    232 assertEquals(-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.
    236 var x1 = 0x10000000;
    237 var x2 = 0x40000002;
    238 var x3 = 0x40000000;
    239 assertEquals(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.
    243 x1 = 0x10000000
    244 x2 = 4
    245 x3 = 2
    246 assertEquals(0x40000000, x1 << (x2 - x3), "0x10000000<<2(2)");
    247 
    248 
    249 // Test shift operators on non-smi inputs, giving smi and non-smi results.
    250 function 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 
    641 testShiftNonSmis();
    642 
    643 function 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 
    667 intConversion();
    668 
    669 // Verify that we handle the (optimized) corner case of shifting by
    670 // zero even for non-smis.
    671 function shiftByZero(n) { return n << 0; }
    672 
    673 assertEquals(3, shiftByZero(3.1415));
    674