commit 0fdd4ee10cf23a943043fe788f9c909a3f6e5811
parent 9aa3304e2fa4134ff8306ee1a69a6f1b00cc3bc7
Author: André Bargull <andre.bargull@gmail.com>
Date: Thu, 23 Oct 2025 09:56:07 +0000
Bug 1995489: Use 64-bit multiplication for ma_mul32TestOverflow. r=spidermonkey-reviewers,iain
- GCC and Clang both use 64-bit multiplication for `__builtin_mul_overflow` on loong64.
- On mips64, GCC uses 64-bit multiplication, whereas Clang uses `mult` + `mul` (mips64r2)
resp. `mul` + `muh` (mips64r6). Let's use the GCC approach for consistency with loong64
and riscv64.
Differential Revision: https://phabricator.services.mozilla.com/D269355
Diffstat:
3 files changed, 26 insertions(+), 27 deletions(-)
diff --git a/js/src/jit/loong64/MacroAssembler-loong64.cpp b/js/src/jit/loong64/MacroAssembler-loong64.cpp
@@ -1621,23 +1621,19 @@ void MacroAssemblerLOONG64::ma_mul32TestOverflow(Register rd, Register rj,
Register rk, Label* overflow) {
UseScratchRegisterScope temps(asMasm());
Register scratch = temps.Acquire();
- Register scratch2 = temps.Acquire();
- as_mulh_w(scratch, rj, rk);
- as_mul_w(rd, rj, rk);
- as_srai_w(scratch2, rd, 31);
- ma_b(scratch, Register(scratch2), overflow, Assembler::NotEqual);
+ as_mul_d(rd, rj, rk);
+ as_slli_w(scratch, rd, 0);
+ ma_b(rd, scratch, overflow, Assembler::NotEqual);
}
void MacroAssemblerLOONG64::ma_mul32TestOverflow(Register rd, Register rj,
Imm32 imm, Label* overflow) {
UseScratchRegisterScope temps(asMasm());
Register scratch = temps.Acquire();
- Register scratch2 = temps.Acquire();
ma_li(scratch, imm);
- as_mulh_w(scratch2, rj, scratch);
- as_mul_w(rd, rj, scratch);
- as_srai_w(scratch, rd, 31);
- ma_b(scratch, Register(scratch2), overflow, Assembler::NotEqual);
+ as_mul_d(rd, rj, scratch);
+ as_slli_w(scratch, rd, 0);
+ ma_b(rd, scratch, overflow, Assembler::NotEqual);
}
void MacroAssemblerLOONG64::ma_div_branch_overflow(Register rd, Register rj,
diff --git a/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp b/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp
@@ -357,29 +357,33 @@ void MacroAssemblerMIPSShared::ma_mul32TestOverflow(Register rd, Register rs,
Register rt,
Label* overflow) {
UseScratchRegisterScope temps(*this);
- Register scratch2 = temps.Acquire();
Register scratch = temps.Acquire();
+
#ifdef MIPSR6
- if (rd == rs) {
- ma_move(scratch2, rs);
- rs = scratch2;
- }
- as_mul(rd, rs, rt);
- as_muh(scratch2, rs, rt);
+ as_dmul(rd, rs, rt);
#else
- as_mult(rs, rt);
+ as_dmult(rs, rt);
as_mflo(rd);
- as_mfhi(scratch2);
#endif
- as_sra(scratch, rd, 31);
- ma_b(scratch, scratch2, overflow, Assembler::NotEqual);
+ ma_sll(scratch, rd, Imm32(0));
+ ma_b(rd, scratch, overflow, Assembler::NotEqual);
}
void MacroAssemblerMIPSShared::ma_mul32TestOverflow(Register rd, Register rs,
Imm32 imm,
Label* overflow) {
- ma_li(rd, imm);
- ma_mul32TestOverflow(rd, rs, rd, overflow);
+ UseScratchRegisterScope temps(*this);
+ Register scratch = temps.Acquire();
+
+ ma_li(scratch, imm);
+#ifdef MIPSR6
+ as_dmul(rd, rs, scratch);
+#else
+ as_dmult(rs, scratch);
+ as_mflo(rd);
+#endif
+ ma_sll(scratch, rd, Imm32(0));
+ ma_b(rd, scratch, overflow, Assembler::NotEqual);
}
void MacroAssemblerMIPSShared::ma_div_branch_overflow(Register rd, Register rs,
diff --git a/js/src/jit/riscv64/MacroAssembler-riscv64.cpp b/js/src/jit/riscv64/MacroAssembler-riscv64.cpp
@@ -4762,12 +4762,11 @@ void MacroAssemblerRiscv64::ma_mul32TestOverflow(Register rd, Register rj,
Imm32 imm, Label* overflow) {
UseScratchRegisterScope temps(this);
Register scratch = temps.Acquire();
- Register scratch2 = temps.Acquire();
- MOZ_ASSERT(rd != scratch && rj != scratch2);
+ MOZ_ASSERT(rd != scratch && rj != scratch);
- ma_li(scratch2, imm);
+ ma_li(scratch, imm);
- mul(rd, rj, scratch2);
+ mul(rd, rj, scratch);
sext_w(scratch, rd);
ma_b(scratch, rd, overflow, Assembler::NotEqual);
}