diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/opcode.cc | 29 | ||||
-rw-r--r-- | src/opcode.h | 3 | ||||
-rw-r--r-- | src/type-checker.cc | 99 |
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; } |