Index: src/interpreter/interpreter.cc |
diff --git a/src/interpreter/interpreter.cc b/src/interpreter/interpreter.cc |
index acc69c43967019bac0b29301ed753a55330c5c41..241e5f5606b81fbb4db65edd8c641cd4b12dda44 100644 |
--- a/src/interpreter/interpreter.cc |
+++ b/src/interpreter/interpreter.cc |
@@ -811,25 +811,98 @@ void Interpreter::DoMod(InterpreterAssembler* assembler) { |
DoBinaryOpWithFeedback<ModulusWithFeedbackStub>(assembler); |
} |
+void Interpreter::DoBitwiseBinaryOp(Token::Value bitwise_op, |
+ InterpreterAssembler* assembler) { |
+ Node* reg_index = __ BytecodeOperandReg(0); |
+ Node* lhs = __ LoadRegister(reg_index); |
+ Node* rhs = __ GetAccumulator(); |
+ Node* context = __ GetContext(); |
+ Node* slot_index = __ BytecodeOperandIdx(1); |
+ Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
+ |
+ InterpreterAssembler::Variable var_lhs_type_feedback( |
rmcilroy
2016/08/11 14:09:23
nit - this can just be Variable (without Interpret
epertoso
2016/08/11 14:18:05
Done.
|
+ assembler, MachineRepresentation::kWord32), |
+ var_rhs_type_feedback(assembler, MachineRepresentation::kWord32); |
+ Node* lhs_value = __ TruncateTaggedToWord32WithFeedback( |
+ context, lhs, &var_lhs_type_feedback); |
+ Node* rhs_value = __ TruncateTaggedToWord32WithFeedback( |
+ context, rhs, &var_rhs_type_feedback); |
+ Node* value = nullptr; |
rmcilroy
2016/08/11 14:09:23
Unused outside the switch - just declare in the sw
epertoso
2016/08/11 14:18:05
Done.
|
+ Node* result = nullptr; |
+ |
+ switch (bitwise_op) { |
+ case Token::BIT_OR: |
+ value = __ Word32Or(lhs_value, rhs_value); |
+ result = __ ChangeInt32ToTagged(value); |
+ break; |
+ case Token::BIT_AND: |
+ value = __ Word32And(lhs_value, rhs_value); |
+ result = __ ChangeInt32ToTagged(value); |
+ break; |
+ case Token::BIT_XOR: |
+ value = __ Word32Xor(lhs_value, rhs_value); |
+ result = __ ChangeInt32ToTagged(value); |
+ break; |
+ case Token::SHL: |
+ value = __ Word32Shl(lhs_value, |
+ __ Word32And(rhs_value, __ Int32Constant(0x1f))); |
+ result = __ ChangeInt32ToTagged(value); |
+ break; |
+ case Token::SHR: |
+ value = __ Word32Shr(lhs_value, |
+ __ Word32And(rhs_value, __ Int32Constant(0x1f))); |
+ result = __ ChangeUint32ToTagged(value); |
+ break; |
+ case Token::SAR: |
+ value = __ Word32Sar(lhs_value, |
+ __ Word32And(rhs_value, __ Int32Constant(0x1f))); |
+ result = __ ChangeInt32ToTagged(value); |
+ break; |
+ default: |
+ UNREACHABLE(); |
+ } |
+ |
+ Node* result_type = |
+ __ Select(__ WordIsSmi(result), |
+ __ Int32Constant(BinaryOperationFeedback::kSignedSmall), |
+ __ Int32Constant(BinaryOperationFeedback::kNumber)); |
+ |
+ if (FLAG_debug_code) { |
+ InterpreterAssembler::Label ok(assembler); |
rmcilroy
2016/08/11 14:09:23
nit - just Label
epertoso
2016/08/11 14:18:05
Done.
|
+ __ GotoIf(__ WordIsSmi(result), &ok); |
+ Node* result_map = __ LoadMap(result); |
+ __ AbortIfWordNotEqual(result_map, __ HeapNumberMapConstant(), |
+ kExpectedHeapNumber); |
+ __ Bind(&ok); |
+ } |
+ |
+ Node* input_feedback = |
+ __ Word32Or(var_lhs_type_feedback.value(), var_rhs_type_feedback.value()); |
+ __ UpdateFeedback(__ Word32Or(result_type, input_feedback), |
+ type_feedback_vector, slot_index); |
+ __ SetAccumulator(result); |
+ __ Dispatch(); |
+} |
+ |
// BitwiseOr <src> |
// |
// BitwiseOr register <src> to accumulator. |
void Interpreter::DoBitwiseOr(InterpreterAssembler* assembler) { |
- DoBinaryOp<BitwiseOrStub>(assembler); |
+ DoBitwiseBinaryOp(Token::BIT_OR, assembler); |
} |
// BitwiseXor <src> |
// |
// BitwiseXor register <src> to accumulator. |
void Interpreter::DoBitwiseXor(InterpreterAssembler* assembler) { |
- DoBinaryOp<BitwiseXorStub>(assembler); |
+ DoBitwiseBinaryOp(Token::BIT_XOR, assembler); |
} |
// BitwiseAnd <src> |
// |
// BitwiseAnd register <src> to accumulator. |
void Interpreter::DoBitwiseAnd(InterpreterAssembler* assembler) { |
- DoBinaryOp<BitwiseAndStub>(assembler); |
+ DoBitwiseBinaryOp(Token::BIT_AND, assembler); |
} |
// ShiftLeft <src> |
@@ -839,7 +912,7 @@ void Interpreter::DoBitwiseAnd(InterpreterAssembler* assembler) { |
// before the operation. 5 lsb bits from the accumulator are used as count |
// i.e. <src> << (accumulator & 0x1F). |
void Interpreter::DoShiftLeft(InterpreterAssembler* assembler) { |
- DoBinaryOp<ShiftLeftStub>(assembler); |
+ DoBitwiseBinaryOp(Token::SHL, assembler); |
} |
// ShiftRight <src> |
@@ -849,7 +922,7 @@ void Interpreter::DoShiftLeft(InterpreterAssembler* assembler) { |
// accumulator to uint32 before the operation. 5 lsb bits from the accumulator |
// are used as count i.e. <src> >> (accumulator & 0x1F). |
void Interpreter::DoShiftRight(InterpreterAssembler* assembler) { |
- DoBinaryOp<ShiftRightStub>(assembler); |
+ DoBitwiseBinaryOp(Token::SAR, assembler); |
} |
// ShiftRightLogical <src> |
@@ -859,7 +932,7 @@ void Interpreter::DoShiftRight(InterpreterAssembler* assembler) { |
// uint32 before the operation 5 lsb bits from the accumulator are used as |
// count i.e. <src> << (accumulator & 0x1F). |
void Interpreter::DoShiftRightLogical(InterpreterAssembler* assembler) { |
- DoBinaryOp<ShiftRightLogicalStub>(assembler); |
+ DoBitwiseBinaryOp(Token::SHR, assembler); |
} |
// AddSmi <imm> <reg> |