summaryrefslogtreecommitdiffstats
path: root/qemu/tests/tcg/mips/mips32-dsp
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/tests/tcg/mips/mips32-dsp')
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/Makefile136
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/absq_s_ph.c31
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/absq_s_w.c37
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/addq_ph.c46
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/addq_s_ph.c69
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/addq_s_w.c44
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/addsc.c33
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/addu_qb.c35
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/addu_s_qb.c35
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/addwc.c49
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/bitrev.c20
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/bposge32.c44
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/cmp_eq_ph.c35
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/cmp_le_ph.c35
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/cmp_lt_ph.c35
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/cmpgu_eq_qb.c31
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/cmpgu_le_qb.c31
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/cmpgu_lt_qb.c31
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/cmpu_eq_qb.c35
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/cmpu_le_qb.c35
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/cmpu_lt_qb.c35
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/dpaq_s_w_ph.c31
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/dpaq_sa_l_w.c125
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/dpau_h_qbl.c27
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/dpau_h_qbr.c27
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/dpsq_s_w_ph.c45
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/dpsq_sa_l_w.c55
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/dpsu_h_qbl.c27
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/dpsu_h_qbr.c27
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/extp.c62
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/extpdp.c64
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/extpdpv.c47
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/extpv.c45
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/extr_r_w.c94
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/extr_rs_w.c117
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/extr_s_h.c86
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/extr_w.c94
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/extrv_r_w.c79
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/extrv_rs_w.c77
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/extrv_s_h.c88
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/extrv_w.c80
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/insv.c36
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/lbux.c25
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/lhx.c25
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/lwx.c25
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/madd.c31
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/maddu.c31
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/main.c6
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/maq_s_w_phl.c55
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/maq_s_w_phr.c55
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/maq_sa_w_phl.c55
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/maq_sa_w_phr.c55
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/mfhi.c21
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/mflo.c21
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/modsub.c30
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/msub.c30
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/msubu.c30
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/mthi.c21
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/mthlip.c58
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/mtlo.c21
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/muleq_s_w_phl.c41
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/muleq_s_w_phr.c40
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/muleu_s_ph_qbl.c25
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/muleu_s_ph_qbr.c25
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/mulq_rs_ph.c42
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/mult.c24
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/multu.c24
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/packrl_ph.c21
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/pick_ph.c49
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/pick_qb.c36
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/preceq_w_phl.c20
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/preceq_w_phr.c20
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/precequ_ph_qbl.c20
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/precequ_ph_qbla.c20
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/precequ_ph_qbr.c20
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/precequ_ph_qbra.c20
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/preceu_ph_qbl.c20
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/preceu_ph_qbla.c20
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/preceu_ph_qbr.c20
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/preceu_ph_qbra.c20
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/precrq_ph_w.c21
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/precrq_qb_ph.c21
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/precrq_rs_ph_w.c51
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/precrqu_s_qb_ph.c24
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/raddu_w_qb.c20
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/rddsp.c46
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/repl_ph.c23
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/repl_qb.c16
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/replv_ph.c19
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/replv_qb.c19
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/shilo.c45
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/shilov.c49
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/shll_ph.c55
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/shll_qb.c55
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/shll_s_ph.c24
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/shll_s_w.c52
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/shllv_ph.c40
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/shllv_qb.c38
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/shllv_s_ph.c40
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/shllv_s_w.c40
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/shra_ph.c30
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/shra_r_ph.c30
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/shra_r_w.c30
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/shrav_ph.c32
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/shrav_r_ph.c32
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/shrav_r_w.c32
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/shrl_qb.c31
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/shrlv_qb.c32
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/subq_ph.c40
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/subq_s_ph.c58
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/subq_s_w.c74
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/subu_qb.c25
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/subu_s_qb.c25
-rw-r--r--qemu/tests/tcg/mips/mips32-dsp/wrdsp.c46
114 files changed, 4552 insertions, 0 deletions
diff --git a/qemu/tests/tcg/mips/mips32-dsp/Makefile b/qemu/tests/tcg/mips/mips32-dsp/Makefile
new file mode 100644
index 000000000..c3a0a0094
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/Makefile
@@ -0,0 +1,136 @@
+-include ../../config-host.mak
+
+CROSS=mips64el-unknown-linux-gnu-
+
+SIM=qemu-mipsel
+SIM_FLAGS=-cpu 74Kf
+
+CC = $(CROSS)gcc
+CFLAGS = -mabi=32 -march=mips32r2 -mgp32 -mdsp -static
+
+TESTCASES = absq_s_ph.tst
+TESTCASES += absq_s_w.tst
+TESTCASES += addq_ph.tst
+TESTCASES += addq_s_ph.tst
+TESTCASES += addq_s_w.tst
+TESTCASES += addsc.tst
+TESTCASES += addu_qb.tst
+TESTCASES += addu_s_qb.tst
+TESTCASES += addwc.tst
+TESTCASES += bitrev.tst
+TESTCASES += bposge32.tst
+TESTCASES += cmp_eq_ph.tst
+TESTCASES += cmpgu_eq_qb.tst
+TESTCASES += cmpgu_le_qb.tst
+TESTCASES += cmpgu_lt_qb.tst
+TESTCASES += cmp_le_ph.tst
+TESTCASES += cmp_lt_ph.tst
+TESTCASES += cmpu_eq_qb.tst
+TESTCASES += cmpu_le_qb.tst
+TESTCASES += cmpu_lt_qb.tst
+TESTCASES += dpaq_sa_l_w.tst
+TESTCASES += dpaq_s_w_ph.tst
+TESTCASES += dpau_h_qbl.tst
+TESTCASES += dpau_h_qbr.tst
+TESTCASES += dpsq_sa_l_w.tst
+TESTCASES += dpsq_s_w_ph.tst
+TESTCASES += dpsu_h_qbl.tst
+TESTCASES += dpsu_h_qbr.tst
+TESTCASES += extp.tst
+TESTCASES += extpdp.tst
+TESTCASES += extpdpv.tst
+TESTCASES += extpv.tst
+TESTCASES += extr_rs_w.tst
+TESTCASES += extr_r_w.tst
+TESTCASES += extr_s_h.tst
+TESTCASES += extrv_rs_w.tst
+TESTCASES += extrv_r_w.tst
+TESTCASES += extrv_s_h.tst
+TESTCASES += extrv_w.tst
+TESTCASES += extr_w.tst
+TESTCASES += insv.tst
+TESTCASES += lbux.tst
+TESTCASES += lhx.tst
+TESTCASES += lwx.tst
+TESTCASES += madd.tst
+TESTCASES += maddu.tst
+TESTCASES += maq_sa_w_phl.tst
+TESTCASES += maq_sa_w_phr.tst
+TESTCASES += maq_s_w_phl.tst
+TESTCASES += maq_s_w_phr.tst
+TESTCASES += mfhi.tst
+TESTCASES += mflo.tst
+TESTCASES += modsub.tst
+TESTCASES += msub.tst
+TESTCASES += msubu.tst
+TESTCASES += mthi.tst
+TESTCASES += mthlip.tst
+TESTCASES += mtlo.tst
+TESTCASES += muleq_s_w_phl.tst
+TESTCASES += muleq_s_w_phr.tst
+TESTCASES += muleu_s_ph_qbl.tst
+TESTCASES += muleu_s_ph_qbr.tst
+TESTCASES += mulq_rs_ph.tst
+TESTCASES += mult.tst
+TESTCASES += multu.tst
+TESTCASES += packrl_ph.tst
+TESTCASES += pick_ph.tst
+TESTCASES += pick_qb.tst
+TESTCASES += precequ_ph_qbla.tst
+TESTCASES += precequ_ph_qbl.tst
+TESTCASES += precequ_ph_qbra.tst
+TESTCASES += precequ_ph_qbr.tst
+TESTCASES += preceq_w_phl.tst
+TESTCASES += preceq_w_phr.tst
+TESTCASES += preceu_ph_qbla.tst
+TESTCASES += preceu_ph_qbl.tst
+TESTCASES += preceu_ph_qbra.tst
+TESTCASES += preceu_ph_qbr.tst
+TESTCASES += precrq_ph_w.tst
+TESTCASES += precrq_qb_ph.tst
+TESTCASES += precrq_rs_ph_w.tst
+TESTCASES += precrqu_s_qb_ph.tst
+TESTCASES += raddu_w_qb.tst
+TESTCASES += rddsp.tst
+TESTCASES += repl_ph.tst
+TESTCASES += repl_qb.tst
+TESTCASES += replv_ph.tst
+TESTCASES += replv_qb.tst
+TESTCASES += shilo.tst
+TESTCASES += shilov.tst
+TESTCASES += shll_ph.tst
+TESTCASES += shll_qb.tst
+TESTCASES += shll_s_ph.tst
+TESTCASES += shll_s_w.tst
+TESTCASES += shllv_ph.tst
+TESTCASES += shllv_qb.tst
+TESTCASES += shllv_s_ph.tst
+TESTCASES += shllv_s_w.tst
+TESTCASES += shra_ph.tst
+TESTCASES += shra_r_ph.tst
+TESTCASES += shra_r_w.tst
+TESTCASES += shrav_ph.tst
+TESTCASES += shrav_r_ph.tst
+TESTCASES += shrav_r_w.tst
+TESTCASES += shrl_qb.tst
+TESTCASES += shrlv_qb.tst
+TESTCASES += subq_ph.tst
+TESTCASES += subq_s_ph.tst
+TESTCASES += subq_s_w.tst
+TESTCASES += subu_qb.tst
+TESTCASES += subu_s_qb.tst
+TESTCASES += wrdsp.tst
+
+all: $(TESTCASES)
+
+%.tst: %.c
+ $(CC) $(CFLAGS) $< -o $@
+
+check: $(TESTCASES)
+ @for case in $(TESTCASES); do \
+ echo $(SIM) $(SIM_FLAGS) ./$$case;\
+ $(SIM) $(SIM_FLAGS) ./$$case; \
+ done
+
+clean:
+ $(RM) -rf $(TESTCASES)
diff --git a/qemu/tests/tcg/mips/mips32-dsp/absq_s_ph.c b/qemu/tests/tcg/mips/mips32-dsp/absq_s_ph.c
new file mode 100644
index 000000000..aa8411202
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/absq_s_ph.c
@@ -0,0 +1,31 @@
+#include<stdio.h>
+#include<assert.h>
+
+
+int main()
+{
+ int rd, rt;
+ int result;
+
+ rt = 0x10017EFD;
+ result = 0x10017EFD;
+
+ __asm
+ ("absq_s.ph %0, %1\n\t"
+ : "=r"(rd)
+ : "r"(rt)
+ );
+ assert(rd == result);
+
+ rt = 0x8000A536;
+ result = 0x7FFF5ACA;
+
+ __asm
+ ("absq_s.ph %0, %1\n\t"
+ : "=r"(rd)
+ : "r"(rt)
+ );
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/absq_s_w.c b/qemu/tests/tcg/mips/mips32-dsp/absq_s_w.c
new file mode 100644
index 000000000..3f52a4803
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/absq_s_w.c
@@ -0,0 +1,37 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rt;
+ int result;
+
+ rt = 0x80000000;
+ result = 0x7FFFFFFF;
+ __asm
+ ("absq_s.w %0, %1\n\t"
+ : "=r"(rd)
+ : "r"(rt)
+ );
+ assert(rd == result);
+
+ rt = 0x80030000;
+ result = 0x7FFD0000;
+ __asm
+ ("absq_s.w %0, %1\n\t"
+ : "=r"(rd)
+ : "r"(rt)
+ );
+ assert(rd == result);
+
+ rt = 0x31036080;
+ result = 0x31036080;
+ __asm
+ ("absq_s.w %0, %1\n\t"
+ : "=r"(rd)
+ : "r"(rt)
+ );
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/addq_ph.c b/qemu/tests/tcg/mips/mips32-dsp/addq_ph.c
new file mode 100644
index 000000000..96a549637
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/addq_ph.c
@@ -0,0 +1,46 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt;
+ int dsp;
+ int result;
+
+ rs = 0xFFFFFFFF;
+ rt = 0x10101010;
+ result = 0x100F100F;
+ __asm
+ ("addq.ph %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt)
+ );
+ assert(result == rd);
+
+ rs = 0x3712847D;
+ rt = 0x0031AF2D;
+ result = 0x374333AA;
+ __asm
+ ("addq.ph %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt)
+ );
+ assert(result == rd);
+
+ rs = 0x7fff847D;
+ rt = 0x0031AF2D;
+ result = 0x803033AA;
+ __asm
+ ("addq.ph %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt)
+ );
+ assert(result == rd);
+
+ __asm("rddsp %0\n\t"
+ : "=r"(dsp)
+ );
+ assert(((dsp >> 20) & 0x01) == 1);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/addq_s_ph.c b/qemu/tests/tcg/mips/mips32-dsp/addq_s_ph.c
new file mode 100644
index 000000000..5f865f6cf
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/addq_s_ph.c
@@ -0,0 +1,69 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt;
+ int dsp;
+ int result;
+
+ rs = 0xFFFFFFFF;
+ rt = 0x10101010;
+ result = 0x100F100F;
+ __asm
+ ("addq_s.ph %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt)
+ );
+ assert(result == rd);
+
+ rs = 0x3712847D;
+ rt = 0x0031AF2D;
+ result = 0x37438000;
+ __asm
+ ("addq_s.ph %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt)
+ );
+ assert(result == rd);
+
+ __asm
+ ("rddsp %0\n\t"
+ : "=r"(dsp)
+ );
+ assert(((dsp >> 20) & 0x01) == 1);
+
+ rs = 0x7fff847D;
+ rt = 0x0031AF2D;
+ result = 0x7fff8000;
+ __asm
+ ("addq_s.ph %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt)
+ );
+ assert(result == rd);
+
+ __asm
+ ("rddsp %0\n\t"
+ : "=r"(dsp)
+ );
+ assert(((dsp >> 20) & 0x01) == 1);
+
+ rs = 0x8030847D;
+ rt = 0x8a00AF2D;
+ result = 0x80008000;
+ __asm
+ ("addq_s.ph %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt)
+ );
+ assert(result == rd);
+
+ __asm
+ ("rddsp %0\n\t"
+ : "=r"(dsp)
+ );
+ assert(((dsp >> 20) & 0x01) == 1);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/addq_s_w.c b/qemu/tests/tcg/mips/mips32-dsp/addq_s_w.c
new file mode 100644
index 000000000..1e13acf68
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/addq_s_w.c
@@ -0,0 +1,44 @@
+#include<stdio.h>
+#include<assert.h>
+
+
+int main()
+{
+ int rd, rs, rt;
+ int result;
+
+ rt = 0x10017EFD;
+ rs = 0x11111111;
+ result = 0x2112900e;
+
+ __asm
+ ("addq_s.w %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt)
+ );
+ assert(rd == result);
+
+ rt = 0x80017EFD;
+ rs = 0x81111111;
+ result = 0x80000000;
+
+ __asm
+ ("addq_s.w %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt)
+ );
+ assert(rd == result);
+
+ rt = 0x7fffffff;
+ rs = 0x01111111;
+ result = 0x7fffffff;
+
+ __asm
+ ("addq_s.w %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt)
+ );
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/addsc.c b/qemu/tests/tcg/mips/mips32-dsp/addsc.c
new file mode 100644
index 000000000..ace749f66
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/addsc.c
@@ -0,0 +1,33 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt;
+ int dsp;
+ int result;
+
+ rs = 0x0000000F;
+ rt = 0x00000001;
+ result = 0x00000010;
+ __asm
+ ("addsc %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt)
+ );
+ assert(rd == result);
+
+ rs = 0xFFFF0FFF;
+ rt = 0x00010111;
+ result = 0x00001110;
+ __asm
+ ("addsc %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ assert(rd == result);
+ assert(((dsp >> 13) & 0x01) == 1);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/addu_qb.c b/qemu/tests/tcg/mips/mips32-dsp/addu_qb.c
new file mode 100644
index 000000000..23ba2e90d
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/addu_qb.c
@@ -0,0 +1,35 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt;
+ int dsp;
+ int result;
+
+ rs = 0x00FF00FF;
+ rt = 0x00010001;
+ result = 0x00000000;
+ __asm
+ ("addu.qb %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ assert(rd == result);
+ assert(((dsp >> 20) & 0x01) == 1);
+
+ rs = 0xFFFF1111;
+ rt = 0x00020001;
+ result = 0xFF011112;
+ __asm
+ ("addu.qb %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ assert(rd == result);
+ assert(((dsp >> 20) & 0x01) == 1);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/addu_s_qb.c b/qemu/tests/tcg/mips/mips32-dsp/addu_s_qb.c
new file mode 100644
index 000000000..fe7fd3e6a
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/addu_s_qb.c
@@ -0,0 +1,35 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt;
+ int dsp;
+ int result;
+
+ rs = 0x10FF01FF;
+ rt = 0x10010001;
+ result = 0x20FF01FF;
+ __asm
+ ("addu_s.qb %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ assert(rd == result);
+ assert(((dsp >> 20) & 0x1) == 1);
+
+ rs = 0xFFFF1111;
+ rt = 0x00020001;
+ result = 0xFFFF1112;
+ __asm
+ ("addu_s.qb %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ assert(rd == result);
+ assert(((dsp >> 20) & 0x1) == 1);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/addwc.c b/qemu/tests/tcg/mips/mips32-dsp/addwc.c
new file mode 100644
index 000000000..8a8d81fab
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/addwc.c
@@ -0,0 +1,49 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt;
+ int dspi, dspo;
+ int result;
+
+ rs = 0x10FF01FF;
+ rt = 0x10010001;
+ dspi = 0x00002000;
+ result = 0x21000201;
+ __asm
+ ("wrdsp %3\n"
+ "addwc %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt), "r"(dspi)
+ );
+ assert(rd == result);
+
+ rs = 0xFFFF1111;
+ rt = 0x00020001;
+ dspi = 0x00;
+ result = 0x00011112;
+ __asm
+ ("wrdsp %3\n"
+ "addwc %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt), "r"(dspi)
+ );
+ assert(rd == result);
+
+ rs = 0x8FFF1111;
+ rt = 0x80020001;
+ dspi = 0x00;
+ result = 0x10011112;
+ __asm
+ ("wrdsp %4\n"
+ "addwc %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dspo)
+ : "r"(rs), "r"(rt), "r"(dspi)
+ );
+ assert(rd == result);
+ assert(((dspo >> 20) & 0x01) == 1);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/bitrev.c b/qemu/tests/tcg/mips/mips32-dsp/bitrev.c
new file mode 100644
index 000000000..04d8a3844
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/bitrev.c
@@ -0,0 +1,20 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rt;
+ int result;
+
+ rt = 0x12345678;
+ result = 0x00001E6A;
+
+ __asm
+ ("bitrev %0, %1\n\t"
+ : "=r"(rd)
+ : "r"(rt)
+ );
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/bposge32.c b/qemu/tests/tcg/mips/mips32-dsp/bposge32.c
new file mode 100644
index 000000000..d25417ea7
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/bposge32.c
@@ -0,0 +1,44 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int dsp, sum;
+ int result;
+
+ dsp = 0x20;
+ sum = 0x01;
+ result = 0x02;
+
+ __asm
+ ("wrdsp %1\n\t"
+ "bposge32 test1\n\t"
+ "nop\n\t"
+ "addi %0, 0xA2\n\t"
+ "nop\n\t"
+ "test1:\n\t"
+ "addi %0, 0x01\n\t"
+ : "+r"(sum)
+ : "r"(dsp)
+ );
+ assert(sum == result);
+
+ dsp = 0x10;
+ sum = 0x01;
+ result = 0xA4;
+
+ __asm
+ ("wrdsp %1\n\t"
+ "bposge32 test2\n\t"
+ "nop\n\t"
+ "addi %0, 0xA2\n\t"
+ "nop\n\t"
+ "test2:\n\t"
+ "addi %0, 0x01\n\t"
+ : "+r"(sum)
+ : "r"(dsp)
+ );
+ assert(sum == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/cmp_eq_ph.c b/qemu/tests/tcg/mips/mips32-dsp/cmp_eq_ph.c
new file mode 100644
index 000000000..957bd88ce
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/cmp_eq_ph.c
@@ -0,0 +1,35 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt;
+ int result;
+
+ rs = 0x11777066;
+ rt = 0x55AA33FF;
+ result = 0x00;
+ __asm
+ ("cmp.eq.ph %1, %2\n\t"
+ "rddsp %0\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt)
+ );
+
+ rd = (rd >> 24) & 0x03;
+ assert(rd == result);
+
+ rs = 0x11777066;
+ rt = 0x11777066;
+ result = 0x03;
+ __asm
+ ("cmp.eq.ph %1, %2\n\t"
+ "rddsp %0\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt)
+ );
+ rd = (rd >> 24) & 0x03;
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/cmp_le_ph.c b/qemu/tests/tcg/mips/mips32-dsp/cmp_le_ph.c
new file mode 100644
index 000000000..356f156c5
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/cmp_le_ph.c
@@ -0,0 +1,35 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt;
+ int result;
+
+ rs = 0x11777066;
+ rt = 0x55AA33FF;
+ result = 0x02;
+ __asm
+ ("cmp.le.ph %1, %2\n\t"
+ "rddsp %0\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt)
+ );
+
+ rd = (rd >> 24) & 0x03;
+ assert(rd == result);
+
+ rs = 0x11777066;
+ rt = 0x11777066;
+ result = 0x03;
+ __asm
+ ("cmp.le.ph %1, %2\n\t"
+ "rddsp %0\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt)
+ );
+ rd = (rd >> 24) & 0x03;
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/cmp_lt_ph.c b/qemu/tests/tcg/mips/mips32-dsp/cmp_lt_ph.c
new file mode 100644
index 000000000..3fb4827ad
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/cmp_lt_ph.c
@@ -0,0 +1,35 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt;
+ int result;
+
+ rs = 0x11777066;
+ rt = 0x55AA33FF;
+ result = 0x02;
+ __asm
+ ("cmp.lt.ph %1, %2\n\t"
+ "rddsp %0\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt)
+ );
+
+ rd = (rd >> 24) & 0x03;
+ assert(rd == result);
+
+ rs = 0x11777066;
+ rt = 0x11777066;
+ result = 0x00;
+ __asm
+ ("cmp.lt.ph %1, %2\n\t"
+ "rddsp %0\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt)
+ );
+ rd = (rd >> 24) & 0x03;
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/cmpgu_eq_qb.c b/qemu/tests/tcg/mips/mips32-dsp/cmpgu_eq_qb.c
new file mode 100644
index 000000000..2615c84c7
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/cmpgu_eq_qb.c
@@ -0,0 +1,31 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt;
+ int result;
+
+ rs = 0x11777066;
+ rt = 0x55AA70FF;
+ result = 0x02;
+ __asm
+ ("cmpgu.eq.qb %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt)
+ );
+
+ assert(rd == result);
+
+ rs = 0x11777066;
+ rt = 0x11777066;
+ result = 0x0F;
+ __asm
+ ("cmpgu.eq.qb %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt)
+ );
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/cmpgu_le_qb.c b/qemu/tests/tcg/mips/mips32-dsp/cmpgu_le_qb.c
new file mode 100644
index 000000000..65d0813c3
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/cmpgu_le_qb.c
@@ -0,0 +1,31 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt;
+ int result;
+
+ rs = 0x11777066;
+ rt = 0x55AA70FF;
+ result = 0x0F;
+ __asm
+ ("cmpgu.le.qb %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt)
+ );
+
+ assert(rd == result);
+
+ rs = 0x11777066;
+ rt = 0x11766066;
+ result = 0x09;
+ __asm
+ ("cmpgu.le.qb %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt)
+ );
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/cmpgu_lt_qb.c b/qemu/tests/tcg/mips/mips32-dsp/cmpgu_lt_qb.c
new file mode 100644
index 000000000..7dddad985
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/cmpgu_lt_qb.c
@@ -0,0 +1,31 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt;
+ int result;
+
+ rs = 0x11777066;
+ rt = 0x55AA70FF;
+ result = 0x0D;
+ __asm
+ ("cmpgu.lt.qb %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt)
+ );
+
+ assert(rd == result);
+
+ rs = 0x11777066;
+ rt = 0x11766066;
+ result = 0x00;
+ __asm
+ ("cmpgu.lt.qb %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt)
+ );
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/cmpu_eq_qb.c b/qemu/tests/tcg/mips/mips32-dsp/cmpu_eq_qb.c
new file mode 100644
index 000000000..680f2a199
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/cmpu_eq_qb.c
@@ -0,0 +1,35 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rs, rt;
+ int dsp;
+ int result;
+
+ rs = 0x11777066;
+ rt = 0x55AA70FF;
+ result = 0x02;
+ __asm
+ ("cmpu.eq.qb %1, %2\n\t"
+ "rddsp %0\n\t"
+ : "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ dsp = (dsp >> 24) & 0x0F;
+ assert(dsp == result);
+
+ rs = 0x11777066;
+ rt = 0x11777066;
+ result = 0x0F;
+ __asm
+ ("cmpu.eq.qb %1, %2\n\t"
+ "rddsp %0\n\t"
+ : "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ dsp = (dsp >> 24) & 0x0F;
+ assert(dsp == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/cmpu_le_qb.c b/qemu/tests/tcg/mips/mips32-dsp/cmpu_le_qb.c
new file mode 100644
index 000000000..43cfa509c
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/cmpu_le_qb.c
@@ -0,0 +1,35 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rs, rt;
+ int dsp;
+ int result;
+
+ rs = 0x11777066;
+ rt = 0x55AA70FF;
+ result = 0x0F;
+ __asm
+ ("cmpu.le.qb %1, %2\n\t"
+ "rddsp %0\n\t"
+ : "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ dsp = (dsp >> 24) & 0x0F;
+ assert(dsp == result);
+
+ rs = 0x11777066;
+ rt = 0x11777066;
+ result = 0x0F;
+ __asm
+ ("cmpu.le.qb %1, %2\n\t"
+ "rddsp %0\n\t"
+ : "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ dsp = (dsp >> 24) & 0x0F;
+ assert(dsp == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/cmpu_lt_qb.c b/qemu/tests/tcg/mips/mips32-dsp/cmpu_lt_qb.c
new file mode 100644
index 000000000..074ca5b40
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/cmpu_lt_qb.c
@@ -0,0 +1,35 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rs, rt;
+ int dsp;
+ int result;
+
+ rs = 0x11777066;
+ rt = 0x55AA70FF;
+ result = 0x0D;
+ __asm
+ ("cmpu.lt.qb %1, %2\n\t"
+ "rddsp %0\n\t"
+ : "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ dsp = (dsp >> 24) & 0x0F;
+ assert(dsp == result);
+
+ rs = 0x11777066;
+ rt = 0x11777066;
+ result = 0x00;
+ __asm
+ ("cmpu.lt.qb %1, %2\n\t"
+ "rddsp %0\n\t"
+ : "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ dsp = (dsp >> 24) & 0x0F;
+ assert(dsp == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/dpaq_s_w_ph.c b/qemu/tests/tcg/mips/mips32-dsp/dpaq_s_w_ph.c
new file mode 100644
index 000000000..a6425b6ed
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/dpaq_s_w_ph.c
@@ -0,0 +1,31 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rs, rt, dsp;
+ int ach = 0, acl = 0;
+ int resulth, resultl, resultdsp;
+
+ rs = 0x800000FF;
+ rt = 0x80000002;
+ resulth = 0x00;
+ resultl = 0x800003FB;
+ resultdsp = 0x01;
+ __asm
+ ("mthi %0, $ac1\n\t"
+ "mtlo %1, $ac1\n\t"
+ "dpaq_s.w.ph $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);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/dpaq_sa_l_w.c b/qemu/tests/tcg/mips/mips32-dsp/dpaq_sa_l_w.c
new file mode 100644
index 000000000..cbf900713
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/dpaq_sa_l_w.c
@@ -0,0 +1,125 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rs, rt, dsp;
+ int ach = 0, acl = 0;
+ int resulth, resultl, resultdsp;
+
+ rs = 0x80000000;
+ rt = 0x80000000;
+ resulth = 0x7FFFFFFF;
+ resultl = 0xFFFFFFFF;
+ resultdsp = 0x01;
+ __asm
+ ("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 = 0x00000012;
+ acl = 0x00000048;
+ rs = 0x80000000;
+ rt = 0x80000000;
+
+ resulth = 0x7FFFFFFF;
+ resultl = 0xFFFFFFFF;
+ resultdsp = 0x01;
+ __asm
+ ("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 = 0x741532A0;
+ acl = 0xFCEABB08;
+ rs = 0x80000000;
+ rt = 0x80000000;
+
+ resulth = 0x7FFFFFFF;
+ resultl = 0xFFFFFFFF;
+ resultdsp = 0x01;
+ __asm
+ ("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 = 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"
+ "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);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/dpau_h_qbl.c b/qemu/tests/tcg/mips/mips32-dsp/dpau_h_qbl.c
new file mode 100644
index 000000000..6017b5e73
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/dpau_h_qbl.c
@@ -0,0 +1,27 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rs, rt;
+ int ach = 5, acl = 3;
+ int resulth, resultl;
+
+ rs = 0x800000FF;
+ rt = 0x80000002;
+ resulth = 0x05;
+ resultl = 0x4003;
+ __asm
+ ("mthi %0, $ac1\n\t"
+ "mtlo %1, $ac1\n\t"
+ "dpau.h.qbl $ac1, %2, %3\n\t"
+ "mfhi %0, $ac1\n\t"
+ "mflo %1, $ac1\n\t"
+ : "+r"(ach), "+r"(acl)
+ : "r"(rs), "r"(rt)
+ );
+ assert(ach == resulth);
+ assert(acl == resultl);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/dpau_h_qbr.c b/qemu/tests/tcg/mips/mips32-dsp/dpau_h_qbr.c
new file mode 100644
index 000000000..e4abb2e2a
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/dpau_h_qbr.c
@@ -0,0 +1,27 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rs, rt;
+ int ach = 5, acl = 3;
+ int resulth, resultl;
+
+ rs = 0x800000FF;
+ rt = 0x80000002;
+ resulth = 0x05;
+ resultl = 0x0201;
+ __asm
+ ("mthi %0, $ac1\n\t"
+ "mtlo %1, $ac1\n\t"
+ "dpau.h.qbr $ac1, %2, %3\n\t"
+ "mfhi %0, $ac1\n\t"
+ "mflo %1, $ac1\n\t"
+ : "+r"(ach), "+r"(acl)
+ : "r"(rs), "r"(rt)
+ );
+ assert(ach == resulth);
+ assert(acl == resultl);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/dpsq_s_w_ph.c b/qemu/tests/tcg/mips/mips32-dsp/dpsq_s_w_ph.c
new file mode 100644
index 000000000..74058fe7e
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/dpsq_s_w_ph.c
@@ -0,0 +1,45 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rs, rt;
+ int ach = 5, acl = 5;
+ int resulth, resultl;
+
+ rs = 0xBC0123AD;
+ rt = 0x01643721;
+ resulth = 0x00000004;
+ resultl = 0xF15F94A3;
+ __asm
+ ("mthi %0, $ac1\n\t"
+ "mtlo %1, $ac1\n\t"
+ "dpsq_s.w.ph $ac1, %2, %3\n\t"
+ "mfhi %0, $ac1\n\t"
+ "mflo %1, $ac1\n\t"
+ : "+r"(ach), "+r"(acl)
+ : "r"(rs), "r"(rt)
+ );
+ assert(ach == resulth);
+ assert(acl == resultl);
+
+ ach = 0x1424EF1F;
+ acl = 0x1035219A;
+ rs = 0x800083AD;
+ rt = 0x80003721;
+ resulth = 0x1424EF1E;
+ resultl = 0xC5C0D901;
+ __asm
+ ("mthi %0, $ac1\n\t"
+ "mtlo %1, $ac1\n\t"
+ "dpsq_s.w.ph $ac1, %2, %3\n\t"
+ "mfhi %0, $ac1\n\t"
+ "mflo %1, $ac1\n\t"
+ : "+r"(ach), "+r"(acl)
+ : "r"(rs), "r"(rt)
+ );
+ assert(ach == resulth);
+ assert(acl == resultl);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/dpsq_sa_l_w.c b/qemu/tests/tcg/mips/mips32-dsp/dpsq_sa_l_w.c
new file mode 100644
index 000000000..eda3b14e2
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/dpsq_sa_l_w.c
@@ -0,0 +1,55 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rs, rt, dsp;
+ int ach = 5, acl = 5;
+ int resulth, resultl, resultdsp;
+
+ rs = 0xBC0123AD;
+ rt = 0x01643721;
+ resulth = 0x00BD3A22;
+ resultl = 0xD138776B;
+ resultdsp = 0x00;
+ __asm
+ ("mthi %0, $ac1\n\t"
+ "mtlo %1, $ac1\n\t"
+ "dpsq_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 = 0x54321123;
+ acl = 5;
+ rs = 0x80000000;
+ rt = 0x80000000;
+
+ resulth = 0xd4321123;
+ resultl = 0x06;
+ resultdsp = 0x01;
+
+ __asm
+ ("mthi %0, $ac1\n\t"
+ "mtlo %1, $ac1\n\t"
+ "dpsq_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);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/dpsu_h_qbl.c b/qemu/tests/tcg/mips/mips32-dsp/dpsu_h_qbl.c
new file mode 100644
index 000000000..94e2bf625
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/dpsu_h_qbl.c
@@ -0,0 +1,27 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rs, rt;
+ int ach = 5, acl = 5;
+ int resulth, resultl;
+
+ rs = 0xBC0123AD;
+ rt = 0x01643721;
+ resulth = 0x04;
+ resultl = 0xFFFFFEE5;
+ __asm
+ ("mthi %0, $ac1\n\t"
+ "mtlo %1, $ac1\n\t"
+ "dpsu.h.qbl $ac1, %2, %3\n\t"
+ "mfhi %0, $ac1\n\t"
+ "mflo %1, $ac1\n\t"
+ : "+r"(ach), "+r"(acl)
+ : "r"(rs), "r"(rt)
+ );
+ assert(ach == resulth);
+ assert(acl == resultl);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/dpsu_h_qbr.c b/qemu/tests/tcg/mips/mips32-dsp/dpsu_h_qbr.c
new file mode 100644
index 000000000..a1e663563
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/dpsu_h_qbr.c
@@ -0,0 +1,27 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rs, rt;
+ int ach = 5, acl = 5;
+ int resulth, resultl;
+
+ rs = 0xBC0123AD;
+ rt = 0x01643721;
+ resulth = 0x04;
+ resultl = 0xFFFFE233;
+ __asm
+ ("mthi %0, $ac1\n\t"
+ "mtlo %1, $ac1\n\t"
+ "dpsu.h.qbr $ac1, %2, %3\n\t"
+ "mfhi %0, $ac1\n\t"
+ "mflo %1, $ac1\n\t"
+ : "+r"(ach), "+r"(acl)
+ : "r"(rs), "r"(rt)
+ );
+ assert(ach == resulth);
+ assert(acl == resultl);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/extp.c b/qemu/tests/tcg/mips/mips32-dsp/extp.c
new file mode 100644
index 000000000..b18bdb34c
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/extp.c
@@ -0,0 +1,62 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rt, ach, acl, dsp;
+ int result;
+
+ ach = 0x05;
+ acl = 0xB4CB;
+ dsp = 0x07;
+ result = 0x000C;
+
+ __asm
+ ("wrdsp %1, 0x01\n\t"
+ "mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "extp %0, $ac1, 0x03\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "+r"(dsp)
+ : "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 14) & 0x01;
+ assert(dsp == 0);
+ assert(result == rt);
+
+ ach = 0x05;
+ acl = 0xB4CB;
+ dsp = 0x01;
+
+ __asm
+ ("wrdsp %1, 0x01\n\t"
+ "mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "extp %0, $ac1, 0x03\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "+r"(dsp)
+ : "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 14) & 0x01;
+ assert(dsp == 1);
+
+ ach = 0;
+ acl = 0x80000001;
+ dsp = 0x1F;
+ result = 0x80000001;
+
+ __asm
+ ("wrdsp %1\n\t"
+ "mthi %2, $ac2\n\t"
+ "mtlo %3, $ac2\n\t"
+ "extp %0, $ac2, 0x1F\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "+r"(dsp)
+ : "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 14) & 0x01;
+ assert(dsp == 0);
+ assert(result == rt);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/extpdp.c b/qemu/tests/tcg/mips/mips32-dsp/extpdp.c
new file mode 100644
index 000000000..79ee16e8b
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/extpdp.c
@@ -0,0 +1,64 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rt, ach, acl, dsp, pos, efi;
+ int result;
+
+ ach = 0x05;
+ acl = 0xB4CB;
+ dsp = 0x07;
+ result = 0x000C;
+
+ __asm
+ ("wrdsp %1, 0x01\n\t"
+ "mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "extpdp %0, $ac1, 0x03\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "+r"(dsp)
+ : "r"(ach), "r"(acl)
+ );
+ pos = dsp & 0x3F;
+ efi = (dsp >> 14) & 0x01;
+ assert(pos == 3);
+ assert(efi == 0);
+ assert(result == rt);
+
+ ach = 0x05;
+ acl = 0xB4CB;
+ dsp = 0x01;
+
+ __asm
+ ("wrdsp %1, 0x01\n\t"
+ "mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "extpdp %0, $ac1, 0x03\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "+r"(dsp)
+ : "r"(ach), "r"(acl)
+ );
+ efi = (dsp >> 14) & 0x01;
+ assert(efi == 1);
+
+
+ ach = 0;
+ acl = 0;
+ dsp = 0;
+ result = 0;
+
+ __asm
+ ("wrdsp %1\n\t"
+ "mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "extpdp %0, $ac1, 0x00\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "+r"(dsp)
+ : "r"(ach), "r"(acl)
+ );
+ assert(dsp == 0x3F);
+ assert(result == rt);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/extpdpv.c b/qemu/tests/tcg/mips/mips32-dsp/extpdpv.c
new file mode 100644
index 000000000..f5774eed3
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/extpdpv.c
@@ -0,0 +1,47 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rt, rs, ach, acl, dsp, pos, efi;
+ int result;
+
+ ach = 0x05;
+ acl = 0xB4CB;
+ dsp = 0x07;
+ rs = 0x03;
+ result = 0x000C;
+
+ __asm
+ ("wrdsp %1, 0x01\n\t"
+ "mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "extpdpv %0, $ac1, %4\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "+r"(dsp)
+ : "r"(ach), "r"(acl), "r"(rs)
+ );
+ pos = dsp & 0x3F;
+ efi = (dsp >> 14) & 0x01;
+ assert(pos == 3);
+ assert(efi == 0);
+ assert(result == rt);
+
+ ach = 0x05;
+ acl = 0xB4CB;
+ dsp = 0x01;
+
+ __asm
+ ("wrdsp %1, 0x01\n\t"
+ "mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "extpdpv %0, $ac1, %4\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "+r"(dsp)
+ : "r"(ach), "r"(acl), "r"(rs)
+ );
+ efi = (dsp >> 14) & 0x01;
+ assert(efi == 1);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/extpv.c b/qemu/tests/tcg/mips/mips32-dsp/extpv.c
new file mode 100644
index 000000000..401b94afa
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/extpv.c
@@ -0,0 +1,45 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rt, ac, ach, acl, dsp;
+ int result;
+
+ ach = 0x05;
+ acl = 0xB4CB;
+ dsp = 0x07;
+ ac = 0x03;
+ result = 0x000C;
+
+ __asm
+ ("wrdsp %1, 0x01\n\t"
+ "mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "extpv %0, $ac1, %4\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "+r"(dsp)
+ : "r"(ach), "r"(acl), "r"(ac)
+ );
+ dsp = (dsp >> 14) & 0x01;
+ assert(dsp == 0);
+ assert(result == rt);
+
+ ach = 0x05;
+ acl = 0xB4CB;
+ dsp = 0x01;
+
+ __asm
+ ("wrdsp %1, 0x01\n\t"
+ "mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "extpv %0, $ac1, %4\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "+r"(dsp)
+ : "r"(ach), "r"(acl), "r"(ac)
+ );
+ dsp = (dsp >> 14) & 0x01;
+ assert(dsp == 1);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/extr_r_w.c b/qemu/tests/tcg/mips/mips32-dsp/extr_r_w.c
new file mode 100644
index 000000000..489c1931b
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/extr_r_w.c
@@ -0,0 +1,94 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rt, ach, acl, dsp;
+ int result;
+
+ ach = 0x05;
+ acl = 0xB4CB;
+ result = 0xA0001699;
+ __asm
+ ("mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "extr_r.w %0, $ac1, 0x03\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "=r"(dsp)
+ : "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 1);
+ assert(result == rt);
+
+ /* Clear dspcontrol */
+ dsp = 0;
+ __asm
+ ("wrdsp %0\n\t"
+ :
+ : "r"(dsp)
+ );
+
+ ach = 0x01;
+ acl = 0xB4CB;
+ result = 0x10000B4D;
+ __asm
+ ("mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "extr_r.w %0, $ac1, 0x04\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "=r"(dsp)
+ : "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 0);
+ assert(result == rt);
+
+ /* Clear dspcontrol */
+ dsp = 0;
+ __asm
+ ("wrdsp %0\n\t"
+ :
+ : "r"(dsp)
+ );
+
+ ach = 0x3fffffff;
+ acl = 0x2bcdef01;
+ result = 0x7ffffffe;
+ __asm
+ ("mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "extr_r.w %0, $ac1, 0x1F\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "=r"(dsp)
+ : "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 0);
+ assert(result == rt);
+
+ /* Clear dspcontrol */
+ dsp = 0;
+ __asm
+ ("wrdsp %0\n\t"
+ :
+ : "r"(dsp)
+ );
+
+ ach = 0xFFFFFFFF;
+ acl = 0xFFFFFFFF;
+ result = 0;
+ __asm
+ ("mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "extr_r.w %0, $ac1, 0x1F\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "=r"(dsp)
+ : "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 0);
+ assert(result == rt);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/extr_rs_w.c b/qemu/tests/tcg/mips/mips32-dsp/extr_rs_w.c
new file mode 100644
index 000000000..f9d2ed646
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/extr_rs_w.c
@@ -0,0 +1,117 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rt, ach, acl, dsp;
+ int result;
+
+ ach = 0x05;
+ acl = 0xB4CB;
+ result = 0x7FFFFFFF;
+ __asm
+ ("mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "extr_rs.w %0, $ac1, 0x03\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "=r"(dsp)
+ : "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 1);
+ assert(result == rt);
+
+ /* Clear dspcontrol */
+ dsp = 0;
+ __asm
+ ("wrdsp %0\n\t"
+ :
+ : "r"(dsp)
+ );
+
+ ach = 0x01;
+ acl = 0xB4CB;
+ result = 0x10000B4D;
+ __asm
+ ("mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "extr_rs.w %0, $ac1, 0x04\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "=r"(dsp)
+ : "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 0);
+ assert(result == rt);
+
+ /* Clear dspcontrol */
+ dsp = 0;
+ __asm
+ ("wrdsp %0\n\t"
+ :
+ : "r"(dsp)
+ );
+
+ ach = 0x3fffffff;
+ acl = 0x2bcdef01;
+ result = 0x7ffffffe;
+ __asm
+ ("mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "extr_rs.w %0, $ac1, 0x1F\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "=r"(dsp)
+ : "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 0);
+ assert(result == rt);
+
+ /* Clear dspcontrol */
+ dsp = 0;
+ __asm
+ ("wrdsp %0\n\t"
+ :
+ : "r"(dsp)
+ );
+
+ ach = 0x80000000;
+ acl = 0x00000000;
+ result = 0x80000000;
+ __asm
+ ("mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "extr_rs.w %0, $ac1, 0x1F\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "=r"(dsp)
+ : "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 1);
+ assert(result == rt);
+
+ /* Clear dspcontrol */
+ dsp = 0;
+ __asm
+ ("wrdsp %0\n\t"
+ :
+ : "r"(dsp)
+ );
+
+ ach = 0xFFFFFFFF;
+ acl = 0xFFFFFFFF;
+ result = 0;
+ __asm
+ ("mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "extr_rs.w %0, $ac1, 0x1F\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "=r"(dsp)
+ : "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 0);
+ assert(result == rt);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/extr_s_h.c b/qemu/tests/tcg/mips/mips32-dsp/extr_s_h.c
new file mode 100644
index 000000000..9bc2a63cc
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/extr_s_h.c
@@ -0,0 +1,86 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rt, ach, acl, dsp;
+ int result;
+
+ ach = 0x05;
+ acl = 0xB4CB;
+ result = 0x00007FFF;
+ __asm
+ ("mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "extr_s.h %0, $ac1, 0x03\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "=r"(dsp)
+ : "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 1);
+ assert(result == rt);
+
+ ach = 0xffffffff;
+ acl = 0x12344321;
+ result = 0xFFFF8000;
+ __asm
+ ("mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "extr_s.h %0, $ac1, 0x08\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "=r"(dsp)
+ : "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 1);
+ assert(result == rt);
+
+ /* Clear dsp */
+ dsp = 0;
+ __asm
+ ("wrdsp %0\n\t"
+ :
+ : "r"(dsp)
+ );
+
+ ach = 0x00;
+ acl = 0x4321;
+ result = 0x432;
+ __asm
+ ("mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "extr_s.h %0, $ac1, 0x04\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "=r"(dsp)
+ : "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 0);
+ assert(result == rt);
+
+ /* Clear dsp */
+ dsp = 0;
+ __asm
+ ("wrdsp %0\n\t"
+ :
+ : "r"(dsp)
+ );
+
+ ach = 0x123;
+ acl = 0x87654321;
+ result = 0x1238;
+ __asm
+ ("mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "extr_s.h %0, $ac1, 28\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "=r"(dsp)
+ : "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 0);
+ assert(result == rt);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/extr_w.c b/qemu/tests/tcg/mips/mips32-dsp/extr_w.c
new file mode 100644
index 000000000..cf926146d
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/extr_w.c
@@ -0,0 +1,94 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rt, ach, acl, dsp;
+ int result;
+
+ ach = 0x05;
+ acl = 0xB4CB;
+ result = 0xA0001699;
+ __asm
+ ("mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "extr.w %0, $ac1, 0x03\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "=r"(dsp)
+ : "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 1);
+ assert(result == rt);
+
+ /* Clear dspcontrol */
+ dsp = 0;
+ __asm
+ ("wrdsp %0\n\t"
+ :
+ : "r"(dsp)
+ );
+
+ ach = 0x01;
+ acl = 0xB4CB;
+ result = 0x10000B4C;
+ __asm
+ ("mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "extr.w %0, $ac1, 0x04\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "=r"(dsp)
+ : "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 0);
+ assert(result == rt);
+
+ /* Clear dspcontrol */
+ dsp = 0;
+ __asm
+ ("wrdsp %0\n\t"
+ :
+ : "r"(dsp)
+ );
+
+ ach = 0x3fffffff;
+ acl = 0x2bcdef01;
+ result = 0x7ffffffe;
+ __asm
+ ("mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "extr.w %0, $ac1, 0x1F\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "=r"(dsp)
+ : "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 0);
+ assert(result == rt);
+
+ /* Clear dspcontrol */
+ dsp = 0;
+ __asm
+ ("wrdsp %0\n\t"
+ :
+ : "r"(dsp)
+ );
+
+ ach = 0xFFFFFFFF;
+ acl = 0xFFFFFFFF;
+ result = 0xFFFFFFFF;
+ __asm
+ ("mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "extr.w %0, $ac1, 0x1F\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "=r"(dsp)
+ : "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 0);
+ assert(result == rt);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/extrv_r_w.c b/qemu/tests/tcg/mips/mips32-dsp/extrv_r_w.c
new file mode 100644
index 000000000..2403b3afe
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/extrv_r_w.c
@@ -0,0 +1,79 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rt, rs, ach, acl, dsp;
+ int result;
+
+ ach = 0x05;
+ acl = 0xB4CB;
+ dsp = 0x07;
+ rs = 0x03;
+ result = 0xA0001699;
+
+ __asm
+ ("wrdsp %1, 0x01\n\t"
+ "mthi %3, $ac1\n\t"
+ "mtlo %4, $ac1\n\t"
+ "extrv_r.w %0, $ac1, %2\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "+r"(dsp)
+ : "r"(rs), "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 1);
+ assert(result == rt);
+
+ /* Clear dspcontrol */
+ dsp = 0;
+ __asm
+ ("wrdsp %0\n\t"
+ :
+ : "r"(dsp)
+ );
+
+ rs = 4;
+ ach = 0x01;
+ acl = 0xB4CB;
+ result = 0x10000B4D;
+ __asm
+ ("wrdsp %1, 0x01\n\t"
+ "mthi %3, $ac1\n\t"
+ "mtlo %4, $ac1\n\t"
+ "extrv_r.w %0, $ac1, %2\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "+r"(dsp)
+ : "r"(rs), "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 0);
+ assert(result == rt);
+
+ /* Clear dspcontrol */
+ dsp = 0;
+ __asm
+ ("wrdsp %0\n\t"
+ :
+ : "r"(dsp)
+ );
+
+ rs = 31;
+ ach = 0x3fffffff;
+ acl = 0x2bcdef01;
+ result = 0x7ffffffe;
+ __asm
+ ("wrdsp %1, 0x01\n\t"
+ "mthi %3, $ac1\n\t"
+ "mtlo %4, $ac1\n\t"
+ "extrv_r.w %0, $ac1, %2\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "+r"(dsp)
+ : "r"(rs), "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 0);
+ assert(result == rt);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/extrv_rs_w.c b/qemu/tests/tcg/mips/mips32-dsp/extrv_rs_w.c
new file mode 100644
index 000000000..ccceeb9f4
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/extrv_rs_w.c
@@ -0,0 +1,77 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rt, rs, ach, acl, dsp;
+ int result;
+
+ rs = 0x03;
+ ach = 0x05;
+ acl = 0xB4CB;
+ result = 0x7FFFFFFF;
+ __asm
+ ("wrdsp %1, 0x01\n\t"
+ "mthi %3, $ac1\n\t"
+ "mtlo %4, $ac1\n\t"
+ "extrv_rs.w %0, $ac1, %2\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "+r"(dsp)
+ : "r"(rs), "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 1);
+ assert(result == rt);
+
+ /* Clear dspcontrol */
+ dsp = 0;
+ __asm
+ ("wrdsp %0\n\t"
+ :
+ : "r"(dsp)
+ );
+
+ rs = 0x04;
+ ach = 0x01;
+ acl = 0xB4CB;
+ result = 0x10000B4D;
+ __asm
+ ("wrdsp %1, 0x01\n\t"
+ "mthi %3, $ac1\n\t"
+ "mtlo %4, $ac1\n\t"
+ "extrv_rs.w %0, $ac1, %2\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "+r"(dsp)
+ : "r"(rs), "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 0);
+ assert(result == rt);
+
+ /* Clear dspcontrol */
+ dsp = 0;
+ __asm
+ ("wrdsp %0\n\t"
+ :
+ : "r"(dsp)
+ );
+
+ rs = 0x1F;
+ ach = 0x3fffffff;
+ acl = 0x2bcdef01;
+ result = 0x7ffffffe;
+ __asm
+ ("wrdsp %1, 0x01\n\t"
+ "mthi %3, $ac1\n\t"
+ "mtlo %4, $ac1\n\t"
+ "extrv_rs.w %0, $ac1, %2\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "+r"(dsp)
+ : "r"(rs), "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 0);
+ assert(result == rt);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/extrv_s_h.c b/qemu/tests/tcg/mips/mips32-dsp/extrv_s_h.c
new file mode 100644
index 000000000..feac3e2e3
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/extrv_s_h.c
@@ -0,0 +1,88 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rt, rs, ach, acl, dsp;
+ int result;
+
+ ach = 0x05;
+ acl = 0xB4CB;
+ dsp = 0x07;
+ rs = 0x03;
+ result = 0x00007FFF;
+
+ __asm
+ ("wrdsp %1, 0x01\n\t"
+ "mthi %3, $ac1\n\t"
+ "mtlo %4, $ac1\n\t"
+ "extrv_s.h %0, $ac1, %2\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "+r"(dsp)
+ : "r"(rs), "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 1);
+ assert(result == rt);
+
+ rs = 0x08;
+ ach = 0xffffffff;
+ acl = 0x12344321;
+ result = 0xFFFF8000;
+ __asm
+ ("wrdsp %1, 0x01\n\t"
+ "mthi %3, $ac1\n\t"
+ "mtlo %4, $ac1\n\t"
+ "extrv_s.h %0, $ac1, %2\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "+r"(dsp)
+ : "r"(rs), "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 1);
+ assert(result == rt);
+
+ /* Clear dsp */
+ dsp = 0;
+ __asm
+ ("wrdsp %0\n\t"
+ :
+ : "r"(dsp)
+ );
+
+ rs = 0x04;
+ ach = 0x00;
+ acl = 0x4321;
+ result = 0x432;
+ __asm
+ ("wrdsp %1, 0x01\n\t"
+ "mthi %3, $ac1\n\t"
+ "mtlo %4, $ac1\n\t"
+ "extrv_s.h %0, $ac1, %2\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "+r"(dsp)
+ : "r"(rs), "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 0);
+ assert(result == rt);
+
+ rs = 0x1C;
+ ach = 0x123;
+ acl = 0x87654321;
+ result = 0x1238;
+ __asm
+ ("wrdsp %1, 0x01\n\t"
+ "mthi %3, $ac1\n\t"
+ "mtlo %4, $ac1\n\t"
+ "extrv_s.h %0, $ac1, %2\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "+r"(dsp)
+ : "r"(rs), "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 0);
+ assert(result == rt);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/extrv_w.c b/qemu/tests/tcg/mips/mips32-dsp/extrv_w.c
new file mode 100644
index 000000000..9e8b238a0
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/extrv_w.c
@@ -0,0 +1,80 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rt, rs, ach, acl, dsp;
+ int result;
+
+ ach = 0x05;
+ acl = 0xB4CB;
+ dsp = 0x07;
+ rs = 0x03;
+ result = 0xA0001699;
+
+ __asm
+ ("wrdsp %1, 0x01\n\t"
+ "mthi %3, $ac1\n\t"
+ "mtlo %4, $ac1\n\t"
+ "extrv.w %0, $ac1, %2\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "+r"(dsp)
+ : "r"(rs), "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 1);
+ assert(result == rt);
+
+ /* Clear dspcontrol */
+ dsp = 0;
+ __asm
+ ("wrdsp %0\n\t"
+ :
+ : "r"(dsp)
+ );
+
+ rs = 4;
+ ach = 0x01;
+ acl = 0xB4CB;
+ result = 0x10000B4C;
+ __asm
+ ("wrdsp %1, 0x01\n\t"
+ "mthi %3, $ac1\n\t"
+ "mtlo %4, $ac1\n\t"
+ "extrv.w %0, $ac1, %2\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "+r"(dsp)
+ : "r"(rs), "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 0);
+ assert(result == rt);
+
+ /* Clear dspcontrol */
+ dsp = 0;
+ __asm
+ ("wrdsp %0\n\t"
+ :
+ : "r"(dsp)
+ );
+
+ rs = 31;
+ ach = 0x3fffffff;
+ acl = 0x2bcdef01;
+ result = 0x7ffffffe;
+ __asm
+ ("wrdsp %1, 0x01\n\t"
+ "mthi %3, $ac1\n\t"
+ "mtlo %4, $ac1\n\t"
+ "extrv.w %0, $ac1, %2\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "+r"(dsp)
+ : "r"(rs), "r"(ach), "r"(acl)
+ );
+ dsp = (dsp >> 23) & 0x01;
+ assert(dsp == 0);
+ assert(result == rt);
+
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/insv.c b/qemu/tests/tcg/mips/mips32-dsp/insv.c
new file mode 100644
index 000000000..9d674697c
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/insv.c
@@ -0,0 +1,36 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rt, rs, dsp;
+ int result;
+
+ /* msb = 10, lsb = 5 */
+ dsp = 0x305;
+ rt = 0x12345678;
+ rs = 0x87654321;
+ result = 0x12345438;
+ __asm
+ ("wrdsp %2, 0x03\n\t"
+ "insv %0, %1\n\t"
+ : "+r"(rt)
+ : "r"(rs), "r"(dsp)
+ );
+ assert(rt == result);
+
+ dsp = 0x1000;
+ rt = 0xF0F0F0F0;
+ rs = 0xA5A5A5A5;
+ result = 0xA5A5A5A5;
+
+ __asm
+ ("wrdsp %2\n\t"
+ "insv %0, %1\n\t"
+ : "+r"(rt)
+ : "r"(rs), "r"(dsp)
+ );
+ assert(rt == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/lbux.c b/qemu/tests/tcg/mips/mips32-dsp/lbux.c
new file mode 100644
index 000000000..2337abea2
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/lbux.c
@@ -0,0 +1,25 @@
+#include <stdio.h>
+#include <assert.h>
+
+int main(void)
+{
+ int value, rd;
+ int *p;
+ unsigned long addr, index;
+ int result;
+
+ value = 0xBCDEF389;
+ p = &value;
+ addr = (unsigned long)p;
+ index = 0;
+ result = value & 0xFF;
+ __asm
+ ("lbux %0, %1(%2)\n\t"
+ : "=r"(rd)
+ : "r"(index), "r"(addr)
+ );
+
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/lhx.c b/qemu/tests/tcg/mips/mips32-dsp/lhx.c
new file mode 100644
index 000000000..10be3b385
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/lhx.c
@@ -0,0 +1,25 @@
+#include <stdio.h>
+#include <assert.h>
+
+int main(void)
+{
+ int value, rd;
+ int *p;
+ unsigned long addr, index;
+ int result;
+
+ value = 0xBCDEF389;
+ p = &value;
+ addr = (unsigned long)p;
+ index = 0;
+ result = 0xFFFFF389;
+ __asm
+ ("lhx %0, %1(%2)\n\t"
+ : "=r"(rd)
+ : "r"(index), "r"(addr)
+ );
+
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/lwx.c b/qemu/tests/tcg/mips/mips32-dsp/lwx.c
new file mode 100644
index 000000000..e6543c9e7
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/lwx.c
@@ -0,0 +1,25 @@
+#include <stdio.h>
+#include <assert.h>
+
+int main(void)
+{
+ int value, rd;
+ int *p;
+ unsigned long addr, index;
+ int result;
+
+ value = 0xBCDEF389;
+ p = &value;
+ addr = (unsigned long)p;
+ index = 0;
+ result = 0xBCDEF389;
+ __asm
+ ("lwx %0, %1(%2)\n\t"
+ : "=r"(rd)
+ : "r"(index), "r"(addr)
+ );
+
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/madd.c b/qemu/tests/tcg/mips/mips32-dsp/madd.c
new file mode 100644
index 000000000..af4bfcfe9
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/madd.c
@@ -0,0 +1,31 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rt, rs;
+ int achi, acli;
+ int acho, aclo;
+ int resulth, resultl;
+
+ achi = 0x05;
+ acli = 0xB4CB;
+ rs = 0x01;
+ rt = 0x01;
+ resulth = 0x05;
+ resultl = 0xB4CC;
+
+ __asm
+ ("mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "madd $ac1, %4, %5\n\t"
+ "mfhi %0, $ac1\n\t"
+ "mflo %1, $ac1\n\t"
+ : "=r"(acho), "=r"(aclo)
+ : "r"(achi), "r"(acli), "r"(rs), "r"(rt)
+ );
+ assert(resulth == acho);
+ assert(resultl == aclo);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/maddu.c b/qemu/tests/tcg/mips/mips32-dsp/maddu.c
new file mode 100644
index 000000000..af4bfcfe9
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/maddu.c
@@ -0,0 +1,31 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rt, rs;
+ int achi, acli;
+ int acho, aclo;
+ int resulth, resultl;
+
+ achi = 0x05;
+ acli = 0xB4CB;
+ rs = 0x01;
+ rt = 0x01;
+ resulth = 0x05;
+ resultl = 0xB4CC;
+
+ __asm
+ ("mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "madd $ac1, %4, %5\n\t"
+ "mfhi %0, $ac1\n\t"
+ "mflo %1, $ac1\n\t"
+ : "=r"(acho), "=r"(aclo)
+ : "r"(achi), "r"(acli), "r"(rs), "r"(rt)
+ );
+ assert(resulth == acho);
+ assert(resultl == aclo);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/main.c b/qemu/tests/tcg/mips/mips32-dsp/main.c
new file mode 100644
index 000000000..b296b20c9
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/main.c
@@ -0,0 +1,6 @@
+#include<stdio.h>
+
+int main()
+{
+ printf("hello world\n");
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/maq_s_w_phl.c b/qemu/tests/tcg/mips/mips32-dsp/maq_s_w_phl.c
new file mode 100644
index 000000000..0f7c07015
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/maq_s_w_phl.c
@@ -0,0 +1,55 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rt, rs;
+ int achi, acli;
+ int dsp;
+ int acho, aclo;
+ int resulth, resultl;
+ int resdsp;
+
+ achi = 0x00000005;
+ acli = 0x0000B4CB;
+ rs = 0xFF060000;
+ rt = 0xCB000000;
+ resulth = 0x00000005;
+ resultl = 0x006838CB;
+
+ __asm
+ ("mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "maq_s.w.phl $ac1, %4, %5\n\t"
+ "mfhi %0, $ac1\n\t"
+ "mflo %1, $ac1\n\t"
+ : "=r"(acho), "=r"(aclo)
+ : "r"(achi), "r"(acli), "r"(rs), "r"(rt)
+ );
+ assert(resulth == acho);
+ assert(resultl == aclo);
+
+ achi = 0x00000006;
+ acli = 0x0000B4CB;
+ rs = 0x80000000;
+ rt = 0x80000000;
+ resulth = 0x00000006;
+ resultl = 0x8000B4CA;
+ resdsp = 1;
+
+ __asm
+ ("mthi %3, $ac1\n\t"
+ "mtlo %4, $ac1\n\t"
+ "maq_s.w.phl $ac1, %5, %6\n\t"
+ "mfhi %0, $ac1\n\t"
+ "mflo %1, $ac1\n\t"
+ "rddsp %2\n\t"
+ : "=r"(acho), "=r"(aclo), "=r"(dsp)
+ : "r"(achi), "r"(acli), "r"(rs), "r"(rt)
+ );
+ assert(resulth == acho);
+ assert(resultl == aclo);
+ assert(((dsp >> 17) & 0x01) == resdsp);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/maq_s_w_phr.c b/qemu/tests/tcg/mips/mips32-dsp/maq_s_w_phr.c
new file mode 100644
index 000000000..942722a53
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/maq_s_w_phr.c
@@ -0,0 +1,55 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rt, rs;
+ int achi, acli;
+ int dsp;
+ int acho, aclo;
+ int resulth, resultl;
+ int resdsp;
+
+ achi = 0x00000005;
+ acli = 0x0000B4CB;
+ rs = 0x0000FF06;
+ rt = 0x0000CB00;
+ resulth = 0x00000005;
+ resultl = 0x006838CB;
+
+ __asm
+ ("mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "maq_s.w.phr $ac1, %4, %5\n\t"
+ "mfhi %0, $ac1\n\t"
+ "mflo %1, $ac1\n\t"
+ : "=r"(acho), "=r"(aclo)
+ : "r"(achi), "r"(acli), "r"(rs), "r"(rt)
+ );
+ assert(resulth == acho);
+ assert(resultl == aclo);
+
+ achi = 0x00000006;
+ acli = 0x0000B4CB;
+ rs = 0x00008000;
+ rt = 0x00008000;
+ resulth = 0x00000006;
+ resultl = 0x8000B4CA;
+ resdsp = 1;
+
+ __asm
+ ("mthi %3, $ac1\n\t"
+ "mtlo %4, $ac1\n\t"
+ "maq_s.w.phr $ac1, %5, %6\n\t"
+ "mfhi %0, $ac1\n\t"
+ "mflo %1, $ac1\n\t"
+ "rddsp %2\n\t"
+ : "=r"(acho), "=r"(aclo), "=r"(dsp)
+ : "r"(achi), "r"(acli), "r"(rs), "r"(rt)
+ );
+ assert(resulth == acho);
+ assert(resultl == aclo);
+ assert(((dsp >> 17) & 0x01) == resdsp);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/maq_sa_w_phl.c b/qemu/tests/tcg/mips/mips32-dsp/maq_sa_w_phl.c
new file mode 100644
index 000000000..d83dce6f3
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/maq_sa_w_phl.c
@@ -0,0 +1,55 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rt, rs;
+ int achi, acli;
+ int dsp;
+ int acho, aclo;
+ int resulth, resultl;
+ int resdsp;
+
+ achi = 0x00000000;
+ acli = 0x0000B4CB;
+ rs = 0xFF060000;
+ rt = 0xCB000000;
+ resulth = 0x00000000;
+ resultl = 0x006838CB;
+
+ __asm
+ ("mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "maq_sa.w.phl $ac1, %4, %5\n\t"
+ "mfhi %0, $ac1\n\t"
+ "mflo %1, $ac1\n\t"
+ : "=r"(acho), "=r"(aclo)
+ : "r"(achi), "r"(acli), "r"(rs), "r"(rt)
+ );
+ assert(resulth == acho);
+ assert(resultl == aclo);
+
+ achi = 0x00000000;
+ acli = 0x0000B4CB;
+ rs = 0x80000000;
+ rt = 0x80000000;
+ resulth = 0x00;
+ resultl = 0x7fffffff;
+ resdsp = 0x01;
+
+ __asm
+ ("mthi %3, $ac1\n\t"
+ "mtlo %4, $ac1\n\t"
+ "maq_sa.w.phl $ac1, %5, %6\n\t"
+ "mfhi %0, $ac1\n\t"
+ "mflo %1, $ac1\n\t"
+ "rddsp %2\n\t"
+ : "=r"(acho), "=r"(aclo), "=r"(dsp)
+ : "r"(achi), "r"(acli), "r"(rs), "r"(rt)
+ );
+ assert(resulth == acho);
+ assert(resultl == aclo);
+ assert(((dsp >> 17) & 0x01) == 0x01);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/maq_sa_w_phr.c b/qemu/tests/tcg/mips/mips32-dsp/maq_sa_w_phr.c
new file mode 100644
index 000000000..d2331118a
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/maq_sa_w_phr.c
@@ -0,0 +1,55 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rt, rs;
+ int achi, acli;
+ int dsp;
+ int acho, aclo;
+ int resulth, resultl;
+ int resdsp;
+
+ achi = 0x00000000;
+ acli = 0x0000B4CB;
+ rs = 0x0000FF06;
+ rt = 0x0000CB00;
+ resulth = 0x00000000;
+ resultl = 0x006838CB;
+
+ __asm
+ ("mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "maq_sa.w.phr $ac1, %4, %5\n\t"
+ "mfhi %0, $ac1\n\t"
+ "mflo %1, $ac1\n\t"
+ : "=r"(acho), "=r"(aclo)
+ : "r"(achi), "r"(acli), "r"(rs), "r"(rt)
+ );
+ assert(resulth == acho);
+ assert(resultl == aclo);
+
+ achi = 0x00000000;
+ acli = 0x0000B4CB;
+ rs = 0x00008000;
+ rt = 0x00008000;
+ resulth = 0x00000000;
+ resultl = 0x7FFFFFFF;
+ resdsp = 0x01;
+
+ __asm
+ ("mthi %3, $ac1\n\t"
+ "mtlo %4, $ac1\n\t"
+ "maq_sa.w.phr $ac1, %5, %6\n\t"
+ "mfhi %0, $ac1\n\t"
+ "mflo %1, $ac1\n\t"
+ "rddsp %2\n\t"
+ : "=r"(acho), "=r"(aclo), "=r"(dsp)
+ : "r"(achi), "r"(acli), "r"(rs), "r"(rt)
+ );
+ assert(resulth == acho);
+ assert(resultl == aclo);
+ assert(((dsp >> 17) & 0x01) == 0x01);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/mfhi.c b/qemu/tests/tcg/mips/mips32-dsp/mfhi.c
new file mode 100644
index 000000000..43a80669d
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/mfhi.c
@@ -0,0 +1,21 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int achi, acho;
+ int result;
+
+ achi = 0x004433;
+ result = 0x004433;
+
+ __asm
+ ("mthi %1, $ac1\n\t"
+ "mfhi %0, $ac1\n\t"
+ : "=r"(acho)
+ : "r"(achi)
+ );
+ assert(result == acho);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/mflo.c b/qemu/tests/tcg/mips/mips32-dsp/mflo.c
new file mode 100644
index 000000000..caeafdb05
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/mflo.c
@@ -0,0 +1,21 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int acli, aclo;
+ int result;
+
+ acli = 0x004433;
+ result = 0x004433;
+
+ __asm
+ ("mthi %1, $ac1\n\t"
+ "mfhi %0, $ac1\n\t"
+ : "=r"(aclo)
+ : "r"(acli)
+ );
+ assert(result == aclo);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/modsub.c b/qemu/tests/tcg/mips/mips32-dsp/modsub.c
new file mode 100644
index 000000000..c294eebb5
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/modsub.c
@@ -0,0 +1,30 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt;
+ int result;
+
+ rs = 0xFFFFFFFF;
+ rt = 0x000000FF;
+ result = 0xFFFFFF00;
+ __asm
+ ("modsub %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt)
+ );
+ assert(result == rd);
+
+ rs = 0x00000000;
+ rt = 0x00CD1FFF;
+ result = 0x0000CD1F;
+ __asm
+ ("modsub %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt)
+ );
+ assert(result == rd);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/msub.c b/qemu/tests/tcg/mips/mips32-dsp/msub.c
new file mode 100644
index 000000000..5779e6f47
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/msub.c
@@ -0,0 +1,30 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int achi, acli, rs, rt;
+ int acho, aclo;
+ int resulth, resultl;
+
+ rs = 0x00BBAACC;
+ rt = 0x0B1C3D2F;
+ achi = 0x00004433;
+ acli = 0xFFCC0011;
+ resulth = 0xFFF81F29;
+ resultl = 0xB355089D;
+
+ __asm
+ ("mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "msub $ac1, %4, %5\n\t"
+ "mfhi %0, $ac1\n\t"
+ "mflo %1, $ac1\n\t"
+ : "=r"(acho), "=r"(aclo)
+ : "r"(achi), "r"(acli), "r"(rs), "r"(rt)
+ );
+ assert(acho == resulth);
+ assert(aclo == resultl);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/msubu.c b/qemu/tests/tcg/mips/mips32-dsp/msubu.c
new file mode 100644
index 000000000..e0f9b5a77
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/msubu.c
@@ -0,0 +1,30 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int achi, acli, rs, rt;
+ int acho, aclo;
+ int resulth, resultl;
+
+ rs = 0x00BBAACC;
+ rt = 0x0B1C3D2F;
+ achi = 0x00004433;
+ acli = 0xFFCC0011;
+ resulth = 0xFFF81F29;
+ resultl = 0xB355089D;
+
+ __asm
+ ("mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "msubu $ac1, %4, %5\n\t"
+ "mfhi %0, $ac1\n\t"
+ "mflo %1, $ac1\n\t"
+ : "=r"(acho), "=r"(aclo)
+ : "r"(achi), "r"(acli), "r"(rs), "r"(rt)
+ );
+ assert(acho == resulth);
+ assert(aclo == resultl);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/mthi.c b/qemu/tests/tcg/mips/mips32-dsp/mthi.c
new file mode 100644
index 000000000..43a80669d
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/mthi.c
@@ -0,0 +1,21 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int achi, acho;
+ int result;
+
+ achi = 0x004433;
+ result = 0x004433;
+
+ __asm
+ ("mthi %1, $ac1\n\t"
+ "mfhi %0, $ac1\n\t"
+ : "=r"(acho)
+ : "r"(achi)
+ );
+ assert(result == acho);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/mthlip.c b/qemu/tests/tcg/mips/mips32-dsp/mthlip.c
new file mode 100644
index 000000000..85f94d845
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/mthlip.c
@@ -0,0 +1,58 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rs, ach, acl, dsp;
+ int result, resulth, resultl;
+
+ dsp = 0x07;
+ ach = 0x05;
+ acl = 0xB4CB;
+ rs = 0x00FFBBAA;
+ resulth = 0xB4CB;
+ resultl = 0x00FFBBAA;
+ result = 0x27;
+
+ __asm
+ ("wrdsp %0, 0x01\n\t"
+ "mthi %1, $ac1\n\t"
+ "mtlo %2, $ac1\n\t"
+ "mthlip %3, $ac1\n\t"
+ "mfhi %1, $ac1\n\t"
+ "mflo %2, $ac1\n\t"
+ "rddsp %0\n\t"
+ : "+r"(dsp), "+r"(ach), "+r"(acl)
+ : "r"(rs)
+ );
+ dsp = dsp & 0x3F;
+ assert(dsp == result);
+ assert(ach == resulth);
+ assert(acl == resultl);
+
+ dsp = 0x1f;
+ ach = 0x05;
+ acl = 0xB4CB;
+ rs = 0x00FFBBAA;
+ resulth = 0xB4CB;
+ resultl = 0x00FFBBAA;
+ result = 0x3f;
+
+ __asm
+ ("wrdsp %0, 0x01\n\t"
+ "mthi %1, $ac1\n\t"
+ "mtlo %2, $ac1\n\t"
+ "mthlip %3, $ac1\n\t"
+ "mfhi %1, $ac1\n\t"
+ "mflo %2, $ac1\n\t"
+ "rddsp %0\n\t"
+ : "+r"(dsp), "+r"(ach), "+r"(acl)
+ : "r"(rs)
+ );
+ dsp = dsp & 0x3F;
+ assert(dsp == result);
+ assert(ach == resulth);
+ assert(acl == resultl);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/mtlo.c b/qemu/tests/tcg/mips/mips32-dsp/mtlo.c
new file mode 100644
index 000000000..caeafdb05
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/mtlo.c
@@ -0,0 +1,21 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int acli, aclo;
+ int result;
+
+ acli = 0x004433;
+ result = 0x004433;
+
+ __asm
+ ("mthi %1, $ac1\n\t"
+ "mfhi %0, $ac1\n\t"
+ : "=r"(aclo)
+ : "r"(acli)
+ );
+ assert(result == aclo);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/muleq_s_w_phl.c b/qemu/tests/tcg/mips/mips32-dsp/muleq_s_w_phl.c
new file mode 100644
index 000000000..b3a5370fe
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/muleq_s_w_phl.c
@@ -0,0 +1,41 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt, dsp;
+ int result, resultdsp;
+
+ rs = 0x80001234;
+ rt = 0x80001234;
+ result = 0x7FFFFFFF;
+ resultdsp = 1;
+
+ __asm
+ ("muleq_s.w.phl %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ dsp = (dsp >> 21) & 0x01;
+ assert(rd == result);
+ assert(dsp == resultdsp);
+
+ rs = 0x12349988;
+ rt = 0x43219988;
+ result = 0x98be968;
+ resultdsp = 1;
+
+ __asm
+ ("muleq_s.w.phl %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ dsp = (dsp >> 21) & 0x01;
+ assert(rd == result);
+ assert(dsp == resultdsp);
+
+ return 0;
+}
+
diff --git a/qemu/tests/tcg/mips/mips32-dsp/muleq_s_w_phr.c b/qemu/tests/tcg/mips/mips32-dsp/muleq_s_w_phr.c
new file mode 100644
index 000000000..8066d7d02
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/muleq_s_w_phr.c
@@ -0,0 +1,40 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt, dsp;
+ int result, resultdsp;
+
+ rs = 0x8000;
+ rt = 0x8000;
+ result = 0x7FFFFFFF;
+ resultdsp = 1;
+
+ __asm
+ ("muleq_s.w.phr %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ dsp = (dsp >> 21) & 0x01;
+ assert(rd == result);
+ assert(dsp == resultdsp);
+
+ rs = 0x1234;
+ rt = 0x4321;
+ result = 0x98be968;
+ resultdsp = 1;
+
+ __asm
+ ("muleq_s.w.phr %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ dsp = (dsp >> 21) & 0x01;
+ assert(rd == result);
+ assert(dsp == resultdsp);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/muleu_s_ph_qbl.c b/qemu/tests/tcg/mips/mips32-dsp/muleu_s_ph_qbl.c
new file mode 100644
index 000000000..66a382806
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/muleu_s_ph_qbl.c
@@ -0,0 +1,25 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt, dsp;
+ int result, resultdsp;
+
+ rs = 0x80001234;
+ rt = 0x80004321;
+ result = 0xFFFF0000;
+ resultdsp = 1;
+
+ __asm
+ ("muleu_s.ph.qbl %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ dsp = (dsp >> 21) & 0x01;
+ assert(rd == result);
+ assert(dsp == resultdsp);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/muleu_s_ph_qbr.c b/qemu/tests/tcg/mips/mips32-dsp/muleu_s_ph_qbr.c
new file mode 100644
index 000000000..4cc6c8f7c
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/muleu_s_ph_qbr.c
@@ -0,0 +1,25 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt, dsp;
+ int result, resultdsp;
+
+ rs = 0x8000;
+ rt = 0x80004321;
+ result = 0xFFFF0000;
+ resultdsp = 1;
+
+ __asm
+ ("muleu_s.ph.qbr %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ dsp = (dsp >> 21) & 0x01;
+ assert(rd == result);
+ assert(dsp == resultdsp);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/mulq_rs_ph.c b/qemu/tests/tcg/mips/mips32-dsp/mulq_rs_ph.c
new file mode 100644
index 000000000..370c2a801
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/mulq_rs_ph.c
@@ -0,0 +1,42 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt, dsp;
+ int result, resultdsp;
+
+ rs = 0x80001234;
+ rt = 0x80004321;
+ result = 0x7FFF098C;
+ resultdsp = 1;
+
+ __asm
+ ("wrdsp $0\n\t"
+ "mulq_rs.ph %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ dsp = (dsp >> 21) & 0x01;
+ assert(rd == result);
+ assert(dsp == resultdsp);
+
+ rs = 0x80011234;
+ rt = 0x80024321;
+ result = 0x7FFD098C;
+ resultdsp = 0;
+
+ __asm
+ ("wrdsp $0\n\t"
+ "mulq_rs.ph %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ dsp = (dsp >> 21) & 0x01;
+ assert(rd == result);
+ assert(dsp == resultdsp);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/mult.c b/qemu/tests/tcg/mips/mips32-dsp/mult.c
new file mode 100644
index 000000000..15e6fde92
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/mult.c
@@ -0,0 +1,24 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rs, rt, ach, acl;
+ int result, resulth, resultl;
+
+ rs = 0x00FFBBAA;
+ rt = 0x4B231000;
+ resulth = 0x4b0f01;
+ resultl = 0x71f8a000;
+ __asm
+ ("mult $ac1, %2, %3\n\t"
+ "mfhi %0, $ac1\n\t"
+ "mflo %1, $ac1\n\t"
+ : "=r"(ach), "=r"(acl)
+ : "r"(rs), "r"(rt)
+ );
+ assert(ach == resulth);
+ assert(acl == resultl);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/multu.c b/qemu/tests/tcg/mips/mips32-dsp/multu.c
new file mode 100644
index 000000000..85d36c1b6
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/multu.c
@@ -0,0 +1,24 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rs, rt, ach, acl;
+ int result, resulth, resultl;
+
+ rs = 0x00FFBBAA;
+ rt = 0x4B231000;
+ resulth = 0x4b0f01;
+ resultl = 0x71f8a000;
+ __asm
+ ("multu $ac1, %2, %3\n\t"
+ "mfhi %0, $ac1\n\t"
+ "mflo %1, $ac1\n\t"
+ : "=r"(ach), "=r"(acl)
+ : "r"(rs), "r"(rt)
+ );
+ assert(ach == resulth);
+ assert(acl == resultl);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/packrl_ph.c b/qemu/tests/tcg/mips/mips32-dsp/packrl_ph.c
new file mode 100644
index 000000000..1f8e69992
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/packrl_ph.c
@@ -0,0 +1,21 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt;
+ int result;
+
+ rs = 0x12345678;
+ rt = 0x87654321;
+ result = 0x56788765;
+
+ __asm
+ ("packrl.ph %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt)
+ );
+ assert(result == rd);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/pick_ph.c b/qemu/tests/tcg/mips/mips32-dsp/pick_ph.c
new file mode 100644
index 000000000..929a002e7
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/pick_ph.c
@@ -0,0 +1,49 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt, dsp;
+ int result;
+
+ rs = 0x12345678;
+ rt = 0x87654321;
+ dsp = 0x0A000000;
+ result = 0x12344321;
+
+ __asm
+ ("wrdsp %3, 0x10\n\t"
+ "pick.ph %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt), "r"(dsp)
+ );
+ assert(rd == result);
+
+ rs = 0x12345678;
+ rt = 0x87654321;
+ dsp = 0x03000000;
+ result = 0x12345678;
+
+ __asm
+ ("wrdsp %3, 0x10\n\t"
+ "pick.ph %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt), "r"(dsp)
+ );
+ assert(rd == result);
+
+ rs = 0x12345678;
+ rt = 0x87654321;
+ dsp = 0x00000000;
+ result = 0x87654321;
+
+ __asm
+ ("wrdsp %3, 0x10\n\t"
+ "pick.ph %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt), "r"(dsp)
+ );
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/pick_qb.c b/qemu/tests/tcg/mips/mips32-dsp/pick_qb.c
new file mode 100644
index 000000000..a79047524
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/pick_qb.c
@@ -0,0 +1,36 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt, dsp;
+ int result;
+
+ rs = 0x12345678;
+ rt = 0x87654321;
+ dsp = 0x0f000000;
+ result = 0x12345678;
+
+ __asm
+ ("wrdsp %3, 0x10\n\t"
+ "pick.qb %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt), "r"(dsp)
+ );
+ assert(rd == result);
+
+ rs = 0x12345678;
+ rt = 0x87654321;
+ dsp = 0x00000000;
+ result = 0x87654321;
+
+ __asm
+ ("wrdsp %3, 0x10\n\t"
+ "pick.qb %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt), "r"(dsp)
+ );
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/preceq_w_phl.c b/qemu/tests/tcg/mips/mips32-dsp/preceq_w_phl.c
new file mode 100644
index 000000000..bf70bf7d3
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/preceq_w_phl.c
@@ -0,0 +1,20 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rt;
+ int result;
+
+ rt = 0x87654321;
+ result = 0x87650000;
+
+ __asm
+ ("preceq.w.phl %0, %1\n\t"
+ : "=r"(rd)
+ : "r"(rt)
+ );
+ assert(result == rd);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/preceq_w_phr.c b/qemu/tests/tcg/mips/mips32-dsp/preceq_w_phr.c
new file mode 100644
index 000000000..3f885ef58
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/preceq_w_phr.c
@@ -0,0 +1,20 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rt;
+ int result;
+
+ rt = 0x87654321;
+ result = 0x43210000;
+
+ __asm
+ ("preceq.w.phr %0, %1\n\t"
+ : "=r"(rd)
+ : "r"(rt)
+ );
+ assert(result == rd);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/precequ_ph_qbl.c b/qemu/tests/tcg/mips/mips32-dsp/precequ_ph_qbl.c
new file mode 100644
index 000000000..63b7a9568
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/precequ_ph_qbl.c
@@ -0,0 +1,20 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rt;
+ int result;
+
+ rt = 0x87654321;
+ result = 0x43803280;
+
+ __asm
+ ("precequ.ph.qbl %0, %1\n\t"
+ : "=r"(rd)
+ : "r"(rt)
+ );
+ assert(result == rd);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/precequ_ph_qbla.c b/qemu/tests/tcg/mips/mips32-dsp/precequ_ph_qbla.c
new file mode 100644
index 000000000..31627f0bd
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/precequ_ph_qbla.c
@@ -0,0 +1,20 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rt;
+ int result;
+
+ rt = 0x87654321;
+ result = 0x43802180;
+
+ __asm
+ ("precequ.ph.qbla %0, %1\n\t"
+ : "=r"(rd)
+ : "r"(rt)
+ );
+ assert(result == rd);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/precequ_ph_qbr.c b/qemu/tests/tcg/mips/mips32-dsp/precequ_ph_qbr.c
new file mode 100644
index 000000000..b6f72d3cb
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/precequ_ph_qbr.c
@@ -0,0 +1,20 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rt;
+ int result;
+
+ rt = 0x87654321;
+ result = 0x21801080;
+
+ __asm
+ ("precequ.ph.qbr %0, %1\n\t"
+ : "=r"(rd)
+ : "r"(rt)
+ );
+ assert(result == rd);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/precequ_ph_qbra.c b/qemu/tests/tcg/mips/mips32-dsp/precequ_ph_qbra.c
new file mode 100644
index 000000000..4764fd031
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/precequ_ph_qbra.c
@@ -0,0 +1,20 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rt;
+ int result;
+
+ rt = 0x87654321;
+ result = 0x32801080;
+
+ __asm
+ ("precequ.ph.qbra %0, %1\n\t"
+ : "=r"(rd)
+ : "r"(rt)
+ );
+ assert(result == rd);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/preceu_ph_qbl.c b/qemu/tests/tcg/mips/mips32-dsp/preceu_ph_qbl.c
new file mode 100644
index 000000000..fa95c26cc
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/preceu_ph_qbl.c
@@ -0,0 +1,20 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rt;
+ int result;
+
+ rt = 0x87654321;
+ result = 0x00870065;
+
+ __asm
+ ("preceu.ph.qbl %0, %1\n\t"
+ : "=r"(rd)
+ : "r"(rt)
+ );
+ assert(result == rd);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/preceu_ph_qbla.c b/qemu/tests/tcg/mips/mips32-dsp/preceu_ph_qbla.c
new file mode 100644
index 000000000..021f21a74
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/preceu_ph_qbla.c
@@ -0,0 +1,20 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rt;
+ int result;
+
+ rt = 0x87654321;
+ result = 0x00870043;
+
+ __asm
+ ("preceu.ph.qbla %0, %1\n\t"
+ : "=r"(rd)
+ : "r"(rt)
+ );
+ assert(result == rd);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/preceu_ph_qbr.c b/qemu/tests/tcg/mips/mips32-dsp/preceu_ph_qbr.c
new file mode 100644
index 000000000..03df18c72
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/preceu_ph_qbr.c
@@ -0,0 +1,20 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rt;
+ int result;
+
+ rt = 0x87654321;
+ result = 0x00430021;
+
+ __asm
+ ("preceu.ph.qbr %0, %1\n\t"
+ : "=r"(rd)
+ : "r"(rt)
+ );
+ assert(result == rd);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/preceu_ph_qbra.c b/qemu/tests/tcg/mips/mips32-dsp/preceu_ph_qbra.c
new file mode 100644
index 000000000..634327618
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/preceu_ph_qbra.c
@@ -0,0 +1,20 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rt;
+ int result;
+
+ rt = 0x87654321;
+ result = 0x00650021;
+
+ __asm
+ ("preceu.ph.qbra %0, %1\n\t"
+ : "=r"(rd)
+ : "r"(rt)
+ );
+ assert(result == rd);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/precrq_ph_w.c b/qemu/tests/tcg/mips/mips32-dsp/precrq_ph_w.c
new file mode 100644
index 000000000..25d45f1a9
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/precrq_ph_w.c
@@ -0,0 +1,21 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt;
+ int result;
+
+ rs = 0x12345678;
+ rt = 0x87654321;
+ result = 0x12348765;
+
+ __asm
+ ("precrq.ph.w %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt)
+ );
+ assert(result == rd);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/precrq_qb_ph.c b/qemu/tests/tcg/mips/mips32-dsp/precrq_qb_ph.c
new file mode 100644
index 000000000..fe23acce8
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/precrq_qb_ph.c
@@ -0,0 +1,21 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt;
+ int result;
+
+ rs = 0x12345678;
+ rt = 0x87654321;
+ result = 0x12568743;
+
+ __asm
+ ("precrq.qb.ph %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt)
+ );
+ assert(result == rd);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/precrq_rs_ph_w.c b/qemu/tests/tcg/mips/mips32-dsp/precrq_rs_ph_w.c
new file mode 100644
index 000000000..da6845bf2
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/precrq_rs_ph_w.c
@@ -0,0 +1,51 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt;
+ int dsp;
+ int result;
+
+ rs = 0x12345678;
+ rt = 0x87654321;
+ result = 0x12348765;
+
+ __asm
+ ("wrdsp $0\n\t"
+ "precrq_rs.ph.w %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rs), "r"(rt)
+ );
+ assert(result == rd);
+
+ rs = 0x7FFFC678;
+ rt = 0x865432A0;
+ result = 0x7FFF8654;
+
+ __asm
+ ("wrdsp $0\n\t"
+ "precrq_rs.ph.w %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ assert(((dsp >> 22) & 0x01) == 1);
+ assert(result == rd);
+
+ rs = 0xBEEFFEED;
+ rt = 0x7FFF8000;
+ result = 0xBEF07FFF;
+
+ __asm
+ ("wrdsp $0\n\t"
+ "precrq_rs.ph.w %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ assert(((dsp >> 22) & 0x01) == 1);
+ assert(result == rd);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/precrqu_s_qb_ph.c b/qemu/tests/tcg/mips/mips32-dsp/precrqu_s_qb_ph.c
new file mode 100644
index 000000000..7481d5af3
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/precrqu_s_qb_ph.c
@@ -0,0 +1,24 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt;
+ int dsp;
+ int result;
+
+ rs = 0x12345678;
+ rt = 0x87657FFF;
+ result = 0x24AC00FF;
+
+ __asm
+ ("precrqu_s.qb.ph %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ assert(result == rd);
+ assert(((dsp >> 22) & 0x01) == 0x01);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/raddu_w_qb.c b/qemu/tests/tcg/mips/mips32-dsp/raddu_w_qb.c
new file mode 100644
index 000000000..77a983c0d
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/raddu_w_qb.c
@@ -0,0 +1,20 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs;
+ int result;
+
+ rs = 0x12345678;
+ result = 0x114;
+
+ __asm
+ ("raddu.w.qb %0, %1\n\t"
+ : "=r"(rd)
+ : "r"(rs)
+ );
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/rddsp.c b/qemu/tests/tcg/mips/mips32-dsp/rddsp.c
new file mode 100644
index 000000000..2f3028503
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/rddsp.c
@@ -0,0 +1,46 @@
+#include<stdio.h>
+#include<assert.h>
+
+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;
+
+ 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) | \
+ (efi_i << 14) | \
+ (c_i << 13) | \
+ (scount_i << 7) | \
+ pos_i;
+
+ __asm
+ ("wrdsp %1, 0x3F\n\t"
+ "rddsp %0, 0x3F\n\t"
+ : "=r"(dsp_o)
+ : "r"(dsp_i)
+ );
+
+ ccond_o = (dsp_o >> 24) & 0xFF;
+ outflag_o = (dsp_o >> 16) & 0xFF;
+ efi_o = (dsp_o >> 14) & 0x01;
+ c_o = (dsp_o >> 14) & 0x01;
+ scount_o = (dsp_o >> 7) & 0x3F;
+ pos_o = dsp_o & 0x1F;
+
+ 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/qemu/tests/tcg/mips/mips32-dsp/repl_ph.c b/qemu/tests/tcg/mips/mips32-dsp/repl_ph.c
new file mode 100644
index 000000000..21074953b
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/repl_ph.c
@@ -0,0 +1,23 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, result;
+
+ result = 0x01BF01BF;
+ __asm
+ ("repl.ph %0, 0x1BF\n\t"
+ : "=r"(rd)
+ );
+ assert(rd == result);
+
+ result = 0x01FF01FF;
+ __asm
+ ("repl.ph %0, 0x01FF\n\t"
+ : "=r"(rd)
+ );
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/repl_qb.c b/qemu/tests/tcg/mips/mips32-dsp/repl_qb.c
new file mode 100644
index 000000000..6631393ea
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/repl_qb.c
@@ -0,0 +1,16 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, result;
+
+ result = 0xBFBFBFBF;
+ __asm
+ ("repl.qb %0, 0xBF\n\t"
+ : "=r"(rd)
+ );
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/replv_ph.c b/qemu/tests/tcg/mips/mips32-dsp/replv_ph.c
new file mode 100644
index 000000000..07fb15f1f
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/replv_ph.c
@@ -0,0 +1,19 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rt;
+ int result;
+
+ rt = 0x12345678;
+ result = 0x56785678;
+ __asm
+ ("replv.ph %0, %1\n\t"
+ : "=r"(rd)
+ : "r"(rt)
+ );
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/replv_qb.c b/qemu/tests/tcg/mips/mips32-dsp/replv_qb.c
new file mode 100644
index 000000000..dd1271fed
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/replv_qb.c
@@ -0,0 +1,19 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rt;
+ int result;
+
+ rt = 0x12345678;
+ result = 0x78787878;
+ __asm
+ ("replv.qb %0, %1\n\t"
+ : "=r"(rd)
+ : "r"(rt)
+ );
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/shilo.c b/qemu/tests/tcg/mips/mips32-dsp/shilo.c
new file mode 100644
index 000000000..ce8ebc69c
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/shilo.c
@@ -0,0 +1,45 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int ach, acl;
+ int resulth, resultl;
+
+ ach = 0xBBAACCFF;
+ acl = 0x1C3B001D;
+
+ resulth = 0x17755;
+ resultl = 0x99fe3876;
+
+ __asm
+ ("mthi %0, $ac1\n\t"
+ "mtlo %1, $ac1\n\t"
+ "shilo $ac1, 0x0F\n\t"
+ "mfhi %0, $ac1\n\t"
+ "mflo %1, $ac1\n\t"
+ : "+r"(ach), "+r"(acl)
+ );
+ assert(ach == resulth);
+ assert(acl == resultl);
+
+
+ ach = 0x1;
+ acl = 0x80000000;
+
+ resulth = 0x3;
+ resultl = 0x0;
+
+ __asm
+ ("mthi %0, $ac1\n\t"
+ "mtlo %1, $ac1\n\t"
+ "shilo $ac1, -1\n\t"
+ "mfhi %0, $ac1\n\t"
+ "mflo %1, $ac1\n\t"
+ : "+r"(ach), "+r"(acl)
+ );
+ assert(ach == resulth);
+ assert(acl == resultl);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/shilov.c b/qemu/tests/tcg/mips/mips32-dsp/shilov.c
new file mode 100644
index 000000000..e1d6cea4b
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/shilov.c
@@ -0,0 +1,49 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rs, ach, acl;
+ int resulth, resultl;
+
+ rs = 0x0F;
+ ach = 0xBBAACCFF;
+ acl = 0x1C3B001D;
+
+ resulth = 0x17755;
+ resultl = 0x99fe3876;
+
+ __asm
+ ("mthi %0, $ac1\n\t"
+ "mtlo %1, $ac1\n\t"
+ "shilov $ac1, %2\n\t"
+ "mfhi %0, $ac1\n\t"
+ "mflo %1, $ac1\n\t"
+ : "+r"(ach), "+r"(acl)
+ : "r"(rs)
+ );
+ assert(ach == resulth);
+ assert(acl == resultl);
+
+
+ rs = 0xffffffff;
+ ach = 0x1;
+ acl = 0x80000000;
+
+ resulth = 0x3;
+ resultl = 0x0;
+
+ __asm
+ ("mthi %0, $ac1\n\t"
+ "mtlo %1, $ac1\n\t"
+ "shilov $ac1, %2\n\t"
+ "mfhi %0, $ac1\n\t"
+ "mflo %1, $ac1\n\t"
+ : "+r"(ach), "+r"(acl)
+ : "r"(rs)
+ );
+ assert(ach == resulth);
+ assert(acl == resultl);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/shll_ph.c b/qemu/tests/tcg/mips/mips32-dsp/shll_ph.c
new file mode 100644
index 000000000..5fa58ccf6
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/shll_ph.c
@@ -0,0 +1,55 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rt, dsp;
+ int result, resultdsp;
+
+ rt = 0x12345678;
+ result = 0xA000C000;
+ resultdsp = 1;
+
+ __asm
+ ("wrdsp $0\n\t"
+ "shll.ph %0, %2, 0x0B\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rt)
+ );
+ dsp = (dsp >> 22) & 0x01;
+ assert(dsp == resultdsp);
+ assert(rd == result);
+
+ rt = 0x7fff8000;
+ result = 0xfffe0000;
+ resultdsp = 1;
+
+ __asm
+ ("wrdsp $0\n\t"
+ "shll.ph %0, %2, 0x01\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rt)
+ );
+ dsp = (dsp >> 22) & 0x01;
+ assert(dsp == resultdsp);
+ assert(rd == result);
+
+ rt = 0x00000001;
+ result = 0x00008000;
+ resultdsp = 1;
+
+ __asm
+ ("wrdsp $0\n\t"
+ "shll.ph %0, %2, 0x0F\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rt)
+ );
+ dsp = (dsp >> 22) & 0x01;
+ assert(dsp == resultdsp);
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/shll_qb.c b/qemu/tests/tcg/mips/mips32-dsp/shll_qb.c
new file mode 100644
index 000000000..729716d62
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/shll_qb.c
@@ -0,0 +1,55 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rt, dsp;
+ int result, resultdsp;
+
+ rt = 0x87654321;
+ result = 0x87654321;
+ resultdsp = 0x00;
+
+ __asm
+ ("wrdsp $0\n\t"
+ "shll.qb %0, %2, 0x00\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rt)
+ );
+ dsp = (dsp >> 22) & 0x01;
+ assert(dsp == resultdsp);
+ assert(rd == result);
+
+ rt = 0x87654321;
+ result = 0x38281808;
+ resultdsp = 0x01;
+
+ __asm
+ ("wrdsp $0\n\t"
+ "shll.qb %0, %2, 0x03\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rt)
+ );
+ dsp = (dsp >> 22) & 0x01;
+ assert(dsp == resultdsp);
+ assert(rd == result);
+
+ rt = 0x00000001;
+ result = 0x00000080;
+ resultdsp = 0x00;
+
+ __asm
+ ("wrdsp $0\n\t"
+ "shll.qb %0, %2, 0x07\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rt)
+ );
+ dsp = (dsp >> 22) & 0x01;
+ assert(dsp == resultdsp);
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/shll_s_ph.c b/qemu/tests/tcg/mips/mips32-dsp/shll_s_ph.c
new file mode 100644
index 000000000..910fea3b3
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/shll_s_ph.c
@@ -0,0 +1,24 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rt, dsp;
+ int result, resultdsp;
+
+ rt = 0x12345678;
+ result = 0x7FFF7FFF;
+ resultdsp = 0x01;
+
+ __asm
+ ("shll_s.ph %0, %2, 0x0B\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rt)
+ );
+ dsp = (dsp >> 22) & 0x01;
+ assert(dsp == resultdsp);
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/shll_s_w.c b/qemu/tests/tcg/mips/mips32-dsp/shll_s_w.c
new file mode 100644
index 000000000..628c75210
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/shll_s_w.c
@@ -0,0 +1,52 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rt, dsp;
+ int result, resultdsp;
+
+ rt = 0x82345678;
+ result = 0x82345678;
+ resultdsp = 0x00;
+
+ __asm
+ ("shll_s.w %0, %2, 0x0\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rt)
+ );
+ dsp = (dsp >> 22) & 0x01;
+ assert(dsp == resultdsp);
+ assert(rd == result);
+
+ rt = 0x82345678;
+ result = 0x80000000;
+ resultdsp = 0x01;
+
+ __asm
+ ("shll_s.w %0, %2, 0x0B\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rt)
+ );
+ dsp = (dsp >> 22) & 0x01;
+ assert(dsp == resultdsp);
+ assert(rd == result);
+
+ rt = 0x12345678;
+ result = 0x7FFFFFFF;
+ resultdsp = 0x01;
+
+ __asm
+ ("shll_s.w %0, %2, 0x0B\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rt)
+ );
+ dsp = (dsp >> 22) & 0x01;
+ assert(dsp == resultdsp);
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/shllv_ph.c b/qemu/tests/tcg/mips/mips32-dsp/shllv_ph.c
new file mode 100644
index 000000000..f98a6322d
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/shllv_ph.c
@@ -0,0 +1,40 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt, dsp;
+ int result, resultdsp;
+
+ rs = 0x0;
+ rt = 0x12345678;
+ result = 0x12345678;
+ resultdsp = 0;
+
+ __asm
+ ("shllv.ph %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rt), "r"(rs)
+ );
+ dsp = (dsp >> 22) & 0x01;
+ assert(dsp == resultdsp);
+ assert(rd == result);
+
+ rs = 0x0B;
+ rt = 0x12345678;
+ result = 0xA000C000;
+ resultdsp = 1;
+
+ __asm
+ ("shllv.ph %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rt), "r"(rs)
+ );
+ dsp = (dsp >> 22) & 0x01;
+ assert(dsp == resultdsp);
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/shllv_qb.c b/qemu/tests/tcg/mips/mips32-dsp/shllv_qb.c
new file mode 100644
index 000000000..6d8ff4a25
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/shllv_qb.c
@@ -0,0 +1,38 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt, dsp;
+ int result, resultdsp;
+
+ rs = 0x03;
+ rt = 0x87654321;
+ result = 0x38281808;
+ resultdsp = 0x01;
+
+ __asm
+ ("shllv.qb %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rt), "r"(rs)
+ );
+ dsp = (dsp >> 22) & 0x01;
+ assert(rd == result);
+
+ rs = 0x00;
+ rt = 0x87654321;
+ result = 0x87654321;
+ resultdsp = 0x01;
+
+ __asm
+ ("shllv.qb %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rt), "r"(rs)
+ );
+ dsp = (dsp >> 22) & 0x01;
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/shllv_s_ph.c b/qemu/tests/tcg/mips/mips32-dsp/shllv_s_ph.c
new file mode 100644
index 000000000..fc9bd3276
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/shllv_s_ph.c
@@ -0,0 +1,40 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt, dsp;
+ int result, resultdsp;
+
+ rs = 0x0;
+ rt = 0x12345678;
+ result = 0x12345678;
+ resultdsp = 0x0;
+
+ __asm
+ ("shllv_s.ph %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rt), "r"(rs)
+ );
+ dsp = (dsp >> 22) & 0x01;
+ assert(dsp == resultdsp);
+ assert(rd == result);
+
+ rs = 0x0B;
+ rt = 0x12345678;
+ result = 0x7FFF7FFF;
+ resultdsp = 0x01;
+
+ __asm
+ ("shllv_s.ph %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rt), "r"(rs)
+ );
+ dsp = (dsp >> 22) & 0x01;
+ assert(dsp == resultdsp);
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/shllv_s_w.c b/qemu/tests/tcg/mips/mips32-dsp/shllv_s_w.c
new file mode 100644
index 000000000..350c25617
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/shllv_s_w.c
@@ -0,0 +1,40 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt, dsp;
+ int result, resultdsp;
+
+ rs = 0x0B;
+ rt = 0x12345678;
+ result = 0x7FFFFFFF;
+ resultdsp = 0x01;
+
+ __asm
+ ("shllv_s.w %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rt), "r"(rs)
+ );
+ dsp = (dsp >> 22) & 0x01;
+ assert(dsp == resultdsp);
+ assert(rd == result);
+
+ rs = 0x0;
+ rt = 0x12345678;
+ result = 0x12345678;
+ resultdsp = 0x01;
+
+ __asm
+ ("shllv_s.w %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rt), "r"(rs)
+ );
+ dsp = (dsp >> 22) & 0x01;
+ assert(dsp == resultdsp);
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/shra_ph.c b/qemu/tests/tcg/mips/mips32-dsp/shra_ph.c
new file mode 100644
index 000000000..5b2d840a6
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/shra_ph.c
@@ -0,0 +1,30 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rt;
+ int result;
+
+ rt = 0x87654321;
+ result = 0xF0EC0864;
+
+ __asm
+ ("shra.ph %0, %1, 0x03\n\t"
+ : "=r"(rd)
+ : "r"(rt)
+ );
+ assert(rd == result);
+
+ rt = 0x87654321;
+ result = 0x87654321;
+
+ __asm
+ ("shra.ph %0, %1, 0x00\n\t"
+ : "=r"(rd)
+ : "r"(rt)
+ );
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/shra_r_ph.c b/qemu/tests/tcg/mips/mips32-dsp/shra_r_ph.c
new file mode 100644
index 000000000..adc4ae68b
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/shra_r_ph.c
@@ -0,0 +1,30 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rt;
+ int result;
+
+ rt = 0x87654321;
+ result = 0xF0ED0864;
+
+ __asm
+ ("shra_r.ph %0, %1, 0x03\n\t"
+ : "=r"(rd)
+ : "r"(rt)
+ );
+ assert(rd == result);
+
+ rt = 0x87654321;
+ result = 0x87654321;
+
+ __asm
+ ("shra_r.ph %0, %1, 0x00\n\t"
+ : "=r"(rd)
+ : "r"(rt)
+ );
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/shra_r_w.c b/qemu/tests/tcg/mips/mips32-dsp/shra_r_w.c
new file mode 100644
index 000000000..ec0cf2c72
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/shra_r_w.c
@@ -0,0 +1,30 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rt;
+ int result;
+
+ rt = 0x87654321;
+ result = 0xF0ECA864;
+
+ __asm
+ ("shra_r.w %0, %1, 0x03\n\t"
+ : "=r"(rd)
+ : "r"(rt)
+ );
+ assert(rd == result);
+
+ rt = 0x87654321;
+ result = 0x87654321;
+
+ __asm
+ ("shra_r.w %0, %1, 0x0\n\t"
+ : "=r"(rd)
+ : "r"(rt)
+ );
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/shrav_ph.c b/qemu/tests/tcg/mips/mips32-dsp/shrav_ph.c
new file mode 100644
index 000000000..6e42aaf8e
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/shrav_ph.c
@@ -0,0 +1,32 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt;
+ int result;
+
+ rs = 0x03;
+ rt = 0x87654321;
+ result = 0xF0EC0864;
+
+ __asm
+ ("shrav.ph %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rt), "r"(rs)
+ );
+ assert(rd == result);
+
+ rs = 0x00;
+ rt = 0x87654321;
+ result = 0x87654321;
+
+ __asm
+ ("shrav.ph %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rt), "r"(rs)
+ );
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/shrav_r_ph.c b/qemu/tests/tcg/mips/mips32-dsp/shrav_r_ph.c
new file mode 100644
index 000000000..f03b978d0
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/shrav_r_ph.c
@@ -0,0 +1,32 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt;
+ int result;
+
+ rs = 0x03;
+ rt = 0x87654321;
+ result = 0xF0ED0864;
+
+ __asm
+ ("shrav_r.ph %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rt), "r"(rs)
+ );
+ assert(rd == result);
+
+ rs = 0x00;
+ rt = 0x87654321;
+ result = 0x87654321;
+
+ __asm
+ ("shrav_r.ph %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rt), "r"(rs)
+ );
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/shrav_r_w.c b/qemu/tests/tcg/mips/mips32-dsp/shrav_r_w.c
new file mode 100644
index 000000000..2ab03bb5d
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/shrav_r_w.c
@@ -0,0 +1,32 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt;
+ int result;
+
+ rs = 0x03;
+ rt = 0x87654321;
+ result = 0xF0ECA864;
+
+ __asm
+ ("shrav_r.w %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rt), "r"(rs)
+ );
+ assert(rd == result);
+
+ rs = 0x00;
+ rt = 0x40000000;
+ result = 0x40000000;
+
+ __asm
+ ("shrav_r.w %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rt), "r"(rs)
+ );
+
+ assert(rd == result);
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/shrl_qb.c b/qemu/tests/tcg/mips/mips32-dsp/shrl_qb.c
new file mode 100644
index 000000000..a7e4e6a5e
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/shrl_qb.c
@@ -0,0 +1,31 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rt;
+ int result;
+
+ rt = 0x12345678;
+ result = 0x00010203;
+
+ __asm
+ ("shrl.qb %0, %1, 0x05\n\t"
+ : "=r"(rd)
+ : "r"(rt)
+ );
+ assert(rd == result);
+
+ rt = 0x12345678;
+ result = 0x12345678;
+
+ __asm
+ ("shrl.qb %0, %1, 0x0\n\t"
+ : "=r"(rd)
+ : "r"(rt)
+ );
+
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/shrlv_qb.c b/qemu/tests/tcg/mips/mips32-dsp/shrlv_qb.c
new file mode 100644
index 000000000..db77f6d0e
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/shrlv_qb.c
@@ -0,0 +1,32 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt;
+ int result;
+
+ rs = 0x05;
+ rt = 0x12345678;
+ result = 0x00010203;
+
+ __asm
+ ("shrlv.qb %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rt), "r"(rs)
+ );
+ assert(rd == result);
+
+ rs = 0x00;
+ rt = 0x12345678;
+ result = 0x12345678;
+
+ __asm
+ ("shrlv.qb %0, %1, %2\n\t"
+ : "=r"(rd)
+ : "r"(rt), "r"(rs)
+ );
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/subq_ph.c b/qemu/tests/tcg/mips/mips32-dsp/subq_ph.c
new file mode 100644
index 000000000..fdd7b38b6
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/subq_ph.c
@@ -0,0 +1,40 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt, dsp;
+ int result, resultdsp;
+
+ rs = 0x77777777;
+ rt = 0x67654321;
+ result = 0x10123456;
+ resultdsp = 0x0;
+
+ __asm
+ ("subq.ph %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ dsp = (dsp >> 20) & 0x01;
+ assert(dsp == resultdsp);
+ assert(rd == result);
+
+ rs = 0x12345678;
+ rt = 0x87654321;
+ result = 0x8ACF1357;
+ resultdsp = 0x01;
+
+ __asm
+ ("subq.ph %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ dsp = (dsp >> 20) & 0x01;
+ assert(dsp == resultdsp);
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/subq_s_ph.c b/qemu/tests/tcg/mips/mips32-dsp/subq_s_ph.c
new file mode 100644
index 000000000..64c89ebd5
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/subq_s_ph.c
@@ -0,0 +1,58 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt, dsp;
+ int result, resultdsp;
+
+ rs = 0x12345678;
+ rt = 0x87654321;
+ result = 0x7FFF1357;
+ resultdsp = 0x01;
+
+ __asm
+ ("wrdsp $0\n\t"
+ "subq_s.ph %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ dsp = (dsp >> 20) & 0x01;
+ assert(dsp == resultdsp);
+ assert(rd == result);
+
+ rs = 0x12348000;
+ rt = 0x87657000;
+ result = 0x7FFF8000;
+ resultdsp = 0x01;
+
+ __asm
+ ("wrdsp $0\n\t"
+ "subq_s.ph %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ dsp = (dsp >> 20) & 0x01;
+ assert(dsp == resultdsp);
+ assert(rd == result);
+
+ rs = 0x12340000;
+ rt = 0x87658000;
+ result = 0x7FFF7FFF;
+ resultdsp = 0x01;
+
+ __asm
+ ("wrdsp $0\n\t"
+ "subq_s.ph %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ dsp = (dsp >> 20) & 0x01;
+ assert(dsp == resultdsp);
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/subq_s_w.c b/qemu/tests/tcg/mips/mips32-dsp/subq_s_w.c
new file mode 100644
index 000000000..9d456a90f
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/subq_s_w.c
@@ -0,0 +1,74 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt, dsp;
+ int result, resultdsp;
+
+ rs = 0x12345678;
+ rt = 0x87654321;
+ result = 0x7FFFFFFF;
+ resultdsp = 0x01;
+
+ __asm
+ ("wrdsp $0\n\t"
+ "subq_s.w %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ dsp = (dsp >> 20) & 0x01;
+ assert(dsp == resultdsp);
+ assert(rd == result);
+
+ rs = 0x66666;
+ rt = 0x55555;
+ result = 0x11111;
+ resultdsp = 0x0;
+
+ __asm
+ ("wrdsp $0\n\t"
+ "subq_s.w %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ dsp = (dsp >> 20) & 0x01;
+ assert(dsp == resultdsp);
+ assert(rd == result);
+
+ rs = 0x0;
+ rt = 0x80000000;
+ result = 0x7FFFFFFF;
+ resultdsp = 0x01;
+
+ __asm
+ ("wrdsp $0\n\t"
+ "subq_s.w %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ dsp = (dsp >> 20) & 0x01;
+ assert(dsp == resultdsp);
+ assert(rd == result);
+
+ rs = 0x80000000;
+ rt = 0x80000000;
+ result = 0;
+ resultdsp = 0x00;
+
+ __asm
+ ("wrdsp $0\n\t"
+ "subq_s.w %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ dsp = (dsp >> 20) & 0x01;
+ assert(dsp == resultdsp);
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/subu_qb.c b/qemu/tests/tcg/mips/mips32-dsp/subu_qb.c
new file mode 100644
index 000000000..420909615
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/subu_qb.c
@@ -0,0 +1,25 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt, dsp;
+ int result, resultdsp;
+
+ rs = 0x12345678;
+ rt = 0x87654321;
+ result = 0x8BCF1357;
+ resultdsp = 0x01;
+
+ __asm
+ ("subu.qb %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ dsp = (dsp >> 20) & 0x01;
+ assert(dsp == resultdsp);
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/subu_s_qb.c b/qemu/tests/tcg/mips/mips32-dsp/subu_s_qb.c
new file mode 100644
index 000000000..3d650533d
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/subu_s_qb.c
@@ -0,0 +1,25 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+ int rd, rs, rt, dsp;
+ int result, resultdsp;
+
+ rs = 0x12345678;
+ rt = 0x87654321;
+ result = 0x00001357;
+ resultdsp = 0x01;
+
+ __asm
+ ("subu_s.qb %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ dsp = (dsp >> 20) & 0x01;
+ assert(dsp == resultdsp);
+ assert(rd == result);
+
+ return 0;
+}
diff --git a/qemu/tests/tcg/mips/mips32-dsp/wrdsp.c b/qemu/tests/tcg/mips/mips32-dsp/wrdsp.c
new file mode 100644
index 000000000..dc54943a9
--- /dev/null
+++ b/qemu/tests/tcg/mips/mips32-dsp/wrdsp.c
@@ -0,0 +1,46 @@
+#include<stdio.h>
+#include<assert.h>
+
+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;
+
+ 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) | \
+ (efi_i << 14) | \
+ (c_i << 13) | \
+ (scount_i << 7) | \
+ pos_i;
+
+ __asm
+ ("wrdsp %1, 0x3F\n\t"
+ "rddsp %0, 0x3F\n\t"
+ : "=r"(dsp_o)
+ : "r"(dsp_i)
+ );
+
+ ccond_o = (dsp_o >> 24) & 0xFF;
+ outflag_o = (dsp_o >> 16) & 0xFF;
+ efi_o = (dsp_o >> 14) & 0x01;
+ c_o = (dsp_o >> 14) & 0x01;
+ scount_o = (dsp_o >> 7) & 0x3F;
+ pos_o = dsp_o & 0x1F;
+
+ 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;
+}