summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPetar Jovanovic <petarj@mips.com>2012-12-06 20:30:35 +0100
committerAurelien Jarno <aurelien@aurel32.net>2013-01-01 11:10:47 +0100
commiteec8972a5bc744eda695a86a984d746c240dff90 (patch)
treeb1d626358872a9c91cbacf2202635d778e55dbb6
parenta795ef8dcb8cbadffc996c41ff38927a97645234 (diff)
downloadqemu-eec8972a5bc744eda695a86a984d746c240dff90.zip
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: Petar Jovanovic <petarj@mips.com> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
-rw-r--r--target-mips/dsp_helper.c8
-rw-r--r--tests/tcg/mips/mips32-dsp/rddsp.c32
-rw-r--r--tests/tcg/mips/mips32-dsp/wrdsp.c32
3 files changed, 32 insertions, 40 deletions
diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
index 14daf91950..acf7ceb1d1 100644
--- a/target-mips/dsp_helper.c
+++ b/target-mips/dsp_helper.c
@@ -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) {
diff --git a/tests/tcg/mips/mips32-dsp/rddsp.c b/tests/tcg/mips/mips32-dsp/rddsp.c
index e8948ec1d9..2f30285033 100644
--- a/tests/tcg/mips/mips32-dsp/rddsp.c
+++ b/tests/tcg/mips/mips32-dsp/rddsp.c
@@ -6,14 +6,13 @@ 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 */
- efi_i = 0x00000001;/* 5 */
- c_i = 0x00000001;/* 2 */
- scount_i = 0x0000000F;/* 1 */
- pos_i = 0x0000000C;/* 0 */
+ ccond_i = 0x0000000C; /* 4 */
+ outflag_i = 0x0000001B; /* 3 */
+ efi_i = 0x00000001; /* 5 */
+ c_i = 0x00000001; /* 2 */
+ scount_i = 0x0000000F; /* 1 */
+ pos_i = 0x0000000C; /* 0 */
dsp_i = (ccond_i << 24) | \
(outflag_i << 16) | \
@@ -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;
}
diff --git a/tests/tcg/mips/mips32-dsp/wrdsp.c b/tests/tcg/mips/mips32-dsp/wrdsp.c
index e8948ec1d9..dc54943a99 100644
--- a/tests/tcg/mips/mips32-dsp/wrdsp.c
+++ b/tests/tcg/mips/mips32-dsp/wrdsp.c
@@ -6,14 +6,13 @@ 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 */
- efi_i = 0x00000001;/* 5 */
- c_i = 0x00000001;/* 2 */
- scount_i = 0x0000000F;/* 1 */
- pos_i = 0x0000000C;/* 0 */
+ ccond_i = 0x000000BC; /* 4 */
+ outflag_i = 0x0000001B; /* 3 */
+ efi_i = 0x00000001; /* 5 */
+ c_i = 0x00000001; /* 2 */
+ scount_i = 0x0000000F; /* 1 */
+ pos_i = 0x0000000C; /* 0 */
dsp_i = (ccond_i << 24) | \
(outflag_i << 16) | \
@@ -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;
}