Repository: tetratelabs/wazero
Pull request #555 (2022-05-13 03:23:58)

Adds SIMD opcodes and feature flag
part of #484 

Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>


Patch:
diff --git a/config.go b/config.go
index 467f3ca0..5f149845 100644
--- a/config.go
+++ b/config.go
@@ -105,6 +105,12 @@ type RuntimeConfig interface {
 	// See https://github.com/WebAssembly/spec/blob/main/proposals/sign-extension-ops/Overview.md
 	WithFeatureSignExtensionOps(bool) RuntimeConfig
 
+	// WithFeatureSIMD enables the vector value type and vector instructions (aka SIMD).  This defaults to false
+	// as the feature was not in WebAssembly 1.0.
+	//
+	// See https://github.com/WebAssembly/spec/blob/main/proposals/simd/SIMD.md
+	WithFeatureSIMD(bool) RuntimeConfig
+
 	// WithWasmCore1 enables features included in the WebAssembly Core Specification 1.0. Selecting this
 	// overwrites any currently accumulated features with only those included in this W3C recommendation.
 	//
@@ -202,6 +208,13 @@ func (c *runtimeConfig) WithFeatureSignExtensionOps(enabled bool) RuntimeConfig
 	return &ret
 }
 
+// WithFeatureSIMD implements RuntimeConfig.WithFeatureSIMD
+func (c *runtimeConfig) WithFeatureSIMD(enabled bool) RuntimeConfig {
+	ret := *c // copy
+	ret.enabledFeatures = ret.enabledFeatures.Set(wasm.FeatureSIMD, enabled)
+	return &ret
+}
+
 // WithWasmCore1 implements RuntimeConfig.WithWasmCore1
 func (c *runtimeConfig) WithWasmCore1() RuntimeConfig {
 	ret := *c // copy
diff --git a/internal/wasm/features.go b/internal/wasm/features.go
index 063356f4..0c7cdb3a 100644
--- a/internal/wasm/features.go
+++ b/internal/wasm/features.go
@@ -24,8 +24,8 @@ const Features20220419 = Features20191205 |
 	FeatureMultiValue |
 	FeatureNonTrappingFloatToIntConversion |
 	FeatureReferenceTypes |
-	FeatureSignExtensionOps
-	// TODO: FeatureSIMD
+	FeatureSignExtensionOps |
+	FeatureSIMD
 
 const (
 	// FeatureBulkMemoryOperations decides if parsing should succeed on the following instructions:
@@ -97,6 +97,11 @@ const (
 	//
 	// See https://github.com/WebAssembly/spec/blob/main/proposals/sign-extension-ops/Overview.md
 	FeatureSignExtensionOps
+
+	// FeatureSIMD enables the vector value type and vector instructions.
+	//
+	// See https://github.com/WebAssembly/spec/blob/main/proposals/simd/SIMD.md
+	FeatureSIMD
 )
 
 // Set assigns the value for the given feature.
@@ -123,9 +128,10 @@ func (f Features) Require(feature Features) error {
 // String implements fmt.Stringer by returning each enabled feature.
 func (f Features) String() string {
 	var builder strings.Builder
-	for i := Features(0); i < 63; i++ { // cycle through all bits to reduce code and maintenance
-		if f.Get(i) {
-			if name := featureName(i); name != "" {
+	for i := 0; i <= 63; i++ { // cycle through all bits to reduce code and maintenance
+		target := Features(1 << i)
+		if f.Get(target) {
+			if name := featureName(target); name != "" {
 				if builder.Len() > 0 {
 					builder.WriteByte('|')
 				}
@@ -156,6 +162,9 @@ func featureName(f Features) string {
 	case FeatureReferenceTypes:
 		// match https://github.com/WebAssembly/spec/blob/main/proposals/reference-types/Overview.md
 		return "reference-types"
+	case FeatureSIMD:
+		// match https://github.com/WebAssembly/spec/blob/main/proposals/simd/SIMD.md
+		return "simd"
 	}
 	return ""
 }
diff --git a/internal/wasm/func_validation.go b/internal/wasm/func_validation.go
index cfecce23..c57db4b7 100644
--- a/internal/wasm/func_validation.go
+++ b/internal/wasm/func_validation.go
@@ -1042,6 +1042,19 @@ func (m *Module) validateFunctionWithMaxStackValues(
 					valueTypeStack.push(r)
 				}
 			}
+		} else if op == OpcodeVecPrefix {
+			pc++
+			// Vector instructions come with two bytes which starts with OpcodeVecPrefix,
+			// and the second byte determines the actual instruction.
+			vecOpcode := body[pc]
+			if err := enabledFeatures.Require(FeatureSIMD); err != nil {
+				return fmt.Errorf("%s invalid as %v", vectorInstructionName[vecOpcode], err)
+			}
+
+			switch vecOpcode {
+			default:
+				return fmt.Errorf("TODO: SIMD instruction %s will be implemented in #506", vectorInstructionName[vecOpcode])
+			}
 		} else if op == OpcodeBlock {
 			bt, num, err := DecodeBlockType(types, bytes.NewReader(body[pc+1:]), enabledFeatures)
 			if err != nil {
diff --git a/internal/wasm/instruction.go b/internal/wasm/instruction.go
index 14e5d516..09712c38 100644
--- a/internal/wasm/instruction.go
+++ b/internal/wasm/instruction.go
@@ -277,6 +277,10 @@ const (
 	// Introduced in FeatureNonTrappingFloatToIntConversion, but used in other
 	// features, such as FeatureBulkMemoryOperations.
 	OpcodeMiscPrefix Opcode = 0xfc
+
+	// OpcodeVecPrefix is the prefix of all vector isntructions introduced in
+	// FeatureSIMD.
+	OpcodeVecPrefix Opcode = 0xfd
 )
 
 // OpcodeMisc represents opcodes of the miscellaneous operations.
@@ -315,6 +319,292 @@ const (
 	OpcodeMiscTableFill OpcodeMisc = 0x11
 )
 
+// OpcodeVec represents an opcode of a vector instructions whic has
+// multi-byte encoding and is prefixed by OpcodeMiscPrefix.
+//
+// These opcodes are toggled with FeatureSIMD.
+type OpcodeVec = byte
+
+const (
+	// Loads and stores.
+	OpcodeVecV128Load        OpcodeVec = 0x00
+	OpcodeVecV128Load8x8_s   OpcodeVec = 0x01
+	OpcodeVecV128Load8x8_u   OpcodeVec = 0x02
+	OpcodeVecV128Load16x4_s  OpcodeVec = 0x03
+	OpcodeVecV128Load16x4_u  OpcodeVec = 0x04
+	OpcodeVecV128Load32x2_s  OpcodeVec = 0x05
+	OpcodeVecV128Load32x2_u  OpcodeVec = 0x06
+	OpcodeVecV128Load8Splat  OpcodeVec = 0x07
+	OpcodeVecV128Load16Splat OpcodeVec = 0x08
+	OpcodeVecV128Load32Splat OpcodeVec = 0x09
+	OpcodeVecV128Load64Splat OpcodeVec = 0x0a
+
+	OpcodeVecV128Load32zero OpcodeVec = 0x5c
+	OpcodeVecV128Load64zero OpcodeVec = 0x5d
+
+	OpcodeVecV128Store       OpcodeVec = 0x0b
+	OpcodeVecV128Load8Lane   OpcodeVec = 0x54
+	OpcodeVecV128Load16Lane  OpcodeVec = 0x55
+	OpcodeVecV128Load32Lane  OpcodeVec = 0x56
+	OpcodeVecV128Load64Lane  OpcodeVec = 0x57
+	OpcodeVecV128Store8Lane  OpcodeVec = 0x58
+	OpcodeVecV128Store16Lane OpcodeVec = 0x59
+	OpcodeVecV128Store32Lane OpcodeVec = 0x5a
+	OpcodeVecV128Store64Lane OpcodeVec = 0x5b
+
+	// Const instruction.
+	OpcodeVecV128Const OpcodeVec = 0x0c
+
+	// Shuffles.
+	OpcodeVecV128i8x16Shuffle OpcodeVec = 0x0d
+
+	// Extrac and replaces.
+	OpcodeVecI8x16ExtractLaneS OpcodeVec = 0x15
+	OpcodeVecI8x16ExtractLaneU OpcodeVec = 0x16
+	OpcodeVecI8x16ReplaceLane  OpcodeVec = 0x17
+	OpcodeVecI16x8ExtractLaneS OpcodeVec = 0x18
+	OpcodeVecI16x8ExtractLaneU OpcodeVec = 0x19
+	OpcodeVecI16x8ReplaceLane  OpcodeVec = 0x1a
+	OpcodeVecI32x4ExtractLane  OpcodeVec = 0x1b
+	OpcodeVecI32x4ReplaceLane  OpcodeVec = 0x1c
+	OpcodeVecI64x2ExtractLane  OpcodeVec = 0x1d
+	OpcodeVecI64x2ReplaceLane  OpcodeVec = 0x1e
+	OpcodeVecF32x4ExtractLane  OpcodeVec = 0x1f
+	OpcodeVecF32x4ReplaceLane  OpcodeVec = 0x20
+	OpcodeVecF64x2ExtractLane  OpcodeVec = 0x21
+	OpcodeVecF64x2ReplaceLane  OpcodeVec = 0x22
+
+	// Splat and swizzle.
+	OpcodeVecI8x16Swizzle OpcodeVec = 0x0e
+	OpcodeVecI8x16Splat   OpcodeVec = 0x0f
+	OpcodeVecI16x8Splat   OpcodeVec = 0x10
+	OpcodeVecI32x4Splat   OpcodeVec = 0x11
+	OpcodeVecI64x2Splat   OpcodeVec = 0x12
+	OpcodeVecF32x4Splat   OpcodeVec = 0x13
+	OpcodeVecF64x2Splat   OpcodeVec = 0x14
+
+	// i8 comparisons.
+	OpcodeVecI8x16Eq  OpcodeVec = 0x23
+	OpcodeVecI8x16Ne  OpcodeVec = 0x24
+	OpcodeVecI8x16LtS OpcodeVec = 0x25
+	OpcodeVecI8x16LtU OpcodeVec = 0x26
+	OpcodeVecI8x16GtS OpcodeVec = 0x27
+	OpcodeVecI8x16GtU OpcodeVec = 0x28
+	OpcodeVecI8x16LeS OpcodeVec = 0x29
+	OpcodeVecI8x16LeU OpcodeVec = 0x2a
+	OpcodeVecI8x16GeS OpcodeVec = 0x2b
+	OpcodeVecI8x16GeU OpcodeVec = 0x2c
+
+	// i16 comparisons.
+	OpcodeVecI16x8Eq  OpcodeVec = 0x2d
+	OpcodeVecI16x8Ne  OpcodeVec = 0x2e
+	OpcodeVecI16x8LtS OpcodeVec = 0x2f
+	OpcodeVecI16x8LtU OpcodeVec = 0x30
+	OpcodeVecI16x8GtS OpcodeVec = 0x31
+	OpcodeVecI16x8GtU OpcodeVec = 0x32
+	OpcodeVecI16x8LeS OpcodeVec = 0x33
+	OpcodeVecI16x8LeU OpcodeVec = 0x34
+	OpcodeVecI16x8GeS OpcodeVec = 0x35
+	OpcodeVecI16x8GeU OpcodeVec = 0x36
+
+	// i32 comparisons.
+	OpcodeVecI32x4Eq  OpcodeVec = 0x37
+	OpcodeVecI32x4Ne  OpcodeVec = 0x38
+	OpcodeVecI32x4LtS OpcodeVec = 0x39
+	OpcodeVecI32x4LtU OpcodeVec = 0x3a
+	OpcodeVecI32x4GtS OpcodeVec = 0x3b
+	OpcodeVecI32x4GtU OpcodeVec = 0x3c
+	OpcodeVecI32x4LeS OpcodeVec = 0x3d
+	OpcodeVecI32x4LeU OpcodeVec = 0x3e
+	OpcodeVecI32x4GeS OpcodeVec = 0x3f
+	OpcodeVecI32x4GeU OpcodeVec = 0x40
+
+	// i64 comparisons.
+	OpcodeVecI64x2Eq  OpcodeVec = 0xd6
+	OpcodeVecI64x2Ne  OpcodeVec = 0xd7
+	OpcodeVecI64x2LtS OpcodeVec = 0xd8
+	OpcodeVecI64x2GtS OpcodeVec = 0xd9
+	OpcodeVecI64x2LeS OpcodeVec = 0xda
+	OpcodeVecI64x2GeS OpcodeVec = 0xdb
+
+	// f32 comparisons.
+	OpcodeVecF32x4Eq OpcodeVec = 0x41
+	OpcodeVecF32x4Ne OpcodeVec = 0x42
+	OpcodeVecF32x4Lt OpcodeVec = 0x43
+	OpcodeVecF32x4Gt OpcodeVec = 0x44
+	OpcodeVecF32x4Le OpcodeVec = 0x45
+	OpcodeVecF32x4Ge OpcodeVec = 0x46
+
+	// f64 comparisons.
+	OpcodeVecF64x2Eq OpcodeVec = 0x47
+	OpcodeVecF64x2Ne OpcodeVec = 0x48
+	OpcodeVecF64x2Lt OpcodeVec = 0x49
+	OpcodeVecF64x2Gt OpcodeVec = 0x4a
+	OpcodeVecF64x2Le OpcodeVec = 0x4b
+	OpcodeVecF64x2Ge OpcodeVec = 0x4c
+
+	// v128 logical instructions.
+	OpcodeVecV128Not       OpcodeVec = 0x4d
+	OpcodeVecV128And       OpcodeVec = 0x4e
+	OpcodeVecV128AndNot    OpcodeVec = 0x4f
+	OpcodeVecV128Or        OpcodeVec = 0x50
+	OpcodeVecV128Xor       OpcodeVec = 0x51
+	OpcodeVecV128Bitselect OpcodeVec = 0x52
+	OpcodeVecV128AnyTrue   OpcodeVec = 0x53
+
+	// i8 misc.
+	OpcodeVecI8x16Abs          OpcodeVec = 0x60
+	OpcodeVecI8x16Neg          OpcodeVec = 0x61
+	OpcodeVecI8x16Popcnt       OpcodeVec = 0x62
+	OpcodeVecI8x16AllTrue      OpcodeVec = 0x63
+	OpcodeVecI8x16BitMask      OpcodeVec = 0x64
+	OpcodeVecI8x16NarrowI16x8S OpcodeVec = 0x65
+	OpcodeVecI8x16NarrowI16x8U OpcodeVec = 0x66
+
+	OpcodeVecI8x16Shl     OpcodeVec = 0x6b
+	OpcodeVecI8x16ShrS    OpcodeVec = 0x6c
+	OpcodeVecI8x16ShrU    OpcodeVec = 0x6d
+	OpcodeVecI8x16Add     OpcodeVec = 0x6e
+	OpcodeVecI8x16AddSatS OpcodeVec = 0x6f
+
+	OpcodeVecI8x16AddSatU OpcodeVec = 0x70
+	OpcodeVecI8x16Sub     OpcodeVec = 0x71
+	OpcodeVecI8x16SubSatS OpcodeVec = 0x72
+	OpcodeVecI8x16SubSatU OpcodeVec = 0x73
+	OpcodeVecI8x16MinS    OpcodeVec = 0x76
+	OpcodeVecI8x16MinU    OpcodeVec = 0x77
+	OpcodeVecI8x16MaxS    OpcodeVec = 0x78
+	OpcodeVecI8x16MaxU    OpcodeVec = 0x79
+	OpcodeVecI8x16ArgrU   OpcodeVec = 0x7b
+
+	// i16 misc.
+	OpcodeVecI16x8ExtaddPairwiseI8x16S OpcodeVec = 0x7c
+	OpcodeVecI16x8ExtaddPairwiseI8x16U OpcodeVec = 0x7d
+	OpcodeVecI16x8Abs                  OpcodeVec = 0x80
+	OpcodeVecI16x8Neg                  OpcodeVec = 0x81
+	OpcodeVecI16x8Q16mulrSatS          OpcodeVec = 0x82
+	OpcodeVecI16x8AllTrue              OpcodeVec = 0x83
+	OpcodeVecI16x8BitMask              OpcodeVec = 0x84
+	OpcodeVecI16x8NarrowI32x4S         OpcodeVec = 0x85
+	OpcodeVecI16x8NarrowI32x4U         OpcodeVec = 0x86
+	OpcodeVecI16x8ExtendLowI8x16S      OpcodeVec = 0x87
+	OpcodeVecI16x8ExtendHighI8x16S     OpcodeVec = 0x88
+	OpcodeVecI16x8ExtendLowI8x16U      OpcodeVec = 0x89
+	OpcodeVecI16x8ExtendHighI8x16U     OpcodeVec = 0x8a
+	OpcodeVecI16x8Shl                  OpcodeVec = 0x8b
+	OpcodeVecI16x8ShrS                 OpcodeVec = 0x8c
+	OpcodeVecI16x8ShrU                 OpcodeVec = 0x8d
+	OpcodeVecI16x8Add                  OpcodeVec = 0x8e
+	OpcodeVecI16x8AddSatS              OpcodeVec = 0x8f
+	OpcodeVecI16x8AddSatU              OpcodeVec = 0x90
+	OpcodeVecI16x8Sub                  OpcodeVec = 0x91
+	OpcodeVecI16x8SubSatS              OpcodeVec = 0x92
+	OpcodeVecI16x8SubSatU              OpcodeVec = 0x93
+	OpcodeVecI16x8Mul                  OpcodeVec = 0x95
+	OpcodeVecI16x8MinS                 OpcodeVec = 0x96
+	OpcodeVecI16x8MinU                 OpcodeVec = 0x97
+	OpcodeVecI16x8MaxS                 OpcodeVec = 0x98
+	OpcodeVecI16x8MaxU                 OpcodeVec = 0x99
+	OpcodeVecI16x8ArgrU                OpcodeVec = 0x9b
+	OpcodeVecI16x8ExtMulLowI8x16S      OpcodeVec = 0x9c
+	OpcodeVecI16x8ExtMulHighI8x16S     OpcodeVec = 0x9d
+	OpcodeVecI16x8ExtMulLowI8x16U      OpcodeVec = 0x9e
+	OpcodeVecI16x8ExtMulHighI8x16U     OpcodeVec = 0x9f
+
+	// i32 misc.
+	OpcodeVecI32x4ExtaddPairwiseI16x8S OpcodeVec = 0x7e
+	OpcodeVecI32x4ExtaddPairwiseI16x8U OpcodeVec = 0x7f
+	OpcodeVecI32x4Abs                  OpcodeVec = 0xa0
+	OpcodeVecI32x4Neg                  OpcodeVec = 0xa1
+	OpcodeVecI32x4AllTrue              OpcodeVec = 0xa3
+	OpcodeVecI32x4BitMask              OpcodeVec = 0xa4
+	OpcodeVecI32x4ExtendLowI16x8S      OpcodeVec = 0xa7
+	OpcodeVecI32x4ExtendHighI16x8S     OpcodeVec = 0xa8
+	OpcodeVecI32x4ExtendLowI16x8U      OpcodeVec = 0xa9
+	OpcodeVecI32x4ExtendHighI16x8U     OpcodeVec = 0xaa
+	OpcodeVecI32x4Shl                  OpcodeVec = 0xab
+	OpcodeVecI32x4ShrS                 OpcodeVec = 0xac
+	OpcodeVecI32x4ShrU                 OpcodeVec = 0xad
+	OpcodeVecI32x4Add                  OpcodeVec = 0xae
+	OpcodeVecI32x4Sub                  OpcodeVec = 0xb1
+	OpcodeVecI32x4Mul                  OpcodeVec = 0xb5
+	OpcodeVecI32x4MinS                 OpcodeVec = 0xb6
+	OpcodeVecI32x4MinU                 OpcodeVec = 0xb7
+	OpcodeVecI32x4MaxS                 OpcodeVec = 0xb8
+	OpcodeVecI32x4MaxU                 OpcodeVec = 0xb9
+	OpcodeVecI32x4DotI16x8S            OpcodeVec = 0xba
+	OpcodeVecI32x4ExtMulLowI16x8S      OpcodeVec = 0xbc
+	OpcodeVecI32x4ExtMulHighI16x8S     OpcodeVec = 0xbd
+	OpcodeVecI32x4ExtMulLowI16x8U      OpcodeVec = 0xbe
+	OpcodeVecI32x4ExtMulHighI16x8U     OpcodeVec = 0xbf
+
+	// i64 misc.
+	OpcodeVecI64x2Abs              OpcodeVec = 0xc0
+	OpcodeVecI64x2Neg              OpcodeVec = 0xc1
+	OpcodeVecI64x2AllTrue          OpcodeVec = 0xc3
+	OpcodeVecI64x2BitMask          OpcodeVec = 0xc4
+	OpcodeVecI64x2ExtendLowI32x4S  OpcodeVec = 0xc7
+	OpcodeVecI64x2ExtendHighI32x4S OpcodeVec = 0xc8
+	OpcodeVecI64x2ExtendLowI32x4U  OpcodeVec = 0xc9
+	OpcodeVecI64x2ExtendHighI32x4U OpcodeVec = 0xca
+	OpcodeVecI64x2Shl              OpcodeVec = 0xcb
+	OpcodeVecI64x2ShrS             OpcodeVec = 0xcc
+	OpcodeVecI64x2ShrU             OpcodeVec = 0xcd
+	OpcodeVecI64x2Add              OpcodeVec = 0xce
+	OpcodeVecI64x2Sub              OpcodeVec = 0xd1
+	OpcodeVecI64x2Mul              OpcodeVec = 0xd5
+	OpcodeVecI64x2ExtMulLowI32x4S  OpcodeVec = 0xdc
+	OpcodeVecI64x2ExtMulHighI32x4S OpcodeVec = 0xdd
+	OpcodeVecI64x2ExtMulLowI32x4U  OpcodeVec = 0xde
+	OpcodeVecI64x2ExtMulHighI32x4U OpcodeVec = 0xdf
+
+	// f32 misc.
+	OpcodeVecF32x4Ceil    OpcodeVec = 0x67
+	OpcodeVecF32x4Floor   OpcodeVec = 0x68
+	OpcodeVecF32x4Trunc   OpcodeVec = 0x69
+	OpcodeVecF32x4Nearest OpcodeVec = 0x6a
+	OpcodeVecF32x4Abs     OpcodeVec = 0xe0
+	OpcodeVecF32x4Neg     OpcodeVec = 0xe1
+	OpcodeVecF32x4Sqrt    OpcodeVec = 0xe3
+	OpcodeVecF32x4Add     OpcodeVec = 0xe4
+	OpcodeVecF32x4Sub     OpcodeVec = 0xe5
+	OpcodeVecF32x4Mul     OpcodeVec = 0xe6
+	OpcodeVecF32x4Div     OpcodeVec = 0xe7
+	OpcodeVecF32x4Min     OpcodeVec = 0xe8
+	OpcodeVecF32x4Max     OpcodeVec = 0xe9
+	OpcodeVecF32x4Pmin    OpcodeVec = 0xea
+	OpcodeVecF32x4Pmax    OpcodeVec = 0xeb
+
+	// f64 misc.
+	OpcodeVecF64x4Ceil    OpcodeVec = 0x74
+	OpcodeVecF64x4Floor   OpcodeVec = 0x75
+	OpcodeVecF64x4Trunc   OpcodeVec = 0x7a
+	OpcodeVecF64x4Nearest OpcodeVec = 0x94
+	OpcodeVecF64x4Abs     OpcodeVec = 0xec
+	OpcodeVecF64x4Neg     OpcodeVec = 0xed
+	OpcodeVecF64x4Sqrt    OpcodeVec = 0xef
+	OpcodeVecF64x4Add     OpcodeVec = 0xf0
+	OpcodeVecF64x4Sub     OpcodeVec = 0xf1
+	OpcodeVecF64x4Mul     OpcodeVec = 0xf2
+	OpcodeVecF64x4Div     OpcodeVec = 0xf3
+	OpcodeVecF64x4Min     OpcodeVec = 0xf4
+	OpcodeVecF64x4Max     OpcodeVec = 0xf5
+	OpcodeVecF64x4Pmin    OpcodeVec = 0xf6
+	OpcodeVecF64x4Pmax    OpcodeVec = 0xf7
+
+	// conversions.
+	OpcodeVecI32x4TruncSatF32x4S      OpcodeVec = 0xf8
+	OpcodeVecI32x4TruncSatF32x4U      OpcodeVec = 0xf9
+	OpcodeVecF32x4ConvertI32x4S       OpcodeVec = 0xfa
+	OpcodeVecF32x4ConvertI32x4U       OpcodeVec = 0xfb
+	OpcodeVecI32x4TruncSatF64x2SZero  OpcodeVec = 0xfc
+	OpcodeVecI32x4TruncSatF64x2UZero  OpcodeVec = 0xfd
+	OpcodeVecF64x2ConvertI32x4S       OpcodeVec = 0xfe
+	OpcodeVecF64x2ConvertI32x4U       OpcodeVec = 0xff
+	OpcodeVecF32x4DemoteF64x2Zero     OpcodeVec = 0x5e
+	OpcodeVecF64x2PromoteLowF32x4Zero OpcodeVec = 0x5f
+)
+
 const (
 	OpcodeUnreachableName       = "unreachable"
 	OpcodeNopName               = "nop"
@@ -506,6 +796,7 @@ const (
 	OpcodeI64Extend32SName = "i64.extend32_s"
 
 	OpcodeMiscPrefixName = "misc_prefix"
+	OpcodeVecPrefixName  = "vector_prefix"
 )
 
 var instructionNames = [256]string{
@@ -698,6 +989,7 @@ var instructionNames = [256]string{
 	OpcodeI64Extend32S: OpcodeI64Extend32SName,
 
 	OpcodeMiscPrefix: OpcodeMiscPrefixName,
+	OpcodeVecPrefix:  OpcodeVecPrefixName,
 }
 
 // InstructionName returns the instruction corresponding to this binary Opcode.
@@ -754,3 +1046,486 @@ var miscInstructionNames = [256]string{
 func MiscInstructionName(oc OpcodeMisc) string {
 	return miscInstructionNames[oc]
 }
+
+const (
+	OpcodeVecV128LoadName                  = "v128.load"
+	OpcodeVecV128Load8x8_sName             = "v128.load8x8_s"
+	OpcodeVecV128Load8x8_uName             = "v128.load8x8_u"
+	OpcodeVecV128Load16x4_sName            = "v128.load16x4_s"
+	OpcodeVecV128Load16x4_uName            = "v128.load16x4_u"
+	OpcodeVecV128Load32x2_sName            = "v128.load32x2_s"
+	OpcodeVecV128Load32x2_uName            = "v128.load32x2_u"
+	OpcodeVecV128Load8SplatName            = "v128.load8_splat"
+	OpcodeVecV128Load16SplatName           = "v128.load16_splat"
+	OpcodeVecV128Load32SplatName           = "v128.load32_splat"
+	OpcodeVecV128Load64SplatName           = "v128.load64_splat"
+	OpcodeVecV128Load32zeroName            = "v128.load32_zero"
+	OpcodeVecV128Load64zeroName            = "v128.load64_zero"
+	OpcodeVecV128StoreName                 = "v128.store"
+	OpcodeVecV128Load8LaneName             = "v128.load8_lane"
+	OpcodeVecV128Load16LaneName            = "v128.load16_lane"
+	OpcodeVecV128Load32LaneName            = "v128.load32_lane"
+	OpcodeVecV128Load64LaneName            = "v128.load64_lane"
+	OpcodeVecV128Store8LaneName            = "v128.store8_lane"
+	OpcodeVecV128Store16LaneName           = "v128.store16_lane"
+	OpcodeVecV128Store32LaneName           = "v128.store32_lane"
+	OpcodeVecV128Store64LaneName           = "v128.store64_lane"
+	OpcodeVecV128ConstName                 = "v128.const"
+	OpcodeVecV128i8x16ShuffleName          = "v128.shuffle"
+	OpcodeVecI8x16ExtractLaneSName         = "i8x16.extract_lane_s"
+	OpcodeVecI8x16ExtractLaneUName         = "i8x16.extract_lane_u"
+	OpcodeVecI8x16ReplaceLaneName          = "i8x16.replace_lane"
+	OpcodeVecI16x8ExtractLaneSName         = "i16x4.extract_lane_s"
+	OpcodeVecI16x8ExtractLaneUName         = "i16x4.extract_lane_u"
+	OpcodeVecI16x8ReplaceLaneName          = "i16x4.replace"
+	OpcodeVecI32x4ExtractLaneName          = "i32x4.extract_lane"
+	OpcodeVecI32x4ReplaceLaneName          = "i32x4.replace_lane"
+	OpcodeVecI64x2ExtractLaneName          = "i64x2.extract_lane"
+	OpcodeVecI64x2ReplaceLaneName          = "i64x2.replace_lane"
+	OpcodeVecF32x4ExtractLaneName          = "f32x4.extract_lane"
+	OpcodeVecF32x4ReplaceLaneName          = "f32x4.replace_lane"
+	OpcodeVecF64x2ExtractLaneName          = "f64x2.extract_lane"
+	OpcodeVecF64x2ReplaceLaneName          = "f64x2.replace_lane"
+	OpcodeVecI8x16SwizzleName              = "i8x16.swizzle"
+	OpcodeVecI8x16SplatName                = "i8x16.splat"
+	OpcodeVecI16x8SplatName                = "i16x8.splat"
+	OpcodeVecI32x4SplatName                = "i32x4.splat"
+	OpcodeVecI64x2SplatName                = "i64x2.splat"
+	OpcodeVecF32x4SplatName                = "f32x4.splat"
+	OpcodeVecF64x2SplatName                = "f64x2.splat"
+	OpcodeVecI8x16EqName                   = "i8x16.eq"
+	OpcodeVecI8x16NeName                   = "i8x16.ne"
+	OpcodeVecI8x16LtSName                  = "i8x16.lt_s"
+	OpcodeVecI8x16LtUName                  = "i8x16.lt_u"
+	OpcodeVecI8x16GtSName                  = "i8x16.gt_s"
+	OpcodeVecI8x16GtUName                  = "i8x16.gt_u"
+	OpcodeVecI8x16LeSName                  = "i8x16.le_s"
+	OpcodeVecI8x16LeUName                  = "i8x16.le_u"
+	OpcodeVecI8x16GeSName                  = "i8x16.ge_s"
+	OpcodeVecI8x16GeUName                  = "i8x16.ge_u"
+	OpcodeVecI16x8EqName                   = "i16x8.eq"
+	OpcodeVecI16x8NeName                   = "i16x8.ne"
+	OpcodeVecI16x8LtSName                  = "i16x8.lt_s"
+	OpcodeVecI16x8LtUName                  = "i16x8.lt_u"
+	OpcodeVecI16x8GtSName                  = "i16x8.gt_s"
+	OpcodeVecI16x8GtUName                  = "i16x8.gt_u"
+	OpcodeVecI16x8LeSName                  = "i16x8.le_s"
+	OpcodeVecI16x8LeUName                  = "i16x8.le_u"
+	OpcodeVecI16x8GeSName                  = "i16x8.ge_s"
+	OpcodeVecI16x8GeUName                  = "i16x8.ge_u"
+	OpcodeVecI32x4EqName                   = "i32x4.eq"
+	OpcodeVecI32x4NeName                   = "i32x4.ne"
+	OpcodeVecI32x4LtSName                  = "i32x4.lt_s"
+	OpcodeVecI32x4LtUName                  = "i32x4.lt_u"
+	OpcodeVecI32x4GtSName                  = "i32x4.gt_s"
+	OpcodeVecI32x4GtUName                  = "i32x4.gt_u"
+	OpcodeVecI32x4LeSName                  = "i32x4.le_s"
+	OpcodeVecI32x4LeUName                  = "i32x4.le_u"
+	OpcodeVecI32x4GeSName                  = "i32x4.ge_s"
+	OpcodeVecI32x4GeUName                  = "i32x4.ge_u"
+	OpcodeVecI64x2EqName                   = "i64x2.eq"
+	OpcodeVecI64x2NeName                   = "i64x2.ne"
+	OpcodeVecI64x2LtSName                  = "i64x2.lt"
+	OpcodeVecI64x2GtSName                  = "i64x2.gt"
+	OpcodeVecI64x2LeSName                  = "i64x2.le"
+	OpcodeVecI64x2GeSName                  = "i64x2.ge"
+	OpcodeVecF32x4EqName                   = "f32x4.eq"
+	OpcodeVecF32x4NeName                   = "f32x4.ne"
+	OpcodeVecF32x4LtName                   = "f32x4.lt"
+	OpcodeVecF32x4GtName                   = "f32x4.gt"
+	OpcodeVecF32x4LeName                   = "f32x4.le"
+	OpcodeVecF32x4GeName                   = "f32x4.ge"
+	OpcodeVecF64x2EqName                   = "f64x2.eq"
+	OpcodeVecF64x2NeName                   = "f64x2.ne"
+	OpcodeVecF64x2LtName                   = "f64x2.lt"
+	OpcodeVecF64x2GtName                   = "f64x2.gt"
+	OpcodeVecF64x2LeName                   = "f64x2.le"
+	OpcodeVecF64x2GeName                   = "f64x2.ge"
+	OpcodeVecV128NotName                   = "v128.not"
+	OpcodeVecV128AndName                   = "v128.and"
+	OpcodeVecV128AndNotName                = "v128.andnot"
+	OpcodeVecV128OrName                    = "v128.or"
+	OpcodeVecV128XorName                   = "v128.xor"
+	OpcodeVecV128BitselectName             = "v128.bitselect"
+	OpcodeVecV128AnyTrueName               = "v128.any_true"
+	OpcodeVecI8x16AbsName                  = "i8x16.abs"
+	OpcodeVecI8x16NegName                  = "i8x16.neg"
+	OpcodeVecI8x16PopcntName               = "i8x16.popcnt"
+	OpcodeVecI8x16AllTrueName              = "i8x16.all_true"
+	OpcodeVecI8x16BitMaskName              = "i8x16.bitmask"
+	OpcodeVecI8x16NarrowI16x8SName         = "i8x16.narrow_i16x8_s"
+	OpcodeVecI8x16NarrowI16x8UName         = "i8x16.narrow_i16x8_u"
+	OpcodeVecI8x16ShlName                  = "i8x16.shl"
+	OpcodeVecI8x16ShrSName                 = "i8x16.shr_s"
+	OpcodeVecI8x16ShrUName                 = "i8x16.shr_u"
+	OpcodeVecI8x16AddName                  = "i8x16.add"
+	OpcodeVecI8x16AddSatSName              = "i8x16.add_sat_s"
+	OpcodeVecI8x16AddSatUName              = "i8x16.add_sat_u"
+	OpcodeVecI8x16SubName                  = "i8x16.sub"
+	OpcodeVecI8x16SubSatSName              = "i8x16.sub_s"
+	OpcodeVecI8x16SubSatUName              = "i8x16.sub_u"
+	OpcodeVecI8x16MinSName                 = "i8x16.min_s"
+	OpcodeVecI8x16MinUName                 = "i8x16.min_u"
+	OpcodeVecI8x16MaxSName                 = "i8x16.max_s"
+	OpcodeVecI8x16MaxUName                 = "i8x16.max_u"
+	OpcodeVecI8x16ArgrUName                = "i8x16.argr_u"
+	OpcodeVecI16x8ExtaddPairwiseI8x16SName = "i16x8.extadd_pairwise_i8x16_s"
+	OpcodeVecI16x8ExtaddPairwiseI8x16UName = "i16x8.extadd_pairwise_i8x16_u"
+	OpcodeVecI16x8AbsName                  = "i16x8.abs"
+	OpcodeVecI16x8NegName                  = "i16x8.neg"
+	OpcodeVecI16x8Q16mulrSatSName          = "i16x8.q15mulr_sat_s"
+	OpcodeVecI16x8AllTrueName              = "i16x8.all_true"
+	OpcodeVecI16x8BitMaskName              = "i16x8.bitmask"
+	OpcodeVecI16x8NarrowI32x4SName         = "i16x8.narrow_i32x4_s"
+	OpcodeVecI16x8NarrowI32x4UName         = "i16x8.narrow_i32x4_u"
+	OpcodeVecI16x8ExtendLowI8x16SName      = "i16x8.extend_low_i8x16_s"
+	OpcodeVecI16x8ExtendHighI8x16SName     = "i16x8.extend_high_i8x16_s"
+	OpcodeVecI16x8ExtendLowI8x16UName      = "i16x8.extend_low_i8x16_u"
+	OpcodeVecI16x8ExtendHighI8x16UName     = "i16x8.extend_high_i8x16_u"
+	OpcodeVecI16x8ShlName                  = "i16x8.shl"
+	OpcodeVecI16x8ShrSName                 = "i16x8.shr_s"
+	OpcodeVecI16x8ShrUName                 = "i16x8.shr_u"
+	OpcodeVecI16x8AddName                  = "i16x8.add"
+	OpcodeVecI16x8AddSatSName              = "i16x8.add_sat_s"
+	OpcodeVecI16x8AddSatUName              = "i16x8.add_sat_u"
+	OpcodeVecI16x8SubName                  = "i16x8.sub"
+	OpcodeVecI16x8SubSatSName              = "i16x8.sub_sat_s"
+	OpcodeVecI16x8SubSatUName              = "i16x8.sub_sat_u"
+	OpcodeVecI16x8MulName                  = "i16x8.mul"
+	OpcodeVecI16x8MinSName                 = "i16x8.min_s"
+	OpcodeVecI16x8MinUName                 = "i16x8.min_u"
+	OpcodeVecI16x8MaxSName                 = "i16x8.max_s"
+	OpcodeVecI16x8MaxUName                 = "i16x8.max_u"
+	OpcodeVecI16x8ArgrUName                = "i16x8.argr_u"
+	OpcodeVecI16x8ExtMulLowI8x16SName      = "i16x8.extmul_low_i8x16_s"
+	OpcodeVecI16x8ExtMulHighI8x16SName     = "i16x8.extmul_high_i8x16_s"
+	OpcodeVecI16x8ExtMulLowI8x16UName      = "i16x8.extmul_low_i8x16_u"
+	OpcodeVecI16x8ExtMulHighI8x16UName     = "i16x8.extmul_high_i8x16_u"
+	OpcodeVecI32x4ExtaddPairwiseI16x8SName = "i32x4.extadd_pairwise_i16x8_s"
+	OpcodeVecI32x4ExtaddPairwiseI16x8UName = "i32x4.extadd_pairwise_i16x8_u"
+	OpcodeVecI32x4AbsName                  = "i32x4.abs"
+	OpcodeVecI32x4NegName                  = "i32x4.neg"
+	OpcodeVecI32x4AllTrueName              = "i32x4.all_true"
+	OpcodeVecI32x4BitMaskName              = "i32x4.bitmask"
+	OpcodeVecI32x4ExtendLowI16x8SName      = "i32x4.extend_low_i16x8_s"
+	OpcodeVecI32x4ExtendHighI16x8SName     = "i32x4.extend_high_i16x8_s"
+	OpcodeVecI32x4ExtendLowI16x8UName      = "i32x4.extend_low_i16x8_u"
+	OpcodeVecI32x4ExtendHighI16x8UName     = "i32x4.extend_high_i16x8_u"
+	OpcodeVecI32x4ShlName                  = "i32x4.shl"
+	OpcodeVecI32x4ShrSName                 = "i32x4.shr_s"
+	OpcodeVecI32x4ShrUName                 = "i32x4.shr_u"
+	OpcodeVecI32x4AddName                  = "i32x4.add"
+	OpcodeVecI32x4SubName                  = "i32x4.sub"
+	OpcodeVecI32x4MulName                  = "i32x4.mul"
+	OpcodeVecI32x4MinSName                 = "i32x4.min_s"
+	OpcodeVecI32x4MinUName                 = "i32x4.min_u"
+	OpcodeVecI32x4MaxSName                 = "i32x4.max_s"
+	OpcodeVecI32x4MaxUName                 = "i32x4.max_u"
+	OpcodeVecI32x4DotI16x8SName            = "i32x4.dot_i16x8_s"
+	OpcodeVecI32x4ExtMulLowI16x8SName      = "i32x4.extmul_low_i16x8_s"
+	OpcodeVecI32x4ExtMulHighI16x8SName     = "i32x4.extmul_high_i16x8_s"
+	OpcodeVecI32x4ExtMulLowI16x8UName      = "i32x4.extmul_low_i16x8_u"
+	OpcodeVecI32x4ExtMulHighI16x8UName     = "i32x4.extmul_high_i16x8_u"
+	OpcodeVecI64x2AbsName                  = "i64x2.abs"
+	OpcodeVecI64x2NegName                  = "i64x2.neg"
+	OpcodeVecI64x2AllTrueName              = "i64x2.all_true"
+	OpcodeVecI64x2BitMaskName              = "i64x2.bitmask"
+	OpcodeVecI64x2ExtendLowI32x4SName      = "i64x2.extend_low_i32x4_s"
+	OpcodeVecI64x2ExtendHighI32x4SName     = "i64x2.extend_high_i32x4_s"
+	OpcodeVecI64x2ExtendLowI32x4UName      = "i64x2.extend_low_i32x4_u"
+	OpcodeVecI64x2ExtendHighI32x4UName     = "i64x2.extend_high_i32x4_u"
+	OpcodeVecI64x2ShlName                  = "i64x2.shl"
+	OpcodeVecI64x2ShrSName                 = "i64x2.shr_s"
+	OpcodeVecI64x2ShrUName                 = "i64x2.shr_u"
+	OpcodeVecI64x2AddName                  = "i64x2.add"
+	OpcodeVecI64x2SubName                  = "i64x2.sub"
+	OpcodeVecI64x2MulName                  = "i64x2.mul"
+	OpcodeVecI64x2ExtMulLowI32x4SName      = "i64x2.extmul_low_i32x4_s"
+	OpcodeVecI64x2ExtMulHighI32x4SName     = "i64x2.extmul_high_i32x4_s"
+	OpcodeVecI64x2ExtMulLowI32x4UName      = "i64x2.extmul_low_i32x4_u"
+	OpcodeVecI64x2ExtMulHighI32x4UName     = "i64x2.extmul_high_i32x4_u"
+	OpcodeVecF32x4CeilName                 = "f32x4.ceil"
+	OpcodeVecF32x4FloorName                = "f32x4.floor"
+	OpcodeVecF32x4TruncName                = "f32x4.trunc"
+	OpcodeVecF32x4NearestName              = "f32x4.nearest"
+	OpcodeVecF32x4AbsName                  = "f32x4.abs"
+	OpcodeVecF32x4NegName                  = "f32x4.neg"
+	OpcodeVecF32x4SqrtName                 = "f32x4.sqrt"
+	OpcodeVecF32x4AddName                  = "f32x4.add"
+	OpcodeVecF32x4SubName                  = "f32x4.sub"
+	OpcodeVecF32x4MulName                  = "f32x4.mul"
+	OpcodeVecF32x4DivName                  = "f32x4.div"
+	OpcodeVecF32x4MinName                  = "f32x4.min"
+	OpcodeVecF32x4MaxName                  = "f32x4.max"
+	OpcodeVecF32x4PminName                 = "f32x4.pmin"
+	OpcodeVecF32x4PmaxName                 = "f32x4.pmax"
+	OpcodeVecF64x4CeilName                 = "f64x2.ceil"
+	OpcodeVecF64x4FloorName                = "f64x2.floor"
+	OpcodeVecF64x4TruncName                = "f64x2.trunc"
+	OpcodeVecF64x4NearestName              = "f64x2.nearest"
+	OpcodeVecF64x4AbsName                  = "f64x2.abs"
+	OpcodeVecF64x4NegName                  = "f64x2.neg"
+	OpcodeVecF64x4SqrtName                 = "f64x2.sqrt"
+	OpcodeVecF64x4AddName                  = "f64x2.add"
+	OpcodeVecF64x4SubName                  = "f64x2.sub"
+	OpcodeVecF64x4MulName                  = "f64x2.mul"
+	OpcodeVecF64x4DivName                  = "f64x2.div"
+	OpcodeVecF64x4MinName                  = "f64x2.min"
+	OpcodeVecF64x4MaxName                  = "f64x2.max"
+	OpcodeVecF64x4PminName                 = "f64x2.pmin"
+	OpcodeVecF64x4PmaxName                 = "f64x2.pmax"
+	OpcodeVecI32x4TruncSatF32x4SName       = "i32x4.trunc_sat_f32x4_s"
+	OpcodeVecI32x4TruncSatF32x4UName       = "i32x4.trunc_sat_f32x4_u"
+	OpcodeVecF32x4ConvertI32x4SName        = "f32x4.convert_i32x4_s"
+	OpcodeVecF32x4ConvertI32x4UName        = "f32x4.convert_i32x4_u"
+	OpcodeVecI32x4TruncSatF64x2SZeroName   = "i32x4.trunc_sat_f64x2_s_zero"
+	OpcodeVecI32x4TruncSatF64x2UZeroName   = "i32x4.trunc_sat_f64x2_u_zero"
+	OpcodeVecF64x2ConvertI32x4SName        = "f64x2.convert_low_i32x4_s"
+	OpcodeVecF64x2ConvertI32x4UName        = "f64x2.convert_low_i32x4_u"
+	OpcodeVecF32x4DemoteF64x2ZeroName      = "f32x4.demote_f64x2_zero"
+	OpcodeVecF64x2PromoteLowF32x4ZeroName  = "f64x2.promote_low_f32x4"
+)
+
+var vectorInstructionName = map[OpcodeVec]string{
+	OpcodeVecV128Load:                  OpcodeVecV128LoadName,
+	OpcodeVecV128Load8x8_s:             OpcodeVecV128Load8x8_sName,
+	OpcodeVecV128Load8x8_u:             OpcodeVecV128Load8x8_uName,
+	OpcodeVecV128Load16x4_s:            OpcodeVecV128Load16x4_sName,
+	OpcodeVecV128Load16x4_u:            OpcodeVecV128Load16x4_uName,
+	OpcodeVecV128Load32x2_s:            OpcodeVecV128Load32x2_sName,
+	OpcodeVecV128Load32x2_u:            OpcodeVecV128Load32x2_uName,
+	OpcodeVecV128Load8Splat:            OpcodeVecV128Load8SplatName,
+	OpcodeVecV128Load16Splat:           OpcodeVecV128Load16SplatName,
+	OpcodeVecV128Load32Splat:           OpcodeVecV128Load32SplatName,
+	OpcodeVecV128Load64Splat:           OpcodeVecV128Load64SplatName,
+	OpcodeVecV128Load32zero:            OpcodeVecV128Load32zeroName,
+	OpcodeVecV128Load64zero:            OpcodeVecV128Load64zeroName,
+	OpcodeVecV128Store:                 OpcodeVecV128StoreName,
+	OpcodeVecV128Load8Lane:             OpcodeVecV128Load8LaneName,
+	OpcodeVecV128Load16Lane:            OpcodeVecV128Load16LaneName,
+	OpcodeVecV128Load32Lane:            OpcodeVecV128Load32LaneName,
+	OpcodeVecV128Load64Lane:            OpcodeVecV128Load64LaneName,
+	OpcodeVecV128Store8Lane:            OpcodeVecV128Store8LaneName,
+	OpcodeVecV128Store16Lane:           OpcodeVecV128Store16LaneName,
+	OpcodeVecV128Store32Lane:           OpcodeVecV128Store32LaneName,
+	OpcodeVecV128Store64Lane:           OpcodeVecV128Store64LaneName,
+	OpcodeVecV128Const:                 OpcodeVecV128ConstName,
+	OpcodeVecV128i8x16Shuffle:          OpcodeVecV128i8x16ShuffleName,
+	OpcodeVecI8x16ExtractLaneS:         OpcodeVecI8x16ExtractLaneSName,
+	OpcodeVecI8x16ExtractLaneU:         OpcodeVecI8x16ExtractLaneUName,
+	OpcodeVecI8x16ReplaceLane:          OpcodeVecI8x16ReplaceLaneName,
+	OpcodeVecI16x8ExtractLaneS:         OpcodeVecI16x8ExtractLaneSName,
+	OpcodeVecI16x8ExtractLaneU:         OpcodeVecI16x8ExtractLaneUName,
+	OpcodeVecI16x8ReplaceLane:          OpcodeVecI16x8ReplaceLaneName,
+	OpcodeVecI32x4ExtractLane:          OpcodeVecI32x4ExtractLaneName,
+	OpcodeVecI32x4ReplaceLane:          OpcodeVecI32x4ReplaceLaneName,
+	OpcodeVecI64x2ExtractLane:          OpcodeVecI64x2ExtractLaneName,
+	OpcodeVecI64x2ReplaceLane:          OpcodeVecI64x2ReplaceLaneName,
+	OpcodeVecF32x4ExtractLane:          OpcodeVecF32x4ExtractLaneName,
+	OpcodeVecF32x4ReplaceLane:          OpcodeVecF32x4ReplaceLaneName,
+	OpcodeVecF64x2ExtractLane:          OpcodeVecF64x2ExtractLaneName,
+	OpcodeVecF64x2ReplaceLane:          OpcodeVecF64x2ReplaceLaneName,
+	OpcodeVecI8x16Swizzle:              OpcodeVecI8x16SwizzleName,
+	OpcodeVecI8x16Splat:                OpcodeVecI8x16SplatName,
+	OpcodeVecI16x8Splat:                OpcodeVecI16x8SplatName,
+	OpcodeVecI32x4Splat:                OpcodeVecI32x4SplatName,
+	OpcodeVecI64x2Splat:                OpcodeVecI64x2SplatName,
+	OpcodeVecF32x4Splat:                OpcodeVecF32x4SplatName,
+	OpcodeVecF64x2Splat:                OpcodeVecF64x2SplatName,
+	OpcodeVecI8x16Eq:                   OpcodeVecI8x16EqName,
+	OpcodeVecI8x16Ne:                   OpcodeVecI8x16NeName,
+	OpcodeVecI8x16LtS:                  OpcodeVecI8x16LtSName,
+	OpcodeVecI8x16LtU:                  OpcodeVecI8x16LtUName,
+	OpcodeVecI8x16GtS:                  OpcodeVecI8x16GtSName,
+	OpcodeVecI8x16GtU:                  OpcodeVecI8x16GtUName,
+	OpcodeVecI8x16LeS:                  OpcodeVecI8x16LeSName,
+	OpcodeVecI8x16LeU:                  OpcodeVecI8x16LeUName,
+	OpcodeVecI8x16GeS:                  OpcodeVecI8x16GeSName,
+	OpcodeVecI8x16GeU:                  OpcodeVecI8x16GeUName,
+	OpcodeVecI16x8Eq:                   OpcodeVecI16x8EqName,
+	OpcodeVecI16x8Ne:                   OpcodeVecI16x8NeName,
+	OpcodeVecI16x8LtS:                  OpcodeVecI16x8LtSName,
+	OpcodeVecI16x8LtU:                  OpcodeVecI16x8LtUName,
+	OpcodeVecI16x8GtS:                  OpcodeVecI16x8GtSName,
+	OpcodeVecI16x8GtU:                  OpcodeVecI16x8GtUName,
+	OpcodeVecI16x8LeS:                  OpcodeVecI16x8LeSName,
+	OpcodeVecI16x8LeU:                  OpcodeVecI16x8LeUName,
+	OpcodeVecI16x8GeS:                  OpcodeVecI16x8GeSName,
+	OpcodeVecI16x8GeU:                  OpcodeVecI16x8GeUName,
+	OpcodeVecI32x4Eq:                   OpcodeVecI32x4EqName,
+	OpcodeVecI32x4Ne:                   OpcodeVecI32x4NeName,
+	OpcodeVecI32x4LtS:                  OpcodeVecI32x4LtSName,
+	OpcodeVecI32x4LtU:                  OpcodeVecI32x4LtUName,
+	OpcodeVecI32x4GtS:                  OpcodeVecI32x4GtSName,
+	OpcodeVecI32x4GtU:                  OpcodeVecI32x4GtUName,
+	OpcodeVecI32x4LeS:                  OpcodeVecI32x4LeSName,
+	OpcodeVecI32x4LeU:                  OpcodeVecI32x4LeUName,
+	OpcodeVecI32x4GeS:                  OpcodeVecI32x4GeSName,
+	OpcodeVecI32x4GeU:                  OpcodeVecI32x4GeUName,
+	OpcodeVecI64x2Eq:                   OpcodeVecI64x2EqName,
+	OpcodeVecI64x2Ne:                   OpcodeVecI64x2NeName,
+	OpcodeVecI64x2LtS:                  OpcodeVecI64x2LtSName,
+	OpcodeVecI64x2GtS:                  OpcodeVecI64x2GtSName,
+	OpcodeVecI64x2LeS:                  OpcodeVecI64x2LeSName,
+	OpcodeVecI64x2GeS:                  OpcodeVecI64x2GeSName,
+	OpcodeVecF32x4Eq:                   OpcodeVecF32x4EqName,
+	OpcodeVecF32x4Ne:                   OpcodeVecF32x4NeName,
+	OpcodeVecF32x4Lt:                   OpcodeVecF32x4LtName,
+	OpcodeVecF32x4Gt:                   OpcodeVecF32x4GtName,
+	OpcodeVecF32x4Le:                   OpcodeVecF32x4LeName,
+	OpcodeVecF32x4Ge:                   OpcodeVecF32x4GeName,
+	OpcodeVecF64x2Eq:                   OpcodeVecF64x2EqName,
+	OpcodeVecF64x2Ne:                   OpcodeVecF64x2NeName,
+	OpcodeVecF64x2Lt:                   OpcodeVecF64x2LtName,
+	OpcodeVecF64x2Gt:                   OpcodeVecF64x2GtName,
+	OpcodeVecF64x2Le:                   OpcodeVecF64x2LeName,
+	OpcodeVecF64x2Ge:                   OpcodeVecF64x2GeName,
+	OpcodeVecV128Not:                   OpcodeVecV128NotName,
+	OpcodeVecV128And:                   OpcodeVecV128AndName,
+	OpcodeVecV128AndNot:                OpcodeVecV128AndNotName,
+	OpcodeVecV128Or:                    OpcodeVecV128OrName,
+	OpcodeVecV128Xor:                   OpcodeVecV128XorName,
+	OpcodeVecV128Bitselect:             OpcodeVecV128BitselectName,
+	OpcodeVecV128AnyTrue:               OpcodeVecV128AnyTrueName,
+	OpcodeVecI8x16Abs:                  OpcodeVecI8x16AbsName,
+	OpcodeVecI8x16Neg:                  OpcodeVecI8x16NegName,
+	OpcodeVecI8x16Popcnt:               OpcodeVecI8x16PopcntName,
+	OpcodeVecI8x16AllTrue:              OpcodeVecI8x16AllTrueName,
+	OpcodeVecI8x16BitMask:              OpcodeVecI8x16BitMaskName,
+	OpcodeVecI8x16NarrowI16x8S:         OpcodeVecI8x16NarrowI16x8SName,
+	OpcodeVecI8x16NarrowI16x8U:         OpcodeVecI8x16NarrowI16x8UName,
+	OpcodeVecI8x16Shl:                  OpcodeVecI8x16ShlName,
+	OpcodeVecI8x16ShrS:                 OpcodeVecI8x16ShrSName,
+	OpcodeVecI8x16ShrU:                 OpcodeVecI8x16ShrUName,
+	OpcodeVecI8x16Add:                  OpcodeVecI8x16AddName,
+	OpcodeVecI8x16AddSatS:              OpcodeVecI8x16AddSatSName,
+	OpcodeVecI8x16AddSatU:              OpcodeVecI8x16AddSatUName,
+	OpcodeVecI8x16Sub:                  OpcodeVecI8x16SubName,
+	OpcodeVecI8x16SubSatS:              OpcodeVecI8x16SubSatSName,
+	OpcodeVecI8x16SubSatU:              OpcodeVecI8x16SubSatUName,
+	OpcodeVecI8x16MinS:                 OpcodeVecI8x16MinSName,
+	OpcodeVecI8x16MinU:                 OpcodeVecI8x16MinUName,
+	OpcodeVecI8x16MaxS:                 OpcodeVecI8x16MaxSName,
+	OpcodeVecI8x16MaxU:                 OpcodeVecI8x16MaxUName,
+	OpcodeVecI8x16ArgrU:                OpcodeVecI8x16ArgrUName,
+	OpcodeVecI16x8ExtaddPairwiseI8x16S: OpcodeVecI16x8ExtaddPairwiseI8x16SName,
+	OpcodeVecI16x8ExtaddPairwiseI8x16U: OpcodeVecI16x8ExtaddPairwiseI8x16UName,
+	OpcodeVecI16x8Abs:                  OpcodeVecI16x8AbsName,
+	OpcodeVecI16x8Neg:                  OpcodeVecI16x8NegName,
+	OpcodeVecI16x8Q16mulrSatS:          OpcodeVecI16x8Q16mulrSatSName,
+	OpcodeVecI16x8AllTrue:              OpcodeVecI16x8AllTrueName,
+	OpcodeVecI16x8BitMask:              OpcodeVecI16x8BitMaskName,
+	OpcodeVecI16x8NarrowI32x4S:         OpcodeVecI16x8NarrowI32x4SName,
+	OpcodeVecI16x8NarrowI32x4U:         OpcodeVecI16x8NarrowI32x4UName,
+	OpcodeVecI16x8ExtendLowI8x16S:      OpcodeVecI16x8ExtendLowI8x16SName,
+	OpcodeVecI16x8ExtendHighI8x16S:     OpcodeVecI16x8ExtendHighI8x16SName,
+	OpcodeVecI16x8ExtendLowI8x16U:      OpcodeVecI16x8ExtendLowI8x16UName,
+	OpcodeVecI16x8ExtendHighI8x16U:     OpcodeVecI16x8ExtendHighI8x16UName,
+	OpcodeVecI16x8Shl:                  OpcodeVecI16x8ShlName,
+	OpcodeVecI16x8ShrS:                 OpcodeVecI16x8ShrSName,
+	OpcodeVecI16x8ShrU:                 OpcodeVecI16x8ShrUName,
+	OpcodeVecI16x8Add:                  OpcodeVecI16x8AddName,
+	OpcodeVecI16x8AddSatS:              OpcodeVecI16x8AddSatSName,
+	OpcodeVecI16x8AddSatU:              OpcodeVecI16x8AddSatUName,
+	OpcodeVecI16x8Sub:                  OpcodeVecI16x8SubName,
+	OpcodeVecI16x8SubSatS:              OpcodeVecI16x8SubSatSName,
+	OpcodeVecI16x8SubSatU:              OpcodeVecI16x8SubSatUName,
+	OpcodeVecI16x8Mul:                  OpcodeVecI16x8MulName,
+	OpcodeVecI16x8MinS:                 OpcodeVecI16x8MinSName,
+	OpcodeVecI16x8MinU:                 OpcodeVecI16x8MinUName,
+	OpcodeVecI16x8MaxS:                 OpcodeVecI16x8MaxSName,
+	OpcodeVecI16x8MaxU:                 OpcodeVecI16x8MaxUName,
+	OpcodeVecI16x8ArgrU:                OpcodeVecI16x8ArgrUName,
+	OpcodeVecI16x8ExtMulLowI8x16S:      OpcodeVecI16x8ExtMulLowI8x16SName,
+	OpcodeVecI16x8ExtMulHighI8x16S:     OpcodeVecI16x8ExtMulHighI8x16SName,
+	OpcodeVecI16x8ExtMulLowI8x16U:      OpcodeVecI16x8ExtMulLowI8x16UName,
+	OpcodeVecI16x8ExtMulHighI8x16U:     OpcodeVecI16x8ExtMulHighI8x16UName,
+	OpcodeVecI32x4ExtaddPairwiseI16x8S: OpcodeVecI32x4ExtaddPairwiseI16x8SName,
+	OpcodeVecI32x4ExtaddPairwiseI16x8U: OpcodeVecI32x4ExtaddPairwiseI16x8UName,
+	OpcodeVecI32x4Abs:                  OpcodeVecI32x4AbsName,
+	OpcodeVecI32x4Neg:                  OpcodeVecI32x4NegName,
+	OpcodeVecI32x4AllTrue:              OpcodeVecI32x4AllTrueName,
+	OpcodeVecI32x4BitMask:              OpcodeVecI32x4BitMaskName,
+	OpcodeVecI32x4ExtendLowI16x8S:      OpcodeVecI32x4ExtendLowI16x8SName,
+	OpcodeVecI32x4ExtendHighI16x8S:     OpcodeVecI32x4ExtendHighI16x8SName,
+	OpcodeVecI32x4ExtendLowI16x8U:      OpcodeVecI32x4ExtendLowI16x8UName,
+	OpcodeVecI32x4ExtendHighI16x8U:     OpcodeVecI32x4ExtendHighI16x8UName,
+	OpcodeVecI32x4Shl:                  OpcodeVecI32x4ShlName,
+	OpcodeVecI32x4ShrS:                 OpcodeVecI32x4ShrSName,
+	OpcodeVecI32x4ShrU:                 OpcodeVecI32x4ShrUName,
+	OpcodeVecI32x4Add:                  OpcodeVecI32x4AddName,
+	OpcodeVecI32x4Sub:                  OpcodeVecI32x4SubName,
+	OpcodeVecI32x4Mul:                  OpcodeVecI32x4MulName,
+	OpcodeVecI32x4MinS:                 OpcodeVecI32x4MinSName,
+	OpcodeVecI32x4MinU:                 OpcodeVecI32x4MinUName,
+	OpcodeVecI32x4MaxS:                 OpcodeVecI32x4MaxSName,
+	OpcodeVecI32x4MaxU:                 OpcodeVecI32x4MaxUName,
+	OpcodeVecI32x4DotI16x8S:            OpcodeVecI32x4DotI16x8SName,
+	OpcodeVecI32x4ExtMulLowI16x8S:      OpcodeVecI32x4ExtMulLowI16x8SName,
+	OpcodeVecI32x4ExtMulHighI16x8S:     OpcodeVecI32x4ExtMulHighI16x8SName,
+	OpcodeVecI32x4ExtMulLowI16x8U:      OpcodeVecI32x4ExtMulLowI16x8UName,
+	OpcodeVecI32x4ExtMulHighI16x8U:     OpcodeVecI32x4ExtMulHighI16x8UName,
+	OpcodeVecI64x2Abs:                  OpcodeVecI64x2AbsName,
+	OpcodeVecI64x2Neg:                  OpcodeVecI64x2NegName,
+	OpcodeVecI64x2AllTrue:              OpcodeVecI64x2AllTrueName,
+	OpcodeVecI64x2BitMask:              OpcodeVecI64x2BitMaskName,
+	OpcodeVecI64x2ExtendLowI32x4S:      OpcodeVecI64x2ExtendLowI32x4SName,
+	OpcodeVecI64x2ExtendHighI32x4S:     OpcodeVecI64x2ExtendHighI32x4SName,
+	OpcodeVecI64x2ExtendLowI32x4U:      OpcodeVecI64x2ExtendLowI32x4UName,
+	OpcodeVecI64x2ExtendHighI32x4U:     OpcodeVecI64x2ExtendHighI32x4UName,
+	OpcodeVecI64x2Shl:                  OpcodeVecI64x2ShlName,
+	OpcodeVecI64x2ShrS:                 OpcodeVecI64x2ShrSName,
+	OpcodeVecI64x2ShrU:                 OpcodeVecI64x2ShrUName,
+	OpcodeVecI64x2Add:                  OpcodeVecI64x2AddName,
+	OpcodeVecI64x2Sub:                  OpcodeVecI64x2SubName,
+	OpcodeVecI64x2Mul:                  OpcodeVecI64x2MulName,
+	OpcodeVecI64x2ExtMulLowI32x4S:      OpcodeVecI64x2ExtMulLowI32x4SName,
+	OpcodeVecI64x2ExtMulHighI32x4S:     OpcodeVecI64x2ExtMulHighI32x4SName,
+	OpcodeVecI64x2ExtMulLowI32x4U:      OpcodeVecI64x2ExtMulLowI32x4UName,
+	OpcodeVecI64x2ExtMulHighI32x4U:     OpcodeVecI64x2ExtMulHighI32x4UName,
+	OpcodeVecF32x4Ceil:                 OpcodeVecF32x4CeilName,
+	OpcodeVecF32x4Floor:                OpcodeVecF32x4FloorName,
+	OpcodeVecF32x4Trunc:                OpcodeVecF32x4TruncName,
+	OpcodeVecF32x4Nearest:              OpcodeVecF32x4NearestName,
+	OpcodeVecF32x4Abs:                  OpcodeVecF32x4AbsName,
+	OpcodeVecF32x4Neg:                  OpcodeVecF32x4NegName,
+	OpcodeVecF32x4Sqrt:                 OpcodeVecF32x4SqrtName,
+	OpcodeVecF32x4Add:                  OpcodeVecF32x4AddName,
+	OpcodeVecF32x4Sub:                  OpcodeVecF32x4SubName,
+	OpcodeVecF32x4Mul:                  OpcodeVecF32x4MulName,
+	OpcodeVecF32x4Div:                  OpcodeVecF32x4DivName,
+	OpcodeVecF32x4Min:                  OpcodeVecF32x4MinName,
+	OpcodeVecF32x4Max:                  OpcodeVecF32x4MaxName,
+	OpcodeVecF32x4Pmin:                 OpcodeVecF32x4PminName,
+	OpcodeVecF32x4Pmax:                 OpcodeVecF32x4PmaxName,
+	OpcodeVecF64x4Ceil:                 OpcodeVecF64x4CeilName,
+	OpcodeVecF64x4Floor:                OpcodeVecF64x4FloorName,
+	OpcodeVecF64x4Trunc:                OpcodeVecF64x4TruncName,
+	OpcodeVecF64x4Nearest:              OpcodeVecF64x4NearestName,
+	OpcodeVecF64x4Abs:                  OpcodeVecF64x4AbsName,
+	OpcodeVecF64x4Neg:                  OpcodeVecF64x4NegName,
+	OpcodeVecF64x4Sqrt:                 OpcodeVecF64x4SqrtName,
+	OpcodeVecF64x4Add:                  OpcodeVecF64x4AddName,
+	OpcodeVecF64x4Sub:                  OpcodeVecF64x4SubName,
+	OpcodeVecF64x4Mul:                  OpcodeVecF64x4MulName,
+	OpcodeVecF64x4Div:                  OpcodeVecF64x4DivName,
+	OpcodeVecF64x4Min:                  OpcodeVecF64x4MinName,
+	OpcodeVecF64x4Max:                  OpcodeVecF64x4MaxName,
+	OpcodeVecF64x4Pmin:                 OpcodeVecF64x4PminName,
+	OpcodeVecF64x4Pmax:                 OpcodeVecF64x4PmaxName,
+	OpcodeVecI32x4TruncSatF32x4S:       OpcodeVecI32x4TruncSatF32x4SName,
+	OpcodeVecI32x4TruncSatF32x4U:       OpcodeVecI32x4TruncSatF32x4UName,
+	OpcodeVecF32x4ConvertI32x4S:        OpcodeVecF32x4ConvertI32x4SName,
+	OpcodeVecF32x4ConvertI32x4U:        OpcodeVecF32x4ConvertI32x4UName,
+	OpcodeVecI32x4TruncSatF64x2SZero:   OpcodeVecI32x4TruncSatF64x2SZeroName,
+	OpcodeVecI32x4TruncSatF64x2UZero:   OpcodeVecI32x4TruncSatF64x2UZeroName,
+	OpcodeVecF64x2ConvertI32x4S:        OpcodeVecF64x2ConvertI32x4SName,
+	OpcodeVecF64x2ConvertI32x4U:        OpcodeVecF64x2ConvertI32x4UName,
+	OpcodeVecF32x4DemoteF64x2Zero:      OpcodeVecF32x4DemoteF64x2ZeroName,
+	OpcodeVecF64x2PromoteLowF32x4Zero:  OpcodeVecF64x2PromoteLowF32x4ZeroName,
+}
+
+// VectorInstreuctionName returns the instruction name corresponding to the vector Opcode.
+func VectorInstreuctionName(oc OpcodeVec) (ret string) {
+	return vectorInstructionName[oc]
+}


Test patch:
diff --git a/config_test.go b/config_test.go
index f50557d3..9fd4541f 100644
--- a/config_test.go
+++ b/config_test.go
@@ -91,6 +91,15 @@ func TestRuntimeConfig(t *testing.T) {
 				enabledFeatures: wasm.FeatureBulkMemoryOperations | wasm.FeatureReferenceTypes,
 			},
 		},
+		{
+			name: "simd",
+			with: func(c RuntimeConfig) RuntimeConfig {
+				return c.WithFeatureSIMD(true)
+			},
+			expected: &runtimeConfig{
+				enabledFeatures: wasm.FeatureSIMD,
+			},
+		},
 	}
 	for _, tt := range tests {
 		tc := tt
diff --git a/internal/wasm/features_test.go b/internal/wasm/features_test.go
index 11d1b358..59dd7211 100644
--- a/internal/wasm/features_test.go
+++ b/internal/wasm/features_test.go
@@ -60,9 +60,12 @@ func TestFeatures_String(t *testing.T) {
 		{name: "mutable-global", feature: FeatureMutableGlobal, expected: "mutable-global"},
 		{name: "sign-extension-ops", feature: FeatureSignExtensionOps, expected: "sign-extension-ops"},
 		{name: "multi-value", feature: FeatureMultiValue, expected: "multi-value"},
+		{name: "simd", feature: FeatureSIMD, expected: "simd"},
 		{name: "features", feature: FeatureMutableGlobal | FeatureMultiValue, expected: "multi-value|mutable-global"},
 		{name: "undefined", feature: 1 << 63, expected: ""},
-		{name: "2.0", feature: Features20220419, expected: "bulk-memory-operations|multi-value|mutable-global|nontrapping-float-to-int-conversion|reference-types|sign-extension-ops"},
+		{name: "2.0", feature: Features20220419,
+			expected: "bulk-memory-operations|multi-value|mutable-global|" +
+				"nontrapping-float-to-int-conversion|reference-types|sign-extension-ops|simd"},
 	}
 
 	for _, tt := range tests {
diff --git a/internal/wasm/func_validation_test.go b/internal/wasm/func_validation_test.go
index 9f4cf4be..0b81160b 100644
--- a/internal/wasm/func_validation_test.go
+++ b/internal/wasm/func_validation_test.go
@@ -2654,3 +2654,43 @@ func TestModule_funcValidation_Select_error(t *testing.T) {
 		})
 	}
 }
+
+func TestModule_funcValidation_SIMD_error(t *testing.T) {
+	for _, tc := range []struct {
+		name        string
+		body        []byte
+		flag        Features
+		expectedErr string
+	}{
+		{
+			name: "simd disabled",
+			body: []byte{
+				OpcodeVecPrefix,
+				OpcodeVecF32x4Abs,
+			},
+			flag:        Features20191205,
+			expectedErr: "f32x4.abs invalid as feature \"simd\" is disabled",
+		},
+		{
+			// TODO delete this case after SIMD impl completion.
+			name: "unimplemented",
+			body: []byte{
+				OpcodeVecPrefix,
+				OpcodeVecF32x4DemoteF64x2Zero,
+			},
+			flag:        FeatureSIMD,
+			expectedErr: "TODO: SIMD instruction f32x4.demote_f64x2_zero will be implemented in #506",
+		},
+	} {
+		tc := tc
+		t.Run(tc.name, func(t *testing.T) {
+			m := &Module{
+				TypeSection:     []*FunctionType{v_v},
+				FunctionSection: []Index{0},
+				CodeSection:     []*Code{{Body: tc.body}},
+			}
+			err := m.validateFunction(tc.flag, 0, []Index{0}, nil, nil, nil, nil)
+			require.EqualError(t, err, tc.expectedErr)
+		})
+	}
+}