mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-29 02:27:30 +09:00
Issue #3049 - Allow more LoongArch minimal JIT arguments
This commit is contained in:
parent
43a6d946f8
commit
2198d41700
2 changed files with 58 additions and 21 deletions
|
|
@ -8,6 +8,15 @@ function withLocal(a, b) {
|
||||||
return d + 1;
|
return d + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function addEight(a, b, c, d, e, f, g, h) {
|
||||||
|
return a + b + c + d + e + f + g + h;
|
||||||
|
}
|
||||||
|
|
||||||
|
function assignSixthArg(a, b, c, d, e, f) {
|
||||||
|
f = a + e;
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
function overflow(a, b) {
|
function overflow(a, b) {
|
||||||
return a + b;
|
return a + b;
|
||||||
}
|
}
|
||||||
|
|
@ -259,8 +268,12 @@ function groupedSwitchValue(a) {
|
||||||
for (var i = 0; i < 100; i++) {
|
for (var i = 0; i < 100; i++) {
|
||||||
assertEq(add(i, i + 1), (i + i + 1));
|
assertEq(add(i, i + 1), (i + i + 1));
|
||||||
assertEq(withLocal(i, 7), i + 7);
|
assertEq(withLocal(i, 7), i + 7);
|
||||||
|
assertEq(addEight(i, 1, 2, 3, 4, 5, 6, 7), i + 28);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assertEq(assignSixthArg(2, 0, 0, 0, 5, 99), 7);
|
||||||
|
assertEq(assignSixthArg(-3, 0, 0, 0, 8, 11), 5);
|
||||||
|
|
||||||
assertEq(overflow(2147483647, 1), 2147483648);
|
assertEq(overflow(2147483647, 1), 2147483648);
|
||||||
assertEq(unsupported(2, 3), 5.5);
|
assertEq(unsupported(2, 3), 5.5);
|
||||||
assertEq(largeResult(7), 307);
|
assertEq(largeResult(7), 307);
|
||||||
|
|
|
||||||
|
|
@ -48,8 +48,10 @@ enum LoongArchReg : uint8_t {
|
||||||
t8 = 20
|
t8 = 20
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr LoongArchReg ArgRegs[] = { a0, a1 };
|
static constexpr size_t MaxArgCount = 16;
|
||||||
static constexpr LoongArchReg LocalRegs[] = { a3, a4, a5, a6, a7 };
|
static constexpr LoongArchReg ArgsPointerReg = a0;
|
||||||
|
static constexpr LoongArchReg ResultPointerReg = a1;
|
||||||
|
static constexpr LoongArchReg LocalRegs[] = { a2, a3, a4, a5, a6, a7 };
|
||||||
static constexpr LoongArchReg StackRegs[] = { t0, t1, t2, t3, t4, t5, t6 };
|
static constexpr LoongArchReg StackRegs[] = { t0, t1, t2, t3, t4, t5, t6 };
|
||||||
static constexpr LoongArchReg WideScratch = t7;
|
static constexpr LoongArchReg WideScratch = t7;
|
||||||
static constexpr LoongArchReg NarrowScratch = t8;
|
static constexpr LoongArchReg NarrowScratch = t8;
|
||||||
|
|
@ -76,7 +78,7 @@ IsNumericKind(MinimalValueKind kind)
|
||||||
return kind == MinimalValueKind::Int32 || kind == MinimalValueKind::Boolean;
|
return kind == MinimalValueKind::Int32 || kind == MinimalValueKind::Boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
using TinyLoongArchJitCode = bool (*)(int32_t arg0, int32_t arg1, MinimalJitResult* out);
|
using TinyLoongArchJitCode = bool (*)(int32_t* args, MinimalJitResult* out);
|
||||||
|
|
||||||
enum MinimalFastPathKind : uint8_t {
|
enum MinimalFastPathKind : uint8_t {
|
||||||
MinimalFastPathUninitialized = 0,
|
MinimalFastPathUninitialized = 0,
|
||||||
|
|
@ -185,7 +187,7 @@ struct ControlFlowState
|
||||||
size_t stackDepth;
|
size_t stackDepth;
|
||||||
LoongArchReg stackRegs[mozilla::ArrayLength(StackRegs)];
|
LoongArchReg stackRegs[mozilla::ArrayLength(StackRegs)];
|
||||||
MinimalValueKind stackKinds[mozilla::ArrayLength(StackRegs)];
|
MinimalValueKind stackKinds[mozilla::ArrayLength(StackRegs)];
|
||||||
MinimalValueKind argKinds[mozilla::ArrayLength(ArgRegs)];
|
MinimalValueKind argKinds[MaxArgCount];
|
||||||
MinimalValueKind localKinds[mozilla::ArrayLength(LocalRegs)];
|
MinimalValueKind localKinds[mozilla::ArrayLength(LocalRegs)];
|
||||||
|
|
||||||
ControlFlowState()
|
ControlFlowState()
|
||||||
|
|
@ -208,7 +210,7 @@ class MinimalLoongArchCompiler
|
||||||
size_t failPatches_[128];
|
size_t failPatches_[128];
|
||||||
size_t failPatchCount_;
|
size_t failPatchCount_;
|
||||||
StackValue stack_[mozilla::ArrayLength(StackRegs)];
|
StackValue stack_[mozilla::ArrayLength(StackRegs)];
|
||||||
MinimalValueKind argKinds_[mozilla::ArrayLength(ArgRegs)];
|
MinimalValueKind argKinds_[MaxArgCount];
|
||||||
MinimalValueKind localKinds_[mozilla::ArrayLength(LocalRegs)];
|
MinimalValueKind localKinds_[mozilla::ArrayLength(LocalRegs)];
|
||||||
size_t stackDepth_;
|
size_t stackDepth_;
|
||||||
bool reachable_;
|
bool reachable_;
|
||||||
|
|
@ -230,7 +232,7 @@ class MinimalLoongArchCompiler
|
||||||
stack_[i].reg = state.stackRegs[i];
|
stack_[i].reg = state.stackRegs[i];
|
||||||
stack_[i].kind = state.stackKinds[i];
|
stack_[i].kind = state.stackKinds[i];
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < mozilla::ArrayLength(argKinds_); i++)
|
for (size_t i = 0; i < MaxArgCount; i++)
|
||||||
argKinds_[i] = state.argKinds[i];
|
argKinds_[i] = state.argKinds[i];
|
||||||
for (size_t i = 0; i < mozilla::ArrayLength(localKinds_); i++)
|
for (size_t i = 0; i < mozilla::ArrayLength(localKinds_); i++)
|
||||||
localKinds_[i] = state.localKinds[i];
|
localKinds_[i] = state.localKinds[i];
|
||||||
|
|
@ -247,7 +249,7 @@ class MinimalLoongArchCompiler
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < mozilla::ArrayLength(argKinds_); i++) {
|
for (size_t i = 0; i < MaxArgCount; i++) {
|
||||||
if (argKinds_[i] != state.argKinds[i])
|
if (argKinds_[i] != state.argKinds[i])
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -265,7 +267,7 @@ class MinimalLoongArchCompiler
|
||||||
state->stackRegs[i] = stack_[i].reg;
|
state->stackRegs[i] = stack_[i].reg;
|
||||||
state->stackKinds[i] = stack_[i].kind;
|
state->stackKinds[i] = stack_[i].kind;
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < mozilla::ArrayLength(argKinds_); i++)
|
for (size_t i = 0; i < MaxArgCount; i++)
|
||||||
state->argKinds[i] = argKinds_[i];
|
state->argKinds[i] = argKinds_[i];
|
||||||
for (size_t i = 0; i < mozilla::ArrayLength(localKinds_); i++)
|
for (size_t i = 0; i < mozilla::ArrayLength(localKinds_); i++)
|
||||||
state->localKinds[i] = localKinds_[i];
|
state->localKinds[i] = localKinds_[i];
|
||||||
|
|
@ -323,6 +325,19 @@ class MinimalLoongArchCompiler
|
||||||
return emit(EncodeUnsignedImm12(0x03c00000, dst, src, imm));
|
return emit(EncodeUnsignedImm12(0x03c00000, dst, src, imm));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool emitLoadWord(LoongArchReg dst, LoongArchReg base, uint32_t offset) {
|
||||||
|
return emit(EncodeUnsignedImm12(0x28800000, dst, base, offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool emitStoreWord(LoongArchReg src, LoongArchReg base, uint32_t offset) {
|
||||||
|
return emit(EncodeUnsignedImm12(0x29800000, src, base, offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool emitLoadArg(LoongArchReg dst, uint32_t slot) {
|
||||||
|
MOZ_ASSERT(slot < MaxArgCount);
|
||||||
|
return emitLoadWord(dst, ArgsPointerReg, slot * sizeof(int32_t));
|
||||||
|
}
|
||||||
|
|
||||||
bool emitSltui(LoongArchReg dst, LoongArchReg src, uint32_t imm) {
|
bool emitSltui(LoongArchReg dst, LoongArchReg src, uint32_t imm) {
|
||||||
return emit(EncodeUnsignedImm12(0x02400000, dst, src, imm));
|
return emit(EncodeUnsignedImm12(0x02400000, dst, src, imm));
|
||||||
}
|
}
|
||||||
|
|
@ -542,11 +557,11 @@ class MinimalLoongArchCompiler
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emitReturn(const StackValue& result) {
|
bool emitReturn(const StackValue& result) {
|
||||||
if (!emit(EncodeUnsignedImm12(0x29800000, result.reg, a2, 0)))
|
if (!emitStoreWord(result.reg, ResultPointerReg, 0))
|
||||||
return false;
|
return false;
|
||||||
if (!emitLoadImm32(NarrowScratch, int32_t(result.kind)))
|
if (!emitLoadImm32(NarrowScratch, int32_t(result.kind)))
|
||||||
return false;
|
return false;
|
||||||
if (!emit(EncodeUnsignedImm12(0x29800000, NarrowScratch, a2, sizeof(uint32_t))))
|
if (!emitStoreWord(NarrowScratch, ResultPointerReg, sizeof(uint32_t)))
|
||||||
return false;
|
return false;
|
||||||
if (!emit(EncodeImm12(0x02800000, a0, zero, 1)))
|
if (!emit(EncodeImm12(0x02800000, a0, zero, 1)))
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -643,14 +658,14 @@ class MinimalLoongArchCompiler
|
||||||
bool emitStoreArg(uint32_t slot) {
|
bool emitStoreArg(uint32_t slot) {
|
||||||
if (slot >= script_->numArgs() || !stackDepth_)
|
if (slot >= script_->numArgs() || !stackDepth_)
|
||||||
return false;
|
return false;
|
||||||
if (!emitMove(ArgRegs[slot], stack_[stackDepth_ - 1].reg))
|
if (!emitStoreWord(stack_[stackDepth_ - 1].reg, ArgsPointerReg, slot * sizeof(int32_t)))
|
||||||
return false;
|
return false;
|
||||||
argKinds_[slot] = stack_[stackDepth_ - 1].kind;
|
argKinds_[slot] = stack_[stackDepth_ - 1].kind;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool supportedScriptShape() const {
|
bool supportedScriptShape() const {
|
||||||
return script_->numArgs() <= 2 &&
|
return script_->numArgs() <= MaxArgCount &&
|
||||||
script_->nfixed() <= mozilla::ArrayLength(LocalRegs) &&
|
script_->nfixed() <= mozilla::ArrayLength(LocalRegs) &&
|
||||||
!script_->isAsync() &&
|
!script_->isAsync() &&
|
||||||
!script_->isStarGenerator() &&
|
!script_->isStarGenerator() &&
|
||||||
|
|
@ -701,7 +716,9 @@ class MinimalLoongArchCompiler
|
||||||
reachable_(true),
|
reachable_(true),
|
||||||
sawReturn_(false)
|
sawReturn_(false)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < mozilla::ArrayLength(argKinds_); i++)
|
for (size_t i = 0; i < MaxArgCount; i++)
|
||||||
|
argKinds_[i] = MinimalValueKind::Undefined;
|
||||||
|
for (size_t i = 0; i < script_->numArgs(); i++)
|
||||||
argKinds_[i] = MinimalValueKind::Int32;
|
argKinds_[i] = MinimalValueKind::Int32;
|
||||||
for (size_t i = 0; i < mozilla::ArrayLength(localKinds_); i++)
|
for (size_t i = 0; i < mozilla::ArrayLength(localKinds_); i++)
|
||||||
localKinds_[i] = MinimalValueKind::Undefined;
|
localKinds_[i] = MinimalValueKind::Undefined;
|
||||||
|
|
@ -738,8 +755,12 @@ class MinimalLoongArchCompiler
|
||||||
uint32_t arg = GET_ARGNO(pc);
|
uint32_t arg = GET_ARGNO(pc);
|
||||||
if (arg >= script_->numArgs())
|
if (arg >= script_->numArgs())
|
||||||
return false;
|
return false;
|
||||||
if (!pushTempFromReg(ArgRegs[arg], argKinds_[arg]))
|
if (stackDepth_ >= mozilla::ArrayLength(StackRegs))
|
||||||
return false;
|
return false;
|
||||||
|
LoongArchReg dst = allocStackReg();
|
||||||
|
if (!emitLoadArg(dst, arg))
|
||||||
|
return false;
|
||||||
|
stack_[stackDepth_++] = { dst, argKinds_[arg] };
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case JSOP_SETARG:
|
case JSOP_SETARG:
|
||||||
|
|
@ -853,6 +874,7 @@ class MinimalLoongArchCompiler
|
||||||
case JSOP_CHECKLEXICAL:
|
case JSOP_CHECKLEXICAL:
|
||||||
case JSOP_LOOPENTRY:
|
case JSOP_LOOPENTRY:
|
||||||
case JSOP_JUMPTARGET:
|
case JSOP_JUMPTARGET:
|
||||||
|
case JSOP_LINENO:
|
||||||
case JSOP_NOP:
|
case JSOP_NOP:
|
||||||
case JSOP_CONDSWITCH:
|
case JSOP_CONDSWITCH:
|
||||||
break;
|
break;
|
||||||
|
|
@ -1201,7 +1223,7 @@ class MinimalLoongArchCompiler
|
||||||
static bool
|
static bool
|
||||||
CanUseMinimalJit(JSScript* script, const CallArgs& args)
|
CanUseMinimalJit(JSScript* script, const CallArgs& args)
|
||||||
{
|
{
|
||||||
if (!script || script->numArgs() > 2)
|
if (!script || script->numArgs() > MaxArgCount)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (args.length() < script->numArgs())
|
if (args.length() < script->numArgs())
|
||||||
|
|
@ -1435,9 +1457,10 @@ TryCallLoongArchMinimalJit(JSContext* cx, HandleFunction fun, const CallArgs& ar
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
MinimalJitResult result = { 0, MinimalValueKind::Int32 };
|
MinimalJitResult result = { 0, MinimalValueKind::Int32 };
|
||||||
int32_t arg0 = script->numArgs() >= 1 ? args[0].toInt32() : 0;
|
int32_t argPayloads[MaxArgCount] = { 0 };
|
||||||
int32_t arg1 = script->numArgs() >= 2 ? args[1].toInt32() : 0;
|
for (uint32_t i = 0; i < script->numArgs(); i++)
|
||||||
if (!fn(arg0, arg1, &result))
|
argPayloads[i] = args[i].toInt32();
|
||||||
|
if (!fn(argPayloads, &result))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
args.rval().set(MinimalJitResultToValue(result));
|
args.rval().set(MinimalJitResultToValue(result));
|
||||||
|
|
@ -1468,9 +1491,10 @@ TryEnterLoongArchMinimalJit(JSContext* cx, RunState& state)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
MinimalJitResult result = { 0, MinimalValueKind::Int32 };
|
MinimalJitResult result = { 0, MinimalValueKind::Int32 };
|
||||||
int32_t arg0 = state.script()->numArgs() >= 1 ? invoke.args()[0].toInt32() : 0;
|
int32_t argPayloads[MaxArgCount] = { 0 };
|
||||||
int32_t arg1 = state.script()->numArgs() >= 2 ? invoke.args()[1].toInt32() : 0;
|
for (uint32_t i = 0; i < state.script()->numArgs(); i++)
|
||||||
if (!fn(arg0, arg1, &result))
|
argPayloads[i] = invoke.args()[i].toInt32();
|
||||||
|
if (!fn(argPayloads, &result))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
state.setReturnValue(MinimalJitResultToValue(result));
|
state.setReturnValue(MinimalJitResultToValue(result));
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue