Issue #3049 - Add LoongArch minimal JIT multiply support

This commit is contained in:
Basilisk-Dev 2026-04-22 23:39:10 -04:00 committed by wuggy
commit 3faf2d1249
2 changed files with 47 additions and 3 deletions

View file

@ -80,6 +80,14 @@ function unsignedRightShift(a, b) {
return a >>> b;
}
function multiply(a, b) {
return a * b;
}
function multiplyZero(a) {
return a * 0;
}
function assignArg(a, b) {
a = a < b;
return a;
@ -150,6 +158,11 @@ assertEq(leftShift(1, 33), 2);
assertEq(rightShift(-8, 1), -4);
assertEq(unsignedRightShift(-1, 1), 2147483647);
assertEq(unsignedRightShift(-1, 0), 4294967295);
assertEq(multiply(6, 7), 42);
assertEq(multiply(-3, 7), -21);
assertEq(multiply(1073741824, 4), 4294967296);
assertEq(multiplyZero(3), 0);
assertEq(1 / multiplyZero(-3), -Infinity);
assertEq(assignArg(2, 3), true);
assertEq(assignArg(3, 2), false);
assertEq(boolToNumeric(2, 3), 1);

View file

@ -349,6 +349,31 @@ class MinimalLoongArchCompiler
MOZ_CRASH("bad shift opcode");
}
bool emitMul(LoongArchReg lhs, LoongArchReg rhs, LoongArchReg out) {
if (!emit(EncodeThreeReg(0x001c8000, WideScratch, lhs, rhs)))
return false;
if (!emit(EncodeThreeReg(0x001c0000, out, lhs, rhs)))
return false;
if (!emitLoadImm32(NarrowScratch, 31))
return false;
if (!emit(EncodeThreeReg(0x00180000, NarrowScratch, out, NarrowScratch)))
return false;
if (!emitFailureBranch())
return false;
if (!emitEq(out, zero, WideScratch, false))
return false;
if (!emit(EncodeThreeReg(0x00150000, NarrowScratch, lhs, rhs)))
return false;
if (!emit(EncodeThreeReg(0x00120000, NarrowScratch, NarrowScratch, zero)))
return false;
if (!emit(EncodeThreeReg(0x00148000, WideScratch, WideScratch, NarrowScratch)))
return false;
if (!emitMove(NarrowScratch, zero))
return false;
return emitFailureBranch();
}
bool emitBranch(BranchKind kind, LoongArchReg reg, uint32_t targetPcOffset) {
BranchPatch patch = { wordCount_, targetPcOffset, kind, reg };
if (!branchPatches_.append(patch))
@ -608,7 +633,8 @@ class MinimalLoongArchCompiler
case JSOP_NOP:
break;
case JSOP_ADD:
case JSOP_SUB: {
case JSOP_SUB:
case JSOP_MUL: {
StackValue rhs;
StackValue lhs;
if (!pop(&rhs) || !pop(&lhs))
@ -616,8 +642,13 @@ class MinimalLoongArchCompiler
if (!IsNumericKind(lhs.kind) || !IsNumericKind(rhs.kind))
return false;
LoongArchReg out = allocStackReg();
if (!emitCheckedBinary(op, lhs.reg, rhs.reg, out))
return false;
if (op == JSOP_MUL) {
if (!emitMul(lhs.reg, rhs.reg, out))
return false;
} else {
if (!emitCheckedBinary(op, lhs.reg, rhs.reg, out))
return false;
}
stack_[stackDepth_++] = { out, MinimalValueKind::Int32 };
break;
}