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:
Lars T Hansen 2016-06-29 10:54:08 +02:00
Родитель 570bcc2702
Коммит c5d9947c1a
3 изменённых файлов: 123 добавлений и 78 удалений

Просмотреть файл

@ -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);