[jit] Disable the optimization added by 63eb94e451a59491034516f2ec9f27d586b34d86...
[mono.git] / mono / mini / simd-intrinsics.c
index ae9bfa2a4aef6da14b9ffb7af958593c3f6a2b78..ff737bbe9347a7b0f5d2fce3e44832386bd9c356 100644 (file)
@@ -12,6 +12,7 @@
 
 #include "mini.h"
 #include "ir-emit.h"
+#include "mono/utils/bsearch.h"
 
 /*
 General notes on SIMD intrinsics
@@ -121,392 +122,403 @@ enum {
 typedef struct {
        guint16 name;
        guint16 opcode;
+       guint8 simd_version_flags;
        guint8 simd_emit_mode : 4;
-       guint8 simd_version : 4;
-       guint8 flags;
+       guint8 flags : 4;
 } SimdIntrinsc;
 
 static const SimdIntrinsc vector4f_intrinsics[] = {
-       { SN_ctor, OP_EXPAND_R4, SIMD_EMIT_CTOR },
-       { SN_AddSub, OP_ADDSUBPS, SIMD_EMIT_BINARY, SIMD_VERSION_SSE3 },
-       { SN_AndNot, OP_ANDNPS, SIMD_EMIT_BINARY },
-       { SN_CompareEqual, OP_COMPPS, SIMD_EMIT_BINARY, SIMD_VERSION_SSE1, SIMD_COMP_EQ },
-       { SN_CompareLessEqual, OP_COMPPS, SIMD_EMIT_BINARY, SIMD_VERSION_SSE1, SIMD_COMP_LE },
-       { SN_CompareLessThan, OP_COMPPS, SIMD_EMIT_BINARY, SIMD_VERSION_SSE1, SIMD_COMP_LT },
-       { SN_CompareNotEqual, OP_COMPPS, SIMD_EMIT_BINARY, SIMD_VERSION_SSE1, SIMD_COMP_NEQ },
-       { SN_CompareNotLessEqual, OP_COMPPS, SIMD_EMIT_BINARY, SIMD_VERSION_SSE1, SIMD_COMP_NLE },
-       { SN_CompareNotLessThan, OP_COMPPS, SIMD_EMIT_BINARY, SIMD_VERSION_SSE1, SIMD_COMP_NLT },
-       { SN_CompareOrdered, OP_COMPPS, SIMD_EMIT_BINARY, SIMD_VERSION_SSE1, SIMD_COMP_ORD },
-       { SN_CompareUnordered, OP_COMPPS, SIMD_EMIT_BINARY, SIMD_VERSION_SSE1, SIMD_COMP_UNORD },
-       { SN_DuplicateHigh, OP_DUPPS_HIGH, SIMD_EMIT_UNARY, SIMD_VERSION_SSE3 },
-       { SN_DuplicateLow, OP_DUPPS_LOW, SIMD_EMIT_UNARY, SIMD_VERSION_SSE3 },
-       { SN_HorizontalAdd, OP_HADDPS, SIMD_EMIT_BINARY, SIMD_VERSION_SSE3 },
-       { SN_HorizontalSub, OP_HSUBPS, SIMD_EMIT_BINARY, SIMD_VERSION_SSE3 },   
-       { SN_InterleaveHigh, OP_UNPACK_HIGHPS, SIMD_EMIT_BINARY },
-       { SN_InterleaveLow, OP_UNPACK_LOWPS, SIMD_EMIT_BINARY },
-       { SN_InvSqrt, OP_RSQRTPS, SIMD_EMIT_UNARY },
-       { SN_LoadAligned, 0, SIMD_EMIT_LOAD_ALIGNED },
-       { SN_Max, OP_MAXPS, SIMD_EMIT_BINARY },
-       { SN_Min, OP_MINPS, SIMD_EMIT_BINARY },
-       { SN_PrefetchTemporalAllCacheLevels, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_0 },
-       { SN_PrefetchTemporal1stLevelCache, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_1 },
-       { SN_PrefetchTemporal2ndLevelCache, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_2 },
-       { SN_PrefetchNonTemporal, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_NTA },
-       { SN_Reciprocal, OP_RCPPS, SIMD_EMIT_UNARY },
-       { SN_Shuffle, OP_PSHUFLED, SIMD_EMIT_SHUFFLE },
-       { SN_Sqrt, OP_SQRTPS, SIMD_EMIT_UNARY },
-       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, SIMD_EMIT_STORE },
-       { SN_StoreNonTemporal, OP_STOREX_NTA_MEMBASE_REG, SIMD_EMIT_STORE },
-       { SN_get_W, 3, SIMD_EMIT_GETTER },
-       { SN_get_X, 0, SIMD_EMIT_GETTER },
-       { SN_get_Y, 1, SIMD_EMIT_GETTER },
-       { SN_get_Z, 2, SIMD_EMIT_GETTER },
-       { SN_op_Addition, OP_ADDPS, SIMD_EMIT_BINARY },
-       { SN_op_BitwiseAnd, OP_ANDPS, SIMD_EMIT_BINARY },
-       { SN_op_BitwiseOr, OP_ORPS, SIMD_EMIT_BINARY },
-       { SN_op_Division, OP_DIVPS, SIMD_EMIT_BINARY },
-       { SN_op_Equality, OP_COMPPS, SIMD_EMIT_EQUALITY, SIMD_VERSION_SSE1, SIMD_COMP_EQ },
-       { SN_op_ExclusiveOr, OP_XORPS, SIMD_EMIT_BINARY },
-       { SN_op_Explicit, 0, SIMD_EMIT_CAST }, 
-       { SN_op_Inequality, OP_COMPPS, SIMD_EMIT_EQUALITY, SIMD_VERSION_SSE1, SIMD_COMP_NEQ },
-       { SN_op_Multiply, OP_MULPS, SIMD_EMIT_BINARY },
-       { SN_op_Subtraction, OP_SUBPS, SIMD_EMIT_BINARY },
-       { SN_set_W, 3, SIMD_EMIT_SETTER },
-       { SN_set_X, 0, SIMD_EMIT_SETTER },
-       { SN_set_Y, 1, SIMD_EMIT_SETTER },
-       { SN_set_Z, 2, SIMD_EMIT_SETTER },
+       { SN_ctor, OP_EXPAND_R4, SIMD_VERSION_SSE1, SIMD_EMIT_CTOR },
+       { SN_AddSub, OP_ADDSUBPS, SIMD_VERSION_SSE3, SIMD_EMIT_BINARY},
+       { SN_AndNot, OP_ANDNPS, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY},
+       { SN_CompareEqual, OP_COMPPS, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY, SIMD_COMP_EQ },
+       { SN_CompareLessEqual, OP_COMPPS, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY, SIMD_COMP_LE },
+       { SN_CompareLessThan, OP_COMPPS, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY, SIMD_COMP_LT },
+       { SN_CompareNotEqual, OP_COMPPS, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY, SIMD_COMP_NEQ },
+       { SN_CompareNotLessEqual, OP_COMPPS, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY, SIMD_COMP_NLE },
+       { SN_CompareNotLessThan, OP_COMPPS, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY, SIMD_COMP_NLT },
+       { SN_CompareOrdered, OP_COMPPS, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY, SIMD_COMP_ORD },
+       { SN_CompareUnordered, OP_COMPPS, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY, SIMD_COMP_UNORD },
+       { SN_ConvertToDouble, OP_CVTPS2PD, SIMD_VERSION_SSE2, SIMD_EMIT_UNARY },
+       { SN_ConvertToInt, OP_CVTPS2DQ, SIMD_VERSION_SSE2, SIMD_EMIT_UNARY },
+       { SN_ConvertToIntTruncated, OP_CVTTPS2DQ, SIMD_VERSION_SSE2, SIMD_EMIT_UNARY },
+       { SN_DuplicateHigh, OP_DUPPS_HIGH, SIMD_VERSION_SSE3, SIMD_EMIT_UNARY },
+       { SN_DuplicateLow, OP_DUPPS_LOW, SIMD_VERSION_SSE3, SIMD_EMIT_UNARY },
+       { SN_HorizontalAdd, OP_HADDPS, SIMD_VERSION_SSE3, SIMD_EMIT_BINARY },
+       { SN_HorizontalSub, OP_HSUBPS, SIMD_VERSION_SSE3, SIMD_EMIT_BINARY },   
+       { SN_InterleaveHigh, OP_UNPACK_HIGHPS, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_InterleaveLow, OP_UNPACK_LOWPS, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_InvSqrt, OP_RSQRTPS, SIMD_VERSION_SSE1, SIMD_EMIT_UNARY },
+       { SN_LoadAligned, 0, SIMD_VERSION_SSE1, SIMD_EMIT_LOAD_ALIGNED },
+       { SN_Max, OP_MAXPS, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_Min, OP_MINPS, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_PrefetchTemporalAllCacheLevels, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_0 },
+       { SN_PrefetchTemporal1stLevelCache, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_1 },
+       { SN_PrefetchTemporal2ndLevelCache, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_2 },
+       { SN_PrefetchNonTemporal, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_NTA },
+       { SN_Reciprocal, OP_RCPPS, SIMD_VERSION_SSE1, SIMD_EMIT_UNARY },
+       { SN_Shuffle, OP_PSHUFLED, SIMD_VERSION_SSE1, SIMD_EMIT_SHUFFLE },
+       { SN_Sqrt, OP_SQRTPS, SIMD_VERSION_SSE1, SIMD_EMIT_UNARY },
+       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, SIMD_VERSION_SSE1, SIMD_EMIT_STORE },
+       { SN_StoreNonTemporal, OP_STOREX_NTA_MEMBASE_REG, SIMD_VERSION_SSE1, SIMD_EMIT_STORE },
+       { SN_get_W, 3, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_X, 0, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_Y, 1, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_Z, 2, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_op_Addition, OP_ADDPS, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseAnd, OP_ANDPS, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseOr, OP_ORPS, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_Division, OP_DIVPS, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_Equality, OP_COMPPS, SIMD_VERSION_SSE1, SIMD_EMIT_EQUALITY, SIMD_COMP_EQ },
+       { SN_op_ExclusiveOr, OP_XORPS, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_Explicit, 0, SIMD_VERSION_SSE1, SIMD_EMIT_CAST }, 
+       { SN_op_Inequality, OP_COMPPS, SIMD_VERSION_SSE1, SIMD_EMIT_EQUALITY, SIMD_COMP_NEQ },
+       { SN_op_Multiply, OP_MULPS, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_Subtraction, OP_SUBPS, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_set_W, 3, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_X, 0, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_Y, 1, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_Z, 2, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER }
 };
 
 static const SimdIntrinsc vector2d_intrinsics[] = {
-       { SN_ctor, OP_EXPAND_R8, SIMD_EMIT_CTOR },
-       { SN_AddSub, OP_ADDSUBPD, SIMD_EMIT_BINARY, SIMD_VERSION_SSE3 },
-       { SN_AndNot, OP_ANDNPD, SIMD_EMIT_BINARY },
-       { SN_CompareEqual, OP_COMPPD, SIMD_EMIT_BINARY, SIMD_VERSION_SSE1, SIMD_COMP_EQ },
-       { SN_CompareLessEqual, OP_COMPPD, SIMD_EMIT_BINARY, SIMD_VERSION_SSE1, SIMD_COMP_LE },
-       { SN_CompareLessThan, OP_COMPPD, SIMD_EMIT_BINARY, SIMD_VERSION_SSE1, SIMD_COMP_LT },
-       { SN_CompareNotEqual, OP_COMPPD, SIMD_EMIT_BINARY, SIMD_VERSION_SSE1, SIMD_COMP_NEQ },
-       { SN_CompareNotLessEqual, OP_COMPPD, SIMD_EMIT_BINARY, SIMD_VERSION_SSE1, SIMD_COMP_NLE },
-       { SN_CompareNotLessThan, OP_COMPPD, SIMD_EMIT_BINARY, SIMD_VERSION_SSE1, SIMD_COMP_NLT },
-       { SN_CompareOrdered, OP_COMPPD, SIMD_EMIT_BINARY, SIMD_VERSION_SSE1, SIMD_COMP_ORD },
-       { SN_CompareUnordered, OP_COMPPD, SIMD_EMIT_BINARY, SIMD_VERSION_SSE1, SIMD_COMP_UNORD },
-       { SN_Duplicate, OP_DUPPD, SIMD_EMIT_UNARY, SIMD_VERSION_SSE3 },
-       { SN_HorizontalAdd, OP_HADDPD, SIMD_EMIT_BINARY, SIMD_VERSION_SSE3 },
-       { SN_HorizontalSub, OP_HSUBPD, SIMD_EMIT_BINARY, SIMD_VERSION_SSE3 },   
-       { SN_InterleaveHigh, OP_UNPACK_HIGHPD, SIMD_EMIT_BINARY },
-       { SN_InterleaveLow, OP_UNPACK_LOWPD, SIMD_EMIT_BINARY },
-       { SN_LoadAligned, 0, SIMD_EMIT_LOAD_ALIGNED },
-       { SN_Max, OP_MAXPD, SIMD_EMIT_BINARY },
-       { SN_Min, OP_MINPD, SIMD_EMIT_BINARY },
-       { SN_PrefetchTemporalAllCacheLevels, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_0 },
-       { SN_PrefetchTemporal1stLevelCache, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_1 },
-       { SN_PrefetchTemporal2ndLevelCache, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_2 },
-       { SN_PrefetchNonTemporal, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_NTA },
-       { SN_Sqrt, OP_SQRTPD, SIMD_EMIT_UNARY },
-       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, SIMD_EMIT_STORE },
-       { SN_get_X, 0, SIMD_EMIT_GETTER_QWORD },
-       { SN_get_Y, 1, SIMD_EMIT_GETTER_QWORD },
-       { SN_op_Addition, OP_ADDPD, SIMD_EMIT_BINARY },
-       { SN_op_BitwiseAnd, OP_ANDPD, SIMD_EMIT_BINARY },
-       { SN_op_BitwiseOr, OP_ORPD, SIMD_EMIT_BINARY },
-       { SN_op_Division, OP_DIVPD, SIMD_EMIT_BINARY },
-       { SN_op_ExclusiveOr, OP_XORPD, SIMD_EMIT_BINARY },
-       { SN_op_Explicit, 0, SIMD_EMIT_CAST }, 
-       { SN_op_Multiply, OP_MULPD, SIMD_EMIT_BINARY },
-       { SN_op_Subtraction, OP_SUBPD, SIMD_EMIT_BINARY },
-       { SN_set_X, 0, SIMD_EMIT_SETTER },
-       { SN_set_Y, 1, SIMD_EMIT_SETTER },
+       { SN_ctor, OP_EXPAND_R8, SIMD_VERSION_SSE1, SIMD_EMIT_CTOR },
+       { SN_AddSub, OP_ADDSUBPD, SIMD_VERSION_SSE3, SIMD_EMIT_BINARY,},
+       { SN_AndNot, OP_ANDNPD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_CompareEqual, OP_COMPPD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY, SIMD_COMP_EQ },
+       { SN_CompareLessEqual, OP_COMPPD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY, SIMD_COMP_LE },
+       { SN_CompareLessThan, OP_COMPPD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY, SIMD_COMP_LT },
+       { SN_CompareNotEqual, OP_COMPPD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY, SIMD_COMP_NEQ },
+       { SN_CompareNotLessEqual, OP_COMPPD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY, SIMD_COMP_NLE },
+       { SN_CompareNotLessThan, OP_COMPPD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY, SIMD_COMP_NLT },
+       { SN_CompareOrdered, OP_COMPPD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY, SIMD_COMP_ORD },
+       { SN_CompareUnordered, OP_COMPPD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY, SIMD_COMP_UNORD },
+       { SN_ConvertToFloat, OP_CVTPD2PS, SIMD_VERSION_SSE2, SIMD_EMIT_UNARY },
+       { SN_ConvertToInt, OP_CVTPD2DQ, SIMD_VERSION_SSE2, SIMD_EMIT_UNARY },
+       { SN_ConvertToIntTruncated, OP_CVTTPD2DQ, SIMD_VERSION_SSE2, SIMD_EMIT_UNARY },
+       { SN_Duplicate, OP_DUPPD, SIMD_VERSION_SSE3, SIMD_EMIT_UNARY },
+       { SN_HorizontalAdd, OP_HADDPD, SIMD_VERSION_SSE3, SIMD_EMIT_BINARY },
+       { SN_HorizontalSub, OP_HSUBPD, SIMD_VERSION_SSE3, SIMD_EMIT_BINARY },   
+       { SN_InterleaveHigh, OP_UNPACK_HIGHPD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_InterleaveLow, OP_UNPACK_LOWPD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_LoadAligned, 0, SIMD_VERSION_SSE1, SIMD_EMIT_LOAD_ALIGNED },
+       { SN_Max, OP_MAXPD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_Min, OP_MINPD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_PrefetchTemporalAllCacheLevels, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_0 },
+       { SN_PrefetchTemporal1stLevelCache, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_1 },
+       { SN_PrefetchTemporal2ndLevelCache, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_2 },
+       { SN_PrefetchNonTemporal, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_NTA },
+       { SN_Shuffle, OP_SHUFPD, SIMD_VERSION_SSE1, SIMD_EMIT_SHUFFLE },
+       { SN_Sqrt, OP_SQRTPD, SIMD_VERSION_SSE1, SIMD_EMIT_UNARY },
+       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, SIMD_VERSION_SSE1, SIMD_EMIT_STORE },
+       { SN_get_X, 0, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER_QWORD },
+       { SN_get_Y, 1, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER_QWORD },
+       { SN_op_Addition, OP_ADDPD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseAnd, OP_ANDPD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseOr, OP_ORPD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_Division, OP_DIVPD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_ExclusiveOr, OP_XORPD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_Explicit, 0, SIMD_VERSION_SSE1, SIMD_EMIT_CAST }, 
+       { SN_op_Multiply, OP_MULPD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_Subtraction, OP_SUBPD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_set_X, 0, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_Y, 1, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
 };
 
 static const SimdIntrinsc vector2ul_intrinsics[] = {
-       { SN_ctor, OP_EXPAND_I8, SIMD_EMIT_CTOR },
-       { SN_CompareEqual, OP_PCMPEQQ, SIMD_EMIT_BINARY, SIMD_VERSION_SSE41 },
-       { SN_LoadAligned, 0, SIMD_EMIT_LOAD_ALIGNED },
-       { SN_PrefetchTemporalAllCacheLevels, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_0 },
-       { SN_PrefetchTemporal1stLevelCache, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_1 },
-       { SN_PrefetchTemporal2ndLevelCache, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_2 },
-       { SN_PrefetchNonTemporal, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_NTA },
-       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, SIMD_EMIT_STORE },
-       { SN_UnpackHigh, OP_UNPACK_HIGHQ, SIMD_EMIT_BINARY },
-       { SN_UnpackLow, OP_UNPACK_LOWQ, SIMD_EMIT_BINARY },
-       { SN_get_X, 0, SIMD_EMIT_GETTER_QWORD },
-       { SN_get_Y, 1, SIMD_EMIT_GETTER_QWORD },
-       { SN_op_Addition, OP_PADDQ, SIMD_EMIT_BINARY },
-       { SN_op_BitwiseAnd, OP_PAND, SIMD_EMIT_BINARY },
-       { SN_op_BitwiseOr, OP_POR, SIMD_EMIT_BINARY },
-       { SN_op_ExclusiveOr, OP_PXOR, SIMD_EMIT_BINARY },
-       { SN_op_Explicit, 0, SIMD_EMIT_CAST },
-       { SN_op_LeftShift, OP_PSHLQ, SIMD_EMIT_SHIFT },
-       { SN_op_Multiply, OP_PMULQ, SIMD_EMIT_BINARY },
-       { SN_op_RightShift, OP_PSHRQ, SIMD_EMIT_SHIFT },
-       { SN_op_Subtraction, OP_PSUBQ, SIMD_EMIT_BINARY },
-       { SN_set_X, 0, SIMD_EMIT_SETTER },
-       { SN_set_Y, 1, SIMD_EMIT_SETTER },
+       { SN_ctor, OP_EXPAND_I8, SIMD_VERSION_SSE1, SIMD_EMIT_CTOR },
+       { SN_CompareEqual, OP_PCMPEQQ, SIMD_VERSION_SSE41, SIMD_EMIT_BINARY },
+       { SN_LoadAligned, 0, SIMD_VERSION_SSE1, SIMD_EMIT_LOAD_ALIGNED },
+       { SN_PrefetchTemporalAllCacheLevels, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_0 },
+       { SN_PrefetchTemporal1stLevelCache, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_1 },
+       { SN_PrefetchTemporal2ndLevelCache, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_2 },
+       { SN_PrefetchNonTemporal, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_NTA },
+       { SN_Shuffle, OP_SHUFPD, SIMD_VERSION_SSE1, SIMD_EMIT_SHUFFLE },
+       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, SIMD_VERSION_SSE1, SIMD_EMIT_STORE },
+       { SN_UnpackHigh, OP_UNPACK_HIGHQ, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_UnpackLow, OP_UNPACK_LOWQ, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_get_X, 0, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER_QWORD },
+       { SN_get_Y, 1, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER_QWORD },
+       { SN_op_Addition, OP_PADDQ, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseAnd, OP_PAND, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseOr, OP_POR, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_ExclusiveOr, OP_PXOR, SIMD_EMIT_BINARY, SIMD_VERSION_SSE1 },
+       { SN_op_Explicit, 0, SIMD_VERSION_SSE1, SIMD_EMIT_CAST },
+       { SN_op_LeftShift, OP_PSHLQ, SIMD_VERSION_SSE1, SIMD_EMIT_SHIFT },
+       { SN_op_Multiply, OP_PMULQ, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_RightShift, OP_PSHRQ, SIMD_VERSION_SSE1, SIMD_EMIT_SHIFT },
+       { SN_op_Subtraction, OP_PSUBQ, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_set_X, 0, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_Y, 1, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
 };
 
 static const SimdIntrinsc vector2l_intrinsics[] = {
-       { SN_ctor, OP_EXPAND_I8, SIMD_EMIT_CTOR },
-       { SN_CompareEqual, OP_PCMPEQQ, SIMD_EMIT_BINARY, SIMD_VERSION_SSE41 },
-       { SN_CompareGreaterThan, OP_PCMPGTQ, SIMD_EMIT_BINARY, SIMD_VERSION_SSE42 },
-       { SN_LoadAligned, 0, SIMD_EMIT_LOAD_ALIGNED },
-       { SN_LogicalRightShift, OP_PSHRQ, SIMD_EMIT_SHIFT },
-       { SN_PrefetchTemporalAllCacheLevels, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_0 },
-       { SN_PrefetchTemporal1stLevelCache, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_1 },
-       { SN_PrefetchTemporal2ndLevelCache, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_2 },
-       { SN_PrefetchNonTemporal, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_NTA },
-       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, SIMD_EMIT_STORE },
-       { SN_UnpackHigh, OP_UNPACK_HIGHQ, SIMD_EMIT_BINARY },
-       { SN_UnpackLow, OP_UNPACK_LOWQ, SIMD_EMIT_BINARY },
-       { SN_get_X, 0, SIMD_EMIT_GETTER_QWORD },
-       { SN_get_Y, 1, SIMD_EMIT_GETTER_QWORD },
-       { SN_op_Addition, OP_PADDQ, SIMD_EMIT_BINARY },
-       { SN_op_BitwiseAnd, OP_PAND, SIMD_EMIT_BINARY },
-       { SN_op_BitwiseOr, OP_POR, SIMD_EMIT_BINARY },
-       { SN_op_ExclusiveOr, OP_PXOR, SIMD_EMIT_BINARY },
-       { SN_op_Explicit, 0, SIMD_EMIT_CAST },
-       { SN_op_LeftShift, OP_PSHLQ, SIMD_EMIT_SHIFT },
-       { SN_op_Multiply, OP_PMULQ, SIMD_EMIT_BINARY },
-       { SN_op_Subtraction, OP_PSUBQ, SIMD_EMIT_BINARY },
-       { SN_set_X, 0, SIMD_EMIT_SETTER },
-       { SN_set_Y, 1, SIMD_EMIT_SETTER },
+       { SN_ctor, OP_EXPAND_I8, SIMD_VERSION_SSE1, SIMD_EMIT_CTOR },
+       { SN_CompareEqual, OP_PCMPEQQ, SIMD_VERSION_SSE41, SIMD_EMIT_BINARY },
+       { SN_CompareGreaterThan, OP_PCMPGTQ, SIMD_VERSION_SSE42, SIMD_EMIT_BINARY },
+       { SN_LoadAligned, 0, SIMD_VERSION_SSE1, SIMD_EMIT_LOAD_ALIGNED },
+       { SN_LogicalRightShift, OP_PSHRQ, SIMD_VERSION_SSE1, SIMD_EMIT_SHIFT },
+       { SN_PrefetchTemporalAllCacheLevels, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_0 },
+       { SN_PrefetchTemporal1stLevelCache, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_1 },
+       { SN_PrefetchTemporal2ndLevelCache, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_2 },
+       { SN_PrefetchNonTemporal, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_NTA },
+       { SN_Shuffle, OP_SHUFPD, SIMD_VERSION_SSE1, SIMD_EMIT_SHUFFLE },
+       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, SIMD_VERSION_SSE1, SIMD_EMIT_STORE },
+       { SN_UnpackHigh, OP_UNPACK_HIGHQ, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_UnpackLow, OP_UNPACK_LOWQ, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_get_X, 0, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER_QWORD },
+       { SN_get_Y, 1, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER_QWORD },
+       { SN_op_Addition, OP_PADDQ, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseAnd, OP_PAND, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseOr, OP_POR, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_ExclusiveOr, OP_PXOR, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_Explicit, 0, SIMD_VERSION_SSE1, SIMD_EMIT_CAST },
+       { SN_op_LeftShift, OP_PSHLQ, SIMD_VERSION_SSE1, SIMD_EMIT_SHIFT },
+       { SN_op_Multiply, OP_PMULQ, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_Subtraction, OP_PSUBQ, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_set_X, 0, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_Y, 1, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
 };
 
 static const SimdIntrinsc vector4ui_intrinsics[] = {
-       { SN_ctor, OP_EXPAND_I4, SIMD_EMIT_CTOR },
-       { SN_ArithmeticRightShift, OP_PSARD, SIMD_EMIT_SHIFT },
-       { SN_CompareEqual, OP_PCMPEQD, SIMD_EMIT_BINARY },
-       { SN_LoadAligned, 0, SIMD_EMIT_LOAD_ALIGNED },
-       { SN_Max, OP_PMAXD_UN, SIMD_EMIT_BINARY, SIMD_VERSION_SSE41 },
-       { SN_Min, OP_PMIND_UN, SIMD_EMIT_BINARY, SIMD_VERSION_SSE41 },
-       { SN_PrefetchTemporalAllCacheLevels, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_0 },
-       { SN_PrefetchTemporal1stLevelCache, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_1 },
-       { SN_PrefetchTemporal2ndLevelCache, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_2 },
-       { SN_PrefetchNonTemporal, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_NTA },
-       { SN_Shuffle, OP_PSHUFLED, SIMD_EMIT_SHUFFLE },
-       { SN_SignedPackWithSignedSaturation, OP_PACKD, SIMD_EMIT_BINARY },
-       { SN_SignedPackWithUnsignedSaturation, OP_PACKD_UN, SIMD_EMIT_BINARY, SIMD_VERSION_SSE41 },
-       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, SIMD_EMIT_STORE },
-       { SN_UnpackHigh, OP_UNPACK_HIGHD, SIMD_EMIT_BINARY },
-       { SN_UnpackLow, OP_UNPACK_LOWD, SIMD_EMIT_BINARY },
-       { SN_get_W, 3, SIMD_EMIT_GETTER },
-       { SN_get_X, 0, SIMD_EMIT_GETTER },
-       { SN_get_Y, 1, SIMD_EMIT_GETTER },
-       { SN_get_Z, 2, SIMD_EMIT_GETTER },
-       { SN_op_Addition, OP_PADDD, SIMD_EMIT_BINARY },
-       { SN_op_BitwiseAnd, OP_PAND, SIMD_EMIT_BINARY },
-       { SN_op_BitwiseOr, OP_POR, SIMD_EMIT_BINARY },
-       { SN_op_Equality, OP_PCMPEQD, SIMD_EMIT_EQUALITY, SIMD_VERSION_SSE1, SIMD_COMP_EQ },
-       { SN_op_ExclusiveOr, OP_PXOR, SIMD_EMIT_BINARY },
-       { SN_op_Explicit, 0, SIMD_EMIT_CAST },
-       { SN_op_Inequality, OP_PCMPEQD, SIMD_EMIT_EQUALITY, SIMD_VERSION_SSE1, SIMD_COMP_NEQ },
-       { SN_op_LeftShift, OP_PSHLD, SIMD_EMIT_SHIFT },
-       { SN_op_Multiply, OP_PMULD, SIMD_EMIT_BINARY, SIMD_VERSION_SSE41 },
-       { SN_op_RightShift, OP_PSHRD, SIMD_EMIT_SHIFT },
-       { SN_op_Subtraction, OP_PSUBD, SIMD_EMIT_BINARY },
-       { SN_set_W, 3, SIMD_EMIT_SETTER },
-       { SN_set_X, 0, SIMD_EMIT_SETTER },
-       { SN_set_Y, 1, SIMD_EMIT_SETTER },
-       { SN_set_Z, 2, SIMD_EMIT_SETTER },
+       { SN_ctor, OP_EXPAND_I4, SIMD_VERSION_SSE1, SIMD_EMIT_CTOR },
+       { SN_ArithmeticRightShift, OP_PSARD, SIMD_VERSION_SSE1, SIMD_EMIT_SHIFT },
+       { SN_CompareEqual, OP_PCMPEQD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_LoadAligned, 0, SIMD_VERSION_SSE1, SIMD_EMIT_LOAD_ALIGNED },
+       { SN_Max, OP_PMAXD_UN, SIMD_VERSION_SSE41, SIMD_EMIT_BINARY },
+       { SN_Min, OP_PMIND_UN, SIMD_VERSION_SSE41, SIMD_EMIT_BINARY },
+       { SN_PrefetchTemporalAllCacheLevels, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_0 },
+       { SN_PrefetchTemporal1stLevelCache, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_1 },
+       { SN_PrefetchTemporal2ndLevelCache, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_2 },
+       { SN_PrefetchNonTemporal, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_NTA },
+       { SN_Shuffle, OP_PSHUFLED, SIMD_VERSION_SSE1, SIMD_EMIT_SHUFFLE },
+       { SN_SignedPackWithSignedSaturation, OP_PACKD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_SignedPackWithUnsignedSaturation, OP_PACKD_UN, SIMD_VERSION_SSE41, SIMD_EMIT_BINARY },
+       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, SIMD_VERSION_SSE1, SIMD_EMIT_STORE },
+       { SN_UnpackHigh, OP_UNPACK_HIGHD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_UnpackLow, OP_UNPACK_LOWD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_get_W, 3, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_X, 0, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_Y, 1, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_Z, 2, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_op_Addition, OP_PADDD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseAnd, OP_PAND, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseOr, OP_POR, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_Equality, OP_PCMPEQD, SIMD_VERSION_SSE1, SIMD_EMIT_EQUALITY, SIMD_COMP_EQ },
+       { SN_op_ExclusiveOr, OP_PXOR, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_Explicit, 0, SIMD_VERSION_SSE1, SIMD_EMIT_CAST },
+       { SN_op_Inequality, OP_PCMPEQD, SIMD_VERSION_SSE1, SIMD_EMIT_EQUALITY, SIMD_COMP_NEQ },
+       { SN_op_LeftShift, OP_PSHLD, SIMD_VERSION_SSE1, SIMD_EMIT_SHIFT },
+       { SN_op_Multiply, OP_PMULD, SIMD_VERSION_SSE41, SIMD_EMIT_BINARY },
+       { SN_op_RightShift, OP_PSHRD, SIMD_VERSION_SSE1, SIMD_EMIT_SHIFT },
+       { SN_op_Subtraction, OP_PSUBD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_set_W, 3, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_X, 0, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_Y, 1, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_Z, 2, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
 };
 
 static const SimdIntrinsc vector4i_intrinsics[] = {
-       { SN_ctor, OP_EXPAND_I4, SIMD_EMIT_CTOR },
-       { SN_CompareEqual, OP_PCMPEQD, SIMD_EMIT_BINARY },
-       { SN_CompareGreaterThan, OP_PCMPGTD, SIMD_EMIT_BINARY },
-       { SN_LoadAligned, 0, SIMD_EMIT_LOAD_ALIGNED },
-       { SN_LogicalRightShift, OP_PSHRD, SIMD_EMIT_SHIFT },
-       { SN_Max, OP_PMAXD, SIMD_EMIT_BINARY, SIMD_VERSION_SSE41 },
-       { SN_Min, OP_PMIND, SIMD_EMIT_BINARY, SIMD_VERSION_SSE41 },
-       { SN_PackWithSignedSaturation, OP_PACKD, SIMD_EMIT_BINARY },
-       { SN_PackWithUnsignedSaturation, OP_PACKD_UN, SIMD_EMIT_BINARY, SIMD_VERSION_SSE41 },
-       { SN_PrefetchTemporalAllCacheLevels, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_0 },
-       { SN_PrefetchTemporal1stLevelCache, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_1 },
-       { SN_PrefetchTemporal2ndLevelCache, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_2 },
-       { SN_PrefetchNonTemporal, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_NTA },
-       { SN_Shuffle, OP_PSHUFLED, SIMD_EMIT_SHUFFLE },
-       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, SIMD_EMIT_STORE },
-       { SN_UnpackHigh, OP_UNPACK_HIGHD, SIMD_EMIT_BINARY },
-       { SN_UnpackLow, OP_UNPACK_LOWD, SIMD_EMIT_BINARY },
-       { SN_get_W, 3, SIMD_EMIT_GETTER },
-       { SN_get_X, 0, SIMD_EMIT_GETTER },
-       { SN_get_Y, 1, SIMD_EMIT_GETTER },
-       { SN_get_Z, 2, SIMD_EMIT_GETTER },
-       { SN_op_Addition, OP_PADDD, SIMD_EMIT_BINARY },
-       { SN_op_BitwiseAnd, OP_PAND, SIMD_EMIT_BINARY },
-       { SN_op_BitwiseOr, OP_POR, SIMD_EMIT_BINARY },
-       { SN_op_Equality, OP_PCMPEQD, SIMD_EMIT_EQUALITY, SIMD_VERSION_SSE1, SIMD_COMP_EQ },
-       { SN_op_ExclusiveOr, OP_PXOR, SIMD_EMIT_BINARY },
-       { SN_op_Explicit, 0, SIMD_EMIT_CAST },
-       { SN_op_Inequality, OP_PCMPEQD, SIMD_EMIT_EQUALITY, SIMD_VERSION_SSE1, SIMD_COMP_NEQ },
-       { SN_op_LeftShift, OP_PSHLD, SIMD_EMIT_SHIFT },
-       { SN_op_Multiply, OP_PMULD, SIMD_EMIT_BINARY, SIMD_VERSION_SSE41 },
-       { SN_op_RightShift, OP_PSARD, SIMD_EMIT_SHIFT },
-       { SN_op_Subtraction, OP_PSUBD, SIMD_EMIT_BINARY },
-       { SN_set_W, 3, SIMD_EMIT_SETTER },
-       { SN_set_X, 0, SIMD_EMIT_SETTER },
-       { SN_set_Y, 1, SIMD_EMIT_SETTER },
-       { SN_set_Z, 2, SIMD_EMIT_SETTER },
+       { SN_ctor, OP_EXPAND_I4, SIMD_VERSION_SSE1, SIMD_EMIT_CTOR },
+       { SN_CompareEqual, OP_PCMPEQD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_CompareGreaterThan, OP_PCMPGTD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_ConvertToDouble, OP_CVTDQ2PD, SIMD_VERSION_SSE2, SIMD_EMIT_UNARY },
+       { SN_ConvertToFloat, OP_CVTDQ2PS, SIMD_VERSION_SSE2, SIMD_EMIT_UNARY },
+       { SN_LoadAligned, 0, SIMD_VERSION_SSE1, SIMD_EMIT_LOAD_ALIGNED },
+       { SN_LogicalRightShift, OP_PSHRD, SIMD_VERSION_SSE1, SIMD_EMIT_SHIFT },
+       { SN_Max, OP_PMAXD, SIMD_VERSION_SSE41, SIMD_EMIT_BINARY },
+       { SN_Min, OP_PMIND, SIMD_VERSION_SSE41, SIMD_EMIT_BINARY },
+       { SN_PackWithSignedSaturation, OP_PACKD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_PackWithUnsignedSaturation, OP_PACKD_UN, SIMD_VERSION_SSE41, SIMD_EMIT_BINARY },
+       { SN_PrefetchTemporalAllCacheLevels, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_0 },
+       { SN_PrefetchTemporal1stLevelCache, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_1 },
+       { SN_PrefetchTemporal2ndLevelCache, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_2 },
+       { SN_PrefetchNonTemporal, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_NTA },
+       { SN_Shuffle, OP_PSHUFLED, SIMD_VERSION_SSE1, SIMD_EMIT_SHUFFLE },
+       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, SIMD_VERSION_SSE1, SIMD_EMIT_STORE },
+       { SN_UnpackHigh, OP_UNPACK_HIGHD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_UnpackLow, OP_UNPACK_LOWD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_get_W, 3, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_X, 0, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_Y, 1, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_Z, 2, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_op_Addition, OP_PADDD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseAnd, OP_PAND, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseOr, OP_POR, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_Equality, OP_PCMPEQD, SIMD_VERSION_SSE1, SIMD_EMIT_EQUALITY, SIMD_COMP_EQ },
+       { SN_op_ExclusiveOr, OP_PXOR, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_Explicit, 0, SIMD_VERSION_SSE1, SIMD_EMIT_CAST },
+       { SN_op_Inequality, OP_PCMPEQD, SIMD_VERSION_SSE1, SIMD_EMIT_EQUALITY, SIMD_COMP_NEQ },
+       { SN_op_LeftShift, OP_PSHLD, SIMD_VERSION_SSE1, SIMD_EMIT_SHIFT },
+       { SN_op_Multiply, OP_PMULD, SIMD_VERSION_SSE41, SIMD_EMIT_BINARY },
+       { SN_op_RightShift, OP_PSARD, SIMD_VERSION_SSE1, SIMD_EMIT_SHIFT },
+       { SN_op_Subtraction, OP_PSUBD, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_set_W, 3, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_X, 0, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_Y, 1, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_Z, 2, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
 };
 
 static const SimdIntrinsc vector8us_intrinsics[] = {
-       { SN_ctor, OP_EXPAND_I2, SIMD_EMIT_CTOR },
-       { SN_AddWithSaturation, OP_PADDW_SAT_UN, SIMD_EMIT_BINARY },
-       { SN_ArithmeticRightShift, OP_PSARW, SIMD_EMIT_SHIFT },
-       { SN_Average, OP_PAVGW_UN, SIMD_EMIT_BINARY },
-       { SN_CompareEqual, OP_PCMPEQW, SIMD_EMIT_BINARY },
-       { SN_LoadAligned, 0, SIMD_EMIT_LOAD_ALIGNED },
-       { SN_Max, OP_PMAXW_UN, SIMD_EMIT_BINARY, SIMD_VERSION_SSE41 },
-       { SN_Min, OP_PMINW_UN, SIMD_EMIT_BINARY, SIMD_VERSION_SSE41 },
-       { SN_MultiplyStoreHigh, OP_PMULW_HIGH_UN, SIMD_EMIT_BINARY },
-       { SN_PrefetchTemporalAllCacheLevels, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_0 },
-       { SN_PrefetchTemporal1stLevelCache, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_1 },
-       { SN_PrefetchTemporal2ndLevelCache, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_2 },
-       { SN_PrefetchNonTemporal, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_NTA },
-       { SN_ShuffleHigh, OP_PSHUFLEW_HIGH, SIMD_EMIT_SHUFFLE },
-       { SN_ShuffleLow, OP_PSHUFLEW_LOW, SIMD_EMIT_SHUFFLE },
-       { SN_SignedPackWithSignedSaturation, OP_PACKW, SIMD_EMIT_BINARY },
-       { SN_SignedPackWithUnsignedSaturation, OP_PACKW_UN, SIMD_EMIT_BINARY },
-       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, SIMD_EMIT_STORE },
-       { SN_SubtractWithSaturation, OP_PSUBW_SAT_UN, SIMD_EMIT_BINARY },
-       { SN_UnpackHigh, OP_UNPACK_HIGHW, SIMD_EMIT_BINARY },
-       { SN_UnpackLow, OP_UNPACK_LOWW, SIMD_EMIT_BINARY },
-       { SN_get_V0, 0, SIMD_EMIT_GETTER },
-       { SN_get_V1, 1, SIMD_EMIT_GETTER },
-       { SN_get_V2, 2, SIMD_EMIT_GETTER },
-       { SN_get_V3, 3, SIMD_EMIT_GETTER },
-       { SN_get_V4, 4, SIMD_EMIT_GETTER },
-       { SN_get_V5, 5, SIMD_EMIT_GETTER },
-       { SN_get_V6, 6, SIMD_EMIT_GETTER },
-       { SN_get_V7, 7, SIMD_EMIT_GETTER },
-       { SN_op_Addition, OP_PADDW, SIMD_EMIT_BINARY },
-       { SN_op_BitwiseAnd, OP_PAND, SIMD_EMIT_BINARY },
-       { SN_op_BitwiseOr, OP_POR, SIMD_EMIT_BINARY },
-       { SN_op_Equality, OP_PCMPEQW, SIMD_EMIT_EQUALITY, SIMD_VERSION_SSE1, SIMD_COMP_EQ },
-       { SN_op_ExclusiveOr, OP_PXOR, SIMD_EMIT_BINARY },
-       { SN_op_Explicit, 0, SIMD_EMIT_CAST },
-       { SN_op_Inequality, OP_PCMPEQW, SIMD_EMIT_EQUALITY, SIMD_VERSION_SSE1, SIMD_COMP_NEQ },
-       { SN_op_LeftShift, OP_PSHLW, SIMD_EMIT_SHIFT },
-       { SN_op_Multiply, OP_PMULW, SIMD_EMIT_BINARY },
-       { SN_op_RightShift, OP_PSHRW, SIMD_EMIT_SHIFT },
-       { SN_op_Subtraction, OP_PSUBW, SIMD_EMIT_BINARY },
-       { SN_set_V0, 0, SIMD_EMIT_SETTER },
-       { SN_set_V1, 1, SIMD_EMIT_SETTER },
-       { SN_set_V2, 2, SIMD_EMIT_SETTER },
-       { SN_set_V3, 3, SIMD_EMIT_SETTER },
-       { SN_set_V4, 4, SIMD_EMIT_SETTER },
-       { SN_set_V5, 5, SIMD_EMIT_SETTER },
-       { SN_set_V6, 6, SIMD_EMIT_SETTER },
-       { SN_set_V7, 7, SIMD_EMIT_SETTER },
+       { SN_ctor, OP_EXPAND_I2, SIMD_VERSION_SSE1, SIMD_EMIT_CTOR },
+       { SN_AddWithSaturation, OP_PADDW_SAT_UN, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_ArithmeticRightShift, OP_PSARW, SIMD_VERSION_SSE1, SIMD_EMIT_SHIFT },
+       { SN_Average, OP_PAVGW_UN, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_CompareEqual, OP_PCMPEQW, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY, SIMD_VERSION_SSE1 },
+       { SN_LoadAligned, 0, SIMD_VERSION_SSE1, SIMD_EMIT_LOAD_ALIGNED },
+       { SN_Max, OP_PMAXW_UN, SIMD_VERSION_SSE41, SIMD_EMIT_BINARY },
+       { SN_Min, OP_PMINW_UN, SIMD_VERSION_SSE41, SIMD_EMIT_BINARY },
+       { SN_MultiplyStoreHigh, OP_PMULW_HIGH_UN, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_PrefetchTemporalAllCacheLevels, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_0 },
+       { SN_PrefetchTemporal1stLevelCache, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_1 },
+       { SN_PrefetchTemporal2ndLevelCache, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_2 },
+       { SN_PrefetchNonTemporal, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_NTA },
+       { SN_ShuffleHigh, OP_PSHUFLEW_HIGH, SIMD_VERSION_SSE1, SIMD_EMIT_SHUFFLE },
+       { SN_ShuffleLow, OP_PSHUFLEW_LOW, SIMD_VERSION_SSE1, SIMD_EMIT_SHUFFLE },
+       { SN_SignedPackWithSignedSaturation, OP_PACKW, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_SignedPackWithUnsignedSaturation, OP_PACKW_UN, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, SIMD_VERSION_SSE1, SIMD_EMIT_STORE },
+       { SN_SubtractWithSaturation, OP_PSUBW_SAT_UN, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_UnpackHigh, OP_UNPACK_HIGHW, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_UnpackLow, OP_UNPACK_LOWW, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_get_V0, 0, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V1, 1, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V2, 2, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V3, 3, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V4, 4, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V5, 5, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V6, 6, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V7, 7, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_op_Addition, OP_PADDW, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseAnd, OP_PAND, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseOr, OP_POR, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_Equality, OP_PCMPEQW, SIMD_VERSION_SSE1, SIMD_EMIT_EQUALITY, SIMD_COMP_EQ },
+       { SN_op_ExclusiveOr, OP_PXOR, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_Explicit, 0, SIMD_VERSION_SSE1, SIMD_EMIT_CAST },
+       { SN_op_Inequality, OP_PCMPEQW, SIMD_VERSION_SSE1, SIMD_EMIT_EQUALITY, SIMD_COMP_NEQ },
+       { SN_op_LeftShift, OP_PSHLW, SIMD_VERSION_SSE1, SIMD_EMIT_SHIFT },
+       { SN_op_Multiply, OP_PMULW, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_RightShift, OP_PSHRW, SIMD_VERSION_SSE1, SIMD_EMIT_SHIFT },
+       { SN_op_Subtraction, OP_PSUBW, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_set_V0, 0, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V1, 1, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V2, 2, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V3, 3, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V4, 4, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V5, 5, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V6, 6, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V7, 7, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
 };
 
 static const SimdIntrinsc vector8s_intrinsics[] = {
-       { SN_ctor, OP_EXPAND_I2, SIMD_EMIT_CTOR },
-       { SN_AddWithSaturation, OP_PADDW_SAT, SIMD_EMIT_BINARY },
-       { SN_CompareEqual, OP_PCMPEQW, SIMD_EMIT_BINARY },
-       { SN_CompareGreaterThan, OP_PCMPGTW, SIMD_EMIT_BINARY },
-       { SN_LoadAligned, 0, SIMD_EMIT_LOAD_ALIGNED },
-       { SN_LogicalRightShift, OP_PSHRW, SIMD_EMIT_SHIFT },
-       { SN_Max, OP_PMAXW, SIMD_EMIT_BINARY },
-       { SN_Min, OP_PMINW, SIMD_EMIT_BINARY },
-       { SN_MultiplyStoreHigh, OP_PMULW_HIGH, SIMD_EMIT_BINARY },
-       { SN_PackWithSignedSaturation, OP_PACKW, SIMD_EMIT_BINARY },
-       { SN_PackWithUnsignedSaturation, OP_PACKW_UN, SIMD_EMIT_BINARY },
-       { SN_PrefetchTemporalAllCacheLevels, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_0 },
-       { SN_PrefetchTemporal1stLevelCache, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_1 },
-       { SN_PrefetchTemporal2ndLevelCache, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_2 },
-       { SN_PrefetchNonTemporal, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_NTA },
-       { SN_ShuffleHigh, OP_PSHUFLEW_HIGH, SIMD_EMIT_SHUFFLE },
-       { SN_ShuffleLow, OP_PSHUFLEW_LOW, SIMD_EMIT_SHUFFLE },
-       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, SIMD_EMIT_STORE },
-       { SN_SubtractWithSaturation, OP_PSUBW_SAT_UN, SIMD_EMIT_BINARY },
-       { SN_UnpackHigh, OP_UNPACK_HIGHW, SIMD_EMIT_BINARY },
-       { SN_UnpackLow, OP_UNPACK_LOWW, SIMD_EMIT_BINARY },
-       { SN_get_V0, 0, SIMD_EMIT_GETTER },
-       { SN_get_V1, 1, SIMD_EMIT_GETTER },
-       { SN_get_V2, 2, SIMD_EMIT_GETTER },
-       { SN_get_V3, 3, SIMD_EMIT_GETTER },
-       { SN_get_V4, 4, SIMD_EMIT_GETTER },
-       { SN_get_V5, 5, SIMD_EMIT_GETTER },
-       { SN_get_V6, 6, SIMD_EMIT_GETTER },
-       { SN_get_V7, 7, SIMD_EMIT_GETTER },
-       { SN_op_Addition, OP_PADDW, SIMD_EMIT_BINARY },
-       { SN_op_BitwiseAnd, OP_PAND, SIMD_EMIT_BINARY },
-       { SN_op_BitwiseOr, OP_POR, SIMD_EMIT_BINARY },
-       { SN_op_Equality, OP_PCMPEQW, SIMD_EMIT_EQUALITY, SIMD_VERSION_SSE1, SIMD_COMP_EQ },
-       { SN_op_ExclusiveOr, OP_PXOR, SIMD_EMIT_BINARY },
-       { SN_op_Explicit, 0, SIMD_EMIT_CAST },
-       { SN_op_Inequality, OP_PCMPEQW, SIMD_EMIT_EQUALITY, SIMD_VERSION_SSE1, SIMD_COMP_NEQ },
-       { SN_op_LeftShift, OP_PSHLW, SIMD_EMIT_SHIFT },
-       { SN_op_Multiply, OP_PMULW, SIMD_EMIT_BINARY },
-       { SN_op_RightShift, OP_PSARW, SIMD_EMIT_SHIFT },
-       { SN_op_Subtraction, OP_PSUBW, SIMD_EMIT_BINARY },
-       { SN_set_V0, 0, SIMD_EMIT_SETTER },
-       { SN_set_V1, 1, SIMD_EMIT_SETTER },
-       { SN_set_V2, 2, SIMD_EMIT_SETTER },
-       { SN_set_V3, 3, SIMD_EMIT_SETTER },
-       { SN_set_V4, 4, SIMD_EMIT_SETTER },
-       { SN_set_V5, 5, SIMD_EMIT_SETTER },
-       { SN_set_V6, 6, SIMD_EMIT_SETTER },
-       { SN_set_V7, 7, SIMD_EMIT_SETTER },
+       { SN_ctor, OP_EXPAND_I2, SIMD_VERSION_SSE1, SIMD_EMIT_CTOR },
+       { SN_AddWithSaturation, OP_PADDW_SAT, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_CompareEqual, OP_PCMPEQW, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_CompareGreaterThan, OP_PCMPGTW, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_LoadAligned, 0, SIMD_VERSION_SSE1, SIMD_EMIT_LOAD_ALIGNED },
+       { SN_LogicalRightShift, OP_PSHRW, SIMD_VERSION_SSE1, SIMD_EMIT_SHIFT },
+       { SN_Max, OP_PMAXW, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_Min, OP_PMINW, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_MultiplyStoreHigh, OP_PMULW_HIGH, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_PackWithSignedSaturation, OP_PACKW, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_PackWithUnsignedSaturation, OP_PACKW_UN, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_PrefetchTemporalAllCacheLevels, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_0 },
+       { SN_PrefetchTemporal1stLevelCache, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_1 },
+       { SN_PrefetchTemporal2ndLevelCache, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_2 },
+       { SN_PrefetchNonTemporal, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_NTA },
+       { SN_ShuffleHigh, OP_PSHUFLEW_HIGH, SIMD_VERSION_SSE1, SIMD_EMIT_SHUFFLE },
+       { SN_ShuffleLow, OP_PSHUFLEW_LOW, SIMD_VERSION_SSE1, SIMD_EMIT_SHUFFLE },
+       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, SIMD_VERSION_SSE1, SIMD_EMIT_STORE },
+       { SN_SubtractWithSaturation, OP_PSUBW_SAT_UN, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_UnpackHigh, OP_UNPACK_HIGHW, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_UnpackLow, OP_UNPACK_LOWW, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_get_V0, 0, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V1, 1, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V2, 2, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V3, 3, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V4, 4, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V5, 5, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V6, 6, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V7, 7, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_op_Addition, OP_PADDW, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseAnd, OP_PAND, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseOr, OP_POR, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_Equality, OP_PCMPEQW, SIMD_VERSION_SSE1, SIMD_EMIT_EQUALITY, SIMD_COMP_EQ },
+       { SN_op_ExclusiveOr, OP_PXOR, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_Explicit, 0, SIMD_VERSION_SSE1, SIMD_EMIT_CAST },
+       { SN_op_Inequality, OP_PCMPEQW, SIMD_VERSION_SSE1, SIMD_EMIT_EQUALITY, SIMD_COMP_NEQ },
+       { SN_op_LeftShift, OP_PSHLW, SIMD_VERSION_SSE1, SIMD_EMIT_SHIFT },
+       { SN_op_Multiply, OP_PMULW, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_RightShift, OP_PSARW, SIMD_VERSION_SSE1, SIMD_EMIT_SHIFT },
+       { SN_op_Subtraction, OP_PSUBW, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_set_V0, 0, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V1, 1, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V2, 2, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V3, 3, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V4, 4, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V5, 5, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V6, 6, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V7, 7, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
 };
 
 static const SimdIntrinsc vector16b_intrinsics[] = {
-       { SN_ctor, OP_EXPAND_I1, SIMD_EMIT_CTOR },
-       { SN_AddWithSaturation, OP_PADDB_SAT_UN, SIMD_EMIT_BINARY },
-       { SN_Average, OP_PAVGB_UN, SIMD_EMIT_BINARY },
-       { SN_CompareEqual, OP_PCMPEQB, SIMD_EMIT_BINARY },
-       { SN_ExtractByteMask, 0, SIMD_EMIT_EXTRACT_MASK },
-       { SN_LoadAligned, 0, SIMD_EMIT_LOAD_ALIGNED },
-       { SN_Max, OP_PMAXB_UN, SIMD_EMIT_BINARY },
-       { SN_Min, OP_PMINB_UN, SIMD_EMIT_BINARY },
-       { SN_PrefetchTemporalAllCacheLevels, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_0 },
-       { SN_PrefetchTemporal1stLevelCache, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_1 },
-       { SN_PrefetchTemporal2ndLevelCache, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_2 },
-       { SN_PrefetchNonTemporal, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_NTA },
-       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, SIMD_EMIT_STORE },
-       { SN_SubtractWithSaturation, OP_PSUBB_SAT_UN, SIMD_EMIT_BINARY },
-       { SN_SumOfAbsoluteDifferences, OP_PSUM_ABS_DIFF, SIMD_EMIT_BINARY },
-       { SN_UnpackHigh, OP_UNPACK_HIGHB, SIMD_EMIT_BINARY },
-       { SN_UnpackLow, OP_UNPACK_LOWB, SIMD_EMIT_BINARY },
-       { SN_get_V0, 0, SIMD_EMIT_GETTER },
-       { SN_get_V1, 1, SIMD_EMIT_GETTER },
-       { SN_get_V10, 10, SIMD_EMIT_GETTER },
-       { SN_get_V11, 11, SIMD_EMIT_GETTER },
-       { SN_get_V12, 12, SIMD_EMIT_GETTER },
-       { SN_get_V13, 13, SIMD_EMIT_GETTER },
-       { SN_get_V14, 14, SIMD_EMIT_GETTER },
-       { SN_get_V15, 15, SIMD_EMIT_GETTER },
-       { SN_get_V2, 2, SIMD_EMIT_GETTER },
-       { SN_get_V3, 3, SIMD_EMIT_GETTER },
-       { SN_get_V4, 4, SIMD_EMIT_GETTER },
-       { SN_get_V5, 5, SIMD_EMIT_GETTER },
-       { SN_get_V6, 6, SIMD_EMIT_GETTER },
-       { SN_get_V7, 7, SIMD_EMIT_GETTER },
-       { SN_get_V8, 8, SIMD_EMIT_GETTER },
-       { SN_get_V9, 9, SIMD_EMIT_GETTER },
-       { SN_op_Addition, OP_PADDB, SIMD_EMIT_BINARY },
-       { SN_op_BitwiseAnd, OP_PAND, SIMD_EMIT_BINARY },
-       { SN_op_BitwiseOr, OP_POR, SIMD_EMIT_BINARY },
-       { SN_op_Equality, OP_PCMPEQB, SIMD_EMIT_EQUALITY, SIMD_VERSION_SSE1, SIMD_COMP_EQ },
-       { SN_op_ExclusiveOr, OP_PXOR, SIMD_EMIT_BINARY },
-       { SN_op_Explicit, 0, SIMD_EMIT_CAST },
-       { SN_op_Inequality, OP_PCMPEQB, SIMD_EMIT_EQUALITY, SIMD_VERSION_SSE1, SIMD_COMP_NEQ },
-       { SN_op_Subtraction, OP_PSUBB, SIMD_EMIT_BINARY },
-       { SN_set_V0, 0, SIMD_EMIT_SETTER },
-       { SN_set_V1, 1, SIMD_EMIT_SETTER },
-       { SN_set_V10, 10, SIMD_EMIT_SETTER },
-       { SN_set_V11, 11, SIMD_EMIT_SETTER },
-       { SN_set_V12, 12, SIMD_EMIT_SETTER },
-       { SN_set_V13, 13, SIMD_EMIT_SETTER },
-       { SN_set_V14, 14, SIMD_EMIT_SETTER },
-       { SN_set_V15, 15, SIMD_EMIT_SETTER },
-       { SN_set_V2, 2, SIMD_EMIT_SETTER },
-       { SN_set_V3, 3, SIMD_EMIT_SETTER },
-       { SN_set_V4, 4, SIMD_EMIT_SETTER },
-       { SN_set_V5, 5, SIMD_EMIT_SETTER },
-       { SN_set_V6, 6, SIMD_EMIT_SETTER },
-       { SN_set_V7, 7, SIMD_EMIT_SETTER },
-       { SN_set_V8, 8, SIMD_EMIT_SETTER },
-       { SN_set_V9, 9, SIMD_EMIT_SETTER },
+       { SN_ctor, OP_EXPAND_I1, SIMD_VERSION_SSE1, SIMD_EMIT_CTOR },
+       { SN_AddWithSaturation, OP_PADDB_SAT_UN, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_Average, OP_PAVGB_UN, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_CompareEqual, OP_PCMPEQB, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_ExtractByteMask, 0, SIMD_VERSION_SSE1, SIMD_EMIT_EXTRACT_MASK },
+       { SN_LoadAligned, 0, SIMD_VERSION_SSE1, SIMD_EMIT_LOAD_ALIGNED },
+       { SN_Max, OP_PMAXB_UN, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_Min, OP_PMINB_UN, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_PrefetchTemporalAllCacheLevels, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_0 },
+       { SN_PrefetchTemporal1stLevelCache, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_1 },
+       { SN_PrefetchTemporal2ndLevelCache, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_2 },
+       { SN_PrefetchNonTemporal, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_NTA },
+       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, SIMD_VERSION_SSE1, SIMD_EMIT_STORE },
+       { SN_SubtractWithSaturation, OP_PSUBB_SAT_UN, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_SumOfAbsoluteDifferences, OP_PSUM_ABS_DIFF, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_UnpackHigh, OP_UNPACK_HIGHB, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_UnpackLow, OP_UNPACK_LOWB, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_get_V0, 0, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V1, 1, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V10, 10, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V11, 11, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V12, 12, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V13, 13, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V14, 14, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V15, 15, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V2, 2, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V3, 3, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V4, 4, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V5, 5, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V6, 6, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V7, 7, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V8, 8, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V9, 9, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_op_Addition, OP_PADDB, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseAnd, OP_PAND, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseOr, OP_POR, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_Equality, OP_PCMPEQB, SIMD_VERSION_SSE1, SIMD_EMIT_EQUALITY, SIMD_COMP_EQ },
+       { SN_op_ExclusiveOr, OP_PXOR, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_Explicit, 0, SIMD_VERSION_SSE1, SIMD_EMIT_CAST },
+       { SN_op_Inequality, OP_PCMPEQB, SIMD_VERSION_SSE1, SIMD_EMIT_EQUALITY, SIMD_COMP_NEQ },
+       { SN_op_Subtraction, OP_PSUBB, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_set_V0, 0, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V1, 1, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V10, 10, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V11, 11, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V12, 12, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V13, 13, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V14, 14, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V15, 15, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V2, 2, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V3, 3, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V4, 4, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V5, 5, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V6, 6, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V7, 7, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V8, 8, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V9, 9, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
 };
 
 /*
@@ -514,62 +526,62 @@ Missing:
 setters
  */
 static const SimdIntrinsc vector16sb_intrinsics[] = {
-       { SN_ctor, OP_EXPAND_I1, SIMD_EMIT_CTOR },
-       { SN_AddWithSaturation, OP_PADDB_SAT, SIMD_EMIT_BINARY },
-       { SN_CompareEqual, OP_PCMPEQB, SIMD_EMIT_BINARY },
-       { SN_CompareGreaterThan, OP_PCMPGTB, SIMD_EMIT_BINARY },
-       { SN_ExtractByteMask, 0, SIMD_EMIT_EXTRACT_MASK },
-       { SN_LoadAligned, 0, SIMD_EMIT_LOAD_ALIGNED },
-       { SN_Max, OP_PMAXB, SIMD_EMIT_BINARY, SIMD_VERSION_SSE41 },
-       { SN_Min, OP_PMINB, SIMD_EMIT_BINARY, SIMD_VERSION_SSE41 },
-       { SN_PrefetchTemporalAllCacheLevels, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_0 },
-       { SN_PrefetchTemporal1stLevelCache, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_1 },
-       { SN_PrefetchTemporal2ndLevelCache, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_2 },
-       { SN_PrefetchNonTemporal, 0, SIMD_EMIT_PREFETCH, SIMD_VERSION_SSE1, SIMD_PREFETCH_MODE_NTA },
-       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, SIMD_EMIT_STORE },
-       { SN_SubtractWithSaturation, OP_PSUBB_SAT, SIMD_EMIT_BINARY },
-       { SN_UnpackHigh, OP_UNPACK_HIGHB, SIMD_EMIT_BINARY },
-       { SN_UnpackLow, OP_UNPACK_LOWB, SIMD_EMIT_BINARY },
-       { SN_get_V0, 0, SIMD_EMIT_GETTER },
-       { SN_get_V1, 1, SIMD_EMIT_GETTER },
-       { SN_get_V10, 10, SIMD_EMIT_GETTER },
-       { SN_get_V11, 11, SIMD_EMIT_GETTER },
-       { SN_get_V12, 12, SIMD_EMIT_GETTER },
-       { SN_get_V13, 13, SIMD_EMIT_GETTER },
-       { SN_get_V14, 14, SIMD_EMIT_GETTER },
-       { SN_get_V15, 15, SIMD_EMIT_GETTER },
-       { SN_get_V2, 2, SIMD_EMIT_GETTER },
-       { SN_get_V3, 3, SIMD_EMIT_GETTER },
-       { SN_get_V4, 4, SIMD_EMIT_GETTER },
-       { SN_get_V5, 5, SIMD_EMIT_GETTER },
-       { SN_get_V6, 6, SIMD_EMIT_GETTER },
-       { SN_get_V7, 7, SIMD_EMIT_GETTER },
-       { SN_get_V8, 8, SIMD_EMIT_GETTER },
-       { SN_get_V9, 9, SIMD_EMIT_GETTER },
-       { SN_op_Addition, OP_PADDB, SIMD_EMIT_BINARY },
-       { SN_op_BitwiseAnd, OP_PAND, SIMD_EMIT_BINARY },
-       { SN_op_BitwiseOr, OP_POR, SIMD_EMIT_BINARY },
-       { SN_op_Equality, OP_PCMPEQB, SIMD_EMIT_EQUALITY, SIMD_VERSION_SSE1, SIMD_COMP_EQ },
-       { SN_op_ExclusiveOr, OP_PXOR, SIMD_EMIT_BINARY },
-       { SN_op_Explicit, 0, SIMD_EMIT_CAST },
-       { SN_op_Inequality, OP_PCMPEQB, SIMD_EMIT_EQUALITY, SIMD_VERSION_SSE1, SIMD_COMP_NEQ },
-       { SN_op_Subtraction, OP_PSUBB, SIMD_EMIT_BINARY },
-       { SN_set_V0, 0, SIMD_EMIT_SETTER },
-       { SN_set_V1, 1, SIMD_EMIT_SETTER },
-       { SN_set_V10, 10, SIMD_EMIT_SETTER },
-       { SN_set_V11, 11, SIMD_EMIT_SETTER },
-       { SN_set_V12, 12, SIMD_EMIT_SETTER },
-       { SN_set_V13, 13, SIMD_EMIT_SETTER },
-       { SN_set_V14, 14, SIMD_EMIT_SETTER },
-       { SN_set_V15, 15, SIMD_EMIT_SETTER },
-       { SN_set_V2, 2, SIMD_EMIT_SETTER },
-       { SN_set_V3, 3, SIMD_EMIT_SETTER },
-       { SN_set_V4, 4, SIMD_EMIT_SETTER },
-       { SN_set_V5, 5, SIMD_EMIT_SETTER },
-       { SN_set_V6, 6, SIMD_EMIT_SETTER },
-       { SN_set_V7, 7, SIMD_EMIT_SETTER },
-       { SN_set_V8, 8, SIMD_EMIT_SETTER },
-       { SN_set_V9, 9, SIMD_EMIT_SETTER },
+       { SN_ctor, OP_EXPAND_I1, SIMD_VERSION_SSE1, SIMD_EMIT_CTOR },
+       { SN_AddWithSaturation, OP_PADDB_SAT, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_CompareEqual, OP_PCMPEQB, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_CompareGreaterThan, OP_PCMPGTB, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_ExtractByteMask, 0, SIMD_VERSION_SSE1, SIMD_EMIT_EXTRACT_MASK },
+       { SN_LoadAligned, 0, SIMD_VERSION_SSE1, SIMD_EMIT_LOAD_ALIGNED },
+       { SN_Max, OP_PMAXB, SIMD_VERSION_SSE41, SIMD_EMIT_BINARY },
+       { SN_Min, OP_PMINB, SIMD_VERSION_SSE41, SIMD_EMIT_BINARY },
+       { SN_PrefetchTemporalAllCacheLevels, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_0 },
+       { SN_PrefetchTemporal1stLevelCache, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_1 },
+       { SN_PrefetchTemporal2ndLevelCache, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_2 },
+       { SN_PrefetchNonTemporal, 0, SIMD_VERSION_SSE1, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_NTA },
+       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, SIMD_VERSION_SSE1, SIMD_EMIT_STORE },
+       { SN_SubtractWithSaturation, OP_PSUBB_SAT, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_UnpackHigh, OP_UNPACK_HIGHB, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_UnpackLow, OP_UNPACK_LOWB, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_get_V0, 0, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V1, 1, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V10, 10, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V11, 11, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V12, 12, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V13, 13, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V14, 14, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V15, 15, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V2, 2, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V3, 3, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V4, 4, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V5, 5, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V6, 6, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V7, 7, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V8, 8, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_get_V9, 9, SIMD_VERSION_SSE1, SIMD_EMIT_GETTER },
+       { SN_op_Addition, OP_PADDB, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseAnd, OP_PAND, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseOr, OP_POR, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_Equality, OP_PCMPEQB, SIMD_VERSION_SSE1, SIMD_EMIT_EQUALITY, SIMD_COMP_EQ },
+       { SN_op_ExclusiveOr, OP_PXOR, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_op_Explicit, 0, SIMD_VERSION_SSE1, SIMD_EMIT_CAST },
+       { SN_op_Inequality, OP_PCMPEQB, SIMD_VERSION_SSE1, SIMD_EMIT_EQUALITY, SIMD_COMP_NEQ },
+       { SN_op_Subtraction, OP_PSUBB, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_set_V0, 0, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V1, 1, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V10, 10, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V11, 11, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V12, 12, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V13, 13, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V14, 14, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V15, 15, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V2, 2, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V3, 3, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V4, 4, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V5, 5, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V6, 6, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V7, 7, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V8, 8, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
+       { SN_set_V9, 9, SIMD_VERSION_SSE1, SIMD_EMIT_SETTER },
 };
 
 static guint32 simd_supported_versions;
