Skip to content

Commit c773cdd

Browse files
committed
deps:V8:cherry-pick c4d06ba586f33b8e5db8
Origin commit message: [loong64][compiler] Extend Word64Select instruction functionality Change-Id: Iba762777642d2d2d3aa904f9afc1e9005139992e Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/7801520 Reviewed-by: Zhao Jiazhong <zhaojiazhong-hf@loongson.cn> Commit-Queue: Liu Yu <liuyu@loongson.cn> Reviewed-by: Darius Mercadier <dmercadier@chromium.org> Auto-Submit: Liu Yu <liuyu@loongson.cn> Cr-Commit-Position: refs/heads/main@{#107619} Refs: v8/v8@c4d06ba
1 parent b345a17 commit c773cdd

7 files changed

Lines changed: 443 additions & 45 deletions

File tree

common.gypi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040

4141
# Reset this number to 0 on major V8 upgrades.
4242
# Increment by one for each non-official patch applied to deps/v8.
43-
'v8_embedder_string': '-node.20',
43+
'v8_embedder_string': '-node.21',
4444

4545
##### V8 defaults for Node.js #####
4646

deps/v8/src/codegen/loong64/macro-assembler-loong64.cc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3140,6 +3140,21 @@ void MacroAssembler::TruncateDoubleToI(Isolate* isolate, Zone* zone,
31403140
bind(&done);
31413141
}
31423142

3143+
void MacroAssembler::SelectWord(Register result, Register cond, Register v_true,
3144+
Register v_false) {
3145+
if (v_false == zero_reg) {
3146+
maskeqz(result, v_true, cond);
3147+
} else if (v_true == zero_reg) {
3148+
masknez(result, v_false, cond);
3149+
} else {
3150+
UseScratchRegisterScope temps(this);
3151+
Register scratch = temps.Acquire();
3152+
maskeqz(scratch, v_true, cond);
3153+
masknez(result, v_false, cond);
3154+
or_(result, scratch, result);
3155+
}
3156+
}
3157+
31433158
void MacroAssembler::CompareWord(Condition cond, Register dst, Register lhs,
31443159
const Operand& rhs) {
31453160
switch (cond) {

deps/v8/src/codegen/loong64/macro-assembler-loong64.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,10 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
140140
// Print a message to stdout and abort execution.
141141
void Abort(AbortReason msg);
142142

143+
// Select v_true if cond is non-zero, otherwise select v_false.
144+
void SelectWord(Register result, Register cond, Register v_true,
145+
Register v_false);
146+
143147
void CompareWord(Condition cond, Register dst, Register lhs,
144148
const Operand& rhs);
145149
void Branch(Label* label, bool need_link = false);

deps/v8/src/compiler/backend/loong64/code-generator-loong64.cc

Lines changed: 140 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1363,10 +1363,14 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
13631363
case kLoong64Sub_d:
13641364
__ Sub_d(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
13651365
break;
1366-
case kLoong64SubOvf_d:
1366+
case kLoong64SubOvf_d: {
1367+
UseScratchRegisterScope temps(masm());
1368+
DCHECK(temps.hasAvailable());
1369+
temps.Exclude(t8);
13671370
__ SubOverflow_d(i.OutputRegister(), i.InputRegister(0),
13681371
i.InputOperand(1), t8);
13691372
break;
1373+
}
13701374
case kLoong64Mul_w:
13711375
__ Mul_w(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
13721376
break;
@@ -4591,7 +4595,7 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
45914595
}
45924596
return;
45934597
} else {
4594-
PrintF("AssembleArchBranch Unimplemented arch_opcode is : %d\n",
4598+
PrintF("AssembleArchBoolean Unimplemented arch_opcode is : %d\n",
45954599
instr->arch_opcode());
45964600
TRACE("UNIMPLEMENTED code_generator_loong64: %s at line %d\n", __FUNCTION__,
45974601
__LINE__);
@@ -4646,56 +4650,49 @@ void CodeGenerator::AssembleArchSelect(Instruction* instr,
46464650
size_t output_index = instr->OutputCount() - 1;
46474651
// We don't know how many inputs were consumed by the condition, so we have to
46484652
// calculate the indices of the last two inputs.
4649-
DCHECK_GE(instr->InputCount(), 4);
46504653
size_t true_value_index = instr->InputCount() - 2;
46514654
size_t false_value_index = instr->InputCount() - 1;
4655+
Register result = i.OutputRegister(output_index);
4656+
Register v_true = i.InputOrZeroRegister(true_value_index);
4657+
Register v_false = i.InputOrZeroRegister(false_value_index);
4658+
4659+
DCHECK(
4660+
LocationOperand::cast(instr->OutputAt(output_index))->representation() ==
4661+
MachineRepresentation::kWord64);
46524662

46534663
if (instr->arch_opcode() == kLoong64Tst) {
4664+
DCHECK_GE(instr->InputCount(), 4);
46544665
Condition cc = FlagsConditionToConditionTst(condition);
4655-
Register result = i.OutputRegister(output_index);
4656-
Register v_true = i.InputOrZeroRegister(true_value_index);
4657-
Register v_false = i.InputOrZeroRegister(false_value_index);
4658-
if (v_true == zero_reg || v_false == zero_reg) {
4659-
if (v_true == zero_reg) {
4660-
v_true = v_false;
4661-
cc = NegateCondition(cc);
4662-
}
4663-
if (cc == eq)
4664-
__ masknez(result, v_true, t8);
4665-
else
4666-
__ maskeqz(result, v_true, t8);
4667-
} else if (result == v_true || result == v_false) {
4668-
if (result == v_false) {
4669-
v_false = v_true;
4670-
cc = NegateCondition(cc);
4671-
}
4672-
Label done;
4673-
__ Branch(&done, cc, t8, Operand(0));
4674-
__ Move(result, v_false);
4675-
__ bind(&done);
4676-
} else {
4677-
UseScratchRegisterScope temps(masm());
4678-
Register scratch = temps.Acquire();
4679-
if (cc == eq) {
4680-
Register temp = v_true;
4681-
v_true = v_false;
4682-
v_false = temp;
4683-
}
4684-
__ maskeqz(scratch, v_true, t8);
4685-
__ masknez(result, v_false, t8);
4686-
__ or_(result, scratch, result);
4666+
if (cc == eq) {
4667+
Register temp = v_true;
4668+
v_true = v_false;
4669+
v_false = temp;
46874670
}
4671+
__ SelectWord(result, t8, v_true, v_false);
46884672
UseScratchRegisterScope temps(masm());
46894673
temps.Include(t8);
46904674
return;
46914675
} else if (instr->arch_opcode() == kLoong64Cmp64 ||
4692-
instr->arch_opcode() == kLoong64Cmp32) {
4676+
instr->arch_opcode() == kLoong64Cmp32 ||
4677+
instr->arch_opcode() == kArchStackPointerGreaterThan) {
46934678
Condition cc = FlagsConditionToConditionCmp(condition);
4694-
Register left = i.InputRegister(0);
4695-
Operand right = i.InputOperand(1);
4696-
Register result = i.OutputRegister(output_index);
4697-
Register v_true = i.InputOrZeroRegister(true_value_index);
4698-
Register v_false = i.InputOrZeroRegister(false_value_index);
4679+
Register left = no_reg;
4680+
Operand right = Operand(0);
4681+
if (instr->arch_opcode() == kArchStackPointerGreaterThan) {
4682+
DCHECK_GE(instr->InputCount(), 3);
4683+
DCHECK((cc == ls) || (cc == hi));
4684+
left = sp;
4685+
right = i.InputOperand(0);
4686+
uint32_t offset;
4687+
if (ShouldApplyOffsetToStackCheck(instr, &offset)) {
4688+
left = i.TempRegister(1);
4689+
__ Sub_d(left, sp, offset);
4690+
}
4691+
} else {
4692+
DCHECK_GE(instr->InputCount(), 4);
4693+
left = i.InputRegister(0);
4694+
right = i.InputOperand(1);
4695+
}
46994696
if (v_true == zero_reg || v_false == zero_reg) {
47004697
if (v_true == zero_reg) {
47014698
v_true = v_false;
@@ -4725,6 +4722,108 @@ void CodeGenerator::AssembleArchSelect(Instruction* instr,
47254722
__ bind(&done);
47264723
}
47274724
return;
4725+
} else if (instr->arch_opcode() == kLoong64Add_d ||
4726+
instr->arch_opcode() == kLoong64Sub_d) {
4727+
DCHECK_GE(instr->InputCount(), 4);
4728+
Condition cc = FlagsConditionToConditionOvf(condition);
4729+
if (cc == eq) {
4730+
Register temp = v_true;
4731+
v_true = v_false;
4732+
v_false = temp;
4733+
}
4734+
UseScratchRegisterScope temps(masm());
4735+
Register scratch1 = temps.Acquire();
4736+
Register scratch2 = temps.Acquire();
4737+
__ srai_d(scratch1, i.OutputRegister(), 32);
4738+
__ srai_w(scratch2, i.OutputRegister(), 31);
4739+
if (v_false == zero_reg) {
4740+
__ xor_(scratch1, scratch1, scratch2);
4741+
__ maskeqz(result, v_true, scratch1);
4742+
} else if (v_true == zero_reg) {
4743+
__ xor_(scratch1, scratch1, scratch2);
4744+
__ masknez(result, v_false, scratch1);
4745+
} else if (result == v_true || result == v_false) {
4746+
if (result == v_false) {
4747+
v_false = v_true;
4748+
cc = NegateCondition(cc);
4749+
}
4750+
Label done;
4751+
__ Branch(&done, cc, scratch2, Operand(scratch1));
4752+
__ Move(result, v_false);
4753+
__ bind(&done);
4754+
} else {
4755+
Label true_label, done;
4756+
__ Branch(&true_label, cc, scratch2, Operand(scratch1));
4757+
__ Move(result, v_false);
4758+
__ Branch(&done);
4759+
__ bind(&true_label);
4760+
__ Move(result, v_true);
4761+
__ bind(&done);
4762+
}
4763+
return;
4764+
} else if (instr->arch_opcode() == kLoong64AddOvf_d ||
4765+
instr->arch_opcode() == kLoong64SubOvf_d) {
4766+
DCHECK_GE(instr->InputCount(), 4);
4767+
// Overflow occurs if overflow register is negative
4768+
Condition cc = lt;
4769+
if (condition == kNotOverflow) {
4770+
Register temp = v_true;
4771+
v_true = v_false;
4772+
v_false = temp;
4773+
}
4774+
if (v_false == zero_reg) {
4775+
__ slt(t8, t8, zero_reg);
4776+
__ maskeqz(result, v_true, t8);
4777+
} else if (v_true == zero_reg) {
4778+
__ slt(t8, t8, zero_reg);
4779+
__ masknez(result, v_false, t8);
4780+
} else if (result == v_true || result == v_false) {
4781+
if (result == v_false) {
4782+
v_false = v_true;
4783+
cc = NegateCondition(cc);
4784+
}
4785+
Label done;
4786+
__ Branch(&done, cc, t8, Operand(zero_reg));
4787+
__ Move(result, v_false);
4788+
__ bind(&done);
4789+
} else {
4790+
Label true_label, done;
4791+
__ Branch(&true_label, cc, t8, Operand(zero_reg));
4792+
__ Move(result, v_false);
4793+
__ Branch(&done);
4794+
__ bind(&true_label);
4795+
__ Move(result, v_true);
4796+
__ bind(&done);
4797+
}
4798+
UseScratchRegisterScope temps(masm());
4799+
temps.Include(t8);
4800+
} else if (instr->arch_opcode() == kLoong64MulOvf_w ||
4801+
instr->arch_opcode() == kLoong64MulOvf_d) {
4802+
DCHECK_GE(instr->InputCount(), 4);
4803+
Condition cc = FlagsConditionToConditionOvf(condition);
4804+
if (cc == eq) {
4805+
Register temp = v_true;
4806+
v_true = v_false;
4807+
v_false = temp;
4808+
}
4809+
__ SelectWord(result, t8, v_true, v_false);
4810+
UseScratchRegisterScope temps(masm());
4811+
temps.Include(t8);
4812+
return;
4813+
} else if (instr->arch_opcode() == kLoong64Float32Cmp ||
4814+
instr->arch_opcode() == kLoong64Float64Cmp) {
4815+
bool predicate;
4816+
FlagsConditionToConditionCmpFPU(&predicate, condition);
4817+
UseScratchRegisterScope temps(masm());
4818+
Register scratch = temps.Acquire();
4819+
if (!predicate) {
4820+
Register temp = v_true;
4821+
v_true = v_false;
4822+
v_false = temp;
4823+
}
4824+
__ movcf2gr(scratch, FCC0);
4825+
__ SelectWord(result, scratch, v_true, v_false);
4826+
return;
47284827
} else {
47294828
PrintF("AssembleArchSelect Unimplemented arch_opcode is : %d\n",
47304829
instr->arch_opcode());

deps/v8/src/compiler/backend/loong64/instruction-selector-loong64.cc

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,20 @@ class Loong64OperandGenerator final : public OperandGenerator {
4848
return UseRegister(node);
4949
}
5050

51+
InstructionOperand UseRegisterAtEndOrImmediateZero(OpIndex node) {
52+
if (const ConstantOp* constant =
53+
selector()->Get(node).TryCast<ConstantOp>()) {
54+
if ((constant->IsIntegral() && constant->integral() == 0) ||
55+
(constant->kind == ConstantOp::Kind::kFloat32 &&
56+
constant->float32().get_bits() == 0) ||
57+
(constant->kind == ConstantOp::Kind::kFloat64 &&
58+
constant->float64().get_bits() == 0)) {
59+
return UseImmediate(node);
60+
}
61+
}
62+
return UseRegisterAtEnd(node);
63+
}
64+
5165
bool IsIntegerConstant(OpIndex node) {
5266
int64_t unused;
5367
return selector()->MatchSignedIntegralConstant(node, &unused);
@@ -307,7 +321,7 @@ static void VisitBinop(InstructionSelector* selector, turboshaft::OpIndex node,
307321
InstructionCode reverse_opcode,
308322
FlagsContinuation* cont) {
309323
Loong64OperandGenerator g(selector);
310-
InstructionOperand inputs[2];
324+
InstructionOperand inputs[4];
311325
size_t input_count = 0;
312326
InstructionOperand outputs[1];
313327
size_t output_count = 0;
@@ -331,6 +345,13 @@ static void VisitBinop(InstructionSelector* selector, turboshaft::OpIndex node,
331345
inputs[input_count++] = g.UseOperand(right_node, opcode);
332346
}
333347

348+
if (cont->IsSelect()) {
349+
inputs[input_count++] =
350+
g.UseRegisterAtEndOrImmediateZero(cont->true_value());
351+
inputs[input_count++] =
352+
g.UseRegisterAtEndOrImmediateZero(cont->false_value());
353+
}
354+
334355
outputs[output_count++] = g.DefineAsRegister(node);
335356

336357
DCHECK_NE(0u, input_count);
@@ -2169,9 +2190,14 @@ void InstructionSelector::VisitStackPointerGreaterThan(
21692190
? OperandGenerator::kUniqueRegister
21702191
: OperandGenerator::kRegister;
21712192

2172-
InstructionOperand inputs[] = {g.UseRegisterWithMode(value, register_mode)};
2173-
static constexpr int input_count = arraysize(inputs);
2193+
InstructionOperand inputs[3];
2194+
int input_count = 0;
2195+
inputs[input_count++] = g.UseRegisterWithMode(value, register_mode);
21742196

2197+
if (cont->IsSelect()) {
2198+
inputs[input_count++] = g.UseRegisterOrImmediateZero(cont->true_value());
2199+
inputs[input_count++] = g.UseRegisterOrImmediateZero(cont->false_value());
2200+
}
21752201
EmitWithContinuation(opcode, output_count, outputs, input_count, inputs,
21762202
temp_count, temps, cont);
21772203
}

deps/v8/test/cctest/BUILD.gn

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,10 @@ v8_source_set("cctest_sources") {
233233
if (is_win) {
234234
sources += [ "test-stack-unwinding-win64.cc" ]
235235
}
236+
} else if (v8_current_cpu == "loong64") {
237+
if (v8_enable_turbofan) {
238+
sources += [ "compiler/test-run-machops-select-loong64.cc" ]
239+
}
236240
}
237241

238242
if (v8_use_perfetto) {

0 commit comments

Comments
 (0)