Blame gst-libs/gst/audio/audio-resampler-x86-sse2.c

Packit 0652a1
/* GStreamer
Packit 0652a1
 * Copyright (C) <2016> Wim Taymans <wim.taymans@gmail.com>
Packit 0652a1
 *
Packit 0652a1
 * This library is free software; you can redistribute it and/or
Packit 0652a1
 * modify it under the terms of the GNU Library General Public
Packit 0652a1
 * License as published by the Free Software Foundation; either
Packit 0652a1
 * version 2 of the License, or (at your option) any later version.
Packit 0652a1
 *
Packit 0652a1
 * This library is distributed in the hope that it will be useful,
Packit 0652a1
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 0652a1
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 0652a1
 * Library General Public License for more details.
Packit 0652a1
 *
Packit 0652a1
 * You should have received a copy of the GNU Library General Public
Packit 0652a1
 * License along with this library; if not, write to the
Packit 0652a1
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
Packit 0652a1
 * Boston, MA 02110-1301, USA.
Packit 0652a1
 */
Packit 0652a1
Packit 0652a1
#ifdef HAVE_CONFIG_H
Packit 0652a1
#  include "config.h"
Packit 0652a1
#endif
Packit 0652a1
Packit 0652a1
#include "audio-resampler-x86-sse2.h"
Packit 0652a1
Packit 0652a1
#if defined (HAVE_EMMINTRIN_H) && defined(__SSE2__)
Packit 0652a1
#include <emmintrin.h>
Packit 0652a1
Packit 0652a1
static inline void
Packit 0652a1
inner_product_gint16_full_1_sse2 (gint16 * o, const gint16 * a,
Packit 0652a1
    const gint16 * b, gint len, const gint16 * icoeff, gint bstride)
Packit 0652a1
{
Packit 0652a1
  gint i;
Packit 0652a1
  __m128i sum, t;
Packit 0652a1
Packit 0652a1
  sum = _mm_setzero_si128 ();
Packit 0652a1
Packit 0652a1
  for (i = 0; i < len; i += 16) {
Packit 0652a1
    t = _mm_loadu_si128 ((__m128i *) (a + i));
Packit 0652a1
    sum =
Packit 0652a1
        _mm_add_epi32 (sum, _mm_madd_epi16 (t,
Packit 0652a1
            _mm_load_si128 ((__m128i *) (b + i + 0))));
Packit 0652a1
Packit 0652a1
    t = _mm_loadu_si128 ((__m128i *) (a + i + 8));
Packit 0652a1
    sum =
Packit 0652a1
        _mm_add_epi32 (sum, _mm_madd_epi16 (t,
Packit 0652a1
            _mm_load_si128 ((__m128i *) (b + i + 8))));
Packit 0652a1
  }
Packit 0652a1
  sum = _mm_add_epi32 (sum, _mm_shuffle_epi32 (sum, _MM_SHUFFLE (2, 3, 2, 3)));
Packit 0652a1
  sum = _mm_add_epi32 (sum, _mm_shuffle_epi32 (sum, _MM_SHUFFLE (1, 1, 1, 1)));
Packit 0652a1
Packit 0652a1
  sum = _mm_add_epi32 (sum, _mm_set1_epi32 (1 << (PRECISION_S16 - 1)));
Packit 0652a1
  sum = _mm_srai_epi32 (sum, PRECISION_S16);
Packit 0652a1
  sum = _mm_packs_epi32 (sum, sum);
Packit 0652a1
  *o = _mm_extract_epi16 (sum, 0);
Packit 0652a1
}
Packit 0652a1
Packit 0652a1
static inline void
Packit 0652a1
inner_product_gint16_linear_1_sse2 (gint16 * o, const gint16 * a,
Packit 0652a1
    const gint16 * b, gint len, const gint16 * icoeff, gint bstride)
Packit 0652a1
{
Packit 0652a1
  gint i = 0;
Packit 0652a1
  __m128i sum[2], t;
Packit 0652a1
  __m128i f = _mm_set_epi64x (0, *((gint64 *) icoeff));
Packit 0652a1
  const gint16 *c[2] = { (gint16 *) ((gint8 *) b + 0 * bstride),
Packit 0652a1
    (gint16 *) ((gint8 *) b + 1 * bstride)
Packit 0652a1
  };
Packit 0652a1
Packit 0652a1
  sum[0] = sum[1] = _mm_setzero_si128 ();
Packit 0652a1
  f = _mm_unpacklo_epi16 (f, sum[0]);
Packit 0652a1
Packit 0652a1
  for (; i < len; i += 16) {
Packit 0652a1
    t = _mm_loadu_si128 ((__m128i *) (a + i + 0));
Packit 0652a1
    sum[0] =
Packit 0652a1
        _mm_add_epi32 (sum[0], _mm_madd_epi16 (t,
Packit 0652a1
            _mm_load_si128 ((__m128i *) (c[0] + i + 0))));
Packit 0652a1
    sum[1] =
Packit 0652a1
        _mm_add_epi32 (sum[1], _mm_madd_epi16 (t,
Packit 0652a1
            _mm_load_si128 ((__m128i *) (c[1] + i + 0))));
Packit 0652a1
Packit 0652a1
    t = _mm_loadu_si128 ((__m128i *) (a + i + 8));
Packit 0652a1
    sum[0] =
Packit 0652a1
        _mm_add_epi32 (sum[0], _mm_madd_epi16 (t,
Packit 0652a1
            _mm_load_si128 ((__m128i *) (c[0] + i + 8))));
Packit 0652a1
    sum[1] =
Packit 0652a1
        _mm_add_epi32 (sum[1], _mm_madd_epi16 (t,
Packit 0652a1
            _mm_load_si128 ((__m128i *) (c[1] + i + 8))));
Packit 0652a1
  }
Packit 0652a1
  sum[0] = _mm_srai_epi32 (sum[0], PRECISION_S16);
Packit 0652a1
  sum[1] = _mm_srai_epi32 (sum[1], PRECISION_S16);
Packit 0652a1
Packit 0652a1
  sum[0] =
Packit 0652a1
      _mm_madd_epi16 (sum[0], _mm_shuffle_epi32 (f, _MM_SHUFFLE (0, 0, 0, 0)));
Packit 0652a1
  sum[1] =
Packit 0652a1
      _mm_madd_epi16 (sum[1], _mm_shuffle_epi32 (f, _MM_SHUFFLE (1, 1, 1, 1)));
Packit 0652a1
  sum[0] = _mm_add_epi32 (sum[0], sum[1]);
Packit 0652a1
Packit 0652a1
  sum[0] =
Packit 0652a1
      _mm_add_epi32 (sum[0], _mm_shuffle_epi32 (sum[0], _MM_SHUFFLE (2, 3, 2,
Packit 0652a1
              3)));
Packit 0652a1
  sum[0] =
Packit 0652a1
      _mm_add_epi32 (sum[0], _mm_shuffle_epi32 (sum[0], _MM_SHUFFLE (1, 1, 1,
Packit 0652a1
              1)));
Packit 0652a1
Packit 0652a1
  sum[0] = _mm_add_epi32 (sum[0], _mm_set1_epi32 (1 << (PRECISION_S16 - 1)));
Packit 0652a1
  sum[0] = _mm_srai_epi32 (sum[0], PRECISION_S16);
Packit 0652a1
  sum[0] = _mm_packs_epi32 (sum[0], sum[0]);
Packit 0652a1
  *o = _mm_extract_epi16 (sum[0], 0);
Packit 0652a1
}
Packit 0652a1
Packit 0652a1
static inline void
Packit 0652a1
inner_product_gint16_cubic_1_sse2 (gint16 * o, const gint16 * a,
Packit 0652a1
    const gint16 * b, gint len, const gint16 * icoeff, gint bstride)
Packit 0652a1
{
Packit 0652a1
  gint i = 0;
Packit 0652a1
  __m128i sum[4], t[4];
Packit 0652a1
  __m128i f = _mm_set_epi64x (0, *((long long *) icoeff));
Packit 0652a1
  const gint16 *c[4] = { (gint16 *) ((gint8 *) b + 0 * bstride),
Packit 0652a1
    (gint16 *) ((gint8 *) b + 1 * bstride),
Packit 0652a1
    (gint16 *) ((gint8 *) b + 2 * bstride),
Packit 0652a1
    (gint16 *) ((gint8 *) b + 3 * bstride)
Packit 0652a1
  };
Packit 0652a1
Packit 0652a1
  sum[0] = sum[1] = sum[2] = sum[3] = _mm_setzero_si128 ();
Packit 0652a1
  f = _mm_unpacklo_epi16 (f, sum[0]);
Packit 0652a1
Packit 0652a1
  for (; i < len; i += 8) {
Packit 0652a1
    t[0] = _mm_loadu_si128 ((__m128i *) (a + i));
Packit 0652a1
    sum[0] =
Packit 0652a1
        _mm_add_epi32 (sum[0], _mm_madd_epi16 (t[0],
Packit 0652a1
            _mm_load_si128 ((__m128i *) (c[0] + i))));
Packit 0652a1
    sum[1] =
Packit 0652a1
        _mm_add_epi32 (sum[1], _mm_madd_epi16 (t[0],
Packit 0652a1
            _mm_load_si128 ((__m128i *) (c[1] + i))));
Packit 0652a1
    sum[2] =
Packit 0652a1
        _mm_add_epi32 (sum[2], _mm_madd_epi16 (t[0],
Packit 0652a1
            _mm_load_si128 ((__m128i *) (c[2] + i))));
Packit 0652a1
    sum[3] =
Packit 0652a1
        _mm_add_epi32 (sum[3], _mm_madd_epi16 (t[0],
Packit 0652a1
            _mm_load_si128 ((__m128i *) (c[3] + i))));
Packit 0652a1
  }
Packit 0652a1
  t[0] = _mm_unpacklo_epi32 (sum[0], sum[1]);
Packit 0652a1
  t[1] = _mm_unpacklo_epi32 (sum[2], sum[3]);
Packit 0652a1
  t[2] = _mm_unpackhi_epi32 (sum[0], sum[1]);
Packit 0652a1
  t[3] = _mm_unpackhi_epi32 (sum[2], sum[3]);
Packit 0652a1
Packit 0652a1
  sum[0] =
Packit 0652a1
      _mm_add_epi32 (_mm_unpacklo_epi64 (t[0], t[1]), _mm_unpackhi_epi64 (t[0],
Packit 0652a1
          t[1]));
Packit 0652a1
  sum[2] =
Packit 0652a1
      _mm_add_epi32 (_mm_unpacklo_epi64 (t[2], t[3]), _mm_unpackhi_epi64 (t[2],
Packit 0652a1
          t[3]));
Packit 0652a1
  sum[0] = _mm_add_epi32 (sum[0], sum[2]);
Packit 0652a1
Packit 0652a1
  sum[0] = _mm_srai_epi32 (sum[0], PRECISION_S16);
Packit 0652a1
  sum[0] = _mm_madd_epi16 (sum[0], f);
Packit 0652a1
Packit 0652a1
  sum[0] =
Packit 0652a1
      _mm_add_epi32 (sum[0], _mm_shuffle_epi32 (sum[0], _MM_SHUFFLE (2, 3, 2,
Packit 0652a1
              3)));
Packit 0652a1
  sum[0] =
Packit 0652a1
      _mm_add_epi32 (sum[0], _mm_shuffle_epi32 (sum[0], _MM_SHUFFLE (1, 1, 1,
Packit 0652a1
              1)));
Packit 0652a1
Packit 0652a1
  sum[0] = _mm_add_epi32 (sum[0], _mm_set1_epi32 (1 << (PRECISION_S16 - 1)));
Packit 0652a1
  sum[0] = _mm_srai_epi32 (sum[0], PRECISION_S16);
Packit 0652a1
  sum[0] = _mm_packs_epi32 (sum[0], sum[0]);
Packit 0652a1
  *o = _mm_extract_epi16 (sum[0], 0);
Packit 0652a1
}
Packit 0652a1
Packit 0652a1
static inline void
Packit 0652a1
inner_product_gdouble_full_1_sse2 (gdouble * o, const gdouble * a,
Packit 0652a1
    const gdouble * b, gint len, const gdouble * icoeff, gint bstride)
Packit 0652a1
{
Packit 0652a1
  gint i = 0;
Packit 0652a1
  __m128d sum = _mm_setzero_pd ();
Packit 0652a1
Packit 0652a1
  for (; i < len; i += 8) {
Packit 0652a1
    sum =
Packit 0652a1
        _mm_add_pd (sum, _mm_mul_pd (_mm_loadu_pd (a + i + 0),
Packit 0652a1
            _mm_load_pd (b + i + 0)));
Packit 0652a1
    sum =
Packit 0652a1
        _mm_add_pd (sum, _mm_mul_pd (_mm_loadu_pd (a + i + 2),
Packit 0652a1
            _mm_load_pd (b + i + 2)));
Packit 0652a1
    sum =
Packit 0652a1
        _mm_add_pd (sum, _mm_mul_pd (_mm_loadu_pd (a + i + 4),
Packit 0652a1
            _mm_load_pd (b + i + 4)));
Packit 0652a1
    sum =
Packit 0652a1
        _mm_add_pd (sum, _mm_mul_pd (_mm_loadu_pd (a + i + 6),
Packit 0652a1
            _mm_load_pd (b + i + 6)));
Packit 0652a1
  }
Packit 0652a1
  sum = _mm_add_sd (sum, _mm_unpackhi_pd (sum, sum));
Packit 0652a1
  _mm_store_sd (o, sum);
Packit 0652a1
}
Packit 0652a1
Packit 0652a1
static inline void
Packit 0652a1
inner_product_gdouble_linear_1_sse2 (gdouble * o, const gdouble * a,
Packit 0652a1
    const gdouble * b, gint len, const gdouble * icoeff, gint bstride)
Packit 0652a1
{
Packit 0652a1
  gint i = 0;
Packit 0652a1
  __m128d sum[2], t;
Packit 0652a1
  const gdouble *c[2] = { (gdouble *) ((gint8 *) b + 0 * bstride),
Packit 0652a1
    (gdouble *) ((gint8 *) b + 1 * bstride)
Packit 0652a1
  };
Packit 0652a1
Packit 0652a1
  sum[0] = sum[1] = _mm_setzero_pd ();
Packit 0652a1
Packit 0652a1
  for (; i < len; i += 4) {
Packit 0652a1
    t = _mm_loadu_pd (a + i + 0);
Packit 0652a1
    sum[0] = _mm_add_pd (sum[0], _mm_mul_pd (t, _mm_load_pd (c[0] + i + 0)));
Packit 0652a1
    sum[1] = _mm_add_pd (sum[1], _mm_mul_pd (t, _mm_load_pd (c[1] + i + 0)));
Packit 0652a1
    t = _mm_loadu_pd (a + i + 2);
Packit 0652a1
    sum[0] = _mm_add_pd (sum[0], _mm_mul_pd (t, _mm_load_pd (c[0] + i + 2)));
Packit 0652a1
    sum[1] = _mm_add_pd (sum[1], _mm_mul_pd (t, _mm_load_pd (c[1] + i + 2)));
Packit 0652a1
  }
Packit 0652a1
  sum[0] = _mm_mul_pd (_mm_sub_pd (sum[0], sum[1]), _mm_load1_pd (icoeff));
Packit 0652a1
  sum[0] = _mm_add_pd (sum[0], sum[1]);
Packit 0652a1
  sum[0] = _mm_add_sd (sum[0], _mm_unpackhi_pd (sum[0], sum[0]));
Packit 0652a1
  _mm_store_sd (o, sum[0]);
Packit 0652a1
}
Packit 0652a1
Packit 0652a1
static inline void
Packit 0652a1
inner_product_gdouble_cubic_1_sse2 (gdouble * o, const gdouble * a,
Packit 0652a1
    const gdouble * b, gint len, const gdouble * icoeff, gint bstride)
Packit 0652a1
{
Packit 0652a1
  gint i;
Packit 0652a1
  __m128d f[2], sum[4], t;
Packit 0652a1
  const gdouble *c[4] = { (gdouble *) ((gint8 *) b + 0 * bstride),
Packit 0652a1
    (gdouble *) ((gint8 *) b + 1 * bstride),
Packit 0652a1
    (gdouble *) ((gint8 *) b + 2 * bstride),
Packit 0652a1
    (gdouble *) ((gint8 *) b + 3 * bstride)
Packit 0652a1
  };
Packit 0652a1
Packit 0652a1
  f[0] = _mm_loadu_pd (icoeff + 0);
Packit 0652a1
  f[1] = _mm_loadu_pd (icoeff + 2);
Packit 0652a1
  sum[0] = sum[1] = sum[2] = sum[3] = _mm_setzero_pd ();
Packit 0652a1
Packit 0652a1
  for (i = 0; i < len; i += 2) {
Packit 0652a1
    t = _mm_loadu_pd (a + i + 0);
Packit 0652a1
    sum[0] = _mm_add_pd (sum[0], _mm_mul_pd (t, _mm_load_pd (c[0] + i)));
Packit 0652a1
    sum[1] = _mm_add_pd (sum[1], _mm_mul_pd (t, _mm_load_pd (c[1] + i)));
Packit 0652a1
    sum[2] = _mm_add_pd (sum[2], _mm_mul_pd (t, _mm_load_pd (c[2] + i)));
Packit 0652a1
    sum[3] = _mm_add_pd (sum[3], _mm_mul_pd (t, _mm_load_pd (c[3] + i)));
Packit 0652a1
  }
Packit 0652a1
  sum[0] =
Packit 0652a1
      _mm_mul_pd (sum[0], _mm_shuffle_pd (f[0], f[0], _MM_SHUFFLE2 (0, 0)));
Packit 0652a1
  sum[1] =
Packit 0652a1
      _mm_mul_pd (sum[1], _mm_shuffle_pd (f[0], f[0], _MM_SHUFFLE2 (1, 1)));
Packit 0652a1
  sum[2] =
Packit 0652a1
      _mm_mul_pd (sum[2], _mm_shuffle_pd (f[1], f[1], _MM_SHUFFLE2 (0, 0)));
Packit 0652a1
  sum[3] =
Packit 0652a1
      _mm_mul_pd (sum[3], _mm_shuffle_pd (f[1], f[1], _MM_SHUFFLE2 (1, 1)));
Packit 0652a1
  sum[0] = _mm_add_pd (sum[0], sum[1]);
Packit 0652a1
  sum[2] = _mm_add_pd (sum[2], sum[3]);
Packit 0652a1
  sum[0] = _mm_add_pd (sum[0], sum[2]);
Packit 0652a1
  sum[0] = _mm_add_sd (sum[0], _mm_unpackhi_pd (sum[0], sum[0]));
Packit 0652a1
  _mm_store_sd (o, sum[0]);
Packit 0652a1
}
Packit 0652a1
Packit 0652a1
MAKE_RESAMPLE_FUNC (gint16, full, 1, sse2);
Packit 0652a1
MAKE_RESAMPLE_FUNC (gint16, linear, 1, sse2);
Packit 0652a1
MAKE_RESAMPLE_FUNC (gint16, cubic, 1, sse2);
Packit 0652a1
Packit 0652a1
MAKE_RESAMPLE_FUNC (gdouble, full, 1, sse2);
Packit 0652a1
MAKE_RESAMPLE_FUNC (gdouble, linear, 1, sse2);
Packit 0652a1
MAKE_RESAMPLE_FUNC (gdouble, cubic, 1, sse2);
Packit 0652a1
Packit 0652a1
void
Packit 0652a1
interpolate_gint16_linear_sse2 (gpointer op, const gpointer ap,
Packit 0652a1
    gint len, const gpointer icp, gint astride)
