Skip to content
Open
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 @@ -40,7 +40,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.20',
'v8_embedder_string': '-node.21',

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

Expand Down
15 changes: 15 additions & 0 deletions deps/v8/src/codegen/loong64/macro-assembler-loong64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3140,6 +3140,21 @@ void MacroAssembler::TruncateDoubleToI(Isolate* isolate, Zone* zone,
bind(&done);
}

void MacroAssembler::SelectWord(Register result, Register cond, Register v_true,
Register v_false) {
if (v_false == zero_reg) {
maskeqz(result, v_true, cond);
} else if (v_true == zero_reg) {
masknez(result, v_false, cond);
} else {
UseScratchRegisterScope temps(this);
Register scratch = temps.Acquire();
maskeqz(scratch, v_true, cond);
masknez(result, v_false, cond);
or_(result, scratch, result);
}
}

void MacroAssembler::CompareWord(Condition cond, Register dst, Register lhs,
const Operand& rhs) {
switch (cond) {
Expand Down
4 changes: 4 additions & 0 deletions deps/v8/src/codegen/loong64/macro-assembler-loong64.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
// Print a message to stdout and abort execution.
void Abort(AbortReason msg);

// Select v_true if cond is non-zero, otherwise select v_false.
void SelectWord(Register result, Register cond, Register v_true,
Register v_false);

void CompareWord(Condition cond, Register dst, Register lhs,
const Operand& rhs);
void Branch(Label* label, bool need_link = false);
Expand Down
181 changes: 140 additions & 41 deletions deps/v8/src/compiler/backend/loong64/code-generator-loong64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1363,10 +1363,14 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kLoong64Sub_d:
__ Sub_d(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
break;
case kLoong64SubOvf_d:
case kLoong64SubOvf_d: {
UseScratchRegisterScope temps(masm());
DCHECK(temps.hasAvailable());
temps.Exclude(t8);
__ SubOverflow_d(i.OutputRegister(), i.InputRegister(0),
i.InputOperand(1), t8);
break;
}
case kLoong64Mul_w:
__ Mul_w(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
break;
Expand Down Expand Up @@ -4591,7 +4595,7 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
}
return;
} else {
PrintF("AssembleArchBranch Unimplemented arch_opcode is : %d\n",
PrintF("AssembleArchBoolean Unimplemented arch_opcode is : %d\n",
instr->arch_opcode());
TRACE("UNIMPLEMENTED code_generator_loong64: %s at line %d\n", __FUNCTION__,
__LINE__);
Expand Down Expand Up @@ -4646,56 +4650,49 @@ void CodeGenerator::AssembleArchSelect(Instruction* instr,
size_t output_index = instr->OutputCount() - 1;
// We don't know how many inputs were consumed by the condition, so we have to
// calculate the indices of the last two inputs.
DCHECK_GE(instr->InputCount(), 4);
size_t true_value_index = instr->InputCount() - 2;
size_t false_value_index = instr->InputCount() - 1;
Register result = i.OutputRegister(output_index);
Register v_true = i.InputOrZeroRegister(true_value_index);
Register v_false = i.InputOrZeroRegister(false_value_index);

DCHECK(
LocationOperand::cast(instr->OutputAt(output_index))->representation() ==
MachineRepresentation::kWord64);

if (instr->arch_opcode() == kLoong64Tst) {
DCHECK_GE(instr->InputCount(), 4);
Condition cc = FlagsConditionToConditionTst(condition);
Register result = i.OutputRegister(output_index);
Register v_true = i.InputOrZeroRegister(true_value_index);
Register v_false = i.InputOrZeroRegister(false_value_index);
if (v_true == zero_reg || v_false == zero_reg) {
if (v_true == zero_reg) {
v_true = v_false;
cc = NegateCondition(cc);
}
if (cc == eq)
__ masknez(result, v_true, t8);
else
__ maskeqz(result, v_true, t8);
} else if (result == v_true || result == v_false) {
if (result == v_false) {
v_false = v_true;
cc = NegateCondition(cc);
}
Label done;
__ Branch(&done, cc, t8, Operand(0));
__ Move(result, v_false);
__ bind(&done);
} else {
UseScratchRegisterScope temps(masm());
Register scratch = temps.Acquire();
if (cc == eq) {
Register temp = v_true;
v_true = v_false;
v_false = temp;
}
__ maskeqz(scratch, v_true, t8);
__ masknez(result, v_false, t8);
__ or_(result, scratch, result);
if (cc == eq) {
Register temp = v_true;
v_true = v_false;
v_false = temp;
}
__ SelectWord(result, t8, v_true, v_false);
UseScratchRegisterScope temps(masm());
temps.Include(t8);
return;
} else if (instr->arch_opcode() == kLoong64Cmp64 ||
instr->arch_opcode() == kLoong64Cmp32) {
instr->arch_opcode() == kLoong64Cmp32 ||
instr->arch_opcode() == kArchStackPointerGreaterThan) {
Condition cc = FlagsConditionToConditionCmp(condition);
Register left = i.InputRegister(0);
Operand right = i.InputOperand(1);
Register result = i.OutputRegister(output_index);
Register v_true = i.InputOrZeroRegister(true_value_index);
Register v_false = i.InputOrZeroRegister(false_value_index);
Register left = no_reg;
Operand right = Operand(0);
if (instr->arch_opcode() == kArchStackPointerGreaterThan) {
DCHECK_GE(instr->InputCount(), 3);
DCHECK((cc == ls) || (cc == hi));
left = sp;
right = i.InputOperand(0);
uint32_t offset;
if (ShouldApplyOffsetToStackCheck(instr, &offset)) {
left = i.TempRegister(1);
__ Sub_d(left, sp, offset);
}
} else {
DCHECK_GE(instr->InputCount(), 4);
left = i.InputRegister(0);
right = i.InputOperand(1);
}
if (v_true == zero_reg || v_false == zero_reg) {
if (v_true == zero_reg) {
v_true = v_false;
Expand Down Expand Up @@ -4725,6 +4722,108 @@ void CodeGenerator::AssembleArchSelect(Instruction* instr,
__ bind(&done);
}
return;
} else if (instr->arch_opcode() == kLoong64Add_d ||
instr->arch_opcode() == kLoong64Sub_d) {
DCHECK_GE(instr->InputCount(), 4);
Condition cc = FlagsConditionToConditionOvf(condition);
if (cc == eq) {
Register temp = v_true;
v_true = v_false;
v_false = temp;
}
UseScratchRegisterScope temps(masm());
Register scratch1 = temps.Acquire();
Register scratch2 = temps.Acquire();
__ srai_d(scratch1, i.OutputRegister(), 32);
__ srai_w(scratch2, i.OutputRegister(), 31);
if (v_false == zero_reg) {
__ xor_(scratch1, scratch1, scratch2);
__ maskeqz(result, v_true, scratch1);
} else if (v_true == zero_reg) {
__ xor_(scratch1, scratch1, scratch2);
__ masknez(result, v_false, scratch1);
} else if (result == v_true || result == v_false) {
if (result == v_false) {
v_false = v_true;
cc = NegateCondition(cc);
}
Label done;
__ Branch(&done, cc, scratch2, Operand(scratch1));
__ Move(result, v_false);
__ bind(&done);
} else {
Label true_label, done;
__ Branch(&true_label, cc, scratch2, Operand(scratch1));
__ Move(result, v_false);
__ Branch(&done);
__ bind(&true_label);
__ Move(result, v_true);
__ bind(&done);
}
return;
} else if (instr->arch_opcode() == kLoong64AddOvf_d ||
instr->arch_opcode() == kLoong64SubOvf_d) {
DCHECK_GE(instr->InputCount(), 4);
// Overflow occurs if overflow register is negative
Condition cc = lt;
if (condition == kNotOverflow) {
Register temp = v_true;
v_true = v_false;
v_false = temp;
}
if (v_false == zero_reg) {
__ slt(t8, t8, zero_reg);
__ maskeqz(result, v_true, t8);
} else if (v_true == zero_reg) {
__ slt(t8, t8, zero_reg);
__ masknez(result, v_false, t8);
} else if (result == v_true || result == v_false) {
if (result == v_false) {
v_false = v_true;
cc = NegateCondition(cc);
}
Label done;
__ Branch(&done, cc, t8, Operand(zero_reg));
__ Move(result, v_false);
__ bind(&done);
} else {
Label true_label, done;
__ Branch(&true_label, cc, t8, Operand(zero_reg));
__ Move(result, v_false);
__ Branch(&done);
__ bind(&true_label);
__ Move(result, v_true);
__ bind(&done);
}
UseScratchRegisterScope temps(masm());
temps.Include(t8);
} else if (instr->arch_opcode() == kLoong64MulOvf_w ||
instr->arch_opcode() == kLoong64MulOvf_d) {
DCHECK_GE(instr->InputCount(), 4);
Condition cc = FlagsConditionToConditionOvf(condition);
if (cc == eq) {
Register temp = v_true;
v_true = v_false;
v_false = temp;
}
__ SelectWord(result, t8, v_true, v_false);
UseScratchRegisterScope temps(masm());
temps.Include(t8);
return;
} else if (instr->arch_opcode() == kLoong64Float32Cmp ||
instr->arch_opcode() == kLoong64Float64Cmp) {
bool predicate;
FlagsConditionToConditionCmpFPU(&predicate, condition);
UseScratchRegisterScope temps(masm());
Register scratch = temps.Acquire();
if (!predicate) {
Register temp = v_true;
v_true = v_false;
v_false = temp;
}
__ movcf2gr(scratch, FCC0);
__ SelectWord(result, scratch, v_true, v_false);
return;
} else {
PrintF("AssembleArchSelect Unimplemented arch_opcode is : %d\n",
instr->arch_opcode());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,20 @@ class Loong64OperandGenerator final : public OperandGenerator {
return UseRegister(node);
}

InstructionOperand UseRegisterAtEndOrImmediateZero(OpIndex node) {
if (const ConstantOp* constant =
selector()->Get(node).TryCast<ConstantOp>()) {
if ((constant->IsIntegral() && constant->integral() == 0) ||
(constant->kind == ConstantOp::Kind::kFloat32 &&
constant->float32().get_bits() == 0) ||
(constant->kind == ConstantOp::Kind::kFloat64 &&
constant->float64().get_bits() == 0)) {
return UseImmediate(node);
}
}
return UseRegisterAtEnd(node);
}

bool IsIntegerConstant(OpIndex node) {
int64_t unused;
return selector()->MatchSignedIntegralConstant(node, &unused);
Expand Down Expand Up @@ -307,7 +321,7 @@ static void VisitBinop(InstructionSelector* selector, turboshaft::OpIndex node,
InstructionCode reverse_opcode,
FlagsContinuation* cont) {
Loong64OperandGenerator g(selector);
InstructionOperand inputs[2];
InstructionOperand inputs[4];
size_t input_count = 0;
InstructionOperand outputs[1];
size_t output_count = 0;
Expand All @@ -331,6 +345,13 @@ static void VisitBinop(InstructionSelector* selector, turboshaft::OpIndex node,
inputs[input_count++] = g.UseOperand(right_node, opcode);
}

if (cont->IsSelect()) {
inputs[input_count++] =
g.UseRegisterAtEndOrImmediateZero(cont->true_value());
inputs[input_count++] =
g.UseRegisterAtEndOrImmediateZero(cont->false_value());
}

outputs[output_count++] = g.DefineAsRegister(node);

DCHECK_NE(0u, input_count);
Expand Down Expand Up @@ -2169,9 +2190,14 @@ void InstructionSelector::VisitStackPointerGreaterThan(
? OperandGenerator::kUniqueRegister
: OperandGenerator::kRegister;

InstructionOperand inputs[] = {g.UseRegisterWithMode(value, register_mode)};
static constexpr int input_count = arraysize(inputs);
InstructionOperand inputs[3];
int input_count = 0;
inputs[input_count++] = g.UseRegisterWithMode(value, register_mode);

if (cont->IsSelect()) {
inputs[input_count++] = g.UseRegisterOrImmediateZero(cont->true_value());
inputs[input_count++] = g.UseRegisterOrImmediateZero(cont->false_value());
}
EmitWithContinuation(opcode, output_count, outputs, input_count, inputs,
temp_count, temps, cont);
}
Expand Down
4 changes: 4 additions & 0 deletions deps/v8/test/cctest/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,10 @@ v8_source_set("cctest_sources") {
if (is_win) {
sources += [ "test-stack-unwinding-win64.cc" ]
}
} else if (v8_current_cpu == "loong64") {
if (v8_enable_turbofan) {
sources += [ "compiler/test-run-machops-select-loong64.cc" ]
}
}

if (v8_use_perfetto) {
Expand Down
Loading
Loading