From 6e5dbed51ee508759ed8b5adabc998ba8faf4774 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 20 Aug 2009 19:46:06 +0200 Subject: remap: add MMX mono to stereo --- src/pulsecore/remap_mmx.c | 174 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 src/pulsecore/remap_mmx.c (limited to 'src/pulsecore/remap_mmx.c') diff --git a/src/pulsecore/remap_mmx.c b/src/pulsecore/remap_mmx.c new file mode 100644 index 00000000..6690cfa4 --- /dev/null +++ b/src/pulsecore/remap_mmx.c @@ -0,0 +1,174 @@ +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2009 Wim Taymans + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include +#include +#include + +#include "cpu-x86.h" +#include "remap.h" + +#define LOAD_SAMPLES \ + " movq (%1), %%mm0 \n\t" \ + " movq 8(%1), %%mm2 \n\t" \ + " movq 16(%1), %%mm4 \n\t" \ + " movq 24(%1), %%mm6 \n\t" \ + " movq %%mm0, %%mm1 \n\t" \ + " movq %%mm2, %%mm3 \n\t" \ + " movq %%mm4, %%mm5 \n\t" \ + " movq %%mm6, %%mm7 \n\t" + +#define UNPACK_SAMPLES(s) \ + " punpckl"#s" %%mm0, %%mm0 \n\t" \ + " punpckh"#s" %%mm1, %%mm1 \n\t" \ + " punpckl"#s" %%mm2, %%mm2 \n\t" \ + " punpckh"#s" %%mm3, %%mm3 \n\t" \ + " punpckl"#s" %%mm4, %%mm4 \n\t" \ + " punpckh"#s" %%mm5, %%mm5 \n\t" \ + " punpckl"#s" %%mm6, %%mm6 \n\t" \ + " punpckh"#s" %%mm7, %%mm7 \n\t" \ + +#define STORE_SAMPLES \ + " movq %%mm0, (%0) \n\t" \ + " movq %%mm1, 8(%0) \n\t" \ + " movq %%mm2, 16(%0) \n\t" \ + " movq %%mm3, 24(%0) \n\t" \ + " movq %%mm4, 32(%0) \n\t" \ + " movq %%mm5, 40(%0) \n\t" \ + " movq %%mm6, 48(%0) \n\t" \ + " movq %%mm7, 56(%0) \n\t" \ + " add $32, %1 \n\t" \ + " add $64, %0 \n\t" + +#define HANDLE_SINGLE(s) \ + " movd (%1), %%mm0 \n\t" \ + " movq %%mm0, %%mm1 \n\t" \ + " punpckl"#s" %%mm0, %%mm0 \n\t" \ + " movq %%mm0, (%0) \n\t" \ + " add $4, %1 \n\t" \ + " add $8, %0 \n\t" + +static void remap_mono_to_stereo_mmx (pa_remap_t *m, void *dst, const void *src, unsigned n) { + pa_reg_x86 temp; + + switch (*m->format) { + case PA_SAMPLE_FLOAT32NE: + { + __asm__ __volatile__ ( + " mov %3, %2 \n\t" + " sar $3, %2 \n\t" /* prepare for processing 8 samples at a time */ + " cmp $0, %2 \n\t" + " je 2f \n\t" + + "1: \n\t" /* do samples in groups of 8 */ + LOAD_SAMPLES + UNPACK_SAMPLES(dq) + STORE_SAMPLES + " dec %2 \n\t" + " jne 1b \n\t" + + "2: \n\t" + " mov %3, %2 \n\t" + " and $7, %2 \n\t" /* prepare for processing the remaining samples */ + " je 4f \n\t" + + "3: \n\t" + HANDLE_SINGLE(dq) + " dec %2 \n\t" + " jne 3b \n\t" + + "4: \n\t" + " emms \n\t" + + : "+r" (dst), "+r" (src), "=&r" (temp) + : "r" ((pa_reg_x86)n) + : "cc" + ); + break; + } + case PA_SAMPLE_S16NE: + { + __asm__ __volatile__ ( + " mov %3, %2 \n\t" + " sar $3, %2 \n\t" /* prepare for processing 8 samples at a time */ + " cmp $0, %2 \n\t" + " je 2f \n\t" + + "1: \n\t" /* do samples in groups of 16 */ + LOAD_SAMPLES + UNPACK_SAMPLES(wd) + STORE_SAMPLES + " dec %2 \n\t" + " jne 1b \n\t" + + "2: \n\t" + " mov %3, %2 \n\t" + " and $7, %2 \n\t" /* prepare for processing the remaining samples */ + " je 4f \n\t" + + "3: \n\t" + HANDLE_SINGLE(wd) + " dec %2 \n\t" + " jne 3b \n\t" + + "4: \n\t" + " emms \n\t" + + : "+r" (dst), "+r" (src), "=&r" (temp) + : "r" ((pa_reg_x86)n) + : "cc" + ); + break; + } + default: + pa_assert_not_reached(); + } +} + +/* set the function that will execute the remapping based on the matrices */ +static void init_remap_mmx (pa_remap_t *m) { + unsigned n_oc, n_ic; + + n_oc = m->o_ss->channels; + n_ic = m->i_ss->channels; + + /* find some common channel remappings, fall back to full matrix operation. */ + if (n_ic == 1 && n_oc == 2 && + m->map_table_f[0][0] >= 1.0 && m->map_table_f[1][0] >= 1.0) { + m->do_remap = (pa_do_remap_func_t) remap_mono_to_stereo_mmx; + pa_log_info("Using MMX mono to stereo remapping"); + } +} + +void pa_remap_func_init_mmx (pa_cpu_x86_flag_t flags) { +#if defined (__i386__) || defined (__amd64__) + pa_log_info("Initialising MMX optimized remappers."); + + pa_set_init_remap_func ((pa_init_remap_func_t) init_remap_mmx); +#endif /* defined (__i386__) || defined (__amd64__) */ +} -- cgit From 6076cef2092391d8b46aa84f86857cffebce4583 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 20 Aug 2009 20:00:50 +0200 Subject: remap: make the MMX code pretier --- src/pulsecore/remap_mmx.c | 74 +++++++++++++++-------------------------------- 1 file changed, 24 insertions(+), 50 deletions(-) (limited to 'src/pulsecore/remap_mmx.c') diff --git a/src/pulsecore/remap_mmx.c b/src/pulsecore/remap_mmx.c index 6690cfa4..bfcae6c5 100644 --- a/src/pulsecore/remap_mmx.c +++ b/src/pulsecore/remap_mmx.c @@ -73,6 +73,28 @@ " add $4, %1 \n\t" \ " add $8, %0 \n\t" +#define MONO_TO_STEREO(s) \ + " mov %3, %2 \n\t" \ + " sar $3, %2 \n\t" \ + " cmp $0, %2 \n\t" \ + " je 2f \n\t" \ + "1: \n\t" \ + LOAD_SAMPLES \ + UNPACK_SAMPLES(s) \ + STORE_SAMPLES \ + " dec %2 \n\t" \ + " jne 1b \n\t" \ + "2: \n\t" \ + " mov %3, %2 \n\t" \ + " and $7, %2 \n\t" \ + " je 4f \n\t" \ + "3: \n\t" \ + HANDLE_SINGLE(s) \ + " dec %2 \n\t" \ + " jne 3b \n\t" \ + "4: \n\t" \ + " emms \n\t" + static void remap_mono_to_stereo_mmx (pa_remap_t *m, void *dst, const void *src, unsigned n) { pa_reg_x86 temp; @@ -80,31 +102,7 @@ static void remap_mono_to_stereo_mmx (pa_remap_t *m, void *dst, const void *src, case PA_SAMPLE_FLOAT32NE: { __asm__ __volatile__ ( - " mov %3, %2 \n\t" - " sar $3, %2 \n\t" /* prepare for processing 8 samples at a time */ - " cmp $0, %2 \n\t" - " je 2f \n\t" - - "1: \n\t" /* do samples in groups of 8 */ - LOAD_SAMPLES - UNPACK_SAMPLES(dq) - STORE_SAMPLES - " dec %2 \n\t" - " jne 1b \n\t" - - "2: \n\t" - " mov %3, %2 \n\t" - " and $7, %2 \n\t" /* prepare for processing the remaining samples */ - " je 4f \n\t" - - "3: \n\t" - HANDLE_SINGLE(dq) - " dec %2 \n\t" - " jne 3b \n\t" - - "4: \n\t" - " emms \n\t" - + MONO_TO_STEREO(dq) /* do doubles to quads */ : "+r" (dst), "+r" (src), "=&r" (temp) : "r" ((pa_reg_x86)n) : "cc" @@ -114,31 +112,7 @@ static void remap_mono_to_stereo_mmx (pa_remap_t *m, void *dst, const void *src, case PA_SAMPLE_S16NE: { __asm__ __volatile__ ( - " mov %3, %2 \n\t" - " sar $3, %2 \n\t" /* prepare for processing 8 samples at a time */ - " cmp $0, %2 \n\t" - " je 2f \n\t" - - "1: \n\t" /* do samples in groups of 16 */ - LOAD_SAMPLES - UNPACK_SAMPLES(wd) - STORE_SAMPLES - " dec %2 \n\t" - " jne 1b \n\t" - - "2: \n\t" - " mov %3, %2 \n\t" - " and $7, %2 \n\t" /* prepare for processing the remaining samples */ - " je 4f \n\t" - - "3: \n\t" - HANDLE_SINGLE(wd) - " dec %2 \n\t" - " jne 3b \n\t" - - "4: \n\t" - " emms \n\t" - + MONO_TO_STEREO(wd) /* do words to doubles */ : "+r" (dst), "+r" (src), "=&r" (temp) : "r" ((pa_reg_x86)n) : "cc" -- cgit From 57fb77134b319c6f7eaf262c561082fcae49c1a3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 24 Aug 2009 17:01:44 +0200 Subject: remap: fix build for non-x86 builds --- src/pulsecore/remap_mmx.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/pulsecore/remap_mmx.c') diff --git a/src/pulsecore/remap_mmx.c b/src/pulsecore/remap_mmx.c index bfcae6c5..00252dac 100644 --- a/src/pulsecore/remap_mmx.c +++ b/src/pulsecore/remap_mmx.c @@ -95,6 +95,7 @@ "4: \n\t" \ " emms \n\t" +#if defined (__i386__) || defined (__amd64__) static void remap_mono_to_stereo_mmx (pa_remap_t *m, void *dst, const void *src, unsigned n) { pa_reg_x86 temp; @@ -138,6 +139,7 @@ static void init_remap_mmx (pa_remap_t *m) { pa_log_info("Using MMX mono to stereo remapping"); } } +#endif /* defined (__i386__) || defined (__amd64__) */ void pa_remap_func_init_mmx (pa_cpu_x86_flag_t flags) { #if defined (__i386__) || defined (__amd64__) -- cgit From 59070892ed070d0c42d8d9b91d267a39c5763a9c Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 26 Aug 2009 19:29:21 +0200 Subject: remap: cleanup assembler a little --- src/pulsecore/remap_mmx.c | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) (limited to 'src/pulsecore/remap_mmx.c') diff --git a/src/pulsecore/remap_mmx.c b/src/pulsecore/remap_mmx.c index 00252dac..b5fe82ee 100644 --- a/src/pulsecore/remap_mmx.c +++ b/src/pulsecore/remap_mmx.c @@ -51,7 +51,7 @@ " punpckl"#s" %%mm4, %%mm4 \n\t" \ " punpckh"#s" %%mm5, %%mm5 \n\t" \ " punpckl"#s" %%mm6, %%mm6 \n\t" \ - " punpckh"#s" %%mm7, %%mm7 \n\t" \ + " punpckh"#s" %%mm7, %%mm7 \n\t" #define STORE_SAMPLES \ " movq %%mm0, (%0) \n\t" \ @@ -67,32 +67,31 @@ #define HANDLE_SINGLE(s) \ " movd (%1), %%mm0 \n\t" \ - " movq %%mm0, %%mm1 \n\t" \ " punpckl"#s" %%mm0, %%mm0 \n\t" \ " movq %%mm0, (%0) \n\t" \ " add $4, %1 \n\t" \ " add $8, %0 \n\t" -#define MONO_TO_STEREO(s) \ - " mov %3, %2 \n\t" \ - " sar $3, %2 \n\t" \ - " cmp $0, %2 \n\t" \ - " je 2f \n\t" \ - "1: \n\t" \ - LOAD_SAMPLES \ - UNPACK_SAMPLES(s) \ - STORE_SAMPLES \ - " dec %2 \n\t" \ - " jne 1b \n\t" \ - "2: \n\t" \ - " mov %3, %2 \n\t" \ - " and $7, %2 \n\t" \ - " je 4f \n\t" \ - "3: \n\t" \ - HANDLE_SINGLE(s) \ - " dec %2 \n\t" \ - " jne 3b \n\t" \ - "4: \n\t" \ +#define MONO_TO_STEREO(s) \ + " mov %3, %2 \n\t" \ + " sar $3, %2 \n\t" \ + " cmp $0, %2 \n\t" \ + " je 2f \n\t" \ + "1: \n\t" \ + LOAD_SAMPLES \ + UNPACK_SAMPLES(s) \ + STORE_SAMPLES \ + " dec %2 \n\t" \ + " jne 1b \n\t" \ + "2: \n\t" \ + " mov %3, %2 \n\t" \ + " and $7, %2 \n\t" \ + " je 4f \n\t" \ + "3: \n\t" \ + HANDLE_SINGLE(s) \ + " dec %2 \n\t" \ + " jne 3b \n\t" \ + "4: \n\t" \ " emms \n\t" #if defined (__i386__) || defined (__amd64__) -- cgit From dc221f204b89fca85c0125e55f3afea4a807ffa7 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Sat, 29 Aug 2009 12:22:42 +0200 Subject: remap: fix counters for mmx and sse remap Take the size of the sample into account when calculating the amount of samples we process in parallel. --- src/pulsecore/remap_mmx.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) (limited to 'src/pulsecore/remap_mmx.c') diff --git a/src/pulsecore/remap_mmx.c b/src/pulsecore/remap_mmx.c index b5fe82ee..79e4f1fc 100644 --- a/src/pulsecore/remap_mmx.c +++ b/src/pulsecore/remap_mmx.c @@ -65,16 +65,24 @@ " add $32, %1 \n\t" \ " add $64, %0 \n\t" -#define HANDLE_SINGLE(s) \ +#define HANDLE_SINGLE_dq() \ " movd (%1), %%mm0 \n\t" \ - " punpckl"#s" %%mm0, %%mm0 \n\t" \ + " punpckldq %%mm0, %%mm0 \n\t" \ " movq %%mm0, (%0) \n\t" \ " add $4, %1 \n\t" \ " add $8, %0 \n\t" -#define MONO_TO_STEREO(s) \ - " mov %3, %2 \n\t" \ - " sar $3, %2 \n\t" \ +#define HANDLE_SINGLE_wd() \ + " movw (%1), %w3 \n\t" \ + " movd %3, %%mm0 \n\t" \ + " punpcklwd %%mm0, %%mm0 \n\t" \ + " movd %%mm0, (%0) \n\t" \ + " add $2, %1 \n\t" \ + " add $4, %0 \n\t" + +#define MONO_TO_STEREO(s,shift,mask) \ + " mov %4, %2 \n\t" \ + " sar $"#shift", %2 \n\t" \ " cmp $0, %2 \n\t" \ " je 2f \n\t" \ "1: \n\t" \ @@ -84,11 +92,11 @@ " dec %2 \n\t" \ " jne 1b \n\t" \ "2: \n\t" \ - " mov %3, %2 \n\t" \ - " and $7, %2 \n\t" \ + " mov %4, %2 \n\t" \ + " and $"#mask", %2 \n\t" \ " je 4f \n\t" \ "3: \n\t" \ - HANDLE_SINGLE(s) \ + HANDLE_SINGLE_##s() \ " dec %2 \n\t" \ " jne 3b \n\t" \ "4: \n\t" \ @@ -96,14 +104,14 @@ #if defined (__i386__) || defined (__amd64__) static void remap_mono_to_stereo_mmx (pa_remap_t *m, void *dst, const void *src, unsigned n) { - pa_reg_x86 temp; + pa_reg_x86 temp, temp2; switch (*m->format) { case PA_SAMPLE_FLOAT32NE: { __asm__ __volatile__ ( - MONO_TO_STEREO(dq) /* do doubles to quads */ - : "+r" (dst), "+r" (src), "=&r" (temp) + MONO_TO_STEREO(dq,3,7) /* do doubles to quads */ + : "+r" (dst), "+r" (src), "=&r" (temp), "=&r" (temp2) : "r" ((pa_reg_x86)n) : "cc" ); @@ -112,8 +120,8 @@ static void remap_mono_to_stereo_mmx (pa_remap_t *m, void *dst, const void *src, case PA_SAMPLE_S16NE: { __asm__ __volatile__ ( - MONO_TO_STEREO(wd) /* do words to doubles */ - : "+r" (dst), "+r" (src), "=&r" (temp) + MONO_TO_STEREO(wd,4,15) /* do words to doubles */ + : "+r" (dst), "+r" (src), "=&r" (temp), "=&r" (temp2) : "r" ((pa_reg_x86)n) : "cc" ); -- cgit From 71e066c873e5bd31bd446ac0f8d0e97cc0b12ace Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 9 Sep 2009 04:28:22 +0200 Subject: simd: be more precise which SIMD optimizations we activate --- src/pulsecore/remap_mmx.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/pulsecore/remap_mmx.c') diff --git a/src/pulsecore/remap_mmx.c b/src/pulsecore/remap_mmx.c index 79e4f1fc..d358a58b 100644 --- a/src/pulsecore/remap_mmx.c +++ b/src/pulsecore/remap_mmx.c @@ -150,8 +150,12 @@ static void init_remap_mmx (pa_remap_t *m) { void pa_remap_func_init_mmx (pa_cpu_x86_flag_t flags) { #if defined (__i386__) || defined (__amd64__) - pa_log_info("Initialising MMX optimized remappers."); - pa_set_init_remap_func ((pa_init_remap_func_t) init_remap_mmx); + if (flags & PA_CPU_X86_MMX) { + pa_log_info("Initialising MMX optimized remappers."); + + pa_set_init_remap_func ((pa_init_remap_func_t) init_remap_mmx); + } + #endif /* defined (__i386__) || defined (__amd64__) */ } -- cgit