mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-28 01:57:30 +09:00
Issue #3049 - Stabilize loongarch64 Ion patching and wasm loads
This commit is contained in:
parent
f796b3f7f1
commit
85c6fcc68e
3 changed files with 164 additions and 65 deletions
|
|
@ -22,20 +22,13 @@ void js::jit::PatchJump(CodeLocationJump& jump_, CodeLocationLabel label,
|
||||||
ReprotectCode reprotect) {
|
ReprotectCode reprotect) {
|
||||||
Instruction* inst = reinterpret_cast<Instruction*>(jump_.raw());
|
Instruction* inst = reinterpret_cast<Instruction*>(jump_.raw());
|
||||||
|
|
||||||
// jumpWithPatch() reserves four instructions:
|
// jumpWithPatch() emits a long-jump template up front so patching only
|
||||||
// beq zero, zero, 0
|
// updates the embedded target pointer and never mutates live control-flow
|
||||||
// INVALID_OFFSET
|
// opcodes in place.
|
||||||
// nop
|
MaybeAutoWritableJitCode awjc(inst, 3 * sizeof(uint32_t), reprotect);
|
||||||
// nop
|
Assembler::UpdateLoad64Value(inst, uintptr_t(label.raw()));
|
||||||
// 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));
|
AutoFlushICache::flush(uintptr_t(inst), 3 * 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
|
||||||
|
|
@ -2337,7 +2330,12 @@ void Assembler::bind(RepatchLabel* label) {
|
||||||
if (label->used() && !oom()) {
|
if (label->used() && !oom()) {
|
||||||
BufferOffset branch(label->offset());
|
BufferOffset branch(label->offset());
|
||||||
InstImm* inst = reinterpret_cast<InstImm*>(editSrc(branch));
|
InstImm* inst = reinterpret_cast<InstImm*>(editSrc(branch));
|
||||||
bind(inst, branch.getOffset(), dest.getOffset());
|
if ((inst[0].extractBitField(31, 25)) ==
|
||||||
|
((uint32_t)op_lu12i_w >> 25)) {
|
||||||
|
addLongJump(branch, dest);
|
||||||
|
} else {
|
||||||
|
bind(inst, branch.getOffset(), dest.getOffset());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
label->bind(dest.getOffset());
|
label->bind(dest.getOffset());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1547,6 +1547,145 @@ void MacroAssemblerLOONGARCH64::ma_store(Imm32 imm, const BaseIndex& dest,
|
||||||
asMasm().ma_store(scratch, Address(scratch2, 0), size, extension);
|
asMasm().ma_store(scratch, Address(scratch2, 0), size, extension);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacroAssemblerLOONGARCH64::ma_load_unaligned(
|
||||||
|
const wasm::MemoryAccessDesc& access, Register dest, const BaseIndex& src,
|
||||||
|
Register temp, LoadStoreSize size, LoadStoreExtension extension) {
|
||||||
|
MOZ_ASSERT(dest != temp);
|
||||||
|
|
||||||
|
asMasm().computeEffectiveAddress(src, temp);
|
||||||
|
|
||||||
|
BufferOffset load = as_ld_bu(dest, temp, 0);
|
||||||
|
if (size != SizeByte) {
|
||||||
|
ScratchRegisterScope scratch(asMasm());
|
||||||
|
const size_t byteSize = size / 8;
|
||||||
|
for (size_t i = 1; i < byteSize; i++) {
|
||||||
|
as_ld_bu(scratch, temp, i);
|
||||||
|
as_slli_d(scratch, scratch, 8 * i);
|
||||||
|
as_or(dest, dest, scratch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (size) {
|
||||||
|
case SizeByte:
|
||||||
|
if (extension == SignExtend) {
|
||||||
|
as_ext_w_b(dest, dest);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SizeHalfWord:
|
||||||
|
if (extension == SignExtend) {
|
||||||
|
as_ext_w_h(dest, dest);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SizeWord:
|
||||||
|
if (extension == SignExtend) {
|
||||||
|
as_addi_w(dest, dest, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SizeDouble:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
MOZ_CRASH("Invalid argument for ma_load_unaligned");
|
||||||
|
}
|
||||||
|
|
||||||
|
append(access, load.getOffset(), asMasm().framePushed());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroAssemblerLOONGARCH64::ma_store_unaligned(
|
||||||
|
const wasm::MemoryAccessDesc& access, Register data, const BaseIndex& dest,
|
||||||
|
Register temp, LoadStoreSize size, LoadStoreExtension extension) {
|
||||||
|
(void)extension;
|
||||||
|
|
||||||
|
MOZ_ASSERT(data != temp);
|
||||||
|
|
||||||
|
asMasm().computeEffectiveAddress(dest, temp);
|
||||||
|
|
||||||
|
BufferOffset store = as_st_b(data, temp, 0);
|
||||||
|
if (size != SizeByte) {
|
||||||
|
ScratchRegisterScope scratch(asMasm());
|
||||||
|
const size_t byteSize = size / 8;
|
||||||
|
for (size_t i = 1; i < byteSize; i++) {
|
||||||
|
as_srli_d(scratch, data, 8 * i);
|
||||||
|
as_st_b(scratch, temp, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
append(access, store.getOffset(), asMasm().framePushed());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroAssemblerLOONGARCH64::loadUnalignedDouble(
|
||||||
|
const wasm::MemoryAccessDesc& access, const BaseIndex& src, Register temp,
|
||||||
|
FloatRegister dest) {
|
||||||
|
asMasm().computeEffectiveAddress(src, temp);
|
||||||
|
|
||||||
|
ScratchRegisterScope scratch(asMasm());
|
||||||
|
SecondScratchRegisterScope scratch2(asMasm());
|
||||||
|
|
||||||
|
BufferOffset load = as_ld_bu(scratch, temp, 0);
|
||||||
|
for (size_t i = 1; i < sizeof(double); i++) {
|
||||||
|
as_ld_bu(scratch2, temp, i);
|
||||||
|
as_slli_d(scratch2, scratch2, 8 * i);
|
||||||
|
as_or(scratch, scratch, scratch2);
|
||||||
|
}
|
||||||
|
|
||||||
|
append(access, load.getOffset(), asMasm().framePushed());
|
||||||
|
moveToDouble(scratch, dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroAssemblerLOONGARCH64::loadUnalignedFloat32(
|
||||||
|
const wasm::MemoryAccessDesc& access, const BaseIndex& src, Register temp,
|
||||||
|
FloatRegister dest) {
|
||||||
|
asMasm().computeEffectiveAddress(src, temp);
|
||||||
|
|
||||||
|
ScratchRegisterScope scratch(asMasm());
|
||||||
|
SecondScratchRegisterScope scratch2(asMasm());
|
||||||
|
|
||||||
|
BufferOffset load = as_ld_bu(scratch, temp, 0);
|
||||||
|
for (size_t i = 1; i < sizeof(float); i++) {
|
||||||
|
as_ld_bu(scratch2, temp, i);
|
||||||
|
as_slli_d(scratch2, scratch2, 8 * i);
|
||||||
|
as_or(scratch, scratch, scratch2);
|
||||||
|
}
|
||||||
|
|
||||||
|
append(access, load.getOffset(), asMasm().framePushed());
|
||||||
|
moveToFloat32(scratch, dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroAssemblerLOONGARCH64::storeUnalignedDouble(
|
||||||
|
const wasm::MemoryAccessDesc& access, FloatRegister src, Register temp,
|
||||||
|
const BaseIndex& dest) {
|
||||||
|
asMasm().computeEffectiveAddress(dest, temp);
|
||||||
|
|
||||||
|
ScratchRegisterScope scratch(asMasm());
|
||||||
|
SecondScratchRegisterScope scratch2(asMasm());
|
||||||
|
moveFromDouble(src, scratch);
|
||||||
|
|
||||||
|
BufferOffset store = as_st_b(scratch, temp, 0);
|
||||||
|
for (size_t i = 1; i < sizeof(double); i++) {
|
||||||
|
as_srli_d(scratch2, scratch, 8 * i);
|
||||||
|
as_st_b(scratch2, temp, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
append(access, store.getOffset(), asMasm().framePushed());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroAssemblerLOONGARCH64::storeUnalignedFloat32(
|
||||||
|
const wasm::MemoryAccessDesc& access, FloatRegister src, Register temp,
|
||||||
|
const BaseIndex& dest) {
|
||||||
|
asMasm().computeEffectiveAddress(dest, temp);
|
||||||
|
|
||||||
|
ScratchRegisterScope scratch(asMasm());
|
||||||
|
SecondScratchRegisterScope scratch2(asMasm());
|
||||||
|
moveFromFloat32(src, scratch);
|
||||||
|
|
||||||
|
BufferOffset store = as_st_b(scratch, temp, 0);
|
||||||
|
for (size_t i = 1; i < sizeof(float); i++) {
|
||||||
|
as_srli_d(scratch2, scratch, 8 * i);
|
||||||
|
as_st_b(scratch2, temp, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
append(access, store.getOffset(), asMasm().framePushed());
|
||||||
|
}
|
||||||
|
|
||||||
// Branches when done from within loongarch-specific code.
|
// Branches when done from within loongarch-specific code.
|
||||||
// TODO(loongarch64) Optimize ma_b
|
// TODO(loongarch64) Optimize ma_b
|
||||||
void MacroAssemblerLOONGARCH64::ma_b(Register lhs, Register rhs, Label* label,
|
void MacroAssemblerLOONGARCH64::ma_b(Register lhs, Register rhs, Label* label,
|
||||||
|
|
@ -2512,16 +2651,18 @@ CodeOffsetJump MacroAssemblerLOONGARCH64Compat::backedgeJump(
|
||||||
|
|
||||||
CodeOffsetJump MacroAssemblerLOONGARCH64Compat::jumpWithPatch(
|
CodeOffsetJump MacroAssemblerLOONGARCH64Compat::jumpWithPatch(
|
||||||
RepatchLabel* label, Label* documentation) {
|
RepatchLabel* label, Label* documentation) {
|
||||||
|
(void)documentation;
|
||||||
MOZ_ASSERT(!label->used());
|
MOZ_ASSERT(!label->used());
|
||||||
|
|
||||||
BufferOffset bo = nextOffset();
|
BufferOffset bo = nextOffset();
|
||||||
label->use(bo.getOffset());
|
label->use(bo.getOffset());
|
||||||
|
|
||||||
m_buffer.ensureSpace(4 * sizeof(uint32_t));
|
m_buffer.ensureSpace(4 * sizeof(uint32_t));
|
||||||
writeInst(InstImm(op_beq, BOffImm16(0), zero, zero).encode());
|
if (label->bound()) {
|
||||||
writeInst(LabelBase::INVALID_OFFSET);
|
addLongJump(bo, BufferOffset(label->offset()));
|
||||||
as_nop();
|
}
|
||||||
as_nop();
|
ma_liPatchable(ScratchRegister, ImmWord(LabelBase::INVALID_OFFSET));
|
||||||
|
as_jirl(zero, ScratchRegister, BOffImm16(0));
|
||||||
return CodeOffsetJump(bo.getOffset());
|
return CodeOffsetJump(bo.getOffset());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -559,62 +559,22 @@ class MacroAssemblerLOONGARCH64 : public Assembler {
|
||||||
}
|
}
|
||||||
void ma_load_unaligned(const wasm::MemoryAccessDesc& access, Register dest,
|
void ma_load_unaligned(const wasm::MemoryAccessDesc& access, Register dest,
|
||||||
const BaseIndex& src, Register temp,
|
const BaseIndex& src, Register temp,
|
||||||
LoadStoreSize size, LoadStoreExtension extension) {
|
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,
|
void ma_store_unaligned(const wasm::MemoryAccessDesc& access, Register data,
|
||||||
const BaseIndex& dest, Register temp,
|
const BaseIndex& dest, Register temp,
|
||||||
LoadStoreSize size, LoadStoreExtension extension) {
|
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,
|
void loadUnalignedDouble(const wasm::MemoryAccessDesc& access,
|
||||||
const BaseIndex& src, Register temp,
|
const BaseIndex& src, Register temp,
|
||||||
FloatRegister dest) {
|
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,
|
void loadUnalignedFloat32(const wasm::MemoryAccessDesc& access,
|
||||||
const BaseIndex& src, Register temp,
|
const BaseIndex& src, Register temp,
|
||||||
FloatRegister dest) {
|
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,
|
void storeUnalignedDouble(const wasm::MemoryAccessDesc& access,
|
||||||
FloatRegister src, Register temp,
|
FloatRegister src, Register temp,
|
||||||
const BaseIndex& dest) {
|
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,
|
void storeUnalignedFloat32(const wasm::MemoryAccessDesc& access,
|
||||||
FloatRegister src, Register temp,
|
FloatRegister src, Register temp,
|
||||||
const BaseIndex& dest) {
|
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);
|
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(Register dst, Register lhs, Imm32 imm, Condition c);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue