| Index: src/ia32/codegen-ia32.cc
|
| ===================================================================
|
| --- src/ia32/codegen-ia32.cc (revision 4470)
|
| +++ src/ia32/codegen-ia32.cc (working copy)
|
| @@ -1180,16 +1180,23 @@
|
| case Token::SAR:
|
| if (left.is_smi()) return TypeInfo::Smi();
|
| // Result is a smi if we shift by a constant >= 1, otherwise an integer32.
|
| + // Shift amount is masked with 0x1F (ECMA standard 11.7.2).
|
| return (right.is_constant() && right.handle()->IsSmi()
|
| - && Smi::cast(*right.handle())->value() >= 1)
|
| + && (Smi::cast(*right.handle())->value() & 0x1F) >= 1)
|
| ? TypeInfo::Smi()
|
| : TypeInfo::Integer32();
|
| case Token::SHR:
|
| - // Result is a smi if we shift by a constant >= 2, otherwise an integer32.
|
| - return (right.is_constant() && right.handle()->IsSmi()
|
| - && Smi::cast(*right.handle())->value() >= 2)
|
| - ? TypeInfo::Smi()
|
| - : TypeInfo::Integer32();
|
| + // Result is a smi if we shift by a constant >= 2, an integer32 if
|
| + // we shift by 1, and an unsigned 32-bit integer if we shift by 0.
|
| + if (right.is_constant() && right.handle()->IsSmi()) {
|
| + int shift_amount = Smi::cast(*right.handle())->value() & 0x1F;
|
| + if (shift_amount > 1) {
|
| + return TypeInfo::Smi();
|
| + } else if (shift_amount > 0) {
|
| + return TypeInfo::Integer32();
|
| + }
|
| + }
|
| + return TypeInfo::Number();
|
| case Token::ADD:
|
| if (operands_type.IsSmi()) {
|
| // The Integer32 range is big enough to take the sum of any two Smis.
|
|
|