Issue #3049 - loongarch64: fix wasm and debug-trap jit-test regressions

This commit is contained in:
Basilisk-Dev 2026-04-26 09:44:50 -04:00 committed by wuggy
commit 4428bafcac
5 changed files with 56 additions and 18 deletions

View file

@ -1801,7 +1801,9 @@ class InstJump : public Instruction {
((off.encode() >> 16) & 0x3ff);
}
uint32_t extractImm26Value() {
return extractBitField(Imm26Shift + Imm26Bits - 1, Imm26Shift);
uint32_t low16 = extractBitField(Imm16Shift + Imm16Bits - 1, Imm16Shift);
uint32_t high10 = extractBitField(9, 0);
return (high10 << 16) | low16;
}
};

View file

@ -50,6 +50,22 @@ static inline void SignExtendAtomicResult(MacroAssemblerLOONGARCH64Compat& masm,
}
}
static inline void ZeroExtendAtomicResult(MacroAssemblerLOONGARCH64Compat& masm,
int nbytes, Register output) {
switch (nbytes) {
case 1:
masm.as_bstrpick_d(output, output, 7, 0);
break;
case 2:
masm.as_bstrpick_d(output, output, 15, 0);
break;
case 4:
break;
default:
MOZ_CRASH("unexpected atomic width");
}
}
template <typename T>
static inline void PrepareAtomicAddress(
MacroAssemblerLOONGARCH64Compat& masm, int nbytes, const T& address,
@ -137,7 +153,15 @@ static void CompareExchangeLoongArch64(
}
if (oldval != InvalidReg) {
masm.ma_b(output, oldval, &done, Assembler::NotEqual, ShortJump);
masm.move32(oldval, valueTemp);
if (nbytes != 4) {
if (signExtend) {
SignExtendAtomicResult(masm, nbytes, valueTemp);
} else {
ZeroExtendAtomicResult(masm, nbytes, valueTemp);
}
}
masm.ma_b(output, valueTemp, &done, Assembler::NotEqual, ShortJump);
}
masm.move32(newval, valueTemp);
@ -1288,13 +1312,21 @@ void MacroAssemblerLOONGARCH64::ma_fst_d(FloatRegister src, Address address) {
}
void MacroAssemblerLOONGARCH64::ma_pop(FloatRegister f) {
as_fld_d(f, StackPointer, 0);
as_addi_d(StackPointer, StackPointer, sizeof(double));
if (f.isDouble()) {
as_fld_d(f, StackPointer, 0);
} else {
as_fld_s(f, StackPointer, 0);
}
as_addi_d(StackPointer, StackPointer, f.size());
}
void MacroAssemblerLOONGARCH64::ma_push(FloatRegister f) {
as_addi_d(StackPointer, StackPointer, (int32_t) - sizeof(double));
as_fst_d(f, StackPointer, 0);
as_addi_d(StackPointer, StackPointer, -int32_t(f.size()));
if (f.isDouble()) {
as_fst_d(f, StackPointer, 0);
} else {
as_fst_s(f, StackPointer, 0);
}
}
void MacroAssemblerLOONGARCH64::ma_li(Register dest, ImmGCPtr ptr) {
@ -2583,7 +2615,7 @@ void MacroAssembler::Push(const ImmGCPtr ptr) {
void MacroAssembler::Push(FloatRegister f) {
ma_push(f);
adjustFrame(int32_t(sizeof(double)));
adjustFrame(int32_t(f.size()));
}
void MacroAssembler::Pop(Register reg) {
@ -2593,7 +2625,7 @@ void MacroAssembler::Pop(Register reg) {
void MacroAssembler::Pop(FloatRegister f) {
ma_pop(f);
adjustFrame(-int32_t(sizeof(double)));
adjustFrame(-int32_t(f.size()));
}
void MacroAssembler::Pop(const ValueOperand& val) {

View file

@ -898,10 +898,6 @@ JitRuntime::generateDebugTrapHandler(JSContext* cx)
Register scratch1 = t0;
Register scratch2 = t1;
// Load BaselineFrame pointer in scratch1.
masm.movePtr(BaselineFrameReg, scratch1);
masm.subPtr(Imm32(BaselineFrame::Size()), scratch1);
// Enter a stub frame and call the HandleDebugTrap VM function. Ensure
// the stub frame has a nullptr ICStub pointer, since this pointer is
// marked during GC.
@ -912,6 +908,13 @@ JitRuntime::generateDebugTrapHandler(JSContext* cx)
if (!code)
return nullptr;
// Reload the caller's BaselineFrame pointer from the stub frame before
// reserving VM arguments. This avoids relying on a volatile scratch
// register across stub-frame setup.
masm.loadPtr(Address(StackPointer, offsetof(BaselineStubFrame, savedFrame)),
scratch1);
masm.subPtr(Imm32(BaselineFrame::Size()), scratch1);
masm.subPtr(Imm32(2 * sizeof(uintptr_t)), StackPointer);
masm.storePtr(ra, Address(StackPointer, sizeof(uintptr_t)));
masm.storePtr(scratch1, Address(StackPointer, 0));

View file

@ -1103,7 +1103,7 @@ class BaseCompiler
}
void loadConstI32(Register r, Stk& src) {
masm.mov(ImmWord((uint32_t)src.i32val() & 0xFFFFFFFFU), r);
masm.move32(Imm32(src.i32val()), r);
}
void loadMemI32(Register r, Stk& src) {

View file

@ -837,10 +837,12 @@ wasm::ToggleProfiling(const Code& code, const CallSite& callSite, bool enabled)
callerInsn->extractImm16(&calleeOffset);
void* callee = calleeOffset.getDest(reinterpret_cast<Instruction*>(caller));
#elif defined(JS_CODEGEN_LOONGARCH64)
uint8_t* caller = callerRetAddr - Assembler::PatchWrite_NearCallSize();
uint8_t* caller = callerRetAddr - sizeof(uint32_t);
Instruction* callerInsn = reinterpret_cast<Instruction*>(caller);
void* callee =
reinterpret_cast<void*>(Assembler::ExtractLoad64Value(callerInsn));
MOZ_ASSERT(callerInsn->extractOpcode() == ((uint32_t)op_bl >> OpcodeShift));
int32_t calleeOffset =
int32_t(reinterpret_cast<InstJump*>(callerInsn)->extractImm26Value() << 8) >> 6;
void* callee = caller + calleeOffset;
#elif defined(JS_CODEGEN_NONE)
MOZ_CRASH();
void* callee = nullptr;
@ -869,8 +871,7 @@ wasm::ToggleProfiling(const Code& code, const CallSite& callSite, bool enabled)
#elif defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
new (caller) InstImm(op_regimm, zero, rt_bgezal, BOffImm16(to - caller));
#elif defined(JS_CODEGEN_LOONGARCH64)
Assembler::UpdateLoad64Value(reinterpret_cast<Instruction*>(caller),
uint64_t(to));
reinterpret_cast<InstJump*>(caller)->setJOffImm26(JOffImm26(to - caller));
#elif defined(JS_CODEGEN_NONE)
MOZ_CRASH();
#else