зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1313336 - ARM64 wasmLoad and wasmStore masm instructions. r=jolesen
--HG-- extra : rebase_source : c6d1a2e881027a8ff19af75d78de4ba61bc9f212 extra : source : affa83b4c7892c90cf691cbf60eb3b1427b19a6f
This commit is contained in:
Родитель
5f0fbf8882
Коммит
0e74aff0c4
|
@ -1489,23 +1489,23 @@ class MacroAssembler : public MacroAssemblerSpecific
|
|||
void wasmStore(const wasm::MemoryAccessDesc& access, AnyRegister value, Operand dstAddr) DEFINED_ON(x86, x64);
|
||||
void wasmStoreI64(const wasm::MemoryAccessDesc& access, Register64 value, Operand dstAddr) DEFINED_ON(x86);
|
||||
|
||||
// For all the ARM wasmLoad and wasmStore functions, `ptr` MUST equal
|
||||
// `ptrScratch`, and that register will be updated based on conditions
|
||||
// For all the ARM and ARM64 wasmLoad and wasmStore functions, `ptr` MUST
|
||||
// equal `ptrScratch`, and that register will be updated based on conditions
|
||||
// listed below (where it is only mentioned as `ptr`).
|
||||
|
||||
// `ptr` will be updated if access.offset() != 0 or access.type() == Scalar::Int64.
|
||||
void wasmLoad(const wasm::MemoryAccessDesc& access, Register memoryBase, Register ptr,
|
||||
Register ptrScratch, AnyRegister output)
|
||||
DEFINED_ON(arm, mips_shared);
|
||||
DEFINED_ON(arm, arm64, mips_shared);
|
||||
void wasmLoadI64(const wasm::MemoryAccessDesc& access, Register memoryBase, Register ptr,
|
||||
Register ptrScratch, Register64 output)
|
||||
DEFINED_ON(arm, mips32, mips64);
|
||||
DEFINED_ON(arm, arm64, mips32, mips64);
|
||||
void wasmStore(const wasm::MemoryAccessDesc& access, AnyRegister value, Register memoryBase,
|
||||
Register ptr, Register ptrScratch)
|
||||
DEFINED_ON(arm, mips_shared);
|
||||
DEFINED_ON(arm, arm64, mips_shared);
|
||||
void wasmStoreI64(const wasm::MemoryAccessDesc& access, Register64 value, Register memoryBase,
|
||||
Register ptr, Register ptrScratch)
|
||||
DEFINED_ON(arm, mips32, mips64);
|
||||
DEFINED_ON(arm, arm64, mips32, mips64);
|
||||
|
||||
// `ptr` will always be updated.
|
||||
void wasmUnalignedLoad(const wasm::MemoryAccessDesc& access, Register memoryBase, Register ptr,
|
||||
|
|
|
@ -242,6 +242,147 @@ MacroAssemblerCompat::breakpoint()
|
|||
Brk((code++) & 0xffff);
|
||||
}
|
||||
|
||||
// Either `any` is valid or `sixtyfour` is valid. Return a 32-bit ARMRegister
|
||||
// in the first case and an ARMRegister of the desired size in the latter case.
|
||||
|
||||
static inline ARMRegister
|
||||
SelectGPReg(AnyRegister any, Register64 sixtyfour, unsigned size = 64)
|
||||
{
|
||||
MOZ_ASSERT(any.isValid() != (sixtyfour != Register64::Invalid()));
|
||||
|
||||
if (sixtyfour == Register64::Invalid())
|
||||
return ARMRegister(any.gpr(), 32);
|
||||
|
||||
return ARMRegister(sixtyfour.reg, size);
|
||||
}
|
||||
|
||||
// Assert that `sixtyfour` is invalid and then return an FP register from `any`
|
||||
// of the desired size.
|
||||
|
||||
static inline ARMFPRegister
|
||||
SelectFPReg(AnyRegister any, Register64 sixtyfour, unsigned size)
|
||||
{
|
||||
MOZ_ASSERT(sixtyfour == Register64::Invalid());
|
||||
return ARMFPRegister(any.fpu(), size);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerCompat::wasmLoadImpl(const wasm::MemoryAccessDesc& access, Register memoryBase_,
|
||||
Register ptr_, Register ptrScratch_, AnyRegister outany,
|
||||
Register64 out64)
|
||||
{
|
||||
uint32_t offset = access.offset();
|
||||
MOZ_ASSERT(offset < wasm::OffsetGuardLimit);
|
||||
|
||||
MOZ_ASSERT(ptr_ == ptrScratch_);
|
||||
|
||||
ARMRegister memoryBase(memoryBase_, 64);
|
||||
ARMRegister ptr(ptr_, 64);
|
||||
if (offset)
|
||||
Add(ptr, ptr, Operand(offset));
|
||||
|
||||
asMasm().memoryBarrierBefore(access.sync());
|
||||
|
||||
MemOperand srcAddr(memoryBase, ptr);
|
||||
size_t loadOffset = asMasm().currentOffset();
|
||||
switch (access.type()) {
|
||||
case Scalar::Int8:
|
||||
Ldrsb(SelectGPReg(outany, out64), srcAddr);
|
||||
break;
|
||||
case Scalar::Uint8:
|
||||
Ldrb(SelectGPReg(outany, out64), srcAddr);
|
||||
break;
|
||||
case Scalar::Int16:
|
||||
Ldrsh(SelectGPReg(outany, out64), srcAddr);
|
||||
break;
|
||||
case Scalar::Uint16:
|
||||
Ldrh(SelectGPReg(outany, out64), srcAddr);
|
||||
break;
|
||||
case Scalar::Int32:
|
||||
if (out64 != Register64::Invalid())
|
||||
Ldrsw(SelectGPReg(outany, out64), srcAddr);
|
||||
else
|
||||
Ldr(SelectGPReg(outany, out64, 32), srcAddr);
|
||||
break;
|
||||
case Scalar::Uint32:
|
||||
Ldr(SelectGPReg(outany, out64, 32), srcAddr);
|
||||
break;
|
||||
case Scalar::Int64:
|
||||
Ldr(SelectGPReg(outany, out64), srcAddr);
|
||||
break;
|
||||
case Scalar::Float32:
|
||||
Ldr(SelectFPReg(outany, out64, 32), srcAddr);
|
||||
break;
|
||||
case Scalar::Float64:
|
||||
Ldr(SelectFPReg(outany, out64, 64), srcAddr);
|
||||
break;
|
||||
case Scalar::Uint8Clamped:
|
||||
case Scalar::MaxTypedArrayViewType:
|
||||
case Scalar::Float32x4:
|
||||
case Scalar::Int32x4:
|
||||
case Scalar::Int8x16:
|
||||
case Scalar::Int16x8:
|
||||
MOZ_CRASH("unexpected array type");
|
||||
}
|
||||
append(access, loadOffset, framePushed());
|
||||
|
||||
asMasm().memoryBarrierAfter(access.sync());
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerCompat::wasmStoreImpl(const wasm::MemoryAccessDesc& access, AnyRegister valany,
|
||||
Register64 val64, Register memoryBase_, Register ptr_,
|
||||
Register ptrScratch_)
|
||||
{
|
||||
uint32_t offset = access.offset();
|
||||
MOZ_ASSERT(offset < wasm::OffsetGuardLimit);
|
||||
|
||||
MOZ_ASSERT(ptr_ == ptrScratch_);
|
||||
|
||||
ARMRegister memoryBase(memoryBase_, 64);
|
||||
ARMRegister ptr(ptr_, 64);
|
||||
if (offset)
|
||||
Add(ptr, ptr, Operand(offset));
|
||||
|
||||
asMasm().memoryBarrierBefore(access.sync());
|
||||
|
||||
MemOperand dstAddr(memoryBase, ptr);
|
||||
size_t storeOffset = asMasm().currentOffset();
|
||||
switch (access.type()) {
|
||||
case Scalar::Int8:
|
||||
case Scalar::Uint8:
|
||||
Strb(SelectGPReg(valany, val64), dstAddr);
|
||||
break;
|
||||
case Scalar::Int16:
|
||||
case Scalar::Uint16:
|
||||
Strh(SelectGPReg(valany, val64), dstAddr);
|
||||
break;
|
||||
case Scalar::Int32:
|
||||
case Scalar::Uint32:
|
||||
Str(SelectGPReg(valany, val64), dstAddr);
|
||||
break;
|
||||
case Scalar::Int64:
|
||||
Str(SelectGPReg(valany, val64), dstAddr);
|
||||
break;
|
||||
case Scalar::Float32:
|
||||
Str(SelectFPReg(valany, val64, 32), dstAddr);
|
||||
break;
|
||||
case Scalar::Float64:
|
||||
Str(SelectFPReg(valany, val64, 64), dstAddr);
|
||||
break;
|
||||
case Scalar::Float32x4:
|
||||
case Scalar::Int32x4:
|
||||
case Scalar::Int8x16:
|
||||
case Scalar::Int16x8:
|
||||
case Scalar::Uint8Clamped:
|
||||
case Scalar::MaxTypedArrayViewType:
|
||||
MOZ_CRASH("unexpected array type");
|
||||
}
|
||||
append(access, storeOffset, framePushed());
|
||||
|
||||
asMasm().memoryBarrierAfter(access.sync());
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::reserveStack(uint32_t amount)
|
||||
{
|
||||
|
@ -1160,6 +1301,34 @@ MacroAssembler::oolWasmTruncateCheckF64ToI64(FloatRegister input, Register64 out
|
|||
wasmTrap(wasm::Trap::IntegerOverflow, off);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::wasmLoad(const wasm::MemoryAccessDesc& access, Register memoryBase, Register ptr,
|
||||
Register ptrScratch, AnyRegister output)
|
||||
{
|
||||
wasmLoadImpl(access, memoryBase, ptr, ptrScratch, output, Register64::Invalid());
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::wasmLoadI64(const wasm::MemoryAccessDesc& access, Register memoryBase, Register ptr,
|
||||
Register ptrScratch, Register64 output)
|
||||
{
|
||||
wasmLoadImpl(access, memoryBase, ptr, ptrScratch, AnyRegister(), output);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::wasmStore(const wasm::MemoryAccessDesc& access, AnyRegister value,
|
||||
Register memoryBase, Register ptr, Register ptrScratch)
|
||||
{
|
||||
wasmStoreImpl(access, value, Register64::Invalid(), memoryBase, ptr, ptrScratch);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::wasmStoreI64(const wasm::MemoryAccessDesc& access, Register64 value,
|
||||
Register memoryBase, Register ptr, Register ptrScratch)
|
||||
{
|
||||
wasmStoreImpl(access, AnyRegister(), value, memoryBase, ptr, ptrScratch);
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// Convert floating point.
|
||||
|
||||
|
|
|
@ -1926,6 +1926,13 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
|
|||
return value;
|
||||
}
|
||||
|
||||
void wasmLoadImpl(const wasm::MemoryAccessDesc& access, Register memoryBase,
|
||||
Register ptr, Register ptrScratch, AnyRegister outany,
|
||||
Register64 out64);
|
||||
void wasmStoreImpl(const wasm::MemoryAccessDesc& access, AnyRegister valany,
|
||||
Register64 val64, Register memoryBase, Register ptr,
|
||||
Register ptrScratch);
|
||||
|
||||
// Emit a BLR or NOP instruction. ToggleCall can be used to patch
|
||||
// this instruction.
|
||||
CodeOffset toggledCall(JitCode* target, bool enabled) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче