All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH V2 0/4] MIPS ASE DSP Support for Qemu
@ 2012-03-22 13:36 Jia Liu
  2012-03-22 13:36 ` [Qemu-devel] [PATCH V2 1/4] add MIPS DSP helpers define Jia Liu
                   ` (6 more replies)
  0 siblings, 7 replies; 14+ messages in thread
From: Jia Liu @ 2012-03-22 13:36 UTC (permalink / raw)
  To: qemu-devel; +Cc: sw, aurelien

This is the MIPS ASE DSP Support for Qemu.

Signed-off-by: Jia Liu <proljc@gmail.com>
---

Version History:

V2:
Addressed Stefan's review comments:
- fixed coding style.
- changed acc into unsigned int form int and no initialization in translation.
- added return value in testcases.

V1:
- add MIPS ASE DSP Support.

Jia Liu (4):
  add MIPS DSP helpers define
  add MIPS DSP helpers implement
  add MIPS DSP translation
  add MIPS DSP testcase

 target-mips/helper.h                           |  152 +
 target-mips/op_helper.c                        | 3936 ++++++++++++++++++++++++
 target-mips/translate.c                        | 1110 +++++++-
 tests/tcg/mips/mips32-dsp/Makefile             |  133 +
 tests/tcg/mips/mips32-dsp/absq_s_ph.c          |   30 +
 tests/tcg/mips/mips32-dsp/absq_s_w.c           |   37 +
 tests/tcg/mips/mips32-dsp/addq_ph.c            |   30 +
 tests/tcg/mips/mips32-dsp/addq_s_ph.c          |   30 +
 tests/tcg/mips/mips32-dsp/addsc.c              |   30 +
 tests/tcg/mips/mips32-dsp/addu_qb.c            |   30 +
 tests/tcg/mips/mips32-dsp/addu_s_qb.c          |   30 +
 tests/tcg/mips/mips32-dsp/addwc.c              |   30 +
 tests/tcg/mips/mips32-dsp/bitrev.c             |   20 +
 tests/tcg/mips/mips32-dsp/bposge32.c           |   44 +
 tests/tcg/mips/mips32-dsp/cmp_eq_ph.c          |   35 +
 tests/tcg/mips/mips32-dsp/cmp_le_ph.c          |   35 +
 tests/tcg/mips/mips32-dsp/cmp_lt_ph.c          |   35 +
 tests/tcg/mips/mips32-dsp/cmpgu_eq_qb.c        |   31 +
 tests/tcg/mips/mips32-dsp/cmpgu_le_qb.c        |   31 +
 tests/tcg/mips/mips32-dsp/cmpgu_lt_qb.c        |   31 +
 tests/tcg/mips/mips32-dsp/cmpu_eq_qb.c         |   35 +
 tests/tcg/mips/mips32-dsp/cmpu_le_qb.c         |   35 +
 tests/tcg/mips/mips32-dsp/cmpu_lt_qb.c         |   35 +
 tests/tcg/mips/mips32-dsp/dpaq_s_w_ph.c        |   31 +
 tests/tcg/mips/mips32-dsp/dpaq_sa_l_w.c        |   31 +
 tests/tcg/mips/mips32-dsp/dpau_h_qbl.c         |   27 +
 tests/tcg/mips/mips32-dsp/dpau_h_qbr.c         |   27 +
 tests/tcg/mips/mips32-dsp/dpsq_s_w_ph.c        |   27 +
 tests/tcg/mips/mips32-dsp/dpsq_sa_l_w.c        |   31 +
 tests/tcg/mips/mips32-dsp/dpsu_h_qbl.c         |   27 +
 tests/tcg/mips/mips32-dsp/dpsu_h_qbr.c         |   27 +
 tests/tcg/mips/mips32-dsp/extp.c               |   44 +
 tests/tcg/mips/mips32-dsp/extpdp.c             |   46 +
 tests/tcg/mips/mips32-dsp/extpdpv.c            |   47 +
 tests/tcg/mips/mips32-dsp/extpv.c              |   45 +
 tests/tcg/mips/mips32-dsp/extr_r_w.c           |   25 +
 tests/tcg/mips/mips32-dsp/extr_rs_w.c          |   25 +
 tests/tcg/mips/mips32-dsp/extr_s_h.c           |   25 +
 tests/tcg/mips/mips32-dsp/extr_w.c             |   25 +
 tests/tcg/mips/mips32-dsp/extrv_r_w.c          |   29 +
 tests/tcg/mips/mips32-dsp/extrv_rs_w.c         |   29 +
 tests/tcg/mips/mips32-dsp/extrv_s_h.c          |   29 +
 tests/tcg/mips/mips32-dsp/extrv_w.c            |   29 +
 tests/tcg/mips/mips32-dsp/insv.c               |   23 +
 tests/tcg/mips/mips32-dsp/lbux.c               |   23 +
 tests/tcg/mips/mips32-dsp/lhx.c                |   23 +
 tests/tcg/mips/mips32-dsp/lwx.c                |   23 +
 tests/tcg/mips/mips32-dsp/madd.c               |   31 +
 tests/tcg/mips/mips32-dsp/maddu.c              |   31 +
 tests/tcg/mips/mips32-dsp/maq_s_w_phl.c        |   31 +
 tests/tcg/mips/mips32-dsp/maq_s_w_phr.c        |   31 +
 tests/tcg/mips/mips32-dsp/maq_sa_w_phl.c       |   31 +
 tests/tcg/mips/mips32-dsp/maq_sa_w_phr.c       |   31 +
 tests/tcg/mips/mips32-dsp/mfhi.c               |   21 +
 tests/tcg/mips/mips32-dsp/mflo.c               |   21 +
 tests/tcg/mips/mips32-dsp/modsub.c             |   30 +
 tests/tcg/mips/mips32-dsp/msub.c               |   30 +
 tests/tcg/mips/mips32-dsp/msubu.c              |   30 +
 tests/tcg/mips/mips32-dsp/mthi.c               |   21 +
 tests/tcg/mips/mips32-dsp/mthlip.c             |   34 +
 tests/tcg/mips/mips32-dsp/mtlo.c               |   21 +
 tests/tcg/mips/mips32-dsp/muleq_s_w_phr.c      |   40 +
 tests/tcg/mips/mips32-dsp/muleu_s_ph_qbl.c     |   25 +
 tests/tcg/mips/mips32-dsp/muleu_s_ph_qbr.c     |   25 +
 tests/tcg/mips/mips32-dsp/mulq_rs_ph.c         |   25 +
 tests/tcg/mips/mips32-dsp/mult.c               |   24 +
 tests/tcg/mips/mips32-dsp/multu.c              |   24 +
 tests/tcg/mips/mips32-dsp/packrl_ph.c          |   21 +
 tests/tcg/mips/mips32-dsp/pick_ph.c            |   23 +
 tests/tcg/mips/mips32-dsp/pick_qb.c            |   23 +
 tests/tcg/mips/mips32-dsp/preceq_w_phl.c       |   20 +
 tests/tcg/mips/mips32-dsp/preceq_w_phr.c       |   20 +
 tests/tcg/mips/mips32-dsp/precequ_ph_qbl.c     |   20 +
 tests/tcg/mips/mips32-dsp/precequ_ph_qbla.c    |   20 +
 tests/tcg/mips/mips32-dsp/precequ_ph_qbr.c     |   20 +
 tests/tcg/mips/mips32-dsp/precequ_ph_qbra.c    |   20 +
 tests/tcg/mips/mips32-dsp/preceu_ph_qbl.c      |   20 +
 tests/tcg/mips/mips32-dsp/preceu_ph_qbla.c     |   20 +
 tests/tcg/mips/mips32-dsp/preceu_ph_qbr.c      |   20 +
 tests/tcg/mips/mips32-dsp/preceu_ph_qbra.c     |   20 +
 tests/tcg/mips/mips32-dsp/precrq_ph_w.c        |   21 +
 tests/tcg/mips/mips32-dsp/precrq_qb_ph.c       |   21 +
 tests/tcg/mips/mips32-dsp/precrq_rs_ph_w.c     |   21 +
 tests/tcg/mips/mips32-dsp/precrqu_s_qb_ph.c    |   21 +
 tests/tcg/mips/mips32-dsp/raddu_w_qb.c         |   20 +
 tests/tcg/mips/mips32-dsp/rddsp.c              |   54 +
 tests/tcg/mips/mips32-dsp/repl_ph.c            |   23 +
 tests/tcg/mips/mips32-dsp/repl_qb.c            |   16 +
 tests/tcg/mips/mips32-dsp/replv_ph.c           |   19 +
 tests/tcg/mips/mips32-dsp/replv_qb.c           |   19 +
 tests/tcg/mips/mips32-dsp/shilo.c              |   27 +
 tests/tcg/mips/mips32-dsp/shilov.c             |   29 +
 tests/tcg/mips/mips32-dsp/shll_ph.c            |   24 +
 tests/tcg/mips/mips32-dsp/shll_qb.c            |   23 +
 tests/tcg/mips/mips32-dsp/shll_s_ph.c          |   24 +
 tests/tcg/mips/mips32-dsp/shll_s_w.c           |   24 +
 tests/tcg/mips/mips32-dsp/shllv_ph.c           |   25 +
 tests/tcg/mips/mips32-dsp/shllv_qb.c           |   24 +
 tests/tcg/mips/mips32-dsp/shllv_s_ph.c         |   25 +
 tests/tcg/mips/mips32-dsp/shllv_s_w.c          |   25 +
 tests/tcg/mips/mips32-dsp/shra_ph.c            |   20 +
 tests/tcg/mips/mips32-dsp/shra_r_ph.c          |   20 +
 tests/tcg/mips/mips32-dsp/shra_r_w.c           |   20 +
 tests/tcg/mips/mips32-dsp/shrav_ph.c           |   21 +
 tests/tcg/mips/mips32-dsp/shrav_r_ph.c         |   21 +
 tests/tcg/mips/mips32-dsp/shrav_r_w.c          |   21 +
 tests/tcg/mips/mips32-dsp/shrl_qb.c            |   20 +
 tests/tcg/mips/mips32-dsp/shrlv_qb.c           |   21 +
 tests/tcg/mips/mips32-dsp/subq_ph.c            |   25 +
 tests/tcg/mips/mips32-dsp/subq_s_ph.c          |   25 +
 tests/tcg/mips/mips32-dsp/subq_s_w.c           |   25 +
 tests/tcg/mips/mips32-dsp/subu_qb.c            |   25 +
 tests/tcg/mips/mips32-dsp/subu_s_qb.c          |   25 +
 tests/tcg/mips/mips32-dsp/wrdsp.c              |   54 +
 tests/tcg/mips/mips32-dspr2/Makefile           |   71 +
 tests/tcg/mips/mips32-dspr2/absq_s_qb.c        |   31 +
 tests/tcg/mips/mips32-dspr2/addqh_ph.c         |   30 +
 tests/tcg/mips/mips32-dspr2/addqh_r_ph.c       |   30 +
 tests/tcg/mips/mips32-dspr2/addqh_r_w.c        |   34 +
 tests/tcg/mips/mips32-dspr2/addqh_w.c          |   34 +
 tests/tcg/mips/mips32-dspr2/addu_ph.c          |   30 +
 tests/tcg/mips/mips32-dspr2/addu_s_ph.c        |   30 +
 tests/tcg/mips/mips32-dspr2/adduh_qb.c         |   30 +
 tests/tcg/mips/mips32-dspr2/adduh_r_qb.c       |   30 +
 tests/tcg/mips/mips32-dspr2/append.c           |   30 +
 tests/tcg/mips/mips32-dspr2/balign.c           |   30 +
 tests/tcg/mips/mips32-dspr2/cmpgdu_eq_qb.c     |   37 +
 tests/tcg/mips/mips32-dspr2/cmpgdu_le_qb.c     |   37 +
 tests/tcg/mips/mips32-dspr2/cmpgdu_lt_qb.c     |   37 +
 tests/tcg/mips/mips32-dspr2/dpa_w_ph.c         |   27 +
 tests/tcg/mips/mips32-dspr2/dpaqx_s_w_ph.c     |   57 +
 tests/tcg/mips/mips32-dspr2/dpaqx_sa_w_ph.c    |   30 +
 tests/tcg/mips/mips32-dspr2/dpax_w_ph.c        |   27 +
 tests/tcg/mips/mips32-dspr2/dps_w_ph.c         |   27 +
 tests/tcg/mips/mips32-dspr2/dpsqx_s_w_ph.c     |   31 +
 tests/tcg/mips/mips32-dspr2/dpsqx_sa_w_ph.c    |   31 +
 tests/tcg/mips/mips32-dspr2/dpsx_w_ph.c        |   27 +
 tests/tcg/mips/mips32-dspr2/mul_ph.c           |   25 +
 tests/tcg/mips/mips32-dspr2/mul_s_ph.c         |   25 +
 tests/tcg/mips/mips32-dspr2/muleq_s_w_phl.c    |   40 +
 tests/tcg/mips/mips32-dspr2/mulq_rs_w.c        |   36 +
 tests/tcg/mips/mips32-dspr2/mulq_s_ph.c        |   25 +
 tests/tcg/mips/mips32-dspr2/mulq_s_w.c         |   36 +
 tests/tcg/mips/mips32-dspr2/mulsa_w_ph.c       |   29 +
 tests/tcg/mips/mips32-dspr2/mulsaq_s_w_ph.c    |   29 +
 tests/tcg/mips/mips32-dspr2/precr_qb_ph.c      |   21 +
 tests/tcg/mips/mips32-dspr2/precr_sra_ph_w.c   |   32 +
 tests/tcg/mips/mips32-dspr2/precr_sra_r_ph_w.c |   32 +
 tests/tcg/mips/mips32-dspr2/prepend.c          |   30 +
 tests/tcg/mips/mips32-dspr2/shra_qb.c          |   30 +
 tests/tcg/mips/mips32-dspr2/shra_r_qb.c        |   30 +
 tests/tcg/mips/mips32-dspr2/shrav_qb.c         |   32 +
 tests/tcg/mips/mips32-dspr2/shrav_r_qb.c       |   32 +
 tests/tcg/mips/mips32-dspr2/shrl_ph.c          |   20 +
 tests/tcg/mips/mips32-dspr2/shrlv_ph.c         |   21 +
 tests/tcg/mips/mips32-dspr2/subqh_ph.c         |   21 +
 tests/tcg/mips/mips32-dspr2/subqh_r_ph.c       |   21 +
 tests/tcg/mips/mips32-dspr2/subqh_r_w.c        |   21 +
 tests/tcg/mips/mips32-dspr2/subqh_w.c          |   21 +
 tests/tcg/mips/mips32-dspr2/subu_ph.c          |   25 +
 tests/tcg/mips/mips32-dspr2/subu_s_ph.c        |   25 +
 tests/tcg/mips/mips32-dspr2/subuh_qb.c         |   21 +
 tests/tcg/mips/mips32-dspr2/subuh_r_qb.c       |   21 +
 163 files changed, 9770 insertions(+), 24 deletions(-)
 create mode 100644 tests/tcg/mips/mips32-dsp/Makefile
 create mode 100644 tests/tcg/mips/mips32-dsp/absq_s_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/absq_s_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/addq_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/addq_s_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/addsc.c
 create mode 100644 tests/tcg/mips/mips32-dsp/addu_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/addu_s_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/addwc.c
 create mode 100644 tests/tcg/mips/mips32-dsp/bitrev.c
 create mode 100644 tests/tcg/mips/mips32-dsp/bposge32.c
 create mode 100644 tests/tcg/mips/mips32-dsp/cmp_eq_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/cmp_le_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/cmp_lt_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/cmpgu_eq_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/cmpgu_le_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/cmpgu_lt_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/cmpu_eq_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/cmpu_le_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/cmpu_lt_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/dpaq_s_w_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/dpaq_sa_l_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/dpau_h_qbl.c
 create mode 100644 tests/tcg/mips/mips32-dsp/dpau_h_qbr.c
 create mode 100644 tests/tcg/mips/mips32-dsp/dpsq_s_w_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/dpsq_sa_l_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/dpsu_h_qbl.c
 create mode 100644 tests/tcg/mips/mips32-dsp/dpsu_h_qbr.c
 create mode 100644 tests/tcg/mips/mips32-dsp/extp.c
 create mode 100644 tests/tcg/mips/mips32-dsp/extpdp.c
 create mode 100644 tests/tcg/mips/mips32-dsp/extpdpv.c
 create mode 100644 tests/tcg/mips/mips32-dsp/extpv.c
 create mode 100644 tests/tcg/mips/mips32-dsp/extr_r_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/extr_rs_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/extr_s_h.c
 create mode 100644 tests/tcg/mips/mips32-dsp/extr_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/extrv_r_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/extrv_rs_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/extrv_s_h.c
 create mode 100644 tests/tcg/mips/mips32-dsp/extrv_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/insv.c
 create mode 100644 tests/tcg/mips/mips32-dsp/lbux.c
 create mode 100644 tests/tcg/mips/mips32-dsp/lhx.c
 create mode 100644 tests/tcg/mips/mips32-dsp/lwx.c
 create mode 100644 tests/tcg/mips/mips32-dsp/madd.c
 create mode 100644 tests/tcg/mips/mips32-dsp/maddu.c
 create mode 100644 tests/tcg/mips/mips32-dsp/maq_s_w_phl.c
 create mode 100644 tests/tcg/mips/mips32-dsp/maq_s_w_phr.c
 create mode 100644 tests/tcg/mips/mips32-dsp/maq_sa_w_phl.c
 create mode 100644 tests/tcg/mips/mips32-dsp/maq_sa_w_phr.c
 create mode 100644 tests/tcg/mips/mips32-dsp/mfhi.c
 create mode 100644 tests/tcg/mips/mips32-dsp/mflo.c
 create mode 100644 tests/tcg/mips/mips32-dsp/modsub.c
 create mode 100644 tests/tcg/mips/mips32-dsp/msub.c
 create mode 100644 tests/tcg/mips/mips32-dsp/msubu.c
 create mode 100644 tests/tcg/mips/mips32-dsp/mthi.c
 create mode 100644 tests/tcg/mips/mips32-dsp/mthlip.c
 create mode 100644 tests/tcg/mips/mips32-dsp/mtlo.c
 create mode 100644 tests/tcg/mips/mips32-dsp/muleq_s_w_phr.c
 create mode 100644 tests/tcg/mips/mips32-dsp/muleu_s_ph_qbl.c
 create mode 100644 tests/tcg/mips/mips32-dsp/muleu_s_ph_qbr.c
 create mode 100644 tests/tcg/mips/mips32-dsp/mulq_rs_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/mult.c
 create mode 100644 tests/tcg/mips/mips32-dsp/multu.c
 create mode 100644 tests/tcg/mips/mips32-dsp/packrl_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/pick_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/pick_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/preceq_w_phl.c
 create mode 100644 tests/tcg/mips/mips32-dsp/preceq_w_phr.c
 create mode 100644 tests/tcg/mips/mips32-dsp/precequ_ph_qbl.c
 create mode 100644 tests/tcg/mips/mips32-dsp/precequ_ph_qbla.c
 create mode 100644 tests/tcg/mips/mips32-dsp/precequ_ph_qbr.c
 create mode 100644 tests/tcg/mips/mips32-dsp/precequ_ph_qbra.c
 create mode 100644 tests/tcg/mips/mips32-dsp/preceu_ph_qbl.c
 create mode 100644 tests/tcg/mips/mips32-dsp/preceu_ph_qbla.c
 create mode 100644 tests/tcg/mips/mips32-dsp/preceu_ph_qbr.c
 create mode 100644 tests/tcg/mips/mips32-dsp/preceu_ph_qbra.c
 create mode 100644 tests/tcg/mips/mips32-dsp/precrq_ph_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/precrq_qb_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/precrq_rs_ph_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/precrqu_s_qb_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/raddu_w_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/rddsp.c
 create mode 100644 tests/tcg/mips/mips32-dsp/repl_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/repl_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/replv_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/replv_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shilo.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shilov.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shll_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shll_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shll_s_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shll_s_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shllv_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shllv_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shllv_s_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shllv_s_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shra_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shra_r_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shra_r_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shrav_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shrav_r_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shrav_r_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shrl_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shrlv_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/subq_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/subq_s_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/subq_s_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/subu_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/subu_s_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/wrdsp.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/Makefile
 create mode 100644 tests/tcg/mips/mips32-dspr2/absq_s_qb.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/addqh_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/addqh_r_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/addqh_r_w.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/addqh_w.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/addu_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/addu_s_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/adduh_qb.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/adduh_r_qb.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/append.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/balign.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/cmpgdu_eq_qb.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/cmpgdu_le_qb.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/cmpgdu_lt_qb.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/dpa_w_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/dpaqx_s_w_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/dpaqx_sa_w_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/dpax_w_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/dps_w_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/dpsqx_s_w_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/dpsqx_sa_w_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/dpsx_w_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/mul_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/mul_s_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/muleq_s_w_phl.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/mulq_rs_w.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/mulq_s_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/mulq_s_w.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/mulsa_w_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/mulsaq_s_w_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/precr_qb_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/precr_sra_ph_w.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/precr_sra_r_ph_w.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/prepend.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/shra_qb.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/shra_r_qb.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/shrav_qb.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/shrav_r_qb.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/shrl_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/shrlv_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/subqh_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/subqh_r_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/subqh_r_w.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/subqh_w.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/subu_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/subu_s_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/subuh_qb.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/subuh_r_qb.c

-- 
1.7.5.4

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH V2 1/4] add MIPS DSP helpers define
  2012-03-22 13:36 [Qemu-devel] [PATCH V2 0/4] MIPS ASE DSP Support for Qemu Jia Liu
@ 2012-03-22 13:36 ` Jia Liu
  2012-03-22 13:36 ` [Qemu-devel] [PATCH V2 2/4] add MIPS DSP helpers implement Jia Liu
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Jia Liu @ 2012-03-22 13:36 UTC (permalink / raw)
  To: qemu-devel; +Cc: sw, aurelien

This is the helper define of MIPS ASE DSP.

Signed-off-by: Jia Liu <proljc@gmail.com>
---

Version History:

V2:
- Addressed Stefan's review comments, use "one space after comma" codeing style.

V1:
- add MIPS ASE DSP helper define.

 target-mips/helper.h |  152 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 152 insertions(+), 0 deletions(-)

diff --git a/target-mips/helper.h b/target-mips/helper.h
index 442f684..f814a89 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -297,4 +297,156 @@ DEF_HELPER_0(rdhwr_ccres, tl)
 DEF_HELPER_1(pmon, void, int)
 DEF_HELPER_0(wait, void)
 
+/* MIPS32 DSP */
+DEF_HELPER_1(absqsph, i32, i32)
+DEF_HELPER_1(absqsw, i32, i32)
+DEF_HELPER_2(addqph, i32, i32, i32)
+DEF_HELPER_2(addqsph, i32, i32, i32)
+DEF_HELPER_2(addqsw, i32, i32, i32)
+DEF_HELPER_2(addsc, i32, i32, i32)
+DEF_HELPER_2(addwc, i32, i32, i32)
+DEF_HELPER_1(bitrev, i32, i32)
+DEF_HELPER_2(cmpeqph, void, i32, i32)
+DEF_HELPER_2(cmpltph, void, i32, i32)
+DEF_HELPER_2(cmpleph, void, i32, i32)
+DEF_HELPER_2(cmpgueqqb, i32, i32, i32)
+DEF_HELPER_2(cmpgultqb, i32, i32, i32)
+DEF_HELPER_2(cmpguleqb, i32, i32, i32)
+DEF_HELPER_2(cmpueqqb, void, i32, i32)
+DEF_HELPER_2(cmpultqb, void, i32, i32)
+DEF_HELPER_2(cmpuleqb, void, i32, i32)
+DEF_HELPER_3(dpaqswph, void, int, i32, i32)
+DEF_HELPER_3(dpaqsalw, void, int, i32, i32)
+DEF_HELPER_3(dpauhqbl, void, int, i32, i32)
+DEF_HELPER_3(dpauhqbr, void, int, i32, i32)
+DEF_HELPER_3(dpsqswph, void, int, i32, i32)
+DEF_HELPER_3(dpsqsalw, void, int, i32, i32)
+DEF_HELPER_3(dpsuhqbl, void, int, i32, i32)
+DEF_HELPER_3(dpsuhqbr, void, int, i32, i32)
+DEF_HELPER_3(extp, void, int, int, int)
+DEF_HELPER_3(extpdp, void, int, int, int)
+DEF_HELPER_3(extpdpv, void, int, i32, int)
+DEF_HELPER_3(extpv, void, int, i32, int)
+DEF_HELPER_3(extrsh, void, int, int, int)
+DEF_HELPER_3(extrw, void, int, int, int)
+DEF_HELPER_3(extrrw, void, int, int, int)
+DEF_HELPER_3(extrrsw, void, int, int, int)
+DEF_HELPER_2(extrvsh, i32, int, i32);
+DEF_HELPER_3(extrvw, void, int, i32, int)
+DEF_HELPER_3(extrvrw, void, int, i32, int)
+DEF_HELPER_3(extrvrsw, void, int, i32, int)
+DEF_HELPER_3(insv, void, int, i32, i32)
+DEF_HELPER_2(lbux, tl, tl, int)
+DEF_HELPER_2(lhx, i32, i32, int)
+DEF_HELPER_2(lwx, i32, i32, int)
+DEF_HELPER_3(maqswphl, void, int, i32, i32)
+DEF_HELPER_3(maqsawphl, void, int, i32, i32)
+DEF_HELPER_3(maqswphr, void, int, i32, i32)
+DEF_HELPER_3(maqsawphr, void, int, i32, i32)
+DEF_HELPER_2(modsub, i32, i32, i32)
+DEF_HELPER_2(mthlip, void, int, i32)
+DEF_HELPER_2(muleqswphl, i32, i32, i32)
+DEF_HELPER_2(muleqswphr, i32, i32, i32)
+DEF_HELPER_2(muleusphqbl, i32, i32, i32)
+DEF_HELPER_2(muleusphqbr, i32, i32, i32)
+DEF_HELPER_2(mulqrsph, i32, i32, i32)
+DEF_HELPER_3(mulsaqswph, void, int, i32, i32)
+DEF_HELPER_2(packrlph, i32, i32, i32)
+DEF_HELPER_2(pickqb, i32, i32, i32)
+DEF_HELPER_1(preceqwphl, i32, i32)
+DEF_HELPER_2(pickph, i32, i32, i32)
+DEF_HELPER_1(preceqwphr, i32, i32)
+DEF_HELPER_1(precequphqbl, i32, i32)
+DEF_HELPER_1(precequphqbla, i32, i32)
+DEF_HELPER_1(precequphqbr, i32, i32)
+DEF_HELPER_1(precequphqbra, i32, i32)
+DEF_HELPER_1(preceuphqbl, i32, i32)
+DEF_HELPER_1(preceuphqbla, i32, i32)
+DEF_HELPER_1(preceuphqbr, i32, i32)
+DEF_HELPER_1(preceuphqbra, i32, i32)
+DEF_HELPER_2(precrqqbph, i32, i32, i32)
+DEF_HELPER_2(precrqphw, i32, i32, i32)
+DEF_HELPER_2(precrqrsphw, i32, i32, i32)
+DEF_HELPER_2(precrqusqbph, i32, i32, i32)
+DEF_HELPER_1(radduwqb, i32, i32)
+DEF_HELPER_1(rddsp, i32, i32)
+DEF_HELPER_1(replph, i32, i32)
+DEF_HELPER_1(replqb, i32, i32)
+DEF_HELPER_1(replvph, i32, i32)
+DEF_HELPER_1(replvqb, i32, i32)
+DEF_HELPER_2(shilo, void, int, int)
+DEF_HELPER_2(shilov, void, int, i32)
+DEF_HELPER_2(shllph, i32, int, i32)
+DEF_HELPER_2(shllsph, i32, int, i32)
+DEF_HELPER_2(shllqb, i32, int, i32)
+DEF_HELPER_2(shllsw, i32, int, i32)
+DEF_HELPER_2(shllvph, i32, i32, i32)
+DEF_HELPER_2(shllvsph, i32, i32, i32)
+DEF_HELPER_2(shllvqb, i32, i32, i32)
+DEF_HELPER_2(shllvsw, i32, i32, i32)
+DEF_HELPER_2(shraph, i32, int, i32)
+DEF_HELPER_2(shrarph, i32, int, i32)
+DEF_HELPER_2(shrarw, i32, int, i32)
+DEF_HELPER_2(shravph, i32, i32, i32)
+DEF_HELPER_2(shravrph, i32, i32, i32)
+DEF_HELPER_2(shravrw, i32, i32, i32)
+DEF_HELPER_2(shrlqb, i32, int, i32)
+DEF_HELPER_2(shrlvqb, i32, i32, i32)
+DEF_HELPER_2(subqph, i32, i32, i32)
+DEF_HELPER_2(subqsph, i32, i32, i32)
+DEF_HELPER_2(subqsw, i32, i32, i32)
+DEF_HELPER_2(subuqb, i32, i32, i32)
+DEF_HELPER_2(subusqb, i32, i32, i32)
+DEF_HELPER_2(wrdsp, void, i32, int)
+
+/* MIPS32 DSPR2 */
+DEF_HELPER_1(absqsqb, i32, i32)
+DEF_HELPER_2(addqhph, i32, i32, i32)
+DEF_HELPER_2(addqhrph, i32, i32, i32)
+DEF_HELPER_2(addqhw, i32, i32, i32)
+DEF_HELPER_2(addqhrw, i32, i32, i32)
+DEF_HELPER_2(adduhqb, i32, i32, i32)
+DEF_HELPER_2(adduhrqb, i32, i32, i32)
+DEF_HELPER_2(adduph, i32, i32, i32)
+DEF_HELPER_2(addusph, i32, i32, i32)
+DEF_HELPER_2(adduqb, i32, i32, i32)
+DEF_HELPER_2(addusqb, i32, i32, i32)
+DEF_HELPER_3(append, i32, i32, i32, int)
+DEF_HELPER_3(balign, i32, i32, i32, i32)
+DEF_HELPER_2(cmpgdueqqb, i32, i32, i32)
+DEF_HELPER_2(cmpgdultqb, i32, i32, i32)
+DEF_HELPER_2(cmpgduleqb, i32, i32, i32)
+DEF_HELPER_3(dpawph, void, int, i32, i32)
+DEF_HELPER_3(dpaqxswph, void, int, i32, i32)
+DEF_HELPER_3(dpaqxsawph, void, int, i32, i32)
+DEF_HELPER_3(dpaxwph, void, int, i32, i32)
+DEF_HELPER_3(dpswph, void, int, i32, i32)
+DEF_HELPER_3(dpsqxswph, void, int, i32, i32)
+DEF_HELPER_3(dpsqxsawph, void, int, i32, i32)
+DEF_HELPER_3(dpsxwph, void, int, i32, i32)
+DEF_HELPER_2(mulph, i32, i32, i32)
+DEF_HELPER_2(mulsph, i32, i32, i32)
+DEF_HELPER_2(mulqsph, i32, i32, i32)
+DEF_HELPER_2(mulqrsw, i32, i32, i32)
+DEF_HELPER_2(mulqsw, i32, i32, i32)
+DEF_HELPER_3(mulsawph, void, int, i32, i32)
+DEF_HELPER_2(precrqbph, i32, i32, i32)
+DEF_HELPER_3(precrsraphw, i32, int, i32, i32)
+DEF_HELPER_3(precrsrarphw, i32, int, i32, i32)
+DEF_HELPER_3(prepend, i32, int, i32, i32)
+DEF_HELPER_2(shraqb, i32, int, i32)
+DEF_HELPER_2(shrarqb, i32, int, i32)
+DEF_HELPER_2(shravqb, i32, i32, i32)
+DEF_HELPER_2(shravrqb, i32, i32, i32)
+DEF_HELPER_2(shrlph, i32, int, i32)
+DEF_HELPER_2(shrlvph, i32, i32, i32)
+DEF_HELPER_2(subqhph, i32, i32, i32)
+DEF_HELPER_2(subqhrph, i32, i32, i32)
+DEF_HELPER_2(subqhw, i32, i32, i32)
+DEF_HELPER_2(subqhrw, i32, i32, i32)
+DEF_HELPER_2(subuph, i32, i32, i32)
+DEF_HELPER_2(subusph, i32, i32, i32)
+DEF_HELPER_2(subuhqb, i32, i32, i32)
+DEF_HELPER_2(subuhrqb, i32, i32, i32)
+
 #include "def-helper.h"
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH V2 2/4] add MIPS DSP helpers implement
  2012-03-22 13:36 [Qemu-devel] [PATCH V2 0/4] MIPS ASE DSP Support for Qemu Jia Liu
  2012-03-22 13:36 ` [Qemu-devel] [PATCH V2 1/4] add MIPS DSP helpers define Jia Liu
@ 2012-03-22 13:36 ` Jia Liu
  2012-03-22 13:54   ` Peter Maydell
  2012-03-22 13:36 ` [Qemu-devel] [PATCH V2 3/4] add MIPS DSP translation Jia Liu
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Jia Liu @ 2012-03-22 13:36 UTC (permalink / raw)
  To: qemu-devel; +Cc: sw, aurelien

This is the helper implementation of MIPS ASE DSP.

Signed-off-by: Jia Liu <proljc@gmail.com>
---

Version History:

V2:
- Addressed Stefan's review comments, coding style fixed.

V1:
- add MIPS ASE DSP helper implementation.

 target-mips/op_helper.c | 3936 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 3936 insertions(+), 0 deletions(-)

diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 3a20731..cca1b1e 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -3409,3 +3409,3939 @@ FOP_COND_PS(le,  float32_le(fst0, fst1, &env->active_fpu.fp_status),
                  float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
 FOP_COND_PS(ngt, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)    || float32_le(fst0, fst1, &env->active_fpu.fp_status),
                  float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
+
+/* MIPS DSP functions begin */
+static inline void set_DSPControl_overflow_flag(uint32_t flag, int position)
+{
+    env->active_tc.DSPControl |= (target_ulong)flag << position;
+}
+
+static inline void set_DSPControl_carryflag(uint32_t flag)
+{
+    env->active_tc.DSPControl |= (target_ulong)flag << 13;
+}
+
+static inline uint32_t get_DSPControl_carryflag(void)
+{
+    uint32_t flag;
+
+    flag = (env->active_tc.DSPControl >> 13) & 0x01;
+
+    return flag;
+}
+
+static inline void set_DSPControl_24(uint32_t flag, int len)
+{
+    if (len == 2)
+        env->active_tc.DSPControl &= 0xFCFFFFFF;
+    else if (len == 4)
+        env->active_tc.DSPControl &= 0xF0FFFFFF;
+
+    env->active_tc.DSPControl |= (target_ulong)flag << 24;
+}
+
+static inline void set_DSPControl_pos(uint32_t pos)
+{
+    target_ulong dspc;
+
+    dspc = env->active_tc.DSPControl;
+    dspc = dspc & 0xFFFFFFC0;
+    dspc |= pos;
+    env->active_tc.DSPControl = dspc;
+}
+
+static inline uint32_t get_DSPControl_pos(void)
+{
+    target_ulong dspc;
+    uint32_t pos;
+
+    dspc = env->active_tc.DSPControl;
+    pos = dspc & 0x3F;
+
+    return pos;
+}
+
+static inline void set_DSPControl_efi(uint32_t flag)
+{
+    env->active_tc.DSPControl &= 0xFFFFBFFF;
+    env->active_tc.DSPControl |= (target_ulong)flag << 14;
+}
+
+/* get abs value */
+static inline int8_t mipsdsp_sat_abs_u8(uint8_t a)
+{
+    int8_t temp;
+    temp = a;
+
+    if (a == 0x80) {
+        set_DSPControl_overflow_flag(1, 20);
+        temp = 0x7f;
+    } else {
+        if ((a & 0x80) == 0x80)
+            temp = -temp;
+    }
+
+    return temp;
+}
+
+static inline int16_t mipsdsp_sat_abs_u16(uint16_t a)
+{
+    int16_t temp;
+    temp = a;
+
+    if (a == 0x8000) {
+        set_DSPControl_overflow_flag(1, 20);
+        temp = 0x7fff;
+    } else {
+        if ((a & 0x8000) == 0x8000)
+            temp = -temp;
+    }
+
+    return temp;
+}
+
+static inline int32_t mipsdsp_sat_abs_u32(uint32_t a)
+{
+    int32_t temp;
+    temp = a;
+
+    if (a == 0x80000000) {
+        set_DSPControl_overflow_flag(1, 20);
+        temp = 0x7FFFFFFF;
+    } else {
+        if ((a & 0x80000000) == 0x80000000)
+            temp = -temp;
+    }
+
+    return temp;
+}
+
+/* get sum value */
+static inline int16_t mipsdsp_add_i16(int16_t a, int16_t b)
+{
+    int16_t tempS;
+    int32_t tempI, temp15, temp16;
+
+    tempS = a + b;
+    tempI = a + b;
+    temp15 = (tempI & 0x8000) >> 15;
+    temp16 = (tempI & 0x10000) >> 16;
+
+    if (temp15 != temp16)
+        set_DSPControl_overflow_flag(1, 20);
+
+    return tempS;
+}
+
+static inline int16_t mipsdsp_sat_add_i16(int16_t a, int16_t b)
+{
+    int16_t tempS;
+    int32_t tempI, temp15, temp16;
+
+    tempS = a + b;
+    tempI = (int32_t)a + (int32_t)b;
+    temp15 = (tempI & 0x8000) >> 15;
+    temp16 = (tempI & 0x10000) >> 16;
+
+    if (temp15 != temp16) {
+        if (temp16 == 0)
+            tempS = 0x7FFF;
+        else
+            tempS = 0x8000;
+        set_DSPControl_overflow_flag(1, 20);
+    }
+
+    return tempS;
+}
+
+static inline int32_t mipsdsp_sat_add_i32(int32_t a, int32_t b)
+{
+    int32_t tempI;
+    int64_t tempL, temp31, temp32;
+
+    tempI = a + b;
+    tempL = (int64_t)a + (int64_t)b;
+    temp31 = (tempL & 0x80000000) >> 31;
+    temp32 = (tempL & 0x100000000) >> 32;
+
+    if (temp31 != temp32) {
+        if (temp32 == 0)
+            tempI = 0x7FFFFFFF;
+        else
+            tempI = 0x80000000;
+        set_DSPControl_overflow_flag(1, 20);
+    }
+
+    return tempI;
+}
+
+static inline uint8_t mipsdsp_add_u8(uint8_t a, uint8_t b)
+{
+    uint8_t  result;
+    uint16_t tempA, tempB, temp;
+
+    tempA = a;
+    tempB = b;
+    temp = tempA + tempB;
+    result = temp & 0xFF;
+
+    if ((temp & 0x0100) == 0x0100)
+        set_DSPControl_overflow_flag(1, 20);
+
+    return result;
+}
+
+static inline uint16_t mipsdsp_add_u16(uint16_t a, uint16_t b)
+{
+    uint16_t result;
+    uint32_t tempA, tempB, temp;
+
+    tempA = a;
+    tempB = b;
+    temp = tempA + tempB;
+    result = temp & 0xFFFF;
+
+    if ((temp & 0x00010000) == 0x00010000)
+        set_DSPControl_overflow_flag(1, 20);
+
+    return result;
+}
+
+static inline uint8_t mipsdsp_sat_add_u8(uint8_t a, uint8_t b)
+{
+    uint8_t  result;
+    uint16_t tempA, tempB, temp;
+
+    tempA = a;
+    tempB = b;
+    temp = tempA + tempB;
+    result = temp & 0xFF;
+
+    if ((0x0100 & temp) == 0x0100) {
+        result = 0xFF;
+        set_DSPControl_overflow_flag(1, 20);
+    }
+
+    return result;
+}
+
+static inline uint16_t mipsdsp_sat_add_u16(uint16_t a, uint16_t b)
+{
+    uint16_t result;
+    uint32_t tempA, tempB, temp;
+
+    tempA = a;
+    tempB = b;
+    temp = tempA + tempB;
+    result = temp & 0xFFFF;
+
+    if ((0x00010000 & temp) == 0x00010000) {
+        result = 0xFFFF;
+        set_DSPControl_overflow_flag(1, 20);
+    }
+
+    return result;
+}
+
+static inline int32_t mipsdsp_sat32_acc_q31(int32_t acc, int32_t a)
+{
+    int64_t tempA, temp;
+    int32_t temp32, temp31, result;
+
+    temp = ((int64_t)env->active_tc.HI[acc] << 32) | \
+           ((int64_t)env->active_tc.LO[acc] & 0x00000000FFFFFFFF);
+    tempA = a;
+    temp += tempA;
+    temp32 = (temp >> 32) & 0x01;
+    temp31 = (temp >> 31) & 0x01;
+    result = temp & 0xFFFFFFFF;
+
+    if (temp32 != temp31) {
+        if (temp32 == 0)
+            result = 0x80000000;
+        else
+            result = 0x7FFFFFFF;
+        set_DSPControl_overflow_flag(1, 16 + acc);
+    }
+
+    return result;
+}
+
+static inline int32_t mipsdsp_mul_i16_i16(int16_t a, int16_t b)
+{
+    int32_t temp, tempA, tempB;
+
+    tempA = a;
+    tempB = b;
+    temp = tempA * tempB;
+
+    if ((temp > 0x7FFF) || (temp < 0xFFFF8000))
+        set_DSPControl_overflow_flag(1, 21);
+    temp &= 0x0000FFFF;
+
+    return temp;
+}
+
+static inline int32_t mipsdsp_sat16_mul_i16_i16(int16_t a, int16_t b)
+{
+    int32_t temp, tempA, tempB;
+
+    tempA = a;
+    tempB = b;
+    temp = tempA * tempB;
+
+    if (temp > 0x7FFF) {
+        temp = 0x00007FFF;
+        set_DSPControl_overflow_flag(1, 21);
+    } else if (temp < 0x00007FFF) {
+        temp = 0xFFFF8000;
+        set_DSPControl_overflow_flag(1, 21);
+    }
+    temp &= 0x0000FFFF;
+
+    return temp;
+}
+
+static inline int32_t mipsdsp_mul_q15_q15_overflowflag21(uint16_t a, uint16_t b)
+{
+    int16_t tempA, tempB;
+    int32_t temp;
+
+    tempA = a;
+    tempB = b;
+
+    if ((a == 0x8000) && (b == 0x8000)) {
+        temp = 0x7FFFFFFF;
+        set_DSPControl_overflow_flag(1, 21);
+    } else
+        temp = ((int32_t)tempA * (int32_t)tempB) << 1;
+
+    return temp;
+}
+
+/* right shift */
+static inline int16_t mipsdsp_rshift1_add_q16(int16_t a, int16_t b)
+{
+    int32_t temp, tempA, tempB;
+    int16_t result;
+
+    tempA = a;
+    tempB = b;
+    temp = tempA + tempB;
+    result = (temp >> 1) & 0xFFFF;
+
+    return result;
+}
+
+/* round right shift */
+static inline int16_t mipsdsp_rrshift1_add_q16(int16_t a, int16_t b)
+{
+    int32_t temp, tempA, tempB;
+    int16_t result;
+
+    tempA = a;
+    tempB = b;
+    temp = tempA + tempB;
+    temp += 1;
+    result = (temp >> 1) & 0xFFFF;
+
+    return result;
+}
+
+static inline int32_t mipsdsp_rshift1_add_q32(int32_t a, int32_t b)
+{
+    int64_t temp, tempA, tempB;
+    int32_t result;
+
+    tempA = a;
+    tempB = b;
+    temp = tempA + tempB;
+    result = (temp >> 1) & 0xFFFFFFFF;
+
+    return result;
+}
+
+static inline int32_t mipsdsp_rrshift1_add_q32(int32_t a, int32_t b)
+{
+    int64_t temp, tempA, tempB;
+    int32_t result;
+    tempA = a;
+    tempB = b;
+
+    temp = tempA + tempB;
+    temp += 1;
+    result = (temp >> 1) & 0xFFFFFFFF;
+
+    return result;
+}
+
+static inline uint8_t mipsdsp_rshift1_add_u8(uint8_t a, uint8_t b)
+{
+    uint16_t tempA, tempB, temp;
+    uint8_t  result;
+
+    tempA = a;
+    tempB = b;
+    temp = tempA + tempB;
+    result = (temp >> 1) & 0x00FF;
+
+    return result;
+}
+
+static inline uint8_t mipsdsp_rrshift1_add_u8(uint8_t a, uint8_t b)
+{
+    uint16_t tempA, tempB, temp;
+    uint8_t  result;
+
+    tempA = a;
+    tempB = b;
+    temp = tempA + tempB + 1;
+    result = (temp >> 1) & 0x00FF;
+
+    return result;
+}
+
+static inline int64_t mipsdsp_rashift_short_acc(int32_t ac,
+                                                int32_t shift)
+{
+    int32_t sign, temp31;
+    int64_t temp, acc;
+
+    sign = (env->active_tc.HI[ac] >> 31) & 0x01;
+    acc = ((int64_t)env->active_tc.HI[ac] << 32) | \
+          ((int64_t)env->active_tc.LO[ac] & 0xFFFFFFFF);
+    if (shift == 0)
+        temp = acc;
+    else {
+        if (sign == 0)
+            temp = (((int64_t)0x01 << (32 - shift + 1)) - 1) & (acc >> shift);
+        else
+            temp = ((((int64_t)0x01 << (shift + 1)) - 1) << (32 - shift)) | \
+                   (acc >> shift);
+    }
+
+    temp31 = (temp >> 31) & 0x01;
+    if (sign != temp31)
+        set_DSPControl_overflow_flag(1, 23);
+
+    return temp;
+}
+
+/*  128 bits long. p[0] is LO, p[1] is HI. */
+static inline void mipsdsp__rashift_short_acc(int64_t *p,
+                                              int32_t ac,
+                                              int32_t shift)
+{
+    int64_t acc;
+
+    acc = ((int64_t)env->active_tc.HI[ac] << 32) | \
+          ((int64_t)env->active_tc.LO[ac] & 0xFFFFFFFF);
+    if (shift == 0) {
+        p[0] = acc << 1;
+        p[1] = (acc >> 63) & 0x01;
+    } else {
+        p[0] = acc >> (shift - 1);
+        p[1] = 0;
+    }
+}
+
+static inline int32_t mipsdsp_mul_q15_q15(int32_t ac, uint16_t a, uint16_t b)
+{
+    uint16_t tempA, tempB;
+    int32_t temp;
+
+    tempA = a;
+    tempB = b;
+
+    if ((a == 0x8000) && (b == 0x8000)) {
+        temp = 0x7FFFFFFF;
+        set_DSPControl_overflow_flag(1, 16 + ac);
+    } else
+        temp = ((uint32_t)tempA * (uint32_t)tempB) << 1;
+
+    return temp;
+}
+
+static inline int64_t mipsdsp_mul_q31_q31(int32_t ac, uint32_t a, uint32_t b)
+{
+    uint32_t tempA, tempB;
+    uint64_t temp;
+
+    tempA = a;
+    tempB = b;
+
+    if ((a == 0x80000000) && (b == 0x80000000)) {
+        temp = 0x7FFFFFFFFFFFFFFF;
+        set_DSPControl_overflow_flag(1, 16 + ac);
+    } else
+        temp = ((uint64_t)tempA * (uint64_t)tempB) << 1;
+
+    return temp;
+}
+
+static inline uint16_t mipsdsp_mul_u8_u8(uint8_t a, uint8_t b)
+{
+    uint16_t temp;
+    temp = (uint16_t)a * (uint16_t)b;
+
+    return temp;
+}
+
+static inline uint16_t mipsdsp_mul_u8_u16(uint8_t a, uint16_t b)
+{
+    uint16_t tempS;
+    uint32_t tempI, tempA, tempB;
+
+    tempA = a;
+    tempB = b;
+    tempI = tempA * tempB;
+    if (tempI > 0x00) {
+        tempI = 0x0000FFFF;
+        set_DSPControl_overflow_flag(1, 21);
+    }
+    tempS = tempI & 0x0000FFFF;
+    return tempS;
+}
+
+static inline int16_t mipsdsp_rndq15_mul_q15_q15(uint16_t a, uint16_t b)
+{
+    int16_t result, tempA, tempB;
+    int32_t temp;
+
+    tempA = a;
+    tempB = b;
+
+    if ((a == 0x8000) && (b == 0x8000)) {
+        temp = 0x7FFF0000;
+        set_DSPControl_overflow_flag(1, 21);
+    } else {
+        temp = ((int32_t)tempA * (int32_t)tempB) << 1;
+        temp = temp + 0x00008000;
+    }
+    result = (temp & 0xFFFF0000) >> 16;
+
+    return result;
+}
+
+static inline int32_t mipsdsp_sat16_mul_q15_q15(uint16_t a, uint16_t b)
+{
+    int16_t tempA, tempB;
+    int32_t temp;
+
+    tempA = a;
+    tempB = b;
+
+    if ((a == 0x8000) && (b == 0x8000)) {
+        temp = 0x7FFF0000;
+        set_DSPControl_overflow_flag(1, 21);
+    } else {
+        temp = ((uint32_t)tempA * (uint32_t)tempB);
+        temp = temp << 1;
+    }
+    temp = (temp >> 16) & 0x0000FFFF;
+
+    return temp;
+}
+
+static inline uint16_t mipsdsp_trunc16_sat16_round(uint32_t a)
+{
+    uint16_t result;
+    uint32_t temp32, temp31;
+    int64_t temp;
+
+    temp = (int32_t)a + 0x00008000;
+    temp32 = (temp >> 32) & 0x01;
+    temp31 = (temp >> 31) & 0x01;
+
+    if (temp32 != temp31) {
+        temp = 0x7FFFFFFF;
+        set_DSPControl_overflow_flag(1, 22);
+    }
+    result = (temp >> 16) & 0xFFFF;
+
+    return result;
+}
+
+static inline uint8_t mipsdsp_sat8_reduce_precision(uint16_t a)
+{
+    uint8_t  result;
+    uint16_t mag;
+    uint32_t sign;
+
+    sign = (a >> 15) & 0x01;
+    mag = a & 0x7FFF;
+
+    if (sign == 0) {
+        if (mag > 0x7F80) {
+            result = 0xFF;
+            set_DSPControl_overflow_flag(1, 22);
+        } else
+            result = (mag >> 7) & 0xFFFF;
+    } else {
+        result = 0x00;
+        set_DSPControl_overflow_flag(1, 22);
+    }
+
+    return result;
+}
+
+static inline uint8_t mipsdsp_lshift8(uint8_t a, uint8_t s)
+{
+    uint8_t sign;
+    uint8_t temp, discard;
+
+    if (s == 0)
+        temp = a;
+    else {
+        sign = (a >> 7) & 0x01;
+        temp = a << s;
+        if (sign != 0)
+            discard = (((0x01 << (8 - s)) - 1) << s) | \
+                      ((a >> (6 - (s - 1))) & ((0x01 << s) - 1));
+        else
+            discard = a >> (6 - (s - 1));
+
+        if (discard != 0x00)
+            set_DSPControl_overflow_flag(1, 22);
+    }
+
+    return temp;
+}
+
+static inline uint8_t mipsdsp_rshift8(uint8_t a, uint8_t s)
+{
+    uint8_t temp;
+    if (s == 0)
+        temp = a;
+    else
+        temp = a >> s;
+    return temp;
+}
+
+static inline uint16_t mipsdsp_lshift16(uint16_t a, uint8_t s)
+{
+    uint8_t  sign;
+    uint16_t temp, discard;
+
+    if (s == 0)
+        temp = a;
+    else {
+        sign = (a >> 15) & 0x01;
+        temp = a << s;
+        if (sign != 0)
+            discard = (((0x01 << (16 - s)) - 1) << s) | \
+                      ((a >> (14 - (s - 1))) & ((0x01 << s) - 1));
+        else
+            discard = a >> (14 - (s - 1));
+
+        if ((discard != 0x0000) && (discard != 0xFFFF))
+            set_DSPControl_overflow_flag(1, 22);
+    }
+
+    return temp;
+}
+
+static inline uint16_t mipsdsp_sat16_lshift(uint16_t a, uint8_t s)
+{
+    uint8_t  sign;
+    uint16_t temp, discard;
+
+    if (s == 0)
+        temp = a;
+    else {
+        sign = (a >> 15) & 0x01;
+        temp = a << s;
+        if (sign != 0)
+            discard = (((0x01 << (16 - s)) - 1) << s) | \
+                      ((a >> (14 - (s - 1))) & ((0x01 << s) - 1));
+        else
+            discard = a >> (14 - (s - 1));
+        if ((discard != 0x0000) && (discard != 0xFFFF)) {
+            temp = (sign == 0) ? 0x7FFF : 0x8000;
+            set_DSPControl_overflow_flag(1, 22);
+        }
+    }
+
+    return temp;
+}
+
+static inline uint32_t mipsdsp_sat32_lshift(uint32_t a, uint8_t s)
+{
+    uint8_t  sign;
+    uint32_t temp, discard;
+
+    if (s == 0)
+        temp = a;
+    else {
+        sign = (a >> 31) & 0x01;
+        temp = a << s;
+        if (sign != 0)
+            discard = (((0x01 << (32 - s)) - 1) << s) | \
+                      ((a >> (30 - (s - 1))) & ((0x01 << s) - 1));
+        else
+            discard = a >> (30 - (s - 1));
+        if ((discard != 0x00000000) && (discard != 0xFFFFFFFF)) {
+            temp = (sign == 0) ? 0x7FFFFFFF : 0x80000000;
+            set_DSPControl_overflow_flag(1, 22);
+        }
+    }
+
+    return temp;
+}
+
+static inline uint16_t mipsdsp_rashift16(uint16_t a, uint8_t s)
+{
+    int16_t i, temp;
+
+    i = a;
+    if (s == 0)
+        temp = a;
+    else
+        temp = i >> s;
+
+    return temp;
+}
+
+static inline uint16_t mipsdsp_rnd16_rashift(uint16_t a, uint8_t s)
+{
+    int16_t  i, result;
+    uint32_t temp;
+
+    i = a;
+    if (s == 0)
+        temp = (uint32_t)a << 1;
+    else
+        temp = (int32_t)i >> (s - 1);
+    temp   = temp + 1;
+    result = temp >> 1;
+
+    return result;
+}
+
+static inline uint32_t mipsdsp_rnd32_rashift(uint32_t a, uint8_t s)
+{
+    int32_t i;
+    int64_t temp;
+    uint32_t result;
+
+    i = a;
+    if (s == 0)
+        temp = a << 1;
+    else
+        temp = (int64_t)i >> (s - 1);
+    temp += 1;
+    result = (temp >> 1) & 0x00000000FFFFFFFF;
+
+    return result;
+}
+
+static inline uint16_t mipsdsp_sub_i16(int16_t a, int16_t b)
+{
+    uint8_t  temp16, temp15;
+    uint16_t result;
+    int32_t  temp;
+
+    temp = (int32_t)a - (int32_t)b;
+    temp16 = (temp >> 16) & 0x01;
+    temp15 = (temp >> 15) & 0x01;
+    if (temp16 != temp15)
+        set_DSPControl_overflow_flag(1, 20);
+    result = temp & 0x0000FFFF;
+
+    return result;
+}
+
+static inline uint16_t mipsdsp_sat16_sub(int16_t a, int16_t b)
+{
+    uint8_t  temp16, temp15;
+    uint16_t result;
+    int32_t  temp;
+
+    temp = (int32_t)a - (int32_t)b;
+    temp16 = (temp >> 16) & 0x01;
+    temp15 = (temp >> 15) & 0x01;
+    if (temp16 != temp15) {
+        if (temp16 == 0)
+            temp = 0x7FFF;
+        else
+            temp = 0x8000;
+        set_DSPControl_overflow_flag(1, 20);
+    }
+    result = temp & 0x0000FFFF;
+
+    return result;
+}
+
+static inline uint32_t mipsdsp_sat32_sub(int32_t a, int32_t b)
+{
+    uint8_t  temp32, temp31;
+    uint32_t result;
+    int64_t  temp;
+
+    temp = (int64_t)a - (int64_t)b;
+    temp32 = (temp >> 32) & 0x01;
+    temp31 = (temp >> 31) & 0x01;
+    if (temp32 != temp31) {
+        if (temp32 == 0)
+            temp = 0x7FFFFFFF;
+        else
+            temp = 0x80000000;
+        set_DSPControl_overflow_flag(1, 20);
+    }
+    result = temp & 0x00000000FFFFFFFF;
+
+    return result;
+}
+
+static inline uint16_t mipsdsp_rshift1_sub_q16(int16_t a, int16_t b)
+{
+    int32_t  temp;
+    uint16_t result;
+
+    temp = (int32_t)a - (int32_t)b;
+    result = (temp >> 1) & 0x0000FFFF;
+
+    return result;
+}
+
+static inline uint16_t mipsdsp_rrshift1_sub_q16(int16_t a, int16_t b)
+{
+    int32_t  temp;
+    uint16_t result;
+
+    temp = (int32_t)a - (int32_t)b;
+    temp += 1;
+    result = (temp >> 1) & 0x0000FFFF;
+
+    return result;
+}
+
+static inline uint32_t mipsdsp_rshift1_sub_q32(int32_t a, int32_t b)
+{
+    int64_t  temp;
+    uint32_t result;
+
+    temp   = (int64_t)a - (int64_t)b;
+    result = (temp >> 1) & 0x00000000FFFFFFFF;
+
+    return result;
+}
+
+static inline uint32_t mipsdsp_rrshift1_sub_q32(int32_t a, int32_t b)
+{
+    int64_t  temp;
+    uint32_t result;
+
+    temp = (int64_t)a - (int64_t)b;
+    temp += 1;
+    result = (temp >> 1) & 0x00000000FFFFFFFF;
+
+    return result;
+}
+
+static inline uint16_t mipsdsp_sub_u16_u16(uint16_t a, uint16_t b)
+{
+    uint8_t  temp16;
+    uint16_t result;
+    uint32_t temp;
+
+    temp = (uint32_t)a - (uint32_t)b;
+    temp16 = (temp >> 16) & 0x01;
+    if (temp16 == 1)
+        set_DSPControl_overflow_flag(1, 20);
+    result = temp & 0x0000FFFF;
+    return result;
+}
+
+static inline uint16_t mipsdsp_satu16_sub_u16_u16(uint16_t a, uint16_t b)
+{
+    uint8_t  temp16;
+    uint16_t result;
+    uint32_t temp;
+
+    temp   = (uint32_t)a - (uint32_t)b;
+    temp16 = (temp >> 16) & 0x01;
+
+    if (temp16 == 1) {
+        temp = 0x0000;
+        set_DSPControl_overflow_flag(1, 20);
+    }
+    result = temp & 0x0000FFFF;
+
+    return result;
+}
+
+static inline uint8_t mipsdsp_sub_u8(uint8_t a, uint8_t b)
+{
+    uint8_t  result, temp8;
+    uint16_t temp;
+
+    temp = (uint16_t)a - (uint16_t)b;
+    temp8 = (temp >> 8) & 0x01;
+    if (temp8 == 0)
+        set_DSPControl_overflow_flag(1, 20);
+    result = temp & 0x00FF;
+
+    return result;
+}
+
+static inline uint8_t mipsdsp_satu8_sub(uint8_t a, uint8_t b)
+{
+    uint8_t  result, temp8;
+    uint16_t temp;
+
+    temp = (uint16_t)a - (uint16_t)b;
+    temp8 = (temp >> 8) & 0x01;
+    if (temp8 == 1) {
+        temp = 0x00;
+        set_DSPControl_overflow_flag(1, 20);
+    }
+    result = temp & 0x00FF;
+
+    return result;
+}
+/* MIPS DSP functions end */
+
+#define MIPSDSP_LHI 0xFFFFFFFF00000000
+#define MIPSDSP_LLO 0x00000000FFFFFFFF
+#define MIPSDSP_HI  0xFFFF0000
+#define MIPSDSP_LO  0x0000FFFF
+#define MIPSDSP_Q3  0xFF000000
+#define MIPSDSP_Q2  0x00FF0000
+#define MIPSDSP_Q1  0x0000FF00
+#define MIPSDSP_Q0  0x000000FF
+
+/* MIPS DSP */
+uint32_t helper_absqsph(uint32_t rt)
+{
+    uint32_t rd;
+    int16_t tempA, tempB;
+
+    tempA = (rt & MIPSDSP_HI) >> 16;
+    tempB =  rt & MIPSDSP_LO;
+
+    rd = ((uint32_t)mipsdsp_sat_abs_u16 (tempA) << 16) | \
+         ((uint32_t)(mipsdsp_sat_abs_u16 (tempB)) & 0xFFFF);
+
+    return rd;
+}
+
+uint32_t helper_absqsw(uint32_t rt)
+{
+    uint32_t rd;
+    int32_t temp;
+
+    temp = rt;
+    rd = mipsdsp_sat_abs_u32(temp);
+
+    return rd;
+}
+
+uint32_t helper_addqph(uint32_t rs, uint32_t rt)
+{
+    int16_t  rsh, rsl, rth, rtl, temph, templ;
+    uint32_t rd;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+
+    temph = mipsdsp_add_i16(rsh, rth);
+    templ = mipsdsp_add_i16(rsl, rtl);
+    rd = ((unsigned int)temph << 16) | ((unsigned int)templ & 0xFFFF);
+
+    return rd;
+}
+
+uint32_t helper_addqsph(uint32_t rs, uint32_t rt)
+{
+    int16_t rsh, rsl, rth, rtl, temph, templ;
+    uint32_t rd;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+
+    temph = mipsdsp_sat_add_i16(rsh, rth);
+    templ = mipsdsp_sat_add_i16(rsl, rtl);
+    rd = ((uint32_t)temph << 16) | ((uint32_t)templ & 0xFFFF);
+
+    return rd;
+}
+
+uint32_t helper_addqsw(uint32_t rs, uint32_t rt)
+{
+    uint32_t rd;
+    rd = mipsdsp_sat_add_i32(rs, rt);
+    return rd;
+}
+
+uint32_t helper_addsc(uint32_t rs, uint32_t rt)
+{
+    uint32_t rd;
+    uint64_t temp, tempRs, tempRt;
+    int32_t flag;
+
+    tempRs = (uint64_t)rs & MIPSDSP_LLO;
+    tempRt = (uint64_t)rt & MIPSDSP_LLO;
+
+    temp = tempRs + tempRt;
+    flag = (temp & 0x0100000000) >> 32;
+    set_DSPControl_carryflag(flag);
+    rd = temp & MIPSDSP_LLO;
+
+    return rd;
+}
+
+uint32_t helper_addwc(uint32_t rs, uint32_t rt)
+{
+    uint32_t rd;
+    int32_t temp32, temp31;
+    int64_t rsL, rtL, tempL;
+
+    rsL = (int32_t)rs;
+    rtL = (int32_t)rt;
+    tempL = rsL + rtL + get_DSPControl_carryflag();
+    temp31 = (tempL >> 31) & 0x01;
+    temp32 = (tempL >> 32) & 0x01;
+
+    if (temp31 != temp32)
+        set_DSPControl_overflow_flag(1, 20);
+
+    rd = tempL & MIPSDSP_LLO;
+
+    return rd;
+}
+
+uint32_t helper_bitrev(uint32_t rt)
+{
+    int32_t temp;
+    uint32_t rd;
+
+    temp = rt & MIPSDSP_LO;
+    rd = temp;
+
+    return rd;
+}
+
+void helper_cmpeqph(uint32_t rs, uint32_t rt)
+{
+    int16_t rsh, rsl, rth, rtl;
+    int32_t flag;
+    int32_t ccA = 0, ccB = 0;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+
+    if (rsh == rth)
+        ccB = 1;
+    if (rsl == rtl)
+        ccA = 1;
+    flag = (ccB << 1) | ccA;
+    set_DSPControl_24(flag, 2);
+}
+
+void helper_cmpltph(uint32_t rs, uint32_t rt)
+{
+    int16_t rsh, rsl, rth, rtl;
+    int32_t flag;
+    int32_t ccA = 0, ccB = 0;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+
+    if (rsh < rth)
+        ccB = 1;
+
+    if (rsl < rtl)
+        ccA = 1;
+
+    flag = (ccB << 1) | ccA;
+    set_DSPControl_24(flag, 2);
+}
+
+void helper_cmpleph(uint32_t rs, uint32_t rt)
+{
+    int16_t rsh, rsl, rth, rtl;
+    int32_t flag;
+    int32_t ccA = 0, ccB = 0;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+
+    if (rsh <= rth)
+        ccB = 1;
+
+    if (rsl <= rtl)
+        ccA = 1;
+
+    flag = (ccB << 1) | ccA;
+    set_DSPControl_24(flag, 2);
+}
+
+uint32_t helper_cmpgueqqb(uint32_t rs, uint32_t rt)
+{
+    uint8_t rs3, rs2, rs1, rs0;
+    uint8_t rt3, rt2, rt1, rt0;
+    uint8_t cc3 = 0, cc2 = 0, cc1 = 0, cc0 = 0;
+    uint32_t temp;
+    uint32_t rd;
+
+    rs3 = (rs & MIPSDSP_Q3) >> 24;
+    rs2 = (rs & MIPSDSP_Q2) >> 16;
+    rs1 = (rs & MIPSDSP_Q1) >> 8;
+    rs0 =  rs & MIPSDSP_Q0;
+
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    rt1 = (rt & MIPSDSP_Q1) >> 8;
+    rt0 =  rt & MIPSDSP_Q0;
+
+    if (rs3 == rt3)
+        cc3 = 1;
+
+    if (rs2 == rt2)
+        cc2 = 1;
+
+    if (rs1 == rt1)
+        cc1 = 1;
+
+    if (rs0 == rt0)
+        cc0 = 1;
+
+    temp = (cc3 << 3) | (cc2 << 2) | (cc1 << 1) | cc0;
+    rd = temp;
+
+    return rd;
+}
+
+uint32_t helper_cmpgultqb(uint32_t rs, uint32_t rt)
+{
+    uint8_t rs3, rs2, rs1, rs0;
+    uint8_t rt3, rt2, rt1, rt0;
+    uint32_t cc3 = 0, cc2 = 0, cc1 = 0, cc0 = 0;
+    uint32_t temp;
+    uint32_t rd;
+
+    rs3 = (rs & MIPSDSP_Q3) >> 24;
+    rs2 = (rs & MIPSDSP_Q2) >> 16;
+    rs1 = (rs & MIPSDSP_Q1) >> 8;
+    rs0 =  rs & MIPSDSP_Q0;
+
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    rt1 = (rt & MIPSDSP_Q1) >> 8;
+    rt0 =  rt & MIPSDSP_Q0;
+
+    if (rs3 < rt3)
+        cc3 = 1;
+
+    if (rs2 < rt2)
+        cc2 = 1;
+
+    if (rs1 < rt1)
+        cc1 = 1;
+
+    if (rs0 < rt0)
+        cc0 = 1;
+
+    temp = (cc3 << 3) | (cc2 << 2) | (cc1 << 1) | cc0;
+    rd = temp;
+
+    return rd;
+}
+
+uint32_t helper_cmpguleqb(uint32_t rs, uint32_t rt)
+{
+    uint8_t rs3, rs2, rs1, rs0;
+    uint8_t rt3, rt2, rt1, rt0;
+    uint32_t cc3 = 0, cc2 = 0, cc1 = 0, cc0 = 0;
+    uint32_t temp;
+    uint32_t rd;
+
+    rs3 = (rs & MIPSDSP_Q3) >> 24;
+    rs2 = (rs & MIPSDSP_Q2) >> 16;
+    rs1 = (rs & MIPSDSP_Q1) >> 8;
+    rs0 =  rs & MIPSDSP_Q0;
+
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    rt1 = (rt & MIPSDSP_Q1) >> 8;
+    rt0 =  rt & MIPSDSP_Q0;
+
+    if (rs3 <= rt3)
+        cc3 = 1;
+
+    if (rs2 <= rt2)
+        cc2 = 1;
+
+    if (rs1 <= rt1)
+        cc1 = 1;
+
+    if (rs0 <= rt0)
+        cc0 = 1;
+
+    temp = (cc3 << 3) | (cc2 << 2) | (cc1 << 1) | cc0;
+    rd = temp;
+
+    return rd;
+}
+
+void helper_cmpueqqb(uint32_t rs, uint32_t rt)
+{
+    uint8_t rs3, rs2, rs1, rs0;
+    uint8_t rt3, rt2, rt1, rt0;
+    uint32_t cc3 = 0, cc2 = 0, cc1 = 0, cc0 = 0;
+    uint32_t flag;
+
+    rs3 = (rs & MIPSDSP_Q3) >> 24;
+    rs2 = (rs & MIPSDSP_Q2) >> 16;
+    rs1 = (rs & MIPSDSP_Q1) >> 8;
+    rs0 =  rs & MIPSDSP_Q0;
+
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    rt1 = (rt & MIPSDSP_Q1) >> 8;
+    rt0 =  rt & MIPSDSP_Q0;
+
+    if (rs3 == rt3)
+        cc3 = 1;
+
+    if (rs2 == rt2)
+        cc2 = 1;
+
+    if (rs1 == rt1)
+        cc1 = 1;
+
+    if (rs0 == rt0)
+        cc0 = 1;
+
+    flag = (cc3 << 3) | (cc2 << 2) | (cc1 << 1) | cc0;
+    set_DSPControl_24(flag, 4);
+}
+
+void helper_cmpultqb(uint32_t rs, uint32_t rt)
+{
+    uint8_t rs3, rs2, rs1, rs0;
+    uint8_t rt3, rt2, rt1, rt0;
+    uint32_t cc3 = 0, cc2 = 0, cc1 = 0, cc0 = 0;
+    uint32_t flag;
+
+    rs3 = (rs & MIPSDSP_Q3) >> 24;
+    rs2 = (rs & MIPSDSP_Q2) >> 16;
+    rs1 = (rs & MIPSDSP_Q1) >> 8;
+    rs0 =  rs & MIPSDSP_Q0;
+
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    rt1 = (rt & MIPSDSP_Q1) >> 8;
+    rt0 =  rt & MIPSDSP_Q0;
+
+    if (rs3 < rt3)
+        cc3 = 1;
+
+    if (rs2 < rt2)
+        cc2 = 1;
+
+    if (rs1 < rt1)
+        cc1 = 1;
+
+    if (rs0 < rt0)
+        cc0 = 1;
+
+    flag = (cc3 << 3) | (cc2 << 2) | (cc1 << 1) | cc0;
+    set_DSPControl_24(flag, 4);
+}
+
+void helper_cmpuleqb(uint32_t rs, uint32_t rt)
+{
+    uint8_t rs3, rs2, rs1, rs0;
+    uint8_t rt3, rt2, rt1, rt0;
+    uint32_t cc3 = 0, cc2 = 0, cc1 = 0, cc0 = 0;
+    uint32_t flag;
+
+    rs3 = (rs & MIPSDSP_Q3) >> 24;
+    rs2 = (rs & MIPSDSP_Q2) >> 16;
+    rs1 = (rs & MIPSDSP_Q1) >> 8;
+    rs0 =  rs & MIPSDSP_Q0;
+
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    rt1 = (rt & MIPSDSP_Q1) >> 8;
+    rt0 =  rt & MIPSDSP_Q0;
+
+    if (rs3 <= rt3)
+        cc3 = 1;
+
+    if (rs2 <= rt2)
+        cc2 = 1;
+
+    if (rs1 <= rt1)
+        cc1 = 1;
+
+    if (rs0 <= rt0)
+        cc0 = 1;
+
+    flag = (cc3 << 3) | (cc2 << 2) | (cc1 << 1) | cc0;
+    set_DSPControl_24(flag, 4);
+}
+
+void helper_dpaqswph(int ac, uint32_t rs, uint32_t rt)
+{
+    int16_t rsh, rsl, rth, rtl;
+    int32_t tempB, tempA;
+    int64_t acc, dotp, tempBL, tempAL;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+
+    tempB = mipsdsp_mul_q15_q15(ac, rsh, rth);
+    tempA = mipsdsp_mul_q15_q15(ac, rsl, rtl);
+    tempBL = tempB;
+    tempAL = tempA;
+    dotp = tempBL + tempAL;
+    acc = ((uint64_t)env->active_tc.HI[ac] << 32) | \
+          ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
+    acc += dotp;
+
+    env->active_tc.HI[ac] = (acc & MIPSDSP_LHI) >> 32;
+    env->active_tc.LO[ac] =  acc & MIPSDSP_LLO;
+}
+
+void helper_dpaqsalw(int ac, uint32_t rs, uint32_t rt)
+{
+    int32_t temp64, temp63, tempacc63, tempdotp63, tempDL63;
+    int64_t dotp, acc;
+    int64_t tempDL[2];
+    uint64_t temp;
+
+    dotp = mipsdsp_mul_q31_q31(ac, rs, rt);
+    acc = ((uint64_t)env->active_tc.HI[ac] << 32) | \
+          ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
+    tempDL[0] = acc + dotp;
+
+    tempacc63  = (acc >> 63) & 0x01;
+    tempdotp63 = (dotp >> 63) & 0x01;
+    tempDL63   = (tempDL[0] >> 63) & 0x01;
+
+    if (((tempacc63 == 1) && (tempdotp63 == 1)) | \
+        (((tempacc63 == 1) || (tempdotp63 == 1)) && tempDL63 == 0))
+        tempDL[1] = 1;
+    else
+        tempDL[1] = 0;
+
+    temp = tempDL[0];
+    temp64 = tempDL[1] & 0x01;
+    temp63 = (tempDL[0] >> 63) & 0x01;
+
+    if (temp64 != temp63) {
+        if (temp64 == 1)
+            temp = 0x8000000000000000;
+        else
+            temp = 0x7FFFFFFFFFFFFFFF;
+
+        set_DSPControl_overflow_flag(1, 16 + ac);
+    }
+
+    env->active_tc.HI[ac] = (temp & MIPSDSP_LHI) >> 32;
+    env->active_tc.LO[ac] =  temp & MIPSDSP_LLO;
+}
+
+void helper_dpauhqbl(int ac, uint32_t rs, uint32_t rt)
+{
+    uint8_t rs3, rs2;
+    uint8_t rt3, rt2;
+    uint16_t tempB, tempA;
+    uint64_t tempC, tempBL, tempAL, dotp;
+
+    rs3 = (rs & MIPSDSP_Q3) >> 24;
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+    rs2 = (rs & MIPSDSP_Q2) >> 16;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    tempB = mipsdsp_mul_u8_u8(rs3, rt3);
+    tempA = mipsdsp_mul_u8_u8(rs2, rt2);
+    tempBL = tempB;
+    tempAL = tempA;
+    dotp = tempBL + tempAL;
+    tempC = (((uint64_t)env->active_tc.HI[ac] << 32) |  \
+             ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO)) + dotp;
+
+    env->active_tc.HI[ac] = (tempC & MIPSDSP_LHI) >> 32;
+    env->active_tc.LO[ac] =  tempC & MIPSDSP_LLO;
+}
+
+void helper_dpauhqbr(int ac, uint32_t rs, uint32_t rt)
+{
+    uint8_t rs1, rs0;
+    uint8_t rt1, rt0;
+    uint16_t tempB, tempA;
+    uint64_t tempC, tempBL, tempAL, dotp;
+
+    rs1 = (rs & MIPSDSP_Q1) >> 8;
+    rt1 = (rt & MIPSDSP_Q1) >> 8;
+    rs0 = (rs & MIPSDSP_Q0);
+    rt0 = (rt & MIPSDSP_Q0);
+    tempB = mipsdsp_mul_u8_u8(rs1, rt1);
+    tempA = mipsdsp_mul_u8_u8(rs0, rt0);
+    tempBL = tempB;
+    tempAL = tempA;
+    dotp = tempBL + tempAL;
+    tempC = (((uint64_t)env->active_tc.HI[ac] << 32) | \
+             ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO)) + dotp;
+
+    env->active_tc.HI[ac] = (tempC & MIPSDSP_LHI) >> 32;
+    env->active_tc.LO[ac] =  tempC & MIPSDSP_LLO;
+}
+
+void helper_dpsqswph(int ac, uint32_t rs, uint32_t rt)
+{
+    int16_t rsh, rsl, rth, rtl;
+    int32_t tempB, tempA;
+    int64_t acc, dotp, tempBL, tempAL;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+
+    tempB = mipsdsp_mul_q15_q15(ac, rsh, rth);
+    tempA = mipsdsp_mul_q15_q15(ac, rsl, rtl);
+    tempBL = tempB;
+    tempAL = tempA;
+    dotp = tempBL + tempAL;
+    acc = ((uint64_t)env->active_tc.HI[ac] << 32) | \
+           ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
+    acc -= dotp;
+
+    env->active_tc.HI[ac] = (acc & MIPSDSP_LHI) >> 32;
+    env->active_tc.LO[ac] =  acc & MIPSDSP_LLO;
+}
+
+void helper_dpsqsalw(int ac, uint32_t rs, uint32_t rt)
+{
+    int32_t temp64, temp63, tempacc63, tempdotp63, tempDL63;
+    int64_t dotp, acc;
+    int64_t tempDL[2];
+    uint64_t temp;
+
+    dotp = mipsdsp_mul_q31_q31(ac, rs, rt);
+    acc = ((uint64_t)env->active_tc.HI[ac] << 32) | \
+          ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
+    tempDL[0] = acc - dotp;
+
+    tempacc63  = (acc >> 63) & 0x01;
+    tempdotp63 = (dotp >> 63) & 0x01;
+    tempDL63   = (tempDL[0] >> 63) & 0x01;
+
+    if (((tempacc63 == 1) && (tempdotp63 == 0)) | \
+        (((tempacc63 == 1) || (tempdotp63 == 0)) && tempDL63 == 0))
+        tempDL[1] = 1;
+    else
+        tempDL[1] = 0;
+
+    temp = tempDL[0];
+    temp64 = tempDL[1] & 0x01;
+    temp63 = (tempDL[0] >> 63) & 0x01;
+    if (temp64 != temp63) {
+        if (temp64 == 1)
+            temp = 0x8000000000000000;
+        else
+            temp = 0x7FFFFFFFFFFFFFFF;
+        set_DSPControl_overflow_flag(1, ac + 16);
+    }
+
+    env->active_tc.HI[ac] = (temp & MIPSDSP_LHI) >> 32;
+    env->active_tc.LO[ac] =  temp & MIPSDSP_LLO;
+}
+
+void helper_dpsuhqbl(int ac, uint32_t rs, uint32_t rt)
+{
+    uint8_t  rs3, rs2, rt3, rt2;
+    uint16_t tempB,  tempA;
+    uint64_t dotp, tempBL, tempAL, tempC;
+
+    rs3 = (rs & MIPSDSP_Q3) >> 24;
+    rs2 = (rs & MIPSDSP_Q2) >> 16;
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+
+    tempB = mipsdsp_mul_u8_u8(rs3, rt3);
+    tempA = mipsdsp_mul_u8_u8(rs2, rt2);
+    tempBL = tempB & 0xFFFF;
+    tempAL = tempA & 0xFFFF;
+
+    dotp   = tempBL + tempAL;
+    tempC  = ((uint64_t)env->active_tc.HI[ac] << 32) | \
+             ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
+    tempC -= dotp;
+
+    env->active_tc.HI[ac] = (tempC & MIPSDSP_LHI) >> 32;
+    env->active_tc.LO[ac] =  tempC & MIPSDSP_LLO;
+}
+
+void helper_dpsuhqbr(int ac, uint32_t rs, uint32_t rt)
+{
+    uint8_t  rs1, rs0, rt1, rt0;
+    uint16_t tempB,  tempA;
+    uint64_t dotp, tempBL, tempAL, tempC;
+
+    rs1 = (rs & MIPSDSP_Q1) >> 8;
+    rs0 = (rs & MIPSDSP_Q0);
+    rt1 = (rt & MIPSDSP_Q1) >> 8;
+    rt0 = (rt & MIPSDSP_Q0);
+
+    tempB = mipsdsp_mul_u8_u8(rs1, rt1);
+    tempA = mipsdsp_mul_u8_u8(rs0, rt0);
+    tempBL = tempB & 0xFFFF;
+    tempAL = tempA & 0xFFFF;
+
+    dotp   = tempBL + tempAL;
+    tempC  = ((uint64_t)env->active_tc.HI[ac] << 32) | \
+             ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
+    tempC -= dotp;
+
+    env->active_tc.HI[ac] = (tempC & MIPSDSP_LHI) >> 32;
+    env->active_tc.LO[ac] =  tempC & MIPSDSP_LLO;
+}
+
+void helper_extp(int ac, int size, int rt)
+{
+    int32_t start_pos;
+
+    start_pos = get_DSPControl_pos();
+    if (start_pos - (size + 1) >= -1) {
+        uint32_t temp;
+        uint64_t acc;
+
+        acc = ((uint64_t)env->active_tc.HI[ac] << 32) | \
+              ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
+        temp = (acc >> (start_pos - size)) & \
+               (((uint32_t)0x01 << (size + 1)) - 1);
+        env->active_tc.gpr[rt] = temp;
+        set_DSPControl_efi(0);
+    } else {
+        set_DSPControl_efi(1);
+    }
+}
+
+void helper_extpdp(int ac, int size, int rt)
+{
+    int32_t start_pos;
+
+    start_pos = get_DSPControl_pos();
+    if (start_pos - (size + 1) >= -1) {
+        uint32_t temp;
+        uint64_t acc;
+
+        acc  = ((uint64_t)env->active_tc.HI[ac] << 32) | \
+               ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
+        temp = (acc >> (start_pos - size)) & \
+               (((uint32_t)0x01 << (size + 1)) - 1);
+
+        env->active_tc.gpr[rt] = temp;
+        set_DSPControl_pos(start_pos - (size + 1));
+        set_DSPControl_efi(0);
+    } else
+        set_DSPControl_efi(1);
+}
+
+void helper_extpdpv(int ac, uint32_t rs, int rt)
+{
+    int32_t start_pos, size;
+
+    start_pos = get_DSPControl_pos();
+    size = rs & 0x1F;
+
+    if (start_pos - (size + 1) >= -1) {
+        uint32_t temp;
+        uint64_t acc;
+        acc  = ((uint64_t)env->active_tc.HI[ac] << 32) | \
+               ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
+        temp = (acc >> (start_pos - size)) & (((int)0x01 << (size + 1)) - 1);
+        env->active_tc.gpr[rt] = temp;
+        set_DSPControl_pos(start_pos - (size + 1));
+        set_DSPControl_efi(0);
+    } else
+        set_DSPControl_efi(1);
+}
+
+void helper_extpv(int ac, uint32_t rs, int rt)
+{
+    int32_t start_pos, size;
+
+    start_pos = get_DSPControl_pos();
+    size = rs & 0x1F;
+
+    if (start_pos - (size + 1) >= -1) {
+        uint32_t temp;
+        uint64_t acc;
+        acc = ((uint64_t)env->active_tc.HI[ac] << 32) | \
+              ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
+        temp = (acc >> (start_pos - size)) & \
+               (((uint32_t)0x01 << (size + 1)) - 1);
+        env->active_tc.gpr[rt] = temp;
+        set_DSPControl_efi(0);
+    } else
+        set_DSPControl_efi(1);
+}
+
+void helper_extrsh(int ac, int shift, int rt)
+{
+    int64_t temp;
+
+    temp = mipsdsp_rashift_short_acc(ac, shift);
+    if (temp > 0x0000000000007FFF) {
+        temp &= MIPSDSP_LHI;
+        temp |= 0x00007FFF;
+        set_DSPControl_overflow_flag(1, 23);
+    } else if (temp < 0xFFFFFFFFFFFF8000) {
+        temp &= MIPSDSP_LHI;
+        temp |= 0xFFFF8000;
+        set_DSPControl_overflow_flag(1, 23);
+    }
+
+    env->active_tc.gpr[rt] = temp & 0xFFFFFFFF;
+}
+
+void helper_extrw(int ac, int shift, int rt)
+{
+    int32_t tempI;
+    int64_t tempDL[2];
+
+    mipsdsp__rashift_short_acc(tempDL, ac, shift);
+    if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \
+        (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI))
+        set_DSPControl_overflow_flag(1, 23);
+
+    tempI = (tempDL[0] >> 1) & MIPSDSP_LLO;
+    env->active_tc.gpr[rt] = tempI;
+
+    tempDL[0] += 1;
+    if (tempDL[0] == 0)
+        tempDL[1] += 1;
+
+    if ((!(tempDL[1] == 0 && (tempDL[0] & MIPSDSP_LHI) == 0x00)) && \
+        (!(tempDL[1] == 1 && (tempDL[0] & MIPSDSP_LHI) == MIPSDSP_LHI)))
+        set_DSPControl_overflow_flag(1, 23);
+}
+
+void helper_extrrw(int ac, int shift, int rt)
+{
+    int32_t tempI;
+    int64_t tempDL[2];
+
+    mipsdsp__rashift_short_acc(tempDL, ac, shift);
+    if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \
+        (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI))
+        set_DSPControl_overflow_flag(1, 23);
+
+    tempDL[0] += 1;
+    if (tempDL[0] == 0)
+        tempDL[1] += 1;
+
+    if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \
+        (tempDL[1] != 1 && (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI))
+        set_DSPControl_overflow_flag(1, 23);
+    tempI = tempDL[0] >> 1;
+
+    env->active_tc.gpr[rt] = tempI;
+}
+
+void helper_extrrsw(int ac, int shift, int rt)
+{
+    int32_t tempI, temp64;
+    int64_t tempDL[2];
+
+    mipsdsp__rashift_short_acc(tempDL, ac, shift);
+    if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \
+        (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI))
+        set_DSPControl_overflow_flag(1, 23);
+    tempDL[0] += 1;
+    if (tempDL[0] == 0)
+        tempDL[1] += 1;
+    tempI = tempDL[0] >> 1;
+
+    if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \
+        (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) {
+        temp64 = tempDL[1];
+        if (temp64 == 0)
+            tempI = 0x7FFFFFFF;
+        else
+            tempI = 0x80000000;
+        set_DSPControl_overflow_flag(1, 23);
+    }
+    env->active_tc.gpr[rt] = tempI;
+}
+
+uint32_t helper_extrvsh(int ac, uint32_t rs)
+{
+    uint32_t rd;
+    int32_t shift, tempI;
+    int64_t tempL;
+
+    shift = rs & 0x0F;
+    tempL = mipsdsp_rashift_short_acc(ac, shift);
+    if (tempL > 0x000000000007FFF) {
+        tempI = 0x00007FFF;
+        set_DSPControl_overflow_flag(1, 23);
+    } else if (tempL < 0xFFFFFFFFFFF8000) {
+        tempI = 0xFFFF8000;
+        set_DSPControl_overflow_flag(1, 23);
+    }
+    rd = tempI;
+
+    return rd;
+}
+
+void helper_extrvw(int ac, uint32_t rs, int rt)
+{
+    int32_t shift, tempI;
+    int64_t tempDL[2];
+
+    shift = rs & 0x0F;
+    mipsdsp__rashift_short_acc(tempDL, ac, shift);
+    if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \
+        (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI))
+        set_DSPControl_overflow_flag(1, 23);
+
+    tempI = tempDL[0] >> 1;
+    env->active_tc.gpr[rt] = tempI;
+
+    tempDL[0] += 1;
+    if (tempDL[0] == 0)
+        tempDL[1] += 1;
+    if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \
+        (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI))
+        set_DSPControl_overflow_flag(1, 23);
+}
+
+void helper_extrvrw(int ac, uint32_t rs, int rt)
+{
+    int32_t shift, tempI;
+    int64_t tempDL[2];
+
+    shift = rs & 0x0F;
+    mipsdsp__rashift_short_acc(tempDL, ac, shift);
+    if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \
+        (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI))
+        set_DSPControl_overflow_flag(1, 23);
+
+    tempDL[0] += 1;
+    if (tempDL[0] == 0)
+        tempDL[1] += 1;
+
+    if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \
+        (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI))
+        set_DSPControl_overflow_flag(1, 23);
+    tempI = tempDL[0] >> 1;
+    env->active_tc.gpr[rt] = tempI;
+}
+
+void helper_extrvrsw(int ac, uint32_t rs, int rt)
+{
+    int32_t shift, tempI;
+    int64_t tempDL[2];
+
+    shift = rs & 0x0F;
+    mipsdsp__rashift_short_acc(tempDL, ac, shift);
+    if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \
+        (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI))
+        set_DSPControl_overflow_flag(1, 23);
+
+    tempDL[0] += 1;
+    if (tempDL[0] == 0)
+        tempDL[1] += 1;
+    tempI = tempDL[0] >> 1;
+
+    if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \
+        (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) {
+        if (tempDL[1] == 0)
+            tempI = 0x7FFFFFFF;
+        else
+            tempI = 0x80000000;
+        set_DSPControl_overflow_flag(1, 23);
+    }
+    env->active_tc.gpr[rt] = tempI;
+}
+
+void helper_insv(int reg_rt, uint32_t rs, uint32_t rt)
+{
+    uint32_t pos, size, msb, lsb, rs_f, rt_f;
+    uint32_t temp, temprs, temprt;
+    target_ulong dspc;
+
+    dspc = env->active_tc.DSPControl;
+    pos  = dspc & 0x1F;
+    size = (dspc >> 7) & 0x1F;
+    msb  = pos + size - 1;
+    lsb  = pos;
+
+    if (lsb > msb)
+        return;
+
+    rs_f = (((int32_t)0x01 << (msb - lsb + 1 + 1)) - 1) << lsb;
+    rt_f = rs_f ^ 0xFFFFFFFF;
+    temprs = rs & rs_f;
+    temprt = rt & rt_f;
+    temp = temprs | temprt;
+    env->active_tc.gpr[reg_rt] = temp;
+}
+
+target_ulong helper_lbux(target_ulong addr, int mem_idx)
+{
+    target_ulong temp;
+
+    temp = do_lbu(addr, mem_idx);
+    temp = temp & MIPSDSP_Q0;
+
+    return temp;
+}
+
+uint32_t helper_lhx(target_ulong vaddr, int mem_idx)
+{
+    target_ulong temp;
+    int16_t half;
+    uint32_t rd;
+
+    temp = do_lw(vaddr, mem_idx);
+    half = temp & 0x0000FFFF;
+    rd   = (int32_t)half;
+
+    return rd;
+}
+
+uint32_t helper_lwx(target_ulong vaddr, int mem_idx)
+{
+    target_ulong temp;
+    uint32_t rd;
+
+    temp = do_lw(vaddr, mem_idx);
+    rd   = (int32_t)temp;
+
+    return rd;
+}
+
+void helper_maqswphl(int ac, uint32_t rs, uint32_t rt)
+{
+    int16_t rsh, rth;
+    int32_t  tempA;
+    int64_t tempL, tempAL, acc;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    tempA  = mipsdsp_mul_q15_q15(ac, rsh, rth);
+    tempAL = tempA;
+    acc = ((uint64_t)env->active_tc.HI[ac] << 32) | \
+          ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
+    tempL  = tempAL + acc;
+    env->active_tc.HI[ac] = (tempL & MIPSDSP_LHI) >> 32;
+    env->active_tc.LO[ac] =  tempL & MIPSDSP_LLO;
+}
+
+void helper_maqsawphl(int ac, uint32_t rs, uint32_t rt)
+{
+    int16_t rsh, rth;
+    int32_t tempA;
+    int64_t tempAL;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    tempA = mipsdsp_mul_q15_q15(ac, rsh, rth);
+    tempA = mipsdsp_sat32_acc_q31(ac, tempA);
+    tempAL = tempA;
+
+    env->active_tc.HI[ac] = (tempAL & MIPSDSP_LHI) >> 32;
+    env->active_tc.LO[ac] =  tempAL & MIPSDSP_LLO;
+}
+
+void helper_maqswphr(int ac, uint32_t rs, uint32_t rt)
+{
+    int16_t rsl, rtl;
+    int32_t tempA;
+    int64_t tempL, tempAL, acc;
+
+    rsl = rs & MIPSDSP_LO;
+    rtl = rt & MIPSDSP_LO;
+    tempA  = mipsdsp_mul_q15_q15(ac, rsl, rtl);
+    tempAL = tempA;
+    acc = ((uint64_t)env->active_tc.HI[ac] << 32) | \
+          ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
+    tempL = tempAL + acc;
+
+    env->active_tc.HI[ac] = (tempL & MIPSDSP_LHI) >> 32;
+    env->active_tc.LO[ac] =  tempL & MIPSDSP_LLO;
+}
+
+void helper_maqsawphr(int ac, uint32_t rs, uint32_t rt)
+{
+    int16_t rsl, rtl;
+    int32_t tempA;
+    int64_t tempAL;
+
+    rsl = rs & MIPSDSP_LO;
+    rtl = rs & MIPSDSP_LO;
+
+    tempA = mipsdsp_mul_q15_q15(ac, rsl, rtl);
+    tempA = mipsdsp_sat32_acc_q31(ac, tempA);
+    tempAL = tempA;
+
+    env->active_tc.HI[ac] = (tempAL & MIPSDSP_LHI) >> 32;
+    env->active_tc.LO[ac] =  tempAL & MIPSDSP_LLO;
+}
+
+uint32_t helper_modsub(uint32_t rs, uint32_t rt)
+{
+    int32_t decr;
+    uint16_t lastindex;
+    uint32_t rd;
+
+    decr = rt & MIPSDSP_Q0;
+    lastindex = (rt >> 8) & MIPSDSP_LO;
+
+    if (rs == 0x00000000)
+        rd = (uint32_t)lastindex;
+    else
+        rd = rs - decr;
+
+    return rd;
+}
+
+void helper_mthlip(int ac, uint32_t rs)
+{
+    int32_t tempA, tempB, pos;
+
+    tempA = rs;
+    tempB = env->active_tc.LO[ac];
+    env->active_tc.HI[ac] = tempB;
+    env->active_tc.LO[ac] = tempA;
+    pos = get_DSPControl_pos();
+
+    if (pos > 32)
+        return;
+    else
+        set_DSPControl_pos(pos + 32);
+}
+
+uint32_t helper_muleqswphl(uint32_t rs, uint32_t rt)
+{
+    int16_t rsh, rth;
+    int32_t temp;
+    uint32_t rd;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    temp = mipsdsp_mul_q15_q15_overflowflag21(rsh, rth);
+    rd = temp;
+
+    return rd;
+}
+
+uint32_t helper_muleqswphr(uint32_t rs, uint32_t rt)
+{
+    int16_t rsl, rtl;
+    int32_t temp;
+    uint32_t rd;
+
+    rsl = rs & MIPSDSP_LO;
+    rtl = rt & MIPSDSP_LO;
+    temp = mipsdsp_mul_q15_q15_overflowflag21(rsl, rtl);
+    rd = temp;
+
+    return rd;
+}
+
+uint32_t helper_muleusphqbl(uint32_t rs, uint32_t rt)
+{
+    uint8_t rs3, rs2;
+    uint16_t tempB, tempA, rth, rtl;
+    uint32_t temp;
+    uint32_t rd;
+
+    rs3 = (rs & MIPSDSP_Q3) >> 24;
+    rs2 = (rs & MIPSDSP_Q2) >> 16;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+    tempB = mipsdsp_mul_u8_u16(rs3, rth);
+    tempA = mipsdsp_mul_u8_u16(rs2, rtl);
+    temp = ((uint32_t)tempB << 16) | ((uint32_t)tempA & MIPSDSP_LO);
+    rd = temp;
+    return rd;
+}
+
+uint32_t helper_muleusphqbr(uint32_t rs, uint32_t rt)
+{
+    uint8_t  rs1, rs0;
+    uint16_t tempB, tempA;
+    uint16_t rth,   rtl;
+    uint32_t temp;
+    uint32_t rd;
+
+    rs1 = (rs & MIPSDSP_Q1) >> 8;
+    rs0 =  rs & MIPSDSP_Q0;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+
+    tempB = mipsdsp_mul_u8_u16(rs1, rth);
+    tempA = mipsdsp_mul_u8_u16(rs0, rtl);
+    temp = ((uint32_t)tempB << 16) | ((uint32_t)tempA & MIPSDSP_LO);
+    rd = temp;
+    return rd;
+}
+
+uint32_t helper_mulqrsph(uint32_t rs, uint32_t rt)
+{
+    int16_t tempB, tempA, rsh, rsl, rth, rtl;
+    int32_t temp;
+    uint32_t rd;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+
+    tempB = mipsdsp_rndq15_mul_q15_q15(rsh, rth);
+    tempA = mipsdsp_rndq15_mul_q15_q15(rsl, rtl);
+    temp = ((uint32_t)tempB << 16) | ((uint32_t)tempA & MIPSDSP_LO);
+    rd = temp;
+
+    return rd;
+}
+
+void helper_mulsaqswph(int ac, uint32_t rs, uint32_t rt)
+{
+    int16_t rsh, rsl, rth, rtl;
+    int32_t tempB, tempA;
+    int64_t tempBL, tempAL, acc, dotp;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+
+    tempB = mipsdsp_mul_q15_q15(ac, rsh, rth);
+    tempA = mipsdsp_mul_q15_q15(ac, rsl, rtl);
+    tempBL = tempB;
+    tempAL = tempA;
+    dotp = tempBL - tempAL;
+    acc = ((uint64_t)env->active_tc.HI[ac] << 32) | \
+          ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
+    dotp = dotp + acc;
+    env->active_tc.HI[ac] = (dotp & MIPSDSP_LHI) >> 32;
+    env->active_tc.LO[ac] =  dotp & MIPSDSP_LLO;
+}
+
+uint32_t helper_packrlph(uint32_t rs, uint32_t rt)
+{
+    uint16_t rsl, rth;
+    uint32_t rd;
+
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rd = (rsl << 16) | rth;
+
+    return rd;
+}
+
+uint32_t helper_pickqb(uint32_t rs, uint32_t rt)
+{
+    uint8_t rs3, rs2, rs1, rs0;
+    uint8_t rt3, rt2, rt1, rt0;
+    uint8_t tp3, tp2, tp1, tp0;
+
+    uint32_t dsp27, dsp26, dsp25, dsp24, rd;
+    target_ulong dsp;
+
+    rs3 = (rs & MIPSDSP_Q3) >> 24;
+    rs2 = (rs & MIPSDSP_Q2) >> 16;
+    rs1 = (rs & MIPSDSP_Q1) >>  8;
+    rs0 =  rs & MIPSDSP_Q0;
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    rt1 = (rt & MIPSDSP_Q1) >>  8;
+    rt0 =  rt & MIPSDSP_Q0;
+
+    dsp = env->active_tc.DSPControl;
+    dsp27 = (dsp >> 27) & 0x01;
+    dsp26 = (dsp >> 26) & 0x01;
+    dsp25 = (dsp >> 25) & 0x01;
+    dsp24 = (dsp >> 24) & 0x01;
+
+    tp3 = dsp27 == 1 ? rs3 : rt3;
+    tp2 = dsp26 == 1 ? rs2 : rt2;
+    tp1 = dsp25 == 1 ? rs1 : rt1;
+    tp0 = dsp24 == 1 ? rs0 : rt0;
+
+    rd = ((uint32_t)tp3 << 24) | \
+         ((uint32_t)tp2 << 16) | \
+         ((uint32_t)tp1 << 8)  | \
+         (uint32_t)tp0;
+
+    return rd;
+}
+
+uint32_t helper_preceqwphl(uint32_t rt)
+{
+    uint32_t rd;
+
+    rd = rt & MIPSDSP_HI;
+
+    return rd;
+}
+
+uint32_t helper_pickph(uint32_t rs, uint32_t rt)
+{
+    uint16_t rsh, rsl, rth, rtl;
+    uint16_t tempB, tempA;
+    uint32_t dsp25, dsp24;
+    uint32_t rd;
+    target_ulong dsp;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+
+    dsp = env->active_tc.DSPControl;
+    dsp25 = (dsp >> 25) & 0x01;
+    dsp24 = (dsp >> 24) & 0x01;
+
+    tempB = (dsp25 == 1) ? rsh : rth;
+    tempA = (dsp24 == 1) ? rsl : rtl;
+    rd = (((uint32_t)tempB << 16) & MIPSDSP_HI) | (uint32_t)tempA;
+
+    return rd;
+}
+
+uint32_t helper_preceqwphr(uint32_t rt)
+{
+    uint16_t rtl;
+    uint32_t rd;
+
+    rtl = rt & MIPSDSP_LO;
+    rd  = rtl << 16;
+
+    return rd;
+}
+
+uint32_t helper_precequphqbl(uint32_t rt)
+{
+    uint8_t  rt3, rt2;
+    uint16_t tempB, tempA;
+    uint32_t rd;
+
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+
+    tempB = (uint16_t)rt3 << 7;
+    tempA = (uint16_t)rt2 << 7;
+    rd = ((uint32_t)tempB << 16) | (uint32_t)tempA;
+
+    return rd;
+}
+
+uint32_t helper_precequphqbla(uint32_t rt)
+{
+    uint8_t  rt3, rt1;
+    uint16_t tempB, tempA;
+    uint32_t rd;
+
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+    rt1 = (rt & MIPSDSP_Q1) >> 8;
+
+    tempB = (uint16_t)rt3 << 7;
+    tempA = (uint16_t)rt1 << 7;
+    rd = ((uint32_t)tempB << 16) | (uint32_t)tempA;
+
+    return rd;
+}
+
+uint32_t helper_precequphqbr(uint32_t rt)
+{
+    uint8_t  rt1, rt0;
+    uint16_t tempB, tempA;
+    uint32_t rd;
+
+    rt1 = (rt & MIPSDSP_Q1) >> 8;
+    rt0 =  rt & MIPSDSP_Q0;
+    tempB = (uint16_t)rt1 << 7;
+    tempA = (uint16_t)rt0 << 7;
+    rd = ((uint32_t)tempB << 16) | (uint32_t)tempA;
+
+    return rd;
+}
+
+uint32_t helper_precequphqbra(uint32_t rt)
+{
+    uint8_t  rt2, rt0;
+    uint16_t tempB, tempA;
+    uint32_t rd;
+
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    rt0 =  rt & MIPSDSP_Q0;
+    tempB = (uint16_t)rt2 << 7;
+    tempA = (uint16_t)rt0 << 7;
+    rd = ((uint32_t)tempB << 16) | (uint32_t)tempA;
+
+    return rd;
+}
+
+uint32_t helper_preceuphqbl(uint32_t rt)
+{
+    uint8_t  rt3, rt2;
+    uint16_t tempB, tempA;
+    uint32_t rd;
+
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    tempB = (uint16_t) rt3;
+    tempA = (uint16_t) rt2;
+    rd = ((uint32_t)tempB << 16) | ((uint32_t)tempA & MIPSDSP_LO);
+
+    return rd;
+}
+
+uint32_t helper_preceuphqbla(uint32_t rt)
+{
+    uint8_t  rt3, rt1;
+    uint16_t tempB, tempA;
+    uint32_t rd;
+
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+    rt1 = (rt & MIPSDSP_Q1) >> 8;
+    tempB = (uint16_t) rt3;
+    tempA = (uint16_t) rt1;
+    rd = ((uint32_t)tempB << 16) | ((uint32_t)tempA & MIPSDSP_LO);
+
+    return rd;
+}
+
+uint32_t helper_preceuphqbr(uint32_t rt)
+{
+    uint8_t  rt1, rt0;
+    uint16_t tempB, tempA;
+    uint32_t rd;
+
+    rt1 = (rt & MIPSDSP_Q1) >> 8;
+    rt0 =  rt & MIPSDSP_Q0;
+    tempB = (uint16_t) rt1;
+    tempA = (uint16_t) rt0;
+    rd = ((uint32_t)tempB << 16) | ((uint32_t)tempA & MIPSDSP_LO);
+    return rd;
+}
+
+uint32_t helper_preceuphqbra(uint32_t rt)
+{
+    uint8_t  rt2, rt0;
+    uint16_t tempB, tempA;
+    uint32_t rd;
+
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    rt0 =  rt & MIPSDSP_Q0;
+    tempB = (uint16_t)rt2;
+    tempA = (uint16_t)rt0;
+    rd = ((uint32_t)tempB << 16) | ((uint32_t)tempA & MIPSDSP_LO);
+    return rd;
+}
+
+uint32_t helper_precrqqbph(uint32_t rs, uint32_t rt)
+{
+    uint8_t tempD, tempC, tempB, tempA;
+    uint32_t rd;
+
+    tempD = (rs & MIPSDSP_Q3) >> 24;
+    tempC = (rs & MIPSDSP_Q1) >> 8;
+    tempB = (rt & MIPSDSP_Q3) >> 24;
+    tempA = (rt & MIPSDSP_Q1) >> 8;
+
+    rd = ((uint32_t)tempD << 24) | ((uint32_t)tempC << 16) | \
+         ((uint32_t)tempB << 8) | (uint32_t)tempA;
+
+    return rd;
+}
+
+uint32_t helper_precrqphw(uint32_t rs, uint32_t rt)
+{
+    uint16_t tempB, tempA;
+    uint32_t rd;
+
+    tempB = (rs & MIPSDSP_HI) >> 16;
+    tempA = (rt & MIPSDSP_HI) >> 16;
+    rd = ((uint32_t)tempB << 16) | ((uint32_t)tempA & MIPSDSP_LO);
+
+    return rd;
+}
+
+uint32_t helper_precrqrsphw(uint32_t rs, uint32_t rt)
+{
+    uint16_t tempB, tempA;
+    uint32_t rd;
+
+    tempB = mipsdsp_trunc16_sat16_round(rs);
+    tempA = mipsdsp_trunc16_sat16_round(rt);
+    rd = ((uint32_t)tempB << 16) | (uint32_t)tempA;
+
+    return rd;
+}
+
+uint32_t helper_precrqusqbph(uint32_t rs, uint32_t rt)
+{
+    uint8_t  tempD, tempC, tempB, tempA;
+    uint16_t rsh, rsl, rth, rtl;
+    uint32_t rd;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+
+    tempD = mipsdsp_sat8_reduce_precision(rsh);
+    tempC = mipsdsp_sat8_reduce_precision(rsl);
+    tempB = mipsdsp_sat8_reduce_precision(rth);
+    tempA = mipsdsp_sat8_reduce_precision(rtl);
+
+    rd = ((uint32_t)tempD << 24) | ((uint32_t)tempC << 16) | \
+         ((uint32_t)tempB << 8) | (uint32_t)tempA;
+
+    return rd;
+}
+
+uint32_t helper_radduwqb(uint32_t rs)
+{
+    uint8_t  rs3, rs2, rs1, rs0;
+    uint16_t temp;
+    uint32_t rd;
+
+    rs3 = (rs & MIPSDSP_Q3) >> 24;
+    rs2 = (rs & MIPSDSP_Q2) >> 16;
+    rs1 = (rs & MIPSDSP_Q1) >>  8;
+    rs0 =  rs & MIPSDSP_Q0;
+
+    temp = (uint16_t)rs3 + (uint16_t)rs2 + (uint16_t)rs1 + (uint16_t)rs0;
+    rd = temp;
+
+    return rd;
+}
+
+uint32_t helper_rddsp(uint32_t masknum)
+{
+    uint8_t  mask[6];
+    uint32_t ruler, i;
+    uint32_t temp;
+    uint32_t rd;
+    target_ulong dsp;
+
+    ruler = 0x01;
+    for (i = 0; i < 6; i++) {
+        mask[i] = (masknum & ruler) >> i ;
+        ruler = ruler << 1;
+    }
+
+    temp  = 0x00;
+    dsp = env->active_tc.DSPControl;
+
+    if (mask[0] == 1)
+        temp |= dsp & 0x3F;
+
+    if (mask[1] == 1)
+        temp |= dsp & 0x1F80;
+
+    if (mask[2] == 1)
+        temp |= dsp & 0x2000;
+
+    if (mask[3] == 1)
+        temp |= dsp & 0x00FF0000;
+
+    if (mask[4] == 1)
+        temp |= dsp & 0xFF000000;
+
+    if (mask[5] == 1)
+        temp |= dsp & 0x4000;
+
+    rd = temp;
+
+    return rd;
+}
+
+uint32_t helper_replph(uint32_t imm)
+{
+    int16_t temp;
+    int16_t imm_temp;
+    uint32_t rd;
+
+    imm_temp = imm & 0x03FF;
+    temp = (imm_temp << 22) >> 22;
+    rd = (((uint32_t)temp << 16) & MIPSDSP_HI) | \
+         ((uint32_t)temp & MIPSDSP_LO);
+
+    return rd;
+}
+
+uint32_t helper_replqb(uint32_t imm)
+{
+    uint8_t  temp;
+    uint32_t rd;
+
+    temp = imm & 0x00FF;
+    rd = ((uint32_t)temp << 24) | ((uint32_t)temp << 16) | \
+         ((uint32_t)temp << 8) | (uint32_t)temp;
+
+    return rd;
+}
+
+uint32_t helper_replvph(uint32_t rt)
+{
+    uint16_t temp;
+    uint32_t rd;
+
+    temp = rt & MIPSDSP_LO;
+    rd = ((uint32_t)temp << 16) | (uint32_t)temp;
+
+    return rd;
+}
+
+uint32_t helper_replvqb(uint32_t rt)
+{
+    uint8_t temp;
+    uint32_t rd;
+
+    temp = rt & MIPSDSP_Q0;
+    rd = ((uint32_t)temp << 24) | ((uint32_t)temp << 16) | \
+         ((uint32_t)temp << 8) | (uint32_t)temp;
+
+    return rd;
+}
+
+void helper_shilo(int ac, int shift)
+{
+    uint8_t  sign;
+    uint64_t temp, acc;
+
+    shift = (shift << 26) >> 26;
+    sign  = (shift >> 5) & 0x01;
+    shift = (sign == 0) ? shift : -shift;
+    acc = (((uint64_t)env->active_tc.HI[ac] << 32) & MIPSDSP_LHI) | \
+          ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
+
+    if (shift == 0)
+        temp = acc;
+    else {
+        if (sign == 0)
+            temp = acc >> shift;
+        else
+            temp = acc << shift;
+    }
+
+    env->active_tc.HI[ac] = (temp & MIPSDSP_LHI) >> 32;
+    env->active_tc.LO[ac] =  temp & MIPSDSP_LLO;
+}
+
+void helper_shilov(int ac, uint32_t rs)
+{
+    uint8_t sign;
+    int8_t  rs5_0;
+    uint64_t temp, acc;
+
+    rs5_0 = rs & 0x3F;
+    rs = (rs5_0 << 2) >> 2;
+    sign = (rs5_0 >> 5) & 0x01;
+    rs5_0 = (sign == 0) ? rs : -rs;
+    acc = (((uint64_t)env->active_tc.HI[ac] << 32) & MIPSDSP_LHI) | \
+           ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
+    if (rs5_0 == 0)
+        temp = acc;
+    else {
+        if (sign == 0)
+            temp = acc >> rs5_0;
+        else
+            temp = acc << rs5_0;
+    }
+
+    env->active_tc.HI[ac] = (temp & MIPSDSP_LHI) >> 32;
+    env->active_tc.LO[ac] =  temp & MIPSDSP_LLO;
+}
+
+uint32_t helper_shllph(int sa, uint32_t rt)
+{
+    uint16_t rth, rtl;
+    uint16_t tempB, tempA;
+    uint32_t rd;
+
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+    tempB = mipsdsp_lshift16(rth, sa);
+    tempA = mipsdsp_lshift16(rtl, sa);
+    rd = ((uint32_t)tempB << 16) | (uint32_t)tempA;
+
+    return rd;
+}
+
+uint32_t helper_shllsph(int sa, uint32_t rt)
+{
+    uint16_t rth, rtl;
+    uint16_t tempB, tempA;
+    uint32_t rd;
+
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+    tempB = mipsdsp_sat16_lshift(rth, sa);
+    tempA = mipsdsp_sat16_lshift(rtl, sa);
+    rd = ((uint32_t)tempB << 16) | (uint32_t)tempA;
+
+    return rd;
+}
+
+uint32_t helper_shllqb(int sa, uint32_t rt)
+{
+    uint8_t  rt3, rt2, rt1, rt0;
+    uint8_t  tempD, tempC, tempB, tempA;
+    uint32_t rd;
+
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    rt1 = (rt & MIPSDSP_Q1) >>  8;
+    rt0 =  rt & MIPSDSP_Q0;
+
+    tempD = mipsdsp_lshift8(rt3, sa);
+    tempC = mipsdsp_lshift8(rt2, sa);
+    tempB = mipsdsp_lshift8(rt1, sa);
+    tempA = mipsdsp_lshift8(rt0, sa);
+    rd = ((uint32_t)tempD << 24) | ((uint32_t)tempC << 16) | \
+         ((uint32_t)tempB << 8) | ((uint32_t)tempA);
+
+    return rd;
+}
+
+uint32_t helper_shllsw(int sa, uint32_t rt)
+{
+    uint32_t temp, rd;
+
+    temp = mipsdsp_sat32_lshift(rt, sa);
+    rd   = temp;
+
+    return rd;
+}
+
+uint32_t helper_shllvph(uint32_t rs, uint32_t rt)
+{
+    uint8_t  rs3_0;
+    uint16_t rth, rtl, tempB, tempA;
+    uint32_t rd;
+
+    rth   = (rt & MIPSDSP_HI) >> 16;
+    rtl   =  rt & MIPSDSP_LO;
+    rs3_0 = rs & 0x0F;
+
+    tempB = mipsdsp_lshift16(rth, rs3_0);
+    tempA = mipsdsp_lshift16(rtl, rs3_0);
+    rd = ((uint32_t)tempB << 16) | (uint32_t)tempA;
+
+    return rd;
+}
+
+uint32_t helper_shllvsph(uint32_t rs, uint32_t rt)
+{
+    uint8_t  rs3_0;
+    uint16_t rth, rtl, tempB, tempA;
+    uint32_t rd;
+
+    rth   = (rt & MIPSDSP_HI) >> 16;
+    rtl   =  rt & MIPSDSP_LO;
+    rs3_0 = rs & 0x0F;
+
+    tempB = mipsdsp_sat16_lshift(rth, rs3_0);
+    tempA = mipsdsp_sat16_lshift(rtl, rs3_0);
+    rd = ((uint32_t)tempB << 16) | (uint32_t)tempA;
+
+    return rd;
+}
+
+uint32_t helper_shllvqb(uint32_t rs, uint32_t rt)
+{
+    uint8_t  rs2_0;
+    uint8_t  rt3, rt2, rt1, rt0;
+    uint8_t  tempD, tempC, tempB, tempA;
+    uint32_t rd;
+
+    rs2_0 = rs & 0x07;
+    rt3   = (rt & MIPSDSP_Q3) >> 24;
+    rt2   = (rt & MIPSDSP_Q2) >> 16;
+    rt1   = (rt & MIPSDSP_Q1) >>  8;
+    rt0   =  rt & MIPSDSP_Q0;
+
+    tempD = mipsdsp_lshift8(rt3, rs2_0);
+    tempC = mipsdsp_lshift8(rt2, rs2_0);
+    tempB = mipsdsp_lshift8(rt1, rs2_0);
+    tempA = mipsdsp_lshift8(rt0, rs2_0);
+
+    rd = ((uint32_t)tempD << 24) | ((uint32_t)tempC << 16) | \
+         ((uint32_t)tempB << 8) | (uint32_t)tempA;
+
+    return rd;
+}
+
+uint32_t helper_shllvsw(uint32_t rs, uint32_t rt)
+{
+    uint8_t  rs4_0;
+    uint32_t rd;
+
+    rs4_0 = rs & 0x1F;
+    rd = mipsdsp_sat32_lshift(rt, rs4_0);
+
+    return rd;
+}
+
+uint32_t helper_shraph(int sa, uint32_t rt)
+{
+    uint16_t rth, rtl;
+    uint16_t tempB, tempA;
+    uint32_t rd;
+
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+    tempB = mipsdsp_rashift16(rth, sa);
+    tempA = mipsdsp_rashift16(rtl, sa);
+    rd = ((uint32_t)tempB << 16) | (uint32_t) tempA;
+
+    return rd;
+}
+
+uint32_t helper_shrarph(int sa, uint32_t rt)
+{
+    uint16_t rth, rtl;
+    uint16_t tempB, tempA;
+    uint32_t rd;
+
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+    tempB = mipsdsp_rnd16_rashift(rth, sa);
+    tempA = mipsdsp_rnd16_rashift(rtl, sa);
+    rd = ((uint32_t)tempB << 16) | (uint32_t) tempA;
+
+    return rd;
+}
+
+uint32_t helper_shrarw(int sa, uint32_t rt)
+{
+    uint32_t rd;
+
+    rd = mipsdsp_rnd32_rashift(rt, sa);
+
+    return rd;
+}
+
+uint32_t helper_shravph(uint32_t rs, uint32_t rt)
+{
+    uint8_t  rs3_0;
+    uint16_t rth, rtl;
+    uint16_t tempB, tempA;
+    uint32_t rd;
+
+    rs3_0 = rs & 0x0F;
+    rth   = (rt & MIPSDSP_HI) >> 16;
+    rtl   =  rt & MIPSDSP_LO;
+    tempB = mipsdsp_rashift16(rth, rs3_0);
+    tempA = mipsdsp_rashift16(rtl, rs3_0);
+    rd = ((uint32_t)tempB << 16) | (uint32_t)tempA;
+
+    return rd;
+}
+
+uint32_t helper_shravrph(uint32_t rs, uint32_t rt)
+{
+    uint8_t  rs3_0;
+    uint16_t rth, rtl;
+    uint16_t tempB, tempA;
+    uint32_t rd;
+
+    rs3_0 = rs & 0x0F;
+    rth   = (rt & MIPSDSP_HI) >> 16;
+    rtl   =  rt & MIPSDSP_LO;
+    tempB = mipsdsp_rnd16_rashift(rth, rs3_0);
+    tempA = mipsdsp_rnd16_rashift(rtl, rs3_0);
+
+    rd = ((uint32_t)tempB << 16) | (uint32_t)tempA;
+
+    return rd;
+}
+
+uint32_t helper_shravrw(uint32_t rs, uint32_t rt)
+{
+    uint8_t rs4_0;
+    uint32_t rd;
+
+    rs4_0 = rs & 0x1F;
+    rd = mipsdsp_rnd32_rashift(rt, rs4_0);
+
+    return rd;
+}
+
+uint32_t helper_shrlqb(int sa, uint32_t rt)
+{
+    uint8_t  rt3, rt2, rt1, rt0;
+    uint8_t  tempD, tempC, tempB, tempA;
+    uint32_t rd;
+
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    rt1 = (rt & MIPSDSP_Q1) >>  8;
+    rt0 =  rt & MIPSDSP_Q0;
+
+    tempD = mipsdsp_rshift8(rt3, sa);
+    tempC = mipsdsp_rshift8(rt2, sa);
+    tempB = mipsdsp_rshift8(rt1, sa);
+    tempA = mipsdsp_rshift8(rt0, sa);
+
+    rd = ((uint32_t)tempD << 24) | ((uint32_t)tempC << 16) | \
+         ((uint32_t)tempB << 8) | (uint32_t)tempA;
+
+    return rd;
+}
+
+uint32_t helper_shrlvqb(uint32_t rs, uint32_t rt)
+{
+    uint8_t rs2_0;
+    uint8_t rt3, rt2, rt1, rt0;
+    uint8_t tempD, tempC, tempB, tempA;
+    uint32_t rd;
+
+    rs2_0 = rs & 0x07;
+    rt3   = (rt & MIPSDSP_Q3) >> 24;
+    rt2   = (rt & MIPSDSP_Q2) >> 16;
+    rt1   = (rt & MIPSDSP_Q1) >>  8;
+    rt0   =  rt & MIPSDSP_Q0;
+
+    tempD = mipsdsp_rshift8(rt3, rs2_0);
+    tempC = mipsdsp_rshift8(rt2, rs2_0);
+    tempB = mipsdsp_rshift8(rt1, rs2_0);
+    tempA = mipsdsp_rshift8(rt0, rs2_0);
+    rd = ((uint32_t)tempD << 24) | ((uint32_t)tempC << 16) | \
+         ((uint32_t)tempB << 8) | (uint32_t)tempA;
+
+    return rd;
+}
+
+uint32_t helper_subqph(uint32_t rs, uint32_t rt)
+{
+    uint16_t rsh, rsl;
+    uint16_t rth, rtl;
+    uint16_t tempB, tempA;
+    uint32_t rd;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+
+    tempB = mipsdsp_sub_i16(rsh, rth);
+    tempA = mipsdsp_sub_i16(rsl, rtl);
+    rd = ((uint32_t)tempB << 16) | (uint32_t)tempA;
+
+    return rd;
+}
+
+uint32_t helper_subqsph(uint32_t rs, uint32_t rt)
+{
+    uint16_t rsh, rsl;
+    uint16_t rth, rtl;
+    uint16_t tempB, tempA;
+    uint32_t rd;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+
+    tempB = mipsdsp_sat16_sub(rsh, rth);
+    tempA = mipsdsp_sat16_sub(rsl, rtl);
+    rd = ((uint32_t)tempB << 16) | (uint32_t)tempA;
+
+    return rd;
+}
+
+uint32_t helper_subqsw(uint32_t rs, uint32_t rt)
+{
+    uint32_t rd;
+
+    rd = mipsdsp_sat32_sub(rs, rt);
+
+    return rd;
+}
+
+uint32_t helper_subuqb(uint32_t rs, uint32_t rt)
+{
+    uint8_t rs3, rs2, rs1, rs0;
+    uint8_t rt3, rt2, rt1, rt0;
+    uint8_t tempD, tempC, tempB, tempA;
+    uint32_t rd;
+
+    rs3 = (rs & MIPSDSP_Q3) >> 24;
+    rs2 = (rs & MIPSDSP_Q2) >> 16;
+    rs1 = (rs & MIPSDSP_Q1) >>  8;
+    rs0 =  rs & MIPSDSP_Q0;
+
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    rt1 = (rt & MIPSDSP_Q1) >>  8;
+    rt0 =  rt & MIPSDSP_Q0;
+
+    tempD = mipsdsp_sub_u8(rs3, rt3);
+    tempC = mipsdsp_sub_u8(rs2, rt2);
+    tempB = mipsdsp_sub_u8(rs1, rt1);
+    tempA = mipsdsp_sub_u8(rs0, rt0);
+
+    rd = ((uint32_t)tempD << 24) | ((uint32_t)tempC << 16) | \
+         ((uint32_t)tempB << 8) | (uint32_t)tempA;
+    return rd;
+}
+
+uint32_t helper_subusqb(uint32_t rs, uint32_t rt)
+{
+    uint8_t rs3, rs2, rs1, rs0;
+    uint8_t rt3, rt2, rt1, rt0;
+    uint8_t tempD, tempC, tempB, tempA;
+    uint32_t rd;
+
+    rs3 = (rs & MIPSDSP_Q3) >> 24;
+    rs2 = (rs & MIPSDSP_Q2) >> 16;
+    rs1 = (rs & MIPSDSP_Q1) >>  8;
+    rs0 =  rs & MIPSDSP_Q0;
+
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    rt1 = (rt & MIPSDSP_Q1) >>  8;
+    rt0 =  rt & MIPSDSP_Q0;
+
+    tempD = mipsdsp_satu8_sub(rs3, rt3);
+    tempC = mipsdsp_satu8_sub(rs2, rt2);
+    tempB = mipsdsp_satu8_sub(rs1, rt1);
+    tempA = mipsdsp_satu8_sub(rs0, rt0);
+
+    rd = ((uint32_t)tempD << 24) | ((uint32_t)tempC << 16) | \
+         ((uint32_t)tempB << 8) | (uint32_t)tempA;
+
+    return rd;
+}
+
+void helper_wrdsp(uint32_t rs, int mask_num)
+{
+    uint8_t  mask[6];
+    uint8_t  i;
+    uint32_t newbits, overwrite;
+    target_ulong dsp;
+
+    newbits   = 0x00;
+    overwrite = 0xFFFFFFFF;
+    dsp = env->active_tc.DSPControl;
+
+    for (i = 0; i < 6; i++)
+        mask[i] = (mask_num >> i) & 0x01;
+
+    if (mask[0] == 1) {
+        overwrite &= 0xFFFFFFC0;
+        newbits   &= 0xFFFFFFC0;
+        newbits   |= 0x0000003F & rs;
+    }
+
+    if (mask[1] == 1) {
+        overwrite &= 0xFFFFE07F;
+        newbits   &= 0xFFFFE07F;
+        newbits   |= 0x00001F80 & rs;
+    }
+
+    if (mask[2] == 1) {
+        overwrite &= 0xFFFFDFFF;
+        newbits   &= 0xFFFFDFFF;
+        newbits   |= 0x00002000 & rs;
+    }
+
+    if (mask[3] == 1) {
+        overwrite &= 0xFF00FFFF;
+        newbits   &= 0xFF00FFFF;
+        newbits   |= 0x00FF0000 & rs;
+    }
+
+    if (mask[4] == 1) {
+        overwrite &= 0x00FFFFFF;
+        newbits   &= 0x00FFFFFF;
+        newbits   |= 0xFF000000 & rs;
+    }
+
+    if (mask[5] == 1) {
+        overwrite &= 0xFFFFBFFF;
+        newbits   &= 0xFFFFBFFF;
+        newbits   |= 0x00004000 & rs;
+    }
+
+    dsp = dsp & overwrite;
+    dsp = dsp | newbits;
+    env->active_tc.DSPControl = dsp;
+}
+
+/* MIPS DSPR2 */
+uint32_t helper_absqsqb(uint32_t rt)
+{
+    uint32_t rd;
+    int8_t tempD, tempC, tempB, tempA;
+
+    tempD = (rt & MIPSDSP_Q3) >> 24;
+    tempC = (rt & MIPSDSP_Q2) >> 16;
+    tempB = (rt & MIPSDSP_Q1) >> 8;
+    tempA =  rt & MIPSDSP_Q0;
+
+    rd = (((uint32_t)mipsdsp_sat_abs_u8 (tempD) << 24) & MIPSDSP_Q3) | \
+         (((uint32_t)mipsdsp_sat_abs_u8 (tempC) << 16) & MIPSDSP_Q2) | \
+         (((uint32_t)mipsdsp_sat_abs_u8 (tempB) << 8) & MIPSDSP_Q1) | \
+         ((uint32_t)mipsdsp_sat_abs_u8 (tempA) & MIPSDSP_Q0);
+
+    return rd;
+}
+
+uint32_t helper_addqhph(uint32_t rs, uint32_t rt)
+{
+    uint32_t rd;
+    int16_t rsh, rsl, rth, rtl, temph, templ;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+
+    temph = mipsdsp_rshift1_add_q16(rsh, rth);
+    templ = mipsdsp_rshift1_add_q16(rsl, rtl);
+    rd = ((uint32_t)temph << 16) | ((uint32_t)templ & MIPSDSP_LO);
+
+    return rd;
+}
+
+uint32_t helper_addqhrph(uint32_t rs, uint32_t rt)
+{
+    uint32_t rd;
+    int16_t rsh, rsl, rth, rtl, temph, templ;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+
+    temph = mipsdsp_rrshift1_add_q16(rsh, rth);
+    templ = mipsdsp_rrshift1_add_q16(rsl, rtl);
+    rd = ((uint32_t)temph << 16) | ((uint32_t)templ & MIPSDSP_LO);
+
+    return rd;
+}
+
+uint32_t helper_addqhw(uint32_t rs, uint32_t rt)
+{
+    uint32_t rd;
+
+    rd = mipsdsp_rshift1_add_q32(rs, rt);
+
+    return rd;
+}
+
+uint32_t helper_addqhrw(uint32_t rs, uint32_t rt)
+{
+    uint32_t rd;
+
+    rd = mipsdsp_rrshift1_add_q32(rs, rt);
+
+    return rd;
+}
+
+uint32_t helper_adduph(uint32_t rs, uint32_t rt)
+{
+    uint16_t rsh, rsl, rth, rtl, temph, templ;
+    uint32_t rd;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+    temph = mipsdsp_add_u16(rsh, rth);
+    templ = mipsdsp_add_u16(rsl, rtl);
+    rd = ((uint32_t)temph << 16) | ((uint32_t)templ & MIPSDSP_LO);
+
+    return rd;
+}
+
+uint32_t helper_addusph(uint32_t rs, uint32_t rt)
+{
+    uint16_t rsh, rsl, rth, rtl, temph, templ;
+    uint32_t rd;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+    temph = mipsdsp_sat_add_u16(rsh, rth);
+    templ = mipsdsp_sat_add_u16(rsl, rtl);
+    rd = ((uint32_t)temph << 16) | ((uint32_t)templ & MIPSDSP_LO);
+
+    return rd;
+}
+
+uint32_t helper_adduqb(uint32_t rs, uint32_t rt)
+{
+    uint32_t rd;
+    uint8_t  rs0, rs1, rs2, rs3;
+    uint8_t  rt0, rt1, rt2, rt3;
+    uint8_t  temp0, temp1, temp2, temp3;
+
+    rs0 =  rs & MIPSDSP_Q0;
+    rs1 = (rs & MIPSDSP_Q1) >>  8;
+    rs2 = (rs & MIPSDSP_Q2) >> 16;
+    rs3 = (rs & MIPSDSP_Q3) >> 24;
+
+    rt0 =  rt & MIPSDSP_Q0;
+    rt1 = (rt & MIPSDSP_Q1) >>  8;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+
+    temp0 = mipsdsp_add_u8(rs0, rt0);
+    temp1 = mipsdsp_add_u8(rs1, rt1);
+    temp2 = mipsdsp_add_u8(rs2, rt2);
+    temp3 = mipsdsp_add_u8(rs3, rt3);
+
+    rd = (((uint32_t)temp3 << 24) & MIPSDSP_Q3) | \
+         (((uint32_t)temp2 << 16) & MIPSDSP_Q2) | \
+         (((uint32_t)temp1 <<  8) & MIPSDSP_Q1) | \
+         ((uint32_t)temp0 & MIPSDSP_Q0);
+
+    return rd;
+}
+
+uint32_t helper_addusqb(uint32_t rs, uint32_t rt)
+{
+    uint32_t rd;
+    uint8_t rs0, rs1, rs2, rs3;
+    uint8_t rt0, rt1, rt2, rt3;
+    uint8_t temp0, temp1, temp2, temp3;
+
+    rs0 =  rs & MIPSDSP_Q0;
+    rs1 = (rs & MIPSDSP_Q1) >>  8;
+    rs2 = (rs & MIPSDSP_Q2) >> 16;
+    rs3 = (rs & MIPSDSP_Q3) >> 24;
+
+    rt0 =  rt & MIPSDSP_Q0;
+    rt1 = (rt & MIPSDSP_Q1) >>  8;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+
+    temp0 = mipsdsp_sat_add_u8(rs0, rt0);
+    temp1 = mipsdsp_sat_add_u8(rs1, rt1);
+    temp2 = mipsdsp_sat_add_u8(rs2, rt2);
+    temp3 = mipsdsp_sat_add_u8(rs3, rt3);
+
+    rd = (((uint8_t)temp3 << 24) & MIPSDSP_Q3) | \
+         (((uint8_t)temp2 << 16) & MIPSDSP_Q2) | \
+         (((uint8_t)temp1 <<  8) & MIPSDSP_Q1) | \
+         ((uint8_t)temp0 & MIPSDSP_Q0);
+
+    return rd;
+}
+
+uint32_t helper_adduhqb(uint32_t rs, uint32_t rt)
+{
+    uint32_t rd;
+    uint8_t  rs0, rs1, rs2, rs3;
+    uint8_t  rt0, rt1, rt2, rt3;
+    uint8_t  temp0, temp1, temp2, temp3;
+
+    rs0 =  rs & MIPSDSP_Q0;
+    rs1 = (rs & MIPSDSP_Q1) >>  8;
+    rs2 = (rs & MIPSDSP_Q2) >> 16;
+    rs3 = (rs & MIPSDSP_Q3) >> 24;
+
+    rt0 =  rt & MIPSDSP_Q0;
+    rt1 = (rt & MIPSDSP_Q1) >>  8;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+
+    temp0 = mipsdsp_rshift1_add_u8(rs0, rt0);
+    temp1 = mipsdsp_rshift1_add_u8(rs1, rt1);
+    temp2 = mipsdsp_rshift1_add_u8(rs2, rt2);
+    temp3 = mipsdsp_rshift1_add_u8(rs3, rt3);
+
+    rd = (((uint32_t)temp3 << 24) & MIPSDSP_Q3) | \
+         (((uint32_t)temp2 << 16) & MIPSDSP_Q2) | \
+         (((uint32_t)temp1 <<  8) & MIPSDSP_Q1) | \
+         ((uint32_t)temp0        & MIPSDSP_Q0);
+
+    return rd;
+}
+
+uint32_t helper_adduhrqb(uint32_t rs, uint32_t rt)
+{
+    uint32_t rd;
+    uint8_t  rs0, rs1, rs2, rs3;
+    uint8_t  rt0, rt1, rt2, rt3;
+    uint8_t  temp0, temp1, temp2, temp3;
+
+    rs0 =  rs & MIPSDSP_Q0;
+    rs1 = (rs & MIPSDSP_Q1) >>  8;
+    rs2 = (rs & MIPSDSP_Q2) >> 16;
+    rs3 = (rs & MIPSDSP_Q3) >> 24;
+
+    rt0 =  rt & MIPSDSP_Q0;
+    rt1 = (rt & MIPSDSP_Q1) >>  8;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+
+    temp0 = mipsdsp_rrshift1_add_u8(rs0, rt0);
+    temp1 = mipsdsp_rrshift1_add_u8(rs1, rt1);
+    temp2 = mipsdsp_rrshift1_add_u8(rs2, rt2);
+    temp3 = mipsdsp_rrshift1_add_u8(rs3, rt3);
+
+    rd = (((uint32_t)temp3 << 24) & MIPSDSP_Q3) | \
+         (((uint32_t)temp2 << 16) & MIPSDSP_Q2) | \
+         (((uint32_t)temp1 <<  8) & MIPSDSP_Q1) | \
+         ((uint32_t)temp0 & MIPSDSP_Q0);
+
+    return rd;
+}
+
+uint32_t helper_append(uint32_t rt, uint32_t rs, int sa)
+{
+    int len;
+    uint32_t temp;
+
+    len = sa & 0x1F;
+
+    if (len == 0)
+        temp = rt;
+    else {
+        temp = (rt << len) | (rs & (((uint32_t)0x01 << len) - 1));
+    }
+    rt = temp;
+
+    return temp;
+}
+
+uint32_t helper_balign(uint32_t rt, uint32_t rs, uint32_t bp)
+{
+    uint32_t temp;
+    bp = bp & 0x03;
+
+    if (bp == 0 || bp == 2)
+        return rt;
+    else
+        temp = (rt << (8 * bp)) | (rs >> (8 * (4 - bp)));
+    rt = temp;
+
+    return rt;
+}
+
+
+uint32_t helper_cmpgdueqqb(uint32_t rs, uint32_t rt)
+{
+    uint32_t rd;
+    uint8_t  rs0, rs1, rs2, rs3;
+    uint8_t  rt0, rt1, rt2, rt3;
+    uint32_t cc0 = 0, cc1 = 0, cc2 = 0, cc3 = 0;
+    uint32_t flag;
+
+    rs0 =  rs & MIPSDSP_Q0;
+    rs1 = (rs & MIPSDSP_Q1) >>  8;
+    rs2 = (rs & MIPSDSP_Q2) >> 16;
+    rs3 = (rs & MIPSDSP_Q3) >> 24;
+
+    rt0 =  rt & MIPSDSP_Q0;
+    rt1 = (rt & MIPSDSP_Q1) >>  8;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+
+    if (rs0 == rt0)
+        cc0 = 1;
+
+    if (rs1 == rt1)
+        cc1 = 1;
+
+    if (rs2 == rt2)
+        cc2 = 1;
+
+    if (rs3 == rt3)
+        cc3 = 1;
+
+    flag = (cc3 << 3) | (cc2 << 2) | (cc1 << 1) | cc0;
+    set_DSPControl_24(flag, 4);
+    rd = flag;
+
+    return rd;
+}
+
+uint32_t helper_cmpgdultqb(uint32_t rs, uint32_t rt)
+{
+    uint32_t rd;
+    uint8_t  rs0, rs1, rs2, rs3;
+    uint8_t  rt0, rt1, rt2, rt3;
+    uint32_t cc0 = 0, cc1 = 0, cc2 = 0, cc3 = 0;
+    uint32_t flag;
+
+    rs0 =  rs & MIPSDSP_Q0;
+    rs1 = (rs & MIPSDSP_Q1) >>  8;
+    rs2 = (rs & MIPSDSP_Q2) >> 16;
+    rs3 = (rs & MIPSDSP_Q3) >> 24;
+    rt0 =  rt & MIPSDSP_Q0;
+    rt1 = (rt & MIPSDSP_Q1) >>  8;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+
+    if (rs0 < rt0)
+        cc0 = 1;
+
+    if (rs1 < rt1)
+        cc1 = 1;
+
+    if (rs2 < rt2)
+        cc2 = 1;
+
+    if (rs3 < rt3)
+        cc3 = 1;
+
+    flag = (cc3 << 3) | (cc2 << 2) | (cc1 << 1) | cc0;
+    set_DSPControl_24(flag, 4);
+    rd = flag;
+
+    return rd;
+}
+
+uint32_t helper_cmpgduleqb(uint32_t rs, uint32_t rt)
+{
+    uint32_t rd;
+    uint8_t  rs0, rs1, rs2, rs3;
+    uint8_t  rt0, rt1, rt2, rt3;
+    uint32_t cc0 = 0, cc1 = 0, cc2 = 0, cc3 = 0;
+    uint32_t flag;
+
+    rs0 =  rs & MIPSDSP_Q0;
+    rs1 = (rs & MIPSDSP_Q1) >>  8;
+    rs2 = (rs & MIPSDSP_Q2) >> 16;
+    rs3 = (rs & MIPSDSP_Q3) >> 24;
+
+    rt0 =  rt & MIPSDSP_Q0;
+    rt1 = (rt & MIPSDSP_Q1) >>  8;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+
+    if (rs0 <= rt0)
+        cc0 = 1;
+
+    if (rs1 <= rt1)
+        cc1 = 1;
+
+    if (rs2 <= rt2)
+        cc2 = 1;
+
+    if (rs3 <= rt3)
+        cc3 = 1;
+
+    flag = (cc3 << 3) | (cc2 << 2) | (cc1 << 1) | cc0;
+    set_DSPControl_24(flag, 4);
+    rd = flag;
+
+    return rd;
+}
+
+void helper_dpawph(int ac, uint32_t rs, uint32_t rt)
+{
+    uint16_t rsh, rsl, rth, rtl;
+    int32_t  tempA, tempB;
+    int64_t  acc, tempAL, tempBL;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+
+    tempB = (int32_t)rsh * (int32_t)rth;
+    tempA = (int32_t)rsl * (int32_t)rtl;
+    tempBL = tempB;
+    tempAL = tempA;
+
+    acc = ((uint64_t)env->active_tc.HI[ac] << 32) | \
+          ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
+    acc += tempBL + tempAL;
+
+    env->active_tc.HI[ac] = (acc & MIPSDSP_LHI) >> 32;
+    env->active_tc.LO[ac] =  acc & MIPSDSP_LLO;
+}
+
+void helper_dpaqxswph(int ac, uint32_t rs, uint32_t rt)
+{
+    uint16_t rsh, rsl, rth, rtl;
+    int32_t tempB, tempA;
+    int64_t acc, dotp, tempBL, tempAL;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+
+    tempB = mipsdsp_mul_q15_q15(ac, rsh, rtl);
+    tempA = mipsdsp_mul_q15_q15(ac, rsl, rth);
+    tempBL = tempB;
+    tempAL = tempA;
+    dotp = tempBL + tempAL;
+    acc = ((uint64_t)env->active_tc.HI[ac] << 32) | \
+          ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
+    acc += dotp;
+
+    env->active_tc.HI[ac] = (acc & MIPSDSP_LHI) >> 32;
+    env->active_tc.LO[ac] =  acc & MIPSDSP_LLO;
+}
+
+void helper_dpaqxsawph(int ac, uint32_t rs, uint32_t rt)
+{
+    int16_t rsh, rsl, rth, rtl;
+    int32_t tempB, tempA, tempC62_31, tempC63;
+    int64_t acc, dotp, tempBL, tempAL, tempC;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+
+    tempB = mipsdsp_mul_q15_q15(ac, rsh, rtl);
+    tempA = mipsdsp_mul_q15_q15(ac, rsl, rth);
+    tempBL = tempB;
+    tempAL = tempA;
+    dotp = tempBL + tempAL;
+    acc = ((uint64_t)env->active_tc.HI[ac] << 32) | \
+          ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
+    tempC = acc + dotp;
+    tempC63 = (tempC >> 63) & 0x01;
+    tempC62_31 = (tempC >> 31) & 0xFFFFFFFF;
+
+    if ((tempC63 == 0) && (tempC62_31 == 0xFFFFFFFF)) {
+        tempC = 0x80000000;
+        set_DSPControl_overflow_flag(1, 16 + ac);
+    }
+
+    env->active_tc.HI[ac] = (tempC & MIPSDSP_LHI) >> 32;
+    env->active_tc.LO[ac] =  tempC & MIPSDSP_LLO;
+}
+
+void helper_dpaxwph(int ac, uint32_t rs, uint32_t rt)
+{
+    uint16_t rsh, rsl, rth, rtl;
+    int32_t tempB, tempA;
+    int64_t acc, dotp, tempBL, tempAL;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+
+    tempB  = (uint32_t)rsh * (uint32_t)rth;
+    tempA  = (uint32_t)rsl * (uint32_t)rtl;
+    tempBL = tempB;
+    tempAL = tempA;
+    dotp =  tempBL + tempAL;
+    acc  =  ((uint64_t)env->active_tc.HI[ac] << 32) | \
+            ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
+    acc  += dotp;
+
+    env->active_tc.HI[ac] = (acc & MIPSDSP_LHI) >> 32;
+    env->active_tc.LO[ac] =  acc & MIPSDSP_LLO;
+}
+
+void helper_dpswph(int ac, uint32_t rs, uint32_t rt)
+{
+    uint16_t rsh, rsl, rth, rtl;
+    int32_t tempB, tempA;
+    int64_t acc, dotp, tempBL, tempAL;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+
+    tempB  = (int32_t)rsh * (int32_t)rth;
+    tempA  = (int32_t)rsl * (int32_t)rtl;
+    tempBL = tempB;
+    tempAL = tempA;
+    dotp =  tempBL + tempAL;
+    acc  =  ((uint64_t)env->active_tc.HI[ac] << 32) | \
+            ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
+    acc  -= dotp;
+
+    env->active_tc.HI[ac] = (acc & MIPSDSP_LHI) >> 32;
+    env->active_tc.LO[ac] =  acc & MIPSDSP_LLO;
+}
+
+void helper_dpsqxswph(int ac, uint32_t rs, uint32_t rt)
+{
+    int16_t rsh, rsl, rth, rtl;
+    int32_t tempB, tempA;
+    int64_t dotp, tempC, tempBL, tempAL;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+
+    tempB = mipsdsp_mul_q15_q15(ac, rsh, rtl);
+    tempA = mipsdsp_mul_q15_q15(ac, rsl, rth);
+    tempBL = tempB;
+    tempAL = tempA;
+    dotp = tempBL + tempAL;
+    tempC = (((uint64_t)env->active_tc.HI[ac] << 32) | \
+            ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO)) - dotp;
+
+    env->active_tc.HI[ac] = (tempC & MIPSDSP_LHI) >> 32;
+    env->active_tc.LO[ac] =  tempC & MIPSDSP_LLO;
+}
+
+void helper_dpsqxsawph(int ac, uint32_t rs, uint32_t rt)
+{
+    int16_t rsh, rsl, rth, rtl;
+    int32_t tempB, tempA, tempC63, tempC62_31;
+    int64_t dotp, tempBL, tempAL, tempC;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+    tempB = mipsdsp_mul_q15_q15(ac, rsh, rtl);
+    tempA = mipsdsp_mul_q15_q15(ac, rsl, rth);
+
+    tempBL = tempB;
+    tempAL = tempA;
+    dotp   = tempBL + tempAL;
+    tempC  = ((uint64_t)env->active_tc.HI[ac] << 32) | \
+             ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
+    tempC -= dotp;
+
+    tempC63 = (tempC >> 63) & 0x01;
+    tempC62_31 = (tempC >> 31) & 0xFFFFFFFF;
+
+    if ((tempC63 == 0) && (tempC62_31 != 0)) {
+        tempC = 0x7FFFFFFF;
+        set_DSPControl_overflow_flag(1, 16 + ac);
+    }
+
+    if ((tempC63 == 1) && (tempC62_31 != 0xFFFFFFFF)) {
+        tempC = 0xFFFFFFFF80000000;
+        set_DSPControl_overflow_flag(1, 16 + ac);
+    }
+
+    env->active_tc.HI[ac] = (tempC & MIPSDSP_LHI) >> 32;
+    env->active_tc.LO[ac] =  tempC & MIPSDSP_LLO;
+}
+
+void helper_dpsxwph(int ac, uint32_t rs, uint32_t rt)
+{
+    uint16_t rsh, rsl, rth, rtl;
+    int32_t  tempB,  tempA;
+    int64_t acc, dotp, tempBL, tempAL;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+
+    tempB = (int32_t)rsh * (int32_t)rtl;
+    tempA = (int32_t)rsl * (int32_t)rth;
+    tempBL = tempB;
+    tempAL = tempA;
+    dotp = tempBL + tempAL;
+
+    acc  = ((uint64_t)env->active_tc.HI[ac] << 32) | \
+           ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
+    acc -= dotp;
+    env->active_tc.HI[ac] = (acc & MIPSDSP_LHI) >> 32;
+    env->active_tc.LO[ac] =  acc & MIPSDSP_LLO;
+}
+
+uint32_t helper_mulph(uint32_t rs, uint32_t rt)
+{
+    int16_t rsh, rsl, rth, rtl;
+    int32_t tempB, tempA;
+    uint32_t rd;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+    tempB = mipsdsp_mul_i16_i16(rsh, rth);
+    tempA = mipsdsp_mul_i16_i16(rsl, rtl);
+
+    rd = ((tempB & MIPSDSP_LO) << 16) | (tempA & MIPSDSP_LO);
+
+    return rd;
+}
+
+uint32_t helper_mulsph(uint32_t rs, uint32_t rt)
+{
+    int16_t  rsh, rsl, rth, rtl;
+    int32_t  tempB, tempA;
+    uint32_t rd;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+    tempB = mipsdsp_sat16_mul_i16_i16(rsh, rth);
+    tempA = mipsdsp_sat16_mul_i16_i16(rsl, rtl);
+
+    rd = ((tempB & MIPSDSP_LO) << 16) | (tempA & MIPSDSP_LO);
+
+    return rd;
+}
+
+uint32_t helper_mulqsph(uint32_t rs, uint32_t rt)
+{
+    int16_t rsh, rsl, rth, rtl;
+    int32_t temp, tempB, tempA;
+    uint32_t rd;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+
+    tempB = mipsdsp_sat16_mul_q15_q15(rsh, rth);
+    tempA = mipsdsp_sat16_mul_q15_q15(rsl, rtl);
+    temp = ((tempB & MIPSDSP_LO) << 16) | (tempA & MIPSDSP_LO);
+    rd = temp;
+
+    return rd;
+}
+
+uint32_t helper_mulqrsw(uint32_t rs, uint32_t rt)
+{
+    uint32_t rd;
+    int32_t tempI;
+    int64_t tempL;
+
+    if ((rs == 0x80000000) && (rt == 0x80000000)) {
+        tempL = 0x7FFFFFFF00000000;
+        set_DSPControl_overflow_flag(1, 21);
+    } else {
+        tempL  = ((int64_t)rs * (int64_t)rt) << 1;
+        tempL += 0x80000000;
+    }
+    tempI = (tempL & MIPSDSP_LHI) >> 32;
+    rd = tempI;
+
+    return rd;
+}
+
+uint32_t helper_mulqsw(uint32_t rs, uint32_t rt)
+{
+    uint32_t rd;
+    int32_t tempI;
+    int64_t tempL;
+
+    if ((rs == 0x80000000) && (rt == 0x80000000)) {
+        tempL = 0x7FFFFFFF00000000;
+        set_DSPControl_overflow_flag(1, 21);
+    } else {
+        tempL  = ((int64_t)rs * (int64_t)rt) << 1;
+    }
+    tempI = (tempL & MIPSDSP_LHI) >> 32;
+    rd = tempI;
+
+    return rd;
+}
+
+void helper_mulsawph(int ac, uint32_t rs, uint32_t rt)
+{
+    uint16_t rsh, rsl, rth, rtl;
+    int32_t tempB, tempA;
+    int64_t dotp, acc, tempBL, tempAL;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+
+    tempB = (int32_t)rsh * (int32_t)rth;
+    tempA = (int32_t)rsl * (int32_t)rtl;
+    tempBL = tempB;
+    tempAL = tempA;
+
+    dotp = tempBL - tempAL;
+    acc  = ((int64_t)env->active_tc.HI[ac] << 32) | \
+           ((int64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
+    acc = acc + dotp;
+
+    env->active_tc.HI[ac] = (acc & MIPSDSP_LHI) >> 32;
+    env->active_tc.LO[ac] =  acc & MIPSDSP_LLO;
+}
+
+uint32_t helper_precrqbph(uint32_t rs, uint32_t rt)
+{
+    uint8_t  rs2, rs0, rt2, rt0;
+    uint32_t rd;
+
+    rs2 = (rs & MIPSDSP_Q2) >> 16;
+    rs0 =  rs & MIPSDSP_Q0;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    rt0 =  rt & MIPSDSP_Q0;
+    rd = ((uint32_t)rs2 << 24) | ((uint32_t)rs0 << 16) | \
+         ((uint32_t)rt2 << 8) | (uint32_t)rt0;
+
+    return rd;
+}
+
+uint32_t helper_precrsraphw(int sa, uint32_t rs, uint32_t rt)
+{
+    uint16_t tempB, tempA;
+
+    if (sa == 0) {
+        tempB = rt & MIPSDSP_LO;
+        tempA = rs & MIPSDSP_LO;
+    } else {
+        tempB = ((int32_t)rt >> sa) & MIPSDSP_LO;
+        tempA = ((int32_t)rs >> sa) & MIPSDSP_LO;
+    }
+    rt = ((uint32_t)tempB << 16) | ((uint32_t)tempA & MIPSDSP_LO);
+
+    return rt;
+}
+
+uint32_t helper_precrsrarphw(int sa, uint32_t rs, uint32_t rt)
+{
+    uint64_t tempB, tempA;
+
+    if (sa == 0) {
+        tempB = (rt & MIPSDSP_LO) << 1;
+        tempA = (rs & MIPSDSP_LO) << 1;
+    } else {
+        tempB = ((int32_t)rt >> (sa - 1)) + 1;
+        tempA = ((int32_t)rs >> (sa - 1)) + 1;
+    }
+    rt = (((tempB >> 1) & MIPSDSP_LO) << 16) | ((tempA >> 1) & MIPSDSP_LO);
+
+    return rt;
+}
+
+uint32_t helper_prepend(int sa, uint32_t rs, uint32_t rt)
+{
+    uint32_t temp;
+
+    if (sa == 0)
+        temp = rt;
+    else
+        temp = (rs << (32 - sa)) | rt >> sa;
+
+    rt = temp;
+
+    return rt;
+}
+
+uint32_t helper_shraqb(int sa, uint32_t rt)
+{
+    int8_t  rt3, rt2, rt1, rt0;
+    uint8_t tempD, tempC, tempB, tempA;
+    uint32_t rd;
+
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    rt1 = (rt & MIPSDSP_Q1) >>  8;
+    rt0 =  rt & MIPSDSP_Q0;
+
+    tempD = rt3 >> sa;
+    tempC = rt2 >> sa;
+    tempB = rt1 >> sa;
+    tempA = rt0 >> sa;
+
+    rd = ((uint32_t)tempD << 24) | ((uint32_t)tempC << 16) | \
+          ((uint32_t)tempB << 8) | (uint32_t)tempA;
+
+    return rd;
+}
+
+uint32_t helper_shrarqb(int sa, uint32_t rt)
+{
+    int8_t  rt3, rt2, rt1, rt0;
+    uint16_t tempD, tempC, tempB, tempA;
+    uint32_t rd;
+
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    rt1 = (rt & MIPSDSP_Q1) >>  8;
+    rt0 =  rt & MIPSDSP_Q0;
+
+    if (sa == 0) {
+        tempD = rt3 & 0x00FF;
+        tempC = rt2 & 0x00FF;
+        tempB = rt1 & 0x00FF;
+        tempA = rt0 & 0x00FF;
+    } else {
+        tempD = ((int16_t)rt3 >> (sa - 1)) + 1;
+        tempC = ((int16_t)rt2 >> (sa - 1)) + 1;
+        tempB = ((int16_t)rt1 >> (sa - 1)) + 1;
+        tempA = ((int16_t)rt0 >> (sa - 1)) + 1;
+    }
+
+    rd = ((uint32_t)((tempD >> 1) & 0x00FF) << 24) | \
+         ((uint32_t)((tempC >> 1) & 0x00FF) << 16) | \
+         ((uint32_t)((tempB >> 1) & 0x00FF) <<  8) | \
+         (uint32_t)((tempA >> 1) & 0x00FF) ;
+
+    return rd;
+}
+
+uint32_t helper_shravqb(uint32_t rs, uint32_t rt)
+{
+    uint8_t  rs2_0;
+    int8_t   rt3, rt2, rt1, rt0;
+    uint8_t  tempD, tempC, tempB, tempA;
+    uint32_t rd;
+
+    rs2_0 = rs & 0x07;
+    rt3   = (rt & MIPSDSP_Q3) >> 24;
+    rt2   = (rt & MIPSDSP_Q2) >> 16;
+    rt1   = (rt & MIPSDSP_Q1) >>  8;
+    rt0   =  rt & MIPSDSP_Q0;
+
+    if (rs2_0 == 0) {
+        tempD = rt3;
+        tempC = rt2;
+        tempB = rt1;
+        tempA = rt0;
+    } else {
+        tempD = rt3 >> rs2_0;
+        tempC = rt2 >> rs2_0;
+        tempB = rt1 >> rs2_0;
+        tempA = rt0 >> rs2_0;
+    }
+
+    rd = ((uint32_t)tempD << 24) | ((uint32_t)tempC << 16) | \
+         ((uint32_t)tempB << 8) | (uint32_t)tempA;
+
+    return rd;
+}
+
+uint32_t helper_shravrqb(uint32_t rs, uint32_t rt)
+{
+    uint8_t rs2_0;
+    int8_t  rt3, rt2, rt1, rt0;
+    uint16_t tempD, tempC, tempB, tempA;
+    uint32_t rd;
+
+    rs2_0 = rs & 0x07;
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    rt1 = (rt & MIPSDSP_Q1) >>  8;
+    rt0 =  rt & MIPSDSP_Q0;
+
+    if (rs2_0 == 0) {
+        tempD = (int16_t)rt3 << 1;
+        tempC = (int16_t)rt2 << 1;
+        tempB = (int16_t)rt1 << 1;
+        tempA = (int16_t)rt0 << 1;
+    } else {
+        tempD = ((int16_t)rt3 >> (rs2_0 - 1)) + 1;
+        tempC = ((int16_t)rt2 >> (rs2_0 - 1)) + 1;
+        tempB = ((int16_t)rt1 >> (rs2_0 - 1)) + 1;
+        tempA = ((int16_t)rt0 >> (rs2_0 - 1)) + 1;
+    }
+
+    rd = ((uint32_t)((tempD >> 1) & 0x00FF) << 24) | \
+         ((uint32_t)((tempC >> 1) & 0x00FF) << 16) | \
+         ((uint32_t)((tempB >> 1) & 0x00FF) <<  8) | \
+         (uint32_t)((tempA >> 1) & 0x00FF) ;
+
+    return rd;
+}
+
+uint32_t helper_shrlph(int sa, uint32_t rt)
+{
+    uint16_t rth, rtl;
+    uint16_t tempB, tempA;
+    uint32_t rd;
+
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+    tempB = rth >> sa;
+    tempA = rtl >> sa;
+    rd = ((uint32_t)tempB << 16) | (uint32_t)tempA;
+
+    return rd;
+}
+
+uint32_t helper_shrlvph(uint32_t rs, uint32_t rt)
+{
+    uint8_t  rs3_0;
+    uint16_t rth, rtl;
+    uint16_t tempB, tempA;
+    uint32_t rd;
+
+    rs3_0 = rs & 0x0F;
+    rth   = (rt & MIPSDSP_HI) >> 16;
+    rtl   =  rt & MIPSDSP_LO;
+
+    tempB = rth >> rs3_0;
+    tempA = rtl >> rs3_0;
+    rd = ((uint32_t)tempB << 16) | (uint32_t)tempA;
+
+    return rd;
+}
+
+uint32_t helper_subqhph(uint32_t rs, uint32_t rt)
+{
+    uint16_t rsh, rsl;
+    uint16_t rth, rtl;
+    uint16_t tempB, tempA;
+    uint32_t rd;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+    tempB = mipsdsp_rshift1_sub_q16(rsh, rth);
+    tempA = mipsdsp_rshift1_sub_q16(rsl, rtl);
+    rd = ((uint32_t)tempB << 16) | (uint32_t)tempA;
+
+    return rd;
+}
+
+uint32_t helper_subqhrph(uint32_t rs, uint32_t rt)
+{
+    uint16_t rsh, rsl;
+    uint16_t rth, rtl;
+    uint16_t tempB, tempA;
+    uint32_t rd;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+    tempB = mipsdsp_rrshift1_sub_q16(rsh, rth);
+    tempA = mipsdsp_rrshift1_sub_q16(rsl, rtl);
+    rd = ((uint32_t)tempB << 16) | (uint32_t)tempA;
+
+    return rd;
+}
+
+uint32_t helper_subqhw(uint32_t rs, uint32_t rt)
+{
+    uint32_t rd;
+
+    rd = mipsdsp_rshift1_sub_q32(rs, rt);
+
+    return rd;
+}
+
+uint32_t helper_subqhrw(uint32_t rs, uint32_t rt)
+{
+    uint32_t rd;
+
+    rd = mipsdsp_rrshift1_sub_q32(rs, rt);
+
+    return rd;
+}
+
+uint32_t helper_subuph(uint32_t rs, uint32_t rt)
+{
+    uint16_t rsh, rsl, rth, rtl;
+    uint16_t tempB, tempA;
+    uint32_t rd;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+
+    tempB = mipsdsp_sub_u16_u16(rth, rsh);
+    tempA = mipsdsp_sub_u16_u16(rtl, rsl);
+    rd = ((uint32_t)tempB << 16) | (uint32_t)tempA;
+    return rd;
+}
+
+uint32_t helper_subusph(uint32_t rs, uint32_t rt)
+{
+    uint16_t rsh, rsl, rth, rtl;
+    uint16_t tempB, tempA;
+    uint32_t rd;
+
+    rsh = (rs & MIPSDSP_HI) >> 16;
+    rsl =  rs & MIPSDSP_LO;
+    rth = (rt & MIPSDSP_HI) >> 16;
+    rtl =  rt & MIPSDSP_LO;
+
+    tempB = mipsdsp_satu16_sub_u16_u16(rth, rsh);
+    tempA = mipsdsp_satu16_sub_u16_u16(rtl, rsl);
+    rd = ((uint32_t)tempB << 16) | (uint32_t)tempA;
+
+    return rd;
+}
+
+uint32_t helper_subuhqb(uint32_t rs, uint32_t rt)
+{
+    uint8_t rs3, rs2, rs1, rs0;
+    uint8_t rt3, rt2, rt1, rt0;
+    uint8_t tempD, tempC, tempB, tempA;
+    uint32_t rd;
+
+    rs3 = (rs & MIPSDSP_Q3) >> 24;
+    rs2 = (rs & MIPSDSP_Q2) >> 16;
+    rs1 = (rs & MIPSDSP_Q1) >>  8;
+    rs0 =  rs & MIPSDSP_Q0;
+
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    rt1 = (rt & MIPSDSP_Q1) >>  8;
+    rt0 =  rt & MIPSDSP_Q0;
+
+    tempD = ((uint16_t)rs3 - (uint16_t)rt3) >> 1;
+    tempC = ((uint16_t)rs2 - (uint16_t)rt2) >> 1;
+    tempB = ((uint16_t)rs1 - (uint16_t)rt1) >> 1;
+    tempA = ((uint16_t)rs0 - (uint16_t)rt0) >> 1;
+
+    rd = ((uint32_t)tempD << 24) | ((uint32_t)tempC << 16) | \
+         ((uint32_t)tempB << 8) | (uint32_t)tempA;
+
+    return rd;
+}
+
+uint32_t helper_subuhrqb(uint32_t rs, uint32_t rt)
+{
+    uint8_t rs3, rs2, rs1, rs0;
+    uint8_t rt3, rt2, rt1, rt0;
+    uint8_t tempD, tempC, tempB, tempA;
+    uint32_t rd;
+
+    rs3 = (rs & MIPSDSP_Q3) >> 24;
+    rs2 = (rs & MIPSDSP_Q2) >> 16;
+    rs1 = (rs & MIPSDSP_Q1) >>  8;
+    rs0 =  rs & MIPSDSP_Q0;
+
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    rt1 = (rt & MIPSDSP_Q1) >>  8;
+    rt0 =  rt & MIPSDSP_Q0;
+
+    tempD = ((uint16_t)rs3 - (uint16_t)rt3 + 1) >> 1;
+    tempC = ((uint16_t)rs2 - (uint16_t)rt2 + 1) >> 1;
+    tempB = ((uint16_t)rs1 - (uint16_t)rt1 + 1) >> 1;
+    tempA = ((uint16_t)rs0 - (uint16_t)rt0 + 1) >> 1;
+
+    rd = ((uint32_t)tempD << 24) | ((uint32_t)tempC << 16) | \
+         ((uint32_t)tempB << 8) | (uint32_t)tempA;
+
+    return rd;
+}
+
+#undef MIPSDSP_LHI
+#undef MIPSDSP_LLO
+#undef MIPSDSP_HI
+#undef MIPSDSP_LO
+#undef MIPSDSP_Q0
+#undef MIPSDSP_Q1
+#undef MIPSDSP_Q2
+#undef MIPSDSP_Q3
+
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH V2 3/4] add MIPS DSP translation
  2012-03-22 13:36 [Qemu-devel] [PATCH V2 0/4] MIPS ASE DSP Support for Qemu Jia Liu
  2012-03-22 13:36 ` [Qemu-devel] [PATCH V2 1/4] add MIPS DSP helpers define Jia Liu
  2012-03-22 13:36 ` [Qemu-devel] [PATCH V2 2/4] add MIPS DSP helpers implement Jia Liu
@ 2012-03-22 13:36 ` Jia Liu
  2012-03-22 13:36 ` [Qemu-devel] [PATCH V2 4/4] add MIPS DSP testcase Jia Liu
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Jia Liu @ 2012-03-22 13:36 UTC (permalink / raw)
  To: qemu-devel; +Cc: sw, aurelien

This is the translation of MIPS ASE DSP.

Signed-off-by: Jia Liu <proljc@gmail.com>
---

Version History:

V2:
- Addressed Stefan's review comments, changed acc into unsigned int form int, and no initialization.
- Coding style fixed.

V1:
- add MIPS ASE DSP translation.

 target-mips/translate.c | 1110 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 1086 insertions(+), 24 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index a663b74..0c6c7b0 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -249,6 +249,11 @@ enum {
     OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
 };
 
+/* REGIMM mipsdsp opcodes */
+enum {
+    OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
+};
+
 /* Special2 opcodes */
 #define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
 
@@ -312,6 +317,21 @@ enum {
     OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
     OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
     OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
+
+    /* MIPS DSP */
+    OPC_ABSQ_S_PH_DSP  = 0x12 | OPC_SPECIAL3,
+    OPC_ADDU_QB_DSP    = 0x10 | OPC_SPECIAL3,
+    /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
+    /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3,     */
+    OPC_APPEND_DSP     = 0x31 | OPC_SPECIAL3,
+    OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
+    OPC_DPA_W_PH_DSP   = 0x30 | OPC_SPECIAL3,
+    OPC_EXTR_W_DSP     = 0x38 | OPC_SPECIAL3,
+    OPC_INSV_DSP       = 0x0C | OPC_SPECIAL3,
+    OPC_LX_DSP         = 0x0A | OPC_SPECIAL3,
+    /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP.   */
+    /* OPC_MUL_PH_DSP  = 0x18 | OPC_SPECIAL3,   */
+    OPC_SHLL_QB_DSP    = 0x13 | OPC_SPECIAL3,
 };
 
 /* BSHFL opcodes */
@@ -331,6 +351,231 @@ enum {
     OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
 };
 
+#define MASK_ABSQ_S_PH(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
+/* MIPS DSP */
+enum {
+    OPC_ABSQ_S_PH       = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
+    OPC_ABSQ_S_W        = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
+    OPC_BITREV          = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
+    OPC_PRECEQ_W_PHL    = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
+    OPC_PRECEQ_W_PHR    = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
+    OPC_PRECEQU_PH_QBL  = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
+    OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
+    OPC_PRECEQU_PH_QBR  = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
+    OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
+    OPC_PRECEU_PH_QBL   = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
+    OPC_PRECEU_PH_QBLA  = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
+    OPC_PRECEU_PH_QBR   = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
+    OPC_PRECEU_PH_QBRA  = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
+    OPC_REPL_PH         = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
+    OPC_REPL_QB         = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
+    OPC_REPLV_PH        = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
+    OPC_REPLV_QB        = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
+};
+
+/* MIPS DSPR2 */
+enum {
+    OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
+};
+
+#define MASK_ADDU_QB(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
+/* MIPS DSP */
+enum {
+    OPC_ADDQ_PH        = (0x0A << 6) | OPC_ADDU_QB_DSP,
+    OPC_ADDQ_S_PH      = (0x0E << 6) | OPC_ADDU_QB_DSP,
+    OPC_ADDQ_S_W       = (0x16 << 6) | OPC_ADDU_QB_DSP,
+    OPC_ADDSC          = (0x10 << 6) | OPC_ADDU_QB_DSP,
+    OPC_ADDU_QB        = (0x00 << 6) | OPC_ADDU_QB_DSP,
+    OPC_ADDU_S_QB      = (0x04 << 6) | OPC_ADDU_QB_DSP,
+    OPC_ADDWC          = (0x11 << 6) | OPC_ADDU_QB_DSP,
+    OPC_MODSUB         = (0x12 << 6) | OPC_ADDU_QB_DSP,
+    OPC_MULEQ_S_W_PHL  = (0x1C << 6) | OPC_ADDU_QB_DSP,
+    OPC_MULEQ_S_W_PHR  = (0x1D << 6) | OPC_ADDU_QB_DSP,
+    OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
+    OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
+    OPC_MULQ_RS_PH     = (0x1F << 6) | OPC_ADDU_QB_DSP,
+    OPC_RADDU_W_QB     = (0x14 << 6) | OPC_ADDU_QB_DSP,
+    OPC_SUBQ_PH        = (0x0B << 6) | OPC_ADDU_QB_DSP,
+    OPC_SUBQ_S_PH      = (0x0F << 6) | OPC_ADDU_QB_DSP,
+    OPC_SUBQ_S_W       = (0x17 << 6) | OPC_ADDU_QB_DSP,
+    OPC_SUBU_QB        = (0x01 << 6) | OPC_ADDU_QB_DSP,
+    OPC_SUBU_S_QB      = (0x05 << 6) | OPC_ADDU_QB_DSP,
+};
+
+/* MIPS DSPR2 */
+enum {
+    OPC_ADDU_PH   = (0x08 << 6) | OPC_ADDU_QB_DSP,
+    OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
+    OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
+    OPC_SUBU_PH   = (0x09 << 6) | OPC_ADDU_QB_DSP,
+    OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
+};
+
+#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
+#define MASK_ADDUH_QB(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
+/* MIPS DSPR2 */
+enum {
+    OPC_ADDQH_PH   = (0x08 << 6) | OPC_ADDUH_QB_DSP,
+    OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
+    OPC_ADDQH_W    = (0x10 << 6) | OPC_ADDUH_QB_DSP,
+    OPC_ADDQH_R_W  = (0x12 << 6) | OPC_ADDUH_QB_DSP,
+    OPC_ADDUH_QB   = (0x00 << 6) | OPC_ADDUH_QB_DSP,
+    OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
+    OPC_MUL_PH     = (0x0C << 6) | OPC_ADDUH_QB_DSP,
+    OPC_MUL_S_PH   = (0x0E << 6) | OPC_ADDUH_QB_DSP,
+    OPC_SUBQH_PH   = (0x09 << 6) | OPC_ADDUH_QB_DSP,
+    OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
+    OPC_SUBQH_W    = (0x11 << 6) | OPC_ADDUH_QB_DSP,
+    OPC_SUBQH_R_W  = (0x13 << 6) | OPC_ADDUH_QB_DSP,
+    OPC_SUBUH_QB   = (0x01 << 6) | OPC_ADDUH_QB_DSP,
+    OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
+};
+
+#define OPC_MUL_PH_DSP OPC_ADDUH_QB_DSP
+/* #define MASK_MUL_PH(op) MASK_SPECIAL3(op) | (op & (0x1F << 6)) */
+/* MIPS DSPR2 */
+enum {
+    OPC_MULQ_RS_W = (0x17 << 6) | OPC_MUL_PH_DSP,
+    OPC_MULQ_S_W  = (0x16 << 6) | OPC_MUL_PH_DSP,
+};
+
+#define MASK_APPEND(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
+/* MIPS DSPR2 */
+enum {
+    OPC_APPEND  = (0x00 << 6) | OPC_APPEND_DSP,
+    OPC_BALIGN  = (0x10 << 6) | OPC_APPEND_DSP,
+    OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
+};
+
+#define MASK_CMPU_EQ_QB(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
+/* MIPS DSP */
+enum {
+    OPC_CMP_EQ_PH       = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
+    OPC_CMP_LT_PH       = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
+    OPC_CMP_LE_PH       = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
+    OPC_CMPGU_EQ_QB     = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
+    OPC_CMPGU_LT_QB     = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
+    OPC_CMPGU_LE_QB     = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
+    OPC_CMPU_EQ_QB      = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
+    OPC_CMPU_LT_QB      = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
+    OPC_CMPU_LE_QB      = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
+    OPC_PACKRL_PH       = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
+    OPC_PICK_QB         = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
+    OPC_PICK_PH         = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
+    OPC_PRECRQ_QB_PH    = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
+    OPC_PRECRQ_PH_W     = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
+    OPC_PRECRQ_RS_PH_W  = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
+    OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
+};
+
+/* MIPS DSPR2 */
+enum {
+    OPC_CMPGDU_EQ_QB     = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
+    OPC_CMPGDU_LT_QB     = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
+    OPC_CMPGDU_LE_QB     = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
+    OPC_PRECR_QB_PH      = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
+    OPC_PRECR_SRA_PH_W   = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
+    OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
+};
+
+#define MASK_DPA_W_PH(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
+/* MIPS DSP */
+enum {
+    OPC_DPAQ_S_W_PH   = (0x04 << 6) | OPC_DPA_W_PH_DSP,
+    OPC_DPAQ_SA_L_W   = (0x0C << 6) | OPC_DPA_W_PH_DSP,
+    OPC_DPAU_H_QBL    = (0x03 << 6) | OPC_DPA_W_PH_DSP,
+    OPC_DPAU_H_QBR    = (0x07 << 6) | OPC_DPA_W_PH_DSP,
+    OPC_DPSQ_S_W_PH   = (0x05 << 6) | OPC_DPA_W_PH_DSP,
+    OPC_DPSQ_SA_L_W   = (0x0D << 6) | OPC_DPA_W_PH_DSP,
+    OPC_DPSU_H_QBL    = (0x0B << 6) | OPC_DPA_W_PH_DSP,
+    OPC_DPSU_H_QBR    = (0x0F << 6) | OPC_DPA_W_PH_DSP,
+    OPC_MAQ_S_W_PHL   = (0x14 << 6) | OPC_DPA_W_PH_DSP,
+    OPC_MAQ_SA_W_PHL  = (0x10 << 6) | OPC_DPA_W_PH_DSP,
+    OPC_MAQ_S_W_PHR   = (0x16 << 6) | OPC_DPA_W_PH_DSP,
+    OPC_MAQ_SA_W_PHR  = (0x12 << 6) | OPC_DPA_W_PH_DSP,
+    OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
+};
+
+/* MIPS DSPR2 */
+enum{
+    OPC_DPA_W_PH      = (0x00 << 6) | OPC_DPA_W_PH_DSP,
+    OPC_DPAQX_S_W_PH  = (0x18 << 6) | OPC_DPA_W_PH_DSP,
+    OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
+    OPC_DPAX_W_PH     = (0x08 << 6) | OPC_DPA_W_PH_DSP,
+    OPC_DPS_W_PH      = (0x01 << 6) | OPC_DPA_W_PH_DSP,
+    OPC_DPSQX_S_W_PH  = (0x19 << 6) | OPC_DPA_W_PH_DSP,
+    OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
+    OPC_DPSX_W_PH          = (0x09 << 6) | OPC_DPA_W_PH_DSP,
+    OPC_MULSA_W_PH    = (0x02 << 6) | OPC_DPA_W_PH_DSP,
+};
+
+#define MASK_EXTR_W(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
+/* MIPS DSP */
+enum {
+    OPC_EXTP       = (0x02 << 6) | OPC_EXTR_W_DSP,
+    OPC_EXTPDP     = (0x0A << 6) | OPC_EXTR_W_DSP,
+    OPC_EXTPDPV    = (0x0B << 6) | OPC_EXTR_W_DSP,
+    OPC_EXTPV      = (0x03 << 6) | OPC_EXTR_W_DSP,
+    OPC_EXTR_S_H   = (0x0E << 6) | OPC_EXTR_W_DSP,
+    OPC_EXTR_W     = (0x00 << 6) | OPC_EXTR_W_DSP,
+    OPC_EXTR_R_W   = (0x04 << 6) | OPC_EXTR_W_DSP,
+    OPC_EXTR_RS_W  = (0x06 << 6) | OPC_EXTR_W_DSP,
+    OPC_EXTRV_S_H  = (0x0F << 6) | OPC_EXTR_W_DSP,
+    OPC_EXTRV_W    = (0x01 << 6) | OPC_EXTR_W_DSP,
+    OPC_EXTRV_R_W  = (0x05 << 6) | OPC_EXTR_W_DSP,
+    OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
+    OPC_MTHLIP     = (0x1F << 6) | OPC_EXTR_W_DSP,
+    OPC_RDDSP      = (0x12 << 6) | OPC_EXTR_W_DSP,
+    OPC_SHILO      = (0x1A << 6) | OPC_EXTR_W_DSP,
+    OPC_SHILOV     = (0x1B << 6) | OPC_EXTR_W_DSP,
+    OPC_WRDSP      = (0x13 << 6) | OPC_EXTR_W_DSP,
+};
+
+#define MASK_INSV(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
+/* MIPS DSP */
+enum {
+    OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
+};
+
+#define MASK_LX(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
+/* MIPS DSP */
+enum {
+    OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
+    OPC_LHX  = (0x04 << 6) | OPC_LX_DSP,
+    OPC_LWX  = (0x00 << 6) | OPC_LX_DSP,
+};
+
+#define MASK_SHLL_QB(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
+/* MIPS DSP */
+enum {
+    OPC_SHLL_PH    = (0x08 << 6) | OPC_SHLL_QB_DSP,
+    OPC_SHLL_S_PH  = (0x0C << 6) | OPC_SHLL_QB_DSP,
+    OPC_SHLL_QB    = (0x00 << 6) | OPC_SHLL_QB_DSP,
+    OPC_SHLL_S_W   = (0x14 << 6) | OPC_SHLL_QB_DSP,
+    OPC_SHLLV_PH   = (0x0A << 6) | OPC_SHLL_QB_DSP,
+    OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
+    OPC_SHLLV_QB   = (0x02 << 6) | OPC_SHLL_QB_DSP,
+    OPC_SHLLV_S_W  = (0x16 << 6) | OPC_SHLL_QB_DSP,
+    OPC_SHRA_PH    = (0x09 << 6) | OPC_SHLL_QB_DSP,
+    OPC_SHRA_R_PH  = (0x0D << 6) | OPC_SHLL_QB_DSP,
+    OPC_SHRA_R_W   = (0x15 << 6) | OPC_SHLL_QB_DSP,
+    OPC_SHRAV_PH   = (0x0B << 6) | OPC_SHLL_QB_DSP,
+    OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
+    OPC_SHRAV_R_W  = (0x17 << 6) | OPC_SHLL_QB_DSP,
+    OPC_SHRL_QB    = (0x01 << 6) | OPC_SHLL_QB_DSP,
+    OPC_SHRLV_QB   = (0x03 << 6) | OPC_SHLL_QB_DSP,
+};
+
+/* MIPS DSPR2 */
+enum {
+    OPC_SHRA_QB    = (0x04 << 6) | OPC_SHLL_QB_DSP,
+    OPC_SHRA_R_QB  = (0x05 << 6) | OPC_SHLL_QB_DSP,
+    OPC_SHRAV_QB   = (0x06 << 6) | OPC_SHLL_QB_DSP,
+    OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
+    OPC_SHRL_PH    = (0x19 << 6) | OPC_SHLL_QB_DSP,
+    OPC_SHRLV_PH   = (0x1B << 6) | OPC_SHLL_QB_DSP,
+};
+
 /* Coprocessor 0 (rs field) */
 #define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
 
@@ -1972,6 +2217,7 @@ static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
 {
     const char *opn = "hilo";
+    unsigned int acc;
 
     if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
         /* Treat as NOP. */
@@ -1980,25 +2226,29 @@ static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
     }
     switch (opc) {
     case OPC_MFHI:
-        tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
+        acc = ((ctx->opcode) >> 21) & 0x03;
+        tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
         opn = "mfhi";
         break;
     case OPC_MFLO:
-        tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
+        acc = ((ctx->opcode) >> 21) & 0x03;
+        tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
         opn = "mflo";
         break;
     case OPC_MTHI:
+        acc = ((ctx->opcode) >> 11) & 0x03;
         if (reg != 0)
-            tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
+            tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
         else
-            tcg_gen_movi_tl(cpu_HI[0], 0);
+            tcg_gen_movi_tl(cpu_HI[acc], 0);
         opn = "mthi";
         break;
     case OPC_MTLO:
+        acc = ((ctx->opcode) >> 11) & 0x03;
         if (reg != 0)
-            tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
+            tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
         else
-            tcg_gen_movi_tl(cpu_LO[0], 0);
+            tcg_gen_movi_tl(cpu_LO[acc], 0);
         opn = "mtlo";
         break;
     }
@@ -2011,6 +2261,7 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
 {
     const char *opn = "mul/div";
     TCGv t0, t1;
+    unsigned int acc;
 
     switch (opc) {
     case OPC_DIV:
@@ -2073,6 +2324,7 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
         {
             TCGv_i64 t2 = tcg_temp_new_i64();
             TCGv_i64 t3 = tcg_temp_new_i64();
+            acc = (ctx->opcode >> 11) & 0x03;
 
             tcg_gen_ext_tl_i64(t2, t0);
             tcg_gen_ext_tl_i64(t3, t1);
@@ -2082,8 +2334,8 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
             tcg_gen_shri_i64(t2, t2, 32);
             tcg_gen_trunc_i64_tl(t1, t2);
             tcg_temp_free_i64(t2);
-            tcg_gen_ext32s_tl(cpu_LO[0], t0);
-            tcg_gen_ext32s_tl(cpu_HI[0], t1);
+            tcg_gen_ext32s_tl(cpu_LO[acc], t0);
+            tcg_gen_ext32s_tl(cpu_HI[acc], t1);
         }
         opn = "mult";
         break;
@@ -2091,6 +2343,7 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
         {
             TCGv_i64 t2 = tcg_temp_new_i64();
             TCGv_i64 t3 = tcg_temp_new_i64();
+            acc = (ctx->opcode >> 11) & 0x03;
 
             tcg_gen_ext32u_tl(t0, t0);
             tcg_gen_ext32u_tl(t1, t1);
@@ -2102,8 +2355,8 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
             tcg_gen_shri_i64(t2, t2, 32);
             tcg_gen_trunc_i64_tl(t1, t2);
             tcg_temp_free_i64(t2);
-            tcg_gen_ext32s_tl(cpu_LO[0], t0);
-            tcg_gen_ext32s_tl(cpu_HI[0], t1);
+            tcg_gen_ext32s_tl(cpu_LO[acc], t0);
+            tcg_gen_ext32s_tl(cpu_HI[acc], t1);
         }
         opn = "multu";
         break;
@@ -2150,19 +2403,20 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
         {
             TCGv_i64 t2 = tcg_temp_new_i64();
             TCGv_i64 t3 = tcg_temp_new_i64();
+            acc = (ctx->opcode >> 11) & 0x03;
 
             tcg_gen_ext_tl_i64(t2, t0);
             tcg_gen_ext_tl_i64(t3, t1);
             tcg_gen_mul_i64(t2, t2, t3);
-            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
+            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
             tcg_gen_add_i64(t2, t2, t3);
             tcg_temp_free_i64(t3);
             tcg_gen_trunc_i64_tl(t0, t2);
             tcg_gen_shri_i64(t2, t2, 32);
             tcg_gen_trunc_i64_tl(t1, t2);
             tcg_temp_free_i64(t2);
-            tcg_gen_ext32s_tl(cpu_LO[0], t0);
-            tcg_gen_ext32s_tl(cpu_HI[0], t1);
+            tcg_gen_ext32s_tl(cpu_LO[acc], t0);
+            tcg_gen_ext32s_tl(cpu_HI[acc], t1);
         }
         opn = "madd";
         break;
@@ -2170,21 +2424,22 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
        {
             TCGv_i64 t2 = tcg_temp_new_i64();
             TCGv_i64 t3 = tcg_temp_new_i64();
+            acc = (ctx->opcode) & 0x03;
 
             tcg_gen_ext32u_tl(t0, t0);
             tcg_gen_ext32u_tl(t1, t1);
             tcg_gen_extu_tl_i64(t2, t0);
             tcg_gen_extu_tl_i64(t3, t1);
             tcg_gen_mul_i64(t2, t2, t3);
-            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
+            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
             tcg_gen_add_i64(t2, t2, t3);
             tcg_temp_free_i64(t3);
             tcg_gen_trunc_i64_tl(t0, t2);
             tcg_gen_shri_i64(t2, t2, 32);
             tcg_gen_trunc_i64_tl(t1, t2);
             tcg_temp_free_i64(t2);
-            tcg_gen_ext32s_tl(cpu_LO[0], t0);
-            tcg_gen_ext32s_tl(cpu_HI[0], t1);
+            tcg_gen_ext32s_tl(cpu_LO[acc], t0);
+            tcg_gen_ext32s_tl(cpu_HI[acc], t1);
         }
         opn = "maddu";
         break;
@@ -2192,19 +2447,20 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
         {
             TCGv_i64 t2 = tcg_temp_new_i64();
             TCGv_i64 t3 = tcg_temp_new_i64();
+            acc = (ctx->opcode >> 11) & 0x03;
 
             tcg_gen_ext_tl_i64(t2, t0);
             tcg_gen_ext_tl_i64(t3, t1);
             tcg_gen_mul_i64(t2, t2, t3);
-            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
+            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
             tcg_gen_sub_i64(t2, t3, t2);
             tcg_temp_free_i64(t3);
             tcg_gen_trunc_i64_tl(t0, t2);
             tcg_gen_shri_i64(t2, t2, 32);
             tcg_gen_trunc_i64_tl(t1, t2);
             tcg_temp_free_i64(t2);
-            tcg_gen_ext32s_tl(cpu_LO[0], t0);
-            tcg_gen_ext32s_tl(cpu_HI[0], t1);
+            tcg_gen_ext32s_tl(cpu_LO[acc], t0);
+            tcg_gen_ext32s_tl(cpu_HI[acc], t1);
         }
         opn = "msub";
         break;
@@ -2212,21 +2468,22 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
         {
             TCGv_i64 t2 = tcg_temp_new_i64();
             TCGv_i64 t3 = tcg_temp_new_i64();
+            acc = (ctx->opcode >> 11) & 0x03;
 
             tcg_gen_ext32u_tl(t0, t0);
             tcg_gen_ext32u_tl(t1, t1);
             tcg_gen_extu_tl_i64(t2, t0);
             tcg_gen_extu_tl_i64(t3, t1);
             tcg_gen_mul_i64(t2, t2, t3);
-            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
+            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
             tcg_gen_sub_i64(t2, t3, t2);
             tcg_temp_free_i64(t3);
             tcg_gen_trunc_i64_tl(t0, t2);
             tcg_gen_shri_i64(t2, t2, 32);
             tcg_gen_trunc_i64_tl(t1, t2);
             tcg_temp_free_i64(t2);
-            tcg_gen_ext32s_tl(cpu_LO[0], t0);
-            tcg_gen_ext32s_tl(cpu_HI[0], t1);
+            tcg_gen_ext32s_tl(cpu_LO[acc], t0);
+            tcg_gen_ext32s_tl(cpu_HI[acc], t1);
         }
         opn = "msubu";
         break;
@@ -2743,6 +3000,12 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
         }
         btgt = ctx->pc + insn_bytes + offset;
         break;
+    case OPC_BPOSGE32:
+        t0 = cpu_dspctrl;
+        tcg_gen_andi_i32(t0, t0, 0x3F);
+        bcond_compute = 1;
+        btgt = ctx->pc + insn_bytes + offset;
+        break;
     case OPC_J:
     case OPC_JAL:
     case OPC_JALX:
@@ -2931,6 +3194,10 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
             MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
             goto likely;
+        case OPC_BPOSGE32:
+            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 31);
+            MIPS_DEBUG("bposge32 %s, " TARGET_FMT_lx, t0, btgt);
+            goto not_likely;
         case OPC_BLTZALS:
         case OPC_BLTZAL:
             ctx->hflags |= (opc == OPC_BLTZALS
@@ -11168,8 +11435,6 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
             *is_branch = 1;
             break;
         case BPOSGE64:
-        case BPOSGE32:
-            /* MIPS DSP: not implemented */
             /* Fall through */
         default:
             MIPS_INVAL("pool32i");
@@ -12033,10 +12298,801 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
             break;
         case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
         case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
+        /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
+         * the same mask and op1. */
+            if (op1 == OPC_MULT_G_2E) {
+                int is_mult_g_2e = 0;
+                op2 = MASK_ADDUH_QB(ctx->opcode);
+                switch (op2) {
+                /* MIPS DSPR2 */
+                case  OPC_ADDQH_PH:
+                    gen_helper_addqhph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                    break;
+                case  OPC_ADDQH_R_PH:
+                    gen_helper_addqhrph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                    break;
+                case  OPC_ADDQH_W:
+                    gen_helper_addqhw(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                    break;
+                case  OPC_ADDQH_R_W:
+                    gen_helper_addqhrw(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                    break;
+                case  OPC_ADDUH_QB:
+                    gen_helper_adduhqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                    break;
+                case  OPC_ADDUH_R_QB:
+                    gen_helper_adduhrqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                    break;
+                case  OPC_MUL_PH:
+                    gen_helper_mulph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                    break;
+                case  OPC_MUL_S_PH:
+                    gen_helper_mulsph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                    break;
+                case  OPC_SUBQH_PH:
+                    gen_helper_subqhph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                    break;
+                case  OPC_SUBQH_R_PH:
+                    gen_helper_subqhrph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                    break;
+                case  OPC_SUBQH_W:
+                    gen_helper_subqhw(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                    break;
+                case  OPC_SUBQH_R_W:
+                    gen_helper_subqhrw(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                    break;
+                case  OPC_SUBUH_QB:
+                    gen_helper_subuhqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                    break;
+                case  OPC_SUBUH_R_QB:
+                    gen_helper_subuhrqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                    break;
+                /* OPC_MUL_PH_DSP */
+                /* MIPS DSPR2 */
+                case OPC_MULQ_RS_W:
+                    gen_helper_mulqrsw(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                    break;
+                case OPC_MULQ_S_W:
+                    gen_helper_mulqsw(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                    break;
+                default:
+                    is_mult_g_2e = 1;
+                    break;
+                }
+                if (is_mult_g_2e == 0)
+                    break;
+            }
         case OPC_MOD_G_2E ... OPC_MODU_G_2E:
             check_insn(env, ctx, INSN_LOONGSON2E);
             gen_loongson_integer(ctx, op1, rd, rs, rt);
             break;
+        /* MIPS DSP opcodes */
+        case OPC_ABSQ_S_PH_DSP:
+            op2 = MASK_ABSQ_S_PH(ctx->opcode);
+            switch (op2) {
+            /* MIPS DSP */
+            case OPC_ABSQ_S_PH:
+                gen_helper_absqsph(cpu_gpr[rd], cpu_gpr[rt]);
+                break;
+            case OPC_ABSQ_S_W:
+                gen_helper_absqsw(cpu_gpr[rd], cpu_gpr[rt]);
+                break;
+            case OPC_BITREV:
+                gen_helper_bitrev(cpu_gpr[rd], cpu_gpr[rt]);
+                break;
+            case OPC_PRECEQ_W_PHL:
+                gen_helper_preceqwphl(cpu_gpr[rd], cpu_gpr[rt]);
+                break;
+            case OPC_PRECEQ_W_PHR:
+                gen_helper_preceqwphr(cpu_gpr[rd], cpu_gpr[rt]);
+                break;
+            case OPC_PRECEQU_PH_QBL:
+                gen_helper_precequphqbl(cpu_gpr[rd], cpu_gpr[rt]);
+                break;
+            case OPC_PRECEQU_PH_QBLA:
+                gen_helper_precequphqbla(cpu_gpr[rd], cpu_gpr[rt]);
+                break;
+            case OPC_PRECEQU_PH_QBR:
+                gen_helper_precequphqbr(cpu_gpr[rd], cpu_gpr[rt]);
+                break;
+            case OPC_PRECEQU_PH_QBRA:
+                gen_helper_precequphqbra(cpu_gpr[rd], cpu_gpr[rt]);
+                break;
+            case OPC_PRECEU_PH_QBL:
+                gen_helper_preceuphqbl(cpu_gpr[rd], cpu_gpr[rt]);
+                break;
+            case OPC_PRECEU_PH_QBLA:
+                gen_helper_preceuphqbla(cpu_gpr[rd], cpu_gpr[rt]);
+                break;
+            case OPC_PRECEU_PH_QBR:
+                gen_helper_preceuphqbr(cpu_gpr[rd], cpu_gpr[rt]);
+                break;
+            case OPC_PRECEU_PH_QBRA:
+                gen_helper_preceuphqbra(cpu_gpr[rd], cpu_gpr[rt]);
+                break;
+            case OPC_REPL_PH:
+                {
+                    TCGv temp_imm;
+                    imm = (ctx->opcode >> 16) & 0x03FF;
+                    temp_imm = tcg_const_i32(imm);
+                    gen_helper_replph(cpu_gpr[rd], temp_imm);
+                    tcg_temp_free(temp_imm);
+                    break;
+                }
+            case OPC_REPL_QB:
+                {
+                    TCGv temp_imm;
+                    imm = (ctx->opcode >> 16) & 0xFF;
+                    temp_imm = tcg_const_i32(imm);
+                    gen_helper_replqb(cpu_gpr[rd], temp_imm);
+                    tcg_temp_free(temp_imm);
+                    break;
+                }
+            case OPC_REPLV_PH:
+                gen_helper_replvph(cpu_gpr[rd], cpu_gpr[rt]);
+                break;
+            case OPC_REPLV_QB:
+                gen_helper_replvqb(cpu_gpr[rd], cpu_gpr[rt]);
+                break;
+            /* MIPS DSPR2 */
+            case OPC_ABSQ_S_QB:
+                gen_helper_absqsqb(cpu_gpr[rd], cpu_gpr[rt]);
+                break;
+            }
+            break;
+        case OPC_ADDU_QB_DSP:
+            op2 = MASK_ADDU_QB(ctx->opcode);
+            switch (op2) {
+            /* MIPS DSP */
+            case OPC_ADDQ_PH:
+                gen_helper_addqph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_ADDQ_S_PH:
+                gen_helper_addqsph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_ADDQ_S_W:
+                gen_helper_addqsw(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_ADDSC:
+                gen_helper_addsc(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_ADDU_QB:
+                gen_helper_adduqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_ADDU_S_QB:
+                gen_helper_addusqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_ADDWC:
+                gen_helper_addwc(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_MODSUB:
+                gen_helper_modsub(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_MULEQ_S_W_PHL:
+                gen_helper_muleqswphl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_MULEQ_S_W_PHR:
+                gen_helper_muleqswphr(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_MULEU_S_PH_QBL:
+                gen_helper_muleusphqbl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_MULEU_S_PH_QBR:
+                gen_helper_muleusphqbr(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_MULQ_RS_PH:
+                gen_helper_mulqrsph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_RADDU_W_QB:
+                gen_helper_radduwqb(cpu_gpr[rd], cpu_gpr[rs]);
+                break;
+            case OPC_SUBQ_PH:
+                gen_helper_subqph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_SUBQ_S_PH:
+                gen_helper_subqsph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_SUBQ_S_W:
+                gen_helper_subqsw(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_SUBU_QB:
+                gen_helper_subuqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_SUBU_S_QB:
+                gen_helper_subusqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            /* MIPS DSPR2 */
+            case OPC_ADDU_PH:
+                gen_helper_adduph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_ADDU_S_PH:
+                gen_helper_addusph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_MULQ_S_PH:
+                gen_helper_mulqsph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_SUBU_PH:
+                gen_helper_subuph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_SUBU_S_PH:
+                gen_helper_subusph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            }
+            break;
+        case OPC_APPEND_DSP:
+            op2 = MASK_APPEND(ctx->opcode);
+            switch (op2) {
+            /* MIPS DSPR2 */
+            case OPC_APPEND:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_append(cpu_gpr[rt], cpu_gpr[rt],
+                                      cpu_gpr[rs], temp_rd);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_BALIGN:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_balign(cpu_gpr[rt], cpu_gpr[rt],
+                                      cpu_gpr[rs], temp_rd);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_PREPEND:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_prepend(cpu_gpr[rt], temp_rd,
+                                       cpu_gpr[rs], cpu_gpr[rt]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            }
+            break;
+        case OPC_CMPU_EQ_QB_DSP:
+            op2 = MASK_CMPU_EQ_QB(ctx->opcode);
+            switch (op2) {
+            /* MIPS DSP */
+            case OPC_CMP_EQ_PH:
+                gen_helper_cmpeqph(cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_CMP_LT_PH:
+                gen_helper_cmpltph(cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_CMP_LE_PH:
+                gen_helper_cmpleph(cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_CMPGU_EQ_QB:
+                gen_helper_cmpgueqqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_CMPGU_LT_QB:
+                gen_helper_cmpgultqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_CMPGU_LE_QB:
+                gen_helper_cmpguleqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_CMPU_EQ_QB:
+                gen_helper_cmpueqqb(cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_CMPU_LT_QB:
+                gen_helper_cmpultqb(cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_CMPU_LE_QB:
+                gen_helper_cmpuleqb(cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_PACKRL_PH:
+                gen_helper_packrlph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_PICK_QB:
+                gen_helper_pickqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_PICK_PH:
+                gen_helper_pickph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_PRECRQ_QB_PH:
+                gen_helper_precrqqbph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_PRECRQ_PH_W:
+                gen_helper_precrqphw(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_PRECRQ_RS_PH_W:
+                gen_helper_precrqrsphw(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_PRECRQU_S_QB_PH:
+                gen_helper_precrqusqbph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            /* MIPS DSPR2 */
+            case OPC_CMPGDU_EQ_QB:
+                gen_helper_cmpgdueqqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_CMPGDU_LT_QB:
+                gen_helper_cmpgdultqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_CMPGDU_LE_QB:
+                gen_helper_cmpgduleqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_PRECR_QB_PH:
+                gen_helper_precrqbph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                break;
+            case OPC_PRECR_SRA_PH_W:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_precrsraphw(cpu_gpr[rt], temp_rd,
+                                           cpu_gpr[rs], cpu_gpr[rt]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_PRECR_SRA_R_PH_W:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_precrsrarphw(cpu_gpr[rt], temp_rd,
+                                            cpu_gpr[rs], cpu_gpr[rt]);
+                    break;
+                }
+            }
+            break;
+        case OPC_DPA_W_PH_DSP:
+            op2 = MASK_DPA_W_PH(ctx->opcode);
+            switch (op2) {
+            /* MIPS DSP */
+            case OPC_DPAQ_S_W_PH:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_dpaqswph(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_DPAQ_SA_L_W:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_dpaqsalw(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_DPAU_H_QBL:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_dpauhqbl(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_DPAU_H_QBR:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_dpauhqbr(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_DPSQ_S_W_PH:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_dpsqswph(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_DPSQ_SA_L_W:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_dpsqsalw(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_DPSU_H_QBL:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_dpsuhqbl(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_DPSU_H_QBR:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_dpsuhqbr(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_MAQ_S_W_PHL:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_maqswphl(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_MAQ_SA_W_PHL:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_maqsawphl(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_MAQ_S_W_PHR:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_maqswphr(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_MAQ_SA_W_PHR:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_maqsawphr(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_MULSAQ_S_W_PH:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_mulsaqswph(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            /* MIPS DSPR2 */
+            case OPC_DPA_W_PH:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_dpawph(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_DPAQX_S_W_PH:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_dpaqxswph(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_DPAQX_SA_W_PH:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_dpaqxsawph(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_DPAX_W_PH:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_dpaxwph(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_DPS_W_PH:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_dpswph(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_DPSQX_S_W_PH:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_dpsqxswph(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_DPSQX_SA_W_PH:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_dpsqxsawph(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_DPSX_W_PH:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_dpsxwph(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_MULSA_W_PH:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_mulsawph(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            }
+            break;
+        case OPC_EXTR_W_DSP:
+            op2 = MASK_EXTR_W(ctx->opcode);
+            switch (op2) {
+            /* MIPS DSP */
+            case OPC_EXTP:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    TCGv temp_rs = tcg_const_i32(rs);
+                    TCGv temp_rt = tcg_const_i32(rt);
+                    gen_helper_extp(temp_rd, temp_rs, temp_rt);
+                    tcg_temp_free(temp_rd);
+                    tcg_temp_free(temp_rs);
+                    tcg_temp_free(temp_rt);
+                    break;
+                }
+            case OPC_EXTPDP:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    TCGv temp_rs = tcg_const_i32(rs);
+                    TCGv temp_rt = tcg_const_i32(rt);
+                    gen_helper_extpdp(temp_rd, temp_rs, temp_rt);
+                    tcg_temp_free(temp_rd);
+                    tcg_temp_free(temp_rs);
+                    tcg_temp_free(temp_rt);
+                    break;
+                }
+            case OPC_EXTPDPV:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    TCGv temp_rt = tcg_const_i32(rt);
+                    gen_helper_extpdpv(temp_rd, cpu_gpr[rs], temp_rt);
+                    tcg_temp_free(temp_rd);
+                    tcg_temp_free(temp_rt);
+                    break;
+                }
+            case OPC_EXTPV:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    TCGv temp_rt = tcg_const_i32(rt);
+                    gen_helper_extpv(temp_rd, cpu_gpr[rs], temp_rt);
+                    tcg_temp_free(temp_rd);
+                    tcg_temp_free(temp_rt);
+                    break;
+                }
+            case OPC_EXTR_S_H:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    TCGv temp_rs = tcg_const_i32(rs);
+                    TCGv temp_rt = tcg_const_i32(rt);
+                    gen_helper_extrsh(temp_rd, temp_rs, temp_rt);
+                    tcg_temp_free(temp_rd);
+                    tcg_temp_free(temp_rs);
+                    tcg_temp_free(temp_rt);
+                    break;
+                }
+            case OPC_EXTR_W:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    TCGv temp_rs = tcg_const_i32(rs);
+                    TCGv temp_rt = tcg_const_i32(rt);
+                    gen_helper_extrw(temp_rd, temp_rs, temp_rt);
+                    tcg_temp_free(temp_rd);
+                    tcg_temp_free(temp_rs);
+                    tcg_temp_free(temp_rt);
+                    break;
+                }
+            case OPC_EXTR_R_W:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    TCGv temp_rs = tcg_const_i32(rs);
+                    TCGv temp_rt = tcg_const_i32(rt);
+                    gen_helper_extrrw(temp_rd, temp_rs, temp_rt);
+                    tcg_temp_free(temp_rd);
+                    tcg_temp_free(temp_rs);
+                    tcg_temp_free(temp_rt);
+                    break;
+                }
+            case OPC_EXTR_RS_W:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    TCGv temp_rs = tcg_const_i32(rs);
+                    TCGv temp_rt = tcg_const_i32(rt);
+                    gen_helper_extrrsw(temp_rd, temp_rs, temp_rt);
+                    tcg_temp_free(temp_rd);
+                    tcg_temp_free(temp_rs);
+                    tcg_temp_free(temp_rt);
+                    break;
+                }
+            case OPC_EXTRV_S_H:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_extrvsh(cpu_gpr[rt], temp_rd, cpu_gpr[rs]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_EXTRV_W:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    TCGv temp_rt = tcg_const_i32(rt);
+                    gen_helper_extrvw(temp_rd, cpu_gpr[rs], temp_rt);
+                    tcg_temp_free(temp_rd);
+                    tcg_temp_free(temp_rt);
+                    break;
+                }
+            case OPC_EXTRV_R_W:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    TCGv temp_rt = tcg_const_i32(rt);
+                    gen_helper_extrvrw(temp_rd, cpu_gpr[rs], temp_rt);
+                    tcg_temp_free(temp_rd);
+                    tcg_temp_free(temp_rt);
+                    break;
+                }
+            case OPC_EXTRV_RS_W:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    TCGv temp_rt = tcg_const_i32(rt);
+                    gen_helper_extrvrsw(temp_rd, cpu_gpr[rs], temp_rt);
+                    tcg_temp_free(temp_rd);
+                    tcg_temp_free(temp_rt);
+                    break;
+                }
+            case OPC_MTHLIP:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_mthlip(temp_rd, cpu_gpr[rs]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_RDDSP:
+                {
+                    TCGv temp_imm;
+                    imm = (ctx->opcode >> 16) & 0x03FF;
+                    temp_imm = tcg_const_i32(imm);
+                    gen_helper_rddsp(cpu_gpr[rd], temp_imm);
+                    tcg_temp_free(temp_imm);
+                    break;
+                }
+            case OPC_SHILO:
+                {
+                    TCGv temp_imm;
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    imm = (ctx->opcode >> 20) & 0x3F;
+                    temp_imm = tcg_const_i32(imm);
+                    gen_helper_shilo(temp_rd, temp_imm);
+                    tcg_temp_free(temp_imm);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_SHILOV:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_shilov(temp_rd, cpu_gpr[rs]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_WRDSP:
+                {
+                    TCGv temp_imm;
+                    imm = (ctx->opcode >> 11) & 0x3FF;
+                    temp_imm = tcg_const_i32(imm);
+                    gen_helper_wrdsp(cpu_gpr[rs], temp_imm);
+                    tcg_temp_free(temp_imm);
+                    break;
+                }
+            }
+            break;
+        case OPC_INSV_DSP:
+            op2 = MASK_INSV(ctx->opcode);
+            switch (op2) {
+            /* MIPS DSP */
+            case OPC_INSV:
+                {
+                    TCGv temp_rt = tcg_const_i32(rt);
+                    gen_helper_insv(temp_rt, cpu_gpr[rs], cpu_gpr[rt]);
+                    tcg_temp_free(temp_rt);
+                    break;
+                }
+            }
+            break;
+        case OPC_LX_DSP:
+            op2 = MASK_LX(ctx->opcode);
+            switch (op2) {
+            case OPC_LBUX:
+                {
+                    TCGv addr     = tcg_temp_new();
+                    TCGv temp_mem = tcg_temp_new();
+
+                    save_cpu_state(ctx, 1);
+                    gen_op_addr_add(ctx, addr, cpu_gpr[rs], cpu_gpr[rt]);
+                    temp_mem = tcg_const_i32(ctx->mem_idx);
+                    gen_helper_lbux(cpu_gpr[rd], addr, temp_mem);
+                    tcg_temp_free_i32(addr);
+                    tcg_temp_free_i32(temp_mem);
+                    break;
+                }
+            case OPC_LHX:
+                {
+                    TCGv addr     = tcg_temp_new();
+                    TCGv temp_mem = tcg_temp_new();
+
+                    save_cpu_state(ctx, 1);
+                    gen_op_addr_add(ctx, addr, cpu_gpr[rs], cpu_gpr[rt]);
+                    temp_mem = tcg_const_i32(ctx->mem_idx);
+                    gen_helper_lhx(cpu_gpr[rd], addr, temp_mem);
+                    tcg_temp_free_i32(addr);
+                    tcg_temp_free_i32(temp_mem);
+                    break;
+                }
+            case OPC_LWX:
+                {
+                    TCGv addr     = tcg_temp_new();
+                    TCGv temp_mem = tcg_temp_new();
+
+                    save_cpu_state(ctx, 1);
+                    gen_op_addr_add(ctx, addr, cpu_gpr[rs], cpu_gpr[rt]);
+                    temp_mem = tcg_const_i32(ctx->mem_idx);
+                    gen_helper_lwx(cpu_gpr[rd], addr, temp_mem);
+                    tcg_temp_free_i32(addr);
+                    tcg_temp_free_i32(temp_mem);
+                    break;
+                }
+            }
+            break;
+        case OPC_SHLL_QB_DSP:
+            {
+              TCGv temp_rs = tcg_const_i32(rs);
+              op2 = MASK_SHLL_QB(ctx->opcode);
+              switch (op2) {
+              /* MIPS DSP */
+              case OPC_SHLL_PH:
+                  gen_helper_shllph(cpu_gpr[rd], temp_rs, cpu_gpr[rt]);
+                  break;
+              case OPC_SHLL_S_PH:
+                  gen_helper_shllsph(cpu_gpr[rd], temp_rs, cpu_gpr[rt]);
+                  break;
+              case OPC_SHLL_QB:
+                  gen_helper_shllqb(cpu_gpr[rd], temp_rs, cpu_gpr[rt]);
+                  break;
+              case OPC_SHLL_S_W:
+                  gen_helper_shllsw(cpu_gpr[rd], temp_rs, cpu_gpr[rt]);
+                  break;
+              case OPC_SHLLV_PH:
+                  gen_helper_shllvph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                  break;
+              case OPC_SHLLV_S_PH:
+                  gen_helper_shllvsph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                  break;
+              case OPC_SHLLV_QB:
+                  gen_helper_shllvqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                  break;
+              case OPC_SHLLV_S_W:
+                  gen_helper_shllvsw(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                  break;
+              case OPC_SHRA_PH:
+                  gen_helper_shraph(cpu_gpr[rd], temp_rs, cpu_gpr[rt]);
+                  break;
+              case OPC_SHRA_R_PH:
+                  gen_helper_shrarph(cpu_gpr[rd], temp_rs, cpu_gpr[rt]);
+                  break;
+              case OPC_SHRA_R_W:
+                  gen_helper_shrarw(cpu_gpr[rd], temp_rs, cpu_gpr[rt]);
+                  break;
+              case OPC_SHRAV_PH:
+                  gen_helper_shravph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                  break;
+              case OPC_SHRAV_R_PH:
+                  gen_helper_shravrph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                  break;
+              case OPC_SHRAV_R_W:
+                  gen_helper_shravrw(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                  break;
+              case OPC_SHRL_QB:
+                  gen_helper_shrlqb(cpu_gpr[rd], temp_rs, cpu_gpr[rt]);
+                  break;
+              case OPC_SHRLV_QB:
+                  gen_helper_shrlvqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                  break;
+              /* MIPS DSPR2 */
+              case OPC_SHRA_QB:
+                  gen_helper_shraqb(cpu_gpr[rd], temp_rs, cpu_gpr[rt]);
+                  break;
+              case OPC_SHRA_R_QB:
+                  gen_helper_shrarqb(cpu_gpr[rd], temp_rs, cpu_gpr[rt]);
+                  break;
+              case OPC_SHRAV_QB:
+                  gen_helper_shravqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                  break;
+              case OPC_SHRAV_R_QB:
+                  gen_helper_shravrqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                  break;
+              case OPC_SHRL_PH:
+                  gen_helper_shrlph(cpu_gpr[rd], temp_rs, cpu_gpr[rt]);
+                  break;
+              case OPC_SHRLV_PH:
+                  gen_helper_shrlvph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+                  break;
+              }
+              tcg_temp_free(temp_rs);
+              break;
+          }
 #if defined(TARGET_MIPS64)
         case OPC_DEXTM ... OPC_DEXT:
         case OPC_DINSM ... OPC_DINS:
@@ -12079,6 +13135,12 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
             check_insn(env, ctx, ISA_MIPS32R2);
             /* Treat as NOP. */
             break;
+        case OPC_BPOSGE32:    /* mipsdsp branch */
+            {
+                gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
+                *is_branch = 1;
+                break;
+            }
         default:            /* Invalid */
             MIPS_INVAL("regimm");
             generate_exception(ctx, EXCP_RI);
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH V2 4/4] add MIPS DSP testcase
  2012-03-22 13:36 [Qemu-devel] [PATCH V2 0/4] MIPS ASE DSP Support for Qemu Jia Liu
                   ` (2 preceding siblings ...)
  2012-03-22 13:36 ` [Qemu-devel] [PATCH V2 3/4] add MIPS DSP translation Jia Liu
@ 2012-03-22 13:36 ` Jia Liu
  2012-03-22 14:01 ` [Qemu-devel] [PATCH V2 0/4] MIPS ASE DSP Support for Qemu Peter Maydell
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Jia Liu @ 2012-03-22 13:36 UTC (permalink / raw)
  To: qemu-devel; +Cc: sw, aurelien

This is the testcases of MIPS ASE DSP.

Signed-off-by: Jia Liu <proljc@gmail.com>
---

Version History:

V2:
- Addressed Stefan's review comments, add return value.
- Coding style fixed.

V1:
- add MIPS ASE DSP testcases.

 tests/tcg/mips/mips32-dsp/Makefile             |  133 ++++++++++++++++++++++++
 tests/tcg/mips/mips32-dsp/absq_s_ph.c          |   30 ++++++
 tests/tcg/mips/mips32-dsp/absq_s_w.c           |   37 +++++++
 tests/tcg/mips/mips32-dsp/addq_ph.c            |   30 ++++++
 tests/tcg/mips/mips32-dsp/addq_s_ph.c          |   30 ++++++
 tests/tcg/mips/mips32-dsp/addsc.c              |   30 ++++++
 tests/tcg/mips/mips32-dsp/addu_qb.c            |   30 ++++++
 tests/tcg/mips/mips32-dsp/addu_s_qb.c          |   30 ++++++
 tests/tcg/mips/mips32-dsp/addwc.c              |   30 ++++++
 tests/tcg/mips/mips32-dsp/bitrev.c             |   20 ++++
 tests/tcg/mips/mips32-dsp/bposge32.c           |   44 ++++++++
 tests/tcg/mips/mips32-dsp/cmp_eq_ph.c          |   35 ++++++
 tests/tcg/mips/mips32-dsp/cmp_le_ph.c          |   35 ++++++
 tests/tcg/mips/mips32-dsp/cmp_lt_ph.c          |   35 ++++++
 tests/tcg/mips/mips32-dsp/cmpgu_eq_qb.c        |   31 ++++++
 tests/tcg/mips/mips32-dsp/cmpgu_le_qb.c        |   31 ++++++
 tests/tcg/mips/mips32-dsp/cmpgu_lt_qb.c        |   31 ++++++
 tests/tcg/mips/mips32-dsp/cmpu_eq_qb.c         |   35 ++++++
 tests/tcg/mips/mips32-dsp/cmpu_le_qb.c         |   35 ++++++
 tests/tcg/mips/mips32-dsp/cmpu_lt_qb.c         |   35 ++++++
 tests/tcg/mips/mips32-dsp/dpaq_s_w_ph.c        |   31 ++++++
 tests/tcg/mips/mips32-dsp/dpaq_sa_l_w.c        |   31 ++++++
 tests/tcg/mips/mips32-dsp/dpau_h_qbl.c         |   27 +++++
 tests/tcg/mips/mips32-dsp/dpau_h_qbr.c         |   27 +++++
 tests/tcg/mips/mips32-dsp/dpsq_s_w_ph.c        |   27 +++++
 tests/tcg/mips/mips32-dsp/dpsq_sa_l_w.c        |   31 ++++++
 tests/tcg/mips/mips32-dsp/dpsu_h_qbl.c         |   27 +++++
 tests/tcg/mips/mips32-dsp/dpsu_h_qbr.c         |   27 +++++
 tests/tcg/mips/mips32-dsp/extp.c               |   44 ++++++++
 tests/tcg/mips/mips32-dsp/extpdp.c             |   46 ++++++++
 tests/tcg/mips/mips32-dsp/extpdpv.c            |   47 +++++++++
 tests/tcg/mips/mips32-dsp/extpv.c              |   45 ++++++++
 tests/tcg/mips/mips32-dsp/extr_r_w.c           |   25 +++++
 tests/tcg/mips/mips32-dsp/extr_rs_w.c          |   25 +++++
 tests/tcg/mips/mips32-dsp/extr_s_h.c           |   25 +++++
 tests/tcg/mips/mips32-dsp/extr_w.c             |   25 +++++
 tests/tcg/mips/mips32-dsp/extrv_r_w.c          |   29 +++++
 tests/tcg/mips/mips32-dsp/extrv_rs_w.c         |   29 +++++
 tests/tcg/mips/mips32-dsp/extrv_s_h.c          |   29 +++++
 tests/tcg/mips/mips32-dsp/extrv_w.c            |   29 +++++
 tests/tcg/mips/mips32-dsp/insv.c               |   23 ++++
 tests/tcg/mips/mips32-dsp/lbux.c               |   23 ++++
 tests/tcg/mips/mips32-dsp/lhx.c                |   23 ++++
 tests/tcg/mips/mips32-dsp/lwx.c                |   23 ++++
 tests/tcg/mips/mips32-dsp/madd.c               |   31 ++++++
 tests/tcg/mips/mips32-dsp/maddu.c              |   31 ++++++
 tests/tcg/mips/mips32-dsp/maq_s_w_phl.c        |   31 ++++++
 tests/tcg/mips/mips32-dsp/maq_s_w_phr.c        |   31 ++++++
 tests/tcg/mips/mips32-dsp/maq_sa_w_phl.c       |   31 ++++++
 tests/tcg/mips/mips32-dsp/maq_sa_w_phr.c       |   31 ++++++
 tests/tcg/mips/mips32-dsp/mfhi.c               |   21 ++++
 tests/tcg/mips/mips32-dsp/mflo.c               |   21 ++++
 tests/tcg/mips/mips32-dsp/modsub.c             |   30 ++++++
 tests/tcg/mips/mips32-dsp/msub.c               |   30 ++++++
 tests/tcg/mips/mips32-dsp/msubu.c              |   30 ++++++
 tests/tcg/mips/mips32-dsp/mthi.c               |   21 ++++
 tests/tcg/mips/mips32-dsp/mthlip.c             |   34 ++++++
 tests/tcg/mips/mips32-dsp/mtlo.c               |   21 ++++
 tests/tcg/mips/mips32-dsp/muleq_s_w_phr.c      |   40 +++++++
 tests/tcg/mips/mips32-dsp/muleu_s_ph_qbl.c     |   25 +++++
 tests/tcg/mips/mips32-dsp/muleu_s_ph_qbr.c     |   25 +++++
 tests/tcg/mips/mips32-dsp/mulq_rs_ph.c         |   25 +++++
 tests/tcg/mips/mips32-dsp/mult.c               |   24 +++++
 tests/tcg/mips/mips32-dsp/multu.c              |   24 +++++
 tests/tcg/mips/mips32-dsp/packrl_ph.c          |   21 ++++
 tests/tcg/mips/mips32-dsp/pick_ph.c            |   23 ++++
 tests/tcg/mips/mips32-dsp/pick_qb.c            |   23 ++++
 tests/tcg/mips/mips32-dsp/preceq_w_phl.c       |   20 ++++
 tests/tcg/mips/mips32-dsp/preceq_w_phr.c       |   20 ++++
 tests/tcg/mips/mips32-dsp/precequ_ph_qbl.c     |   20 ++++
 tests/tcg/mips/mips32-dsp/precequ_ph_qbla.c    |   20 ++++
 tests/tcg/mips/mips32-dsp/precequ_ph_qbr.c     |   20 ++++
 tests/tcg/mips/mips32-dsp/precequ_ph_qbra.c    |   20 ++++
 tests/tcg/mips/mips32-dsp/preceu_ph_qbl.c      |   20 ++++
 tests/tcg/mips/mips32-dsp/preceu_ph_qbla.c     |   20 ++++
 tests/tcg/mips/mips32-dsp/preceu_ph_qbr.c      |   20 ++++
 tests/tcg/mips/mips32-dsp/preceu_ph_qbra.c     |   20 ++++
 tests/tcg/mips/mips32-dsp/precrq_ph_w.c        |   21 ++++
 tests/tcg/mips/mips32-dsp/precrq_qb_ph.c       |   21 ++++
 tests/tcg/mips/mips32-dsp/precrq_rs_ph_w.c     |   21 ++++
 tests/tcg/mips/mips32-dsp/precrqu_s_qb_ph.c    |   21 ++++
 tests/tcg/mips/mips32-dsp/raddu_w_qb.c         |   20 ++++
 tests/tcg/mips/mips32-dsp/rddsp.c              |   54 ++++++++++
 tests/tcg/mips/mips32-dsp/repl_ph.c            |   23 ++++
 tests/tcg/mips/mips32-dsp/repl_qb.c            |   16 +++
 tests/tcg/mips/mips32-dsp/replv_ph.c           |   19 ++++
 tests/tcg/mips/mips32-dsp/replv_qb.c           |   19 ++++
 tests/tcg/mips/mips32-dsp/shilo.c              |   27 +++++
 tests/tcg/mips/mips32-dsp/shilov.c             |   29 +++++
 tests/tcg/mips/mips32-dsp/shll_ph.c            |   24 +++++
 tests/tcg/mips/mips32-dsp/shll_qb.c            |   23 ++++
 tests/tcg/mips/mips32-dsp/shll_s_ph.c          |   24 +++++
 tests/tcg/mips/mips32-dsp/shll_s_w.c           |   24 +++++
 tests/tcg/mips/mips32-dsp/shllv_ph.c           |   25 +++++
 tests/tcg/mips/mips32-dsp/shllv_qb.c           |   24 +++++
 tests/tcg/mips/mips32-dsp/shllv_s_ph.c         |   25 +++++
 tests/tcg/mips/mips32-dsp/shllv_s_w.c          |   25 +++++
 tests/tcg/mips/mips32-dsp/shra_ph.c            |   20 ++++
 tests/tcg/mips/mips32-dsp/shra_r_ph.c          |   20 ++++
 tests/tcg/mips/mips32-dsp/shra_r_w.c           |   20 ++++
 tests/tcg/mips/mips32-dsp/shrav_ph.c           |   21 ++++
 tests/tcg/mips/mips32-dsp/shrav_r_ph.c         |   21 ++++
 tests/tcg/mips/mips32-dsp/shrav_r_w.c          |   21 ++++
 tests/tcg/mips/mips32-dsp/shrl_qb.c            |   20 ++++
 tests/tcg/mips/mips32-dsp/shrlv_qb.c           |   21 ++++
 tests/tcg/mips/mips32-dsp/subq_ph.c            |   25 +++++
 tests/tcg/mips/mips32-dsp/subq_s_ph.c          |   25 +++++
 tests/tcg/mips/mips32-dsp/subq_s_w.c           |   25 +++++
 tests/tcg/mips/mips32-dsp/subu_qb.c            |   25 +++++
 tests/tcg/mips/mips32-dsp/subu_s_qb.c          |   25 +++++
 tests/tcg/mips/mips32-dsp/wrdsp.c              |   54 ++++++++++
 tests/tcg/mips/mips32-dspr2/Makefile           |   71 +++++++++++++
 tests/tcg/mips/mips32-dspr2/absq_s_qb.c        |   31 ++++++
 tests/tcg/mips/mips32-dspr2/addqh_ph.c         |   30 ++++++
 tests/tcg/mips/mips32-dspr2/addqh_r_ph.c       |   30 ++++++
 tests/tcg/mips/mips32-dspr2/addqh_r_w.c        |   34 ++++++
 tests/tcg/mips/mips32-dspr2/addqh_w.c          |   34 ++++++
 tests/tcg/mips/mips32-dspr2/addu_ph.c          |   30 ++++++
 tests/tcg/mips/mips32-dspr2/addu_s_ph.c        |   30 ++++++
 tests/tcg/mips/mips32-dspr2/adduh_qb.c         |   30 ++++++
 tests/tcg/mips/mips32-dspr2/adduh_r_qb.c       |   30 ++++++
 tests/tcg/mips/mips32-dspr2/append.c           |   30 ++++++
 tests/tcg/mips/mips32-dspr2/balign.c           |   30 ++++++
 tests/tcg/mips/mips32-dspr2/cmpgdu_eq_qb.c     |   37 +++++++
 tests/tcg/mips/mips32-dspr2/cmpgdu_le_qb.c     |   37 +++++++
 tests/tcg/mips/mips32-dspr2/cmpgdu_lt_qb.c     |   37 +++++++
 tests/tcg/mips/mips32-dspr2/dpa_w_ph.c         |   27 +++++
 tests/tcg/mips/mips32-dspr2/dpaqx_s_w_ph.c     |   57 ++++++++++
 tests/tcg/mips/mips32-dspr2/dpaqx_sa_w_ph.c    |   30 ++++++
 tests/tcg/mips/mips32-dspr2/dpax_w_ph.c        |   27 +++++
 tests/tcg/mips/mips32-dspr2/dps_w_ph.c         |   27 +++++
 tests/tcg/mips/mips32-dspr2/dpsqx_s_w_ph.c     |   31 ++++++
 tests/tcg/mips/mips32-dspr2/dpsqx_sa_w_ph.c    |   31 ++++++
 tests/tcg/mips/mips32-dspr2/dpsx_w_ph.c        |   27 +++++
 tests/tcg/mips/mips32-dspr2/mul_ph.c           |   25 +++++
 tests/tcg/mips/mips32-dspr2/mul_s_ph.c         |   25 +++++
 tests/tcg/mips/mips32-dspr2/muleq_s_w_phl.c    |   40 +++++++
 tests/tcg/mips/mips32-dspr2/mulq_rs_w.c        |   36 +++++++
 tests/tcg/mips/mips32-dspr2/mulq_s_ph.c        |   25 +++++
 tests/tcg/mips/mips32-dspr2/mulq_s_w.c         |   36 +++++++
 tests/tcg/mips/mips32-dspr2/mulsa_w_ph.c       |   29 +++++
 tests/tcg/mips/mips32-dspr2/mulsaq_s_w_ph.c    |   29 +++++
 tests/tcg/mips/mips32-dspr2/precr_qb_ph.c      |   21 ++++
 tests/tcg/mips/mips32-dspr2/precr_sra_ph_w.c   |   32 ++++++
 tests/tcg/mips/mips32-dspr2/precr_sra_r_ph_w.c |   32 ++++++
 tests/tcg/mips/mips32-dspr2/prepend.c          |   30 ++++++
 tests/tcg/mips/mips32-dspr2/shra_qb.c          |   30 ++++++
 tests/tcg/mips/mips32-dspr2/shra_r_qb.c        |   30 ++++++
 tests/tcg/mips/mips32-dspr2/shrav_qb.c         |   32 ++++++
 tests/tcg/mips/mips32-dspr2/shrav_r_qb.c       |   32 ++++++
 tests/tcg/mips/mips32-dspr2/shrl_ph.c          |   20 ++++
 tests/tcg/mips/mips32-dspr2/shrlv_ph.c         |   21 ++++
 tests/tcg/mips/mips32-dspr2/subqh_ph.c         |   21 ++++
 tests/tcg/mips/mips32-dspr2/subqh_r_ph.c       |   21 ++++
 tests/tcg/mips/mips32-dspr2/subqh_r_w.c        |   21 ++++
 tests/tcg/mips/mips32-dspr2/subqh_w.c          |   21 ++++
 tests/tcg/mips/mips32-dspr2/subu_ph.c          |   25 +++++
 tests/tcg/mips/mips32-dspr2/subu_s_ph.c        |   25 +++++
 tests/tcg/mips/mips32-dspr2/subuh_qb.c         |   21 ++++
 tests/tcg/mips/mips32-dspr2/subuh_r_qb.c       |   21 ++++
 160 files changed, 4596 insertions(+), 0 deletions(-)
 create mode 100644 tests/tcg/mips/mips32-dsp/Makefile
 create mode 100644 tests/tcg/mips/mips32-dsp/absq_s_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/absq_s_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/addq_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/addq_s_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/addsc.c
 create mode 100644 tests/tcg/mips/mips32-dsp/addu_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/addu_s_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/addwc.c
 create mode 100644 tests/tcg/mips/mips32-dsp/bitrev.c
 create mode 100644 tests/tcg/mips/mips32-dsp/bposge32.c
 create mode 100644 tests/tcg/mips/mips32-dsp/cmp_eq_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/cmp_le_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/cmp_lt_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/cmpgu_eq_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/cmpgu_le_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/cmpgu_lt_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/cmpu_eq_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/cmpu_le_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/cmpu_lt_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/dpaq_s_w_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/dpaq_sa_l_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/dpau_h_qbl.c
 create mode 100644 tests/tcg/mips/mips32-dsp/dpau_h_qbr.c
 create mode 100644 tests/tcg/mips/mips32-dsp/dpsq_s_w_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/dpsq_sa_l_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/dpsu_h_qbl.c
 create mode 100644 tests/tcg/mips/mips32-dsp/dpsu_h_qbr.c
 create mode 100644 tests/tcg/mips/mips32-dsp/extp.c
 create mode 100644 tests/tcg/mips/mips32-dsp/extpdp.c
 create mode 100644 tests/tcg/mips/mips32-dsp/extpdpv.c
 create mode 100644 tests/tcg/mips/mips32-dsp/extpv.c
 create mode 100644 tests/tcg/mips/mips32-dsp/extr_r_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/extr_rs_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/extr_s_h.c
 create mode 100644 tests/tcg/mips/mips32-dsp/extr_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/extrv_r_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/extrv_rs_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/extrv_s_h.c
 create mode 100644 tests/tcg/mips/mips32-dsp/extrv_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/insv.c
 create mode 100644 tests/tcg/mips/mips32-dsp/lbux.c
 create mode 100644 tests/tcg/mips/mips32-dsp/lhx.c
 create mode 100644 tests/tcg/mips/mips32-dsp/lwx.c
 create mode 100644 tests/tcg/mips/mips32-dsp/madd.c
 create mode 100644 tests/tcg/mips/mips32-dsp/maddu.c
 create mode 100644 tests/tcg/mips/mips32-dsp/maq_s_w_phl.c
 create mode 100644 tests/tcg/mips/mips32-dsp/maq_s_w_phr.c
 create mode 100644 tests/tcg/mips/mips32-dsp/maq_sa_w_phl.c
 create mode 100644 tests/tcg/mips/mips32-dsp/maq_sa_w_phr.c
 create mode 100644 tests/tcg/mips/mips32-dsp/mfhi.c
 create mode 100644 tests/tcg/mips/mips32-dsp/mflo.c
 create mode 100644 tests/tcg/mips/mips32-dsp/modsub.c
 create mode 100644 tests/tcg/mips/mips32-dsp/msub.c
 create mode 100644 tests/tcg/mips/mips32-dsp/msubu.c
 create mode 100644 tests/tcg/mips/mips32-dsp/mthi.c
 create mode 100644 tests/tcg/mips/mips32-dsp/mthlip.c
 create mode 100644 tests/tcg/mips/mips32-dsp/mtlo.c
 create mode 100644 tests/tcg/mips/mips32-dsp/muleq_s_w_phr.c
 create mode 100644 tests/tcg/mips/mips32-dsp/muleu_s_ph_qbl.c
 create mode 100644 tests/tcg/mips/mips32-dsp/muleu_s_ph_qbr.c
 create mode 100644 tests/tcg/mips/mips32-dsp/mulq_rs_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/mult.c
 create mode 100644 tests/tcg/mips/mips32-dsp/multu.c
 create mode 100644 tests/tcg/mips/mips32-dsp/packrl_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/pick_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/pick_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/preceq_w_phl.c
 create mode 100644 tests/tcg/mips/mips32-dsp/preceq_w_phr.c
 create mode 100644 tests/tcg/mips/mips32-dsp/precequ_ph_qbl.c
 create mode 100644 tests/tcg/mips/mips32-dsp/precequ_ph_qbla.c
 create mode 100644 tests/tcg/mips/mips32-dsp/precequ_ph_qbr.c
 create mode 100644 tests/tcg/mips/mips32-dsp/precequ_ph_qbra.c
 create mode 100644 tests/tcg/mips/mips32-dsp/preceu_ph_qbl.c
 create mode 100644 tests/tcg/mips/mips32-dsp/preceu_ph_qbla.c
 create mode 100644 tests/tcg/mips/mips32-dsp/preceu_ph_qbr.c
 create mode 100644 tests/tcg/mips/mips32-dsp/preceu_ph_qbra.c
 create mode 100644 tests/tcg/mips/mips32-dsp/precrq_ph_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/precrq_qb_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/precrq_rs_ph_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/precrqu_s_qb_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/raddu_w_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/rddsp.c
 create mode 100644 tests/tcg/mips/mips32-dsp/repl_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/repl_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/replv_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/replv_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shilo.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shilov.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shll_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shll_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shll_s_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shll_s_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shllv_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shllv_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shllv_s_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shllv_s_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shra_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shra_r_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shra_r_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shrav_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shrav_r_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shrav_r_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shrl_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/shrlv_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/subq_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/subq_s_ph.c
 create mode 100644 tests/tcg/mips/mips32-dsp/subq_s_w.c
 create mode 100644 tests/tcg/mips/mips32-dsp/subu_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/subu_s_qb.c
 create mode 100644 tests/tcg/mips/mips32-dsp/wrdsp.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/Makefile
 create mode 100644 tests/tcg/mips/mips32-dspr2/absq_s_qb.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/addqh_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/addqh_r_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/addqh_r_w.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/addqh_w.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/addu_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/addu_s_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/adduh_qb.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/adduh_r_qb.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/append.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/balign.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/cmpgdu_eq_qb.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/cmpgdu_le_qb.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/cmpgdu_lt_qb.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/dpa_w_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/dpaqx_s_w_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/dpaqx_sa_w_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/dpax_w_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/dps_w_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/dpsqx_s_w_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/dpsqx_sa_w_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/dpsx_w_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/mul_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/mul_s_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/muleq_s_w_phl.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/mulq_rs_w.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/mulq_s_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/mulq_s_w.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/mulsa_w_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/mulsaq_s_w_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/precr_qb_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/precr_sra_ph_w.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/precr_sra_r_ph_w.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/prepend.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/shra_qb.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/shra_r_qb.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/shrav_qb.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/shrav_r_qb.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/shrl_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/shrlv_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/subqh_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/subqh_r_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/subqh_r_w.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/subqh_w.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/subu_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/subu_s_ph.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/subuh_qb.c
 create mode 100644 tests/tcg/mips/mips32-dspr2/subuh_r_qb.c

diff --git a/tests/tcg/mips/mips32-dsp/Makefile b/tests/tcg/mips/mips32-dsp/Makefile
new file mode 100644
index 0000000..ee8a386
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/Makefile
@@ -0,0 +1,133 @@
+-include ../../config-host.mak
+
+CROSS=mipsel-unknown-linux-gnu-
+
+SIM=qemu-mipsel
+
+CC      = $(CROSS)gcc
+CFLAGS  = -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 += 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_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) ./$$case;\
+        $(SIM) ./$$case; \
+	done
+
+clean:
+	$(RM) -rf $(TESTCASES)
diff --git a/tests/tcg/mips/mips32-dsp/absq_s_ph.c b/tests/tcg/mips/mips32-dsp/absq_s_ph.c
new file mode 100644
index 0000000..f54d833
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/absq_s_ph.c
@@ -0,0 +1,30 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rt;
+    int result;
+
+    rt     = 0x10017EFD;
+    result = 0x10017EFD;
+
+    __asm volatile
+        ("absq_s.ph %0, %1\n\t"
+         :"=r"(rd)
+         :"r"(rt)
+        );
+    assert(rd == result);
+
+    rt     = 0x8000A536;
+    result = 0x7FFF5ACA;
+
+    __asm volatile
+        ("absq_s.ph %0, %1\n\t"
+         :"=r"(rd)
+         :"r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/absq_s_w.c b/tests/tcg/mips/mips32-dsp/absq_s_w.c
new file mode 100644
index 0000000..4cb7dd8
--- /dev/null
+++ b/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 volatile
+        ("absq_s.w %0, %1\n\t"
+         :"=r"(rd)
+         :"r"(rt)
+        );
+    assert(rd == result);
+
+    rt     = 0x80030000;
+    result = 0x7FFD0000;
+    __asm volatile
+        ("absq_s.w %0, %1\n\t"
+         :"=r"(rd)
+         :"r"(rt)
+        );
+    assert(rd == result);
+
+    rt     = 0x31036080;
+    result = 0x31036080;
+    __asm volatile
+        ("absq_s.w %0, %1\n\t"
+         :"=r"(rd)
+         :"r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/addq_ph.c b/tests/tcg/mips/mips32-dsp/addq_ph.c
new file mode 100644
index 0000000..30fe7ac
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/addq_ph.c
@@ -0,0 +1,30 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt;
+    int result;
+
+    rs     = 0xFFFFFFFF;
+    rt     = 0x10101010;
+    result = 0x100F100F;
+    __asm volatile
+        ("addq.ph   %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(result == rd);
+
+    rs     = 0x3712847D;
+    rt     = 0x0031AF2D;
+    result = 0x374333AA;
+    __asm volatile
+        ("addq.ph   %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(result == rd);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/addq_s_ph.c b/tests/tcg/mips/mips32-dsp/addq_s_ph.c
new file mode 100644
index 0000000..47d8fed
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/addq_s_ph.c
@@ -0,0 +1,30 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt;
+    int result;
+
+    rs     = 0xFFFFFFFF;
+    rt     = 0x10101010;
+    result = 0x100F100F;
+    __asm volatile
+        ("addq_s.ph   %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(result == rd);
+
+    rs     = 0x3712847D;
+    rt     = 0x0031AF2D;
+    result = 0x37438000;
+    __asm volatile
+        ("addq_s.ph   %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(result == rd);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/addsc.c b/tests/tcg/mips/mips32-dsp/addsc.c
new file mode 100644
index 0000000..16a3ad6
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/addsc.c
@@ -0,0 +1,30 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt;
+    int result;
+
+    rs     = 0x0000000F;
+    rt     = 0x00000001;
+    result = 0x00000010;
+    __asm volatile
+        ("addsc %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd == result);
+
+    rs     = 0xFFFF0FFF;
+    rt     = 0x00010111;
+    result = 0x00001110;
+    __asm volatile
+        ("addsc %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/addu_qb.c b/tests/tcg/mips/mips32-dsp/addu_qb.c
new file mode 100644
index 0000000..1f6ef83
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/addu_qb.c
@@ -0,0 +1,30 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt;
+    int result;
+
+    rs     = 0x00FF00FF;
+    rt     = 0x00010001;
+    result = 0x00000000;
+    __asm volatile
+        ("addu.qb %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd == result);
+
+    rs     = 0xFFFF1111;
+    rt     = 0x00020001;
+    result = 0xFF011112;
+    __asm volatile
+        ("addu.qb %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/addu_s_qb.c b/tests/tcg/mips/mips32-dsp/addu_s_qb.c
new file mode 100644
index 0000000..afdb5d6
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/addu_s_qb.c
@@ -0,0 +1,30 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt;
+    int result;
+
+    rs     = 0x10FF01FF;
+    rt     = 0x10010001;
+    result = 0x20FF01FF;
+    __asm volatile
+        ("addu_s.qb %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd == result);
+
+    rs     = 0xFFFF1111;
+    rt     = 0x00020001;
+    result = 0xFFFF1112;
+    __asm volatile
+        ("addu_s.qb %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/addwc.c b/tests/tcg/mips/mips32-dsp/addwc.c
new file mode 100644
index 0000000..df2f029
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/addwc.c
@@ -0,0 +1,30 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt;
+    int result;
+
+    rs     = 0x10FF01FF;
+    rt     = 0x10010001;
+    result = 0x21000200;
+    __asm volatile
+        ("addwc %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd == result);
+
+    rs     = 0xFFFF1111;
+    rt     = 0x00020001;
+    result = 0x00011112;
+    __asm volatile
+        ("addwc %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/bitrev.c b/tests/tcg/mips/mips32-dsp/bitrev.c
new file mode 100644
index 0000000..c0f05bd
--- /dev/null
+++ b/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 = 0x00005678;
+
+    __asm volatile
+        ("bitrev %0, %1\n\t"
+         :"=r"(rd)
+         :"r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/bposge32.c b/tests/tcg/mips/mips32-dsp/bposge32.c
new file mode 100644
index 0000000..558416f
--- /dev/null
+++ b/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 volatile
+        ("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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/cmp_eq_ph.c b/tests/tcg/mips/mips32-dsp/cmp_eq_ph.c
new file mode 100644
index 0000000..6984727
--- /dev/null
+++ b/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 volatile
+        ("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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/cmp_le_ph.c b/tests/tcg/mips/mips32-dsp/cmp_le_ph.c
new file mode 100644
index 0000000..e5a8f8f
--- /dev/null
+++ b/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 volatile
+        ("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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/cmp_lt_ph.c b/tests/tcg/mips/mips32-dsp/cmp_lt_ph.c
new file mode 100644
index 0000000..c47e4da
--- /dev/null
+++ b/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 volatile
+        ("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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/cmpgu_eq_qb.c b/tests/tcg/mips/mips32-dsp/cmpgu_eq_qb.c
new file mode 100644
index 0000000..b5547bb
--- /dev/null
+++ b/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 volatile
+        ("cmpgu.eq.qb %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+
+    assert(rd == result);
+
+    rs     = 0x11777066;
+    rt     = 0x11777066;
+    result = 0x0F;
+    __asm volatile
+        ("cmpgu.eq.qb %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/cmpgu_le_qb.c b/tests/tcg/mips/mips32-dsp/cmpgu_le_qb.c
new file mode 100644
index 0000000..eac2497
--- /dev/null
+++ b/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 volatile
+        ("cmpgu.le.qb %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+
+    assert(rd == result);
+
+    rs     = 0x11777066;
+    rt     = 0x11766066;
+    result = 0x09;
+    __asm volatile
+        ("cmpgu.le.qb %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/cmpgu_lt_qb.c b/tests/tcg/mips/mips32-dsp/cmpgu_lt_qb.c
new file mode 100644
index 0000000..ecf2cc2
--- /dev/null
+++ b/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 volatile
+        ("cmpgu.lt.qb %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+
+    assert(rd == result);
+
+    rs     = 0x11777066;
+    rt     = 0x11766066;
+    result = 0x00;
+    __asm volatile
+        ("cmpgu.lt.qb %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/cmpu_eq_qb.c b/tests/tcg/mips/mips32-dsp/cmpu_eq_qb.c
new file mode 100644
index 0000000..f074510
--- /dev/null
+++ b/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 volatile
+        ("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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/cmpu_le_qb.c b/tests/tcg/mips/mips32-dsp/cmpu_le_qb.c
new file mode 100644
index 0000000..10ddcc9
--- /dev/null
+++ b/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 volatile
+        ("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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/cmpu_lt_qb.c b/tests/tcg/mips/mips32-dsp/cmpu_lt_qb.c
new file mode 100644
index 0000000..9e99a52
--- /dev/null
+++ b/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 volatile
+        ("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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/dpaq_s_w_ph.c b/tests/tcg/mips/mips32-dsp/dpaq_s_w_ph.c
new file mode 100644
index 0000000..baa4bc3
--- /dev/null
+++ b/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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/dpaq_sa_l_w.c b/tests/tcg/mips/mips32-dsp/dpaq_sa_l_w.c
new file mode 100644
index 0000000..dc4cb31
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/dpaq_sa_l_w.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   = 0x7FFFFFFF;
+    resultl   = 0xFFFFFFFF;
+    resultdsp = 0x01;
+    __asm volatile
+        ("mthi        %0, $ac1    \n\t"
+         "mtlo        %0, $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/tests/tcg/mips/mips32-dsp/dpau_h_qbl.c b/tests/tcg/mips/mips32-dsp/dpau_h_qbl.c
new file mode 100644
index 0000000..698f9c5
--- /dev/null
+++ b/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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/dpau_h_qbr.c b/tests/tcg/mips/mips32-dsp/dpau_h_qbr.c
new file mode 100644
index 0000000..da411dd
--- /dev/null
+++ b/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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/dpsq_s_w_ph.c b/tests/tcg/mips/mips32-dsp/dpsq_s_w_ph.c
new file mode 100644
index 0000000..bd8bb68
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/dpsq_s_w_ph.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 = 0xEE9794A3;
+    __asm volatile
+        ("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/tests/tcg/mips/mips32-dsp/dpsq_sa_l_w.c b/tests/tcg/mips/mips32-dsp/dpsq_sa_l_w.c
new file mode 100644
index 0000000..f2b6855
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/dpsq_sa_l_w.c
@@ -0,0 +1,31 @@
+#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 = 0x7FFFFFFF;
+    resultl = 0xFFFFFFFF;
+    resultdsp = 0x01;
+    __asm volatile
+        ("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/tests/tcg/mips/mips32-dsp/dpsu_h_qbl.c b/tests/tcg/mips/mips32-dsp/dpsu_h_qbl.c
new file mode 100644
index 0000000..c68cdac
--- /dev/null
+++ b/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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/dpsu_h_qbr.c b/tests/tcg/mips/mips32-dsp/dpsu_h_qbr.c
new file mode 100644
index 0000000..432656c
--- /dev/null
+++ b/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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/extp.c b/tests/tcg/mips/mips32-dsp/extp.c
new file mode 100644
index 0000000..4b4d742
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/extp.c
@@ -0,0 +1,44 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rt, ach, acl, dsp;
+    int result;
+
+    ach = 0x05;
+    acl = 0xB4CB;
+    dsp = 0x07;
+    result = 0x000C;
+
+    __asm volatile
+        ("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 volatile
+        ("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);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/extpdp.c b/tests/tcg/mips/mips32-dsp/extpdp.c
new file mode 100644
index 0000000..d5eab8b
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/extpdp.c
@@ -0,0 +1,46 @@
+#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 volatile
+        ("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 volatile
+        ("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);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/extpdpv.c b/tests/tcg/mips/mips32-dsp/extpdpv.c
new file mode 100644
index 0000000..b158fda
--- /dev/null
+++ b/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 volatile
+        ("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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/extpv.c b/tests/tcg/mips/mips32-dsp/extpv.c
new file mode 100644
index 0000000..0421627
--- /dev/null
+++ b/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 volatile
+        ("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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/extr_r_w.c b/tests/tcg/mips/mips32-dsp/extr_r_w.c
new file mode 100644
index 0000000..4b3eb4c
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/extr_r_w.c
@@ -0,0 +1,25 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rt, ach, acl, dsp;
+    int result;
+
+    ach = 0x05;
+    acl = 0xB4CB;
+    result = 0xA0001699;
+    __asm volatile
+        ("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);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/extr_rs_w.c b/tests/tcg/mips/mips32-dsp/extr_rs_w.c
new file mode 100644
index 0000000..9eccb98
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/extr_rs_w.c
@@ -0,0 +1,25 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rt, ach, acl, dsp;
+    int result;
+
+    ach = 0x05;
+    acl = 0xB4CB;
+    result = 0x7FFFFFFF;
+    __asm volatile
+        ("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);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/extr_s_h.c b/tests/tcg/mips/mips32-dsp/extr_s_h.c
new file mode 100644
index 0000000..446388f
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/extr_s_h.c
@@ -0,0 +1,25 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rt, ach, acl, dsp;
+    int result;
+
+    ach = 0x05;
+    acl = 0xB4CB;
+    result = 0x00007FFF;
+    __asm volatile
+        ("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);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/extr_w.c b/tests/tcg/mips/mips32-dsp/extr_w.c
new file mode 100644
index 0000000..4c17fc2
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/extr_w.c
@@ -0,0 +1,25 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rt, ach, acl, dsp;
+    int result;
+
+    ach = 0x05;
+    acl = 0xB4CB;
+    result = 0xA0001699;
+    __asm volatile
+        ("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);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/extrv_r_w.c b/tests/tcg/mips/mips32-dsp/extrv_r_w.c
new file mode 100644
index 0000000..ce9d157
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/extrv_r_w.c
@@ -0,0 +1,29 @@
+#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 volatile
+        ("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);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/extrv_rs_w.c b/tests/tcg/mips/mips32-dsp/extrv_rs_w.c
new file mode 100644
index 0000000..6704ab2
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/extrv_rs_w.c
@@ -0,0 +1,29 @@
+#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 = 0x7FFFFFFF;
+
+    __asm volatile
+        ("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);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/extrv_s_h.c b/tests/tcg/mips/mips32-dsp/extrv_s_h.c
new file mode 100644
index 0000000..a752580
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/extrv_s_h.c
@@ -0,0 +1,29 @@
+#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 volatile
+        ("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);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/extrv_w.c b/tests/tcg/mips/mips32-dsp/extrv_w.c
new file mode 100644
index 0000000..0f33942
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/extrv_w.c
@@ -0,0 +1,29 @@
+#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 volatile
+        ("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);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/insv.c b/tests/tcg/mips/mips32-dsp/insv.c
new file mode 100644
index 0000000..5678269
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/insv.c
@@ -0,0 +1,23 @@
+#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 = 0x12345338;
+    __asm volatile
+        ("wrdsp %2, 0x03\n\t"
+         "insv  %0, %1  \n\t"
+         :"+r"(rt)
+         :"r"(rs), "r"(dsp)
+        );
+    assert(rt == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/lbux.c b/tests/tcg/mips/mips32-dsp/lbux.c
new file mode 100644
index 0000000..4fe83c5
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/lbux.c
@@ -0,0 +1,23 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int value, index, rd;
+    int result;
+
+    value  = 0xBCDEF389;
+    index  = 28;
+    result = value & 0xFF;
+    __asm volatile
+        ("lw  $10, 28($fp)\n\t"
+         "sw  %2,  28($fp)\n\t"
+         "lbux %0, %1($fp)\n\t"
+         "sw  $10, 28($fp)\n\t"
+         :"=r"(rd)
+         :"r"(index), "r"(value)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/lhx.c b/tests/tcg/mips/mips32-dsp/lhx.c
new file mode 100644
index 0000000..aa28e54
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/lhx.c
@@ -0,0 +1,23 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int value, index, rd;
+    int result;
+
+    value  = 0xBCDEF389;
+    index  = 28;
+    result = 0xFFFFF389;
+    __asm volatile
+        ("lw  $10, 28($fp)\n\t"
+         "sw  %2,  28($fp)\n\t"
+         "lhx %0, %1($fp)\n\t"
+         "sw  $10, 28($fp)\n\t"
+         :"=r"(rd)
+         :"r"(index), "r"(value)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/lwx.c b/tests/tcg/mips/mips32-dsp/lwx.c
new file mode 100644
index 0000000..352e0a1
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/lwx.c
@@ -0,0 +1,23 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int value, index, rd;
+    int result;
+
+    value  = 0xBCDEF389;
+    index  = 28;
+    result = value;
+    __asm volatile
+        ("lw  $10, 28($fp)\n\t"
+         "sw  %2,  28($fp)\n\t"
+         "lwx %0, %1($fp)\n\t"
+         "sw  $10, 28($fp)\n\t"
+         :"=r"(rd)
+         :"r"(index), "r"(value)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/madd.c b/tests/tcg/mips/mips32-dsp/madd.c
new file mode 100644
index 0000000..588929c
--- /dev/null
+++ b/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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/maddu.c b/tests/tcg/mips/mips32-dsp/maddu.c
new file mode 100644
index 0000000..588929c
--- /dev/null
+++ b/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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/maq_s_w_phl.c b/tests/tcg/mips/mips32-dsp/maq_s_w_phl.c
new file mode 100644
index 0000000..f87bd44
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/maq_s_w_phl.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  = 0xFF060000;
+    rt  = 0xCB000000;
+    resulth = 0x04;
+    resultl = 0x947438CB;
+
+    __asm volatile
+        ("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);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/maq_s_w_phr.c b/tests/tcg/mips/mips32-dsp/maq_s_w_phr.c
new file mode 100644
index 0000000..207278e
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/maq_s_w_phr.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  = 0xFF06;
+    rt  = 0xCB00;
+    resulth = 0x04;
+    resultl = 0x947438CB;
+
+    __asm volatile
+        ("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);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/maq_sa_w_phl.c b/tests/tcg/mips/mips32-dsp/maq_sa_w_phl.c
new file mode 100644
index 0000000..7896990
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/maq_sa_w_phl.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  = 0xFF060000;
+    rt  = 0xCB000000;
+    resulth = 0xFFFFFFFF;
+    resultl = 0x80000000;
+
+    __asm volatile
+        ("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);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/maq_sa_w_phr.c b/tests/tcg/mips/mips32-dsp/maq_sa_w_phr.c
new file mode 100644
index 0000000..8e92681
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/maq_sa_w_phr.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  = 0xFF06;
+    rt  = 0xCB00;
+    resulth = 0xFFFFFFFF;
+    resultl = 0x80000000;
+
+    __asm volatile
+        ("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);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/mfhi.c b/tests/tcg/mips/mips32-dsp/mfhi.c
new file mode 100644
index 0000000..156c070
--- /dev/null
+++ b/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 volatile
+        ("mthi %1, $ac1\n\t"
+         "mfhi %0, $ac1\n\t"
+         :"=r"(acho)
+         :"r"(achi)
+        );
+    assert(result == acho);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/mflo.c b/tests/tcg/mips/mips32-dsp/mflo.c
new file mode 100644
index 0000000..0a4aa8c
--- /dev/null
+++ b/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 volatile
+        ("mthi %1, $ac1\n\t"
+         "mfhi %0, $ac1\n\t"
+         :"=r"(aclo)
+         :"r"(acli)
+        );
+    assert(result == aclo);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/modsub.c b/tests/tcg/mips/mips32-dsp/modsub.c
new file mode 100644
index 0000000..72f9a78
--- /dev/null
+++ b/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 volatile
+        ("modsub %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(result == rd);
+
+    rs     = 0x00000000;
+    rt     = 0x00CD1FFF;
+    result = 0x0000CD1F;
+    __asm volatile
+        ("modsub %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(result == rd);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/msub.c b/tests/tcg/mips/mips32-dsp/msub.c
new file mode 100644
index 0000000..00ab8d8
--- /dev/null
+++ b/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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/msubu.c b/tests/tcg/mips/mips32-dsp/msubu.c
new file mode 100644
index 0000000..6b8c644
--- /dev/null
+++ b/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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/mthi.c b/tests/tcg/mips/mips32-dsp/mthi.c
new file mode 100644
index 0000000..156c070
--- /dev/null
+++ b/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 volatile
+        ("mthi %1, $ac1\n\t"
+         "mfhi %0, $ac1\n\t"
+         :"=r"(acho)
+         :"r"(achi)
+        );
+    assert(result == acho);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/mthlip.c b/tests/tcg/mips/mips32-dsp/mthlip.c
new file mode 100644
index 0000000..b055f51
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/mthlip.c
@@ -0,0 +1,34 @@
+#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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/mtlo.c b/tests/tcg/mips/mips32-dsp/mtlo.c
new file mode 100644
index 0000000..0a4aa8c
--- /dev/null
+++ b/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 volatile
+        ("mthi %1, $ac1\n\t"
+         "mfhi %0, $ac1\n\t"
+         :"=r"(aclo)
+         :"r"(acli)
+        );
+    assert(result == aclo);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/muleq_s_w_phr.c b/tests/tcg/mips/mips32-dsp/muleq_s_w_phr.c
new file mode 100644
index 0000000..eb61190
--- /dev/null
+++ b/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 volatile
+        ("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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/muleu_s_ph_qbl.c b/tests/tcg/mips/mips32-dsp/muleu_s_ph_qbl.c
new file mode 100644
index 0000000..4400203
--- /dev/null
+++ b/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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/muleu_s_ph_qbr.c b/tests/tcg/mips/mips32-dsp/muleu_s_ph_qbr.c
new file mode 100644
index 0000000..3e8cc9f
--- /dev/null
+++ b/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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/mulq_rs_ph.c b/tests/tcg/mips/mips32-dsp/mulq_rs_ph.c
new file mode 100644
index 0000000..38527a0
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/mulq_rs_ph.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 = 0x7FFF098C;
+    resultdsp = 1;
+
+    __asm volatile
+        ("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/tests/tcg/mips/mips32-dsp/mult.c b/tests/tcg/mips/mips32-dsp/mult.c
new file mode 100644
index 0000000..d915af8
--- /dev/null
+++ b/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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/multu.c b/tests/tcg/mips/mips32-dsp/multu.c
new file mode 100644
index 0000000..d915af8
--- /dev/null
+++ b/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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/packrl_ph.c b/tests/tcg/mips/mips32-dsp/packrl_ph.c
new file mode 100644
index 0000000..802a82d
--- /dev/null
+++ b/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 volatile
+        ("packrl.ph %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(result == rd);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/pick_ph.c b/tests/tcg/mips/mips32-dsp/pick_ph.c
new file mode 100644
index 0000000..b71ddde
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/pick_ph.c
@@ -0,0 +1,23 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt, dsp;
+    int result;
+
+    rs = 0x12345678;
+    rt = 0x87654321;
+    dsp = 0x0A000000;
+    result = 0x12344321;
+
+    __asm volatile
+        ("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/tests/tcg/mips/mips32-dsp/pick_qb.c b/tests/tcg/mips/mips32-dsp/pick_qb.c
new file mode 100644
index 0000000..10a19ce
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/pick_qb.c
@@ -0,0 +1,23 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt, dsp;
+    int result;
+
+    rs = 0x12345678;
+    rt = 0x87654321;
+    dsp = 0x0A000000;
+    result = 0x12655621;
+
+    __asm volatile
+        ("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/tests/tcg/mips/mips32-dsp/preceq_w_phl.c b/tests/tcg/mips/mips32-dsp/preceq_w_phl.c
new file mode 100644
index 0000000..e8b066b
--- /dev/null
+++ b/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 volatile
+        ("preceq.w.phl %0, %1\n\t"
+         :"=r"(rd)
+         :"r"(rt)
+        );
+    assert(result == rd);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/preceq_w_phr.c b/tests/tcg/mips/mips32-dsp/preceq_w_phr.c
new file mode 100644
index 0000000..c86f872
--- /dev/null
+++ b/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 volatile
+        ("preceq.w.phr %0, %1\n\t"
+         :"=r"(rd)
+         :"r"(rt)
+        );
+    assert(result == rd);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/precequ_ph_qbl.c b/tests/tcg/mips/mips32-dsp/precequ_ph_qbl.c
new file mode 100644
index 0000000..e482807
--- /dev/null
+++ b/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 volatile
+        ("precequ.ph.qbl %0, %1\n\t"
+         :"=r"(rd)
+         :"r"(rt)
+        );
+    assert(result == rd);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/precequ_ph_qbla.c b/tests/tcg/mips/mips32-dsp/precequ_ph_qbla.c
new file mode 100644
index 0000000..d9ef398
--- /dev/null
+++ b/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 volatile
+        ("precequ.ph.qbla %0, %1\n\t"
+         :"=r"(rd)
+         :"r"(rt)
+        );
+    assert(result == rd);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/precequ_ph_qbr.c b/tests/tcg/mips/mips32-dsp/precequ_ph_qbr.c
new file mode 100644
index 0000000..853e54e
--- /dev/null
+++ b/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 volatile
+        ("precequ.ph.qbr %0, %1\n\t"
+         :"=r"(rd)
+         :"r"(rt)
+        );
+    assert(result == rd);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/precequ_ph_qbra.c b/tests/tcg/mips/mips32-dsp/precequ_ph_qbra.c
new file mode 100644
index 0000000..5243525
--- /dev/null
+++ b/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 volatile
+        ("precequ.ph.qbra %0, %1\n\t"
+         :"=r"(rd)
+         :"r"(rt)
+        );
+    assert(result == rd);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/preceu_ph_qbl.c b/tests/tcg/mips/mips32-dsp/preceu_ph_qbl.c
new file mode 100644
index 0000000..2d6b6d4
--- /dev/null
+++ b/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 volatile
+        ("preceu.ph.qbl %0, %1\n\t"
+         :"=r"(rd)
+         :"r"(rt)
+        );
+    assert(result == rd);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/preceu_ph_qbla.c b/tests/tcg/mips/mips32-dsp/preceu_ph_qbla.c
new file mode 100644
index 0000000..76025f6
--- /dev/null
+++ b/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 volatile
+        ("preceu.ph.qbla %0, %1\n\t"
+         :"=r"(rd)
+         :"r"(rt)
+        );
+    assert(result == rd);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/preceu_ph_qbr.c b/tests/tcg/mips/mips32-dsp/preceu_ph_qbr.c
new file mode 100644
index 0000000..9280dd6
--- /dev/null
+++ b/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 volatile
+        ("preceu.ph.qbr %0, %1\n\t"
+         :"=r"(rd)
+         :"r"(rt)
+        );
+    assert(result == rd);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/preceu_ph_qbra.c b/tests/tcg/mips/mips32-dsp/preceu_ph_qbra.c
new file mode 100644
index 0000000..60f3db6
--- /dev/null
+++ b/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 volatile
+        ("preceu.ph.qbra %0, %1\n\t"
+         :"=r"(rd)
+         :"r"(rt)
+        );
+    assert(result == rd);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/precrq_ph_w.c b/tests/tcg/mips/mips32-dsp/precrq_ph_w.c
new file mode 100644
index 0000000..66f1643
--- /dev/null
+++ b/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 volatile
+        ("precrq.ph.w %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(result == rd);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/precrq_qb_ph.c b/tests/tcg/mips/mips32-dsp/precrq_qb_ph.c
new file mode 100644
index 0000000..2ab9d17
--- /dev/null
+++ b/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 volatile
+        ("precrq.qb.ph %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(result == rd);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/precrq_rs_ph_w.c b/tests/tcg/mips/mips32-dsp/precrq_rs_ph_w.c
new file mode 100644
index 0000000..0dfedfc
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/precrq_rs_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 volatile
+        ("precrq_rs.ph.w %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(result == rd);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/precrqu_s_qb_ph.c b/tests/tcg/mips/mips32-dsp/precrqu_s_qb_ph.c
new file mode 100644
index 0000000..741f3ac
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/precrqu_s_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 = 0x24AC0086;
+
+    __asm volatile
+        ("precrqu_s.qb.ph %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(result == rd);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/raddu_w_qb.c b/tests/tcg/mips/mips32-dsp/raddu_w_qb.c
new file mode 100644
index 0000000..b75fc0a
--- /dev/null
+++ b/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 volatile
+        ("raddu.w.qb %0, %1\n\t"
+         :"=r"(rd)
+         :"r"(rs)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/rddsp.c b/tests/tcg/mips/mips32-dsp/rddsp.c
new file mode 100644
index 0000000..2795c96
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/rddsp.c
@@ -0,0 +1,54 @@
+#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;
+    int ccond_r, outflag_r, efi_r, c_r, scount_r, pos_r;
+
+    ccond_i   = 0x000000BC;/* 4 */
+    outflag_i = 0x0000001B;/* 3 */
+    efi_i     = 0x00000001;/* 5 */
+    c_i       = 0x00000001;/* 2 */
+    scount_i  = 0x0000000F;/* 1 */
+    pos_i     = 0x0000000C;/* 0 */
+
+    dsp_i = (ccond_i   << 24) | \
+            (outflag_i << 16) | \
+            (efi_i     << 14) | \
+            (c_i       << 13) | \
+            (scount_i  <<  7) | \
+            pos_i;
+
+    ccond_r   = ccond_i;
+    outflag_r = outflag_i;
+    efi_r     = efi_i;
+    c_r       = c_i;
+    scount_r  = scount_i;
+    pos_r     = pos_i;
+
+    __asm volatile
+        ("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_r);
+    assert(outflag_o == outflag_r);
+    assert(efi_o     == efi_r);
+    assert(c_o       == c_r);
+    assert(scount_o  == scount_r);
+    assert(pos_o     == pos_r);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/repl_ph.c b/tests/tcg/mips/mips32-dsp/repl_ph.c
new file mode 100644
index 0000000..2c20054
--- /dev/null
+++ b/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 volatile
+        ("repl.ph %0, 0x1BF\n\t"
+         :"=r"(rd)
+        );
+    assert(rd == result);
+
+    result = 0xFE00FE00;
+    __asm volatile
+        ("repl.ph %0, -512\n\t"
+         :"=r"(rd)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/repl_qb.c b/tests/tcg/mips/mips32-dsp/repl_qb.c
new file mode 100644
index 0000000..7574a6b
--- /dev/null
+++ b/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 volatile
+        ("repl.qb %0, 0xBF\n\t"
+         :"=r"(rd)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/replv_ph.c b/tests/tcg/mips/mips32-dsp/replv_ph.c
new file mode 100644
index 0000000..87d87ba
--- /dev/null
+++ b/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 volatile
+        ("replv.ph %0, %1\n\t"
+         :"=r"(rd)
+         :"r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/replv_qb.c b/tests/tcg/mips/mips32-dsp/replv_qb.c
new file mode 100644
index 0000000..7eced6b
--- /dev/null
+++ b/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 volatile
+        ("replv.qb %0, %1\n\t"
+         :"=r"(rd)
+         :"r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/shilo.c b/tests/tcg/mips/mips32-dsp/shilo.c
new file mode 100644
index 0000000..40d7b9b
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/shilo.c
@@ -0,0 +1,27 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int ach, acl;
+    int resulth, resultl;
+
+    ach = 0xBBAACCFF;
+    acl = 0x1C3B001D;
+
+    resulth = 0x17755;
+    resultl = 0x99fe3876;
+
+    __asm volatile
+        ("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);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/shilov.c b/tests/tcg/mips/mips32-dsp/shilov.c
new file mode 100644
index 0000000..80ea5d2
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/shilov.c
@@ -0,0 +1,29 @@
+#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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/shll_ph.c b/tests/tcg/mips/mips32-dsp/shll_ph.c
new file mode 100644
index 0000000..7a0e97f
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/shll_ph.c
@@ -0,0 +1,24 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rt, dsp;
+    int result, resultdsp;
+
+    rt        = 0x12345678;
+    result    = 0xA000C000;
+    resultdsp = 1;
+
+    __asm volatile
+        ("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);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/shll_qb.c b/tests/tcg/mips/mips32-dsp/shll_qb.c
new file mode 100644
index 0000000..64a494d
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/shll_qb.c
@@ -0,0 +1,23 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rt, dsp;
+    int result, resultdsp;
+
+    rt     = 0x87654321;
+    result = 0x38281808;
+    resultdsp = 0x01;
+
+    __asm volatile
+        ("shll.qb %0, %2, 0x03\n\t"
+         "rddsp   %1\n\t"
+         :"=r"(rd), "=r"(dsp)
+         :"r"(rt)
+        );
+    dsp = (dsp >> 22) & 0x01;
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/shll_s_ph.c b/tests/tcg/mips/mips32-dsp/shll_s_ph.c
new file mode 100644
index 0000000..8b306d4
--- /dev/null
+++ b/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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/shll_s_w.c b/tests/tcg/mips/mips32-dsp/shll_s_w.c
new file mode 100644
index 0000000..00f4543
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/shll_s_w.c
@@ -0,0 +1,24 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rt, dsp;
+    int result, resultdsp;
+
+    rt        = 0x12345678;
+    result    = 0x7FFFFFFF;
+    resultdsp = 0x01;
+
+    __asm volatile
+        ("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/tests/tcg/mips/mips32-dsp/shllv_ph.c b/tests/tcg/mips/mips32-dsp/shllv_ph.c
new file mode 100644
index 0000000..76be5bb
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/shllv_ph.c
@@ -0,0 +1,25 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt, dsp;
+    int result, resultdsp;
+
+    rs        = 0x0B;
+    rt        = 0x12345678;
+    result    = 0xA000C000;
+    resultdsp = 1;
+
+    __asm volatile
+        ("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/tests/tcg/mips/mips32-dsp/shllv_qb.c b/tests/tcg/mips/mips32-dsp/shllv_qb.c
new file mode 100644
index 0000000..785ec0a
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/shllv_qb.c
@@ -0,0 +1,24 @@
+#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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/shllv_s_ph.c b/tests/tcg/mips/mips32-dsp/shllv_s_ph.c
new file mode 100644
index 0000000..bcee2b6
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/shllv_s_ph.c
@@ -0,0 +1,25 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt, dsp;
+    int result, resultdsp;
+
+    rs        = 0x0B;
+    rt        = 0x12345678;
+    result    = 0x7FFF7FFF;
+    resultdsp = 0x01;
+
+    __asm volatile
+        ("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/tests/tcg/mips/mips32-dsp/shllv_s_w.c b/tests/tcg/mips/mips32-dsp/shllv_s_w.c
new file mode 100644
index 0000000..bc6588b
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/shllv_s_w.c
@@ -0,0 +1,25 @@
+#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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/shra_ph.c b/tests/tcg/mips/mips32-dsp/shra_ph.c
new file mode 100644
index 0000000..349dc41
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/shra_ph.c
@@ -0,0 +1,20 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rt;
+    int result;
+
+    rt     = 0x87654321;
+    result = 0xF0EC0864;
+
+    __asm volatile
+        ("shra.ph %0, %1, 0x03\n\t"
+         :"=r"(rd)
+         :"r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/shra_r_ph.c b/tests/tcg/mips/mips32-dsp/shra_r_ph.c
new file mode 100644
index 0000000..057e349
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/shra_r_ph.c
@@ -0,0 +1,20 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rt;
+    int result;
+
+    rt     = 0x87654321;
+    result = 0xF0ED0864;
+
+    __asm volatile
+        ("shra_r.ph %0, %1, 0x03\n\t"
+         :"=r"(rd)
+         :"r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/shra_r_w.c b/tests/tcg/mips/mips32-dsp/shra_r_w.c
new file mode 100644
index 0000000..1f12aab
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/shra_r_w.c
@@ -0,0 +1,20 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rt;
+    int result;
+
+    rt     = 0x87654321;
+    result = 0xF0ECA864;
+
+    __asm volatile
+        ("shra_r.w %0, %1, 0x03\n\t"
+         :"=r"(rd)
+         :"r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/shrav_ph.c b/tests/tcg/mips/mips32-dsp/shrav_ph.c
new file mode 100644
index 0000000..50809ee
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/shrav_ph.c
@@ -0,0 +1,21 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt;
+    int result;
+
+    rs     = 0x03;
+    rt     = 0x87654321;
+    result = 0xF0EC0864;
+
+    __asm volatile
+        ("shrav.ph %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rt), "r"(rs)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/shrav_r_ph.c b/tests/tcg/mips/mips32-dsp/shrav_r_ph.c
new file mode 100644
index 0000000..9bdce5f
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/shrav_r_ph.c
@@ -0,0 +1,21 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt;
+    int result;
+
+    rs     = 0x03;
+    rt     = 0x87654321;
+    result = 0xF0ED0864;
+
+    __asm volatile
+        ("shrav_r.ph %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rt), "r"(rs)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/shrav_r_w.c b/tests/tcg/mips/mips32-dsp/shrav_r_w.c
new file mode 100644
index 0000000..e9722a6
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/shrav_r_w.c
@@ -0,0 +1,21 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt;
+    int result;
+
+    rs     = 0x03;
+    rt     = 0x87654321;
+    result = 0xF0ECA864;
+
+    __asm volatile
+        ("shrav_r.w %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rt), "r"(rs)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/shrl_qb.c b/tests/tcg/mips/mips32-dsp/shrl_qb.c
new file mode 100644
index 0000000..a3c9070
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/shrl_qb.c
@@ -0,0 +1,20 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rt;
+    int result;
+
+    rt     = 0x12345678;
+    result = 0x00010203;
+
+    __asm volatile
+        ("shrl.qb %0, %1, 0x05\n\t"
+         :"=r"(rd)
+         :"r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/shrlv_qb.c b/tests/tcg/mips/mips32-dsp/shrlv_qb.c
new file mode 100644
index 0000000..119d908
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/shrlv_qb.c
@@ -0,0 +1,21 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt;
+    int result;
+
+    rs     = 0x05;
+    rt     = 0x12345678;
+    result = 0x00010203;
+
+    __asm volatile
+        ("shrlv.qb %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rt), "r"(rs)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dsp/subq_ph.c b/tests/tcg/mips/mips32-dsp/subq_ph.c
new file mode 100644
index 0000000..bfa6532
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/subq_ph.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    = 0x8ACF1357;
+    resultdsp = 0x01;
+
+    __asm volatile
+        ("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/tests/tcg/mips/mips32-dsp/subq_s_ph.c b/tests/tcg/mips/mips32-dsp/subq_s_ph.c
new file mode 100644
index 0000000..1bf13f8
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/subq_s_ph.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    = 0x7FFF1357;
+    resultdsp = 0x01;
+
+    __asm volatile
+        ("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/tests/tcg/mips/mips32-dsp/subq_s_w.c b/tests/tcg/mips/mips32-dsp/subq_s_w.c
new file mode 100644
index 0000000..391368e
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/subq_s_w.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    = 0x7FFFFFFF;
+    resultdsp = 0x01;
+
+    __asm volatile
+        ("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/tests/tcg/mips/mips32-dsp/subu_qb.c b/tests/tcg/mips/mips32-dsp/subu_qb.c
new file mode 100644
index 0000000..a8f7f25
--- /dev/null
+++ b/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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/subu_s_qb.c b/tests/tcg/mips/mips32-dsp/subu_s_qb.c
new file mode 100644
index 0000000..cc5a25f
--- /dev/null
+++ b/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 volatile
+        ("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/tests/tcg/mips/mips32-dsp/wrdsp.c b/tests/tcg/mips/mips32-dsp/wrdsp.c
new file mode 100644
index 0000000..2795c96
--- /dev/null
+++ b/tests/tcg/mips/mips32-dsp/wrdsp.c
@@ -0,0 +1,54 @@
+#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;
+    int ccond_r, outflag_r, efi_r, c_r, scount_r, pos_r;
+
+    ccond_i   = 0x000000BC;/* 4 */
+    outflag_i = 0x0000001B;/* 3 */
+    efi_i     = 0x00000001;/* 5 */
+    c_i       = 0x00000001;/* 2 */
+    scount_i  = 0x0000000F;/* 1 */
+    pos_i     = 0x0000000C;/* 0 */
+
+    dsp_i = (ccond_i   << 24) | \
+            (outflag_i << 16) | \
+            (efi_i     << 14) | \
+            (c_i       << 13) | \
+            (scount_i  <<  7) | \
+            pos_i;
+
+    ccond_r   = ccond_i;
+    outflag_r = outflag_i;
+    efi_r     = efi_i;
+    c_r       = c_i;
+    scount_r  = scount_i;
+    pos_r     = pos_i;
+
+    __asm volatile
+        ("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_r);
+    assert(outflag_o == outflag_r);
+    assert(efi_o     == efi_r);
+    assert(c_o       == c_r);
+    assert(scount_o  == scount_r);
+    assert(pos_o     == pos_r);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/Makefile b/tests/tcg/mips/mips32-dspr2/Makefile
new file mode 100644
index 0000000..68b5649
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/Makefile
@@ -0,0 +1,71 @@
+-include ../../config-host.mak
+
+CROSS=mipsel-unknown-linux-gnu-
+
+SIM=qemu-mipsel
+
+CC      = $(CROSS)gcc
+CFLAGS  = -march=mips32r2 -mgp32 -mdspr2 -static
+
+TESTCASES = absq_s_qb.tst
+TESTCASES += addqh_ph.tst
+TESTCASES += addqh_r_ph.tst
+TESTCASES += addqh_r_w.tst
+TESTCASES += addqh_w.tst
+TESTCASES += adduh_qb.tst
+TESTCASES += adduh_r_qb.tst
+TESTCASES += addu_ph.tst
+TESTCASES += addu_s_ph.tst
+TESTCASES += append.tst
+TESTCASES += balign.tst
+TESTCASES += cmpgdu_eq_qb.tst
+TESTCASES += cmpgdu_le_qb.tst
+TESTCASES += cmpgdu_lt_qb.tst
+TESTCASES += dpaqx_sa_w_ph.tst
+TESTCASES += dpa_w_ph.tst
+TESTCASES += dpax_w_ph.tst
+TESTCASES += dpaqx_s_w_ph.tst
+TESTCASES += dpsqx_sa_w_ph.tst
+TESTCASES += dpsqx_s_w_ph.tst
+TESTCASES += dps_w_ph.tst
+TESTCASES += dpsx_w_ph.tst
+TESTCASES += muleq_s_w_phl.tst
+TESTCASES += mul_ph.tst
+TESTCASES += mulq_rs_w.tst
+TESTCASES += mulq_s_ph.tst
+TESTCASES += mulq_s_w.tst
+TESTCASES += mulsaq_s_w_ph.tst
+TESTCASES += mulsa_w_ph.tst
+TESTCASES += mul_s_ph.tst
+TESTCASES += precr_qb_ph.tst
+TESTCASES += precr_sra_ph_w.tst
+TESTCASES += precr_sra_r_ph_w.tst
+TESTCASES += prepend.tst
+TESTCASES += shra_qb.tst
+TESTCASES += shra_r_qb.tst
+TESTCASES += shrav_qb.tst
+TESTCASES += shrav_r_qb.tst
+TESTCASES += shrl_ph.tst
+TESTCASES += shrlv_ph.tst
+TESTCASES += subqh_ph.tst
+TESTCASES += subqh_r_ph.tst
+TESTCASES += subqh_r_w.tst
+TESTCASES += subqh_w.tst
+TESTCASES += subuh_qb.tst
+TESTCASES += subuh_r_qb.tst
+TESTCASES += subu_ph.tst
+TESTCASES += subu_s_ph.tst
+
+all: $(TESTCASES)
+
+%.tst: %.c
+	$(CC) $(CFLAGS) $< -o $@
+
+check: $(TESTCASES)
+	@for case in $(TESTCASES); do \
+        echo $(SIM) ./$$case;\
+		$(SIM) ./$$case; \
+	done
+
+clean:
+	$(RM) -rf $(TESTCASES)
diff --git a/tests/tcg/mips/mips32-dspr2/absq_s_qb.c b/tests/tcg/mips/mips32-dspr2/absq_s_qb.c
new file mode 100644
index 0000000..baeaa77
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/absq_s_qb.c
@@ -0,0 +1,31 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int input, result;
+    int hope;
+
+    input = 0x701BA35E;
+    hope  = 0x701B5D5E;
+
+    __asm volatile
+        ("absq_s.qb %0, %1\n\t"
+         :"=r"(result)
+         :"r"(input)
+        );
+    assert(result == hope);
+
+
+    input = 0x801BA35E;
+    hope  = 0x7F1B5D5E;
+
+    __asm volatile
+        ("absq_s.qb %0, %1\n\t"
+         :"=r"(result)
+         :"r"(input)
+        );
+    assert(result == hope);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/addqh_ph.c b/tests/tcg/mips/mips32-dspr2/addqh_ph.c
new file mode 100644
index 0000000..a317b97
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/addqh_ph.c
@@ -0,0 +1,30 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt;
+    int result;
+
+    rs     = 0x706A13FE;
+    rt     = 0x13065174;
+    result = 0x41B832B9;
+    __asm volatile
+        ("addqh.ph %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd == result);
+
+    rs     = 0x01000100;
+    rt     = 0x02000100;
+    result = 0x01800100;
+    __asm volatile
+        ("addqh.ph %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/addqh_r_ph.c b/tests/tcg/mips/mips32-dspr2/addqh_r_ph.c
new file mode 100644
index 0000000..23fb3e5
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/addqh_r_ph.c
@@ -0,0 +1,30 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt;
+    int result;
+
+    rs     = 0x706A13FE;
+    rt     = 0x13065174;
+    result = 0x41B832B9;
+    __asm volatile
+        ("addqh_r.ph %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd == result);
+
+    rs     = 0x01000100;
+    rt     = 0x02000100;
+    result = 0x01800100;
+    __asm volatile
+        ("addqh_r.ph %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/addqh_r_w.c b/tests/tcg/mips/mips32-dspr2/addqh_r_w.c
new file mode 100644
index 0000000..7433f0f
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/addqh_r_w.c
@@ -0,0 +1,34 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt;
+    int result;
+
+    rs     = 0x00000010;
+    rt     = 0x00000001;
+    result = 0x00000009;
+
+    __asm volatile
+        ("addqh_r.w  %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+
+    assert(rd == result);
+
+    rs     = 0xFFFFFFFE;
+    rt     = 0x00000001;
+    result = 0x00000000;
+
+    __asm volatile
+        ("addqh_r.w  %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/addqh_w.c b/tests/tcg/mips/mips32-dspr2/addqh_w.c
new file mode 100644
index 0000000..0b7126c
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/addqh_w.c
@@ -0,0 +1,34 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt;
+    int result;
+
+    rs     = 0x00000010;
+    rt     = 0x00000001;
+    result = 0x00000008;
+
+    __asm volatile
+        ("addqh.w  %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+
+    assert(rd == result);
+
+    rs     = 0xFFFFFFFE;
+    rt     = 0x00000001;
+    result = 0xFFFFFFFF;
+
+    __asm volatile
+        ("addqh.w  %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/addu_ph.c b/tests/tcg/mips/mips32-dspr2/addu_ph.c
new file mode 100644
index 0000000..7b4cb4d
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/addu_ph.c
@@ -0,0 +1,30 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt;
+    int result;
+
+    rs     = 0x00FF00FF;
+    rt     = 0x00010001;
+    result = 0x01000100;
+    __asm volatile
+        ("addu.ph %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd == result);
+
+    rs     = 0xFFFF1111;
+    rt     = 0x00020001;
+    result = 0x00011112;
+    __asm volatile
+        ("addu.ph %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/addu_s_ph.c b/tests/tcg/mips/mips32-dspr2/addu_s_ph.c
new file mode 100644
index 0000000..9a9babe
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/addu_s_ph.c
@@ -0,0 +1,30 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt;
+    int result;
+
+    rs     = 0x00FE00FE;
+    rt     = 0x00020001;
+    result = 0x010000FF;
+    __asm volatile
+        ("addu_s.ph %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd == result);
+
+    rs     = 0xFFFF1111;
+    rt     = 0x00020001;
+    result = 0xFFFF1112;
+    __asm volatile
+        ("addu_s.ph %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/adduh_qb.c b/tests/tcg/mips/mips32-dspr2/adduh_qb.c
new file mode 100644
index 0000000..e2c46da
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/adduh_qb.c
@@ -0,0 +1,30 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt;
+    int result;
+
+    rs     = 0xFF0055AA;
+    rt     = 0x0113421B;
+    result = 0x80094B62;
+    __asm volatile
+        ("adduh.qb %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd == result);
+
+    rs     = 0xFFFF0FFF;
+    rt     = 0x00010111;
+    result = 0x7F800888;
+    __asm volatile
+        ("adduh.qb %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/adduh_r_qb.c b/tests/tcg/mips/mips32-dspr2/adduh_r_qb.c
new file mode 100644
index 0000000..0b4e8a0
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/adduh_r_qb.c
@@ -0,0 +1,30 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt;
+    int result;
+
+    rs     = 0xFF0055AA;
+    rt     = 0x01112211;
+    result = 0x80093C5E;
+    __asm volatile
+        ("adduh_r.qb %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd == result);
+
+    rs     = 0xFFFF0FFF;
+    rt     = 0x00010111;
+    result = 0x80800888;
+    __asm volatile
+        ("adduh_r.qb %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/append.c b/tests/tcg/mips/mips32-dspr2/append.c
new file mode 100644
index 0000000..647c374
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/append.c
@@ -0,0 +1,30 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rs, rt;
+    int result;
+
+    rs     = 0xFF0055AA;
+    rt     = 0x0113421B;
+    result = 0x02268436;
+    __asm volatile
+        ("append %0, %1, 0x01\n\t"
+         :"+r"(rt)
+         :"r"(rs)
+        );
+    assert(rt == result);
+
+    rs     = 0xFFFF0FFF;
+    rt     = 0x00010111;
+    result = 0x0010111F;
+    __asm volatile
+        ("append %0, %1, 0x04\n\t"
+         :"+r"(rt)
+         :"r"(rs)
+        );
+    assert(rt == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/balign.c b/tests/tcg/mips/mips32-dspr2/balign.c
new file mode 100644
index 0000000..1d89889
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/balign.c
@@ -0,0 +1,30 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rs, rt;
+    int result;
+
+    rs     = 0xFF0055AA;
+    rt     = 0x0113421B;
+    result = 0x13421BFF;
+    __asm volatile
+        ("balign %0, %1, 0x01\n\t"
+         :"+r"(rt)
+         :"r"(rs)
+        );
+    assert(rt == result);
+
+    rs     = 0xFFFF0FFF;
+    rt     = 0x00010111;
+    result = 0x11FFFF0F;
+    __asm volatile
+        ("balign %0, %1, 0x03\n\t"
+         :"+r"(rt)
+         :"r"(rs)
+        );
+    assert(rt == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/cmpgdu_eq_qb.c b/tests/tcg/mips/mips32-dspr2/cmpgdu_eq_qb.c
new file mode 100644
index 0000000..3493ce7
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/cmpgdu_eq_qb.c
@@ -0,0 +1,37 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt;
+    int dsp;
+    int result;
+
+    rs         = 0x11777066;
+    rt         = 0x55AA70FF;
+    result     = 0x02;
+    __asm volatile
+        ("cmpgdu.eq.qb %0, %2, %3\n\t"
+         "rddsp %1\n\t"
+         :"=r"(rd), "=r"(dsp)
+         :"r"(rs), "r"(rt)
+        );
+    dsp = (dsp >> 24) & 0x0F;
+    assert(rd  == result);
+    assert(dsp == result);
+
+    rs     = 0x11777066;
+    rt     = 0x11777066;
+    result = 0x0F;
+    __asm volatile
+        ("cmpgdu.eq.qb %0, %2, %3\n\t"
+         "rddsp %1\n\t"
+         :"=r"(rd), "=r"(dsp)
+         :"r"(rs), "r"(rt)
+        );
+    dsp = (dsp >> 24) & 0x0F;
+    assert(rd  == result);
+    assert(dsp == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/cmpgdu_le_qb.c b/tests/tcg/mips/mips32-dspr2/cmpgdu_le_qb.c
new file mode 100644
index 0000000..1a77a7c
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/cmpgdu_le_qb.c
@@ -0,0 +1,37 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt;
+    int dsp;
+    int result;
+
+    rs         = 0x11777066;
+    rt         = 0x55AA70FF;
+    result     = 0x0F;
+    __asm volatile
+        ("cmpgdu.le.qb %0, %2, %3\n\t"
+         "rddsp %1\n\t"
+         :"=r"(rd), "=r"(dsp)
+         :"r"(rs), "r"(rt)
+        );
+    dsp = (dsp >> 24) & 0x0F;
+    assert(rd  == result);
+    assert(dsp == result);
+
+    rs     = 0x11777066;
+    rt     = 0x11707066;
+    result = 0x0B;
+    __asm volatile
+        ("cmpgdu.le.qb %0, %2, %3\n\t"
+         "rddsp %1\n\t"
+         :"=r"(rd), "=r"(dsp)
+         :"r"(rs), "r"(rt)
+        );
+    dsp = (dsp >> 24) & 0x0F;
+    assert(rd  == result);
+    assert(dsp == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/cmpgdu_lt_qb.c b/tests/tcg/mips/mips32-dspr2/cmpgdu_lt_qb.c
new file mode 100644
index 0000000..e88c6f3
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/cmpgdu_lt_qb.c
@@ -0,0 +1,37 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt;
+    int dsp;
+    int result;
+
+    rs         = 0x11777066;
+    rt         = 0x55AA70FF;
+    result     = 0x0D;
+    __asm volatile
+        ("cmpgdu.lt.qb %0, %2, %3\n\t"
+         "rddsp %1\n\t"
+         :"=r"(rd), "=r"(dsp)
+         :"r"(rs), "r"(rt)
+        );
+    dsp = (dsp >> 24) & 0x0F;
+    assert(rd  == result);
+    assert(dsp == result);
+
+    rs     = 0x11777066;
+    rt     = 0x11777066;
+    result = 0x00;
+    __asm volatile
+        ("cmpgdu.lt.qb %0, %2, %3\n\t"
+         "rddsp %1\n\t"
+         :"=r"(rd), "=r"(dsp)
+         :"r"(rs), "r"(rt)
+        );
+    dsp = (dsp >> 24) & 0x0F;
+    assert(rd  == result);
+    assert(dsp == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/dpa_w_ph.c b/tests/tcg/mips/mips32-dspr2/dpa_w_ph.c
new file mode 100644
index 0000000..96251a9
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/dpa_w_ph.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     = 0x00FF00FF;
+    rt     = 0x00010002;
+    resulth = 0x05;
+    resultl = 0x0302;
+    __asm volatile
+        ("mthi  %0, $ac1\n\t"
+         "mtlo  %1, $ac1\n\t"
+         "dpa.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/tests/tcg/mips/mips32-dspr2/dpaqx_s_w_ph.c b/tests/tcg/mips/mips32-dspr2/dpaqx_s_w_ph.c
new file mode 100644
index 0000000..fb1b9c0
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/dpaqx_s_w_ph.c
@@ -0,0 +1,57 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rs, rt, dsp;
+    int ach = 5, acl = 5;
+    int resulth, resultl, resultdsp;
+
+    rs     = 0x800000FF;
+    rt     = 0x00018000;
+    resulth = 0x05;
+    resultl = 0x80000202;
+    resultdsp = 0x01;
+    __asm volatile
+        ("mthi  %0, $ac1\n\t"
+         "mtlo  %1, $ac1\n\t"
+         "dpaqx_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);
+
+    ach    = 5;
+    acl    = 5;
+    rs     = 0x00FF00FF;
+    rt     = 0x00010002;
+    resulth = 0x05;
+    resultl = 0x05FF;
+    /***********************************************************
+     * Because of we set outflag at last time, although this
+     * time we set nothing, but it is stay the last time value.
+     **********************************************************/
+    resultdsp = 0x01;
+    __asm volatile
+        ("mthi  %0, $ac1\n\t"
+         "mtlo  %1, $ac1\n\t"
+         "dpaqx_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/tests/tcg/mips/mips32-dspr2/dpaqx_sa_w_ph.c b/tests/tcg/mips/mips32-dspr2/dpaqx_sa_w_ph.c
new file mode 100644
index 0000000..d438657
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/dpaqx_sa_w_ph.c
@@ -0,0 +1,30 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rs, rt, dsp;
+    int ach = 5, acl = 5;
+    int resulth, resultl, resultdsp;
+
+    rs     = 0x00FF00FF;
+    rt     = 0x00010002;
+    resulth = 0x05;
+    resultl = 0x05FF;
+    resultdsp = 0x00;
+    __asm volatile
+        ("mthi  %0, $ac1\n\t"
+         "mtlo  %1, $ac1\n\t"
+         "dpaqx_sa.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)
+        );
+    assert(dsp == resultdsp);
+    assert(ach == resulth);
+    assert(acl == resultl);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/dpax_w_ph.c b/tests/tcg/mips/mips32-dspr2/dpax_w_ph.c
new file mode 100644
index 0000000..749f86b
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/dpax_w_ph.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     = 0x00FF00FF;
+    rt     = 0x00010002;
+    resulth = 0x05;
+    resultl = 0x0302;
+    __asm volatile
+        ("mthi  %0, $ac1\n\t"
+         "mtlo  %1, $ac1\n\t"
+         "dpax.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/tests/tcg/mips/mips32-dspr2/dps_w_ph.c b/tests/tcg/mips/mips32-dspr2/dps_w_ph.c
new file mode 100644
index 0000000..9701480
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/dps_w_ph.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     = 0x00FF00FF;
+    rt     = 0x00010002;
+    resulth = 0x04;
+    resultl = 0xFFFFFD08;
+    __asm volatile
+        ("mthi  %0, $ac1\n\t"
+         "mtlo  %1, $ac1\n\t"
+         "dps.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/tests/tcg/mips/mips32-dspr2/dpsqx_s_w_ph.c b/tests/tcg/mips/mips32-dspr2/dpsqx_s_w_ph.c
new file mode 100644
index 0000000..16a4822
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/dpsqx_s_w_ph.c
@@ -0,0 +1,31 @@
+#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 = 0x04;
+    resultl = 0xAEA3E09B;
+    resultdsp = 0x00;
+    __asm volatile
+        ("mthi  %0, $ac1\n\t"
+         "mtlo  %1, $ac1\n\t"
+         "dpsqx_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/tests/tcg/mips/mips32-dspr2/dpsqx_sa_w_ph.c b/tests/tcg/mips/mips32-dspr2/dpsqx_sa_w_ph.c
new file mode 100644
index 0000000..7fb196b
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/dpsqx_sa_w_ph.c
@@ -0,0 +1,31 @@
+#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 = 0x00;
+    resultl = 0x7FFFFFFF;
+    resultdsp = 0x01;
+    __asm volatile
+        ("mthi  %0, $ac1\n\t"
+         "mtlo  %1, $ac1\n\t"
+         "dpsqx_sa.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/tests/tcg/mips/mips32-dspr2/dpsx_w_ph.c b/tests/tcg/mips/mips32-dspr2/dpsx_w_ph.c
new file mode 100644
index 0000000..9379f5e
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/dpsx_w_ph.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 = 0xD751F050;
+    __asm volatile
+        ("mthi  %0, $ac1\n\t"
+         "mtlo  %1, $ac1\n\t"
+         "dpsx.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/tests/tcg/mips/mips32-dspr2/mul_ph.c b/tests/tcg/mips/mips32-dspr2/mul_ph.c
new file mode 100644
index 0000000..ace04a0
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/mul_ph.c
@@ -0,0 +1,25 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt, dsp;
+    int result, resultdsp;
+
+    rs = 0x03FB1234;
+    rt = 0x0BCC4321;
+    result = 0xF504F4B4;
+    resultdsp = 1;
+
+    __asm volatile
+        ("mul.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/tests/tcg/mips/mips32-dspr2/mul_s_ph.c b/tests/tcg/mips/mips32-dspr2/mul_s_ph.c
new file mode 100644
index 0000000..ca75c71
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/mul_s_ph.c
@@ -0,0 +1,25 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt, dsp;
+    int result, resultdsp;
+
+    rs = 0x03FB1234;
+    rt = 0x0BCC4321;
+    result = 0x7fff7FFF;
+    resultdsp = 1;
+
+    __asm volatile
+        ("mul_s.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/tests/tcg/mips/mips32-dspr2/muleq_s_w_phl.c b/tests/tcg/mips/mips32-dspr2/muleq_s_w_phl.c
new file mode 100644
index 0000000..0e59718
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/muleq_s_w_phl.c
@@ -0,0 +1,40 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt, dsp;
+    int result, resultdsp;
+
+    rs = 0x80001234;
+    rt = 0x80004321;
+    result = 0x7FFFFFFF;
+    resultdsp = 1;
+
+    __asm volatile
+        ("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 = 0x12340000;
+    rt = 0x43210000;
+    result = 0x98be968;
+    resultdsp = 1;
+
+    __asm volatile
+        ("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/tests/tcg/mips/mips32-dspr2/mulq_rs_w.c b/tests/tcg/mips/mips32-dspr2/mulq_rs_w.c
new file mode 100644
index 0000000..78b4b98
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/mulq_rs_w.c
@@ -0,0 +1,36 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt, dsp;
+    int result, resultdsp;
+
+    rs = 0x80001234;
+    rt = 0x80004321;
+    result = 0x80005555;
+
+    __asm volatile
+        ("mulq_rs.w %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd  == result);
+
+    rs = 0x80000000;
+    rt = 0x80000000;
+    result = 0x7FFFFFFF;
+    resultdsp = 1;
+
+    __asm volatile
+        ("mulq_rs.w %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/tests/tcg/mips/mips32-dspr2/mulq_s_ph.c b/tests/tcg/mips/mips32-dspr2/mulq_s_ph.c
new file mode 100644
index 0000000..5659a5f
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/mulq_s_ph.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 = 0x7FFF098B;
+    resultdsp = 1;
+
+    __asm volatile
+        ("mulq_s.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/tests/tcg/mips/mips32-dspr2/mulq_s_w.c b/tests/tcg/mips/mips32-dspr2/mulq_s_w.c
new file mode 100644
index 0000000..8eeefe3
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/mulq_s_w.c
@@ -0,0 +1,36 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt, dsp;
+    int result, resultdsp;
+
+    rs = 0x80001234;
+    rt = 0x80004321;
+    result = 0x80005555;
+
+    __asm volatile
+        ("mulq_s.w %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd  == result);
+
+    rs = 0x80000000;
+    rt = 0x80000000;
+    result = 0x7FFFFFFF;
+    resultdsp = 1;
+
+    __asm volatile
+        ("mulq_s.w %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/tests/tcg/mips/mips32-dspr2/mulsa_w_ph.c b/tests/tcg/mips/mips32-dspr2/mulsa_w_ph.c
new file mode 100644
index 0000000..f250968
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/mulsa_w_ph.c
@@ -0,0 +1,29 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rs, rt, ach, acl;
+    int resulth, resultl;
+
+    ach = 0x05;
+    acl = 0x00BBDDCC;
+    rs = 0x80001234;
+    rt = 0x80004321;
+    resulth = 0x05;
+    resultl = 0x3BF5E918;
+
+    __asm volatile
+        ("mthi %0, $ac1\n\t"
+         "mtlo %1, $ac1\n\t"
+         "mulsa.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/tests/tcg/mips/mips32-dspr2/mulsaq_s_w_ph.c b/tests/tcg/mips/mips32-dspr2/mulsaq_s_w_ph.c
new file mode 100644
index 0000000..a44274b
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/mulsaq_s_w_ph.c
@@ -0,0 +1,29 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rs, rt, ach, acl;
+    int resulth, resultl;
+
+    ach = 0x05;
+    acl = 0x00BBDDCC;
+    rs = 0x80001234;
+    rt = 0x80004321;
+    resulth = 0x05;
+    resultl = 0x772ff463;
+
+    __asm volatile
+        ("mthi %0, $ac1\n\t"
+         "mtlo %1, $ac1\n\t"
+         "mulsaq_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/tests/tcg/mips/mips32-dspr2/precr_qb_ph.c b/tests/tcg/mips/mips32-dspr2/precr_qb_ph.c
new file mode 100644
index 0000000..a05d945
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/precr_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 = 0x34786521;
+
+    __asm volatile
+        ("precr.qb.ph %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(result == rd);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/precr_sra_ph_w.c b/tests/tcg/mips/mips32-dspr2/precr_sra_ph_w.c
new file mode 100644
index 0000000..77dcb99
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/precr_sra_ph_w.c
@@ -0,0 +1,32 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rs, rt;
+    int result;
+
+    rs = 0x12345678;
+    rt = 0x87654321;
+    result = 0x43215678;
+
+    __asm volatile
+        ("precr_sra.ph.w %0, %1, 0x00\n\t"
+         :"+r"(rt)
+         :"r"(rs)
+        );
+    assert(result == rt);
+
+    rs = 0x12345678;
+    rt = 0x87654321;
+    result = 0xFFFF0000;
+
+    __asm volatile
+        ("precr_sra.ph.w %0, %1, 0x1F\n\t"
+         :"+r"(rt)
+         :"r"(rs)
+        );
+    assert(result == rt);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/precr_sra_r_ph_w.c b/tests/tcg/mips/mips32-dspr2/precr_sra_r_ph_w.c
new file mode 100644
index 0000000..9afca04
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/precr_sra_r_ph_w.c
@@ -0,0 +1,32 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rs, rt;
+    int result;
+
+    rs = 0x12345678;
+    rt = 0x87654321;
+    result = 0x43215678;
+
+    __asm volatile
+        ("precr_sra_r.ph.w %0, %1, 0x00\n\t"
+         :"+r"(rt)
+         :"r"(rs)
+        );
+    assert(result == rt);
+
+    rs = 0x12345678;
+    rt = 0x87654321;
+    result = 0xFFFF0000;
+
+    __asm volatile
+        ("precr_sra_r.ph.w %0, %1, 0x1F\n\t"
+         :"+r"(rt)
+         :"r"(rs)
+        );
+    assert(result == rt);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/prepend.c b/tests/tcg/mips/mips32-dspr2/prepend.c
new file mode 100644
index 0000000..6824ecc
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/prepend.c
@@ -0,0 +1,30 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rs, rt;
+    int result;
+
+    rs = 0x12345678;
+    rt = 0x87654321;
+    result = 0x87654321;
+    __asm volatile
+        ("prepend %0, %1, 0x00\n\t"
+         :"+r"(rt)
+         :"r"(rs)
+        );
+    assert(rt == result);
+
+    rs = 0x12345678;
+    rt = 0x87654321;
+    result = 0xACF10ECA;
+    __asm volatile
+        ("prepend %0, %1, 0x0F\n\t"
+         :"+r"(rt)
+         :"r"(rs)
+        );
+    assert(rt == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/shra_qb.c b/tests/tcg/mips/mips32-dspr2/shra_qb.c
new file mode 100644
index 0000000..5254182
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/shra_qb.c
@@ -0,0 +1,30 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rt;
+    int result;
+
+    rt = 0x12345678;
+    result = 0x02060A0F;
+
+    __asm volatile
+        ("shra.qb %0, %1, 0x03\n\t"
+         :"=r"(rd)
+         :"r"(rt)
+        );
+    assert(rd == result);
+
+    rt = 0x87654321;
+    result = 0xF00C0804;
+
+    __asm volatile
+        ("shra.qb %0, %1, 0x03\n\t"
+         :"=r"(rd)
+         :"r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/shra_r_qb.c b/tests/tcg/mips/mips32-dspr2/shra_r_qb.c
new file mode 100644
index 0000000..ce51c53
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/shra_r_qb.c
@@ -0,0 +1,30 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rt;
+    int result;
+
+    rt = 0x12345678;
+    result = 0x02070B0F;
+
+    __asm volatile
+        ("shra_r.qb %0, %1, 0x03\n\t"
+         :"=r"(rd)
+         :"r"(rt)
+        );
+    assert(rd == result);
+
+    rt = 0x87654321;
+    result = 0xF10D0804;
+
+    __asm volatile
+        ("shra_r.qb %0, %1, 0x03\n\t"
+         :"=r"(rd)
+         :"r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/shrav_qb.c b/tests/tcg/mips/mips32-dspr2/shrav_qb.c
new file mode 100644
index 0000000..4a79943
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/shrav_qb.c
@@ -0,0 +1,32 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt;
+    int result;
+
+    rs = 0x03;
+    rt = 0x12345678;
+    result = 0x02060A0F;
+
+    __asm volatile
+        ("shrav.qb %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rt), "r"(rs)
+        );
+    assert(rd == result);
+
+    rs = 0x03;
+    rt = 0x87654321;
+    result = 0xF00C0804;
+
+    __asm volatile
+        ("shrav.qb %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rt), "r"(rs)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/shrav_r_qb.c b/tests/tcg/mips/mips32-dspr2/shrav_r_qb.c
new file mode 100644
index 0000000..b1efe84
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/shrav_r_qb.c
@@ -0,0 +1,32 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt;
+    int result;
+
+    rs = 0x03;
+    rt = 0x12345678;
+    result = 0x02070B0F;
+
+    __asm volatile
+        ("shrav_r.qb %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rt), "r"(rs)
+        );
+    assert(rd == result);
+
+    rs = 0x03;
+    rt = 0x87654321;
+    result = 0xF10D0804;
+
+    __asm volatile
+        ("shrav_r.qb %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rt), "r"(rs)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/shrl_ph.c b/tests/tcg/mips/mips32-dspr2/shrl_ph.c
new file mode 100644
index 0000000..4839ecf
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/shrl_ph.c
@@ -0,0 +1,20 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rt;
+    int result;
+
+    rt     = 0x12345678;
+    result = 0x009102B3;
+
+    __asm volatile
+        ("shrl.ph %0, %1, 0x05\n\t"
+         :"=r"(rd)
+         :"r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/shrlv_ph.c b/tests/tcg/mips/mips32-dspr2/shrlv_ph.c
new file mode 100644
index 0000000..bfd3752
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/shrlv_ph.c
@@ -0,0 +1,21 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt;
+    int result;
+
+    rs     = 0x05;
+    rt     = 0x12345678;
+    result = 0x009102B3;
+
+    __asm volatile
+        ("shrlv.ph %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rt), "r"(rs)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/subqh_ph.c b/tests/tcg/mips/mips32-dspr2/subqh_ph.c
new file mode 100644
index 0000000..35afa57
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/subqh_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 = 0x456709AB;
+
+    __asm volatile
+        ("subqh.ph %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/subqh_r_ph.c b/tests/tcg/mips/mips32-dspr2/subqh_r_ph.c
new file mode 100644
index 0000000..5c78dfe
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/subqh_r_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 = 0x456809AC;
+
+    __asm volatile
+        ("subqh_r.ph %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/subqh_r_w.c b/tests/tcg/mips/mips32-dspr2/subqh_r_w.c
new file mode 100644
index 0000000..4320581
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/subqh_r_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 = 0x456789AC;
+
+    __asm volatile
+        ("subqh_r.w %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/subqh_w.c b/tests/tcg/mips/mips32-dspr2/subqh_w.c
new file mode 100644
index 0000000..5c564aa
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/subqh_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 = 0x456789AB;
+
+    __asm volatile
+        ("subqh.w %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/subu_ph.c b/tests/tcg/mips/mips32-dspr2/subu_ph.c
new file mode 100644
index 0000000..a7c6caa
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/subu_ph.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    = 0x7531ECA9;
+    resultdsp = 0x01;
+
+    __asm volatile
+        ("subu.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/tests/tcg/mips/mips32-dspr2/subu_s_ph.c b/tests/tcg/mips/mips32-dspr2/subu_s_ph.c
new file mode 100644
index 0000000..1b0c8f6
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/subu_s_ph.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    = 0x75310000;
+    resultdsp = 0x01;
+
+    __asm volatile
+        ("subu_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/tests/tcg/mips/mips32-dspr2/subuh_qb.c b/tests/tcg/mips/mips32-dspr2/subuh_qb.c
new file mode 100644
index 0000000..1ffdcf4
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/subuh_qb.c
@@ -0,0 +1,21 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt;
+    int result;
+
+    rs = 0x12345678;
+    rt = 0x87654321;
+    result = 0xC5E7092B;
+
+    __asm volatile
+        ("subuh.qb %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
diff --git a/tests/tcg/mips/mips32-dspr2/subuh_r_qb.c b/tests/tcg/mips/mips32-dspr2/subuh_r_qb.c
new file mode 100644
index 0000000..581d17e
--- /dev/null
+++ b/tests/tcg/mips/mips32-dspr2/subuh_r_qb.c
@@ -0,0 +1,21 @@
+#include<stdio.h>
+#include<assert.h>
+
+int main()
+{
+    int rd, rs, rt;
+    int result;
+
+    rs = 0x12345678;
+    rt = 0x87654321;
+    result = 0xC6E80A2C;
+
+    __asm volatile
+        ("subuh_r.qb %0, %1, %2\n\t"
+         :"=r"(rd)
+         :"r"(rs), "r"(rt)
+        );
+    assert(rd == result);
+
+    return 0;
+}
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH V2 2/4] add MIPS DSP helpers implement
  2012-03-22 13:36 ` [Qemu-devel] [PATCH V2 2/4] add MIPS DSP helpers implement Jia Liu
@ 2012-03-22 13:54   ` Peter Maydell
  2012-03-23  1:24     ` Jia Liu
  0 siblings, 1 reply; 14+ messages in thread
From: Peter Maydell @ 2012-03-22 13:54 UTC (permalink / raw)
  To: Jia Liu; +Cc: sw, qemu-devel, aurelien

On 22 March 2012 13:36, Jia Liu <proljc@gmail.com> wrote:
> This is the helper implementation of MIPS ASE DSP.
>
> Signed-off-by: Jia Liu <proljc@gmail.com>

git am complains about this patch:
Applying: add MIPS DSP helpers implement
/home/petmay01/linaro/qemu-from-laptop/qemu/.git/rebase-apply/patch:17:
new blank line at EOF.
+
warning: 1 line adds whitespace errors.

-- PMM

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH V2 0/4] MIPS ASE DSP Support for Qemu
  2012-03-22 13:36 [Qemu-devel] [PATCH V2 0/4] MIPS ASE DSP Support for Qemu Jia Liu
                   ` (3 preceding siblings ...)
  2012-03-22 13:36 ` [Qemu-devel] [PATCH V2 4/4] add MIPS DSP testcase Jia Liu
@ 2012-03-22 14:01 ` Peter Maydell
  2012-03-23  1:40   ` Jia Liu
  2012-03-23  7:21   ` 陳韋任
  2012-03-22 14:03 ` Peter Maydell
  2012-03-23 16:01 ` Richard Henderson
  6 siblings, 2 replies; 14+ messages in thread
From: Peter Maydell @ 2012-03-22 14:01 UTC (permalink / raw)
  To: Jia Liu; +Cc: sw, qemu-devel, aurelien

On 22 March 2012 13:36, Jia Liu <proljc@gmail.com> wrote:
> Jia Liu (4):
>  add MIPS DSP helpers define
>  add MIPS DSP helpers implement
>  add MIPS DSP translation
>  add MIPS DSP testcase

You can't split these changes into patches like this.
Every patch needs to be complete of itself, and in particular
it has to compile cleanly at each intermediate point, not just
after all patches are applied. If you apply just patch 1/4
then compilation fails:
  LINK  mips-softmmu/qemu-system-mips
translate.o: In function `mips_tcg_init':
/home/petmay01/linaro/qemu-from-laptop/qemu/target-mips/helper.h:301:
undefined reference to `helper_absqsph'
/home/petmay01/linaro/qemu-from-laptop/qemu/target-mips/helper.h:302:
undefined reference to `helper_absqsw'
/home/petmay01/linaro/qemu-from-laptop/qemu/target-mips/helper.h:303:
undefined reference to `helper_addqph'
[snipped long list of similar errors]

It would be better to break it up as patches each of
which adds support for a coherent bite-sized subset of
these instructions (so each individual patch includes
the helper function declaration, implementation and
translate.c changes for a smaller number of instructions).

You also need to test compilation on a 32 bit host, as that
is currently broken. For example:
/home/petmay01/linaro/qemu-from-laptop/qemu/target-mips/op_helper.c:
In function ‘mipsdsp_sat_add_i32’:
/home/petmay01/linaro/qemu-from-laptop/qemu/target-mips/op_helper.c:3565:
error: integer constant is too large for ‘long’ type
/home/petmay01/linaro/qemu-from-laptop/qemu/target-mips/op_helper.c:
In function ‘mipsdsp_mul_q31_q31’:
/home/petmay01/linaro/qemu-from-laptop/qemu/target-mips/op_helper.c:3874:
error: integer constant is too large for ‘long’ type
[and on for another long list of errors]

Most of these seem to be that you need the "ULL" suffix for
constants which are more than 32 bits wide.

-- PMM

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH V2 0/4] MIPS ASE DSP Support for Qemu
  2012-03-22 13:36 [Qemu-devel] [PATCH V2 0/4] MIPS ASE DSP Support for Qemu Jia Liu
                   ` (4 preceding siblings ...)
  2012-03-22 14:01 ` [Qemu-devel] [PATCH V2 0/4] MIPS ASE DSP Support for Qemu Peter Maydell
@ 2012-03-22 14:03 ` Peter Maydell
  2012-03-23  1:31   ` Jia Liu
  2012-03-23 16:01 ` Richard Henderson
  6 siblings, 1 reply; 14+ messages in thread
From: Peter Maydell @ 2012-03-22 14:03 UTC (permalink / raw)
  To: Jia Liu; +Cc: sw, qemu-devel, aurelien

On 22 March 2012 13:36, Jia Liu <proljc@gmail.com> wrote:
> This is the MIPS ASE DSP Support for Qemu.
> Jia Liu (4):
>  add MIPS DSP helpers define
>  add MIPS DSP helpers implement
>  add MIPS DSP translation
>  add MIPS DSP testcase

Most of these patches generate lots of errors when run
through scripts/checkpatch.pl, which you should fix.

-- PMM

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH V2 2/4] add MIPS DSP helpers implement
  2012-03-22 13:54   ` Peter Maydell
@ 2012-03-23  1:24     ` Jia Liu
  0 siblings, 0 replies; 14+ messages in thread
From: Jia Liu @ 2012-03-23  1:24 UTC (permalink / raw)
  To: Peter Maydell; +Cc: sw, qemu-devel, aurelien

On Thu, Mar 22, 2012 at 9:54 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 22 March 2012 13:36, Jia Liu <proljc@gmail.com> wrote:
>> This is the helper implementation of MIPS ASE DSP.
>>
>> Signed-off-by: Jia Liu <proljc@gmail.com>
>
> git am complains about this patch:
> Applying: add MIPS DSP helpers implement
> /home/petmay01/linaro/qemu-from-laptop/qemu/.git/rebase-apply/patch:17:
> new blank line at EOF.
> +
> warning: 1 line adds whitespace errors.
>
> -- PMM


If I delete the blank line, scripts/checkpatch.pl will say:
ERROR: patch seems to be corrupt (line wrapped?)
#3967: FILE: target-mips/op_helper.c:7346:
1.7.5.4

and I think I should delete the blank line, thank you peter.

Regards,
Jia.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH V2 0/4] MIPS ASE DSP Support for Qemu
  2012-03-22 14:03 ` Peter Maydell
@ 2012-03-23  1:31   ` Jia Liu
  0 siblings, 0 replies; 14+ messages in thread
From: Jia Liu @ 2012-03-23  1:31 UTC (permalink / raw)
  To: Peter Maydell; +Cc: sw, qemu-devel, aurelien

On Thu, Mar 22, 2012 at 10:03 PM, Peter Maydell
<peter.maydell@linaro.org> wrote:
> On 22 March 2012 13:36, Jia Liu <proljc@gmail.com> wrote:
>> This is the MIPS ASE DSP Support for Qemu.
>> Jia Liu (4):
>>  add MIPS DSP helpers define
>>  add MIPS DSP helpers implement
>>  add MIPS DSP translation
>>  add MIPS DSP testcase
>
> Most of these patches generate lots of errors when run
> through scripts/checkpatch.pl, which you should fix.
>
> -- PMM

Thank you, Peter. I've fix the ERRORS in 0004, but I think I have to
keep the ERRORS in 0003.

Regards,
Jia.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH V2 0/4] MIPS ASE DSP Support for Qemu
  2012-03-22 14:01 ` [Qemu-devel] [PATCH V2 0/4] MIPS ASE DSP Support for Qemu Peter Maydell
@ 2012-03-23  1:40   ` Jia Liu
  2012-03-23  7:21   ` 陳韋任
  1 sibling, 0 replies; 14+ messages in thread
From: Jia Liu @ 2012-03-23  1:40 UTC (permalink / raw)
  To: Peter Maydell; +Cc: sw, qemu-devel, aurelien

On Thu, Mar 22, 2012 at 10:01 PM, Peter Maydell
<peter.maydell@linaro.org> wrote:
> On 22 March 2012 13:36, Jia Liu <proljc@gmail.com> wrote:
>> Jia Liu (4):
>>  add MIPS DSP helpers define
>>  add MIPS DSP helpers implement
>>  add MIPS DSP translation
>>  add MIPS DSP testcase
>
> You can't split these changes into patches like this.
> Every patch needs to be complete of itself, and in particular
> it has to compile cleanly at each intermediate point, not just
> after all patches are applied. If you apply just patch 1/4
> then compilation fails:
>  LINK  mips-softmmu/qemu-system-mips
> translate.o: In function `mips_tcg_init':
> /home/petmay01/linaro/qemu-from-laptop/qemu/target-mips/helper.h:301:
> undefined reference to `helper_absqsph'
> /home/petmay01/linaro/qemu-from-laptop/qemu/target-mips/helper.h:302:
> undefined reference to `helper_absqsw'
> /home/petmay01/linaro/qemu-from-laptop/qemu/target-mips/helper.h:303:
> undefined reference to `helper_addqph'
> [snipped long list of similar errors]
>
> It would be better to break it up as patches each of
> which adds support for a coherent bite-sized subset of
> these instructions (so each individual patch includes
> the helper function declaration, implementation and
> translate.c changes for a smaller number of instructions).
>

Thank you.
So I should split these changes into 2 patches, 0001 DSP Support, 0002
testcases. Is it OK?

> You also need to test compilation on a 32 bit host, as that
> is currently broken. For example:
> /home/petmay01/linaro/qemu-from-laptop/qemu/target-mips/op_helper.c:
> In function ‘mipsdsp_sat_add_i32’:
> /home/petmay01/linaro/qemu-from-laptop/qemu/target-mips/op_helper.c:3565:
> error: integer constant is too large for ‘long’ type
> /home/petmay01/linaro/qemu-from-laptop/qemu/target-mips/op_helper.c:
> In function ‘mipsdsp_mul_q31_q31’:
> /home/petmay01/linaro/qemu-from-laptop/qemu/target-mips/op_helper.c:3874:
> error: integer constant is too large for ‘long’ type
> [and on for another long list of errors]
>
> Most of these seem to be that you need the "ULL" suffix for
> constants which are more than 32 bits wide.
>

Sorry, I'm working on a x64 machine, but I'll test it at a i386 machine.

Thank you every much!

> -- PMM

Regards,
Jia.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH V2 0/4] MIPS ASE DSP Support for Qemu
  2012-03-22 14:01 ` [Qemu-devel] [PATCH V2 0/4] MIPS ASE DSP Support for Qemu Peter Maydell
  2012-03-23  1:40   ` Jia Liu
@ 2012-03-23  7:21   ` 陳韋任
  1 sibling, 0 replies; 14+ messages in thread
From: 陳韋任 @ 2012-03-23  7:21 UTC (permalink / raw)
  To: Jia Liu; +Cc: sw, qemu-devel, aurelien, Peter Maydell

> It would be better to break it up as patches each of
> which adds support for a coherent bite-sized subset of
> these instructions (so each individual patch includes
> the helper function declaration, implementation and
> translate.c changes for a smaller number of instructions).

  I am reading MIPS ASE DSP manual [1]. I think you can group those instructions
as "Chapter 4. MIPS DSP ASE Instruction Summary" does. So you might have
following patches,

  [1/] MIPS ASE DSP Support - Arithmetic Sub-class (~50 ins)
  [2/] MIPS ASE DSP Support - GPR-Based Shift Sub-class (~22 ins)
  [3/] MIPS ASE DSP Support - Multiply Sub-class (~38 ins)
  [4/] MIPS ASE DSP Support - Bit/ Manipulation Sub-class (~6 ins)
  [5/] MIPS ASE DSP Support - Compare-Pick Sub-class (~18 ins)
  [6/] MIPS ASE DSP Support - Accumulator and DSPControl Access Sub-class (~21 ins)
  [7/] MIPS ASE DSP Support - Indexed-Load and Branch Sub-class (4 ins)
  [8/] MIPS ASE DSP Testcase

You can combine smaller subsets into a bigger one to make each patch equally
sized. Each patch adding MIPS ASE DSP support should be self-contained, which
means you can apply (and compile) them one-by-one, no error occured. I think
testcase for all ASE DSP instructions can be just one patch.

Regards,
chenwj

[1] MIPS32® Architecture for Programmers VolumeIV-e: The MIPS® DSP
    Application-Specific Extension to the MIPS32®Architecture
    http://www.mips.com/products/product-materials/processor/mips-architecture/

-- 
Wei-Ren Chen (陳韋任)
Computer Systems Lab, Institute of Information Science,
Academia Sinica, Taiwan (R.O.C.)
Tel:886-2-2788-3799 #1667
Homepage: http://people.cs.nctu.edu.tw/~chenwj

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH V2 0/4] MIPS ASE DSP Support for Qemu
  2012-03-22 13:36 [Qemu-devel] [PATCH V2 0/4] MIPS ASE DSP Support for Qemu Jia Liu
                   ` (5 preceding siblings ...)
  2012-03-22 14:03 ` Peter Maydell
@ 2012-03-23 16:01 ` Richard Henderson
  2012-03-26  1:07   ` Jia Liu
  6 siblings, 1 reply; 14+ messages in thread
From: Richard Henderson @ 2012-03-23 16:01 UTC (permalink / raw)
  To: Jia Liu; +Cc: sw, qemu-devel, aurelien

> +DEF_HELPER_1(absqsph, i32, i32)

Many of these helpers merely compute a function.  They do not trap,
they do not modify global state.  They should be using the 
DEF_HELPER_FLAGS_N macro to define them, so that the TCG compiler
can optimize around the functions better.

>  target-mips/op_helper.c | 3936 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 3936 insertions(+), 0 deletions(-)

Nearly 4000 lines to me says: put these in their own file.

It would be my preference if this were done in a way that
exposes any implicit uses of the ENV variable.  But even
failing that, the makefile can be adjusted to apply HELPER_CFLAGS
to other helper files.


r~

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH V2 0/4] MIPS ASE DSP Support for Qemu
  2012-03-23 16:01 ` Richard Henderson
@ 2012-03-26  1:07   ` Jia Liu
  0 siblings, 0 replies; 14+ messages in thread
From: Jia Liu @ 2012-03-26  1:07 UTC (permalink / raw)
  To: Richard Henderson; +Cc: sw, qemu-devel, aurelien

On Sat, Mar 24, 2012 at 12:01 AM, Richard Henderson <rth@twiddle.net> wrote:
>> +DEF_HELPER_1(absqsph, i32, i32)
>
> Many of these helpers merely compute a function.  They do not trap,
> they do not modify global state.  They should be using the
> DEF_HELPER_FLAGS_N macro to define them, so that the TCG compiler
> can optimize around the functions better.
>
>>  target-mips/op_helper.c | 3936 +++++++++++++++++++++++++++++++++++++++++++++++
>>  1 files changed, 3936 insertions(+), 0 deletions(-)
>
> Nearly 4000 lines to me says: put these in their own file.
>
> It would be my preference if this were done in a way that
> exposes any implicit uses of the ENV variable.  But even
> failing that, the makefile can be adjusted to apply HELPER_CFLAGS
> to other helper files.
>

Thanks for comment, put these in their own file is a good idea.
I'll do it.

>
> r~

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2012-03-26  1:07 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-03-22 13:36 [Qemu-devel] [PATCH V2 0/4] MIPS ASE DSP Support for Qemu Jia Liu
2012-03-22 13:36 ` [Qemu-devel] [PATCH V2 1/4] add MIPS DSP helpers define Jia Liu
2012-03-22 13:36 ` [Qemu-devel] [PATCH V2 2/4] add MIPS DSP helpers implement Jia Liu
2012-03-22 13:54   ` Peter Maydell
2012-03-23  1:24     ` Jia Liu
2012-03-22 13:36 ` [Qemu-devel] [PATCH V2 3/4] add MIPS DSP translation Jia Liu
2012-03-22 13:36 ` [Qemu-devel] [PATCH V2 4/4] add MIPS DSP testcase Jia Liu
2012-03-22 14:01 ` [Qemu-devel] [PATCH V2 0/4] MIPS ASE DSP Support for Qemu Peter Maydell
2012-03-23  1:40   ` Jia Liu
2012-03-23  7:21   ` 陳韋任
2012-03-22 14:03 ` Peter Maydell
2012-03-23  1:31   ` Jia Liu
2012-03-23 16:01 ` Richard Henderson
2012-03-26  1:07   ` Jia Liu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.