[Pixman] [PATCH 07/11] MIPS: DSPr1: empty implementation with runtime detection

Nemanja Lukic nemanja.lukic at rt-rk.com
Mon Oct 28 10:04:45 PDT 2013


---
 configure.ac                    |   40 +++++++++
 pixman/Makefile.am              |   14 +++
 pixman/pixman-mips-common-asm.h |   13 +++
 pixman/pixman-mips-dspr1-asm.S  |   33 +++++++
 pixman/pixman-mips-dspr1-asm.h  |   37 ++++++++
 pixman/pixman-mips-dspr1.c      |  177 +++++++++++++++++++++++++++++++++++++++
 pixman/pixman-mips-dspr2-asm.h  |    2 +-
 pixman/pixman-mips-dspr2.c      |   24 +++++
 pixman/pixman-mips.c            |   23 +++++-
 pixman/pixman-private.h         |    5 +
 10 files changed, 366 insertions(+), 2 deletions(-)
 create mode 100644 pixman/pixman-mips-dspr1-asm.S
 create mode 100644 pixman/pixman-mips-dspr1-asm.h
 create mode 100644 pixman/pixman-mips-dspr1.c

diff --git a/configure.ac b/configure.ac
index 6d425ca..b9130b9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -754,6 +754,46 @@ if test $enable_mips32r2 = yes && test $have_mips32r2 = no ; then
 fi
 
 dnl ==========================================================================
+dnl Check if assembler is gas compatible and supports MIPS DSPr1 instructions
+
+have_mips_dspr1=no
+AC_MSG_CHECKING(whether to use MIPS DSPr1 assembler)
+
+AC_COMPILE_IFELSE([[
+int
+main () {
+    int c = 0, a = 0, b = 0;
+    __asm__ __volatile__ (
+        ".set      arch=mips32r2             \n\t"
+        ".set      dsp                       \n\t"
+        "packrl.ph %[c], %[a], %[b]          \n\t"
+        : [c] "=r" (c)
+        : [a] "r" (a), [b] "r" (b)
+  );
+  return c;
+}]], have_mips_dspr1=yes)
+
+AC_ARG_ENABLE(mips-dspr1,
+   [AC_HELP_STRING([--disable-mips-dspr1],
+                   [disable MIPS DSPr1 fast paths])],
+   [enable_mips_dspr1=$enableval], [enable_mips_dspr1=auto])
+
+if test $enable_mips_dspr1 = no ; then
+   have_mips_dspr1=disabled
+fi
+
+if test $have_mips_dspr1 = yes ; then
+   AC_DEFINE(USE_MIPS_DSPR1, 1, [use MIPS DSPr1 assembly optimizations])
+fi
+
+AM_CONDITIONAL(USE_MIPS_DSPR1, test $have_mips_dspr1 = yes)
+
+AC_MSG_RESULT($have_mips_dspr1)
+if test $enable_mips_dspr1 = yes && test $have_mips_dspr1 = no ; then
+   AC_MSG_ERROR([MIPS DSPr1 instructions not detected])
+fi
+
+dnl ==========================================================================
 dnl Check if assembler is gas compatible and supports MIPS DSPr2 instructions
 
 have_mips_dspr2=no
diff --git a/pixman/Makefile.am b/pixman/Makefile.am
index 7a7d629..63f4066 100644
--- a/pixman/Makefile.am
+++ b/pixman/Makefile.am
@@ -126,6 +126,20 @@ libpixman_1_la_LIBADD += libpixman-mips32r2.la
 ASM_CFLAGS_mips32r2=
 endif
 
+# mips dspr1 code
+if USE_MIPS_DSPR1
+noinst_LTLIBRARIES += libpixman-mips-dspr1.la
+libpixman_mips_dspr1_la_SOURCES = \
+        pixman-mips-dspr1.c \
+        pixman-mips-common.h \
+        pixman-mips-common-asm.h \
+        pixman-mips-dspr1-asm.S \
+        pixman-mips-dspr1-asm.h
+libpixman_1_la_LIBADD += libpixman-mips-dspr1.la
+
+ASM_CFLAGS_mips_dspr1=
+endif
+
 # mips dspr2 code
 if USE_MIPS_DSPR2
 noinst_LTLIBRARIES += libpixman-mips-dspr2.la
diff --git a/pixman/pixman-mips-common-asm.h b/pixman/pixman-mips-common-asm.h
index 186f17a..096ccf4 100644
--- a/pixman/pixman-mips-common-asm.h
+++ b/pixman/pixman-mips-common-asm.h
@@ -88,6 +88,13 @@ symbol##suffix: .frame  sp, 0, ra;                      \
 LEAF_MIPS(symbol, _mips32r2)
 
 /*
+ * LEAF_MIPS_DSPR1 - declare leaf routine for MIPS DSPr1
+ */
+#define LEAF_MIPS_DSPR1(symbol)                         \
+LEAF_MIPS(symbol, _mips_dspr1)                          \
+                .set    dsp;
+
+/*
  * LEAF_MIPS_DSPR2 - declare leaf routine for MIPS DSPr2
  */
 #define LEAF_MIPS_DSPR2(symbol)                         \
@@ -109,6 +116,12 @@ LEAF_MIPS(symbol, _mips_dspr2)                          \
 END(function, _mips32r2)
 
 /*
+ * END_MIPS_DSPR1 - mark end of mips_dspr1 function
+ */
+#define END_MIPS_DSPR1(function)                        \
+END(function, _mips_dspr1)
+
+/*
  * END_MIPS_DSPR2 - mark end of mips_dspr2 function
  */
 #define END_MIPS_DSPR2(function)                        \
diff --git a/pixman/pixman-mips-dspr1-asm.S b/pixman/pixman-mips-dspr1-asm.S
new file mode 100644
index 0000000..c6b4e98
--- /dev/null
+++ b/pixman/pixman-mips-dspr1-asm.S
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012-2013
+ *      MIPS Technologies, Inc., California.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Author:  Nemanja Lukic (nemanja.lukic at rt-rk.com)
+ */
+
+#include "pixman-private.h"
+#include "pixman-mips-dspr1-asm.h"
diff --git a/pixman/pixman-mips-dspr1-asm.h b/pixman/pixman-mips-dspr1-asm.h
new file mode 100644
index 0000000..0fe0bf0
--- /dev/null
+++ b/pixman/pixman-mips-dspr1-asm.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012-2013
+ *      MIPS Technologies, Inc., California.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Author:  Nemanja Lukic (nemanja.lukic at rt-rk.com)
+ */
+
+#ifndef PIXMAN_MIPS_DSPR1_ASM_H
+#define PIXMAN_MIPS_DSPR1_ASM_H
+
+#include "pixman-mips32r2-asm.h"
+
+#endif /* PIXMAN_MIPS_DSPR1_ASM_H */
diff --git a/pixman/pixman-mips-dspr1.c b/pixman/pixman-mips-dspr1.c
new file mode 100644
index 0000000..970ef04
--- /dev/null
+++ b/pixman/pixman-mips-dspr1.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2012-2013
+ *      MIPS Technologies, Inc., California.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Author:  Nemanja Lukic (nemanja.lukic at rt-rk.com)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "pixman-private.h"
+#include "pixman-mips-common.h"
+
+static pixman_bool_t
+mips_dspr1_fill (pixman_implementation_t *imp,
+                 uint32_t *               bits,
+                 int                      stride,
+                 int                      bpp,
+                 int                      x,
+                 int                      y,
+                 int                      width,
+                 int                      height,
+                 uint32_t                 _xor)
+{
+    uint8_t *byte_line;
+    uint32_t byte_width;
+
+    switch (bpp)
+    {
+    case 16:
+        stride = stride * (int) sizeof (uint32_t) / 2;
+        byte_line = (uint8_t *)(((uint16_t *)bits) + stride * y + x);
+        byte_width = width * 2;
+        stride *= 2;
+
+        while (height--)
+        {
+            uint8_t *dst = byte_line;
+            byte_line += stride;
+            pixman_fill_buff16_mips_dspr2 (dst, byte_width, _xor & 0xffff);
+        }
+        return TRUE;
+    case 32:
+#ifdef USE_MIPS32R2
+        stride = stride * (int) sizeof (uint32_t) / 4;
+        byte_line = (uint8_t *)(((uint32_t *)bits) + stride * y + x);
+        byte_width = width * 4;
+        stride *= 4;
+#else
+        bits = bits + y * stride + x;
+#endif
+        while (height--)
+        {
+#ifdef USE_MIPS32R2
+            uint8_t *dst = byte_line;
+            byte_line += stride;
+            pixman_fill_buff32_mips32r2 (dst, byte_width, _xor);
+#else
+            int i;
+
+            for (i = 0; i < width; ++i)
+                bits[i] = _xor;
+
+            bits += stride;
+#endif
+        }
+        return TRUE;
+    default:
+        return FALSE;
+    }
+}
+
+static pixman_bool_t
+mips_dspr1_blt (pixman_implementation_t *imp,
+                uint32_t *               src_bits,
+                uint32_t *               dst_bits,
+                int                      src_stride,
+                int                      dst_stride,
+                int                      src_bpp,
+                int                      dst_bpp,
+                int                      src_x,
+                int                      src_y,
+                int                      dest_x,
+                int                      dest_y,
+                int                      width,
+                int                      height)
+{
+    if (src_bpp != dst_bpp)
+        return FALSE;
+
+    uint8_t *src_bytes;
+    uint8_t *dst_bytes;
+    uint32_t byte_width;
+    int32_t temp;
+
+    temp = src_bpp >> 3;
+
+    src_stride = src_stride * (int) sizeof (uint32_t) / temp;
+    dst_stride = dst_stride * (int) sizeof (uint32_t) / temp;
+    if (src_bpp == 16)
+    {
+        src_bytes =(uint8_t *)(((uint16_t *)src_bits)
+                                          + src_stride * (src_y) + (src_x));
+        dst_bytes = (uint8_t *)(((uint16_t *)dst_bits)
+                                           + dst_stride * (dest_y) + (dest_x));
+    }
+    else if (src_bpp == 32)
+    {
+        src_bytes = (uint8_t *)(((uint32_t *)src_bits)
+                                           + src_stride * (src_y) + (src_x));
+        dst_bytes = (uint8_t *)(((uint32_t *)dst_bits)
+                                           + dst_stride * (dest_y) + (dest_x));
+    }
+    else
+        return FALSE;
+
+    byte_width = width * temp;
+    src_stride *= temp;
+    dst_stride *= temp;
+
+    while (height--)
+    {
+        uint8_t *src = src_bytes;
+        uint8_t *dst = dst_bytes;
+        src_bytes += src_stride;
+        dst_bytes += dst_stride;
+#ifdef USE_MIPS32R2
+        pixman_fast_memcpy_mips32r2 (dst, src, byte_width);
+#else
+        memcpy (dst, src, byte_width);
+#endif
+    }
+
+    return TRUE;
+}
+
+static const pixman_fast_path_t mips_dspr1_fast_paths[] =
+{
+    { PIXMAN_OP_NONE },
+};
+
+pixman_implementation_t *
+_pixman_implementation_create_mips_dspr1 (pixman_implementation_t *fallback)
+{
+    pixman_implementation_t *imp =
+        _pixman_implementation_create (fallback, mips_dspr1_fast_paths);
+
+    imp->blt = mips_dspr1_blt;
+    imp->fill = mips_dspr1_fill;
+
+    return imp;
+}
diff --git a/pixman/pixman-mips-dspr2-asm.h b/pixman/pixman-mips-dspr2-asm.h
index b43d008..73051c8 100644
--- a/pixman/pixman-mips-dspr2-asm.h
+++ b/pixman/pixman-mips-dspr2-asm.h
@@ -32,7 +32,7 @@
 #ifndef PIXMAN_MIPS_DSPR2_ASM_H
 #define PIXMAN_MIPS_DSPR2_ASM_H
 
-#include "pixman-mips32r2-asm.h"
+#include "pixman-mips-dspr1-asm.h"
 
 /*
  * Conversion of two r5g6b5 pixels (in1_565 and in2_565) to two a8r8g8b8 pixels
diff --git a/pixman/pixman-mips-dspr2.c b/pixman/pixman-mips-dspr2.c
index 742c5e8..7c445d6 100644
--- a/pixman/pixman-mips-dspr2.c
+++ b/pixman/pixman-mips-dspr2.c
@@ -166,22 +166,46 @@ mips_dspr2_fill (pixman_implementation_t *imp,
                  int                      height,
                  uint32_t                 _xor)
 {
+#if defined(USE_MIPS32R2) || defined(USE_MIPS_DSPR1)
     uint8_t *byte_line;
     uint32_t byte_width;
+#endif
+
+#ifndef USE_MIPS_DSPR1
+    int32_t short_stride;
+    uint16_t *dst;
+    uint16_t v;
+#endif
 
     switch (bpp)
     {
     case 16:
+#ifdef USE_MIPS_DSPR1
         stride = stride * (int) sizeof (uint32_t) / 2;
         byte_line = (uint8_t *)(((uint16_t *)bits) + stride * y + x);
         byte_width = width * 2;
         stride *= 2;
+#else
+        short_stride = (stride * (int)sizeof (uint32_t)) / (int)sizeof (uint16_t);
+        dst = (uint16_t *)bits;
+        v = _xor & 0xffff;
+        dst = dst + y * short_stride + x;
+#endif
 
         while (height--)
         {
+#ifdef USE_MIPS_DSPR1
             uint8_t *dst = byte_line;
             byte_line += stride;
             pixman_fill_buff16_mips_dspr2 (dst, byte_width, _xor & 0xffff);
+#else
+            int i;
+
+            for (i = 0; i < width; ++i)
+                dst[i] = v;
+
+            dst += short_stride;
+#endif
         }
         return TRUE;
     case 32:
diff --git a/pixman/pixman-mips.c b/pixman/pixman-mips.c
index a8f208d..221da24 100644
--- a/pixman/pixman-mips.c
+++ b/pixman/pixman-mips.c
@@ -34,6 +34,14 @@ static const char *mips_dspr2_cores[] =
 };
 #endif
 
+#ifdef USE_MIPS_DSPR1
+static const char *mips_dspr1_cores[] =
+{
+    "MIPS 1004K", "MIPS 74K",
+    "MIPS 34K", "MIPS 24KE", NULL
+};
+#endif
+
 #ifdef USE_MIPS32R2
 static const char *mips32r2_cores[] =
 {
@@ -53,7 +61,7 @@ static const char *mips_loongson_cores[] =
 #endif
 
 #if defined(USE_MIPS_DSPR2) || defined(USE_LOONGSON_MMI) || \
-    defined(USE_MIPS32R2)
+    defined(USE_MIPS32R2) || defined(USE_MIPS_DSPR1)
 
 static pixman_bool_t
 have_feature (const char **cores, const char *search_string)
@@ -144,6 +152,19 @@ _pixman_mips_get_implementations (pixman_implementation_t *imp)
             imp = _pixman_implementation_create_mips32r2 (imp);
 #endif
 
+#ifdef USE_MIPS_DSPR1
+    if (!_pixman_disabled ("mips-dspr1"))
+    {
+        int already_compiling_everything_for_dspr1 = 0;
+#if defined(__mips_dsp) && (__mips_dsp_rev >= 1)
+        already_compiling_everything_for_dspr1 = 1;
+#endif
+        if (already_compiling_everything_for_dspr1 ||
+            have_feature (mips_dspr1_cores, "dsp"))
+            imp = _pixman_implementation_create_mips_dspr1 (imp);
+    }
+#endif
+
 #ifdef USE_MIPS_DSPR2
     if (!_pixman_disabled ("mips-dspr2"))
     {
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 32726e5..0ea6f30 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -613,6 +613,11 @@ pixman_implementation_t *
 _pixman_implementation_create_mips_dspr2 (pixman_implementation_t *fallback);
 #endif
 
+#ifdef USE_MIPS_DSPR1
+pixman_implementation_t *
+_pixman_implementation_create_mips_dspr1 (pixman_implementation_t *fallback);
+#endif
+
 #ifdef USE_MIPS32R2
 pixman_implementation_t *
 _pixman_implementation_create_mips32r2 (pixman_implementation_t *fallback);
-- 
1.7.3



More information about the Pixman mailing list