diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/binary-reader-ir.cc | 10 | ||||
-rw-r--r-- | src/binary-reader-logging.cc | 1 | ||||
-rw-r--r-- | src/binary-reader-logging.h | 3 | ||||
-rw-r--r-- | src/binary-reader-nop.h | 5 | ||||
-rw-r--r-- | src/binary-reader.cc | 11 | ||||
-rw-r--r-- | src/binary-reader.h | 3 | ||||
-rw-r--r-- | src/binary-writer.cc | 3 | ||||
-rw-r--r-- | src/expr-visitor.cc | 4 | ||||
-rw-r--r-- | src/expr-visitor.h | 2 | ||||
-rw-r--r-- | src/interp/binary-reader-interp.cc | 11 | ||||
-rw-r--r-- | src/interp/interp.cc | 17 | ||||
-rw-r--r-- | src/interp/interp.h | 2 | ||||
-rw-r--r-- | src/interp/istream.cc | 2 | ||||
-rw-r--r-- | src/ir-util.cc | 1 | ||||
-rw-r--r-- | src/ir.cc | 1 | ||||
-rw-r--r-- | src/ir.h | 2 | ||||
-rw-r--r-- | src/lexer-keywords.txt | 2 | ||||
-rw-r--r-- | src/opcode.def | 2 | ||||
-rw-r--r-- | src/prebuilt/lexer-keywords.cc | 111 | ||||
-rw-r--r-- | src/shared-validator.cc | 12 | ||||
-rw-r--r-- | src/shared-validator.h | 1 | ||||
-rw-r--r-- | src/validator.cc | 7 | ||||
-rw-r--r-- | src/wat-writer.cc | 6 |
23 files changed, 165 insertions, 54 deletions
diff --git a/src/binary-reader-ir.cc b/src/binary-reader-ir.cc index cdda3311..71bc3f9a 100644 --- a/src/binary-reader-ir.cc +++ b/src/binary-reader-ir.cc @@ -206,6 +206,9 @@ class BinaryReaderIR : public BinaryReaderNop { Result OnLoadSplatExpr(Opcode opcode, Address alignment_log2, Address offset) override; + Result OnLoadZeroExpr(Opcode opcode, + Address alignment_log2, + Address offset) override; Result OnElemSegmentCount(Index count) override; Result BeginElemSegment(Index index, @@ -1089,6 +1092,13 @@ Result BinaryReaderIR::OnLoadSplatExpr(Opcode opcode, MakeUnique<LoadSplatExpr>(opcode, 1 << alignment_log2, offset)); } +Result BinaryReaderIR::OnLoadZeroExpr(Opcode opcode, + Address alignment_log2, + Address offset) { + return AppendExpr( + MakeUnique<LoadZeroExpr>(opcode, 1 << alignment_log2, offset)); +} + Result BinaryReaderIR::OnElemSegmentCount(Index count) { WABT_TRY module_->elem_segments.reserve(count); diff --git a/src/binary-reader-logging.cc b/src/binary-reader-logging.cc index 5cebbe92..c0a05fe6 100644 --- a/src/binary-reader-logging.cc +++ b/src/binary-reader-logging.cc @@ -831,6 +831,7 @@ DEFINE_INDEX_DESC(OnReturnCallExpr, "func_index") DEFINE_INDEX_INDEX(OnReturnCallIndirectExpr, "sig_index", "table_index") DEFINE0(OnReturnExpr) DEFINE_LOAD_STORE_OPCODE(OnLoadSplatExpr); +DEFINE_LOAD_STORE_OPCODE(OnLoadZeroExpr); DEFINE_LOAD_STORE_OPCODE(OnStoreExpr); DEFINE_INDEX_DESC(OnThrowExpr, "event_index") DEFINE0(OnUnreachableExpr) diff --git a/src/binary-reader-logging.h b/src/binary-reader-logging.h index 70dcbae6..e585ff27 100644 --- a/src/binary-reader-logging.h +++ b/src/binary-reader-logging.h @@ -234,6 +234,9 @@ class BinaryReaderLogging : public BinaryReaderDelegate { Result OnLoadSplatExpr(Opcode opcode, Address alignment_log2, Address offset) override; + Result OnLoadZeroExpr(Opcode opcode, + Address alignment_log2, + Address offset) override; Result BeginElemSection(Offset size) override; Result OnElemSegmentCount(Index count) override; diff --git a/src/binary-reader-nop.h b/src/binary-reader-nop.h index f72dbf10..aedd4486 100644 --- a/src/binary-reader-nop.h +++ b/src/binary-reader-nop.h @@ -312,6 +312,11 @@ class BinaryReaderNop : public BinaryReaderDelegate { Address offset) override { return Result::Ok; } + Result OnLoadZeroExpr(Opcode opcode, + Address alignment_log2, + Address offset) override { + return Result::Ok; + } /* Elem section */ Result BeginElemSection(Offset size) override { return Result::Ok; } diff --git a/src/binary-reader.cc b/src/binary-reader.cc index 0ada95ba..289e7ba2 100644 --- a/src/binary-reader.cc +++ b/src/binary-reader.cc @@ -1318,6 +1318,17 @@ Result BinaryReader::ReadFunctionBody(Offset end_offset) { CALLBACK(OnOpcodeUint32Uint32, alignment_log2, offset); break; } + case Opcode::V128Load32Zero: + case Opcode::V128Load64Zero: { + Address alignment_log2; + CHECK_RESULT(ReadAlignment(&alignment_log2, "load alignment")); + Address offset; + CHECK_RESULT(ReadAddress(&offset, 0, "load offset")); + + CALLBACK(OnLoadZeroExpr, opcode, alignment_log2, offset); + CALLBACK(OnOpcodeUint32Uint32, alignment_log2, offset); + break; + } case Opcode::I32TruncF32S: case Opcode::I32TruncF64S: case Opcode::I32TruncF32U: diff --git a/src/binary-reader.h b/src/binary-reader.h index 19643aa8..1a7ef0bd 100644 --- a/src/binary-reader.h +++ b/src/binary-reader.h @@ -298,6 +298,9 @@ class BinaryReaderDelegate { virtual Result OnLoadSplatExpr(Opcode opcode, Address alignment_log2, Address offset) = 0; + virtual Result OnLoadZeroExpr(Opcode opcode, + Address alignment_log2, + Address offset) = 0; /* Elem section */ virtual Result BeginElemSection(Offset size) = 0; diff --git a/src/binary-writer.cc b/src/binary-writer.cc index c744aca4..2f97354e 100644 --- a/src/binary-writer.cc +++ b/src/binary-writer.cc @@ -1026,6 +1026,9 @@ void BinaryWriter::WriteExpr(const Func* func, const Expr* expr) { case ExprType::LoadSplat: WriteLoadStoreExpr<LoadSplatExpr>(func, expr, "load offset"); break; + case ExprType::LoadZero: + WriteLoadStoreExpr<LoadZeroExpr>(func, expr, "load offset"); + break; case ExprType::Unreachable: WriteOpcode(stream_, Opcode::Unreachable); break; diff --git a/src/expr-visitor.cc b/src/expr-visitor.cc index af80e705..78b4a52c 100644 --- a/src/expr-visitor.cc +++ b/src/expr-visitor.cc @@ -270,6 +270,10 @@ Result ExprVisitor::HandleDefaultState(Expr* expr) { CHECK_RESULT(delegate_->OnLoadSplatExpr(cast<LoadSplatExpr>(expr))); break; + case ExprType::LoadZero: + CHECK_RESULT(delegate_->OnLoadZeroExpr(cast<LoadZeroExpr>(expr))); + break; + case ExprType::LocalGet: CHECK_RESULT(delegate_->OnLocalGetExpr(cast<LocalGetExpr>(expr))); break; diff --git a/src/expr-visitor.h b/src/expr-visitor.h index f30607ce..0412048e 100644 --- a/src/expr-visitor.h +++ b/src/expr-visitor.h @@ -134,6 +134,7 @@ class ExprVisitor::Delegate { virtual Result OnSimdLaneOpExpr(SimdLaneOpExpr*) = 0; virtual Result OnSimdShuffleOpExpr(SimdShuffleOpExpr*) = 0; virtual Result OnLoadSplatExpr(LoadSplatExpr*) = 0; + virtual Result OnLoadZeroExpr(LoadZeroExpr*) = 0; }; class ExprVisitor::DelegateNop : public ExprVisitor::Delegate { @@ -208,6 +209,7 @@ class ExprVisitor::DelegateNop : public ExprVisitor::Delegate { Result OnSimdLaneOpExpr(SimdLaneOpExpr*) override { return Result::Ok; } Result OnSimdShuffleOpExpr(SimdShuffleOpExpr*) override { return Result::Ok; } Result OnLoadSplatExpr(LoadSplatExpr*) override { return Result::Ok; } + Result OnLoadZeroExpr(LoadZeroExpr*) override { return Result::Ok; } }; } // namespace wabt diff --git a/src/interp/binary-reader-interp.cc b/src/interp/binary-reader-interp.cc index 0cd9c523..0da318ae 100644 --- a/src/interp/binary-reader-interp.cc +++ b/src/interp/binary-reader-interp.cc @@ -216,6 +216,9 @@ class BinaryReaderInterp : public BinaryReaderNop { Result OnLoadSplatExpr(Opcode opcode, Address alignment_log2, Address offset) override; + Result OnLoadZeroExpr(Opcode opcode, + Address alignment_log2, + Address offset) override; Result OnElemSegmentCount(Index count) override; Result BeginElemSegment(Index index, @@ -906,6 +909,14 @@ Result BinaryReaderInterp::OnLoadSplatExpr(Opcode opcode, return Result::Ok; } +Result BinaryReaderInterp::OnLoadZeroExpr(Opcode opcode, + Address align_log2, + Address offset) { + CHECK_RESULT(validator_.OnLoadZero(loc, opcode, GetAlignment(align_log2))); + istream_.Emit(opcode, kMemoryIndex0, offset); + return Result::Ok; +} + Result BinaryReaderInterp::OnAtomicLoadExpr(Opcode opcode, Address align_log2, Address offset) { diff --git a/src/interp/interp.cc b/src/interp/interp.cc index a8730880..6538a341 100644 --- a/src/interp/interp.cc +++ b/src/interp/interp.cc @@ -1636,6 +1636,9 @@ RunResult Thread::StepInternal(Trap::Ptr* out_trap) { case O::V128Load32Splat: return DoSimdLoadSplat<u32x4, u32>(instr, out_trap); case O::V128Load64Splat: return DoSimdLoadSplat<u64x2, u64>(instr, out_trap); + case O::V128Load32Zero: return DoSimdLoadZero<u32x4, u32>(instr, out_trap); + case O::V128Load64Zero: return DoSimdLoadZero<u64x2, u64>(instr, out_trap); + case O::I8X16NarrowI16X8S: return DoSimdNarrow<s8x16, s16x8>(); case O::I8X16NarrowI16X8U: return DoSimdNarrow<u8x16, s16x8>(); case O::I16X8NarrowI32X4S: return DoSimdNarrow<s16x8, s32x4>(); @@ -2162,6 +2165,20 @@ RunResult Thread::DoSimdLoadSplat(Instr instr, Trap::Ptr* out_trap) { return RunResult::Ok; } +template <typename S, typename T> +RunResult Thread::DoSimdLoadZero(Instr instr, Trap::Ptr* out_trap) { + using L = typename S::LaneType; + L val; + if (Load<L>(instr, &val, out_trap) != RunResult::Ok) { + return RunResult::Trap; + } + S result; + std::fill(std::begin(result.v), std::end(result.v), 0); + result[0] = val; + Push(result); + return RunResult::Ok; +} + RunResult Thread::DoSimdSwizzle() { using S = u8x16; auto rhs = Pop<S>(); diff --git a/src/interp/interp.h b/src/interp/interp.h index e0acd1bb..2b7f1652 100644 --- a/src/interp/interp.h +++ b/src/interp/interp.h @@ -1152,6 +1152,8 @@ class Thread : public Object { RunResult DoSimdShift(BinopFunc<R, T>); template <typename S, typename T> RunResult DoSimdLoadSplat(Instr, Trap::Ptr* out_trap); + template <typename S, typename T> + RunResult DoSimdLoadZero(Instr, Trap::Ptr* out_trap); RunResult DoSimdSwizzle(); RunResult DoSimdShuffle(Instr); template <typename S, typename T> diff --git a/src/interp/istream.cc b/src/interp/istream.cc index ab052545..67025c85 100644 --- a/src/interp/istream.cc +++ b/src/interp/istream.cc @@ -571,6 +571,8 @@ Instr Istream::Read(Offset* offset) const { case Opcode::V128Load64Splat: case Opcode::V128Load8Splat: case Opcode::V128Load: + case Opcode::V128Load32Zero: + case Opcode::V128Load64Zero: // Index + memory offset immediates, 1 operand. instr.kind = InstrKind::Imm_Index_Offset_Op_1; instr.imm_u32x2.fst = ReadAt<u32>(offset); diff --git a/src/ir-util.cc b/src/ir-util.cc index ef1c9a20..f5f0a5db 100644 --- a/src/ir-util.cc +++ b/src/ir-util.cc @@ -180,6 +180,7 @@ ModuleContext::Arities ModuleContext::GetExprArity(const Expr& expr) const { case ExprType::TableGet: case ExprType::RefIsNull: case ExprType::LoadSplat: + case ExprType::LoadZero: return { 1, 1 }; case ExprType::Drop: @@ -69,6 +69,7 @@ const char* ExprTypeName[] = { "SimdLaneOp", "SimdShuffleOp", "LoadSplat", + "LoadZero", "Store", "TableCopy", "ElemDrop", @@ -325,6 +325,7 @@ enum class ExprType { SimdLaneOp, SimdShuffleOp, LoadSplat, + LoadZero, Store, TableCopy, ElemDrop, @@ -620,6 +621,7 @@ typedef LoadStoreExpr<ExprType::AtomicRmwCmpxchg> AtomicRmwCmpxchgExpr; typedef LoadStoreExpr<ExprType::AtomicWait> AtomicWaitExpr; typedef LoadStoreExpr<ExprType::AtomicNotify> AtomicNotifyExpr; typedef LoadStoreExpr<ExprType::LoadSplat> LoadSplatExpr; +typedef LoadStoreExpr<ExprType::LoadZero> LoadZeroExpr; class AtomicFenceExpr : public ExprMixin<ExprType::AtomicFence> { public: diff --git a/src/lexer-keywords.txt b/src/lexer-keywords.txt index 44b9beec..b9cea8c7 100644 --- a/src/lexer-keywords.txt +++ b/src/lexer-keywords.txt @@ -566,6 +566,8 @@ v128.load, TokenType::Load, Opcode::V128Load v128.not, TokenType::Unary, Opcode::V128Not v128.or, TokenType::Binary, Opcode::V128Or v128.any_true, TokenType::Unary, Opcode::V128AnyTrue +v128.load32_zero, TokenType::Load, Opcode::V128Load32Zero +v128.load64_zero, TokenType::Load, Opcode::V128Load64Zero v128.store, TokenType::Store, Opcode::V128Store v128, Type::V128 v128.xor, TokenType::Binary, Opcode::V128Xor diff --git a/src/opcode.def b/src/opcode.def index da3015ab..1625cc31 100644 --- a/src/opcode.def +++ b/src/opcode.def @@ -346,6 +346,8 @@ WABT_OPCODE(V128, V128, V128, ___, 0, 0xfd, 0x50, V128Or, "v128.or", "") WABT_OPCODE(V128, V128, V128, ___, 0, 0xfd, 0x51, V128Xor, "v128.xor", "") WABT_OPCODE(V128, V128, V128, V128, 0, 0xfd, 0x52, V128BitSelect, "v128.bitselect", "") WABT_OPCODE(I32, V128, ___, ___, 0, 0xfd, 0x53, V128AnyTrue, "v128.any_true", "") +WABT_OPCODE(V128, I32, ___, ___, 4, 0xfd, 0x5c, V128Load32Zero, "v128.load32_zero", "") +WABT_OPCODE(V128, I32, ___, ___, 8, 0xfd, 0x5d, V128Load64Zero, "v128.load64_zero", "") WABT_OPCODE(V128, V128, ___, ___, 0, 0xfd, 0x5e, F32X4DemoteF64X2Zero, "f32x4.demote_f64x2_zero", "") WABT_OPCODE(V128, V128, ___, ___, 0, 0xfd, 0x5f, F64X2PromoteLowF32X4, "f64x2.promote_low_f32x4", "") WABT_OPCODE(V128, V128, ___, ___, 0, 0xfd, 0x60, I8X16Abs, "i8x16.abs", "") diff --git a/src/prebuilt/lexer-keywords.cc b/src/prebuilt/lexer-keywords.cc index 3a15fe5c..996daa9d 100644 --- a/src/prebuilt/lexer-keywords.cc +++ b/src/prebuilt/lexer-keywords.cc @@ -158,7 +158,7 @@ Perfect_Hash::InWordSet (const char *str, size_t len) { enum { - TOTAL_KEYWORDS = 601, + TOTAL_KEYWORDS = 603, MIN_WORD_LENGTH = 2, MAX_WORD_LENGTH = 29, MIN_HASH_VALUE = 27, @@ -470,10 +470,10 @@ Perfect_Hash::InWordSet (const char *str, size_t len) #line 288 "src/lexer-keywords.txt" {"i32.store16", TokenType::Store, Opcode::I32Store16}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 570 "src/lexer-keywords.txt" +#line 572 "src/lexer-keywords.txt" {"v128", Type::V128}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 587 "src/lexer-keywords.txt" +#line 589 "src/lexer-keywords.txt" {"f32.demote/f64", TokenType::Convert, Opcode::F32DemoteF64}, {""}, {""}, {""}, {""}, {""}, #line 385 "src/lexer-keywords.txt" @@ -533,7 +533,7 @@ Perfect_Hash::InWordSet (const char *str, size_t len) {"i64.atomic.store16", TokenType::AtomicStore, Opcode::I64AtomicStore16}, #line 251 "src/lexer-keywords.txt" {"i32.atomic.store16", TokenType::AtomicStore, Opcode::I32AtomicStore16}, -#line 621 "src/lexer-keywords.txt" +#line 623 "src/lexer-keywords.txt" {"unwind", TokenType::Unwind, Opcode::Unwind}, #line 406 "src/lexer-keywords.txt" {"i64.load32_s", TokenType::Load, Opcode::I64Load32S}, @@ -552,7 +552,7 @@ Perfect_Hash::InWordSet (const char *str, size_t len) #line 295 "src/lexer-keywords.txt" {"i32.trunc_f64_u", TokenType::Convert, Opcode::I32TruncF64U}, {""}, -#line 619 "src/lexer-keywords.txt" +#line 621 "src/lexer-keywords.txt" {"set_local", TokenType::LocalSet, Opcode::LocalSet}, #line 453 "src/lexer-keywords.txt" {"i64x2.bitmask", TokenType::Unary, Opcode::I64X2Bitmask}, @@ -562,7 +562,7 @@ Perfect_Hash::InWordSet (const char *str, size_t len) #line 109 "src/lexer-keywords.txt" {"f32x4", TokenType::F32X4}, {""}, -#line 620 "src/lexer-keywords.txt" +#line 622 "src/lexer-keywords.txt" {"tee_local", TokenType::LocalTee, Opcode::LocalTee}, #line 338 "src/lexer-keywords.txt" {"i32x4", TokenType::I32X4}, @@ -592,7 +592,7 @@ Perfect_Hash::InWordSet (const char *str, size_t len) #line 542 "src/lexer-keywords.txt" {"return_call", TokenType::ReturnCall, Opcode::ReturnCall}, {""}, {""}, {""}, {""}, -#line 569 "src/lexer-keywords.txt" +#line 571 "src/lexer-keywords.txt" {"v128.store", TokenType::Store, Opcode::V128Store}, #line 116 "src/lexer-keywords.txt" {"f64.convert_i64_s", TokenType::Convert, Opcode::F64ConvertI64S}, @@ -607,13 +607,13 @@ Perfect_Hash::InWordSet (const char *str, size_t len) #line 80 "src/lexer-keywords.txt" {"f32.trunc", TokenType::Unary, Opcode::F32Trunc}, {""}, {""}, {""}, {""}, -#line 611 "src/lexer-keywords.txt" +#line 613 "src/lexer-keywords.txt" {"i64.trunc_s/f64", TokenType::Convert, Opcode::I64TruncF64S}, -#line 599 "src/lexer-keywords.txt" +#line 601 "src/lexer-keywords.txt" {"i32.trunc_s/f64", TokenType::Convert, Opcode::I32TruncF64S}, -#line 615 "src/lexer-keywords.txt" +#line 617 "src/lexer-keywords.txt" {"i64.trunc_u/f64", TokenType::Convert, Opcode::I64TruncF64U}, -#line 603 "src/lexer-keywords.txt" +#line 605 "src/lexer-keywords.txt" {"i32.trunc_u/f64", TokenType::Convert, Opcode::I32TruncF64U}, {""}, {""}, #line 430 "src/lexer-keywords.txt" @@ -689,18 +689,18 @@ Perfect_Hash::InWordSet (const char *str, size_t len) #line 33 "src/lexer-keywords.txt" {"call_indirect", TokenType::CallIndirect, Opcode::CallIndirect}, {""}, -#line 581 "src/lexer-keywords.txt" +#line 583 "src/lexer-keywords.txt" {"i64.atomic.wait", TokenType::AtomicWait, Opcode::MemoryAtomicWait64}, -#line 580 "src/lexer-keywords.txt" +#line 582 "src/lexer-keywords.txt" {"i32.atomic.wait", TokenType::AtomicWait, Opcode::MemoryAtomicWait32}, {""}, {""}, {""}, {""}, {""}, -#line 610 "src/lexer-keywords.txt" +#line 612 "src/lexer-keywords.txt" {"i64.trunc_s/f32", TokenType::Convert, Opcode::I64TruncF32S}, -#line 598 "src/lexer-keywords.txt" +#line 600 "src/lexer-keywords.txt" {"i32.trunc_s/f32", TokenType::Convert, Opcode::I32TruncF32S}, -#line 614 "src/lexer-keywords.txt" +#line 616 "src/lexer-keywords.txt" {"i64.trunc_u/f32", TokenType::Convert, Opcode::I64TruncF32U}, -#line 602 "src/lexer-keywords.txt" +#line 604 "src/lexer-keywords.txt" {"i32.trunc_u/f32", TokenType::Convert, Opcode::I32TruncF32U}, {""}, {""}, #line 393 "src/lexer-keywords.txt" @@ -715,11 +715,11 @@ Perfect_Hash::InWordSet (const char *str, size_t len) {"i32x4.abs", TokenType::Unary, Opcode::I32X4Abs}, #line 171 "src/lexer-keywords.txt" {"get", TokenType::Get}, -#line 607 "src/lexer-keywords.txt" +#line 609 "src/lexer-keywords.txt" {"i64.extend_s/i32", TokenType::Convert, Opcode::I64ExtendI32S}, #line 534 "src/lexer-keywords.txt" {"ref.extern", TokenType::RefExtern}, -#line 608 "src/lexer-keywords.txt" +#line 610 "src/lexer-keywords.txt" {"i64.extend_u/i32", TokenType::Convert, Opcode::I64ExtendI32U}, {""}, {""}, #line 528 "src/lexer-keywords.txt" @@ -824,13 +824,13 @@ Perfect_Hash::InWordSet (const char *str, size_t len) {""}, {""}, {""}, {""}, #line 532 "src/lexer-keywords.txt" {"param", TokenType::Param}, -#line 589 "src/lexer-keywords.txt" +#line 591 "src/lexer-keywords.txt" {"f64.convert_s/i32", TokenType::Convert, Opcode::F64ConvertI32S}, -#line 583 "src/lexer-keywords.txt" +#line 585 "src/lexer-keywords.txt" {"f32.convert_s/i32", TokenType::Convert, Opcode::F32ConvertI32S}, -#line 591 "src/lexer-keywords.txt" +#line 593 "src/lexer-keywords.txt" {"f64.convert_u/i32", TokenType::Convert, Opcode::F64ConvertI32U}, -#line 585 "src/lexer-keywords.txt" +#line 587 "src/lexer-keywords.txt" {"f32.convert_u/i32", TokenType::Convert, Opcode::F32ConvertI32U}, {""}, {""}, #line 541 "src/lexer-keywords.txt" @@ -891,7 +891,10 @@ Perfect_Hash::InWordSet (const char *str, size_t len) {""}, {""}, #line 147 "src/lexer-keywords.txt" {"f64x2.ge", TokenType::Compare, Opcode::F64X2Ge}, - {""}, {""}, +#line 570 "src/lexer-keywords.txt" + {"v128.load64_zero", TokenType::Load, Opcode::V128Load64Zero}, +#line 569 "src/lexer-keywords.txt" + {"v128.load32_zero", TokenType::Load, Opcode::V128Load32Zero}, #line 362 "src/lexer-keywords.txt" {"i64.atomic.rmw32.and_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw32AndU}, #line 447 "src/lexer-keywords.txt" @@ -949,7 +952,7 @@ Perfect_Hash::InWordSet (const char *str, size_t len) #line 66 "src/lexer-keywords.txt" {"f32.gt", TokenType::Compare, Opcode::F32Gt}, {""}, -#line 571 "src/lexer-keywords.txt" +#line 573 "src/lexer-keywords.txt" {"v128.xor", TokenType::Binary, Opcode::V128Xor}, {""}, {""}, {""}, {""}, #line 357 "src/lexer-keywords.txt" @@ -1014,13 +1017,13 @@ Perfect_Hash::InWordSet (const char *str, size_t len) #line 315 "src/lexer-keywords.txt" {"v128.load16x4_u", TokenType::Load, Opcode::V128Load16X4U}, {""}, {""}, -#line 590 "src/lexer-keywords.txt" +#line 592 "src/lexer-keywords.txt" {"f64.convert_s/i64", TokenType::Convert, Opcode::F64ConvertI64S}, -#line 584 "src/lexer-keywords.txt" +#line 586 "src/lexer-keywords.txt" {"f32.convert_s/i64", TokenType::Convert, Opcode::F32ConvertI64S}, -#line 592 "src/lexer-keywords.txt" +#line 594 "src/lexer-keywords.txt" {"f64.convert_u/i64", TokenType::Convert, Opcode::F64ConvertI64U}, -#line 586 "src/lexer-keywords.txt" +#line 588 "src/lexer-keywords.txt" {"f32.convert_u/i64", TokenType::Convert, Opcode::F32ConvertI64U}, {""}, {""}, {""}, {""}, {""}, {""}, #line 318 "src/lexer-keywords.txt" @@ -1071,13 +1074,13 @@ Perfect_Hash::InWordSet (const char *str, size_t len) {""}, {""}, #line 205 "src/lexer-keywords.txt" {"i16x8.ne", TokenType::Compare, Opcode::I16X8Ne}, -#line 593 "src/lexer-keywords.txt" +#line 595 "src/lexer-keywords.txt" {"f64.promote/f32", TokenType::Convert, Opcode::F64PromoteF32}, {""}, {""}, #line 213 "src/lexer-keywords.txt" {"i16x8.sub", TokenType::Binary, Opcode::I16X8Sub}, {""}, {""}, {""}, -#line 596 "src/lexer-keywords.txt" +#line 598 "src/lexer-keywords.txt" {"get_local", TokenType::LocalGet, Opcode::LocalGet}, {""}, #line 194 "src/lexer-keywords.txt" @@ -1138,7 +1141,7 @@ Perfect_Hash::InWordSet (const char *str, size_t len) {""}, {""}, {""}, {""}, {""}, {""}, #line 176 "src/lexer-keywords.txt" {"i16x8.abs", TokenType::Unary, Opcode::I16X8Abs}, -#line 618 "src/lexer-keywords.txt" +#line 620 "src/lexer-keywords.txt" {"set_global", TokenType::GlobalSet, Opcode::GlobalSet}, {""}, {""}, #line 91 "src/lexer-keywords.txt" @@ -1150,7 +1153,7 @@ Perfect_Hash::InWordSet (const char *str, size_t len) #line 311 "src/lexer-keywords.txt" {"i32x4.gt_u", TokenType::Compare, Opcode::I32X4GtU}, {""}, {""}, -#line 594 "src/lexer-keywords.txt" +#line 596 "src/lexer-keywords.txt" {"f64.reinterpret/i64", TokenType::Convert, Opcode::F64ReinterpretI64}, #line 308 "src/lexer-keywords.txt" {"i32x4.ge_s", TokenType::Compare, Opcode::I32X4GeS}, @@ -1221,7 +1224,7 @@ Perfect_Hash::InWordSet (const char *str, size_t len) {"v128.any_true", TokenType::Unary, Opcode::V128AnyTrue}, #line 484 "src/lexer-keywords.txt" {"i8x16.le_s", TokenType::Compare, Opcode::I8X16LeS}, -#line 588 "src/lexer-keywords.txt" +#line 590 "src/lexer-keywords.txt" {"f32.reinterpret/i32", TokenType::Convert, Opcode::F32ReinterpretI32}, #line 485 "src/lexer-keywords.txt" {"i8x16.le_u", TokenType::Compare, Opcode::I8X16LeU}, @@ -1232,7 +1235,7 @@ Perfect_Hash::InWordSet (const char *str, size_t len) #line 491 "src/lexer-keywords.txt" {"i8x16.min_u", TokenType::Binary, Opcode::I8X16MinU}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 575 "src/lexer-keywords.txt" +#line 577 "src/lexer-keywords.txt" {"v128.load8_splat", TokenType::Load, Opcode::V128Load8Splat}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, #line 366 "src/lexer-keywords.txt" @@ -1243,13 +1246,13 @@ Perfect_Hash::InWordSet (const char *str, size_t len) #line 182 "src/lexer-keywords.txt" {"i16x8.bitmask", TokenType::Unary, Opcode::I16X8Bitmask}, {""}, -#line 613 "src/lexer-keywords.txt" +#line 615 "src/lexer-keywords.txt" {"i64.trunc_s:sat/f64", TokenType::Convert, Opcode::I64TruncSatF64S}, -#line 601 "src/lexer-keywords.txt" +#line 603 "src/lexer-keywords.txt" {"i32.trunc_s:sat/f64", TokenType::Convert, Opcode::I32TruncSatF64S}, -#line 617 "src/lexer-keywords.txt" +#line 619 "src/lexer-keywords.txt" {"i64.trunc_u:sat/f64", TokenType::Convert, Opcode::I64TruncSatF64U}, -#line 605 "src/lexer-keywords.txt" +#line 607 "src/lexer-keywords.txt" {"i32.trunc_u:sat/f64", TokenType::Convert, Opcode::I32TruncSatF64U}, #line 157 "src/lexer-keywords.txt" {"f64x2.pmax", TokenType::Binary, Opcode::F64X2PMax}, @@ -1259,7 +1262,7 @@ Perfect_Hash::InWordSet (const char *str, size_t len) #line 235 "src/lexer-keywords.txt" {"i32.atomic.rmw16.xchg_u", TokenType::AtomicRmw, Opcode::I32AtomicRmw16XchgU}, {""}, {""}, {""}, {""}, {""}, -#line 582 "src/lexer-keywords.txt" +#line 584 "src/lexer-keywords.txt" {"anyfunc", Type::FuncRef}, #line 350 "src/lexer-keywords.txt" {"i64.atomic.load16_u", TokenType::AtomicLoad, Opcode::I64AtomicLoad16U}, @@ -1285,9 +1288,9 @@ Perfect_Hash::InWordSet (const char *str, size_t len) #line 558 "src/lexer-keywords.txt" {"try", TokenType::Try, Opcode::Try}, {""}, {""}, -#line 574 "src/lexer-keywords.txt" +#line 576 "src/lexer-keywords.txt" {"v128.load64_splat", TokenType::Load, Opcode::V128Load64Splat}, -#line 573 "src/lexer-keywords.txt" +#line 575 "src/lexer-keywords.txt" {"v128.load32_splat", TokenType::Load, Opcode::V128Load32Splat}, {""}, {""}, {""}, #line 177 "src/lexer-keywords.txt" @@ -1301,15 +1304,15 @@ Perfect_Hash::InWordSet (const char *str, size_t len) #line 74 "src/lexer-keywords.txt" {"f32.neg", TokenType::Unary, Opcode::F32Neg}, {""}, -#line 612 "src/lexer-keywords.txt" +#line 614 "src/lexer-keywords.txt" {"i64.trunc_s:sat/f32", TokenType::Convert, Opcode::I64TruncSatF32S}, -#line 600 "src/lexer-keywords.txt" +#line 602 "src/lexer-keywords.txt" {"i32.trunc_s:sat/f32", TokenType::Convert, Opcode::I32TruncSatF32S}, -#line 616 "src/lexer-keywords.txt" +#line 618 "src/lexer-keywords.txt" {"i64.trunc_u:sat/f32", TokenType::Convert, Opcode::I64TruncSatF32U}, -#line 604 "src/lexer-keywords.txt" +#line 606 "src/lexer-keywords.txt" {"i32.trunc_u:sat/f32", TokenType::Convert, Opcode::I32TruncSatF32U}, -#line 572 "src/lexer-keywords.txt" +#line 574 "src/lexer-keywords.txt" {"v128.load16_splat", TokenType::Load, Opcode::V128Load16Splat}, #line 502 "src/lexer-keywords.txt" {"i8x16.sub_sat_s", TokenType::Binary, Opcode::I8X16SubSatS}, @@ -1321,7 +1324,7 @@ Perfect_Hash::InWordSet (const char *str, size_t len) {"i64.atomic.rmw8.or_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw8OrU}, #line 240 "src/lexer-keywords.txt" {"i32.atomic.rmw8.or_u", TokenType::AtomicRmw, Opcode::I32AtomicRmw8OrU}, -#line 606 "src/lexer-keywords.txt" +#line 608 "src/lexer-keywords.txt" {"i32.wrap/i64", TokenType::Convert, Opcode::I32WrapI64}, {""}, {""}, #line 28 "src/lexer-keywords.txt" @@ -1435,7 +1438,7 @@ Perfect_Hash::InWordSet (const char *str, size_t len) #line 101 "src/lexer-keywords.txt" {"f32x4.pmax", TokenType::Binary, Opcode::F32X4PMax}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 577 "src/lexer-keywords.txt" +#line 579 "src/lexer-keywords.txt" {"i8x16.swizzle", TokenType::Binary, Opcode::I8X16Swizzle}, {""}, {""}, {""}, {""}, {""}, {""}, #line 44 "src/lexer-keywords.txt" @@ -1487,10 +1490,10 @@ Perfect_Hash::InWordSet (const char *str, size_t len) #line 340 "src/lexer-keywords.txt" {"i32x4.trunc_sat_f32x4_u", TokenType::Unary, Opcode::I32X4TruncSatF32X4U}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 595 "src/lexer-keywords.txt" +#line 597 "src/lexer-keywords.txt" {"get_global", TokenType::GlobalGet, Opcode::GlobalGet}, {""}, {""}, {""}, -#line 609 "src/lexer-keywords.txt" +#line 611 "src/lexer-keywords.txt" {"i64.reinterpret/f64", TokenType::Convert, Opcode::I64ReinterpretF64}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, #line 280 "src/lexer-keywords.txt" @@ -1532,7 +1535,7 @@ Perfect_Hash::InWordSet (const char *str, size_t len) #line 481 "src/lexer-keywords.txt" {"i8x16.ge_u", TokenType::Compare, Opcode::I8X16GeU}, {""}, {""}, {""}, -#line 597 "src/lexer-keywords.txt" +#line 599 "src/lexer-keywords.txt" {"i32.reinterpret/f32", TokenType::Convert, Opcode::I32ReinterpretF32}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, @@ -1541,7 +1544,7 @@ Perfect_Hash::InWordSet (const char *str, size_t len) {"i8x16.splat", TokenType::Unary, Opcode::I8X16Splat}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 579 "src/lexer-keywords.txt" +#line 581 "src/lexer-keywords.txt" {"atomic.notify", TokenType::AtomicNotify, Opcode::MemoryAtomicNotify}, {""}, {""}, {""}, {""}, {""}, #line 37 "src/lexer-keywords.txt" @@ -1621,7 +1624,7 @@ Perfect_Hash::InWordSet (const char *str, size_t len) #line 60 "src/lexer-keywords.txt" {"f32.copysign", TokenType::Binary, Opcode::F32Copysign}, {""}, {""}, {""}, -#line 576 "src/lexer-keywords.txt" +#line 578 "src/lexer-keywords.txt" {"i8x16.shuffle", TokenType::SimdShuffleOp, Opcode::I8X16Shuffle}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, diff --git a/src/shared-validator.cc b/src/shared-validator.cc index 5d3b8acf..3f970276 100644 --- a/src/shared-validator.cc +++ b/src/shared-validator.cc @@ -895,6 +895,18 @@ Result SharedValidator::OnLoadSplat(const Location& loc, return result; } +Result SharedValidator::OnLoadZero(const Location& loc, + Opcode opcode, + Address alignment) { + Result result = Result::Ok; + MemoryType mt; + expr_loc_ = &loc; + result |= CheckMemoryIndex(Var(0, loc), &mt); + result |= CheckAlign(loc, alignment, opcode.GetMemorySize()); + result |= typechecker_.OnLoad(opcode, mt.limits); + return result; +} + Result SharedValidator::OnLocalGet(const Location& loc, Var local_var) { Result result = Result::Ok; Type type = Type::Any; diff --git a/src/shared-validator.h b/src/shared-validator.h index 456693bf..34f48d72 100644 --- a/src/shared-validator.h +++ b/src/shared-validator.h @@ -139,6 +139,7 @@ class SharedValidator { Result OnIf(const Location&, Type sig_type); Result OnLoad(const Location&, Opcode, Address align); Result OnLoadSplat(const Location&, Opcode, Address align); + Result OnLoadZero(const Location&, Opcode, Address align); Result OnLocalGet(const Location&, Var); Result OnLocalSet(const Location&, Var); Result OnLocalTee(const Location&, Var); diff --git a/src/validator.cc b/src/validator.cc index 4733954f..fed3a950 100644 --- a/src/validator.cc +++ b/src/validator.cc @@ -151,6 +151,7 @@ class Validator : public ExprVisitor::Delegate { Result OnSimdLaneOpExpr(SimdLaneOpExpr*) override; Result OnSimdShuffleOpExpr(SimdShuffleOpExpr*) override; Result OnLoadSplatExpr(LoadSplatExpr*) override; + Result OnLoadZeroExpr(LoadZeroExpr*) override; private: Type GetDeclarationType(const FuncDeclaration&); @@ -583,6 +584,12 @@ Result Validator::OnLoadSplatExpr(LoadSplatExpr* expr) { return Result::Ok; } +Result Validator::OnLoadZeroExpr(LoadZeroExpr* expr) { + result_ |= validator_.OnLoadZero(expr->loc, expr->opcode, + expr->opcode.GetAlignment(expr->align)); + return Result::Ok; +} + Validator::Validator(Errors* errors, const Module* module, const ValidateOptions& options) diff --git a/src/wat-writer.cc b/src/wat-writer.cc index 0c051f83..d6daa584 100644 --- a/src/wat-writer.cc +++ b/src/wat-writer.cc @@ -574,6 +574,7 @@ class WatWriter::ExprVisitorDelegate : public ExprVisitor::Delegate { Result OnSimdLaneOpExpr(SimdLaneOpExpr*) override; Result OnSimdShuffleOpExpr(SimdShuffleOpExpr*) override; Result OnLoadSplatExpr(LoadSplatExpr*) override; + Result OnLoadZeroExpr(LoadZeroExpr*) override; private: WatWriter* writer_; @@ -995,6 +996,11 @@ Result WatWriter::ExprVisitorDelegate::OnLoadSplatExpr(LoadSplatExpr* expr) { return Result::Ok; } +Result WatWriter::ExprVisitorDelegate::OnLoadZeroExpr(LoadZeroExpr* expr) { + writer_->WriteLoadStoreExpr<LoadZeroExpr>(expr); + return Result::Ok; +} + void WatWriter::WriteExpr(const Expr* expr) { WABT_TRACE(WriteExprList); ExprVisitorDelegate delegate(this); |