summaryrefslogtreecommitdiffstats
path: root/src/pulsecore/svolume_mmx.c
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@collabora.co.uk>2009-10-29 14:49:52 +0100
committerLennart Poettering <lennart@poettering.net>2009-10-30 05:09:15 +0100
commit056930cbcde117036cdb707ed3e111b7833724ea (patch)
treef8e6255619b94a21c911a0ea6afc374c3e56133f /src/pulsecore/svolume_mmx.c
parent8a49514f74cacd523117aabcd4514543db63a4ed (diff)
svolume: fix MMX error
We need to sign extend the lower part of the multiplication before adding it to the higher part. Makes -1 * 0xffff work again.
Diffstat (limited to 'src/pulsecore/svolume_mmx.c')
-rw-r--r--src/pulsecore/svolume_mmx.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/src/pulsecore/svolume_mmx.c b/src/pulsecore/svolume_mmx.c
index 5bf72ed0..a011789c 100644
--- a/src/pulsecore/svolume_mmx.c
+++ b/src/pulsecore/svolume_mmx.c
@@ -62,7 +62,9 @@
" movq "#s", %%mm5 \n\t" \
" pmulhw "#v", "#s" \n\t" /* .. | 0 | vl*p0 | */ \
" paddw %%mm4, "#s" \n\t" /* .. | 0 | vl*p0 | + sign correct */ \
+ " pslld $16, "#s" \n\t" /* .. | vl*p0 | 0 | */ \
" psrld $16, "#v" \n\t" /* .. | 0 | vh | */ \
+ " psrad $16, "#s" \n\t" /* .. | vl*p0 | sign extend */ \
" pmaddwd %%mm5, "#v" \n\t" /* .. | p0 * vh | */ \
" paddd "#s", "#v" \n\t" /* .. | p0 * v0 | */ \
" packssdw "#v", "#v" \n\t" /* .. | p1*v1 | p0*v0 | */
@@ -257,11 +259,14 @@ static void run_test (void) {
printf ("checking MMX %zd\n", sizeof (samples));
pa_random (samples, sizeof (samples));
+ /* for (i = 0; i < SAMPLES; i++)
+ samples[i] = -1; */
memcpy (samples_ref, samples, sizeof (samples));
memcpy (samples_orig, samples, sizeof (samples));
for (i = 0; i < CHANNELS; i++)
volumes[i] = rand() >> 1;
+ /* volumes[i] = 0x0000ffff; */
for (padding = 0; padding < PADDING; padding++, i++)
volumes[i] = volumes[padding];
@@ -269,7 +274,7 @@ static void run_test (void) {
pa_volume_s16ne_mmx (samples, volumes, CHANNELS, sizeof (samples));
for (i = 0; i < SAMPLES; i++) {
if (samples[i] != samples_ref[i]) {
- printf ("%d: %04x != %04x (%04x * %04x)\n", i, samples[i], samples_ref[i],
+ printf ("%d: %04x != %04x (%04x * %08x)\n", i, samples[i], samples_ref[i],
samples_orig[i], volumes[i % CHANNELS]);
}
}