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