| 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());
|
|
|