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

Søren Sandmann soren.sandmann at gmail.com
Fri Apr 11 12:27:58 PDT 2014


More information is needed in the commit log. 

Also, the subject line claims to add an *empty* dspr1 implementation
with runtime detection, but the implementation added is not actually
empty: it contains blt and fill routines.

See the highlevel comments for much more about blt() and fill(), but
I'll note here that this commit makes all kinds of mysterious changes to
the dspr2 implementation. This is just not acceptable in a commit that
claims to add an "empty implementation".


Søren

Nemanja Lukic <nemanja.lukic at rt-rk.com> writes:

> ---
>  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 230633d..c891d29 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -755,6 +755,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);


More information about the Pixman mailing list