Bug 1073096 - ARM support for atomics for Odin/asm.js. r=dtc-moz

This commit is contained in:
Lars T Hansen 2014-11-20 16:27:43 +01:00
parent 6637ae2522
commit 6490953881
2 changed files with 101 additions and 4 deletions

View File

@ -1890,6 +1890,8 @@ CodeGeneratorARM::visitAsmJSLoadHeap(LAsmJSLoadHeap *ins)
default: MOZ_CRASH("unexpected array type");
}
memoryBarrier(mir->barrierBefore());
const LAllocation *ptr = ins->ptr();
if (ptr->isConstant()) {
@ -1906,6 +1908,7 @@ CodeGeneratorARM::visitAsmJSLoadHeap(LAsmJSLoadHeap *ins)
masm.ma_dataTransferN(IsLoad, size, isSigned, HeapReg, Imm32(ptrImm),
ToRegister(ins->output()), Offset, Assembler::Always);
}
memoryBarrier(mir->barrierAfter());
return true;
}
@ -1922,6 +1925,7 @@ CodeGeneratorARM::visitAsmJSLoadHeap(LAsmJSLoadHeap *ins)
masm.ma_dataTransferN(IsLoad, size, isSigned, HeapReg, ptrReg,
ToRegister(ins->output()), Offset, Assembler::Always);
}
memoryBarrier(mir->barrierAfter());
return true;
}
@ -1943,6 +1947,7 @@ CodeGeneratorARM::visitAsmJSLoadHeap(LAsmJSLoadHeap *ins)
masm.ma_mov(Imm32(0), d, NoSetCond, Assembler::AboveOrEqual);
masm.ma_dataTransferN(IsLoad, size, isSigned, HeapReg, ptrReg, d, Offset, Assembler::Below);
}
memoryBarrier(mir->barrierAfter());
masm.append(AsmJSHeapAccess(bo.getOffset()));
return true;
}
@ -1966,6 +1971,7 @@ CodeGeneratorARM::visitAsmJSStoreHeap(LAsmJSStoreHeap *ins)
default: MOZ_CRASH("unexpected array type");
}
const LAllocation *ptr = ins->ptr();
memoryBarrier(mir->barrierBefore());
if (ptr->isConstant()) {
MOZ_ASSERT(!mir->needsBoundsCheck());
int32_t ptrImm = ptr->toConstant()->toInt32();
@ -1980,6 +1986,7 @@ CodeGeneratorARM::visitAsmJSStoreHeap(LAsmJSStoreHeap *ins)
masm.ma_dataTransferN(IsStore, size, isSigned, HeapReg, Imm32(ptrImm),
ToRegister(ins->value()), Offset, Assembler::Always);
}
memoryBarrier(mir->barrierAfter());
return true;
}
@ -1997,6 +2004,7 @@ CodeGeneratorARM::visitAsmJSStoreHeap(LAsmJSStoreHeap *ins)
masm.ma_dataTransferN(IsStore, size, isSigned, HeapReg, ptrReg,
ToRegister(ins->value()), Offset, Assembler::Always);
}
memoryBarrier(mir->barrierAfter());
return true;
}
@ -2011,6 +2019,7 @@ CodeGeneratorARM::visitAsmJSStoreHeap(LAsmJSStoreHeap *ins)
masm.ma_dataTransferN(IsStore, size, isSigned, HeapReg, ptrReg,
ToRegister(ins->value()), Offset, Assembler::Below);
}
memoryBarrier(mir->barrierAfter());
masm.append(AsmJSHeapAccess(bo.getOffset()));
return true;
}
@ -2018,13 +2027,77 @@ CodeGeneratorARM::visitAsmJSStoreHeap(LAsmJSStoreHeap *ins)
bool
CodeGeneratorARM::visitAsmJSCompareExchangeHeap(LAsmJSCompareExchangeHeap *ins)
{
MOZ_CRASH("NYI");
MAsmJSCompareExchangeHeap *mir = ins->mir();
Scalar::Type vt = mir->viewType();
const LAllocation *ptr = ins->ptr();
Register ptrReg = ToRegister(ptr);
BaseIndex srcAddr(HeapReg, ptrReg, TimesOne);
Register oldval = ToRegister(ins->oldValue());
Register newval = ToRegister(ins->newValue());
Label rejoin;
uint32_t maybeCmpOffset = 0;
if (mir->needsBoundsCheck()) {
Label goahead;
BufferOffset bo = masm.ma_BoundsCheck(ptrReg);
Register out = ToRegister(ins->output());
maybeCmpOffset = bo.getOffset();
masm.ma_b(&goahead, Assembler::LessThan);
memoryBarrier(MembarFull);
masm.as_eor(out, out, O2Reg(out));
masm.ma_b(&rejoin, Assembler::Always);
masm.bind(&goahead);
}
masm.compareExchangeToTypedIntArray(vt == Scalar::Uint32 ? Scalar::Int32 : vt,
srcAddr, oldval, newval, InvalidReg,
ToAnyRegister(ins->output()));
if (rejoin.used()) {
masm.bind(&rejoin);
masm.append(AsmJSHeapAccess(maybeCmpOffset));
}
return true;
}
bool
CodeGeneratorARM::visitAsmJSAtomicBinopHeap(LAsmJSAtomicBinopHeap *ins)
{
MOZ_CRASH("NYI");
MAsmJSAtomicBinopHeap *mir = ins->mir();
Scalar::Type vt = mir->viewType();
const LAllocation *ptr = ins->ptr();
Register ptrReg = ToRegister(ptr);
Register temp = ins->temp()->isBogusTemp() ? InvalidReg : ToRegister(ins->temp());
const LAllocation* value = ins->value();
AtomicOp op = mir->operation();
BaseIndex srcAddr(HeapReg, ptrReg, TimesOne);
Label rejoin;
uint32_t maybeCmpOffset = 0;
if (mir->needsBoundsCheck()) {
Label goahead;
BufferOffset bo = masm.ma_BoundsCheck(ptrReg);
Register out = ToRegister(ins->output());
maybeCmpOffset = bo.getOffset();
masm.ma_b(&goahead, Assembler::LessThan);
memoryBarrier(MembarFull);
masm.as_eor(out, out, O2Reg(out));
masm.ma_b(&rejoin, Assembler::Always);
masm.bind(&goahead);
}
if (value->isConstant())
masm.atomicBinopToTypedIntArray(op, vt == Scalar::Uint32 ? Scalar::Int32 : vt,
Imm32(ToInt32(value)), srcAddr, temp, InvalidReg,
ToAnyRegister(ins->output()));
else
masm.atomicBinopToTypedIntArray(op, vt == Scalar::Uint32 ? Scalar::Int32 : vt,
ToRegister(value), srcAddr, temp, InvalidReg,
ToAnyRegister(ins->output()));
if (rejoin.used()) {
masm.bind(&rejoin);
masm.append(AsmJSHeapAccess(maybeCmpOffset));
}
return true;
}
bool

View File

@ -640,11 +640,35 @@ LIRGeneratorARM::visitCompareExchangeTypedArrayElement(MCompareExchangeTypedArra
bool
LIRGeneratorARM::visitAsmJSCompareExchangeHeap(MAsmJSCompareExchangeHeap *ins)
{
MOZ_CRASH("NYI");
MOZ_ASSERT(ins->viewType() != Scalar::Uint8Clamped);
MOZ_ASSERT(ins->viewType() != Scalar::Float32);
MOZ_ASSERT(ins->viewType() != Scalar::Float64);
MDefinition *ptr = ins->ptr();
MOZ_ASSERT(ptr->type() == MIRType_Int32);
LAsmJSCompareExchangeHeap *lir =
new(alloc()) LAsmJSCompareExchangeHeap(useRegister(ptr),
useRegister(ins->oldValue()),
useRegister(ins->newValue()));
return define(lir, ins);
}
bool
LIRGeneratorARM::visitAsmJSAtomicBinopHeap(MAsmJSAtomicBinopHeap *ins)
{
MOZ_CRASH("NYI");
MOZ_ASSERT(ins->viewType() != Scalar::Uint8Clamped);
MOZ_ASSERT(ins->viewType() != Scalar::Float32);
MOZ_ASSERT(ins->viewType() != Scalar::Float64);
MDefinition *ptr = ins->ptr();
MOZ_ASSERT(ptr->type() == MIRType_Int32);
LAsmJSAtomicBinopHeap *lir =
new(alloc()) LAsmJSAtomicBinopHeap(useRegister(ptr),
useRegister(ins->value()),
LDefinition::BogusTemp());
return define(lir, ins);
}