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]);          }      }  | 
