Commit eec8972a authored by Petar Jovanovic's avatar Petar Jovanovic Committed by Aurelien Jarno
Browse files

target-mips: Fix incorrect reads and writes to DSPControl register



Upper 4 bits of ccond (bits 31..28 ) of DSPControl register are not used in
the MIPS32 architecture. They are used in the MIPS64 architecture. For MIPS32
these bits must be written as zero, and return zero on read.

The change fixes writes (WRDSP) and reads (RDDSP) to the register. It also fixes
the tests that use these instructions, and makes them smaller and simpler.

Signed-off-by: default avatarPetar Jovanovic <petarj@mips.com>
Signed-off-by: default avatarAurelien Jarno <aurelien@aurel32.net>
parent a795ef8d
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -3948,7 +3948,11 @@ void helper_wrdsp(target_ulong rs, target_ulong mask_num, CPUMIPSState *env)
    if (mask[4] == 1) {
        overwrite &= 0x00FFFFFF;
        newbits   &= 0x00FFFFFF;
#if defined(TARGET_MIPS64)
        newbits   |= 0xFF000000 & rs;
#else
        newbits   |= 0x0F000000 & rs;
#endif
    }

    if (mask[5] == 1) {
@@ -3999,7 +4003,11 @@ target_ulong helper_rddsp(target_ulong masknum, CPUMIPSState *env)
    }

    if (mask[4] == 1) {
#if defined(TARGET_MIPS64)
        temp |= dsp & 0xFF000000;
#else
        temp |= dsp & 0x0F000000;
#endif
    }

    if (mask[5] == 1) {
+12 −20
Original line number Diff line number Diff line
@@ -6,9 +6,8 @@ int main()
    int dsp_i, dsp_o;
    int ccond_i, outflag_i, efi_i, c_i, scount_i, pos_i;
    int ccond_o, outflag_o, efi_o, c_o, scount_o, pos_o;
    int ccond_r, outflag_r, efi_r, c_r, scount_r, pos_r;

    ccond_i   = 0x000000BC;/* 4 */
    ccond_i   = 0x0000000C;  /* 4 */
    outflag_i = 0x0000001B;  /* 3 */
    efi_i     = 0x00000001;  /* 5 */
    c_i       = 0x00000001;  /* 2 */
@@ -22,13 +21,6 @@ int main()
            (scount_i  <<  7) | \
            pos_i;

    ccond_r   = ccond_i;
    outflag_r = outflag_i;
    efi_r     = efi_i;
    c_r       = c_i;
    scount_r  = scount_i;
    pos_r     = pos_i;

    __asm
        ("wrdsp %1, 0x3F\n\t"
         "rddsp %0, 0x3F\n\t"
@@ -43,12 +35,12 @@ int main()
    scount_o  = (dsp_o >>  7) & 0x3F;
    pos_o     =  dsp_o & 0x1F;

    assert(ccond_o   == ccond_r);
    assert(outflag_o == outflag_r);
    assert(efi_o     == efi_r);
    assert(c_o       == c_r);
    assert(scount_o  == scount_r);
    assert(pos_o     == pos_r);
    assert(ccond_o   == ccond_i);
    assert(outflag_o == outflag_i);
    assert(efi_o     == efi_i);
    assert(c_o       == c_i);
    assert(scount_o  == scount_i);
    assert(pos_o     == pos_i);

    return 0;
}
+12 −20
Original line number Diff line number Diff line
@@ -6,7 +6,6 @@ int main()
    int dsp_i, dsp_o;
    int ccond_i, outflag_i, efi_i, c_i, scount_i, pos_i;
    int ccond_o, outflag_o, efi_o, c_o, scount_o, pos_o;
    int ccond_r, outflag_r, efi_r, c_r, scount_r, pos_r;

    ccond_i   = 0x000000BC;  /* 4 */
    outflag_i = 0x0000001B;  /* 3 */
@@ -22,13 +21,6 @@ int main()
            (scount_i  <<  7) | \
            pos_i;

    ccond_r   = ccond_i;
    outflag_r = outflag_i;
    efi_r     = efi_i;
    c_r       = c_i;
    scount_r  = scount_i;
    pos_r     = pos_i;

    __asm
        ("wrdsp %1, 0x3F\n\t"
         "rddsp %0, 0x3F\n\t"
@@ -43,12 +35,12 @@ int main()
    scount_o  = (dsp_o >>  7) & 0x3F;
    pos_o     =  dsp_o & 0x1F;

    assert(ccond_o   == ccond_r);
    assert(outflag_o == outflag_r);
    assert(efi_o     == efi_r);
    assert(c_o       == c_r);
    assert(scount_o  == scount_r);
    assert(pos_o     == pos_r);
    assert(ccond_o   == (ccond_i & 0x0F));
    assert(outflag_o == outflag_i);
    assert(efi_o     == efi_i);
    assert(c_o       == c_i);
    assert(scount_o  == scount_i);
    assert(pos_o     == pos_i);

    return 0;
}