Issue #3049 - Enable loongarch64 Ion backend build and runtime

This commit is contained in:
Basilisk-Dev 2026-04-24 15:36:36 -04:00 committed by wuggy
commit 81e98512a9
12 changed files with 337 additions and 25 deletions

View file

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

View file

@ -162,7 +162,7 @@ static inline bool
IsIonEnabled(JSContext* cx)
{
// The ARM64 Ion engine is not yet implemented.
#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 cx->options().ion() &&

View file

@ -429,6 +429,7 @@ struct FloatRegister {
MOZ_ASSERT(!invalid_);
return FloatRegister(Encoding(encoding_), FloatRegisters::Double);
}
FloatRegister doubleOverlay() const { return asDouble(); }
FloatRegister asSimd128() const { MOZ_CRASH(); }
constexpr uint32_t size() const {

View file

@ -154,7 +154,9 @@ static constexpr Register IntArgReg4 = a4;
static constexpr Register IntArgReg5 = a5;
static constexpr Register IntArgReg6 = a6;
static constexpr Register IntArgReg7 = a7;
static constexpr Register GlobalReg = s6;
static constexpr Register HeapReg = s7;
static const int32_t WasmGlobalRegBias = 32768;
// Registerd used in RegExpMatcher instruction (do not use JSReturnOperand).
static constexpr Register RegExpMatcherRegExpReg = CallTempReg0;
@ -1015,6 +1017,7 @@ class AssemblerLOONGARCH64 : public AssemblerShared {
public:
void setUnlimitedBuffer() {}
bool oom() const;
bool bailed() const { return m_buffer.bail(); }
void setPrinter(Sprinter* sp) {
#ifdef JS_JITSPEW
@ -1798,6 +1801,13 @@ class InstJump : public Instruction {
}
};
inline bool IsUnaligned(const wasm::MemoryAccessDesc& access) {
if (!access.align()) {
return false;
}
return access.align() < access.byteSize();
}
class ABIArgGenerator {
public:
ABIArgGenerator()

View file

@ -38,17 +38,6 @@ void MacroAssembler::restoreFrameAlignmentForICArguments(AfterICSaveLive& aic) {
}
}
FrameSizeClass FrameSizeClass::FromDepth(uint32_t frameDepth) {
(void)frameDepth;
return FrameSizeClass::None();
}
FrameSizeClass FrameSizeClass::ClassLimit() { return FrameSizeClass(0); }
uint32_t FrameSizeClass::frameSize() const {
MOZ_CRASH("loongarch64 does not use frame size classes");
}
void MacroAssembler::clampDoubleToUint8(FloatRegister input, Register output) {
ScratchRegisterScope scratch(asMasm());
ScratchDoubleScope fpscratch(asMasm());
@ -82,6 +71,18 @@ void MacroAssemblerLOONGARCH64Compat::convertUInt32ToDouble(Register src,
as_ffint_d_l(dest, dest);
}
void MacroAssemblerLOONGARCH64Compat::convertInt64ToDouble(Register src,
FloatRegister dest) {
as_movgr2fr_d(dest, src);
as_ffint_d_l(dest, dest);
}
void MacroAssemblerLOONGARCH64Compat::convertInt64ToFloat32(Register src,
FloatRegister dest) {
as_movgr2fr_d(dest, src);
as_ffint_s_l(dest, dest);
}
void MacroAssemblerLOONGARCH64Compat::convertUInt64ToDouble(Register src,
FloatRegister dest) {
Label positive, done;
@ -125,6 +126,31 @@ void MacroAssemblerLOONGARCH64Compat::convertUInt32ToFloat32(Register src,
as_ffint_s_l(dest, dest);
}
void MacroAssemblerLOONGARCH64Compat::convertUInt64ToFloat32(Register src,
FloatRegister dest) {
Label positive, done;
ma_b(src, src, &positive, NotSigned, ShortJump);
ScratchRegisterScope scratch(asMasm());
SecondScratchRegisterScope scratch2(asMasm());
MOZ_ASSERT(src != scratch);
MOZ_ASSERT(src != scratch2);
ma_and(scratch, src, Imm32(1));
as_srli_d(scratch2, src, 1);
as_or(scratch, scratch, scratch2);
as_movgr2fr_d(dest, scratch);
as_ffint_s_l(dest, dest);
asMasm().addFloat32(dest, dest);
ma_b(&done, ShortJump);
bind(&positive);
as_movgr2fr_d(dest, src);
as_ffint_s_l(dest, dest);
bind(&done);
}
void MacroAssemblerLOONGARCH64Compat::convertDoubleToFloat32(FloatRegister src,
FloatRegister dest) {
as_fcvt_s_d(dest, src);

View file

@ -291,23 +291,72 @@ class MacroAssemblerLOONGARCH64 : public Assembler {
void ma_mod_mask(Register src, Register dest, Register hold, Register remain,
int32_t shift, Label* negZero = nullptr);
void ma_and(Register rd, Register rs) { as_and(rd, rd, rs); }
void ma_and(Register rd, Imm32 imm) { ma_and(rd, rd, imm); }
void as_addu(Register rd, Register rj, Register rk) { as_add_w(rd, rj, rk); }
void ma_addu(Register rd, Register rs) { as_add_w(rd, rd, rs); }
void ma_addu(Register rd, Imm32 imm) { ma_add_w(rd, rd, imm); }
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 as_subu(Register rd, Register rj, Register rk) { as_sub_w(rd, rj, rk); }
void ma_subu(Register rd, Register rs) { as_sub_w(rd, rd, rs); }
void ma_subu(Register rd, Imm32 imm) { ma_sub_w(rd, rd, 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_addTestOverflow(Register rd, Register rj, Register rk,
Label* overflow) {
ma_add32TestOverflow(rd, rj, rk, overflow);
}
void ma_addTestOverflow(Register rd, Register rj, Imm32 imm,
Label* overflow) {
ma_add32TestOverflow(rd, rj, imm, overflow);
}
void ma_subTestOverflow(Register rd, Register rj, Register rk,
Label* overflow) {
ma_sub32TestOverflow(rd, rj, rk, overflow);
}
void ma_subTestOverflow(Register rd, Register rj, Imm32 imm,
Label* overflow) {
ma_sub32TestOverflow(rd, rj, imm, overflow);
}
void ma_negu(Register rd, Register rj) { as_sub_w(rd, zero, rj); }
void ma_not(Register rd, Register rj) { as_nor(rd, rj, zero); }
void ma_or(Register rd, Register rs) { as_or(rd, rd, rs); }
void ma_or(Register rd, Imm32 imm) { ma_or(rd, rd, imm); }
void ma_xor(Register rd, Register rs) { as_xor(rd, rd, rs); }
void ma_xor(Register rd, Imm32 imm) { ma_xor(rd, rd, imm); }
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_dsll(Register rd, Register rj, Register rk) { as_sll_d(rd, rj, rk); }
void ma_dsll(Register rd, Register rj, Imm32 imm) {
as_slli_d(rd, rj, imm.value & 0x3f);
}
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_dsrl(Register rd, Register rj, Register rk) { as_srl_d(rd, rj, rk); }
void ma_dsrl(Register rd, Register rj, Imm32 imm) {
as_srli_d(rd, rj, imm.value & 0x3f);
}
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);
}
void ma_dsra(Register rd, Register rj, Register rk) { as_sra_d(rd, rj, rk); }
void ma_dsra(Register rd, Register rj, Imm32 imm) {
as_srai_d(rd, rj, imm.value & 0x3f);
}
void ma_dins(Register rd, Register rj, Imm32 pos, Imm32 size) {
as_bstrins_d(rd, rj, pos.value + size.value - 1, pos.value);
}
void ma_dext(Register rd, Register rj, Imm32 pos, Imm32 size) {
as_bstrpick_d(rd, rj, pos.value + size.value - 1, pos.value);
}
void as_clz(Register rd, Register rj) { as_clz_w(rd, rj); }
void ma_ctz(Register rd, Register rj) { as_ctz_w(rd, rj); }
// branches when done from within la-specific code
void ma_b(Register lhs, Register rhs, Label* l, Condition c,
@ -375,13 +424,159 @@ class MacroAssemblerLOONGARCH64 : public Assembler {
void ma_jump(ImmPtr dest);
void as_mul(Register rd, Register rj, Register rk) { as_mul_w(rd, rj, rk); }
void as_movz(Register rd, Register rs, Register rt) { moveIfZero(rd, rs, rt); }
void as_movz(FloatFormat fmt, FloatRegister fd, FloatRegister fs,
Register rt) {
ma_fmovz(fmt, fd, fs, rt);
}
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_dmtc1(Register rt, FloatRegister fs) { as_movgr2fr_d(fs, rt); }
void as_dmfc1(Register rt, FloatRegister fs) { as_movfr2gr_d(rt, fs); }
BufferOffset as_cfc1(Register rd, FPControl) { return as_movfcsr2gr(rd); }
BufferOffset as_ext(Register rd, Register rj, int32_t pos, int32_t size) {
return as_bstrpick_w(rd, rj, pos + size - 1, pos);
}
void as_divs(FloatRegister fd, FloatRegister fj, FloatRegister fk) {
as_fdiv_s(fd, fj, fk);
BufferOffset as_ins(Register rd, Register rj, int32_t pos, int32_t size) {
return as_bstrins_w(rd, rj, pos + size - 1, pos);
}
BufferOffset as_sd(Register rd, Register rj, int32_t si12) {
return as_st_d(rd, rj, si12);
}
BufferOffset as_sd(FloatRegister fd, Register rj, int32_t si12) {
return as_fst_d(fd, rj, si12);
}
BufferOffset as_ld(FloatRegister fd, Register rj, int32_t si12) {
return as_fld_d(fd, rj, si12);
}
BufferOffset as_absd(FloatRegister fd, FloatRegister fj) {
return as_fabs_d(fd, fj);
}
BufferOffset as_abss(FloatRegister fd, FloatRegister fj) {
return as_fabs_s(fd, fj);
}
BufferOffset as_addd(FloatRegister fd, FloatRegister fj, FloatRegister fk) {
return as_fadd_d(fd, fj, fk);
}
BufferOffset as_adds(FloatRegister fd, FloatRegister fj, FloatRegister fk) {
return as_fadd_s(fd, fj, fk);
}
BufferOffset as_subd(FloatRegister fd, FloatRegister fj, FloatRegister fk) {
return as_fsub_d(fd, fj, fk);
}
BufferOffset as_subs(FloatRegister fd, FloatRegister fj, FloatRegister fk) {
return as_fsub_s(fd, fj, fk);
}
BufferOffset as_muld(FloatRegister fd, FloatRegister fj, FloatRegister fk) {
return as_fmul_d(fd, fj, fk);
}
BufferOffset as_muls(FloatRegister fd, FloatRegister fj, FloatRegister fk) {
return as_fmul_s(fd, fj, fk);
}
BufferOffset as_divd(FloatRegister fd, FloatRegister fj, FloatRegister fk) {
return as_fdiv_d(fd, fj, fk);
}
BufferOffset as_divs(FloatRegister fd, FloatRegister fj, FloatRegister fk) {
return as_fdiv_s(fd, fj, fk);
}
BufferOffset as_negd(FloatRegister fd, FloatRegister fj) {
return as_fneg_d(fd, fj);
}
BufferOffset as_negs(FloatRegister fd, FloatRegister fj) {
return as_fneg_s(fd, fj);
}
BufferOffset as_sqrtd(FloatRegister fd, FloatRegister fj) {
return as_fsqrt_d(fd, fj);
}
BufferOffset as_sqrts(FloatRegister fd, FloatRegister fj) {
return as_fsqrt_s(fd, fj);
}
BufferOffset as_floorwd(FloatRegister fd, FloatRegister fj) {
return as_ftintrm_w_d(fd, fj);
}
BufferOffset as_floorws(FloatRegister fd, FloatRegister fj) {
return as_ftintrm_w_s(fd, fj);
}
BufferOffset as_ceilwd(FloatRegister fd, FloatRegister fj) {
return as_ftintrp_w_d(fd, fj);
}
BufferOffset as_ceilws(FloatRegister fd, FloatRegister fj) {
return as_ftintrp_w_s(fd, fj);
}
BufferOffset as_truncld(FloatRegister fd, FloatRegister fj) {
return as_ftintrz_l_d(fd, fj);
}
BufferOffset as_truncls(FloatRegister fd, FloatRegister fj) {
return as_ftintrz_l_s(fd, fj);
}
BufferOffset as_truncwd(FloatRegister fd, FloatRegister fj) {
return as_ftintrz_w_d(fd, fj);
}
BufferOffset as_truncws(FloatRegister fd, FloatRegister fj) {
return as_ftintrz_w_s(fd, fj);
}
BufferOffset ma_BoundsCheck(Register bounded) {
BufferOffset bo = nextOffset();
ma_liPatchable(bounded, Imm32(0));
return bo;
}
void ma_load_unaligned(const wasm::MemoryAccessDesc& access, Register dest,
const BaseIndex& src, Register temp,
LoadStoreSize size, LoadStoreExtension extension) {
(void)access;
(void)dest;
(void)src;
(void)temp;
(void)size;
(void)extension;
MOZ_CRASH("wasm unaligned integer loads are not supported on loongarch64 yet");
}
void ma_store_unaligned(const wasm::MemoryAccessDesc& access, Register data,
const BaseIndex& dest, Register temp,
LoadStoreSize size, LoadStoreExtension extension) {
(void)access;
(void)data;
(void)dest;
(void)temp;
(void)size;
(void)extension;
MOZ_CRASH("wasm unaligned integer stores are not supported on loongarch64 yet");
}
void loadUnalignedDouble(const wasm::MemoryAccessDesc& access,
const BaseIndex& src, Register temp,
FloatRegister dest) {
(void)access;
(void)src;
(void)temp;
(void)dest;
MOZ_CRASH("wasm unaligned double loads are not supported on loongarch64 yet");
}
void loadUnalignedFloat32(const wasm::MemoryAccessDesc& access,
const BaseIndex& src, Register temp,
FloatRegister dest) {
(void)access;
(void)src;
(void)temp;
(void)dest;
MOZ_CRASH("wasm unaligned float loads are not supported on loongarch64 yet");
}
void storeUnalignedDouble(const wasm::MemoryAccessDesc& access,
FloatRegister src, Register temp,
const BaseIndex& dest) {
(void)access;
(void)src;
(void)temp;
(void)dest;
MOZ_CRASH("wasm unaligned double stores are not supported on loongarch64 yet");
}
void storeUnalignedFloat32(const wasm::MemoryAccessDesc& access,
FloatRegister src, Register temp,
const BaseIndex& dest) {
(void)access;
(void)src;
(void)temp;
(void)dest;
MOZ_CRASH("wasm unaligned float stores are not supported on loongarch64 yet");
}
void ma_cmp_set(Register dst, Register lhs, Register rhs, Condition c);
@ -471,8 +666,11 @@ class MacroAssemblerLOONGARCH64Compat : public MacroAssemblerLOONGARCH64 {
convertInt32ToDouble(Address(scratch, src.offset), dest);
};
void convertUInt32ToDouble(Register src, FloatRegister dest);
void convertInt64ToDouble(Register src, FloatRegister dest);
void convertInt64ToFloat32(Register src, FloatRegister dest);
void convertUInt32ToFloat32(Register src, FloatRegister dest);
void convertDoubleToFloat32(FloatRegister src, FloatRegister dest);
void convertUInt64ToFloat32(Register src, FloatRegister dest);
void convertDoubleToInt32(FloatRegister src, Register dest, Label* fail,
bool negativeZeroCheck = true);
void convertDoubleToPtr(FloatRegister src, Register dest, Label* fail,
@ -776,10 +974,16 @@ class MacroAssemblerLOONGARCH64Compat : public MacroAssemblerLOONGARCH64 {
void loadInt32OrDouble(const Address& src, FloatRegister dest);
void loadInt32OrDouble(const BaseIndex& addr, FloatRegister dest);
void loadConstantDouble(double dp, FloatRegister dest);
void loadConstantDouble(wasm::RawF64 dp, FloatRegister dest) {
loadConstantDouble(dp.fp(), dest);
}
void boolValueToFloat32(const ValueOperand& operand, FloatRegister dest);
void int32ValueToFloat32(const ValueOperand& operand, FloatRegister dest);
void loadConstantFloat32(float f, FloatRegister dest);
void loadConstantFloat32(wasm::RawF32 f, FloatRegister dest) {
loadConstantFloat32(f.fp(), dest);
}
void testNullSet(Condition cond, const ValueOperand& value, Register dest);
@ -1077,6 +1281,11 @@ class MacroAssemblerLOONGARCH64Compat : public MacroAssemblerLOONGARCH64 {
void zeroDouble(FloatRegister reg) { moveToDouble(zero, reg); }
void cmp64Set(Assembler::Condition cond, Register lhs, Imm32 rhs,
Register dest) {
ma_cmp_set(dest, lhs, rhs, cond);
}
void convertUInt64ToDouble(Register src, FloatRegister dest);
static bool convertUInt64ToDoubleNeedsTemp();
void convertUInt64ToDouble(Register64 src, FloatRegister dest, Register temp);

View file

@ -2235,6 +2235,10 @@ CodeGeneratorMIPSShared::visitAsmJSStoreHeap(LAsmJSStoreHeap* ins)
void
CodeGeneratorMIPSShared::visitAsmJSCompareExchangeHeap(LAsmJSCompareExchangeHeap* ins)
{
#ifdef JS_CODEGEN_LOONGARCH64
(void)ins;
MOZ_CRASH("asm.js atomics are not supported on loongarch64 yet");
#else
MAsmJSCompareExchangeHeap* mir = ins->mir();
Scalar::Type vt = mir->access().type();
const LAllocation* ptr = ins->ptr();
@ -2252,11 +2256,16 @@ CodeGeneratorMIPSShared::visitAsmJSCompareExchangeHeap(LAsmJSCompareExchangeHeap
srcAddr, oldval, newval, InvalidReg,
valueTemp, offsetTemp, maskTemp,
ToAnyRegister(ins->output()));
#endif
}
void
CodeGeneratorMIPSShared::visitAsmJSAtomicExchangeHeap(LAsmJSAtomicExchangeHeap* ins)
{
#ifdef JS_CODEGEN_LOONGARCH64
(void)ins;
MOZ_CRASH("asm.js atomics are not supported on loongarch64 yet");
#else
MAsmJSAtomicExchangeHeap* mir = ins->mir();
Scalar::Type vt = mir->access().type();
Register ptrReg = ToRegister(ins->ptr());
@ -2271,6 +2280,7 @@ CodeGeneratorMIPSShared::visitAsmJSAtomicExchangeHeap(LAsmJSAtomicExchangeHeap*
masm.atomicExchangeToTypedIntArray(vt == Scalar::Uint32 ? Scalar::Int32 : vt,
srcAddr, value, InvalidReg, valueTemp,
offsetTemp, maskTemp, ToAnyRegister(ins->output()));
#endif
}
void
@ -2549,6 +2559,19 @@ CodeGeneratorMIPSShared::atomicBinopToTypedIntArray(AtomicOp op, Scalar::Type ar
Register offsetTemp, Register maskTemp,
AnyRegister output)
{
#ifdef JS_CODEGEN_LOONGARCH64
(void)op;
(void)arrayType;
(void)value;
(void)mem;
(void)flagTemp;
(void)outTemp;
(void)valueTemp;
(void)offsetTemp;
(void)maskTemp;
(void)output;
MOZ_CRASH("asm.js atomics are not supported on loongarch64 yet");
#else
MOZ_ASSERT(flagTemp != InvalidReg);
MOZ_ASSERT_IF(arrayType == Scalar::Uint32, outTemp != InvalidReg);
@ -2686,6 +2709,7 @@ CodeGeneratorMIPSShared::atomicBinopToTypedIntArray(AtomicOp op, Scalar::Type ar
default:
MOZ_CRASH("Invalid typed array type");
}
#endif
}
template void
@ -2720,6 +2744,17 @@ CodeGeneratorMIPSShared::atomicBinopToTypedIntArray(AtomicOp op, Scalar::Type ar
const T& mem, Register flagTemp, Register valueTemp,
Register offsetTemp, Register maskTemp)
{
#ifdef JS_CODEGEN_LOONGARCH64
(void)op;
(void)arrayType;
(void)value;
(void)mem;
(void)flagTemp;
(void)valueTemp;
(void)offsetTemp;
(void)maskTemp;
MOZ_CRASH("atomics are not supported on loongarch64 Ion yet");
#else
MOZ_ASSERT(flagTemp != InvalidReg);
switch (arrayType) {
@ -2792,6 +2827,7 @@ CodeGeneratorMIPSShared::atomicBinopToTypedIntArray(AtomicOp op, Scalar::Type ar
default:
MOZ_CRASH("Invalid typed array type");
}
#endif
}
template void
@ -2819,11 +2855,16 @@ CodeGeneratorMIPSShared::atomicBinopToTypedIntArray(AtomicOp op, Scalar::Type ar
void
CodeGeneratorMIPSShared::visitWasmAddOffset(LWasmAddOffset* lir)
{
#ifdef JS_CODEGEN_LOONGARCH64
(void)lir;
MOZ_CRASH("wasm is not supported on loongarch64 yet");
#else
MWasmAddOffset* mir = lir->mir();
Register base = ToRegister(lir->base());
Register out = ToRegister(lir->output());
masm.ma_addTestCarry(out, base, Imm32(mir->offset()), trap(mir, wasm::Trap::OutOfBounds));
#endif
}
template <typename T>
@ -2911,6 +2952,10 @@ CodeGeneratorMIPSShared::visitAtomicTypedArrayElementBinopForEffect(LAtomicTyped
void
CodeGeneratorMIPSShared::visitCompareExchangeTypedArrayElement(LCompareExchangeTypedArrayElement* lir)
{
#ifdef JS_CODEGEN_LOONGARCH64
(void)lir;
MOZ_CRASH("atomics are not supported on loongarch64 Ion yet");
#else
Register elements = ToRegister(lir->elements());
AnyRegister output = ToAnyRegister(lir->output());
Register temp = lir->temp()->isBogusTemp() ? InvalidReg : ToRegister(lir->temp());
@ -2933,11 +2978,16 @@ CodeGeneratorMIPSShared::visitCompareExchangeTypedArrayElement(LCompareExchangeT
masm.compareExchangeToTypedIntArray(arrayType, dest, oldval, newval, temp,
valueTemp, offsetTemp, maskTemp, output);
}
#endif
}
void
CodeGeneratorMIPSShared::visitAtomicExchangeTypedArrayElement(LAtomicExchangeTypedArrayElement* lir)
{
#ifdef JS_CODEGEN_LOONGARCH64
(void)lir;
MOZ_CRASH("atomics are not supported on loongarch64 Ion yet");
#else
Register elements = ToRegister(lir->elements());
AnyRegister output = ToAnyRegister(lir->output());
Register temp = lir->temp()->isBogusTemp() ? InvalidReg : ToRegister(lir->temp());
@ -2959,4 +3009,5 @@ CodeGeneratorMIPSShared::visitAtomicExchangeTypedArrayElement(LAtomicExchangeTyp
masm.atomicExchangeToTypedIntArray(arrayType, dest, value, temp,
valueTemp, offsetTemp, maskTemp, output);
}
#endif
}

View file

@ -383,12 +383,19 @@ CodeGeneratorMIPS64::visitDivOrModI64(LDivOrModI64* lir)
masm.bind(&notmin);
}
#ifdef JS_CODEGEN_LOONGARCH64
if (lir->mir()->isMod())
masm.as_mod_d(output, lhs, rhs);
else
masm.as_div_d(output, lhs, rhs);
#else
masm.as_ddiv(lhs, rhs);
if (lir->mir()->isMod())
masm.as_mfhi(output);
else
masm.as_mflo(output);
#endif
masm.bind(&done);
}
@ -406,12 +413,19 @@ CodeGeneratorMIPS64::visitUDivOrModI64(LUDivOrModI64* lir)
if (lir->canBeDivideByZero())
masm.ma_b(rhs, rhs, trap(lir, wasm::Trap::IntegerDivideByZero), Assembler::Zero);
#ifdef JS_CODEGEN_LOONGARCH64
if (lir->mir()->isMod())
masm.as_mod_du(output, lhs, rhs);
else
masm.as_div_du(output, lhs, rhs);
#else
masm.as_ddivu(lhs, rhs);
if (lir->mir()->isMod())
masm.as_mfhi(output);
else
masm.as_mflo(output);
#endif
masm.bind(&done);
}

View file

@ -5,7 +5,11 @@
#include "jit/mips64/Lowering-mips64.h"
#include "jit/mips64/Assembler-mips64.h"
#ifdef JS_CODEGEN_LOONGARCH64
# include "jit/loongarch64/Assembler-loongarch64.h"
#else
# include "jit/mips64/Assembler-mips64.h"
#endif
#include "jit/MIR.h"

View file

@ -543,11 +543,11 @@ 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',
'jit/mips64/CodeGenerator-mips64.cpp',
'jit/mips64/Lowering-mips64.cpp',
'jit/mips64/MoveEmitter-mips64.cpp',
]
elif CONFIG['JS_CODEGEN_MIPS32'] or CONFIG['JS_CODEGEN_MIPS64']:
@ -786,4 +786,3 @@ selfhosted.inputs = [
# We are keeping this in the main moz.build because it is file specific
if CONFIG['CLANG_CXX'] or CONFIG['GNU_CXX']:
SOURCES['jsdtoa.cpp'].flags += ['-Wno-implicit-fallthrough']

View file

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

View file

@ -1264,7 +1264,7 @@ pref("javascript.options.strict.debug", false);
pref("javascript.options.unboxed_objects", false);
pref("javascript.options.baselinejit", true);
#if defined(JS_CODEGEN_LOONGARCH64)
pref("javascript.options.ion", false);
pref("javascript.options.ion", true);
pref("javascript.options.asmjs", false);
pref("javascript.options.wasm", false);
#else