target-mips: fix mipsdsp_mul_q31_q31

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.jovanovic@imgtec.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
Petar Jovanovic 2013-07-29 04:06:12 +02:00 committed by Aurelien Jarno
parent f05d4d94d6
commit b6a9f4682e
3 changed files with 59 additions and 11 deletions

View File

@ -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;

View File

@ -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"

View File

@ -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"