Packit 0652a1
{
Packit 0652a1
  gint i = 0;
Packit 0652a1
  gint16 *o = op, *a = ap, *ic = icp;
Packit 0652a1
  __m128i ta, tb, t1, t2;
Packit 0652a1
  __m128i f = _mm_set_epi64x (0, *((gint64 *) ic));
Packit 0652a1
  const gint16 *c[2] = { (gint16 *) ((gint8 *) a + 0 * astride),
Packit 0652a1
    (gint16 *) ((gint8 *) a + 1 * astride)
Packit 0652a1
  };
Packit 0652a1
Packit 0652a1
  f = _mm_unpacklo_epi32 (f, f);
Packit 0652a1
  f = _mm_unpacklo_epi64 (f, f);
Packit 0652a1
Packit 0652a1
  for (; i < len; i += 8) {
Packit 0652a1
    ta = _mm_load_si128 ((__m128i *) (c[0] + i));
Packit 0652a1
    tb = _mm_load_si128 ((__m128i *) (c[1] + i));
Packit 0652a1
Packit 0652a1
    t1 = _mm_madd_epi16 (_mm_unpacklo_epi16 (ta, tb), f);
Packit 0652a1
    t2 = _mm_madd_epi16 (_mm_unpackhi_epi16 (ta, tb), f);
Packit 0652a1
Packit 0652a1
    t1 = _mm_add_epi32 (t1, _mm_set1_epi32 (1 << (PRECISION_S16 - 1)));
Packit 0652a1
    t2 = _mm_add_epi32 (t2, _mm_set1_epi32 (1 << (PRECISION_S16 - 1)));
Packit 0652a1
Packit 0652a1
    t1 = _mm_srai_epi32 (t1, PRECISION_S16);
Packit 0652a1
    t2 = _mm_srai_epi32 (t2, PRECISION_S16);
Packit 0652a1
Packit 0652a1
    t1 = _mm_packs_epi32 (t1, t2);
Packit 0652a1
    _mm_store_si128 ((__m128i *) (o + i), t1);
Packit 0652a1
  }
Packit 0652a1
}
Packit 0652a1
Packit 0652a1
void
Packit 0652a1
interpolate_gint16_cubic_sse2 (gpointer op, const gpointer ap,
Packit 0652a1
    gint len, const gpointer icp, gint astride)
Packit 0652a1
{
Packit 0652a1
  gint i = 0;
Packit 0652a1
  gint16 *o = op, *a = ap, *ic = icp;
Packit 0652a1
  __m128i ta, tb, tl1, tl2, th1, th2;
Packit 0652a1
  __m128i f[2];
Packit 0652a1
  const gint16 *c[4] = { (gint16 *) ((gint8 *) a + 0 * astride),
Packit 0652a1
    (gint16 *) ((gint8 *) a + 1 * astride),
Packit 0652a1
    (gint16 *) ((gint8 *) a + 2 * astride),
Packit 0652a1
    (gint16 *) ((gint8 *) a + 3 * astride)
Packit 0652a1
  };
Packit 0652a1
Packit 0652a1
  f[0] = _mm_set_epi16 (ic[1], ic[0], ic[1], ic[0], ic[1], ic[0], ic[1], ic[0]);
Packit 0652a1
  f[1] = _mm_set_epi16 (ic[3], ic[2], ic[3], ic[2], ic[3], ic[2], ic[3], ic[2]);
Packit 0652a1
Packit 0652a1
  for (; i < len; i += 8) {
Packit 0652a1
    ta = _mm_load_si128 ((__m128i *) (c[0] + i));
Packit 0652a1
    tb = _mm_load_si128 ((__m128i *) (c[1] + i));
Packit 0652a1
Packit 0652a1
    tl1 = _mm_madd_epi16 (_mm_unpacklo_epi16 (ta, tb), f[0]);
Packit 0652a1
    th1 = _mm_madd_epi16 (_mm_unpackhi_epi16 (ta, tb), f[0]);
Packit 0652a1
Packit 0652a1
    ta = _mm_load_si128 ((__m128i *) (c[2] + i));
Packit 0652a1
    tb = _mm_load_si128 ((__m128i *) (c[3] + i));
Packit 0652a1
Packit 0652a1
    tl2 = _mm_madd_epi16 (_mm_unpacklo_epi16 (ta, tb), f[1]);
Packit 0652a1
    th2 = _mm_madd_epi16 (_mm_unpackhi_epi16 (ta, tb), f[1]);
Packit 0652a1
Packit 0652a1
    tl1 = _mm_add_epi32 (tl1, tl2);
Packit 0652a1
    th1 = _mm_add_epi32 (th1, th2);
Packit 0652a1
Packit 0652a1
    tl1 = _mm_add_epi32 (tl1, _mm_set1_epi32 (1 << (PRECISION_S16 - 1)));
Packit 0652a1
    th1 = _mm_add_epi32 (th1, _mm_set1_epi32 (1 << (PRECISION_S16 - 1)));
Packit 0652a1
Packit 0652a1
    tl1 = _mm_srai_epi32 (tl1, PRECISION_S16);
Packit 0652a1
    th1 = _mm_srai_epi32 (th1, PRECISION_S16);
Packit 0652a1
Packit 0652a1
    tl1 = _mm_packs_epi32 (tl1, th1);
Packit 0652a1
    _mm_store_si128 ((__m128i *) (o + i), tl1);
Packit 0652a1
  }
Packit 0652a1
}
Packit 0652a1
Packit 0652a1
void
Packit 0652a1
interpolate_gdouble_linear_sse2 (gpointer op, const gpointer ap,
Packit 0652a1
    gint len, const gpointer icp, gint astride)
Packit 0652a1
{
Packit 0652a1
  gint i;
Packit 0652a1
  gdouble *o = op, *a = ap, *ic = icp;
Packit 0652a1
  __m128d f[2], t1, t2;
Packit 0652a1
  const gdouble *c[2] = { (gdouble *) ((gint8 *) a + 0 * astride),
Packit 0652a1
    (gdouble *) ((gint8 *) a + 1 * astride)
Packit 0652a1
  };
Packit 0652a1
Packit 0652a1
  f[0] = _mm_load1_pd (ic + 0);
Packit 0652a1
  f[1] = _mm_load1_pd (ic + 1);
Packit 0652a1
Packit 0652a1
  for (i = 0; i < len; i += 4) {
Packit 0652a1
    t1 = _mm_mul_pd (_mm_load_pd (c[0] + i + 0), f[0]);
Packit 0652a1
    t2 = _mm_mul_pd (_mm_load_pd (c[1] + i + 0), f[1]);
Packit 0652a1
    _mm_store_pd (o + i + 0, _mm_add_pd (t1, t2));
Packit 0652a1
Packit 0652a1
    t1 = _mm_mul_pd (_mm_load_pd (c[0] + i + 2), f[0]);
Packit 0652a1
    t2 = _mm_mul_pd (_mm_load_pd (c[1] + i + 2), f[1]);
Packit 0652a1
    _mm_store_pd (o + i + 2, _mm_add_pd (t1, t2));
Packit 0652a1
  }
Packit 0652a1
}
Packit 0652a1
Packit 0652a1
void
Packit 0652a1
interpolate_gdouble_cubic_sse2 (gpointer op, const gpointer ap,
Packit 0652a1
    gint len, const gpointer icp, gint astride)
Packit 0652a1
{
Packit 0652a1
  gint i;
Packit 0652a1
  gdouble *o = op, *a = ap, *ic = icp;
Packit 0652a1
  __m128d f[4], t[4];
Packit 0652a1
  const gdouble *c[4] = { (gdouble *) ((gint8 *) a + 0 * astride),
Packit 0652a1
    (gdouble *) ((gint8 *) a + 1 * astride),
Packit 0652a1
    (gdouble *) ((gint8 *) a + 2 * astride),
Packit 0652a1
    (gdouble *) ((gint8 *) a + 3 * astride)
Packit 0652a1
  };
Packit 0652a1
Packit 0652a1
  f[0] = _mm_load1_pd (ic + 0);
Packit 0652a1
  f[1] = _mm_load1_pd (ic + 1);
Packit 0652a1
  f[2] = _mm_load1_pd (ic + 2);
Packit 0652a1
  f[3] = _mm_load1_pd (ic + 3);
Packit 0652a1
Packit 0652a1
  for (i = 0; i < len; i += 2) {
Packit 0652a1
    t[0] = _mm_mul_pd (_mm_load_pd (c[0] + i + 0), f[0]);
Packit 0652a1
    t[1] = _mm_mul_pd (_mm_load_pd (c[1] + i + 0), f[1]);
Packit 0652a1
    t[2] = _mm_mul_pd (_mm_load_pd (c[2] + i + 0), f[2]);
Packit 0652a1
    t[3] = _mm_mul_pd (_mm_load_pd (c[3] + i + 0), f[3]);
Packit 0652a1
    t[0] = _mm_add_pd (t[0], t[1]);
Packit 0652a1
    t[2] = _mm_add_pd (t[2], t[3]);
Packit 0652a1
    _mm_store_pd (o + i + 0, _mm_add_pd (t[0], t[2]));
Packit 0652a1
  }
Packit 0652a1
}
Packit 0652a1
Packit 0652a1
#endif