diff options
-rw-r--r-- | src/wasm/wat-parser.cpp | 44 | ||||
-rw-r--r-- | test/lit/wat-kitchen-sink.wast | 66 |
2 files changed, 108 insertions, 2 deletions
diff --git a/src/wasm/wat-parser.cpp b/src/wasm/wat-parser.cpp index 16f33d2d7..8aab01029 100644 --- a/src/wasm/wat-parser.cpp +++ b/src/wasm/wat-parser.cpp @@ -722,6 +722,9 @@ struct NullInstrParserCtx { return Ok{}; } + InstrT makeMemoryCopy(Index, MemoryT*, MemoryT*) { return Ok{}; } + InstrT makeMemoryFill(Index, MemoryT*) { return Ok{}; } + template<typename HeapTypeT> InstrT makeRefNull(Index, HeapTypeT) { return {}; } @@ -1690,6 +1693,33 @@ struct ParseDefsCtx : InstrParserCtx<ParseDefsCtx> { builder.makeSIMDLoadStoreLane( op, memarg.offset, memarg.align, lane, *ptr, *vec, *m)); } + + Result<> makeMemoryCopy(Index pos, Name* destMem, Name* srcMem) { + auto destMemory = self().getMemory(pos, destMem); + CHECK_ERR(destMemory); + auto srcMemory = self().getMemory(pos, srcMem); + CHECK_ERR(srcMemory); + auto size = pop(pos); + CHECK_ERR(size); + auto src = pop(pos); + CHECK_ERR(src); + auto dest = pop(pos); + CHECK_ERR(dest); + return push( + pos, builder.makeMemoryCopy(*dest, *src, *size, *destMemory, *srcMemory)); + } + + Result<> makeMemoryFill(Index pos, Name* mem) { + auto m = self().getMemory(pos, mem); + CHECK_ERR(m); + auto size = pop(pos); + CHECK_ERR(size); + auto val = pop(pos); + CHECK_ERR(val); + auto dest = pop(pos); + CHECK_ERR(dest); + return push(pos, builder.makeMemoryFill(*dest, *val, *size, *m)); + } }; // ================ @@ -2607,12 +2637,22 @@ Result<typename Ctx::InstrT> makeDataDrop(Ctx& ctx, Index pos) { template<typename Ctx> Result<typename Ctx::InstrT> makeMemoryCopy(Ctx& ctx, Index pos) { - return ctx.in.err("unimplemented instruction"); + auto destMem = maybeMemidx(ctx); + CHECK_ERR(destMem); + std::optional<typename Ctx::MemoryT> srcMem = std::nullopt; + if (destMem) { + auto mem = memidx(ctx); + CHECK_ERR(mem); + srcMem = *mem; + } + return ctx.makeMemoryCopy(pos, destMem.getPtr(), srcMem ? &*srcMem : nullptr); } template<typename Ctx> Result<typename Ctx::InstrT> makeMemoryFill(Ctx& ctx, Index pos) { - return ctx.in.err("unimplemented instruction"); + auto mem = maybeMemidx(ctx); + CHECK_ERR(mem); + return ctx.makeMemoryFill(pos, mem.getPtr()); } template<typename Ctx> diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index 4c1ac92e7..e621961a7 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -37,6 +37,8 @@ ;; CHECK: (type $i32_i64_v128_=>_none (func_subtype (param i32 i64 v128) func)) + ;; CHECK: (type $i32_i32_i64_i64_=>_none (func_subtype (param i32 i32 i64 i64) func)) + ;; CHECK: (rec ;; CHECK-NEXT: (type $s0 (struct_subtype data)) (type $s0 (sub (struct))) @@ -1057,6 +1059,70 @@ v128.store64_lane 3 align=4 0 ) + ;; CHECK: (func $memory-copy (type $i32_i32_i64_i64_=>_none) (param $0 i32) (param $1 i32) (param $2 i64) (param $3 i64) + ;; CHECK-NEXT: (memory.copy $mem $mem + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (memory.copy $mem $mem-i32 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (memory.copy $mem-i64 $mem-i64 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i64.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $memory-copy (param i32 i32 i64 i64) + local.get 0 + local.get 1 + i32.const 2 + memory.copy + local.get 0 + local.get 1 + i32.const 3 + memory.copy 0 $mem-i32 + local.get 2 + local.get 3 + i64.const 4 + memory.copy $mem-i64 3 + ) + + ;; CHECK: (func $memory-fill (type $i32_i64_=>_none) (param $0 i32) (param $1 i64) + ;; CHECK-NEXT: (memory.fill $mem + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (memory.fill $mem + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (memory.fill $mem-i64 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: (i64.const 6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $memory-fill (param i32 i64) + local.get 0 + i32.const 1 + i32.const 2 + memory.fill + local.get 0 + i32.const 3 + i32.const 4 + memory.fill 0 + local.get 1 + i32.const 5 + i64.const 6 + memory.fill $mem-i64 + ) + ;; CHECK: (func $use-types (type $ref|$s0|_ref|$s1|_ref|$s2|_ref|$s3|_ref|$s4|_ref|$s5|_ref|$s6|_ref|$s7|_ref|$s8|_ref|$a0|_ref|$a1|_ref|$a2|_ref|$a3|_ref|$subvoid|_ref|$submany|_=>_none) (param $0 (ref $s0)) (param $1 (ref $s1)) (param $2 (ref $s2)) (param $3 (ref $s3)) (param $4 (ref $s4)) (param $5 (ref $s5)) (param $6 (ref $s6)) (param $7 (ref $s7)) (param $8 (ref $s8)) (param $9 (ref $a0)) (param $10 (ref $a1)) (param $11 (ref $a2)) (param $12 (ref $a3)) (param $13 (ref $subvoid)) (param $14 (ref $submany)) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) |