Issue #3049 - loongarch64: retire stale JIT TODOs

This commit is contained in:
Basilisk-Dev 2026-04-25 22:17:42 -04:00 committed by wuggy
commit 5cfc8c8457
5 changed files with 51 additions and 130 deletions

View file

@ -73,7 +73,7 @@ uint32_t FloatRegister::getRegisterDumpOffsetInBytes() {
}
bool CPUFlagsHaveBeenComputed() {
// TODO(loongarch64): Add CPU flags support.
// No optional LoongArch64 CPU feature bits are consumed by this backend yet.
return true;
}

View file

@ -293,7 +293,8 @@ class FloatRegisters {
static const SetType AllDoubleMask = AllPhysMask * SpreadDouble;
static const SetType NoneMask = SetType(0);
// TODO(loongarch64): Much less than ARM64 here.
// LoongArch64 only tracks the scalar callee-saved fp registers here; there
// are no SIMD aliases to account for in this backend yet.
static const SetType NonVolatileMask =
SetType((1 << FloatRegisters::f24) | (1 << FloatRegisters::f25) |
(1 << FloatRegisters::f26) | (1 << FloatRegisters::f27) |

View file

@ -49,11 +49,10 @@ void js::jit::PatchJump(CodeLocationJump& jump_, CodeLocationLabel label,
// Note this is used for inter-wasm calls and may pass arguments and results
// in floating point registers even if the system ABI does not.
// TODO(loongarch64): Inconsistent with LoongArch's calling convention.
// LoongArch floating-point parameters calling convention:
// The first eight floating-point parameters should be passed in f0-f7, and
// the other floating point parameters will be passed like integer parameters.
// But we just pass the other floating-point parameters on stack here.
// For the internal JIT ABI we spill floating-point arguments beyond f0-f7 to
// the stack instead of recycling integer argument registers. Caller and callee
// both use this discipline, so it remains self-consistent even though the
// native LoongArch C ABI would next use integer argument slots.
ABIArg ABIArgGenerator::next(MIRType type) {
switch (type) {
case MIRType::Int32:
@ -335,7 +334,8 @@ void AssemblerLOONGARCH64::WriteInstStatic(uint32_t x, uint32_t* dest) {
}
BufferOffset AssemblerLOONGARCH64::haltingAlign(int alignment) {
// TODO(loongarch64): Implement a proper halting align.
// Like ARM64, we currently pad with nops because there is no dedicated
// backend-specific halting fill sequence here yet.
return nopAlign(alignment);
}

View file

@ -237,8 +237,8 @@ static_assert(JitStackAlignment % sizeof(Value) == 0 &&
JitStackValueAlignment >= 1,
"Stack alignment should be a non-zero multiple of sizeof(Value)");
// TODO(loongarch64): this is just a filler to prevent a build failure. The
// LoongArch SIMD alignment requirements still need to be explored.
// The backend does not expose LSX/LASX registers yet, but wasm/JIT constant
// pools still assume 16-byte alignment for SIMD-sized data blobs.
static constexpr uint32_t SimdMemoryAlignment = 16;
static_assert(CodeAlignment % SimdMemoryAlignment == 0,
@ -258,9 +258,7 @@ static constexpr uint32_t WasmCheckedTailEntryOffset = 16u;
static constexpr Scale ScalePointer = TimesEight;
// TODO(loongarch64): Add LoongArch instruction types description.
// LoongArch instruction encoding constants.
// LoongArch instruction encoding constants and operand field positions.
static const uint32_t RJShift = 5;
static const uint32_t RJBits = 5;
static const uint32_t RKShift = 10;
@ -342,11 +340,11 @@ static const uint32_t BOffImm21Mask = ((1 << Imm21Bits) - 1) << Imm21Shift;
static const uint32_t BOffImm26Mask = ((1 << Imm26Bits) - 1) << Imm26Shift;
static const uint32_t RegMask = Registers::Total - 1;
// TODO(loongarch64) Change to syscall?
// LoongArch break encodes a 10-bit immediate trap code.
static const uint32_t MAX_BREAK_CODE = 1024 - 1;
static const uint32_t WASM_TRAP = 6; // BRK_OVERFLOW
// TODO(loongarch64) Change to LoongArch instruction type.
// Forward declarations for decoded instruction wrappers.
class Instruction;
class InstReg;
class InstImm;
@ -864,7 +862,7 @@ class LOONGBufferWithExecutableCopy : public LOONGBuffer {
class AssemblerLOONGARCH64 : public AssemblerShared {
public:
// TODO(loongarch64): Should we remove these conditions here?
// Keep these aligned with the shared MacroAssembler condition space.
enum Condition {
Equal,
NotEqual,

View file

@ -859,7 +859,6 @@ void MacroAssemblerLOONGARCH64::ma_subPtrTestOverflow(Register rd, Register rj,
void MacroAssemblerLOONGARCH64::ma_subPtrTestOverflow(Register rd, Register rj,
Imm32 imm, Label* overflow) {
// TODO(loongarch64): Check subPtrTestOverflow
MOZ_ASSERT(imm.value != INT32_MIN);
ma_addPtrTestOverflow(rd, rj, Imm32(-imm.value), overflow);
}
@ -907,77 +906,37 @@ void MacroAssemblerLOONGARCH64::ma_mulPtrTestOverflow(Register rd, Register rj,
void MacroAssemblerLOONGARCH64::ma_load(Register dest, Address address,
LoadStoreSize size,
LoadStoreExtension extension) {
int32_t encodedOffset;
Register base;
// TODO: use as_ldx_b/h/w/d, could decrease as_add_d instr.
switch (size) {
case SizeByte:
case SizeHalfWord:
if (!is_intN(address.offset, 12)) {
ma_li(ScratchRegister, Imm32(address.offset));
as_add_d(ScratchRegister, address.base, ScratchRegister);
base = ScratchRegister;
encodedOffset = 0;
if (ZeroExtend == extension) {
ma_ld_bu(dest, address);
} else {
encodedOffset = address.offset;
base = address.base;
ma_ld_b(dest, address);
}
if (size == SizeByte) {
if (ZeroExtend == extension) {
as_ld_bu(dest, base, encodedOffset);
} else {
as_ld_b(dest, base, encodedOffset);
}
break;
case SizeHalfWord:
if (ZeroExtend == extension) {
ma_ld_hu(dest, address);
} else {
if (ZeroExtend == extension) {
as_ld_hu(dest, base, encodedOffset);
} else {
as_ld_h(dest, base, encodedOffset);
}
ma_ld_h(dest, address);
}
break;
case SizeWord:
if ((address.offset & 0x3) == 0 && SignExtend == extension &&
Imm16::IsInSignedRange(address.offset)) {
as_ldptr_w(dest, address.base, address.offset);
} else if (ZeroExtend == extension) {
ma_ld_wu(dest, address);
} else {
ma_ld_w(dest, address);
}
break;
case SizeDouble:
if ((address.offset & 0x3) == 0 &&
(size == SizeDouble ||
(size == SizeWord && SignExtend == extension))) {
if (!Imm16::IsInSignedRange(address.offset)) {
ma_li(ScratchRegister, Imm32(address.offset));
as_add_d(ScratchRegister, address.base, ScratchRegister);
base = ScratchRegister;
encodedOffset = 0;
} else {
encodedOffset = address.offset;
base = address.base;
}
if (size == SizeWord) {
as_ldptr_w(dest, base, encodedOffset);
} else {
as_ldptr_d(dest, base, encodedOffset);
}
Imm16::IsInSignedRange(address.offset)) {
as_ldptr_d(dest, address.base, address.offset);
} else {
if (!is_intN(address.offset, 12)) {
ma_li(ScratchRegister, Imm32(address.offset));
as_add_d(ScratchRegister, address.base, ScratchRegister);
base = ScratchRegister;
encodedOffset = 0;
} else {
encodedOffset = address.offset;
base = address.base;
}
if (size == SizeWord) {
if (ZeroExtend == extension) {
as_ld_wu(dest, base, encodedOffset);
} else {
as_ld_w(dest, base, encodedOffset);
}
} else {
as_ld_d(dest, base, encodedOffset);
}
ma_ld_d(dest, address);
}
break;
default:
@ -988,63 +947,27 @@ void MacroAssemblerLOONGARCH64::ma_load(Register dest, Address address,
void MacroAssemblerLOONGARCH64::ma_store(Register data, Address address,
LoadStoreSize size,
LoadStoreExtension extension) {
int32_t encodedOffset;
Register base;
// TODO: use as_stx_b/h/w/d, could decrease as_add_d instr.
switch (size) {
case SizeByte:
ma_st_b(data, address);
break;
case SizeHalfWord:
if (!is_intN(address.offset, 12)) {
ma_li(ScratchRegister, Imm32(address.offset));
as_add_d(ScratchRegister, address.base, ScratchRegister);
base = ScratchRegister;
encodedOffset = 0;
} else {
encodedOffset = address.offset;
base = address.base;
}
if (size == SizeByte) {
as_st_b(data, base, encodedOffset);
} else {
as_st_h(data, base, encodedOffset);
}
ma_st_h(data, address);
break;
case SizeWord:
case SizeDouble:
if ((address.offset & 0x3) == 0) {
if (!Imm16::IsInSignedRange(address.offset)) {
ma_li(ScratchRegister, Imm32(address.offset));
as_add_d(ScratchRegister, address.base, ScratchRegister);
base = ScratchRegister;
encodedOffset = 0;
} else {
encodedOffset = address.offset;
base = address.base;
}
if (size == SizeWord) {
as_stptr_w(data, base, encodedOffset);
} else {
as_stptr_d(data, base, encodedOffset);
}
if ((address.offset & 0x3) == 0 &&
Imm16::IsInSignedRange(address.offset)) {
as_stptr_w(data, address.base, address.offset);
} else {
if (!is_intN(address.offset, 12)) {
ma_li(ScratchRegister, Imm32(address.offset));
as_add_d(ScratchRegister, address.base, ScratchRegister);
base = ScratchRegister;
encodedOffset = 0;
} else {
encodedOffset = address.offset;
base = address.base;
}
if (size == SizeWord) {
as_st_w(data, base, encodedOffset);
} else {
as_st_d(data, base, encodedOffset);
}
ma_st_w(data, address);
}
break;
case SizeDouble:
if ((address.offset & 0x3) == 0 &&
Imm16::IsInSignedRange(address.offset)) {
as_stptr_d(data, address.base, address.offset);
} else {
ma_st_d(data, address);
}
break;
default:
@ -1274,8 +1197,8 @@ void MacroAssemblerLOONGARCH64::ma_cmp_set(Register rd, Register rj, ImmPtr imm,
void MacroAssemblerLOONGARCH64::ma_cmp_set(Register rd, Address address, Imm32 imm,
Condition c) {
// TODO(loongarch64): 32-bit ma_cmp_set?
SecondScratchRegisterScope scratch2(asMasm());
// Match the register/Imm32 helper by comparing a sign-extended 32-bit value.
ma_ld_w(scratch2, address);
ma_cmp_set(rd, Register(scratch2), imm, c);
}
@ -1818,8 +1741,7 @@ void MacroAssemblerLOONGARCH64::storeUnalignedFloat32(
append(access, store.getOffset(), asMasm().framePushed());
}
// Branches when done from within loongarch-specific code.
// TODO(loongarch64) Optimize ma_b
// Branches emitted from loongarch64-specific code paths.
void MacroAssemblerLOONGARCH64::ma_b(Register lhs, Register rhs, Label* label,
Condition c, JumpKind jumpKind) {
switch (c) {
@ -2488,7 +2410,7 @@ void MacroAssemblerLOONGARCH64Compat::wasmLoadI64Impl(
as_ldx_w(output.reg, memoryBase, ptr);
break;
case Scalar::Uint32:
// TODO(loongarch64): Why need zero-extension here?
// Register64 consumers expect the upper half to be cleared for Uint32.
as_ldx_wu(output.reg, memoryBase, ptr);
break;
case Scalar::Int64: