Commit 0bedf6f0 authored by bmeurer's avatar bmeurer Committed by Commit bot

[stubs] Introduce AddStub and SubtractStub.

This adds two new stubs, AddStub and SubtractStub, for the plus and the
minus operators, and hooks them up with TurboFan and Ignition.
Especially the addition case is very heavy and we might want to look
into splitting that up further into specialized stubs (similar to what
we did with ToNumberStub recently).

R=epertoso@chromium.org

Review URL: https://codereview.chromium.org/1823083002

Cr-Commit-Position: refs/heads/master@{#34994}
parent 890f3dd7
......@@ -206,6 +206,18 @@ Callable CodeFactory::RegExpExec(Isolate* isolate) {
return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
}
// static
Callable CodeFactory::Add(Isolate* isolate) {
AddStub stub(isolate);
return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
}
// static
Callable CodeFactory::Subtract(Isolate* isolate) {
SubtractStub stub(isolate);
return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
}
// static
Callable CodeFactory::LessThan(Isolate* isolate) {
LessThanStub stub(isolate);
......
......@@ -79,6 +79,8 @@ class CodeFactory final {
static Callable RegExpConstructResult(Isolate* isolate);
static Callable RegExpExec(Isolate* isolate);
static Callable Add(Isolate* isolate);
static Callable Subtract(Isolate* isolate);
static Callable LessThan(Isolate* isolate);
static Callable LessThanOrEqual(Isolate* isolate);
static Callable GreaterThan(Isolate* isolate);
......
......@@ -515,6 +515,540 @@ void StringLengthStub::GenerateAssembly(
assembler->Return(result);
}
void AddStub::GenerateAssembly(compiler::CodeStubAssembler* assembler) const {
typedef compiler::CodeStubAssembler::Label Label;
typedef compiler::Node Node;
typedef compiler::CodeStubAssembler::Variable Variable;
Node* context = assembler->Parameter(2);
// Shared entry for floating point addition.
Label do_fadd(assembler);
Variable var_fadd_lhs(assembler, MachineRepresentation::kFloat64),
var_fadd_rhs(assembler, MachineRepresentation::kFloat64);
// We might need to loop several times due to ToPrimitive, ToString and/or
// ToNumber conversions.
Variable var_lhs(assembler, MachineRepresentation::kTagged),
var_rhs(assembler, MachineRepresentation::kTagged);
Variable* loop_vars[2] = {&var_lhs, &var_rhs};
Label loop(assembler, 2, loop_vars);
var_lhs.Bind(assembler->Parameter(0));
var_rhs.Bind(assembler->Parameter(1));
assembler->Goto(&loop);
assembler->Bind(&loop);
{
// Load the current {lhs} and {rhs} values.
Node* lhs = var_lhs.value();
Node* rhs = var_rhs.value();
// Check if the {lhs} is a Smi or a HeapObject.
Label if_lhsissmi(assembler), if_lhsisnotsmi(assembler);
assembler->Branch(assembler->WordIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi);
assembler->Bind(&if_lhsissmi);
{
// Check if the {rhs} is also a Smi.
Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler);
assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi,
&if_rhsisnotsmi);
assembler->Bind(&if_rhsissmi);
{
// TODO(bmeurer): Properly fuse Int64AddWithOverflow on x64
Node* pair = assembler->SmiAddWithOverflow(lhs, rhs);
Node* result = assembler->Projection(0, pair);
Node* overflow = assembler->Projection(1, pair);
Label if_overflow(assembler), if_notoverflow(assembler);
assembler->Branch(overflow, &if_overflow, &if_notoverflow);
assembler->Bind(&if_overflow);
{
var_fadd_lhs.Bind(assembler->SmiToFloat64(lhs));
var_fadd_rhs.Bind(assembler->SmiToFloat64(rhs));
assembler->Goto(&do_fadd);
}
assembler->Bind(&if_notoverflow);
assembler->Return(result);
}
assembler->Bind(&if_rhsisnotsmi);
{
// Load the map of {rhs}.
Node* rhs_map = assembler->LoadObjectField(rhs, HeapObject::kMapOffset);
// Check if the {rhs} is a HeapNumber.
Label if_rhsisnumber(assembler),
if_rhsisnotnumber(assembler, Label::kDeferred);
Node* number_map = assembler->HeapNumberMapConstant();
assembler->Branch(assembler->WordEqual(rhs_map, number_map),
&if_rhsisnumber, &if_rhsisnotnumber);
assembler->Bind(&if_rhsisnumber);
{
var_fadd_lhs.Bind(assembler->SmiToFloat64(lhs));
var_fadd_rhs.Bind(assembler->LoadHeapNumberValue(rhs));
assembler->Goto(&do_fadd);
}
assembler->Bind(&if_rhsisnotnumber);
{
// Load the instance type of {rhs}.
Node* rhs_instance_type = assembler->LoadMapInstanceType(rhs_map);
// Check if the {rhs} is a String.
Label if_rhsisstring(assembler, Label::kDeferred),
if_rhsisnotstring(assembler, Label::kDeferred);
assembler->Branch(assembler->Int32LessThan(
rhs_instance_type,
assembler->Int32Constant(FIRST_NONSTRING_TYPE)),
&if_rhsisstring, &if_rhsisnotstring);
assembler->Bind(&if_rhsisstring);
{
// Convert {lhs}, which is a Smi, to a String and concatenate the
// resulting string with the String {rhs}.
Callable callable = CodeFactory::StringAdd(
assembler->isolate(), STRING_ADD_CONVERT_LEFT, NOT_TENURED);
assembler->TailCallStub(callable, context, lhs, rhs);
}
assembler->Bind(&if_rhsisnotstring);
{
// Check if {rhs} is a JSReceiver.
Label if_rhsisreceiver(assembler, Label::kDeferred),
if_rhsisnotreceiver(assembler, Label::kDeferred);
assembler->Branch(
assembler->Int32LessThanOrEqual(
assembler->Int32Constant(FIRST_JS_RECEIVER_TYPE),
rhs_instance_type),
&if_rhsisreceiver, &if_rhsisnotreceiver);
assembler->Bind(&if_rhsisreceiver);
{
// Convert {rhs} to a primitive first passing no hint.
// TODO(bmeurer): Hook up ToPrimitiveStub here, once it's there.
var_rhs.Bind(
assembler->CallRuntime(Runtime::kToPrimitive, context, rhs));
assembler->Goto(&loop);
}
assembler->Bind(&if_rhsisnotreceiver);
{
// Convert {rhs} to a Number first.
Callable callable =
CodeFactory::NonNumberToNumber(assembler->isolate());
var_rhs.Bind(assembler->CallStub(callable, context, rhs));
assembler->Goto(&loop);
}
}
}
}
}
assembler->Bind(&if_lhsisnotsmi);
{
// Load the map and instance type of {lhs}.
Node* lhs_instance_type = assembler->LoadInstanceType(lhs);
// Check if {lhs} is a String.
Label if_lhsisstring(assembler), if_lhsisnotstring(assembler);
assembler->Branch(assembler->Int32LessThan(
lhs_instance_type,
assembler->Int32Constant(FIRST_NONSTRING_TYPE)),
&if_lhsisstring, &if_lhsisnotstring);
assembler->Bind(&if_lhsisstring);
{
// Convert {rhs} to a String (using the sequence of ToPrimitive with
// no hint followed by ToString) and concatenate the strings.
Callable callable = CodeFactory::StringAdd(
assembler->isolate(), STRING_ADD_CONVERT_RIGHT, NOT_TENURED);
assembler->TailCallStub(callable, context, lhs, rhs);
}
assembler->Bind(&if_lhsisnotstring);
{
// Check if {rhs} is a Smi.
Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler);
assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi,
&if_rhsisnotsmi);
assembler->Bind(&if_rhsissmi);
{
// Check if {lhs} is a Number.
Label if_lhsisnumber(assembler),
if_lhsisnotnumber(assembler, Label::kDeferred);
assembler->Branch(assembler->Word32Equal(
lhs_instance_type,
assembler->Int32Constant(HEAP_NUMBER_TYPE)),
&if_lhsisnumber, &if_lhsisnotnumber);
assembler->Bind(&if_lhsisnumber);
{
// The {lhs} is a HeapNumber, the {rhs} is a Smi, just add them.
var_fadd_lhs.Bind(assembler->LoadHeapNumberValue(lhs));
var_fadd_rhs.Bind(assembler->SmiToFloat64(rhs));
assembler->Goto(&do_fadd);
}
assembler->Bind(&if_lhsisnotnumber);
{
// The {lhs} is neither a Number nor a String, and the {rhs} is a
// Smi.
Label if_lhsisreceiver(assembler, Label::kDeferred),
if_lhsisnotreceiver(assembler, Label::kDeferred);
assembler->Branch(
assembler->Int32LessThanOrEqual(
assembler->Int32Constant(FIRST_JS_RECEIVER_TYPE),
lhs_instance_type),
&if_lhsisreceiver, &if_lhsisnotreceiver);
assembler->Bind(&if_lhsisreceiver);
{
// Convert {lhs} to a primitive first passing no hint.
// TODO(bmeurer): Hook up ToPrimitiveStub here, once it's there.
var_lhs.Bind(
assembler->CallRuntime(Runtime::kToPrimitive, context, lhs));
assembler->Goto(&loop);
}
assembler->Bind(&if_lhsisnotreceiver);
{
// Convert {lhs} to a Number first.
Callable callable =
CodeFactory::NonNumberToNumber(assembler->isolate());
var_lhs.Bind(assembler->CallStub(callable, context, lhs));
assembler->Goto(&loop);
}
}
}
assembler->Bind(&if_rhsisnotsmi);
{
// Load the instance type of {rhs}.
Node* rhs_instance_type = assembler->LoadInstanceType(rhs);
// Check if {rhs} is a String.
Label if_rhsisstring(assembler), if_rhsisnotstring(assembler);
assembler->Branch(assembler->Int32LessThan(
rhs_instance_type,
assembler->Int32Constant(FIRST_NONSTRING_TYPE)),
&if_rhsisstring, &if_rhsisnotstring);
assembler->Bind(&if_rhsisstring);
{
// Convert {lhs} to a String (using the sequence of ToPrimitive with
// no hint followed by ToString) and concatenate the strings.
Callable callable = CodeFactory::StringAdd(
assembler->isolate(), STRING_ADD_CONVERT_LEFT, NOT_TENURED);
assembler->TailCallStub(callable, context, lhs, rhs);
}
assembler->Bind(&if_rhsisnotstring);
{
// Check if {lhs} is a HeapNumber.
Label if_lhsisnumber(assembler), if_lhsisnotnumber(assembler);
assembler->Branch(assembler->Word32Equal(
lhs_instance_type,
assembler->Int32Constant(HEAP_NUMBER_TYPE)),
&if_lhsisnumber, &if_lhsisnotnumber);
assembler->Bind(&if_lhsisnumber);
{
// Check if {rhs} is also a HeapNumber.
Label if_rhsisnumber(assembler),
if_rhsisnotnumber(assembler, Label::kDeferred);
assembler->Branch(assembler->Word32Equal(
rhs_instance_type,
assembler->Int32Constant(HEAP_NUMBER_TYPE)),
&if_rhsisnumber, &if_rhsisnotnumber);
assembler->Bind(&if_rhsisnumber);
{
// Perform a floating point addition.
var_fadd_lhs.Bind(assembler->LoadHeapNumberValue(lhs));
var_fadd_rhs.Bind(assembler->LoadHeapNumberValue(rhs));
assembler->Goto(&do_fadd);
}
assembler->Bind(&if_rhsisnotnumber);
{
// Check if {rhs} is a JSReceiver.
Label if_rhsisreceiver(assembler, Label::kDeferred),
if_rhsisnotreceiver(assembler, Label::kDeferred);
assembler->Branch(
assembler->Int32LessThanOrEqual(
assembler->Int32Constant(FIRST_JS_RECEIVER_TYPE),
rhs_instance_type),
&if_rhsisreceiver, &if_rhsisnotreceiver);
assembler->Bind(&if_rhsisreceiver);
{
// Convert {rhs} to a primitive first passing no hint.
// TODO(bmeurer): Hook up ToPrimitiveStub here too.
var_rhs.Bind(assembler->CallRuntime(Runtime::kToPrimitive,
context, rhs));
assembler->Goto(&loop);
}
assembler->Bind(&if_rhsisnotreceiver);
{
// Convert {rhs} to a Number first.
Callable callable =
CodeFactory::NonNumberToNumber(assembler->isolate());
var_rhs.Bind(assembler->CallStub(callable, context, rhs));
assembler->Goto(&loop);
}
}
}
assembler->Bind(&if_lhsisnotnumber);
{
// Check if {lhs} is a JSReceiver.
Label if_lhsisreceiver(assembler, Label::kDeferred),
if_lhsisnotreceiver(assembler);
assembler->Branch(
assembler->Int32LessThanOrEqual(
assembler->Int32Constant(FIRST_JS_RECEIVER_TYPE),
lhs_instance_type),
&if_lhsisreceiver, &if_lhsisnotreceiver);
assembler->Bind(&if_lhsisreceiver);
{
// Convert {lhs} to a primitive first passing no hint.
// TODO(bmeurer): Hook up ToPrimitiveStub here, once it's there.
var_lhs.Bind(assembler->CallRuntime(Runtime::kToPrimitive,
context, lhs));
assembler->Goto(&loop);
}
assembler->Bind(&if_lhsisnotreceiver);
{
// Check if {rhs} is a JSReceiver.
Label if_rhsisreceiver(assembler, Label::kDeferred),
if_rhsisnotreceiver(assembler, Label::kDeferred);
assembler->Branch(
assembler->Int32LessThanOrEqual(
assembler->Int32Constant(FIRST_JS_RECEIVER_TYPE),
rhs_instance_type),
&if_rhsisreceiver, &if_rhsisnotreceiver);
assembler->Bind(&if_rhsisreceiver);
{
// Convert {rhs} to a primitive first passing no hint.
// TODO(bmeurer): Hook up ToPrimitiveStub here too.
var_rhs.Bind(assembler->CallRuntime(Runtime::kToPrimitive,
context, rhs));
assembler->Goto(&loop);
}
assembler->Bind(&if_rhsisnotreceiver);
{
// Convert {lhs} to a Number first.
Callable callable =
CodeFactory::NonNumberToNumber(assembler->isolate());
var_lhs.Bind(assembler->CallStub(callable, context, lhs));
assembler->Goto(&loop);
}
}
}
}
}
}
}
}
assembler->Bind(&do_fadd);
{
Node* lhs_value = var_fadd_lhs.value();
Node* rhs_value = var_fadd_rhs.value();
Node* value = assembler->Float64Add(lhs_value, rhs_value);
// TODO(bmeurer): Introduce a ChangeFloat64ToTagged.
Node* result = assembler->Allocate(HeapNumber::kSize,
compiler::CodeStubAssembler::kNone);
assembler->StoreMapNoWriteBarrier(result,
assembler->HeapNumberMapConstant());
assembler->StoreHeapNumberValue(result, value);
assembler->Return(result);
}
}
void SubtractStub::GenerateAssembly(
compiler::CodeStubAssembler* assembler) const {
typedef compiler::CodeStubAssembler::Label Label;
typedef compiler::Node Node;
typedef compiler::CodeStubAssembler::Variable Variable;
Node* context = assembler->Parameter(2);
// Shared entry for floating point subtraction.
Label do_fsub(assembler);
Variable var_fsub_lhs(assembler, MachineRepresentation::kFloat64),
var_fsub_rhs(assembler, MachineRepresentation::kFloat64);
// We might need to loop several times due to ToPrimitive and/or ToNumber
// conversions.
Variable var_lhs(assembler, MachineRepresentation::kTagged),
var_rhs(assembler, MachineRepresentation::kTagged);
Variable* loop_vars[2] = {&var_lhs, &var_rhs};
Label loop(assembler, 2, loop_vars);
var_lhs.Bind(assembler->Parameter(0));
var_rhs.Bind(assembler->Parameter(1));
assembler->Goto(&loop);
assembler->Bind(&loop);
{
// Load the current {lhs} and {rhs} values.
Node* lhs = var_lhs.value();
Node* rhs = var_rhs.value();
// Check if the {lhs} is a Smi or a HeapObject.
Label if_lhsissmi(assembler), if_lhsisnotsmi(assembler);
assembler->Branch(assembler->WordIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi);
assembler->Bind(&if_lhsissmi);
{
// Check if the {rhs} is also a Smi.
Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler);
assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi,
&if_rhsisnotsmi);
assembler->Bind(&if_rhsissmi);
{
// Try a fast Smi subtraction first.
Node* pair = assembler->SmiSubWithOverflow(lhs, rhs);
Node* result = assembler->Projection(0, pair);
Node* overflow = assembler->Projection(1, pair);
// Check if the Smi subtraction overflowed.
Label if_overflow(assembler), if_notoverflow(assembler);
assembler->Branch(overflow, &if_overflow, &if_notoverflow);
assembler->Bind(&if_overflow);
{
// The result doesn't fit into Smi range.
var_fsub_lhs.Bind(assembler->SmiToFloat64(lhs));
var_fsub_rhs.Bind(assembler->SmiToFloat64(rhs));
assembler->Goto(&do_fsub);
}
assembler->Bind(&if_notoverflow);
assembler->Return(result);
}
assembler->Bind(&if_rhsisnotsmi);
{
// Load the map of the {rhs}.
Node* rhs_map = assembler->LoadMap(rhs);
// Check if {rhs} is a HeapNumber.
Label if_rhsisnumber(assembler),
if_rhsisnotnumber(assembler, Label::kDeferred);
Node* number_map = assembler->HeapNumberMapConstant();
assembler->Branch(assembler->WordEqual(rhs_map, number_map),
&if_rhsisnumber, &if_rhsisnotnumber);
assembler->Bind(&if_rhsisnumber);
{
// Perform a floating point subtraction.
var_fsub_lhs.Bind(assembler->SmiToFloat64(lhs));
var_fsub_rhs.Bind(assembler->LoadHeapNumberValue(rhs));
assembler->Goto(&do_fsub);
}
assembler->Bind(&if_rhsisnotnumber);
{
// Convert the {rhs} to a Number first.
Callable callable = CodeFactory::NonNumberToNumber(isolate());
var_rhs.Bind(assembler->CallStub(callable, context, rhs));
assembler->Goto(&loop);
}
}
}
assembler->Bind(&if_lhsisnotsmi);
{
// Load the map of the {lhs}.
Node* lhs_map = assembler->LoadMap(lhs);
// Check if the {lhs} is a HeapNumber.
Label if_lhsisnumber(assembler),
if_lhsisnotnumber(assembler, Label::kDeferred);
Node* number_map = assembler->HeapNumberMapConstant();
assembler->Branch(assembler->WordEqual(lhs_map, number_map),
&if_lhsisnumber, &if_lhsisnotnumber);
assembler->Bind(&if_lhsisnumber);
{
// Check if the {rhs} is a Smi.
Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler);
assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi,
&if_rhsisnotsmi);
assembler->Bind(&if_rhsissmi);
{
// Perform a floating point subtraction.
var_fsub_lhs.Bind(assembler->LoadHeapNumberValue(lhs));
var_fsub_rhs.Bind(assembler->SmiToFloat64(rhs));
assembler->Goto(&do_fsub);
}
assembler->Bind(&if_rhsisnotsmi);
{
// Load the map of the {rhs}.
Node* rhs_map = assembler->LoadMap(rhs);
// Check if the {rhs} is a HeapNumber.
Label if_rhsisnumber(assembler),
if_rhsisnotnumber(assembler, Label::kDeferred);
assembler->Branch(assembler->WordEqual(rhs_map, number_map),
&if_rhsisnumber, &if_rhsisnotnumber);
assembler->Bind(&if_rhsisnumber);
{
// Perform a floating point subtraction.
var_fsub_lhs.Bind(assembler->LoadHeapNumberValue(lhs));
var_fsub_rhs.Bind(assembler->LoadHeapNumberValue(rhs));
assembler->Goto(&do_fsub);
}
assembler->Bind(&if_rhsisnotnumber);
{
// Convert the {rhs} to a Number first.
Callable callable = CodeFactory::NonNumberToNumber(isolate());
var_rhs.Bind(assembler->CallStub(callable, context, rhs));
assembler->Goto(&loop);
}
}
}
assembler->Bind(&if_lhsisnotnumber);
{
// Convert the {lhs} to a Number first.
Callable callable = CodeFactory::NonNumberToNumber(isolate());
var_lhs.Bind(assembler->CallStub(callable, context, lhs));
assembler->Goto(&loop);
}
}
}
assembler->Bind(&do_fsub);
{
Node* lhs_value = var_fsub_lhs.value();
Node* rhs_value = var_fsub_rhs.value();
Node* value = assembler->Float64Sub(lhs_value, rhs_value);
// TODO(bmeurer): Introduce a ChangeFloat64ToTagged.
Node* result = assembler->Allocate(HeapNumber::kSize,
compiler::CodeStubAssembler::kNone);
assembler->StoreMapNoWriteBarrier(result,
assembler->HeapNumberMapConstant());
assembler->StoreHeapNumberValue(result, value);
assembler->Return(result);
}
}
namespace {
enum RelationalComparisonMode {
......
......@@ -111,6 +111,8 @@ namespace internal {
V(AllocateUint8x16) \
V(AllocateBool8x16) \
V(StringLength) \
V(Add) \
V(Subtract) \
V(LessThan) \
V(LessThanOrEqual) \
V(GreaterThan) \
......@@ -667,6 +669,22 @@ class StringLengthStub : public TurboFanCodeStub {
DEFINE_TURBOFAN_CODE_STUB(StringLength, TurboFanCodeStub);
};
class AddStub final : public TurboFanCodeStub {
public:
explicit AddStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
DEFINE_TURBOFAN_CODE_STUB(Add, TurboFanCodeStub);
};
class SubtractStub final : public TurboFanCodeStub {
public:
explicit SubtractStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
DEFINE_TURBOFAN_CODE_STUB(Subtract, TurboFanCodeStub);
};
class LessThanStub final : public TurboFanCodeStub {
public:
explicit LessThanStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
......
......@@ -175,6 +175,16 @@ Node* CodeStubAssembler::SmiToFloat64(Node* value) {
Node* CodeStubAssembler::SmiAdd(Node* a, Node* b) { return IntPtrAdd(a, b); }
Node* CodeStubAssembler::SmiAddWithOverflow(Node* a, Node* b) {
return IntPtrAddWithOverflow(a, b);
}
Node* CodeStubAssembler::SmiSub(Node* a, Node* b) { return IntPtrSub(a, b); }
Node* CodeStubAssembler::SmiSubWithOverflow(Node* a, Node* b) {
return IntPtrSubWithOverflow(a, b);
}
Node* CodeStubAssembler::SmiEqual(Node* a, Node* b) { return WordEqual(a, b); }
Node* CodeStubAssembler::SmiLessThan(Node* a, Node* b) {
......
......@@ -63,8 +63,12 @@ class Schedule;
#define CODE_STUB_ASSEMBLER_BINARY_OP_LIST(V) \
CODE_STUB_ASSEMBLER_COMPARE_BINARY_OP_LIST(V) \
V(Float64Add) \
V(Float64Sub) \
V(IntPtrAdd) \
V(IntPtrAddWithOverflow) \
V(IntPtrSub) \
V(IntPtrSubWithOverflow) \
V(Int32Add) \
V(Int32Sub) \
V(Int32Mul) \
......@@ -263,6 +267,9 @@ class CodeStubAssembler {
// Smi operations.
Node* SmiAdd(Node* a, Node* b);
Node* SmiAddWithOverflow(Node* a, Node* b);
Node* SmiSub(Node* a, Node* b);
Node* SmiSubWithOverflow(Node* a, Node* b);
Node* SmiEqual(Node* a, Node* b);
Node* SmiLessThan(Node* a, Node* b);
Node* SmiLessThanOrEqual(Node* a, Node* b);
......
......@@ -76,8 +76,6 @@ REPLACE_BINARY_OP_IC_CALL(JSBitwiseAnd, Token::BIT_AND)
REPLACE_BINARY_OP_IC_CALL(JSShiftLeft, Token::SHL)
REPLACE_BINARY_OP_IC_CALL(JSShiftRight, Token::SAR)
REPLACE_BINARY_OP_IC_CALL(JSShiftRightLogical, Token::SHR)
REPLACE_BINARY_OP_IC_CALL(JSAdd, Token::ADD)
REPLACE_BINARY_OP_IC_CALL(JSSubtract, Token::SUB)
REPLACE_BINARY_OP_IC_CALL(JSMultiply, Token::MUL)
REPLACE_BINARY_OP_IC_CALL(JSDivide, Token::DIV)
REPLACE_BINARY_OP_IC_CALL(JSModulus, Token::MOD)
......@@ -98,6 +96,8 @@ REPLACE_RUNTIME_CALL(JSConvertReceiver, Runtime::kConvertReceiver)
Callable callable = CodeFactory::Name(isolate()); \
ReplaceWithStubCall(node, callable, flags); \
}
REPLACE_STUB_CALL(Add)
REPLACE_STUB_CALL(Subtract)
REPLACE_STUB_CALL(LessThan)
REPLACE_STUB_CALL(LessThanOrEqual)
REPLACE_STUB_CALL(GreaterThan)
......
......@@ -347,7 +347,9 @@ class RawMachineAssembler {
}
INTPTR_BINOP(Int, Add);
INTPTR_BINOP(Int, AddWithOverflow);
INTPTR_BINOP(Int, Sub);
INTPTR_BINOP(Int, SubWithOverflow);
INTPTR_BINOP(Int, LessThan);
INTPTR_BINOP(Int, LessThanOrEqual);
INTPTR_BINOP(Word, Equal);
......
......@@ -650,7 +650,7 @@ void Interpreter::DoBinaryOp(Runtime::FunctionId function_id,
//
// Add register <src> to accumulator.
void Interpreter::DoAdd(InterpreterAssembler* assembler) {
DoBinaryOp(Runtime::kAdd, assembler);
DoBinaryOp(CodeFactory::Add(isolate_), assembler);
}
......@@ -658,7 +658,7 @@ void Interpreter::DoAdd(InterpreterAssembler* assembler) {
//
// Subtract register <src> from accumulator.
void Interpreter::DoSub(InterpreterAssembler* assembler) {
DoBinaryOp(Runtime::kSubtract, assembler);
DoBinaryOp(CodeFactory::Subtract(isolate_), assembler);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment