Bug 1287349 - wasm: MIPS: Implement WasmBoundsCheck/Load/Store in Codegen. r=luke

---
 .../jit/mips-shared/CodeGenerator-mips-shared.cpp  | 130 +++++++++++++++++++++
 js/src/jit/mips-shared/CodeGenerator-mips-shared.h |   3 +
 2 files changed, 133 insertions(+)
This commit is contained in:
Heiher 2016-07-21 09:23:56 +08:00
parent fe68761b42
commit ad8fab5cfd
2 changed files with 133 additions and 0 deletions

View File

@ -1654,6 +1654,136 @@ CodeGeneratorMIPSShared::visitAsmJSCall(LAsmJSCall* ins)
emitAsmJSCall(ins);
}
void
CodeGeneratorMIPSShared::visitWasmBoundsCheck(LWasmBoundsCheck* ins)
{
MWasmBoundsCheck* mir = ins->mir();
uint32_t offset = mir->offset();
if (offset > INT32_MAX) {
masm.jump(wasm::JumpTarget::OutOfBounds);
return;
}
uint32_t endOffset = mir->endOffset();
Register ptr = ToRegister(ins->ptr());
masm.move32(Imm32(endOffset), SecondScratchReg);
masm.addPtr(ptr, SecondScratchReg);
// Detect unsigned overflow.
masm.ma_b(SecondScratchReg, ptr, wasm::JumpTarget::OutOfBounds, Assembler::LessThan);
BufferOffset bo = masm.ma_BoundsCheck(ScratchRegister);
masm.ma_b(SecondScratchReg, ScratchRegister, wasm::JumpTarget::OutOfBounds, Assembler::Above);
masm.append(wasm::BoundsCheck(bo.getOffset()));
}
void
CodeGeneratorMIPSShared::visitWasmLoad(LWasmLoad* lir)
{
const MWasmLoad* mir = lir->mir();
MOZ_ASSERT(!mir->barrierBefore() && !mir->barrierAfter(), "atomics NYI");
uint32_t offset = mir->offset();
if (offset > INT32_MAX) {
// This is unreachable because of bounds checks.
masm.breakpoint();
return;
}
Register ptr = ToRegister(lir->ptr());
// Maybe add the offset.
if (offset) {
Register ptrPlusOffset = ToRegister(lir->ptrCopy());
masm.addPtr(Imm32(offset), ptrPlusOffset);
ptr = ptrPlusOffset;
} else {
MOZ_ASSERT(lir->ptrCopy()->isBogusTemp());
}
unsigned byteSize = mir->byteSize();
bool isSigned;
bool isFloat = false;
switch (mir->accessType()) {
case Scalar::Int8: isSigned = true; break;
case Scalar::Uint8: isSigned = false; break;
case Scalar::Int16: isSigned = true; break;
case Scalar::Uint16: isSigned = false; break;
case Scalar::Int32: isSigned = true; break;
case Scalar::Uint32: isSigned = false; break;
case Scalar::Float64: isFloat = true; break;
case Scalar::Float32: isFloat = true; break;
default: MOZ_CRASH("unexpected array type");
}
if (isFloat) {
if (byteSize == 4) {
masm.loadFloat32(BaseIndex(HeapReg, ptr, TimesOne), ToFloatRegister(lir->output()));
} else
masm.loadDouble(BaseIndex(HeapReg, ptr, TimesOne), ToFloatRegister(lir->output()));
} else {
masm.ma_load(ToRegister(lir->output()), BaseIndex(HeapReg, ptr, TimesOne),
static_cast<LoadStoreSize>(8 * byteSize), isSigned ? SignExtend : ZeroExtend);
}
}
void
CodeGeneratorMIPSShared::visitWasmStore(LWasmStore* lir)
{
const MWasmStore* mir = lir->mir();
MOZ_ASSERT(!mir->barrierBefore() && !mir->barrierAfter(), "atomics NYI");
uint32_t offset = mir->offset();
if (offset > INT32_MAX) {
// This is unreachable because of bounds checks.
masm.breakpoint();
return;
}
Register ptr = ToRegister(lir->ptr());
// Maybe add the offset.
if (offset) {
Register ptrPlusOffset = ToRegister(lir->ptrCopy());
masm.addPtr(Imm32(offset), ptrPlusOffset);
ptr = ptrPlusOffset;
} else {
MOZ_ASSERT(lir->ptrCopy()->isBogusTemp());
}
unsigned byteSize = mir->byteSize();
bool isSigned;
bool isFloat = false;
switch (mir->accessType()) {
case Scalar::Int8: isSigned = true; break;
case Scalar::Uint8: isSigned = false; break;
case Scalar::Int16: isSigned = true; break;
case Scalar::Uint16: isSigned = false; break;
case Scalar::Int32: isSigned = true; break;
case Scalar::Uint32: isSigned = false; break;
case Scalar::Int64: isSigned = true; break;
case Scalar::Float64: isFloat = true; break;
case Scalar::Float32: isFloat = true; break;
default: MOZ_CRASH("unexpected array type");
}
if (isFloat) {
if (byteSize == 4) {
masm.storeFloat32(ToFloatRegister(lir->value()), BaseIndex(HeapReg, ptr, TimesOne));
} else
masm.storeDouble(ToFloatRegister(lir->value()), BaseIndex(HeapReg, ptr, TimesOne));
} else {
masm.ma_store(ToRegister(lir->value()), BaseIndex(HeapReg, ptr, TimesOne),
static_cast<LoadStoreSize>(8 * byteSize), isSigned ? SignExtend : ZeroExtend);
}
}
void
CodeGeneratorMIPSShared::visitAsmJSLoadHeap(LAsmJSLoadHeap* ins)
{

View File

@ -193,6 +193,9 @@ class CodeGeneratorMIPSShared : public CodeGeneratorShared
void visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic* ins);
void visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStatic* ins);
void visitAsmJSCall(LAsmJSCall* ins);
void visitWasmBoundsCheck(LWasmBoundsCheck* ins);
void visitWasmLoad(LWasmLoad* ins);
void visitWasmStore(LWasmStore* ins);
void visitAsmJSLoadHeap(LAsmJSLoadHeap* ins);
void visitAsmJSStoreHeap(LAsmJSStoreHeap* ins);
void visitAsmJSCompareExchangeHeap(LAsmJSCompareExchangeHeap* ins);