Index: src/x64/codegen-x64.cc |
=================================================================== |
--- src/x64/codegen-x64.cc (revision 3862) |
+++ src/x64/codegen-x64.cc (working copy) |
@@ -5187,15 +5187,15 @@ |
} |
// Get number type of left and right sub-expressions. |
- bool only_numbers = left.is_number() && right.is_number(); |
- bool only_smis = left.is_smi() && right.is_smi(); |
+ NumberInfo::Type operands_type = |
+ NumberInfo::Combine(left.number_info(), right.number_info()); |
Result answer; |
if (left_is_non_smi_constant || right_is_non_smi_constant) { |
GenericBinaryOpStub stub(op, |
overwrite_mode, |
NO_SMI_CODE_IN_STUB, |
- only_numbers); |
+ operands_type); |
answer = stub.GenerateCall(masm_, frame_, &left, &right); |
} else if (right_is_smi_constant) { |
answer = ConstantSmiBinaryOperation(op, &left, right.handle(), |
@@ -5215,50 +5215,59 @@ |
GenericBinaryOpStub stub(op, |
overwrite_mode, |
NO_GENERIC_BINARY_FLAGS, |
- only_numbers); |
+ operands_type); |
answer = stub.GenerateCall(masm_, frame_, &left, &right); |
} |
} |
// Set NumberInfo of result according to the operation performed. |
- NumberInfo::Type info = NumberInfo::kUnknown; |
+ // We rely on the fact that smis have a 32 bit payload on x64. |
+ ASSERT(kSmiValueSize == 32); |
+ NumberInfo::Type result_type = NumberInfo::kUnknown; |
switch (op) { |
case Token::COMMA: |
- info = right.number_info(); |
+ result_type = right.number_info(); |
break; |
case Token::OR: |
case Token::AND: |
- // Could be anything. Check inputs. |
- if (only_numbers) |
- info = NumberInfo::kNumber; |
+ // Result type can be either of the two input types. |
+ result_type = operands_type; |
break; |
case Token::BIT_OR: |
case Token::BIT_XOR: |
case Token::BIT_AND: |
+ // Result is always a smi. |
+ result_type = NumberInfo::kSmi; |
+ break; |
case Token::SAR: |
+ case Token::SHL: |
+ // Result is always a smi. |
+ result_type = NumberInfo::kSmi; |
+ break; |
case Token::SHR: |
- // TODO(fsc): Make use of the fact that smis are 32 bits on x64. |
- info = only_smis ? NumberInfo::kSmi : NumberInfo::kNumber; |
+ // Result of x >>> y is always a smi if y >= 1, otherwise a number. |
+ result_type = (right.is_constant() && right.handle()->IsSmi() |
+ && Smi::cast(*right.handle())->value() >= 1) |
+ ? NumberInfo::kSmi |
+ : NumberInfo::kNumber; |
break; |
- case Token::SHL: |
- info = NumberInfo::kNumber; |
- break; |
case Token::ADD: |
- // Could be strings or numbers. Check types of inputs. |
- if (only_numbers) { |
- info = NumberInfo::kNumber; |
- } |
+ // Result could be a string or a number. Check types of inputs. |
+ result_type = NumberInfo::IsNumber(operands_type) |
+ ? NumberInfo::kNumber |
+ : NumberInfo::kUnknown; |
break; |
case Token::SUB: |
case Token::MUL: |
case Token::DIV: |
case Token::MOD: |
- info = NumberInfo::kNumber; |
+ // Result is always a number. |
+ result_type = NumberInfo::kNumber; |
break; |
default: |
UNREACHABLE(); |
} |
- answer.set_number_info(info); |
+ answer.set_number_info(result_type); |
frame_->Push(&answer); |
} |
@@ -8154,7 +8163,7 @@ |
args_in_registers_ ? "RegArgs" : "StackArgs", |
args_reversed_ ? "_R" : "", |
use_sse3_ ? "SSE3" : "SSE2", |
- only_numbers_in_stub_ ? "_OnlyNumbers" : ""); |
+ NumberInfo::ToString(operands_type_)); |
return name_; |
} |
@@ -8478,7 +8487,7 @@ |
case Token::DIV: { |
// rax: y |
// rdx: x |
- if (only_numbers_in_stub_) { |
+ if (NumberInfo::IsNumber(operands_type_)) { |
if (FLAG_debug_code) { |
// Assert at runtime that inputs are only numbers. |
__ AbortIfNotNumber(rdx, "GenericBinaryOpStub operand not a number."); |