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:
		
							parent
							
								
									f05d4d94d6
								
							
						
					
					
						commit
						b6a9f4682e
					
				| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue