зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1277011
- Abstract asm.js loadHeap and storeHeap on ARM. r=nbp
--HG-- extra : rebase_source : e6b7b5d9ea0310e35f51bd3ae473eb34a9fcf311 extra : source : f228cee547d5a39d447d0cd24bce223628ee0828
This commit is contained in:
Родитель
570bcc2702
Коммит
c5d9947c1a
|
@ -2175,50 +2175,16 @@ CodeGeneratorARM::visitAsmJSLoadHeap(LAsmJSLoadHeap* ins)
|
|||
masm.ma_dataTransferN(IsLoad, size, isSigned, HeapReg, Imm32(ptrImm),
|
||||
ToRegister(ins->output()), Offset, Assembler::Always);
|
||||
}
|
||||
memoryBarrier(mir->barrierAfter());
|
||||
return;
|
||||
}
|
||||
|
||||
Register ptrReg = ToRegister(ptr);
|
||||
|
||||
if (!mir->needsBoundsCheck()) {
|
||||
if (isFloat) {
|
||||
VFPRegister vd(ToFloatRegister(ins->output()));
|
||||
if (size == 32)
|
||||
masm.ma_vldr(vd.singleOverlay(), HeapReg, ptrReg, 0, Assembler::Always);
|
||||
else
|
||||
masm.ma_vldr(vd, HeapReg, ptrReg, 0, Assembler::Always);
|
||||
} else {
|
||||
masm.ma_dataTransferN(IsLoad, size, isSigned, HeapReg, ptrReg,
|
||||
ToRegister(ins->output()), Offset, Assembler::Always);
|
||||
}
|
||||
memoryBarrier(mir->barrierAfter());
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t cmpOffset = masm.ma_BoundsCheck(ptrReg).getOffset();
|
||||
masm.append(wasm::BoundsCheck(cmpOffset));
|
||||
|
||||
if (isFloat) {
|
||||
FloatRegister dst = ToFloatRegister(ins->output());
|
||||
VFPRegister vd(dst);
|
||||
if (size == 32) {
|
||||
masm.ma_vldr(Address(GlobalReg, wasm::NaN32GlobalDataOffset - AsmJSGlobalRegBias),
|
||||
vd.singleOverlay(), Assembler::AboveOrEqual);
|
||||
masm.ma_vldr(vd.singleOverlay(), HeapReg, ptrReg, 0, Assembler::Below);
|
||||
} else {
|
||||
masm.ma_vldr(Address(GlobalReg, wasm::NaN64GlobalDataOffset - AsmJSGlobalRegBias),
|
||||
vd, Assembler::AboveOrEqual);
|
||||
masm.ma_vldr(vd, HeapReg, ptrReg, 0, Assembler::Below);
|
||||
}
|
||||
} else {
|
||||
Register d = ToRegister(ins->output());
|
||||
if (mir->isAtomicAccess())
|
||||
masm.ma_b(wasm::JumpTarget::OutOfBounds, Assembler::AboveOrEqual);
|
||||
Register ptrReg = ToRegister(ptr);
|
||||
if (isFloat)
|
||||
masm.ma_loadHeapAsmJS(ptrReg, size, mir->needsBoundsCheck(),
|
||||
/*faultOnOOB=*/false, ToFloatRegister(ins->output()));
|
||||
else
|
||||
masm.ma_mov(Imm32(0), d, Assembler::AboveOrEqual);
|
||||
masm.ma_dataTransferN(IsLoad, size, isSigned, HeapReg, ptrReg, d, Offset, Assembler::Below);
|
||||
masm.ma_loadHeapAsmJS(ptrReg, size, isSigned, mir->needsBoundsCheck(),
|
||||
mir->isAtomicAccess(), ToRegister(ins->output()));
|
||||
}
|
||||
|
||||
memoryBarrier(mir->barrierAfter());
|
||||
}
|
||||
|
||||
|
@ -2240,8 +2206,11 @@ CodeGeneratorARM::visitAsmJSStoreHeap(LAsmJSStoreHeap* ins)
|
|||
case Scalar::Float32: isFloat = true; size = 32; break;
|
||||
default: MOZ_CRASH("unexpected array type");
|
||||
}
|
||||
const LAllocation* ptr = ins->ptr();
|
||||
|
||||
memoryBarrier(mir->barrierBefore());
|
||||
|
||||
const LAllocation* ptr = ins->ptr();
|
||||
|
||||
if (ptr->isConstant()) {
|
||||
MOZ_ASSERT(!mir->needsBoundsCheck());
|
||||
int32_t ptrImm = ptr->toConstant()->toInt32();
|
||||
|
@ -2257,44 +2226,16 @@ CodeGeneratorARM::visitAsmJSStoreHeap(LAsmJSStoreHeap* ins)
|
|||
masm.ma_dataTransferN(IsStore, size, isSigned, HeapReg, Imm32(ptrImm),
|
||||
ToRegister(ins->value()), Offset, Assembler::Always);
|
||||
}
|
||||
memoryBarrier(mir->barrierAfter());
|
||||
return;
|
||||
}
|
||||
|
||||
Register ptrReg = ToRegister(ptr);
|
||||
|
||||
if (!mir->needsBoundsCheck()) {
|
||||
Register ptrReg = ToRegister(ptr);
|
||||
if (isFloat) {
|
||||
VFPRegister vd(ToFloatRegister(ins->value()));
|
||||
BaseIndex addr(HeapReg, ptrReg, TimesOne, 0);
|
||||
if (size == 32)
|
||||
masm.storeFloat32(vd, addr);
|
||||
else
|
||||
masm.storeDouble(vd, addr);
|
||||
} else {
|
||||
masm.ma_dataTransferN(IsStore, size, isSigned, HeapReg, ptrReg,
|
||||
ToRegister(ins->value()), Offset, Assembler::Always);
|
||||
}
|
||||
memoryBarrier(mir->barrierAfter());
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t cmpOffset = masm.ma_BoundsCheck(ptrReg).getOffset();
|
||||
masm.append(wasm::BoundsCheck(cmpOffset));
|
||||
|
||||
if (isFloat) {
|
||||
VFPRegister vd(ToFloatRegister(ins->value()));
|
||||
if (size == 32)
|
||||
masm.ma_vstr(vd.singleOverlay(), HeapReg, ptrReg, 0, 0, Assembler::Below);
|
||||
else
|
||||
masm.ma_vstr(vd, HeapReg, ptrReg, 0, 0, Assembler::Below);
|
||||
} else {
|
||||
if (mir->isAtomicAccess())
|
||||
masm.ma_b(wasm::JumpTarget::OutOfBounds, Assembler::AboveOrEqual);
|
||||
masm.ma_dataTransferN(IsStore, size, isSigned, HeapReg, ptrReg,
|
||||
ToRegister(ins->value()), Offset, Assembler::Below);
|
||||
Register ptrReg = ToRegister(ptr);
|
||||
if (isFloat)
|
||||
masm.ma_storeHeapAsmJS(ptrReg, size, mir->needsBoundsCheck(), /*faultOnOOB=*/false,
|
||||
ToFloatRegister(ins->value()));
|
||||
else
|
||||
masm.ma_storeHeapAsmJS(ptrReg, size, isSigned, mir->needsBoundsCheck(),
|
||||
mir->isAtomicAccess(), ToRegister(ins->value()));
|
||||
}
|
||||
|
||||
memoryBarrier(mir->barrierAfter());
|
||||
}
|
||||
|
||||
|
|
|
@ -2116,6 +2116,55 @@ MacroAssemblerARMCompat::loadFloat32(const BaseIndex& src, FloatRegister dest)
|
|||
ma_vldr(Address(scratch, offset), VFPRegister(dest).singleOverlay());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MacroAssemblerARMCompat::ma_loadHeapAsmJS(Register ptrReg, int size, bool needsBoundsCheck,
|
||||
bool faultOnOOB, FloatRegister output)
|
||||
{
|
||||
if (size == 32)
|
||||
output = output.singleOverlay();
|
||||
|
||||
if (!needsBoundsCheck) {
|
||||
ma_vldr(output, HeapReg, ptrReg, 0, Assembler::Always);
|
||||
} else {
|
||||
uint32_t cmpOffset = ma_BoundsCheck(ptrReg).getOffset();
|
||||
append(wasm::BoundsCheck(cmpOffset));
|
||||
|
||||
if (faultOnOOB) {
|
||||
ma_b(wasm::JumpTarget::OutOfBounds, Assembler::AboveOrEqual);
|
||||
}
|
||||
else {
|
||||
size_t nanOffset =
|
||||
size == 32 ? wasm::NaN32GlobalDataOffset : wasm::NaN64GlobalDataOffset;
|
||||
ma_vldr(Address(GlobalReg, nanOffset - AsmJSGlobalRegBias), output,
|
||||
Assembler::AboveOrEqual);
|
||||
}
|
||||
ma_vldr(output, HeapReg, ptrReg, 0, Assembler::Below);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerARMCompat::ma_loadHeapAsmJS(Register ptrReg, int size, bool isSigned,
|
||||
bool needsBoundsCheck, bool faultOnOOB,
|
||||
Register output)
|
||||
{
|
||||
if (!needsBoundsCheck) {
|
||||
ma_dataTransferN(IsLoad, size, isSigned, HeapReg, ptrReg, output, Offset,
|
||||
Assembler::Always);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t cmpOffset = ma_BoundsCheck(ptrReg).getOffset();
|
||||
append(wasm::BoundsCheck(cmpOffset));
|
||||
|
||||
if (faultOnOOB)
|
||||
ma_b(wasm::JumpTarget::OutOfBounds, Assembler::AboveOrEqual);
|
||||
else
|
||||
ma_mov(Imm32(0), output, Assembler::AboveOrEqual);
|
||||
|
||||
ma_dataTransferN(IsLoad, size, isSigned, HeapReg, ptrReg, output, Offset, Assembler::Below);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerARMCompat::store8(Imm32 imm, const Address& address)
|
||||
{
|
||||
|
@ -2292,6 +2341,51 @@ MacroAssemblerARMCompat::storePtr(Register src, AbsoluteAddress dest)
|
|||
storePtr(src, Address(scratch, 0));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerARMCompat::ma_storeHeapAsmJS(Register ptrReg, int size, bool needsBoundsCheck,
|
||||
bool faultOnOOB, FloatRegister value)
|
||||
{
|
||||
if (!needsBoundsCheck) {
|
||||
BaseIndex addr(HeapReg, ptrReg, TimesOne, 0);
|
||||
if (size == 32)
|
||||
asMasm().storeFloat32(value, addr);
|
||||
else
|
||||
asMasm().storeDouble(value, addr);
|
||||
} else {
|
||||
uint32_t cmpOffset = ma_BoundsCheck(ptrReg).getOffset();
|
||||
append(wasm::BoundsCheck(cmpOffset));
|
||||
|
||||
if (faultOnOOB)
|
||||
ma_b(wasm::JumpTarget::OutOfBounds, Assembler::AboveOrEqual);
|
||||
|
||||
if (size == 32)
|
||||
value = value.singleOverlay();
|
||||
|
||||
ma_vstr(value, HeapReg, ptrReg, 0, 0, Assembler::Below);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerARMCompat::ma_storeHeapAsmJS(Register ptrReg, int size, bool isSigned,
|
||||
bool needsBoundsCheck, bool faultOnOOB,
|
||||
Register value)
|
||||
{
|
||||
if (!needsBoundsCheck) {
|
||||
ma_dataTransferN(IsStore, size, isSigned, HeapReg, ptrReg, value, Offset,
|
||||
Assembler::Always);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t cmpOffset = ma_BoundsCheck(ptrReg).getOffset();
|
||||
append(wasm::BoundsCheck(cmpOffset));
|
||||
|
||||
if (faultOnOOB)
|
||||
ma_b(wasm::JumpTarget::OutOfBounds, Assembler::AboveOrEqual);
|
||||
|
||||
ma_dataTransferN(IsStore, size, isSigned, HeapReg, ptrReg, value, Offset,
|
||||
Assembler::Below);
|
||||
}
|
||||
|
||||
// Note: this function clobbers the input register.
|
||||
void
|
||||
MacroAssembler::clampDoubleToUint8(FloatRegister input, Register output)
|
||||
|
|
|
@ -962,6 +962,11 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
|||
void loadFloat32(const Address& addr, FloatRegister dest);
|
||||
void loadFloat32(const BaseIndex& src, FloatRegister dest);
|
||||
|
||||
void ma_loadHeapAsmJS(Register ptrReg, int size, bool needsBoundsCheck, bool faultOnOOB,
|
||||
FloatRegister output);
|
||||
void ma_loadHeapAsmJS(Register ptrReg, int size, bool isSigned, bool needsBoundsCheck,
|
||||
bool faultOnOOB, Register output);
|
||||
|
||||
void store8(Register src, const Address& address);
|
||||
void store8(Imm32 imm, const Address& address);
|
||||
void store8(Register src, const BaseIndex& address);
|
||||
|
@ -993,6 +998,11 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
|||
ma_vmov(src, dest, cc);
|
||||
}
|
||||
|
||||
void ma_storeHeapAsmJS(Register ptrReg, int size, bool needsBoundsCheck, bool faultOnOOB,
|
||||
FloatRegister value);
|
||||
void ma_storeHeapAsmJS(Register ptrReg, int size, bool isSigned, bool needsBoundsCheck,
|
||||
bool faultOnOOB, Register value);
|
||||
|
||||
private:
|
||||
template<typename T>
|
||||
Register computePointer(const T& src, Register r);
|
||||
|
|
Загрузка…
Ссылка в новой задаче