diff druntime/src/compiler/dmd/arrayreal.d @ 1458:e0b2d67cfe7c

Added druntime (this should be removed once it works).
author Robert Clipsham <robert@octarineparrot.com>
date Tue, 02 Jun 2009 17:43:06 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/druntime/src/compiler/dmd/arrayreal.d	Tue Jun 02 17:43:06 2009 +0100
@@ -0,0 +1,241 @@
+/**
+ * Contains SSE2 and MMX versions of certain operations for real.
+ *
+ * Copyright: Copyright Digital Mars 2008 - 2009.
+ * License:   <a href="http://www.boost.org/LICENSE_1_0.txt>Boost License 1.0</a>.
+ * Authors:   Walter Bright, based on code originally written by Burton Radons
+ *
+ *          Copyright Digital Mars 2008 - 2009.
+ * Distributed under the Boost Software License, Version 1.0.
+ *    (See accompanying file LICENSE_1_0.txt or copy at
+ *          http://www.boost.org/LICENSE_1_0.txt)
+ */
+module rt.arrayreal;
+
+import rt.util.cpuid;
+
+version (unittest)
+{
+    private import core.stdc.stdio : printf;
+    /* This is so unit tests will test every CPU variant
+     */
+    int cpuid;
+    const int CPUID_MAX = 1;
+    bool mmx()      { return cpuid == 1 && rt.util.cpuid.mmx(); }
+    bool sse()      { return cpuid == 2 && rt.util.cpuid.sse(); }
+    bool sse2()     { return cpuid == 3 && rt.util.cpuid.sse2(); }
+    bool amd3dnow() { return cpuid == 4 && rt.util.cpuid.amd3dnow(); }
+}
+else
+{
+    alias rt.util.cpuid.mmx mmx;
+    alias rt.util.cpuid.sse sse;
+    alias rt.util.cpuid.sse2 sse2;
+    alias rt.util.cpuid.amd3dnow amd3dnow;
+}
+
+//version = log;
+
+bool disjoint(T)(T[] a, T[] b)
+{
+    return (a.ptr + a.length <= b.ptr || b.ptr + b.length <= a.ptr);
+}
+
+alias real T;
+
+extern (C):
+
+/* ======================================================================== */
+
+/***********************
+ * Computes:
+ *      a[] = b[] + c[]
+ */
+
+T[] _arraySliceSliceAddSliceAssign_r(T[] a, T[] c, T[] b)
+in
+{
+        assert(a.length == b.length && b.length == c.length);
+        assert(disjoint(a, b));
+        assert(disjoint(a, c));
+        assert(disjoint(b, c));
+}
+body
+{
+    for (int i = 0; i < a.length; i++)
+        a[i] = b[i] + c[i];
+    return a;
+}
+
+unittest
+{
+    printf("_arraySliceSliceAddSliceAssign_r unittest\n");
+    for (cpuid = 0; cpuid < CPUID_MAX; cpuid++)
+    {
+        version (log) printf("    cpuid %d\n", cpuid);
+
+        for (int j = 0; j < 2; j++)
+        {
+            const int dim = 67;
+            T[] a = new T[dim + j];     // aligned on 16 byte boundary
+            a = a[j .. dim + j];        // misalign for second iteration
+            T[] b = new T[dim + j];
+            b = b[j .. dim + j];
+            T[] c = new T[dim + j];
+            c = c[j .. dim + j];
+
+            for (int i = 0; i < dim; i++)
+            {   a[i] = cast(T)i;
+                b[i] = cast(T)(i + 7);
+                c[i] = cast(T)(i * 2);
+            }
+
+            c[] = a[] + b[];
+
+            for (int i = 0; i < dim; i++)
+            {
+                if (c[i] != cast(T)(a[i] + b[i]))
+                {
+                    printf("[%d]: %Lg != %Lg + %Lg\n", i, c[i], a[i], b[i]);
+                    assert(0);
+                }
+            }
+        }
+    }
+}
+
+/* ======================================================================== */
+
+/***********************
+ * Computes:
+ *      a[] = b[] - c[]
+ */
+
+T[] _arraySliceSliceMinSliceAssign_r(T[] a, T[] c, T[] b)
+in
+{
+        assert(a.length == b.length && b.length == c.length);
+        assert(disjoint(a, b));
+        assert(disjoint(a, c));
+        assert(disjoint(b, c));
+}
+body
+{
+    for (int i = 0; i < a.length; i++)
+        a[i] = b[i] - c[i];
+    return a;
+}
+
+
+unittest
+{
+    printf("_arraySliceSliceMinSliceAssign_r unittest\n");
+    for (cpuid = 0; cpuid < CPUID_MAX; cpuid++)
+    {
+        version (log) printf("    cpuid %d\n", cpuid);
+
+        for (int j = 0; j < 2; j++)
+        {
+            const int dim = 67;
+            T[] a = new T[dim + j];     // aligned on 16 byte boundary
+            a = a[j .. dim + j];        // misalign for second iteration
+            T[] b = new T[dim + j];
+            b = b[j .. dim + j];
+            T[] c = new T[dim + j];
+            c = c[j .. dim + j];
+
+            for (int i = 0; i < dim; i++)
+            {   a[i] = cast(T)i;
+                b[i] = cast(T)(i + 7);
+                c[i] = cast(T)(i * 2);
+            }
+
+            c[] = a[] - b[];
+
+            for (int i = 0; i < dim; i++)
+            {
+                if (c[i] != cast(T)(a[i] - b[i]))
+                {
+                    printf("[%d]: %Lg != %Lg - %Lg\n", i, c[i], a[i], b[i]);
+                    assert(0);
+                }
+            }
+        }
+    }
+}
+
+/* ======================================================================== */
+
+/***********************
+ * Computes:
+ *      a[] -= b[] * value
+ */
+
+T[] _arraySliceExpMulSliceMinass_r(T[] a, T value, T[] b)
+{
+    return _arraySliceExpMulSliceAddass_r(a, -value, b);
+}
+
+/***********************
+ * Computes:
+ *      a[] += b[] * value
+ */
+
+T[] _arraySliceExpMulSliceAddass_r(T[] a, T value, T[] b)
+in
+{
+        assert(a.length == b.length);
+        assert(disjoint(a, b));
+}
+body
+{
+    auto aptr = a.ptr;
+    auto aend = aptr + a.length;
+    auto bptr = b.ptr;
+
+    // Handle remainder
+    while (aptr < aend)
+        *aptr++ += *bptr++ * value;
+
+    return a;
+}
+
+unittest
+{
+    printf("_arraySliceExpMulSliceAddass_r unittest\n");
+
+    cpuid = 1;
+    {
+        version (log) printf("    cpuid %d\n", cpuid);
+
+        for (int j = 0; j < 1; j++)
+        {
+            const int dim = 67;
+            T[] a = new T[dim + j];     // aligned on 16 byte boundary
+            a = a[j .. dim + j];        // misalign for second iteration
+            T[] b = new T[dim + j];
+            b = b[j .. dim + j];
+            T[] c = new T[dim + j];
+            c = c[j .. dim + j];
+
+            for (int i = 0; i < dim; i++)
+            {   a[i] = cast(T)i;
+                b[i] = cast(T)(i + 7);
+                c[i] = cast(T)(i * 2);
+            }
+
+            b[] = c[];
+            c[] += a[] * 6;
+
+            for (int i = 0; i < dim; i++)
+            {
+                //printf("[%d]: %Lg ?= %Lg + %Lg * 6\n", i, c[i], b[i], a[i]);
+                if (c[i] != cast(T)(b[i] + a[i] * 6))
+                {
+                    printf("[%d]: %Lg ?= %Lg + %Lg * 6\n", i, c[i], b[i], a[i]);
+                    assert(0);
+                }
+            }
+        }
+    }
+}