Index: src/interpreter/interpreter.cc |
diff --git a/src/interpreter/interpreter.cc b/src/interpreter/interpreter.cc |
index 227bef538fafff8487362d8ff4af26aaba6ff7a4..1d12bfbc17c838bf50af90056852489f2aa7e3e0 100644 |
--- a/src/interpreter/interpreter.cc |
+++ b/src/interpreter/interpreter.cc |
@@ -836,6 +836,174 @@ void Interpreter::DoShiftRightLogical(InterpreterAssembler* assembler) { |
DoBinaryOp<ShiftRightLogicalStub>(assembler); |
} |
+// AddSmi <imm> <reg> |
+// |
+// Adds an immediate value <imm> to register <reg>. For this |
+// operation <reg> is the lhs operand and <imm> is the <rhs> operand. |
+void Interpreter::DoAddSmi(InterpreterAssembler* assembler) { |
+ Variable var_result(assembler, MachineRepresentation::kTagged); |
+ Label fastpath(assembler), slowpath(assembler, Label::kDeferred), |
+ end(assembler); |
+ |
+ Node* reg_index = __ BytecodeOperandReg(1); |
+ Node* left = __ LoadRegister(reg_index); |
+ Node* raw_int = __ BytecodeOperandImm(0); |
+ Node* right = __ SmiTag(raw_int); |
+ |
+ // {right} is known to be a Smi. |
+ // Check if the {left} is a Smi take the fast path. |
+ __ BranchIf(__ WordIsSmi(left), &fastpath, &slowpath); |
+ __ Bind(&fastpath); |
+ { |
+ // Try fast Smi addition first. |
+ Node* pair = __ SmiAddWithOverflow(left, right); |
+ Node* overflow = __ Projection(1, pair); |
+ |
+ // Check if the Smi additon overflowed. |
+ Label if_notoverflow(assembler); |
+ __ BranchIf(overflow, &slowpath, &if_notoverflow); |
+ __ Bind(&if_notoverflow); |
+ { |
+ var_result.Bind(__ Projection(0, pair)); |
+ __ Goto(&end); |
+ } |
+ } |
+ __ Bind(&slowpath); |
+ { |
+ Node* context = __ GetContext(); |
+ Callable callable = CodeFactory::Add(__ isolate()); |
+ var_result.Bind(__ CallStub(callable, context, left, right)); |
+ __ Goto(&end); |
+ } |
+ __ Bind(&end); |
+ { |
+ __ SetAccumulator(var_result.value()); |
+ __ Dispatch(); |
+ } |
+} |
+ |
+// SubSmi <imm> <reg> |
+// |
+// Subtracts an immediate value <imm> to register <reg>. For this |
+// operation <reg> is the lhs operand and <imm> is the rhs operand. |
+void Interpreter::DoSubSmi(InterpreterAssembler* assembler) { |
+ Variable var_result(assembler, MachineRepresentation::kTagged); |
+ Label fastpath(assembler), slowpath(assembler, Label::kDeferred), |
+ end(assembler); |
+ |
+ Node* reg_index = __ BytecodeOperandReg(1); |
+ Node* left = __ LoadRegister(reg_index); |
+ Node* raw_int = __ BytecodeOperandImm(0); |
+ Node* right = __ SmiTag(raw_int); |
+ |
+ // {right} is known to be a Smi. |
+ // Check if the {left} is a Smi take the fast path. |
+ __ BranchIf(__ WordIsSmi(left), &fastpath, &slowpath); |
+ __ Bind(&fastpath); |
+ { |
+ // Try fast Smi subtraction first. |
+ Node* pair = __ SmiSubWithOverflow(left, right); |
+ Node* overflow = __ Projection(1, pair); |
+ |
+ // Check if the Smi subtraction overflowed. |
+ Label if_notoverflow(assembler); |
+ __ BranchIf(overflow, &slowpath, &if_notoverflow); |
+ __ Bind(&if_notoverflow); |
+ { |
+ var_result.Bind(__ Projection(0, pair)); |
+ __ Goto(&end); |
+ } |
+ } |
+ __ Bind(&slowpath); |
+ { |
+ Node* context = __ GetContext(); |
+ Callable callable = CodeFactory::Subtract(__ isolate()); |
+ var_result.Bind(__ CallStub(callable, context, left, right)); |
+ __ Goto(&end); |
+ } |
+ __ Bind(&end); |
+ { |
+ __ SetAccumulator(var_result.value()); |
+ __ Dispatch(); |
+ } |
+} |
+ |
+// BitwiseOr <imm> <reg> |
+// |
+// BitwiseOr <reg> with <imm>. For this operation <reg> is the lhs |
+// operand and <imm> is the rhs operand. |
+void Interpreter::DoBitwiseOrSmi(InterpreterAssembler* assembler) { |
+ Node* reg_index = __ BytecodeOperandReg(1); |
+ Node* left = __ LoadRegister(reg_index); |
+ Node* raw_int = __ BytecodeOperandImm(0); |
+ Node* right = __ SmiTag(raw_int); |
+ Node* context = __ GetContext(); |
+ Node* lhs_value = __ TruncateTaggedToWord32(context, left); |
+ Node* rhs_value = __ SmiToWord32(right); |
+ Node* value = __ Word32Or(lhs_value, rhs_value); |
+ Node* result = __ ChangeInt32ToTagged(value); |
+ __ SetAccumulator(result); |
+ __ Dispatch(); |
+} |
+ |
+// BitwiseAnd <imm> <reg> |
+// |
+// BitwiseAnd <reg> with <imm>. For this operation <reg> is the lhs |
+// operand and <imm> is the rhs operand. |
+void Interpreter::DoBitwiseAndSmi(InterpreterAssembler* assembler) { |
+ Node* reg_index = __ BytecodeOperandReg(1); |
+ Node* left = __ LoadRegister(reg_index); |
+ Node* raw_int = __ BytecodeOperandImm(0); |
+ Node* right = __ SmiTag(raw_int); |
+ Node* context = __ GetContext(); |
+ Node* lhs_value = __ TruncateTaggedToWord32(context, left); |
+ Node* rhs_value = __ SmiToWord32(right); |
+ Node* value = __ Word32And(lhs_value, rhs_value); |
+ Node* result = __ ChangeInt32ToTagged(value); |
+ __ SetAccumulator(result); |
+ __ Dispatch(); |
+} |
+ |
+// ShiftLeftSmi <imm> <reg> |
+// |
+// Left shifts register <src> by the count specified in <imm>. |
+// Register <src> is converted to an int32 before the operation. The 5 |
+// lsb bits from <imm> are used as count i.e. <src> << (<imm> & 0x1F). |
+void Interpreter::DoShiftLeftSmi(InterpreterAssembler* assembler) { |
+ Node* reg_index = __ BytecodeOperandReg(1); |
+ Node* left = __ LoadRegister(reg_index); |
+ Node* raw_int = __ BytecodeOperandImm(0); |
+ Node* right = __ SmiTag(raw_int); |
+ Node* context = __ GetContext(); |
+ Node* lhs_value = __ TruncateTaggedToWord32(context, left); |
+ Node* rhs_value = __ SmiToWord32(right); |
+ Node* shift_count = __ Word32And(rhs_value, __ Int32Constant(0x1f)); |
+ Node* value = __ Word32Shl(lhs_value, shift_count); |
+ Node* result = __ ChangeInt32ToTagged(value); |
+ __ SetAccumulator(result); |
+ __ Dispatch(); |
+} |
+ |
+// ShiftRightSmi <imm> <reg> |
+// |
+// Right shifts register <src> by the count specified in <imm>. |
+// Register <src> is converted to an int32 before the operation. The 5 |
+// lsb bits from <imm> are used as count i.e. <src> << (<imm> & 0x1F). |
+void Interpreter::DoShiftRightSmi(InterpreterAssembler* assembler) { |
+ Node* reg_index = __ BytecodeOperandReg(1); |
+ Node* left = __ LoadRegister(reg_index); |
+ Node* raw_int = __ BytecodeOperandImm(0); |
+ Node* right = __ SmiTag(raw_int); |
+ Node* context = __ GetContext(); |
+ Node* lhs_value = __ TruncateTaggedToWord32(context, left); |
+ Node* rhs_value = __ SmiToWord32(right); |
+ Node* shift_count = __ Word32And(rhs_value, __ Int32Constant(0x1f)); |
+ Node* value = __ Word32Sar(lhs_value, shift_count); |
+ Node* result = __ ChangeInt32ToTagged(value); |
+ __ SetAccumulator(result); |
+ __ Dispatch(); |
+} |
+ |
void Interpreter::DoUnaryOp(Callable callable, |
InterpreterAssembler* assembler) { |
Node* target = __ HeapConstant(callable.code()); |