mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-30 12:27:29 +09:00
Issue #3049 - Support more LoongArch minimal JIT branch ops
This commit is contained in:
parent
460765fc80
commit
43a6d946f8
2 changed files with 180 additions and 0 deletions
|
|
@ -192,6 +192,70 @@ function sumRange(n) {
|
|||
return total;
|
||||
}
|
||||
|
||||
function coalesceArg(a) {
|
||||
return a ?? 9;
|
||||
}
|
||||
|
||||
function coalesceLocal() {
|
||||
var x;
|
||||
return x ?? 5;
|
||||
}
|
||||
|
||||
function coalesceNull() {
|
||||
return null ?? 5;
|
||||
}
|
||||
|
||||
function sparseSwitchValue(a) {
|
||||
var out = -1;
|
||||
switch (a) {
|
||||
case 1:
|
||||
out = 10;
|
||||
break;
|
||||
case 4:
|
||||
out = 40;
|
||||
break;
|
||||
default:
|
||||
out = 99;
|
||||
break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function denseSwitchValue(a) {
|
||||
var out = -1;
|
||||
switch (a) {
|
||||
case 0:
|
||||
out = 7;
|
||||
break;
|
||||
case 1:
|
||||
out = 8;
|
||||
break;
|
||||
case 2:
|
||||
out = 9;
|
||||
break;
|
||||
default:
|
||||
out = 11;
|
||||
break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function groupedSwitchValue(a) {
|
||||
var out = 0;
|
||||
switch (a) {
|
||||
case 0:
|
||||
case 1:
|
||||
out = 10;
|
||||
break;
|
||||
case 3:
|
||||
out = 30;
|
||||
default:
|
||||
out = out + 1;
|
||||
break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
for (var i = 0; i < 100; i++) {
|
||||
assertEq(add(i, i + 1), (i + i + 1));
|
||||
assertEq(withLocal(i, 7), i + 7);
|
||||
|
|
@ -272,6 +336,21 @@ assertEq(chooseOrder(2, 3), true);
|
|||
assertEq(chooseOrder(3, 2), false);
|
||||
assertEq(sumRange(0), 0);
|
||||
assertEq(sumRange(5), 10);
|
||||
assertEq(coalesceArg(0), 0);
|
||||
assertEq(coalesceArg(7), 7);
|
||||
assertEq(coalesceLocal(), 5);
|
||||
assertEq(coalesceNull(), 5);
|
||||
assertEq(sparseSwitchValue(1), 10);
|
||||
assertEq(sparseSwitchValue(4), 40);
|
||||
assertEq(sparseSwitchValue(2), 99);
|
||||
assertEq(denseSwitchValue(0), 7);
|
||||
assertEq(denseSwitchValue(1), 8);
|
||||
assertEq(denseSwitchValue(2), 9);
|
||||
assertEq(denseSwitchValue(5), 11);
|
||||
assertEq(groupedSwitchValue(0), 10);
|
||||
assertEq(groupedSwitchValue(1), 10);
|
||||
assertEq(groupedSwitchValue(3), 31);
|
||||
assertEq(groupedSwitchValue(5), 1);
|
||||
|
||||
(function testPropertyWrappers() {
|
||||
function getX(obj) { return obj.x; }
|
||||
|
|
|
|||
|
|
@ -854,7 +854,22 @@ class MinimalLoongArchCompiler
|
|||
case JSOP_LOOPENTRY:
|
||||
case JSOP_JUMPTARGET:
|
||||
case JSOP_NOP:
|
||||
case JSOP_CONDSWITCH:
|
||||
break;
|
||||
case JSOP_COALESCE: {
|
||||
if (!stackDepth_)
|
||||
return false;
|
||||
MinimalValueKind kind = stack_[stackDepth_ - 1].kind;
|
||||
if (kind == MinimalValueKind::Null || kind == MinimalValueKind::Undefined)
|
||||
break;
|
||||
uint32_t target = uint32_t(int32_t(pcOffset) + GET_JUMP_OFFSET(pc));
|
||||
if (!recordTargetState(target))
|
||||
return false;
|
||||
if (!emitBranch(BranchKind::Always, zero, target))
|
||||
return false;
|
||||
reachable_ = false;
|
||||
break;
|
||||
}
|
||||
case JSOP_OR:
|
||||
case JSOP_AND: {
|
||||
if (!stackDepth_)
|
||||
|
|
@ -867,6 +882,87 @@ class MinimalLoongArchCompiler
|
|||
return false;
|
||||
break;
|
||||
}
|
||||
case JSOP_CASE: {
|
||||
StackValue rhs;
|
||||
StackValue lhs;
|
||||
if (!pop(&rhs) || !pop(&lhs))
|
||||
return false;
|
||||
uint32_t target = uint32_t(int32_t(pcOffset) + GET_JUMP_OFFSET(pc));
|
||||
if (lhs.kind != rhs.kind) {
|
||||
stack_[stackDepth_++] = lhs;
|
||||
break;
|
||||
}
|
||||
if (!recordTargetState(target))
|
||||
return false;
|
||||
if (lhs.kind == MinimalValueKind::Null || lhs.kind == MinimalValueKind::Undefined) {
|
||||
if (!emitBranch(BranchKind::Always, zero, target))
|
||||
return false;
|
||||
reachable_ = false;
|
||||
break;
|
||||
}
|
||||
if (!emitEq(lhs.reg, rhs.reg, WideScratch, false))
|
||||
return false;
|
||||
if (!emitBranch(BranchKind::IfTrue, WideScratch, target))
|
||||
return false;
|
||||
stack_[stackDepth_++] = lhs;
|
||||
break;
|
||||
}
|
||||
case JSOP_TABLESWITCH: {
|
||||
StackValue input;
|
||||
if (!pop(&input))
|
||||
return false;
|
||||
if (input.kind != MinimalValueKind::Int32)
|
||||
return false;
|
||||
|
||||
uint32_t defaultTarget = uint32_t(int32_t(pcOffset) + GET_JUMP_OFFSET(pc));
|
||||
if (!recordTargetState(defaultTarget))
|
||||
return false;
|
||||
|
||||
jsbytecode* tablePc = pc + JUMP_OFFSET_LEN;
|
||||
int32_t low = GET_JUMP_OFFSET(tablePc);
|
||||
tablePc += JUMP_OFFSET_LEN;
|
||||
int32_t high = GET_JUMP_OFFSET(tablePc);
|
||||
tablePc += JUMP_OFFSET_LEN;
|
||||
if (high < low)
|
||||
return false;
|
||||
|
||||
if (!emitLoadImm32(NarrowScratch, low))
|
||||
return false;
|
||||
if (!emitCompare(JSOP_LT, input.reg, NarrowScratch, WideScratch))
|
||||
return false;
|
||||
if (!emitBranch(BranchKind::IfTrue, WideScratch, defaultTarget))
|
||||
return false;
|
||||
|
||||
if (!emitLoadImm32(NarrowScratch, high))
|
||||
return false;
|
||||
if (!emitCompare(JSOP_GT, input.reg, NarrowScratch, WideScratch))
|
||||
return false;
|
||||
if (!emitBranch(BranchKind::IfTrue, WideScratch, defaultTarget))
|
||||
return false;
|
||||
|
||||
uint32_t caseCount = uint32_t(high - low + 1);
|
||||
for (uint32_t i = 0; i < caseCount; i++) {
|
||||
int32_t rel = GET_JUMP_OFFSET(tablePc);
|
||||
tablePc += JUMP_OFFSET_LEN;
|
||||
if (!rel)
|
||||
continue;
|
||||
|
||||
uint32_t target = uint32_t(int32_t(pcOffset) + rel);
|
||||
if (!recordTargetState(target))
|
||||
return false;
|
||||
if (!emitLoadImm32(NarrowScratch, low + int32_t(i)))
|
||||
return false;
|
||||
if (!emitEq(input.reg, NarrowScratch, WideScratch, false))
|
||||
return false;
|
||||
if (!emitBranch(BranchKind::IfTrue, WideScratch, target))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!emitBranch(BranchKind::Always, zero, defaultTarget))
|
||||
return false;
|
||||
reachable_ = false;
|
||||
break;
|
||||
}
|
||||
case JSOP_ADD:
|
||||
case JSOP_SUB:
|
||||
case JSOP_MUL:
|
||||
|
|
@ -1031,7 +1127,12 @@ class MinimalLoongArchCompiler
|
|||
return false;
|
||||
stack_[stackDepth_ - 1].kind = MinimalValueKind::Int32;
|
||||
break;
|
||||
case JSOP_DEFAULT:
|
||||
case JSOP_GOTO: {
|
||||
if (!stackDepth_ && op == JSOP_DEFAULT)
|
||||
return false;
|
||||
if (op == JSOP_DEFAULT)
|
||||
stackDepth_--;
|
||||
uint32_t target = uint32_t(int32_t(pcOffset) + GET_JUMP_OFFSET(pc));
|
||||
if (!recordTargetState(target))
|
||||
return false;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue