From 9679f714f7c3a1da7af0ddd1c2005f8f7ffd039b Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Tue, 12 May 2020 12:40:13 +0800 Subject: Bug 1441521 : [MIPS] Optimize comparation with small constants Tag: #1542 --- .../jit/mips-shared/MacroAssembler-mips-shared.cpp | 183 ++++++++++++++++----- .../jit/mips-shared/MacroAssembler-mips-shared.h | 1 + js/src/jit/mips32/MacroAssembler-mips32.cpp | 13 -- js/src/jit/mips32/MacroAssembler-mips32.h | 19 ++- js/src/jit/mips64/MacroAssembler-mips64-inl.h | 5 +- js/src/jit/mips64/MacroAssembler-mips64.cpp | 23 +-- 6 files changed, 170 insertions(+), 74 deletions(-) (limited to 'js') diff --git a/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp b/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp index 811fb01f1..3665f3072 100644 --- a/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp +++ b/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp @@ -740,9 +740,17 @@ MacroAssemblerMIPSShared::ma_b(Register lhs, Imm32 imm, Label* label, Condition else branchWithCode(getBranchCode(lhs, c), label, jumpKind); } else { - MOZ_ASSERT(lhs != ScratchRegister); - ma_li(ScratchRegister, imm); - ma_b(lhs, ScratchRegister, label, c, jumpKind); + switch (c) { + case Equal: + case NotEqual: + MOZ_ASSERT(lhs != ScratchRegister); + ma_li(ScratchRegister, imm); + ma_b(lhs, ScratchRegister, label, c, jumpKind); + break; + default: + Condition cond = ma_cmp(ScratchRegister, lhs, imm, c); + asMasm().branchWithCode(getBranchCode(ScratchRegister, cond), label, jumpKind); + } } } @@ -862,20 +870,59 @@ MacroAssemblerMIPSShared::ma_cmp(Register scratch, Register lhs, Register rhs, C // beq at,$zero,offs as_slt(scratch, rhs, lhs); return Equal; - case Equal : - case NotEqual: - case Zero: - case NonZero: - case Always: - case Signed: - case NotSigned: - MOZ_CRASH("There is a better way to compare for equality."); - break; - case Overflow: - MOZ_CRASH("Overflow condition not supported for MIPS."); - break; default: - MOZ_CRASH("Invalid condition for branch."); + MOZ_CRASH("Invalid condition."); + } + return Always; +} + +Assembler::Condition +MacroAssemblerMIPSShared::ma_cmp(Register scratch, Register lhs, Imm32 imm, Condition c) +{ + switch (c) { + case Above: + case BelowOrEqual: + if (Imm16::IsInSignedRange(imm.value + 1) && imm.value != -1) { + // lhs <= rhs via lhs < rhs + 1 if rhs + 1 does not overflow + as_sltiu(scratch, lhs, imm.value + 1); + + return (c == BelowOrEqual ? NotEqual : Equal); + } else { + ma_li(scratch, imm); + as_sltu(scratch, scratch, lhs); + return (c == BelowOrEqual ? Equal : NotEqual); + } + case AboveOrEqual: + case Below: + if (Imm16::IsInSignedRange(imm.value)) { + as_sltiu(scratch, lhs, imm.value); + } else { + ma_li(scratch, imm); + as_sltu(scratch, lhs, scratch); + } + return (c == AboveOrEqual ? Equal : NotEqual); + case GreaterThan: + case LessThanOrEqual: + if (Imm16::IsInSignedRange(imm.value + 1)) { + // lhs <= rhs via lhs < rhs + 1. + as_slti(scratch, lhs, imm.value + 1); + return (c == LessThanOrEqual ? NotEqual : Equal); + } else { + ma_li(scratch, imm); + as_slt(scratch, scratch, lhs); + return (c == LessThanOrEqual ? Equal : NotEqual); + } + case GreaterThanOrEqual: + case LessThan: + if (Imm16::IsInSignedRange(imm.value)) { + as_slti(scratch, lhs, imm.value); + } else { + ma_li(scratch, imm); + as_slt(scratch, lhs, scratch); + } + return (c == GreaterThanOrEqual ? Equal : NotEqual); + default: + MOZ_CRASH("Invalid condition."); } return Always; } @@ -947,22 +994,21 @@ MacroAssemblerMIPSShared::ma_cmp_set(Register rd, Register rs, Register rt, Cond case Zero: MOZ_ASSERT(rs == rt); // seq d,s,$zero => - // xor d,s,$zero - // sltiu d,d,1 - as_xor(rd, rs, zero); - as_sltiu(rd, rd, 1); + // sltiu d,s,1 + as_sltiu(rd, rs, 1); break; case NonZero: + MOZ_ASSERT(rs == rt); // sne d,s,$zero => - // xor d,s,$zero - // sltu d,$zero,d - as_xor(rd, rs, zero); - as_sltu(rd, zero, rd); + // sltu d,$zero,s + as_sltu(rd, zero, rs); break; case Signed: + MOZ_ASSERT(rs == rt); as_slt(rd, rs, zero); break; case NotSigned: + MOZ_ASSERT(rs == rt); // sge d,s,$zero => // slt d,s,$zero // xori d,d,1 @@ -970,7 +1016,7 @@ MacroAssemblerMIPSShared::ma_cmp_set(Register rd, Register rs, Register rt, Cond as_xori(rd, rd, 1); break; default: - MOZ_CRASH("Invalid condition for ma_cmp_set."); + MOZ_CRASH("Invalid condition."); } } @@ -1067,39 +1113,102 @@ void MacroAssemblerMIPSShared::ma_cmp_set_double(Register dest, FloatRegister lhs, FloatRegister rhs, DoubleCondition c) { - ma_li(dest, Imm32(0)); - ma_li(ScratchRegister, Imm32(1)); - FloatTestKind moveCondition; compareFloatingPoint(DoubleFloat, lhs, rhs, c, &moveCondition); + ma_li(dest, Imm32(1)); + if (moveCondition == TestForTrue) - as_movt(dest, ScratchRegister); + as_movf(dest, zero); else - as_movf(dest, ScratchRegister); + as_movt(dest, zero); } void MacroAssemblerMIPSShared::ma_cmp_set_float32(Register dest, FloatRegister lhs, FloatRegister rhs, DoubleCondition c) { - ma_li(dest, Imm32(0)); - ma_li(ScratchRegister, Imm32(1)); - FloatTestKind moveCondition; compareFloatingPoint(SingleFloat, lhs, rhs, c, &moveCondition); + ma_li(dest, Imm32(1)); + if (moveCondition == TestForTrue) - as_movt(dest, ScratchRegister); + as_movf(dest, zero); else - as_movf(dest, ScratchRegister); + as_movt(dest, zero); } void MacroAssemblerMIPSShared::ma_cmp_set(Register rd, Register rs, Imm32 imm, Condition c) { - ma_li(ScratchRegister, imm); - ma_cmp_set(rd, rs, ScratchRegister, c); + if (imm.value == 0) { + switch (c) { + case Equal : + case BelowOrEqual: + as_sltiu(rd, rs, 1); + break; + case NotEqual: + case Above: + as_sltu(rd, zero, rs); + break; + case AboveOrEqual: + case Below: + as_ori(rd, zero, c == AboveOrEqual ? 1: 0); + break; + case GreaterThan: + case LessThanOrEqual: + as_slt(rd, zero, rs); + if (c == LessThanOrEqual) + as_xori(rd, rd, 1); + break; + case LessThan: + case GreaterThanOrEqual: + as_slt(rd, rs, zero); + if (c == GreaterThanOrEqual) + as_xori(rd, rd, 1); + break; + case Zero: + as_sltiu(rd, rs, 1); + break; + case NonZero: + as_sltu(rd, zero, rs); + break; + case Signed: + as_slt(rd, rs, zero); + break; + case NotSigned: + as_slt(rd, rs, zero); + as_xori(rd, rd, 1); + break; + default: + MOZ_CRASH("Invalid condition."); + } + return; + } + + switch (c) { + case Equal: + case NotEqual: + MOZ_ASSERT(rs != ScratchRegister); + ma_xor(rd, rs, imm); + if (c == Equal) + as_sltiu(rd, rd, 1); + else + as_sltu(rd, zero, rd); + break; + case Zero: + case NonZero: + case Signed: + case NotSigned: + MOZ_CRASH("Invalid condition."); + default: + Condition cond = ma_cmp(rd, rs, imm, c); + MOZ_ASSERT(cond == Equal || cond == NotEqual); + + if(cond == Equal) + as_xori(rd, rd, 1); + } } // fp instructions diff --git a/js/src/jit/mips-shared/MacroAssembler-mips-shared.h b/js/src/jit/mips-shared/MacroAssembler-mips-shared.h index 304610991..cd75b2e37 100644 --- a/js/src/jit/mips-shared/MacroAssembler-mips-shared.h +++ b/js/src/jit/mips-shared/MacroAssembler-mips-shared.h @@ -54,6 +54,7 @@ class MacroAssemblerMIPSShared : public Assembler const MacroAssembler& asMasm() const; Condition ma_cmp(Register rd, Register lhs, Register rhs, Condition c); + Condition ma_cmp(Register rd, Register lhs, Imm32 imm, Condition c); void compareFloatingPoint(FloatFormat fmt, FloatRegister lhs, FloatRegister rhs, DoubleCondition c, FloatTestKind* testKind, diff --git a/js/src/jit/mips32/MacroAssembler-mips32.cpp b/js/src/jit/mips32/MacroAssembler-mips32.cpp index b4a148d8f..7472ed78b 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.cpp +++ b/js/src/jit/mips32/MacroAssembler-mips32.cpp @@ -503,19 +503,6 @@ MacroAssemblerMIPS::ma_b(Address addr, ImmGCPtr imm, Label* label, Condition c, ma_b(SecondScratchReg, imm, label, c, jumpKind); } -void -MacroAssemblerMIPS::ma_cmp_set(Register rd, Register rs, Address addr, Condition c) -{ - ma_lw(ScratchRegister, addr); - ma_cmp_set(rd, rs, ScratchRegister, c); -} - -void -MacroAssemblerMIPS::ma_cmp_set(Register dst, Address lhs, Register rhs, Condition c) -{ - ma_lw(ScratchRegister, lhs); - ma_cmp_set(dst, ScratchRegister, rhs, c); -} // fp instructions void diff --git a/js/src/jit/mips32/MacroAssembler-mips32.h b/js/src/jit/mips32/MacroAssembler-mips32.h index 69e7c4fe5..37d279b09 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.h +++ b/js/src/jit/mips32/MacroAssembler-mips32.h @@ -104,7 +104,7 @@ class MacroAssemblerMIPS : public MacroAssemblerMIPSShared void ma_b(Address addr, ImmGCPtr imm, Label* l, Condition c, JumpKind jumpKind = MixedJump); void ma_b(Address addr, Register rhs, Label* l, Condition c, JumpKind jumpKind = MixedJump) { MOZ_ASSERT(rhs != ScratchRegister); - ma_load(ScratchRegister, addr, SizeWord); + ma_lw(ScratchRegister, addr); ma_b(ScratchRegister, rhs, l, c, jumpKind); } @@ -125,12 +125,19 @@ class MacroAssemblerMIPS : public MacroAssemblerMIPSShared void ma_cmp_set(Register dst, Register lhs, ImmPtr imm, Condition c) { ma_cmp_set(dst, lhs, Imm32(uint32_t(imm.value)), c); } - void ma_cmp_set(Register rd, Register rs, Address addr, Condition c); - void ma_cmp_set(Register dst, Address lhs, Register rhs, Condition c); - void ma_cmp_set(Register dst, Address lhs, ImmPtr imm, Condition c) { + void ma_cmp_set(Register dst, Register lhs, Address addr, Condition c) { + MOZ_ASSERT(lhs != ScratchRegister); + ma_lw(ScratchRegister, addr); + ma_cmp_set(dst, lhs, ScratchRegister, c); + } + void ma_cmp_set(Register dst, Address lhs, Register rhs, Condition c) { + MOZ_ASSERT(rhs != ScratchRegister); ma_lw(ScratchRegister, lhs); - ma_li(SecondScratchReg, Imm32(uint32_t(imm.value))); - ma_cmp_set(dst, ScratchRegister, SecondScratchReg, c); + ma_cmp_set(dst, ScratchRegister, rhs, c); + } + void ma_cmp_set(Register dst, Address lhs, ImmPtr imm, Condition c) { + ma_lw(SecondScratchReg, lhs); + ma_cmp_set(dst, SecondScratchReg, imm, c); } // These fuctions abstract the access to high part of the double precision diff --git a/js/src/jit/mips64/MacroAssembler-mips64-inl.h b/js/src/jit/mips64/MacroAssembler-mips64-inl.h index 7d42c249c..e88122f57 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64-inl.h +++ b/js/src/jit/mips64/MacroAssembler-mips64-inl.h @@ -726,9 +726,8 @@ inline void MacroAssembler::cmpPtrSet(Assembler::Condition cond, Address lhs, ImmPtr rhs, Register dest) { - loadPtr(lhs, ScratchRegister); - movePtr(rhs, SecondScratchReg); - cmpPtrSet(cond, ScratchRegister, SecondScratchReg, dest); + loadPtr(lhs, SecondScratchReg); + cmpPtrSet(cond, SecondScratchReg, rhs, dest); } template<> diff --git a/js/src/jit/mips64/MacroAssembler-mips64.cpp b/js/src/jit/mips64/MacroAssembler-mips64.cpp index d283d0b4c..9604e38a4 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.cpp +++ b/js/src/jit/mips64/MacroAssembler-mips64.cpp @@ -719,14 +719,8 @@ MacroAssemblerMIPS64::ma_push(Register r) void MacroAssemblerMIPS64::ma_b(Register lhs, ImmWord imm, Label* label, Condition c, JumpKind jumpKind) { - MOZ_ASSERT(c != Overflow); - if (imm.value == 0) { - if (c == Always || c == AboveOrEqual) - ma_b(label, jumpKind); - else if (c == Below) - ; // This condition is always false. No branch required. - else - branchWithCode(getBranchCode(lhs, c), label, jumpKind); + if (imm.value <= INT32_MAX) { + ma_b(lhs, Imm32(uint32_t(imm.value)), label, c, jumpKind); } else { MOZ_ASSERT(lhs != ScratchRegister); ma_li(ScratchRegister, imm); @@ -759,19 +753,18 @@ MacroAssemblerMIPS64::ma_b(Address addr, ImmGCPtr imm, Label* label, Condition c void MacroAssemblerMIPS64::ma_cmp_set(Register rd, Register rs, ImmWord imm, Condition c) { - if (imm.value == 0) { - ma_cmp_set(rd, rs, zero, c); - return; + if (imm.value <= INT32_MAX) { + ma_cmp_set(rd, rs, Imm32(uint32_t(imm.value)), c); + } else { + ma_li(ScratchRegister, imm); + ma_cmp_set(rd, rs, ScratchRegister, c); } - ma_li(ScratchRegister, imm); - ma_cmp_set(rd, rs, ScratchRegister, c); } void MacroAssemblerMIPS64::ma_cmp_set(Register rd, Register rs, ImmPtr imm, Condition c) { - ma_li(ScratchRegister, ImmWord(uintptr_t(imm.value))); - ma_cmp_set(rd, rs, ScratchRegister, c); + ma_cmp_set(rd, rs, ImmWord(uintptr_t(imm.value)), c); } // fp instructions -- cgit v1.2.3