--- 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.lu...@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.lu...@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.lu...@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 _______________________________________________ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman