Issue #3049 - Enable loongarch64 wasm runtime and Ion patching

This commit is contained in:
Basilisk-Dev 2026-04-24 16:22:59 -04:00 committed by wuggy
commit f796b3f7f1
9 changed files with 63 additions and 27 deletions

View file

@ -295,9 +295,8 @@ LoadContextOptions(const char* aPrefName, void* /* aClosure */)
bool useIon = GetWorkerPref<bool>(NS_LITERAL_CSTRING("ion"));
#if defined(JS_CODEGEN_LOONGARCH64)
// asm.js and wasm are still disabled on loongarch64 workers.
// asm.js is still disabled on loongarch64 workers.
useAsmJS = false;
useWasm = false;
#endif
bool useNativeRegExp = GetWorkerPref<bool>(NS_LITERAL_CSTRING("native_regexp"));

View file

@ -1875,7 +1875,8 @@ MacroAssembler::outOfLineTruncateSlow(FloatRegister src, Register dest, bool wid
bool compilingWasm)
{
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64) || \
defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64) || \
defined(JS_CODEGEN_LOONGARCH64)
if (widenFloatToDouble) {
convertFloat32ToDouble(src, ScratchDoubleReg);
src = ScratchDoubleReg;
@ -1905,7 +1906,8 @@ MacroAssembler::outOfLineTruncateSlow(FloatRegister src, Register dest, bool wid
storeCallInt32Result(dest);
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64) || \
defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64) || \
defined(JS_CODEGEN_LOONGARCH64)
// Nothing
#elif defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
if (widenFloatToDouble)

View file

@ -20,10 +20,22 @@ using namespace js::jit;
void js::jit::PatchJump(CodeLocationJump& jump_, CodeLocationLabel label,
ReprotectCode reprotect) {
(void)jump_;
(void)label;
(void)reprotect;
MOZ_CRASH("Ion patching is not supported on loongarch64");
Instruction* inst = reinterpret_cast<Instruction*>(jump_.raw());
// jumpWithPatch() reserves four instructions:
// beq zero, zero, 0
// INVALID_OFFSET
// nop
// nop
// Patch that block into the long-jump form used elsewhere in the backend:
// load64 scratch, target
// jirl zero, scratch, 0
MaybeAutoWritableJitCode awjc(inst, 4 * sizeof(uint32_t), reprotect);
Assembler::WriteLoad64Instructions(inst, ScratchRegister,
uintptr_t(label.raw()));
inst[3] = InstImm(op_jirl, BOffImm16(0), ScratchRegister, zero);
AutoFlushICache::flush(uintptr_t(inst), 4 * sizeof(uint32_t));
}
// Note this is used for inter-wasm calls and may pass arguments and results

View file

@ -209,6 +209,12 @@ static constexpr Register WasmTableCallScratchReg1 = ABINonArgReg1;
static constexpr Register WasmTableCallScratchReg = WasmTableCallScratchReg0;
static constexpr Register WasmTableCallSigReg = ABINonArgReg2;
static constexpr Register WasmTableCallIndexReg = ABINonArgReg3;
static constexpr Register WasmIonExitRegCallee = t0;
static constexpr Register WasmIonExitRegE0 = a0;
static constexpr Register WasmIonExitRegE1 = a1;
static constexpr Register WasmIonExitRegD0 = a0;
static constexpr Register WasmIonExitRegD1 = a1;
static constexpr Register WasmIonExitRegD2 = t0;
// Register used as a scratch along the return path in the fast js -> wasm stub
// code. This must not overlap ReturnReg, JSReturnOperand, or InstanceReg.

View file

@ -66,7 +66,7 @@ wasm::HasCompilerSupport(ExclusiveContext* cx)
return false;
#endif
#if defined(JS_CODEGEN_NONE) || defined(JS_CODEGEN_ARM64) || defined(JS_CODEGEN_LOONGARCH64)
#if defined(JS_CODEGEN_NONE) || defined(JS_CODEGEN_ARM64)
return false;
#else
return true;

View file

@ -1363,13 +1363,6 @@ ProcessHasSignalHandlers()
# endif
#endif
#if defined(JS_CODEGEN_LOONGARCH64)
// The loongarch64 port is baseline-only for now: no wasm compiler support
// and no Ion interrupt machinery that depends on these process-wide
// signal handlers. Keeping them installed risks misrouting ordinary faults.
return false;
#endif
// The interrupt handler allows the main thread to be paused from another
// thread (see InterruptRunningJitCode).
#if defined(XP_WIN)

View file

@ -588,10 +588,6 @@ static const unsigned SavedTlsReg = sizeof(void*);
ProfilingOffsets
wasm::GenerateImportJitExit(MacroAssembler& masm, const FuncImport& fi, Label* throwLabel)
{
#if defined(JS_CODEGEN_LOONGARCH64)
MOZ_CRASH("wasm import JIT exits are unsupported on loongarch64");
return ProfilingOffsets();
#else
masm.setFramePushed(0);
// JIT calls use the following stack layout (sp grows to the left):
@ -814,7 +810,6 @@ wasm::GenerateImportJitExit(MacroAssembler& masm, const FuncImport& fi, Label* t
offsets.end = masm.currentOffset();
return offsets;
#endif
}
// Generate a stub that calls into ReportTrap with the right trap reason.
@ -1056,7 +1051,38 @@ wasm::GenerateInterruptExit(MacroAssembler& masm, Label* throwLabel)
masm.ret();
#elif defined(JS_CODEGEN_ARM64)
MOZ_CRASH();
#elif defined (JS_CODEGEN_NONE) || defined(JS_CODEGEN_LOONGARCH64)
#elif defined(JS_CODEGEN_LOONGARCH64)
// Reserve space to store the resumePC. We restore all machine state from
// the saved register image and use the reserved `rx` register as the final
// jump scratch to resume execution.
masm.subFromStackPtr(Imm32(sizeof(intptr_t)));
masm.setFramePushed(0);
static_assert(!SupportsSimd, "high lanes of SIMD registers need to be saved too.");
masm.PushRegsInMask(AllRegsExceptSP);
// Save the unaligned stack pointer in a non-volatile register, then align
// for the C++ call into HandleExecutionInterrupt.
masm.moveStackPtrTo(s0);
masm.andToStackPtr(Imm32(~(ABIStackAlignment - 1)));
// Store resumePC into the reserved space above the saved register block.
masm.loadWasmActivationFromSymbolicAddress(IntArgReg0);
masm.loadPtr(Address(IntArgReg0, WasmActivation::offsetOfResumePC()), IntArgReg1);
masm.storePtr(IntArgReg1, Address(s0, masm.framePushed()));
masm.assertStackAlignment(ABIStackAlignment);
masm.call(SymbolicAddress::HandleExecutionInterrupt);
masm.branchIfFalseBool(ReturnReg, throwLabel);
// Restore the interrupted machine state before resuming execution.
masm.moveToStackPtr(s0);
masm.PopRegsInMask(AllRegsExceptSP);
masm.loadPtr(Address(StackPointer, 0), rx);
masm.addToStackPtr(Imm32(sizeof(intptr_t)));
masm.jump(rx);
#elif defined (JS_CODEGEN_NONE)
MOZ_CRASH();
#else
# error "Unknown architecture!"

View file

@ -1421,10 +1421,8 @@ ReloadPrefsCallback(const char* pref, void* data)
bool useNativeRegExp = Preferences::GetBool(JS_OPTIONS_DOT_STR "native_regexp") && !safeMode;
#if defined(JS_CODEGEN_LOONGARCH64)
// asm.js, wasm, and native regexp JIT are still disabled on loongarch64.
// asm.js and native regexp JIT are still disabled on loongarch64.
useAsmJS = false;
useWasm = false;
useWasmBaseline = false;
useNativeRegExp = false;
#endif

View file

@ -1266,7 +1266,7 @@ pref("javascript.options.baselinejit", true);
#if defined(JS_CODEGEN_LOONGARCH64)
pref("javascript.options.ion", true);
pref("javascript.options.asmjs", false);
pref("javascript.options.wasm", false);
pref("javascript.options.wasm", true);
#else
pref("javascript.options.ion", true);
// JIT warm-up thresholds (-1 keeps engine defaults).
@ -1282,7 +1282,7 @@ pref("javascript.options.ion.inlining", true);
// only enable it by default for 64bit builds
#ifdef HAVE_64BIT_BUILD
# if defined(JS_CODEGEN_LOONGARCH64)
pref("javascript.options.wasm_baselinejit", false);
pref("javascript.options.wasm_baselinejit", true);
# else
pref("javascript.options.wasm_baselinejit", true);
# endif