@@ -866,22 +878,75 @@ get_simd_ctor_spill_area (MonoCompile *cfg, MonoClass *avector_klass)
        return cfg->simd_ctor_var;
 }
 
+static int
+mono_type_to_expand_op (MonoType *type)
+{
+       switch (type->type) {
+       case MONO_TYPE_I1:
+       case MONO_TYPE_U1:
+               return OP_EXPAND_I1;
+       case MONO_TYPE_I2:
+       case MONO_TYPE_U2:
+               return OP_EXPAND_I2;
+       case MONO_TYPE_I4:
+       case MONO_TYPE_U4:
+               return OP_EXPAND_I4;
+       case MONO_TYPE_I8:
+       case MONO_TYPE_U8:
+               return OP_EXPAND_I8;
+       case MONO_TYPE_R4:
+               return OP_EXPAND_R4;
+       case MONO_TYPE_R8:
+               return OP_EXPAND_R8;
+       default:
+               g_assert_not_reached ();
+       }
+}
+
+static int
+get_simd_vreg_or_expanded_scalar (MonoCompile *cfg, MonoMethod *cmethod, MonoInst *src, int position)
+{
+       MonoInst *ins;
+       MonoMethodSignature *sig = mono_method_signature (cmethod);
+       int expand_op;
+
+       g_assert (sig->param_count == 2);
+       g_assert (position == 0 || position == 1);
+
+       if (mono_class_from_mono_type (sig->params [position])->simd_type)
+               return get_simd_vreg (cfg, cmethod, src);
+
+       expand_op = mono_type_to_expand_op (sig->params [position]);
+       MONO_INST_NEW (cfg, ins, expand_op);
+       ins->klass = cmethod->klass;
+       ins->sreg1 = src->dreg;
+       ins->type = STACK_VTYPE;
+       ins->dreg = alloc_ireg (cfg);
+       MONO_ADD_INS (cfg->cbb, ins);
+
+       if (expand_op == OP_EXPAND_R4)
+               ins->backend.spill_var = get_int_to_float_spill_area (cfg);
+       else if (expand_op == OP_EXPAND_R8)
+               ins->backend.spill_var = get_double_spill_area (cfg);
+
+       return ins->dreg;
+}
+
 static MonoInst*
 simd_intrinsic_emit_binary (const SimdIntrinsc *intrinsic, MonoCompile *cfg, MonoMethod *cmethod, MonoInst **args)
 {
        MonoInst* ins;
        int left_vreg, right_vreg;
 
-       left_vreg = get_simd_vreg (cfg, cmethod, args [0]);
-       right_vreg = get_simd_vreg (cfg, cmethod, args [1]);
-       
+       left_vreg = get_simd_vreg_or_expanded_scalar (cfg, cmethod, args [0], 0);
+       right_vreg = get_simd_vreg_or_expanded_scalar (cfg, cmethod, args [1], 1);
+
 
        MONO_INST_NEW (cfg, ins, intrinsic->opcode);
        ins->klass = cmethod->klass;
        ins->sreg1 = left_vreg;
        ins->sreg2 = right_vreg;
        ins->type = STACK_VTYPE;
-       ins->klass = cmethod->klass;
        ins->dreg = alloc_ireg (cfg);
        ins->inst_c0 = intrinsic->flags;
        MONO_ADD_INS (cfg->cbb, ins);
@@ -921,8 +986,9 @@ mono_type_to_extract_op (MonoType *type)
        case MONO_TYPE_U4:
        case MONO_TYPE_R4:
                return OP_EXTRACT_I4;
+       default:
+               g_assert_not_reached ();
        }
