Commit e8f5adbe authored by Ilija.Pavlovic's avatar Ilija.Pavlovic Committed by Commit bot

MIPS[64]: Fix `MIPS: Improve Float(32|64)(Max|Min)`.

Fix 7a6f294f.

The first correction enables correct execution DoMathMinMax when two
input registers are the same register.
The second correction adds NOP instructions after branch instructions
in tests macro_float_minmaxf(32|64).

TEST=cctest/test-macro-assembler-mips[64]/macro_float_minmax_f32
     cctest/test-macro-assembler-mips[64]/macro_float_minmax_f64
     mjsunit/regress/math-min
BUG=

Review-Url: https://codereview.chromium.org/2556793003
Cr-Commit-Position: refs/heads/master@{#41596}
parent 4a637abe
......@@ -1262,52 +1262,36 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
FPURegister dst = i.OutputSingleRegister();
FPURegister src1 = i.InputSingleRegister(0);
FPURegister src2 = i.InputSingleRegister(1);
if (src1.is(src2)) {
__ Move_s(dst, src1);
} else {
auto ool = new (zone()) OutOfLineFloat32Max(this, dst, src1, src2);
__ Float32Max(dst, src1, src2, ool->entry());
__ bind(ool->exit());
}
auto ool = new (zone()) OutOfLineFloat32Max(this, dst, src1, src2);
__ Float32Max(dst, src1, src2, ool->entry());
__ bind(ool->exit());
break;
}
case kMipsFloat64Max: {
DoubleRegister dst = i.OutputDoubleRegister();
DoubleRegister src1 = i.InputDoubleRegister(0);
DoubleRegister src2 = i.InputDoubleRegister(1);
if (src1.is(src2)) {
__ Move_d(dst, src1);
} else {
auto ool = new (zone()) OutOfLineFloat64Max(this, dst, src1, src2);
__ Float64Max(dst, src1, src2, ool->entry());
__ bind(ool->exit());
}
auto ool = new (zone()) OutOfLineFloat64Max(this, dst, src1, src2);
__ Float64Max(dst, src1, src2, ool->entry());
__ bind(ool->exit());
break;
}
case kMipsFloat32Min: {
FPURegister dst = i.OutputSingleRegister();
FPURegister src1 = i.InputSingleRegister(0);
FPURegister src2 = i.InputSingleRegister(1);
if (src1.is(src2)) {
__ Move_s(dst, src1);
} else {
auto ool = new (zone()) OutOfLineFloat32Min(this, dst, src1, src2);
__ Float32Min(dst, src1, src2, ool->entry());
__ bind(ool->exit());
}
auto ool = new (zone()) OutOfLineFloat32Min(this, dst, src1, src2);
__ Float32Min(dst, src1, src2, ool->entry());
__ bind(ool->exit());
break;
}
case kMipsFloat64Min: {
DoubleRegister dst = i.OutputDoubleRegister();
DoubleRegister src1 = i.InputDoubleRegister(0);
DoubleRegister src2 = i.InputDoubleRegister(1);
if (src1.is(src2)) {
__ Move_d(dst, src1);
} else {
auto ool = new (zone()) OutOfLineFloat64Min(this, dst, src1, src2);
__ Float64Min(dst, src1, src2, ool->entry());
__ bind(ool->exit());
}
auto ool = new (zone()) OutOfLineFloat64Min(this, dst, src1, src2);
__ Float64Min(dst, src1, src2, ool->entry());
__ bind(ool->exit());
break;
}
case kMipsCvtSD: {
......
......@@ -1453,52 +1453,36 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
FPURegister dst = i.OutputSingleRegister();
FPURegister src1 = i.InputSingleRegister(0);
FPURegister src2 = i.InputSingleRegister(1);
if (src1.is(src2)) {
__ Move_s(dst, src1);
} else {
auto ool = new (zone()) OutOfLineFloat32Max(this, dst, src1, src2);
__ Float32Max(dst, src1, src2, ool->entry());
__ bind(ool->exit());
}
auto ool = new (zone()) OutOfLineFloat32Max(this, dst, src1, src2);
__ Float32Max(dst, src1, src2, ool->entry());
__ bind(ool->exit());
break;
}
case kMips64Float64Max: {
FPURegister dst = i.OutputDoubleRegister();
FPURegister src1 = i.InputDoubleRegister(0);
FPURegister src2 = i.InputDoubleRegister(1);
if (src1.is(src2)) {
__ Move_d(dst, src1);
} else {
auto ool = new (zone()) OutOfLineFloat64Max(this, dst, src1, src2);
__ Float64Max(dst, src1, src2, ool->entry());
__ bind(ool->exit());
}
auto ool = new (zone()) OutOfLineFloat64Max(this, dst, src1, src2);
__ Float64Max(dst, src1, src2, ool->entry());
__ bind(ool->exit());
break;
}
case kMips64Float32Min: {
FPURegister dst = i.OutputSingleRegister();
FPURegister src1 = i.InputSingleRegister(0);
FPURegister src2 = i.InputSingleRegister(1);
if (src1.is(src2)) {
__ Move_s(dst, src1);
} else {
auto ool = new (zone()) OutOfLineFloat32Min(this, dst, src1, src2);
__ Float32Min(dst, src1, src2, ool->entry());
__ bind(ool->exit());
}
auto ool = new (zone()) OutOfLineFloat32Min(this, dst, src1, src2);
__ Float32Min(dst, src1, src2, ool->entry());
__ bind(ool->exit());
break;
}
case kMips64Float64Min: {
FPURegister dst = i.OutputDoubleRegister();
FPURegister src1 = i.InputDoubleRegister(0);
FPURegister src2 = i.InputDoubleRegister(1);
if (src1.is(src2)) {
__ Move_d(dst, src1);
} else {
auto ool = new (zone()) OutOfLineFloat64Min(this, dst, src1, src2);
__ Float64Min(dst, src1, src2, ool->entry());
__ bind(ool->exit());
}
auto ool = new (zone()) OutOfLineFloat64Min(this, dst, src1, src2);
__ Float64Min(dst, src1, src2, ool->entry());
__ bind(ool->exit());
break;
}
case kMips64Float64SilenceNaN:
......
......@@ -5879,7 +5879,10 @@ void MacroAssembler::JumpIfNotBothSequentialOneByteStrings(Register first,
void MacroAssembler::Float32Max(FPURegister dst, FPURegister src1,
FPURegister src2, Label* out_of_line) {
DCHECK(!src1.is(src2));
if (src1.is(src2)) {
Move_s(dst, src1);
return;
}
// Check if one of operands is NaN.
BranchF32(nullptr, out_of_line, eq, src1, src2);
......@@ -5889,27 +5892,19 @@ void MacroAssembler::Float32Max(FPURegister dst, FPURegister src1,
} else {
Label return_left, return_right, done;
c(OLT, S, src1, src2);
bc1t(&return_right);
nop();
c(OLT, S, src2, src1);
bc1t(&return_left);
nop();
BranchF32(&return_right, nullptr, lt, src1, src2);
BranchF32(&return_left, nullptr, lt, src2, src1);
// Operands are equal, but check for +/-0.
mfc1(t8, src1);
beq(t8, zero_reg, &return_left);
nop();
b(&return_right);
nop();
Branch(&return_left, eq, t8, Operand(zero_reg));
Branch(&return_right);
bind(&return_right);
if (!src2.is(dst)) {
Move_s(dst, src2);
}
b(&done);
nop();
Branch(&done);
bind(&return_left);
if (!src1.is(dst)) {
......@@ -5922,13 +5917,15 @@ void MacroAssembler::Float32Max(FPURegister dst, FPURegister src1,
void MacroAssembler::Float32MaxOutOfLine(FPURegister dst, FPURegister src1,
FPURegister src2) {
DCHECK(!src1.is(src2));
add_s(dst, src1, src2);
}
void MacroAssembler::Float32Min(FPURegister dst, FPURegister src1,
FPURegister src2, Label* out_of_line) {
DCHECK(!src1.is(src2));
if (src1.is(src2)) {
Move_s(dst, src1);
return;
}
// Check if one of operands is NaN.
BranchF32(nullptr, out_of_line, eq, src1, src2);
......@@ -5938,27 +5935,19 @@ void MacroAssembler::Float32Min(FPURegister dst, FPURegister src1,
} else {
Label return_left, return_right, done;
c(OLT, S, src1, src2);
bc1t(&return_left);
nop();
c(OLT, S, src2, src1);
bc1t(&return_right);
nop();
BranchF32(&return_left, nullptr, lt, src1, src2);
BranchF32(&return_right, nullptr, lt, src2, src1);
// Left equals right => check for -0.
mfc1(t8, src1);
beq(t8, zero_reg, &return_right);
nop();
b(&return_left);
nop();
Branch(&return_right, eq, t8, Operand(zero_reg));
Branch(&return_left);
bind(&return_right);
if (!src2.is(dst)) {
Move_s(dst, src2);
}
b(&done);
nop();
Branch(&done);
bind(&return_left);
if (!src1.is(dst)) {
......@@ -5971,13 +5960,15 @@ void MacroAssembler::Float32Min(FPURegister dst, FPURegister src1,
void MacroAssembler::Float32MinOutOfLine(FPURegister dst, FPURegister src1,
FPURegister src2) {
DCHECK(!src1.is(src2));
add_s(dst, src1, src2);
}
void MacroAssembler::Float64Max(DoubleRegister dst, DoubleRegister src1,
DoubleRegister src2, Label* out_of_line) {
DCHECK(!src1.is(src2));
if (src1.is(src2)) {
Move_d(dst, src1);
return;
}
// Check if one of operands is NaN.
BranchF64(nullptr, out_of_line, eq, src1, src2);
......@@ -5987,27 +5978,19 @@ void MacroAssembler::Float64Max(DoubleRegister dst, DoubleRegister src1,
} else {
Label return_left, return_right, done;
c(OLT, D, src1, src2);
bc1t(&return_right);
nop();
c(OLT, D, src2, src1);
bc1t(&return_left);
nop();
BranchF64(&return_right, nullptr, lt, src1, src2);
BranchF64(&return_left, nullptr, lt, src2, src1);
// Left equals right => check for -0.
Mfhc1(t8, src1);
beq(t8, zero_reg, &return_left);
nop();
b(&return_right);
nop();
Branch(&return_left, eq, t8, Operand(zero_reg));
Branch(&return_right);
bind(&return_right);
if (!src2.is(dst)) {
Move_d(dst, src2);
}
b(&done);
nop();
Branch(&done);
bind(&return_left);
if (!src1.is(dst)) {
......@@ -6021,13 +6004,15 @@ void MacroAssembler::Float64Max(DoubleRegister dst, DoubleRegister src1,
void MacroAssembler::Float64MaxOutOfLine(DoubleRegister dst,
DoubleRegister src1,
DoubleRegister src2) {
DCHECK(!src1.is(src2));
add_d(dst, src1, src2);
}
void MacroAssembler::Float64Min(DoubleRegister dst, DoubleRegister src1,
DoubleRegister src2, Label* out_of_line) {
DCHECK(!src1.is(src2));
if (src1.is(src2)) {
Move_d(dst, src1);
return;
}
// Check if one of operands is NaN.
BranchF64(nullptr, out_of_line, eq, src1, src2);
......@@ -6037,27 +6022,19 @@ void MacroAssembler::Float64Min(DoubleRegister dst, DoubleRegister src1,
} else {
Label return_left, return_right, done;
c(OLT, D, src1, src2);
bc1t(&return_left);
nop();
c(OLT, D, src2, src1);
bc1t(&return_right);
nop();
BranchF64(&return_left, nullptr, lt, src1, src2);
BranchF64(&return_right, nullptr, lt, src2, src1);
// Left equals right => check for -0.
Mfhc1(t8, src1);
beq(t8, zero_reg, &return_right);
nop();
b(&return_left);
nop();
Branch(&return_right, eq, t8, Operand(zero_reg));
Branch(&return_left);
bind(&return_right);
if (!src2.is(dst)) {
Move_d(dst, src2);
}
b(&done);
nop();
Branch(&done);
bind(&return_left);
if (!src1.is(dst)) {
......@@ -6071,7 +6048,6 @@ void MacroAssembler::Float64Min(DoubleRegister dst, DoubleRegister src1,
void MacroAssembler::Float64MinOutOfLine(DoubleRegister dst,
DoubleRegister src1,
DoubleRegister src2) {
DCHECK(!src1.is(src2));
add_d(dst, src1, src2);
}
......
......@@ -6302,7 +6302,10 @@ void MacroAssembler::JumpIfNotBothSequentialOneByteStrings(Register first,
void MacroAssembler::Float32Max(FPURegister dst, FPURegister src1,
FPURegister src2, Label* out_of_line) {
DCHECK(!src1.is(src2));
if (src1.is(src2)) {
Move_s(dst, src1);
return;
}
// Check if one of operands is NaN.
BranchF32(nullptr, out_of_line, eq, src1, src2);
......@@ -6312,28 +6315,20 @@ void MacroAssembler::Float32Max(FPURegister dst, FPURegister src1,
} else {
Label return_left, return_right, done;
c(OLT, S, src1, src2);
bc1t(&return_right);
nop();
c(OLT, S, src2, src1);
bc1t(&return_left);
nop();
BranchF32(&return_right, nullptr, lt, src1, src2);
BranchF32(&return_left, nullptr, lt, src2, src1);
// Operands are equal, but check for +/-0.
mfc1(t8, src1);
dsll32(t8, t8, 0);
beq(t8, zero_reg, &return_left);
nop();
b(&return_right);
nop();
Branch(&return_left, eq, t8, Operand(zero_reg));
Branch(&return_right);
bind(&return_right);
if (!src2.is(dst)) {
Move_s(dst, src2);
}
b(&done);
nop();
Branch(&done);
bind(&return_left);
if (!src1.is(dst)) {
......@@ -6346,13 +6341,15 @@ void MacroAssembler::Float32Max(FPURegister dst, FPURegister src1,
void MacroAssembler::Float32MaxOutOfLine(FPURegister dst, FPURegister src1,
FPURegister src2) {
DCHECK(!src1.is(src2));
add_s(dst, src1, src2);
}
void MacroAssembler::Float32Min(FPURegister dst, FPURegister src1,
FPURegister src2, Label* out_of_line) {
DCHECK(!src1.is(src2));
if (src1.is(src2)) {
Move_s(dst, src1);
return;
}
// Check if one of operands is NaN.
BranchF32(nullptr, out_of_line, eq, src1, src2);
......@@ -6362,28 +6359,20 @@ void MacroAssembler::Float32Min(FPURegister dst, FPURegister src1,
} else {
Label return_left, return_right, done;
c(OLT, S, src1, src2);
bc1t(&return_left);
nop();
c(OLT, S, src2, src1);
bc1t(&return_right);
nop();
BranchF32(&return_left, nullptr, lt, src1, src2);
BranchF32(&return_right, nullptr, lt, src2, src1);
// Left equals right => check for -0.
mfc1(t8, src1);
dsll32(t8, t8, 0);
beq(t8, zero_reg, &return_right);
nop();
b(&return_left);
nop();
Branch(&return_right, eq, t8, Operand(zero_reg));
Branch(&return_left);
bind(&return_right);
if (!src2.is(dst)) {
Move_s(dst, src2);
}
b(&done);
nop();
Branch(&done);
bind(&return_left);
if (!src1.is(dst)) {
......@@ -6396,13 +6385,15 @@ void MacroAssembler::Float32Min(FPURegister dst, FPURegister src1,
void MacroAssembler::Float32MinOutOfLine(FPURegister dst, FPURegister src1,
FPURegister src2) {
DCHECK(!src1.is(src2));
add_s(dst, src1, src2);
}
void MacroAssembler::Float64Max(FPURegister dst, FPURegister src1,
FPURegister src2, Label* out_of_line) {
DCHECK(!src1.is(src2));
if (src1.is(src2)) {
Move_d(dst, src1);
return;
}
// Check if one of operands is NaN.
BranchF64(nullptr, out_of_line, eq, src1, src2);
......@@ -6412,27 +6403,19 @@ void MacroAssembler::Float64Max(FPURegister dst, FPURegister src1,
} else {
Label return_left, return_right, done;
c(OLT, D, src1, src2);
bc1t(&return_right);
nop();
c(OLT, D, src2, src1);
bc1t(&return_left);
nop();
BranchF64(&return_right, nullptr, lt, src1, src2);
BranchF64(&return_left, nullptr, lt, src2, src1);
// Left equals right => check for -0.
dmfc1(t8, src1);
beq(t8, zero_reg, &return_left);
nop();
b(&return_right);
nop();
Branch(&return_left, eq, t8, Operand(zero_reg));
Branch(&return_right);
bind(&return_right);
if (!src2.is(dst)) {
Move_d(dst, src2);
}
b(&done);
nop();
Branch(&done);
bind(&return_left);
if (!src1.is(dst)) {
......@@ -6445,13 +6428,15 @@ void MacroAssembler::Float64Max(FPURegister dst, FPURegister src1,
void MacroAssembler::Float64MaxOutOfLine(FPURegister dst, FPURegister src1,
FPURegister src2) {
DCHECK(!src1.is(src2));
add_d(dst, src1, src2);
}
void MacroAssembler::Float64Min(FPURegister dst, FPURegister src1,
FPURegister src2, Label* out_of_line) {
DCHECK(!src1.is(src2));
if (src1.is(src2)) {
Move_d(dst, src1);
return;
}
// Check if one of operands is NaN.
BranchF64(nullptr, out_of_line, eq, src1, src2);
......@@ -6461,27 +6446,19 @@ void MacroAssembler::Float64Min(FPURegister dst, FPURegister src1,
} else {
Label return_left, return_right, done;
c(OLT, D, src1, src2);
bc1t(&return_left);
nop();
c(OLT, D, src2, src1);
bc1t(&return_right);
nop();
BranchF64(&return_left, nullptr, lt, src1, src2);
BranchF64(&return_right, nullptr, lt, src2, src1);
// Left equals right => check for -0.
dmfc1(t8, src1);
beq(t8, zero_reg, &return_right);
nop();
b(&return_left);
nop();
Branch(&return_right, eq, t8, Operand(zero_reg));
Branch(&return_left);
bind(&return_right);
if (!src2.is(dst)) {
Move_d(dst, src2);
}
b(&done);
nop();
Branch(&done);
bind(&return_left);
if (!src1.is(dst)) {
......@@ -6494,7 +6471,6 @@ void MacroAssembler::Float64Min(FPURegister dst, FPURegister src1,
void MacroAssembler::Float64MinOutOfLine(FPURegister dst, FPURegister src1,
FPURegister src2) {
DCHECK(!src1.is(src2));
add_d(dst, src1, src2);
}
......
......@@ -1406,27 +1406,27 @@ static ::F4 GenerateMacroFloat32MinMax(MacroAssembler* masm) {
// Generate out-of-line cases.
__ bind(&ool_min_abc);
__ Float32MinOutOfLine(a, b, c);
__ b(&done_min_abc);
__ Branch(&done_min_abc);
__ bind(&ool_min_aab);
__ Float32MinOutOfLine(a, a, b);
__ b(&done_min_aab);
__ Branch(&done_min_aab);
__ bind(&ool_min_aba);
__ Float32MinOutOfLine(a, b, a);
__ b(&done_min_aba);
__ Branch(&done_min_aba);
__ bind(&ool_max_abc);
__ Float32MaxOutOfLine(a, b, c);
__ b(&done_max_abc);
__ Branch(&done_max_abc);
__ bind(&ool_max_aab);
__ Float32MaxOutOfLine(a, a, b);
__ b(&done_max_aab);
__ Branch(&done_max_aab);
__ bind(&ool_max_aba);
__ Float32MaxOutOfLine(a, b, a);
__ b(&done_max_aba);
__ Branch(&done_max_aba);
CodeDesc desc;
masm->GetCode(&desc);
......@@ -1549,27 +1549,27 @@ static ::F4 GenerateMacroFloat64MinMax(MacroAssembler* masm) {
// Generate out-of-line cases.
__ bind(&ool_min_abc);
__ Float64MinOutOfLine(a, b, c);
__ b(&done_min_abc);
__ Branch(&done_min_abc);
__ bind(&ool_min_aab);
__ Float64MinOutOfLine(a, a, b);
__ b(&done_min_aab);
__ Branch(&done_min_aab);
__ bind(&ool_min_aba);
__ Float64MinOutOfLine(a, b, a);
__ b(&done_min_aba);
__ Branch(&done_min_aba);
__ bind(&ool_max_abc);
__ Float64MaxOutOfLine(a, b, c);
__ b(&done_max_abc);
__ Branch(&done_max_abc);
__ bind(&ool_max_aab);
__ Float64MaxOutOfLine(a, a, b);
__ b(&done_max_aab);
__ Branch(&done_max_aab);
__ bind(&ool_max_aba);
__ Float64MaxOutOfLine(a, b, a);
__ b(&done_max_aba);
__ Branch(&done_max_aba);
CodeDesc desc;
masm->GetCode(&desc);
......
......@@ -2016,27 +2016,27 @@ static ::F4 GenerateMacroFloat32MinMax(MacroAssembler* masm) {
// Generate out-of-line cases.
__ bind(&ool_min_abc);
__ Float32MinOutOfLine(a, b, c);
__ b(&done_min_abc);
__ Branch(&done_min_abc);
__ bind(&ool_min_aab);
__ Float32MinOutOfLine(a, a, b);
__ b(&done_min_aab);
__ Branch(&done_min_aab);
__ bind(&ool_min_aba);
__ Float32MinOutOfLine(a, b, a);
__ b(&done_min_aba);
__ Branch(&done_min_aba);
__ bind(&ool_max_abc);
__ Float32MaxOutOfLine(a, b, c);
__ b(&done_max_abc);
__ Branch(&done_max_abc);
__ bind(&ool_max_aab);
__ Float32MaxOutOfLine(a, a, b);
__ b(&done_max_aab);
__ Branch(&done_max_aab);
__ bind(&ool_max_aba);
__ Float32MaxOutOfLine(a, b, a);
__ b(&done_max_aba);
__ Branch(&done_max_aba);
CodeDesc desc;
masm->GetCode(&desc);
......@@ -2159,27 +2159,27 @@ static ::F4 GenerateMacroFloat64MinMax(MacroAssembler* masm) {
// Generate out-of-line cases.
__ bind(&ool_min_abc);
__ Float64MinOutOfLine(a, b, c);
__ b(&done_min_abc);
__ Branch(&done_min_abc);
__ bind(&ool_min_aab);
__ Float64MinOutOfLine(a, a, b);
__ b(&done_min_aab);
__ Branch(&done_min_aab);
__ bind(&ool_min_aba);
__ Float64MinOutOfLine(a, b, a);
__ b(&done_min_aba);
__ Branch(&done_min_aba);
__ bind(&ool_max_abc);
__ Float64MaxOutOfLine(a, b, c);
__ b(&done_max_abc);
__ Branch(&done_max_abc);
__ bind(&ool_max_aab);
__ Float64MaxOutOfLine(a, a, b);
__ b(&done_max_aab);
__ Branch(&done_max_aab);
__ bind(&ool_max_aba);
__ Float64MaxOutOfLine(a, b, a);
__ b(&done_max_aba);
__ Branch(&done_max_aba);
CodeDesc desc;
masm->GetCode(&desc);
......
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