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 @@ -43,7 +43,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.32',
'v8_embedder_string': '-node.33',

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

Expand Down
98 changes: 52 additions & 46 deletions deps/v8/src/compiler/backend/riscv/code-generator-riscv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -433,24 +433,62 @@ FPUCondition FlagsConditionToConditionCmpFPU(bool* predicate,
*predicate = true;
return GE;
case kFloatLessThanOrUnordered:
*predicate = true;
return LT;
*predicate = false;
return GE;
case kFloatGreaterThanOrUnordered:
*predicate = false;
return LE;
case kFloatGreaterThanOrEqualOrUnordered:
*predicate = false;
return LT;
case kFloatLessThanOrEqualOrUnordered:
*predicate = true;
return LE;
*predicate = false;
return GT;
default:
*predicate = true;
break;
}
UNREACHABLE();
}

// Emits the actual floating-point comparison for a kRiscvCmpS/kRiscvCmpD
// instruction, materializing its boolean result (0 or 1) into {dst}.
// The comparison itself is a pseudo-instruction (like the integer kRiscvCmp):
// nothing is emitted at the instruction site. Instead, the comparison and the
// FPUCondition-to-machine mapping are resolved together here, at the single
// flags consumer (branch, boolean materialization, or select), using the
// consumer's final FlagsCondition {condition} (which ComputeBranchInfo may
// have negated for branches). This makes it structurally impossible for
// complementary conditions to observe a comparison that was emitted for a
// different condition.
// The returned predicate tells the consumer how to interpret {dst}: when
// false, the comparison result must be inverted to obtain the condition's
// truth value (this is how conditions involving "unordered" are expressed
// with RISC-V's NaN-false flt/fle/feq instructions).
void EmitFPCompare(MacroAssembler* masm, RiscvOperandConverter& i,
Instruction* instr, FlagsCondition condition, Register dst,
bool* predicate) {
FPUCondition cc = FlagsConditionToConditionCmpFPU(predicate, condition);
if (instr->arch_opcode() == kRiscvCmpS) {
FPURegister left = i.InputOrZeroSingleRegister(0);
FPURegister right = i.InputOrZeroSingleRegister(1);
if ((left == kSingleRegZero || right == kSingleRegZero) &&
!masm->IsSingleZeroRegSet()) {
masm->LoadFPRImmediate(kSingleRegZero, 0.0f);
}
masm->CompareF32(dst, cc, left, right);
} else {
DCHECK_EQ(instr->arch_opcode(), kRiscvCmpD);
FPURegister left = i.InputOrZeroDoubleRegister(0);
FPURegister right = i.InputOrZeroDoubleRegister(1);
if ((left == kDoubleRegZero || right == kDoubleRegZero) &&
!masm->IsDoubleZeroRegSet()) {
masm->LoadFPRImmediate(kDoubleRegZero, 0.0);
}
masm->CompareF64(dst, cc, left, right);
}
}

#if V8_ENABLE_WEBASSEMBLY
class WasmOutOfLineTrap : public OutOfLineCode {
public:
Expand Down Expand Up @@ -1597,26 +1635,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
// Pseudo-instruction used for cmpzero/branch. No opcode emitted here.
break;

case kRiscvCmpS: {
FPURegister left = i.InputOrZeroSingleRegister(0);
FPURegister right = i.InputOrZeroSingleRegister(1);
bool predicate;
FPUCondition cc =
FlagsConditionToConditionCmpFPU(&predicate, instr->flags_condition());

if ((left == kSingleRegZero || right == kSingleRegZero) &&
!__ IsSingleZeroRegSet()) {
__ LoadFPRImmediate(kSingleRegZero, 0.0f);
}
switch (FlagsModeField::decode(instr->opcode())) {
case kFlags_set:
__ CompareF32(i.OutputRegister(), cc, left, right);
break;
default:
__ CompareF32(kScratchReg, cc, left, right);
break;
}
} break;
case kRiscvCmpS:
// Pseudo-instruction used for FP cmp/branch. No opcode emitted here;
// the comparison is emitted by the flags consumer via EmitFPCompare.
break;
case kRiscvAddS:
// TODO(plind): add special case: combine mult & add.
__ fadd_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
Expand Down Expand Up @@ -1645,25 +1667,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ fsqrt_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
break;
}
case kRiscvCmpD: {
FPURegister left = i.InputOrZeroDoubleRegister(0);
FPURegister right = i.InputOrZeroDoubleRegister(1);
bool predicate;
FPUCondition cc =
FlagsConditionToConditionCmpFPU(&predicate, instr->flags_condition());
if ((left == kDoubleRegZero || right == kDoubleRegZero) &&
!__ IsDoubleZeroRegSet()) {
__ LoadFPRImmediate(kDoubleRegZero, 0.0);
}
switch (FlagsModeField::decode(instr->opcode())) {
case kFlags_set:
__ CompareF64(i.OutputRegister(), cc, left, right);
break;
default:
__ CompareF64(kScratchReg, cc, left, right);
break;
}
} break;
case kRiscvCmpD:
// Pseudo-instruction used for FP cmp/branch. No opcode emitted here;
// the comparison is emitted by the flags consumer via EmitFPCompare.
break;
#if V8_TARGET_ARCH_RISCV32
case kRiscvAddPair:
__ AddPair(i.OutputRegister(0), i.OutputRegister(1), i.InputRegister(0),
Expand Down Expand Up @@ -4600,8 +4607,7 @@ void AssembleBranchToLabels(CodeGenerator* gen, MacroAssembler* masm,
} else if (instr->arch_opcode() == kRiscvCmpS ||
instr->arch_opcode() == kRiscvCmpD) {
bool predicate;
FlagsConditionToConditionCmpFPU(&predicate, condition);
// floating-point compare result is set in kScratchReg
EmitFPCompare(masm, i, instr, condition, kScratchReg, &predicate);
if (predicate) {
__ BranchTrueF(kScratchReg, tlabel);
} else {
Expand Down Expand Up @@ -5005,7 +5011,7 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
} else if (instr->arch_opcode() == kRiscvCmpD ||
instr->arch_opcode() == kRiscvCmpS) {
bool predicate;
FlagsConditionToConditionCmpFPU(&predicate, condition);
EmitFPCompare(masm(), i, instr, condition, result, &predicate);
// RISCV compare returns 0 or 1, do nothing when predicate; otherwise
// toggle result (i.e., 0 -> 1, 1 -> 0)
if (!predicate) {
Expand Down
Loading