[jit] Transition the SIMD code to use the MONO_CPU_... set of flags instead of the...
authormonojenkins <jo.shields+jenkins@xamarin.com>
Tue, 17 Mar 2020 01:02:22 +0000 (21:02 -0400)
committerGitHub <noreply@github.com>
Tue, 17 Mar 2020 01:02:22 +0000 (21:02 -0400)
Co-authored-by: vargaz <vargaz@users.noreply.github.com>
16 files changed:
src/mono/mono/mini/Makefile.am.in
src/mono/mono/mini/aot-compiler.c
src/mono/mono/mini/aot-runtime.c
src/mono/mono/mini/mini-amd64.c
src/mono/mono/mini/mini-arm.c
src/mono/mono/mini/mini-arm64.c
src/mono/mono/mini/mini-mips.c
src/mono/mono/mini/mini-ppc.c
src/mono/mono/mini/mini-riscv.c
src/mono/mono/mini/mini-s390x.c
src/mono/mono/mini/mini-sparc.c
src/mono/mono/mini/mini-wasm.c
src/mono/mono/mini/mini-x86.c
src/mono/mono/mini/mini.c
src/mono/mono/mini/mini.h
src/mono/mono/mini/simd-intrinsics.c

index 025f100f015f7f72884b5fe53ce4ab497c418546..567313b6c7f4a73cc02c3138da8a46302c5ad6c6 100755 (executable)
@@ -921,11 +921,7 @@ gctest: mono gc-test.exe
        MONO_DEBUG_OPTIONS=clear-nursery-at-gc $(MINI_RUNTIME) --regression gc-test.exe
 
 LLVM_AOT_RUNTIME_OPTS=$(if $(LLVM),--llvm,)
-if AMD64
-LLVM_AOT_COMPILER_OPTS=$(if $(LLVM),llvmllc=-mattr=+sse3,)
-else
-LLVM_AOT_COMPILER_OPTS=
-endif
+LLVM_AOT_COMPILER_OPTS=mcpu=native
 GSHAREDVT_RUNTIME_OPTS=$(if $(GSHAREDVT),-O=gsharedvt,)
 
 aotcheck: mono $(regtests)
index f92545f50222f5ba8ac965eb03c434db3bf56340..215dd5db108c14c5122ed59af46085f78e7211a3 100644 (file)
@@ -12921,10 +12921,6 @@ acfg_create (MonoAssembly *ass, guint32 jit_opts)
        acfg->globals = g_ptr_array_new ();
        acfg->image = image;
        acfg->jit_opts = jit_opts;
-       /* TODO: Write out set of SIMD instructions used, rather than just those available */
-#ifndef MONO_CROSS_COMPILE
-       acfg->simd_opts = mono_arch_cpu_enumerate_simd_versions ();
-#endif
        acfg->mempool = mono_mempool_new ();
        acfg->extra_methods = g_ptr_array_new ();
        acfg->unwind_info_offsets = g_hash_table_new (NULL, NULL);
index b8c755543ea1ac3d4995805a6753347fffb15644..c603e03dae7a9f728bf4a325d8ea54a1cd0ac5a0 100644 (file)
@@ -1916,11 +1916,6 @@ check_usable (MonoAssembly *assembly, MonoAotFileInfo *info, guint8 *blob, char
                usable = FALSE;
        }
 
-       if (!mono_aot_only && (info->simd_opts & ~mono_arch_cpu_enumerate_simd_versions ())) {
-               msg = g_strdup ("compiled with unsupported SIMD extensions");
-               usable = FALSE;
-       }
-
        if (info->gc_name_index != -1) {
                char *gc_name = (char*)&blob [info->gc_name_index];
                const char *current_gc_name = mono_gc_get_gc_name ();
index 5de18f7e27d5d4e445d2aac934b51688f36f3dd1..8958f5f8c628e58cb014a0a8f080c8edf599de9b 100644 (file)
@@ -1467,45 +1467,28 @@ mono_arch_cpu_optimizations (guint32 *exclude_mask)
        return opts;
 }
 
-/*
- * This function test for all SSE functions supported.
- *
- * Returns a bitmask corresponding to all supported versions.
- * 
- */
-guint32
-mono_arch_cpu_enumerate_simd_versions (void)
+MonoCPUFeatures
+mono_arch_get_cpu_features (void)
 {
-       guint32 sse_opts = 0;
+       guint64 features = MONO_CPU_INITED;
 
        if (mono_hwcap_x86_has_sse1)
-               sse_opts |= SIMD_VERSION_SSE1;
+               features |= MONO_CPU_X86_SSE;
 
        if (mono_hwcap_x86_has_sse2)
-               sse_opts |= SIMD_VERSION_SSE2;
+               features |= MONO_CPU_X86_SSE2;
 
        if (mono_hwcap_x86_has_sse3)
-               sse_opts |= SIMD_VERSION_SSE3;
+               features |= MONO_CPU_X86_SSE3;
 
        if (mono_hwcap_x86_has_ssse3)
-               sse_opts |= SIMD_VERSION_SSSE3;
+               features |= MONO_CPU_X86_SSSE3;
 
        if (mono_hwcap_x86_has_sse41)
-               sse_opts |= SIMD_VERSION_SSE41;
+               features |= MONO_CPU_X86_SSE41;
 
        if (mono_hwcap_x86_has_sse42)
-               sse_opts |= SIMD_VERSION_SSE42;
-
-       if (mono_hwcap_x86_has_sse4a)
-               sse_opts |= SIMD_VERSION_SSE4a;
-
-       return sse_opts;
-}
-
-MonoCPUFeatures
-mono_arch_get_cpu_features (void)
-{
-       guint64 features = MONO_CPU_INITED;
+               features |= MONO_CPU_X86_SSE42;
 
        if (mono_hwcap_x86_has_popcnt)
                features |= MONO_CPU_X86_POPCNT;
index 00c0be5fdfebb7501e472f909dd6a7f2b43fc493..55825042dc64c2cfff2ac85bb29dff489532e2c3 100644 (file)
@@ -916,19 +916,6 @@ mono_arch_cpu_optimizations (guint32 *exclude_mask)
        return 0;
 }
 
-/*
- * This function test for all SIMD functions supported.
- *
- * Returns a bitmask corresponding to all supported versions.
- *
- */
-guint32
-mono_arch_cpu_enumerate_simd_versions (void)
-{
-       /* SIMD is currently unimplemented */
-       return 0;
-}
-
 gboolean
 mono_arm_is_hard_float (void)
 {
index 8452d6073f9b71e0210b6b8f3dbd337b21cf1241..aa019c5e37adc70649c7ad4daccc954bc6d8d719 100644 (file)
@@ -258,12 +258,6 @@ mono_arch_cpu_optimizations (guint32 *exclude_mask)
        return 0;
 }
 