-       g_assert_not_reached ();
 }
 
 /*Returns the amount to shift the element index to get the dword it belongs to*/
@@ -940,8 +1006,34 @@ mono_type_elements_shift_bits (MonoType *type)
        case MONO_TYPE_U4:
        case MONO_TYPE_R4:
                return 0;
+       default:
+               g_assert_not_reached ();
+       }
+}
+
+static G_GNUC_UNUSED int
+mono_type_to_insert_op (MonoType *type)
+{
+       switch (type->type) {
+       case MONO_TYPE_I1:
+       case MONO_TYPE_U1:
+               return OP_INSERT_I1;
+       case MONO_TYPE_I2:
+       case MONO_TYPE_U2:
+               return OP_INSERT_I2;
+       case MONO_TYPE_I4:
+       case MONO_TYPE_U4:
+               return OP_INSERT_I4;
+       case MONO_TYPE_I8:
+       case MONO_TYPE_U8:
+               return OP_INSERT_I8;
+       case MONO_TYPE_R4:
+               return OP_INSERT_R4;
+       case MONO_TYPE_R8:
+               return OP_INSERT_R8;
+       default:
+               g_assert_not_reached ();
        }
-       g_assert_not_reached ();
 }
 
 static int
@@ -964,8 +1056,9 @@ mono_type_to_slow_insert_op (MonoType *type)
                return OP_INSERTX_R4_SLOW;
        case MONO_TYPE_R8:
                return OP_INSERTX_R8_SLOW;
