summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@collabora.co.uk>2009-10-29 14:49:52 +0100
committerColin Guthrie <cguthrie@mandriva.org>2009-10-30 09:07:00 +0000
commitcc1e90f94b159cdf2d59dfb604613bf04582be50 (patch)
tree0e51034b5d6996471c61dc6a44d36961d2c235aa
parentafd1b6d355ef1a41cb3592485855e273a5de69c1 (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.c7
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]);
}
}