Index: src/mips64/macro-assembler-mips64.cc |
diff --git a/src/mips64/macro-assembler-mips64.cc b/src/mips64/macro-assembler-mips64.cc |
index 9b5be9b2c654d1afa3c8711916f47b4e7762f855..fbbb8b75d7a070c4a70754a0727091f4c5e08bba 100644 |
--- a/src/mips64/macro-assembler-mips64.cc |
+++ b/src/mips64/macro-assembler-mips64.cc |
@@ -2524,186 +2524,6 @@ void MacroAssembler::Movf(Register rd, Register rs, uint16_t cc) { |
movf(rd, rs, cc); |
} |
-#define __ masm-> |
- |
-static bool ZeroHelper_d(MacroAssembler* masm, MaxMinKind kind, FPURegister dst, |
- FPURegister src1, FPURegister src2, Label* equal) { |
- if (src1.is(src2)) { |
- __ Move(dst, src1); |
- return true; |
- } |
- |
- Label other, compare_not_equal; |
- FPURegister left, right; |
- if (kind == MaxMinKind::kMin) { |
- left = src1; |
- right = src2; |
- } else { |
- left = src2; |
- right = src1; |
- } |
- |
- __ BranchF64(&compare_not_equal, nullptr, ne, src1, src2); |
- // Left and right hand side are equal, check for -0 vs. +0. |
- __ dmfc1(t8, src1); |
- __ Branch(&other, eq, t8, Operand(0x8000000000000000)); |
- __ Move_d(dst, right); |
- __ Branch(equal); |
- __ bind(&other); |
- __ Move_d(dst, left); |
- __ Branch(equal); |
- __ bind(&compare_not_equal); |
- return false; |
-} |
- |
-static bool ZeroHelper_s(MacroAssembler* masm, MaxMinKind kind, FPURegister dst, |
- FPURegister src1, FPURegister src2, Label* equal) { |
- if (src1.is(src2)) { |
- __ Move(dst, src1); |
- return true; |
- } |
- |
- Label other, compare_not_equal; |
- FPURegister left, right; |
- if (kind == MaxMinKind::kMin) { |
- left = src1; |
- right = src2; |
- } else { |
- left = src2; |
- right = src1; |
- } |
- |
- __ BranchF32(&compare_not_equal, nullptr, ne, src1, src2); |
- // Left and right hand side are equal, check for -0 vs. +0. |
- __ FmoveLow(t8, src1); |
- __ dsll32(t8, t8, 0); |
- __ Branch(&other, eq, t8, Operand(0x8000000000000000)); |
- __ Move_s(dst, right); |
- __ Branch(equal); |
- __ bind(&other); |
- __ Move_s(dst, left); |
- __ Branch(equal); |
- __ bind(&compare_not_equal); |
- return false; |
-} |
- |
-#undef __ |
- |
-void MacroAssembler::MinNaNCheck_d(FPURegister dst, FPURegister src1, |
- FPURegister src2, Label* nan) { |
- if (nan) { |
- BranchF64(nullptr, nan, eq, src1, src2); |
- } |
- if (kArchVariant >= kMips64r6) { |
- min_d(dst, src1, src2); |
- } else { |
- Label skip; |
- if (!ZeroHelper_d(this, MaxMinKind::kMin, dst, src1, src2, &skip)) { |
- if (dst.is(src1)) { |
- BranchF64(&skip, nullptr, le, src1, src2); |
- Move_d(dst, src2); |
- } else if (dst.is(src2)) { |
- BranchF64(&skip, nullptr, ge, src1, src2); |
- Move_d(dst, src1); |
- } else { |
- Label right; |
- BranchF64(&right, nullptr, gt, src1, src2); |
- Move_d(dst, src1); |
- Branch(&skip); |
- bind(&right); |
- Move_d(dst, src2); |
- } |
- } |
- bind(&skip); |
- } |
-} |
- |
-void MacroAssembler::MaxNaNCheck_d(FPURegister dst, FPURegister src1, |
- FPURegister src2, Label* nan) { |
- if (nan) { |
- BranchF64(nullptr, nan, eq, src1, src2); |
- } |
- if (kArchVariant >= kMips64r6) { |
- max_d(dst, src1, src2); |
- } else { |
- Label skip; |
- if (!ZeroHelper_d(this, MaxMinKind::kMax, dst, src1, src2, &skip)) { |
- if (dst.is(src1)) { |
- BranchF64(&skip, nullptr, ge, src1, src2); |
- Move_d(dst, src2); |
- } else if (dst.is(src2)) { |
- BranchF64(&skip, nullptr, le, src1, src2); |
- Move_d(dst, src1); |
- } else { |
- Label right; |
- BranchF64(&right, nullptr, lt, src1, src2); |
- Move_d(dst, src1); |
- Branch(&skip); |
- bind(&right); |
- Move_d(dst, src2); |
- } |
- } |
- bind(&skip); |
- } |
-} |
- |
-void MacroAssembler::MinNaNCheck_s(FPURegister dst, FPURegister src1, |
- FPURegister src2, Label* nan) { |
- if (nan) { |
- BranchF32(nullptr, nan, eq, src1, src2); |
- } |
- if (kArchVariant >= kMips64r6) { |
- min_s(dst, src1, src2); |
- } else { |
- Label skip; |
- if (!ZeroHelper_s(this, MaxMinKind::kMin, dst, src1, src2, &skip)) { |
- if (dst.is(src1)) { |
- BranchF32(&skip, nullptr, le, src1, src2); |
- Move_s(dst, src2); |
- } else if (dst.is(src2)) { |
- BranchF32(&skip, nullptr, ge, src1, src2); |
- Move_s(dst, src1); |
- } else { |
- Label right; |
- BranchF32(&right, nullptr, gt, src1, src2); |
- Move_s(dst, src1); |
- Branch(&skip); |
- bind(&right); |
- Move_s(dst, src2); |
- } |
- } |
- bind(&skip); |
- } |
-} |
- |
-void MacroAssembler::MaxNaNCheck_s(FPURegister dst, FPURegister src1, |
- FPURegister src2, Label* nan) { |
- if (nan) { |
- BranchF32(nullptr, nan, eq, src1, src2); |
- } |
- if (kArchVariant >= kMips64r6) { |
- max_s(dst, src1, src2); |
- } else { |
- Label skip; |
- if (!ZeroHelper_s(this, MaxMinKind::kMax, dst, src1, src2, &skip)) { |
- if (dst.is(src1)) { |
- BranchF32(&skip, nullptr, ge, src1, src2); |
- Move_s(dst, src2); |
- } else if (dst.is(src2)) { |
- BranchF32(&skip, nullptr, le, src1, src2); |
- Move_s(dst, src1); |
- } else { |
- Label right; |
- BranchF32(&right, nullptr, lt, src1, src2); |
- Move_s(dst, src1); |
- Branch(&skip); |
- bind(&right); |
- Move_s(dst, src2); |
- } |
- } |
- bind(&skip); |
- } |
-} |
void MacroAssembler::Clz(Register rd, Register rs) { |
clz(rd, rs); |
@@ -6480,6 +6300,203 @@ void MacroAssembler::JumpIfNotBothSequentialOneByteStrings(Register first, |
scratch2, failure); |
} |
+void MacroAssembler::Float32Max(FPURegister dst, FPURegister src1, |
+ FPURegister src2, Label* out_of_line) { |
+ DCHECK(!src1.is(src2)); |
+ |
+ // Check if one of operands is NaN. |
+ BranchF32(nullptr, out_of_line, eq, src1, src2); |
+ |
+ if (kArchVariant >= kMips64r6) { |
+ max_s(dst, src1, src2); |
+ } 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(); |
+ |
+ // 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(); |
+ |
+ bind(&return_right); |
+ if (!src2.is(dst)) { |
+ Move_s(dst, src2); |
+ } |
+ b(&done); |
+ nop(); |
+ |
+ bind(&return_left); |
+ if (!src1.is(dst)) { |
+ Move_s(dst, src1); |
+ } |
+ |
+ bind(&done); |
+ } |
+} |
+ |
+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)); |
+ |
+ // Check if one of operands is NaN. |
+ BranchF32(nullptr, out_of_line, eq, src1, src2); |
+ |
+ if (kArchVariant >= kMips64r6) { |
+ min_s(dst, src1, src2); |
+ } 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(); |
+ |
+ // Left equals right => check for -0. |
+ mfc1(t8, src1); |
+ dsll32(t8, t8, 0); |
+ beq(t8, zero_reg, &return_right); |
+ nop(); |
+ b(&return_left); |
+ nop(); |
+ |
+ bind(&return_right); |
+ if (!src2.is(dst)) { |
+ Move_s(dst, src2); |
+ } |
+ b(&done); |
+ nop(); |
+ |
+ bind(&return_left); |
+ if (!src1.is(dst)) { |
+ Move_s(dst, src1); |
+ } |
+ |
+ bind(&done); |
+ } |
+} |
+ |
+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)); |
+ |
+ // Check if one of operands is NaN. |
+ BranchF64(nullptr, out_of_line, eq, src1, src2); |
+ |
+ if (kArchVariant >= kMips64r6) { |
+ max_d(dst, src1, src2); |
+ } 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(); |
+ |
+ // Left equals right => check for -0. |
+ dmfc1(t8, src1); |
+ beq(t8, zero_reg, &return_left); |
+ nop(); |
+ b(&return_right); |
+ nop(); |
+ |
+ bind(&return_right); |
+ if (!src2.is(dst)) { |
+ Move_d(dst, src2); |
+ } |
+ b(&done); |
+ nop(); |
+ |
+ bind(&return_left); |
+ if (!src1.is(dst)) { |
+ Move_d(dst, src1); |
+ } |
+ |
+ bind(&done); |
+ } |
+} |
+ |
+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)); |
+ |
+ // Check if one of operands is NaN. |
+ BranchF64(nullptr, out_of_line, eq, src1, src2); |
+ |
+ if (kArchVariant >= kMips64r6) { |
+ min_d(dst, src1, src2); |
+ } 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(); |
+ |
+ // Left equals right => check for -0. |
+ dmfc1(t8, src1); |
+ beq(t8, zero_reg, &return_right); |
+ nop(); |
+ b(&return_left); |
+ nop(); |
+ |
+ bind(&return_right); |
+ if (!src2.is(dst)) { |
+ Move_d(dst, src2); |
+ } |
+ b(&done); |
+ nop(); |
+ |
+ bind(&return_left); |
+ if (!src1.is(dst)) { |
+ Move_d(dst, src1); |
+ } |
+ |
+ bind(&done); |
+ } |
+} |
+ |
+void MacroAssembler::Float64MinOutOfLine(FPURegister dst, FPURegister src1, |
+ FPURegister src2) { |
+ DCHECK(!src1.is(src2)); |
+ add_d(dst, src1, src2); |
+} |
void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte( |
Register first, Register second, Register scratch1, Register scratch2, |