diff options
author | Wim Taymans <wim.taymans@collabora.co.uk> | 2009-10-29 14:49:52 +0100 |
---|---|---|
committer | Colin Guthrie <cguthrie@mandriva.org> | 2009-10-30 09:07:00 +0000 |
commit | cc1e90f94b159cdf2d59dfb604613bf04582be50 (patch) | |
tree | 0e51034b5d6996471c61dc6a44d36961d2c235aa | |
parent | afd1b6d355ef1a41cb3592485855e273a5de69c1 (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.
-rw-r--r-- | src/pulsecore/svolume_mmx.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/src/pulsecore/svolume_mmx.c b/src/pulsecore/svolume_mmx.c index 1768eb50..aa04a522 100644 --- a/src/pulsecore/svolume_mmx.c +++ b/src/pulsecore/svolume_mmx.c @@ -60,7 +60,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 | */ @@ -255,11 +257,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]; @@ -267,7 +272,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]); } } |