-guint32
-mono_arch_cpu_enumerate_simd_versions (void)
-{
-       return 0;
-}
-
 void
 mono_arch_register_lowlevel_calls (void)
 {
index 6f6fdba6699ef38f22c62528efc9e6603b0754d0..c816d01596a1d85388bbd5f1a138e5a8e48e99af 100644 (file)
@@ -720,19 +720,6 @@ mono_arch_cpu_optimizations (guint32 *exclude_mask)
        return opts;
 }
 
-/*
- * This function test for all SIMD functions supported.
- *
- * Returns a bitmask corresponding to all supported versions.
- *
- */
-guint32
-mono_arch_cpu_enumerate_simd_versions (void)
-{
-       /* SIMD is currently unimplemented */
-       return 0;
-}
-
 GList *
 mono_arch_get_allocatable_int_vars (MonoCompile *cfg)
 {
index 1b2e38a01bed5b41fb60b498dd667f6e6d619966..0d65d4b88fb4eb74c0909b0b56981626d3cb1b64 100644 (file)
@@ -617,19 +617,6 @@ mono_arch_cpu_optimizations (guint32 *exclude_mask)
        return opts;
 }
 
-/*
- * This function test for all SIMD functions supported.
- *
- * Returns a bitmask corresponding to all supported versions.
- *
- */
-guint32
-mono_arch_cpu_enumerate_simd_versions (void)
-{
-       /* SIMD is currently unimplemented */
-       return 0;
-}
-
 #ifdef __mono_ppc64__
 #define CASE_PPC32(c)
 #define CASE_PPC64(c)  case c:
index f43a213ea71fef5357f4471c68bdaa9362bf16e9..6d46c884f8c8a70d7d15d18556aef2b523c114d7 100644 (file)
@@ -136,12 +136,6 @@ mono_arch_cpu_optimizations (guint32 *exclude_mask)
        return 0;
 }
 
-guint32
-mono_arch_cpu_enumerate_simd_versions (void)
-{
-       return 0;
-}
-
 gboolean
 mono_arch_have_fast_tls (void)
 {
index 2e7b2b7cc9cc5ed71500a05efbd9b42d55a9f214..7771fec126dc0bc3b24be5b68025171d381f8a95 100644 (file)
@@ -6721,31 +6721,6 @@ mono_arch_get_seq_point_info (MonoDomain *domain, guint8 *code)
 
 #endif
 
-/*------------------------------------------------------------------*/
-/*                                                                  */
-/* Name            - mono_arch_cpu_enumerate_simd_versions.                */
-/*                                                                  */
-/* Function - If this CPU supports vector operations then it        */
-/*            supports the equivalent of SSE1-4.                    */
-/*                                                                  */
-/*------------------------------------------------------------------*/
-
-guint32
-mono_arch_cpu_enumerate_simd_versions (void)
-{
-       guint32 sseOpts = 0;
-
-       if (mono_hwcap_s390x_has_vec)
-               sseOpts = (SIMD_VERSION_SSE1  | SIMD_VERSION_SSE2 |
-                          SIMD_VERSION_SSE3  | SIMD_VERSION_SSSE3 |
-                          SIMD_VERSION_SSE41 | SIMD_VERSION_SSE42 |
-                          SIMD_VERSION_SSE4a);
-
-       return (sseOpts);
-}
-
-/*========================= End of Function ========================*/
-
 /*------------------------------------------------------------------*/
 /*                                                                  */
 /* Name            - mono_arch_opcode_supported.                           */
index 0b4b7fccd975d8bf6af92fce2d137a7864d0a942..e5bce3815348d69efcee346a825025aa4cef951e 100644 (file)
@@ -246,19 +246,6 @@ mono_arch_cpu_optimizations (guint32 *exclude_mask)
        return opts;
 }
 
-/*
- * This function test for all SIMD functions supported.
- *
- * Returns a bitmask corresponding to all supported versions.
- *
- */
-guint32
-mono_arch_cpu_enumerate_simd_versions (void)
-{
-       /* SIMD is currently unimplemented */
-       return 0;
-}
-
 #ifdef __GNUC__
 #define flushi(addr)    __asm__ __volatile__ ("iflush %0"::"r"(addr):"memory")
 #else /* assume Sun's compiler */
index 6840bec69aacd7162198e492ef356aa9f05db156..8f1eef7f0c150dfb7196c2fe0a5256d4c4bb6003 100644 (file)
@@ -461,12 +461,6 @@ mono_arch_build_imt_trampoline (MonoVTable *vtable, MonoDomain *domain, MonoIMTC
        g_error ("mono_arch_build_imt_trampoline");
 }
 
-guint32
-mono_arch_cpu_enumerate_simd_versions (void)
-{
-       return 0;
-}
-
 guint32
 mono_arch_cpu_optimizations (guint32 *exclude_mask)
 {
index fd66c80e8efeb7fe068b4bd6fd3b9644748bfa32..464dc5d969d61762a1cfdf57c3e88b8390847923 100644 (file)
@@ -784,39 +784,30 @@ mono_arch_cpu_optimizations (guint32 *exclude_mask)
        return opts;
 }
 
-/*
- * This function test for all SSE functions supported.
- *
- * Returns a bitmask corresponding to all supported versions.
- * 
- */
-guint32
-mono_arch_cpu_enumerate_simd_versions (void)
+MonoCPUFeatures
+mono_arch_get_cpu_features (void)
 {
-       guint32 sse_opts = 0;
+       guint64 features = MONO_CPU_INITED;
 
        if (mono_hwcap_x86_has_sse1)
-               sse_opts |= SIMD_VERSION_SSE1;
+               features |= MONO_CPU_X86_SSE;
 
        if (mono_hwcap_x86_has_sse2)
-               sse_opts |= SIMD_VERSION_SSE2;
+               features |= MONO_CPU_X86_SSE2;
 
        if (mono_hwcap_x86_has_sse3)
-               sse_opts |= SIMD_VERSION_SSE3;
+               features |= MONO_CPU_X86_SSE3;
 
        if (mono_hwcap_x86_has_ssse3)
-               sse_opts |= SIMD_VERSION_SSSE3;
+               features |= MONO_CPU_X86_SSSE3;
 
        if (mono_hwcap_x86_has_sse41)
-               sse_opts |= SIMD_VERSION_SSE41;
+               features |= MONO_CPU_X86_SSE41;
 
        if (mono_hwcap_x86_has_sse42)
-               sse_opts |= SIMD_VERSION_SSE42;
-
-       if (mono_hwcap_x86_has_sse4a)
-               sse_opts |= SIMD_VERSION_SSE4a;
+               features |= MONO_CPU_X86_SSE42;
 
-       return sse_opts;
+       return (MonoCPUFeatures)features;
 }
 
 /*
index 145c140fb456f5a96f322caa639f20349ccf19d3..08c21ad418898c92d0dcba9446630c2554155652 100644 (file)
@@ -4335,7 +4335,7 @@ mini_get_cpu_features (MonoCompile* cfg)
                // detect current CPU features if we are in JIT mode or AOT with use_current_cpu flag.
 #if defined(ENABLE_LLVM)
                features = mono_llvm_get_cpu_features (); // llvm has a nice built-in API to detect features
-#elif defined(TARGET_AMD64)
+#elif defined(TARGET_AMD64) || defined(TARGET_X86)
                features = mono_arch_get_cpu_features ();
 #endif
        }
index a0bd7203c6ef4ac6fb172a411e63292a8867b035..0e75d01d8f667a84852a6c6a0685a256517abc9d 100644 (file)
@@ -2783,28 +2783,6 @@ char* mono_get_method_from_ip (void *ip);
 
 /* SIMD support */
 
