diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/binary-reader-ir.cc | 12 | ||||
-rw-r--r-- | src/binary-reader-logging.cc | 15 | ||||
-rw-r--r-- | src/binary-reader-logging.h | 2 | ||||
-rw-r--r-- | src/binary-reader-nop.h | 2 | ||||
-rw-r--r-- | src/binary-reader.cc | 20 | ||||
-rw-r--r-- | src/binary-reader.h | 2 | ||||
-rw-r--r-- | src/interp/binary-reader-interp.cc | 8 | ||||
-rw-r--r-- | src/ir.h | 14 | ||||
-rw-r--r-- | src/wast-parser.cc | 26 | ||||
-rw-r--r-- | src/wast-parser.h | 2 |
10 files changed, 81 insertions, 22 deletions
diff --git a/src/binary-reader-ir.cc b/src/binary-reader-ir.cc index bc2fc2dd..3722e4bd 100644 --- a/src/binary-reader-ir.cc +++ b/src/binary-reader-ir.cc @@ -203,10 +203,12 @@ class BinaryReaderIR : public BinaryReaderNop { Result EndFunctionBody(Index index) override; Result OnSimdLaneOpExpr(Opcode opcode, uint64_t value) override; Result OnSimdLoadLaneExpr(Opcode opcode, + Index memidx, Address alignment_log2, Address offset, uint64_t value) override; Result OnSimdStoreLaneExpr(Opcode opcode, + Index memidx, Address alignment_log2, Address offset, uint64_t value) override; @@ -1099,19 +1101,21 @@ Result BinaryReaderIR::OnSimdLaneOpExpr(Opcode opcode, uint64_t value) { } Result BinaryReaderIR::OnSimdLoadLaneExpr(Opcode opcode, + Index memidx, Address alignment_log2, Address offset, uint64_t value) { - return AppendExpr( - MakeUnique<SimdLoadLaneExpr>(opcode, 1 << alignment_log2, offset, value)); + return AppendExpr(MakeUnique<SimdLoadLaneExpr>( + opcode, Var(memidx), 1 << alignment_log2, offset, value)); } Result BinaryReaderIR::OnSimdStoreLaneExpr(Opcode opcode, + Index memidx, Address alignment_log2, Address offset, uint64_t value) { - return AppendExpr(MakeUnique<SimdStoreLaneExpr>(opcode, 1 << alignment_log2, - offset, value)); + return AppendExpr(MakeUnique<SimdStoreLaneExpr>( + opcode, Var(memidx), 1 << alignment_log2, offset, value)); } Result BinaryReaderIR::OnSimdShuffleOpExpr(Opcode opcode, v128 value) { diff --git a/src/binary-reader-logging.cc b/src/binary-reader-logging.cc index 7e103540..459fca24 100644 --- a/src/binary-reader-logging.cc +++ b/src/binary-reader-logging.cc @@ -717,12 +717,15 @@ Result BinaryReaderLogging::OnComdatEntry(ComdatType kind, Index index) { } #define DEFINE_SIMD_LOAD_STORE_LANE_OPCODE(name) \ - Result BinaryReaderLogging::name(Opcode opcode, Address alignment_log2, \ - Address offset, uint64_t value) { \ - LOGF(#name "(opcode: \"%s\" (%u), align log2: %" PRIaddress \ - ", offset: %" PRIaddress ", lane: %" PRIu64 ")\n", \ - opcode.GetName(), opcode.GetCode(), alignment_log2, offset, value); \ - return reader_->name(opcode, alignment_log2, offset, value); \ + Result BinaryReaderLogging::name(Opcode opcode, Index memidx, \ + Address alignment_log2, Address offset, \ + uint64_t value) { \ + LOGF(#name "(opcode: \"%s\" (%u), memidx: %" PRIindex \ + ", align log2: %" PRIaddress ", offset: %" PRIaddress \ + ", lane: %" PRIu64 ")\n", \ + opcode.GetName(), opcode.GetCode(), memidx, alignment_log2, offset, \ + value); \ + return reader_->name(opcode, memidx, alignment_log2, offset, value); \ } #define DEFINE0(name) \ diff --git a/src/binary-reader-logging.h b/src/binary-reader-logging.h index c722181b..1c2f302a 100644 --- a/src/binary-reader-logging.h +++ b/src/binary-reader-logging.h @@ -235,10 +235,12 @@ class BinaryReaderLogging : public BinaryReaderDelegate { Result EndCodeSection() override; Result OnSimdLaneOpExpr(Opcode opcode, uint64_t value) override; Result OnSimdLoadLaneExpr(Opcode opcode, + Index memidx, Address alignment_log2, Address offset, uint64_t value) override; Result OnSimdStoreLaneExpr(Opcode opcode, + Index memidx, Address alignment_log2, Address offset, uint64_t value) override; diff --git a/src/binary-reader-nop.h b/src/binary-reader-nop.h index 1acf1c24..d87ec922 100644 --- a/src/binary-reader-nop.h +++ b/src/binary-reader-nop.h @@ -315,12 +315,14 @@ class BinaryReaderNop : public BinaryReaderDelegate { return Result::Ok; } Result OnSimdLoadLaneExpr(Opcode opcode, + Index memidx, Address alignment_log2, Address offset, uint64_t value) override { return Result::Ok; } Result OnSimdStoreLaneExpr(Opcode opcode, + Index memidx, Address alignment_log2, Address offset, uint64_t value) override { diff --git a/src/binary-reader.cc b/src/binary-reader.cc index 1d75ad07..c584b018 100644 --- a/src/binary-reader.cc +++ b/src/binary-reader.cc @@ -1328,12 +1328,20 @@ Result BinaryReader::ReadInstructions(bool stop_on_end, case Opcode::V128Load64Lane: { Address alignment_log2; CHECK_RESULT(ReadAlignment(&alignment_log2, "load alignment")); + Index memidx = 0; + if (alignment_log2 >> 6) { + ERROR_IF(!options_.features.multi_memory_enabled(), + "multi_memory not allowed"); + CHECK_RESULT(ReadMemidx(&memidx, "store memidx")); + alignment_log2 = alignment_log2 & ((1 << 6) - 1); + } Address offset; CHECK_RESULT(ReadAddress(&offset, 0, "load offset")); uint8_t lane_val; CHECK_RESULT(ReadU8(&lane_val, "Lane idx")); - CALLBACK(OnSimdLoadLaneExpr, opcode, alignment_log2, offset, lane_val); + CALLBACK(OnSimdLoadLaneExpr, opcode, memidx, alignment_log2, offset, + lane_val); CALLBACK(OnOpcodeUint32Uint32Uint32, alignment_log2, offset, lane_val); break; } @@ -1343,12 +1351,20 @@ Result BinaryReader::ReadInstructions(bool stop_on_end, case Opcode::V128Store64Lane: { Address alignment_log2; CHECK_RESULT(ReadAlignment(&alignment_log2, "load alignment")); + Index memidx = 0; + if (alignment_log2 >> 6) { + ERROR_IF(!options_.features.multi_memory_enabled(), + "multi_memory not allowed"); + CHECK_RESULT(ReadMemidx(&memidx, "store memidx")); + alignment_log2 = alignment_log2 & ((1 << 6) - 1); + } Address offset; CHECK_RESULT(ReadAddress(&offset, 0, "load offset")); uint8_t lane_val; CHECK_RESULT(ReadU8(&lane_val, "Lane idx")); - CALLBACK(OnSimdStoreLaneExpr, opcode, alignment_log2, offset, lane_val); + CALLBACK(OnSimdStoreLaneExpr, opcode, memidx, alignment_log2, offset, + lane_val); CALLBACK(OnOpcodeUint32Uint32Uint32, alignment_log2, offset, lane_val); break; } diff --git a/src/binary-reader.h b/src/binary-reader.h index b38e6c9c..10602e7c 100644 --- a/src/binary-reader.h +++ b/src/binary-reader.h @@ -299,10 +299,12 @@ class BinaryReaderDelegate { virtual Result OnSimdLaneOpExpr(Opcode opcode, uint64_t value) = 0; virtual Result OnSimdShuffleOpExpr(Opcode opcode, v128 value) = 0; virtual Result OnSimdLoadLaneExpr(Opcode opcode, + Index memidx, Address alignment_log2, Address offset, uint64_t value) = 0; virtual Result OnSimdStoreLaneExpr(Opcode opcode, + Index memidx, Address alignment_log2, Address offset, uint64_t value) = 0; diff --git a/src/interp/binary-reader-interp.cc b/src/interp/binary-reader-interp.cc index cf4436f6..25f4d84f 100644 --- a/src/interp/binary-reader-interp.cc +++ b/src/interp/binary-reader-interp.cc @@ -238,10 +238,12 @@ class BinaryReaderInterp : public BinaryReaderNop { Result EndFunctionBody(Index index) override; Result OnSimdLaneOpExpr(Opcode opcode, uint64_t value) override; Result OnSimdLoadLaneExpr(Opcode opcode, + Index memidx, Address alignment_log2, Address offset, uint64_t value) override; Result OnSimdStoreLaneExpr(Opcode opcode, + Index memidx, Address alignment_log2, Address offset, uint64_t value) override; @@ -901,22 +903,24 @@ uint32_t GetAlignment(Address alignment_log2) { } Result BinaryReaderInterp::OnSimdLoadLaneExpr(Opcode opcode, + Index memidx, Address alignment_log2, Address offset, uint64_t value) { CHECK_RESULT(validator_.OnSimdLoadLane(GetLocation(), opcode, GetAlignment(alignment_log2), value)); - istream_.Emit(opcode, kMemoryIndex0, offset, static_cast<u8>(value)); + istream_.Emit(opcode, memidx, offset, static_cast<u8>(value)); return Result::Ok; } Result BinaryReaderInterp::OnSimdStoreLaneExpr(Opcode opcode, + Index memidx, Address alignment_log2, Address offset, uint64_t value) { CHECK_RESULT(validator_.OnSimdStoreLane(GetLocation(), opcode, GetAlignment(alignment_log2), value)); - istream_.Emit(opcode, kMemoryIndex0, offset, static_cast<u8>(value)); + istream_.Emit(opcode, memidx, offset, static_cast<u8>(value)); return Result::Ok; } @@ -501,35 +501,41 @@ class SimdLaneOpExpr : public ExprMixin<ExprType::SimdLaneOp> { uint64_t val; }; -class SimdLoadLaneExpr : public OpcodeExpr<ExprType::SimdLoadLane> { +class SimdLoadLaneExpr : public MemoryExpr<ExprType::SimdLoadLane> { public: SimdLoadLaneExpr(Opcode opcode, + Var memidx, Address align, Address offset, uint64_t val, const Location& loc = Location()) - : OpcodeExpr<ExprType::SimdLoadLane>(opcode, loc), + : MemoryExpr<ExprType::SimdLoadLane>(memidx, loc), + opcode(opcode), align(align), offset(offset), val(val) {} + Opcode opcode; Address align; Address offset; uint64_t val; }; -class SimdStoreLaneExpr : public OpcodeExpr<ExprType::SimdStoreLane> { +class SimdStoreLaneExpr : public MemoryExpr<ExprType::SimdStoreLane> { public: SimdStoreLaneExpr(Opcode opcode, + Var memidx, Address align, Address offset, uint64_t val, const Location& loc = Location()) - : OpcodeExpr<ExprType::SimdStoreLane>(opcode, loc), + : MemoryExpr<ExprType::SimdStoreLane>(memidx, loc), + opcode(opcode), align(align), offset(offset), val(val) {} + Opcode opcode; Address align; Address offset; uint64_t val; diff --git a/src/wast-parser.cc b/src/wast-parser.cc index 353eed36..f2fcf73e 100644 --- a/src/wast-parser.cc +++ b/src/wast-parser.cc @@ -583,8 +583,8 @@ TokenTypePair WastParser::PeekPair() { return TokenTypePair{{Peek(), Peek(1)}}; } -bool WastParser::PeekMatch(TokenType type) { - return Peek() == type; +bool WastParser::PeekMatch(TokenType type, size_t n) { + return Peek(n) == type; } bool WastParser::PeekMatchLpar(TokenType type) { @@ -1945,6 +1945,26 @@ Result WastParser::ParseSIMDLoadStoreInstr(Location loc, std::unique_ptr<Expr>* out_expr) { ErrorUnlessOpcodeEnabled(token); + Var memidx(0, loc); + + if (options_->features.multi_memory_enabled()) { + // We have to be a little careful when reading the memeory index. + // If there is just a single integer folloing the instruction that + // represents the lane index, so we check for either a pair of intergers + // or an integers followed by offset= or align=. + bool try_read_mem_index = true; + if (PeekMatch(TokenType::Nat)) { + // The next token could be a memory index or a lane index + if (!PeekMatch(TokenType::OffsetEqNat, 1) && + !PeekMatch(TokenType::AlignEqNat, 1) && + !PeekMatch(TokenType::Nat, 1)) { + try_read_mem_index = false; + } + } + if (try_read_mem_index) { + CHECK_RESULT(ParseMemidx(loc, &memidx)); + } + } Address offset; Address align; ParseOffsetOpt(&offset); @@ -1957,7 +1977,7 @@ Result WastParser::ParseSIMDLoadStoreInstr(Location loc, return Result::Error; } - out_expr->reset(new T(token.opcode(), align, offset, lane_idx, loc)); + out_expr->reset(new T(token.opcode(), memidx, align, offset, lane_idx, loc)); return Result::Ok; } diff --git a/src/wast-parser.h b/src/wast-parser.h index 4a449c7f..8c799b7f 100644 --- a/src/wast-parser.h +++ b/src/wast-parser.h @@ -82,7 +82,7 @@ class WastParser { TokenTypePair PeekPair(); // Returns true if the next token's type is equal to the parameter. - bool PeekMatch(TokenType); + bool PeekMatch(TokenType, size_t n = 0); // Returns true if the next token's type is '(' and the following token is // equal to the parameter. |