diff --git a/js/src/asmjs/Wasm.cpp b/js/src/asmjs/Wasm.cpp index 468af1f9a25b..e7cdd53b6a7d 100644 --- a/js/src/asmjs/Wasm.cpp +++ b/js/src/asmjs/Wasm.cpp @@ -386,9 +386,6 @@ DecodeLoadStoreAddress(FunctionDecoder &f) if (!f.d().readVarU32(&offset)) return f.fail("expected memory access offset"); - if (offset != 0) - return f.fail("NYI: address offsets"); - uint32_t align; if (!f.d().readVarU32(&align)) return f.fail("expected memory access alignment"); diff --git a/js/src/asmjs/WasmIonCompile.cpp b/js/src/asmjs/WasmIonCompile.cpp index 345e25b89ed2..c279e9fdd7f4 100644 --- a/js/src/asmjs/WasmIonCompile.cpp +++ b/js/src/asmjs/WasmIonCompile.cpp @@ -1365,7 +1365,6 @@ static bool EmitHeapAddress(FunctionCompiler& f, MDefinition** base, MAsmJSHeapAccess* access) { uint32_t offset = f.readVarU32(); - MOZ_ASSERT(offset == 0, "Non-zero offsets not supported yet"); access->setOffset(offset); uint32_t align = f.readVarU32(); @@ -1374,13 +1373,24 @@ EmitHeapAddress(FunctionCompiler& f, MDefinition** base, MAsmJSHeapAccess* acces if (!EmitExpr(f, ExprType::I32, base)) return false; - // TODO Remove this (and the viewType param) after implementing unaligned - // loads/stores. if (f.mg().isAsmJS()) { MOZ_ASSERT(offset == 0 && "asm.js validation does not produce load/store offsets"); return true; } + // TODO Remove this after implementing non-wraparound offset semantics. + uint32_t endOffset = access->endOffset(); + if (endOffset < offset) + return false; + bool accessNeedsBoundsCheck = true; + if (endOffset > f.mirGen().foldableOffsetRange(accessNeedsBoundsCheck)) { + MDefinition* rhs = f.constant(Int32Value(offset), MIRType_Int32); + *base = f.binary(*base, rhs, MIRType_Int32); + offset = 0; + access->setOffset(offset); + } + + // TODO Remove this after implementing unaligned loads/stores. int32_t maskVal = ~(Scalar::byteSize(access->accessType()) - 1); if (maskVal == -1) return true; diff --git a/js/src/jit-test/tests/wasm/basic-memory.js b/js/src/jit-test/tests/wasm/basic-memory.js index 86728071c18f..39a6096b9d86 100644 --- a/js/src/jit-test/tests/wasm/basic-memory.js +++ b/js/src/jit-test/tests/wasm/basic-memory.js @@ -78,20 +78,20 @@ testLoad('i32', '', 0, 0, 0, 0x03020100); testLoad('i32', '', 1, 0, 0, 0x03020100); // TODO: unaligned NYI //testLoad('i32', '', 1, 0, 0, 0x04030201); // TODO: unaligned NYI -//testLoad('i32', '', 0, 1, 0, 0x01020304); // TODO: offsets NYI -//testLoad('i32', '', 1, 1, 4, 0x02030405); // TODO: offsets NYI +testLoad('i32', '', 0, 4, 0, 0x07060504); +//testLoad('i32', '', 1, 3, 4, 0x07060504); // TODO: unaligned base NYI //testLoad('i64', '', 0, 0, 0, 0x0001020304050607); // TODO: i64 NYI //testLoad('i64', '', 1, 0, 0, 0x0102030405060708); // TODO: i64 NYI //testLoad('i64', '', 0, 1, 0, 0x0102030405060708); // TODO: i64 NYI //testLoad('i64', '', 1, 1, 4, 0x0203040506070809); // TODO: i64 NYI testLoad('f32', '', 0, 0, 0, 3.820471434542632e-37); //testLoad('f32', '', 1, 0, 0, 1.539989614439558e-36); // TODO: unaligned NYI -//testLoad('f32', '', 0, 1, 0, 0x01020304); // TODO: offsets NYI -//testLoad('f32', '', 1, 1, 4, 0x02030405); // TODO: offsets NYI +testLoad('f32', '', 0, 4, 0, 1.0082513512365273e-34); +//testLoad('f32', '', 1, 3, 4, 1.0082513512365273e-34); // TODO: unaligned base NYI testLoad('f64', '', 0, 0, 0, 7.949928895127363e-275); //testLoad('f64', '', 1, 0, 0, 5.447603722011605e-270); // TODO: unaligned NYI -//testLoad('f64', '', 0, 1, 0, 0x01020304); // TODO: offsets NYI -//testLoad('f64', '', 1, 1, 4, 0x02030405); // TODO: offsets NYI +testLoad('f64', '', 0, 8, 0, 3.6919162048650923e-236); +//testLoad('f64', '', 1, 7, 4, 3.6919162048650923e-236); // TODO: unaligned base NYI testLoad('i32', '8_s', 16, 0, 0, -0x10); testLoad('i32', '8_u', 16, 0, 0, 0xf0); @@ -138,12 +138,12 @@ testStoreNYI('32'); testStore('f32', '', 0, 0, 0, 0.01234566979110241); //testStore('f32', '', 1, 0, 0, 0.01234566979110241); // TODO: unaligned NYI -//testStore('f32', '', 0, 1, 0, 0.01234567); // TODO: offsets NYI -//testStore('f32', '', 1, 1, 4, 0.01234567); // TODO: offsets NYI +testStore('f32', '', 0, 4, 0, 0.01234566979110241); +//testStore('f32', '', 1, 3, 4, 0.01234566979110241); // TODO: unaligned base NYI testStore('f64', '', 0, 0, 0, 0.89012345); //testStore('f64', '', 1, 0, 0, 0.89012345); // TODO: unaligned NYI -//testStore('f64', '', 0, 1, 0, 0.89012345); // TODO: offsets NYI -//testStore('f64', '', 1, 1, 4, 0.89012345); // TODO: offsets NYI +testStore('f64', '', 0, 8, 0, 0.89012345); +testStore('f64', '', 1, 7, 4, 0.89012345); testStore('i32', '8', 0, 0, 0, 0x23); testStore('i32', '16', 0, 0, 0, 0x2345);