+       default:
+               g_assert_not_reached ();
        }
-       g_assert_not_reached ();
 }
 
 static MonoInst*
@@ -976,11 +1069,17 @@ simd_intrinsic_emit_setter (const SimdIntrinsc *intrinsic, MonoCompile *cfg, Mon
        int size, align;
        gboolean indirect;
        int dreg;
-       size = mono_type_size (sig->params [0], &align); 
 
        size = mono_type_size (sig->params [0], &align); 
 
-       if (size == 2 || size == 4 || size == 8) {
+       if (COMPILE_LLVM (cfg)) {
+               MONO_INST_NEW (cfg, ins, mono_type_to_insert_op (sig->params [0]));
+               ins->klass = cmethod->klass;
+               ins->dreg = ins->sreg1 = dreg = load_simd_vreg (cfg, cmethod, args [0], &indirect);
+               ins->sreg2 = args [1]->dreg;
+               ins->inst_c0 = intrinsic->opcode;
+               MONO_ADD_INS (cfg->cbb, ins);
+       } else if (size == 2 || size == 4 || size == 8) {
                MONO_INST_NEW (cfg, ins, mono_type_to_slow_insert_op (sig->params [0]));
                ins->klass = cmethod->klass;
                /*This is a partial load so we encode the dependency on the previous value by setting dreg and sreg1 to the same value.*/
@@ -1031,7 +1130,7 @@ simd_intrinsic_emit_getter (const SimdIntrinsc *intrinsic, MonoCompile *cfg, Mon
 
        vreg = load_simd_vreg (cfg, cmethod, args [0], NULL);
 
-       if (intrinsic->opcode >> shift_bits) {
+       if ((intrinsic->opcode >> shift_bits) && !cfg->compile_llvm) {
                MONO_INST_NEW (cfg, ins, OP_PSHUFLED);
                ins->klass = cmethod->klass;
                ins->sreg1 = vreg;
@@ -1046,7 +1145,10 @@ simd_intrinsic_emit_getter (const SimdIntrinsc *intrinsic, MonoCompile *cfg, Mon
        ins->sreg1 = vreg;
        ins->type = STACK_I4;
        ins->dreg = vreg = alloc_ireg (cfg);
-       ins->inst_c0 = intrinsic->opcode & ((1 << shift_bits) - 1);
+       if (cfg->compile_llvm)
+               ins->inst_c0 = intrinsic->opcode;
+       else
+               ins->inst_c0 = intrinsic->opcode & ((1 << shift_bits) - 1);
        MONO_ADD_INS (cfg->cbb, ins);
 
        if (sig->ret->type == MONO_TYPE_R4) {
@@ -1260,24 +1362,32 @@ static MonoInst*
 simd_intrinsic_emit_shuffle (const SimdIntrinsc *intrinsic, MonoCompile *cfg, MonoMethod *cmethod, MonoInst **args)
 {
        MonoInst *ins;
-       int vreg;
-
-       /*TODO Exposing shuffle is not a good thing as it's non obvious. We should come up with better abstractions*/
+       int vreg, vreg2 = -1;
+       int param_count = mono_method_signature (cmethod)->param_count;
 
-       if (args [1]->opcode != OP_ICONST) {
+       if (args [param_count - 1]->opcode != OP_ICONST) {
                /*TODO Shuffle with non literals is not yet supported */
                return NULL;
        }
+
        vreg = get_simd_vreg (cfg, cmethod, args [0]);
-       NULLIFY_INS (args [1]);
+       if (param_count == 3)
+               vreg2 = get_simd_vreg (cfg, cmethod, args [1]);
+
+       NULLIFY_INS (args [param_count - 1]);
+
 
        MONO_INST_NEW (cfg, ins, intrinsic->opcode);
        ins->klass = cmethod->klass;
        ins->sreg1 = vreg;
-       ins->inst_c0 = args [1]->inst_c0;
+       ins->sreg2 = vreg2;
+       ins->inst_c0 = args [param_count - 1]->inst_c0;
        ins->type = STACK_VTYPE;
        ins->dreg = alloc_ireg (cfg);
        MONO_ADD_INS (cfg->cbb, ins);
+
+       if (param_count == 3 && ins->opcode == OP_PSHUFLED)
+               ins->opcode = OP_SHUFPS;
        return ins;
 }
 
@@ -1368,7 +1478,7 @@ simd_version_name (guint32 version)
 static MonoInst*
 emit_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args, const SimdIntrinsc *intrinsics, guint32 size)
 {
-       const SimdIntrinsc * result = bsearch (cmethod->name, intrinsics, size, sizeof (SimdIntrinsc), &simd_intrinsic_compare_by_name);
+       const SimdIntrinsc * result = mono_binary_search (cmethod->name, intrinsics, size, sizeof (SimdIntrinsc), &simd_intrinsic_compare_by_name);
        if (!result) {
                DEBUG (printf ("function doesn't have a simd intrinsic %s::%s/%d\n", cmethod->klass->name, cmethod->name, fsig->param_count));
                return NULL;
@@ -1382,9 +1492,16 @@ emit_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
                        mono_print_ins (args [i]);
                }
        }
-       if (result->simd_version && !((1 << result->simd_version) & simd_supported_versions)) {
-               if (IS_DEBUG_ON (cfg))
-                       printf ("function %s::%s/%d requires unsuported SIMD instruction set %s \n", cmethod->klass->name, cmethod->name, fsig->param_count, simd_version_name (result->simd_version));
+       if (result->simd_version_flags && !(result->simd_version_flags & simd_supported_versions)) {
+               if (IS_DEBUG_ON (cfg)) {
+                       int x;
+                       printf ("function %s::%s/%d requires one of unsuported SIMD instruction set(s): ", cmethod->klass->name, cmethod->name, fsig->param_count);
+                       for (x = 1; x <= SIMD_VERSION_INDEX_END; x++)
+                               if (result->simd_version_flags & (1 << x))
+                                       printf ("%s ", simd_version_name (1 << x));
+
+                       printf ("\n");
+               }
                return NULL;
        }