MIPS DSP configure detection and initial blend optimizations.
authorDamir Tatalovic <dtatalovic@mips.com>
Fri, 2 Mar 2012 16:43:52 +0000 (17:43 +0100)
committerQt by Nokia <qt-info@nokia.com>
Thu, 22 Mar 2012 17:59:45 +0000 (18:59 +0100)
Adds new MIPS configure test and -no-mips_dsp and -no-mips_dspr2
configure options.

List of optimized implementations:

- comp_func_SourceOver
- comp_func_Source
- qt_memfill32
- qt_destFetchARGB32
- qt_destStoreARGB32
- blend [RGB32][RGB32]
- blend [ARGB32_Pre][RGB32]
- blend [RGB32][ARGB32_Pre]
- blend [ARGB32_Pre][ARGB32_Pre]

Change-Id: I35411858295b7b3f4895eb56e3b93397528903cc
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
configure
src/gui/gui.pro
src/gui/painting/painting.pri
src/gui/painting/qdrawhelper.cpp
src/gui/painting/qdrawhelper_mips_dsp.cpp [new file with mode: 0644]
src/gui/painting/qdrawhelper_mips_dsp_asm.S [new file with mode: 0644]
src/gui/painting/qdrawhelper_mips_dsp_p.h [new file with mode: 0644]
src/gui/painting/qdrawhelper_mips_dspr2_asm.S [new file with mode: 0644]
src/gui/painting/qt_mips_asm_dsp.h [new file with mode: 0644]

index 502f466..8af4e87 100755 (executable)
--- a/configure
+++ b/configure
@@ -739,6 +739,8 @@ CFG_NAS=no
 CFG_ACCESSIBILITY=auto
 CFG_IWMMXT=no
 CFG_NEON=auto
+CFG_MIPS_DSP=yes
+CFG_MIPS_DSPR2=yes
 CFG_CLOCK_GETTIME=auto
 CFG_CLOCK_MONOTONIC=auto
 CFG_MREMAP=auto
@@ -1542,6 +1544,20 @@ while [ "$#" -gt 0 ]; do
             UNKNOWN_OPT=yes
         fi
         ;;
+    mips_dsp)
+        if [ "$VAL" = "no" ]; then
+            CFG_MIPS_DSP="$VAL"
+        else
+            UNKNOWN_OPT=yes
+        fi
+        ;;
+    mips_dspr2)
+        if [ "$VAL" = "no" ]; then
+            CFG_MIPS_DSPR2="$VAL"
+        else
+            UNKNOWN_OPT=yes
+        fi
+        ;;
     reduce-relocations)
         if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
             CFG_REDUCE_RELOCATIONS="$VAL"
@@ -3093,6 +3109,8 @@ cat << EOF
     -no-sse4.2.......... Do not compile with use of SSE4.2 instructions.
     -no-avx ............ Do not compile with use of AVX instructions.
     -no-neon ........... Do not compile with use of NEON instructions.
+    -no-mips_dsp ....... Do not compile with use of MIPS DSP instructions.
+    -no-mips_dspr2 ..... Do not compile with use of MIPS DSP rev2 instructions.
 
     -qtnamespace <name>  Wraps all Qt library code in 'namespace <name> {...}'.
     -qtlibinfix <infix>  Renames all libQt*.so to libQt*<infix>.so.
@@ -4046,6 +4064,20 @@ elif [ "$CFG_ARCH" != "arm" ]; then
     CFG_NEON=no
 fi
 
+# detect mips_dsp support
+if [ "${CFG_ARCH}" = "mips" ] && [ "${CFG_MIPS_DSP}" = "yes" ]; then
+  CFG_MIPS_DSP=yes
+    else
+  CFG_MIPS_DSP=no
+fi
+
+# detect mips_dspr2 support
+if [ "${CFG_ARCH}" = "mips" ] && [ "${CFG_MIPS_DSPR2}" = "yes" ]; then
+  CFG_MIPS_DSPR2=yes
+    else
+  CFG_MIPS_DSPR2=no
+fi
+
 [ "$XPLATFORM_MINGW" = "yes" ] && QMakeVar add styles "windowsxp windowsvista"
 
 # detect zlib
@@ -5581,6 +5613,10 @@ fi
 [ "$CFG_AVX" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG avx"
 [ "$CFG_IWMMXT" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG iwmmxt"
 [ "$CFG_NEON" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG neon"
+if [ "$CFG_ARCH" = "mips" ]; then
+    [ "$CFG_MIPS_DSP" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG mips_dsp"
+    [ "$CFG_MIPS_DSPR2" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG mips_dspr2"
+fi
 if [ "$CFG_CLOCK_GETTIME" = "yes" ]; then
     QT_CONFIG="$QT_CONFIG clock-gettime"
 fi
@@ -6535,6 +6571,9 @@ elif [ "$CFG_ARCH" = "arm" ]; then
     echo "iWMMXt support ......... ${CFG_IWMMXT}"
     echo "NEON support ........... ${CFG_NEON}"
 fi
+if [ "$CFG_ARCH" = "mips" ]; then
+    echo "MIPS_DSP/MIPS_DSPR2..... ${CFG_MIPS_DSP}/${CFG_MIPS_DSPR2}"
+fi
 echo "IPv6 ifname support .... $CFG_IPV6IFNAME"
 echo "getaddrinfo support .... $CFG_GETADDRINFO"
 echo "getifaddrs support ..... $CFG_GETIFADDRS"
index e6a820b..1fb3790 100644 (file)
@@ -151,4 +151,24 @@ win32:!contains(QT_CONFIG, directwrite) {
         sse2: SOURCES += $$SSE2_SOURCES
         ssse3: SOURCES += $$SSSE3_SOURCES
         iwmmxt: SOURCES += $$IWMMXT_SOURCES
-    }
\ No newline at end of file
+    }
+
+mips_dsp:*-g++* {
+    DEFINES += QT_HAVE_MIPS_DSP
+    HEADERS += $$MIPS_DSP_HEADERS
+
+    DRAWHELPER_MIPS_DSP_ASM_FILES = $$MIPS_DSP_ASM
+        mips_dspr2 {
+            DEFINES += QT_HAVE_MIPS_DSPR2
+            DRAWHELPER_MIPS_DSP_ASM_FILES += $$MIPS_DSPR2_ASM
+        }
+    mips_dsp_compiler.commands = $$QMAKE_CXX -c
+    mips_dsp_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
+    mips_dsp_compiler.dependency_type = TYPE_C
+    mips_dsp_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
+    mips_dsp_compiler.input = DRAWHELPER_MIPS_DSP_ASM_FILES MIPS_DSP_SOURCES
+    mips_dsp_compiler.variable_out = OBJECTS
+    mips_dsp_compiler.name = compiling[mips_dsp] ${QMAKE_FILE_IN}
+    silent:mips_dsp_compiler.commands = @echo compiling[mips_dsp] ${QMAKE_FILE_IN} && $$mips_dsp_compiler.commands
+    QMAKE_EXTRA_COMPILERS += mips_dsp_compiler
+}
index 4cd2351..3ce2e5b 100644 (file)
@@ -109,4 +109,9 @@ NEON_SOURCES += painting/qdrawhelper_neon.cpp
 NEON_HEADERS += painting/qdrawhelper_neon_p.h
 NEON_ASM += ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S
 
+MIPS_DSP_SOURCES += painting/qdrawhelper_mips_dsp.cpp
+MIPS_DSP_HEADERS += painting/qdrawhelper_mips_dsp_p.h painting/qt_mips_asm_dsp.h
+MIPS_DSP_ASM += painting/qdrawhelper_mips_dsp_asm.S
+MIPS_DSPR2_ASM += painting/qdrawhelper_mips_dspr2_asm.S
+
 include($$PWD/../../3rdparty/zlib_dependency.pri)
index 0491a3d..9877dc6 100644 (file)
@@ -47,6 +47,9 @@
 #include <private/qdrawhelper_arm_simd_p.h>
 #endif
 #include <private/qdrawhelper_neon_p.h>
+#ifdef QT_HAVE_MIPS_DSP
+#include <private/qdrawhelper_mips_dsp_p.h>
+#endif
 #include <private/qmath_p.h>
 #include <qmath.h>
 
@@ -6057,6 +6060,22 @@ void qInitDrawhelperAsm()
     }
 #endif
 
+#if defined(QT_HAVE_MIPS_DSP)
+        functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_asm_mips_dsp;
+        functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_mips_dsp;
+
+        qt_memfill32 = qt_memfill32_asm_mips_dsp;
+
+        qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_mips_dsp;
+        qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_mips_dsp;
+        qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_mips_dsp;
+        qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_mips_dsp;
+
+        destFetchProc[QImage::Format_ARGB32] = qt_destFetchARGB32_mips_dsp;
+
+        destStoreProc[QImage::Format_ARGB32] = qt_destStoreARGB32_mips_dsp;
+
+#endif // QT_HAVE_MIPS_DSP
     if (functionForModeSolidAsm) {
         const int destinationMode = QPainter::CompositionMode_Destination;
         functionForModeSolidAsm[destinationMode] = functionForModeSolid_C[destinationMode];
diff --git a/src/gui/painting/qdrawhelper_mips_dsp.cpp b/src/gui/painting/qdrawhelper_mips_dsp.cpp
new file mode 100644 (file)
index 0000000..9b104eb
--- /dev/null
@@ -0,0 +1,176 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 MIPS Technologies, www.mips.com, author Damir Tatalovic <dtatalovic@mips.com>
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <private/qdrawhelper_p.h>
+#include <private/qdrawhelper_mips_dsp_p.h>
+#include <private/qpaintengine_raster_p.h>
+
+QT_BEGIN_NAMESPACE
+
+#if defined(QT_HAVE_MIPS_DSP)
+
+extern "C" uint INTERPOLATE_PIXEL_255_asm_mips_dsp(uint x, uint a, uint y, uint b);
+
+extern "C"  uint BYTE_MUL_asm_mips_dsp(uint x, uint a);
+
+extern "C" uint * destfetchARGB32_asm_mips_dsp(uint *buffer, const uint *data, int length);
+
+extern "C" uint * qt_destStoreARGB32_asm_mips_dsp(uint *buffer, const uint *data, int length);
+
+#if defined(QT_HAVE_MIPS_DSPR2)
+
+extern "C" uint INTERPOLATE_PIXEL_255_asm_mips_dspr2(uint x, uint a, uint y, uint b);
+
+extern "C" uint BYTE_MUL_asm_mips_dspr2(uint x, uint a);
+
+#endif // QT_HAVE_MIPS_DSPR2
+
+void qt_blend_argb32_on_argb32_mips_dsp(uchar *destPixels, int dbpl,
+                                      const uchar *srcPixels, int sbpl,
+                                      int w, int h,
+                                      int const_alpha)
+
+{
+#ifdef QT_DEBUG_DRAW
+    fprintf(stdout,
+            "qt_blend_argb32_on_argb32: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n",
+            destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
+    fflush(stdout);
+#endif
+
+    const uint *src = (const uint *) srcPixels;
+    uint *dst = (uint *) destPixels;
+    if (const_alpha == 256) {
+        for (int y=0; y<h; ++y) {
+            for (int x=0; x<w; ++x) {
+                uint s = src[x];
+                if (s >= 0xff000000)
+                    dst[x] = s;
+                else if (s != 0)
+#if !defined(QT_HAVE_MIPS_DSPR2)
+                    dst[x] = s + BYTE_MUL_asm_mips_dsp(dst[x], qAlpha(~s));
+#else
+                    dst[x] = s + BYTE_MUL_asm_mips_dspr2(dst[x], qAlpha(~s));
+#endif
+            }
+            dst = (quint32 *)(((uchar *) dst) + dbpl);
+            src = (const quint32 *)(((const uchar *) src) + sbpl);
+        }
+    } else if (const_alpha != 0) {
+        const_alpha = (const_alpha * 255) >> 8;
+        for (int y=0; y<h; ++y) {
+            for (int x=0; x<w; ++x) {
+#if !defined(QT_HAVE_MIPS_DSPR2)
+                uint s = BYTE_MUL_asm_mips_dsp(src[x], const_alpha);
+                dst[x] = s + BYTE_MUL_asm_mips_dsp(dst[x], qAlpha(~s));
+#else
+                uint s = BYTE_MUL_asm_mips_dspr2(src[x], const_alpha);
+                dst[x] = s + BYTE_MUL_asm_mips_dspr2(dst[x], qAlpha(~s));
+#endif
+            }
+            dst = (quint32 *)(((uchar *) dst) + dbpl);
+            src = (const quint32 *)(((const uchar *) src) + sbpl);
+        }
+    }
+}
+
+void qt_blend_rgb32_on_rgb32_mips_dsp(uchar *destPixels, int dbpl,
+                                    const uchar *srcPixels, int sbpl,
+                                    int w, int h,
+                                    int const_alpha)
+{
+#ifdef QT_DEBUG_DRAW
+    fprintf(stdout,
+            "qt_blend_rgb32_on_rgb32: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n",
+            destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
+    fflush(stdout);
+#endif
+
+    if (const_alpha != 256) {
+        qt_blend_argb32_on_argb32_mips_dsp(destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
+        return;
+    }
+
+    const uint *src = (const uint *) srcPixels;
+    uint *dst = (uint *) destPixels;
+    int len = w * 4;
+    for (int y=0; y<h; ++y) {
+        memcpy(dst, src, len);
+        dst = (quint32 *)(((uchar *) dst) + dbpl);
+        src = (const quint32 *)(((const uchar *) src) + sbpl);
+    }
+}
+
+void comp_func_Source_mips_dsp(uint *dest, const uint *src, int length, uint const_alpha)
+{
+    if (const_alpha == 255) {
+        ::memcpy(dest, src, length * sizeof(uint));
+    } else {
+        int ialpha = 255 - const_alpha;
+        for (int i = 0; i < length; ++i) {
+#if !defined(QT_HAVE_MIPS_DSPR2)
+            dest[i] = INTERPOLATE_PIXEL_255_asm_mips_dsp(src[i], const_alpha, dest[i], ialpha);
+#else
+            dest[i] = INTERPOLATE_PIXEL_255_asm_mips_dspr2(src[i], const_alpha, dest[i], ialpha);
+#endif
+        }
+    }
+}
+
+uint * QT_FASTCALL qt_destFetchARGB32_mips_dsp(uint *buffer,
+                                          QRasterBuffer *rasterBuffer,
+                                          int x, int y, int length)
+{
+    const uint *data = (const uint *)rasterBuffer->scanLine(y) + x;
+    buffer = destfetchARGB32_asm_mips_dsp(buffer, data, length);
+    return buffer;
+}
+
+void QT_FASTCALL qt_destStoreARGB32_mips_dsp(QRasterBuffer *rasterBuffer, int x, int y,
+                                             const uint *buffer, int length)
+{
+    uint *data = (uint *)rasterBuffer->scanLine(y) + x;
+    qt_destStoreARGB32_asm_mips_dsp(data, buffer, length);
+}
+
+#endif // QT_HAVE_MIPS_DSP
+
+QT_END_NAMESPACE
diff --git a/src/gui/painting/qdrawhelper_mips_dsp_asm.S b/src/gui/painting/qdrawhelper_mips_dsp_asm.S
new file mode 100644 (file)
index 0000000..f426905
--- /dev/null
@@ -0,0 +1,424 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 MIPS Technologies, www.mips.com, author Damir Tatalovic <dtatalovic@mips.com>
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qt_mips_asm_dsp.h"
+
+LEAF_MIPS_DSP(INTERPOLATE_PIXEL_255_asm_mips_dsp)
+/*
+ * a0 - uint x (First value to multiply)
+ * a1 - uint a (Multiplicator byte for first value)
+ * a2 - uint y (Second value to multiply)
+ * a3 - uint b (Multiplicator byte for second value)
+ */
+
+    .set reorder
+    li                t4, 8388736
+    preceu.ph.qbra    t0, a0        /* (x & 0xff00ff) */
+    mul               t0, t0, a1    /* (x & 0xff00ff) * a */
+    preceu.ph.qbra    t1, a2        /* (y & 0xff00ff) */
+    mul               t1, t1, a3    /* (y & 0xff00ff) * b */
+    addu              t0, t0, t1    /* (x & 0xff00ff) * a +
+                                     * (y & 0xff00ff) * b
+                                     */
+    preceu.ph.qbla    t1, t0        /* (t >> 8) & 0xff00ff */
+    addu              t0, t0, t1    /* t + ((t >> 8) & 0xff00ff */
+    addu              t0, t0, t4    /* t + ((t >> 8) & 0xff00ff) + 0x800080 */
+    preceu.ph.qbla    t0, t0        /* t >> 8 and t&=0xff00ff */
+    preceu.ph.qbla    t2, a0        /* (x>>8) & 0xff00ff */
+    mul               t2, t2, a1    /* ((x>>8) & 0xff00ff) * a */
+    preceu.ph.qbla    t3, a2        /* ((y>>8) & 0xff00ff) */
+    mul               t3, t3, a3    /* ((y>>8) & 0xff00ff) * b */
+    addu              t2, t2, t3    /* ((x>>8) & 0xff00ff) * a +
+                                     * ((y >> 8) & 0xff00ff) * b
+                                     */
+    preceu.ph.qbla    t3, t2        /* (x>>8) & 0xff00ff */
+    addu              t2, t2, t3    /* (x>>8) & 0xff00ff) + 0x800080 */
+    addu              t2, t2, t4    /* x + ((x>>8) & 0xff00ff) + 0x800080 */
+    and               t2, t2, 0xff00ff00
+    or                t1, t0, t2
+    move              v0, t1
+    j                 ra
+
+END(INTERPOLATE_PIXEL_255_asm_mips_dsp)
+
+LEAF_MIPS_DSP(BYTE_MUL_asm_mips_dsp)
+/*
+ * a0 - uint x (Value to multiply)
+ * a1 - uint a (Multiplicator byte)
+ */
+
+    .set reorder
+    replv.ph          a1, a1         /* a1 = 0x00a00a */
+    li                t4, 8388736    /* t4 = 0x800080 */
+    muleu_s.ph.qbl    t0, a0, a1
+    muleu_s.ph.qbr    t2, a0, a1
+    preceu.ph.qbla    t1, t0
+    addu              t0, t0, t1
+    addu              t0, t0, t4
+    preceu.ph.qbla    t3, t2
+    addu              t2, t2, t3
+    addu              t2, t2, t4
+    precrq.qb.ph      t4, t0, t2
+    move              v0, t4
+    j                 ra
+
+END(BYTE_MUL_asm_mips_dsp)
+
+LEAF_MIPS_DSP(destfetchARGB32_asm_mips_dsp)
+/*
+ * a0 - buffer address (dst)
+ * a1 - data address (src)
+ * a2 - length
+ */
+
+    beqz              a2, 2f
+     move             v0, a0         /* just return the address of buffer
+                                      * for storing returning values */
+    move              v0, a0
+    andi              t1, a2, 0x1
+    li                t7, 8388736    /* t7 = 0x800080 */
+    beqz              t1, 1f
+     nop
+    lw                t8, 0(a1)
+    addiu             a2, a2, -1
+    srl               t6, t8, 24     /* t6 = alpha */
+
+    preceu.ph.qbra    t0, t8
+    mul               t1, t0, t6
+    preceu.ph.qbla    t4, t8
+    mul               t5, t4, t6
+
+    preceu.ph.qbla    t2, t1
+    addq.ph           t3, t1, t2
+    addq.ph           t3, t3, t7
+    preceu.ph.qbla    t1, t3         /* t1 holds R & B blended with alpha
+                                      * | 0 | dRab | 0 | dBab | */
+    preceu.ph.qbla    t2, t5
+    addq.ph           t3, t2, t5
+    addq.ph           t4, t3, t7
+    preceu.ph.qbla    t2, t4         /* t2 holds A & G blended with alpha
+                                      * | 0 | dAab | 0 | dGab | */
+    andi              t2, t2, 255    /* t2 = 0xff */
+
+    sll               t0, t6, 24
+    sll               t3, t2, 8
+    or                t4, t0, t3
+    or                t0, t1, t4
+    sw                t0, 0(a0)
+    addiu             a0, a0, 4
+    addiu             a1, a1, 4
+    beqz              a2, 2f         /* there was only one member */
+     nop
+1:
+    lw                t0, 0(a1)      /* t0 = src1 */
+    lw                t1, 4(a1)      /* t1 = src2 */
+    precrq.qb.ph      t4, t0, t1     /* t4 = a1 G1 a2 G2 */
+    preceu.ph.qbra    t3, t4         /* t3 = 0 G1 0 G2 */
+    preceu.ph.qbla    t2, t4         /* t2 = | 0 | a1 | 0 | a2 | */
+    srl               t5, t2, 8
+    or                t8, t2, t5     /* t8 = 0 a1 a1 a2 */
+    muleu_s.ph.qbr    t5, t8, t3
+
+    addiu             a2, a2, -2
+    addiu             a1, a1, 8
+    precrq.ph.w       t9, t0, t1
+    preceu.ph.qbra    t9, t9
+
+    preceu.ph.qbla    t6, t5
+    addq.ph           t5, t5, t6
+    addq.ph           t2, t5, t7
+    muleu_s.ph.qbr    t6, t8, t9
+    sll               t3, t1, 16
+    packrl.ph         t3, t0, t3
+    preceu.ph.qbra    t3, t3
+    muleu_s.ph.qbr    t8, t8, t3
+    preceu.ph.qbla    t3, t6
+    addq.ph           t3, t6, t3
+    addq.ph           t3, t3, t7
+    preceu.ph.qbla    t5, t8
+    addq.ph           t5, t8, t5
+    addq.ph           t5, t5, t7
+
+    precrq.ph.w       t0, t4, t3     /* t0 = | 0 |  a1 | 0 | dR1 | */
+    precrq.ph.w       t1, t2, t5     /* t1 = | 0 | dG1 | 0 | dB1 | */
+    precrq.qb.ph      t6, t0, t1     /* t6 = | a1 | dR1 | dG1 | dB1 | */
+    sll               t3, t3, 16
+    sll               t5, t5, 16
+    packrl.ph         t0, t4, t3
+    packrl.ph         t1, t2, t5
+    precrq.qb.ph      t8, t0, t1     /* t8 = | a2 | dR2 | dG2 | dB2 | */
+    sw                t6, 0(a0)
+    sw                t8, 4(a0)
+    bnez              a2, 1b
+     addiu            a0, a0, 8
+2:
+    j                 ra
+     nop
+
+END(destfetchARGB32_asm_mips_dsp)
+
+LEAF_MIPS_DSP(qt_memfill32_asm_mips_dsp)
+/*
+ * a0 - destination address (dst)
+ * a1 - value
+ * a2 - count
+ */
+
+    beqz      a2, 5f
+     nop
+    li        t8, 8
+    andi      t0, a2, 0x7    /* t0 holds how many counts exceeds 8 */
+    beqzl     t0, 2f         /* count is multiple of 8 (8, 16, 24, ....) */
+     addiu    a2, a2, -8
+    subu      a2, a2, t0
+1:
+    sw        a1, 0(a0)
+    addiu     t0, t0, -1
+    bnez      t0, 1b
+     addiu    a0, a0, 4
+    bgeu      a2, t8, 2f
+     addiu    a2, a2, -8
+    b         5f
+     nop
+2:
+    beqz      a2, 4f
+     nop
+3:
+    pref      30, 32(a0)
+    addiu     a2, a2, -8
+    sw        a1, 0( a0)
+    sw        a1, 4(a0)
+    sw        a1, 8(a0)
+    sw        a1, 12(a0)
+    addiu     a0, a0, 32
+    sw        a1, -16(a0)
+    sw        a1, -12(a0)
+    sw        a1, -8(a0)
+    bnez      a2, 3b
+     sw       a1, -4(a0)
+4:
+    sw        a1, 0(a0)
+    sw        a1, 4(a0)
+    sw        a1, 8(a0)
+    sw        a1, 12(a0)
+    addiu     a0, a0, 32
+    sw        a1, -16(a0)
+    sw        a1, -12(a0)
+    sw        a1, -8(a0)
+    sw        a1, -4(a0)
+5:
+    jr        ra
+     nop
+
+END(qt_memfill32_asm_mips_dsp)
+
+LEAF_MIPS_DSP(comp_func_SourceOver_asm_mips_dsp)
+/*
+ * a0 - uint *dest
+ * a1 - const uint *src
+ * a2 - int length
+ * a3 - uint const_alpha
+ */
+
+    beqz              a2, 5f
+     nop
+    li                t8, 0xff
+    li                t7, 8388736    /* t7 = 0x800080 */
+    bne               a3, t8, 4f
+     nop
+
+/* part where const_alpha = 255 */
+    b                 2f
+     nop
+1:
+    addiu             a0, a0, 4
+    addiu             a2, a2, -1
+    beqz              a2, 5f
+     nop
+2:
+    lw                t0, 0(a1)      /* t0 = s = src[i] */
+    addiu             a1, a1, 4
+    nor               t1, t0, zero
+    srl               t1, t1, 24     /* t1 = ~qAlpha(s) */
+    bnez              t1, 3f
+     nop
+    sw                t0, 0(a0)      /* dst[i] = src[i] */
+    addiu             a2, a2, -1
+    bnez              a2, 2b
+     addiu            a0, a0, 4
+    b 5f
+     nop
+3:
+    beqz              t0, 1b
+     nop
+
+    lw                t4, 0(a0)
+    replv.ph          t6, t1
+    muleu_s.ph.qbl    t2, t4, t6
+    muleu_s.ph.qbr    t3, t4, t6
+    addiu             a2, a2, -1
+    preceu.ph.qbla    t4, t2
+    addq.ph           t4, t2, t4
+    addq.ph           t4, t4, t7
+    preceu.ph.qbla    t5, t3
+    addq.ph           t5, t5, t3
+    addq.ph           t5, t5, t7
+    precrq.qb.ph      t8, t4, t5    /* t8 = | dsA | dsR | dsG | dsB | */
+    addu              t8, t0, t8    /* dst[i] =
+                                     * s + BYTE_MUL(dst[i],~qAlpha(s)) */
+    sw                t8, 0(a0)
+    bnez              a2, 2b
+     addiu            a0, a0, 4
+    b                 5f
+     nop
+4:
+    lw                t0, 0(a0)     /* t0 - dst[i] "1" */
+    lw                t1, 0(a1)     /* t1 - src[i] "2" */
+    addiu             a1, a1, 4
+    addiu             a2, a2, -1
+    replv.ph          t6, a3        /* a1 = 0x00a00a */
+    muleu_s.ph.qbl    t2, t1, t6
+    muleu_s.ph.qbr    t3, t1, t6
+    preceu.ph.qbla    t4, t2
+    addq.ph           t4, t2, t4
+    addq.ph           t4, t4, t7
+    preceu.ph.qbla    t5, t3
+    addq.ph           t5, t5, t3
+    addq.ph           t5, t5, t7
+    precrq.qb.ph      t8, t4, t5    /* t8 = | dsA | dsR | dsG | dsB | */
+
+    nor               t6, t8, zero
+    srl               t6, t6, 24
+    replv.ph          t6, t6
+
+    muleu_s.ph.qbl    t2, t0, t6
+    muleu_s.ph.qbr    t3, t0, t6
+    preceu.ph.qbla    t4, t2
+    addq.ph           t4, t2, t4
+    addq.ph           t4, t4, t7
+    preceu.ph.qbla    t5, t3
+    addq.ph           t5, t5, t3
+    addq.ph           t5, t5, t7
+    precrq.qb.ph      t6, t4, t5    /* t6 = | ddA | ddR | ddG | ddB | */
+
+    addu              t0, t8, t6
+    sw                t0, 0(a0)
+    bnez              a2, 4b
+     addiu            a0, a0, 4
+5:
+    jr                ra
+     nop
+
+END(comp_func_SourceOver_asm_mips_dsp)
+
+LEAF_MIPS_DSP(qt_destStoreARGB32_asm_mips_dsp)
+/*
+ * a0 - uint * data
+ * a1 - const uint *buffer
+ * a2 - int length
+ */
+
+    blez      a2, 6f
+    move      v1, zero
+    li        t0, 255
+    lui       a3, 0xff
+    j         2f
+     lui      t2, 0xff00
+1:
+    addiu     v1, v1, 1
+    sw        zero, 0(a0)
+    addiu     a1, a1, 4
+    beq       v1, a2, 6f
+    addiu     a0, a0, 4
+2:
+    lw        v0, 0(a1)
+    srl       t3, v0, 0x18
+    beql      t3, t0, 5f
+    addiu     v1, v1, 1
+    beqz      t3, 1b
+
+    srl       t1, v0, 0x8
+    andi      t1, t1, 0xff
+
+    teq       t3, zero, 0x7
+    div       zero, a3, t3
+    move      t8, t3
+    andi      t6, v0, 0xff
+
+    srl       t3,v0,0x10
+    andi      t3,t3,0xff
+
+    and       t5, v0, t2
+    mflo      t4
+
+    mult      $ac0, t4, t6
+    mult      $ac1, t1, t4
+    mul       t4, t3, t4
+
+    sltiu     t8, t8, 2
+    beqz      t8, 3f
+     nop
+    mflo      t6, $ac0
+    mflo      t1, $ac1
+    sra       t6, t6, 0x10
+    sra       t1, t1, 0x8
+    b         4f
+     nop
+3:
+    extr.w    t6, $ac0, 0x10
+    extr.w    t1, $ac1, 0x8
+4:
+    and       v0, t4, a3
+    or        v0, v0, t6
+    or        v0, v0, t5
+    andi      t1, t1, 0xff00
+    or        v0, v0, t1
+    addiu     v1, v1, 1
+5:
+    sw        v0, 0(a0)
+    addiu     a1, a1, 4
+    bne       v1, a2, 2b
+    addiu     a0, a0, 4
+6:
+    jr        ra
+     nop
+
+END(qt_destStoreARGB32_asm_mips_dsp)
diff --git a/src/gui/painting/qdrawhelper_mips_dsp_p.h b/src/gui/painting/qdrawhelper_mips_dsp_p.h
new file mode 100644 (file)
index 0000000..c68a3ff
--- /dev/null
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 MIPS Technologies, www.mips.com, author Damir Tatalovic <dtatalovic@mips.com>
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDRAWHELPER_MIPS_P_H
+#define QDRAWHELPER_MIPS_P_H
+
+#include <private/qdrawhelper_p.h>
+
+QT_BEGIN_NAMESPACE
+
+#if defined(QT_HAVE_MIPS_DSP)
+
+extern "C" void qt_memfill32_asm_mips_dsp(quint32 *dest, quint32 value, int count);
+
+extern "C" void comp_func_SourceOver_asm_mips_dsp(uint *dest, const uint *src, int length, uint const_alpha);
+
+void qt_blend_argb32_on_argb32_mips_dsp(uchar *destPixels, int dbpl,
+                                      const uchar *srcPixels, int sbpl,
+                                      int w, int h,
+                                      int const_alpha);
+
+void qt_blend_rgb32_on_rgb32_mips_dsp(uchar *destPixels, int dbpl,
+                                    const uchar *srcPixels, int sbpl,
+                                    int w, int h,
+                                    int const_alpha);
+
+void comp_func_Source_mips_dsp(uint *dest, const uint *src, int length, uint const_alpha);
+
+uint * QT_FASTCALL qt_destFetchARGB32_mips_dsp(uint *buffer,
+                                          QRasterBuffer *rasterBuffer,
+                                          int x, int y, int length);
+
+void QT_FASTCALL qt_destStoreARGB32_mips_dsp(QRasterBuffer *rasterBuffer, int x, int y,
+                                             const uint *buffer, int length);
+
+#endif // QT_HAVE_MIPS_DSP
+
+QT_END_NAMESPACE
+
+#endif // QDRAWHELPER_MIPS_P_H
diff --git a/src/gui/painting/qdrawhelper_mips_dspr2_asm.S b/src/gui/painting/qdrawhelper_mips_dspr2_asm.S
new file mode 100644 (file)
index 0000000..688d16b
--- /dev/null
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 MIPS Technologies, www.mips.com, author Damir Tatalovic <dtatalovic@mips.com>
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qt_mips_asm_dsp.h"
+
+LEAF_MIPS_DSPR2(INTERPOLATE_PIXEL_255_asm_mips_dspr2)
+/*
+ * a0 - uint x (First value to multiply)
+ * a1 - uint a (Multiplicator byte for first value)
+ * a2 - uint y (Second value to multiply)
+ * a3 - uint b (Multiplicator byte for second value)
+ */
+
+    .set reorder
+    replv.ph          a1, a1
+    replv.ph          a3, a3
+    li                t8, 8388736
+    muleu_s.ph.qbl    t0, a0, a1
+    muleu_s.ph.qbl    t1, a2, a3
+    muleu_s.ph.qbr    t2, a0, a1
+    muleu_s.ph.qbr    t3, a2, a3
+    addu.ph           t4, t0, t1
+    addu.ph           t5, t2, t3
+    preceu.ph.qbla    t0, t4
+    addu              t1, t0, t8
+    addu              t1, t4, t1
+    preceu.ph.qbla    t6, t5
+    addu              t7, t6, t8
+    addu              t7, t5, t7
+    precrq.qb.ph      t2, t1, t7
+    move              v0, t2
+    j                 ra
+
+END(INTERPOLATE_PIXEL_255_asm_mips_dspr2)
+
+LEAF_MIPS_DSPR2(BYTE_MUL_asm_mips_dspr2)
+/*
+ * a0 - uint x (Value to multiply)
+ * a1 - uint a (Multiplicator byte)
+ */
+
+    .set reorder
+    replv.ph          a1, a1              /* a1 = 0x00a00a */
+    li                t4, 8388736         /* t4 = 0x800080 */
+    muleu_s.ph.qbl    t0, a0, a1
+    muleu_s.ph.qbr    t2, a0, a1
+    preceu.ph.qbla    t1, t0
+    addu              t0, t0, t1
+    addu              t0, t0, t4
+    preceu.ph.qbla    t3, t2
+    addu              t2, t2, t3
+    addu              t2, t2, t4
+    precrq.qb.ph      t4, t0, t2
+    move              v0, t4
+    j                 ra
+
+END(BYTE_MUL_asm_mips_dspr2)
diff --git a/src/gui/painting/qt_mips_asm_dsp.h b/src/gui/painting/qt_mips_asm_dsp.h
new file mode 100644 (file)
index 0000000..bcde706
--- /dev/null
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 MIPS Technologies, www.mips.com, author Damir Tatalovic <dtatalovic@mips.com>
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT_MIPS_DSP_H__
+#define QT_MIPS_DSP_H__
+
+#define zero $0
+#define AT   $1
+#define v0   $2
+#define v1   $3
+#define a0   $4
+#define a1   $5
+#define a2   $6
+#define a3   $7
+#define t0   $8
+#define t1   $9
+#define t2   $10
+#define t3   $11
+#define t4   $12
+#define t5   $13
+#define t6   $14
+#define t7   $15
+#define s0   $16
+#define s1   $17
+#define s2   $18
+#define s3   $19
+#define s4   $20
+#define s5   $21
+#define s6   $22
+#define s7   $23
+#define t8   $24
+#define t9   $25
+#define k0   $26
+#define k1   $27
+#define gp   $28
+#define sp   $29
+#define fp   $30
+#define s8   $30
+#define ra   $31
+
+/*
+ * LEAF_MIPS32R2 - declare leaf_mips32r2 routine
+ */
+#define LEAF_MIPS32R2(symbol)                           \
+                .globl  symbol;                         \
+                .align  2;                              \
+                .type   symbol,@function;               \
+                .ent    symbol,0;                       \
+symbol:         .frame  sp, 0, ra;                      \
+                .set    arch=mips32r2;                  \
+                .set    noreorder;
+
+/*
+ * LEAF_MIPS_DSP - declare leaf_mips_dsp routine
+ */
+#define LEAF_MIPS_DSP(symbol)                           \
+LEAF_MIPS32R2(symbol)                                   \
+                .set    dsp;
+
+/*
+ * LEAF_MIPS_DSPR2 - declare leaf_mips_dspr2 routine
+ */
+#define LEAF_MIPS_DSPR2(symbol)                         \
+LEAF_MIPS32R2(symbol)                                   \
+                .set   dspr2;
+
+/*
+ * END - mark end of function
+ */
+#define END(function)                                   \
+                .set    reorder;                        \
+                .end    function;                       \
+                .size   function,.-function
+
+#endif //QT_MIPS_DSP_H__