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")); bool useIon = GetWorkerPref<bool>(NS_LITERAL_CSTRING("ion"));
#if defined(JS_CODEGEN_LOONGARCH64) #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; useAsmJS = false;
useWasm = false;
#endif #endif
bool useNativeRegExp = GetWorkerPref<bool>(NS_LITERAL_CSTRING("native_regexp")); 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) bool compilingWasm)
{ {
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64) || \ #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) { if (widenFloatToDouble) {
convertFloat32ToDouble(src, ScratchDoubleReg); convertFloat32ToDouble(src, ScratchDoubleReg);
src = ScratchDoubleReg; src = ScratchDoubleReg;
@ -1905,7 +1906,8 @@ MacroAssembler::outOfLineTruncateSlow(FloatRegister src, Register dest, bool wid
storeCallInt32Result(dest); storeCallInt32Result(dest);
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64) || \ #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 // Nothing
#elif defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64) #elif defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
if (widenFloatToDouble) if (widenFloatToDouble)

View file

@ -20,10 +20,22 @@ using namespace js::jit;
void js::jit::PatchJump(CodeLocationJump& jump_, CodeLocationLabel label, void js::jit::PatchJump(CodeLocationJump& jump_, CodeLocationLabel label,
ReprotectCode reprotect) { ReprotectCode reprotect) {
(void)jump_; Instruction* inst = reinterpret_cast<Instruction*>(jump_.raw());
(void)label;
(void)reprotect; // jumpWithPatch() reserves four instructions:
MOZ_CRASH("Ion patching is not supported on loongarch64"); // 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 // 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 WasmTableCallScratchReg = WasmTableCallScratchReg0;
static constexpr Register WasmTableCallSigReg = ABINonArgReg2; static constexpr Register WasmTableCallSigReg = ABINonArgReg2;
static constexpr Register WasmTableCallIndexReg = ABINonArgReg3; 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 // Register used as a scratch along the return path in the fast js -> wasm stub
// code. This must not overlap ReturnReg, JSReturnOperand, or InstanceReg. // code. This must not overlap ReturnReg, JSReturnOperand, or InstanceReg.

View file

@ -66,7 +66,7 @@ wasm::HasCompilerSupport(ExclusiveContext* cx)
return false; return false;
#endif #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; return false;
#else #else
return true; return true;

View file

@ -1363,13 +1363,6 @@ ProcessHasSignalHandlers()
# endif # endif
#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 // The interrupt handler allows the main thread to be paused from another
// thread (see InterruptRunningJitCode). // thread (see InterruptRunningJitCode).
#if defined(XP_WIN) #if defined(XP_WIN)

View file

@ -588,10 +588,6 @@ static const unsigned SavedTlsReg = sizeof(void*);
ProfilingOffsets ProfilingOffsets
wasm::GenerateImportJitExit(MacroAssembler& masm, const FuncImport& fi, Label* throwLabel) 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); masm.setFramePushed(0);
// JIT calls use the following stack layout (sp grows to the left): // 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(); offsets.end = masm.currentOffset();
return offsets; return offsets;
#endif
} }
// Generate a stub that calls into ReportTrap with the right trap reason. // Generate a stub that calls into ReportTrap with the right trap reason.
@ -1056,7 +1051,38 @@ wasm::GenerateInterruptExit(MacroAssembler& masm, Label* throwLabel)
masm.ret(); masm.ret();
#elif defined(JS_CODEGEN_ARM64) #elif defined(JS_CODEGEN_ARM64)
MOZ_CRASH(); 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(); MOZ_CRASH();
#else #else
# error "Unknown architecture!" # 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; bool useNativeRegExp = Preferences::GetBool(JS_OPTIONS_DOT_STR "native_regexp") && !safeMode;
#if defined(JS_CODEGEN_LOONGARCH64) #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; useAsmJS = false;
useWasm = false;
useWasmBaseline = false;
useNativeRegExp = false; useNativeRegExp = false;
#endif #endif

View file

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