driver.c (opt_sets): Added combinations of simd, sse2 and sse3.
authorRodrigo Kumpera <kumpera@gmail.com>
Tue, 7 Oct 2008 16:56:53 +0000 (16:56 -0000)
committerRodrigo Kumpera <kumpera@gmail.com>
Tue, 7 Oct 2008 16:56:53 +0000 (16:56 -0000)
mini-x86.c (mono_arch_cpu_optimizazions): Detect sse3 and now
only disable simd intrinsics if no sse2 is detected.

* optflags-def.h: Added sse3.

* simd-intrinsics.c: Avoid generated sse3 intrinsics if the optimization
is disabled.

svn path=/trunk/mono/; revision=115114

mono/mini/driver.c
mono/mini/mini-x86.c
mono/mini/optflags-def.h
mono/mini/simd-intrinsics.c

index 3115aafa77f4a7bd9f42d17610ae7d1f811e9287..7163a10ea6e5114bb23eee1691879fdd0057c42c 100644 (file)
@@ -299,6 +299,9 @@ opt_sets [] = {
        MONO_OPT_FCMOV,
 #ifdef MONO_ARCH_SIMD_INTRINSICS
        MONO_OPT_SIMD,
+       MONO_OPT_SSE2,
+       MONO_OPT_SIMD | MONO_OPT_SSE2,
+       MONO_OPT_SIMD | MONO_OPT_SSE2 | MONO_OPT_SSE3,
 #endif
        MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_INTRINS,
        MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS,
index 7d37ae4eac01125584b670be2912beca314cc0de..689b370d5624fad0fb05b640e5c1524ccfca2328 100644 (file)
@@ -682,9 +682,14 @@ mono_arch_cpu_optimizazions (guint32 *exclude_mask)
                        opts |= MONO_OPT_SSE2;
                else
                        *exclude_mask |= MONO_OPT_SSE2;
+               if (ecx & 1)
+                       opts |= MONO_OPT_SSE3;
+               else
+                       *exclude_mask |= MONO_OPT_SSE3;
+
 #ifdef MONO_ARCH_SIMD_INTRINSICS
-               /*SIMD intrinsics require SSE3.*/
-               if (!(ecx & 1))
+               /*SIMD intrinsics require at least SSE2.*/
+               if (!(opts & MONO_OPT_SSE2))
                        *exclude_mask |= MONO_OPT_SIMD;
 #endif
        }
index 88a9a2bb9186db9aedf15bfdfd1595d1343433a4..1a46c30749d526904c46206ef12c9b0f2e1af66e 100644 (file)
@@ -24,4 +24,5 @@ OPTFLAG(TREEPROP ,22, "treeprop",   "Tree propagation")
 OPTFLAG(SSE2     ,23, "sse2",       "SSE2 instructions on x86")
 OPTFLAG(GSHARED  ,24, "gshared",    "Share generics")
 OPTFLAG(SIMD    ,25, "simd",       "Simd intrinsics")
+OPTFLAG(SSE3    ,26, "sse3",       "SSE3 instructions on x86")
 
index 2b25a0c28b8ce7946f82ec871b05ab0ebaa26bbb..2d682768eae4dc93794e0415ebc02051d5981906 100644 (file)
@@ -24,13 +24,13 @@ TODO add support for indexed versions of simd ops
 TODO to an amd64 port and figure out how to properly handle extractors/.ctor
 TODO make sure locals, arguments and spills are properly aligned.
 TODO add support for fusing a XMOVE into a simd op in mono_spill_global_vars.
-TODO make it work under SSE2 by emulating the few SSE3 opcodes.
 TODO add stuff to man pages
 TODO document this under /docs
 TODO make passing a xmm as argument not cause it to be LDADDR'ed (introduce an OP_XPUSH)
 TODO revant the .ctor sequence as it looks very fragile, maybe use a var just like iconv_to_r8_raw. 
 TODO figure out what's wrong with OP_STOREX_MEMBASE_REG and OP_STOREX_MEMBASE (the 2nd is for imm operands)
-TODO handle all uses of MONO_OPT_SSE2
+TODO maybe add SSE3 emulation on top of SSE2, or just implement the corresponding functions using SSE2 intrinsics.
+TODO pass simd arguments in registers or, at least, add SSE support for pushing large (>=16) valuetypes 
 
 General notes for SIMD intrinsics.
 
@@ -62,6 +62,7 @@ without a OP_LDADDR.
 #define DEBUG(a) do { if (IS_DEBUG_ON(cfg)) { a; } } while (0)
 enum {
        SIMD_EMIT_BINARY,
+       SIMD_EMIT_BINARY_SSE3,
        SIMD_EMIT_UNARY,
        SIMD_EMIT_GETTER,
        SIMD_EMIT_CTOR,
@@ -83,9 +84,9 @@ typedef struct {
 
 static const SimdIntrinsc vector4f_intrinsics[] = {
        { ".ctor", 0, SIMD_EMIT_CTOR },
-       { "AddSub", OP_ADDSUBPS, SIMD_EMIT_BINARY },
-       { "HorizontalAdd", OP_HADDPS, SIMD_EMIT_BINARY },
-       { "HorizontalSub", OP_HSUBPS, SIMD_EMIT_BINARY },       
+       { "AddSub", OP_ADDSUBPS, SIMD_EMIT_BINARY_SSE3 },
+       { "HorizontalAdd", OP_HADDPS, SIMD_EMIT_BINARY_SSE3 },
+       { "HorizontalSub", OP_HSUBPS, SIMD_EMIT_BINARY_SSE3 },  
        { "InvSqrt", OP_RSQRTPS, SIMD_EMIT_UNARY },
        { "LoadAligned", 0, SIMD_EMIT_LOAD_ALIGNED },
        { "Max", OP_MAXPS, SIMD_EMIT_BINARY },
@@ -507,6 +508,10 @@ emit_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
        }
 
        switch (result->simd_emit_mode) {
+       case SIMD_EMIT_BINARY_SSE3:
+               if (cfg->opt & MONO_OPT_SSE3)
+                       return simd_intrinsic_emit_binary (result, cfg, cmethod, args);
+               return NULL;
        case SIMD_EMIT_BINARY:
                return simd_intrinsic_emit_binary (result, cfg, cmethod, args);
        case SIMD_EMIT_UNARY: