mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 01:48:05 +00:00
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:
parent
fe68761b42
commit
ad8fab5cfd
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user