mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-09 01:08:39 +09:00
Issue #3049 - Add LoongArch minimal JIT div and mod
This commit is contained in:
parent
3faf2d1249
commit
5d3d0a1245
2 changed files with 106 additions and 3 deletions
|
|
@ -88,6 +88,22 @@ function multiplyZero(a) {
|
|||
return a * 0;
|
||||
}
|
||||
|
||||
function divide(a, b) {
|
||||
return a / b;
|
||||
}
|
||||
|
||||
function divideNegativeZero(a) {
|
||||
return 0 / a;
|
||||
}
|
||||
|
||||
function remainder(a, b) {
|
||||
return a % b;
|
||||
}
|
||||
|
||||
function remainderNegativeZero(a) {
|
||||
return a % 2;
|
||||
}
|
||||
|
||||
function assignArg(a, b) {
|
||||
a = a < b;
|
||||
return a;
|
||||
|
|
@ -163,6 +179,14 @@ assertEq(multiply(-3, 7), -21);
|
|||
assertEq(multiply(1073741824, 4), 4294967296);
|
||||
assertEq(multiplyZero(3), 0);
|
||||
assertEq(1 / multiplyZero(-3), -Infinity);
|
||||
assertEq(divide(8, 2), 4);
|
||||
assertEq(divide(-9, 3), -3);
|
||||
assertEq(divide(7, 2), 3.5);
|
||||
assertEq(1 / divideNegativeZero(-3), -Infinity);
|
||||
assertEq(divide(-2147483648, -1), 2147483648);
|
||||
assertEq(remainder(7, 3), 1);
|
||||
assertEq(remainder(8, 2), 0);
|
||||
assertEq(1 / remainderNegativeZero(-4), -Infinity);
|
||||
assertEq(assignArg(2, 3), true);
|
||||
assertEq(assignArg(3, 2), false);
|
||||
assertEq(boolToNumeric(2, 3), 1);
|
||||
|
|
|
|||
|
|
@ -374,6 +374,72 @@ class MinimalLoongArchCompiler
|
|||
return emitFailureBranch();
|
||||
}
|
||||
|
||||
bool emitDiv(LoongArchReg lhs, LoongArchReg rhs, LoongArchReg out) {
|
||||
if (!emitNot(rhs, WideScratch))
|
||||
return false;
|
||||
if (!emitMove(NarrowScratch, zero))
|
||||
return false;
|
||||
if (!emitFailureBranch())
|
||||
return false;
|
||||
|
||||
if (!emitNot(lhs, WideScratch))
|
||||
return false;
|
||||
if (!emit(EncodeThreeReg(0x00120000, NarrowScratch, rhs, zero)))
|
||||
return false;
|
||||
if (!emit(EncodeThreeReg(0x00148000, WideScratch, WideScratch, NarrowScratch)))
|
||||
return false;
|
||||
if (!emitMove(NarrowScratch, zero))
|
||||
return false;
|
||||
if (!emitFailureBranch())
|
||||
return false;
|
||||
|
||||
if (!emitLoadImm32(NarrowScratch, -1))
|
||||
return false;
|
||||
if (!emitEq(rhs, NarrowScratch, WideScratch, false))
|
||||
return false;
|
||||
if (!emitLoadImm32(NarrowScratch, INT32_MIN))
|
||||
return false;
|
||||
if (!emit(EncodeThreeReg(0x00158000, NarrowScratch, lhs, NarrowScratch)))
|
||||
return false;
|
||||
if (!emitSltui(NarrowScratch, NarrowScratch, 1))
|
||||
return false;
|
||||
if (!emit(EncodeThreeReg(0x00148000, WideScratch, WideScratch, NarrowScratch)))
|
||||
return false;
|
||||
if (!emitMove(NarrowScratch, zero))
|
||||
return false;
|
||||
if (!emitFailureBranch())
|
||||
return false;
|
||||
|
||||
if (!emit(EncodeThreeReg(0x00200000, out, lhs, rhs)))
|
||||
return false;
|
||||
if (!emit(EncodeThreeReg(0x00208000, WideScratch, lhs, rhs)))
|
||||
return false;
|
||||
if (!emitMove(NarrowScratch, zero))
|
||||
return false;
|
||||
return emitFailureBranch();
|
||||
}
|
||||
|
||||
bool emitMod(LoongArchReg lhs, LoongArchReg rhs, LoongArchReg out) {
|
||||
if (!emitNot(rhs, WideScratch))
|
||||
return false;
|
||||
if (!emitMove(NarrowScratch, zero))
|
||||
return false;
|
||||
if (!emitFailureBranch())
|
||||
return false;
|
||||
|
||||
if (!emit(EncodeThreeReg(0x00208000, out, lhs, rhs)))
|
||||
return false;
|
||||
if (!emitNot(out, WideScratch))
|
||||
return false;
|
||||
if (!emit(EncodeThreeReg(0x00120000, NarrowScratch, lhs, 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))
|
||||
|
|
@ -634,7 +700,9 @@ class MinimalLoongArchCompiler
|
|||
break;
|
||||
case JSOP_ADD:
|
||||
case JSOP_SUB:
|
||||
case JSOP_MUL: {
|
||||
case JSOP_MUL:
|
||||
case JSOP_DIV:
|
||||
case JSOP_MOD: {
|
||||
StackValue rhs;
|
||||
StackValue lhs;
|
||||
if (!pop(&rhs) || !pop(&lhs))
|
||||
|
|
@ -642,12 +710,23 @@ class MinimalLoongArchCompiler
|
|||
if (!IsNumericKind(lhs.kind) || !IsNumericKind(rhs.kind))
|
||||
return false;
|
||||
LoongArchReg out = allocStackReg();
|
||||
if (op == JSOP_MUL) {
|
||||
switch (op) {
|
||||
case JSOP_MUL:
|
||||
if (!emitMul(lhs.reg, rhs.reg, out))
|
||||
return false;
|
||||
} else {
|
||||
break;
|
||||
case JSOP_DIV:
|
||||
if (!emitDiv(lhs.reg, rhs.reg, out))
|
||||
return false;
|
||||
break;
|
||||
case JSOP_MOD:
|
||||
if (!emitMod(lhs.reg, rhs.reg, out))
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
if (!emitCheckedBinary(op, lhs.reg, rhs.reg, out))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
stack_[stackDepth_++] = { out, MinimalValueKind::Int32 };
|
||||
break;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue