Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(193)

Unified Diff: src/interpreter/interpreter.cc

Issue 2111923002: [interpreter] Introduce binary op bytecodes for Smi operand. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/interpreter/interpreter.h ('k') | test/cctest/interpreter/bytecode_expectations/ArrayLiterals.golden » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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());
« no previous file with comments | « src/interpreter/interpreter.h ('k') | test/cctest/interpreter/bytecode_expectations/ArrayLiterals.golden » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698