summaryrefslogtreecommitdiff
path: root/src/wast-parser.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/wast-parser.cc')
-rw-r--r--src/wast-parser.cc36
1 files changed, 33 insertions, 3 deletions
diff --git a/src/wast-parser.cc b/src/wast-parser.cc
index 11c2947a..e62b10da 100644
--- a/src/wast-parser.cc
+++ b/src/wast-parser.cc
@@ -1686,10 +1686,40 @@ Result WastParser::ParsePlainInstr(std::unique_ptr<Expr>* out_expr) {
case TokenType::SimdShuffleOp: {
Token token = Consume();
ErrorUnlessOpcodeEnabled(token);
- Const const_;
- CHECK_RESULT((ParseSimdConst(&const_, Type::I32, sizeof(v128))));
+ uint8_t values[16];
+ for (int lane = 0; lane < 16; ++lane) {
+ Location loc = GetLocation();
+
+ if (!PeekMatch(TokenType::Nat)) {
+ return ErrorExpected({"a natural number in range [0, 32)"});
+ }
+
+ Literal literal = Consume().literal();
+
+ string_view sv = literal.text;
+ const char* s = sv.begin();
+ const char* end = sv.end();
+ Result result;
+
+ uint32_t value = 0;
+ result = ParseInt32(s, end, &value, ParseIntType::UnsignedOnly);
+
+ if (Failed(result)) {
+ Error(loc, "invalid literal \"%s\"", literal.text.c_str());
+ return Result::Error;
+ }
+
+ if (value > 31) {
+ Error(loc, "shuffle index \"%s\" out-of-range [0, 32)", literal.text.c_str());
+ return Result::Error;
+ }
+
+ values[lane] = static_cast<uint8_t>(value);
+ }
+ v128 value = Bitcast<v128>(values);
+
out_expr->reset(
- new SimdShuffleOpExpr(token.opcode(), const_.v128_bits, loc));
+ new SimdShuffleOpExpr(token.opcode(), value, loc));
break;
}