-/*
-This enum MUST be kept in sync with its managed mirror Mono.Simd.AccelMode.
- */
-enum {
-       SIMD_VERSION_SSE1       = 1 << 0,
-       SIMD_VERSION_SSE2       = 1 << 1,
-       SIMD_VERSION_SSE3       = 1 << 2,
-       SIMD_VERSION_SSSE3      = 1 << 3,
-       SIMD_VERSION_SSE41      = 1 << 4,
-       SIMD_VERSION_SSE42      = 1 << 5,
-       SIMD_VERSION_SSE4a      = 1 << 6,
-       SIMD_VERSION_ALL        = SIMD_VERSION_SSE1 | SIMD_VERSION_SSE2 |
-                         SIMD_VERSION_SSE3 | SIMD_VERSION_SSSE3 |
-                         SIMD_VERSION_SSE41 | SIMD_VERSION_SSE42 |
-                         SIMD_VERSION_SSE4a,
-
-       /* this value marks the end of the bit indexes used in 
-        * this emum.
-        */
-       SIMD_VERSION_INDEX_END = 6
-};
-
 typedef enum {
        /* Used for lazy initialization */
        MONO_CPU_INITED         = 1 << 0,
@@ -2968,7 +2946,6 @@ typedef enum {
 } SimdOp;
 
 const char *mono_arch_xregname (int reg);
-guint32     mono_arch_cpu_enumerate_simd_versions (void);
 MonoCPUFeatures mono_arch_get_cpu_features (void);
 
 #ifdef MONO_ARCH_SIMD_INTRINSICS
index 684aab360b08c46428cdf0cbb5720dc4215753a4..95367010fe36ec97fc3ac11de389b46128a998be 100644 (file)
@@ -79,6 +79,20 @@ mono_simd_intrinsics_init (void)
 
 #define IS_DEBUG_ON(cfg) ((cfg)->verbose_level >= 3)
 #define DEBUG(a) do { if (IS_DEBUG_ON(cfg)) { a; } } while (0)
+
+/*
+This enum MUST be kept in sync with its managed mirror Mono.Simd.AccelMode.
+ */
+enum {
+       SIMD_VERSION_SSE1       = 1 << 0,
+       SIMD_VERSION_SSE2       = 1 << 1,
+       SIMD_VERSION_SSE3       = 1 << 2,
+       SIMD_VERSION_SSSE3      = 1 << 3,
+       SIMD_VERSION_SSE41      = 1 << 4,
+       SIMD_VERSION_SSE42      = 1 << 5,
+       SIMD_VERSION_SSE4a      = 1 << 6,
+};
+
 enum {
        SIMD_EMIT_BINARY,
        SIMD_EMIT_UNARY,
@@ -118,403 +132,403 @@ enum {
 typedef struct {
        guint16 name;
        guint16 opcode;
-       guint8 simd_version_flags;
+       guint32 simd_version;
        guint8 simd_emit_mode : 4;
        guint8 flags : 4;
 } SimdIntrinsic;
 
 static const SimdIntrinsic vector4f_intrinsics[] = {
-       { 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 }
+       { SN_ctor, OP_EXPAND_R4, MONO_CPU_X86_SSE, SIMD_EMIT_CTOR },
+       { SN_AddSub, OP_ADDSUBPS, MONO_CPU_X86_SSE3, SIMD_EMIT_BINARY},
+       { SN_AndNot, OP_ANDNPS, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY},
+       { SN_CompareEqual, OP_COMPPS, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY, SIMD_COMP_EQ },
+       { SN_CompareLessEqual, OP_COMPPS, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY, SIMD_COMP_LE },
+       { SN_CompareLessThan, OP_COMPPS, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY, SIMD_COMP_LT },
+       { SN_CompareNotEqual, OP_COMPPS, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY, SIMD_COMP_NEQ },
+       { SN_CompareNotLessEqual, OP_COMPPS, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY, SIMD_COMP_NLE },
+       { SN_CompareNotLessThan, OP_COMPPS, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY, SIMD_COMP_NLT },
+       { SN_CompareOrdered, OP_COMPPS, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY, SIMD_COMP_ORD },
+       { SN_CompareUnordered, OP_COMPPS, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY, SIMD_COMP_UNORD },
+       { SN_ConvertToDouble, OP_CVTPS2PD, MONO_CPU_X86_SSE2, SIMD_EMIT_UNARY },
+       { SN_ConvertToInt, OP_CVTPS2DQ, MONO_CPU_X86_SSE2, SIMD_EMIT_UNARY },
+       { SN_ConvertToIntTruncated, OP_CVTTPS2DQ, MONO_CPU_X86_SSE2, SIMD_EMIT_UNARY },
+       { SN_DuplicateHigh, OP_DUPPS_HIGH, MONO_CPU_X86_SSE3, SIMD_EMIT_UNARY },
+       { SN_DuplicateLow, OP_DUPPS_LOW, MONO_CPU_X86_SSE3, SIMD_EMIT_UNARY },
+       { SN_HorizontalAdd, OP_HADDPS, MONO_CPU_X86_SSE3, SIMD_EMIT_BINARY },
+       { SN_HorizontalSub, OP_HSUBPS, MONO_CPU_X86_SSE3, SIMD_EMIT_BINARY },   
+       { SN_InterleaveHigh, OP_UNPACK_HIGHPS, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_InterleaveLow, OP_UNPACK_LOWPS, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_InvSqrt, OP_RSQRTPS, MONO_CPU_X86_SSE, SIMD_EMIT_UNARY },
+       { SN_LoadAligned, 0, MONO_CPU_X86_SSE, SIMD_EMIT_LOAD_ALIGNED },
+       { SN_Max, OP_MAXPS, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_Min, OP_MINPS, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_PrefetchTemporalAllCacheLevels, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_0 },
+       { SN_PrefetchTemporal1stLevelCache, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_1 },
+       { SN_PrefetchTemporal2ndLevelCache, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_2 },
+       { SN_PrefetchNonTemporal, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_NTA },
+       { SN_Reciprocal, OP_RCPPS, MONO_CPU_X86_SSE, SIMD_EMIT_UNARY },
+       { SN_Shuffle, OP_PSHUFLED, MONO_CPU_X86_SSE, SIMD_EMIT_SHUFFLE },
+       { SN_Sqrt, OP_SQRTPS, MONO_CPU_X86_SSE, SIMD_EMIT_UNARY },
+       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, MONO_CPU_X86_SSE, SIMD_EMIT_STORE },
+       { SN_StoreNonTemporal, OP_STOREX_NTA_MEMBASE_REG, MONO_CPU_X86_SSE, SIMD_EMIT_STORE },
+       { SN_get_W, 3, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_X, 0, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_Y, 1, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_Z, 2, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_op_Addition, OP_ADDPS, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseAnd, OP_ANDPS, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseOr, OP_ORPS, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_Division, OP_DIVPS, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_Equality, OP_COMPPS, MONO_CPU_X86_SSE, SIMD_EMIT_EQUALITY, SIMD_COMP_EQ },
+       { SN_op_ExclusiveOr, OP_XORPS, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_Explicit, 0, MONO_CPU_X86_SSE, SIMD_EMIT_CAST }, 
+       { SN_op_Inequality, OP_COMPPS, MONO_CPU_X86_SSE, SIMD_EMIT_EQUALITY, SIMD_COMP_NEQ },
+       { SN_op_Multiply, OP_MULPS, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_Subtraction, OP_SUBPS, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_set_W, 3, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_X, 0, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_Y, 1, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_Z, 2, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER }
 };
 
 static const SimdIntrinsic vector2d_intrinsics[] = {
-       { 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 },
+       { SN_ctor, OP_EXPAND_R8, MONO_CPU_X86_SSE, SIMD_EMIT_CTOR },
+       { SN_AddSub, OP_ADDSUBPD, MONO_CPU_X86_SSE3, SIMD_EMIT_BINARY,},
+       { SN_AndNot, OP_ANDNPD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_CompareEqual, OP_COMPPD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY, SIMD_COMP_EQ },
+       { SN_CompareLessEqual, OP_COMPPD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY, SIMD_COMP_LE },
+       { SN_CompareLessThan, OP_COMPPD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY, SIMD_COMP_LT },
+       { SN_CompareNotEqual, OP_COMPPD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY, SIMD_COMP_NEQ },
+       { SN_CompareNotLessEqual, OP_COMPPD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY, SIMD_COMP_NLE },
+       { SN_CompareNotLessThan, OP_COMPPD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY, SIMD_COMP_NLT },
+       { SN_CompareOrdered, OP_COMPPD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY, SIMD_COMP_ORD },
+       { SN_CompareUnordered, OP_COMPPD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY, SIMD_COMP_UNORD },
+       { SN_ConvertToFloat, OP_CVTPD2PS, MONO_CPU_X86_SSE2, SIMD_EMIT_UNARY },
+       { SN_ConvertToInt, OP_CVTPD2DQ, MONO_CPU_X86_SSE2, SIMD_EMIT_UNARY },
+       { SN_ConvertToIntTruncated, OP_CVTTPD2DQ, MONO_CPU_X86_SSE2, SIMD_EMIT_UNARY },
+       { SN_Duplicate, OP_DUPPD, MONO_CPU_X86_SSE3, SIMD_EMIT_UNARY },
+       { SN_HorizontalAdd, OP_HADDPD, MONO_CPU_X86_SSE3, SIMD_EMIT_BINARY },
+       { SN_HorizontalSub, OP_HSUBPD, MONO_CPU_X86_SSE3, SIMD_EMIT_BINARY },   
+       { SN_InterleaveHigh, OP_UNPACK_HIGHPD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_InterleaveLow, OP_UNPACK_LOWPD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_LoadAligned, 0, MONO_CPU_X86_SSE, SIMD_EMIT_LOAD_ALIGNED },
+       { SN_Max, OP_MAXPD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_Min, OP_MINPD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_PrefetchTemporalAllCacheLevels, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_0 },
+       { SN_PrefetchTemporal1stLevelCache, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_1 },
+       { SN_PrefetchTemporal2ndLevelCache, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_2 },
+       { SN_PrefetchNonTemporal, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_NTA },
+       { SN_Shuffle, OP_SHUFPD, MONO_CPU_X86_SSE, SIMD_EMIT_SHUFFLE },
+       { SN_Sqrt, OP_SQRTPD, MONO_CPU_X86_SSE, SIMD_EMIT_UNARY },
+       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, MONO_CPU_X86_SSE, SIMD_EMIT_STORE },
+       { SN_get_X, 0, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER_QWORD },
+       { SN_get_Y, 1, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER_QWORD },
+       { SN_op_Addition, OP_ADDPD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseAnd, OP_ANDPD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseOr, OP_ORPD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_Division, OP_DIVPD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_ExclusiveOr, OP_XORPD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_Explicit, 0, MONO_CPU_X86_SSE, SIMD_EMIT_CAST }, 
+       { SN_op_Multiply, OP_MULPD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_Subtraction, OP_SUBPD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_set_X, 0, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_Y, 1, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
 };
 
 static const SimdIntrinsic vector2ul_intrinsics[] = {
-       { 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 },
+       { SN_ctor, OP_EXPAND_I8, MONO_CPU_X86_SSE, SIMD_EMIT_CTOR },
+       { SN_CompareEqual, OP_PCMPEQQ, MONO_CPU_X86_SSE41, SIMD_EMIT_BINARY },
+       { SN_LoadAligned, 0, MONO_CPU_X86_SSE, SIMD_EMIT_LOAD_ALIGNED },
+       { SN_PrefetchTemporalAllCacheLevels, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_0 },
+       { SN_PrefetchTemporal1stLevelCache, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_1 },
+       { SN_PrefetchTemporal2ndLevelCache, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_2 },
+       { SN_PrefetchNonTemporal, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_NTA },
+       { SN_Shuffle, OP_SHUFPD, MONO_CPU_X86_SSE, SIMD_EMIT_SHUFFLE },
+       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, MONO_CPU_X86_SSE, SIMD_EMIT_STORE },
+       { SN_UnpackHigh, OP_UNPACK_HIGHQ, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_UnpackLow, OP_UNPACK_LOWQ, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_get_X, 0, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER_QWORD },
+       { SN_get_Y, 1, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER_QWORD },
+       { SN_op_Addition, OP_PADDQ, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseAnd, OP_PAND, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseOr, OP_POR, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_ExclusiveOr, OP_PXOR, SIMD_EMIT_BINARY, MONO_CPU_X86_SSE },
+       { SN_op_Explicit, 0, MONO_CPU_X86_SSE, SIMD_EMIT_CAST },
+       { SN_op_LeftShift, OP_PSHLQ, MONO_CPU_X86_SSE, SIMD_EMIT_SHIFT },
+       { SN_op_Multiply, OP_PMULQ, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_RightShift, OP_PSHRQ, MONO_CPU_X86_SSE, SIMD_EMIT_SHIFT },
+       { SN_op_Subtraction, OP_PSUBQ, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_set_X, 0, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_Y, 1, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
 };
 
 static const SimdIntrinsic vector2l_intrinsics[] = {
-       { 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 },
+       { SN_ctor, OP_EXPAND_I8, MONO_CPU_X86_SSE, SIMD_EMIT_CTOR },
+       { SN_CompareEqual, OP_PCMPEQQ, MONO_CPU_X86_SSE41, SIMD_EMIT_BINARY },
+       { SN_CompareGreaterThan, OP_PCMPGTQ, MONO_CPU_X86_SSE42, SIMD_EMIT_BINARY },
+       { SN_LoadAligned, 0, MONO_CPU_X86_SSE, SIMD_EMIT_LOAD_ALIGNED },
+       { SN_LogicalRightShift, OP_PSHRQ, MONO_CPU_X86_SSE, SIMD_EMIT_SHIFT },
+       { SN_PrefetchTemporalAllCacheLevels, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_0 },
+       { SN_PrefetchTemporal1stLevelCache, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_1 },
+       { SN_PrefetchTemporal2ndLevelCache, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_2 },
+       { SN_PrefetchNonTemporal, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_NTA },
+       { SN_Shuffle, OP_SHUFPD, MONO_CPU_X86_SSE, SIMD_EMIT_SHUFFLE },
+       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, MONO_CPU_X86_SSE, SIMD_EMIT_STORE },
+       { SN_UnpackHigh, OP_UNPACK_HIGHQ, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_UnpackLow, OP_UNPACK_LOWQ, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_get_X, 0, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER_QWORD },
+       { SN_get_Y, 1, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER_QWORD },
+       { SN_op_Addition, OP_PADDQ, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseAnd, OP_PAND, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseOr, OP_POR, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_ExclusiveOr, OP_PXOR, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_Explicit, 0, MONO_CPU_X86_SSE, SIMD_EMIT_CAST },
+       { SN_op_LeftShift, OP_PSHLQ, MONO_CPU_X86_SSE, SIMD_EMIT_SHIFT },
+       { SN_op_Multiply, OP_PMULQ, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_Subtraction, OP_PSUBQ, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_set_X, 0, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_Y, 1, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
 };
 
 static const SimdIntrinsic vector4ui_intrinsics[] = {
-       { 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 },
+       { SN_ctor, OP_EXPAND_I4, MONO_CPU_X86_SSE, SIMD_EMIT_CTOR },
+       { SN_ArithmeticRightShift, OP_PSARD, MONO_CPU_X86_SSE, SIMD_EMIT_SHIFT },
+       { SN_CompareEqual, OP_PCMPEQD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_LoadAligned, 0, MONO_CPU_X86_SSE, SIMD_EMIT_LOAD_ALIGNED },
+       { SN_Max, OP_PMAXD_UN, MONO_CPU_X86_SSE41, SIMD_EMIT_BINARY },
+       { SN_Min, OP_PMIND_UN, MONO_CPU_X86_SSE41, SIMD_EMIT_BINARY },
+       { SN_PrefetchTemporalAllCacheLevels, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_0 },
+       { SN_PrefetchTemporal1stLevelCache, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_1 },
+       { SN_PrefetchTemporal2ndLevelCache, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_2 },
+       { SN_PrefetchNonTemporal, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_NTA },
+       { SN_Shuffle, OP_PSHUFLED, MONO_CPU_X86_SSE, SIMD_EMIT_SHUFFLE },
+       { SN_SignedPackWithSignedSaturation, OP_PACKD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_SignedPackWithUnsignedSaturation, OP_PACKD_UN, MONO_CPU_X86_SSE41, SIMD_EMIT_BINARY },
+       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, MONO_CPU_X86_SSE, SIMD_EMIT_STORE },
+       { SN_UnpackHigh, OP_UNPACK_HIGHD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_UnpackLow, OP_UNPACK_LOWD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_get_W, 3, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_X, 0, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_Y, 1, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_Z, 2, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_op_Addition, OP_PADDD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseAnd, OP_PAND, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseOr, OP_POR, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_Equality, OP_PCMPEQD, MONO_CPU_X86_SSE, SIMD_EMIT_EQUALITY, SIMD_COMP_EQ },
+       { SN_op_ExclusiveOr, OP_PXOR, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_Explicit, 0, MONO_CPU_X86_SSE, SIMD_EMIT_CAST },
+       { SN_op_Inequality, OP_PCMPEQD, MONO_CPU_X86_SSE, SIMD_EMIT_EQUALITY, SIMD_COMP_NEQ },
+       { SN_op_LeftShift, OP_PSHLD, MONO_CPU_X86_SSE, SIMD_EMIT_SHIFT },
+       { SN_op_Multiply, OP_PMULD, MONO_CPU_X86_SSE41, SIMD_EMIT_BINARY },
+       { SN_op_RightShift, OP_PSHRD, MONO_CPU_X86_SSE, SIMD_EMIT_SHIFT },
+       { SN_op_Subtraction, OP_PSUBD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_set_W, 3, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_X, 0, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_Y, 1, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_Z, 2, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
 };
 
 static const SimdIntrinsic vector4i_intrinsics[] = {
-       { 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 },
+       { SN_ctor, OP_EXPAND_I4, MONO_CPU_X86_SSE, SIMD_EMIT_CTOR },
+       { SN_CompareEqual, OP_PCMPEQD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_CompareGreaterThan, OP_PCMPGTD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_ConvertToDouble, OP_CVTDQ2PD, MONO_CPU_X86_SSE2, SIMD_EMIT_UNARY },
+       { SN_ConvertToFloat, OP_CVTDQ2PS, MONO_CPU_X86_SSE2, SIMD_EMIT_UNARY },
+       { SN_LoadAligned, 0, MONO_CPU_X86_SSE, SIMD_EMIT_LOAD_ALIGNED },
+       { SN_LogicalRightShift, OP_PSHRD, MONO_CPU_X86_SSE, SIMD_EMIT_SHIFT },
+       { SN_Max, OP_PMAXD, MONO_CPU_X86_SSE41, SIMD_EMIT_BINARY },
+       { SN_Min, OP_PMIND, MONO_CPU_X86_SSE41, SIMD_EMIT_BINARY },
+       { SN_PackWithSignedSaturation, OP_PACKD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_PackWithUnsignedSaturation, OP_PACKD_UN, MONO_CPU_X86_SSE41, SIMD_EMIT_BINARY },
+       { SN_PrefetchTemporalAllCacheLevels, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_0 },
+       { SN_PrefetchTemporal1stLevelCache, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_1 },
+       { SN_PrefetchTemporal2ndLevelCache, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_2 },
+       { SN_PrefetchNonTemporal, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_NTA },
+       { SN_Shuffle, OP_PSHUFLED, MONO_CPU_X86_SSE, SIMD_EMIT_SHUFFLE },
+       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, MONO_CPU_X86_SSE, SIMD_EMIT_STORE },
+       { SN_UnpackHigh, OP_UNPACK_HIGHD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_UnpackLow, OP_UNPACK_LOWD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_get_W, 3, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_X, 0, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_Y, 1, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_Z, 2, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_op_Addition, OP_PADDD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseAnd, OP_PAND, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseOr, OP_POR, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_Equality, OP_PCMPEQD, MONO_CPU_X86_SSE, SIMD_EMIT_EQUALITY, SIMD_COMP_EQ },
+       { SN_op_ExclusiveOr, OP_PXOR, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_Explicit, 0, MONO_CPU_X86_SSE, SIMD_EMIT_CAST },
+       { SN_op_Inequality, OP_PCMPEQD, MONO_CPU_X86_SSE, SIMD_EMIT_EQUALITY, SIMD_COMP_NEQ },
+       { SN_op_LeftShift, OP_PSHLD, MONO_CPU_X86_SSE, SIMD_EMIT_SHIFT },
+       { SN_op_Multiply, OP_PMULD, MONO_CPU_X86_SSE41, SIMD_EMIT_BINARY },
+       { SN_op_RightShift, OP_PSARD, MONO_CPU_X86_SSE, SIMD_EMIT_SHIFT },
+       { SN_op_Subtraction, OP_PSUBD, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_set_W, 3, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_X, 0, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_Y, 1, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_Z, 2, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
 };
 
 static const SimdIntrinsic vector8us_intrinsics[] = {
-       { 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 },
+       { SN_ctor, OP_EXPAND_I2, MONO_CPU_X86_SSE, SIMD_EMIT_CTOR },
+       { SN_AddWithSaturation, OP_PADDW_SAT_UN, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_ArithmeticRightShift, OP_PSARW, MONO_CPU_X86_SSE, SIMD_EMIT_SHIFT },
+       { SN_Average, OP_PAVGW_UN, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_CompareEqual, OP_PCMPEQW, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY, MONO_CPU_X86_SSE },
+       { SN_LoadAligned, 0, MONO_CPU_X86_SSE, SIMD_EMIT_LOAD_ALIGNED },
+       { SN_Max, OP_PMAXW_UN, MONO_CPU_X86_SSE41, SIMD_EMIT_BINARY },
+       { SN_Min, OP_PMINW_UN, MONO_CPU_X86_SSE41, SIMD_EMIT_BINARY },
+       { SN_MultiplyStoreHigh, OP_PMULW_HIGH_UN, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_PrefetchTemporalAllCacheLevels, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_0 },
+       { SN_PrefetchTemporal1stLevelCache, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_1 },
+       { SN_PrefetchTemporal2ndLevelCache, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_2 },
+       { SN_PrefetchNonTemporal, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_NTA },
+       { SN_ShuffleHigh, OP_PSHUFLEW_HIGH, MONO_CPU_X86_SSE, SIMD_EMIT_SHUFFLE },
+       { SN_ShuffleLow, OP_PSHUFLEW_LOW, MONO_CPU_X86_SSE, SIMD_EMIT_SHUFFLE },
+       { SN_SignedPackWithSignedSaturation, OP_PACKW, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_SignedPackWithUnsignedSaturation, OP_PACKW_UN, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, MONO_CPU_X86_SSE, SIMD_EMIT_STORE },
+       { SN_SubtractWithSaturation, OP_PSUBW_SAT_UN, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_UnpackHigh, OP_UNPACK_HIGHW, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_UnpackLow, OP_UNPACK_LOWW, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_get_V0, 0, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V1, 1, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V2, 2, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V3, 3, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V4, 4, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V5, 5, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V6, 6, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V7, 7, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_op_Addition, OP_PADDW, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseAnd, OP_PAND, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseOr, OP_POR, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_Equality, OP_PCMPEQW, MONO_CPU_X86_SSE, SIMD_EMIT_EQUALITY, SIMD_COMP_EQ },
+       { SN_op_ExclusiveOr, OP_PXOR, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_Explicit, 0, MONO_CPU_X86_SSE, SIMD_EMIT_CAST },
+       { SN_op_Inequality, OP_PCMPEQW, MONO_CPU_X86_SSE, SIMD_EMIT_EQUALITY, SIMD_COMP_NEQ },
+       { SN_op_LeftShift, OP_PSHLW, MONO_CPU_X86_SSE, SIMD_EMIT_SHIFT },
+       { SN_op_Multiply, OP_PMULW, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_RightShift, OP_PSHRW, MONO_CPU_X86_SSE, SIMD_EMIT_SHIFT },
+       { SN_op_Subtraction, OP_PSUBW, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_set_V0, 0, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V1, 1, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V2, 2, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V3, 3, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V4, 4, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V5, 5, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V6, 6, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V7, 7, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
 };
 
 static const SimdIntrinsic vector8s_intrinsics[] = {
-       { 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 },
+       { SN_ctor, OP_EXPAND_I2, MONO_CPU_X86_SSE, SIMD_EMIT_CTOR },
+       { SN_AddWithSaturation, OP_PADDW_SAT, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_CompareEqual, OP_PCMPEQW, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_CompareGreaterThan, OP_PCMPGTW, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_LoadAligned, 0, MONO_CPU_X86_SSE, SIMD_EMIT_LOAD_ALIGNED },
+       { SN_LogicalRightShift, OP_PSHRW, MONO_CPU_X86_SSE, SIMD_EMIT_SHIFT },
+       { SN_Max, OP_PMAXW, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_Min, OP_PMINW, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_MultiplyStoreHigh, OP_PMULW_HIGH, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_PackWithSignedSaturation, OP_PACKW, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_PackWithUnsignedSaturation, OP_PACKW_UN, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_PrefetchTemporalAllCacheLevels, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_0 },
+       { SN_PrefetchTemporal1stLevelCache, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_1 },
+       { SN_PrefetchTemporal2ndLevelCache, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_2 },
+       { SN_PrefetchNonTemporal, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_NTA },
+       { SN_ShuffleHigh, OP_PSHUFLEW_HIGH, MONO_CPU_X86_SSE, SIMD_EMIT_SHUFFLE },
+       { SN_ShuffleLow, OP_PSHUFLEW_LOW, MONO_CPU_X86_SSE, SIMD_EMIT_SHUFFLE },
+       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, MONO_CPU_X86_SSE, SIMD_EMIT_STORE },
+       { SN_SubtractWithSaturation, OP_PSUBW_SAT_UN, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_UnpackHigh, OP_UNPACK_HIGHW, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_UnpackLow, OP_UNPACK_LOWW, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_get_V0, 0, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V1, 1, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V2, 2, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V3, 3, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V4, 4, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V5, 5, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V6, 6, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V7, 7, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_op_Addition, OP_PADDW, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseAnd, OP_PAND, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseOr, OP_POR, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_Equality, OP_PCMPEQW, MONO_CPU_X86_SSE, SIMD_EMIT_EQUALITY, SIMD_COMP_EQ },
+       { SN_op_ExclusiveOr, OP_PXOR, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_Explicit, 0, MONO_CPU_X86_SSE, SIMD_EMIT_CAST },
+       { SN_op_Inequality, OP_PCMPEQW, MONO_CPU_X86_SSE, SIMD_EMIT_EQUALITY, SIMD_COMP_NEQ },
+       { SN_op_LeftShift, OP_PSHLW, MONO_CPU_X86_SSE, SIMD_EMIT_SHIFT },
+       { SN_op_Multiply, OP_PMULW, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_RightShift, OP_PSARW, MONO_CPU_X86_SSE, SIMD_EMIT_SHIFT },
+       { SN_op_Subtraction, OP_PSUBW, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_set_V0, 0, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V1, 1, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V2, 2, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V3, 3, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V4, 4, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V5, 5, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V6, 6, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V7, 7, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
 };
 
 static const SimdIntrinsic vector16b_intrinsics[] = {
-       { 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 },
+       { SN_ctor, OP_EXPAND_I1, MONO_CPU_X86_SSE, SIMD_EMIT_CTOR },
+       { SN_AddWithSaturation, OP_PADDB_SAT_UN, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_Average, OP_PAVGB_UN, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_CompareEqual, OP_PCMPEQB, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_ExtractByteMask, 0, MONO_CPU_X86_SSE, SIMD_EMIT_EXTRACT_MASK },
+       { SN_LoadAligned, 0, MONO_CPU_X86_SSE, SIMD_EMIT_LOAD_ALIGNED },
+       { SN_Max, OP_PMAXB_UN, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_Min, OP_PMINB_UN, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_PrefetchTemporalAllCacheLevels, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_0 },
+       { SN_PrefetchTemporal1stLevelCache, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_1 },
+       { SN_PrefetchTemporal2ndLevelCache, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_2 },
+       { SN_PrefetchNonTemporal, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_NTA },
+       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, MONO_CPU_X86_SSE, SIMD_EMIT_STORE },
+       { SN_SubtractWithSaturation, OP_PSUBB_SAT_UN, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_SumOfAbsoluteDifferences, OP_PSUM_ABS_DIFF, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_UnpackHigh, OP_UNPACK_HIGHB, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_UnpackLow, OP_UNPACK_LOWB, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_get_V0, 0, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V1, 1, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V10, 10, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V11, 11, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V12, 12, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V13, 13, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V14, 14, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V15, 15, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V2, 2, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V3, 3, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V4, 4, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V5, 5, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V6, 6, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V7, 7, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V8, 8, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V9, 9, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_op_Addition, OP_PADDB, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseAnd, OP_PAND, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseOr, OP_POR, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_Equality, OP_PCMPEQB, MONO_CPU_X86_SSE, SIMD_EMIT_EQUALITY, SIMD_COMP_EQ },
+       { SN_op_ExclusiveOr, OP_PXOR, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_Explicit, 0, MONO_CPU_X86_SSE, SIMD_EMIT_CAST },
+       { SN_op_Inequality, OP_PCMPEQB, MONO_CPU_X86_SSE, SIMD_EMIT_EQUALITY, SIMD_COMP_NEQ },
+       { SN_op_Subtraction, OP_PSUBB, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_set_V0, 0, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V1, 1, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V10, 10, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V11, 11, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V12, 12, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V13, 13, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V14, 14, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V15, 15, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V2, 2, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V3, 3, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V4, 4, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V5, 5, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V6, 6, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V7, 7, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V8, 8, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V9, 9, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
 };
 
 /*
@@ -522,66 +536,64 @@ Missing:
 setters
  */
 static const SimdIntrinsic vector16sb_intrinsics[] = {
-       { 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 },
+       { SN_ctor, OP_EXPAND_I1, MONO_CPU_X86_SSE, SIMD_EMIT_CTOR },
+       { SN_AddWithSaturation, OP_PADDB_SAT, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_CompareEqual, OP_PCMPEQB, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_CompareGreaterThan, OP_PCMPGTB, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_ExtractByteMask, 0, MONO_CPU_X86_SSE, SIMD_EMIT_EXTRACT_MASK },
+       { SN_LoadAligned, 0, MONO_CPU_X86_SSE, SIMD_EMIT_LOAD_ALIGNED },
+       { SN_Max, OP_PMAXB, MONO_CPU_X86_SSE41, SIMD_EMIT_BINARY },
+       { SN_Min, OP_PMINB, MONO_CPU_X86_SSE41, SIMD_EMIT_BINARY },
+       { SN_PrefetchTemporalAllCacheLevels, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_0 },
+       { SN_PrefetchTemporal1stLevelCache, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_1 },
+       { SN_PrefetchTemporal2ndLevelCache, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_2 },
+       { SN_PrefetchNonTemporal, 0, MONO_CPU_X86_SSE, SIMD_EMIT_PREFETCH, SIMD_PREFETCH_MODE_NTA },
+       { SN_StoreAligned, OP_STOREX_ALIGNED_MEMBASE_REG, MONO_CPU_X86_SSE, SIMD_EMIT_STORE },
+       { SN_SubtractWithSaturation, OP_PSUBB_SAT, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_UnpackHigh, OP_UNPACK_HIGHB, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_UnpackLow, OP_UNPACK_LOWB, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_get_V0, 0, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V1, 1, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V10, 10, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V11, 11, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V12, 12, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V13, 13, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V14, 14, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V15, 15, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V2, 2, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V3, 3, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V4, 4, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V5, 5, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V6, 6, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V7, 7, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V8, 8, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_get_V9, 9, MONO_CPU_X86_SSE, SIMD_EMIT_GETTER },
+       { SN_op_Addition, OP_PADDB, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseAnd, OP_PAND, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_BitwiseOr, OP_POR, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_Equality, OP_PCMPEQB, MONO_CPU_X86_SSE, SIMD_EMIT_EQUALITY, SIMD_COMP_EQ },
+       { SN_op_ExclusiveOr, OP_PXOR, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_Explicit, 0, MONO_CPU_X86_SSE, SIMD_EMIT_CAST },
+       { SN_op_Inequality, OP_PCMPEQB, MONO_CPU_X86_SSE, SIMD_EMIT_EQUALITY, SIMD_COMP_NEQ },
+       { SN_op_Subtraction, OP_PSUBB, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_set_V0, 0, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V1, 1, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V10, 10, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V11, 11, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V12, 12, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V13, 13, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V14, 14, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V15, 15, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V2, 2, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V3, 3, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V4, 4, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V5, 5, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V6, 6, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V7, 7, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V8, 8, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
+       { SN_set_V9, 9, MONO_CPU_X86_SSE, SIMD_EMIT_SETTER },
 };
 
-static guint32 simd_supported_versions;
-
 static MonoInst* emit_sys_numerics_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args);
 static MonoInst* emit_sys_numerics_vectors_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args);
 
@@ -603,8 +615,6 @@ typedef enum {
 void
 mono_simd_intrinsics_init (void)
 {
-       simd_supported_versions = mono_arch_cpu_enumerate_simd_versions ();
-       /*TODO log the supported flags*/
 }
 
 static gboolean
@@ -1874,28 +1884,6 @@ simd_intrinsic_emit_const (const SimdIntrinsic *intrinsic, MonoCompile *cfg, Mon
        return ins;
 }
 
-static const char *
-simd_version_name (guint32 version)
-{
-       switch (version) {
-       case SIMD_VERSION_SSE1:
-               return "sse1";
-       case SIMD_VERSION_SSE2:
-               return "sse2";
-       case SIMD_VERSION_SSE3:
-               return "sse3";
-       case SIMD_VERSION_SSSE3:
-               return "ssse3";
-       case SIMD_VERSION_SSE41:
-               return "sse41";
-       case SIMD_VERSION_SSE42:
-               return "sse42";
-       case SIMD_VERSION_SSE4a:
-               return "sse4a";
-       }
-       return "n/a";
-}
-
 static MonoInst*
 emit_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args, const SimdIntrinsic *intrinsics, guint32 size)
 {
@@ -1913,17 +1901,14 @@ emit_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
                        mono_print_ins (args [i]);
                }
        }
-       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): ", m_class_get_name (cmethod->klass), 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");
+       if (result->simd_version) {
+               MonoCPUFeatures features = mini_get_cpu_features (cfg);
+               if ((result->simd_version & features) == 0) {
+                       printf ("function %s::%s/%d requires one of unsuported SIMD instruction set(s). \n", m_class_get_name (cmethod->klass), cmethod->name, fsig->param_count);
+                       if (IS_DEBUG_ON (cfg))
+                               printf ("function %s::%s/%d requires one of unsuported SIMD instruction set(s). \n", m_class_get_name (cmethod->klass), cmethod->name, fsig->param_count);
+                       return NULL;
                }
-               return NULL;
        }
 
        switch (result->simd_emit_mode) {
@@ -2040,12 +2025,34 @@ emit_array_extension_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMeth
        return NULL;
 }
 
