On Mon, Jul 29, 2013 at 04:06:12AM +0200, Petar Jovanovic wrote: > From: Petar Jovanovic <petar.jovano...@imgtec.com> > > Multiplication of two fractional word elements is not correct when sign > extension/promotion is needed. This change fixes it by adding correct > casts from unsigned to signed values. > In addition, the tests (dpaq_sa_l_w.c and dpsq_sa_l_w.c) have been extended > to trigger the current issue. > > Signed-off-by: Petar Jovanovic <petar.jovano...@imgtec.com> > --- > target-mips/dsp_helper.c | 2 +- > tests/tcg/mips/mips32-dsp/dpaq_sa_l_w.c | 64 > +++++++++++++++++++++++++++---- > tests/tcg/mips/mips32-dsp/dpsq_sa_l_w.c | 4 +- > 3 files changed, 59 insertions(+), 11 deletions(-) > > diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c > index 93f5d9e..b088a25 100644 > --- a/target-mips/dsp_helper.c > +++ b/target-mips/dsp_helper.c > @@ -583,7 +583,7 @@ static inline int64_t mipsdsp_mul_q31_q31(int32_t ac, > uint32_t a, uint32_t b, > temp = (0x01ull << 63) - 1; > set_DSPControl_overflow_flag(1, 16 + ac, env); > } else { > - temp = ((uint64_t)a * (uint64_t)b) << 1; > + temp = ((int64_t)(int32_t)a * (int32_t)b) << 1; > } > > return temp; > diff --git a/tests/tcg/mips/mips32-dsp/dpaq_sa_l_w.c > b/tests/tcg/mips/mips32-dsp/dpaq_sa_l_w.c > index ce86484..cbf9007 100644 > --- a/tests/tcg/mips/mips32-dsp/dpaq_sa_l_w.c > +++ b/tests/tcg/mips/mips32-dsp/dpaq_sa_l_w.c > @@ -14,7 +14,7 @@ int main() > resultdsp = 0x01; > __asm > ("mthi %0, $ac1\n\t" > - "mtlo %0, $ac1\n\t" > + "mtlo %1, $ac1\n\t" > "dpaq_sa.l.w $ac1, %3, %4\n\t" > "mfhi %0, $ac1\n\t" > "mflo %1, $ac1\n\t" > @@ -27,8 +27,8 @@ int main() > assert(ach == resulth); > assert(acl == resultl); > > - ach = 0x12; > - acl = 0x48; > + ach = 0x00000012; > + acl = 0x00000048; > rs = 0x80000000; > rt = 0x80000000; > > @@ -37,7 +37,7 @@ int main() > resultdsp = 0x01; > __asm > ("mthi %0, $ac1\n\t" > - "mtlo %0, $ac1\n\t" > + "mtlo %1, $ac1\n\t" > "dpaq_sa.l.w $ac1, %3, %4\n\t" > "mfhi %0, $ac1\n\t" > "mflo %1, $ac1\n\t" > @@ -51,16 +51,64 @@ int main() > assert(acl == resultl); > > ach = 0x741532A0; > - acl = 0xfceabb08; > + acl = 0xFCEABB08; > rs = 0x80000000; > rt = 0x80000000; > > - resulth = 0x7fffffff; > - resultl = 0xffffffff; > + resulth = 0x7FFFFFFF; > + resultl = 0xFFFFFFFF; > resultdsp = 0x01; > __asm > ("mthi %0, $ac1\n\t" > - "mtlo %0, $ac1\n\t" > + "mtlo %1, $ac1\n\t" > + "dpaq_sa.l.w $ac1, %3, %4\n\t" > + "mfhi %0, $ac1\n\t" > + "mflo %1, $ac1\n\t" > + "rddsp %2\n\t" > + : "+r"(ach), "+r"(acl), "=r"(dsp) > + : "r"(rs), "r"(rt) > + ); > + dsp = (dsp >> 17) & 0x01; > + assert(dsp == resultdsp); > + assert(ach == resulth); > + assert(acl == resultl); > + > + ach = 0; > + acl = 0; > + rs = 0xC0000000; > + rt = 0x7FFFFFFF; > + > + resulth = 0xC0000000; > + resultl = 0x80000000; > + resultdsp = 0; > + __asm > + ("wrdsp $0\n\t" > + "mthi %0, $ac1\n\t" > + "mtlo %1, $ac1\n\t" > + "dpaq_sa.l.w $ac1, %3, %4\n\t" > + "mfhi %0, $ac1\n\t" > + "mflo %1, $ac1\n\t" > + "rddsp %2\n\t" > + : "+r"(ach), "+r"(acl), "=r"(dsp) > + : "r"(rs), "r"(rt) > + ); > + dsp = (dsp >> 17) & 0x01; > + assert(dsp == resultdsp); > + assert(ach == resulth); > + assert(acl == resultl); > + > + ach = 0x20000000; > + acl = 0; > + rs = 0xE0000000; > + rt = 0x7FFFFFFF; > + > + resulth = 0; > + resultl = 0x40000000; > + resultdsp = 0; > + __asm > + ("wrdsp $0\n\t" > + "mthi %0, $ac1\n\t" > + "mtlo %1, $ac1\n\t" > "dpaq_sa.l.w $ac1, %3, %4\n\t" > "mfhi %0, $ac1\n\t" > "mflo %1, $ac1\n\t" > diff --git a/tests/tcg/mips/mips32-dsp/dpsq_sa_l_w.c > b/tests/tcg/mips/mips32-dsp/dpsq_sa_l_w.c > index b7b73fd..eda3b14 100644 > --- a/tests/tcg/mips/mips32-dsp/dpsq_sa_l_w.c > +++ b/tests/tcg/mips/mips32-dsp/dpsq_sa_l_w.c > @@ -9,8 +9,8 @@ int main() > > rs = 0xBC0123AD; > rt = 0x01643721; > - resulth = 0xfdf4cbe0; > - resultl = 0xd138776b; > + resulth = 0x00BD3A22; > + resultl = 0xD138776B; > resultdsp = 0x00; > __asm > ("mthi %0, $ac1\n\t"
Thanks, applied. -- Aurelien Jarno GPG: 1024D/F1BCDB73 aurel...@aurel32.net http://www.aurel32.net