Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion common.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@

# Reset this number to 0 on major V8 upgrades.
# Increment by one for each non-official patch applied to deps/v8.
'v8_embedder_string': '-node.15',
'v8_embedder_string': '-node.16',

##### V8 defaults for Node.js #####

Expand Down
16 changes: 16 additions & 0 deletions deps/v8/src/compiler/backend/loong64/code-generator-loong64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1397,6 +1397,22 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
i.InputOperand(1), scratch);
break;
}
case kLoong64Add64_3: {
Register low = i.OutputRegister(0);
UseScratchRegisterScope temps(masm());
Register scratch = temps.Acquire();
__ Add_d(scratch, i.InputRegister(0), i.InputOperand(1));
if (instr->OutputCount() > 1) {
Register high = i.OutputRegister(1);
__ Sltu(high, scratch, i.InputRegister(0));
__ Add_d(low, scratch, i.InputOperand(2));
__ Sltu(scratch, low, scratch);
__ Add_d(high, high, scratch);
} else {
__ Add_d(low, scratch, i.InputOperand(2));
}
break;
}
case kLoong64Add128: {
UseScratchRegisterScope temps(masm());
Register scratch = temps.Acquire();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ namespace compiler {
V(Loong64Add_w) \
V(Loong64AddOvf_d) \
V(Loong64AddOvf_w) \
V(Loong64Add64_3) \
V(Loong64Add128) \
V(Loong64Sub_d) \
V(Loong64Sub_w) \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ class Loong64OperandGenerator final : public OperandGenerator {
return UseRegister(node);
}

InstructionOperand UseUniqueOperand(OpIndex node, InstructionCode opcode) {
if (CanBeImmediate(node, opcode)) {
return UseImmediate(node);
}
return UseUniqueRegister(node);
}

bool IsImmediateZero(OpIndex node) {
if (const ConstantOp* constant =
selector()->Get(node).TryCast<ConstantOp>()) {
Expand Down Expand Up @@ -1537,6 +1544,30 @@ void InstructionSelector::VisitUint64MulHigh(OpIndex node) {
VisitRRR(this, kLoong64Mulh_du, node);
}

void InstructionSelector::VisitUint64Add3WithCarry(OpIndex node) {
Loong64OperandGenerator g(this);
const auto& op = Get(node).Cast<Word64Add3Op>();

OptionalV<Word64> out_low = FindProjection(node, 0);
OptionalV<Word64> out_high = FindProjection(node, 1);

InstructionOperand inputs[3];
size_t input_count = 0;
inputs[input_count++] = g.UseRegister(op.first());
inputs[input_count++] = g.UseOperand(op.second(), kLoong64Add_d);
inputs[input_count++] = g.UseUniqueOperand(op.third(), kLoong64Add_d);

InstructionOperand outputs[2];
size_t output_count = 0;
outputs[output_count++] =
g.DefineAsRegister(out_low.valid() ? out_low.value() : node);
if (out_high.valid() && IsUsed(out_high.value())) {
outputs[output_count++] = g.DefineAsRegister(out_high.value());
}

Emit(kLoong64Add64_3, output_count, outputs, input_count, inputs);
}

void InstructionSelector::VisitInt64Mul(OpIndex node) {
Loong64OperandGenerator g(this);
const WordBinopOp& mul = Get(node).Cast<WordBinopOp>();
Expand Down
16 changes: 16 additions & 0 deletions deps/v8/src/compiler/backend/mips64/code-generator-mips64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1024,6 +1024,22 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ DaddOverflow(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1),
kScratchReg);
break;
case kMips64Add64_3: {
Register low = i.OutputRegister(0);
UseScratchRegisterScope temps(masm());
Register scratch = temps.Acquire();
__ Daddu(scratch, i.InputRegister(0), i.InputOperand(1));
if (instr->OutputCount() > 1) {
Register high = i.OutputRegister(1);
__ Sltu(high, scratch, i.InputRegister(0));
__ Daddu(low, scratch, i.InputOperand(2));
__ Sltu(scratch, low, scratch);
__ Daddu(high, high, scratch);
} else {
__ Daddu(low, scratch, i.InputOperand(2));
}
break;
}
case kMips64Add128: {
UseScratchRegisterScope temps(masm());
Register scratch = temps.Acquire();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace compiler {
V(Mips64Add) \
V(Mips64Dadd) \
V(Mips64DaddOvf) \
V(Mips64Add64_3) \
V(Mips64Add128) \
V(Mips64Sub) \
V(Mips64Dsub) \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kMips64MulHighU:
case kMips64Dadd:
case kMips64DaddOvf:
case kMips64Add64_3:
case kMips64Add128:
case kMips64Dclz:
case kMips64Dctz:
Expand Down
31 changes: 31 additions & 0 deletions deps/v8/src/compiler/backend/mips64/instruction-selector-mips64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ class Mips64OperandGenerator final : public OperandGenerator {
return UseRegister(node);
}

InstructionOperand UseUniqueOperand(OpIndex node, InstructionCode opcode) {
if (CanBeImmediate(node, opcode)) {
return UseImmediate(node);
}
return UseUniqueRegister(node);
}

// Use the zero register if the node has the immediate value zero, otherwise
// assign a register.
InstructionOperand UseRegisterOrImmediateZero(OpIndex node) {
Expand Down Expand Up @@ -763,6 +770,30 @@ void InstructionSelector::VisitUint64MulHigh(OpIndex node) {
VisitRRR(this, kMips64DMulHighU, node);
}

void InstructionSelector::VisitUint64Add3WithCarry(OpIndex node) {
Mips64OperandGenerator g(this);
const auto& op = Get(node).Cast<Word64Add3Op>();

OptionalV<Word64> out_low = FindProjection(node, 0);
OptionalV<Word64> out_high = FindProjection(node, 1);

InstructionOperand inputs[3];
size_t input_count = 0;
inputs[input_count++] = g.UseRegister(op.first());
inputs[input_count++] = g.UseOperand(op.second(), kMips64Dadd);
inputs[input_count++] = g.UseUniqueOperand(op.third(), kMips64Dadd);

InstructionOperand outputs[2];
size_t output_count = 0;
outputs[output_count++] =
g.DefineAsRegister(out_low.valid() ? out_low.value() : node);
if (out_high.valid() && IsUsed(out_high.value())) {
outputs[output_count++] = g.DefineAsRegister(out_high.value());
}

Emit(kMips64Add64_3, output_count, outputs, input_count, inputs);
}

void InstructionSelector::VisitInt64Mul(OpIndex node) {
// TODO(MIPS_dev): May could be optimized like in Turbofan.
VisitBinop(this, node, kMips64Dmul, true, kMips64Dmul);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1639,7 +1639,7 @@ class MachineOptimizationReducer : public Next {
}

// TODO(ryandiaz): implement on arm64
#ifdef V8_TARGET_ARCH_X64
#if defined(V8_TARGET_ARCH_X64) || defined(V8_TARGET_ARCH_LOONG64)
if (kind == Word64AddSub128BinopOp::Kind::kAdd) {
// add128(add128(x, 0, y, 0), z, 0) -> add3(x, y, z)
if (const Word64AddSub128BinopOp* nested = TryMatchAdd3(al, ah, bh)) {
Expand All @@ -1654,7 +1654,7 @@ class MachineOptimizationReducer : public Next {
// TODO(ryandiaz): sub128(sub128(x, 0, y, 0), z, 0) -> sub2(x, y, z)
// TODO(ryandiaz): sub128(x, 0, add128(y, 0, z, 0)) -> sub2(x, y, z)
}
#endif // V8_TARGET_ARCH_X64
#endif // defined(V8_TARGET_ARCH_X64) || defined(V8_TARGET_ARCH_LOONG64)
return Next::ReduceWord64AddSub128Binop(al, ah, bl, bh, kind);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2172,4 +2172,38 @@ TEST_F(TurboshaftInstructionSelectorTest, Word32EqualWithReadOnlyRoot) {
EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
}

TEST_F(TurboshaftInstructionSelectorTest, Word64Add3) {
StreamBuilder m(this, MachineType::Uint64(), MachineType::Uint64(),
MachineType::Uint64(), MachineType::Uint64());
V<Word64> p0 = m.Parameter<Word64>(0);
V<Word64> p1 = m.Parameter<Word64>(1);
V<Word64> p2 = m.Parameter<Word64>(2);
V<Word64Pair> res = m.Word64Add3(p0, p1, p2);
OpIndex low = m.Projection(res, 0);
OpIndex high = m.Projection(res, 1);
m.Return(m.Word64Add(low, high));
Stream s = m.Build();
ASSERT_EQ(2U, s.size());
EXPECT_EQ(kLoong64Add64_3, s[0]->arch_opcode());
EXPECT_EQ(kLoong64Add_d, s[1]->arch_opcode());
ASSERT_EQ(3U, s[0]->InputCount());
ASSERT_EQ(2U, s[0]->OutputCount());
}

TEST_F(TurboshaftInstructionSelectorTest, Word64Add3UnusedHigh) {
StreamBuilder m(this, MachineType::Uint64(), MachineType::Uint64(),
MachineType::Uint64(), MachineType::Uint64());
V<Word64> p0 = m.Parameter<Word64>(0);
V<Word64> p1 = m.Parameter<Word64>(1);
V<Word64> p2 = m.Parameter<Word64>(2);
V<Word64Pair> res = m.Word64Add3(p0, p1, p2);
OpIndex low = m.Projection(res, 0);
m.Return(low);
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
EXPECT_EQ(kLoong64Add64_3, s[0]->arch_opcode());
ASSERT_EQ(3U, s[0]->InputCount());
ASSERT_EQ(1U, s[0]->OutputCount());
}

} // namespace v8::internal::compiler::turboshaft
Original file line number Diff line number Diff line change
Expand Up @@ -2112,6 +2112,40 @@ TEST_F(TurboshaftInstructionSelectorTest, AtomicStoreWithWriteBarrier) {
RecordWriteMode::kValueIsAny);
}

TEST_F(TurboshaftInstructionSelectorTest, Word64Add3) {
StreamBuilder m(this, MachineType::Uint64(), MachineType::Uint64(),
MachineType::Uint64(), MachineType::Uint64());
V<Word64> p0 = m.Parameter<Word64>(0);
V<Word64> p1 = m.Parameter<Word64>(1);
V<Word64> p2 = m.Parameter<Word64>(2);
V<Word64Pair> res = m.Word64Add3(p0, p1, p2);
OpIndex low = m.Projection(res, 0);
OpIndex high = m.Projection(res, 1);
m.Return(m.Word64Add(low, high));
Stream s = m.Build();
ASSERT_EQ(2U, s.size());
EXPECT_EQ(kMips64Add64_3, s[0]->arch_opcode());
EXPECT_EQ(kMips64Dadd, s[1]->arch_opcode());
ASSERT_EQ(3U, s[0]->InputCount());
ASSERT_EQ(2U, s[0]->OutputCount());
}

TEST_F(TurboshaftInstructionSelectorTest, Word64Add3UnusedHigh) {
StreamBuilder m(this, MachineType::Uint64(), MachineType::Uint64(),
MachineType::Uint64(), MachineType::Uint64());
V<Word64> p0 = m.Parameter<Word64>(0);
V<Word64> p1 = m.Parameter<Word64>(1);
V<Word64> p2 = m.Parameter<Word64>(2);
V<Word64Pair> res = m.Word64Add3(p0, p1, p2);
OpIndex low = m.Projection(res, 0);
m.Return(low);
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
EXPECT_EQ(kMips64Add64_3, s[0]->arch_opcode());
ASSERT_EQ(3U, s[0]->InputCount());
ASSERT_EQ(1U, s[0]->OutputCount());
}

} // namespace turboshaft
} // namespace compiler
} // namespace internal
Expand Down
Loading