+static guint32
+get_simd_supported_versions (MonoCompile *cfg)
+{
+       MonoCPUFeatures features = mini_get_cpu_features (cfg);
+       guint32 versions = 0;
+
+       if (features & MONO_CPU_X86_SSE)
+               versions |= SIMD_VERSION_SSE1;
+       if (features & MONO_CPU_X86_SSE2)
+               versions |= SIMD_VERSION_SSE2;
+       if (features & MONO_CPU_X86_SSE3)
+               versions |= SIMD_VERSION_SSE3;
+       if (features & MONO_CPU_X86_SSSE3)
+               versions |= SIMD_VERSION_SSSE3;
+       if (features & MONO_CPU_X86_SSE41)
+               versions |= SIMD_VERSION_SSE41;
+       if (features & MONO_CPU_X86_SSE42)
+               versions |= SIMD_VERSION_SSE42;
+       return versions;
+}
+
 static MonoInst*
 emit_simd_runtime_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args)
 {
        if (!strcmp ("get_AccelMode", cmethod->name) && fsig->param_count == 0) {
                MonoInst *ins;
-               EMIT_NEW_ICONST (cfg, ins, simd_supported_versions);
+               guint32 versions = get_simd_supported_versions (cfg);
+               EMIT_NEW_ICONST (cfg, ins, versions);
                return ins;
        }
        return NULL;
@@ -2183,14 +2190,14 @@ static const SimdIntrinsic vector2_intrinsics[] = {
        { SN_ctor, OP_EXPAND_R4 },
        { SN_Abs },
        { SN_Dot, OP_DPPS },
-       { SN_Equals, OP_COMPPS, SIMD_VERSION_SSE1, SIMD_EMIT_EQUALITY, SIMD_COMP_EQ },
-       { SN_Max, OP_MAXPS, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
-       { SN_Min, OP_MINPS, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
-       { SN_SquareRoot, OP_SQRTPS, SIMD_VERSION_SSE1, SIMD_EMIT_UNARY },
-       { SN_op_Addition, OP_ADDPS, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
-       { SN_op_Division, OP_DIVPS, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
-       { SN_op_Multiply, OP_MULPS, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
-       { SN_op_Subtraction, OP_SUBPS, SIMD_VERSION_SSE1, SIMD_EMIT_BINARY },
+       { SN_Equals, OP_COMPPS, MONO_CPU_X86_SSE, SIMD_EMIT_EQUALITY, SIMD_COMP_EQ },
+       { SN_Max, OP_MAXPS, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_Min, OP_MINPS, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_SquareRoot, OP_SQRTPS, MONO_CPU_X86_SSE, SIMD_EMIT_UNARY },
+       { SN_op_Addition, OP_ADDPS, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_Division, OP_DIVPS, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_Multiply, OP_MULPS, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
+       { SN_op_Subtraction, OP_SUBPS, MONO_CPU_X86_SSE, SIMD_EMIT_BINARY },
 };
 
 static MonoInst*
@@ -2294,7 +2301,7 @@ emit_vector_is_hardware_accelerated_intrinsic (MonoCompile *cfg)
 {
        MonoInst *ins;
 
-       if (simd_supported_versions)
+       if (get_simd_supported_versions (cfg))
                EMIT_NEW_ICONST (cfg, ins, 1);
        else
                EMIT_NEW_ICONST (cfg, ins, 0);