Commit d39a06a9 authored by Ng Zhi An's avatar Ng Zhi An Committed by V8 LUCI CQ

[wasm-simd][ia32] f64x2 min max move usage of TempRegister

We have a scratch available, so we can use it instead of asking for a
temporary register from the register allocator. We can also relax the
unique register requirement, since we are careful not to overwrite src0
or src1 in the codegen.

Bug: chromium:1204071
Change-Id: Ia7775167e323b3bca80f63304687cdbd425af0e5
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2873227Reviewed-by: 's avatarBill Budge <bbudge@chromium.org>
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74392}
parent d4ac2dc8
...@@ -1938,44 +1938,42 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -1938,44 +1938,42 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
break; break;
} }
case kIA32F64x2Min: { case kIA32F64x2Min: {
Operand src1 = i.InputOperand(1);
XMMRegister dst = i.OutputSimd128Register(), XMMRegister dst = i.OutputSimd128Register(),
src = i.InputSimd128Register(0), src0 = i.InputSimd128Register(0),
tmp = i.TempSimd128Register(0); src1 = i.InputSimd128Register(1);
// The minpd instruction doesn't propagate NaNs and +0's in its first // The minpd instruction doesn't propagate NaNs and +0's in its first
// operand. Perform minpd in both orders, merge the resuls, and adjust. // operand. Perform minpd in both orders, merge the resuls, and adjust.
__ Movupd(tmp, src1); __ Movapd(kScratchDoubleReg, src1);
__ Minpd(tmp, tmp, src); __ Minpd(kScratchDoubleReg, kScratchDoubleReg, src0);
__ Minpd(dst, src, src1); __ Minpd(dst, src0, src1);
// propagate -0's and NaNs, which may be non-canonical. // propagate -0's and NaNs, which may be non-canonical.
__ Orpd(tmp, dst); __ Orpd(kScratchDoubleReg, dst);
// Canonicalize NaNs by quieting and clearing the payload. // Canonicalize NaNs by quieting and clearing the payload.
__ Cmpunordpd(dst, dst, tmp); __ Cmpunordpd(dst, dst, kScratchDoubleReg);
__ Orpd(tmp, dst); __ Orpd(kScratchDoubleReg, dst);
__ Psrlq(dst, byte{13}); __ Psrlq(dst, byte{13});
__ Andnpd(dst, tmp); __ Andnpd(dst, kScratchDoubleReg);
break; break;
} }
case kIA32F64x2Max: { case kIA32F64x2Max: {
Operand src1 = i.InputOperand(1);
XMMRegister dst = i.OutputSimd128Register(), XMMRegister dst = i.OutputSimd128Register(),
src = i.InputSimd128Register(0), src0 = i.InputSimd128Register(0),
tmp = i.TempSimd128Register(0); src1 = i.InputSimd128Register(1);
// The maxpd instruction doesn't propagate NaNs and +0's in its first // The maxpd instruction doesn't propagate NaNs and +0's in its first
// operand. Perform maxpd in both orders, merge the resuls, and adjust. // operand. Perform maxpd in both orders, merge the resuls, and adjust.
__ Movupd(tmp, src1); __ Movapd(kScratchDoubleReg, src1);
__ Maxpd(tmp, tmp, src); __ Maxpd(kScratchDoubleReg, kScratchDoubleReg, src0);
__ Maxpd(dst, src, src1); __ Maxpd(dst, src0, src1);
// Find discrepancies. // Find discrepancies.
__ Xorpd(dst, tmp); __ Xorpd(dst, kScratchDoubleReg);
// Propagate NaNs, which may be non-canonical. // Propagate NaNs, which may be non-canonical.
__ Orpd(tmp, dst); __ Orpd(kScratchDoubleReg, dst);
// Propagate sign discrepancy and (subtle) quiet NaNs. // Propagate sign discrepancy and (subtle) quiet NaNs.
__ Subpd(tmp, tmp, dst); __ Subpd(kScratchDoubleReg, kScratchDoubleReg, dst);
// Canonicalize NaNs by clearing the payload. Sign is non-deterministic. // Canonicalize NaNs by clearing the payload. Sign is non-deterministic.
__ Cmpunordpd(dst, dst, tmp); __ Cmpunordpd(dst, dst, kScratchDoubleReg);
__ Psrlq(dst, byte{13}); __ Psrlq(dst, byte{13});
__ Andnpd(dst, tmp); __ Andnpd(dst, kScratchDoubleReg);
break; break;
} }
case kIA32F64x2Eq: { case kIA32F64x2Eq: {
......
...@@ -2354,30 +2354,24 @@ void InstructionSelector::VisitS128Const(Node* node) { ...@@ -2354,30 +2354,24 @@ void InstructionSelector::VisitS128Const(Node* node) {
void InstructionSelector::VisitF64x2Min(Node* node) { void InstructionSelector::VisitF64x2Min(Node* node) {
IA32OperandGenerator g(this); IA32OperandGenerator g(this);
InstructionOperand temps[] = {g.TempSimd128Register()}; InstructionOperand operand0 = g.UseRegister(node->InputAt(0));
InstructionOperand operand0 = g.UseUniqueRegister(node->InputAt(0)); InstructionOperand operand1 = g.UseRegister(node->InputAt(1));
InstructionOperand operand1 = g.UseUniqueRegister(node->InputAt(1));
if (IsSupported(AVX)) { if (IsSupported(AVX)) {
Emit(kIA32F64x2Min, g.DefineAsRegister(node), operand0, operand1, Emit(kIA32F64x2Min, g.DefineAsRegister(node), operand0, operand1);
arraysize(temps), temps);
} else { } else {
Emit(kIA32F64x2Min, g.DefineSameAsFirst(node), operand0, operand1, Emit(kIA32F64x2Min, g.DefineSameAsFirst(node), operand0, operand1);
arraysize(temps), temps);
} }
} }
void InstructionSelector::VisitF64x2Max(Node* node) { void InstructionSelector::VisitF64x2Max(Node* node) {
IA32OperandGenerator g(this); IA32OperandGenerator g(this);
InstructionOperand temps[] = {g.TempSimd128Register()}; InstructionOperand operand0 = g.UseRegister(node->InputAt(0));
InstructionOperand operand0 = g.UseUniqueRegister(node->InputAt(0)); InstructionOperand operand1 = g.UseRegister(node->InputAt(1));
InstructionOperand operand1 = g.UseUniqueRegister(node->InputAt(1));
if (IsSupported(AVX)) { if (IsSupported(AVX)) {
Emit(kIA32F64x2Max, g.DefineAsRegister(node), operand0, operand1, Emit(kIA32F64x2Max, g.DefineAsRegister(node), operand0, operand1);
arraysize(temps), temps);
} else { } else {
Emit(kIA32F64x2Max, g.DefineSameAsFirst(node), operand0, operand1, Emit(kIA32F64x2Max, g.DefineSameAsFirst(node), operand0, operand1);
arraysize(temps), temps);
} }
} }
......
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