From 4760c65706c10888a92f34cf5bc8e556383ce1ac Mon Sep 17 00:00:00 2001 From: Basilisk-Dev Date: Fri, 24 Apr 2026 15:09:22 -0400 Subject: [PATCH] Issue #3049 - Wire up loongarch64 Ion backend compilation --- js/src/jit/CodeGenerator.h | 15 +++++- js/src/jit/LIR.h | 3 +- js/src/jit/LOpcodes.h | 2 +- js/src/jit/Lowering.h | 2 +- .../loongarch64/MacroAssembler-loongarch64.h | 46 +++++++++++++++++++ .../mips-shared/CodeGenerator-mips-shared.cpp | 21 ++++++++- .../mips-shared/CodeGenerator-mips-shared.h | 13 ++++++ js/src/jit/mips64/Lowering-mips64.cpp | 6 +++ js/src/jit/mips64/Lowering-mips64.h | 1 + js/src/moz.build | 5 +- 10 files changed, 107 insertions(+), 7 deletions(-) diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h index ed50c4c402..feea29ebae 100644 --- a/js/src/jit/CodeGenerator.h +++ b/js/src/jit/CodeGenerator.h @@ -20,7 +20,7 @@ #elif defined(JS_CODEGEN_ARM64) # include "jit/arm64/CodeGenerator-arm64.h" #elif defined(JS_CODEGEN_LOONGARCH64) -# include "jit/none/CodeGenerator-none.h" +# include "jit/mips64/CodeGenerator-mips64.h" #elif defined(JS_CODEGEN_MIPS32) # include "jit/mips32/CodeGenerator-mips32.h" #elif defined(JS_CODEGEN_MIPS64) @@ -47,6 +47,19 @@ class OutOfLineCallPostWriteBarrier; class OutOfLineCallPostWriteElementBarrier; class OutOfLineIsCallable; class OutOfLineIsConstructor; +class LSimdSplatX4; +class LSimd128Int; +class LSimd128Float; +class LSimdReinterpretCast; +class LSimdExtractElementI; +class LSimdExtractElementF; +class LSimdBinaryCompIx4; +class LSimdBinaryCompFx4; +class LSimdBinaryArithIx4; +class LSimdBinaryArithFx4; +class LSimdBinaryBitwise; +class LSimdGeneralShuffleI; +class LSimdGeneralShuffleF; class OutOfLineRegExpMatcher; class OutOfLineRegExpSearcher; class OutOfLineRegExpTester; diff --git a/js/src/jit/LIR.h b/js/src/jit/LIR.h index 7205bd8b8c..b88ebc046f 100644 --- a/js/src/jit/LIR.h +++ b/js/src/jit/LIR.h @@ -1928,7 +1928,8 @@ LAllocation::toRegister() const # endif # include "jit/mips-shared/LIR-mips-shared.h" #elif defined(JS_CODEGEN_LOONGARCH64) -# include "jit/none/LIR-none.h" +# include "jit/mips64/LIR-mips64.h" +# include "jit/mips-shared/LIR-mips-shared.h" #elif defined(JS_CODEGEN_NONE) # include "jit/none/LIR-none.h" #else diff --git a/js/src/jit/LOpcodes.h b/js/src/jit/LOpcodes.h index 70d874f690..a6891d98ee 100644 --- a/js/src/jit/LOpcodes.h +++ b/js/src/jit/LOpcodes.h @@ -15,7 +15,7 @@ #elif defined(JS_CODEGEN_ARM64) # include "jit/arm64/LOpcodes-arm64.h" #elif defined(JS_CODEGEN_LOONGARCH64) -# include "jit/none/LOpcodes-none.h" +# include "jit/mips64/LOpcodes-mips64.h" #elif defined(JS_CODEGEN_MIPS32) # include "jit/mips32/LOpcodes-mips32.h" #elif defined(JS_CODEGEN_MIPS64) diff --git a/js/src/jit/Lowering.h b/js/src/jit/Lowering.h index f0db465f6e..a1134906dc 100644 --- a/js/src/jit/Lowering.h +++ b/js/src/jit/Lowering.h @@ -19,7 +19,7 @@ #elif defined(JS_CODEGEN_ARM64) # include "jit/arm64/Lowering-arm64.h" #elif defined(JS_CODEGEN_LOONGARCH64) -# include "jit/none/Lowering-none.h" +# include "jit/mips64/Lowering-mips64.h" #elif defined(JS_CODEGEN_MIPS32) # include "jit/mips32/Lowering-mips32.h" #elif defined(JS_CODEGEN_MIPS64) diff --git a/js/src/jit/loongarch64/MacroAssembler-loongarch64.h b/js/src/jit/loongarch64/MacroAssembler-loongarch64.h index 2426013b64..fb2ce7b505 100644 --- a/js/src/jit/loongarch64/MacroAssembler-loongarch64.h +++ b/js/src/jit/loongarch64/MacroAssembler-loongarch64.h @@ -266,6 +266,14 @@ class MacroAssemblerLOONGARCH64 : public Assembler { // multiplies. For now, there are only few that we care about. void ma_mul(Register rd, Register rj, Imm32 imm); + void ma_mul_branch_overflow(Register rd, Register rj, Register rk, + Label* overflow) { + ma_mul32TestOverflow(rd, rj, rk, overflow); + } + void ma_mul_branch_overflow(Register rd, Register rj, Imm32 imm, + Label* overflow) { + ma_mul32TestOverflow(rd, rj, imm, overflow); + } void ma_mul32TestOverflow(Register rd, Register rj, Register rk, Label* overflow); void ma_mul32TestOverflow(Register rd, Register rj, Imm32 imm, @@ -283,6 +291,24 @@ class MacroAssemblerLOONGARCH64 : public Assembler { void ma_mod_mask(Register src, Register dest, Register hold, Register remain, int32_t shift, Label* negZero = nullptr); + void ma_addu(Register rd, Register rj, Register rk) { as_add_w(rd, rj, rk); } + void ma_addu(Register rd, Register rj, Imm32 imm) { ma_add_w(rd, rj, imm); } + void ma_subu(Register rd, Register rj, Register rk) { as_sub_w(rd, rj, rk); } + void ma_subu(Register rd, Register rj, Imm32 imm) { ma_sub_w(rd, rj, imm); } + void ma_negu(Register rd, Register rj) { as_sub_w(rd, zero, rj); } + void ma_sll(Register rd, Register rj, Register rk) { as_sll_w(rd, rj, rk); } + void ma_sll(Register rd, Register rj, Imm32 imm) { + as_slli_w(rd, rj, imm.value & 0x1f); + } + void ma_srl(Register rd, Register rj, Register rk) { as_srl_w(rd, rj, rk); } + void ma_srl(Register rd, Register rj, Imm32 imm) { + as_srli_w(rd, rj, imm.value & 0x1f); + } + void ma_sra(Register rd, Register rj, Register rk) { as_sra_w(rd, rj, rk); } + void ma_sra(Register rd, Register rj, Imm32 imm) { + as_srai_w(rd, rj, imm.value & 0x1f); + } + // branches when done from within la-specific code void ma_b(Register lhs, Register rhs, Label* l, Condition c, JumpKind jumpKind = LongJump); @@ -333,11 +359,31 @@ class MacroAssemblerLOONGARCH64 : public Assembler { void ma_bc_d(FloatRegister lhs, FloatRegister rhs, Label* label, DoubleCondition c, JumpKind jumpKind = LongJump, FPConditionBit fcc = FCC0); + void ma_bc1s(FloatRegister lhs, FloatRegister rhs, Label* label, + DoubleCondition c, JumpKind jumpKind = LongJump, + FPConditionBit fcc = FCC0) { + ma_bc_s(lhs, rhs, label, c, jumpKind, fcc); + } + void ma_bc1d(FloatRegister lhs, FloatRegister rhs, Label* label, + DoubleCondition c, JumpKind jumpKind = LongJump, + FPConditionBit fcc = FCC0) { + ma_bc_d(lhs, rhs, label, c, jumpKind, fcc); + } void ma_call(ImmPtr dest); void ma_jump(ImmPtr dest); + void as_mul(Register rd, Register rj, Register rk) { as_mul_w(rd, rj, rk); } + void as_mtc1(Register rt, FloatRegister fs) { as_movgr2fr_w(fs, rt); } + void as_mfc1(Register rt, FloatRegister fs) { as_movfr2gr_s(rt, fs); } + void as_divd(FloatRegister fd, FloatRegister fj, FloatRegister fk) { + as_fdiv_d(fd, fj, fk); + } + void as_divs(FloatRegister fd, FloatRegister fj, FloatRegister fk) { + as_fdiv_s(fd, fj, fk); + } + void ma_cmp_set(Register dst, Register lhs, Register rhs, Condition c); void ma_cmp_set(Register dst, Register lhs, Imm32 imm, Condition c); void ma_cmp_set_double(Register dst, FloatRegister lhs, FloatRegister rhs, diff --git a/js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp b/js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp index 9e250c5b42..52cc9f37bd 100644 --- a/js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp +++ b/js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp @@ -136,7 +136,7 @@ CodeGeneratorMIPSShared::visitCompare(LCompare* comp) const LAllocation* right = comp->getOperand(1); const LDefinition* def = comp->getDef(0); -#ifdef JS_CODEGEN_MIPS64 +#if defined(JS_CODEGEN_MIPS64) || defined(JS_CODEGEN_LOONGARCH64) if (mir->compareType() == MCompare::Compare_Object) { if (right->isGeneralReg()) masm.cmpPtrSet(cond, ToRegister(left), ToRegister(right), ToRegister(def)); @@ -160,7 +160,7 @@ CodeGeneratorMIPSShared::visitCompareAndBranch(LCompareAndBranch* comp) MCompare* mir = comp->cmpMir(); Assembler::Condition cond = JSOpToCondition(mir->compareType(), comp->jsop()); -#ifdef JS_CODEGEN_MIPS64 +#if defined(JS_CODEGEN_MIPS64) || defined(JS_CODEGEN_LOONGARCH64) if (mir->compareType() == MCompare::Compare_Object) { if (comp->right()->isGeneralReg()) { emitBranch(ToRegister(comp->left()), ToRegister(comp->right()), cond, @@ -617,8 +617,12 @@ CodeGeneratorMIPSShared::visitDivI(LDivI* ins) // All regular. Lets call div. if (mir->canTruncateRemainder()) { +#ifdef JS_CODEGEN_LOONGARCH64 + masm.as_div_w(dest, lhs, rhs); +#else masm.as_div(lhs, rhs); masm.as_mflo(dest); +#endif } else { MOZ_ASSERT(mir->fallible()); @@ -749,8 +753,12 @@ CodeGeneratorMIPSShared::visitModI(LModI* ins) masm.bind(¬Negative); } +#ifdef JS_CODEGEN_LOONGARCH64 + masm.as_mod_w(dest, lhs, rhs); +#else masm.as_div(lhs, rhs); masm.as_mfhi(dest); +#endif // If X%Y == 0 and X < 0, then we *actually* wanted to return -0.0 if (mir->canBeNegativeDividend()) { @@ -2440,15 +2448,24 @@ CodeGeneratorMIPSShared::visitUDivOrMod(LUDivOrMod* ins) } } +#ifdef JS_CODEGEN_LOONGARCH64 + masm.as_mod_wu(ScratchRegister, lhs, rhs); + masm.move32(ScratchRegister, output); +#else masm.as_divu(lhs, rhs); masm.as_mfhi(output); +#endif // If the remainder is > 0, bailout since this must be a double. if (ins->mir()->isDiv()) { if (!ins->mir()->toDiv()->canTruncateRemainder()) bailoutCmp32(Assembler::NonZero, output, output, ins->snapshot()); // Get quotient +#ifdef JS_CODEGEN_LOONGARCH64 + masm.as_div_wu(output, lhs, rhs); +#else masm.as_mflo(output); +#endif } if (!ins->mir()->isTruncated()) diff --git a/js/src/jit/mips-shared/CodeGenerator-mips-shared.h b/js/src/jit/mips-shared/CodeGenerator-mips-shared.h index b8aa95e912..e709351387 100644 --- a/js/src/jit/mips-shared/CodeGenerator-mips-shared.h +++ b/js/src/jit/mips-shared/CodeGenerator-mips-shared.h @@ -13,6 +13,19 @@ namespace jit { class OutOfLineBailout; class OutOfLineTableSwitch; +class LSimdSplatX4; +class LSimd128Int; +class LSimd128Float; +class LSimdReinterpretCast; +class LSimdExtractElementI; +class LSimdExtractElementF; +class LSimdBinaryCompIx4; +class LSimdBinaryCompFx4; +class LSimdBinaryArithIx4; +class LSimdBinaryArithFx4; +class LSimdBinaryBitwise; +class LSimdGeneralShuffleI; +class LSimdGeneralShuffleF; class CodeGeneratorMIPSShared : public CodeGeneratorShared { diff --git a/js/src/jit/mips64/Lowering-mips64.cpp b/js/src/jit/mips64/Lowering-mips64.cpp index cf4e005db8..ce4121fb2c 100644 --- a/js/src/jit/mips64/Lowering-mips64.cpp +++ b/js/src/jit/mips64/Lowering-mips64.cpp @@ -181,3 +181,9 @@ LIRGeneratorMIPS64::visitRandom(MRandom* ins) LRandom *lir = new(alloc()) LRandom(temp(), temp(), temp()); defineFixed(lir, ins, LFloatReg(ReturnDoubleReg)); } + +void +LIRGeneratorMIPS64::visitSignExtendInt64(MSignExtendInt64* ins) +{ + defineInt64(new(alloc()) LSignExtendInt64(useInt64RegisterAtStart(ins->input())), ins); +} diff --git a/js/src/jit/mips64/Lowering-mips64.h b/js/src/jit/mips64/Lowering-mips64.h index 1c24dd2fa0..ef2061ef2f 100644 --- a/js/src/jit/mips64/Lowering-mips64.h +++ b/js/src/jit/mips64/Lowering-mips64.h @@ -46,6 +46,7 @@ class LIRGeneratorMIPS64 : public LIRGeneratorMIPSShared void visitUnbox(MUnbox* unbox); void visitReturn(MReturn* ret); void visitRandom(MRandom* ins); + void visitSignExtendInt64(MSignExtendInt64* ins); }; typedef LIRGeneratorMIPS64 LIRGeneratorSpecific; diff --git a/js/src/moz.build b/js/src/moz.build index 4c160585e4..f2a0a34362 100644 --- a/js/src/moz.build +++ b/js/src/moz.build @@ -533,6 +533,8 @@ elif CONFIG['JS_CODEGEN_LOONGARCH64']: 'jit/mips-shared/Bailouts-mips-shared.cpp', 'jit/mips-shared/BaselineCompiler-mips-shared.cpp', 'jit/mips-shared/BaselineIC-mips-shared.cpp', + 'jit/mips-shared/CodeGenerator-mips-shared.cpp', + 'jit/mips-shared/Lowering-mips-shared.cpp', 'jit/mips-shared/MoveEmitter-mips-shared.cpp', ] jit_ioncheck2_deunified_sources += [ @@ -541,6 +543,8 @@ elif CONFIG['JS_CODEGEN_LOONGARCH64']: 'jit/loongarch64/Bailouts-loongarch64.cpp', 'jit/loongarch64/BaselineCompiler-loongarch64.cpp', 'jit/loongarch64/BaselineIC-loongarch64.cpp', + 'jit/mips64/CodeGenerator-mips64.cpp', + 'jit/mips64/Lowering-mips64.cpp', 'jit/loongarch64/MacroAssembler-loongarch64.cpp', 'jit/loongarch64/SharedIC-loongarch64.cpp', 'jit/loongarch64/Trampoline-loongarch64.cpp', @@ -783,4 +787,3 @@ selfhosted.inputs = [ if CONFIG['CLANG_CXX'] or CONFIG['GNU_CXX']: SOURCES['jsdtoa.cpp'].flags += ['-Wno-implicit-fallthrough'] -