]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
[PATCH] Add micromips support to the MIPS simulator
authorAndrew Bennett <andrew.bennett@imgtec.com>
Fri, 25 Sep 2015 14:52:18 +0000 (15:52 +0100)
committerAndrew Bennett <andrew.bennett@imgtec.com>
Fri, 25 Sep 2015 14:52:18 +0000 (15:52 +0100)
2015-09-25  Andrew Bennett  <andrew.bennett@imgtec.com>
        Ali Lown  <ali.lown@imgtec.com>

sim/common/
* sim-bits.h (EXTEND6): New macro.
(EXTEND12): New macro.
(EXTEND25): New macro.

sim/mips/
* Makefile.in (tmp-micromips): New rule.
(tmp-mach-multi): Add support for micromips.
* configure.ac (mips*-sde-elf* | mips*-mti-elf*): Made a multi sim
that works for both mips64 and micromips64.
(mipsisa32r2*-*-*): Made a multi sim that works for mips32 and
micromips32.
Add build support for micromips.
* dsp.igen (do_ph_s_absq, do_w_s_absq, do_qb_s_absq, do_addsc,
do_addwc, do_bitrev, do_extpv, do_extrv, do_extrv_s_h, do_insv,
do_lxx do_modsub, do_mthlip, do_mulsaq_s_w_ph, do_ph_packrl, do_qb_pick
do_ph_pick, do_qb_ph_precequ, do_qb_ph_preceu, do_w_preceq
do_w_ph_precrq, do_ph_qb_precrq, do_w_ph_rs_precrq do_qb_w_raddu,
do_rddsp, do_repl, do_shilov, do_ph_shl, do_qb_shl do_w_s_shllv,
do_ph_shrlv, do_w_r_shrav, do_wrdsp, do_qb_shrav, do_append,
do_balign, do_ph_w_mulsa, do_ph_qb_precr, do_prepend): New functions.
Refactored instruction code to use these functions.
* dsp2.igen: Refactored instruction code to use the new functions.
* interp.c (decode_coproc): Refactored to work with any instruction
encoding.
(isa_mode): New variable
(RSVD_INSTRUCTION): Changed to 0x00000039.
* m16.igen (BREAK16): Refactored instruction to use do_break16.
(JALX32): Add mips32, mips64, mips32r2 and mips64r2 models.
* micromips.dc: New file.
* micromips.igen: New file.
* micromips16.dc: New file.
* micromipsdsp.igen: New file.
* micromipsrun.c: New file.
* mips.igen (do_swc1): Changed to work with any instruction encoding.
(do_add do_addi do_andi do_dadd do_daddi do_dsll32 do_dsra32
do_dsrl32, do_dsub, do_break, do_break16, do_clo, do_clz, do_dclo
do_dclz, do_lb, do_lh, do_lwr, do_lwl, do_lwc, do_lw, do_lwu, do_lhu
do_ldc, do_lbu, do_ll, do_lld, do_lui, do_madd, do_dsp_madd, do_maddu
do_dsp_maddu, do_dsp_mfhi, do_dsp_mflo, do_movn, do_movz, do_msub
do_dsp_msub, do_msubu, do_dsp_msubu, do_mthi, do_dsp_mthi, do_mtlo
do_dsp_mtlo, do_mul, do_dsp_mult, do_dsp_multu, do_pref, do_sc, do_scd
do_sub, do_sw, do_teq, do_teqi, do_tge, do_tgei, do_tgeiu, do_tgeu, do_tlt
do_tlti, do_tltiu, do_tltu, do_tne, do_tnei, do_abs_fmt, do_add_fmt
do_alnv_ps, do_c_cond_fmt, do_ceil_fmt, do_cfc1, do_ctc1, do_cvt_d_fmt
do_cvt_l_fmt, do_cvt_ps_s, do_cvt_s_fmt, do_cvt_s_pl, do_cvt_s_pu
do_cvt_w_fmt, do_div_fmt, do_dmfc1b, do_dmtc1b, do_floor_fmt, do_luxc1_32
do_luxc1_64, do_lwc1, do_lwxc1, do_madd_fmt, do_mfc1b, do_mov_fmt, do_movtf
do_movtf_fmt, do_movn_fmt, do_movz_fmt, do_msub_fmt, do_mtc1b, do_mul_fmt
do_neg_fmt, do_nmadd_fmt, do_nmsub_fmt, do_pll_ps, do_plu_ps, do_pul_ps
do_puu_ps, do_recip_fmt, do_round_fmt, do_rsqrt_fmt, do_prefx, do_sdc1
do_suxc1_32, do_suxc1_64, do_sqrt_fmt, do_sub_fmt, do_swc1, do_swxc1
do_trunc_fmt): New functions, refactored from existing instructions.
Refactored instruction code to use these functions.
(RSVD): Changed to use new reserved instruction.
(loadstore_ea, not_word_value, unpredictable, check_mt_hilo, check_mf_hilo,
check_mult_hilo, check_div_hilo, check_u64, do_luxc1_32, do_sdc1, do_suxc1_32,
check_fmt_p, check_fpu, do_load_double, do_store_double):  Added micromips32
and micromips64 models.
Added include for micromips.igen and micromipsdsp.igen
Add micromips32 and micromips64 models.
(DecodeCoproc): Updated to use new macro definition.
* mips3264r2.igen (do_dsbh, do_dshd, do_dext, do_dextm, do_dextu, do_di,
do_dins, do_dinsm, do_ei, do_ext, do_mfhc1, do_mthc1, do_ins, do_dinsu,
do_seb, do_seh do_rdhwr, do_wsbh): New functions.
Refactored instruction code to use these functions.
* sim-main.h (CP0_operation): New enum.
(DecodeCoproc): Updated macro.
(IMEM32_MICROMIPS, IMEM16_MICROMIPS, MICROMIPS_MINOR_OPCODE,
MICROMIPS_DELAYSLOT_SIZE_ANY, MICROMIPS_DELAYSLOT_SIZE_16, MICROMIPS_DELAYSLOT_SIZE_32,
ISA_MODE_MIPS32 and ISA_MODE_MICROMIPS): New defines.
(sim_state): Add isa_mode field.

sim/testsuite/sim/mips/
       * basic.exp (run_micromips_test, run_sim_tests): New functions
Add support for micromips tests.
* hilo-hazard-4.s: New file.
* testutils.inc (_dowrite): Changed reserved instruction encoding.
(writemsg): Moved the la and li instructions before the data they are
assigned to, which prevents a bug where MIPS32 relocations are used instead
of micromips relocations when building for micromips.

22 files changed:
sim/common/ChangeLog
sim/common/sim-bits.h
sim/mips/ChangeLog
sim/mips/Makefile.in
sim/mips/configure
sim/mips/configure.ac
sim/mips/dsp.igen
sim/mips/dsp2.igen
sim/mips/interp.c
sim/mips/m16.igen
sim/mips/micromips.dc [new file with mode: 0644]
sim/mips/micromips.igen [new file with mode: 0644]
sim/mips/micromips16.dc [new file with mode: 0644]
sim/mips/micromipsdsp.igen [new file with mode: 0644]
sim/mips/micromipsrun.c [new file with mode: 0644]
sim/mips/mips.igen
sim/mips/mips3264r2.igen
sim/mips/sim-main.h
sim/testsuite/sim/mips/ChangeLog
sim/testsuite/sim/mips/basic.exp
sim/testsuite/sim/mips/hilo-hazard-4.s [new file with mode: 0644]
sim/testsuite/sim/mips/testutils.inc

index 8e47936d67928f950cd67c311f9eb202487927b4..2aa178c8d83e8739c7b99528301006b816a27e34 100644 (file)
@@ -1,3 +1,10 @@
+2015-09-25  Andrew Bennett  <andrew.bennett@imgtec.com>
+           Ali Lown  <ali.lown@imgtec.com>
+
+       * sim-bits.h (EXTEND6): New macro.
+       (EXTEND12): New macro.
+       (EXTEND25): New macro.
+
 2015-06-24  Mike Frysinger  <vapier@gentoo.org>
 
        * sim-trace.c (trace_one_insn): Delete.
index fb6a8218d67594a13ce24f065733e178a7ca90dd..ecfd2301f482ab8408e596806cad02a57a375dee 100644 (file)
@@ -501,11 +501,14 @@ INLINE_SIM_BITS(unsigned_word) MSINSERTED (unsigned_word val, int start, int sto
 
 #define EXTEND4(X)  (LSSEXT ((X), 3))
 #define EXTEND5(X)  (LSSEXT ((X), 4))
+#define EXTEND6(X)  (LSSEXT ((X), 5))
 #define EXTEND8(X)  ((signed_word)(signed8)(X))
 #define EXTEND11(X)  (LSSEXT ((X), 10))
+#define EXTEND12(X)  (LSSEXT ((X), 11))
 #define EXTEND15(X)  (LSSEXT ((X), 14))
 #define EXTEND16(X) ((signed_word)(signed16)(X))
 #define EXTEND24(X)  (LSSEXT ((X), 23))
+#define EXTEND25(X)  (LSSEXT ((X), 24))
 #define EXTEND32(X) ((signed_word)(signed32)(X))
 #define EXTEND64(X) ((signed_word)(signed64)(X))
 
index 012149d8de9da96327350812333065461bd807ba..2865266135c50f8b961590b7eb66fa6a5b671d3b 100644 (file)
@@ -1,3 +1,75 @@
+2015-09-25  Andrew Bennett  <andrew.bennett@imgtec.com>
+           Ali Lown  <ali.lown@imgtec.com>
+
+       * Makefile.in (tmp-micromips): New rule.
+       (tmp-mach-multi): Add support for micromips.
+       * configure.ac (mips*-sde-elf* | mips*-mti-elf*): Made a multi sim
+       that works for both mips64 and micromips64.
+       (mipsisa32r2*-*-*): Made a multi sim that works for mips32 and
+       micromips32.
+       Add build support for micromips.
+       * dsp.igen (do_ph_s_absq, do_w_s_absq, do_qb_s_absq, do_addsc,
+       do_addwc, do_bitrev, do_extpv, do_extrv, do_extrv_s_h, do_insv,
+       do_lxx do_modsub, do_mthlip, do_mulsaq_s_w_ph, do_ph_packrl, do_qb_pick
+       do_ph_pick, do_qb_ph_precequ, do_qb_ph_preceu, do_w_preceq
+       do_w_ph_precrq, do_ph_qb_precrq, do_w_ph_rs_precrq do_qb_w_raddu,
+       do_rddsp, do_repl, do_shilov, do_ph_shl, do_qb_shl do_w_s_shllv,
+       do_ph_shrlv, do_w_r_shrav, do_wrdsp, do_qb_shrav, do_append,
+       do_balign, do_ph_w_mulsa, do_ph_qb_precr, do_prepend): New functions.
+       Refactored instruction code to use these functions.
+       * dsp2.igen: Refactored instruction code to use the new functions.
+       * interp.c (decode_coproc): Refactored to work with any instruction
+       encoding.
+       (isa_mode): New variable
+       (RSVD_INSTRUCTION): Changed to 0x00000039.
+       * m16.igen (BREAK16): Refactored instruction to use do_break16.
+       (JALX32): Add mips32, mips64, mips32r2 and mips64r2 models.
+       * micromips.dc: New file.
+       * micromips.igen: New file.
+       * micromips16.dc: New file.
+       * micromipsdsp.igen: New file.
+       * micromipsrun.c: New file.
+       * mips.igen (do_swc1): Changed to work with any instruction encoding.
+       (do_add do_addi do_andi do_dadd do_daddi do_dsll32 do_dsra32
+       do_dsrl32, do_dsub, do_break, do_break16, do_clo, do_clz, do_dclo,
+       do_dclz, do_lb, do_lh, do_lwr, do_lwl, do_lwc, do_lw, do_lwu, do_lhu,
+       do_ldc, do_lbu, do_ll, do_lld, do_lui, do_madd, do_dsp_madd, do_maddu,
+       do_dsp_maddu, do_dsp_mfhi, do_dsp_mflo, do_movn, do_movz, do_msub,
+       do_dsp_msub, do_msubu, do_dsp_msubu, do_mthi, do_dsp_mthi, do_mtlo,
+       do_dsp_mtlo, do_mul, do_dsp_mult, do_dsp_multu, do_pref, do_sc,
+       do_scd, do_sub, do_sw, do_teq, do_teqi, do_tge, do_tgei, do_tgeiu,
+       do_tgeu, do_tlt do_tlti, do_tltiu, do_tltu, do_tne, do_tnei, do_abs_fmt,
+       do_add_fmt, do_alnv_ps, do_c_cond_fmt, do_ceil_fmt, do_cfc1, do_ctc1,
+       do_cvt_d_fmt, do_cvt_l_fmt, do_cvt_ps_s, do_cvt_s_fmt, do_cvt_s_pl,
+       do_cvt_s_pu, do_cvt_w_fmt, do_div_fmt, do_dmfc1b, do_dmtc1b, do_floor_fmt,
+       do_luxc1_32, do_luxc1_64, do_lwc1, do_lwxc1, do_madd_fmt, do_mfc1b,
+       do_mov_fmt, do_movtf, do_movtf_fmt, do_movn_fmt, do_movz_fmt, do_msub_fmt,
+       do_mtc1b, do_mul_fmt, do_neg_fmt, do_nmadd_fmt, do_nmsub_fmt, do_pll_ps,
+       do_plu_ps, do_pul_ps, do_puu_ps, do_recip_fmt, do_round_fmt, do_rsqrt_fmt,
+       do_prefx, do_sdc1, do_suxc1_32, do_suxc1_64, do_sqrt_fmt, do_sub_fmt,
+       do_swc1, do_swxc1, do_trunc_fmt): New functions, refactored from existing
+       instructions.
+       Refactored instruction code to use these functions.
+       (RSVD): Changed to use new reserved instruction.
+       (loadstore_ea, not_word_value, unpredictable, check_mt_hilo,
+       check_mf_hilo, check_mult_hilo, check_div_hilo, check_u64, do_luxc1_32,
+       do_sdc1, do_suxc1_32, check_fmt_p, check_fpu, do_load_double,
+       do_store_double):  Added micromips32 and micromips64 models.
+       Added include for micromips.igen and micromipsdsp.igen
+       Add micromips32 and micromips64 models.
+       (DecodeCoproc): Updated to use new macro definition.
+       * mips3264r2.igen (do_dsbh, do_dshd, do_dext, do_dextm, do_dextu, do_di,
+       do_dins, do_dinsm, do_ei, do_ext, do_mfhc1, do_mthc1, do_ins, do_dinsu,
+       do_seb, do_seh do_rdhwr, do_wsbh): New functions.
+       Refactored instruction code to use these functions.
+       * sim-main.h (CP0_operation): New enum.
+       (DecodeCoproc): Updated macro.
+       (IMEM32_MICROMIPS, IMEM16_MICROMIPS, MICROMIPS_MINOR_OPCODE,
+       MICROMIPS_DELAYSLOT_SIZE_ANY, MICROMIPS_DELAYSLOT_SIZE_16,
+       MICROMIPS_DELAYSLOT_SIZE_32, ISA_MODE_MIPS32 and
+       ISA_MODE_MICROMIPS): New defines.
+       (sim_state): Add isa_mode field.
+
 2015-06-23  Mike Frysinger  <vapier@gentoo.org>
 
        * configure: Regenerate.
index 17eeab6ae0e3933208b6561428da37c30f1c8821..f02e1bdbd6ffcd169e9b1eb7f6776840a3c2d8dc 100644 (file)
@@ -35,7 +35,29 @@ SIM_M16_OBJ = \
        itable.o \
        m16run.o \
 
-SIM_MULTI_OBJ = itable.o @sim_multi_obj@
+SIM_MICROMIPS_OBJ = \
+       micromips16_support.o \
+       micromips16_semantics.o \
+       micromips16_idecode.o \
+       micromips16_icache.o \
+       \
+       micromips32_support.o \
+       micromips32_semantics.o \
+       micromips32_idecode.o \
+       micromips32_icache.o \
+       \
+       micromips_m32_support.o \
+       micromips_m32_semantics.o \
+       micromips_m32_idecode.o \
+       micromips_m32_icache.o \
+       \
+       itable.o \
+       micromipsrun.o \
+
+
+SIM_MULTI_OBJ = @sim_multi_obj@ \
+               itable.o \
+               multi-run.o \
 
 MIPS_EXTRA_LIBS = @mips_extra_libs@
 
@@ -68,11 +90,11 @@ SIM_EXTRA_LIBS = $(MIPS_EXTRA_LIBS)
 ## COMMON_POST_CONFIG_FRAG
 
 interp.o: $(srcdir)/interp.c config.h sim-main.h itable.h
-cp1.o: $(srcdir)/cp1.c config.h sim-main.h
 
-mdmx.o: $(srcdir)/mdmx.c $(srcdir)/sim-main.h
+m16run.o: sim-main.h m16_idecode.h m32_idecode.h m16run.c $(SIM_EXTRA_DEPS)
 
-dsp.o: $(srcdir)/dsp.c $(srcdir)/sim-main.h
+micromipsrun.o: sim-main.h micromips16_idecode.h micromips32_idecode.h \
+               micromips_m32_idecode.h micromipsrun.c $(SIM_EXTRA_DEPS)
 
 multi-run.o: multi-include.h tmp-mach-multi
 
@@ -83,7 +105,11 @@ IGEN_TRACE= # -G omit-line-numbers # -G trace-rule-selection -G trace-rule-rejec
 IGEN_INSN=$(srcdir)/mips.igen
 IGEN_DC=$(srcdir)/mips.dc
 M16_DC=$(srcdir)/m16.dc
+MICROMIPS32_DC=$(srcdir)/micromips.dc
+MICROMIPS16_DC=$(srcdir)/micromips16.dc
 IGEN_INCLUDE=\
+       $(srcdir)/micromipsdsp.igen \
+       $(srcdir)/micromips.igen \
        $(srcdir)/m16.igen \
        $(srcdir)/m16e.igen \
        $(srcdir)/mdmx.igen \
@@ -104,6 +130,7 @@ BUILT_SRC_FROM_GEN = \
 
 SIM_IGEN_ALL = tmp-igen
 SIM_M16_ALL = tmp-m16
+SIM_MICROMIPS_ALL = tmp-micromips
 SIM_MULTI_ALL = tmp-multi
 
 $(BUILT_SRC_FROM_GEN): $(SIM_@sim_gen@_ALL)
@@ -174,25 +201,6 @@ tmp-igen: $(IGEN_INSN) $(IGEN_DC) ../igen/igen $(IGEN_INCLUDE)
        $(SHELL) $(srcdir)/../../move-if-change tmp-irun.c irun.c
        touch tmp-igen
 
-semantics.o: sim-main.h semantics.c $(SIM_EXTRA_DEPS)
-engine.o: sim-main.h engine.c $(SIM_EXTRA_DEPS)
-support.o: sim-main.h support.c $(SIM_EXTRA_DEPS)
-idecode.o: sim-main.h idecode.c $(SIM_EXTRA_DEPS)
-itable.o: sim-main.h itable.c $(SIM_EXTRA_DEPS)
-m16run.o: sim-main.h m16_idecode.h m32_idecode.h $(SIM_EXTRA_DEPS)
-
-m16_semantics.o: sim-main.h m16_semantics.c $(SIM_EXTRA_DEPS)
-m16_support.o: sim-main.h m16_support.c $(SIM_EXTRA_DEPS)
-m16_idecode.o: sim-main.h m16_idecode.c $(SIM_EXTRA_DEPS)
-m16_icache.o: sim-main.h m16_icache.c $(SIM_EXTRA_DEPS)
-
-m32_semantics.o: sim-main.h m32_semantics.c $(SIM_EXTRA_DEPS)
-m32_support.o: sim-main.h m32_support.c $(SIM_EXTRA_DEPS)
-m32_idecode.o: sim-main.h m32_idecode.c $(SIM_EXTRA_DEPS)
-m32_icache.o: sim-main.h m32_icache.c $(SIM_EXTRA_DEPS)
-
-$(SIM_MULTI_OBJ): sim-main.h $(SIM_EXTRA_DEPS)
-
 BUILT_SRC_FROM_M16 = \
        m16_icache.h \
        m16_icache.c \
@@ -284,8 +292,10 @@ tmp-m16: $(IGEN_INSN) $(IGEN_DC) ../igen/igen $(IGEN_INCLUDE)
        $(SHELL) $(srcdir)/../../move-if-change tmp-icache.c m32_icache.c
        $(SHELL) $(srcdir)/../../move-if-change tmp-idecode.h m32_idecode.h
        $(SHELL) $(srcdir)/../../move-if-change tmp-idecode.c m32_idecode.c
-       $(SHELL) $(srcdir)/../../move-if-change tmp-semantics.h m32_semantics.h
-       $(SHELL) $(srcdir)/../../move-if-change tmp-semantics.c m32_semantics.c
+       $(SHELL) $(srcdir)/../../move-if-change tmp-semantics.h \
+                                               m32_semantics.h
+       $(SHELL) $(srcdir)/../../move-if-change tmp-semantics.c \
+                                               m32_semantics.c
        $(SHELL) $(srcdir)/../../move-if-change tmp-model.h m32_model.h
        $(SHELL) $(srcdir)/../../move-if-change tmp-model.c m32_model.c
        $(SHELL) $(srcdir)/../../move-if-change tmp-support.h m32_support.h
@@ -307,6 +317,196 @@ tmp-m16: $(IGEN_INSN) $(IGEN_DC) ../igen/igen $(IGEN_INCLUDE)
        $(SHELL) $(srcdir)/../../move-if-change tmp-itable.c itable.c
        touch tmp-m16
 
+BUILT_SRC_FROM_MICROMIPS = \
+       micromips16_icache.h \
+       micromips16_icache.c \
+       micromips16_idecode.h \
+       micromips16_idecode.c \
+       micromips16_semantics.h \
+       micromips16_semantics.c \
+       micromips16_model.h \
+       micromips16_model.c \
+       micromips16_support.h \
+       micromips16_support.c \
+       \
+       micromips32_icache.h \
+       micromips32_icache.c \
+       micromips32_idecode.h \
+       micromips32_idecode.c \
+       micromips32_semantics.h \
+       micromips32_semantics.c \
+       micromips32_model.h \
+       micromips32_model.c \
+       micromips32_support.h \
+       micromips32_support.c \
+       \
+       micromips_m32_icache.h \
+       micromips_m32_icache.c \
+       micromips_m32_idecode.h \
+       micromips_m32_idecode.c \
+       micromips_m32_semantics.h \
+       micromips_m32_semantics.c \
+       micromips_m32_model.h \
+       micromips_m32_model.c \
+       micromips_m32_support.h \
+       micromips_m32_support.c \
+
+$(BUILT_SRC_FROM_MICROMIPS): tmp-micromips
+
+tmp-micromips: $(IGEN_INSN) $(IGEN_DC) ../igen/igen $(IGEN_INCLUDE)
+       cd ../igen && $(MAKE)
+       ../igen/igen \
+               $(IGEN_TRACE) \
+               -I $(srcdir) \
+               -Werror \
+               -Wnodiscard \
+               @sim_micromips16_flags@ \
+               -G gen-direct-access \
+               -G gen-zero-r0 \
+               -B 16 \
+               -H 15 \
+               -i $(IGEN_INSN) \
+               -o $(MICROMIPS16_DC) \
+               -P micromips16_ \
+               -x \
+               -n micromips16_icache.h    -hc tmp-icache.h \
+               -n micromips16_icache.c    -c  tmp-icache.c \
+               -n micromips16_semantics.h -hs tmp-semantics.h \
+               -n micromips16_semantics.c -s  tmp-semantics.c \
+               -n micromips16_idecode.h   -hd tmp-idecode.h \
+               -n micromips16_idecode.c   -d  tmp-idecode.c \
+               -n micromips16_model.h     -hm tmp-model.h \
+               -n micromips16_model.c     -m  tmp-model.c \
+               -n micromips16_support.h   -hf tmp-support.h \
+               -n micromips16_support.c   -f  tmp-support.c \
+               #
+       $(SHELL) $(srcdir)/../../move-if-change tmp-icache.h \
+                                               micromips16_icache.h
+       $(SHELL) $(srcdir)/../../move-if-change tmp-icache.c \
+                                               micromips16_icache.c
+       $(SHELL) $(srcdir)/../../move-if-change tmp-idecode.h \
+                                               micromips16_idecode.h
+       $(SHELL) $(srcdir)/../../move-if-change tmp-idecode.c \
+                                               micromips16_idecode.c
+       $(SHELL) $(srcdir)/../../move-if-change tmp-semantics.h \
+                                               micromips16_semantics.h
+       $(SHELL) $(srcdir)/../../move-if-change tmp-semantics.c \
+                                               micromips16_semantics.c
+       $(SHELL) $(srcdir)/../../move-if-change tmp-model.h \
+                                               micromips16_model.h
+       $(SHELL) $(srcdir)/../../move-if-change tmp-model.c \
+                                               micromips16_model.c
+       $(SHELL) $(srcdir)/../../move-if-change tmp-support.h \
+                                               micromips16_support.h
+       $(SHELL) $(srcdir)/../../move-if-change tmp-support.c \
+                                               micromips16_support.c
+       cd ../igen && $(MAKE)
+       ../igen/igen \
+               $(IGEN_TRACE) \
+               -I $(srcdir) \
+               -Werror \
+               -Wnodiscard \
+               @sim_micromips_flags@ \
+               -G gen-direct-access \
+               -G gen-zero-r0 \
+               -B 32 \
+               -H 31 \
+               -i $(IGEN_INSN) \
+               -o $(MICROMIPS32_DC) \
+               -P micromips32_ \
+               -x \
+               -n micromips32_icache.h    -hc tmp-icache.h \
+               -n micromips32_icache.c    -c  tmp-icache.c \
+               -n micromips32_semantics.h -hs tmp-semantics.h \
+               -n micromips32_semantics.c -s  tmp-semantics.c \
+               -n micromips32_idecode.h   -hd tmp-idecode.h \
+               -n micromips32_idecode.c   -d  tmp-idecode.c \
+               -n micromips32_model.h     -hm tmp-model.h \
+               -n micromips32_model.c     -m  tmp-model.c \
+               -n micromips32_support.h   -hf tmp-support.h \
+               -n micromips32_support.c   -f  tmp-support.c \
+               #
+       $(SHELL) $(srcdir)/../../move-if-change tmp-icache.h \
+                                               micromips32_icache.h
+       $(SHELL) $(srcdir)/../../move-if-change tmp-icache.c \
+                                               micromips32_icache.c
+       $(SHELL) $(srcdir)/../../move-if-change tmp-idecode.h  \
+                                               micromips32_idecode.h
+       $(SHELL) $(srcdir)/../../move-if-change tmp-idecode.c \
+                                               micromips32_idecode.c
+       $(SHELL) $(srcdir)/../../move-if-change tmp-semantics.h \
+                                               micromips32_semantics.h
+       $(SHELL) $(srcdir)/../../move-if-change tmp-semantics.c \
+                                               micromips32_semantics.c
+       $(SHELL) $(srcdir)/../../move-if-change tmp-model.h \
+                                               micromips32_model.h
+       $(SHELL) $(srcdir)/../../move-if-change tmp-model.c  \
+                                               micromips32_model.c
+       $(SHELL) $(srcdir)/../../move-if-change tmp-support.h \
+                                               micromips32_support.h
+       $(SHELL) $(srcdir)/../../move-if-change tmp-support.c \
+                                               micromips32_support.c
+       ../igen/igen \
+               $(IGEN_TRACE) \
+               -I $(srcdir) \
+               -Werror \
+               -Wnodiscard \
+               @sim_igen_flags@ \
+               -G gen-direct-access \
+               -G gen-zero-r0 \
+               -B 32 \
+               -H 31 \
+               -i $(IGEN_INSN) \
+               -o $(IGEN_DC) \
+               -P micromips_m32_ \
+               -x \
+               -n micromips_m32_icache.h    -hc tmp-icache.h \
+               -n micromips_m32_icache.c    -c  tmp-icache.c \
+               -n micromips_m32_semantics.h -hs tmp-semantics.h \
+               -n micromips_m32_semantics.c -s  tmp-semantics.c \
+               -n micromips_m32_idecode.h   -hd tmp-idecode.h \
+               -n micromips_m32_idecode.c   -d  tmp-idecode.c \
+               -n micromips_m32_model.h     -hm tmp-model.h \
+               -n micromips_m32_model.c     -m  tmp-model.c \
+               -n micromips_m32_support.h   -hf tmp-support.h \
+               -n micromips_m32_support.c   -f  tmp-support.c \
+               #
+       $(SHELL) $(srcdir)/../../move-if-change tmp-icache.h \
+                                               micromips_m32_icache.h
+       $(SHELL) $(srcdir)/../../move-if-change tmp-icache.c \
+                                               micromips_m32_icache.c
+       $(SHELL) $(srcdir)/../../move-if-change tmp-idecode.h \
+                                               micromips_m32_idecode.h
+       $(SHELL) $(srcdir)/../../move-if-change tmp-idecode.c \
+                                               micromips_m32_idecode.c
+       $(SHELL) $(srcdir)/../../move-if-change tmp-semantics.h \
+                                               micromips_m32_semantics.h
+       $(SHELL) $(srcdir)/../../move-if-change tmp-semantics.c \
+                                               micromips_m32_semantics.c
+       $(SHELL) $(srcdir)/../../move-if-change tmp-model.h \
+                                               micromips_m32_model.h
+       $(SHELL) $(srcdir)/../../move-if-change tmp-model.c \
+                                               micromips_m32_model.c
+       $(SHELL) $(srcdir)/../../move-if-change tmp-support.h \
+                                               micromips_m32_support.h
+       $(SHELL) $(srcdir)/../../move-if-change tmp-support.c \
+                                               micromips_m32_support.c
+       ../igen/igen \
+               $(IGEN_TRACE) \
+               -I $(srcdir) \
+               -Werror \
+               -Wnodiscard \
+               -Wnowidth \
+               @sim_igen_flags@ @sim_micromips_flags@ @sim_micromips16_flags@\
+               -G gen-direct-access \
+               -G gen-zero-r0 \
+               -i $(IGEN_INSN) \
+               -n itable.h    -ht tmp-itable.h \
+               -n itable.c    -t  tmp-itable.c \
+               #
+       $(SHELL) $(srcdir)/../../move-if-change tmp-itable.h itable.h
+       $(SHELL) $(srcdir)/../../move-if-change tmp-itable.c itable.c
+       touch tmp-micromips
 
 BUILT_SRC_FROM_MULTI = @sim_multi_src@
 SIM_MULTI_IGEN_CONFIGS = @sim_multi_igen_configs@
@@ -319,6 +519,15 @@ tmp-mach-multi: $(IGEN_INSN) $(IGEN_DC) ../igen/igen $(IGEN_INCLUDE)
          m=`echo $${t} | sed -e 's/.*:\(.*\):.*/\1/'` ; \
          f=`echo $${t} | sed -e 's/.*://'` ; \
          case $${p} in \
+           micromips16*) e="-B 16 -H 15 -o $(MICROMIPS16_DC) -F 16" ;; \
+           micromips32* | micromips64*) \
+               e="-B 32 -H 31 -o $(MICROMIPS32_DC) -F $${f}" ;; \
+           micromips_m32*) \
+               e="-B 32 -H 31 -o $(IGEN_DC) -F $${f}"; \
+               m="mips32r2,mips3d,mdmx,dsp,dsp2,smartmips" ;; \
+           micromips_m64*) \
+               e="-B 32 -H 31 -o $(IGEN_DC) -F $${f}"; \
+               m="mips64r2,mips3d,mdmx,dsp,dsp2,smartmips" ;; \
            m16*) e="-B 16 -H 15 -o $(M16_DC) -F 16" ;; \
            *) e="-B 32 -H 31 -o $(IGEN_DC) -F $${f}" ;; \
          esac; \
@@ -348,18 +557,30 @@ tmp-mach-multi: $(IGEN_INSN) $(IGEN_DC) ../igen/igen $(IGEN_INCLUDE)
                -n $${p}_engine.h    -he tmp-engine.h \
                -n $${p}_engine.c    -e  tmp-engine.c \
          || exit; \
-         $(SHELL) $(srcdir)/../../move-if-change tmp-icache.h $${p}_icache.h ; \
-         $(SHELL) $(srcdir)/../../move-if-change tmp-icache.c $${p}_icache.c ; \
-         $(SHELL) $(srcdir)/../../move-if-change tmp-idecode.h $${p}_idecode.h ; \
-         $(SHELL) $(srcdir)/../../move-if-change tmp-idecode.c $${p}_idecode.c ; \
-         $(SHELL) $(srcdir)/../../move-if-change tmp-semantics.h $${p}_semantics.h ; \
-         $(SHELL) $(srcdir)/../../move-if-change tmp-semantics.c $${p}_semantics.c ; \
-         $(SHELL) $(srcdir)/../../move-if-change tmp-model.h $${p}_model.h ; \
-         $(SHELL) $(srcdir)/../../move-if-change tmp-model.c $${p}_model.c ; \
-         $(SHELL) $(srcdir)/../../move-if-change tmp-support.h $${p}_support.h ; \
-         $(SHELL) $(srcdir)/../../move-if-change tmp-support.c $${p}_support.c ; \
-         $(SHELL) $(srcdir)/../../move-if-change tmp-engine.h $${p}_engine.h ; \
-         $(SHELL) $(srcdir)/../../move-if-change tmp-engine.c $${p}_engine.c ; \
+         $(SHELL) $(srcdir)/../../move-if-change tmp-icache.h \
+                                                 $${p}_icache.h ; \
+         $(SHELL) $(srcdir)/../../move-if-change tmp-icache.c \
+                                                 $${p}_icache.c ; \
+         $(SHELL) $(srcdir)/../../move-if-change tmp-idecode.h \
+                                                 $${p}_idecode.h ; \
+         $(SHELL) $(srcdir)/../../move-if-change tmp-idecode.c \
+                                                 $${p}_idecode.c ; \
+         $(SHELL) $(srcdir)/../../move-if-change tmp-semantics.h \
+                                                 $${p}_semantics.h ; \
+         $(SHELL) $(srcdir)/../../move-if-change tmp-semantics.c \
+                                                 $${p}_semantics.c ; \
+         $(SHELL) $(srcdir)/../../move-if-change tmp-model.h \
+                                                 $${p}_model.h ; \
+         $(SHELL) $(srcdir)/../../move-if-change tmp-model.c \
+                                                 $${p}_model.c ; \
+         $(SHELL) $(srcdir)/../../move-if-change tmp-support.h \
+                                                 $${p}_support.h ; \
+         $(SHELL) $(srcdir)/../../move-if-change tmp-support.c \
+                                                 $${p}_support.c ; \
+         $(SHELL) $(srcdir)/../../move-if-change tmp-engine.h \
+                                                 $${p}_engine.h ; \
+         $(SHELL) $(srcdir)/../../move-if-change tmp-engine.c \
+                                                 $${p}_engine.c ; \
        done
        touch tmp-mach-multi
 tmp-itable-multi: $(IGEN_INSN) $(IGEN_DC) ../igen/igen $(IGEN_INCLUDE)
@@ -380,7 +601,7 @@ tmp-itable-multi: $(IGEN_INSN) $(IGEN_DC) ../igen/igen $(IGEN_INCLUDE)
        $(SHELL) $(srcdir)/../../move-if-change tmp-itable.h itable.h
        $(SHELL) $(srcdir)/../../move-if-change tmp-itable.c itable.c
        touch tmp-itable-multi
-tmp-run-multi: $(srcdir)/m16run.c
+tmp-run-multi: $(srcdir)/m16run.c $(srcdir)/micromipsrun.c
        for t in $(SIM_MULTI_IGEN_CONFIGS); do \
          case $${t} in \
            m16*) \
@@ -389,7 +610,29 @@ tmp-run-multi: $(srcdir)/m16run.c
                    -e "s/^sim_/m16$${m}_/" \
                    -e "s/m16_/m16$${m}_/" \
                    -e "s/m32_/m32$${m}_/" ; \
-             $(SHELL) $(srcdir)/../../move-if-change tmp-run m16$${m}_run.c ; \
+             $(SHELL) $(srcdir)/../../move-if-change tmp-run \
+                                                     m16$${m}_run.c ; \
+            ;;\
+           micromips32*) \
+             m=`echo $${t} | sed -e 's/^micromips32//' -e 's/:.*//'`; \
+             sed <  $(srcdir)/micromipsrun.c > tmp-run \
+                   -e "s/^sim_/micromips32$${m}_/" \
+                   -e "s/micromips16_/micromips16$${m}_/" \
+                   -e "s/micromips32_/micromips32$${m}_/" \
+                   -e "s/m32_/m32$${m}_/" ; \
+             $(SHELL) $(srcdir)/../../move-if-change tmp-run \
+                                                     micromips$${m}_run.c ; \
+             ;;\
+           micromips64*) \
+             m=`echo $${t} | sed -e 's/^micromips64//' -e 's/:.*//'`; \
+             sed <  $(srcdir)/micromipsrun.c > tmp-run \
+                   -e "s/^sim_/micromips64$${m}_/" \
+                   -e "s/micromips16_/micromips16$${m}_/" \
+                   -e "s/micromips32_/micromips64$${m}_/" \
+                   -e "s/m32_/m64$${m}_/" ; \
+             $(SHELL) $(srcdir)/../../move-if-change tmp-run \
+                                                     micromips$${m}_run.c ; \
+             ;;\
          esac \
        done
        touch tmp-run-multi
@@ -398,9 +641,10 @@ clean-extra:
        rm -f $(BUILT_SRC_FROM_GEN)
        rm -f $(BUILT_SRC_FROM_IGEN)
        rm -f $(BUILT_SRC_FROM_M16)
+       rm -f $(BUILT_SRC_FROM_MICROMIPS)
        rm -f $(BUILT_SRC_FROM_MULTI)
        rm -f tmp-*
-       rm -f m16*.o m32*.o itable*.o
+       rm -f micromips16*.o micromips32*.o m16*.o m32*.o itable*.o
 
 distclean-extra:
        rm -f multi-include.h multi-run.c
index f073b2b86fb52307e2dbd6b001f3835c8272e345..67f7e090a5b2b4878c0871fb7586d4c4dbf953f3 100755 (executable)
@@ -609,6 +609,8 @@ sim_multi_src
 sim_multi_igen_configs
 sim_multi_flags
 sim_gen
+sim_micromips16_flags
+sim_micromips_flags
 sim_m16_flags
 sim_igen_flags
 SIM_SUBTARGET
@@ -12347,7 +12349,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 12350 "configure"
+#line 12352 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12453,7 +12455,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 12456 "configure"
+#line 12458 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -13674,11 +13676,11 @@ case "${target}" in
                        sim_multi_default=mips5000
                        ;;
   mips*-sde-elf* | mips*-mti-elf*)
-                       sim_gen=M16
-                       sim_igen_machine="-M mips64r2,mips3d,mips16,mips16e,mdmx,dsp,dsp2,smartmips"
-                       sim_m16_machine="-M mips16,mips16e,mips64r2"
-                       sim_igen_filter="32,64,f"
-                       sim_mach_default="mipsisa64r2"
+                       sim_gen=MULTI
+                       sim_multi_configs="\
+                         micromips:micromips64,micromipsdsp:32,64,f:mips_micromips\
+                         mips64r2:mips64r2,mips3d,mips16,mips16e,mdmx,dsp,dsp2,smartmips:32,64,f:mipsisa64r2"
+                       sim_multi_default=mipsisa64r2
                        ;;
   mips64*-*-*)         sim_igen_filter="32,64,f"
                        sim_gen=IGEN
@@ -13687,11 +13689,11 @@ case "${target}" in
                        sim_igen_filter="32,64,f"
                        sim_m16_filter="16"
                        ;;
-  mipsisa32r2*-*-*)    sim_gen=M16
-                       sim_igen_machine="-M mips32r2,mips16,mips16e,mdmx,dsp,dsp2,smartmips"
-                       sim_m16_machine="-M mips16,mips16e,mips32r2"
-                       sim_igen_filter="32,f"
-                       sim_mach_default="mipsisa32r2"
+  mipsisa32r2*-*-*)    sim_gen=MULTI
+                       sim_multi_configs="\
+                         micromips:micromips32,micromipsdsp:32,f:mips_micromips\
+                         mips32r2:mips32r2,mips3d,mips16,mips16e,mdmx,dsp,dsp2,smartmips:32,f:mipsisa32r2"
+                       sim_multi_default=mipsisa32r2
                        ;;
   mipsisa32*-*-*)      sim_gen=M16
                        sim_igen_machine="-M mips32,mips16,mips16e,smartmips"
@@ -13763,7 +13765,7 @@ if test ${sim_gen} = MULTI; then
   rm -f multi-include.h multi-run.c
   sim_multi_flags=
   sim_multi_src=
-  sim_multi_obj=multi-run.o
+  sim_multi_obj=
   sim_multi_igen_configs=
   sim_seen_default=no
 
@@ -13790,6 +13792,8 @@ if test ${sim_gen} = MULTI; then
 
 #include "sim-main.h"
 #include "multi-include.h"
+#include "elf-bfd.h"
+#include "elf/mips.h"
 
 #define SD sd
 #define CPU cpu
@@ -13804,6 +13808,9 @@ sim_engine_run (SIM_DESC sd,
 
   if (STATE_ARCHITECTURE (sd) == NULL)
     mach = bfd_mach_${sim_multi_default};
+  else if (elf_elfheader (sd->base.prog_bfd)->e_flags
+          & EF_MIPS_ARCH_ASE_MICROMIPS)
+    mach = bfd_mach_mips_micromips;
   else
     mach = STATE_ARCHITECTURE (SD)->mach;
 
@@ -13833,7 +13840,7 @@ __EOF__
     # the ${sim_multi_configs} entry.
     sim_multi_flags="${sim_multi_flags} -F ${filter} -M ${machine}"
 
-    # Check whether mips16 handling is needed.
+    # Check whether special handling is needed.
     case ${c} in
       *:*mips16*:*)
        # Run igen twice, once for normal mode and once for mips16.
@@ -13846,6 +13853,30 @@ __EOF__
        sim_multi_obj="${sim_multi_obj} m16${name}_run.o"
        sim_multi_flags="${sim_multi_flags} -F 16"
        ;;
+      *:*micromips32*:*)
+       # Run igen thrice, once for micromips32, once for micromips16,
+       # and once for m32.
+       ws="micromips_m32 micromips16 micromips32"
+
+       # The top-level function for the micromips simulator is
+       # in a file micromips${name}_run.c, generated by the
+       # tmp-run-multi Makefile rule.
+       sim_multi_src="${sim_multi_src} micromips${name}_run.c"
+       sim_multi_obj="${sim_multi_obj} micromips${name}_run.o"
+       sim_multi_flags="${sim_multi_flags} -F 16,32"
+       ;;
+      *:*micromips64*:*)
+       # Run igen thrice, once for micromips64, once for micromips16,
+       # and once for m64.
+       ws="micromips_m64 micromips16 micromips64"
+
+       # The top-level function for the micromips simulator is
+       # in a file micromips${name}_run.c, generated by the
+       # tmp-run-multi Makefile rule.
+       sim_multi_src="${sim_multi_src} micromips${name}_run.c"
+       sim_multi_obj="${sim_multi_obj} micromips${name}_run.o"
+       sim_multi_flags="${sim_multi_flags} -F 16,32,64"
+       ;;
       *)
        ws=m32
        ;;
@@ -13931,6 +13962,8 @@ else
 fi
 sim_igen_flags="-F ${sim_igen_filter} ${sim_igen_machine} ${sim_igen_smp}"
 sim_m16_flags=" -F ${sim_m16_filter}  ${sim_m16_machine}  ${sim_igen_smp}"
+sim_micromips16_flags=" -F ${sim_micromips16_filter}  ${sim_micromips16_machine}  ${sim_igen_smp}"
+sim_micromips_flags=" -F ${sim_micromips_filter}  ${sim_micromips_machine}  ${sim_igen_smp}"
 
 
 
index d7863510c72345bcdab377fc7518f4f6af814517..a64232696b467e05eb76cd7577a08510aced716d 100644 (file)
@@ -139,11 +139,11 @@ case "${target}" in
                        sim_multi_default=mips5000
                        ;;
   mips*-sde-elf* | mips*-mti-elf*)
-                       sim_gen=M16
-                       sim_igen_machine="-M mips64r2,mips3d,mips16,mips16e,mdmx,dsp,dsp2,smartmips"
-                       sim_m16_machine="-M mips16,mips16e,mips64r2"
-                       sim_igen_filter="32,64,f"
-                       sim_mach_default="mipsisa64r2"
+                       sim_gen=MULTI
+                       sim_multi_configs="\
+                         micromips:micromips64,micromipsdsp:32,64,f:mips_micromips\
+                         mips64r2:mips64r2,mips3d,mips16,mips16e,mdmx,dsp,dsp2,smartmips:32,64,f:mipsisa64r2"
+                       sim_multi_default=mipsisa64r2
                        ;;
   mips64*-*-*)         sim_igen_filter="32,64,f"
                        sim_gen=IGEN
@@ -152,11 +152,11 @@ case "${target}" in
                        sim_igen_filter="32,64,f"
                        sim_m16_filter="16"
                        ;;
-  mipsisa32r2*-*-*)    sim_gen=M16
-                       sim_igen_machine="-M mips32r2,mips16,mips16e,mdmx,dsp,dsp2,smartmips"
-                       sim_m16_machine="-M mips16,mips16e,mips32r2"
-                       sim_igen_filter="32,f"
-                       sim_mach_default="mipsisa32r2"
+  mipsisa32r2*-*-*)    sim_gen=MULTI
+                       sim_multi_configs="\
+                         micromips:micromips32,micromipsdsp:32,f:mips_micromips\
+                         mips32r2:mips32r2,mips3d,mips16,mips16e,mdmx,dsp,dsp2,smartmips:32,f:mipsisa32r2"
+                       sim_multi_default=mipsisa32r2
                        ;;
   mipsisa32*-*-*)      sim_gen=M16
                        sim_igen_machine="-M mips32,mips16,mips16e,smartmips"
@@ -228,7 +228,7 @@ if test ${sim_gen} = MULTI; then
   rm -f multi-include.h multi-run.c
   sim_multi_flags=
   sim_multi_src=
-  sim_multi_obj=multi-run.o
+  sim_multi_obj=
   sim_multi_igen_configs=
   sim_seen_default=no
 
@@ -255,6 +255,8 @@ if test ${sim_gen} = MULTI; then
 
 #include "sim-main.h"
 #include "multi-include.h"
+#include "elf-bfd.h"
+#include "elf/mips.h"
 
 #define SD sd
 #define CPU cpu
@@ -269,6 +271,9 @@ sim_engine_run (SIM_DESC sd,
 
   if (STATE_ARCHITECTURE (sd) == NULL)
     mach = bfd_mach_${sim_multi_default};
+  else if (elf_elfheader (sd->base.prog_bfd)->e_flags
+          & EF_MIPS_ARCH_ASE_MICROMIPS)
+    mach = bfd_mach_mips_micromips;
   else
     mach = STATE_ARCHITECTURE (SD)->mach;
 
@@ -298,7 +303,7 @@ __EOF__
     # the ${sim_multi_configs} entry.
     sim_multi_flags="${sim_multi_flags} -F ${filter} -M ${machine}"
 
-    # Check whether mips16 handling is needed.
+    # Check whether special handling is needed.
     case ${c} in
       *:*mips16*:*)
        # Run igen twice, once for normal mode and once for mips16.
@@ -311,6 +316,30 @@ __EOF__
        sim_multi_obj="${sim_multi_obj} m16${name}_run.o"
        sim_multi_flags="${sim_multi_flags} -F 16"
        ;;
+      *:*micromips32*:*)
+       # Run igen thrice, once for micromips32, once for micromips16,
+       # and once for m32.
+       ws="micromips_m32 micromips16 micromips32"
+
+       # The top-level function for the micromips simulator is
+       # in a file micromips${name}_run.c, generated by the
+       # tmp-run-multi Makefile rule.
+       sim_multi_src="${sim_multi_src} micromips${name}_run.c"
+       sim_multi_obj="${sim_multi_obj} micromips${name}_run.o"
+       sim_multi_flags="${sim_multi_flags} -F 16,32"
+       ;;
+      *:*micromips64*:*)
+       # Run igen thrice, once for micromips64, once for micromips16,
+       # and once for m64.
+       ws="micromips_m64 micromips16 micromips64"
+
+       # The top-level function for the micromips simulator is
+       # in a file micromips${name}_run.c, generated by the
+       # tmp-run-multi Makefile rule.
+       sim_multi_src="${sim_multi_src} micromips${name}_run.c"
+       sim_multi_obj="${sim_multi_obj} micromips${name}_run.o"
+       sim_multi_flags="${sim_multi_flags} -F 16,32,64"
+       ;;
       *)
        ws=m32
        ;;
@@ -396,15 +425,17 @@ else
 fi
 sim_igen_flags="-F ${sim_igen_filter} ${sim_igen_machine} ${sim_igen_smp}"
 sim_m16_flags=" -F ${sim_m16_filter}  ${sim_m16_machine}  ${sim_igen_smp}"
+sim_micromips16_flags=" -F ${sim_micromips16_filter}  ${sim_micromips16_machine}  ${sim_igen_smp}"
+sim_micromips_flags=" -F ${sim_micromips_filter}  ${sim_micromips_machine}  ${sim_igen_smp}"
 AC_SUBST(sim_igen_flags)
 AC_SUBST(sim_m16_flags)
+AC_SUBST(sim_micromips_flags)
+AC_SUBST(sim_micromips16_flags)
 AC_SUBST(sim_gen)
 AC_SUBST(sim_multi_flags)
 AC_SUBST(sim_multi_igen_configs)
 AC_SUBST(sim_multi_src)
 AC_SUBST(sim_multi_obj)
-
-
 #
 # Add simulated hardware devices
 #
index 96a25dc37c8dac007ec5e087314dc0f7124d68d7..b8d5a6c64f80f208bca82800d1a26d824dcc9aa7 100644 (file)
@@ -4,7 +4,7 @@
 // Copyright (C) 2005-2015 Free Software Foundation, Inc.
 // Contributed by MIPS Technologies, Inc.  Written by Chao-ying Fu.
 //
-// This file is part of GDB, the GNU debugger.
+// This file is part of the MIPS sim
 //
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
   GPR[rd] = EXTEND32 (result);
 }
 
+:function:::void:do_ph_s_absq:int rd, int rt
+{
+  int i;
+  signed16 h0;
+  unsigned32 v1 = GPR[rt];
+  unsigned32 result = 0;
+  for (i = 0; i < 32; i += 16, v1 >>= 16)
+    {
+      h0 = (signed16)(v1 & 0xffff);
+      if (h0 == (signed16)0x8000)
+       {
+         DSPCR |= DSPCR_OUFLAG4;
+         h0 = 0x7fff;
+       }
+      else if (h0 & 0x8000)
+       h0 = -h0;
+      result |= ((unsigned32)((unsigned16)h0) << i);
+    }
+  GPR[rd] = EXTEND32 (result);
+}
+
+:function:::void:do_w_s_absq:int rd, int rt
+{
+  unsigned32 v1 = GPR[rt];
+  signed32 h0 = (signed32)v1;
+  if (h0 == (signed32)0x80000000)
+    {
+      DSPCR |= DSPCR_OUFLAG4;
+      h0 = 0x7fffffff;
+    }
+  else if (h0 & 0x80000000)
+    h0 = -h0;
+  GPR[rd] = EXTEND32 (h0);
+}
+
+:function:::void:do_qb_s_absq:int rd, int rt
+{
+  int i;
+  signed8 q0;
+  unsigned32 v1 = GPR[rt];
+  unsigned32 result = 0;
+  for (i = 0; i < 32; i += 8, v1 >>= 8)
+    {
+      q0 = (signed8)(v1 & 0xff);
+      if (q0 == (signed8)0x80)
+       {
+         DSPCR |= DSPCR_OUFLAG4;
+         q0 = 0x7f;
+       }
+      else if (q0 & 0x80)
+       q0 = -q0;
+      result |= ((unsigned32)((unsigned8)q0) << i);
+    }
+  GPR[rd] = EXTEND32 (result);
+}
+
+:function:::void:do_addsc:int rd, int rs, int rt
+{
+  unsigned32 v1 = GPR[rs];
+  unsigned32 v2 = GPR[rt];
+  unsigned64 h0;
+  h0 = (unsigned64)v1 + (unsigned64)v2;
+  if (h0 & 0x100000000LL)
+    DSPCR |= DSPCR_CARRY;
+  GPR[rd] = EXTEND32 (h0);
+}
+
+:function:::void:do_addwc:int rd, int rs, int rt
+{
+  unsigned32 v1 = GPR[rs];
+  unsigned32 v2 = GPR[rt];
+  unsigned64 h0;
+  signed32 h1 = (signed32) v1;
+  signed32 h2 = (signed32) v2;
+  h0 = (signed64)h1 + (signed64)h2
+    + (signed64)((DSPCR >> DSPCR_CARRY_SHIFT) & DSPCR_CARRY_MASK);
+  if (((h0 & 0x100000000LL) >> 1) != (h0 & 0x80000000))
+    DSPCR |= DSPCR_OUFLAG4;
+  GPR[rd] = EXTEND32 (h0);
+}
+
+:function:::void:do_bitrev:int rd, int rt
+{
+  int i;
+  unsigned32 v1 = GPR[rt];
+  unsigned32 h1 = 0;
+  for (i = 0; i < 16; i++)
+    {
+      if (v1 & (1 << i))
+       h1 |= (1 << (15 - i));
+    }
+  GPR[rd] = EXTEND32 (h1);
+}
+
+// op: 0 = EXTPV, 1 = EXTPDPV
+:function:::void:do_extpv:int rt, int ac, int rs, int op
+{
+  unsigned32 size = GPR[rs] & 0x1f;
+  do_extp (SD_, rt, ac, size, op);
+}
+
+// op: 0 = EXTRV, 1 = EXTRV_R, 2 = EXTRV_RS
+:function:::void:do_extrv:int rt, int ac, int rs, int op
+{
+  unsigned32 shift = GPR[rs] & 0x1f;
+  do_w_extr (SD_, rt, ac, shift, op);
+}
+
+:function:::void:do_extrv_s_h:int rt, int ac, int rs
+{
+  unsigned32 shift = GPR[rs] & 0x1f;
+  do_h_extr (SD_, rt, ac, shift);
+}
+
+:function:::void:do_insv:int rt, int rs
+{
+  unsigned32 v1 = GPR[rs];
+  unsigned32 v2 = GPR[rt];
+  unsigned32 pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
+  unsigned32 size = (DSPCR >> DSPCR_SCOUNT_SHIFT) & DSPCR_SCOUNT_MASK;
+  unsigned32 mask1, mask2, mask3, result;
+  if (size < 32)
+    mask1 = (1 << size) - 1;
+  else
+    mask1 = 0xffffffff;
+  mask2 = (1 << pos) - 1;
+  if (pos + size < 32)
+    mask3 = ~((1 << (pos + size)) - 1);
+  else
+    mask3 = 0;
+  result = (v2 & mask3) | ((v1 & mask1) << pos) | (v2 & mask2);
+  GPR[rt] = EXTEND32 (result);
+}
+
+// op: 0 = NORMAL,  1 = EXTEND16, 2 = EXTEND32
+:function:::void:do_lxx:int rd, int base, int index, int op
+{
+  if (op == 0)
+    GPR[rd] = do_load (SD_, AccessLength_BYTE, GPR[base], GPR[index]);
+  else if (op == 1)
+    GPR[rd] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[base], GPR[index]));
+  else if (op == 2)
+    GPR[rd] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[base], GPR[index]));
+}
+
+:function:::void:do_modsub:int rd, int rs, int rt
+{
+  unsigned32 result = 0;
+  unsigned32 v1 = GPR[rs];
+  unsigned32 v2 = GPR[rt];
+  unsigned32 decr = v2 & 0xff;
+  unsigned32 lastindex = (v2 & 0xffff00) >> 8;
+  if (v1 == 0)
+    result = lastindex;
+  else
+    result =  v1 - decr;
+  GPR[rd] = EXTEND32 (result);
+}
+
+:function:::void:do_mthlip:int rs, int ac
+{
+  unsigned32 pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
+  DSPHI(ac) = DSPLO(ac);
+  DSPLO(ac) = GPR[rs];
+  if (pos >= 32)
+    Unpredictable ();
+  else
+    pos += 32;
+  DSPCR &= (~DSPCR_POS_SMASK);
+  DSPCR |= (pos & DSPCR_POS_MASK) << DSPCR_POS_SHIFT;
+}
+
+:function:::void:do_mulsaq_s_w_ph:int ac, int rs, int rt
+{
+  int i;
+  unsigned32 v1 = GPR[rs];
+  unsigned32 v2 = GPR[rt];
+  signed16 h1, h2;
+  signed32 result;
+  unsigned32 lo = DSPLO(ac);
+  unsigned32 hi = DSPHI(ac);
+  signed64 prod = (signed64)((((unsigned64)hi) << 32) + (unsigned64)lo);
+  for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
+    {
+      h1 = (signed16)(v1 & 0xffff);
+      h2 = (signed16)(v2 & 0xffff);
+      if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000)
+       {
+         DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
+         result = (signed32) 0x7fffffff;
+       }
+      else
+       result = ((signed32)h1 * (signed32)h2) << 1;
+
+      if (i == 0)
+       prod -= (signed64) result;
+      else
+       prod += (signed64) result;
+    }
+  DSPLO(ac) = EXTEND32 (prod);
+  DSPHI(ac) = EXTEND32 (prod >> 32);
+}
+
+:function:::void:do_ph_packrl:int rd, int rs, int rt
+{
+
+  unsigned32 v1 = GPR[rs];
+  unsigned32 v2 = GPR[rt];
+  GPR[rd] = EXTEND32 ((v1 << 16) + (v2 >> 16));
+}
+
+:function:::void:do_qb_pick:int rd, int rs, int rt
+{
+  int i, j;
+  unsigned32 v1 = GPR[rs];
+  unsigned32 v2 = GPR[rt];
+  unsigned8 h1, h2;
+  unsigned32 result = 0;
+  for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8)
+    {
+      h1 = (unsigned8)(v1 & 0xff);
+      h2 = (unsigned8)(v2 & 0xff);
+      if (DSPCR & (1 << (DSPCR_CCOND_SHIFT + j)))
+       result |= (unsigned32)(h1 << i);
+      else
+       result |= (unsigned32)(h2 << i);
+    }
+  GPR[rd] = EXTEND32 (result);
+}
+
+:function:::void:do_ph_pick:int rd, int rs, int rt
+{
+  int i, j;
+  unsigned32 v1 = GPR[rs];
+  unsigned32 v2 = GPR[rt];
+  unsigned16 h1, h2;
+  unsigned32 result = 0;
+  for (i = 0, j = 0; i < 32; i += 16, j++, v1 >>= 16, v2 >>= 16)
+    {
+      h1 = (unsigned16)(v1 & 0xffff);
+      h2 = (unsigned16)(v2 & 0xffff);
+      if (DSPCR & (1 << (DSPCR_CCOND_SHIFT + j)))
+       result |= (unsigned32)(h1 << i);
+      else
+       result |= (unsigned32)(h2 << i);
+    }
+  GPR[rd] = EXTEND32 (result);
+}
+
+// op: 0 = QBR, 1 = QBRA, 2 = QBL, 3 = QBLA
+:function:::void:do_qb_ph_precequ:int rd, int rt, int op
+{
+  unsigned32 v1 = GPR[rt];
+  if (op == 0)
+    GPR[rd] = EXTEND32 ((v1 & 0xff00) << 15) | ((v1 & 0xff) << 7);
+  else if (op == 1)
+    GPR[rd] = EXTEND32 ((v1 & 0xff0000) << 7) | ((v1 & 0xff) << 7);
+  else if (op == 2)
+    GPR[rd] = EXTEND32 ((v1 & 0xff000000) >> 1) | ((v1 & 0xff0000) >> 9);
+  else if (op == 3)
+    GPR[rd] = EXTEND32 ((v1 & 0xff000000) >> 1) | ((v1 & 0xff00) >> 1);
+}
+
+// op: 0 = QBR, 1 = QBRA, 2 = QBL, 3 = QBLA
+:function:::void:do_qb_ph_preceu:int rd, int rt, int op
+{
+  unsigned32 v1 = GPR[rt];
+  if (op == 0)
+    GPR[rd] = EXTEND32 ((v1 & 0xff00) << 8) | (v1 & 0xff);
+  else if (op == 1)
+    GPR[rd] = EXTEND32 ((v1 & 0xff0000) | (v1 & 0xff));
+  else if (op == 2)
+    GPR[rd] = EXTEND32 ((v1 & 0xff000000) >> 8) | ((v1 & 0xff0000) >> 16);
+  else if (op == 3)
+    GPR[rd] = EXTEND32 ((v1 & 0xff000000) >> 8) | ((v1 & 0xff00) >> 8);
+}
+
+// op: 0 = .PHL, 1 = PHR
+:function:::void:do_w_preceq:int rd, int rt, int op
+{
+  unsigned32 v1 = GPR[rt];
+  if (op == 0)
+    GPR[rd] = EXTEND32 (v1 & 0xffff0000);
+  else if (op == 1)
+    GPR[rd] = EXTEND32 ((v1 & 0xffff) << 16);
+}
+
+:function:::void:do_w_ph_precrq:int rd, int rs, int rt
+{
+  unsigned32 v1 = GPR[rs];
+  unsigned32 v2 = GPR[rt];
+  unsigned32 tempu = (v1 & 0xffff0000) >> 16;
+  unsigned32 tempv = (v2 & 0xffff0000) >> 16;
+  GPR[rd] = EXTEND32 ((tempu << 16) | tempv);
+}
+
+// sat: 0 = PRECRQ.QB.PH, 1 = PRECRQU_S.QB.PH
+:function:::void:do_ph_qb_precrq:int rd, int rs, int rt, int sat
+{
+  unsigned32 v1 = GPR[rs];
+  unsigned32 v2 = GPR[rt];
+  unsigned32 tempu = 0, tempv = 0, tempw = 0, tempx = 0;
+  if (sat == 0)
+    {
+      tempu = (v1 & 0xff000000) >> 24;
+      tempv = (v1 & 0xff00) >> 8;
+      tempw = (v2 & 0xff000000) >> 24;
+      tempx = (v2 & 0xff00) >> 8;
+    }
+  else if (sat == 1)
+    {
+      if (v1 & 0x80000000)
+       {
+         DSPCR |= DSPCR_OUFLAG6;
+         tempu = 0;
+       }
+      else if (!(v1 & 0x80000000) && ((v1 >> 16) > (unsigned32)0x7f80))
+       {
+         DSPCR |= DSPCR_OUFLAG6;
+         tempu = 0xff;
+       }
+      else
+       tempu = (v1 & 0x7f800000) >> 23;
+      if (v1 & 0x8000)
+       {
+         DSPCR |= DSPCR_OUFLAG6;
+         tempv = 0;
+       }
+      else if (!(v1 & 0x8000) && ((v1 & 0xffff) > (unsigned32)0x7f80))
+       {
+         DSPCR |= DSPCR_OUFLAG6;
+         tempv = 0xff;
+       }
+      else
+       tempv = (v1 & 0x7f80) >> 7;
+      if (v2 & 0x80000000)
+       {
+         DSPCR |= DSPCR_OUFLAG6;
+         tempw = 0;
+       }
+      else if (!(v2 & 0x80000000) && ((v2 >> 16) > (unsigned32)0x7f80))
+       {
+         DSPCR |= DSPCR_OUFLAG6;
+         tempw = 0xff;
+       }
+      else
+       tempw = (v2 & 0x7f800000) >> 23;
+      if (v2 & 0x8000)
+       {
+         DSPCR |= DSPCR_OUFLAG6;
+         tempx = 0;
+       }
+      else if (!(v2 & 0x8000) && ((v2 & 0xffff) > (unsigned32)0x7f80))
+       {
+         DSPCR |= DSPCR_OUFLAG6;
+         tempx = 0xff;
+       }
+      else
+       tempx = (v2 & 0x7f80) >> 7;
+    }
+  GPR[rd] = EXTEND32 ((tempu << 24) | (tempv << 16) | (tempw << 8) | tempx);
+}
+
+:function:::void:do_w_ph_rs_precrq:int rd, int rs, int rt
+{
+  unsigned32 v1 = GPR[rs];
+  unsigned32 v2 = GPR[rt];
+  signed32 h1 = (signed32)v1;
+  signed32 h2 = (signed32)v2;
+  signed64 temp1 = (signed64)h1 + (signed64)0x8000;
+  signed32 temp2;
+  signed64 temp3 = (signed64)h2 + (signed64)0x8000;
+  signed32 temp4;
+  if (((temp1 & 0x100000000LL) >> 1) != (temp1 & 0x80000000))
+    {
+      DSPCR |= DSPCR_OUFLAG6;
+      temp2 = 0x7fff;
+    }
+  else
+    temp2 = (signed32)((temp1 & 0xffff0000) >> 16);
+  if (((temp3 & 0x100000000LL) >> 1) != (temp3 & 0x80000000))
+    {
+      DSPCR |= DSPCR_OUFLAG6;
+      temp4 = 0x7fff;
+    }
+  else
+    temp4 = (signed32)((temp3 & 0xffff0000) >> 16);
+  GPR[rd] = EXTEND32 ((temp2 << 16) | temp4);
+}
+
+:function:::void:do_qb_w_raddu:int rd, int rs
+{
+  int i;
+  unsigned8 h0;
+  unsigned32 v1 = GPR[rs];
+  unsigned32 result = 0;
+  for (i = 0; i < 32; i += 8, v1 >>= 8)
+    {
+      h0 = (unsigned8)(v1 & 0xff);
+      result += (unsigned32)h0;
+    }
+  GPR[rd] = EXTEND32 (result);
+}
+
+:function:::void:do_rddsp:int rd, int mask
+{
+  unsigned32 result = 0;
+  if (mask & 0x1)
+    {
+      result &= (~DSPCR_POS_SMASK);
+      result |= (DSPCR & DSPCR_POS_SMASK);
+    }
+  if (mask & 0x2)
+    {
+      result &= (~DSPCR_SCOUNT_SMASK);
+      result |= (DSPCR & DSPCR_SCOUNT_SMASK);
+    }
+  if (mask & 0x4)
+    {
+      result &= (~DSPCR_CARRY_SMASK);
+      result |= (DSPCR & DSPCR_CARRY_SMASK);
+    }
+  if (mask & 0x8)
+    {
+      result &= (~DSPCR_OUFLAG_SMASK);
+      result |= (DSPCR & DSPCR_OUFLAG_SMASK);
+    }
+  if (mask & 0x10)
+    {
+      result &= (~DSPCR_CCOND_SMASK);
+      result |= (DSPCR & DSPCR_CCOND_SMASK);
+    }
+  if (mask & 0x20)
+    {
+      result &= (~DSPCR_EFI_SMASK);
+      result |= (DSPCR & DSPCR_EFI_SMASK);
+    }
+  GPR[rd] = EXTEND32 (result);
+}
+
+// op: 0 = REPL.QB, 1 = REPLV.QB, 2 = REPL.PH, 3 = REPLV.PH
+:function:::void:do_repl:int rd, int p2, int op
+{
+  if (op == 0)
+    GPR[rd] = EXTEND32 ((p2 << 24) | (p2 << 16) | (p2 << 8) | p2);
+  else if (op == 1)
+    {
+      unsigned32 v1 = GPR[p2] & 0xff;
+      GPR[rd] = EXTEND32 ((v1 << 24) | (v1 << 16) | (v1 << 8) | v1);
+    }
+  else if (op == 2)
+    {
+      signed32 v1 = p2;
+      if (v1 & 0x200)
+       v1 |= 0xfffffc00;
+      GPR[rd] = EXTEND32 ((v1 << 16) | (v1 & 0xffff));
+    }
+  else if (op == 3)
+    {
+      unsigned32 v1 = GPR[p2];
+      v1 = v1 & 0xffff;
+      GPR[rd] = EXTEND32 ((v1 << 16) | v1);
+    }
+}
+
+:function:::void:do_shilov:int ac, int rs
+{
+  signed32 shift = GPR[rs] & 0x3f;
+  do_shilo (SD_, ac, shift);
+}
+
+// op: 0 = SHLLV, 1 = SHRAV
+// sat: 0 =  normal, 1 = saturate/rounding
+:function:::void:do_ph_shl:int rd, int rt, int rs, int op, int sat
+{
+  unsigned32 shift = GPR[rs] & 0xf;
+  do_ph_shift (SD_, rd, rt, shift, op, sat);
+}
+
+// op: 0 = SHLLV, 1 = SHRLV
+:function:::void:do_qb_shl:int rd, int rt, int rs, int op
+{
+  unsigned32 shift = GPR[rs] & 0x7;
+  do_qb_shift (SD_, rd, rt, shift, op);
+}
+
+:function:::void:do_w_s_shllv:int rd, int rt, int rs
+{
+  unsigned32 shift = GPR[rs] & 0x1f;
+  do_w_shll (SD_, rd, rt, shift);
+}
+
+:function:::void:do_ph_shrlv:int rd, int rt, int rs
+{
+  unsigned32 shift = GPR[rs] & 0xf;
+  do_ph_shrl (SD_, rd, rt, shift);
+}
+
+:function:::void:do_w_r_shrav:int rd, int rt, int rs
+{
+  unsigned32 shift = GPR[rs] & 0x1f;
+  do_w_shra (SD_, rd, rt, shift);
+}
+
+:function:::void:do_wrdsp:int rs, int mask
+{
+  unsigned32 v1 = GPR[rs];
+  if (mask & 0x1)
+    {
+      DSPCR &= (~DSPCR_POS_SMASK);
+      DSPCR |= (v1 & DSPCR_POS_SMASK);
+    }
+  if (mask & 0x2)
+    {
+      DSPCR &= (~DSPCR_SCOUNT_SMASK);
+      DSPCR |= (v1 & DSPCR_SCOUNT_SMASK);
+    }
+  if (mask & 0x4)
+    {
+      DSPCR &= (~DSPCR_CARRY_SMASK);
+      DSPCR |= (v1 & DSPCR_CARRY_SMASK);
+    }
+  if (mask & 0x8)
+    {
+      DSPCR &= (~DSPCR_OUFLAG_SMASK);
+      DSPCR |= (v1 & DSPCR_OUFLAG_SMASK);
+    }
+  if (mask & 0x10)
+    {
+      DSPCR &= (~DSPCR_CCOND_SMASK);
+      DSPCR |= (v1 & DSPCR_CCOND_SMASK);
+    }
+  if (mask & 0x20)
+    {
+      DSPCR &= (~DSPCR_EFI_SMASK);
+      DSPCR |= (v1 & DSPCR_EFI_SMASK);
+    }
+}
+
+// round: 0 = no rounding, 1 = rounding
+:function:::void:do_qb_shrav:int rd, int rt, int rs, int round
+{
+  unsigned32 shift = GPR[rs] & 0x7;
+  do_qb_shra (SD_, rd, rt, shift, round);
+}
+
+:function:::void:do_append:int rt, int rs, int sa
+{
+  unsigned32 v0 = GPR[rs];
+  unsigned32 v1 = GPR[rt];
+  unsigned32 result;
+  unsigned32 mask = (1 << sa) - 1;
+  result = (v1 << sa) | (v0 & mask);
+  GPR[rt] = EXTEND32 (result);
+}
+
+:function:::void:do_balign:int rt, int rs, int bp
+{
+  unsigned32 v0 = GPR[rs];
+  unsigned32 v1 = GPR[rt];
+  unsigned32 result;
+  if (bp == 0)
+    result = v1;
+  else
+    result = (v1 << 8 * bp) | (v0 >> 8 * (4 - bp));
+  GPR[rt] = EXTEND32 (result);
+}
+
+:function:::void:do_ph_w_mulsa:int ac, int rs, int rt
+{
+  int i;
+  unsigned32 v1 = GPR[rs];
+  unsigned32 v2 = GPR[rt];
+  signed16 h1, h2;
+  signed32 result;
+  unsigned32 lo = DSPLO(ac);
+  unsigned32 hi = DSPHI(ac);
+  signed64 prod = (signed64)((((unsigned64)hi) << 32) + (unsigned64)lo);
+  for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
+    {
+      h1 = (signed16)(v1 & 0xffff);
+      h2 = (signed16)(v2 & 0xffff);
+      result = (signed32)h1 * (signed32)h2;
+
+      if (i == 0)
+       prod -= (signed64) result;
+      else
+       prod += (signed64) result;
+    }
+  DSPLO(ac) = EXTEND32 (prod);
+  DSPHI(ac) = EXTEND32 (prod >> 32);
+}
+
+:function:::void:do_ph_qb_precr:int rd, int rs, int rt
+{
+  unsigned32 v1 = GPR[rs];
+  unsigned32 v2 = GPR[rt];
+  unsigned32 tempu = (v1 & 0xff0000) >> 16;
+  unsigned32 tempv = (v1 & 0xff);
+  unsigned32 tempw = (v2 & 0xff0000) >> 16;
+  unsigned32 tempx = (v2 & 0xff);
+  GPR[rd] = EXTEND32 ((tempu << 24) | (tempv << 16) | (tempw << 8) | tempx);
+}
+
+:function:::void:do_prepend:int rt, int rs, int sa
+{
+  unsigned32 v0 = GPR[rs];
+  unsigned32 v1 = GPR[rt];
+  unsigned32 result;
+  if (sa == 0)
+    result = v1;
+  else
+    result = (v0 << (32 - sa)) | (v1 >> sa);
+  GPR[rt] = EXTEND32 (result);
+}
+
 :function:::void:do_w_shra:int rd, int rt, int shift
 {
   unsigned32 result = GPR[rt];
 "addsc r<RD>, r<RS>, r<RT>"
 *dsp:
 {
-  unsigned32 v1 = GPR[RS];
-  unsigned32 v2 = GPR[RT];
-  unsigned64 h0;
-  h0 = (unsigned64)v1 + (unsigned64)v2;
-  if (h0 & 0x100000000LL)
-    DSPCR |= DSPCR_CARRY;
-  GPR[RD] = EXTEND32 (h0);
+  do_addsc (SD_, RD, RS, RT);
 }
 
 011111,5.RS,5.RT,5.RD,10001,010000:SPECIAL3:32::ADDWC
 "addwc r<RD>, r<RS>, r<RT>"
 *dsp:
 {
-  unsigned32 v1 = GPR[RS];
-  unsigned32 v2 = GPR[RT];
-  unsigned64 h0;
-  signed32 h1 = (signed32) v1;
-  signed32 h2 = (signed32) v2;
-  h0 = (signed64)h1 + (signed64)h2
-       + (signed64)((DSPCR >> DSPCR_CARRY_SHIFT) & DSPCR_CARRY_MASK);
-  if (((h0 & 0x100000000LL) >> 1) != (h0 & 0x80000000))
-    DSPCR |= DSPCR_OUFLAG4;
-  GPR[RD] = EXTEND32 (h0);
+  do_addwc (SD_, RD, RS, RT);
 }
 
 011111,5.RS,5.RT,5.RD,10010,010000:SPECIAL3:32::MODSUB
 "modsub r<RD>, r<RS>, r<RT>"
 *dsp:
 {
-  unsigned32 result = 0;
-  unsigned32 v1 = GPR[RS];
-  unsigned32 v2 = GPR[RT];
-  unsigned32 decr = v2 & 0xff;
-  unsigned32 lastindex = (v2 & 0xffff00) >> 8;
-  if (v1 == 0)
-    result = lastindex;
-  else
-    result =  v1 - decr;
-  GPR[RD] = EXTEND32 (result);
+  do_modsub (SD_, RD, RS, RT);
 }
 
 011111,5.RS,00000,5.RD,10100,010000:SPECIAL3:32::RADDU.W.QB
 "raddu.w.qb r<RD>, r<RS>"
 *dsp:
 {
-  int i;
-  unsigned8 h0;
-  unsigned32 v1 = GPR[RS];
-  unsigned32 result = 0;
-  for (i = 0; i < 32; i += 8, v1 >>= 8)
-    {
-      h0 = (unsigned8)(v1 & 0xff);
-      result += (unsigned32)h0;
-    }
-  GPR[RD] = EXTEND32 (result);
+  do_qb_w_raddu (SD_, RD, RS);
 }
 
 011111,00000,5.RT,5.RD,01001,010010:SPECIAL3:32::ABSQ_S.PH
 "absq_s.ph r<RD>, r<RT>"
 *dsp:
 {
-  int i;
-  signed16 h0;
-  unsigned32 v1 = GPR[RT];
-  unsigned32 result = 0;
-  for (i = 0; i < 32; i += 16, v1 >>= 16)
-    {
-      h0 = (signed16)(v1 & 0xffff);
-      if (h0 == (signed16)0x8000)
-       {
-         DSPCR |= DSPCR_OUFLAG4;
-         h0 = 0x7fff;
-       }
-      else if (h0 & 0x8000)
-       h0 = -h0; 
-      result |= ((unsigned32)((unsigned16)h0) << i);
-    }
-  GPR[RD] = EXTEND32 (result);
+  do_ph_s_absq (SD_, RD, RT);
 }
 
 011111,00000,5.RT,5.RD,10001,010010:SPECIAL3:32::ABSQ_S.W
 "absq_s.w r<RD>, r<RT>"
 *dsp:
 {
-  unsigned32 v1 = GPR[RT];
-  signed32 h0 = (signed32)v1;
-  if (h0 == (signed32)0x80000000)
-    {
-      DSPCR |= DSPCR_OUFLAG4;
-      h0 = 0x7fffffff;
-    }
-  else if (h0 & 0x80000000)
-    h0 = -h0; 
-  GPR[RD] = EXTEND32 (h0);
+  do_w_s_absq (SD_, RD, RT);
 }
 
 011111,5.RS,5.RT,5.RD,01100,010001:SPECIAL3:32::PRECRQ.QB.PH
 "precrq.qb.ph r<RD>, r<RS>, r<RT>"
 *dsp:
 {
-  unsigned32 v1 = GPR[RS];
-  unsigned32 v2 = GPR[RT];
-  unsigned32 tempu = (v1 & 0xff000000) >> 24;
-  unsigned32 tempv = (v1 & 0xff00) >> 8;
-  unsigned32 tempw = (v2 & 0xff000000) >> 24;
-  unsigned32 tempx = (v2 & 0xff00) >> 8;
-  GPR[RD] = EXTEND32 ((tempu << 24) | (tempv << 16) | (tempw << 8) | tempx);
+  do_ph_qb_precrq (SD_, RD, RS, RT, 0);
 }
 
 011111,5.RS,5.RT,5.RD,10100,010001:SPECIAL3:32::PRECRQ.PH.W
 "precrq.ph.w r<RD>, r<RS>, r<RT>"
 *dsp:
 {
-  unsigned32 v1 = GPR[RS];
-  unsigned32 v2 = GPR[RT];
-  unsigned32 tempu = (v1 & 0xffff0000) >> 16;
-  unsigned32 tempv = (v2 & 0xffff0000) >> 16;
-  GPR[RD] = EXTEND32 ((tempu << 16) | tempv);
+  do_w_ph_precrq (SD_, RD, RS, RT);
 }
 
 011111,5.RS,5.RT,5.RD,10101,010001:SPECIAL3:32::PRECRQ_RS.PH.W
 "precrq_rs.ph.w r<RD>, r<RS>, r<RT>"
 *dsp:
 {
-  unsigned32 v1 = GPR[RS];
-  unsigned32 v2 = GPR[RT];
-  signed32 h1 = (signed32)v1;
-  signed32 h2 = (signed32)v2;
-  signed64 temp1 = (signed64)h1 + (signed64)0x8000;
-  signed32 temp2;
-  signed64 temp3 = (signed64)h2 + (signed64)0x8000;
-  signed32 temp4;
-  if (((temp1 & 0x100000000LL) >> 1) != (temp1 & 0x80000000))
-    {
-      DSPCR |= DSPCR_OUFLAG6;
-      temp2 = 0x7fff;
-    }
-  else
-    temp2 = (signed32)((temp1 & 0xffff0000) >> 16);
-  if (((temp3 & 0x100000000LL) >> 1) != (temp3 & 0x80000000))
-    {
-      DSPCR |= DSPCR_OUFLAG6;
-      temp4 = 0x7fff;
-    }
-  else
-    temp4 = (signed32)((temp3 & 0xffff0000) >> 16);
-  GPR[RD] = EXTEND32 ((temp2 << 16) | temp4);
+  do_w_ph_rs_precrq (SD_, RD, RS, RT);
 }
 
 011111,5.RS,5.RT,5.RD,01111,010001:SPECIAL3:32::PRECRQU_S.QB.PH
 "precrqu_s.qb.ph r<RD>, r<RS>, r<RT>"
 *dsp:
 {
-  unsigned32 v1 = GPR[RS];
-  unsigned32 v2 = GPR[RT];
-  unsigned32 tempu, tempv, tempw, tempx;
-  if (v1 & 0x80000000)
-    {
-      DSPCR |= DSPCR_OUFLAG6;
-      tempu = 0;
-    }
-  else if (!(v1 & 0x80000000) && ((v1 >> 16) > (unsigned32)0x7f80))
-    {
-      DSPCR |= DSPCR_OUFLAG6;
-      tempu = 0xff;
-    }
-  else
-    tempu = (v1 & 0x7f800000) >> 23;
-  if (v1 & 0x8000)
-    {
-      DSPCR |= DSPCR_OUFLAG6;
-      tempv = 0;
-    }
-  else if (!(v1 & 0x8000) && ((v1 & 0xffff) > (unsigned32)0x7f80))
-    {
-      DSPCR |= DSPCR_OUFLAG6;
-      tempv = 0xff;
-    }
-  else
-    tempv = (v1 & 0x7f80) >> 7;
-  if (v2 & 0x80000000)
-    {
-      DSPCR |= DSPCR_OUFLAG6;
-      tempw = 0;
-    }
-  else if (!(v2 & 0x80000000) && ((v2 >> 16) > (unsigned32)0x7f80))
-    {
-      DSPCR |= DSPCR_OUFLAG6;
-      tempw = 0xff;
-    }
-  else
-    tempw = (v2 & 0x7f800000) >> 23;
-  if (v2 & 0x8000)
-    {
-      DSPCR |= DSPCR_OUFLAG6;
-      tempx = 0;
-    }
-  else if (!(v2 & 0x8000) && ((v2 & 0xffff) > (unsigned32)0x7f80))
-    {
-      DSPCR |= DSPCR_OUFLAG6;
-      tempx = 0xff;
-    }
-  else
-    tempx = (v2 & 0x7f80) >> 7;
-  GPR[RD] = EXTEND32 ((tempu << 24) | (tempv << 16) | (tempw << 8) | tempx);
+  do_ph_qb_precrq (SD_, RD, RS, RT, 1);
 }
 
 011111,00000,5.RT,5.RD,01100,010010:SPECIAL3:32::PRECEQ.W.PHL
 "preceq.w.phl r<RD>, r<RT>"
 *dsp:
 {
-  unsigned32 v1 = GPR[RT];
-  GPR[RD] = EXTEND32 (v1 & 0xffff0000);
+  do_w_preceq (SD_, RD, RT, 0);
 }
 
 011111,00000,5.RT,5.RD,01101,010010:SPECIAL3:32::PRECEQ.W.PHR
 "preceq.w.phr r<RD>, r<RT>"
 *dsp:
 {
-  unsigned32 v1 = GPR[RT];
-  GPR[RD] = EXTEND32 ((v1 & 0xffff) << 16);
+  do_w_preceq (SD_, RD, RT, 1);
 }
 
 011111,00000,5.RT,5.RD,00100,010010:SPECIAL3:32::PRECEQU.PH.QBL
 "precequ.ph.qbl r<RD>, r<RT>"
 *dsp:
 {
-  unsigned32 v1 = GPR[RT];
-  GPR[RD] = EXTEND32 ((v1 & 0xff000000) >> 1) | ((v1 & 0xff0000) >> 9);
+  do_qb_ph_precequ (SD_, RD, RT, 2);
 }
 
 011111,00000,5.RT,5.RD,00101,010010:SPECIAL3:32::PRECEQU.PH.QBR
 "precequ.ph.qbr r<RD>, r<RT>"
 *dsp:
 {
-  unsigned32 v1 = GPR[RT];
-  GPR[RD] = EXTEND32 ((v1 & 0xff00) << 15) | ((v1 & 0xff) << 7);
+  do_qb_ph_precequ (SD_, RD, RT, 0);
 }
 
 011111,00000,5.RT,5.RD,00110,010010:SPECIAL3:32::PRECEQU.PH.QBLA
 "precequ.ph.qbla r<RD>, r<RT>"
 *dsp:
 {
-  unsigned32 v1 = GPR[RT];
-  GPR[RD] = EXTEND32 ((v1 & 0xff000000) >> 1) | ((v1 & 0xff00) >> 1);
+  do_qb_ph_precequ (SD_, RD, RT, 3);
 }
 
 011111,00000,5.RT,5.RD,00111,010010:SPECIAL3:32::PRECEQU.PH.QBRA
 "precequ.ph.qbra r<RD>, r<RT>"
 *dsp:
 {
-  unsigned32 v1 = GPR[RT];
-  GPR[RD] = EXTEND32 ((v1 & 0xff0000) << 7) | ((v1 & 0xff) << 7);
+  do_qb_ph_precequ (SD_, RD, RT, 1);
 }
 
 011111,00000,5.RT,5.RD,11100,010010:SPECIAL3:32::PRECEU.PH.QBL
 "preceu.ph.qbl r<RD>, r<RT>"
 *dsp:
 {
-  unsigned32 v1 = GPR[RT];
-  GPR[RD] = EXTEND32 ((v1 & 0xff000000) >> 8) | ((v1 & 0xff0000) >> 16);
+  do_qb_ph_preceu (SD_, RD, RT, 2);
 }
 
 011111,00000,5.RT,5.RD,11101,010010:SPECIAL3:32::PRECEU.PH.QBR
 "preceu.ph.qbr r<RD>, r<RT>"
 *dsp:
 {
-  unsigned32 v1 = GPR[RT];
-  GPR[RD] = EXTEND32 ((v1 & 0xff00) << 8) | (v1 & 0xff);
+  do_qb_ph_preceu (SD_, RD, RT, 0);
 }
 
 011111,00000,5.RT,5.RD,11110,010010:SPECIAL3:32::PRECEU.PH.QBLA
 "preceu.ph.qbla r<RD>, r<RT>"
 *dsp:
 {
-  unsigned32 v1 = GPR[RT];
-  GPR[RD] = EXTEND32 ((v1 & 0xff000000) >> 8) | ((v1 & 0xff00) >> 8);
+  do_qb_ph_preceu (SD_, RD, RT, 3);
 }
 
 011111,00000,5.RT,5.RD,11111,010010:SPECIAL3:32::PRECEU.PH.QBRA
 "preceu.ph.qbra r<RD>, r<RT>"
 *dsp:
 {
-  unsigned32 v1 = GPR[RT];
-  GPR[RD] = EXTEND32 ((v1 & 0xff0000) | (v1 & 0xff));
+  do_qb_ph_preceu (SD_, RD, RT, 1);
 }
 
 011111,00,3.SHIFT3,5.RT,5.RD,00000,010011:SPECIAL3:32::SHLL.QB
 "shllv.qb r<RD>, r<RT>, r<RS>"
 *dsp:
 {
-  unsigned32 shift = GPR[RS] & 0x7;
-  do_qb_shift (SD_, RD, RT, shift, 0);
+  do_qb_shl (SD_, RD, RT, RS, 0);
 }
 
 011111,0,4.SHIFT4,5.RT,5.RD,01000,010011:SPECIAL3:32::SHLL.PH
 "shllv.ph r<RD>, r<RT>, r<RS>"
 *dsp:
 {
-  unsigned32 shift = GPR[RS] & 0xf;
-  do_ph_shift (SD_, RD, RT, shift, 0, 0);
+  do_ph_shl (SD_, RD, RT, RS, 0, 0);
 }
 
 011111,0,4.SHIFT4,5.RT,5.RD,01100,010011:SPECIAL3:32::SHLL_S.PH
 "shllv_s.ph r<RD>, r<RT>, r<RS>"
 *dsp:
 {
-  unsigned32 shift = GPR[RS] & 0xf;
-  do_ph_shift (SD_, RD, RT, shift, 0, 1);
+  do_ph_shl (SD_, RD, RT, RS, 0, 1);
 }
 
 011111,5.SHIFT5,5.RT,5.RD,10100,010011:SPECIAL3:32::SHLL_S.W
 "shllv_s.w r<RD>, r<RT>, r<RS>"
 *dsp:
 {
-  unsigned32 shift = GPR[RS] & 0x1f;
-  do_w_shll (SD_, RD, RT, shift);
+  do_w_s_shllv (SD_, RD, RT, RS);
 }
 
 011111,00,3.SHIFT3,5.RT,5.RD,00001,010011:SPECIAL3:32::SHRL.QB
 "shrlv.qb r<RD>, r<RT>, r<RS>"
 *dsp:
 {
-  unsigned32 shift = GPR[RS] & 0x7;
-  do_qb_shift (SD_, RD, RT, shift, 1);
+  do_qb_shl (SD_, RD, RT, RS, 1);
 }
 
 011111,0,4.SHIFT4,5.RT,5.RD,01001,010011:SPECIAL3:32::SHRA.PH
 "shrav.ph r<RD>, r<RT>, r<RS>"
 *dsp:
 {
-  unsigned32 shift = GPR[RS] & 0xf;
-  do_ph_shift (SD_, RD, RT, shift, 1, 0);
+  do_ph_shl (SD_, RD, RT, RS, 1, 0);
 }
 
 011111,0,4.SHIFT4,5.RT,5.RD,01101,010011:SPECIAL3:32::SHRA_R.PH
 "shrav_r.ph r<RD>, r<RT>, r<RS>"
 *dsp:
 {
-  unsigned32 shift = GPR[RS] & 0xf;
-  do_ph_shift (SD_, RD, RT, shift, 1, 1);
+  do_ph_shl (SD_, RD, RT, RS, 1, 1);
 }
 
 011111,5.SHIFT5,5.RT,5.RD,10101,010011:SPECIAL3:32::SHRA_R.W
 "shrav_r.w r<RD>, r<RT>, r<RS>"
 *dsp:
 {
-  unsigned32 shift = GPR[RS] & 0x1f;
-  do_w_shra (SD_, RD, RT, shift);
+  do_w_r_shrav (SD_, RD, RT, RS);
 }
 
 // loc: 0 = qhl, 1 = qhr
 "mulsaq_s.w.ph ac<AC>, r<RS>, r<RT>"
 *dsp:
 {
-  int i;
-  unsigned32 v1 = GPR[RS];
-  unsigned32 v2 = GPR[RT];
-  signed16 h1, h2;
-  signed32 result;
-  unsigned32 lo = DSPLO(AC);
-  unsigned32 hi = DSPHI(AC);
-  signed64 prod = (signed64)((((unsigned64)hi) << 32) + (unsigned64)lo);
-  for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
-    {
-      h1 = (signed16)(v1 & 0xffff);
-      h2 = (signed16)(v2 & 0xffff);
-      if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000)
-       {
-         DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + AC));
-         result = (signed32) 0x7fffffff;
-       }
-      else
-       result = ((signed32)h1 * (signed32)h2) << 1;
-
-      if (i == 0)
-       prod -= (signed64) result;
-      else
-       prod += (signed64) result;
-    }
-  DSPLO(AC) = EXTEND32 (prod);
-  DSPHI(AC) = EXTEND32 (prod >> 32);
+  do_mulsaq_s_w_ph (SD_, AC, RS, RT);
 }
 
 // op: 0 = DPAQ 1 = DPSQ
 "bitrev r<RD>, r<RT>"
 *dsp:
 {
-  int i;
-  unsigned32 v1 = GPR[RT];
-  unsigned32 h1 = 0;
-  for (i = 0; i < 16; i++)
-    {
-      if (v1 & (1 << i))
-       h1 |= (1 << (15 - i));
-    }
-  GPR[RD] = EXTEND32 (h1);
+  do_bitrev (SD_, RD, RT);
 }
 
 011111,5.RS,5.RT,00000,00000,001100:SPECIAL3:32::INSV
 "insv r<RT>, r<RS>"
 *dsp:
 {
-  unsigned32 v1 = GPR[RS];
-  unsigned32 v2 = GPR[RT];
-  unsigned32 pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
-  unsigned32 size = (DSPCR >> DSPCR_SCOUNT_SHIFT) & DSPCR_SCOUNT_MASK;
-  unsigned32 mask1, mask2, mask3, result;
-  if (size < 32)
-    mask1 = (1 << size) - 1;
-  else
-    mask1 = 0xffffffff;
-  mask2 = (1 << pos) - 1;
-  if (pos + size < 32)
-    mask3 = ~((1 << (pos + size)) - 1);
-  else
-    mask3 = 0;
-  result = (v2 & mask3) | ((v1 & mask1) << pos) | (v2 & mask2);
-  GPR[RT] = EXTEND32 (result);
+  do_insv (SD_, RT, RS);
 }
 
 011111,00,8.IMM8,5.RD,00010,010010:SPECIAL3:32::REPL.QB
 "repl.qb r<RD>, <IMM8>"
 *dsp:
 {
-  GPR[RD] = EXTEND32 ((IMM8 << 24) | (IMM8 << 16) | (IMM8 << 8) | IMM8);
+  do_repl (SD_, RD, IMM8, 0);
 }
 
 011111,00000,5.RT,5.RD,00011,010010:SPECIAL3:32::REPLV.QB
 "replv.qb r<RD>, r<RT>"
 *dsp:
 {
-  unsigned32 v1 = GPR[RT];
-  v1 = v1 & 0xff;
-  GPR[RD] = EXTEND32 ((v1 << 24) | (v1 << 16) | (v1 << 8) | v1);
+  do_repl (SD_, RD, RT, 1);
 }
 
 011111,10.IMM10,5.RD,01010,010010:SPECIAL3:32::REPL.PH
 "repl.ph r<RD>, <IMM10>"
 *dsp:
 {
-  signed32 v1 = IMM10;
-  if (v1 & 0x200)
-    v1 |= 0xfffffc00;
-  GPR[RD] = EXTEND32 ((v1 << 16) | (v1 & 0xffff));
+  do_repl (SD_, RD, IMM10, 2);
 }
 
 011111,00000,5.RT,5.RD,01011,010010:SPECIAL3:32::REPLV.PH
 "replv.ph r<RD>, r<RT>"
 *dsp:
 {
-  unsigned32 v1 = GPR[RT];
-  v1 = v1 & 0xffff;
-  GPR[RD] = EXTEND32 ((v1 << 16) | v1);
+  do_repl (SD_, RD, RT, 3);
 }
 
 // op: 0 = EQ, 1 = LT, 2 = LE
 "pick.qb r<RD>, r<RS>, r<RT>"
 *dsp:
 {
-  int i, j;
-  unsigned32 v1 = GPR[RS];
-  unsigned32 v2 = GPR[RT];
-  unsigned8 h1, h2;
-  unsigned32 result = 0;
-  for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8)
-    {
-      h1 = (unsigned8)(v1 & 0xff);
-      h2 = (unsigned8)(v2 & 0xff);
-      if (DSPCR & (1 << (DSPCR_CCOND_SHIFT + j)))
-       result |= (unsigned32)(h1 << i);
-      else
-       result |= (unsigned32)(h2 << i);
-    }
-  GPR[RD] = EXTEND32 (result);
+  do_qb_pick (SD_, RD, RS, RT);
 }
 
 011111,5.RS,5.RT,5.RD,01011,010001:SPECIAL3:32::PICK.PH
 "pick.ph r<RD>, r<RS>, r<RT>"
 *dsp:
 {
-  int i, j;
-  unsigned32 v1 = GPR[RS];
-  unsigned32 v2 = GPR[RT];
-  unsigned16 h1, h2;
-  unsigned32 result = 0;
-  for (i = 0, j = 0; i < 32; i += 16, j++, v1 >>= 16, v2 >>= 16)
-    {
-      h1 = (unsigned16)(v1 & 0xffff);
-      h2 = (unsigned16)(v2 & 0xffff);
-      if (DSPCR & (1 << (DSPCR_CCOND_SHIFT + j)))
-       result |= (unsigned32)(h1 << i);
-      else
-       result |= (unsigned32)(h2 << i);
-    }
-  GPR[RD] = EXTEND32 (result);
+  do_ph_pick (SD_, RD, RS, RT);
 }
 
 011111,5.RS,5.RT,5.RD,01110,010001:SPECIAL3:32::PACKRL.PH
 "packrl.ph r<RD>, r<RS>, r<RT>"
 *dsp:
 {
-  unsigned32 v1 = GPR[RS];
-  unsigned32 v2 = GPR[RT];
-  GPR[RD] = EXTEND32 ((v1 << 16) + (v2 >> 16));
+  do_ph_packrl (SD_, RD, RS, RT);
 }
 
 // op: 0 = EXTR, 1 = EXTR_R, 2 = EXTR_RS
 "extrv.w r<RT>, ac<AC>, r<RS>"
 *dsp:
 {
-  unsigned32 shift = GPR[RS] & 0x1f;
-  do_w_extr (SD_, RT, AC, shift, 0);
+  do_extrv (SD_, RT, AC, RS, 0);
 }
 
 011111,5.SHIFT,5.RT,000,2.AC,00100,111000:SPECIAL3:32::EXTR_R.W
 "extrv_r.w r<RT>, ac<AC>, r<RS>"
 *dsp:
 {
-  unsigned32 shift = GPR[RS] & 0x1f;
-  do_w_extr (SD_, RT, AC, shift, 1);
+  do_extrv (SD_, RT, AC, RS, 1);
 }
 
 011111,5.SHIFT,5.RT,000,2.AC,00110,111000:SPECIAL3:32::EXTR_RS.W
 "extrv_rs.w r<RT>, ac<AC>, r<RS>"
 *dsp:
 {
-  unsigned32 shift = GPR[RS] & 0x1f;
-  do_w_extr (SD_, RT, AC, shift, 2);
+  do_extrv (SD_, RT, AC, RS, 2);
 }
 
 :function:::void:do_h_extr:int rt, int ac, int shift
 "extrv_s.h r<RT>, ac<AC>, r<RS>"
 *dsp:
 {
-  unsigned32 shift = GPR[RS] & 0x1f;
-  do_h_extr (SD_, RT, AC, shift);
+  do_extrv_s_h (SD_, RT, AC, RS);
 }
 
 // op: 0 = EXTP, 1 = EXTPDP
 "extpv r<RT>, ac<AC>, r<RS>"
 *dsp:
 {
-  unsigned32 size = GPR[RS] & 0x1f;
-  do_extp (SD_, RT, AC, size, 0);
+  do_extpv (SD_, RT, AC, RS, 0);
 }
 
 011111,5.SIZE,5.RT,000,2.AC,01010,111000:SPECIAL3:32::EXTPDP
 "extpdpv r<RT>, ac<AC>, r<RS>"
 *dsp:
 {
-  unsigned32 size = GPR[RS] & 0x1f;
-  do_extp (SD_, RT, AC, size, 1);
+  do_extpv (SD_, RT, AC, RS, 1);
 }
 
 :function:::void:do_shilo:int ac, int shift
 "shilov ac<AC>, r<RS>"
 *dsp:
 {
-  signed32 shift = GPR[RS] & 0x3f;
-  do_shilo (SD_, AC, shift);
+  do_shilov (SD_, AC, RS);
 }
 
 011111,5.RS,00000,000,2.AC,11111,111000:SPECIAL3:32::MTHLIP
 "mthlip r<RS>, ac<AC>"
 *dsp:
 {
-  unsigned32 pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
-  DSPHI(AC) = DSPLO(AC);
-  DSPLO(AC) = GPR[RS];
-  if (pos >= 32)
-    Unpredictable ();
-  else
-    pos += 32;
-  DSPCR &= (~DSPCR_POS_SMASK);
-  DSPCR |= (pos & DSPCR_POS_MASK) << DSPCR_POS_SHIFT;
+  do_mthlip (SD_, RS, AC);
 }
 
 011111,5.RS,10.MASK10,10011,111000:SPECIAL3:32::WRDSP
 "wrdsp r<RS>, <MASK10>"
 *dsp:
 {
-  unsigned32 v1 = GPR[RS];
-  if (MASK10 & 0x1)
-    {
-      DSPCR &= (~DSPCR_POS_SMASK);
-      DSPCR |= (v1 & DSPCR_POS_SMASK);
-    }
-  if (MASK10 & 0x2)
-    {
-      DSPCR &= (~DSPCR_SCOUNT_SMASK);
-      DSPCR |= (v1 & DSPCR_SCOUNT_SMASK);
-    }
-  if (MASK10 & 0x4)
-    {
-      DSPCR &= (~DSPCR_CARRY_SMASK);
-      DSPCR |= (v1 & DSPCR_CARRY_SMASK);
-    }
-  if (MASK10 & 0x8)
-    {
-      DSPCR &= (~DSPCR_OUFLAG_SMASK);
-      DSPCR |= (v1 & DSPCR_OUFLAG_SMASK);
-    }
-  if (MASK10 & 0x10)
-    {
-      DSPCR &= (~DSPCR_CCOND_SMASK);
-      DSPCR |= (v1 & DSPCR_CCOND_SMASK);
-    }
-  if (MASK10 & 0x20)
-    {
-      DSPCR &= (~DSPCR_EFI_SMASK);
-      DSPCR |= (v1 & DSPCR_EFI_SMASK);
-    }
+  do_wrdsp (SD_, RS, MASK10);
 }
 
 011111,10.MASK10,5.RD,10010,111000:SPECIAL3:32::RDDSP
 "rddsp r<RD>, <MASK10>"
 *dsp:
 {
-  unsigned32 result = 0;
-  if (MASK10 & 0x1)
-    {
-      result &= (~DSPCR_POS_SMASK);
-      result |= (DSPCR & DSPCR_POS_SMASK);
-    }
-  if (MASK10 & 0x2)
-    {
-      result &= (~DSPCR_SCOUNT_SMASK);
-      result |= (DSPCR & DSPCR_SCOUNT_SMASK);
-    }
-  if (MASK10 & 0x4)
-    {
-      result &= (~DSPCR_CARRY_SMASK);
-      result |= (DSPCR & DSPCR_CARRY_SMASK);
-    }
-  if (MASK10 & 0x8)
-    {
-      result &= (~DSPCR_OUFLAG_SMASK);
-      result |= (DSPCR & DSPCR_OUFLAG_SMASK);
-    }
-  if (MASK10 & 0x10)
-    {
-      result &= (~DSPCR_CCOND_SMASK);
-      result |= (DSPCR & DSPCR_CCOND_SMASK);
-    }
-  if (MASK10 & 0x20)
-    {
-      result &= (~DSPCR_EFI_SMASK);
-      result |= (DSPCR & DSPCR_EFI_SMASK);
-    }
-  GPR[RD] = EXTEND32 (result);
+  do_rddsp (SD_, RD, MASK10);
 }
 
 011111,5.BASE,5.INDEX,5.RD,00110,001010:SPECIAL3:32::LBUX
 "lbux r<RD>, r<INDEX>(r<BASE>)"
 *dsp:
 {
-  GPR[RD] = do_load (SD_, AccessLength_BYTE, GPR[BASE], GPR[INDEX]);
+  do_lxx (SD_, RD, BASE, INDEX, 0);
 }
 
 011111,5.BASE,5.INDEX,5.RD,00100,001010:SPECIAL3:32::LHX
 "lhx r<RD>, r<INDEX>(r<BASE>)"
 *dsp:
 {
-  GPR[RD] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[BASE], GPR[INDEX]));
+  do_lxx (SD_, RD, BASE, INDEX, 1);
 }
 
 011111,5.BASE,5.INDEX,5.RD,00000,001010:SPECIAL3:32::LWX
 "lwx r<RD>, r<INDEX>(r<BASE>)"
 *dsp:
 {
-  GPR[RD] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[BASE], GPR[INDEX]));
+  do_lxx (SD_, RD, BASE, INDEX, 2);
 }
 
 000001,00000,11100,16.OFFSET:REGIMM:32::BPOSGE32
index 9cecd628021e44bf9faf8fc60910928e7b48e76a..a8710268d5ad7d9f1161a182b3a40fec84e39eec 100644 (file)
@@ -5,7 +5,7 @@
 // Contributed by MIPS Technologies, Inc.
 // Written by Chao-ying Fu (fu@mips.com).
 //
-// This file is part of GDB, the GNU debugger.
+// This file is part of the MIPS sim
 //
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
 "absq_s.qb r<RD>, r<RT>"
 *dsp2:
 {
-  int i;
-  signed8 q0;
-  unsigned32 v1 = GPR[RT];
-  unsigned32 result = 0;
-  for (i = 0; i < 32; i += 8, v1 >>= 8)
-    {
-      q0 = (signed8)(v1 & 0xff);
-      if (q0 == (signed8)0x80)
-        {
-          DSPCR |= DSPCR_OUFLAG4;
-          q0 = 0x7f;
-        }
-      else if (q0 & 0x80)
-        q0 = -q0;
-      result |= ((unsigned32)((unsigned8)q0) << i);
-    }
-  GPR[RD] = EXTEND32 (result);
+  do_qb_s_absq (SD_, RD, RT);
 }
 
 011111,5.RS,5.RT,5.RD,01000,010000:SPECIAL3:32::ADDU.PH
 "append r<RT>, r<RS>, <SA>"
 *dsp2:
 {
-  unsigned32 v0 = GPR[RS];
-  unsigned32 v1 = GPR[RT];
-  unsigned32 result;
-  unsigned32 mask = (1 << SA) - 1;
-  result = (v1 << SA) | (v0 & mask);
-  GPR[RT] = EXTEND32 (result);
+  do_append (SD_, RT, RS, SA);
 }
 
 011111,5.RS,5.RT,000,2.BP,10000,110001:SPECIAL3:32::BALIGN
 "balign r<RT>, r<RS>, <BP>"
 *dsp2:
 {
-  unsigned32 v0 = GPR[RS];
-  unsigned32 v1 = GPR[RT];
-  unsigned32 result;
-  if (BP == 0)
-    result = v1;
-  else
-    result = (v1 << 8 * BP) | (v0 >> 8 * (4 - BP));
-  GPR[RT] = EXTEND32 (result);
+  do_balign (SD_, RT, RS, BP);
 }
 
 011111,5.RS,5.RT,5.RD,11000,010001:SPECIAL3:32::CMPGDU.EQ.QB
 "mulsa.w.ph ac<AC>, r<RS>, r<RT>"
 *dsp2:
 {
-  int i;
-  unsigned32 v1 = GPR[RS];
-  unsigned32 v2 = GPR[RT];
-  signed16 h1, h2;
-  signed32 result;
-  unsigned32 lo = DSPLO(AC);
-  unsigned32 hi = DSPHI(AC);
-  signed64 prod = (signed64)((((unsigned64)hi) << 32) + (unsigned64)lo);
-  for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
-    {
-      h1 = (signed16)(v1 & 0xffff);
-      h2 = (signed16)(v2 & 0xffff);
-      result = (signed32)h1 * (signed32)h2;
-
-      if (i == 0)
-        prod -= (signed64) result;
-      else
-        prod += (signed64) result;
-    }
-  DSPLO(AC) = EXTEND32 (prod);
-  DSPHI(AC) = EXTEND32 (prod >> 32);
+  do_ph_w_mulsa (SD_, AC, RS, RT);
 }
 
 011111,5.RS,5.RT,5.RD,01101,010001:SPECIAL3:32::PRECR.QB.PH
 "precr.qb.ph r<RD>, r<RS>, r<RT>"
 *dsp2:
 {
-  unsigned32 v1 = GPR[RS];
-  unsigned32 v2 = GPR[RT];
-  unsigned32 tempu = (v1 & 0xff0000) >> 16;
-  unsigned32 tempv = (v1 & 0xff);
-  unsigned32 tempw = (v2 & 0xff0000) >> 16;
-  unsigned32 tempx = (v2 & 0xff);
-  GPR[RD] = EXTEND32 ((tempu << 24) | (tempv << 16) | (tempw << 8) | tempx);
+  do_ph_qb_precr (SD_, RD, RS, RT);
 }
 
 011111,5.RS,5.RT,5.SA,11110,010001:SPECIAL3:32::PRECR_SRA.PH.W
 "prepend r<RT>, r<RS>, <SA>"
 *dsp2:
 {
-  unsigned32 v0 = GPR[RS];
-  unsigned32 v1 = GPR[RT];
-  unsigned32 result;
-  if (SA == 0)
-    result = v1;
-  else
-    result = (v0 << (32 - SA)) | (v1 >> SA);
-  GPR[RT] = EXTEND32 (result);
+  do_prepend (SD_, RT, RS, SA);
 }
 
 011111,00,3.SHIFT3,5.RT,5.RD,00100,010011:SPECIAL3:32::SHRA.QB
 "shrav.qb r<RD>, r<RT>, r<RS>"
 *dsp2:
 {
-  unsigned32 shift = GPR[RS] & 0x7;
-  do_qb_shra (SD_, RD, RT, shift, 0);
+  do_qb_shrav (SD_, RD, RT, RS, 0);
 }
 
 011111,5.RS,5.RT,5.RD,00111,010011:SPECIAL3:32::SHRAV_R.QB
 "shrav_r.qb r<RD>, r<RT>, r<RS>"
 *dsp2:
 {
-  unsigned32 shift = GPR[RS] & 0x7;
-  do_qb_shra (SD_, RD, RT, shift, 1);
+  do_qb_shrav (SD_, RD, RT, RS, 1);
 }
 
 011111,0,4.SHIFT4,5.RT,5.RD,11001,010011:SPECIAL3:32::SHRL.PH
 "shrlv.ph r<RD>, r<RT>, r<RS>"
 *dsp2:
 {
-  unsigned32 shift = GPR[RS] & 0xf;
-  do_ph_shrl (SD_, RD, RT, shift);
+  do_ph_shrlv (SD_, RD, RT, RS);
 }
 
 011111,5.RS,5.RT,5.RD,01001,010000:SPECIAL3:32::SUBU.PH
index ed44cd97e604193202328e58723f83ef477999ea..9dc896434f89e8d6d9b63cb9f52c8eb3d983c76d 100644 (file)
@@ -71,7 +71,7 @@ char* pr_uword64 (uword64 addr);
    trap is required. NOTE: Care must be taken, since this value may be
    used in later revisions of the MIPS ISA. */
 
-#define RSVD_INSTRUCTION           (0x00000005)
+#define RSVD_INSTRUCTION           (0x00000039)
 #define RSVD_INSTRUCTION_MASK      (0xFC00003F)
 
 #define RSVD_INSTRUCTION_ARG_SHIFT 6
@@ -146,7 +146,6 @@ static SIM_ADDR lsipmon_monitor_base = 0xBFC00200;
 
 static SIM_RC sim_firmware_command (SIM_DESC sd, char* arg);
 
-
 #define MEM_SIZE (8 << 20)     /* 8 MBytes */
 
 
@@ -2186,18 +2185,17 @@ void
 decode_coproc (SIM_DESC sd,
               sim_cpu *cpu,
               address_word cia,
-              unsigned int instruction)
+              unsigned int instruction,
+              int coprocnum,
+              CP0_operation op,
+              int rt,
+              int rd,
+              int sel)
 {
-  int coprocnum = ((instruction >> 26) & 3);
-
   switch (coprocnum)
     {
     case 0: /* standard CPU control and cache registers */
       {
-        int code = ((instruction >> 21) & 0x1F);
-       int rt = ((instruction >> 16) & 0x1F);
-       int rd = ((instruction >> 11) & 0x1F);
-       int tail = instruction & 0x3ff;
         /* R4000 Users Manual (second edition) lists the following CP0
            instructions:
                                                                   CODE><-RT><RD-><--TAIL--->
@@ -2212,15 +2210,10 @@ decode_coproc (SIM_DESC sd,
           CACHE   Cache operation                 (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
           ERET    Exception return                (VR4100 = 01000010000000000000000000011000)
           */
-        if (((code == 0x00) || (code == 0x04)      /* MFC0  /  MTC0  */        
-            || (code == 0x01) || (code == 0x05))  /* DMFC0 / DMTC0  */        
-           && tail == 0)
+       if (((op == cp0_mfc0) || (op == cp0_mtc0)      /* MFC0  /  MTC0  */
+            || (op == cp0_dmfc0) || (op == cp0_dmtc0))  /* DMFC0 / DMTC0  */
+           && sel == 0)
          {
-           /* Clear double/single coprocessor move bit. */
-           code &= ~1;
-
-           /* M[TF]C0 (32 bits) | DM[TF]C0 (64 bits) */
-           
            switch (rd)  /* NOTEs: Standard CP0 registers */
              {
                /* 0 = Index               R4000   VR4100  VR4300 */
@@ -2248,7 +2241,7 @@ decode_coproc (SIM_DESC sd,
 
              case 8:
                /* 8 = BadVAddr            R4000   VR4100  VR4300 */
-               if (code == 0x00)
+               if (op == cp0_mfc0 || op == cp0_dmfc0)
                  GPR[rt] = (signed_word) (signed_address) COP0_BADVADDR;
                else
                  COP0_BADVADDR = GPR[rt];
@@ -2256,21 +2249,21 @@ decode_coproc (SIM_DESC sd,
 
 #endif /* SUBTARGET_R3900 */
              case 12:
-               if (code == 0x00)
+               if (op == cp0_mfc0 || op == cp0_dmfc0)
                  GPR[rt] = SR;
                else
                  SR = GPR[rt];
                break;
                /* 13 = Cause              R4000   VR4100  VR4300 */
              case 13:
-               if (code == 0x00)
+               if (op == cp0_mfc0 || op == cp0_dmfc0)
                  GPR[rt] = CAUSE;
                else
                  CAUSE = GPR[rt];
                break;
                /* 14 = EPC                R4000   VR4100  VR4300 */
              case 14:
-               if (code == 0x00)
+               if (op == cp0_mfc0 || op == cp0_dmfc0)
                  GPR[rt] = (signed_word) (signed_address) EPC;
                else
                  EPC = GPR[rt];
@@ -2279,7 +2272,7 @@ decode_coproc (SIM_DESC sd,
 #ifdef SUBTARGET_R3900
                 /* 16 = Debug */
               case 16:
-                if (code == 0x00)
+                if (op == cp0_mfc0 || op == cp0_dmfc0)
                   GPR[rt] = Debug;
                 else
                   Debug = GPR[rt];
@@ -2287,7 +2280,7 @@ decode_coproc (SIM_DESC sd,
 #else
                /* 16 = Config             R4000   VR4100  VR4300 */
               case 16:
-               if (code == 0x00)
+               if (op == cp0_mfc0 || op == cp0_dmfc0)
                  GPR[rt] = C0_CONFIG;
                else
                  /* only bottom three bits are writable */
@@ -2297,7 +2290,7 @@ decode_coproc (SIM_DESC sd,
 #ifdef SUBTARGET_R3900
                 /* 17 = Debug */
               case 17:
-                if (code == 0x00)
+                if (op == cp0_mfc0 || op == cp0_dmfc0)
                   GPR[rt] = DEPC;
                 else
                   DEPC = GPR[rt];
@@ -2320,7 +2313,7 @@ decode_coproc (SIM_DESC sd,
                GPR[rt] = 0xDEADC0DE; /* CPR[0,rd] */
                /* CPR[0,rd] = GPR[rt]; */
              default:
-               if (code == 0x00)
+               if (op == cp0_mfc0 || op == cp0_dmfc0)
                  GPR[rt] = (signed_word) (signed32) COP0_GPR[rd];
                else
                  COP0_GPR[rd] = GPR[rt];
@@ -2332,12 +2325,12 @@ decode_coproc (SIM_DESC sd,
 #endif
              }
          }
-       else if ((code == 0x00 || code == 0x01)
+       else if ((op == cp0_mfc0 || op == cp0_dmfc0)
                 && rd == 16)
          {
            /* [D]MFC0 RT,C0_CONFIG,SEL */
            signed32 cfg = 0;
-           switch (tail & 0x07) 
+           switch (sel)
              {
              case 0:
                cfg = C0_CONFIG;
@@ -2366,7 +2359,7 @@ decode_coproc (SIM_DESC sd,
              }
            GPR[rt] = cfg;
          }
-       else if (code == 0x10 && (tail & 0x3f) == 0x18)
+       else if (op == cp0_eret && sel == 0x18)
          {
            /* ERET */
            if (SR & status_ERL)
@@ -2382,7 +2375,7 @@ decode_coproc (SIM_DESC sd,
                SR &= ~status_EXL;
              }
          }
-        else if (code == 0x10 && (tail & 0x3f) == 0x10)
+        else if (op == cp0_rfe && sel == 0x10)
           {
             /* RFE */
 #ifdef SUBTARGET_R3900
@@ -2394,7 +2387,7 @@ decode_coproc (SIM_DESC sd,
            /* TODO: CACHE register */
 #endif /* SUBTARGET_R3900 */
           }
-        else if (code == 0x10 && (tail & 0x3f) == 0x1F)
+        else if (op == cp0_deret && sel == 0x1F)
           {
             /* DERET */
             Debug &= ~Debug_DM;
index f87a863629bfe0789ffb940c87dfbf290b772ac5..74adacdbf5f242ffd56183defcfae615237f0b88 100644 (file)
 
 011101,26.IMMED:JALX:32::JALX32
 "jalx <IMMED>"
+*mips32:
+*mips64:
+*mips32r2:
+*mips64r2:
 *mips16:
 *vr4100:
 {
 *mips16:
 *vr4100:
 {
-  if (STATE & simDELAYSLOT)
-    PC = cia - 2; /* reference the branch instruction */
-  else
-    PC = cia;
-  SignalException (BreakPoint, instruction_0);
+  do_break16 (SD_, instruction_0);
 }
diff --git a/sim/mips/micromips.dc b/sim/mips/micromips.dc
new file mode 100644 (file)
index 0000000..2593aba
--- /dev/null
@@ -0,0 +1,15 @@
+# most instructions
+# ------ options ------ : Fst : Lst : ff : fl : fe : word : fmt : model ...
+# { : mask : value : word }
+
+# Top level - create a very big switch statement.
+
+  padded-switch,combine :  31 :  26 :    :    :    :      :     :
+
+  switch,combine        :   5 :   0 :    :    :    :      :     :
+
+  switch,combine        :  10 :   0 :    :    :    :      :     :
+
+  switch,combine        :  25 :  16 :    :    :    :      :     :
+  switch,combine        :  25 :  21 :    :    :    :      :     :
+  switch,combine        :  15 :  11 :    :    :    :      :     :
diff --git a/sim/mips/micromips.igen b/sim/mips/micromips.igen
new file mode 100644 (file)
index 0000000..2c62376
--- /dev/null
@@ -0,0 +1,3091 @@
+// Simulator definition for the micromips ASE.
+// Copyright (C) 2005-2015 Free Software Foundation, Inc.
+// Contributed by Imagination Technologies, Ltd.
+// Written by Andrew Bennett <andrew.bennett@imgtec.com>
+//
+// This file is part of the MIPS sim.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+:compute:::int:TBASE:BASE:((BASE < 2) ? (16 + BASE) \: BASE)
+:compute:::int:TRD:RD:((RD < 2) ? (16 + RD) \: RD)
+:compute:::int:TRS:RS:((RS < 2) ? (16 + RS) \: RS)
+:compute:::int:TRT:RT:((RT < 2) ? (16 + RT) \: RT)
+:compute:::int:TRT_S:RT_S:((RT_S == 1 ) ? 17 \: RT_S)
+:compute:::int:ERT:RT:(compute_movep_src_reg (SD_, RT))
+:compute:::int:ERS:RS:(compute_movep_src_reg (SD_, RS))
+
+:compute:::int:IMM_DEC1:IMMEDIATE:((IMMEDIATE == 7) ? -1 \: ((IMMEDIATE == 0) ? 1 \: IMMEDIATE << 2))
+:compute:::int:IMM_DEC2:IMMEDIATE:((IMMEDIATE < 8) ? IMMEDIATE \: (IMMEDIATE - 16))
+:compute:::int:IMM_DEC3:IMMEDIATE:((IMMEDIATE < 2) ? IMMEDIATE + 256 \: ((IMMEDIATE < 256) ? IMMEDIATE \: ((IMMEDIATE < 510) ? IMMEDIATE - 512 \: IMMEDIATE - 768)))
+:compute:::int:IMM_DEC4:IMMEDIATE:(compute_andi16_imm (SD_, IMMEDIATE))
+:compute:::int:IMM_DEC5:IMMEDIATE:((IMMEDIATE < 15) ? IMMEDIATE \: -1)
+:compute:::int:IMM_DEC6:IMMEDIATE:((IMMEDIATE < 127) ? IMMEDIATE \: -1)
+
+:compute:::int:SHIFT_DEC:SHIFT:((SHIFT == 0) ? 8 \: SHIFT)
+
+:compute:::int:IMM_SHIFT_1BIT:IMMEDIATE:(IMMEDIATE << 1)
+:compute:::int:IMM_SHIFT_2BIT:IMMEDIATE:(IMMEDIATE << 2)
+
+:function:::address_word:delayslot_micromips:address_word target, address_word nia, int delayslot_instruction_size
+{
+  instruction_word delay_insn;
+  sim_events_slip (SD, 1);
+  DSPC = CIA;
+  CIA = nia;
+  STATE |= simDELAYSLOT;
+  ENGINE_ISSUE_PREFIX_HOOK();
+  micromips_instruction_decode (SD, CPU, CIA, delayslot_instruction_size);
+  STATE &= ~simDELAYSLOT;
+  return target;
+}
+
+:function:::address_word:process_isa_mode:address_word target
+{
+  SD->isa_mode = target & 0x1;
+  return (target & (-1 << 1));
+}
+
+:function:::address_word:do_micromips_jalr:int rt, int rs, address_word nia, int delayslot_instruction_size
+{
+  GPR[rt] = (nia + delayslot_instruction_size) | ISA_MODE_MICROMIPS;
+  return (process_isa_mode (SD_,
+       delayslot_micromips (SD_, GPR[rs], nia, delayslot_instruction_size)));
+}
+
+:function:::address_word:do_micromips_jal:address_word target, address_word nia, int delayslot_instruction_size
+{
+  RA = (nia + delayslot_instruction_size) | ISA_MODE_MICROMIPS;
+  return delayslot_micromips (SD_, target, nia, delayslot_instruction_size);
+}
+
+
+:function:::unsigned32:compute_movep_src_reg:int reg
+{
+  switch(reg)
+    {
+    case 0: return 0;
+    case 1: return 17;
+    case 2: return 2;
+    case 3: return 3;
+    case 4: return 16;
+    case 5: return 18;
+    case 6: return 19;
+    case 7: return 20;
+    default: return 0;
+    }
+}
+
+:function:::unsigned32:compute_andi16_imm:int encoded_imm
+{
+  switch (encoded_imm)
+    {
+    case 0: return 128;
+    case 1: return 1;
+    case 2: return 2;
+    case 3: return 3;
+    case 4: return 4;
+    case 5: return 7;
+    case 6: return 8;
+    case 7: return 15;
+    case 8: return 16;
+    case 9: return 31;
+    case 10: return 32;
+    case 11: return 63;
+    case 12: return 64;
+    case 13: return 255;
+    case 14: return 32768;
+    case 15: return 65535;
+    default: return 0;
+    }
+}
+
+:function:::FP_formats:convert_fmt_micromips:int fmt
+{
+  switch (fmt)
+    {
+    case 0: return fmt_single;
+    case 1: return fmt_double;
+    case 2: return fmt_ps;
+    default: return fmt_unknown;
+    }
+}
+
+:function:::FP_formats:convert_fmt_micromips_cvt_d:int fmt
+{
+  switch (fmt)
+    {
+    case 0: return fmt_single;
+    case 1: return fmt_word;
+    case 2: return fmt_long;
+    default: return fmt_unknown;
+    }
+}
+
+
+:function:::FP_formats:convert_fmt_micromips_cvt_s:int fmt
+{
+  switch (fmt)
+    {
+    case 0: return fmt_double;
+    case 1: return fmt_word;
+    case 2: return fmt_long;
+    default: return fmt_unknown;
+    }
+}
+
+
+011011,3.RD,6.IMMEDIATE,1:POOL16E:16::ADDIUR1SP
+"addiur1sp r<TRD>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  do_addiu (SD_, SPIDX, TRD, IMMEDIATE << 2);
+}
+
+
+011011,3.RD,3.RS,3.IMMEDIATE,0:POOL16E:16::ADDIUR2
+"addiur2 r<TRD>, r<TRS>, <IMM_DEC1>"
+*micromips32:
+*micromips64:
+{
+  do_addiu (SD_, TRS, TRD, IMM_DEC1);
+}
+
+
+010011,5.RD,4.IMMEDIATE,0:POOL16D:16::ADDIUS5
+"addius5 r<RD>, <IMM_DEC2>"
+*micromips32:
+*micromips64:
+{
+  do_addiu (SD_, RD, RD, IMM_DEC2);
+}
+
+
+010011,9.IMMEDIATE,1:POOL16D:16::ADDIUSP
+"addiusp <IMM_DEC3>"
+*micromips32:
+*micromips64:
+{
+  do_addiu (SD_, SPIDX, SPIDX, IMM_DEC3 << 2);
+}
+
+
+000001,3.RD,3.RT,3.RS,0:POOL16A:16::ADDU16
+"addu16 r<TRD>, r<TRS>, r<TRT>"
+*micromips32:
+*micromips64:
+{
+  do_addu (SD_, TRS, TRT, TRD);
+}
+
+
+001011,3.RD,3.RS,4.IMMEDIATE:MICROMIPS:16::ANDI16
+"andi16 r<TRD>, r<TRS>, <IMM_DEC4>"
+*micromips32:
+*micromips64:
+{
+  do_andi (SD_, TRS, TRD, IMM_DEC4);
+}
+
+
+010001,0010,3.RT,3.RS:POOL16C:16::AND16
+"and16 r<TRT>, r<TRS>"
+*micromips32:
+*micromips64:
+{
+  do_and (SD_, TRS, TRT, TRT);
+}
+
+
+110011,10.IMMEDIATE:MICROMIPS:16::B16
+"b16 <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  NIA = delayslot_micromips (SD_, NIA + (EXTEND11 (IMMEDIATE << 1)),
+                                 NIA, MICROMIPS_DELAYSLOT_SIZE_ANY);
+}
+
+
+100011,3.RS,7.IMMEDIATE:MICROMIPS:16::BEQZ16
+"beqz16 r<TRS>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  if (GPR[TRS] == 0)
+    NIA = delayslot_micromips (SD_, NIA + (EXTEND8 (IMMEDIATE << 1)),
+                                   NIA, MICROMIPS_DELAYSLOT_SIZE_ANY);
+}
+
+
+101011,3.RS,7.IMMEDIATE:MICROMIPS:16::BNEZ16
+"bnez16 r<TRS>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  if (GPR[TRS] != 0)
+    NIA = delayslot_micromips (SD_, NIA + (EXTEND8 (IMMEDIATE << 1)),
+                                   NIA, MICROMIPS_DELAYSLOT_SIZE_ANY);
+}
+
+
+010001,101000,4.CODE:POOL16C:16::BREAK16
+"break16 %#lx<CODE>"
+*micromips32:
+*micromips64:
+{
+  do_break16 (SD_, instruction_0);
+}
+
+
+010001,01110,5.RS:POOL16C:16::JALR16
+"jalr16 r<RS>"
+*micromips32:
+*micromips64:
+{
+  NIA = do_micromips_jalr (SD_, RAIDX, RS, NIA, MICROMIPS_DELAYSLOT_SIZE_32);
+}
+
+
+010001,01111,5.RS:POOL16C:16::JALRS16
+"jalrs16 r<RS>"
+*micromips32:
+*micromips64:
+{
+  NIA = do_micromips_jalr (SD_, RAIDX, RS, NIA, MICROMIPS_DELAYSLOT_SIZE_16);
+}
+
+
+010001,01100,5.RS:POOL16C:16::JR16
+"jr16 r<RS>"
+*micromips32:
+*micromips64:
+{
+  NIA = process_isa_mode (SD_,
+       delayslot_micromips (SD_, GPR[RS], NIA, MICROMIPS_DELAYSLOT_SIZE_ANY));
+}
+
+
+010001,11000,5.IMMEDIATE:POOL16C:16::JRADDIUSP
+"jraddiusp <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  address_word temp = RA;
+  do_addiu (SD_, SPIDX, SPIDX, IMMEDIATE << 2);
+  NIA = process_isa_mode (SD_, temp);
+}
+
+
+010001,01101,5.RS:POOL16C:16::JRC
+"jrc r<RS>"
+*micromips32:
+*micromips64:
+{
+  NIA = process_isa_mode (SD_, GPR[RS]);
+}
+
+
+000010,3.RT,3.BASE,4.IMMEDIATE:MICROMIPS:16::LBU16
+"lbu16 r<TRT>, <IMM_DEC5>(r<TBASE>)"
+*micromips32:
+*micromips64:
+{
+  /* LBU can have a negative offset.  As the offset argument to do_load is
+     unsigned we need to do the address calcuation before the function call so
+     that the load address has been correctly calculated */
+
+  GPR[TRT] = do_load (SD_, AccessLength_BYTE, GPR[TBASE] + IMM_DEC5, 0);
+}
+
+
+001010,3.RT,3.BASE,4.IMMEDIATE:MICROMIPS:16::LHU16
+"lhu16 r<TRT>, <IMM_SHIFT_1BIT>(r<TBASE>)"
+*micromips32:
+*micromips64:
+{
+  GPR[TRT] = do_load (SD_, AccessLength_HALFWORD, GPR[TBASE], IMM_SHIFT_1BIT);
+}
+
+
+111011,3.RD,7.IMMEDIATE:MICROMIPS:16::LI16
+"li16 r<TRD>, <IMM_DEC6>"
+*micromips32:
+*micromips64:
+{
+  GPR[TRD] = IMM_DEC6;
+}
+
+
+011010,3.RT,3.BASE,4.IMMEDIATE:MICROMIPS:16::LW16
+"lw16 r<TRT>, <IMM_SHIFT_2BIT>(r<TBASE>)"
+*micromips32:
+*micromips64:
+{
+  GPR[TRT] = EXTEND32 (
+       do_load (SD_, AccessLength_WORD, GPR[TBASE], IMM_SHIFT_2BIT));
+}
+
+:%s::::LWMREGS:int lwmregs
+*micromips32:
+*micromips64:
+{
+  if (lwmregs == 3)
+    return "s0, s1, s2, s3, ra";
+  else if (lwmregs == 2)
+    return "s0, s1, s2, ra";
+  else if (lwmregs == 1)
+    return "s0, s1, ra";
+  else if (lwmregs == 0)
+    return "s0, ra";
+  else
+    return "";
+}
+
+010001,0100,2.LWMREGS,4.IMMEDIATE:POOL16C:16::LWM16
+"lwm16 %s<LWMREGS>, <IMM_SHIFT_2BIT>(sp)"
+*micromips32:
+*micromips64:
+{
+  int address = GPR[SPIDX] + IMM_SHIFT_2BIT;
+  int reg_offset;
+
+  for (reg_offset = 0; reg_offset <= LWMREGS; reg_offset++)
+    GPR[16 + reg_offset] = EXTEND32 (
+       do_load (SD_, AccessLength_WORD, address, reg_offset * 4));
+
+  RA = EXTEND32 (do_load (SD_, AccessLength_WORD, address, reg_offset * 4));
+}
+
+
+011001,3.RT,7.IMMEDIATE:MICROMIPS:16::LWGP
+"lwgp r<TRT>, <IMM_SHIFT_2BIT>(gp)"
+*micromips32:
+*micromips64:
+{
+  GPR[TRT] = EXTEND32 (
+       do_load (SD_, AccessLength_WORD, GPR[28], IMM_SHIFT_2BIT));
+}
+
+
+010010,5.RT,5.IMMEDIATE:MICROMIPS:16::LWSP
+"lwsp r<RT>, <IMM_SHIFT_2BIT>(sp)"
+*micromips32:
+*micromips64:
+{
+  GPR[RT] = EXTEND32 (do_load (SD_, AccessLength_WORD, SP, IMM_SHIFT_2BIT));
+}
+
+
+010001,10000,5.RD:POOL16C:16::MFHI16
+"mfhi16 r<RD>"
+*micromips32:
+*micromips64:
+{
+  do_mfhi (SD_, RD);
+}
+
+
+010001,10010,5.RD:POOL16C:16::MFLO16
+"mflo16 r<RD>"
+*micromips32:
+*micromips64:
+{
+  do_mflo (SD_, RD);
+}
+
+
+000011,5.RD,5.RS:MICROMIPS:16::MOVE16
+"nop":RD==0&&RS==0
+"move16 r<RD>, r<RS>"
+*micromips32:
+*micromips64:
+{
+  GPR[RD] = GPR[RS];
+}
+
+
+:%s::::DESTREGS:int regs
+*micromips32:
+*micromips64:
+{
+  switch (regs)
+    {
+    case 0: return "a1, a2,";
+    case 1: return "a1, a3,";
+    case 2: return "a2, a3,";
+    case 3: return "a0, s5,";
+    case 4: return "a0, s6,";
+    case 5: return "a0, a1,";
+    case 6: return "a0, a2,";
+    case 7: return "a0, a3,";
+    default: return "";
+    }
+}
+
+100001,3.DESTREGS,3.RT,3.RS,0:MICROMIPS:16::MOVEP
+"movep %s<DESTREGS> r<ERS>, r<ERT>"
+*micromips32:
+*micromips64:
+{
+  int rd;
+  int re;
+  int dest = DESTREGS;
+
+  if (dest == 0 || dest == 1)
+    rd = 5;
+  else if (dest == 2)
+    rd = 6;
+  else
+    rd = 4;
+
+  if (dest == 0 || dest == 6)
+    re = 6;
+  else if (dest == 1 || dest == 2 || dest == 7)
+    re = 7;
+  else if (dest == 3)
+    re = 21;
+  else if (dest == 4)
+    re = 22;
+  /* assume dest is 5 */
+  else
+    re = 5;
+
+  GPR[rd] = GPR[ERS];
+  GPR[re] = GPR[ERT];
+}
+
+
+010001,0000,3.RT,3.RS:POOL16C:16::NOT16
+"not16 r<TRT>, r<TRS>"
+*micromips32:
+*micromips64:
+{
+  do_nor (SD_, 0, TRS, TRT);
+}
+
+
+010001,0011,3.RT,3.RS:POOL16C:16::OR16
+"or16 r<TRT>, r<TRS>"
+*micromips32:
+*micromips64:
+{
+  do_or (SD_, TRS, TRT, TRT);
+}
+
+
+100010,3.RT_S,3.BASE,4.IMMEDIATE:MICROMIPS:16::SB16
+"sb16 r<TRT_S>, <IMMEDIATE>(r<TBASE>)"
+*micromips32:
+*micromips64:
+{
+  do_store (SD_, AccessLength_BYTE, GPR[TBASE], IMMEDIATE, GPR[TRT_S]);
+}
+
+
+010001,101100,4.CODE:POOL16C:16::SDBBP16
+"sdbbp16 %#lx<CODE>"
+*micromips32:
+*micromips64:
+{
+  SignalException (DebugBreakPoint, instruction_0);
+}
+
+
+101010,3.RT_S,3.BASE,4.IMMEDIATE:MICROMIPS:16::SH16
+"sh16 r<TRT_S>, <IMM_SHIFT_1BIT>(r<TBASE>)"
+*micromips32:
+*micromips64:
+{
+  do_store (SD_, AccessLength_HALFWORD, GPR[TBASE], IMM_SHIFT_1BIT, GPR[TRT_S]);
+}
+
+
+001001,3.RD,3.RT,3.SHIFT,0:POOL16B:16::SLL16
+"sll16 r<TRD>, r<TRT>, <SHIFT_DEC>"
+*micromips32:
+*micromips64:
+{
+  do_sll (SD_, TRT, TRD, SHIFT_DEC);
+}
+
+
+001001,3.RD,3.RT,3.SHIFT,1:POOL16B:16::SRL16
+"srl16 r<TRD>, r<TRT>, <SHIFT_DEC>"
+*micromips32:
+*micromips64:
+{
+  do_srl (SD_, TRT, TRD, SHIFT_DEC);
+}
+
+
+000001,3.RD,3.RT,3.RS,1:POOL16A:16::SUBU16
+"subu16 r<TRD>, r<TRS>, r<TRT>"
+*micromips32:
+*micromips64:
+{
+  do_subu (SD_, TRS, TRT, TRD);
+}
+
+
+111010,3.RT_S,3.BASE,4.IMMEDIATE:MICROMIPS:16::SW16
+"sw16 r<TRT_S>, <IMM_SHIFT_2BIT>(r<TBASE>)"
+*micromips32:
+*micromips64:
+{
+  do_store (SD_, AccessLength_WORD, GPR[TBASE], IMM_SHIFT_2BIT, GPR[TRT_S]);
+}
+
+
+110010,5.RT,5.IMMEDIATE:MICROMIPS:16::SWSP
+"swsp r<RT>, <IMM_SHIFT_2BIT>(sp)"
+*micromips32:
+*micromips64:
+{
+  do_store (SD_, AccessLength_WORD, SP, IMM_SHIFT_2BIT, GPR[RT]);
+}
+
+
+010001,0101,2.LWMREGS,4.IMMEDIATE:POOL16C:16::SWM16
+"swm16 %s<LWMREGS>, <IMM_SHIFT_2BIT>(sp)"
+*micromips32:
+*micromips64:
+{
+  int address = GPR[SPIDX] + IMM_SHIFT_2BIT;
+  int reg_offset;
+
+  for (reg_offset = 0; reg_offset <= LWMREGS; reg_offset++)
+    do_store (SD_, AccessLength_WORD, address, reg_offset * 4,
+       GPR[16 + reg_offset]);
+
+  do_store (SD_, AccessLength_WORD, address, reg_offset * 4, RA);
+}
+
+
+010001,0001,3.RT,3.RS:POOL16C:16::XOR16
+"xor16 r<TRT>, r<TRS>"
+*micromips32:
+*micromips64:
+{
+  do_xor (SD_, TRS, TRT, TRT);
+}
+
+
+000000,5.RT,5.RS,5.RD,00100,010000:POOL32A:32::ADD
+"add r<RD>, r<RS>, r<RT>"
+*micromips32:
+*micromips64:
+{
+  do_add (SD_, RS, RT, RD);
+}
+
+
+000100,5.RT,5.RS,16.IMMEDIATE:MICROMIPS:32::ADDI
+"addi r<RT>, r<RS>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  do_addi (SD_, RS, RT, IMMEDIATE);
+}
+
+
+001100,5.RT,5.RS,16.IMMEDIATE:MICROMIPS:32::ADDIU
+"li r<RT>, <IMMEDIATE>":RS==0
+"addiu r<RT>, r<RS>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  do_addiu (SD_, RS, RT, IMMEDIATE);
+}
+
+
+011110,3.RS,23.IMMEDIATE:MICROMIPS:32::ADDIUPC
+"addiupc r<TRS>, <IMM_SHIFT_2BIT>"
+*micromips32:
+*micromips64:
+{
+  GPR[TRS] = EXTEND32 ((CIA & ~3) + EXTEND25 (IMM_SHIFT_2BIT));
+}
+
+
+000000,5.RT,5.RS,5.RD,00101,010000:POOL32A:32::ADDU
+"addu r<RD>, r<RS>, r<RT>"
+*micromips32:
+*micromips64:
+{
+  do_addu (SD_, RS, RT, RD);
+}
+
+
+000000,5.RT,5.RS,5.RD,01001,010000:POOL32A:32::AND
+"and r<RD>, r<RS>, r<RT>"
+*micromips32:
+*micromips64:
+{
+  do_and (SD_, RS, RT, RD);
+}
+
+
+110100,5.RT,5.RS,16.IMMEDIATE:MICROMIPS:32::ANDI
+"andi r<RT>, r<RS>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  do_andi (SD_, RS, RT, IMMEDIATE);
+}
+
+
+010000,1110,1.TF,3.CC,00,16.IMMEDIATE:POOL32I:32,f::BC1a
+"bc1%s<TF> <IMMEDIATE>":CC == 0
+"bc1%s<TF> <CC>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  check_fpu (SD_);
+  if (GETFCC(CC) == TF)
+    {
+      address_word dest = NIA + (EXTEND16 (IMMEDIATE) << 1);
+      NIA = delayslot_micromips (SD_, dest, NIA, MICROMIPS_DELAYSLOT_SIZE_ANY);
+    }
+}
+
+
+010000,1010,1.TF,3.CC,00,16.IMMEDIATE:POOL32I:32::BC2a
+"bc2%s<TF> <CC>, <IMMEDIATE>":CC == 0
+"bc2%s<TF> <CC>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+
+
+100101,5.RT,5.RS,16.IMMEDIATE:MICROMIPS:32::BEQ
+"b <IMMEDIATE>":RT == 0 && RS == 0
+"beq r<RS>, r<RT>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  address_word offset = EXTEND16 (IMMEDIATE) << 1;
+  if ((signed_word) GPR[RS] == (signed_word) GPR[RT])
+    NIA = delayslot_micromips (SD_, NIA + offset, NIA,
+                              MICROMIPS_DELAYSLOT_SIZE_ANY);
+}
+
+010000,00010,5.RS,16.IMMEDIATE:POOL32I:32::BGEZ
+"bgez r<RS>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  address_word offset = EXTEND16 (IMMEDIATE) << 1;
+  if ((signed_word) GPR[RS] >= 0)
+    NIA = delayslot_micromips (SD_, NIA + offset, NIA,
+                              MICROMIPS_DELAYSLOT_SIZE_ANY);
+}
+
+
+010000,00111,5.RS,16.IMMEDIATE:POOL32I:32::BEQZC
+"beqzc r<RS>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  address_word offset = EXTEND16 (IMMEDIATE) << 1;
+  if (GPR[RS] == 0)
+    NIA = NIA + offset;
+}
+
+
+010000,00011,5.RS,16.IMMEDIATE:POOL32I:32::BGEZAL
+"bal <IMMEDIATE>":RS == 0
+"bgezal r<RS>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  address_word offset = EXTEND16 (IMMEDIATE) << 1;
+  if (RS == 31)
+    Unpredictable ();
+  RA = (NIA + MICROMIPS_DELAYSLOT_SIZE_32) | ISA_MODE_MICROMIPS;
+  if ((signed_word) GPR[RS] >= 0)
+    NIA = delayslot_micromips (SD_, NIA + offset, NIA,
+                              MICROMIPS_DELAYSLOT_SIZE_32);
+}
+
+
+010000,00110,5.RS,16.IMMEDIATE:POOL32I:32::BGTZ
+"bgtz r<RS>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  address_word offset = EXTEND16 (IMMEDIATE) << 1;
+  if ((signed_word) GPR[RS] > 0)
+    NIA = delayslot_micromips (SD_, NIA + offset, NIA,
+                              MICROMIPS_DELAYSLOT_SIZE_ANY);
+}
+
+
+010000,10011,5.RS,16.IMMEDIATE:POOL32I:32::BGEZALS
+"bal <IMMEDIATE>":RS == 0
+"bgezals r<RS>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  address_word offset = EXTEND16 (IMMEDIATE) << 1;
+  if (RS == 31)
+    Unpredictable ();
+  RA = (NIA + MICROMIPS_DELAYSLOT_SIZE_16) | ISA_MODE_MICROMIPS;
+  if ((signed_word) GPR[RS] >= 0)
+    NIA = delayslot_micromips (SD_, NIA + offset, NIA,
+                              MICROMIPS_DELAYSLOT_SIZE_16);
+}
+
+
+010000,00100,5.RS,16.IMMEDIATE:POOL32I:32::BLEZ
+"blez r<RS>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  address_word offset = EXTEND16 (IMMEDIATE) << 1;
+  /* NOTE: The branch occurs AFTER the next instruction has been
+     executed */
+  if ((signed_word) GPR[RS] <= 0)
+    NIA = delayslot_micromips (SD_, NIA + offset, NIA,
+                              MICROMIPS_DELAYSLOT_SIZE_ANY);
+}
+
+
+010000,00000,5.RS,16.IMMEDIATE:POOL32I:32::BLTZ
+"bltz r<RS>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  address_word offset = EXTEND16 (IMMEDIATE) << 1;
+  if ((signed_word) GPR[RS] < 0)
+    NIA = delayslot_micromips (SD_, NIA + offset, NIA,
+                              MICROMIPS_DELAYSLOT_SIZE_ANY);
+}
+
+
+010000,00001,5.RS,16.IMMEDIATE:POOL32I:32::BLTZAL
+"bltzal r<RS>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  address_word offset = EXTEND16 (IMMEDIATE) << 1;
+  if (RS == 31)
+    Unpredictable ();
+  RA = (NIA + MICROMIPS_DELAYSLOT_SIZE_32) | ISA_MODE_MICROMIPS;
+  /* NOTE: The branch occurs AFTER the next instruction has been
+     executed */
+  if ((signed_word) GPR[RS] < 0)
+    NIA = delayslot_micromips (SD_, NIA + offset, NIA,
+                              MICROMIPS_DELAYSLOT_SIZE_32);
+}
+
+010000,10001,5.RS,16.IMMEDIATE:POOL32I:32::BLTZALS
+"bltzals r<RS>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  address_word offset = EXTEND16 (IMMEDIATE) << 1;
+  if (RS == 31)
+    Unpredictable ();
+  RA = (NIA + MICROMIPS_DELAYSLOT_SIZE_16) | ISA_MODE_MICROMIPS;
+  if ((signed_word) GPR[RS] < 0)
+    NIA = delayslot_micromips (SD_, NIA + offset, NIA,
+                              MICROMIPS_DELAYSLOT_SIZE_16);
+}
+
+
+101101,5.RT,5.RS,16.IMMEDIATE:MICROMIPS:32::BNE
+"bne r<RS>, r<RT>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  address_word offset = EXTEND16 (IMMEDIATE) << 1;
+  if ((signed_word) GPR[RS] != (signed_word) GPR[RT])
+    NIA = delayslot_micromips (SD_, NIA + offset, NIA,
+                              MICROMIPS_DELAYSLOT_SIZE_ANY);
+}
+
+
+010000,00101,5.RS,16.IMMEDIATE:POOL32I:32::BNEZC
+"bnezc r<RS>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  address_word offset = EXTEND16 (IMMEDIATE) << 1;
+  if ((signed_word) GPR[RS] != 0)
+    NIA = NIA + offset;
+}
+
+
+000000,20.CODE,000111:POOL32A:32::BREAK
+"break %#lx<CODE>"
+*micromips32:
+*micromips64:
+{
+  do_break (SD_, instruction_0);
+}
+
+
+001000,5.OP,5.BASE,0110,12.IMMEDIATE:POOL32B:32::CACHE
+"cache <OP>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+{
+  address_word base = GPR[BASE];
+  address_word offset = EXTEND12 (IMMEDIATE);
+  address_word vaddr = loadstore_ea (SD_, base, offset);
+  address_word paddr;
+  int uncached;
+  if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached,
+                         isTARGET, isREAL))
+    CacheOp (OP, vaddr, paddr, instruction_0);
+}
+
+
+011000,5.OP,5.BASE,1010011,9.IMMEDIATE:POOL32C:32::CACHEE
+"cachee <OP>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+
+
+010101,5.RT,5.FS,0001000000,111011:POOL32F:32,f::CFC1
+"cfc1 r<RT>, f<FS>"
+*micromips32:
+*micromips64:
+{
+  do_cfc1 (SD_, RT, FS);
+}
+
+
+000000,5.RT,5.IMPL,1100110100,111100:POOL32A:32::CFC2
+"cfc2 r<RT>, <IMPL>"
+*micromips32:
+*micromips64:
+
+
+000000,5.RT,5.RS,0100101100,111100:POOL32A:32::CLO
+"clo r<RT>, r<RS>"
+*micromips32:
+*micromips64:
+{
+  do_clo (SD_, RT, RS);
+}
+
+
+000000,5.RT,5.RS,0101101100,111100:POOL32A:32::CLZ
+"clz r<RT>, r<RS>"
+*micromips32:
+*micromips64:
+{
+  do_clz (SD_, RT, RS);
+}
+
+
+000000,23.COFUN,010:POOL32A:32::COP2
+"cop2 <COFUN>"
+*micromips32:
+*micromips64:
+
+
+010101,5.RT,5.FS,0001100000,111011:POOL32F:32,f::CTC1
+"ctc1 r<RT>, f<FS>"
+*micromips32:
+*micromips64:
+{
+  do_ctc1 (SD_, RT, FS);
+}
+
+
+000000,5.RT,5.IMPL,1101110100,111100:POOL32A:32::CTC2
+"ctc2 r<RT>, <IMPL>"
+*micromips32:
+*micromips64:
+
+
+000000,00000000001110001101,111100:POOL32A:32::DERET
+"deret"
+*micromips32:
+*micromips64:
+
+
+000000,00000,5.RS,0100011101,111100:POOL32A:32::DI
+"di":RS == 0
+"di r<RS>"
+*micromips32:
+*micromips64:
+{
+  do_di (SD_, RS);
+}
+
+000000,5.RT,5.RS,1010101100,111100:POOL32A:32::DIV
+"div r<RS>, r<RT>"
+*micromips32:
+*micromips64:
+{
+  do_div (SD_, RS, RT);
+}
+
+
+000000,5.RT,5.RS,1011101100,111100:POOL32A:32::DIVU
+"divu r<RS>, r<RT>"
+*micromips32:
+*micromips64:
+{
+  do_divu (SD_, RS, RT);
+}
+
+
+000000,00000000000001100000,000000:POOL32A:32::EHB
+"ehb"
+*micromips32:
+*micromips64:
+
+
+000000,00000,5.RS,0101011101,111100:POOL32A:32::EI
+"ei":RS == 0
+"ei r<RS>"
+*micromips32:
+*micromips64:
+{
+  do_ei (SD_, RS);
+}
+
+000000,00000000001111001101,111100:POOL32A:32::ERET
+"eret"
+*micromips32:
+*micromips64:
+{
+  if (SR & status_ERL)
+    {
+      /* Oops, not yet available */
+      sim_io_printf (SD, "Warning: ERET when SR[ERL] set not supported");
+      NIA = EPC;
+      SR &= ~status_ERL;
+    }
+  else
+    {
+      NIA = EPC;
+      SR &= ~status_EXL;
+    }
+}
+
+
+000000,5.RT,5.RS,5.MSBD,5.LSB,101100:POOL32A:32::EXT
+"ext r<RT>, r<RS>, <LSB>, <MSBD+1>"
+*micromips32:
+*micromips64:
+{
+  do_ext (SD_, RT, RS, LSB, MSBD);
+}
+
+
+000000,5.RT,5.RS,5.MSBD,5.LSB,001100:POOL32A:32::INS
+"ins r<RT>, r<RS>, <LSB>, <MSBD-LSB+1>"
+*micromips32:
+*micromips64:
+{
+  do_ins (SD_, RT, RS, LSB, MSBD);
+}
+
+
+110101,26.IMMEDIATE:MICROMIPS:32::J
+"j <IMM_SHIFT_1BIT>"
+*micromips32:
+*micromips64:
+{
+  address_word region = (NIA & MASK (63, 27));
+  NIA = delayslot_micromips (SD_, region | (IMM_SHIFT_1BIT), NIA,
+                            MICROMIPS_DELAYSLOT_SIZE_ANY);
+}
+
+
+111101,26.IMMEDIATE:MICROMIPS:32::JAL
+"jal <IMM_SHIFT_1BIT>"
+*micromips32:
+*micromips64:
+{
+  /* NOTE: The region used is that of the delay slot and NOT the
+     current instruction */
+  address_word region = (NIA & MASK (63, 27));
+  NIA = do_micromips_jal (SD_, (region | (IMM_SHIFT_1BIT)), NIA,
+                         MICROMIPS_DELAYSLOT_SIZE_32);
+}
+
+
+011101,26.IMMEDIATE:MICROMIPS:32::JALS
+"jals <IMM_SHIFT_1BIT>"
+*micromips32:
+*micromips64:
+{
+  address_word region = (NIA & MASK (63, 27));
+  NIA = do_micromips_jal (SD_, (region | (IMM_SHIFT_1BIT)), NIA,
+                         MICROMIPS_DELAYSLOT_SIZE_16);
+}
+
+000000,5.RT!0,5.RS,0000111100,111100:POOL32A:32::JALR
+"jalr r<RS>":RT == 31
+"jalr r<RT>, r<RS>"
+*micromips32:
+*micromips64:
+{
+  if (RS == RT)
+    Unpredictable ();
+  NIA = do_micromips_jalr (SD_, RT, RS, NIA, MICROMIPS_DELAYSLOT_SIZE_32);
+}
+
+000000,5.RT,5.RS,0100111100,111100:POOL32A:32::JALRS
+"jalrs r<RT>, r<RS>"
+*micromips32:
+*micromips64:
+{
+  if (RS == RT)
+    Unpredictable ();
+  NIA = do_micromips_jalr (SD_, RT, RS, NIA, MICROMIPS_DELAYSLOT_SIZE_16);
+}
+
+
+111100,26.IMMEDIATE:MICROMIPS:32::JALX
+"jalx <IMM_SHIFT_2BIT>"
+*micromips32:
+*micromips64:
+{
+  address_word region = (NIA & MASK (63, 26));
+  NIA = do_micromips_jal (SD_, (region | (IMM_SHIFT_2BIT)) | ISA_MODE_MIPS32,
+                         NIA, MICROMIPS_DELAYSLOT_SIZE_32);
+  SD->isa_mode = ISA_MODE_MIPS32;
+}
+
+000000,00000,5.RS,0000111100,111100:POOL32A:32::JR
+"jr r<RS>"
+*micromips32:
+*micromips64:
+{
+  NIA = process_isa_mode (SD_,
+                         delayslot_micromips (SD_, GPR[RS], NIA,
+                                              MICROMIPS_DELAYSLOT_SIZE_32));
+}
+
+
+000000,5.RT,5.RS,0001111100,111100:POOL32A:32::JALR.HB
+"jalr.hb r<RT>, r<RS>"
+*micromips32:
+*micromips64:
+{
+  if (RS == RT)
+    Unpredictable ();
+  NIA = do_micromips_jalr (SD_, RT, RS, NIA, MICROMIPS_DELAYSLOT_SIZE_32);
+}
+
+
+000000,5.RT,5.RS,0101111100,111100:POOL32A:32::JALRS.HB
+"jalrs.hb r<RT>, r<RS>"
+*micromips32:
+*micromips64:
+{
+  if (RS == RT)
+    Unpredictable ();
+  NIA = do_micromips_jalr (SD_, RT, RS, NIA, MICROMIPS_DELAYSLOT_SIZE_16);
+}
+
+
+000000,00000,5.RS,0111111100,111100:POOL32A:32::JR.HB
+"jr.hb r<RS>"
+*micromips32:
+*micromips64:
+{
+  NIA = process_isa_mode (SD_,
+                         delayslot_micromips (SD_, GPR[RS], NIA,
+                                              MICROMIPS_DELAYSLOT_SIZE_32));
+}
+
+
+000111,5.RT,5.BASE,16.IMMEDIATE:MICROMIPS:32::LB
+"lb r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+{
+  do_lb (SD_, RT, IMMEDIATE, BASE);
+}
+
+
+011000,5.RT,5.BASE,0110100,9.IMMEDIATE:POOL32C:32::LBE
+"lbe r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+
+
+000101,5.RT,5.BASE,16.IMMEDIATE:MICROMIPS:32::LBU
+"lbu r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+{
+  do_lbu (SD_, RT, IMMEDIATE, BASE);
+}
+
+
+011000,5.RT,5.BASE,0110000,9.IMMEDIATE:POOL32C:32::LBUE
+"lbue r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+
+
+101111,5.FT,5.BASE,16.IMMEDIATE:MICROMIPS:32,f::LDC1a
+"ldc1 f<FT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+{
+  check_fpu (SD_);
+  COP_LD (1, FT, do_load_double (SD_, GPR[BASE], EXTEND16 (IMMEDIATE)));
+}
+
+
+101111,5.FT,5.BASE,16.IMMEDIATE:MICROMIPS:32,f::LDC1b
+"ldc1 f<FT>, <IMMEDIATE>(r<BASE>)"
+*micromips64:
+{
+  check_fpu (SD_);
+  COP_LD (1, FT, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE],
+                         EXTEND16 (IMMEDIATE)));
+}
+
+
+001000,5.RT,5.BASE,0010,12.IMMEDIATE:POOL32B:32::LDC2
+"ldc2 r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+
+
+001111,5.RT,5.BASE,16.IMMEDIATE:MICROMIPS:32::LH
+"lh r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+{
+  do_lh (SD_, RT, IMMEDIATE, BASE);
+}
+
+
+011000,5.RT,5.BASE,0110101,9.IMMEDIATE:POOL32C:32::LHE
+"lhe r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+
+
+001101,5.RT,5.BASE,16.IMMEDIATE:MICROMIPS:32::LHU
+"lhu r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+{
+  do_lhu (SD_, RT, IMMEDIATE, BASE);
+}
+
+
+011000,5.RT,5.BASE,0110001,9.IMMEDIATE:POOL32C:32::LHUE
+"lhue r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+
+
+011000,5.RT,5.BASE,0011,12.IMMEDIATE:POOL32C:32::LL
+"ll r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+{
+  do_ll (SD_, RT, EXTEND12 (IMMEDIATE), BASE);
+}
+
+
+011000,5.RT,5.BASE,0110110,9.IMMEDIATE:POOL32C:32::LLE
+"lle r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+
+
+010000,01101,5.RS,16.IMMEDIATE:POOL32I:32::LUI
+"lui r<RS>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  do_lui (SD_, RS, IMMEDIATE);
+}
+
+
+010101,5.INDEX,5.BASE,5.FD,00101,001000:POOL32F:32,f::LUXC1
+"luxc1 f<FD>, r<INDEX>(r<BASE>)"
+*micromips32:
+{
+  do_luxc1_32 (SD_, FD, INDEX, BASE);
+}
+
+
+010101,5.INDEX,5.BASE,5.FD,00101,001000:POOL32F:64,f::LUXC1
+"luxc1 f<FD>, r<INDEX>(r<BASE>)"
+*micromips64:
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  do_luxc1_64 (SD_, FD, INDEX, BASE);
+}
+
+
+111111,5.RT,5.BASE,16.IMMEDIATE:MICROMIPS:32::LW
+"lw r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+{
+  do_lw (SD_, RT, IMMEDIATE, BASE);
+}
+
+
+100111,5.FT,5.BASE,16.IMMEDIATE:MICROMIPS:32,f::LWC1
+"lwc1 f<FT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+{
+  do_lwc1 (SD_, FT, IMMEDIATE, BASE);
+}
+
+
+001000,5.RT,5.BASE,0000,12.IMMEDIATE:POOL32B:32::LWC2
+"lwc2 r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+
+
+011000,5.RT,5.BASE,0110111,9.IMMEDIATE:POOL32C:32::LWE
+"lwe r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+
+
+011000,5.RT,5.BASE,0110011,9.IMMEDIATE:POOL32C:32::LWEE
+"lwee r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+
+
+011000,5.RT,5.BASE,0000,12.IMMEDIATE:POOL32C:32::LWL
+"lwl r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+{
+  do_lwl (SD_, RT, EXTEND12 (IMMEDIATE), BASE);
+}
+
+
+011000,5.RT,5.BASE,0110010,9.IMMEDIATE:POOL32C:32::LWLE
+"lwle r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+
+:%s::::LWM32REGS:int lwmregs
+*micromips32:
+*micromips64:
+{
+  if (lwmregs & 0x10)
+    {
+      switch(lwmregs & 0xf)
+        {
+        case 0:
+          return "ra";
+        case 1:
+          return "s0, ra";
+        case 2:
+          return "s0, s1, ra";
+        case 3:
+          return "s0, s1, s2, ra";
+        case 4:
+          return "s0, s1, s2, s3, ra";
+        case 5:
+          return "s0, s1, s2, s3, s4, ra";
+        case 6:
+          return "s0, s1, s2, s3, s4, s5, ra";
+        case 7:
+          return "s0, s1, s2, s3, s4, s5, s6, ra";
+        case 8:
+          return "s0, s1, s2, s3, s4, s5, s6, s7, ra";
+        case 9:
+          return "s0, s1, s2, s3, s4, s5, s6, s7, s8, ra";
+        default:
+          return "";
+        }
+    }
+  else
+    {
+      switch(lwmregs & 0xf)
+        {
+        case 1:
+          return "s0";
+        case 2:
+          return "s0, s1";
+        case 3:
+          return "s0, s1, s2";
+        case 4:
+          return "s0, s1, s2, s3";
+        case 5:
+          return "s0, s1, s2, s3, s4";
+        case 6:
+          return "s0, s1, s2, s3, s4, s5";
+        case 7:
+          return "s0, s1, s2, s3, s4, s5, s6";
+        case 8:
+          return "s0, s1, s2, s3, s4, s5, s6, s7";
+        case 9:
+          return "s0, s1, s2, s3, s4, s5, s6, s7, s8";
+        default:
+          return "";
+        }
+    }
+}
+
+001000,5.LWM32REGS,5.BASE,0101,12.IMMEDIATE:POOL32B:32::LWM32
+"lwm32 %s<LWM32REGS>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+{
+  int address_base = GPR[BASE] + EXTEND12 (IMMEDIATE);
+  int reg_offset;
+  for (reg_offset = 0; reg_offset < (LWM32REGS & 0xf); reg_offset++)
+    {
+      int dst = (reg_offset == 8) ? 30 : 16 + reg_offset;
+      GPR[dst] = EXTEND32 (do_load (SD_, AccessLength_WORD, address_base,
+                                   4 * reg_offset));
+    }
+
+  if (LWM32REGS & 0x10)
+    RA = EXTEND32 (do_load (SD_, AccessLength_WORD, address_base,
+                           4 * reg_offset));
+}
+
+
+001000,5.RD,5.BASE,0001,12.IMMEDIATE:POOL32B:32::LWP
+"lwp r<RD>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+{
+  if (BASE == RD || RD == 31)
+    Unpredictable ();
+  else
+    {
+      do_lw (SD_, RD, EXTEND12 (IMMEDIATE), BASE);
+      do_lw (SD_, RD + 1, EXTEND12 (IMMEDIATE) + 4, BASE);
+    }
+}
+
+
+011000,5.RT,5.BASE,0001,12.IMMEDIATE:POOL32C:32::LWR
+"lwr r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+{
+  do_lwr (SD_, RT, EXTEND12 (IMMEDIATE), BASE);
+}
+
+
+011000,5.RT,5.BASE,1110,12.IMMEDIATE:POOL32C:32::LWU
+"lwu r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+{
+  do_lwu (SD_, RT, IMMEDIATE, BASE, instruction_0);
+}
+
+
+010101,5.INDEX,5.BASE,5.FD,00001,001000:POOL32F:32,f::LWXC1
+"lwxc1 f<FD>, <INDEX>(r<BASE>)"
+*micromips32:
+*micromips64:
+{
+  do_lwxc1 (SD_, FD, INDEX, BASE, instruction_0);
+}
+
+
+000000,5.INDEX,5.BASE,5.RD,00100,011000:POOL32A:32::LWXS
+"lwxs r<RD>, r<INDEX>(r<BASE>)"
+*micromips32:
+*micromips64:
+{
+  GPR[RD] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[BASE],
+                              GPR[INDEX] * 4));
+}
+
+
+000000,5.RT,5.RS,1100101100,111100:POOL32A:32::MADD
+"madd r<RS>, r<RT>"
+*micromips32:
+*micromips64:
+{
+  do_madd (SD_, RS, RT);
+}
+
+
+000000,5.RT,5.RS,1101101100,111100:POOL32A:32::MADDU
+"maddu r<RS>, r<RT>"
+*micromips32:
+*micromips64:
+{
+  do_maddu (SD_, RS, RT);
+}
+
+
+000000,5.RT,5.RS,00,3.SEL,00011,111100:POOL32A:32::MFC0
+"mfc0 r<RS>, r<RT>": SEL == 0
+"mfc0 r<RS>, r<RT>, <SEL>"
+*micromips32:
+*micromips64:
+{
+  DecodeCoproc (instruction_0, 0, cp0_mfc0, RT, RS, SEL);
+}
+
+
+010101,5.RT,5.FS,0010000000,111011:POOL32F:32,f::MFC1
+"mfc1 r<RT>, f<FS>"
+*micromips32:
+*micromips64:
+{
+  do_mfc1b (SD_, RT, FS);
+}
+
+
+000000,5.RT,5.IMPL,0100110100,111100:POOL32A:32::MFC2
+"mfc2 r<RT>, <IMPL>"
+*micromips32:
+*micromips64:
+
+
+010101,5.RT,5.FS,0011000000,111011:POOL32F:32,f::MFHC1
+"mfhc1 r<RT>, f<FS>"
+*micromips32:
+*micromips64:
+{
+  do_mfhc1 (SD_, RT, FS);
+}
+
+
+000000,5.RT,5.IMPL,1000110100,111100:POOL32A:32::MFHC2
+"mfhc2 r<RT>, <IMPL>"
+*micromips32:
+*micromips64:
+
+
+000000,00000,5.RS,0000110101,111100:POOL32A:32::MFHI
+"mfhi r<RS>"
+*micromips32:
+*micromips64:
+{
+  do_mfhi (SD_, RS);
+}
+
+
+000000,00000,5.RS,0001110101,111100:POOL32A:32::MFLO
+"mflo r<RS>"
+*micromips32:
+*micromips64:
+{
+  do_mflo (SD_, RS);
+}
+
+
+// MOVF
+// MOVT
+010101,5.RT,5.RS,3.CC,0,1.TF,00101,111011:POOL32F:32::MOVtf
+"mov%s<TF> r<RT>, r<RS>, CC"
+*micromips32:
+*micromips64:
+{
+  do_movtf (SD_, TF, RT, RS, CC);
+}
+
+
+000000,5.RT,5.RS,5.RD,00000,011000:POOL32A:32::MOVN
+"movn r<RD>, r<RS>, r<RT>"
+*micromips32:
+*micromips64:
+{
+  do_movn (SD_, RD, RS, RT);
+}
+
+
+000000,5.RT,5.RS,5.RD,00001,011000:POOL32A:32::MOVZ
+"movz r<RD>, r<RS>, r<RT>"
+*micromips32:
+*micromips64:
+{
+  do_movz (SD_, RD, RS, RT);
+}
+
+
+000000,5.RT,5.RS,1110101100,111100:POOL32A:32::MSUB
+"msub r<RS>, r<RT>"
+*micromips32:
+*micromips64:
+{
+  do_msub (SD_, RS, RT);
+}
+
+
+000000,5.RT,5.RS,1111101100,111100:POOL32A:32::MSUBU
+"msubu r<RS>, r<RT>"
+*micromips32:
+*micromips64:
+{
+  do_msubu (SD_, RS, RT);
+}
+
+
+000000,5.RT,5.RS,00,3.SEL,01011,111100:POOL32A:32::MTC0
+"mtc0 r<RS>, r<RT>": SEL == 0
+"mtc0 r<RS>, r<RT>, <SEL>"
+*micromips32:
+*micromips64:
+{
+  DecodeCoproc (instruction_0, 0, cp0_mtc0, RT, RS, SEL);
+}
+
+
+010101,5.RT,5.FS,0010100000,111011:POOL32F:32,f::MTC1
+"mtc1 r<RT>, f<FS>"
+*micromips32:
+*micromips64:
+{
+  do_mtc1b (SD_, RT, FS);
+}
+
+
+000000,5.RT,5.IMPL,0101110100,111100:POOL32A:32::MTC2
+"mtc2 r<RT>, <IMPL>"
+*micromips32:
+*micromips64:
+
+
+010101,5.RT,5.FS,0011100000,111011:POOL32F:32,f::MTHC1
+"mthc1 r<RT>, f<FS>"
+*micromips32:
+*micromips64:
+{
+  do_mthc1 (SD_, RT, FS);
+}
+
+
+000000,5.RT,5.IMPL,1001110100,111100:POOL32A:32::MTHC2
+"mthc2 r<RT>, <IMPL>"
+*micromips32:
+*micromips64:
+
+
+000000,00000,5.RS,0010110101,111100:POOL32A:32::MTHI
+"mthi r<RS>"
+*micromips32:
+*micromips64:
+{
+  do_mthi (SD_, RS);
+}
+
+
+000000,00000,5.RS,0011110101,111100:POOL32A:32::MTLO
+"mtlo r<RS>"
+*micromips32:
+*micromips64:
+{
+  do_mtlo (SD_, RS);
+}
+
+
+000000,5.RT,5.RS,5.RD,01000,010000:POOL32A:32::MUL
+"mul r<RD>, r<RS>, r<RT>"
+*micromips32:
+*micromips64:
+{
+  do_mul (SD_, RD, RS, RT);
+}
+
+
+000000,5.RT,5.RS,1000101100,111100:POOL32A:32::MULT
+"mult r<RS>, r<RT>"
+*micromips32:
+*micromips64:
+{
+  do_mult (SD_, RS, RT, 0);
+}
+
+
+000000,5.RT,5.RS,1001101100,111100:POOL32A:32::MULTU
+"multu r<RS> r<RT>"
+*micromips32:
+*micromips64:
+{
+  do_multu (SD_, RS, RT, 0);
+}
+
+
+000000,00000000000000000000,000000:POOL32A:32::NOP
+"nop"
+*micromips32:
+*micromips64:
+{
+}
+
+
+000000,5.RT,5.RS,5.RD,01011,010000:POOL32A:32::NOR
+"nor r<RD>, r<RS>, r<RT>"
+*micromips32:
+*micromips64:
+{
+  do_nor (SD_, RS, RT, RD);
+}
+
+
+000000,5.RT,5.RS,5.RD,01010,010000:POOL32A:32::OR
+"or r<RD>, r<RS>, r<RT>"
+*micromips32:
+*micromips64:
+{
+  do_or (SD_, RS, RT, RD);
+}
+
+
+010100,5.RT,5.RS,16.IMMEDIATE:MICROMIPS:32::ORI
+"ori r<RT>, r<RS>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  do_ori (SD_, RS, RT, IMMEDIATE);
+}
+
+
+000000,00000000000010100000,000000:POOL32A:32::PAUSE
+"pause"
+*micromips32:
+*micromips64:
+
+
+011000,5.HINT,5.BASE,0010,12.IMMEDIATE:POOL32C:32::PREF
+"pref <HINT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+{
+  do_pref (SD_, HINT, EXTEND12 (IMMEDIATE), BASE);
+}
+
+
+011000,5.HINT,5.BASE,1010010,9.IMMEDIATE:POOL32C:32::PREFE
+"prefe <HINT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+
+
+010101,5.INDEX,5.BASE,5.HINT,00110,100000:POOL32F:32::PREFX
+"prefx <HINT>, r<INDEX>(r<BASE>)"
+*micromips32:
+*micromips64:
+{
+  do_prefx (SD_, HINT, INDEX, BASE);
+}
+
+000000,5.RT,5.RS,0110101100,111100:POOL32A:32::RDHWR
+"rdhwr r<RS>, r<RT>"
+*micromips32:
+*micromips64:
+{
+  do_rdhwr (SD_, RT, RS);
+}
+
+000000,5.RT,5.RS,1110000101,111100:POOL32A:32::RDPGPR
+"rdpgpr r<RS>, r<RT>"
+*micromips32:
+*micromips64:
+
+
+000000,5.RT,5.RS,5.SHIFT,00011,000000:POOL32A:32::ROTR
+"rotr r<RT>, r<RS>, <SHIFT>"
+*micromips32:
+*micromips64:
+{
+  GPR[RT] = do_ror (SD_, GPR[RS], SHIFT);
+}
+
+
+000000,5.RT,5.RS,5.RD,00011,010000:POOL32A:32::ROTRV
+"rotrv r<RD>, r<RT>, r<RS>"
+*micromips32:
+*micromips64:
+{
+  GPR[RD] = do_ror (SD_, GPR[RT], GPR[RS]);
+}
+
+
+000110,5.RT,5.BASE,16.IMMEDIATE:MICROMIPS:32::SB
+"sb r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+{
+  do_store (SD_, AccessLength_BYTE, GPR[BASE], EXTEND16 (IMMEDIATE), GPR[RT]);
+}
+
+
+011000,5.RT,5.BASE,1010101,9.IMMEDIATE:POOL32C:32::SBE
+"sbe r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+
+
+011000,5.RT,5.BASE,1011,12.IMMEDIATE:POOL32C:32::SC
+"sc r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+{
+  do_sc (SD_, RT, EXTEND12 (IMMEDIATE), BASE, instruction_0);
+}
+
+
+011000,5.RT,5.BASE,1010110,9.IMMEDIATE:POOL32C:32::SCE
+"sce r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+
+
+000000,10.CODE,1101101101,111100:POOL32A:32::SDBBP
+"sdbbp %#lx<CODE>"
+*micromips32:
+*micromips64:
+{
+  SignalException (DebugBreakPoint, instruction_0);
+}
+
+
+101110,5.FT,5.BASE,16.IMMEDIATE:MICROMIPS:32,f::SDC1a
+"sdc1 f<FT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+{
+  do_sdc1 (SD_, FT, IMMEDIATE, BASE);
+}
+
+
+101110,5.FT,5.BASE,16.IMMEDIATE:MICROMIPS:32,f::SDC1b
+"sdc1 f<FT>, <IMMEDIATE>(r<BASE>)"
+*micromips64:
+{
+  check_fpu (SD_);
+  do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (IMMEDIATE),
+           COP_SD (1, FT));
+}
+
+
+001000,5.RT,5.BASE,1010,12.IMMEDIATE:MICROMIPS:32::SDC2
+"sdc2 r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+
+
+000000,5.RT,5.RS,0010101100,111100:POOL32A:32::SEB
+"seb r<RT>, r<RS>"
+*micromips32:
+*micromips64:
+{
+  do_seb (SD_, RT, RS);
+}
+
+
+000000,5.RT,5.RS,0011101100,111100:POOL32A:32::SEH
+"seh r<RT>, r<RS>"
+*micromips32:
+*micromips64:
+{
+  do_seh (SD_, RT, RS);
+}
+
+
+001110,5.RT,5.BASE,16.IMMEDIATE:MICROMIPS:32::SH
+"sh r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+{
+  do_store (SD_, AccessLength_HALFWORD, GPR[BASE], EXTEND16 (IMMEDIATE),
+           GPR[RT]);
+}
+
+
+011000,5.RT,5.BASE,1010100,9.IMMEDIATE:POOL32C:32::SHE
+"she r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+
+
+000000,5.RT!0,5.RS!0,5.SHIFT,00000,000000:POOL32A:32::SLL
+"sll r<RT>, r<RS>, <SHIFT>"
+*micromips32:
+*micromips64:
+{
+  do_sll (SD_, RS, RT, SHIFT);
+}
+
+
+000000,5.RT,5.RS,5.RD,00000,010000:POOL32A:32::SLLV
+"sllv r<RD>, r<RT>, r<RS>"
+*micromips32:
+*micromips64:
+{
+  do_sllv (SD_, RS, RT, RD);
+}
+
+
+000000,5.RT,5.RS,5.RD,01101,010000:POOL32A:32::SLT
+"slt r<RD>, r<RS>, r<RT>"
+*micromips32:
+*micromips64:
+{
+  do_slt (SD_, RS, RT, RD);
+}
+
+
+100100,5.RT,5.RS,16.IMMEDIATE:MICROMIPS:32::SLTI
+"slti r<RT>, r<RS>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  do_slti (SD_, RS, RT, IMMEDIATE);
+}
+
+
+101100,5.RT,5.RS,16.IMMEDIATE:MICROMIPS:32::SLTIU
+"sltiu r<RT>, r<RS>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  do_sltiu (SD_, RS, RT, IMMEDIATE);
+}
+
+
+000000,5.RT,5.RS,5.RD,01110,010000:POOL32A:32::SLTU
+"sltu r<RD>, r<RS>, r<RT>"
+*micromips32:
+*micromips64:
+{
+  do_sltu (SD_, RS, RT, RD);
+}
+
+
+000000,5.RT,5.RS,5.SHIFT,00010,000000:POOL32A:32::SRA
+"sra r<RT>, r<RS>, <SHIFT>"
+*micromips32:
+*micromips64:
+{
+  do_sra (SD_, RS, RT, SHIFT);
+}
+
+
+000000,5.RT,5.RS,5.RD,00010,010000:POOL32A:32::SRAV
+"srav r<RD>, r<RT>, r<RS>"
+*micromips32:
+*micromips64:
+{
+  do_srav (SD_, RS, RT, RD);
+}
+
+
+000000,5.RT,5.RS,5.SHIFT,00001,000000:POOL32A:32::SRL
+"srl r<RT>, r<RS>, <SHIFT>"
+*micromips32:
+*micromips64:
+{
+  do_srl (SD_, RS, RT, SHIFT);
+}
+
+
+000000,5.RT,5.RS,5.RD,00001,010000:POOL32A:32::SRLV
+"srlv r<RD>, r<RT>, r<RS>"
+*micromips32:
+*micromips64:
+{
+  do_srlv (SD_, RS, RT, RD);
+}
+
+
+000000,00000000000000100000,000000:POOL32A:32::SSNOP
+"ssnop"
+*micromips32:
+*micromips64:
+{
+}
+
+
+000000,5.RT,5.RS,5.RD,00110,010000:POOL32A:32::SUB
+"sub r<RD>, r<RS>, r<RT>"
+*micromips32:
+*micromips64:
+{
+  do_sub (SD_, RD, RS, RT);
+}
+
+
+000000,5.RT,5.RS,5.RD,00111,010000:POOL32A:32::SUBU
+"subu r<RD>, r<RS>, r<RT>"
+*micromips32:
+*micromips64:
+{
+  do_subu (SD_, RS, RT, RD);
+}
+
+
+010101,5.INDEX,5.BASE,5.FD,00110,001000:POOL32F:32,f::SUXC1
+"suxc1 f<FD>, r<INDEX>(r<BASE>)"
+*micromips32:
+{
+  do_suxc1_32 (SD_, FD, INDEX, BASE);
+}
+
+
+010101,5.INDEX,5.BASE,5.FD,00110,001000:POOL32F:64,f::SUXC1
+"suxc1 f<FD>, r<INDEX>(r<BASE>)"
+*micromips64:
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  do_suxc1_64 (SD_, FD, INDEX, BASE);
+}
+
+111110,5.RT,5.BASE,16.IMMEDIATE:MICROMIPS:32::SW
+"sw r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+{
+  do_store (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (IMMEDIATE), GPR[RT]);
+}
+
+
+100110,5.FT,5.BASE,16.IMMEDIATE:MICROMIPS:32,f::SWC1
+"swc1 f<FT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+{
+  do_swc1 (SD_, FT, IMMEDIATE, BASE, instruction_0);
+}
+
+
+001000,5.RT,5.BASE,1000,12.IMMEDIATE:POOL32B:32::SWC2
+"swc2 r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+
+
+011000,5.RT,5.BASE,1010111,9.IMMEDIATE:POOL32C:32::SWE
+"swe r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+
+
+011000,5.RT,5.BASE,1000,12.IMMEDIATE:POOL32C:32::SWL
+"swl r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+{
+  do_store_left (SD_, AccessLength_WORD, GPR[BASE], EXTEND12 (IMMEDIATE),
+                GPR[RT]);
+}
+
+
+011000,5.RT,5.BASE,1010000,9.IMMEDIATE:POOL32C:32::SWLE
+"swle r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+
+
+001000,5.LWM32REGS,5.BASE,1101,12.IMMEDIATE:POOL32B:32::SWM32
+"swm32 %s<LWM32REGS>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+{
+  int address_base = GPR[BASE] + EXTEND12 (IMMEDIATE);
+  int reg_offset;
+  for (reg_offset = 0; reg_offset < (LWM32REGS & 0xf); reg_offset++)
+    {
+      int src = (reg_offset == 8) ? 30 : 16 + reg_offset;
+      do_store (SD_, AccessLength_WORD, address_base, 4 * reg_offset,
+               GPR[src]);
+    }
+
+  if (LWM32REGS & 0x10)
+    do_store (SD_, AccessLength_WORD, address_base, 4 * reg_offset, RA);
+}
+
+
+001000,5.RS1,5.BASE,1001,12.IMMEDIATE:POOL32B:32::SWP
+"swp r<RS1>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+{
+  if (RS1 == 31)
+    Unpredictable ();
+  else
+    {
+      do_sw (SD_, RS1, EXTEND12 (IMMEDIATE), BASE);
+      do_sw (SD_, RS1 + 1, EXTEND12 (IMMEDIATE) + 4, BASE);
+    }
+}
+
+
+011000,5.RT,5.BASE,1001,12.IMMEDIATE:POOL32C:32::SWR
+"swr r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+{
+  do_store_right (SD_, AccessLength_WORD, GPR[BASE], EXTEND12 (IMMEDIATE),
+                 GPR[RT]);
+}
+
+
+011000,5.RT,5.BASE,1010001,9.IMMEDIATE:POOL32C:32::SWRE
+"swre r<RT>, <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+
+
+010101,5.INDEX,5.BASE,5.FD,00010,001000:POOL32F:32,f::SWXC1
+"swxc1 f<FD>, r<INDEX>(r<BASE>)"
+*micromips32:
+*micromips64:
+{
+  do_swxc1 (SD_, FD, INDEX, BASE, instruction_0);
+}
+
+
+000000,00000,5.STYPE,0110101101,111100:POOL32A:32::SYNC
+"sync <STYPE>"
+*micromips32:
+*micromips64:
+{
+  SyncOperation (STYPE);
+}
+
+
+010000,10000,5.BASE,16.IMMEDIATE:POOL32I:32::SYNCI
+"synci <IMMEDIATE>(r<BASE>)"
+*micromips32:
+*micromips64:
+{
+}
+
+000000,10.CODE,1000101101,111100:POOL32A:32::SYSCALL
+"syscall %#lx<CODE>"
+*micromips32:
+*micromips64:
+{
+  SignalException (SystemCall, instruction_0);
+}
+
+
+000000,5.RT,5.RS,4.CODE,000000,111100:POOL32A:32::TEQ
+"teq r<RS>, r<RT>"
+*micromips32:
+*micromips64:
+{
+  do_teq (SD_, RS, RT, instruction_0);
+}
+
+
+010000,01110,5.RS,16.IMMEDIATE:POOL32I:32::TEQI
+"teqi r<RS>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  do_teqi (SD_, RS, IMMEDIATE, instruction_0);
+}
+
+
+000000,5.RT,5.RS,4.CODE,001000,111100:POOL32A:32::TGE
+"tge r<RS>, r<RT>"
+*micromips32:
+*micromips64:
+{
+  do_tge (SD_, RS, RT, instruction_0);
+}
+
+
+010000,01001,5.RS,16.IMMEDIATE:POOL32I:32::TGEI
+"tgei r<RS>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  do_tgei (SD_, RS, IMMEDIATE, instruction_0);
+}
+
+
+010000,01011,5.RS,16.IMMEDIATE:POOL32I:32::TGEIU
+"tgeiu r<RS>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  do_tgeiu (SD_, RS, IMMEDIATE, instruction_0);
+}
+
+
+000000,5.RT,5.RS,4.CODE,010000,111100:POOL32A:32::TGEU
+"tgeu r<RS>, r<RT>"
+*micromips32:
+*micromips64:
+{
+  do_tgeu (SD_, RS, RT, instruction_0);
+}
+
+
+000000,00000000000000001101,111100:POOL32A:32::TLBP
+"tlbp"
+*micromips32:
+*micromips64:
+
+
+000000,00000000000001001101,111100:POOL32A:32::TLBR
+"tlbr"
+*micromips32:
+*micromips64:
+
+
+000000,00000000000010001101,111100:POOL32A:32::TLBWI
+"tlbwi"
+*micromips32:
+*micromips64:
+
+
+000000,00000000000011001101,111100:POOL32A:32::TLBWR
+"tlbwr"
+*micromips32:
+*micromips64:
+
+
+000000,5.RT,5.RS,4.CODE,100000,111100:POOL32A:32::TLT
+"tlt r<RS>, r<RT>, %#lx<CODE>"
+*micromips32:
+*micromips64:
+{
+  do_tlt (SD_, RS, RT, instruction_0);
+}
+
+
+010000,01000,5.RS,16.IMMEDIATE:POOL32I:32::TLTI
+"tlti r<RS>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  do_tlti (SD_, RS, IMMEDIATE, instruction_0);
+}
+
+
+010000,01010,5.RS,16.IMMEDIATE:POOL32I:32::TLTIU
+"tltiu r<RS>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  do_tltiu (SD_, RS, IMMEDIATE, instruction_0);
+}
+
+
+000000,5.RT,5.RS,4.CODE,101000,111100:POOL32A:32::TLTU
+"tltu r<RS>, r<RT>"
+*micromips32:
+*micromips64:
+{
+  do_tltu (SD_, RS, RT, instruction_0);
+}
+
+
+000000,5.RT,5.RS,4.CODE,110000,111100:POOL32A:32::TNE
+"tne r<RS>, r<RT>"
+*micromips32:
+*micromips64:
+{
+  do_tne (SD_, RS, RT, instruction_0);
+}
+
+
+010000,01100,5.RS,16.IMMEDIATE:POOL32I:32::TNEI
+"tnei r<RS>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  do_tnei (SD_, RS, IMMEDIATE, instruction_0);
+}
+
+
+000000,10.CODE,1001001101,111100:POOL32A:32::WAIT
+"wait"
+*micromips32:
+*micromips64:
+
+
+000000,5.RT,5.RS,1111000101,111100:POOL32A:32::WRPGPR
+"wrpgpr r<RS>, r<RT>"
+*micromips32:
+*micromips64:
+
+
+000000,5.RT,5.RS,0111101100,111100:POOL32A:32::WSBH
+"wsbh r<RT>, r<RS>"
+*micromips32:
+*micromips64:
+{
+  do_wsbh (SD_, RT, RS);
+}
+
+
+000000,5.RT,5.RS,5.RD,01100,010000:POOL32A:32::XOR
+"xor r<RD>, r<RS>, r<RT>"
+*micromips32:
+*micromips64:
+{
+  do_xor (SD_, RS, RT, RD);
+}
+
+
+011100,5.RT,5.RS,16.IMMEDIATE:MICROMIPS:32::XORI
+"xori r<RT>, r<RS>, <IMMEDIATE>"
+*micromips32:
+*micromips64:
+{
+  do_xori (SD_, RS, RT, IMMEDIATE);
+}
+
+
+:%s::::FMT_MICROMIPS:int fmt
+{
+  switch (fmt)
+    {
+    case 0: return "s";
+    case 1: return "d";
+    case 2: return "ps";
+    default: return "?";
+    }
+}
+
+
+:%s::::FMT_MICROMIPS_CVT_D:int fmt
+{
+  switch (fmt)
+    {
+    case 0: return "s";
+    case 1: return "w";
+    case 2: return "l";
+    default: return "?";
+    }
+}
+
+
+:%s::::FMT_MICROMIPS_CVT_S:int fmt
+{
+  switch (fmt)
+    {
+    case 0: return "d";
+    case 1: return "w";
+    case 2: return "l";
+    default: return "?";
+    }
+}
+
+
+010101,5.FT,5.FS,0,2.FMT_MICROMIPS!3,0001101,111011:POOL32F:32,f::ABS.fmt
+"abs.%s<FMT_MICROMIPS> f<FT>, f<FS>"
+*micromips32:
+*micromips64:
+{
+  do_abs_fmt (SD_, convert_fmt_micromips (SD_, FMT_MICROMIPS), FT, FS,
+             instruction_0);
+}
+
+
+010101,5.FT,5.FS,5.FD,0,2.FMT_MICROMIPS!3,00,110000:POOL32F:32,f::ADD.fmt
+"add.%s<FMT_MICROMIPS> f<FD>, f<FS>, f<FT>"
+*micromips32:
+*micromips64:
+{
+  do_add_fmt (SD_, convert_fmt_micromips (SD_, FMT_MICROMIPS), FD, FS, FT,
+             instruction_0);
+}
+
+
+010101,5.FT,5.FS,5.FD,5.RS,011001:POOL32F:32,f::ALNV.PS
+"alnv.ps f<FD>, f<FS>, f<FT>, r<RS>"
+*micromips32:
+*micromips64:
+{
+  do_alnv_ps (SD_, FD, FS, FT, RS, instruction_0);
+}
+
+
+010101,5.FT,5.FS,3.CC,0,2.FMT_MICROMIPS!3,4.COND,111100:POOL32F:32,f::C.cond.fmt
+"c.%s<COND>.%s<FMT_MICROMIPS> f<FS>, f<FT>":CC == 0
+"c.%s<COND>.%s<FMT_MICROMIPS> <CC>, f<FS>, f<FT>"
+*micromips32:
+*micromips64:
+{
+  do_c_cond_fmt (SD_, COND, convert_fmt_micromips (SD_, FMT_MICROMIPS), CC,
+                FS, FT, instruction_0);
+}
+
+
+010101,5.FT,5.FS,0,1.FMT_MICROMIPS,01001100,111011:POOL32F:32,f::CEIL.L.fmt
+"ceil.l.%s<FMT_MICROMIPS> f<FT>, f<FS>"
+*micromips32:
+*micromips64:
+{
+  do_ceil_fmt (SD_, fmt_long, FMT_MICROMIPS, FT, FS, instruction_0);
+}
+
+
+010101,5.FT,5.FS,0,1.FMT_MICROMIPS,01101100,111011:POOL32F:32,f::CEIL.W.fmt
+"ceil.w.%s<FMT_MICROMIPS> f<FT>, f<FS>"
+*micromips32:
+*micromips64:
+{
+  do_ceil_fmt (SD_, fmt_word, FMT_MICROMIPS, FT, FS, instruction_0);
+}
+
+
+010101,5.FT,5.FS,0,2.FMT_MICROMIPS_CVT_D!3,1001101,111011:POOL32F:32,f::CVT.D.fmt
+"cvt.d.%s<FMT_MICROMIPS_CVT_D> f<FT>, f<FS>"
+*micromips32:
+*micromips64:
+{
+  do_cvt_d_fmt (SD_, convert_fmt_micromips_cvt_d (SD_, FMT_MICROMIPS_CVT_D),
+               FT, FS, instruction_0);
+}
+
+
+010101,5.FT,5.FS,0,1.FMT_MICROMIPS,00000100,111011:POOL32F:32,f::CVT.L.fmt
+"cvt.l.%s<FMT_MICROMIPS> f<FT>, f<FS>"
+*micromips32:
+*micromips64:
+{
+  do_cvt_l_fmt (SD_, FMT_MICROMIPS, FT, FS, instruction_0);
+}
+
+
+010101,5.FT,5.FS,5.FD,00110,000000:POOL32F:32,f::CVT.PS.S
+"cvt.ps.s f<FD>, f<FS>, f<FT>"
+*micromips32:
+*micromips64:
+{
+  do_cvt_ps_s (SD_, FD, FS, FT, instruction_0);
+}
+
+
+010101,5.FT,5.FS,0,2.FMT_MICROMIPS_CVT_S!3,1101101,111011:POOL32F:32,f::CVT.S.fmt
+"cvt.s.%s<FMT_MICROMIPS_CVT_S> f<FT>, f<FS>"
+*micromips32:
+*micromips64:
+{
+  do_cvt_s_fmt (SD_, convert_fmt_micromips_cvt_s (SD_, FMT_MICROMIPS_CVT_S),
+               FT, FS, instruction_0);
+}
+
+
+010101,5.FT,5.FS,00,10000100,111011:POOL32F:32,f::CVT.S.PL
+"cvt.s.pl f<FT>, f<FS>"
+*micromips32:
+*micromips64:
+{
+  do_cvt_s_pl (SD_, FT, FS, instruction_0);
+}
+
+
+010101,5.FT,5.FS,00,10100100,111011:POOL32F:32,f::CVT.S.PU
+"cvt.s.pu f<FT>, f<FS>"
+*micromips32:
+*micromips64:
+{
+  do_cvt_s_pu (SD_, FT, FS, instruction_0);
+}
+
+
+010101,5.FT,5.FS,0,1.FMT_MICROMIPS,00100100,111011:POOL32F:32,f::CVT.W.fmt
+"cvt.w.%s<FMT_MICROMIPS> f<FT>, f<FS>"
+*micromips32:
+*micromips64:
+{
+  do_cvt_w_fmt (SD_, FMT_MICROMIPS, FT, FS, instruction_0);
+}
+
+
+010101,5.FT,5.FS,5.FD,0,2.FMT_MICROMIPS!2!3,11,110000:POOL32F:32,f::DIV.fmt
+"div.%s<FMT_MICROMIPS> f<FD>, f<FS>, f<FT>"
+*micromips32:
+*micromips64:
+{
+  do_div_fmt (SD_, FMT_MICROMIPS, FD, FS, FT, instruction_0);
+}
+
+
+010101,5.FT,5.FS,0,1.FMT_MICROMIPS,00001100,111011:POOL32F:32,f::FLOOR.L.fmt
+"floor.l.%s<FMT_MICROMIPS> f<FT>, f<FS>"
+*micromips32:
+*micromips64:
+{
+  do_floor_fmt (SD_, fmt_long, FMT_MICROMIPS, FT, FS);
+}
+
+
+010101,5.FT,5.FS,0,1.FMT_MICROMIPS,00101100,111011:POOL32F:32,f::FLOOR.W.fmt
+"floor.w.%s<FMT_MICROMIPS> f<FT>, f<FS>"
+*micromips32:
+*micromips64:
+{
+  do_floor_fmt (SD_, fmt_word, FMT_MICROMIPS, FT, FS);
+}
+
+
+010101,5.FT,5.FS,5.FD,5.FR,0,2.FMT_MICROMIPS!3,001:POOL32F:32,f::MADD.fmt
+"madd.%s<FMT_MICROMIPS> f<FD>, f<FR>, f<FS>, f<FT>"
+*micromips32:
+*micromips64:
+{
+  do_madd_fmt (SD_, convert_fmt_micromips (SD_, FMT_MICROMIPS), FD, FR, FS,
+              FT, instruction_0);
+}
+
+010101,5.FT,5.FS,0,2.FMT_MICROMIPS!3,0000001,111011:POOL32F:32,f::MOV.fmt
+"mov.%s<FMT_MICROMIPS> f<FT>, f<FS>"
+*micromips32:
+*micromips64:
+{
+  do_mov_fmt (SD_, convert_fmt_micromips (SD_, FMT_MICROMIPS), FT, FS,
+             instruction_0);
+}
+
+
+010101,5.FT,5.FS,3.CC,00,2.FMT_MICROMIPS!3,00,1.TF,100000:POOL32F:32,f::MOVtf.fmt
+"mov%s<TF>.%s<FMT_MICROMIPS> f<FT>, f<FS>, <CC>"
+*micromips32:
+*micromips64:
+{
+  do_movtf_fmt (SD_, TF, convert_fmt_micromips (SD_, FMT_MICROMIPS), FT,
+               FS, CC);
+}
+
+
+010101,5.FT,5.FS,5.FD,0,2.FMT_MICROMIPS!3,00,111000:POOL32F:32,f::MOVN.fmt
+"movn.%s<FMT_MICROMIPS> f<FD>, f<FS>, r<FT>"
+*micromips32:
+*micromips64:
+{
+  do_movn_fmt (SD_, convert_fmt_micromips (SD_, FMT_MICROMIPS), FD, FS, FT);
+}
+
+010101,5.FT,5.FS,5.FD,0,2.FMT_MICROMIPS!3,01,111000:POOL32F:32,f::MOVZ.fmt
+"movz.%s<FMT_MICROMIPS> f<FD>, f<FS>, r<FT>"
+*micromips32:
+*micromips64:
+{
+  do_movz_fmt (SD_, convert_fmt_micromips (SD_, FMT_MICROMIPS), FD, FS, FT);
+}
+
+
+010101,5.FT,5.FS,5.FD,5.FR,1,2.FMT_MICROMIPS!3,001:POOL32F:32,f::MSUB.fmt
+"msub.%s<FMT_MICROMIPS> f<FD>, f<FR>, f<FS>, f<FT>"
+*micromips32:
+*micromips64:
+{
+  do_msub_fmt (SD_, convert_fmt_micromips (SD_, FMT_MICROMIPS), FD, FR, FS,
+              FT, instruction_0);
+}
+
+010101,5.FT,5.FS,5.FD,0,2.FMT_MICROMIPS!3,10,110000:POOL32F:32,f::MUL.fmt
+"mul.%s<FMT_MICROMIPS> f<FD>, f<FS>, f<FT>"
+*micromips32:
+*micromips64:
+{
+  do_mul_fmt (SD_, convert_fmt_micromips (SD_, FMT_MICROMIPS), FD, FS, FT,
+             instruction_0);
+}
+
+
+010101,5.FT,5.FS,0,2.FMT_MICROMIPS!3,0101101,111011:POOL32F:32,f::NEG.fmt
+"neg.%s<FMT_MICROMIPS> f<FT>, f<FS>"
+*micromips32:
+*micromips64:
+{
+  do_neg_fmt (SD_, convert_fmt_micromips (SD_, FMT_MICROMIPS), FT, FS,
+             instruction_0);
+}
+
+
+010101,5.FT,5.FS,5.FD,5.FR,0,2.FMT_MICROMIPS!3,010:POOL32F:32,f::NMADD.fmt
+"nmadd.%s<FMT_MICROMIPS> f<FD>, f<FR>, f<FS>, f<FT>"
+*micromips32:
+*micromips64:
+{
+  do_nmadd_fmt (SD_, convert_fmt_micromips (SD_, FMT_MICROMIPS), FD, FR, FS,
+               FT, instruction_0);
+}
+
+010101,5.FT,5.FS,5.FD,5.FR,1,2.FMT_MICROMIPS!3,010:POOL32F:32,f::NMSUB.fmt
+"nmsub.%s<FMT_MICROMIPS> f<FD>, f<FR>, f<FS>, f<FT>"
+*micromips32:
+*micromips64:
+{
+  do_nmsub_fmt (SD_, convert_fmt_micromips (SD_, FMT_MICROMIPS), FD, FR, FS,
+               FT, instruction_0);
+}
+
+
+010101,5.FT,5.FS,5.FD,00010,000000:POOL32F:32,f::PLL.PS
+"pll.ps f<FD>, f<FS>, f<FT>"
+*micromips32:
+*micromips64:
+{
+  do_pll_ps (SD_, FD, FS, FT, instruction_0);
+}
+
+
+010101,5.FT,5.FS,5.FD,00011,000000:POOL32F:32,f::PLU.PS
+"plu.ps f<FD>, f<FS>, f<FT>"
+*micromips32:
+*micromips64:
+{
+  do_plu_ps (SD_, FD, FS, FT, instruction_0);
+}
+
+
+010101,5.FT,5.FS,5.FD,00100,000000:POOL32F:32,f::PUL.PS
+"pul.ps f<FD>, f<FS>, f<FT>"
+*micromips32:
+*micromips64:
+{
+  do_pul_ps (SD_, FD, FS, FT, instruction_0);
+}
+
+
+010101,5.FT,5.FS,5.FD,00101,000000:POOL32F:32,f::PUU.PS
+"puu.ps f<FD>, f<FS>, f<FT>"
+*micromips32:
+*micromips64:
+{
+  do_puu_ps (SD_, FD, FS, FT, instruction_0);
+}
+
+
+010101,5.FT,5.FS,0,1.FMT_MICROMIPS,01001000,111011:POOL32F:32,f::RECIP.fmt
+"recip.%s<FMT_MICROMIPS> f<FT>, f<FS>"
+*micromips32:
+*micromips64:
+{
+  do_recip_fmt (SD_, FMT_MICROMIPS, FT, FS);
+}
+
+
+010101,5.FT,5.FS,0,1.FMT_MICROMIPS,11001100,111011:POOL32F:32,f::ROUND.L.fmt
+"round.l.%s<FMT_MICROMIPS> f<FT>, f<FS>"
+*micromips32:
+*micromips64:
+{
+  do_round_fmt (SD_, fmt_long, FMT_MICROMIPS, FT, FS);
+}
+
+
+010101,5.FT,5.FS,0,1.FMT_MICROMIPS,11101100,111011:POOL32F:32,f::ROUND.W.fmt
+"round.w.%s<FMT_MICROMIPS> f<FT>, f<FS>"
+*micromips32:
+*micromips64:
+{
+  do_round_fmt (SD_, fmt_word, FMT_MICROMIPS, FT, FS);
+}
+
+
+010101,5.FT,5.FS,0,1.FMT_MICROMIPS,00001000,111011:POOL32F:32,f::RSQRT.fmt
+"rsqrt.%s<FMT_MICROMIPS> f<FT>, f<FS>"
+*micromips32:
+*micromips64:
+{
+  do_rsqrt_fmt (SD_, FMT_MICROMIPS, FT, FS);
+}
+
+
+010101,5.FT,5.FS,0,1.FMT_MICROMIPS,00101000,111011:POOL32F:32,f::SQRT.fmt
+"sqrt.%s<FMT_MICROMIPS> f<FT>, f<FS>"
+*micromips32:
+*micromips64:
+{
+  do_sqrt_fmt (SD_, FMT_MICROMIPS, FT, FS);
+}
+
+
+010101,5.FT,5.FS,5.FD,0,2.FMT_MICROMIPS!3,01,110000:POOL32F:32,f::SUB.fmt
+"sub.%s<FMT_MICROMIPS> f<FD>, f<FS>, f<FT>"
+*micromips32:
+*micromips64:
+{
+  do_sub_fmt (SD_, convert_fmt_micromips (SD_, FMT_MICROMIPS), FD, FS, FT,
+             instruction_0);
+}
+
+
+010101,5.FT,5.FS,0,1.FMT_MICROMIPS,10001100,111011:POOL32F:32,f::TRUNC.L.fmt
+"trunc.l.%s<FMT_MICROMIPS> f<FT>, f<FS>"
+*micromips32:
+*micromips64:
+{
+  do_trunc_fmt (SD_, fmt_long, FMT_MICROMIPS, FT, FS);
+}
+
+
+010101,5.FT,5.FS,0,1.FMT_MICROMIPS,10101100,111011:POOL32F:32,f::TRUNC.W.fmt
+"trunc.w.%s<FMT_MICROMIPS> f<FT>, f<FS>"
+*micromips32:
+*micromips64:
+{
+  do_trunc_fmt (SD_, fmt_word, FMT_MICROMIPS, FT, FS);
+}
+
+001000,5.LWM32REGS,5.BASE,0111,12.OFFSET:POOL32B:64::LDM
+"ldm %s<LWM32REGS>, <OFFSET>(r<BASE>)"
+*micromips64:
+{
+  int address_base = GPR[BASE] + EXTEND12 (OFFSET);
+  int reg_offset;
+  for (reg_offset = 0; reg_offset < (LWM32REGS & 0xf); reg_offset++)
+    {
+      int dst = (reg_offset == 8) ? 30 : 16 + reg_offset;
+      GPR[dst] = EXTEND64 (do_load (SD_, AccessLength_DOUBLEWORD, address_base,
+                                   8 * reg_offset));
+    }
+
+  if (LWM32REGS & 0x10)
+    RA = EXTEND64 (do_load (SD_, AccessLength_DOUBLEWORD, address_base,
+                           8 * reg_offset));
+}
+
+001000,5.RD,5.BASE,0100,12.OFFSET:POOL32B:64::LDP
+"ldp r<RD>, <OFFSET>(r<BASE>)"
+*micromips64:
+{
+  if (BASE == RD || RD == 31)
+    Unpredictable ();
+  else
+    {
+      check_u64 (SD_, instruction_0);
+      GPR[RD] = EXTEND64 (do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE],
+                                  EXTEND12 (OFFSET)));
+      GPR[RD + 1] = EXTEND64 (do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE],
+                                      EXTEND12 (OFFSET) + 8));
+    }
+}
+
+001000,5.LWM32REGS,5.BASE,1111,12.OFFSET:POOL32B:64::SDM
+"sdm %s<LWM32REGS>, <OFFSET>(r<BASE>)"
+*micromips64:
+{
+  int address_base = GPR[BASE] + EXTEND12 (OFFSET);
+  int reg_offset;
+  for (reg_offset = 0; reg_offset < (LWM32REGS & 0xf); reg_offset++)
+    {
+      int src = (reg_offset == 8) ? 30 : 16 + reg_offset;
+      do_store (SD_, AccessLength_DOUBLEWORD, address_base, 8 * reg_offset,
+               GPR[src]);
+    }
+
+  if (LWM32REGS & 0x10)
+    do_store (SD_, AccessLength_DOUBLEWORD, address_base, 8 * reg_offset, RA);
+}
+
+001000,5.RD,5.BASE,1100,12.OFFSET:POOL32B:64::SDP
+"sdp r<RD>, <OFFSET>(r<BASE>)"
+*micromips64:
+{
+  if (RD == 31)
+    Unpredictable ();
+  else
+    {
+      check_u64 (SD_, instruction_0);
+      do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND12 (OFFSET),
+               GPR[RD]);
+      do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND12 (OFFSET) + 8,
+               GPR[RD + 1]);
+    }
+}
+
+010110,5.RT,5.RS,5.RD,00,100010000:POOL32S:64::DADD
+"dadd r<RD>, r<RS>, r<RT>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_dadd (SD_, RD, RS, RT);
+}
+
+010110,5.RT,5.RS,10.IMMEDIATE,011100:POOL32S:64::DADDI
+"daddi r<RT>, r<RS>, <IMMEDIATE>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_daddi (SD_, RT, RS, IMMEDIATE);
+}
+
+010111,5.RT,5.RS,16.IMMEDIATE:MICROMIPS:64::DADDIU
+"daddiu r<RT>, r<RS>, <IMMEDIATE>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_daddiu (SD_, RS, RT, IMMEDIATE);
+}
+
+010110,5.RT,5.RS,5.RD,00,101010000:POOL32S:64::DADDU
+"daddu r<RD>, r<RS>, r<RT>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_daddu (SD_, RS, RT, RD);
+}
+
+010110,5.RT,5.RS,0100101100,111100:POOL32S:64::DCLO
+"dclo r<RT>, r<RS>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_dclo (SD_, RT, RS);
+}
+
+010110,5.RT,5.RS,0101101100,111100:POOL32S:64::DCLZ
+"dclz r<RT>, r<RS>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_dclz (SD_, RT, RS);
+}
+
+010110,5.RT,5.RS,1010101100,111100:POOL32S:64::DDIV
+"ddiv r<RS>, r<RT>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_ddiv (SD_, RS, RT);
+}
+
+010110,5.RT,5.RS,1011101100,111100:POOL32S:64::DDIVU
+"ddivu r<RS>, r<RT>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_ddivu (SD_, RS, RT);
+}
+
+010110,5.RT,5.RS,5.SIZE,5.LSB,101100:POOL32S:64::DEXT
+"dext r<RT>, r<RS>, <LSB>, <SIZE+1>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_dext (SD_, RT, RS, LSB, SIZE);
+}
+
+010110,5.RT,5.RS,5.SIZE,5.LSB,100100:POOL32S:64::DEXTM
+"dextm r<RT>, r<RS>, <LSB>, <SIZE+33>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_dextm (SD_, RT, RS, LSB, SIZE);
+}
+
+010110,5.RT,5.RS,5.SIZE,5.LSB,010100:POOL32S:64::DEXTU
+"dextu r<RT>, r<RS>, <LSB+32>, <SIZE+1>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_dextu (SD_, RT, RS, LSB, SIZE);
+}
+
+010110,5.RT,5.RS,5.MSB,5.LSB,001100:POOL32S:64::DINS
+"dins r<RT>, r<RS>, <LSB>, <MSB-LSB+1>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_dins (SD_, RT, RS, LSB, MSB);
+}
+
+010110,5.RT,5.RS,5.MSB,5.LSB,000100:POOL32S:64::DINSM
+"dinsm r<RT>, r<RS>, <LSB>, <MSB+32-LSB+1>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_dinsm (SD_, RT, RS, LSB, MSB);
+}
+
+010110,5.RT,5.RS,5.MSB,5.LSB,110100:POOL32S:64::DINSU
+"dinsu r<RT>, r<RS>, <LSB+32>, <MSB-LSB+1>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_dinsu (SD_, RT, RS, LSB, MSB);
+}
+
+010110,5.RT,5.RS,00,3.SEL,00011,111100:POOL32S:64::DMFC0
+"dmfc0 r<RT>, r<RS>": SEL == 0
+"dmfc0 r<RT>, r<RS>, <SEL>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  DecodeCoproc (instruction_0, 0, cp0_dmfc0, RT, RS, SEL);
+}
+
+010101,5.RT,5.FS,00,10010000,111011:POOL32F:64::DMFC1
+"dmfc1 r<RT>, f<FS>"
+*micromips64:
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  do_dmfc1b (SD_, RT, FS);
+}
+
+010110,5.RT,5.RS,00,3.SEL,01011,111100:POOL32S:64::DMTC0
+"dmtc0 r<RT>, r<RS>": SEL == 0
+"dmtc0 r<RT>, r<RS>, <SEL>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  DecodeCoproc (instruction_0, 0, cp0_dmtc0, RT, RS, SEL);
+}
+
+010101,5.RT,5.FS,00,10110000,111011:POOL32F:64::DMTC1
+"dmtc1 r<RT>, f<FS>"
+*micromips64:
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  do_dmtc1b (SD_, RT, FS);
+}
+
+010110,5.RT,5.RS,1000101100,111100:POOL32S:64::DMULT
+"dmult r<RS>, r<RT>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_dmult (SD_, RS, RT, 0);
+}
+
+010110,5.RT,5.RS,1001101100,111100:POOL32S:64::DMULTU
+"dmultu r<RS>, r<RT>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_dmultu (SD_, RS, RT, 0);
+}
+
+010110,5.RT,5.RS,5.SA,00,011000000:POOL32S:64::DROTR
+"drotr r<RT>, r<RS>, <SA>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  GPR[RT] = do_dror (SD_, GPR[RS], SA);
+}
+
+010110,5.RT,5.RS,5.SA,00,011001000:POOL32S:64::DROTR32
+"drotr32 r<RT>, r<RS>, <SA+32>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  GPR[RT] = do_dror (SD_, GPR[RS], SA + 32);
+}
+
+010110,5.RT,5.RS,5.RD,00,011010000:POOL32S:64::DROTRV
+"drotrv r<RD>, r<RT>, r<RS>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  GPR[RD] = do_dror (SD_, GPR[RT], GPR[RS]);
+}
+
+010110,5.RT,5.RS,0111101100,111100:POOL32S:64::DSBH
+"dsbh r<RT>, r<RS>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_dsbh (SD_, RT, RS);
+}
+
+010110,5.RT,5.RS,1111101100,111100:POOL32S:64::DSHD
+"dshd r<RT>, r<RS>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_dshd (SD_, RS, RT);
+}
+
+010110,5.RT,5.RS,5.SA,00,000000000:POOL32S:64::DSLL
+"dsll r<RT>, r<RS>, <SA>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_dsll (SD_, RS, RT, SA);
+}
+
+010110,5.RT,5.RS,5.SA,00,000001000:POOL32S:64::DSLL32
+"dsll32 r<RT>, r<RS>, <SA>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_dsll32 (SD_, RT, RS, SA);
+}
+
+010110,5.RT,5.RS,5.RD,00,000010000:POOL32S:64::DSLLV
+"dsllv r<RD>, r<RT>, r<RS>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_dsllv (SD_, RS, RT, RD);
+}
+
+010110,5.RT,5.RS,5.SA,00,010000000:POOL32S:64::DSRA
+"dsra r<RT>, r<RS>, <SA>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_dsra (SD_, RS, RT, SA);
+}
+
+010110,5.RT,5.RS,5.SA,00,010001000:POOL32S:64::DSRA32
+"dsra32 r<RT>, r<RS>, <SA>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_dsra32 (SD_, RT, RS, SA);
+}
+
+010110,5.RT,5.RS,5.RD,00,010010000:POOL32S:64::DSRAV
+"dsrav r<RD>, r<RS>, r<RT>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_dsrav (SD_, RS, RT, RD);
+}
+
+010110,5.RT,5.RS,5.SA,00,001000000:POOL32S:64::DSRL
+"dsrl r<RT>, r<RS>, <SA>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_dsrl (SD_, RS, RT, SA);
+}
+
+010110,5.RT,5.RS,5.SA,00,001001000:POOL32S:64::DSRL32
+"dsrl32 r<RT>, r<RS>, <SA>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_dsrl32 (SD_, RT, RS, SA);
+}
+
+010110,5.RT,5.RS,5.RD,00,001010000:POOL32S:64::DSRLV
+"dsrlv r<RD>, r<RT>, r<RS>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_dsrlv (SD_, RS, RT, RD);
+}
+
+010110,5.RT,5.RS,5.RD,00,110001000:POOL32S:64::DSUB
+"dsub r<RD>, r<RS>, r<RT>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_dsub (SD_, RD, RS, RT);
+}
+
+010110,5.RT,5.RS,5.RD,00,111001000:POOL32S:64::DSUBU
+"dsubu r<RD>, r<RS>, r<RT>"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_dsubu (SD_, RS, RT, RD);
+}
+
+110111,5.RT,5.BASE,16.OFFSET:MICROMIPS64:64::LD
+"ld r<RT>, <OFFSET>(r<BASE>)"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  GPR[RT] = EXTEND64 (do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE],
+                              EXTEND16 (OFFSET)));
+}
+
+011000,5.RT,5.BASE,0100,12.OFFSET:POOL32C:64::LDL
+"ldl r<RT>, <OFFSET>(r<BASE>)"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  GPR[RT] = do_load_left (SD_, AccessLength_DOUBLEWORD, GPR[BASE],
+                         EXTEND12 (OFFSET), GPR[RT]);
+}
+
+011000,5.RT,5.BASE,0101,12.OFFSET:POOL32C:64::LDR
+"ldr r<RT>, <OFFSET>(r<BASE>)"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  GPR[RT] = do_load_right (SD_, AccessLength_DOUBLEWORD, GPR[BASE],
+                          EXTEND12 (OFFSET), GPR[RT]);
+}
+
+010101,5.INDEX,5.BASE,5.FD,00,011001000:POOL32F:64,f::LDXC1
+"ldxc1 f<FD>, r<INDEX>(r<BASE>)"
+*micromips64:
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  COP_LD (1, FD, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], GPR[INDEX]));
+}
+
+011000,5.RT,5.BASE,0111,12.OFFSET:POOL32C:64::LLD
+"lld r<RT>, <OFFSET>(r<BASE>)"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_lld (SD_, RT, OFFSET, BASE);
+}
+
+011000,5.RT,5.BASE,1111,12.OFFSET:POOL32C:64::SCD
+"scd r<RT>, <OFFSET>(r<BASE>)"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_scd (SD_, RT, OFFSET, BASE);
+}
+
+110110,5.RT,5.BASE,16.OFFSET:MICROMIPS64:64::SD
+"sd r<RT>, <OFFSET>(r<BASE>)"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET),
+           GPR[RT]);
+}
+
+011000,5.RT,5.BASE,1100,12.OFFSET:POOL32C:64::SDL
+"sdl r<RT>, <OFFSET>(r<BASE>)"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_store_left (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND12 (OFFSET),
+                GPR[RT]);
+}
+
+011000,5.RT,5.BASE,1101,12.OFFSET:POOL32C:64::SDR
+"sdr r<RT>, <OFFSET>(r<BASE>)"
+*micromips64:
+{
+  check_u64 (SD_, instruction_0);
+  do_store_right (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND12 (OFFSET),
+                 GPR[RT]);
+}
+
+010101,5.INDEX,5.BASE,5.FD,00,100001000:POOL32F:64,f::SDXC1
+"sdxc1 f<FD>, r<INDEX>(r<BASE>)"
+*micromips64:
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], GPR[INDEX],
+           COP_SD (1, FD));
+}
diff --git a/sim/mips/micromips16.dc b/sim/mips/micromips16.dc
new file mode 100644 (file)
index 0000000..a1cd9a0
--- /dev/null
@@ -0,0 +1,11 @@
+# most instructions
+# ------ options ------ : Fst : Lst : ff : fl : fe : word :  fmt : model ...
+# { : mask : value : word }
+
+# Top level - create a very big switch statement.
+
+  padded-switch,combine :  15 :  10 :    :    :    :      :      :
+
+  switch,combine        :  9 :    6 :    :    :    :      :      :
+  switch,combine        :  9 :    5 :    :    :    :      :      :
+  switch,combine        :  0 :    0 :    :    :    :      :      :
diff --git a/sim/mips/micromipsdsp.igen b/sim/mips/micromipsdsp.igen
new file mode 100644 (file)
index 0000000..daa9f83
--- /dev/null
@@ -0,0 +1,1137 @@
+// Simulator definition for the micromips DSP ASE.
+// Copyright (C) 2005-2015 Free Software Foundation, Inc.
+// Contributed by Imagination Technologies, Ltd.
+// Written by Andrew Bennett <andrew.bennett@imgtec.com>
+//
+// This file is part of the MIPS sim.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+000000,5.RT,5.RS,0001000100,111100:POOL32A:32::ABSQ_S.PH
+"absq_s.ph r<RT>, r<RS>"
+*micromipsdsp:
+{
+  do_ph_s_absq (SD_, RT, RS);
+}
+
+000000,5.RT,5.RS,0000000100,111100:POOL32A:32::ABSQ_S.QB
+"absq_s.qb r<RT>, r<RS>"
+*micromipsdsp:
+{
+  do_qb_s_absq (SD_, RT, RS);
+}
+
+000000,5.RT,5.RS,0010000100,111100:POOL32A:32::ABSQ_S.W
+"absq_s.w r<RT>, r<RS>"
+*micromipsdsp:
+{
+  do_w_s_absq (SD_, RT, RS);
+}
+
+000000,5.RT,5.RS,5.RD,00000,001101:POOL32A:32::ADDQ.PH
+"addq.ph r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_ph_op (SD_, RD, RS, RT, 0, 0);
+}
+
+000000,5.RT,5.RS,5.RD,10000,001101:POOL32A:32::ADDQ_S.PH
+"addq_s.ph r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_ph_op (SD_, RD, RS, RT, 0, 1);
+}
+
+000000,5.RT,5.RS,5.RD,01100,000101:POOL32A:32::ADDQ_S.W
+"addq_s.w r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_w_op (SD_, RD, RS, RT, 0);
+}
+
+000000,5.RT,5.RS,5.RD,00001,001101:POOL32A:32::ADDQH.PH
+"addqh.ph r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qh_ph_op (SD_, RD, RS, RT, 0, 0);
+}
+
+000000,5.RT,5.RS,5.RD,10001,001101:POOL32A:32::ADDQH_R.PH
+"addqh_r.ph r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qh_ph_op (SD_, RD, RS, RT, 0, 1);
+}
+
+000000,5.RT,5.RS,5.RD,00010,001101:POOL32A:32::ADDQH.W
+"addqh.w r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qh_w_op (SD_, RD, RS, RT, 0, 0);
+}
+
+000000,5.RT,5.RS,5.RD,10010,001101:POOL32A:32::ADDQH_R.W
+"addqh_r.w r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qh_w_op (SD_, RD, RS, RT, 0, 1);
+}
+
+000000,5.RT,5.RS,5.RD,01110,000101:POOL32A:32::ADDSC
+"addsc r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_addsc (SD_, RD, RS, RT);
+}
+
+000000,5.RT,5.RS,5.RD,00100,001101:POOL32A:32::ADDU.PH
+"addu.ph r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_u_ph_op (SD_, RD, RS, RT, 0, 0);
+}
+
+000000,5.RT,5.RS,5.RD,10100,001101:POOL32A:32::ADDU_S.PH
+"addu_s.ph r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_u_ph_op (SD_, RD, RS, RT, 0, 1);
+}
+
+000000,5.RT,5.RS,5.RD,00011,001101:POOL32A:32::ADDU.QB
+"addu.qb r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qb_op (SD_, RD, RS, RT, 0, 0);
+}
+
+000000,5.RT,5.RS,5.RD,10011,001101:POOL32A:32::ADDU_S.QB
+"addu_s.qb r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qb_op (SD_, RD, RS, RT, 0, 1);
+}
+
+000000,5.RT,5.RS,5.RD,01111,000101:POOL32A:32::ADDWC
+"addwc r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_addwc (SD_, RD, RS, RT);
+}
+
+000000,5.RT,5.RS,5.RD,00101,001101:POOL32A:32::ADDUH.QB
+"adduh.qb r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_uh_qb_op (SD_, RD, RS, RT, 0, 0);
+}
+
+000000,5.RT,5.RS,5.RD,10101,001101:POOL32A:32::ADDUH_R.QB
+"adduh_r.qb r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_uh_qb_op (SD_, RD, RS, RT, 0, 1);
+}
+
+000000,5.RT,5.RS,5.SA,01000,010101:POOL32A:32::APPEND
+"append r<RT>, r<RS>, <SA>"
+*micromipsdsp:
+{
+  do_append (SD_, RT, RS, SA);
+}
+
+000000,5.RT,5.RS,2.BP,00100010,111100:POOL32A:32::BALIGN
+"balign r<RT>, r<RS>, <BP>"
+*micromipsdsp:
+{
+  do_balign (SD_, RT, RS, BP);
+}
+
+000000,5.RT,5.RS,0011000100,111100:POOL32A:32::BITREV
+"bitrev r<RT>, r<RS>"
+*micromipsdsp:
+{
+  do_bitrev (SD_, RT, RS);
+}
+
+010000,1101100000,16.IMMEDIATE:POOL32I:32::BPOSGE32
+"bposge32 <IMMEDIATE>"
+*micromipsdsp:
+{
+  unsigned32 pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
+  if (pos >= 32)
+    NIA = delayslot_micromips (SD_, NIA + (EXTEND12 (IMMEDIATE) << 1), NIA,
+                              MICROMIPS_DELAYSLOT_SIZE_ANY);
+}
+
+000000,5.RT,5.RS,0000000000,000101:POOL32A:32::CMP.EQ.PH
+"cmp.eq.ph r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_ph_cmpu (SD_, RS, RT, 0);
+}
+
+000000,5.RT,5.RS,0000000001,000101:POOL32A:32::CMP.LT.PH
+"cmp.lt.ph r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_ph_cmpu (SD_, RS, RT, 1);
+}
+
+000000,5.RT,5.RS,0000000010,000101:POOL32A:32::CMP.LE.PH
+"cmp.le.ph r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_ph_cmpu (SD_, RS, RT, 2);
+}
+
+000000,5.RT,5.RS,5.RD,00110,000101:POOL32A:32::CMPGDU.EQ.QB
+"cmpgdu.eq.qb r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qb_cmpgdu (SD_, RD, RS, RT, 0);
+}
+
+000000,5.RT,5.RS,5.RD,00111,000101:POOL32A:32::CMPGDU.LT.QB
+"cmpgdu.lt.qb r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qb_cmpgdu (SD_, RD, RS, RT, 1);
+}
+
+000000,5.RT,5.RS,5.RD,01000,000101:POOL32A:32::CMPGDU.LE.QB
+"cmpgdu.le.qb r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qb_cmpgdu (SD_, RD, RS, RT, 2);
+}
+
+000000,5.RT,5.RS,5.RD,00011,000101:POOL32A:32::CMPGU.EQ.QB
+"cmpgu.eq.qb r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qb_cmpgu (SD_, RD, RS, RT, 0);
+}
+
+000000,5.RT,5.RS,5.RD,00100,000101:POOL32A:32::CMPGU.LT.QB
+"cmpgu.lt.qb r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qb_cmpgu (SD_, RD, RS, RT, 1);
+}
+
+000000,5.RT,5.RS,5.RD,00101,000101:POOL32A:32::CMPGU.LE.QB
+"cmpgu.le.qb r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qb_cmpgu (SD_, RD, RS, RT, 2);
+}
+
+000000,5.RT,5.RS,0000001001,000101:POOL32A:32::CMPU.EQ.QB
+"cmpu.eq.qb r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qb_cmpu (SD_, RS, RT, 0);
+}
+
+000000,5.RT,5.RS,0000001010,000101:POOL32A:32::CMPU.LT.QB
+"cmpu.lt.qb r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qb_cmpu (SD_, RS, RT, 1);
+}
+
+000000,5.RT,5.RS,0000001011,000101:POOL32A:32::CMPU.LE.QB
+"cmpu.le.qb r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qb_cmpu (SD_, RS, RT, 2);
+}
+
+000000,5.RT,5.RS,2.AC,00000010,111100:POOL32A:32::DPA.W.PH
+"dpa.w.ph ac<AC>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_w_ph_dot_product (SD_, AC, RS, RT, 0);
+}
+
+000000,5.RT,5.RS,2.AC,00001010,111100:POOL32A:32::DPAQ_S.W.PH
+"dpaq_s.w.ph ac<AC>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_ph_dot_product (SD_, AC, RS, RT, 0);
+}
+
+000000,5.RT,5.RS,2.AC,01001010,111100:POOL32A:32::DPAQ_SA.L.W
+"dpaq_sa.l.w ac<AC>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_w_dot_product (SD_, AC, RS, RT, 0);
+}
+
+000000,5.RT,5.RS,2.AC,10001010,111100:POOL32A:32::DPAQX_S.W.PH
+"dpaqx_s.w.ph ac<AC>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qx_w_ph_dot_product (SD_, AC, RS, RT, 0, 0);
+}
+
+000000,5.RT,5.RS,2.AC,11001010,111100:POOL32A:32::DPAQX_SA.W.PH
+"dpaqx_sa.w.ph ac<AC>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qx_w_ph_dot_product (SD_, AC, RS, RT, 0, 1);
+}
+
+000000,5.RT,5.RS,2.AC,10000010,111100:POOL32A:32::DPAU.H.QBL
+"dpau.h.qbl ac<AC>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qb_dot_product (SD_, AC, RS, RT, 0, 0);
+}
+
+000000,5.RT,5.RS,2.AC,11000010,111100:POOL32A:32::DPAU.H.QBR
+"dpau.h.qbr ac<AC>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qb_dot_product (SD_, AC, RS, RT, 0, 1);
+}
+
+000000,5.RT,5.RS,2.AC,01000010,111100:POOL32A:32::DPAX.W.PH
+"dpax.w.ph ac<AC>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_x_w_ph_dot_product (SD_, AC, RS, RT, 0);
+}
+
+000000,5.RT,5.RS,2.AC,00010010,111100:POOL32A:32::DPS.W.PH
+"dps.w.ph ac<AC>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_w_ph_dot_product (SD_, AC, RS, RT, 1);
+}
+
+000000,5.RT,5.RS,2.AC,00011010,111100:POOL32A:32::DPSQ_S.W.PH
+"dpsq_s.w.ph ac<AC>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_ph_dot_product (SD_, AC, RS, RT, 1);
+}
+
+000000,5.RT,5.RS,2.AC,01011010,111100:POOL32A:32::DPSQ_SA.L.W
+"dpsq_sa.l.w ac<AC>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_w_dot_product (SD_, AC, RS, RT, 1);
+}
+
+000000,5.RT,5.RS,2.AC,10011010,111100:POOL32A:32::DPSQX_S.W.PH
+"dpsqx_s.w.ph ac<AC>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qx_w_ph_dot_product (SD_, AC, RS, RT, 1, 0);
+}
+
+000000,5.RT,5.RS,2.AC,11011010,111100:POOL32A:32::DPSQX_SA.W.PH
+"dpsqx_sa.w.ph ac<AC>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qx_w_ph_dot_product (SD_, AC, RS, RT, 1, 1);
+}
+
+000000,5.RT,5.RS,2.AC,10010010,111100:POOL32A:32::DPSU.H.QBL
+"dpsu.h.qbl ac<AC>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qb_dot_product (SD_, AC, RS, RT, 1, 0);
+}
+
+000000,5.RT,5.RS,2.AC,11010010,111100:POOL32A:32::DPSU.H.QBR
+"dpsu.h.qbr ac<AC>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qb_dot_product (SD_, AC, RS, RT, 1, 1);
+}
+
+000000,5.RT,5.RS,2.AC,01010010,111100:POOL32A:32::DPSX.W.PH
+"dpsx.w.ph ac<AC>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_x_w_ph_dot_product (SD_, AC, RS, RT, 1);
+}
+
+000000,5.RT,5.SIZE,2.AC,10011001,111100:POOL32A:32::EXTP
+"extp r<RT>, ac<AC>, <SIZE>"
+*micromipsdsp:
+{
+  do_extp (SD_, RT, AC, SIZE, 0);
+}
+
+000000,5.RT,5.SIZE,2.AC,11011001,111100:POOL32A:32::EXTPDP
+"extpdp r<RT>, ac<AC>, <SIZE>"
+*micromipsdsp:
+{
+  do_extp (SD_, RT, AC, SIZE, 1);
+}
+
+000000,5.RT,5.RS,2.AC,11100010,111100:POOL32A:32::EXTPDPV
+"extpdpv r<RT>, ac<AC>, r<RS>"
+*micromipsdsp:
+{
+  do_extpv (SD_, RT, AC, RS, 1);
+}
+
+000000,5.RT,5.RS,2.AC,10100010,111100:POOL32A:32::EXTPV
+"extpv r<RT>, ac<AC>, r<RS>"
+*micromipsdsp:
+{
+  do_extpv (SD_, RT, AC, RS, 0);
+}
+
+000000,5.RT,5.SHIFT,2.AC,00111001,111100:POOL32A:32::EXTR.W
+"extr.w r<RT>, ac<AC>, <SHIFT>"
+*micromipsdsp:
+{
+  do_w_extr (SD_, RT, AC, SHIFT, 0);
+}
+
+000000,5.RT,5.SHIFT,2.AC,01111001,111100:POOL32A:32::EXTR_R.W
+"extr_r.w r<RT>, ac<AC>, <SHIFT>"
+*micromipsdsp:
+{
+  do_w_extr (SD_, RT, AC, SHIFT, 1);
+}
+
+000000,5.RT,5.SHIFT,2.AC,10111001,111100:POOL32A:32::EXTR_RS.W
+"extr_rs.w r<RT>, ac<AC>, <SHIFT>"
+*micromipsdsp:
+{
+  do_w_extr (SD_, RT, AC, SHIFT, 2);
+}
+
+000000,5.RT,5.SHIFT,2.AC,11111001,111100:POOL32A:32::EXTR_S.H
+"extr_s.h r<RT>, ac<AC>, <SHIFT>"
+*micromipsdsp:
+{
+  do_h_extr (SD_, RT, AC, SHIFT);
+}
+
+000000,5.RT,5.RS,2.AC,00111010,111100:POOL32A:32::EXTRV.W
+"extrv.w r<RT>, ac<AC>, r<RS>"
+*micromipsdsp:
+{
+  do_extrv (SD_, RT, AC, RS, 0);
+}
+
+000000,5.RT,5.RS,2.AC,01111010,111100:POOL32A:32::EXTRV_R.W
+"extrv_r.w r<RT>, ac<AC>, r<RS>"
+*micromipsdsp:
+{
+  do_extrv (SD_, RT, AC, RS, 1);
+}
+
+000000,5.RT,5.RS,2.AC,10111010,111100:POOL32A:32::EXTRV_RS.W
+"extrv_rs.w r<RT>, ac<AC>, r<RS>"
+*micromipsdsp:
+{
+  do_extrv (SD_, RT, AC, RS, 2);
+}
+
+000000,5.RT,5.RS,2.AC,11111010,111100:POOL32A:32::EXTRV_S.H
+"extrv_s.h r<RT>, ac<AC>, r<RS>"
+*micromipsdsp:
+{
+  do_extrv_s_h (SD_, RT, AC, RS);
+}
+
+000000,5.RT,5.RS,0100000100,111100:POOL32A:32::INSV
+"insv r<RT>, r<RS>"
+*micromipsdsp:
+{
+  do_insv (SD_, RT, RS);
+}
+
+000000,5.INDEX,5.BASE,5.RD,01000,100101:POOL32A:32::LBUX
+"lbux r<RD>, r<INDEX>(r<BASE>)"
+*micromipsdsp:
+{
+  do_lxx (SD_, RD, BASE, INDEX, 0);
+}
+
+000000,5.INDEX,5.BASE,5.RD,00101,100101:POOL32A:32::LHX
+"lhx r<RD>, r<INDEX>(r<BASE>)"
+*micromipsdsp:
+{
+  do_lxx (SD_, RD, BASE, INDEX, 1);
+}
+
+000000,5.INDEX,5.BASE,5.RD,00110,100101:POOL32A:32::LWX
+"lwx r<RD>, r<INDEX>(r<BASE>)"
+*micromipsdsp:
+{
+  do_lxx (SD_, RD, BASE, INDEX, 2);
+}
+
+000000,5.RT,5.RS,2.AC,00101010,111100:POOL32A:32::MADD_DSP
+"madd ac<AC>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_dsp_madd (SD_, AC, RS, RT);
+}
+
+000000,5.RT,5.RS,2.AC,01101010,111100:POOL32A:32::MADDU_DSP
+"maddu ac<AC>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_dsp_maddu (SD_, AC, RS, RT);
+}
+
+000000,5.RT,5.RS,2.AC,01101001,111100:POOL32A:32::MAQ_S.W.PHL
+"maq_s.w.phl ac<AC>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_ph_maq (SD_, AC, RS, RT, 0, 0);
+}
+
+000000,5.RT,5.RS,2.AC,11101001,111100:POOL32A:32::MAQ_SA.W.PHL
+"maq_sa.w.phl ac<AC>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_ph_maq (SD_, AC, RS, RT, 1, 0);
+}
+
+000000,5.RT,5.RS,2.AC,00101001,111100:POOL32A:32::MAQ_S.W.PHR
+"maq_s.w.phr ac<AC>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_ph_maq (SD_, AC, RS, RT, 0, 1);
+}
+
+000000,5.RT,5.RS,2.AC,10101001,111100:POOL32A:32::MAQ_SA.W.PHR
+"maq_sa.w.phr ac<AC>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_ph_maq (SD_, AC, RS, RT, 1, 1);
+}
+
+000000,00000,5.RS,2.AC,00000001,111100:POOL32A:32::MFHI_DSP
+"mfhi r<RS>, ac<AC>"
+*micromipsdsp:
+{
+  do_dsp_mfhi (SD_, AC, RS);
+}
+
+000000,00000,5.RS,2.AC,01000001,111100:POOL32A:32::MFLO_DSP
+"mflo r<RS>, ac<AC>"
+*micromipsdsp:
+{
+  do_dsp_mflo (SD_, AC, RS);
+}
+
+000000,5.RT,5.RS,5.RD,01010,010101:POOL32A:32::MODSUB
+"modsub r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_modsub (SD_, RD, RS, RT);
+}
+
+000000,5.RT,5.RS,2.AC,10101010,111100:POOL32A:32::MSUB_DSP
+"msub ac<AC>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_dsp_msub (SD_, AC, RS, RT);
+}
+
+000000,5.RT,5.RS,2.AC,11101010,111100:POOL32A:32::MSUBU_DSP
+"msubu ac<AC>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_dsp_msubu (SD_, AC, RS, RT);
+}
+
+000000,00000,5.RS,2.AC,10000001,111100:POOL32A:32::MTHI_DSP
+"mthi r<RS>, ac<AC>"
+*micromipsdsp:
+{
+  do_dsp_mthi (SD_, AC, RS);
+}
+
+000000,00000,5.RS,2.AC,00001001,111100:POOL32A:32::MTHLIP
+"mthlip r<RS>, ac<AC>"
+*micromipsdsp:
+{
+  do_mthlip (SD_, RS, AC);
+}
+
+000000,00000,5.RS,2.AC,11000001,111100:POOL32A:32::MTLO_DSP
+"mtlo r<RS>, ac<AC>"
+*micromipsdsp:
+{
+  do_dsp_mtlo (SD_, AC, RS);
+}
+
+000000,5.RT,5.RS,5.RD,00000,101101:POOL32A:32::MUL.PH
+"mul.ph r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_ph_op (SD_, RD, RS, RT, 2, 0);
+}
+
+000000,5.RT,5.RS,5.RD,10000,101101:POOL32A:32::MUL_S.PH
+"mul_s.ph r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_ph_op (SD_, RD, RS, RT, 2, 1);
+}
+
+000000,5.RT,5.RS,5.RD,00000,100101:POOL32A:32::MULEQ_S.W.PHL
+"muleq_s.w.phl r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_ph_muleq (SD_, RD, RS, RT, 0);
+}
+
+000000,5.RT,5.RS,5.RD,00001,100101:POOL32A:32::MULEQ_S.W.PHR
+"muleq_s.w.phr r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_ph_muleq (SD_, RD, RS, RT, 1);
+}
+
+000000,5.RT,5.RS,5.RD,00010,010101:POOL32A:32::MULEU_S.PH.QBL
+"muleu_s.ph.qbl r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qb_muleu (SD_, RD, RS, RT, 0);
+}
+
+000000,5.RT,5.RS,5.RD,00011,010101:POOL32A:32::MULEU_S.PH.QBR
+"muleu_s.ph.qbr r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qb_muleu (SD_, RD, RS, RT, 1);
+}
+
+000000,5.RT,5.RS,5.RD,00100,010101:POOL32A:32::MULQ_RS.PH
+"mulq_rs.ph r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_ph_mulq (SD_, RD, RS, RT, 1);
+}
+
+000000,5.RT,5.RS,5.RD,00110,010101:POOL32A:32::MULQ_RS.W
+"mulq_rs.w r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_w_mulq (SD_, RD, RS, RT, 1);
+}
+
+000000,5.RT,5.RS,5.RD,00101,010101:POOL32A:32::MULQ_S.PH
+"mulq_s.ph r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_ph_mulq (SD_, RD, RS, RT, 0);
+}
+
+000000,5.RT,5.RS,5.RD,00111,010101:POOL32A:32::MULQ_S.W
+"mulq_s.w r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_w_mulq (SD_, RD, RS, RT, 0);
+}
+
+000000,5.RT,5.RS,2.AC,10110010,111100:POOL32A:32::MULSA.W.PH
+"mulsa.w.ph ac<AC>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_ph_w_mulsa (SD_, AC, RS, RT);
+}
+
+000000,5.RT,5.RS,2.AC,11110010,111100:POOL32A:32::MULSAQ_S.W.PH
+"mulsaq_s.w.ph ac<AC>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_mulsaq_s_w_ph (SD_, AC, RS, RT);
+}
+
+000000,5.RT,5.RS,2.AC,00110010,111100:POOL32A:32::MULT_DSP
+"mult ac<AC>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_dsp_mult (SD_, AC, RS, RT);
+}
+
+000000,5.RT,5.RS,2.AC,01110010,111100:POOL32A:32::MULTU_DSP
+"multu ac<AC>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_dsp_multu (SD_, AC, RS, RT);
+}
+
+000000,5.RT,5.RS,5.RD,00110,101101:POOL32A:32::PACKRL.PH
+"packrl.ph r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_ph_packrl (SD_, RD, RS, RT);
+}
+
+000000,5.RT,5.RS,5.RD,01000,101101:POOL32A:32::PICK.PH
+"pick.ph r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_ph_pick (SD_, RD, RS, RT);
+}
+
+000000,5.RT,5.RS,5.RD,00111,101101:POOL32A:32::PICK.QB
+"pick.qb r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qb_pick (SD_, RD, RS, RT);
+}
+
+000000,5.RT,5.RS,0101000100,111100:POOL32A:32::PRECEQ.W.PHL
+"preceq.w.phl r<RT>, r<RS>"
+*micromipsdsp:
+{
+  do_w_preceq (SD_, RT, RS, 0);
+}
+
+000000,5.RT,5.RS,0110000100,111100:POOL32A:32::PRECEQ.W.PHR
+"preceq.w.phr r<RT>, r<RS>"
+*micromipsdsp:
+{
+  do_w_preceq (SD_, RT, RS, 1);
+}
+
+000000,5.RT,5.RS,0111000100,111100:POOL32A:32::PRECEQU.PH.QBL
+"precequ.ph.qbl r<RT>, r<RS>"
+*micromipsdsp:
+{
+  do_qb_ph_precequ (SD_, RT, RS, 2);
+}
+
+000000,5.RT,5.RS,0111001100,111100:POOL32A:32::PRECEQU.PH.QBLA
+"precequ.ph.qbla r<RT>, r<RS>"
+*micromipsdsp:
+{
+  do_qb_ph_precequ (SD_, RT, RS, 3);
+}
+
+000000,5.RT,5.RS,1001000100,111100:POOL32A:32::PRECEQU.PH.QBR
+"precequ.ph.qbr r<RT>, r<RS>"
+*micromipsdsp:
+{
+  do_qb_ph_precequ (SD_, RT, RS, 0);
+}
+
+000000,5.RT,5.RS,1001001100,111100:POOL32A:32::PRECEQU.PH.QBRA
+"precequ.ph.qbra r<RT>, r<RS>"
+*micromipsdsp:
+{
+  do_qb_ph_precequ (SD_, RT, RS, 1);
+}
+
+000000,5.RT,5.RS,1011000100,111100:POOL32A:32::PRECEU.PH.QBL
+"preceu.ph.qbl r<RT>, r<RS>"
+*micromipsdsp:
+{
+  do_qb_ph_preceu (SD_, RT, RS, 2);
+}
+
+000000,5.RT,5.RS,1011001100,111100:POOL32A:32::PRECEU.PH.QBLA
+"preceu.ph.qbla r<RT>, r<RS>"
+*micromipsdsp:
+{
+  do_qb_ph_preceu (SD_, RT, RS, 3);
+}
+
+000000,5.RT,5.RS,1101000100,111100:POOL32A:32::PRECEU.PH.QBR
+"preceu.ph.qbr r<RT>, r<RS>"
+*micromipsdsp:
+{
+  do_qb_ph_preceu (SD_, RT, RS, 0);
+}
+
+000000,5.RT,5.RS,1101001100,111100:POOL32A:32::PRECEU.PH.QBRA
+"preceu.ph.qbra r<RT>, r<RS>"
+*micromipsdsp:
+{
+  do_qb_ph_preceu (SD_, RT, RS, 1);
+}
+
+000000,5.RT,5.RS,5.RD,00001,101101:POOL32A:32::PRECR.QB.PH
+"precr.qb.ph r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_ph_qb_precr (SD_, RD, RS, RT);
+}
+
+000000,5.RT,5.RS,5.SA,01111,001101:POOL32A:32::PRECR_SRA.PH.W
+"precr_sra.ph.w r<RT>, r<RS>, <SA>"
+*micromipsdsp:
+{
+  do_precr_sra (SD_, RT, RS, SA, 0);
+}
+
+000000,5.RT,5.RS,5.SA,11111,001101:POOL32A:32::PRECR_SRA_R.PH.W
+"precr_sra_r.ph.w r<RT>, r<RS>, <SA>"
+*micromipsdsp:
+{
+  do_precr_sra (SD_, RT, RS, SA, 1);
+}
+
+000000,5.RT,5.RS,5.RD,00011,101101:POOL32A:32::PRECRQ.PH.W
+"precrq.ph.w r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_w_ph_precrq (SD_, RD, RS, RT);
+}
+
+000000,5.RT,5.RS,5.RD,00010,101101:POOL32A:32::PRECRQ.QB.PH
+"precrq.qb.ph r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_ph_qb_precrq (SD_, RD, RS, RT, 0);
+}
+
+000000,5.RT,5.RS,5.RD,00101,101101:POOL32A:32::PRECRQU_S.QB.PH
+"precrqu_s.qb.ph r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_ph_qb_precrq (SD_, RD, RS, RT, 1);
+}
+
+000000,5.RT,5.RS,5.RD,00100,101101:POOL32A:32::PRECRQ_RS.PH.W
+"precrq_rs.ph.w r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_w_ph_rs_precrq (SD_, RD, RS, RT);
+}
+
+000000,5.RT,5.RS,5.SA,01001,010101:POOL32A:32::PREPEND
+"prepend r<RT>, r<RS>, <SA>"
+*micromipsdsp:
+{
+  do_prepend (SD_, RT, RS, SA);
+}
+
+000000,5.RT,5.RS,1111000100,111100:POOL32A:32::RADDU.W.QB
+"raddu.w.qb r<RT>, r<RS>"
+*micromipsdsp:
+{
+  do_qb_w_raddu (SD_, RT, RS);
+}
+
+000000,5.RT,7.CONTROL_MASK,00011001,111100:POOL32A:32::RDDSP
+"rddsp r<RT>":CONTROL_MASK == 1111111111
+"rddsp r<RT>, <CONTROL_MASK>"
+*micromipsdsp:
+{
+  do_rddsp (SD_, RT, CONTROL_MASK);
+}
+
+000000,10.IMMEDIATE,5.RD,00000,111101:POOL32A:32::REPL.PH
+"repl.ph r<RD>, <IMMEDIATE>"
+*micromipsdsp:
+{
+  do_repl (SD_, RD, IMMEDIATE, 2);
+}
+
+000000,5.RT,8.IMMEDIATE,0010111,111100:POOL32A:32::REPL.QB
+"repl.qb r<RT>, <IMMEDIATE>"
+*micromipsdsp:
+{
+  do_repl (SD_, RT, IMMEDIATE, 0);
+}
+
+000000,5.RT,5.RS,0000001100,111100:POOL32A:32::REPLV.PH
+"replv.ph r<RT>, r<RS>"
+*micromipsdsp:
+{
+  do_repl (SD_, RT, RS, 3);
+}
+
+000000,5.RT,5.RS,0001001100,111100:POOL32A:32::REPLV.QB
+"replv.qb r<RT>, r<RS>"
+*micromipsdsp:
+{
+  do_repl (SD_, RT, RS, 1);
+}
+
+000000,0000,6.IMMEDIATE,2.AC,00000000,011101:POOL32A:32::SHILO
+"shilo ac<AC>, <IMMEDIATE>"
+*micromipsdsp:
+{
+  do_shilo (SD_, AC, IMMEDIATE);
+}
+
+000000,00000,5.RS,2.AC,01001001,111100:POOL32A:32::SHILOV
+"shilov ac<AC>, r<RS>"
+*micromipsdsp:
+{
+  do_shilov (SD_, AC, RS);
+}
+
+000000,5.RT,5.RS,4.SHIFT,001110,110101:POOL32A:32::SHLL.PH
+"shll.ph r<RT>, r<RS>, <SHIFT>"
+*micromipsdsp:
+{
+  do_ph_shift (SD_, RT, RS, SHIFT, 0, 0);
+}
+
+000000,5.RT,5.RS,4.SHIFT,101110,110101:POOL32A:32::SHLL_S.PH
+"shll_s.ph r<RT>, r<RS>, <SHIFT>"
+*micromipsdsp:
+{
+  do_ph_shift (SD_, RT, RS, SHIFT, 0, 1);
+}
+
+000000,5.RT,5.RS,3.SHIFT,0100001,111100:POOL32A:32::SHLL.QB
+"shll.qb r<RT>, r<RS>, <SHIFT>"
+*micromipsdsp:
+{
+  do_qb_shift (SD_, RT, RS, SHIFT, 0);
+}
+
+000000,5.RT,5.RS,5.RD,01110,001101:POOL32A:32::SHLLV.PH
+"shllv.ph r<RD>, r<RT>, r<RS>"
+*micromipsdsp:
+{
+  do_ph_shl (SD_, RD, RT, RS, 0, 0);
+}
+
+000000,5.RT,5.RS,5.RD,11110,001101:POOL32A:32::SHLLV_S.PH
+"shllv_s.ph r<RD>, r<RD>, r<RS>"
+*micromipsdsp:
+{
+  do_ph_shl (SD_, RD, RT, RS, 0, 1);
+}
+
+000000,5.RT,5.RS,5.RD,01110,010101:POOL32A:32::SHLLV.QB
+"shllv.qb r<RD>, r<RT>, r<RS>"
+*micromipsdsp:
+{
+  do_qb_shl (SD_, RD, RT, RS, 0);
+}
+
+000000,5.RT,5.RS,5.RD,01111,010101:POOL32A:32::SHLLV_S.W
+"shllv_s.w r<RD>, r<RT>, r<RS>"
+*micromipsdsp:
+{
+  do_w_s_shllv (SD_, RD, RT, RS);
+}
+
+000000,5.RT,5.RS,5.SHIFT,01111,110101:POOL32A:32::SHLL_S.W
+"shll_s.w r<RT>, r<RS>, <SHIFT>"
+*micromipsdsp:
+{
+  do_w_shll (SD_, RT, RS, SHIFT);
+}
+
+000000,5.RT,5.RS,3.SHIFT,0000111,111100:POOL32A:32::SHRA.QB
+"shra.qb r<RT>, r<RS>, <SHIFT>"
+*micromipsdsp:
+{
+  do_qb_shra (SD_, RT, RS, SHIFT, 0);
+}
+
+000000,5.RT,5.RS,3.SHIFT,1000111,111100:POOL32A:32::SHRA_R.QB
+"shra_r.qb r<RT>, r<RS>, <SHIFT>"
+*micromipsdsp:
+{
+  do_qb_shra (SD_, RT, RS, SHIFT, 1);
+}
+
+000000,5.RT,5.RS,4.SHIFT,001100,110101:POOL32A:32::SHRA.PH
+"shra.ph r<RT>, r<RS>, <SHIFT>"
+*micromipsdsp:
+{
+  do_ph_shift (SD_, RT, RS, SHIFT, 1, 0);
+}
+
+000000,5.RT,5.RS,4.SHIFT,011100,110101:POOL32A:32::SHRA_R.PH
+"shra_r.ph r<RT>, r<RS>, <SHIFT>"
+*micromipsdsp:
+{
+  do_ph_shift (SD_, RT, RS, SHIFT, 1, 1);
+}
+
+000000,5.RT,5.RS,5.RD,00110,001101:POOL32A:32::SHRAV.PH
+"shrav.ph r<RD>, r<RT>, r<RS>"
+*micromipsdsp:
+{
+  do_ph_shl (SD_, RD, RT, RS, 1, 0);
+}
+
+000000,5.RT,5.RS,5.RD,10110,001101:POOL32A:32::SHRAV_R.PH
+"shrav_r.ph r<RD>, r<RT>, r<RS>"
+*micromipsdsp:
+{
+  do_ph_shl (SD_, RD, RT, RS, 1, 1);
+}
+
+000000,5.RT,5.RS,5.RD,00111,001101:POOL32A:32::SHRAV.QB
+"shrav.qb r<RD>, r<RT>, r<RS>"
+*micromipsdsp:
+{
+  do_qb_shrav (SD_, RD, RT, RS, 0);
+}
+
+000000,5.RT,5.RS,5.RD,10111,001101:POOL32A:32::SHRAV_R.QB
+"shrav_r.qb r<RD>, r<RT>, r<RS>"
+*micromipsdsp:
+{
+  do_qb_shrav (SD_, RD, RT, RS, 1);
+}
+
+000000,5.RT,5.RS,5.RD,01011,010101:POOL32A:32::SHRAV_R.W
+"shrav_r.w r<RD>, r<RT>, r<RS>"
+*micromipsdsp:
+{
+  do_w_r_shrav (SD_, RD, RT, RS);
+}
+
+000000,5.RT,5.RS,5.SHIFT,01011,110101:POOL32A:32::SHRA_R.W
+"shra_r.w r<RT>, r<RS>, <SHIFT>"
+*micromipsdsp:
+{
+  do_w_shra (SD_, RT, RS, SHIFT);
+}
+
+000000,5.RT,5.RS,4.SHIFT,001111,111100:POOL32A:32::SHRL.PH
+"shrl.ph r<RT>, r<RS>, <SHIFT>"
+*micromipsdsp:
+{
+  do_ph_shrl (SD_, RT, RS, SHIFT);
+}
+
+000000,5.RT,5.RS,3.SHIFT,1100001,111100:POOL32A:32::SHRL.QB
+"shrl.qb r<RT>, r<RS>, <SHIFT>"
+*micromipsdsp:
+{
+  do_qb_shift (SD_, RT, RS, SHIFT, 1);
+}
+
+000000,5.RT,5.RS,5.RD,01100,010101:POOL32A:32::SHRLV.PH
+"shrlv.ph r<RD>, r<RT>, r<RS>"
+*micromipsdsp:
+{
+  do_ph_shrlv (SD_, RD, RT, RS);
+}
+
+000000,5.RT,5.RS,5.RD,01101,010101:POOL32A:32::SHRLV.QB
+"shrlv.qb r<RD>, r<RT>, r<RS>"
+*micromipsdsp:
+{
+  do_qb_shl (SD_, RD, RT, RS, 1);
+}
+
+000000,5.RT,5.RS,5.RD,01000,001101:POOL32A:32::SUBQ.PH
+"subq.ph r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_ph_op (SD_, RD, RS, RT, 1, 0);
+}
+
+000000,5.RT,5.RS,5.RD,11000,001101:POOL32A:32::SUBQ_S.PH
+"subq_s.ph r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_ph_op (SD_, RD, RS, RT, 1, 1);
+}
+
+000000,5.RT,5.RS,5.RD,01101,000101:POOL32A:32::SUBQ_S.W
+"subq_s.w r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_w_op (SD_, RD, RS, RT, 1);
+}
+
+000000,5.RT,5.RS,5.RD,01001,001101:POOL32A:32::SUBQH.PH
+"subqh.ph r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qh_ph_op (SD_, RD, RS, RT, 1, 0);
+}
+
+000000,5.RT,5.RS,5.RD,11001,001101:POOL32A:32::SUBQH_R.PH
+"subqh_r.ph r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qh_ph_op (SD_, RD, RS, RT, 1, 1);
+}
+
+000000,5.RT,5.RS,5.RD,01010,001101:POOL32A:32::SUBQH.W
+"subqh.w r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qh_w_op (SD_, RD, RS, RT, 1, 0);
+}
+
+000000,5.RT,5.RS,5.RD,11010,001101:POOL32A:32::SUBQH_R.W
+"subqh_r.w r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qh_w_op (SD_, RD, RS, RT, 1, 1);
+}
+
+000000,5.RT,5.RS,5.RD,01100,001101:POOL32A:32::SUBU.PH
+"subu.ph r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_u_ph_op (SD_, RD, RS, RT, 1, 0);
+}
+
+000000,5.RT,5.RS,5.RD,11100,001101:POOL32A:32::SUBU_S.PH
+"subu_s.ph r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_u_ph_op (SD_, RD, RS, RT, 1, 1);
+}
+
+000000,5.RT,5.RS,5.RD,01011,001101:POOL32A:32::SUBU.QB
+"subu.qb r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qb_op (SD_, RD, RS, RT, 1, 0);
+}
+
+000000,5.RT,5.RS,5.RD,11011,001101:POOL32A:32::SUBU_S.QB
+"subu_s.qb r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_qb_op (SD_, RD, RS, RT, 1, 1);
+}
+
+000000,5.RT,5.RS,5.RD,01101,001101:POOL32A:32::SUBUH.QB
+"subuh.qb r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_uh_qb_op (SD_, RD, RS, RT, 1, 0);
+}
+
+000000,5.RT,5.RS,5.RD,11101,001101:POOL32A:32::SUBUH_R.QB
+"subuh_r.qb r<RD>, r<RS>, r<RT>"
+*micromipsdsp:
+{
+  do_uh_qb_op (SD_, RD, RS, RT, 1, 1);
+}
+
+000000,5.RT,7.CONTROL_MASK,01011001,111100:POOL32A:32::WRDSP
+"wrdsp r<RT>":CONTROL_MASK == 1111111111
+"wrdsp r<RT>, <CONTROL_MASK>"
+*micromipsdsp:
+{
+  do_wrdsp (SD_, RT, CONTROL_MASK);
+}
diff --git a/sim/mips/micromipsrun.c b/sim/mips/micromipsrun.c
new file mode 100644 (file)
index 0000000..c39138b
--- /dev/null
@@ -0,0 +1,135 @@
+/*  Run function for the micromips simulator
+
+    Copyright (C) 2005-2015 Free Software Foundation, Inc.
+    Contributed by Imagination Technologies, Ltd.
+    Written by Andrew Bennett <andrew.bennett@imgtec.com>.
+
+    This file is part of the MIPS sim.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "sim-main.h"
+#include "micromips16_idecode.h"
+#include "micromips32_idecode.h"
+#include "micromips_m32_idecode.h"
+#include "bfd.h"
+#include "sim-engine.h"
+
+/* These definitions come from the *_support.h files generated by igen and are
+   required because they are used in some of the macros in the code below.
+   Unfortunately we can not just blindly include the *_support.h files to get
+   these definitions because some of the defines in these files are specific
+   for a particular configuration of the simulator for example instruction word
+   size is 16 bits for micromips16 and 32 bits for micromips32.  This means we
+   could break future code changes by doing this, so a safer approach is to just
+   extract the defines that we need to get this file to compile.  */
+#define SD sd
+#define CPU cpu
+
+address_word
+micromips_instruction_decode (SIM_DESC sd, sim_cpu * cpu,
+                             address_word cia,
+                             int instruction_size)
+{
+  if (instruction_size == MICROMIPS_DELAYSLOT_SIZE_ANY)
+    {
+      micromips16_instruction_word instruction_0 = IMEM16_MICROMIPS (cia);
+      if (MICROMIPS_MINOR_OPCODE (instruction_0) > 0
+         && MICROMIPS_MINOR_OPCODE (instruction_0) < 4)
+       return micromips16_idecode_issue (sd, instruction_0, cia);
+      else
+       {
+         micromips32_instruction_word instruction_0 = IMEM32_MICROMIPS (cia);
+         return micromips32_idecode_issue (sd, instruction_0, cia);
+       }
+    }
+  else if (instruction_size == MICROMIPS_DELAYSLOT_SIZE_16)
+    {
+      micromips16_instruction_word instruction_0 = IMEM16_MICROMIPS (cia);
+      if (MICROMIPS_MINOR_OPCODE (instruction_0) > 0
+         && MICROMIPS_MINOR_OPCODE (instruction_0) < 4)
+       return micromips16_idecode_issue (sd, instruction_0, cia);
+      else
+       sim_engine_abort (sd, cpu, cia,
+                         "Invalid 16 bit micromips instruction");
+    }
+  else if (instruction_size == MICROMIPS_DELAYSLOT_SIZE_32)
+    {
+      micromips32_instruction_word instruction_0 = IMEM32_MICROMIPS (cia);
+      return micromips32_idecode_issue (sd, instruction_0, cia);
+    }
+  else
+    return NULL_CIA;
+}
+
+void
+sim_engine_run (SIM_DESC sd, int next_cpu_nr, int nr_cpus,
+               int signal)
+{
+  micromips_m32_instruction_word instruction_0;
+  sim_cpu *cpu = STATE_CPU (sd, next_cpu_nr);
+  micromips32_instruction_address cia = CPU_PC_GET (cpu);
+  sd->isa_mode = ISA_MODE_MIPS32;
+
+  while (1)
+    {
+      micromips32_instruction_address nia;
+
+      /* Allow us to switch back from MIPS32 to microMIPS
+        This covers two cases:
+        1. Setting the correct isa mode based on the start address
+        from the elf header.
+        2. Setting the correct isa mode after a MIPS32 jump or branch
+        instruction.  */
+      if ((sd->isa_mode == ISA_MODE_MIPS32)
+         && ((cia & 0x1) == ISA_MODE_MICROMIPS))
+       {
+         sd->isa_mode = ISA_MODE_MICROMIPS;
+         cia = cia & ~0x1;
+       }
+
+#if defined (ENGINE_ISSUE_PREFIX_HOOK)
+      ENGINE_ISSUE_PREFIX_HOOK ();
+#endif
+      switch (sd->isa_mode)
+       {
+       case ISA_MODE_MICROMIPS:
+         nia =
+           micromips_instruction_decode (sd, cpu, cia,
+                                         MICROMIPS_DELAYSLOT_SIZE_ANY);
+         break;
+       case ISA_MODE_MIPS32:
+         instruction_0 = IMEM32 (cia);
+         nia = micromips_m32_idecode_issue (sd, instruction_0, cia);
+         break;
+       default:
+         nia = NULL_CIA;
+       }
+
+#if defined (ENGINE_ISSUE_POSTFIX_HOOK)
+      ENGINE_ISSUE_POSTFIX_HOOK ();
+#endif
+
+      /* Update the instruction address */
+      cia = nia;
+
+      /* process any events */
+      if (sim_events_tick (sd))
+       {
+         CPU_PC_SET (cpu, cia);
+         sim_events_process (sd);
+         cia = CPU_PC_GET (cpu);
+       }
+    }
+}
index 5a6326fed202936898c1ed1f2b072851a3cc8e09..2862eeb02ea2812d1bbf24e5334e503998cb640a 100644 (file)
@@ -74,6 +74,9 @@
 :model:::dsp:dsp:                      // dsp.igen
 :model:::dsp2:dsp2:                    // dsp2.igen
 :model:::smartmips:smartmips:          // smartmips.igen
+:model:::micromips32:micromips64:      // micromips.igen
+:model:::micromips64:micromips64:      // micromips.igen
+:model:::micromipsdsp:micromipsdsp:    // micromipsdsp.igen
 
 //  Vendor Extensions
 //
@@ -91,7 +94,7 @@
 
 // Pseudo instructions known by interp.c
 // For grep - RSVD_INSTRUCTION, RSVD_INSTRUCTION_MASK
-000000,5.*,5.*,5.*,5.OP,000101:SPECIAL:32::RSVD
+000000,5.*,5.*,5.*,5.OP,111001:SPECIAL:32::RSVD
 "rsvd <OP>"
 {
   SignalException (ReservedInstruction, instruction_0);
 *vr4100:
 *vr5000:
 *r3900:
+*micromips32:
 {
   return base + offset;
 }
 :function:::address_word:loadstore_ea:address_word base, address_word offset
 *mips64:
 *mips64r2:
+*micromips64:
 {
 #if 0 /* XXX FIXME: enable this only after some additional testing.  */
   /* If in user mode and UX is not set, use 32-bit compatibility effective
 *mips32r2:
 *mips64:
 *mips64r2:
+*micromips32:
+*micromips64:
 {
 #if WITH_TARGET_WORD_BITSIZE == 64
   return value != (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
 *mips32r2:
 *mips64:
 *mips64r2:
+*micromips32:
+*micromips64:
 {
   unpredictable_action (CPU, CIA);
 }
 *mips64:
 *mips64r2:
 *r3900:
+*micromips32:
+*micromips64:
 {
   signed64 time = sim_events_time (SD);
   history->mt.timestamp = time;
 *vr4100:
 *vr5000:
 *r3900:
+*micromips32:
+*micromips64:
 {
   signed64 time = sim_events_time (SD);
   int ok = 1;
 *mips64:
 *mips64r2:
 *r3900:
+*micromips32:
+*micromips64:
 {
   /* FIXME: could record the fact that a stall occured if we want */
   signed64 time = sim_events_time (SD);
 *mips32r2:
 *mips64:
 *mips64r2:
+*micromips32:
+*micromips64:
 {
   signed64 time = sim_events_time (SD);
   hi->op.timestamp = time;
 *mips16e:
 *mips64:
 *mips64r2:
+*mips32:
+*mips32r2:
+*micromips64:
+*micromips32:
 {
 #if 0 /* XXX FIXME: enable this only after some additional testing.  */
   if (UserMode && (SR & (status_UX|status_PX)) == 0)
 //
 
 
+:function:::void:do_add:int rs, int rt, int rd
+{
+  if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
+    Unpredictable ();
+  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+  {
+    ALU32_BEGIN (GPR[rs]);
+    ALU32_ADD (GPR[rt]);
+    ALU32_END (GPR[rd]);   /* This checks for overflow.  */
+  }
+  TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_addi:int rs, int rt, unsigned16 immediate
+{
+  if (NotWordValue (GPR[rs]))
+    Unpredictable ();
+  TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
+  {
+    ALU32_BEGIN (GPR[rs]);
+    ALU32_ADD (EXTEND16 (immediate));
+    ALU32_END (GPR[rt]);   /* This checks for overflow.  */
+  }
+  TRACE_ALU_RESULT (GPR[rt]);
+}
+
+:function:::void:do_andi:int rs, int rt, unsigned int immediate
+{
+  TRACE_ALU_INPUT2 (GPR[rs], immediate);
+  GPR[rt] = GPR[rs] & immediate;
+  TRACE_ALU_RESULT (GPR[rt]);
+}
+
+:function:::void:do_dadd:int rd, int rs, int rt
+{
+  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+  {
+    ALU64_BEGIN (GPR[rs]);
+    ALU64_ADD (GPR[rt]);
+    ALU64_END (GPR[rd]);   /* This checks for overflow.  */
+  }
+  TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_daddi:int rt, int rs, int immediate
+{
+  TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
+  {
+    ALU64_BEGIN (GPR[rs]);
+    ALU64_ADD (EXTEND16 (immediate));
+    ALU64_END (GPR[rt]);   /* This checks for overflow.  */
+  }
+  TRACE_ALU_RESULT (GPR[rt]);
+}
+
+:function:::void:do_dsll32:int rd, int rt, int shift
+{
+  int s = 32 + shift;
+  TRACE_ALU_INPUT2 (GPR[rt], s);
+  GPR[rd] = GPR[rt] << s;
+  TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_dsra32:int rd, int rt, int shift
+{
+  int s = 32 + shift;
+  TRACE_ALU_INPUT2 (GPR[rt], s);
+  GPR[rd] = ((signed64) GPR[rt]) >> s;
+  TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_dsrl32:int rd, int rt, int shift
+{
+  int s = 32 + shift;
+  TRACE_ALU_INPUT2 (GPR[rt], s);
+  GPR[rd] = (unsigned64) GPR[rt] >> s;
+  TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_dsub:int rd, int rs, int rt
+{
+  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+  {
+    ALU64_BEGIN (GPR[rs]);
+    ALU64_SUB (GPR[rt]);
+    ALU64_END (GPR[rd]);   /* This checks for overflow.  */
+  }
+  TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_break:address_word instruction_0
+{
+  /* Check for some break instruction which are reserved for use by the
+     simulator.  */
+  unsigned int break_code = instruction_0 & HALT_INSTRUCTION_MASK;
+  if (break_code == (HALT_INSTRUCTION  & HALT_INSTRUCTION_MASK) ||
+      break_code == (HALT_INSTRUCTION2 & HALT_INSTRUCTION_MASK))
+    {
+      sim_engine_halt (SD, CPU, NULL, cia,
+                      sim_exited, (unsigned int)(A0 & 0xFFFFFFFF));
+    }
+  else if (break_code == (BREAKPOINT_INSTRUCTION  & HALT_INSTRUCTION_MASK) ||
+          break_code == (BREAKPOINT_INSTRUCTION2 & HALT_INSTRUCTION_MASK))
+    {
+      if (STATE & simDELAYSLOT)
+       PC = cia - 4; /* reference the branch instruction */
+      else
+       PC = cia;
+      SignalException (BreakPoint, instruction_0);
+    }
+
+  else
+    {
+      /* If we get this far, we're not an instruction reserved by the sim.  Raise
+        the exception. */
+      SignalException (BreakPoint, instruction_0);
+    }
+}
+
+:function:::void:do_break16:address_word instruction_0
+{
+  if (STATE & simDELAYSLOT)
+    PC = cia - 2; /* reference the branch instruction */
+  else
+    PC = cia;
+  SignalException (BreakPoint, instruction_0);
+}
+
+:function:::void:do_clo:int rd, int rs
+{
+  unsigned32 temp = GPR[rs];
+  unsigned32 i, mask;
+  if (NotWordValue (GPR[rs]))
+    Unpredictable ();
+  TRACE_ALU_INPUT1 (GPR[rs]);
+  for (mask = ((unsigned32)1<<31), i = 0; i < 32; ++i)
+    {
+      if ((temp & mask) == 0)
+       break;
+      mask >>= 1;
+    }
+  GPR[rd] = EXTEND32 (i);
+  TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_clz:int rd, int rs
+{
+  unsigned32 temp = GPR[rs];
+  unsigned32 i, mask;
+  if (NotWordValue (GPR[rs]))
+    Unpredictable ();
+  TRACE_ALU_INPUT1 (GPR[rs]);
+  for (mask = ((unsigned32)1<<31), i = 0; i < 32; ++i)
+    {
+      if ((temp & mask) != 0)
+       break;
+      mask >>= 1;
+    }
+  GPR[rd] = EXTEND32 (i);
+  TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_dclo:int rd, int rs
+{
+  unsigned64 temp = GPR[rs];
+  unsigned32 i;
+  unsigned64 mask;
+  TRACE_ALU_INPUT1 (GPR[rs]);
+  for (mask = ((unsigned64)1<<63), i = 0; i < 64; ++i)
+    {
+      if ((temp & mask) == 0)
+       break;
+      mask >>= 1;
+    }
+  GPR[rd] = EXTEND32 (i);
+  TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_dclz:int rd, int rs
+{
+  unsigned64 temp = GPR[rs];
+  unsigned32 i;
+  unsigned64 mask;
+  TRACE_ALU_INPUT1 (GPR[rs]);
+  for (mask = ((unsigned64)1<<63), i = 0; i < 64; ++i)
+    {
+      if ((temp & mask) != 0)
+       break;
+      mask >>= 1;
+    }
+  GPR[rd] = EXTEND32 (i);
+  TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_lb:int rt, int offset, int base
+{
+  GPR[rt] = EXTEND8 (do_load (SD_, AccessLength_BYTE, GPR[base],
+                             EXTEND16 (offset)));
+}
+
+:function:::void:do_lh:int rt, int offset, int base
+{
+  GPR[rt] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[base],
+                              EXTEND16 (offset)));
+}
+
+:function:::void:do_lwr:int rt, int offset, int base
+{
+  GPR[rt] = EXTEND32 (do_load_right (SD_, AccessLength_WORD, GPR[base],
+                                    EXTEND16 (offset), GPR[rt]));
+}
+
+:function:::void:do_lwl:int rt, int offset, int base
+{
+  GPR[rt] = EXTEND32 (do_load_left (SD_, AccessLength_WORD, GPR[base],
+                                   EXTEND16 (offset), GPR[rt]));
+}
+
+:function:::void:do_lwc:int num, int rt, int offset, int base
+{
+  COP_LW (num, rt, do_load (SD_, AccessLength_WORD, GPR[base],
+                           EXTEND16 (offset)));
+}
+
+:function:::void:do_lw:int rt, int offset, int base
+{
+  GPR[rt] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[base],
+                              EXTEND16 (offset)));
+}
+
+:function:::void:do_lwu:int rt, int offset, int base, address_word instruction_0
+{
+  check_u64 (SD_, instruction_0);
+  GPR[rt] = do_load (SD_, AccessLength_WORD, GPR[base], EXTEND16 (offset));
+}
+
+:function:::void:do_lhu:int rt, int offset, int base
+{
+  GPR[rt] = do_load (SD_, AccessLength_HALFWORD, GPR[base], EXTEND16 (offset));
+}
+
+:function:::void:do_ldc:int num, int rt, int offset, int base
+{
+  COP_LD (num, rt, do_load (SD_, AccessLength_DOUBLEWORD, GPR[base],
+                           EXTEND16 (offset)));
+}
+
+:function:::void:do_lbu:int rt, int offset, int base
+{
+  GPR[rt] = do_load (SD_, AccessLength_BYTE, GPR[base], EXTEND16 (offset));
+}
+
+:function:::void:do_ll:int rt, int insn_offset, int basereg
+{
+  address_word base = GPR[basereg];
+  address_word offset = EXTEND16 (insn_offset);
+    {
+      address_word vaddr = loadstore_ea (SD_, base, offset);
+      address_word paddr;
+      int uncached;
+      if ((vaddr & 3) != 0)
+       {
+         SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, read_transfer,
+                          sim_core_unaligned_signal);
+       }
+      else
+       {
+         if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached,
+                                 isTARGET, isREAL))
+           {
+             unsigned64 memval = 0;
+             unsigned64 memval1 = 0;
+             unsigned64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
+             unsigned int shift = 2;
+             unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
+             unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
+             unsigned int byte;
+             paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
+             LoadMemory (&memval, &memval1, uncached, AccessLength_WORD, paddr,
+                        vaddr, isDATA, isREAL);
+             byte = ((vaddr & mask) ^ (bigend << shift));
+             GPR[rt] = EXTEND32 (memval >> (8 * byte));
+             LLBIT = 1;
+           }
+       }
+    }
+}
+
+:function:::void:do_lld:int rt, int roffset, int rbase
+{
+  address_word base = GPR[rbase];
+  address_word offset = EXTEND16 (roffset);
+  {
+    address_word vaddr = loadstore_ea (SD_, base, offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 7) != 0)
+      {
+       SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, read_transfer,
+               sim_core_unaligned_signal);
+      }
+    else
+      {
+       if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached,
+                              isTARGET, isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           LoadMemory (&memval, &memval1, uncached, AccessLength_DOUBLEWORD,
+                       paddr, vaddr, isDATA, isREAL);
+           GPR[rt] = memval;
+           LLBIT = 1;
+         }
+      }
+  }
+}
+
+:function:::void:do_lui:int rt, int immediate
+{
+  TRACE_ALU_INPUT1 (immediate);
+  GPR[rt] = EXTEND32 (immediate << 16);
+  TRACE_ALU_RESULT (GPR[rt]);
+}
+
+:function:::void:do_madd:int rs, int rt
+{
+  signed64 temp;
+  check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
+  if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
+    Unpredictable ();
+  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+  temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
+         + ((signed64) EXTEND32 (GPR[rt]) * (signed64) EXTEND32 (GPR[rs])));
+  LO = EXTEND32 (temp);
+  HI = EXTEND32 (VH4_8 (temp));
+  TRACE_ALU_RESULT2 (HI, LO);
+}
+
+:function:::void:do_dsp_madd:int ac, int rs, int rt
+{
+  signed64 temp;
+  if (ac == 0)
+    check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
+  if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
+    Unpredictable ();
+  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+  temp = (U8_4 (VL4_8 (DSPHI(ac)), VL4_8 (DSPLO(ac)))
+         + ((signed64) EXTEND32 (GPR[rt]) * (signed64) EXTEND32 (GPR[rs])));
+  DSPLO(ac) = EXTEND32 (temp);
+  DSPHI(ac) = EXTEND32 (VH4_8 (temp));
+  if (ac == 0)
+    TRACE_ALU_RESULT2 (HI, LO);
+}
+
+:function:::void:do_maddu:int rs, int rt
+{
+  unsigned64 temp;
+  check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
+  if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
+    Unpredictable ();
+  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+  temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
+         + ((unsigned64) VL4_8 (GPR[rs]) * (unsigned64) VL4_8 (GPR[rt])));
+  ACX += U8_4 (VL4_8 (HI), VL4_8 (LO)) < temp;  /* SmartMIPS */
+  LO = EXTEND32 (temp);
+  HI = EXTEND32 (VH4_8 (temp));
+  TRACE_ALU_RESULT2 (HI, LO);
+}
+
+:function:::void:do_dsp_maddu:int ac, int rs, int rt
+{
+  unsigned64 temp;
+  if (ac == 0)
+    check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
+  if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
+    Unpredictable ();
+  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+  temp = (U8_4 (VL4_8 (DSPHI(ac)), VL4_8 (DSPLO(ac)))
+         + ((unsigned64) VL4_8 (GPR[rs]) * (unsigned64) VL4_8 (GPR[rt])));
+  if (ac == 0)
+    ACX += U8_4 (VL4_8 (HI), VL4_8 (LO)) < temp;  /* SmartMIPS */
+  DSPLO(ac) = EXTEND32 (temp);
+  DSPHI(ac) = EXTEND32 (VH4_8 (temp));
+  if (ac == 0)
+    TRACE_ALU_RESULT2 (HI, LO);
+}
+
+:function:::void:do_dsp_mfhi:int ac, int rd
+{
+  if (ac == 0)
+    do_mfhi (SD_, rd);
+  else
+    GPR[rd] = DSPHI(ac);
+}
+
+:function:::void:do_dsp_mflo:int ac, int rd
+{
+  if (ac == 0)
+    do_mflo (SD_, rd);
+  else
+    GPR[rd] = DSPLO(ac);
+}
+
+:function:::void:do_movn:int rd, int rs, int rt
+{
+  if (GPR[rt] != 0)
+    {
+      GPR[rd] = GPR[rs];
+      TRACE_ALU_RESULT (GPR[rd]);
+    }
+}
+
+:function:::void:do_movz:int rd, int rs, int rt
+{
+  if (GPR[rt] == 0)
+    {
+      GPR[rd] = GPR[rs];
+      TRACE_ALU_RESULT (GPR[rd]);
+    }
+}
+
+:function:::void:do_msub:int rs, int rt
+{
+  signed64 temp;
+  check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
+  if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
+    Unpredictable ();
+  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+  temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
+         - ((signed64) EXTEND32 (GPR[rt]) * (signed64) EXTEND32 (GPR[rs])));
+  LO = EXTEND32 (temp);
+  HI = EXTEND32 (VH4_8 (temp));
+  TRACE_ALU_RESULT2 (HI, LO);
+}
+
+:function:::void:do_dsp_msub:int ac, int rs, int rt
+{
+  signed64 temp;
+  if (ac == 0)
+    check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
+  if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
+    Unpredictable ();
+  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+  temp = (U8_4 (VL4_8 (DSPHI(ac)), VL4_8 (DSPLO(ac)))
+         - ((signed64) EXTEND32 (GPR[rt]) * (signed64) EXTEND32 (GPR[rs])));
+  DSPLO(ac) = EXTEND32 (temp);
+  DSPHI(ac) = EXTEND32 (VH4_8 (temp));
+  if (ac == 0)
+    TRACE_ALU_RESULT2 (HI, LO);
+}
+
+:function:::void:do_msubu:int rs, int rt
+{
+  unsigned64 temp;
+  check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
+  if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
+    Unpredictable ();
+  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+  temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
+         - ((unsigned64) VL4_8 (GPR[rs]) * (unsigned64) VL4_8 (GPR[rt])));
+  LO = EXTEND32 (temp);
+  HI = EXTEND32 (VH4_8 (temp));
+  TRACE_ALU_RESULT2 (HI, LO);
+}
+
+:function:::void:do_dsp_msubu:int ac, int rs, int rt
+{
+  unsigned64 temp;
+  if (ac == 0)
+    check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
+  if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
+    Unpredictable ();
+  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+  temp = (U8_4 (VL4_8 (DSPHI(ac)), VL4_8 (DSPLO(ac)))
+         - ((unsigned64) VL4_8 (GPR[rs]) * (unsigned64) VL4_8 (GPR[rt])));
+  DSPLO(ac) = EXTEND32 (temp);
+  DSPHI(ac) = EXTEND32 (VH4_8 (temp));
+  if (ac == 0)
+    TRACE_ALU_RESULT2 (HI, LO);
+}
+
+:function:::void:do_mthi:int rs
+{
+  check_mt_hilo (SD_, HIHISTORY);
+  HI = GPR[rs];
+}
+
+:function:::void:do_dsp_mthi:int ac, int rs
+{
+  if (ac == 0)
+    check_mt_hilo (SD_, HIHISTORY);
+  DSPHI(ac) = GPR[rs];
+}
+
+:function:::void:do_mtlo:int rs
+{
+  check_mt_hilo (SD_, LOHISTORY);
+  LO = GPR[rs];
+}
+
+:function:::void:do_dsp_mtlo:int ac, int rs
+{
+  if (ac == 0)
+    check_mt_hilo (SD_, LOHISTORY);
+  DSPLO(ac) = GPR[rs];
+}
+
+:function:::void:do_mul:int rd, int rs, int rt
+{
+  signed64 prod;
+  if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
+    Unpredictable ();
+  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+  prod = (((signed64)(signed32) GPR[rs])
+         * ((signed64)(signed32) GPR[rt]));
+  GPR[rd] = EXTEND32 (VL4_8 (prod));
+  TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_dsp_mult:int ac, int rs, int rt
+{
+  signed64 prod;
+  if (ac == 0)
+    check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
+  if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
+    Unpredictable ();
+  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+  prod = ((signed64)(signed32) GPR[rs])
+         * ((signed64)(signed32) GPR[rt]);
+  DSPLO(ac) = EXTEND32 (VL4_8 (prod));
+  DSPHI(ac) = EXTEND32 (VH4_8 (prod));
+  if (ac == 0)
+  {
+    ACX = 0;  /* SmartMIPS */
+    TRACE_ALU_RESULT2 (HI, LO);
+  }
+}
+
+:function:::void:do_dsp_multu:int ac, int rs, int rt
+{
+  unsigned64 prod;
+  if (ac == 0)
+    check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
+  if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
+    Unpredictable ();
+  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+  prod = ((unsigned64)(unsigned32) GPR[rs])
+          * ((unsigned64)(unsigned32) GPR[rt]);
+  DSPLO(ac) = EXTEND32 (VL4_8 (prod));
+  DSPHI(ac) = EXTEND32 (VH4_8 (prod));
+  if (ac == 0)
+    TRACE_ALU_RESULT2 (HI, LO);
+}
+
+:function:::void:do_pref:int hint, int insn_offset, int insn_base
+{
+  address_word base = GPR[insn_base];
+  address_word offset = EXTEND16 (insn_offset);
+  {
+    address_word vaddr = loadstore_ea (SD_, base, offset);
+    address_word paddr;
+    int uncached;
+    {
+      if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached,
+                             isTARGET, isREAL))
+       Prefetch (uncached, paddr, vaddr, isDATA, hint);
+    }
+  }
+}
+
+:function:::void:do_sc:int rt, int offsetarg, int basereg, address_word instruction_0
+{
+  unsigned32 instruction = instruction_0;
+  address_word base = GPR[basereg];
+  address_word offset = EXTEND16 (offsetarg);
+  {
+    address_word vaddr = loadstore_ea (SD_, base, offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 3) != 0)
+      {
+       SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer,
+                        sim_core_unaligned_signal);
+      }
+    else
+      {
+       if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached,
+                               isTARGET, isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           unsigned64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
+           address_word reverseendian =
+             (ReverseEndian ? (mask ^ AccessLength_WORD) : 0);
+           address_word bigendiancpu =
+             (BigEndianCPU ? (mask ^ AccessLength_WORD) : 0);
+           unsigned int byte;
+           paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
+           byte = ((vaddr & mask) ^ bigendiancpu);
+           memval = ((unsigned64) GPR[rt] << (8 * byte));
+           if (LLBIT)
+             {
+               StoreMemory (uncached, AccessLength_WORD, memval, memval1,
+                            paddr, vaddr, isREAL);
+             }
+           GPR[rt] = LLBIT;
+         }
+      }
+  }
+}
+
+:function:::void:do_scd:int rt, int roffset, int rbase
+{
+  address_word base = GPR[rbase];
+  address_word offset = EXTEND16 (roffset);
+  {
+    address_word vaddr = loadstore_ea (SD_, base, offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 7) != 0)
+      {
+       SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, write_transfer,
+                        sim_core_unaligned_signal);
+      }
+    else
+      {
+       if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached,
+                               isTARGET, isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           memval = GPR[rt];
+           if (LLBIT)
+             {
+               StoreMemory (uncached, AccessLength_DOUBLEWORD, memval, memval1,
+                            paddr, vaddr, isREAL);
+             }
+           GPR[rt] = LLBIT;
+         }
+      }
+  }
+}
+
+:function:::void:do_sub:int rs, int rt, int rd
+{
+  if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
+    Unpredictable ();
+  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+  {
+    ALU32_BEGIN (GPR[rs]);
+    ALU32_SUB (GPR[rt]);
+    ALU32_END (GPR[rd]);   /* This checks for overflow.  */
+  }
+  TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_sw:int rt, int offset, int base
+{
+  do_store (SD_, AccessLength_WORD, GPR[base], EXTEND16 (offset), GPR[rt]);
+}
+
+:function:::void:do_teq:int rs, int rt, address_word instruction_0
+{
+  if ((signed_word) GPR[rs] == (signed_word) GPR[rt])
+    SignalException (Trap, instruction_0);
+}
+
+:function:::void:do_teqi:int rs, int immediate, address_word instruction_0
+{
+  if ((signed_word) GPR[rs] == (signed_word) EXTEND16 (immediate))
+    SignalException (Trap, instruction_0);
+}
+
+:function:::void:do_tge:int rs, int rt, address_word instruction_0
+{
+  if ((signed_word) GPR[rs] >= (signed_word) GPR[rt])
+    SignalException (Trap, instruction_0);
+}
+
+:function:::void:do_tgei:int rs, int immediate, address_word instruction_0
+{
+  if ((signed_word) GPR[rs] >= (signed_word) EXTEND16 (immediate))
+    SignalException (Trap, instruction_0);
+}
+
+:function:::void:do_tgeiu:int rs, int immediate, address_word instruction_0
+{
+  if ((unsigned_word) GPR[rs] >= (unsigned_word) EXTEND16 (immediate))
+    SignalException (Trap, instruction_0);
+}
+
+:function:::void:do_tgeu:int rs ,int rt, address_word instruction_0
+{
+  if ((unsigned_word) GPR[rs] >= (unsigned_word) GPR[rt])
+    SignalException (Trap, instruction_0);
+}
+
+:function:::void:do_tlt:int rs, int rt, address_word instruction_0
+{
+  if ((signed_word) GPR[rs] < (signed_word) GPR[rt])
+    SignalException (Trap, instruction_0);
+}
+
+:function:::void:do_tlti:int rs, int immediate, address_word instruction_0
+{
+  if ((signed_word) GPR[rs] < (signed_word) EXTEND16 (immediate))
+    SignalException (Trap, instruction_0);
+}
+
+:function:::void:do_tltiu:int rs, int immediate, address_word instruction_0
+{
+  if ((unsigned_word) GPR[rs] < (unsigned_word) EXTEND16 (immediate))
+    SignalException (Trap, instruction_0);
+}
+
+:function:::void:do_tltu:int rs, int rt, address_word instruction_0
+{
+  if ((unsigned_word) GPR[rs] < (unsigned_word) GPR[rt])
+    SignalException (Trap, instruction_0);
+}
+
+:function:::void:do_tne:int rs, int rt, address_word instruction_0
+{
+  if ((signed_word) GPR[rs] != (signed_word) GPR[rt])
+    SignalException (Trap, instruction_0);
+}
+
+:function:::void:do_tnei:int rs, int immediate, address_word instruction_0
+{
+  if ((signed_word) GPR[rs] != (signed_word) EXTEND16 (immediate))
+    SignalException (Trap, instruction_0);
+}
+
+:function:::void:do_abs_fmt:int fmt, int fd, int fs, address_word instruction_0
+{
+  check_fpu (SD_);
+  check_fmt_p (SD_, fmt, instruction_0);
+  StoreFPR (fd, fmt, AbsoluteValue (ValueFPR (fs, fmt), fmt));
+}
+
+:function:::void:do_add_fmt:int fmt, int fd, int fs, int ft, address_word instruction_0
+{
+  check_fpu (SD_);
+  check_fmt_p (SD_, fmt, instruction_0);
+  StoreFPR (fd, fmt, Add (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt));
+}
+
+:function:::void:do_alnv_ps:int fd, int fs, int ft, int rs, address_word instruction_0
+{
+  unsigned64 fsx;
+  unsigned64 ftx;
+  unsigned64 fdx;
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  fsx = ValueFPR (fs, fmt_ps);
+  if ((GPR[rs] & 0x3) != 0)
+    Unpredictable ();
+  if ((GPR[rs] & 0x4) == 0)
+    fdx = fsx;
+  else
+    {
+      ftx = ValueFPR (ft, fmt_ps);
+      if (BigEndianCPU)
+       fdx = PackPS (PSLower (fsx), PSUpper (ftx));
+      else
+       fdx = PackPS (PSLower (ftx), PSUpper (fsx));
+    }
+  StoreFPR (fd, fmt_ps, fdx);
+}
+
+:function:::void:do_c_cond_fmt:int cond, int fmt, int cc, int fs, int ft, address_word instruction_0
+{
+  check_fpu (SD_);
+  check_fmt_p (SD_, fmt, instruction_0);
+  Compare (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt, cond, cc);
+  TRACE_ALU_RESULT (ValueFCR (31));
+}
+
+:function:::void:do_ceil_fmt:int type, int fmt, int fd, int fs, address_word instruction_0
+{
+  check_fpu (SD_);
+  check_fmt_p (SD_, fmt, instruction_0);
+  StoreFPR (fd, type, Convert (FP_RM_TOPINF, ValueFPR (fs, fmt), fmt,
+           type));
+}
+
+:function:::void:do_cfc1:int rt, int fs
+{
+  check_fpu (SD_);
+  if (fs == 0 || fs == 25 || fs == 26 || fs == 28 || fs == 31)
+    {
+      unsigned_word  fcr = ValueFCR (fs);
+      TRACE_ALU_INPUT1 (fcr);
+      GPR[rt] = fcr;
+    }
+  /* else NOP */
+  TRACE_ALU_RESULT (GPR[rt]);
+}
+
+:function:::void:do_ctc1:int rt, int fs
+{
+  check_fpu (SD_);
+  TRACE_ALU_INPUT1 (GPR[rt]);
+  if (fs == 25 || fs == 26 || fs == 28 || fs == 31)
+      StoreFCR (fs, GPR[rt]);
+  /* else NOP */
+}
+
+:function:::void:do_cvt_d_fmt:int fmt, int fd, int fs, address_word instruction_0
+{
+  check_fpu (SD_);
+  if ((fmt == fmt_double) | 0)
+    SignalException (ReservedInstruction, instruction_0);
+  StoreFPR (fd, fmt_double, Convert (GETRM (), ValueFPR (fs, fmt), fmt,
+           fmt_double));
+}
+
+:function:::void:do_cvt_l_fmt:int fmt, int fd, int fs, address_word instruction_0
+{
+  check_fpu (SD_);
+  if ((fmt == fmt_long) | ((fmt == fmt_long) || (fmt == fmt_word)))
+    SignalException (ReservedInstruction, instruction_0);
+  StoreFPR (fd, fmt_long, Convert (GETRM (), ValueFPR (fs, fmt), fmt,
+           fmt_long));
+}
+
+:function:::void:do_cvt_ps_s:int fd, int fs, int ft, address_word instruction_0
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  StoreFPR (fd, fmt_ps, PackPS (ValueFPR (fs, fmt_single),
+                               ValueFPR (ft, fmt_single)));
+}
+
+:function:::void:do_cvt_s_fmt:int fmt, int fd, int fs, address_word instruction_0
+{
+  check_fpu (SD_);
+  if ((fmt == fmt_single) | 0)
+    SignalException (ReservedInstruction, instruction_0);
+  StoreFPR (fd, fmt_single, Convert (GETRM (), ValueFPR (fs, fmt), fmt,
+           fmt_single));
+}
+
+:function:::void:do_cvt_s_pl:int fd, int fs, address_word instruction_0
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  StoreFPR (fd, fmt_single, PSLower (ValueFPR (fs, fmt_ps)));
+}
+
+:function:::void:do_cvt_s_pu:int fd, int fs, address_word instruction_0
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  StoreFPR (fd, fmt_single, PSUpper (ValueFPR (fs, fmt_ps)));
+}
+
+:function:::void:do_cvt_w_fmt:int fmt, int fd, int fs, address_word instruction_0
+{
+  check_fpu (SD_);
+  if ((fmt == fmt_word) | ((fmt == fmt_long) || (fmt == fmt_word)))
+    SignalException (ReservedInstruction, instruction_0);
+  StoreFPR (fd, fmt_word, Convert (GETRM (), ValueFPR (fs, fmt), fmt,
+           fmt_word));
+}
+
+:function:::void:do_div_fmt:int fmt, int fd, int fs, int ft, address_word instruction_0
+{
+  check_fpu (SD_);
+  StoreFPR (fd, fmt, Divide (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt));
+}
+
+:function:::void:do_dmfc1b:int rt, int fs
+*mipsIV:
+*mipsV:
+*mips64:
+*mips64r2:
+*vr4100:
+*vr5000:
+*r3900:
+*micromips64:
+{
+  if (SizeFGR () == 64)
+    GPR[rt] = FGR[fs];
+  else if ((fs & 0x1) == 0)
+    GPR[rt] = SET64HI (FGR[fs+1]) | FGR[fs];
+  else
+    GPR[rt] = SET64HI (0xDEADC0DE) | 0xBAD0BAD0;
+  TRACE_ALU_RESULT (GPR[rt]);
+}
+
+:function:::void:do_dmtc1b:int rt, int fs
+{
+  if (SizeFGR () == 64)
+    StoreFPR (fs, fmt_uninterpreted_64, GPR[rt]);
+  else if ((fs & 0x1) == 0)
+    StoreFPR (fs, fmt_uninterpreted_64, GPR[rt]);
+  else
+    Unpredictable ();
+}
+
+:function:::void:do_floor_fmt:int type, int fmt, int fd, int fs
+{
+  check_fpu (SD_);
+  StoreFPR (fd, type, Convert (FP_RM_TOMINF, ValueFPR (fs, fmt), fmt,
+           type));
+}
+
+:function:::void:do_luxc1_32:int fd, int rindex, int rbase
+*mips32r2:
+*micromips32:
+{
+  address_word base = GPR[rbase];
+  address_word index = GPR[rindex];
+  address_word vaddr = base + index;
+  check_fpu (SD_);
+  if (SizeFGR () != 64)
+    Unpredictable ();
+  /* Arrange for the bottom 3 bits of (base + index) to be 0.  */
+  if ((vaddr & 0x7) != 0)
+    index -= (vaddr & 0x7);
+  COP_LD (1, fd, do_load_double (SD_, base, index));
+}
+
+:function:::void:do_luxc1_64:int fd, int rindex, int rbase
+{
+  address_word base = GPR[rbase];
+  address_word index = GPR[rindex];
+  address_word vaddr = base + index;
+  if (SizeFGR () != 64)
+    Unpredictable ();
+  /* Arrange for the bottom 3 bits of (base + index) to be 0.  */
+  if ((vaddr & 0x7) != 0)
+    index -= (vaddr & 0x7);
+  COP_LD (1, fd, do_load (SD_, AccessLength_DOUBLEWORD, base, index));
+
+}
+
+:function:::void:do_lwc1:int ft, int offset, int base
+{
+  check_fpu (SD_);
+  COP_LW (1, ft, do_load (SD_, AccessLength_WORD, GPR[base],
+                         EXTEND16 (offset)));
+}
+
+:function:::void:do_lwxc1:int fd, int index, int base, address_word instruction_0
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  COP_LW (1, fd, do_load (SD_, AccessLength_WORD, GPR[base], GPR[index]));
+}
+
+:function:::void:do_madd_fmt:int fmt, int fd, int fr, int fs, int ft, address_word instruction_0
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  check_fmt_p (SD_, fmt, instruction_0);
+  StoreFPR (fd, fmt, MultiplyAdd (ValueFPR (fs, fmt), ValueFPR (ft, fmt),
+                                 ValueFPR (fr, fmt), fmt));
+}
+
+:function:::void:do_mfc1b:int rt, int fs
+{
+  check_fpu (SD_);
+  GPR[rt] = EXTEND32 (FGR[fs]);
+  TRACE_ALU_RESULT (GPR[rt]);
+}
+
+:function:::void:do_mov_fmt:int fmt, int fd, int fs, address_word instruction_0
+{
+  check_fpu (SD_);
+  check_fmt_p (SD_, fmt, instruction_0);
+  StoreFPR (fd, fmt, ValueFPR (fs, fmt));
+}
+
+:function:::void:do_movtf:int tf, int rd, int rs, int cc
+{
+  check_fpu (SD_);
+  if (GETFCC(cc) == tf)
+    GPR[rd] = GPR[rs];
+}
+
+:function:::void:do_movtf_fmt:int tf, int fmt, int fd, int fs, int cc
+{
+  check_fpu (SD_);
+  if (fmt != fmt_ps)
+  {
+    if (GETFCC(cc) == tf)
+      StoreFPR (fd, fmt, ValueFPR (fs, fmt));
+    else
+      StoreFPR (fd, fmt, ValueFPR (fd, fmt));   /* set fmt */
+  }
+  else
+  {
+    unsigned64 fdx;
+    fdx = PackPS (PSUpper (ValueFPR ((GETFCC (cc+1) == tf) ? fs : fd,
+                                     fmt_ps)),
+                  PSLower (ValueFPR ((GETFCC (cc+0) == tf) ? fs : fd,
+                                     fmt_ps)));
+    StoreFPR (fd, fmt_ps, fdx);
+  }
+}
+
+:function:::void:do_movn_fmt:int fmt, int fd, int fs, int rt
+{
+  check_fpu (SD_);
+  if (GPR[rt] != 0)
+    StoreFPR (fd, fmt, ValueFPR (fs, fmt));
+  else
+    StoreFPR (fd, fmt, ValueFPR (fd, fmt));
+}
+
+:function:::void:do_movz_fmt:int fmt, int fd, int fs, int rt
+{
+  check_fpu (SD_);
+  if (GPR[rt] == 0)
+    StoreFPR (fd, fmt, ValueFPR (fs, fmt));
+  else
+    StoreFPR (fd, fmt, ValueFPR (fd, fmt));
+}
+
+:function:::void:do_msub_fmt:int fmt, int fd, int fr, int fs, int ft, address_word instruction_0
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  check_fmt_p (SD_, fmt, instruction_0);
+  StoreFPR (fd, fmt, MultiplySub (ValueFPR (fs, fmt), ValueFPR (ft, fmt),
+                                 ValueFPR (fr, fmt), fmt));
+}
+
+:function:::void:do_mtc1b:int rt, int fs
+{
+  check_fpu (SD_);
+  StoreFPR (fs, fmt_uninterpreted_32, VL4_8 (GPR[rt]));
+}
+
+:function:::void:do_mul_fmt:int fmt, int fd, int fs, int ft, address_word instruction_0
+{
+  check_fpu (SD_);
+  check_fmt_p (SD_, fmt, instruction_0);
+  StoreFPR (fd, fmt, Multiply (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt));
+}
+
+:function:::void:do_neg_fmt:int fmt, int fd, int fs, address_word instruction_0
+{
+  check_fpu (SD_);
+  check_fmt_p (SD_, fmt, instruction_0);
+  StoreFPR (fd, fmt, Negate (ValueFPR (fs, fmt), fmt));
+}
+
+:function:::void:do_nmadd_fmt:int fmt, int fd, int fr, int fs, int ft, address_word instruction_0
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  check_fmt_p (SD_, fmt, instruction_0);
+  StoreFPR (fd, fmt, NegMultiplyAdd (ValueFPR (fs, fmt), ValueFPR (ft, fmt),
+                                    ValueFPR (fr, fmt), fmt));
+}
+
+:function:::void:do_nmsub_fmt:int fmt, int fd, int fr, int fs, int ft, address_word instruction_0
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  check_fmt_p (SD_, fmt, instruction_0);
+  StoreFPR (fd, fmt, NegMultiplySub (ValueFPR (fs, fmt), ValueFPR (ft, fmt),
+                                    ValueFPR (fr, fmt), fmt));
+}
+
+:function:::void:do_pll_ps:int fd, int fs, int ft, address_word instruction_0
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  StoreFPR (fd, fmt_ps, PackPS (PSLower (ValueFPR (fs, fmt_ps)),
+                               PSLower (ValueFPR (ft, fmt_ps))));
+}
+
+:function:::void:do_plu_ps:int fd, int fs, int ft, address_word instruction_0
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  StoreFPR (fd, fmt_ps, PackPS (PSLower (ValueFPR (fs, fmt_ps)),
+                               PSUpper (ValueFPR (ft, fmt_ps))));
+}
+
+:function:::void:do_pul_ps:int fd, int fs, int ft, address_word instruction_0
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  StoreFPR (fd, fmt_ps, PackPS (PSUpper (ValueFPR (fs, fmt_ps)),
+                               PSLower (ValueFPR (ft, fmt_ps))));
+}
+
+:function:::void:do_puu_ps:int fd, int fs, int ft, address_word instruction_0
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  StoreFPR (fd, fmt_ps, PackPS (PSUpper (ValueFPR (fs, fmt_ps)),
+                               PSUpper (ValueFPR (ft, fmt_ps))));
+}
+
+:function:::void:do_recip_fmt:int fmt, int fd, int fs
+{
+  check_fpu (SD_);
+  StoreFPR (fd, fmt, Recip (ValueFPR (fs, fmt), fmt));
+}
+
+:function:::void:do_round_fmt:int type, int fmt, int fd, int fs
+{
+  check_fpu (SD_);
+  StoreFPR (fd, type, Convert (FP_RM_NEAREST, ValueFPR (fs, fmt), fmt,
+           type));
+}
+
+:function:::void:do_rsqrt_fmt:int fmt, int fd, int fs
+{
+  check_fpu (SD_);
+  StoreFPR (fd, fmt, RSquareRoot (ValueFPR (fs, fmt), fmt));
+}
+
+:function:::void:do_prefx:int hint, int rindex, int rbase
+{
+  address_word base = GPR[rbase];
+  address_word index = GPR[rindex];
+  {
+    address_word vaddr = loadstore_ea (SD_, base, index);
+    address_word paddr;
+    int uncached;
+    if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET,
+                           isREAL))
+      Prefetch (uncached, paddr, vaddr, isDATA, hint);
+  }
+}
+
+:function:::void:do_sdc1:int ft, int offset, int base
+*mipsII:
+*mips32:
+*mips32r2:
+*micromips32:
+{
+  check_fpu (SD_);
+  do_store_double (SD_, GPR[base], EXTEND16 (offset), COP_SD (1, ft));
+}
+
+:function:::void:do_suxc1_32:int fs, int rindex, int rbase
+*mips32r2:
+*micromips32:
+{
+  address_word base = GPR[rbase];
+  address_word index = GPR[rindex];
+  address_word vaddr = base + index;
+  check_fpu (SD_);
+  if (SizeFGR () != 64)
+    Unpredictable ();
+  /* Arrange for the bottom 3 bits of (base + index) to be 0.  */
+  if ((vaddr & 0x7) != 0)
+    index -= (vaddr & 0x7);
+  do_store_double (SD_, base, index, COP_SD (1, fs));
+}
+
+:function:::void:do_suxc1_64:int fs, int rindex, int rbase
+{
+  address_word base = GPR[rbase];
+  address_word index = GPR[rindex];
+  address_word vaddr = base + index;
+  if (SizeFGR () != 64)
+    Unpredictable ();
+  /* Arrange for the bottom 3 bits of (base + index) to be 0.  */
+  if ((vaddr & 0x7) != 0)
+    index -= (vaddr & 0x7);
+  do_store (SD_, AccessLength_DOUBLEWORD, base, index, COP_SD (1, fs));
+}
+
+:function:::void:do_sqrt_fmt:int fmt, int fd, int fs
+{
+  check_fpu (SD_);
+  StoreFPR (fd, fmt,  (SquareRoot (ValueFPR (fs, fmt), fmt)));
+}
+
+:function:::void:do_sub_fmt:int fmt, int fd, int fs, int ft, address_word instruction_0
+{
+  check_fpu (SD_);
+  check_fmt_p (SD_, fmt, instruction_0);
+  StoreFPR (fd, fmt, Sub (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt));
+}
+
+:function:::void:do_swc1:int ft, int roffset, int rbase, address_word instruction_0
+{
+  address_word base = GPR[rbase];
+  address_word offset = EXTEND16 (roffset);
+  check_fpu (SD_);
+  {
+    address_word vaddr = loadstore_ea (SD_, base, offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 3) != 0)
+      {
+       SIM_CORE_SIGNAL (SD, CPU, cia, read_map, AccessLength_WORD+1, vaddr,
+                        write_transfer, sim_core_unaligned_signal);
+      }
+    else
+      {
+       if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached,
+                               isTARGET, isREAL))
+         {
+           uword64 memval = 0;
+           uword64 memval1 = 0;
+           uword64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
+           address_word reverseendian =
+             (ReverseEndian ?(mask ^ AccessLength_WORD): 0);
+           address_word bigendiancpu =
+             (BigEndianCPU ?(mask ^ AccessLength_WORD): 0);
+           unsigned int byte;
+           paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
+           byte = ((vaddr & mask) ^ bigendiancpu);
+           memval = (((uword64)COP_SW(1, ft)) << (8 * byte));
+           StoreMemory (uncached, AccessLength_WORD, memval, memval1, paddr,
+                        vaddr, isREAL);
+         }
+      }
+  }
+}
+
+:function:::void:do_swxc1:int fs, int rindex, int rbase, address_word instruction_0
+{
+  address_word base = GPR[rbase];
+  address_word index = GPR[rindex];
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+    {
+      address_word vaddr = loadstore_ea (SD_, base, index);
+      address_word paddr;
+      int uncached;
+      if ((vaddr & 3) != 0)
+       {
+         SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer,
+                          sim_core_unaligned_signal);
+       }
+      else
+       {
+         if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached,
+                                isTARGET, isREAL))
+           {
+             unsigned64 memval = 0;
+             unsigned64 memval1 = 0;
+             unsigned64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
+             address_word reverseendian =
+               (ReverseEndian ? (mask ^ AccessLength_WORD) : 0);
+             address_word bigendiancpu =
+               (BigEndianCPU ? (mask ^ AccessLength_WORD) : 0);
+             unsigned int byte;
+             paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
+             byte = ((vaddr & mask) ^ bigendiancpu);
+             memval = (((unsigned64)COP_SW(1,fs)) << (8 * byte));
+             StoreMemory (uncached, AccessLength_WORD, memval, memval1, paddr,
+                          vaddr, isREAL);
+           }
+       }
+  }
+}
+
+:function:::void:do_trunc_fmt:int type, int fmt, int fd, int fs
+{
+  check_fpu (SD_);
+  StoreFPR (fd, type, Convert (FP_RM_TOZERO, ValueFPR (fs, fmt), fmt,
+           type));
+}
 
 000000,5.RS,5.RT,5.RD,00000,100000:SPECIAL:32::ADD
 "add r<RD>, r<RS>, r<RT>"
 *vr5000:
 *r3900:
 {
-  if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
-    Unpredictable ();
-  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
-  {
-    ALU32_BEGIN (GPR[RS]);
-    ALU32_ADD (GPR[RT]);
-    ALU32_END (GPR[RD]);   /* This checks for overflow.  */
-  }
-  TRACE_ALU_RESULT (GPR[RD]);
+  do_add (SD_, RS, RT, RD);
 }
 
 
 *vr5000:
 *r3900:
 {
-  if (NotWordValue (GPR[RS]))
-    Unpredictable ();
-  TRACE_ALU_INPUT2 (GPR[RS], EXTEND16 (IMMEDIATE));
-  {
-    ALU32_BEGIN (GPR[RS]);
-    ALU32_ADD (EXTEND16 (IMMEDIATE));
-    ALU32_END (GPR[RT]);   /* This checks for overflow.  */
-  }
-  TRACE_ALU_RESULT (GPR[RT]);
+  do_addi (SD_, RS, RT, IMMEDIATE);
 }
 
 
 *vr5000:
 *r3900:
 {
-  TRACE_ALU_INPUT2 (GPR[RS], IMMEDIATE);
-  GPR[RT] = GPR[RS] & IMMEDIATE;
-  TRACE_ALU_RESULT (GPR[RT]);
+  do_andi (SD_,RS, RT, IMMEDIATE);
 }
 
 
 *vr5000:
 *r3900:
 {
-  /* Check for some break instruction which are reserved for use by the simulator.  */
-  unsigned int break_code = instruction_0 & HALT_INSTRUCTION_MASK;
-  if (break_code == (HALT_INSTRUCTION  & HALT_INSTRUCTION_MASK) ||
-      break_code == (HALT_INSTRUCTION2 & HALT_INSTRUCTION_MASK))
-    {
-      sim_engine_halt (SD, CPU, NULL, cia,
-                       sim_exited, (unsigned int)(A0 & 0xFFFFFFFF));
-    }
-  else if (break_code == (BREAKPOINT_INSTRUCTION  & HALT_INSTRUCTION_MASK) ||
-           break_code == (BREAKPOINT_INSTRUCTION2 & HALT_INSTRUCTION_MASK))
-    {
-      if (STATE & simDELAYSLOT)
-        PC = cia - 4; /* reference the branch instruction */
-      else
-        PC = cia;
-      SignalException (BreakPoint, instruction_0);
-    }
-
-  else
-    {
-      /* If we get this far, we're not an instruction reserved by the sim.  Raise
-        the exception. */
-      SignalException (BreakPoint, instruction_0);
-    }
+  do_break (SD_, instruction_0);
 }
 
 
 *mips64r2:
 *vr5500:
 {
-  unsigned32 temp = GPR[RS];
-  unsigned32 i, mask;
   if (RT != RD)
     Unpredictable ();
-  if (NotWordValue (GPR[RS]))
-    Unpredictable ();
-  TRACE_ALU_INPUT1 (GPR[RS]);
-  for (mask = ((unsigned32)1<<31), i = 0; i < 32; ++i)
-    {
-      if ((temp & mask) == 0)
-       break;
-      mask >>= 1;
-    }
-  GPR[RD] = EXTEND32 (i);
-  TRACE_ALU_RESULT (GPR[RD]);
+  do_clo (SD_, RD, RS);
 }
 
 
 *mips64r2:
 *vr5500:
 {
-  unsigned32 temp = GPR[RS];
-  unsigned32 i, mask;
   if (RT != RD)
     Unpredictable ();
-  if (NotWordValue (GPR[RS]))
-    Unpredictable ();
-  TRACE_ALU_INPUT1 (GPR[RS]);
-  for (mask = ((unsigned32)1<<31), i = 0; i < 32; ++i)
-    {
-      if ((temp & mask) != 0)
-       break;
-      mask >>= 1;
-    }
-  GPR[RD] = EXTEND32 (i);
-  TRACE_ALU_RESULT (GPR[RD]);
+  do_clz (SD_, RD, RS);
 }
 
 
 *vr5000:
 {
   check_u64 (SD_, instruction_0);
-  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
-  {
-    ALU64_BEGIN (GPR[RS]);
-    ALU64_ADD (GPR[RT]);
-    ALU64_END (GPR[RD]);   /* This checks for overflow.  */
-  }
-  TRACE_ALU_RESULT (GPR[RD]);
+  do_dadd (SD_, RD, RS, RT);
 }
 
 
 *vr5000:
 {
   check_u64 (SD_, instruction_0);
-  TRACE_ALU_INPUT2 (GPR[RS], EXTEND16 (IMMEDIATE));
-  {
-    ALU64_BEGIN (GPR[RS]);
-    ALU64_ADD (EXTEND16 (IMMEDIATE));
-    ALU64_END (GPR[RT]);   /* This checks for overflow.  */
-  }
-  TRACE_ALU_RESULT (GPR[RT]);
+  do_daddi (SD_, RT, RS, IMMEDIATE);
 }
 
 
 *mips64r2:
 *vr5500:
 {
-  unsigned64 temp = GPR[RS];
-  unsigned32 i;
-  unsigned64 mask;
-  check_u64 (SD_, instruction_0);
   if (RT != RD)
     Unpredictable ();
-  TRACE_ALU_INPUT1 (GPR[RS]);
-  for (mask = ((unsigned64)1<<63), i = 0; i < 64; ++i)
-    {
-      if ((temp & mask) == 0)
-       break;
-      mask >>= 1;
-    }
-  GPR[RD] = EXTEND32 (i);
-  TRACE_ALU_RESULT (GPR[RD]);
+  check_u64 (SD_, instruction_0);
+  do_dclo (SD_, RD, RS);
 }
 
 
 *mips64r2:
 *vr5500:
 {
-  unsigned64 temp = GPR[RS];
-  unsigned32 i;
-  unsigned64 mask;
-  check_u64 (SD_, instruction_0);
   if (RT != RD)
     Unpredictable ();
-  TRACE_ALU_INPUT1 (GPR[RS]);
-  for (mask = ((unsigned64)1<<63), i = 0; i < 64; ++i)
-    {
-      if ((temp & mask) != 0)
-       break;
-      mask >>= 1;
-    }
-  GPR[RD] = EXTEND32 (i);
-  TRACE_ALU_RESULT (GPR[RD]);
+  check_u64 (SD_, instruction_0);
+  do_dclz (SD_, RD, RS);
 }
 
 
 *vr4100:
 *vr5000:
 {
-  int s = 32 + SHIFT;
   check_u64 (SD_, instruction_0);
-  TRACE_ALU_INPUT2 (GPR[RT], s);
-  GPR[RD] = GPR[RT] << s;
-  TRACE_ALU_RESULT (GPR[RD]);
+  do_dsll32 (SD_, RD, RT, SHIFT);
 }
 
 :function:::void:do_dsllv:int rs, int rt, int rd
 *vr4100:
 *vr5000:
 {
-  int s = 32 + SHIFT;
   check_u64 (SD_, instruction_0);
-  TRACE_ALU_INPUT2 (GPR[RT], s);
-  GPR[RD] = ((signed64) GPR[RT]) >> s;
-  TRACE_ALU_RESULT (GPR[RD]);
+  do_dsra32 (SD_, RD, RT, SHIFT);
 }
 
 
 *vr4100:
 *vr5000:
 {
-  int s = 32 + SHIFT;
   check_u64 (SD_, instruction_0);
-  TRACE_ALU_INPUT2 (GPR[RT], s);
-  GPR[RD] = (unsigned64) GPR[RT] >> s;
-  TRACE_ALU_RESULT (GPR[RD]);
+  do_dsrl32 (SD_, RD, RT, SHIFT);
 }
 
 
 *vr5000:
 {
   check_u64 (SD_, instruction_0);
-  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
-  {
-    ALU64_BEGIN (GPR[RS]);
-    ALU64_SUB (GPR[RT]);
-    ALU64_END (GPR[RD]);   /* This checks for overflow.  */
-  }
-  TRACE_ALU_RESULT (GPR[RD]);
+  do_dsub (SD_, RD, RS, RT);
 }
 
 
 *vr5000:
 *r3900:
 {
-  GPR[RT] = EXTEND8 (do_load (SD_, AccessLength_BYTE, GPR[BASE], EXTEND16 (OFFSET)));
+  do_lb (SD_,RT,OFFSET,BASE);
 }
 
 
 *vr5000:
 *r3900:
 {
-  GPR[RT] = do_load (SD_, AccessLength_BYTE, GPR[BASE], EXTEND16 (OFFSET));
+  do_lbu (SD_, RT,OFFSET,BASE);
 }
 
 
 *vr5000:
 *r3900:
 {
-  COP_LD (ZZ, RT, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET)));
+  do_ldc (SD_, ZZ, RT, OFFSET, BASE);
 }
 
 
 *vr5000:
 *r3900:
 {
-  GPR[RT] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[BASE], EXTEND16 (OFFSET)));
+  do_lh (SD_,RT,OFFSET,BASE);
 }
 
 
 *vr5000:
 *r3900:
 {
-  GPR[RT] = do_load (SD_, AccessLength_HALFWORD, GPR[BASE], EXTEND16 (OFFSET));
+  do_lhu (SD_,RT,OFFSET,BASE);
 }
 
 
 *vr4100:
 *vr5000:
 {
-  address_word base = GPR[BASE];
-  address_word offset = EXTEND16 (OFFSET);
-  {
-    address_word vaddr = loadstore_ea (SD_, base, offset);
-    address_word paddr;
-    int uncached;
-    if ((vaddr & 3) != 0)
-      {
-        SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, read_transfer, sim_core_unaligned_signal);
-      }
-    else
-      {
-       if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
-         {
-           unsigned64 memval = 0;
-           unsigned64 memval1 = 0;
-           unsigned64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
-           unsigned int shift = 2;
-           unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
-           unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
-           unsigned int byte;
-           paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
-           LoadMemory(&memval,&memval1,uncached,AccessLength_WORD,paddr,vaddr,isDATA,isREAL);
-           byte = ((vaddr & mask) ^ (bigend << shift));
-           GPR[RT] = EXTEND32 (memval >> (8 * byte));
-           LLBIT = 1;
-         }
-      }
-  }
+  do_ll (SD_, RT, OFFSET, BASE);
 }
 
 
 *vr4100:
 *vr5000:
 {
-  address_word base = GPR[BASE];
-  address_word offset = EXTEND16 (OFFSET);
   check_u64 (SD_, instruction_0);
-  {
-    address_word vaddr = loadstore_ea (SD_, base, offset);
-    address_word paddr;
-    int uncached;
-    if ((vaddr & 7) != 0)
-      {
-       SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, read_transfer, sim_core_unaligned_signal);
-      }
-    else
-      {
-       if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
-         {
-           unsigned64 memval = 0;
-           unsigned64 memval1 = 0;
-           LoadMemory(&memval,&memval1,uncached,AccessLength_DOUBLEWORD,paddr,vaddr,isDATA,isREAL);
-           GPR[RT] = memval;
-           LLBIT = 1;
-         }
-      }
-  }
+  do_lld (SD_, RT, OFFSET, BASE);
 }
 
 
 *vr5000:
 *r3900:
 {
-  TRACE_ALU_INPUT1 (IMMEDIATE);
-  GPR[RT] = EXTEND32 (IMMEDIATE << 16);
-  TRACE_ALU_RESULT (GPR[RT]);
+  do_lui (SD_, RT, IMMEDIATE);
 }
 
 
 *vr5000:
 *r3900:
 {
-  GPR[RT] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET)));
+  do_lw (SD_,RT,OFFSET,BASE);
 }
 
 
 *vr5000:
 *r3900:
 {
-  COP_LW (ZZ, RT, do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET)));
+  do_lwc (SD_, ZZ, RT, OFFSET, BASE);
 }
 
 
 *vr5000:
 *r3900:
 {
-  GPR[RT] = EXTEND32 (do_load_left (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]));
+  do_lwl (SD_, RT, OFFSET, BASE);
 }
 
 
 *vr5000:
 *r3900:
 {
-  GPR[RT] = EXTEND32 (do_load_right (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]));
+  do_lwr (SD_, RT, OFFSET, BASE);
 }
 
 
 *vr4100:
 *vr5000:
 {
-  check_u64 (SD_, instruction_0);
-  GPR[RT] = do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET));
+  do_lwu (SD_, RT, OFFSET, BASE, instruction_0);
 }
 
 
 *mips64:
 *vr5500:
 {
-  signed64 temp;
-  check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
-  if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
-    Unpredictable ();
-  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
-  temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
-          + ((signed64) EXTEND32 (GPR[RT]) * (signed64) EXTEND32 (GPR[RS])));
-  LO = EXTEND32 (temp);
-  HI = EXTEND32 (VH4_8 (temp));
-  TRACE_ALU_RESULT2 (HI, LO);
+  do_madd (SD_, RS, RT);
 }
 
 
 *mips64r2:
 *dsp2:
 {
-  signed64 temp;
-  if (AC == 0)
-    check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
-  if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
-    Unpredictable ();
-  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
-  temp = (U8_4 (VL4_8 (DSPHI(AC)), VL4_8 (DSPLO(AC)))
-         + ((signed64) EXTEND32 (GPR[RT]) * (signed64) EXTEND32 (GPR[RS])));
-  DSPLO(AC) = EXTEND32 (temp);
-  DSPHI(AC) = EXTEND32 (VH4_8 (temp));
-  if (AC == 0)
-    TRACE_ALU_RESULT2 (HI, LO);
+  do_dsp_madd (SD_, AC, RS, RT);
 }
 
 
 *mips64:
 *vr5500:
 {
-  unsigned64 temp;
-  check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
-  if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
-    Unpredictable ();
-  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
-  temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
-          + ((unsigned64) VL4_8 (GPR[RS]) * (unsigned64) VL4_8 (GPR[RT])));
-  ACX += U8_4 (VL4_8 (HI), VL4_8 (LO)) < temp;  /* SmartMIPS */ 
-  LO = EXTEND32 (temp);
-  HI = EXTEND32 (VH4_8 (temp));
-  TRACE_ALU_RESULT2 (HI, LO);
+  do_maddu (SD_, RS, RT);
 }
 
 
 *mips64r2:
 *dsp2:
 {
-  unsigned64 temp;
-  if (AC == 0)
-    check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
-  if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
-    Unpredictable ();
-  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
-  temp = (U8_4 (VL4_8 (DSPHI(AC)), VL4_8 (DSPLO(AC)))
-         + ((unsigned64) VL4_8 (GPR[RS]) * (unsigned64) VL4_8 (GPR[RT])));
-  if (AC == 0)
-    ACX += U8_4 (VL4_8 (HI), VL4_8 (LO)) < temp;  /* SmartMIPS */
-  DSPLO(AC) = EXTEND32 (temp);
-  DSPHI(AC) = EXTEND32 (VH4_8 (temp));
-  if (AC == 0)
-    TRACE_ALU_RESULT2 (HI, LO);
+  do_dsp_maddu (SD_, AC, RS, RT);
 }
 
 
 *mips64r2:
 *dsp:
 {
-  if (AC == 0)
-    do_mfhi (SD_, RD);
-  else
-    GPR[RD] = DSPHI(AC);
+  do_dsp_mfhi (SD_, AC, RD);
 }
 
 
 *mips64r2:
 *dsp:
 {
-  if (AC == 0)
-    do_mflo (SD_, RD);
-  else
-    GPR[RD] = DSPLO(AC);
+  do_dsp_mflo (SD_, AC, RD);
 }
 
 
 *mips64r2:
 *vr5000:
 {
-  if (GPR[RT] != 0)
-    {
-      GPR[RD] = GPR[RS];
-      TRACE_ALU_RESULT (GPR[RD]);
-    }
+  do_movn (SD_, RD, RS, RT);
 }
 
 
 *mips64r2:
 *vr5000:
 {
-  if (GPR[RT] == 0)
-    {
-      GPR[RD] = GPR[RS];
-      TRACE_ALU_RESULT (GPR[RD]);
-    }
+  do_movz (SD_, RD, RS, RT);
 }
 
 
 *mips64:
 *vr5500:
 {
-  signed64 temp;
-  check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
-  if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
-    Unpredictable ();
-  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
-  temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
-          - ((signed64) EXTEND32 (GPR[RT]) * (signed64) EXTEND32 (GPR[RS])));
-  LO = EXTEND32 (temp);
-  HI = EXTEND32 (VH4_8 (temp));
-  TRACE_ALU_RESULT2 (HI, LO);
+  do_msub (SD_, RS, RT);
 }
 
 
 *mips64r2:
 *dsp2:
 {
-  signed64 temp;
-  if (AC == 0)
-    check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
-  if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
-    Unpredictable ();
-  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
-  temp = (U8_4 (VL4_8 (DSPHI(AC)), VL4_8 (DSPLO(AC)))
-         - ((signed64) EXTEND32 (GPR[RT]) * (signed64) EXTEND32 (GPR[RS])));
-  DSPLO(AC) = EXTEND32 (temp);
-  DSPHI(AC) = EXTEND32 (VH4_8 (temp));
-  if (AC == 0)
-    TRACE_ALU_RESULT2 (HI, LO);
+  do_dsp_msub (SD_, AC, RS, RT);
 }
 
 
 *mips64:
 *vr5500:
 {
-  unsigned64 temp;
-  check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
-  if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
-    Unpredictable ();
-  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
-  temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
-          - ((unsigned64) VL4_8 (GPR[RS]) * (unsigned64) VL4_8 (GPR[RT])));
-  LO = EXTEND32 (temp);
-  HI = EXTEND32 (VH4_8 (temp));
-  TRACE_ALU_RESULT2 (HI, LO);
+  do_msubu (SD_, RS, RT);
 }
 
 
 *mips64r2:
 *dsp2:
 {
-  unsigned64 temp;
-  if (AC == 0)
-    check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
-  if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
-    Unpredictable ();
-  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
-  temp = (U8_4 (VL4_8 (DSPHI(AC)), VL4_8 (DSPLO(AC)))
-          - ((unsigned64) VL4_8 (GPR[RS]) * (unsigned64) VL4_8 (GPR[RT])));
-  DSPLO(AC) = EXTEND32 (temp);
-  DSPHI(AC) = EXTEND32 (VH4_8 (temp));
-  if (AC == 0)
-    TRACE_ALU_RESULT2 (HI, LO);
+  do_dsp_msubu (SD_, AC, RS, RT);
 }
 
 
 *mips32:
 *mips64:
 {
-  check_mt_hilo (SD_, HIHISTORY);
-  HI = GPR[RS];
+  do_mthi (SD_, RS);
 }
 
 
 *mips64r2:
 *dsp:
 {
-  if (AC == 0)
-    check_mt_hilo (SD_, HIHISTORY);
-  DSPHI(AC) = GPR[RS];
+  do_dsp_mthi (SD_, AC, RS);
 }
 
 
 *mips32:
 *mips64:
 {
-  check_mt_hilo (SD_, LOHISTORY);
-  LO = GPR[RS];
+  do_mtlo (SD_, RS);
 }
 
 
 *mips64r2:
 *dsp:
 {
-  if (AC == 0)
-    check_mt_hilo (SD_, LOHISTORY);
-  DSPLO(AC) = GPR[RS];
+  do_dsp_mtlo (SD_, AC, RS);
 }
 
 
 *mips64r2:
 *vr5500:
 {
-  signed64 prod;
-  if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
-    Unpredictable ();
-  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
-  prod = (((signed64)(signed32) GPR[RS])
-          * ((signed64)(signed32) GPR[RT]));
-  GPR[RD] = EXTEND32 (VL4_8 (prod));
-  TRACE_ALU_RESULT (GPR[RD]);
+  do_mul (SD_, RD, RS, RT);
 }
 
 
 *mips64r2:
 *dsp2:
 {
-  signed64 prod;
-  if (AC == 0)
-    check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
-  if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
-    Unpredictable ();
-  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
-  prod = ((signed64)(signed32) GPR[RS])
-         * ((signed64)(signed32) GPR[RT]);
-  DSPLO(AC) = EXTEND32 (VL4_8 (prod));
-  DSPHI(AC) = EXTEND32 (VH4_8 (prod));
-  if (AC == 0)
-    {
-      ACX = 0;  /* SmartMIPS */
-      TRACE_ALU_RESULT2 (HI, LO);
-    }
+  do_dsp_mult (SD_, AC, RS, RT);
 }
 
 
 *mips64r2:
 *dsp2:
 {
-  unsigned64 prod;
-  if (AC == 0)
-    check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
-  if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
-    Unpredictable ();
-  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
-  prod = ((unsigned64)(unsigned32) GPR[RS])
-          * ((unsigned64)(unsigned32) GPR[RT]);
-  DSPLO(AC) = EXTEND32 (VL4_8 (prod));
-  DSPHI(AC) = EXTEND32 (VH4_8 (prod));
-  if (AC == 0)
-    TRACE_ALU_RESULT2 (HI, LO);
+  do_dsp_multu (SD_, AC, RS, RT);
 }
 
 
 *mips64r2:
 *vr5000:
 {
-  address_word base = GPR[BASE];
-  address_word offset = EXTEND16 (OFFSET);
-  {
-    address_word vaddr = loadstore_ea (SD_, base, offset);
-    address_word paddr;
-    int uncached;
-    {
-      if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
-       Prefetch(uncached,paddr,vaddr,isDATA,HINT);
-    }
-  }
+  do_pref (SD_, HINT, OFFSET, BASE);
 }
 
 
 *mips32r2:
 *mips64:
 *mips64r2:
-*vr4100:
-*vr5000:
-{
-  unsigned32 instruction = instruction_0;
-  address_word base = GPR[BASE];
-  address_word offset = EXTEND16 (OFFSET);
-  {
-    address_word vaddr = loadstore_ea (SD_, base, offset);
-    address_word paddr;
-    int uncached;
-    if ((vaddr & 3) != 0)
-      {
-       SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer, sim_core_unaligned_signal);
-      }
-    else
-      {
-       if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
-         {
-           unsigned64 memval = 0;
-           unsigned64 memval1 = 0;
-           unsigned64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
-           address_word reverseendian = (ReverseEndian ? (mask ^ AccessLength_WORD) : 0);
-           address_word bigendiancpu = (BigEndianCPU ? (mask ^ AccessLength_WORD) : 0);
-           unsigned int byte;
-           paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
-           byte = ((vaddr & mask) ^ bigendiancpu);
-           memval = ((unsigned64) GPR[RT] << (8 * byte));
-           if (LLBIT)
-             {
-               StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL);
-             }
-           GPR[RT] = LLBIT;
-         }
-      }
-  }
-}
-
-
-111100,5.BASE,5.RT,16.OFFSET:NORMAL:64::SCD
-"scd r<RT>, <OFFSET>(r<BASE>)"
-*mipsIII:
-*mipsIV:
-*mipsV:
-*mips64:
-*mips64r2:
-*vr4100:
-*vr5000:
-{
-  address_word base = GPR[BASE];
-  address_word offset = EXTEND16 (OFFSET);
-  check_u64 (SD_, instruction_0);
-  {
-    address_word vaddr = loadstore_ea (SD_, base, offset);
-    address_word paddr;
-    int uncached;
-    if ((vaddr & 7) != 0)
-      {
-       SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, write_transfer, sim_core_unaligned_signal);
-      }
-    else
-      {
-       if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
-         {
-           unsigned64 memval = 0;
-           unsigned64 memval1 = 0;
-           memval = GPR[RT];
-           if (LLBIT)
-             {
-               StoreMemory(uncached,AccessLength_DOUBLEWORD,memval,memval1,paddr,vaddr,isREAL);
-             }
-           GPR[RT] = LLBIT;
-         }
-      }
-  }
+*vr4100:
+*vr5000:
+{
+  do_sc (SD_, RT, OFFSET, BASE, instruction_0);
+}
+
+
+111100,5.BASE,5.RT,16.OFFSET:NORMAL:64::SCD
+"scd r<RT>, <OFFSET>(r<BASE>)"
+*mipsIII:
+*mipsIV:
+*mipsV:
+*mips64:
+*mips64r2:
+*vr4100:
+*vr5000:
+{
+  check_u64 (SD_, instruction_0);
+  do_scd (SD_, RT, OFFSET, BASE);
 }
 
 
 *vr5000:
 *r3900:
 {
-  if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
-    Unpredictable ();
-  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
-  {
-    ALU32_BEGIN (GPR[RS]);
-    ALU32_SUB (GPR[RT]);
-    ALU32_END (GPR[RD]);   /* This checks for overflow.  */
-  }
-  TRACE_ALU_RESULT (GPR[RD]);
+  do_sub (SD_, RD, RS, RT);
 }
 
 
 *r3900:
 *vr5000:
 {
-  do_store (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
+  do_sw (SD_, RT, OFFSET, BASE);
 }
 
 
 *vr4100:
 *vr5000:
 {
-  if ((signed_word) GPR[RS] == (signed_word) GPR[RT])
-    SignalException (Trap, instruction_0);
+  do_teq (SD_, RS, RT, instruction_0);
 }
 
 
 *vr4100:
 *vr5000:
 {
-  if ((signed_word) GPR[RS] == (signed_word) EXTEND16 (IMMEDIATE))
-    SignalException (Trap, instruction_0);
+  do_teqi (SD_, RS, IMMEDIATE, instruction_0);
 }
 
 
 *vr4100:
 *vr5000:
 {
-  if ((signed_word) GPR[RS] >= (signed_word) GPR[RT])
-    SignalException (Trap, instruction_0);
+  do_tge (SD_, RS, RT, instruction_0);
 }
 
 
 *vr4100:
 *vr5000:
 {
-  if ((signed_word) GPR[RS] >= (signed_word) EXTEND16 (IMMEDIATE))
-    SignalException (Trap, instruction_0);
+  do_tgei (SD_, RS, IMMEDIATE, instruction_0);
 }
 
 
 *vr4100:
 *vr5000:
 {
-  if ((unsigned_word) GPR[RS] >= (unsigned_word) EXTEND16 (IMMEDIATE))
-    SignalException (Trap, instruction_0);
+  do_tgeiu (SD_, RS, IMMEDIATE, instruction_0);
 }
 
 
 *vr4100:
 *vr5000:
 {
-  if ((unsigned_word) GPR[RS] >= (unsigned_word) GPR[RT])
-    SignalException (Trap, instruction_0);
+  do_tgeu (SD_, RS, RT, instruction_0);
 }
 
 
 *vr4100:
 *vr5000:
 {
-  if ((signed_word) GPR[RS] < (signed_word) GPR[RT])
-    SignalException (Trap, instruction_0);
+  do_tlt (SD_, RS, RT, instruction_0);
 }
 
 
 *vr4100:
 *vr5000:
 {
-  if ((signed_word) GPR[RS] < (signed_word) EXTEND16 (IMMEDIATE))
-    SignalException (Trap, instruction_0);
+  do_tlti (SD_, RS, IMMEDIATE, instruction_0);
 }
 
 
 *vr4100:
 *vr5000:
 {
-  if ((unsigned_word) GPR[RS] < (unsigned_word) EXTEND16 (IMMEDIATE))
-    SignalException (Trap, instruction_0);
+  do_tltiu (SD_, RS, IMMEDIATE, instruction_0);
 }
 
 
 *vr4100:
 *vr5000:
 {
-  if ((unsigned_word) GPR[RS] < (unsigned_word) GPR[RT])
-    SignalException (Trap, instruction_0);
+  do_tltu (SD_, RS, RT, instruction_0);
 }
 
 
 *vr4100:
 *vr5000:
 {
-  if ((signed_word) GPR[RS] != (signed_word) GPR[RT])
-    SignalException (Trap, instruction_0);
+  do_tne (SD_, RS, RT, instruction_0);
 }
 
 
 *vr4100:
 *vr5000:
 {
-  if ((signed_word) GPR[RS] != (signed_word) EXTEND16 (IMMEDIATE))
-    SignalException (Trap, instruction_0);
+  do_tnei (SD_, RS, IMMEDIATE, instruction_0);
 }
 
 
 
 :function:::void:check_fmt_p:int fmt, instruction_word insn
 *mips32r2:
+*micromips32:
 {
   if ((fmt != fmt_single) && (fmt != fmt_double) && (fmt != fmt_ps))
     SignalException (ReservedInstruction, insn);
 *mipsV:
 *mips64:
 *mips64r2:
+*micromips64:
 {
   if ((fmt != fmt_single) && (fmt != fmt_double)
       && (fmt != fmt_ps || (UserMode && (SR & (status_UX|status_PX)) == 0)))
 *vr4100:
 *vr5000:
 *r3900:
+*micromips32:
+*micromips64:
 {
   if (! COP_Usable (1))
     SignalExceptionCoProcessorUnusable (1);
 *mipsII:
 *mips32:
 *mips32r2:
+*micromips32:
 {
   int bigendian = (BigEndianCPU ? ! ReverseEndian : ReverseEndian);
   address_word vaddr;
 *mipsII:
 *mips32:
 *mips32r2:
+*micromips32:
 {
   int bigendian = (BigEndianCPU ? ! ReverseEndian : ReverseEndian);
   address_word vaddr;
 *vr5000:
 *r3900:
 {
-  int fmt = FMT;
-  check_fpu (SD_);
-  check_fmt_p (SD_, fmt, instruction_0);
-  StoreFPR (FD, fmt, AbsoluteValue (ValueFPR (FS, fmt), fmt));
+  do_abs_fmt (SD_, FMT, FD, FS, instruction_0);
 }
 
 
 *vr5000:
 *r3900:
 {
-  int fmt = FMT;
-  check_fpu (SD_);
-  check_fmt_p (SD_, fmt, instruction_0);
-  StoreFPR (FD, fmt, Add (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt));
+  do_add_fmt (SD_, FMT, FD, FS, FT, instruction_0);
 }
 
 
 *mips64:
 *mips64r2:
 {
-  unsigned64 fs;
-  unsigned64 ft;
-  unsigned64 fd;
-  check_fpu (SD_);
-  check_u64 (SD_, instruction_0);
-  fs = ValueFPR (FS, fmt_ps);
-  if ((GPR[RS] & 0x3) != 0)
-    Unpredictable ();
-  if ((GPR[RS] & 0x4) == 0)
-    fd = fs;
-  else
-    {
-      ft = ValueFPR (FT, fmt_ps);
-      if (BigEndianCPU)
-       fd = PackPS (PSLower (fs), PSUpper (ft));
-      else
-       fd = PackPS (PSLower (ft), PSUpper (fs));
-    }
-  StoreFPR (FD, fmt_ps, fd);
+  do_alnv_ps (SD_, FD, FS, FT, RS, instruction_0);
 }
 
 
 *vr5000:
 *r3900:
 {
-  int fmt = FMT;
-  check_fpu (SD_);
-  check_fmt_p (SD_, fmt, instruction_0);
-  Compare (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt, COND, CC);
-  TRACE_ALU_RESULT (ValueFCR (31));
+  do_c_cond_fmt (SD_, COND, FMT, CC, FS, FT, instruction_0);
 }
 
 
 *vr5000:
 *r3900:
 {
-  int fmt = FMT;
-  check_fpu (SD_);
-  StoreFPR (FD, fmt_long, Convert (FP_RM_TOPINF, ValueFPR (FS, fmt), fmt,
-           fmt_long));
+  do_ceil_fmt (SD_, fmt_long, FMT, FD, FS, instruction_0);
 }
 
 
 *vr5000:
 *r3900:
 {
-  int fmt = FMT;
-  check_fpu (SD_);
-  StoreFPR (FD, fmt_word, Convert (FP_RM_TOPINF, ValueFPR (FS, fmt), fmt,
-           fmt_word));
+  do_ceil_fmt (SD_, fmt_word, FMT, FD, FS, instruction_0);
 }
 
 
 *mips64:
 *mips64r2:
 {
-  check_fpu (SD_);
-  if (FS == 0 || FS == 25 || FS == 26 || FS == 28 || FS == 31)
-    {
-      unsigned_word  fcr = ValueFCR (FS);
-      TRACE_ALU_INPUT1 (fcr);
-      GPR[RT] = fcr;
-    }
-  /* else NOP */
-  TRACE_ALU_RESULT (GPR[RT]);
+  do_cfc1 (SD_, RT, FS);
 }
 
 010001,00110,5.RT,5.FS,00000000000:COP1:32,f::CTC1a
 *mips64:
 *mips64r2:
 {
-  check_fpu (SD_);
-  TRACE_ALU_INPUT1 (GPR[RT]);
-  if (FS == 25 || FS == 26 || FS == 28 || FS == 31)
-      StoreFCR (FS, GPR[RT]);
-  /* else NOP */
+  do_ctc1 (SD_, RT, FS);
 }
 
 
 *vr5000:
 *r3900:
 {
-  int fmt = FMT;
-  check_fpu (SD_);
-  if ((fmt == fmt_double) | 0)
-    SignalException (ReservedInstruction, instruction_0);
-  StoreFPR (FD, fmt_double, Convert (GETRM (), ValueFPR (FS, fmt), fmt,
-           fmt_double));
+  do_cvt_d_fmt (SD_, FMT, FD, FS, instruction_0);
 }
 
 
 *vr5000:
 *r3900:
 {
-  int fmt = FMT;
-  check_fpu (SD_);
-  if ((fmt == fmt_long) | ((fmt == fmt_long) || (fmt == fmt_word)))
-    SignalException (ReservedInstruction, instruction_0);
-  StoreFPR (FD, fmt_long, Convert (GETRM (), ValueFPR (FS, fmt), fmt,
-           fmt_long));
+  do_cvt_l_fmt (SD_, FMT, FD, FS, instruction_0);
 }
 
 
 *mips64:
 *mips64r2:
 {
-  check_fpu (SD_);
-  check_u64 (SD_, instruction_0);
-  StoreFPR (FD, fmt_ps, PackPS (ValueFPR (FS, fmt_single),
-                               ValueFPR (FT, fmt_single)));
+  do_cvt_ps_s (SD_, FD, FS, FT, instruction_0);
 }
 
 
 *vr5000:
 *r3900:
 {
-  int fmt = FMT;
-  check_fpu (SD_);
-  if ((fmt == fmt_single) | 0)
-    SignalException (ReservedInstruction, instruction_0);
-  StoreFPR (FD, fmt_single, Convert (GETRM (), ValueFPR (FS, fmt), fmt,
-           fmt_single));
+  do_cvt_s_fmt (SD_, FMT, FD, FS, instruction_0);
 }
 
 
 *mips64:
 *mips64r2:
 {
-  check_fpu (SD_);
-  check_u64 (SD_, instruction_0);
-  StoreFPR (FD, fmt_single, PSLower (ValueFPR (FS, fmt_ps)));
+  do_cvt_s_pl (SD_, FD, FS, instruction_0);
 }
 
 
 *mips64:
 *mips64r2:
 {
-  check_fpu (SD_);
-  check_u64 (SD_, instruction_0);
-  StoreFPR (FD, fmt_single, PSUpper (ValueFPR (FS, fmt_ps)));
+  do_cvt_s_pu (SD_, FD, FS, instruction_0);
 }
 
 
 *vr5000:
 *r3900:
 {
-  int fmt = FMT;
-  check_fpu (SD_);
-  if ((fmt == fmt_word) | ((fmt == fmt_long) || (fmt == fmt_word)))
-    SignalException (ReservedInstruction, instruction_0);
-  StoreFPR (FD, fmt_word, Convert (GETRM (), ValueFPR (FS, fmt), fmt,
-           fmt_word));
+  do_cvt_w_fmt (SD_, FMT, FD, FS, instruction_0);
 }
 
 
 *vr5000:
 *r3900:
 {
-  int fmt = FMT;
-  check_fpu (SD_);
-  StoreFPR (FD, fmt, Divide (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt));
+  do_div_fmt (SD_, FMT, FD, FS, FT, instruction_0);
 }
 
 
 {
   check_fpu (SD_);
   check_u64 (SD_, instruction_0);
-  if (SizeFGR () == 64)
-    GPR[RT] = FGR[FS];
-  else if ((FS & 0x1) == 0)
-    GPR[RT] = SET64HI (FGR[FS+1]) | FGR[FS];
-  else
-    GPR[RT] = SET64HI (0xDEADC0DE) | 0xBAD0BAD0;
-  TRACE_ALU_RESULT (GPR[RT]);
+  do_dmfc1b (SD_, RT, FS);
 }
 
 
 {
   check_fpu (SD_);
   check_u64 (SD_, instruction_0);
-  if (SizeFGR () == 64)
-    StoreFPR (FS, fmt_uninterpreted_64, GPR[RT]);
-  else if ((FS & 0x1) == 0)
-    StoreFPR (FS, fmt_uninterpreted_64, GPR[RT]);
-  else
-    Unpredictable ();
+  do_dmtc1b (SD_, RT, FS);
 }
 
 
 *vr5000:
 *r3900:
 {
-  int fmt = FMT;
-  check_fpu (SD_);
-  StoreFPR (FD, fmt_long, Convert (FP_RM_TOMINF, ValueFPR (FS, fmt), fmt,
-           fmt_long));
+  do_floor_fmt (SD_, fmt_long, FMT, FD, FS);
 }
 
 
 *vr5000:
 *r3900:
 {
-  int fmt = FMT;
-  check_fpu (SD_);
-  StoreFPR (FD, fmt_word, Convert (FP_RM_TOMINF, ValueFPR (FS, fmt), fmt,
-           fmt_word));
+  do_floor_fmt (SD_, fmt_word, FMT, FD, FS);
 }
 
 
 "luxc1 f<FD>, r<INDEX>(r<BASE>)"
 *mips32r2:
 {
-  address_word base = GPR[BASE];
-  address_word index = GPR[INDEX];
-  address_word vaddr = base + index;
-  check_fpu (SD_);
-  if (SizeFGR () != 64)
-    Unpredictable ();
-  /* Arrange for the bottom 3 bits of (base + index) to be 0.  */
-  if ((vaddr & 0x7) != 0)
-    index -= (vaddr & 0x7);
-  COP_LD (1, FD, do_load_double (SD_, base, index));
+  do_luxc1_32 (SD_, FD, INDEX, BASE);
 }
 
 
 *mips64:
 *mips64r2:
 {
-  address_word base = GPR[BASE];
-  address_word index = GPR[INDEX];
-  address_word vaddr = base + index;
   check_fpu (SD_);
   check_u64 (SD_, instruction_0);
-  if (SizeFGR () != 64)
-    Unpredictable ();
-  /* Arrange for the bottom 3 bits of (base + index) to be 0.  */
-  if ((vaddr & 0x7) != 0)
-    index -= (vaddr & 0x7);
-  COP_LD (1, FD, do_load (SD_, AccessLength_DOUBLEWORD, base, index));
+  do_luxc1_64 (SD_, FD, INDEX, BASE);
 }
 
 
 *vr5000:
 *r3900:
 {
-  check_fpu (SD_);
-  COP_LW (1, FT, do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET)));
+  do_lwc1 (SD_, FT, OFFSET, BASE);
 }
 
 
 *mips64r2:
 *vr5000:
 {
-  check_fpu (SD_);
-  check_u64 (SD_, instruction_0);
-  COP_LW (1, FD, do_load (SD_, AccessLength_WORD, GPR[BASE], GPR[INDEX]));
+  do_lwxc1 (SD_, FD, INDEX, BASE, instruction_0);
 }
 
 
 *mips64r2:
 *vr5000:
 {
-  int fmt = FMT;
-  check_fpu (SD_);
-  check_u64 (SD_, instruction_0);
-  check_fmt_p (SD_, fmt, instruction_0); 
-  StoreFPR (FD, fmt, MultiplyAdd (ValueFPR (FS, fmt), ValueFPR (FT, fmt),
-                                 ValueFPR (FR, fmt), fmt));
+  do_madd_fmt (SD_, FMT, FD, FR, FS, FT, instruction_0);
 }
 
 
 *vr5000:
 *r3900:
 { 
-  check_fpu (SD_);
-  GPR[RT] = EXTEND32 (FGR[FS]);
-  TRACE_ALU_RESULT (GPR[RT]);
+  do_mfc1b (SD_, RT, FS);
 }
 
 
 *vr5000:
 *r3900:
 {
-  int fmt = FMT;
-  check_fpu (SD_);
-  check_fmt_p (SD_, fmt, instruction_0);
-  StoreFPR (FD, fmt, ValueFPR (FS, fmt));
+  do_mov_fmt (SD_, FMT, FD, FS, instruction_0);
 }
 
 
 *mips64r2:
 *vr5000:
 {
-  check_fpu (SD_);
-  if (GETFCC(CC) == TF)
-    GPR[RD] = GPR[RS];
+  do_movtf (SD_, TF, RD, RS, CC);
 }
 
 
 *mips64r2:
 *vr5000:
 {
-  int fmt = FMT;
-  check_fpu (SD_);
-  if (fmt != fmt_ps)
-    {
-      if (GETFCC(CC) == TF)
-       StoreFPR (FD, fmt, ValueFPR (FS, fmt));
-      else
-       StoreFPR (FD, fmt, ValueFPR (FD, fmt));   /* set fmt */
-    }
-  else
-    {
-      unsigned64 fd;
-      fd = PackPS (PSUpper (ValueFPR ((GETFCC (CC+1) == TF) ? FS : FD,
-                                     fmt_ps)),
-                  PSLower (ValueFPR ((GETFCC (CC+0) == TF) ? FS : FD,
-                                     fmt_ps)));
-      StoreFPR (FD, fmt_ps, fd);
-    }
+  do_movtf_fmt (SD_, TF, FMT, FD, FS, CC);
 }
 
 
 *mips64r2:
 *vr5000:
 {
-  check_fpu (SD_);
-  if (GPR[RT] != 0)
-    StoreFPR (FD, FMT, ValueFPR (FS, FMT));
-  else
-    StoreFPR (FD, FMT, ValueFPR (FD, FMT));
+  do_movn_fmt (SD_, FMT, FD, FS, RT);
 }
 
 
 *mips64r2:
 *vr5000:
 {
-  check_fpu (SD_);
-  if (GPR[RT] == 0)
-    StoreFPR (FD, FMT, ValueFPR (FS, FMT));
-  else
-    StoreFPR (FD, FMT, ValueFPR (FD, FMT));
+  do_movz_fmt (SD_, FMT, FD, FS, RT);
 }
 
 
 *mips64r2:
 *vr5000:
 {
-  int fmt = FMT;
-  check_fpu (SD_);
-  check_u64 (SD_, instruction_0);
-  check_fmt_p (SD_, fmt, instruction_0);
-  StoreFPR (FD, fmt, MultiplySub (ValueFPR (FS, fmt), ValueFPR (FT, fmt),
-                                 ValueFPR (FR, fmt), fmt));
+  do_msub_fmt (SD_, FMT, FD, FR, FS, FT, instruction_0);
 }
 
 
 *vr5000:
 *r3900:
 {
-  check_fpu (SD_); 
-  StoreFPR (FS, fmt_uninterpreted_32, VL4_8 (GPR[RT]));
+  do_mtc1b (SD_, RT, FS);
 }
 
 
 *vr5000:
 *r3900:
 {
-  int fmt = FMT;
-  check_fpu (SD_);
-  check_fmt_p (SD_, fmt, instruction_0);
-  StoreFPR (FD, fmt, Multiply (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt));
+  do_mul_fmt (SD_, FMT, FD, FS, FT, instruction_0);
 }
 
 
 *vr5000:
 *r3900:
 {
-  int fmt = FMT;
-  check_fpu (SD_);
-  check_fmt_p (SD_, fmt, instruction_0);
-  StoreFPR (FD, fmt, Negate (ValueFPR (FS, fmt), fmt));
+  do_neg_fmt (SD_, FMT, FD, FS, instruction_0);
 }
 
 
 *mips64r2:
 *vr5000:
 {
-  int fmt = FMT;
-  check_fpu (SD_);
-  check_u64 (SD_, instruction_0);
-  check_fmt_p (SD_, fmt, instruction_0);
-  StoreFPR (FD, fmt, NegMultiplyAdd (ValueFPR (FS, fmt), ValueFPR (FT, fmt),
-                                    ValueFPR (FR, fmt), fmt));
+  do_nmadd_fmt (SD_, FMT, FD, FR, FS, FT, instruction_0);
 }
 
 
 *mips64r2:
 *vr5000:
 {
-  int fmt = FMT;
-  check_fpu (SD_);
-  check_u64 (SD_, instruction_0);
-  check_fmt_p (SD_, fmt, instruction_0);
-  StoreFPR (FD, fmt, NegMultiplySub (ValueFPR (FS, fmt), ValueFPR (FT, fmt),
-                                    ValueFPR (FR, fmt), fmt));
+  do_nmsub_fmt (SD_, FMT, FD, FR, FS, FT, instruction_0);
 }
 
 
 *mips64:
 *mips64r2:
 {
-  check_fpu (SD_);
-  check_u64 (SD_, instruction_0);
-  StoreFPR (FD, fmt_ps, PackPS (PSLower (ValueFPR (FS, fmt_ps)),
-                               PSLower (ValueFPR (FT, fmt_ps))));
+  do_pll_ps (SD_, FD, FS, FT, instruction_0);
 }
 
 
 *mips64:
 *mips64r2:
 {
-  check_fpu (SD_);
-  check_u64 (SD_, instruction_0);
-  StoreFPR (FD, fmt_ps, PackPS (PSLower (ValueFPR (FS, fmt_ps)),
-                               PSUpper (ValueFPR (FT, fmt_ps))));
+  do_plu_ps (SD_, FD, FS, FT, instruction_0);
 }
 
 
 *mips64r2:
 *vr5000:
 {
-  address_word base = GPR[BASE];
-  address_word index = GPR[INDEX];
-  {
-    address_word vaddr = loadstore_ea (SD_, base, index);
-    address_word paddr;
-    int uncached;
-    if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
-      Prefetch(uncached,paddr,vaddr,isDATA,HINT);
-  }
+  do_prefx (SD_, HINT, INDEX, BASE);
 }
 
 
 *mips64:
 *mips64r2:
 {
-  check_fpu (SD_);
-  check_u64 (SD_, instruction_0);
-  StoreFPR (FD, fmt_ps, PackPS (PSUpper (ValueFPR (FS, fmt_ps)),
-                               PSLower (ValueFPR (FT, fmt_ps))));
+  do_pul_ps (SD_, FD, FS, FT, instruction_0);
 }
 
 
 *mips64:
 *mips64r2:
 {
-  check_fpu (SD_);
-  check_u64 (SD_, instruction_0);
-  StoreFPR (FD, fmt_ps, PackPS (PSUpper (ValueFPR (FS, fmt_ps)),
-                               PSUpper (ValueFPR (FT, fmt_ps))));
+  do_puu_ps (SD_, FD, FS, FT, instruction_0);
 }
 
 
 *mips64r2:
 *vr5000:
 {
-  int fmt = FMT;
-  check_fpu (SD_);
-  StoreFPR (FD, fmt, Recip (ValueFPR (FS, fmt), fmt));
+  do_recip_fmt (SD_, FMT, FD, FS);
 }
 
 
 *vr5000:
 *r3900:
 {
-  int fmt = FMT;
-  check_fpu (SD_);
-  StoreFPR (FD, fmt_long, Convert (FP_RM_NEAREST, ValueFPR (FS, fmt), fmt,
-           fmt_long));
+  do_round_fmt (SD_, fmt_long, FMT, FD, FS);
 }
 
 
 *vr5000:
 *r3900:
 {
-  int fmt = FMT;
-  check_fpu (SD_);
-  StoreFPR (FD, fmt_word, Convert (FP_RM_NEAREST, ValueFPR (FS, fmt), fmt,
-           fmt_word));
+  do_round_fmt (SD_, fmt_word, FMT, FD, FS);
 }
 
 
 *mips64r2:
 *vr5000:
 {
-  int fmt = FMT;
-  check_fpu (SD_);
-  StoreFPR (FD, fmt, RSquareRoot (ValueFPR (FS, fmt), fmt));
+  do_rsqrt_fmt (SD_, FMT, FD, FS);
 }
 
 
 *mips32:
 *mips32r2:
 {
-  check_fpu (SD_);
-  do_store_double (SD_, GPR[BASE], EXTEND16 (OFFSET), COP_SD (1, FT));
+  do_sdc1 (SD_, FT, OFFSET, BASE);
 }
 
 
 "suxc1 f<FS>, r<INDEX>(r<BASE>)"
 *mips32r2:
 {
-  address_word base = GPR[BASE];
-  address_word index = GPR[INDEX];
-  address_word vaddr = base + index;
-  check_fpu (SD_);
-  if (SizeFGR () != 64)
-    Unpredictable ();
-  /* Arrange for the bottom 3 bits of (base + index) to be 0.  */
-  if ((vaddr & 0x7) != 0)
-    index -= (vaddr & 0x7);
-  do_store_double (SD_, base, index, COP_SD (1, FS));
+  do_suxc1_32 (SD_, FS, INDEX, BASE);
 }
 
 
 *mips64:
 *mips64r2:
 {
-  address_word base = GPR[BASE];
-  address_word index = GPR[INDEX];
-  address_word vaddr = base + index;
   check_fpu (SD_);
   check_u64 (SD_, instruction_0);
-  if (SizeFGR () != 64)
-    Unpredictable ();
-  /* Arrange for the bottom 3 bits of (base + index) to be 0.  */
-  if ((vaddr & 0x7) != 0)
-    index -= (vaddr & 0x7);
-  do_store (SD_, AccessLength_DOUBLEWORD, base, index, COP_SD (1, FS));
+  do_suxc1_64 (SD_, FS, INDEX, BASE);
 }
 
 
 *vr5000:
 *r3900:
 {
-  int fmt = FMT;
-  check_fpu (SD_);
-  StoreFPR (FD, fmt,  (SquareRoot (ValueFPR (FS, fmt), fmt)));
+  do_sqrt_fmt (SD_, FMT, FD, FS);
 }
 
 
 *vr5000:
 *r3900:
 {
-  int fmt = FMT;
-  check_fpu (SD_);
-  check_fmt_p (SD_, fmt, instruction_0);
-  StoreFPR (FD, fmt, Sub (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt));
+  do_sub_fmt (SD_, FMT, FD, FS, FT, instruction_0);
 }
 
 
 *vr5000:
 *r3900:
 {
-  address_word base = GPR[BASE];
-  address_word offset = EXTEND16 (OFFSET);
-  check_fpu (SD_);
-  {
-    address_word vaddr = loadstore_ea (SD_, base, offset);
-    address_word paddr;
-    int uncached;
-    if ((vaddr & 3) != 0)
-      {
-       SIM_CORE_SIGNAL (SD, CPU, cia, read_map, AccessLength_WORD+1, vaddr, write_transfer, sim_core_unaligned_signal);
-      }
-    else
-      {
-       if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
-         {
-           uword64 memval = 0;
-           uword64 memval1 = 0;
-           uword64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
-           address_word reverseendian = (ReverseEndian ?(mask ^ AccessLength_WORD): 0);
-           address_word bigendiancpu = (BigEndianCPU ?(mask ^ AccessLength_WORD): 0);
-           unsigned int byte;
-           paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
-           byte = ((vaddr & mask) ^ bigendiancpu);
-           memval = (((uword64)COP_SW(((instruction_0 >> 26) & 0x3),FT)) << (8 * byte));
-           StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL);
-         }
-      }
-  }
+  do_swc1 (SD_, FT, OFFSET, BASE, instruction_0);
 }
 
 
 *mips64r2:
 *vr5000:
 {
-
-  address_word base = GPR[BASE];
-  address_word index = GPR[INDEX];
-  check_fpu (SD_);
-  check_u64 (SD_, instruction_0);
-  {
-   address_word vaddr = loadstore_ea (SD_, base, index);
-   address_word paddr;
-   int uncached;
-   if ((vaddr & 3) != 0)
-     {
-       SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer, sim_core_unaligned_signal);
-     }
-   else
-   {
-    if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
-    {
-     unsigned64 memval = 0;
-     unsigned64 memval1 = 0;
-     unsigned64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
-     address_word reverseendian = (ReverseEndian ? (mask ^ AccessLength_WORD) : 0);
-     address_word bigendiancpu = (BigEndianCPU ? (mask ^ AccessLength_WORD) : 0);
-     unsigned int byte;
-     paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
-     byte = ((vaddr & mask) ^ bigendiancpu);
-     memval = (((unsigned64)COP_SW(1,FS)) << (8 * byte));
-      {
-       StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL);
-      }
-    }
-   }
-  }
+  do_swxc1 (SD_, FS, INDEX, BASE, instruction_0);
 }
 
 
 *vr5000:
 *r3900:
 {
-  int fmt = FMT;
-  check_fpu (SD_);
-  StoreFPR (FD, fmt_long, Convert (FP_RM_TOZERO, ValueFPR (FS, fmt), fmt,
-           fmt_long));
+  do_trunc_fmt (SD_, fmt_long, FMT, FD, FS);
 }
 
 
 *vr5000:
 *r3900:
 {
-  int fmt = FMT;
-  check_fpu (SD_);
-  StoreFPR (FD, fmt_word, Convert (FP_RM_TOZERO, ValueFPR (FS, fmt), fmt,
-           fmt_word));
+  do_trunc_fmt (SD_, fmt_word, FMT, FD, FS);
 }
 
 \f
 }
 
 
-010000,00001,5.RT,5.RD,00000000000:COP0:64::DMFC0
+010000,00001,5.RT,5.RD,00000000,3.SEL:COP0:64::DMFC0
 "dmfc0 r<RT>, r<RD>"
 *mipsIII:
 *mipsIV:
 *mips64r2:
 {
   check_u64 (SD_, instruction_0);
-  DecodeCoproc (instruction_0);
+  DecodeCoproc (instruction_0, 0, cp0_dmfc0, RT, RD, SEL);
 }
 
 
-010000,00101,5.RT,5.RD,00000000000:COP0:64::DMTC0
+010000,00101,5.RT,5.RD,00000000,3.SEL:COP0:64::DMTC0
 "dmtc0 r<RT>, r<RD>"
 *mipsIII:
 *mipsIV:
 *mips64r2:
 {
   check_u64 (SD_, instruction_0);
-  DecodeCoproc (instruction_0);
+  DecodeCoproc (instruction_0, 0, cp0_dmtc0, RT, RD, SEL);
 }
 
 
 }
 
 
-010000,00000,5.RT,5.RD,00000,6.REGX:COP0:32::MFC0
-"mfc0 r<RT>, r<RD> # <REGX>"
+010000,00000,5.RT,5.RD,00000000,3.SEL:COP0:32::MFC0
+"mfc0 r<RT>, r<RD> # <SEL>"
 *mipsI:
 *mipsII:
 *mipsIII:
 *r3900:
 {
   TRACE_ALU_INPUT0 ();
-  DecodeCoproc (instruction_0);
+  DecodeCoproc (instruction_0, 0, cp0_mfc0, RT, RD, SEL);
   TRACE_ALU_RESULT (GPR[RT]);
 }
 
-010000,00100,5.RT,5.RD,00000,6.REGX:COP0:32::MTC0
-"mtc0 r<RT>, r<RD> # <REGX>"
+010000,00100,5.RT,5.RD,00000000,3.SEL:COP0:32::MTC0
+"mtc0 r<RT>, r<RD> # <SEL>"
 *mipsI:
 *mipsII:
 *mipsIII:
 *vr5000:
 *r3900:
 {
-  DecodeCoproc (instruction_0);
+  DecodeCoproc (instruction_0, 0, cp0_mtc0, RT, RD, SEL);
 }
 
 
 *vr5000:
 *r3900:
 {
-  DecodeCoproc (instruction_0);
+  DecodeCoproc (instruction_0, 0, cp0_rfe, 0, 0, 0x10);
 }
 
 
 *vr4100:
 *r3900:
 {
-  DecodeCoproc (instruction_0);
+  DecodeCoproc (instruction_0, 2, 0, 0, 0, 0);
 }
 
 
 :include:::dsp.igen
 :include:::dsp2.igen
 :include:::smartmips.igen
+:include:::micromips.igen
+:include:::micromipsdsp.igen
 
index 90ad55423201d99b767ea9cf3b85996ed8ac4fa2..1c299c3870ad2db60b6bf8d8e46e71eae5f85696 100644 (file)
@@ -4,7 +4,7 @@
 // Copyright (C) 2004-2015 Free Software Foundation, Inc.
 // Contributed by David Ung, of MIPS Technologies.
 //
-// This file is part of GDB, the GNU debugger.
+// This file is part of the MIPS sim.
 // 
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
 // You should have received a copy of the GNU General Public License
 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+:function:::void:do_dsbh:int rd, int rt
+{
+  union { unsigned64 d; unsigned16 h[4]; } u;
+  TRACE_ALU_INPUT1 (GPR[rt]);
+  u.d = GPR[rt];
+  u.h[0] = SWAP_2 (u.h[0]);
+  u.h[1] = SWAP_2 (u.h[1]);
+  u.h[2] = SWAP_2 (u.h[2]);
+  u.h[3] = SWAP_2 (u.h[3]);
+  GPR[rd] = u.d;
+  TRACE_ALU_RESULT1 (GPR[rd]);
+}
+
+:function:::void:do_dshd:int rd, int rt
+{
+  unsigned64 d;
+  TRACE_ALU_INPUT1 (GPR[rt]);
+  d = GPR[rt];
+  GPR[rd] = ((d >> 48)
+            | (d << 48)
+            | ((d & 0x0000ffff00000000ULL) >> 16)
+            | ((d & 0x00000000ffff0000ULL) << 16));
+  TRACE_ALU_RESULT1 (GPR[rd]);
+}
+
+:function:::void:do_dext:int rt, int rs, int lsb, int size
+{
+  TRACE_ALU_INPUT3 (GPR[rs], lsb, size);
+  GPR[rt] = EXTRACTED64 (GPR[rs], lsb + size, lsb);
+  TRACE_ALU_RESULT1 (GPR[rt]);
+}
+
+:function:::void:do_dextm:int rt, int rs, int lsb, int size
+{
+  TRACE_ALU_INPUT3 (GPR[rs], lsb, size);
+  GPR[rt] = EXTRACTED64 (GPR[rs], lsb + size + 32, lsb);
+  TRACE_ALU_RESULT1 (GPR[rt]);
+}
+
+:function:::void:do_dextu:int rt, int rs, int lsb, int size
+{
+  TRACE_ALU_INPUT3 (GPR[rs], lsb, size);
+  GPR[rt] = EXTRACTED64 (GPR[rs], lsb + 32 + size, lsb + 32);
+  TRACE_ALU_RESULT1 (GPR[rt]);
+}
+
+:function:::void:do_di:int rt
+{
+  TRACE_ALU_INPUT0 ();
+  GPR[rt] = EXTEND32 (SR);
+  SR &= ~status_IE;
+  TRACE_ALU_RESULT1 (GPR[rt]);
+}
+
+:function:::void:do_dins:int rt, int rs, int lsb, int msb
+{
+  TRACE_ALU_INPUT4 (GPR[rt], GPR[rs], lsb, msb);
+  if (lsb <= msb)
+    GPR[rt] ^= (GPR[rt] ^ (GPR[rs] << lsb)) & MASK64 (msb, lsb);
+  TRACE_ALU_RESULT1 (GPR[rt]);
+}
+
+:function:::void:do_dinsm:int rt, int rs, int lsb, int msb
+{
+  TRACE_ALU_INPUT4 (GPR[rt], GPR[rs], lsb, msb);
+  if (lsb <= msb + 32)
+    GPR[rt] ^= (GPR[rt] ^ (GPR[rs] << lsb)) & MASK64 (msb + 32, lsb);
+  TRACE_ALU_RESULT1 (GPR[rt]);
+}
+
+:function:::void:do_ei:int rt
+{
+  TRACE_ALU_INPUT0 ();
+  GPR[rt] = EXTEND32 (SR);
+  SR |= status_IE;
+  TRACE_ALU_RESULT1 (GPR[rt]);
+}
+
+:function:::void:do_ext:int rt, int rs, int lsb, int size
+{
+  TRACE_ALU_INPUT3 (GPR[rs], lsb, size);
+  GPR[rt] = EXTEND32 (EXTRACTED32 (GPR[rs], lsb + size, lsb));
+  TRACE_ALU_RESULT1 (GPR[rt]);
+}
+
+:function:::void:do_mfhc1:int rt, int fs
+{
+  check_fpu (SD_);
+  if (SizeFGR() == 64)
+    GPR[rt] = EXTEND32 (WORD64HI (FGR[fs]));
+  else if ((fs & 0x1) == 0)
+    GPR[rt] = EXTEND32 (FGR[fs + 1]);
+  else
+    {
+      if (STATE_VERBOSE_P(SD))
+       sim_io_eprintf (SD,
+                "Warning: PC 0x%lx: MFHC1 32-bit use of odd FPR number\n",
+                       (long) CIA);
+      GPR[rt] = EXTEND32 (0xBADF00D);
+    }
+  TRACE_ALU_RESULT (GPR[rt]);
+}
+
+:function:::void:do_mthc1:int rt, int fs
+{
+  check_fpu (SD_);
+  if (SizeFGR() == 64)
+    StoreFPR (fs, fmt_uninterpreted_64, SET64HI (GPR[rt]) | VL4_8 (FGR[fs]));
+  else if ((fs & 0x1) == 0)
+    StoreFPR (fs + 1, fmt_uninterpreted_32, VL4_8 (GPR[rt]));
+  else
+    {
+      if (STATE_VERBOSE_P(SD))
+       sim_io_eprintf (SD,
+                "Warning: PC 0x%lx: MTHC1 32-bit use of odd FPR number\n",
+                       (long) CIA);
+      StoreFPR (fs, fmt_uninterpreted_32, 0xDEADC0DE);
+    }
+  TRACE_FP_RESULT (GPR[rt]);
+}
+
+:function:::void:do_ins:int rt, int rs, int lsb, int msb
+{
+  TRACE_ALU_INPUT4 (GPR[rt], GPR[rs], lsb, msb);
+  if (lsb <= msb)
+    GPR[rt] = EXTEND32 (GPR[rt] ^
+                       ((GPR[rt] ^ (GPR[rs] << lsb)) & MASK32 (msb, lsb)));
+  TRACE_ALU_RESULT1 (GPR[rt]);
+}
+
+:function:::void:do_dinsu:int rt, int rs, int lsb, int msb
+{
+  TRACE_ALU_INPUT4 (GPR[rt], GPR[rs], lsb, msb);
+  if (lsb <= msb)
+    GPR[rt] ^= (GPR[rt] ^ (GPR[rs] << (lsb + 32)))
+      & MASK64 (msb + 32, lsb + 32);
+  TRACE_ALU_RESULT1 (GPR[rt]);
+}
+
+:function:::void:do_seb:int rd, int rt
+{
+  TRACE_ALU_INPUT1 (GPR[rt]);
+  GPR[rd] = EXTEND8 (GPR[rt]);
+  TRACE_ALU_RESULT1 (GPR[rd]);
+}
+
+:function:::void:do_seh:int rd, int rt
+{
+  TRACE_ALU_INPUT1 (GPR[rt]);
+  GPR[rd] = EXTEND16 (GPR[rt]);
+  TRACE_ALU_RESULT1 (GPR[rd]);
+}
+
+:function:::void:do_rdhwr:int rt, int rd
+{
+  // Return 0 for all hardware registers currently
+  GPR[rt] = EXTEND32 (0);
+  TRACE_ALU_RESULT1 (GPR[rt]);
+}
+
+:function:::void:do_wsbh:int rd, int rt
+{
+  union { unsigned32 w; unsigned16 h[2]; } u;
+  TRACE_ALU_INPUT1 (GPR[rt]);
+  u.w = GPR[rt];
+  u.h[0] = SWAP_2 (u.h[0]);
+  u.h[1] = SWAP_2 (u.h[1]);
+  GPR[rd] = EXTEND32 (u.w);
+  TRACE_ALU_RESULT1 (GPR[rd]);
+}
 
 011111,5.RS,5.RT,5.SIZE,5.LSB,000011::64::DEXT
 "dext r<RT>, r<RS>, <LSB>, <SIZE+1>"
 *mips64r2:
 {
   check_u64 (SD_, instruction_0);
-  TRACE_ALU_INPUT3 (GPR[RS], LSB, SIZE);
-  GPR[RT] = EXTRACTED64 (GPR[RS], LSB + SIZE, LSB);
-  TRACE_ALU_RESULT1 (GPR[RT]);
+  do_dext (SD_, RT, RS, LSB, SIZE);
 }
 
 011111,5.RS,5.RT,5.SIZE,5.LSB,000001::64::DEXTM
 *mips64r2:
 {
   check_u64 (SD_, instruction_0);
-  TRACE_ALU_INPUT3 (GPR[RS], LSB, SIZE);
-  GPR[RT] = EXTRACTED64 (GPR[RS], LSB + SIZE + 32, LSB);
-  TRACE_ALU_RESULT1 (GPR[RT]);
+  do_dextm (SD_, RT, RS, LSB, SIZE);
 }
 
 011111,5.RS,5.RT,5.SIZE,5.LSB,000010::64::DEXTU
 *mips64r2:
 {
   check_u64 (SD_, instruction_0);
-  TRACE_ALU_INPUT3 (GPR[RS], LSB, SIZE);
-  GPR[RT] = EXTRACTED64 (GPR[RS], LSB + 32 + SIZE, LSB + 32);
-  TRACE_ALU_RESULT1 (GPR[RT]);
+  do_dextu (SD_, RT, RS, LSB, SIZE);
 }
 
 
 *mips32r2:
 *mips64r2:
 {
-  TRACE_ALU_INPUT0 ();
-  GPR[RT] = EXTEND32 (SR);
-  SR &= ~status_IE;
-  TRACE_ALU_RESULT1 (GPR[RT]);
+  do_di (SD_, RT);
 }
 
 
 *mips64r2:
 {
   check_u64 (SD_, instruction_0);
-  TRACE_ALU_INPUT4 (GPR[RT], GPR[RS], LSB, MSB);
-  if (LSB <= MSB)
-    GPR[RT] ^= (GPR[RT] ^ (GPR[RS] << LSB)) & MASK64 (MSB, LSB);
-  TRACE_ALU_RESULT1 (GPR[RT]);
+  do_dins (SD_, RT, RS, LSB, MSB);
 }
 
 011111,5.RS,5.RT,5.MSB,5.LSB,000101::64::DINSM
 *mips64r2:
 {
   check_u64 (SD_, instruction_0);
-  TRACE_ALU_INPUT4 (GPR[RT], GPR[RS], LSB, MSB);
-  if (LSB <= MSB + 32)
-    GPR[RT] ^= (GPR[RT] ^ (GPR[RS] << LSB)) & MASK64 (MSB + 32, LSB);
-  TRACE_ALU_RESULT1 (GPR[RT]);
+  do_dinsm (SD_, RT, RS, LSB, MSB);
 }
 
 011111,5.RS,5.RT,5.MSB,5.LSB,000110::64::DINSU
 *mips64r2:
 {
   check_u64 (SD_, instruction_0);
-  TRACE_ALU_INPUT4 (GPR[RT], GPR[RS], LSB, MSB);
-  if (LSB <= MSB)
-    GPR[RT] ^= (GPR[RT] ^ (GPR[RS] << (LSB + 32)))
-      & MASK64 (MSB + 32, LSB + 32);
-  TRACE_ALU_RESULT1 (GPR[RT]);
+  do_dinsu (SD_, RT, RS, LSB, MSB);
 }
 
 
 "dsbh r<RD>, r<RT>"
 *mips64r2:
 {
-  union { unsigned64 d; unsigned16 h[4]; } u;
   check_u64 (SD_, instruction_0);
-  TRACE_ALU_INPUT1 (GPR[RT]);
-  u.d = GPR[RT];
-  u.h[0] = SWAP_2 (u.h[0]);
-  u.h[1] = SWAP_2 (u.h[1]);
-  u.h[2] = SWAP_2 (u.h[2]);
-  u.h[3] = SWAP_2 (u.h[3]);
-  GPR[RD] = u.d;
-  TRACE_ALU_RESULT1 (GPR[RD]);
+  do_dsbh (SD_, RD, RT);
 }
 
 011111,00000,5.RT,5.RD,00101,100100::64::DSHD
 "dshd r<RD>, r<RT>"
 *mips64r2:
 {
-  unsigned64 d;
   check_u64 (SD_, instruction_0);
-  TRACE_ALU_INPUT1 (GPR[RT]);
-  d = GPR[RT];
-  GPR[RD] = ((d >> 48)
-            | (d << 48)
-            | ((d & 0x0000ffff00000000ULL) >> 16)
-            | ((d & 0x00000000ffff0000ULL) << 16));
-  TRACE_ALU_RESULT1 (GPR[RD]);
+  do_dshd (SD_, RD, RT);
 }
 
-
 010000,01011,5.RT,01100,00000,1,00,000::32::EI
 "ei":RT == 0
 "ei r<RT>"
 *mips32r2:
 *mips64r2:
 {
-  TRACE_ALU_INPUT0 ();
-  GPR[RT] = EXTEND32 (SR);
-  SR |= status_IE;
-  TRACE_ALU_RESULT1 (GPR[RT]);
+  do_ei (SD_, RT);
 }
 
 
 *mips32r2:
 *mips64r2:
 {
-  TRACE_ALU_INPUT3 (GPR[RS], LSB, SIZE);
-  GPR[RT] = EXTEND32 (EXTRACTED32 (GPR[RS], LSB + SIZE, LSB));
-  TRACE_ALU_RESULT1 (GPR[RT]);
+  do_ext (SD_, RT, RS, LSB, SIZE);
 }
 
 
 *mips32r2:
 *mips64r2:
 {
-  check_fpu (SD_);
-  if (SizeFGR() == 64)
-    GPR[RT] = EXTEND32 (WORD64HI (FGR[FS]));
-  else if ((FS & 0x1) == 0)
-    GPR[RT] = EXTEND32 (FGR[FS + 1]);
-  else
-    {
-      if (STATE_VERBOSE_P(SD))
-       sim_io_eprintf (SD, 
-                "Warning: PC 0x%lx: MFHC1 32-bit use of odd FPR number\n",
-                       (long) CIA);
-      GPR[RT] = EXTEND32 (0xBADF00D);
-    }
-  TRACE_ALU_RESULT (GPR[RT]);
+  do_mfhc1 (SD_, RT, FS);
 }
 
 010001,00111,5.RT,5.FS,00000000000:COP1Sa:32,f::MTHC1
 *mips32r2:
 *mips64r2:
 {
-  check_fpu (SD_); 
-  if (SizeFGR() == 64)
-    StoreFPR (FS, fmt_uninterpreted_64, SET64HI (GPR[RT]) | VL4_8 (FGR[FS]));
-  else if ((FS & 0x1) == 0)
-    StoreFPR (FS + 1, fmt_uninterpreted_32, VL4_8 (GPR[RT]));
-  else
-    {
-      if (STATE_VERBOSE_P(SD))
-       sim_io_eprintf (SD, 
-                "Warning: PC 0x%lx: MTHC1 32-bit use of odd FPR number\n",
-                       (long) CIA);
-      StoreFPR (FS, fmt_uninterpreted_32, 0xDEADC0DE);
-    }
-  TRACE_FP_RESULT (GPR[RT]);
+  do_mthc1 (SD_, RT, FS);
 }
 
 
 *mips32r2:
 *mips64r2:
 {
-  TRACE_ALU_INPUT4 (GPR[RT], GPR[RS], LSB, MSB);
-  if (LSB <= MSB)
-    GPR[RT] = EXTEND32 (GPR[RT] ^
-                       ((GPR[RT] ^ (GPR[RS] << LSB)) & MASK32 (MSB, LSB)));
-  TRACE_ALU_RESULT1 (GPR[RT]);
+  do_ins (SD_, RT, RS, LSB, MSB);
 }
 
 
 *mips32r2:
 *mips64r2:
 {
-  TRACE_ALU_INPUT1 (GPR[RT]);
-  GPR[RD] = EXTEND8 (GPR[RT]);
-  TRACE_ALU_RESULT1 (GPR[RD]);
+  do_seb (SD_, RD, RT);
 }
 
 011111,00000,5.RT,5.RD,11000,100000::32::SEH
 *mips32r2:
 *mips64r2:
 {
-  TRACE_ALU_INPUT1 (GPR[RT]);
-  GPR[RD] = EXTEND16 (GPR[RT]);
-  TRACE_ALU_RESULT1 (GPR[RD]);
+  do_seh (SD_, RD, RT);
 }
 
 
 *mips32r2:
 *mips64r2:
 {
-  // Return 0 for all hardware registers currently
-  GPR[RT] = EXTEND32 (0);
-  TRACE_ALU_RESULT1 (GPR[RT]);
+  do_rdhwr (SD_, RT, RD);
 }
 
 
 *mips32r2:
 *mips64r2:
 {
-  union { unsigned32 w; unsigned16 h[2]; } u;
-  TRACE_ALU_INPUT1 (GPR[RT]);
-  u.w = GPR[RT];
-  u.h[0] = SWAP_2 (u.h[0]);
-  u.h[1] = SWAP_2 (u.h[1]);
-  GPR[RD] = EXTEND32 (u.w);
-  TRACE_ALU_RESULT1 (GPR[RD]);
+  do_wsbh (SD_, RD, RT);
 }
 
 
index 8d698adad3d375a9bc0257e0628afa49a1a55ac5..42d8db37c4bfa19d76ed60664a110ebe5646ebe7 100644 (file)
@@ -2,7 +2,7 @@
    Copyright (C) 1997-2015 Free Software Foundation, Inc.
    Contributed by Cygnus Support.
 
-This file is part of GDB, the GNU debugger.
+This file is part of the MIPS sim.
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -49,6 +49,20 @@ typedef unsigned64 uword64;
 #define NOTHALFWORDVALUE(v) ((((((uword64)(v)>>16) == 0) && !((v) & ((unsigned)1 << 15))) || (((((uword64)(v)>>32) == 0xFFFFFFFF) && ((((uword64)(v)>>16) & 0xFFFF) == 0xFFFF)) && ((v) & ((unsigned)1 << 15)))) ? (1 == 0) : (1 == 1))
 
 
+typedef enum {
+  cp0_dmfc0,
+  cp0_dmtc0,
+  cp0_mfc0,
+  cp0_mtc0,
+  cp0_tlbr,
+  cp0_tlbwi,
+  cp0_tlbwr,
+  cp0_tlbp,
+  cp0_cache,
+  cp0_eret,
+  cp0_deret,
+  cp0_rfe
+} CP0_operation;
 
 /* Floating-point operations: */
 
@@ -479,6 +493,9 @@ struct sim_state {
 
   sim_cpu *cpu[MAX_NR_PROCESSORS];
 
+  /* microMIPS ISA mode.  */
+  int isa_mode;
+
   sim_state_base base;
 };
 
@@ -690,9 +707,12 @@ cop_sw (SD, CPU, cia, coproc_num, coproc_reg)
 cop_sd (SD, CPU, cia, coproc_num, coproc_reg)
 
 
-void decode_coproc (SIM_DESC sd, sim_cpu *cpu, address_word cia, unsigned int instruction);
-#define DecodeCoproc(instruction) \
-decode_coproc (SD, CPU, cia, (instruction))
+void decode_coproc (SIM_DESC sd, sim_cpu *cpu, address_word cia,
+                   unsigned int instruction, int coprocnum, CP0_operation op,
+                   int rt, int rd, int sel);
+#define DecodeCoproc(instruction,coprocnum,op,rt,rd,sel) \
+  decode_coproc (SD, CPU, cia, (instruction), (coprocnum), (op), \
+                (rt), (rd), (sel))
 
 int sim_monitor (SIM_DESC sd, sim_cpu *cpu, address_word cia, unsigned int arg);
   
@@ -956,6 +976,25 @@ INLINE_SIM_MAIN (unsigned32) ifetch32 (SIM_DESC sd, sim_cpu *cpu, address_word c
 INLINE_SIM_MAIN (unsigned16) ifetch16 (SIM_DESC sd, sim_cpu *cpu, address_word cia, address_word vaddr);
 #define IMEM16(CIA) ifetch16 (SD, CPU, (CIA), ((CIA) & ~1))
 #define IMEM16_IMMED(CIA,NR) ifetch16 (SD, CPU, (CIA), ((CIA) & ~1) + 2 * (NR))
+#define IMEM32_MICROMIPS(CIA) \
+  (ifetch16 (SD, CPU, (CIA), (CIA)) << 16 | ifetch16 (SD, CPU, (CIA + 2), \
+                                                     (CIA + 2)))
+#define IMEM16_MICROMIPS(CIA) ifetch16 (SD, CPU, (CIA), ((CIA)))
+
+#define MICROMIPS_MINOR_OPCODE(INSN) ((INSN & 0x1C00) >> 10)
+
+#define MICROMIPS_DELAYSLOT_SIZE_ANY 0
+#define MICROMIPS_DELAYSLOT_SIZE_16 2
+#define MICROMIPS_DELAYSLOT_SIZE_32 4
+
+extern int isa_mode;
+
+#define ISA_MODE_MIPS32 0
+#define ISA_MODE_MICROMIPS 1
+
+address_word micromips_instruction_decode (SIM_DESC sd, sim_cpu * cpu,
+                                          address_word cia,
+                                          int instruction_size);
 
 #if WITH_TRACE_ANY_P
 void dotrace (SIM_DESC sd, sim_cpu *cpu, FILE *tracefh, int type, SIM_ADDR address, int width, char *comment, ...);
index e5913c1aaab5a1e4c59d0894d45e9f4266e643b7..ada4e4c2c3d5d4fecf15e6979cde35f5c37bd3aa 100644 (file)
@@ -1,3 +1,14 @@
+2015-09-25  Andrew Bennett  <andrew.bennett@imgtec.com>
+           Ali Lown  <ali.lown@imgtec.com>
+
+       * basic.exp (run_micromips_test, run_sim_tests): New functions
+       Add support for micromips tests.
+       * hilo-hazard-4.s: New file.
+       * testutils.inc (_dowrite): Changed reserved instruction encoding.
+       (writemsg): Moved the la and li instructions before the data they are
+       assigned to, which prevents a bug where MIPS32 relocations are used
+       instead of micromips relocations when building for micromips.
+
 2015-04-13  Hans-Peter Nilsson  <hp@axis.com>
 
        * basic.exp: Don't unset target ldscript here.
index ddef53544a2b0f68dcaaa7026c490983a1d3e72b..f810741dbb74459c74576f929022ac4b8cccaa58 100644 (file)
@@ -25,12 +25,28 @@ proc run_hilo_test {testfile models nops} {
     }
 }
 
+# Runs micromips tests by adding -mmicromips to as options
+proc run_micromips_test { name requested_machs } {
+    global global_as_options;
+    set gas_old $global_as_options;
+    append global_as_options " -mmicromips "
+    run_sim_test $name $requested_machs
+    set global_as_options $gas_old
+}
+
+# Runs all specified tests
+proc run_sim_tests { name requested_machs { requested_micromips_machs "" } } {
+    run_sim_test $name $requested_machs
+    run_micromips_test $name $requested_micromips_machs
+}
 
 # Only test mips*-*-elf (e.g., no mips*-*-linux)
 if {[istarget mips*-*-elf]} {
 
     set dspmodels ""
     set mdmxmodels ""
+    set micromipsmodels ""
+    set micromipsdspmodels ""
 
     if {[istarget mipsisa64sb1*-*-elf]} {
        set models "sb1"
@@ -46,11 +62,15 @@ if {[istarget mips*-*-elf]} {
        set submodels ""
        append dspmodels " mips32r2 mips64r2"
        append mdmxmodels " mips64 mips32r2 mips64r2"
+       append micromipsmodels " mips32r2"
+       append micromipsdspmodels " mips32r2 mips64r2"
     } elseif {[istarget mipsisa32*-*-elf]} {
        set models "mips32 mips32r2"
        set submodels "mips1 mips2"
        append dspmodels " mips32r2"
        append mdmxmodels " mips32r2"
+       append micromipsmodels " mips32r2"
+       append micromipsdspmodels " mips32r2"
     } elseif {[istarget mips64vr*-*-elf]} {
        set models "vr4100 vr4111 vr4120 vr5000 vr5400 vr5500"
        set submodels "mips1 mips2 mips3 mips4"
@@ -65,12 +85,14 @@ if {[istarget mips*-*-elf]} {
     append submodels " " $models
     set cpu_option -march
 
-    run_sim_test sanity.s $submodels
+    run_sim_tests sanity.s $submodels $micromipsmodels
+
     foreach nops {0 1} {
        run_hilo_test hilo-hazard-1.s $models $nops
        run_hilo_test hilo-hazard-2.s $models $nops
     }
     run_hilo_test hilo-hazard-3.s $models 2
+    run_hilo_test hilo-hazard-4.s $micromipsmodels 2
 
     run_sim_test fpu64-ps.s $submodels
     run_sim_test fpu64-ps-sb1.s $submodels
@@ -78,6 +100,7 @@ if {[istarget mips*-*-elf]} {
     run_sim_test mdmx-ob.s $mdmxmodels
     run_sim_test mdmx-ob-sb1.s $mdmxmodels
 
-    run_sim_test mips32-dsp.s $dspmodels
-    run_sim_test mips32-dsp2.s $dspmodels
+    run_sim_tests mips32-dsp.s $dspmodels $micromipsdspmodels
+    run_sim_tests mips32-dsp2.s $dspmodels $micromipsdspmodels
+
 }
diff --git a/sim/testsuite/sim/mips/hilo-hazard-4.s b/sim/testsuite/sim/mips/hilo-hazard-4.s
new file mode 100644 (file)
index 0000000..e83fbfa
--- /dev/null
@@ -0,0 +1,37 @@
+# Test for mf{hi,lo} -> mult/div/mt{hi,lo} with 2 nops inbetween.
+#
+# mach:                all
+# as:          -mabi=eabi -mmicromips
+# ld:          -N -Ttext=0x80010000
+# output:      pass\\n
+
+# Copyright (C) 2013-2015 Imagination Technologies, Ltd.
+# All rights reserved.
+# Contributed by Andrew Bennett (andrew.bennett@imgtec.com)
+#
+# This file is part of the MIPS sim.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, see <http://www.gnu.org/licenses/>.
+
+       .include "hilo-hazard.inc"
+       .include "testutils.inc"
+
+       setup
+
+       .set noreorder
+       .ent DIAG
+DIAG:
+       hilo
+       pass
+       .end DIAG
index 6ea59f01c0a342f834ce984d88d123f7b387633b..0029fc098a3953892e0333f6b4d25e3ba9441752 100644 (file)
 # $1, $4, $5, %6, are used as temps by the macros defined here.
 
        .macro writemsg msg
+       la      $5, 901f
+       li      $6, 902f - 901f
        .data
 901:   .ascii  "\msg\n"
 902:
        .previous
-       la      $5, 901b
-       li      $6, 902b - 901b
        .set push
        .set noreorder
        jal     _dowrite
@@ -81,7 +81,7 @@ _pass:
 _dowrite:
        # Write opcode (reserved instruction).  See sim_monitor and its
        # callers in sim/mips/interp.c.
-       .word   0x00000005 | ((8 << 1) << 6)
+       .word   0x00000039 | ((8 << 1) << 6)
        .end _dowrite
 
        .endm   # setup