summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/opcode.cc29
-rw-r--r--src/opcode.h3
-rw-r--r--src/type-checker.cc99
3 files changed, 55 insertions, 76 deletions
diff --git a/src/opcode.cc b/src/opcode.cc
index 6bb01d46..98cfe99e 100644
--- a/src/opcode.cc
+++ b/src/opcode.cc
@@ -337,4 +337,33 @@ bool Opcode::IsEnabled(const Features& features) const {
}
}
+uint32_t Opcode::GetSimdLaneCount() const {
+ switch (enum_) {
+ case Opcode::I8X16ExtractLaneS:
+ case Opcode::I8X16ExtractLaneU:
+ case Opcode::I8X16ReplaceLane:
+ return 16;
+ break;
+ case Opcode::I16X8ExtractLaneS:
+ case Opcode::I16X8ExtractLaneU:
+ case Opcode::I16X8ReplaceLane:
+ return 8;
+ break;
+ case Opcode::F32X4ExtractLane:
+ case Opcode::F32X4ReplaceLane:
+ case Opcode::I32X4ExtractLane:
+ case Opcode::I32X4ReplaceLane:
+ return 4;
+ break;
+ case Opcode::F64X2ExtractLane:
+ case Opcode::F64X2ReplaceLane:
+ case Opcode::I64X2ExtractLane:
+ case Opcode::I64X2ReplaceLane:
+ return 2;
+ break;
+ default:
+ WABT_UNREACHABLE;
+ }
+}
+
} // end anonymous namespace
diff --git a/src/opcode.h b/src/opcode.h
index 86838db7..61d7a3ad 100644
--- a/src/opcode.h
+++ b/src/opcode.h
@@ -61,6 +61,9 @@ struct Opcode {
Type GetParamType3() const { return GetInfo().param3_type; }
Address GetMemorySize() const { return GetInfo().memory_size; }
+ // Get the lane count of an extract/replace simd op.
+ uint32_t GetSimdLaneCount() const;
+
// Return 1 if |alignment| matches the alignment of |opcode|, or if
// |alignment| is WABT_USE_NATURAL_ALIGNMENT.
bool IsNaturallyAligned(Address alignment) const;
diff --git a/src/type-checker.cc b/src/type-checker.cc
index 7e68f6b0..52001139 100644
--- a/src/type-checker.cc
+++ b/src/type-checker.cc
@@ -16,6 +16,8 @@
#include "src/type-checker.h"
+#include <cinttypes>
+
namespace wabt {
TypeChecker::Label::Label(LabelType label_type,
@@ -597,102 +599,47 @@ Result TypeChecker::OnTernary(Opcode opcode) {
Result TypeChecker::OnSimdLaneOp(Opcode opcode, uint64_t lane_idx) {
Result result = Result::Error;
+ uint32_t lane_count = opcode.GetSimdLaneCount();
+ if (lane_idx >= lane_count) {
+ PrintError("lane index must be less than %d (got %" PRIu64 ")", lane_count,
+ lane_idx);
+ }
+
switch (opcode) {
case Opcode::I8X16ExtractLaneS:
- case Opcode::I8X16ExtractLaneU: {
- if(lane_idx >= 16) {
- PrintError("TypeChecker: I8X16 lane Operations: lane index must\
- be less than 16.");
- break;
- }
- result = CheckOpcode1(opcode);
- break;
- }
+ case Opcode::I8X16ExtractLaneU:
case Opcode::I16X8ExtractLaneS:
- case Opcode::I16X8ExtractLaneU: {
- if(lane_idx >= 8) {
- PrintError("TypeChecker: I16X8 lane Operations: lane index must\
- be less than 8.");
- break;
- }
- result = CheckOpcode1(opcode);
- break;
- }
+ case Opcode::I16X8ExtractLaneU:
case Opcode::I32X4ExtractLane:
- case Opcode::F32X4ExtractLane: {
- if(lane_idx >= 4) {
- PrintError("TypeChecker: (I/f)32X4 lane Operations: lane index must\
- be less than 4.");
- break;
- }
- result = CheckOpcode1(opcode);
- break;
- }
+ case Opcode::F32X4ExtractLane:
case Opcode::I64X2ExtractLane:
- case Opcode::F64X2ExtractLane: {
- if(lane_idx >= 2) {
- PrintError("TypeChecker: (I/f)64X2 lane Operations: lane index must\
- be less than 2.");
- break;
- }
+ case Opcode::F64X2ExtractLane:
result = CheckOpcode1(opcode);
break;
- }
- case Opcode::I8X16ReplaceLane: {
- if(lane_idx >= 16) {
- PrintError("TypeChecker: I8X16 lane Operations: lane index must\
- be less than 16.");
- break;
- }
- result = CheckOpcode2(opcode);
- break;
- }
- case Opcode::I16X8ReplaceLane: {
- if(lane_idx >= 8) {
- PrintError("TypeChecker: I16X8 lane Operations: lane index must\
- be less than 8.");
- break;
- }
- result = CheckOpcode2(opcode);
- break;
- }
+ case Opcode::I8X16ReplaceLane:
+ case Opcode::I16X8ReplaceLane:
case Opcode::I32X4ReplaceLane:
- case Opcode::F32X4ReplaceLane: {
- if(lane_idx >= 4) {
- PrintError("TypeChecker: (I/f)32X4 lane Operations: lane index must\
- be less than 4.");
- break;
- }
- result = CheckOpcode2(opcode);
- break;
- }
+ case Opcode::F32X4ReplaceLane:
case Opcode::I64X2ReplaceLane:
- case Opcode::F64X2ReplaceLane: {
- if(lane_idx >= 2) {
- PrintError("TypeChecker: (I/f)64X2 lane Operations: lane index must\
- be less than 2.");
- break;
- }
+ case Opcode::F64X2ReplaceLane:
result = CheckOpcode2(opcode);
break;
- }
default:
- PrintError("TypeChecker::OnSimdLane: called by invalid opcode.");
- }
+ WABT_UNREACHABLE;
+ }
return result;
}
Result TypeChecker::OnSimdShuffleOp(Opcode opcode, v128 lane_idx) {
Result result = Result::Error;
uint8_t simd_data[16];
- memcpy(simd_data, &(lane_idx), 16);
- for(int i = 0; i < 16; i++) {
- if(simd_data[i] >= 32) {
- PrintError("TypeChecker: v8x16 shuffle: each lane index must be >=0 and < 32.");
- return result;
+ memcpy(simd_data, &lane_idx, 16);
+ for (int i = 0; i < 16; i++) {
+ if (simd_data[i] >= 32) {
+ PrintError("lane index must be less than 32 (got %d)", simd_data[i]);
}
}
-
+
result = CheckOpcode2(opcode);
return result;
}