commit a17432cf9e6ade72d7da4f778c2083474bd190fa
parent 704154b7849cdccaaadae7d7f9982108fe7d4812
Author: Xuan Chen <henry.chen@oss.cipunited.com>
Date: Tue, 11 Nov 2025 18:04:47 +0000
Bug 1997517 - Part 4: [mips64] Fix callers of R2-only instructions. r=anba
This patch fixes direct usage of R2 instructions and exhaustion of scratch
registers when emulating R2 instructions.
Differential Revision: https://phabricator.services.mozilla.com/D271759
Diffstat:
3 files changed, 45 insertions(+), 16 deletions(-)
diff --git a/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h b/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h
@@ -132,7 +132,7 @@ void MacroAssembler::byteSwap16ZeroExtend(Register reg) {
void MacroAssembler::byteSwap32(Register reg) {
ma_wsbh(reg, reg);
- as_rotr(reg, reg, 16);
+ ma_ror(reg, reg, Imm32(16));
}
// ===============================================================
diff --git a/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp b/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp
@@ -550,14 +550,19 @@ void MacroAssemblerMIPSShared::ma_load_unaligned(Register dest,
as_lb(scratch, base, hiOffset);
}
as_lbu(dest, base, lowOffset);
- ma_ins(dest, scratch, 8, 24);
+ if (hasR2()) {
+ as_ins(dest, scratch, 8, 24);
+ } else {
+ as_sll(scratch, scratch, 8);
+ as_or(dest, dest, scratch);
+ }
break;
case SizeWord:
MOZ_ASSERT(dest != base);
as_lwl(dest, base, hiOffset);
as_lwr(dest, base, lowOffset);
if (extension == ZeroExtend) {
- as_dext(dest, dest, 0, 32);
+ asMasm().ma_dext(dest, dest, Imm32(0), Imm32(32));
}
break;
case SizeDouble:
@@ -602,7 +607,12 @@ void MacroAssemblerMIPSShared::ma_load_unaligned(Register dest,
as_lb(scratch2, base, hiOffset);
}
as_lbu(dest, base, lowOffset);
- ma_ins(dest, scratch2, 8, 24);
+ if (hasR2()) {
+ as_ins(dest, scratch2, 8, 24);
+ } else {
+ as_sll(scratch2, scratch2, 8);
+ as_or(dest, dest, scratch2);
+ }
break;
case SizeWord:
MOZ_ASSERT(dest != base);
@@ -659,13 +669,18 @@ void MacroAssemblerMIPSShared::ma_load_unaligned(
load = as_lb(temp, base, hiOffset);
}
as_lbu(dest, base, lowOffset);
- ma_ins(dest, temp, 8, 24);
+ if (hasR2()) {
+ as_ins(dest, temp, 8, 24);
+ } else {
+ as_sll(temp, temp, 8);
+ as_or(dest, dest, temp);
+ }
break;
case SizeWord:
load = as_lwl(dest, base, hiOffset);
as_lwr(dest, base, lowOffset);
if (extension == ZeroExtend) {
- as_dext(dest, dest, 0, 32);
+ asMasm().ma_dext(dest, dest, Imm32(0), Imm32(32));
}
break;
case SizeDouble:
@@ -3433,8 +3448,14 @@ void MacroAssembler::copySignDouble(FloatRegister lhs, FloatRegister rhs,
moveFromDouble(rhs, rhsi);
// Combine.
- ma_dins(rhsi, lhsi, Imm32(0), Imm32(63));
-
+ if (hasR2()) {
+ ma_dins(rhsi, lhsi, Imm32(0), Imm32(63));
+ } else {
+ ma_dext(lhsi, lhsi, Imm32(0), Imm32(63));
+ ma_dsrl(rhsi, rhsi, Imm32(63));
+ ma_dsll(rhsi, rhsi, Imm32(63));
+ as_or(rhsi, rhsi, lhsi);
+ }
moveToDouble(rhsi, output);
}
@@ -3448,8 +3469,14 @@ void MacroAssembler::copySignFloat32(FloatRegister lhs, FloatRegister rhs,
moveFromFloat32(rhs, rhsi);
// Combine.
- ma_ins(rhsi, lhsi, 0, 31);
-
+ if (hasR2()) {
+ ma_ins(rhsi, lhsi, 0, 31);
+ } else {
+ ma_ext(lhsi, lhsi, 0, 31);
+ ma_srl(rhsi, rhsi, Imm32(31));
+ ma_sll(rhsi, rhsi, Imm32(31));
+ as_or(rhsi, rhsi, lhsi);
+ }
moveToFloat32(rhsi, output);
}
diff --git a/js/src/jit/mips64/MacroAssembler-mips64.cpp b/js/src/jit/mips64/MacroAssembler-mips64.cpp
@@ -221,7 +221,8 @@ void MacroAssemblerMIPS64::ma_li(Register dest, ImmWord imm) {
as_lui(dest, uint16_t(value >> 16));
} else if (0 == (value >> 32)) {
as_lui(dest, uint16_t(value >> 16));
- as_dinsu(dest, zero, 32, 32);
+ // mips spec recommends dinsu but it is unfriendly to mips3
+ ma_dext(dest, dest, Imm32(0), Imm32(32));
} else if (-1 == (value >> 47) || 0 == (value >> 47)) {
as_lui(dest, uint16_t(value >> 32));
if (uint16_t(value >> 16)) {
@@ -230,7 +231,8 @@ void MacroAssemblerMIPS64::ma_li(Register dest, ImmWord imm) {
as_dsll(dest, dest, 16);
} else if (0 == (value >> 48)) {
as_lui(dest, uint16_t(value >> 32));
- as_dinsu(dest, zero, 32, 32);
+ // mips spec recommends dinsu but it is unfriendly to mips3
+ ma_dext(dest, dest, Imm32(0), Imm32(32));
if (uint16_t(value >> 16)) {
as_ori(dest, dest, uint16_t(value >> 16));
}
@@ -1990,7 +1992,7 @@ void MacroAssemblerMIPS64Compat::boxValue(JSValueType type, Register src,
if (type == JSVAL_TYPE_INT32) {
ma_dins(dest, src, Imm32(0), Imm32(32));
} else {
- ma_dins(dest, src, Imm32(0), Imm32(JSVAL_TAG_SHIFT));
+ as_or(dest, dest, src);
}
}
@@ -2228,7 +2230,7 @@ void MacroAssemblerMIPS64Compat::tagValue(JSValueType type, Register payload,
ma_li(scratch, Imm32(shifted));
// Insert tag into the result.
- as_dinsu(dest.valueReg(), scratch, 32, 32);
+ ma_dins(dest.valueReg(), scratch, Imm32(32), Imm32(32));
return;
}
case JSVAL_TYPE_STRING:
@@ -2246,8 +2248,8 @@ void MacroAssemblerMIPS64Compat::tagValue(JSValueType type, Register payload,
as_daddiu(scratch, zero, signExtendedShiftedTag);
// Insert tag into the result.
- as_dinsu(dest.valueReg(), scratch, JSVAL_TAG_SHIFT,
- 64 - JSVAL_TAG_SHIFT);
+ ma_dins(dest.valueReg(), scratch, Imm32(JSVAL_TAG_SHIFT),
+ Imm32(64 - JSVAL_TAG_SHIFT));
return;
}
case JSVAL_TYPE_DOUBLE: