sh4 target (Samuel Tardieu)
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Thu, 27 Apr 2006 21:07:38 +0000 (21:07 +0000)
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Thu, 27 Apr 2006 21:07:38 +0000 (21:07 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1861 c046a42c-6fe2-441c-8c8c-71466251a162

24 files changed:
Makefile.target
configure
cpu-all.h
cpu-exec.c
dis-asm.h
disas.c
exec-all.h
gdbstub.c
linux-user/elfload.c
linux-user/main.c
linux-user/sh4/syscall.h [new file with mode: 0644]
linux-user/sh4/syscall_nr.h [new file with mode: 0644]
linux-user/sh4/termbits.h [new file with mode: 0644]
linux-user/syscall.c
linux-user/syscall_defs.h
sh4-dis.c [new file with mode: 0644]
softmmu_header.h
target-sh4/cpu.h [new file with mode: 0644]
target-sh4/exec.h [new file with mode: 0644]
target-sh4/helper.c [new file with mode: 0644]
target-sh4/op.c [new file with mode: 0644]
target-sh4/op_helper.c [new file with mode: 0644]
target-sh4/op_mem.c [new file with mode: 0644]
target-sh4/translate.c [new file with mode: 0644]

index 0315153..6c2bd35 100644 (file)
@@ -225,6 +225,10 @@ ifeq ($(TARGET_BASE_ARCH), arm)
 LIBOBJS+= op_helper.o helper.o
 endif
 
+ifeq ($(TARGET_BASE_ARCH), sh4)
+LIBOBJS+= op_helper.o helper.o
+endif
+
 # NOTE: the disassembler code is only needed for debugging
 LIBOBJS+=disas.o 
 ifeq ($(findstring i386, $(TARGET_ARCH) $(ARCH)),i386)
@@ -254,6 +258,9 @@ endif
 ifeq ($(findstring m68k, $(TARGET_ARCH) $(ARCH)),m68k)
 LIBOBJS+=m68k-dis.o
 endif
+ifeq ($(findstring sh4, $(TARGET_ARCH) $(ARCH)),sh4)
+LIBOBJS+=sh4-dis.o
+endif
 
 ifdef CONFIG_GDBSTUB
 OBJS+=gdbstub.o
@@ -341,6 +348,9 @@ ifeq ($(TARGET_BASE_ARCH), arm)
 VL_OBJS+= integratorcp.o versatilepb.o ps2.o smc91c111.o arm_pic.o arm_timer.o
 VL_OBJS+= pl011.o pl050.o pl080.o pl110.o pl190.o
 endif
+ifeq ($(TARGET_BASE_ARCH), sh4)
+VL_OBJS+= shix.o sh7750.o sh7750_regnames.o tc58128.o
+endif
 ifdef CONFIG_GDBSTUB
 VL_OBJS+=gdbstub.o 
 endif
@@ -462,6 +472,16 @@ endif
 
 loader.o: loader.c elf_ops.h
 
+ifeq ($(TARGET_ARCH), sh4)
+op.o: op.c op_mem.c cpu.h
+op_helper.o: op_helper.c exec.h cpu.h
+helper.o: helper.c exec.h cpu.h
+sh7750.o: sh7750.c sh7750.h sh7750_regs.h sh7750_regnames.h cpu.h
+shix.o: shix.c sh7750.h sh7750_regs.h sh7750_regnames.h tc58128.h
+sh7750_regnames.o: sh7750_regnames.c sh7750_regnames.h sh7750_regs.h
+tc58128.o: tc58128.c tc58128.h sh7750.h
+endif
+
 %.o: %.c
        $(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
 
index 07c3738..92632e2 100755 (executable)
--- a/configure
+++ b/configure
@@ -359,7 +359,7 @@ if test -z "$target_list" ; then
     fi
 # the following are Linux specific
     if [ "$user" = "yes" ] ; then
-        target_list="i386-user arm-user armeb-user sparc-user ppc-user mips-user mipsel-user $target_list"
+        target_list="i386-user arm-user armeb-user sparc-user ppc-user mips-user mipsel-user sh4-user $target_list"
     fi
 else
     target_list=`echo "$target_list" | sed -e 's/,/ /g'`
@@ -807,6 +807,10 @@ elif test "$target_cpu" = "mips" -o "$target_cpu" = "mipsel" ; then
   echo "TARGET_ARCH=mips" >> $config_mak
   echo "#define TARGET_ARCH \"mips\"" >> $config_h
   echo "#define TARGET_MIPS 1" >> $config_h
+elif test "$target_cpu" = "sh4" ; then
+  echo "TARGET_ARCH=sh4" >> $config_mak
+  echo "#define TARGET_ARCH \"sh4\"" >> $config_h
+  echo "#define TARGET_SH4 1" >> $config_h
 else
   echo "Unsupported target CPU"
   exit 1
index 9abdf2a..ac65043 100644 (file)
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -732,6 +732,13 @@ void page_unprotect_range(target_ulong data, target_ulong data_size);
 #define cpu_gen_code cpu_mips_gen_code
 #define cpu_signal_handler cpu_mips_signal_handler
 
+#elif defined(TARGET_SH4)
+#define CPUState CPUSH4State
+#define cpu_init cpu_sh4_init
+#define cpu_exec cpu_sh4_exec
+#define cpu_gen_code cpu_sh4_gen_code
+#define cpu_signal_handler cpu_sh4_signal_handler
+
 #else
 
 #error unsupported target CPU
index ca46953..8a585c1 100644 (file)
@@ -190,6 +190,10 @@ static inline TranslationBlock *tb_find_fast(void)
     flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK);
     cs_base = 0;
     pc = env->PC;
+#elif defined(TARGET_SH4)
+    flags = env->sr & (SR_MD | SR_RB);
+    cs_base = 0;         /* XXXXX */
+    pc = env->pc;
 #else
 #error unsupported CPU
 #endif
@@ -363,6 +367,8 @@ int cpu_exec(CPUState *env1)
 #endif
 #elif defined(TARGET_PPC)
 #elif defined(TARGET_MIPS)
+#elif defined(TARGET_SH4)
+    /* XXXXX */
 #else
 #error unsupported target CPU
 #endif
@@ -407,6 +413,8 @@ int cpu_exec(CPUState *env1)
                     do_interrupt(env->exception_index);
 #elif defined(TARGET_ARM)
                     do_interrupt(env);
+#elif defined(TARGET_SH4)
+                   do_interrupt(env);
 #endif
                 }
                 env->exception_index = -1;
@@ -550,6 +558,8 @@ int cpu_exec(CPUState *env1)
                         env->exception_index = EXCP_IRQ;
                         do_interrupt(env);
                     }
+#elif defined(TARGET_SH4)
+                   /* XXXXX */
 #endif
                     if (env->interrupt_request & CPU_INTERRUPT_EXITTB) {
                         env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
@@ -608,6 +618,8 @@ int cpu_exec(CPUState *env1)
                     cpu_dump_state(env, logfile, fprintf, 0);
 #elif defined(TARGET_MIPS)
                     cpu_dump_state(env, logfile, fprintf, 0);
+#elif defined(TARGET_SH4)
+                   cpu_dump_state(env, logfile, fprintf, 0);
 #else
 #error unsupported target CPU 
 #endif
@@ -817,6 +829,8 @@ int cpu_exec(CPUState *env1)
 #endif
 #elif defined(TARGET_PPC)
 #elif defined(TARGET_MIPS)
+#elif defined(TARGET_SH4)
+    /* XXXXX */
 #else
 #error unsupported target CPU
 #endif
@@ -1121,6 +1135,55 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
     return 1;
 }
 
+#elif defined (TARGET_SH4)
+static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
+                                    int is_write, sigset_t *old_set,
+                                    void *puc)
+{
+    TranslationBlock *tb;
+    int ret;
+    
+    if (cpu_single_env)
+        env = cpu_single_env; /* XXX: find a correct solution for multithread */
+#if defined(DEBUG_SIGNAL)
+    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", 
+           pc, address, is_write, *(unsigned long *)old_set);
+#endif
+    /* XXX: locking issue */
+    if (is_write && page_unprotect(h2g(address), pc, puc)) {
+        return 1;
+    }
+
+    /* see if it is an MMU fault */
+    ret = cpu_sh4_handle_mmu_fault(env, address, is_write, 1, 0);
+    if (ret < 0)
+        return 0; /* not an MMU fault */
+    if (ret == 0)
+        return 1; /* the MMU fault was handled without causing real CPU fault */
+
+    /* now we have a real cpu fault */
+    tb = tb_find_pc(pc);
+    if (tb) {
+        /* the PC is inside the translated code. It means that we have
+           a virtual CPU fault */
+        cpu_restore_state(tb, env, pc, puc);
+    }
+    if (ret == 1) {
+#if 0
+        printf("PF exception: NIP=0x%08x error=0x%x %p\n", 
+               env->nip, env->error_code, tb);
+#endif
+    /* we restore the process signal mask as the sigreturn should
+       do it (XXX: use sigsetjmp) */
+        sigprocmask(SIG_SETMASK, old_set, NULL);
+        //        do_raise_exception_err(env->exception_index, env->error_code);
+    } else {
+        /* activate soft MMU for this block */
+        cpu_resume_from_signal(env, puc);
+    }
+    /* never comes here */
+    return 1;
+}
 #else
 #error unsupported target CPU
 #endif
index 9d28785..73b4380 100644 (file)
--- a/dis-asm.h
+++ b/dis-asm.h
@@ -163,10 +163,23 @@ enum bfd_architecture
 #define bfd_mach_z8002         2
   bfd_arch_h8500,      /* Hitachi H8/500 */
   bfd_arch_sh,         /* Hitachi SH */
-#define bfd_mach_sh            0
+#define bfd_mach_sh            1
+#define bfd_mach_sh2        0x20
+#define bfd_mach_sh_dsp     0x2d
+#define bfd_mach_sh2a       0x2a
+#define bfd_mach_sh2a_nofpu 0x2b
+#define bfd_mach_sh2e       0x2e
 #define bfd_mach_sh3        0x30
+#define bfd_mach_sh3_nommu  0x31
+#define bfd_mach_sh3_dsp    0x3d
 #define bfd_mach_sh3e       0x3e
 #define bfd_mach_sh4        0x40
+#define bfd_mach_sh4_nofpu  0x41
+#define bfd_mach_sh4_nommu_nofpu  0x42
+#define bfd_mach_sh4a       0x4a
+#define bfd_mach_sh4a_nofpu 0x4b
+#define bfd_mach_sh4al_dsp  0x4d
+#define bfd_mach_sh5        0x50
   bfd_arch_alpha,      /* Dec Alpha */
   bfd_arch_arm,        /* Advanced Risc Machines ARM */
 #define bfd_mach_arm_2         1
diff --git a/disas.c b/disas.c
index f8281b5..c38da08 100644 (file)
--- a/disas.c
+++ b/disas.c
@@ -73,7 +73,7 @@ generic_print_address (addr, info)
      bfd_vma addr;
      struct disassemble_info *info;
 {
-  (*info->fprintf_func) (info->stream, "0x%llx", addr);
+    (*info->fprintf_func) (info->stream, "0x%llx", addr);
 }
 
 /* Just return the given address.  */
@@ -194,6 +194,9 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
 #endif
 #elif defined(TARGET_M68K)
     print_insn = print_insn_m68k;
+#elif defined(TARGET_SH4)
+    disasm_info.mach = bfd_mach_sh4;
+    print_insn = print_insn_sh;
 #else
     fprintf(out, "0x" TARGET_FMT_lx
            ": Asm output not supported on this arch\n", code);
index e4fc1d6..bc91f71 100644 (file)
@@ -560,6 +560,8 @@ static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr)
     is_user = (env->psrs == 0);
 #elif defined (TARGET_ARM)
     is_user = ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR);
+#elif defined (TARGET_SH4)
+    is_user = ((env->sr & SR_MD) == 0);
 #else
 #error unimplemented CPU
 #endif
index 8157160..bca9b1e 100644 (file)
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -487,6 +487,45 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
     env->PC = tswapl(*(uint32_t *)ptr);
     ptr += 4;
 }
+#elif defined (TARGET_SH4)
+static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
+{
+  uint32_t *ptr = (uint32_t *)mem_buf;
+  int i;
+
+#define SAVE(x) *ptr++=tswapl(x)
+  for (i = 0; i < 16; i++) SAVE(env->gregs[i]);
+  SAVE (env->pc);
+  SAVE (env->pr);
+  SAVE (env->gbr);
+  SAVE (env->vbr);
+  SAVE (env->mach);
+  SAVE (env->macl);
+  SAVE (env->sr);
+  SAVE (0); /* TICKS */
+  SAVE (0); /* STALLS */
+  SAVE (0); /* CYCLES */
+  SAVE (0); /* INSTS */
+  SAVE (0); /* PLR */
+
+  return ((uint8_t *)ptr - mem_buf);
+}
+
+static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
+{
+  uint32_t *ptr = (uint32_t *)mem_buf;
+  int i;
+
+#define LOAD(x) (x)=*ptr++;
+  for (i = 0; i < 16; i++) LOAD(env->gregs[i]);
+  LOAD (env->pc);
+  LOAD (env->pr);
+  LOAD (env->gbr);
+  LOAD (env->vbr);
+  LOAD (env->mach);
+  LOAD (env->macl);
+  LOAD (env->sr);
+}
 #else
 static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
 {
@@ -531,6 +570,8 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
             env->npc = addr + 4;
 #elif defined (TARGET_ARM)
             env->regs[15] = addr;
+#elif defined (TARGET_SH4)
+           env->pc = addr;
 #endif
         }
 #ifdef CONFIG_USER_ONLY
@@ -551,6 +592,8 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
             env->npc = addr + 4;
 #elif defined (TARGET_ARM)
             env->regs[15] = addr;
+#elif defined (TARGET_SH4)
+           env->pc = addr;
 #endif
         }
         cpu_single_step(env, 1);
index 14c0085..98c6e3f 100644 (file)
@@ -274,6 +274,30 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
 
 #endif /* TARGET_MIPS */
 
+#ifdef TARGET_SH4
+
+#define ELF_START_MMAP 0x80000000
+
+#define elf_check_arch(x) ( (x) == EM_SH )
+
+#define ELF_CLASS ELFCLASS32
+#define ELF_DATA  ELFDATA2LSB
+#define ELF_ARCH  EM_SH
+
+#define ELF_PLAT_INIT(_r) /* XXXXX */
+
+static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
+{
+  /* Check other registers XXXXX */
+  regs->pc = infop->entry;
+  regs->regs[15] = infop->start_stack - 16 * 4;
+}
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE        4096
+
+#endif
+
 #ifndef ELF_PLATFORM
 #define ELF_PLATFORM (NULL)
 #endif
index 1f47205..78f45a5 100644 (file)
@@ -1387,6 +1387,38 @@ void cpu_loop(CPUMIPSState *env)
 }
 #endif
 
+#ifdef TARGET_SH4
+void cpu_loop (CPUState *env)
+{
+    int trapnr, ret;
+    //    target_siginfo_t info;
+    
+    while (1) {
+        trapnr = cpu_sh4_exec (env);
+        
+        switch (trapnr) {
+        case 0x160:
+            ret = do_syscall(env, 
+                             env->gregs[0x13], 
+                             env->gregs[0x14], 
+                             env->gregs[0x15], 
+                             env->gregs[0x16], 
+                             env->gregs[0x17], 
+                             env->gregs[0x10], 
+                             0);
+            env->gregs[0x10] = ret;
+            env->pc += 2;
+            break;
+        default:
+            printf ("Unhandled trap: 0x%x\n", trapnr);
+            cpu_dump_state(env, stderr, fprintf, 0);
+            exit (1);
+        }
+        process_pending_signals (env);
+    }
+}
+#endif
+
 void usage(void)
 {
     printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 2003-2005 Fabrice Bellard\n"
@@ -1665,6 +1697,15 @@ int main(int argc, char **argv)
         }
         env->PC = regs->cp0_epc;
     }
+#elif defined(TARGET_SH4)
+    {
+        int i;
+
+        for(i = 0; i < 16; i++) {
+            env->gregs[i] = regs->regs[i];
+        }
+        env->pc = regs->pc;
+    }
 #else
 #error unsupported target CPU
 #endif
diff --git a/linux-user/sh4/syscall.h b/linux-user/sh4/syscall.h
new file mode 100644 (file)
index 0000000..014bf58
--- /dev/null
@@ -0,0 +1,12 @@
+struct target_pt_regs {
+        unsigned long regs[16];
+        unsigned long pc;
+        unsigned long pr;
+        unsigned long sr;
+        unsigned long gbr;
+        unsigned long mach;
+        unsigned long macl;
+        long tra;
+};
+
+#define UNAME_MACHINE "sh4"
diff --git a/linux-user/sh4/syscall_nr.h b/linux-user/sh4/syscall_nr.h
new file mode 100644 (file)
index 0000000..c91ba1b
--- /dev/null
@@ -0,0 +1,292 @@
+/*
+ * This file contains the system call numbers.
+ */
+
+#define TARGET_NR_restart_syscall        0
+#define TARGET_NR_exit           1
+#define TARGET_NR_fork           2
+#define TARGET_NR_read           3
+#define TARGET_NR_write                  4
+#define TARGET_NR_open           5
+#define TARGET_NR_close                  6
+#define TARGET_NR_waitpid                7
+#define TARGET_NR_creat                  8
+#define TARGET_NR_link           9
+#define TARGET_NR_unlink                10
+#define TARGET_NR_execve                11
+#define TARGET_NR_chdir                 12
+#define TARGET_NR_time          13
+#define TARGET_NR_mknod                 14
+#define TARGET_NR_chmod                 15
+#define TARGET_NR_lchown                16
+#define TARGET_NR_break                 17
+#define TARGET_NR_oldstat               18
+#define TARGET_NR_lseek                 19
+#define TARGET_NR_getpid                20
+#define TARGET_NR_mount                 21
+#define TARGET_NR_umount                22
+#define TARGET_NR_setuid                23
+#define TARGET_NR_getuid                24
+#define TARGET_NR_stime                 25
+#define TARGET_NR_ptrace                26
+#define TARGET_NR_alarm                 27
+#define TARGET_NR_oldfstat              28
+#define TARGET_NR_pause                 29
+#define TARGET_NR_utime                 30
+#define TARGET_NR_stty          31
+#define TARGET_NR_gtty          32
+#define TARGET_NR_access                33
+#define TARGET_NR_nice          34
+#define TARGET_NR_ftime                 35
+#define TARGET_NR_sync          36
+#define TARGET_NR_kill          37
+#define TARGET_NR_rename                38
+#define TARGET_NR_mkdir                 39
+#define TARGET_NR_rmdir                 40
+#define TARGET_NR_dup           41
+#define TARGET_NR_pipe          42
+#define TARGET_NR_times                 43
+#define TARGET_NR_prof          44
+#define TARGET_NR_brk           45
+#define TARGET_NR_setgid                46
+#define TARGET_NR_getgid                47
+#define TARGET_NR_signal                48
+#define TARGET_NR_geteuid               49
+#define TARGET_NR_getegid               50
+#define TARGET_NR_acct          51
+#define TARGET_NR_umount2               52
+#define TARGET_NR_lock          53
+#define TARGET_NR_ioctl                 54
+#define TARGET_NR_fcntl                 55
+#define TARGET_NR_mpx           56
+#define TARGET_NR_setpgid               57
+#define TARGET_NR_ulimit                58
+#define TARGET_NR_oldolduname   59
+#define TARGET_NR_umask                 60
+#define TARGET_NR_chroot                61
+#define TARGET_NR_ustat                 62
+#define TARGET_NR_dup2          63
+#define TARGET_NR_getppid               64
+#define TARGET_NR_getpgrp               65
+#define TARGET_NR_setsid                66
+#define TARGET_NR_sigaction             67
+#define TARGET_NR_sgetmask              68
+#define TARGET_NR_ssetmask              69
+#define TARGET_NR_setreuid              70
+#define TARGET_NR_setregid              71
+#define TARGET_NR_sigsuspend            72
+#define TARGET_NR_sigpending            73
+#define TARGET_NR_sethostname   74
+#define TARGET_NR_setrlimit             75
+#define TARGET_NR_getrlimit             76     /* Back compatible 2Gig limited rlimit */
+#define TARGET_NR_getrusage             77
+#define TARGET_NR_gettimeofday  78
+#define TARGET_NR_settimeofday  79
+#define TARGET_NR_getgroups             80
+#define TARGET_NR_setgroups             81
+#define TARGET_NR_select                82
+#define TARGET_NR_symlink               83
+#define TARGET_NR_oldlstat              84
+#define TARGET_NR_readlink              85
+#define TARGET_NR_uselib                86
+#define TARGET_NR_swapon                87
+#define TARGET_NR_reboot                88
+#define TARGET_NR_readdir               89
+#define TARGET_NR_mmap          90
+#define TARGET_NR_munmap                91
+#define TARGET_NR_truncate              92
+#define TARGET_NR_ftruncate             93
+#define TARGET_NR_fchmod                94
+#define TARGET_NR_fchown                95
+#define TARGET_NR_getpriority   96
+#define TARGET_NR_setpriority   97
+#define TARGET_NR_profil                98
+#define TARGET_NR_statfs                99
+#define TARGET_NR_fstatfs              100
+#define TARGET_NR_ioperm               101
+#define TARGET_NR_socketcall           102
+#define TARGET_NR_syslog               103
+#define TARGET_NR_setitimer            104
+#define TARGET_NR_getitimer            105
+#define TARGET_NR_stat         106
+#define TARGET_NR_lstat                107
+#define TARGET_NR_fstat                108
+#define TARGET_NR_olduname             109
+#define TARGET_NR_iopl         110
+#define TARGET_NR_vhangup              111
+#define TARGET_NR_idle         112
+#define TARGET_NR_vm86old              113
+#define TARGET_NR_wait4                114
+#define TARGET_NR_swapoff              115
+#define TARGET_NR_sysinfo              116
+#define TARGET_NR_ipc          117
+#define TARGET_NR_fsync                118
+#define TARGET_NR_sigreturn            119
+#define TARGET_NR_clone                120
+#define TARGET_NR_setdomainname        121
+#define TARGET_NR_uname                122
+#define TARGET_NR_modify_ldt           123
+#define TARGET_NR_adjtimex             124
+#define TARGET_NR_mprotect             125
+#define TARGET_NR_sigprocmask  126
+#define TARGET_NR_create_module        127
+#define TARGET_NR_init_module  128
+#define TARGET_NR_delete_module        129
+#define TARGET_NR_get_kernel_syms      130
+#define TARGET_NR_quotactl             131
+#define TARGET_NR_getpgid              132
+#define TARGET_NR_fchdir               133
+#define TARGET_NR_bdflush              134
+#define TARGET_NR_sysfs                135
+#define TARGET_NR_personality  136
+#define TARGET_NR_afs_syscall  137 /* Syscall for Andrew File System */
+#define TARGET_NR_setfsuid             138
+#define TARGET_NR_setfsgid             139
+#define TARGET_NR__llseek              140
+#define TARGET_NR_getdents             141
+#define TARGET_NR__newselect           142
+#define TARGET_NR_flock                143
+#define TARGET_NR_msync                144
+#define TARGET_NR_readv                145
+#define TARGET_NR_writev               146
+#define TARGET_NR_getsid               147
+#define TARGET_NR_fdatasync            148
+#define TARGET_NR__sysctl              149
+#define TARGET_NR_mlock                150
+#define TARGET_NR_munlock              151
+#define TARGET_NR_mlockall             152
+#define TARGET_NR_munlockall           153
+#define TARGET_NR_sched_setparam               154
+#define TARGET_NR_sched_getparam               155
+#define TARGET_NR_sched_setscheduler           156
+#define TARGET_NR_sched_getscheduler           157
+#define TARGET_NR_sched_yield          158
+#define TARGET_NR_sched_get_priority_max       159
+#define TARGET_NR_sched_get_priority_min       160
+#define TARGET_NR_sched_rr_get_interval        161
+#define TARGET_NR_nanosleep            162
+#define TARGET_NR_mremap               163
+#define TARGET_NR_setresuid            164
+#define TARGET_NR_getresuid            165
+#define TARGET_NR_vm86         166
+#define TARGET_NR_query_module 167
+#define TARGET_NR_poll         168
+#define TARGET_NR_nfsservctl           169
+#define TARGET_NR_setresgid            170
+#define TARGET_NR_getresgid            171
+#define TARGET_NR_prctl              172
+#define TARGET_NR_rt_sigreturn 173
+#define TARGET_NR_rt_sigaction 174
+#define TARGET_NR_rt_sigprocmask       175
+#define TARGET_NR_rt_sigpending        176
+#define TARGET_NR_rt_sigtimedwait      177
+#define TARGET_NR_rt_sigqueueinfo      178
+#define TARGET_NR_rt_sigsuspend        179
+#define TARGET_NR_pread64              180
+#define TARGET_NR_pwrite64             181
+#define TARGET_NR_chown                182
+#define TARGET_NR_getcwd               183
+#define TARGET_NR_capget               184
+#define TARGET_NR_capset               185
+#define TARGET_NR_sigaltstack  186
+#define TARGET_NR_sendfile             187
+#define TARGET_NR_streams1             188     /* some people actually want it */
+#define TARGET_NR_streams2             189     /* some people actually want it */
+#define TARGET_NR_vfork                190
+#define TARGET_NR_ugetrlimit           191     /* SuS compliant getrlimit */
+#define TARGET_NR_mmap2                192
+#define TARGET_NR_truncate64           193
+#define TARGET_NR_ftruncate64  194
+#define TARGET_NR_stat64               195
+#define TARGET_NR_lstat64              196
+#define TARGET_NR_fstat64              197
+#define TARGET_NR_lchown32             198
+#define TARGET_NR_getuid32             199
+#define TARGET_NR_getgid32             200
+#define TARGET_NR_geteuid32            201
+#define TARGET_NR_getegid32            202
+#define TARGET_NR_setreuid32           203
+#define TARGET_NR_setregid32           204
+#define TARGET_NR_getgroups32  205
+#define TARGET_NR_setgroups32  206
+#define TARGET_NR_fchown32             207
+#define TARGET_NR_setresuid32  208
+#define TARGET_NR_getresuid32  209
+#define TARGET_NR_setresgid32  210
+#define TARGET_NR_getresgid32  211
+#define TARGET_NR_chown32              212
+#define TARGET_NR_setuid32             213
+#define TARGET_NR_setgid32             214
+#define TARGET_NR_setfsuid32           215
+#define TARGET_NR_setfsgid32           216
+#define TARGET_NR_pivot_root           217
+#define TARGET_NR_mincore              218
+#define TARGET_NR_madvise              219
+#define TARGET_NR_getdents64           220
+#define TARGET_NR_fcntl64              221
+/* 223 is unused */
+#define TARGET_NR_gettid               224
+#define TARGET_NR_setxattr             226
+#define TARGET_NR_lsetxattr            227
+#define TARGET_NR_fsetxattr            228
+#define TARGET_NR_getxattr             229
+#define TARGET_NR_lgetxattr            230
+#define TARGET_NR_fgetxattr            231
+#define TARGET_NR_listxattr            232
+#define TARGET_NR_llistxattr           233
+#define TARGET_NR_flistxattr           234
+#define TARGET_NR_removexattr  235
+#define TARGET_NR_lremovexattr 236
+#define TARGET_NR_fremovexattr 237
+#define TARGET_NR_tkill                238
+#define TARGET_NR_sendfile64           239
+#define TARGET_NR_futex                240
+#define TARGET_NR_sched_setaffinity    241
+#define TARGET_NR_sched_getaffinity    242
+#define TARGET_NR_set_thread_area      243
+#define TARGET_NR_get_thread_area      244
+#define TARGET_NR_io_setup             245
+#define TARGET_NR_io_destroy           246
+#define TARGET_NR_io_getevents 247
+#define TARGET_NR_io_submit            248
+#define TARGET_NR_io_cancel            249
+#define TARGET_NR_fadvise64            250
+
+#define TARGET_NR_exit_group           252
+#define TARGET_NR_lookup_dcookie       253
+#define TARGET_NR_epoll_create 254
+#define TARGET_NR_epoll_ctl            255
+#define TARGET_NR_epoll_wait           256
+#define TARGET_NR_remap_file_pages     257
+#define TARGET_NR_set_tid_address      258
+#define TARGET_NR_timer_create 259
+#define TARGET_NR_timer_settime        (TARGET_NR_timer_create+1)
+#define TARGET_NR_timer_gettime        (TARGET_NR_timer_create+2)
+#define TARGET_NR_timer_getoverrun     (TARGET_NR_timer_create+3)
+#define TARGET_NR_timer_delete (TARGET_NR_timer_create+4)
+#define TARGET_NR_clock_settime        (TARGET_NR_timer_create+5)
+#define TARGET_NR_clock_gettime        (TARGET_NR_timer_create+6)
+#define TARGET_NR_clock_getres (TARGET_NR_timer_create+7)
+#define TARGET_NR_clock_nanosleep      (TARGET_NR_timer_create+8)
+#define TARGET_NR_statfs64             268
+#define TARGET_NR_fstatfs64            269
+#define TARGET_NR_tgkill               270
+#define TARGET_NR_utimes               271
+#define TARGET_NR_fadvise64_64 272
+#define TARGET_NR_vserver              273
+#define TARGET_NR_mbind              274
+#define TARGET_NR_get_mempolicy      275
+#define TARGET_NR_set_mempolicy      276
+#define TARGET_NR_mq_open            277
+#define TARGET_NR_mq_unlink          (TARGET_NR_mq_open+1)
+#define TARGET_NR_mq_timedsend       (TARGET_NR_mq_open+2)
+#define TARGET_NR_mq_timedreceive    (TARGET_NR_mq_open+3)
+#define TARGET_NR_mq_notify          (TARGET_NR_mq_open+4)
+#define TARGET_NR_mq_getsetattr      (TARGET_NR_mq_open+5)
+#define TARGET_NR_sys_kexec_load       283
+#define TARGET_NR_waitid               284
+#define TARGET_NR_add_key              285
+#define TARGET_NR_request_key  286
+#define TARGET_NR_keyctl               287
+
+#define TARGET_NR_readahead             225        /* XXXXX */
diff --git a/linux-user/sh4/termbits.h b/linux-user/sh4/termbits.h
new file mode 100644 (file)
index 0000000..6dd5845
--- /dev/null
@@ -0,0 +1,274 @@
+/* from asm/termbits.h */
+
+#define TARGET_NCCS 19
+
+struct target_termios {
+       unsigned int c_iflag;                   /* input mode flags */
+       unsigned int c_oflag;                   /* output mode flags */
+       unsigned int c_cflag;                   /* control mode flags */
+       unsigned int c_lflag;                   /* local mode flags */
+       unsigned char c_line;                   /* line discipline */
+       unsigned char c_cc[TARGET_NCCS];        /* control characters */
+};
+
+/* c_cc characters */
+#define TARGET_VINTR 0
+#define TARGET_VQUIT 1
+#define TARGET_VERASE 2
+#define TARGET_VKILL 3
+#define TARGET_VEOF 4
+#define TARGET_VTIME 5
+#define TARGET_VMIN 6
+#define TARGET_VSWTC 7
+#define TARGET_VSTART 8
+#define TARGET_VSTOP 9
+#define TARGET_VSUSP 10
+#define TARGET_VEOL 11
+#define TARGET_VREPRINT 12
+#define TARGET_VDISCARD 13
+#define TARGET_VWERASE 14
+#define TARGET_VLNEXT 15
+#define TARGET_VEOL2 16
+
+/* c_iflag bits */
+#define TARGET_IGNBRK  0000001
+#define TARGET_BRKINT  0000002
+#define TARGET_IGNPAR  0000004
+#define TARGET_PARMRK  0000010
+#define TARGET_INPCK   0000020
+#define TARGET_ISTRIP  0000040
+#define TARGET_INLCR   0000100
+#define TARGET_IGNCR   0000200
+#define TARGET_ICRNL   0000400
+#define TARGET_IUCLC   0001000
+#define TARGET_IXON    0002000
+#define TARGET_IXANY   0004000
+#define TARGET_IXOFF   0010000
+#define TARGET_IMAXBEL 0020000
+#define TARGET_IUTF8   0040000
+
+/* c_oflag bits */
+#define TARGET_OPOST   0000001
+#define TARGET_OLCUC   0000002
+#define TARGET_ONLCR   0000004
+#define TARGET_OCRNL   0000010
+#define TARGET_ONOCR   0000020
+#define TARGET_ONLRET  0000040
+#define TARGET_OFILL   0000100
+#define TARGET_OFDEL   0000200
+#define TARGET_NLDLY   0000400
+#define TARGET_NL0     0000000
+#define TARGET_NL1     0000400
+#define TARGET_CRDLY   0003000
+#define TARGET_CR0     0000000
+#define TARGET_CR1     0001000
+#define TARGET_CR2     0002000
+#define TARGET_CR3     0003000
+#define TARGET_TABDLY  0014000
+#define TARGET_TAB0    0000000
+#define TARGET_TAB1    0004000
+#define TARGET_TAB2    0010000
+#define TARGET_TAB3    0014000
+#define TARGET_XTABS   0014000
+#define TARGET_BSDLY   0020000
+#define TARGET_BS0     0000000
+#define TARGET_BS1     0020000
+#define TARGET_VTDLY   0040000
+#define TARGET_VT0     0000000
+#define TARGET_VT1     0040000
+#define TARGET_FFDLY   0100000
+#define TARGET_FF0     0000000
+#define TARGET_FF1     0100000
+
+/* c_cflag bit meaning */
+#define TARGET_CBAUD   0010017
+#define TARGET_B0      0000000         /* hang up */
+#define TARGET_B50     0000001
+#define TARGET_B75     0000002
+#define TARGET_B110    0000003
+#define TARGET_B134    0000004
+#define TARGET_B150    0000005
+#define TARGET_B200    0000006
+#define TARGET_B300    0000007
+#define TARGET_B600    0000010
+#define TARGET_B1200   0000011
+#define TARGET_B1800   0000012
+#define TARGET_B2400   0000013
+#define TARGET_B4800   0000014
+#define TARGET_B9600   0000015
+#define TARGET_B19200  0000016
+#define TARGET_B38400  0000017
+#define TARGET_EXTA B19200
+#define TARGET_EXTB B38400
+#define TARGET_CSIZE   0000060
+#define TARGET_CS5     0000000
+#define TARGET_CS6     0000020
+#define TARGET_CS7     0000040
+#define TARGET_CS8     0000060
+#define TARGET_CSTOPB  0000100
+#define TARGET_CREAD   0000200
+#define TARGET_PARENB  0000400
+#define TARGET_PARODD  0001000
+#define TARGET_HUPCL   0002000
+#define TARGET_CLOCAL  0004000
+#define TARGET_CBAUDEX 0010000
+#define TARGET_B57600 0010001
+#define TARGET_B115200 0010002
+#define TARGET_B230400 0010003
+#define TARGET_B460800 0010004
+#define TARGET_B500000 0010005
+#define TARGET_B576000 0010006
+#define TARGET_B921600 0010007
+#define TARGET_B1000000 0010010
+#define TARGET_B1152000 0010011
+#define TARGET_B1500000 0010012
+#define TARGET_B2000000 0010013
+#define TARGET_B2500000 0010014
+#define TARGET_B3000000 0010015
+#define TARGET_B3500000 0010016
+#define TARGET_B4000000 0010017
+#define TARGET_CIBAUD    002003600000  /* input baud rate (not used) */
+#define TARGET_CMSPAR    010000000000          /* mark or space (stick) parity */
+#define TARGET_CRTSCTS   020000000000          /* flow control */
+
+/* c_lflag bits */
+#define TARGET_ISIG    0000001
+#define TARGET_ICANON  0000002
+#define TARGET_XCASE   0000004
+#define TARGET_ECHO    0000010
+#define TARGET_ECHOE   0000020
+#define TARGET_ECHOK   0000040
+#define TARGET_ECHONL  0000100
+#define TARGET_NOFLSH  0000200
+#define TARGET_TOSTOP  0000400
+#define TARGET_ECHOCTL 0001000
+#define TARGET_ECHOPRT 0002000
+#define TARGET_ECHOKE  0004000
+#define TARGET_FLUSHO  0010000
+#define TARGET_PENDIN  0040000
+#define TARGET_IEXTEN  0100000
+
+/* tcflow() and TCXONC use these */
+#define TARGET_TCOOFF          0
+#define TARGET_TCOON           1
+#define TARGET_TCIOFF          2
+#define TARGET_TCION           3
+
+/* tcflush() and TCFLSH use these */
+#define TARGET_TCIFLUSH        0
+#define TARGET_TCOFLUSH        1
+#define TARGET_TCIOFLUSH       2
+
+/* tcsetattr uses these */
+#define TARGET_TCSANOW         0
+#define TARGET_TCSADRAIN       1
+#define TARGET_TARGET_TCSAFLUSH        2
+
+/* ioctl */
+#define TARGET_FIOCLEX         TARGET_IO('f', 1)
+#define TARGET_FIONCLEX        TARGET_IO('f', 2)
+#define TARGET_FIOASYNC        TARGET_IOW('f', 125, int)
+#define TARGET_FIONBIO         TARGET_IOW('f', 126, int)
+#define TARGET_FIONREAD        TARGET_IOR('f', 127, int)
+#define TARGET_TIOCINQ         TARGET_FIONREAD
+#define TARGET_FIOQSIZE        TARGET_IOR('f', 128, loff_t)
+#define TARGET_TCGETS          0x5401
+#define TARGET_TCSETS          0x5402
+#define TARGET_TCSETSW         0x5403
+#define TARGET_TCSETSF         0x5404
+#define TARGET_TCGETA          TARGET_IOR('t', 23, struct termio)
+#define TARGET_TIOCSWINSZ      TARGET_IOW('t', 103, struct winsize)
+#define TARGET_TIOCGWINSZ      TARGET_IOR('t', 104, struct winsize)
+#define TARGET_TIOCSTART       TARGET_IO('t', 110)           /* start output, like ^Q */
+#define TARGET_TIOCSTOP        TARGET_IO('t', 111)           /* stop output, like ^S */
+#define TARGET_TIOCOUTQ        TARGET_IOR('t', 115, int)     /* output queue size */
+
+#define TARGET_TIOCSPGRP       TARGET_IOW('t', 118, int)
+#define TARGET_TIOCGPGRP       TARGET_IOR('t', 119, int)
+
+#define TARGET_TCSETA          TARGET_IOW('t', 24, struct termio)
+#define TARGET_TCSETAW         TARGET_IOW('t', 25, struct termio)
+#define TARGET_TCSETAF         TARGET_IOW('t', 28, struct termio)
+#define TARGET_TCSBRK          TARGET_IO('t', 29)
+#define TARGET_TCXONC          TARGET_IO('t', 30)
+#define TARGET_TCFLSH          TARGET_IO('t', 31)
+
+#define TARGET_TIOCSWINSZ      TARGET_IOW('t', 103, struct winsize)
+#define TARGET_TIOCGWINSZ      TARGET_IOR('t', 104, struct winsize)
+#define TARGET_TIOCSTART       TARGET_IO('t', 110)           /* start output, like ^Q */
+#define TARGET_TIOCSTOP        TARGET_IO('t', 111)           /* stop output, like ^S */
+#define TARGET_TIOCOUTQ        TARGET_IOR('t', 115, int)     /* output queue size */
+
+#define TARGET_TIOCSPGRP       TARGET_IOW('t', 118, int)
+#define TARGET_TIOCGPGRP       TARGET_IOR('t', 119, int)
+#define TARGET_TIOCEXCL        TARGET_IO('T', 12) /* 0x540C */
+#define TARGET_TIOCNXCL        TARGET_IO('T', 13) /* 0x540D */
+#define TARGET_TIOCSCTTY       TARGET_IO('T', 14) /* 0x540E */
+
+#define TARGET_TIOCSTI         TARGET_IOW('T', 18, char) /* 0x5412 */
+#define TARGET_TIOCMGET        TARGET_IOR('T', 21, unsigned int) /* 0x5415 */
+#define TARGET_TIOCMBIS        TARGET_IOW('T', 22, unsigned int) /* 0x5416 */
+#define TARGET_TIOCMBIC        TARGET_IOW('T', 23, unsigned int) /* 0x5417 */
+#define TARGET_TIOCMSET        TARGET_IOW('T', 24, unsigned int) /* 0x5418 */
+#define TARGET_TIOCM_LE       0x001
+#define TARGET_TIOCM_DTR      0x002
+#define TARGET_TIOCM_RTS      0x004
+#define TARGET_TIOCM_ST       0x008
+#define TARGET_TIOCM_SR       0x010
+#define TARGET_TIOCM_CTS      0x020
+#define TARGET_TIOCM_CAR      0x040
+#define TARGET_TIOCM_RNG      0x080
+#define TARGET_TIOCM_DSR      0x100
+#define TARGET_TIOCM_CD       TARGET_TIOCM_CAR
+#define TARGET_TIOCM_RI       TARGET_TIOCM_RNG
+
+#define TARGET_TIOCGSOFTCAR    TARGET_IOR('T', 25, unsigned int) /* 0x5419 */
+#define TARGET_TIOCSSOFTCAR    TARGET_IOW('T', 26, unsigned int) /* 0x541A */
+#define TARGET_TIOCLINUX       TARGET_IOW('T', 28, char) /* 0x541C */
+#define TARGET_TIOCCONS        TARGET_IO('T', 29) /* 0x541D */
+#define TARGET_TIOCGSERIAL     TARGET_IOR('T', 30, int) /* 0x541E */
+#define TARGET_TIOCSSERIAL     TARGET_IOW('T', 31, int) /* 0x541F */
+#define TARGET_TIOCPKT         TARGET_IOW('T', 32, int) /* 0x5420 */
+#define TARGET_TIOCPKT_DATA            0
+#define TARGET_TIOCPKT_FLUSHREAD       1
+#define TARGET_TIOCPKT_FLUSHWRITE      2
+#define TARGET_TIOCPKT_STOP            4
+#define TARGET_TIOCPKT_START           8
+#define TARGET_TIOCPKT_NOSTOP         16
+#define TARGET_TIOCPKT_DOSTOP         32
+
+
+#define TARGET_TIOCNOTTY       TARGET_IO('T', 34) /* 0x5422 */
+#define TARGET_TIOCSETD        TARGET_IOW('T', 35, int) /* 0x5423 */
+#define TARGET_TIOCGETD        TARGET_IOR('T', 36, int) /* 0x5424 */
+#define TARGET_TCSBRKP         TARGET_IOW('T', 37, int) /* 0x5425 */ /* Needed for POSIX tcse
+ndbreak() */
+#define TARGET_TIOCSBRK        TARGET_IO('T', 39) /* 0x5427 */ /* BSD compatibility */
+#define TARGET_TIOCCBRK        TARGET_IO('T', 40) /* 0x5428 */ /* BSD compatibility */
+#define TARGET_TIOCGSID        TARGET_IOR('T', 41, pid_t) /* 0x5429 */ /* Return the session 
+ID of FD */
+#define TARGET_TIOCGPTN        TARGET_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-m
+ux device) */
+#define TARGET_TIOCSPTLCK      TARGET_IOW('T',0x31, int)  /* Lock/unlock Pty */
+
+
+#define TARGET_TIOCSERCONFIG   TARGET_IO('T', 83) /* 0x5453 */
+#define TARGET_TIOCSERGWILD    TARGET_IOR('T', 84,  int) /* 0x5454 */
+#define TARGET_TIOCSERSWILD    TARGET_IOW('T', 85,  int) /* 0x5455 */
+#define TARGET_TIOCGLCKTRMIOS  0x5456
+#define TARGET_TIOCSLCKTRMIOS  0x5457
+#define TARGET_TIOCSERGSTRUCT  TARGET_IOR('T', 88, int) /* 0x5458 */ /* For d
+ebugging only */
+#define TARGET_TIOCSERGETLSR   TARGET_IOR('T', 89, unsigned int) /* 0x5459 */ /* Get line sta
+tus register */
+  /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+# define TIOCSER_TEMT    0x01   /* Transmitter physically empty */
+#define TARGET_TIOCSERGETMULTI TARGET_IOR('T', 90, int) /* 0x545A 
+*/ /* Get multiport config  */
+#define TARGET_TIOCSERSETMULTI TARGET_IOW('T', 91, int) /* 0x545B 
+*/ /* Set multiport config */
+
+#define TARGET_TIOCMIWAIT      TARGET_IO('T', 92) /* 0x545C */       /* wait for a change on 
+serial input line(s) */
+#define TARGET_TIOCGICOUNT     TARGET_IOR('T', 93, int) /* 0x545D */ /* read 
+serial port inline interrupt counts */
index c3b22ce..7da469a 100644 (file)
@@ -1618,6 +1618,11 @@ int do_fork(CPUState *env, unsigned int flags, unsigned long newsp)
             for (i = 7; i < 32; i++)
                 new_env->gpr[i] = 0;
         }
+#elif defined(TARGET_SH4)
+       if (!newsp)
+         newsp = env->gregs[15];
+       new_env->gregs[15] = newsp;
+       /* XXXXX */
 #else
 #error unsupported target CPU
 #endif
index c722e3a..4e2dd17 100644 (file)
@@ -48,7 +48,7 @@
 #define TARGET_IOC_NRBITS      8
 #define TARGET_IOC_TYPEBITS    8
 
-#if defined(TARGET_I386) || defined(TARGET_ARM)
+#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SH4)
 
 #define TARGET_IOC_SIZEBITS    14
 #define TARGET_IOC_DIRBITS     2
@@ -293,7 +293,7 @@ struct target_sigaction;
 int do_sigaction(int sig, const struct target_sigaction *act,
                  struct target_sigaction *oact);
 
-#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_MIPS)
+#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_MIPS) || defined (TARGET_SH4)
 
 #if defined(TARGET_SPARC)
 #define TARGET_SA_NOCLDSTOP    8u
@@ -863,7 +863,7 @@ struct target_winsize {
 #define TARGET_MAP_NORESERVE   0x4000          /* don't check for reservations */
 #endif
 
-#if defined(TARGET_I386) || defined(TARGET_ARM)
+#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SH4)
 struct target_stat {
        unsigned short st_dev;
        unsigned short __pad1;
diff --git a/sh4-dis.c b/sh4-dis.c
new file mode 100644 (file)
index 0000000..5f45e5e
--- /dev/null
+++ b/sh4-dis.c
@@ -0,0 +1,2096 @@
+/* Disassemble SH instructions.
+   Copyright 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002, 2003, 2004
+   Free Software Foundation, Inc.
+
+   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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include <stdio.h>
+#include "dis-asm.h"
+
+#define DEFINE_TABLE
+
+typedef enum
+  {
+    HEX_0,
+    HEX_1,
+    HEX_2,
+    HEX_3,
+    HEX_4,
+    HEX_5,
+    HEX_6,
+    HEX_7,
+    HEX_8,
+    HEX_9,
+    HEX_A,
+    HEX_B,
+    HEX_C,
+    HEX_D,
+    HEX_E,
+    HEX_F,
+    HEX_XX00,
+    HEX_00YY,
+    REG_N,
+    REG_N_D,     /* nnn0 */
+    REG_N_B01,   /* nn01 */
+    REG_M,
+    SDT_REG_N,
+    REG_NM,
+    REG_B,
+    BRANCH_12,
+    BRANCH_8,
+    IMM0_4,
+    IMM0_4BY2,
+    IMM0_4BY4,
+    IMM1_4,
+    IMM1_4BY2,
+    IMM1_4BY4,
+    PCRELIMM_8BY2,
+    PCRELIMM_8BY4,
+    IMM0_8,
+    IMM0_8BY2,
+    IMM0_8BY4,
+    IMM1_8,
+    IMM1_8BY2,
+    IMM1_8BY4,
+    PPI,
+    NOPX,
+    NOPY,
+    MOVX,
+    MOVY,
+    MOVX_NOPY,
+    MOVY_NOPX,
+    PSH,
+    PMUL,
+    PPI3,
+    PPI3NC,
+    PDC,
+    PPIC,
+    REPEAT,
+    IMM0_3c,   /* xxxx 0iii */
+    IMM0_3s,   /* xxxx 1iii */
+    IMM0_3Uc,  /* 0iii xxxx */
+    IMM0_3Us,  /* 1iii xxxx */
+    IMM0_20_4,
+    IMM0_20,   /* follows IMM0_20_4 */
+    IMM0_20BY8,        /* follows IMM0_20_4 */
+    DISP0_12,
+    DISP0_12BY2,
+    DISP0_12BY4,
+    DISP0_12BY8,
+    DISP1_12,
+    DISP1_12BY2,
+    DISP1_12BY4,
+    DISP1_12BY8
+  }
+sh_nibble_type;
+
+typedef enum
+  {
+    A_END,
+    A_BDISP12,
+    A_BDISP8,
+    A_DEC_M,
+    A_DEC_N,
+    A_DISP_GBR,
+    A_PC,
+    A_DISP_PC,
+    A_DISP_PC_ABS,
+    A_DISP_REG_M,
+    A_DISP_REG_N,
+    A_GBR,
+    A_IMM,
+    A_INC_M,
+    A_INC_N,
+    A_IND_M,
+    A_IND_N,
+    A_IND_R0_REG_M,
+    A_IND_R0_REG_N,
+    A_MACH,
+    A_MACL,
+    A_PR,
+    A_R0,
+    A_R0_GBR,
+    A_REG_M,
+    A_REG_N,
+    A_REG_B,
+    A_SR,
+    A_VBR,
+    A_TBR,
+    A_DISP_TBR,
+    A_DISP2_TBR,
+    A_DEC_R15,
+    A_INC_R15,
+    A_MOD,
+    A_RE,
+    A_RS,
+    A_DSR,
+    DSP_REG_M,
+    DSP_REG_N,
+    DSP_REG_X,
+    DSP_REG_Y,
+    DSP_REG_E,
+    DSP_REG_F,
+    DSP_REG_G,
+    DSP_REG_A_M,
+    DSP_REG_AX,
+    DSP_REG_XY,
+    DSP_REG_AY,
+    DSP_REG_YX,
+    AX_INC_N,
+    AY_INC_N,
+    AXY_INC_N,
+    AYX_INC_N,
+    AX_IND_N,
+    AY_IND_N,
+    AXY_IND_N,
+    AYX_IND_N,
+    AX_PMOD_N,
+    AXY_PMOD_N,
+    AY_PMOD_N,
+    AYX_PMOD_N,
+    AS_DEC_N,
+    AS_INC_N,
+    AS_IND_N,
+    AS_PMOD_N,
+    A_A0,
+    A_X0,
+    A_X1,
+    A_Y0,
+    A_Y1,
+    A_SSR,
+    A_SPC,
+    A_SGR,
+    A_DBR,
+    F_REG_N,
+    F_REG_M,
+    D_REG_N,
+    D_REG_M,
+    X_REG_N, /* Only used for argument parsing.  */
+    X_REG_M, /* Only used for argument parsing.  */
+    DX_REG_N,
+    DX_REG_M,
+    V_REG_N,
+    V_REG_M,
+    XMTRX_M4,
+    F_FR0,
+    FPUL_N,
+    FPUL_M,
+    FPSCR_N,
+    FPSCR_M
+  }
+sh_arg_type;
+
+typedef enum
+  {
+    A_A1_NUM =   5,
+    A_A0_NUM =   7,
+    A_X0_NUM, A_X1_NUM, A_Y0_NUM, A_Y1_NUM,
+    A_M0_NUM, A_A1G_NUM, A_M1_NUM, A_A0G_NUM
+  }
+sh_dsp_reg_nums;
+
+#define arch_sh1_base  0x0001
+#define arch_sh2_base  0x0002
+#define arch_sh3_base  0x0004
+#define arch_sh4_base  0x0008
+#define arch_sh4a_base 0x0010
+#define arch_sh2a_base  0x0020
+
+/* This is an annotation on instruction types, but we abuse the arch
+   field in instructions to denote it.  */
+#define arch_op32       0x00100000 /* This is a 32-bit opcode.  */
+
+#define arch_sh_no_mmu 0x04000000
+#define arch_sh_has_mmu 0x08000000
+#define arch_sh_no_co  0x10000000 /* neither FPU nor DSP co-processor */
+#define arch_sh_sp_fpu 0x20000000 /* single precision FPU */
+#define arch_sh_dp_fpu 0x40000000 /* double precision FPU */
+#define arch_sh_has_dsp        0x80000000
+
+
+#define arch_sh_base_mask 0x0000003f
+#define arch_opann_mask   0x00100000
+#define arch_sh_mmu_mask  0x0c000000
+#define arch_sh_co_mask   0xf0000000
+
+
+#define arch_sh1       (arch_sh1_base|arch_sh_no_mmu|arch_sh_no_co)
+#define arch_sh2       (arch_sh2_base|arch_sh_no_mmu|arch_sh_no_co)
+#define arch_sh2a      (arch_sh2a_base|arch_sh_no_mmu|arch_sh_dp_fpu)
+#define arch_sh2a_nofpu        (arch_sh2a_base|arch_sh_no_mmu|arch_sh_no_co)
+#define arch_sh2e      (arch_sh2_base|arch_sh2a_base|arch_sh_no_mmu|arch_sh_sp_fpu)
+#define arch_sh_dsp    (arch_sh2_base|arch_sh_no_mmu|arch_sh_has_dsp)
+#define arch_sh3_nommu (arch_sh3_base|arch_sh_no_mmu|arch_sh_no_co)
+#define arch_sh3       (arch_sh3_base|arch_sh_has_mmu|arch_sh_no_co)
+#define arch_sh3e      (arch_sh3_base|arch_sh_has_mmu|arch_sh_sp_fpu)
+#define arch_sh3_dsp   (arch_sh3_base|arch_sh_has_mmu|arch_sh_has_dsp)
+#define arch_sh4       (arch_sh4_base|arch_sh_has_mmu|arch_sh_dp_fpu)
+#define arch_sh4a      (arch_sh4a_base|arch_sh_has_mmu|arch_sh_dp_fpu)
+#define arch_sh4al_dsp (arch_sh4a_base|arch_sh_has_mmu|arch_sh_has_dsp)
+#define arch_sh4_nofpu (arch_sh4_base|arch_sh_has_mmu|arch_sh_no_co)
+#define arch_sh4a_nofpu        (arch_sh4a_base|arch_sh_has_mmu|arch_sh_no_co)
+#define arch_sh4_nommu_nofpu (arch_sh4_base|arch_sh_no_mmu|arch_sh_no_co)
+
+#define SH_MERGE_ARCH_SET(SET1, SET2) ((SET1) & (SET2))
+#define SH_VALID_BASE_ARCH_SET(SET) (((SET) & arch_sh_base_mask) != 0)
+#define SH_VALID_MMU_ARCH_SET(SET)  (((SET) & arch_sh_mmu_mask) != 0)
+#define SH_VALID_CO_ARCH_SET(SET)   (((SET) & arch_sh_co_mask) != 0)
+#define SH_VALID_ARCH_SET(SET) \
+  (SH_VALID_BASE_ARCH_SET (SET) \
+   && SH_VALID_MMU_ARCH_SET (SET) \
+   && SH_VALID_CO_ARCH_SET (SET))
+#define SH_MERGE_ARCH_SET_VALID(SET1, SET2) \
+  SH_VALID_ARCH_SET (SH_MERGE_ARCH_SET (SET1, SET2))
+
+#define SH_ARCH_SET_HAS_FPU(SET) \
+  (((SET) & (arch_sh_sp_fpu | arch_sh_dp_fpu)) != 0)
+#define SH_ARCH_SET_HAS_DSP(SET) \
+  (((SET) & arch_sh_has_dsp) != 0)
+
+/* This is returned from the functions below when an error occurs
+   (in addition to a call to BFD_FAIL). The value should allow
+   the tools to continue to function in most cases - there may
+   be some confusion between DSP and FPU etc.  */
+#define SH_ARCH_UNKNOWN_ARCH 0xffffffff
+
+/* These are defined in bfd/cpu-sh.c .  */
+unsigned int sh_get_arch_from_bfd_mach (unsigned long mach);
+unsigned int sh_get_arch_up_from_bfd_mach (unsigned long mach);
+unsigned long sh_get_bfd_mach_from_arch_set (unsigned int arch_set);
+/* bfd_boolean sh_merge_bfd_arch (bfd *ibfd, bfd *obfd); */
+
+/* Below are the 'architecture sets'.
+   They describe the following inheritance graph:
+
+                SH1
+                 |
+                SH2
+   .------------'|`--------------------.
+  /              |                      \
+SH-DSP          SH3-nommu               SH2E
+ |               |`--------.             |
+ |               |          \            |
+ |              SH3     SH4-nommu-nofpu  |
+ |               |           |           |
+ | .------------'|`----------+---------. |
+ |/                         /           \|
+ |               | .-------'             |
+ |               |/                      |
+SH3-dsp         SH4-nofpu               SH3E
+ |               |`--------------------. |
+ |               |                      \|
+ |              SH4A-nofpu              SH4
+ | .------------' `--------------------. |
+ |/                                     \|
+SH4AL-dsp                               SH4A
+
+*/
+
+/* Central branches */
+#define arch_sh1_up       (arch_sh1 | arch_sh2_up)
+#define arch_sh2_up       (arch_sh2 | arch_sh2e_up | arch_sh2a_nofpu_up | arch_sh3_nommu_up | arch_sh_dsp_up)
+#define arch_sh3_nommu_up (arch_sh3_nommu | arch_sh3_up | arch_sh4_nommu_nofpu_up)
+#define arch_sh3_up       (arch_sh3 | arch_sh3e_up | arch_sh3_dsp_up | arch_sh4_nofp_up)
+#define arch_sh4_nommu_nofpu_up (arch_sh4_nommu_nofpu | arch_sh4_nofp_up)
+#define arch_sh4_nofp_up  (arch_sh4_nofpu | arch_sh4_up | arch_sh4a_nofp_up)
+#define arch_sh4a_nofp_up (arch_sh4a_nofpu | arch_sh4a_up | arch_sh4al_dsp_up)
+
+/* Right branch */
+#define arch_sh2e_up (arch_sh2e | arch_sh2a_up | arch_sh3e_up)
+#define arch_sh3e_up (arch_sh3e | arch_sh4_up)
+#define arch_sh4_up  (arch_sh4 | arch_sh4a_up)
+#define arch_sh4a_up (arch_sh4a)
+
+/* Left branch */
+#define arch_sh_dsp_up    (arch_sh_dsp | arch_sh3_dsp_up)
+#define arch_sh3_dsp_up   (arch_sh3_dsp | arch_sh4al_dsp_up)
+#define arch_sh4al_dsp_up (arch_sh4al_dsp)
+
+/* SH 2a branched off SH2e, adding a lot but not all of SH4 and SH4a.  */
+#define arch_sh2a_up        (arch_sh2a)
+#define arch_sh2a_nofpu_up  (arch_sh2a_nofpu | arch_sh2a_up)
+
+
+typedef struct
+{
+  char *name;
+  sh_arg_type arg[4];
+  sh_nibble_type nibbles[9];
+  unsigned int arch;
+} sh_opcode_info;
+
+#ifdef DEFINE_TABLE
+
+const sh_opcode_info sh_table[] =
+  {
+/* 0111nnnni8*1.... add #<imm>,<REG_N>  */{"add",{A_IMM,A_REG_N},{HEX_7,REG_N,IMM0_8}, arch_sh1_up},
+
+/* 0011nnnnmmmm1100 add <REG_M>,<REG_N> */{"add",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_C}, arch_sh1_up},
+
+/* 0011nnnnmmmm1110 addc <REG_M>,<REG_N>*/{"addc",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_E}, arch_sh1_up},
+
+/* 0011nnnnmmmm1111 addv <REG_M>,<REG_N>*/{"addv",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_F}, arch_sh1_up},
+
+/* 11001001i8*1.... and #<imm>,R0       */{"and",{A_IMM,A_R0},{HEX_C,HEX_9,IMM0_8}, arch_sh1_up},
+
+/* 0010nnnnmmmm1001 and <REG_M>,<REG_N> */{"and",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_9}, arch_sh1_up},
+
+/* 11001101i8*1.... and.b #<imm>,@(R0,GBR)*/{"and.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_D,IMM0_8}, arch_sh1_up},
+
+/* 1010i12......... bra <bdisp12>       */{"bra",{A_BDISP12},{HEX_A,BRANCH_12}, arch_sh1_up},
+
+/* 1011i12......... bsr <bdisp12>       */{"bsr",{A_BDISP12},{HEX_B,BRANCH_12}, arch_sh1_up},
+
+/* 10001001i8p1.... bt <bdisp8>         */{"bt",{A_BDISP8},{HEX_8,HEX_9,BRANCH_8}, arch_sh1_up},
+
+/* 10001011i8p1.... bf <bdisp8>         */{"bf",{A_BDISP8},{HEX_8,HEX_B,BRANCH_8}, arch_sh1_up},
+
+/* 10001101i8p1.... bt.s <bdisp8>       */{"bt.s",{A_BDISP8},{HEX_8,HEX_D,BRANCH_8}, arch_sh2_up},
+
+/* 10001101i8p1.... bt/s <bdisp8>       */{"bt/s",{A_BDISP8},{HEX_8,HEX_D,BRANCH_8}, arch_sh2_up},
+
+/* 10001111i8p1.... bf.s <bdisp8>       */{"bf.s",{A_BDISP8},{HEX_8,HEX_F,BRANCH_8}, arch_sh2_up},
+
+/* 10001111i8p1.... bf/s <bdisp8>       */{"bf/s",{A_BDISP8},{HEX_8,HEX_F,BRANCH_8}, arch_sh2_up},
+
+/* 0000000010001000 clrdmxy             */{"clrdmxy",{0},{HEX_0,HEX_0,HEX_8,HEX_8}, arch_sh4al_dsp_up},
+
+/* 0000000000101000 clrmac              */{"clrmac",{0},{HEX_0,HEX_0,HEX_2,HEX_8}, arch_sh1_up},
+
+/* 0000000001001000 clrs                */{"clrs",{0},{HEX_0,HEX_0,HEX_4,HEX_8}, arch_sh1_up},
+
+/* 0000000000001000 clrt                */{"clrt",{0},{HEX_0,HEX_0,HEX_0,HEX_8}, arch_sh1_up},
+
+/* 10001000i8*1.... cmp/eq #<imm>,R0    */{"cmp/eq",{A_IMM,A_R0},{HEX_8,HEX_8,IMM0_8}, arch_sh1_up},
+
+/* 0011nnnnmmmm0000 cmp/eq <REG_M>,<REG_N>*/{"cmp/eq",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_0}, arch_sh1_up},
+
+/* 0011nnnnmmmm0011 cmp/ge <REG_M>,<REG_N>*/{"cmp/ge",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_3}, arch_sh1_up},
+
+/* 0011nnnnmmmm0111 cmp/gt <REG_M>,<REG_N>*/{"cmp/gt",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_7}, arch_sh1_up},
+
+/* 0011nnnnmmmm0110 cmp/hi <REG_M>,<REG_N>*/{"cmp/hi",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_6}, arch_sh1_up},
+
+/* 0011nnnnmmmm0010 cmp/hs <REG_M>,<REG_N>*/{"cmp/hs",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_2}, arch_sh1_up},
+
+/* 0100nnnn00010101 cmp/pl <REG_N>      */{"cmp/pl",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_5}, arch_sh1_up},
+
+/* 0100nnnn00010001 cmp/pz <REG_N>      */{"cmp/pz",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_1}, arch_sh1_up},
+
+/* 0010nnnnmmmm1100 cmp/str <REG_M>,<REG_N>*/{"cmp/str",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_C}, arch_sh1_up},
+
+/* 0010nnnnmmmm0111 div0s <REG_M>,<REG_N>*/{"div0s",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_7}, arch_sh1_up},
+
+/* 0000000000011001 div0u               */{"div0u",{0},{HEX_0,HEX_0,HEX_1,HEX_9}, arch_sh1_up},
+
+/* 0011nnnnmmmm0100 div1 <REG_M>,<REG_N>*/{"div1",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_4}, arch_sh1_up},
+
+/* 0110nnnnmmmm1110 exts.b <REG_M>,<REG_N>*/{"exts.b",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_E}, arch_sh1_up},
+
+/* 0110nnnnmmmm1111 exts.w <REG_M>,<REG_N>*/{"exts.w",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_F}, arch_sh1_up},
+
+/* 0110nnnnmmmm1100 extu.b <REG_M>,<REG_N>*/{"extu.b",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_C}, arch_sh1_up},
+
+/* 0110nnnnmmmm1101 extu.w <REG_M>,<REG_N>*/{"extu.w",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_D}, arch_sh1_up},
+
+/* 0000nnnn11100011 icbi @<REG_N>       */{"icbi",{A_IND_N},{HEX_0,REG_N,HEX_E,HEX_3}, arch_sh4a_nofp_up},
+
+/* 0100nnnn00101011 jmp @<REG_N>        */{"jmp",{A_IND_N},{HEX_4,REG_N,HEX_2,HEX_B}, arch_sh1_up},
+
+/* 0100nnnn00001011 jsr @<REG_N>        */{"jsr",{A_IND_N},{HEX_4,REG_N,HEX_0,HEX_B}, arch_sh1_up},
+
+/* 0100nnnn00001110 ldc <REG_N>,SR      */{"ldc",{A_REG_N,A_SR},{HEX_4,REG_N,HEX_0,HEX_E}, arch_sh1_up},
+
+/* 0100nnnn00011110 ldc <REG_N>,GBR     */{"ldc",{A_REG_N,A_GBR},{HEX_4,REG_N,HEX_1,HEX_E}, arch_sh1_up},
+
+/* 0100nnnn00111010 ldc <REG_N>,SGR     */{"ldc",{A_REG_N,A_SGR},{HEX_4,REG_N,HEX_3,HEX_A}, arch_sh4_nommu_nofpu_up},
+
+/* 0100mmmm01001010 ldc <REG_M>,TBR     */{"ldc",{A_REG_M,A_TBR},{HEX_4,REG_M,HEX_4,HEX_A}, arch_sh2a_nofpu_up},
+
+/* 0100nnnn00101110 ldc <REG_N>,VBR     */{"ldc",{A_REG_N,A_VBR},{HEX_4,REG_N,HEX_2,HEX_E}, arch_sh1_up},
+
+/* 0100nnnn01011110 ldc <REG_N>,MOD     */{"ldc",{A_REG_N,A_MOD},{HEX_4,REG_N,HEX_5,HEX_E}, arch_sh_dsp_up},
+
+/* 0100nnnn01111110 ldc <REG_N>,RE     */{"ldc",{A_REG_N,A_RE},{HEX_4,REG_N,HEX_7,HEX_E}, arch_sh_dsp_up},
+
+/* 0100nnnn01101110 ldc <REG_N>,RS     */{"ldc",{A_REG_N,A_RS},{HEX_4,REG_N,HEX_6,HEX_E}, arch_sh_dsp_up},
+
+/* 0100nnnn00111110 ldc <REG_N>,SSR     */{"ldc",{A_REG_N,A_SSR},{HEX_4,REG_N,HEX_3,HEX_E}, arch_sh3_nommu_up},
+
+/* 0100nnnn01001110 ldc <REG_N>,SPC     */{"ldc",{A_REG_N,A_SPC},{HEX_4,REG_N,HEX_4,HEX_E}, arch_sh3_nommu_up},
+
+/* 0100nnnn11111010 ldc <REG_N>,DBR     */{"ldc",{A_REG_N,A_DBR},{HEX_4,REG_N,HEX_F,HEX_A}, arch_sh4_nommu_nofpu_up},
+
+/* 0100nnnn1xxx1110 ldc <REG_N>,Rn_BANK */{"ldc",{A_REG_N,A_REG_B},{HEX_4,REG_N,REG_B,HEX_E}, arch_sh3_nommu_up},
+
+/* 0100nnnn00000111 ldc.l @<REG_N>+,SR  */{"ldc.l",{A_INC_N,A_SR},{HEX_4,REG_N,HEX_0,HEX_7}, arch_sh1_up},
+
+/* 0100nnnn00010111 ldc.l @<REG_N>+,GBR */{"ldc.l",{A_INC_N,A_GBR},{HEX_4,REG_N,HEX_1,HEX_7}, arch_sh1_up},
+
+/* 0100nnnn00100111 ldc.l @<REG_N>+,VBR */{"ldc.l",{A_INC_N,A_VBR},{HEX_4,REG_N,HEX_2,HEX_7}, arch_sh1_up},
+
+/* 0100nnnn00110110 ldc.l @<REG_N>+,SGR */{"ldc.l",{A_INC_N,A_SGR},{HEX_4,REG_N,HEX_3,HEX_6}, arch_sh4_nommu_nofpu_up},
+
+/* 0100nnnn01010111 ldc.l @<REG_N>+,MOD */{"ldc.l",{A_INC_N,A_MOD},{HEX_4,REG_N,HEX_5,HEX_7}, arch_sh_dsp_up},
+
+/* 0100nnnn01110111 ldc.l @<REG_N>+,RE */{"ldc.l",{A_INC_N,A_RE},{HEX_4,REG_N,HEX_7,HEX_7}, arch_sh_dsp_up},
+
+/* 0100nnnn01100111 ldc.l @<REG_N>+,RS */{"ldc.l",{A_INC_N,A_RS},{HEX_4,REG_N,HEX_6,HEX_7}, arch_sh_dsp_up},
+
+/* 0100nnnn00110111 ldc.l @<REG_N>+,SSR */{"ldc.l",{A_INC_N,A_SSR},{HEX_4,REG_N,HEX_3,HEX_7}, arch_sh3_nommu_up},
+
+/* 0100nnnn01000111 ldc.l @<REG_N>+,SPC */{"ldc.l",{A_INC_N,A_SPC},{HEX_4,REG_N,HEX_4,HEX_7}, arch_sh3_nommu_up},
+
+/* 0100nnnn11110110 ldc.l @<REG_N>+,DBR */{"ldc.l",{A_INC_N,A_DBR},{HEX_4,REG_N,HEX_F,HEX_6}, arch_sh4_nommu_nofpu_up},
+
+/* 0100nnnn1xxx0111 ldc.l <REG_N>,Rn_BANK */{"ldc.l",{A_INC_N,A_REG_B},{HEX_4,REG_N,REG_B,HEX_7}, arch_sh3_nommu_up},
+
+/* 0100mmmm00110100 ldrc <REG_M>        */{"ldrc",{A_REG_M},{HEX_4,REG_M,HEX_3,HEX_4}, arch_sh4al_dsp_up},
+/* 10001010i8*1.... ldrc #<imm>         */{"ldrc",{A_IMM},{HEX_8,HEX_A,IMM0_8}, arch_sh4al_dsp_up},
+
+/* 10001110i8p2.... ldre @(<disp>,PC)  */{"ldre",{A_DISP_PC},{HEX_8,HEX_E,PCRELIMM_8BY2}, arch_sh_dsp_up},
+
+/* 10001100i8p2.... ldrs @(<disp>,PC)  */{"ldrs",{A_DISP_PC},{HEX_8,HEX_C,PCRELIMM_8BY2}, arch_sh_dsp_up},
+
+/* 0100nnnn00001010 lds <REG_N>,MACH    */{"lds",{A_REG_N,A_MACH},{HEX_4,REG_N,HEX_0,HEX_A}, arch_sh1_up},
+
+/* 0100nnnn00011010 lds <REG_N>,MACL    */{"lds",{A_REG_N,A_MACL},{HEX_4,REG_N,HEX_1,HEX_A}, arch_sh1_up},
+
+/* 0100nnnn00101010 lds <REG_N>,PR      */{"lds",{A_REG_N,A_PR},{HEX_4,REG_N,HEX_2,HEX_A}, arch_sh1_up},
+
+/* 0100nnnn01101010 lds <REG_N>,DSR    */{"lds",{A_REG_N,A_DSR},{HEX_4,REG_N,HEX_6,HEX_A}, arch_sh_dsp_up},
+
+/* 0100nnnn01111010 lds <REG_N>,A0     */{"lds",{A_REG_N,A_A0},{HEX_4,REG_N,HEX_7,HEX_A}, arch_sh_dsp_up},
+
+/* 0100nnnn10001010 lds <REG_N>,X0     */{"lds",{A_REG_N,A_X0},{HEX_4,REG_N,HEX_8,HEX_A}, arch_sh_dsp_up},
+
+/* 0100nnnn10011010 lds <REG_N>,X1     */{"lds",{A_REG_N,A_X1},{HEX_4,REG_N,HEX_9,HEX_A}, arch_sh_dsp_up},
+
+/* 0100nnnn10101010 lds <REG_N>,Y0     */{"lds",{A_REG_N,A_Y0},{HEX_4,REG_N,HEX_A,HEX_A}, arch_sh_dsp_up},
+
+/* 0100nnnn10111010 lds <REG_N>,Y1     */{"lds",{A_REG_N,A_Y1},{HEX_4,REG_N,HEX_B,HEX_A}, arch_sh_dsp_up},
+
+/* 0100nnnn01011010 lds <REG_N>,FPUL    */{"lds",{A_REG_M,FPUL_N},{HEX_4,REG_M,HEX_5,HEX_A}, arch_sh2e_up},
+  
+/* 0100nnnn01101010 lds <REG_M>,FPSCR   */{"lds",{A_REG_M,FPSCR_N},{HEX_4,REG_M,HEX_6,HEX_A}, arch_sh2e_up},
+
+/* 0100nnnn00000110 lds.l @<REG_N>+,MACH*/{"lds.l",{A_INC_N,A_MACH},{HEX_4,REG_N,HEX_0,HEX_6}, arch_sh1_up},
+
+/* 0100nnnn00010110 lds.l @<REG_N>+,MACL*/{"lds.l",{A_INC_N,A_MACL},{HEX_4,REG_N,HEX_1,HEX_6}, arch_sh1_up},
+
+/* 0100nnnn00100110 lds.l @<REG_N>+,PR  */{"lds.l",{A_INC_N,A_PR},{HEX_4,REG_N,HEX_2,HEX_6}, arch_sh1_up},
+
+/* 0100nnnn01100110 lds.l @<REG_N>+,DSR        */{"lds.l",{A_INC_N,A_DSR},{HEX_4,REG_N,HEX_6,HEX_6}, arch_sh_dsp_up},
+
+/* 0100nnnn01110110 lds.l @<REG_N>+,A0 */{"lds.l",{A_INC_N,A_A0},{HEX_4,REG_N,HEX_7,HEX_6}, arch_sh_dsp_up},
+
+/* 0100nnnn10000110 lds.l @<REG_N>+,X0 */{"lds.l",{A_INC_N,A_X0},{HEX_4,REG_N,HEX_8,HEX_6}, arch_sh_dsp_up},
+
+/* 0100nnnn10010110 lds.l @<REG_N>+,X1 */{"lds.l",{A_INC_N,A_X1},{HEX_4,REG_N,HEX_9,HEX_6}, arch_sh_dsp_up},
+
+/* 0100nnnn10100110 lds.l @<REG_N>+,Y0 */{"lds.l",{A_INC_N,A_Y0},{HEX_4,REG_N,HEX_A,HEX_6}, arch_sh_dsp_up},
+
+/* 0100nnnn10110110 lds.l @<REG_N>+,Y1 */{"lds.l",{A_INC_N,A_Y1},{HEX_4,REG_N,HEX_B,HEX_6}, arch_sh_dsp_up},
+
+/* 0100nnnn01010110 lds.l @<REG_M>+,FPUL*/{"lds.l",{A_INC_M,FPUL_N},{HEX_4,REG_M,HEX_5,HEX_6}, arch_sh2e_up},
+  
+/* 0100nnnn01100110 lds.l @<REG_M>+,FPSCR*/{"lds.l",{A_INC_M,FPSCR_N},{HEX_4,REG_M,HEX_6,HEX_6}, arch_sh2e_up},
+
+/* 0000000000111000 ldtlb               */{"ldtlb",{0},{HEX_0,HEX_0,HEX_3,HEX_8}, arch_sh3_up},
+
+/* 0100nnnnmmmm1111 mac.w @<REG_M>+,@<REG_N>+*/{"mac.w",{A_INC_M,A_INC_N},{HEX_4,REG_N,REG_M,HEX_F}, arch_sh1_up},
+
+/* 1110nnnni8*1.... mov #<imm>,<REG_N>  */{"mov",{A_IMM,A_REG_N},{HEX_E,REG_N,IMM0_8}, arch_sh1_up},
+
+/* 0110nnnnmmmm0011 mov <REG_M>,<REG_N> */{"mov",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_3}, arch_sh1_up},
+
+/* 0000nnnnmmmm0100 mov.b <REG_M>,@(R0,<REG_N>)*/{"mov.b",{ A_REG_M,A_IND_R0_REG_N},{HEX_0,REG_N,REG_M,HEX_4}, arch_sh1_up},
+
+/* 0010nnnnmmmm0100 mov.b <REG_M>,@-<REG_N>*/{"mov.b",{ A_REG_M,A_DEC_N},{HEX_2,REG_N,REG_M,HEX_4}, arch_sh1_up},
+
+/* 0010nnnnmmmm0000 mov.b <REG_M>,@<REG_N>*/{"mov.b",{ A_REG_M,A_IND_N},{HEX_2,REG_N,REG_M,HEX_0}, arch_sh1_up},
+
+/* 10000100mmmmi4*1 mov.b @(<disp>,<REG_M>),R0*/{"mov.b",{A_DISP_REG_M,A_R0},{HEX_8,HEX_4,REG_M,IMM0_4}, arch_sh1_up},
+
+/* 11000100i8*1.... mov.b @(<disp>,GBR),R0*/{"mov.b",{A_DISP_GBR,A_R0},{HEX_C,HEX_4,IMM0_8}, arch_sh1_up},
+
+/* 0000nnnnmmmm1100 mov.b @(R0,<REG_M>),<REG_N>*/{"mov.b",{A_IND_R0_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_C}, arch_sh1_up},
+
+/* 0110nnnnmmmm0100 mov.b @<REG_M>+,<REG_N>*/{"mov.b",{A_INC_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_4}, arch_sh1_up},
+
+/* 0110nnnnmmmm0000 mov.b @<REG_M>,<REG_N>*/{"mov.b",{A_IND_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_0}, arch_sh1_up},
+
+/* 10000000mmmmi4*1 mov.b R0,@(<disp>,<REG_M>)*/{"mov.b",{A_R0,A_DISP_REG_M},{HEX_8,HEX_0,REG_M,IMM1_4}, arch_sh1_up},
+
+/* 11000000i8*1.... mov.b R0,@(<disp>,GBR)*/{"mov.b",{A_R0,A_DISP_GBR},{HEX_C,HEX_0,IMM1_8}, arch_sh1_up},
+
+/* 0100nnnn10001011 mov.b R0,@<REG_N>+ */{"mov.b",{A_R0,A_INC_N},{HEX_4,REG_N,HEX_8,HEX_B}, arch_sh2a_nofpu_up},
+/* 0100nnnn11001011 mov.b @-<REG_M>,R0 */{"mov.b",{A_DEC_M,A_R0},{HEX_4,REG_M,HEX_C,HEX_B}, arch_sh2a_nofpu_up},
+/* 0011nnnnmmmm0001 0000dddddddddddd mov.b <REG_M>,@(<DISP12>,<REG_N>) */
+{"mov.b",{A_REG_M,A_DISP_REG_N},{HEX_3,REG_N,REG_M,HEX_1,HEX_0,DISP1_12}, arch_sh2a_nofpu_up | arch_op32},
+/* 0011nnnnmmmm0001 0100dddddddddddd mov.b @(<DISP12>,<REG_M>),<REG_N> */
+{"mov.b",{A_DISP_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_1,HEX_4,DISP0_12}, arch_sh2a_nofpu_up | arch_op32},
+/* 0001nnnnmmmmi4*4 mov.l <REG_M>,@(<disp>,<REG_N>)*/{"mov.l",{ A_REG_M,A_DISP_REG_N},{HEX_1,REG_N,REG_M,IMM1_4BY4}, arch_sh1_up},
+
+/* 0000nnnnmmmm0110 mov.l <REG_M>,@(R0,<REG_N>)*/{"mov.l",{ A_REG_M,A_IND_R0_REG_N},{HEX_0,REG_N,REG_M,HEX_6}, arch_sh1_up},
+
+/* 0010nnnnmmmm0110 mov.l <REG_M>,@-<REG_N>*/{"mov.l",{ A_REG_M,A_DEC_N},{HEX_2,REG_N,REG_M,HEX_6}, arch_sh1_up},
+
+/* 0010nnnnmmmm0010 mov.l <REG_M>,@<REG_N>*/{"mov.l",{ A_REG_M,A_IND_N},{HEX_2,REG_N,REG_M,HEX_2}, arch_sh1_up},
+
+/* 0101nnnnmmmmi4*4 mov.l @(<disp>,<REG_M>),<REG_N>*/{"mov.l",{A_DISP_REG_M,A_REG_N},{HEX_5,REG_N,REG_M,IMM0_4BY4}, arch_sh1_up},
+
+/* 11000110i8*4.... mov.l @(<disp>,GBR),R0*/{"mov.l",{A_DISP_GBR,A_R0},{HEX_C,HEX_6,IMM0_8BY4}, arch_sh1_up},
+
+/* 1101nnnni8p4.... mov.l @(<disp>,PC),<REG_N>*/{"mov.l",{A_DISP_PC,A_REG_N},{HEX_D,REG_N,PCRELIMM_8BY4}, arch_sh1_up},
+
+/* 0000nnnnmmmm1110 mov.l @(R0,<REG_M>),<REG_N>*/{"mov.l",{A_IND_R0_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_E}, arch_sh1_up},
+
+/* 0110nnnnmmmm0110 mov.l @<REG_M>+,<REG_N>*/{"mov.l",{A_INC_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_6}, arch_sh1_up},
+
+/* 0110nnnnmmmm0010 mov.l @<REG_M>,<REG_N>*/{"mov.l",{A_IND_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_2}, arch_sh1_up},
+
+/* 11000010i8*4.... mov.l R0,@(<disp>,GBR)*/{"mov.l",{A_R0,A_DISP_GBR},{HEX_C,HEX_2,IMM1_8BY4}, arch_sh1_up},
+
+/* 0100nnnn10101011 mov.l R0,@<REG_N>+ */{"mov.l",{A_R0,A_INC_N},{HEX_4,REG_N,HEX_A,HEX_B}, arch_sh2a_nofpu_up},
+/* 0100nnnn11001011 mov.l @-<REG_M>,R0 */{"mov.l",{A_DEC_M,A_R0},{HEX_4,REG_M,HEX_E,HEX_B}, arch_sh2a_nofpu_up},
+/* 0011nnnnmmmm0001 0010dddddddddddd mov.l <REG_M>,@(<DISP12>,<REG_N>) */
+{"mov.l",{A_REG_M,A_DISP_REG_N},{HEX_3,REG_N,REG_M,HEX_1,HEX_2,DISP1_12BY4}, arch_sh2a_nofpu_up | arch_op32},
+/* 0011nnnnmmmm0001 0110dddddddddddd mov.l @(<DISP12>,<REG_M>),<REG_N> */
+{"mov.l",{A_DISP_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_1,HEX_6,DISP0_12BY4}, arch_sh2a_nofpu_up | arch_op32},
+/* 0000nnnnmmmm0101 mov.w <REG_M>,@(R0,<REG_N>)*/{"mov.w",{ A_REG_M,A_IND_R0_REG_N},{HEX_0,REG_N,REG_M,HEX_5}, arch_sh1_up},
+
+/* 0010nnnnmmmm0101 mov.w <REG_M>,@-<REG_N>*/{"mov.w",{ A_REG_M,A_DEC_N},{HEX_2,REG_N,REG_M,HEX_5}, arch_sh1_up},
+
+/* 0010nnnnmmmm0001 mov.w <REG_M>,@<REG_N>*/{"mov.w",{ A_REG_M,A_IND_N},{HEX_2,REG_N,REG_M,HEX_1}, arch_sh1_up},
+
+/* 10000101mmmmi4*2 mov.w @(<disp>,<REG_M>),R0*/{"mov.w",{A_DISP_REG_M,A_R0},{HEX_8,HEX_5,REG_M,IMM0_4BY2}, arch_sh1_up},
+
+/* 11000101i8*2.... mov.w @(<disp>,GBR),R0*/{"mov.w",{A_DISP_GBR,A_R0},{HEX_C,HEX_5,IMM0_8BY2}, arch_sh1_up},
+
+/* 1001nnnni8p2.... mov.w @(<disp>,PC),<REG_N>*/{"mov.w",{A_DISP_PC,A_REG_N},{HEX_9,REG_N,PCRELIMM_8BY2}, arch_sh1_up},
+
+/* 0000nnnnmmmm1101 mov.w @(R0,<REG_M>),<REG_N>*/{"mov.w",{A_IND_R0_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_D}, arch_sh1_up},
+
+/* 0110nnnnmmmm0101 mov.w @<REG_M>+,<REG_N>*/{"mov.w",{A_INC_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_5}, arch_sh1_up},
+
+/* 0110nnnnmmmm0001 mov.w @<REG_M>,<REG_N>*/{"mov.w",{A_IND_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_1}, arch_sh1_up},
+
+/* 10000001mmmmi4*2 mov.w R0,@(<disp>,<REG_M>)*/{"mov.w",{A_R0,A_DISP_REG_M},{HEX_8,HEX_1,REG_M,IMM1_4BY2}, arch_sh1_up},
+
+/* 11000001i8*2.... mov.w R0,@(<disp>,GBR)*/{"mov.w",{A_R0,A_DISP_GBR},{HEX_C,HEX_1,IMM1_8BY2}, arch_sh1_up},
+
+/* 0100nnnn10011011 mov.w R0,@<REG_N>+ */{"mov.w",{A_R0,A_INC_N},{HEX_4,REG_N,HEX_9,HEX_B}, arch_sh2a_nofpu_up},
+/* 0100nnnn11011011 mov.w @-<REG_M>,R0 */{"mov.w",{A_DEC_M,A_R0},{HEX_4,REG_M,HEX_D,HEX_B}, arch_sh2a_nofpu_up},
+/* 0011nnnnmmmm0001 0001dddddddddddd mov.w <REG_M>,@(<DISP12>,<REG_N>) */
+{"mov.w",{A_REG_M,A_DISP_REG_N},{HEX_3,REG_N,REG_M,HEX_1,HEX_1,DISP1_12BY2}, arch_sh2a_nofpu_up | arch_op32},
+/* 0011nnnnmmmm0001 0101dddddddddddd mov.w @(<DISP12>,<REG_M>),<REG_N> */
+{"mov.w",{A_DISP_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_1,HEX_5,DISP0_12BY2}, arch_sh2a_nofpu_up | arch_op32},
+/* 11000111i8p4.... mova @(<disp>,PC),R0*/{"mova",{A_DISP_PC,A_R0},{HEX_C,HEX_7,PCRELIMM_8BY4}, arch_sh1_up},
+/* 0000nnnn11000011 movca.l R0,@<REG_N> */{"movca.l",{A_R0,A_IND_N},{HEX_0,REG_N,HEX_C,HEX_3}, arch_sh4_nommu_nofpu_up},
+
+/* 0000nnnn01110011 movco.l r0,@<REG_N> */{"movco.l",{A_R0,A_IND_N},{HEX_0,REG_N,HEX_7,HEX_3}, arch_sh4a_nofp_up},
+/* 0000mmmm01100011 movli.l @<REG_M>,r0 */{"movli.l",{A_IND_M,A_R0},{HEX_0,REG_M,HEX_6,HEX_3}, arch_sh4a_nofp_up},
+
+/* 0000nnnn00101001 movt <REG_N>        */{"movt",{A_REG_N},{HEX_0,REG_N,HEX_2,HEX_9}, arch_sh1_up},
+
+/* 0100mmmm10101001 movua.l @<REG_M>,r0 */{"movua.l",{A_IND_M,A_R0},{HEX_4,REG_M,HEX_A,HEX_9}, arch_sh4a_nofp_up},
+/* 0100mmmm11101001 movua.l @<REG_M>+,r0 */{"movua.l",{A_INC_M,A_R0},{HEX_4,REG_M,HEX_E,HEX_9}, arch_sh4a_nofp_up},
+
+/* 0010nnnnmmmm1111 muls.w <REG_M>,<REG_N>*/{"muls.w",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_F}, arch_sh1_up},
+/* 0010nnnnmmmm1111 muls <REG_M>,<REG_N>*/{"muls",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_F}, arch_sh1_up},
+
+/* 0000nnnnmmmm0111 mul.l <REG_M>,<REG_N>*/{"mul.l",{ A_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_7}, arch_sh2_up},
+
+/* 0010nnnnmmmm1110 mulu.w <REG_M>,<REG_N>*/{"mulu.w",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_E}, arch_sh1_up},
+/* 0010nnnnmmmm1110 mulu <REG_M>,<REG_N>*/{"mulu",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_E}, arch_sh1_up},
+
+/* 0110nnnnmmmm1011 neg <REG_M>,<REG_N> */{"neg",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_B}, arch_sh1_up},
+
+/* 0110nnnnmmmm1010 negc <REG_M>,<REG_N>*/{"negc",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_A}, arch_sh1_up},
+
+/* 0000000000001001 nop                 */{"nop",{0},{HEX_0,HEX_0,HEX_0,HEX_9}, arch_sh1_up},
+
+/* 0110nnnnmmmm0111 not <REG_M>,<REG_N> */{"not",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_7}, arch_sh1_up},
+/* 0000nnnn10010011 ocbi @<REG_N>       */{"ocbi",{A_IND_N},{HEX_0,REG_N,HEX_9,HEX_3}, arch_sh4_nommu_nofpu_up},
+
+/* 0000nnnn10100011 ocbp @<REG_N>       */{"ocbp",{A_IND_N},{HEX_0,REG_N,HEX_A,HEX_3}, arch_sh4_nommu_nofpu_up},
+
+/* 0000nnnn10110011 ocbwb @<REG_N>      */{"ocbwb",{A_IND_N},{HEX_0,REG_N,HEX_B,HEX_3}, arch_sh4_nommu_nofpu_up},
+
+
+/* 11001011i8*1.... or #<imm>,R0        */{"or",{A_IMM,A_R0},{HEX_C,HEX_B,IMM0_8}, arch_sh1_up},
+
+/* 0010nnnnmmmm1011 or <REG_M>,<REG_N>  */{"or",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_B}, arch_sh1_up},
+
+/* 11001111i8*1.... or.b #<imm>,@(R0,GBR)*/{"or.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_F,IMM0_8}, arch_sh1_up},
+
+/* 0000nnnn10000011 pref @<REG_N>       */{"pref",{A_IND_N},{HEX_0,REG_N,HEX_8,HEX_3}, arch_sh4_nommu_nofpu_up | arch_sh2a_nofpu_up},
+
+/* 0000nnnn11010011 prefi @<REG_N>      */{"prefi",{A_IND_N},{HEX_0,REG_N,HEX_D,HEX_3}, arch_sh4a_nofp_up},
+
+/* 0100nnnn00100100 rotcl <REG_N>       */{"rotcl",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_4}, arch_sh1_up},
+
+/* 0100nnnn00100101 rotcr <REG_N>       */{"rotcr",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_5}, arch_sh1_up},
+
+/* 0100nnnn00000100 rotl <REG_N>        */{"rotl",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_4}, arch_sh1_up},
+
+/* 0100nnnn00000101 rotr <REG_N>        */{"rotr",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_5}, arch_sh1_up},
+
+/* 0000000000101011 rte                 */{"rte",{0},{HEX_0,HEX_0,HEX_2,HEX_B}, arch_sh1_up},
+
+/* 0000000000001011 rts                 */{"rts",{0},{HEX_0,HEX_0,HEX_0,HEX_B}, arch_sh1_up},
+
+/* 0000000010011000 setdmx              */{"setdmx",{0},{HEX_0,HEX_0,HEX_9,HEX_8}, arch_sh4al_dsp_up},
+/* 0000000011001000 setdmy              */{"setdmy",{0},{HEX_0,HEX_0,HEX_C,HEX_8}, arch_sh4al_dsp_up},
+
+/* 0000000001011000 sets                */{"sets",{0},{HEX_0,HEX_0,HEX_5,HEX_8}, arch_sh1_up},
+/* 0000000000011000 sett                */{"sett",{0},{HEX_0,HEX_0,HEX_1,HEX_8}, arch_sh1_up},
+
+/* 0100nnnn00010100 setrc <REG_N>       */{"setrc",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_4}, arch_sh_dsp_up},
+
+/* 10000010i8*1.... setrc #<imm>        */{"setrc",{A_IMM},{HEX_8,HEX_2,IMM0_8}, arch_sh_dsp_up},
+
+/* repeat start end <REG_N>            */{"repeat",{A_DISP_PC,A_DISP_PC,A_REG_N},{REPEAT,REG_N,HEX_1,HEX_4}, arch_sh_dsp_up},
+
+/* repeat start end #<imm>             */{"repeat",{A_DISP_PC,A_DISP_PC,A_IMM},{REPEAT,HEX_2,IMM0_8,HEX_8}, arch_sh_dsp_up},
+
+/* 0100nnnnmmmm1100 shad <REG_M>,<REG_N>*/{"shad",{ A_REG_M,A_REG_N},{HEX_4,REG_N,REG_M,HEX_C}, arch_sh3_nommu_up | arch_sh2a_nofpu_up},
+
+/* 0100nnnnmmmm1101 shld <REG_M>,<REG_N>*/{"shld",{ A_REG_M,A_REG_N},{HEX_4,REG_N,REG_M,HEX_D}, arch_sh3_nommu_up | arch_sh2a_nofpu_up},
+
+/* 0100nnnn00100000 shal <REG_N>        */{"shal",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_0}, arch_sh1_up},
+
+/* 0100nnnn00100001 shar <REG_N>        */{"shar",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_1}, arch_sh1_up},
+
+/* 0100nnnn00000000 shll <REG_N>        */{"shll",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_0}, arch_sh1_up},
+
+/* 0100nnnn00101000 shll16 <REG_N>      */{"shll16",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_8}, arch_sh1_up},
+
+/* 0100nnnn00001000 shll2 <REG_N>       */{"shll2",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_8}, arch_sh1_up},
+
+/* 0100nnnn00011000 shll8 <REG_N>       */{"shll8",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_8}, arch_sh1_up},
+
+/* 0100nnnn00000001 shlr <REG_N>        */{"shlr",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_1}, arch_sh1_up},
+
+/* 0100nnnn00101001 shlr16 <REG_N>      */{"shlr16",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_9}, arch_sh1_up},
+
+/* 0100nnnn00001001 shlr2 <REG_N>       */{"shlr2",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_9}, arch_sh1_up},
+
+/* 0100nnnn00011001 shlr8 <REG_N>       */{"shlr8",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_9}, arch_sh1_up},
+
+/* 0000000000011011 sleep               */{"sleep",{0},{HEX_0,HEX_0,HEX_1,HEX_B}, arch_sh1_up},
+
+/* 0000nnnn00000010 stc SR,<REG_N>      */{"stc",{A_SR,A_REG_N},{HEX_0,REG_N,HEX_0,HEX_2}, arch_sh1_up},
+
+/* 0000nnnn00010010 stc GBR,<REG_N>     */{"stc",{A_GBR,A_REG_N},{HEX_0,REG_N,HEX_1,HEX_2}, arch_sh1_up},
+
+/* 0000nnnn00100010 stc VBR,<REG_N>     */{"stc",{A_VBR,A_REG_N},{HEX_0,REG_N,HEX_2,HEX_2}, arch_sh1_up},
+
+/* 0000nnnn01010010 stc MOD,<REG_N>     */{"stc",{A_MOD,A_REG_N},{HEX_0,REG_N,HEX_5,HEX_2}, arch_sh_dsp_up},
+
+/* 0000nnnn01110010 stc RE,<REG_N>     */{"stc",{A_RE,A_REG_N},{HEX_0,REG_N,HEX_7,HEX_2}, arch_sh_dsp_up},
+
+/* 0000nnnn01100010 stc RS,<REG_N>     */{"stc",{A_RS,A_REG_N},{HEX_0,REG_N,HEX_6,HEX_2}, arch_sh_dsp_up},
+
+/* 0000nnnn00110010 stc SSR,<REG_N>     */{"stc",{A_SSR,A_REG_N},{HEX_0,REG_N,HEX_3,HEX_2}, arch_sh3_nommu_up},
+
+/* 0000nnnn01000010 stc SPC,<REG_N>     */{"stc",{A_SPC,A_REG_N},{HEX_0,REG_N,HEX_4,HEX_2}, arch_sh3_nommu_up},
+
+/* 0000nnnn00111010 stc SGR,<REG_N>     */{"stc",{A_SGR,A_REG_N},{HEX_0,REG_N,HEX_3,HEX_A}, arch_sh4_nommu_nofpu_up},
+
+/* 0000nnnn11111010 stc DBR,<REG_N>     */{"stc",{A_DBR,A_REG_N},{HEX_0,REG_N,HEX_F,HEX_A}, arch_sh4_nommu_nofpu_up},
+
+/* 0000nnnn1xxx0010 stc Rn_BANK,<REG_N> */{"stc",{A_REG_B,A_REG_N},{HEX_0,REG_N,REG_B,HEX_2}, arch_sh3_nommu_up},
+
+/* 0000nnnn01001010 stc TBR,<REG_N> */ {"stc",{A_TBR,A_REG_N},{HEX_0,REG_N,HEX_4,HEX_A}, arch_sh2a_nofpu_up},
+
+/* 0100nnnn00000011 stc.l SR,@-<REG_N>  */{"stc.l",{A_SR,A_DEC_N},{HEX_4,REG_N,HEX_0,HEX_3}, arch_sh1_up},
+
+/* 0100nnnn00100011 stc.l VBR,@-<REG_N> */{"stc.l",{A_VBR,A_DEC_N},{HEX_4,REG_N,HEX_2,HEX_3}, arch_sh1_up},
+
+/* 0100nnnn01010011 stc.l MOD,@-<REG_N> */{"stc.l",{A_MOD,A_DEC_N},{HEX_4,REG_N,HEX_5,HEX_3}, arch_sh_dsp_up},
+
+/* 0100nnnn01110011 stc.l RE,@-<REG_N>  */{"stc.l",{A_RE,A_DEC_N},{HEX_4,REG_N,HEX_7,HEX_3}, arch_sh_dsp_up},
+
+/* 0100nnnn01100011 stc.l RS,@-<REG_N>  */{"stc.l",{A_RS,A_DEC_N},{HEX_4,REG_N,HEX_6,HEX_3}, arch_sh_dsp_up},
+
+/* 0100nnnn00110011 stc.l SSR,@-<REG_N> */{"stc.l",{A_SSR,A_DEC_N},{HEX_4,REG_N,HEX_3,HEX_3}, arch_sh3_nommu_up},
+
+/* 0100nnnn01000011 stc.l SPC,@-<REG_N> */{"stc.l",{A_SPC,A_DEC_N},{HEX_4,REG_N,HEX_4,HEX_3}, arch_sh3_nommu_up},
+
+/* 0100nnnn00010011 stc.l GBR,@-<REG_N> */{"stc.l",{A_GBR,A_DEC_N},{HEX_4,REG_N,HEX_1,HEX_3}, arch_sh1_up},
+
+/* 0100nnnn00110010 stc.l SGR,@-<REG_N> */{"stc.l",{A_SGR,A_DEC_N},{HEX_4,REG_N,HEX_3,HEX_2}, arch_sh4_nommu_nofpu_up},
+
+/* 0100nnnn11110010 stc.l DBR,@-<REG_N> */{"stc.l",{A_DBR,A_DEC_N},{HEX_4,REG_N,HEX_F,HEX_2}, arch_sh4_nommu_nofpu_up},
+
+/* 0100nnnn1xxx0011 stc.l Rn_BANK,@-<REG_N> */{"stc.l",{A_REG_B,A_DEC_N},{HEX_4,REG_N,REG_B,HEX_3}, arch_sh3_nommu_up},
+
+/* 0000nnnn00001010 sts MACH,<REG_N>    */{"sts",{A_MACH,A_REG_N},{HEX_0,REG_N,HEX_0,HEX_A}, arch_sh1_up},
+
+/* 0000nnnn00011010 sts MACL,<REG_N>    */{"sts",{A_MACL,A_REG_N},{HEX_0,REG_N,HEX_1,HEX_A}, arch_sh1_up},
+
+/* 0000nnnn00101010 sts PR,<REG_N>      */{"sts",{A_PR,A_REG_N},{HEX_0,REG_N,HEX_2,HEX_A}, arch_sh1_up},
+
+/* 0000nnnn01101010 sts DSR,<REG_N>    */{"sts",{A_DSR,A_REG_N},{HEX_0,REG_N,HEX_6,HEX_A}, arch_sh_dsp_up},
+
+/* 0000nnnn01111010 sts A0,<REG_N>     */{"sts",{A_A0,A_REG_N},{HEX_0,REG_N,HEX_7,HEX_A}, arch_sh_dsp_up},
+
+/* 0000nnnn10001010 sts X0,<REG_N>     */{"sts",{A_X0,A_REG_N},{HEX_0,REG_N,HEX_8,HEX_A}, arch_sh_dsp_up},
+
+/* 0000nnnn10011010 sts X1,<REG_N>     */{"sts",{A_X1,A_REG_N},{HEX_0,REG_N,HEX_9,HEX_A}, arch_sh_dsp_up},
+
+/* 0000nnnn10101010 sts Y0,<REG_N>     */{"sts",{A_Y0,A_REG_N},{HEX_0,REG_N,HEX_A,HEX_A}, arch_sh_dsp_up},
+
+/* 0000nnnn10111010 sts Y1,<REG_N>     */{"sts",{A_Y1,A_REG_N},{HEX_0,REG_N,HEX_B,HEX_A}, arch_sh_dsp_up},
+
+/* 0000nnnn01011010 sts FPUL,<REG_N>    */{"sts",{FPUL_M,A_REG_N},{HEX_0,REG_N,HEX_5,HEX_A}, arch_sh2e_up},
+  
+/* 0000nnnn01101010 sts FPSCR,<REG_N>   */{"sts",{FPSCR_M,A_REG_N},{HEX_0,REG_N,HEX_6,HEX_A}, arch_sh2e_up},
+
+/* 0100nnnn00000010 sts.l MACH,@-<REG_N>*/{"sts.l",{A_MACH,A_DEC_N},{HEX_4,REG_N,HEX_0,HEX_2}, arch_sh1_up},
+
+/* 0100nnnn00010010 sts.l MACL,@-<REG_N>*/{"sts.l",{A_MACL,A_DEC_N},{HEX_4,REG_N,HEX_1,HEX_2}, arch_sh1_up},
+
+/* 0100nnnn00100010 sts.l PR,@-<REG_N>  */{"sts.l",{A_PR,A_DEC_N},{HEX_4,REG_N,HEX_2,HEX_2}, arch_sh1_up},
+
+/* 0100nnnn01100110 sts.l DSR,@-<REG_N>        */{"sts.l",{A_DSR,A_DEC_N},{HEX_4,REG_N,HEX_6,HEX_2}, arch_sh_dsp_up},
+
+/* 0100nnnn01110110 sts.l A0,@-<REG_N> */{"sts.l",{A_A0,A_DEC_N},{HEX_4,REG_N,HEX_7,HEX_2}, arch_sh_dsp_up},
+
+/* 0100nnnn10000110 sts.l X0,@-<REG_N> */{"sts.l",{A_X0,A_DEC_N},{HEX_4,REG_N,HEX_8,HEX_2}, arch_sh_dsp_up},
+
+/* 0100nnnn10010110 sts.l X1,@-<REG_N> */{"sts.l",{A_X1,A_DEC_N},{HEX_4,REG_N,HEX_9,HEX_2}, arch_sh_dsp_up},
+
+/* 0100nnnn10100110 sts.l Y0,@-<REG_N> */{"sts.l",{A_Y0,A_DEC_N},{HEX_4,REG_N,HEX_A,HEX_2}, arch_sh_dsp_up},
+
+/* 0100nnnn10110110 sts.l Y1,@-<REG_N> */{"sts.l",{A_Y1,A_DEC_N},{HEX_4,REG_N,HEX_B,HEX_2}, arch_sh_dsp_up},
+
+/* 0100nnnn01010010 sts.l FPUL,@-<REG_N>*/{"sts.l",{FPUL_M,A_DEC_N},{HEX_4,REG_N,HEX_5,HEX_2}, arch_sh2e_up},
+  
+/* 0100nnnn01100010 sts.l FPSCR,@-<REG_N>*/{"sts.l",{FPSCR_M,A_DEC_N},{HEX_4,REG_N,HEX_6,HEX_2}, arch_sh2e_up},
+
+/* 0011nnnnmmmm1000 sub <REG_M>,<REG_N> */{"sub",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_8}, arch_sh1_up},
+
+/* 0011nnnnmmmm1010 subc <REG_M>,<REG_N>*/{"subc",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_A}, arch_sh1_up},
+
+/* 0011nnnnmmmm1011 subv <REG_M>,<REG_N>*/{"subv",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_B}, arch_sh1_up},
+
+/* 0110nnnnmmmm1000 swap.b <REG_M>,<REG_N>*/{"swap.b",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_8}, arch_sh1_up},
+
+/* 0110nnnnmmmm1001 swap.w <REG_M>,<REG_N>*/{"swap.w",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_9}, arch_sh1_up},
+
+/* 0000000010101011 synco               */{"synco",{0},{HEX_0,HEX_0,HEX_A,HEX_B}, arch_sh4a_nofp_up},
+
+/* 0100nnnn00011011 tas.b @<REG_N>      */{"tas.b",{A_IND_N},{HEX_4,REG_N,HEX_1,HEX_B}, arch_sh1_up},
+
+/* 11000011i8*1.... trapa #<imm>        */{"trapa",{A_IMM},{HEX_C,HEX_3,IMM0_8}, arch_sh1_up},
+
+/* 11001000i8*1.... tst #<imm>,R0       */{"tst",{A_IMM,A_R0},{HEX_C,HEX_8,IMM0_8}, arch_sh1_up},
+
+/* 0010nnnnmmmm1000 tst <REG_M>,<REG_N> */{"tst",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_8}, arch_sh1_up},
+
+/* 11001100i8*1.... tst.b #<imm>,@(R0,GBR)*/{"tst.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_C,IMM0_8}, arch_sh1_up},
+
+/* 11001010i8*1.... xor #<imm>,R0       */{"xor",{A_IMM,A_R0},{HEX_C,HEX_A,IMM0_8}, arch_sh1_up},
+
+/* 0010nnnnmmmm1010 xor <REG_M>,<REG_N> */{"xor",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_A}, arch_sh1_up},
+
+/* 11001110i8*1.... xor.b #<imm>,@(R0,GBR)*/{"xor.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_E,IMM0_8}, arch_sh1_up},
+
+/* 0010nnnnmmmm1101 xtrct <REG_M>,<REG_N>*/{"xtrct",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_D}, arch_sh1_up},
+
+/* 0000nnnnmmmm0111 mul.l <REG_M>,<REG_N>*/{"mul.l",{ A_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_7}, arch_sh1_up},
+
+/* 0100nnnn00010000 dt <REG_N>          */{"dt",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_0}, arch_sh2_up},
+
+/* 0011nnnnmmmm1101 dmuls.l <REG_M>,<REG_N>*/{"dmuls.l",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_D}, arch_sh2_up},
+
+/* 0011nnnnmmmm0101 dmulu.l <REG_M>,<REG_N>*/{"dmulu.l",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_5}, arch_sh2_up},
+
+/* 0000nnnnmmmm1111 mac.l @<REG_M>+,@<REG_N>+*/{"mac.l",{A_INC_M,A_INC_N},{HEX_0,REG_N,REG_M,HEX_F}, arch_sh2_up},
+
+/* 0000nnnn00100011 braf <REG_N>       */{"braf",{A_REG_N},{HEX_0,REG_N,HEX_2,HEX_3}, arch_sh2_up},
+
+/* 0000nnnn00000011 bsrf <REG_N>       */{"bsrf",{A_REG_N},{HEX_0,REG_N,HEX_0,HEX_3}, arch_sh2_up},
+
+/* 111101nnmmmm0000 movs.w @-<REG_N>,<DSP_REG_M> */   {"movs.w",{A_DEC_N,DSP_REG_M},{HEX_F,SDT_REG_N,REG_M,HEX_0}, arch_sh_dsp_up},
+
+/* 111101nnmmmm0001 movs.w @<REG_N>,<DSP_REG_M> */    {"movs.w",{A_IND_N,DSP_REG_M},{HEX_F,SDT_REG_N,REG_M,HEX_4}, arch_sh_dsp_up},
+
+/* 111101nnmmmm0010 movs.w @<REG_N>+,<DSP_REG_M> */   {"movs.w",{A_INC_N,DSP_REG_M},{HEX_F,SDT_REG_N,REG_M,HEX_8}, arch_sh_dsp_up},
+
+/* 111101nnmmmm0011 movs.w @<REG_N>+r8,<DSP_REG_M> */ {"movs.w",{AS_PMOD_N,DSP_REG_M},{HEX_F,SDT_REG_N,REG_M,HEX_C}, arch_sh_dsp_up},
+
+/* 111101nnmmmm0100 movs.w <DSP_REG_M>,@-<REG_N> */   {"movs.w",{DSP_REG_M,A_DEC_N},{HEX_F,SDT_REG_N,REG_M,HEX_1}, arch_sh_dsp_up},
+
+/* 111101nnmmmm0101 movs.w <DSP_REG_M>,@<REG_N> */    {"movs.w",{DSP_REG_M,A_IND_N},{HEX_F,SDT_REG_N,REG_M,HEX_5}, arch_sh_dsp_up},
+
+/* 111101nnmmmm0110 movs.w <DSP_REG_M>,@<REG_N>+ */   {"movs.w",{DSP_REG_M,A_INC_N},{HEX_F,SDT_REG_N,REG_M,HEX_9}, arch_sh_dsp_up},
+
+/* 111101nnmmmm0111 movs.w <DSP_REG_M>,@<REG_N>+r8 */ {"movs.w",{DSP_REG_M,AS_PMOD_N},{HEX_F,SDT_REG_N,REG_M,HEX_D}, arch_sh_dsp_up},
+
+/* 111101nnmmmm1000 movs.l @-<REG_N>,<DSP_REG_M> */   {"movs.l",{A_DEC_N,DSP_REG_M},{HEX_F,SDT_REG_N,REG_M,HEX_2}, arch_sh_dsp_up},
+
+/* 111101nnmmmm1001 movs.l @<REG_N>,<DSP_REG_M> */    {"movs.l",{A_IND_N,DSP_REG_M},{HEX_F,SDT_REG_N,REG_M,HEX_6}, arch_sh_dsp_up},
+
+/* 111101nnmmmm1010 movs.l @<REG_N>+,<DSP_REG_M> */   {"movs.l",{A_INC_N,DSP_REG_M},{HEX_F,SDT_REG_N,REG_M,HEX_A}, arch_sh_dsp_up},
+
+/* 111101nnmmmm1011 movs.l @<REG_N>+r8,<DSP_REG_M> */ {"movs.l",{AS_PMOD_N,DSP_REG_M},{HEX_F,SDT_REG_N,REG_M,HEX_E}, arch_sh_dsp_up},
+
+/* 111101nnmmmm1100 movs.l <DSP_REG_M>,@-<REG_N> */   {"movs.l",{DSP_REG_M,A_DEC_N},{HEX_F,SDT_REG_N,REG_M,HEX_3}, arch_sh_dsp_up},
+
+/* 111101nnmmmm1101 movs.l <DSP_REG_M>,@<REG_N> */    {"movs.l",{DSP_REG_M,A_IND_N},{HEX_F,SDT_REG_N,REG_M,HEX_7}, arch_sh_dsp_up},
+
+/* 111101nnmmmm1110 movs.l <DSP_REG_M>,@<REG_N>+ */   {"movs.l",{DSP_REG_M,A_INC_N},{HEX_F,SDT_REG_N,REG_M,HEX_B}, arch_sh_dsp_up},
+
+/* 111101nnmmmm1111 movs.l <DSP_REG_M>,@<REG_N>+r8 */ {"movs.l",{DSP_REG_M,AS_PMOD_N},{HEX_F,SDT_REG_N,REG_M,HEX_F}, arch_sh_dsp_up},
+
+/* 0*0*0*00** nopx */ {"nopx",{0},{PPI,NOPX}, arch_sh_dsp_up},
+/* *0*0*0**00 nopy */ {"nopy",{0},{PPI,NOPY}, arch_sh_dsp_up},
+/* n*m*0*01** movx.w @<REG_N>,<DSP_REG_X> */    {"movx.w",{AX_IND_N,DSP_REG_X},{PPI,MOVX,HEX_1}, arch_sh_dsp_up},
+/* n*m*0*10** movx.w @<REG_N>+,<DSP_REG_X> */   {"movx.w",{AX_INC_N,DSP_REG_X},{PPI,MOVX,HEX_2}, arch_sh_dsp_up},
+/* n*m*0*11** movx.w @<REG_N>+r8,<DSP_REG_X> */ {"movx.w",{AX_PMOD_N,DSP_REG_X},{PPI,MOVX,HEX_3}, arch_sh_dsp_up},
+/* n*m*1*01** movx.w <DSP_REG_M>,@<REG_N> */    {"movx.w",{DSP_REG_A_M,AX_IND_N},{PPI,MOVX,HEX_9}, arch_sh_dsp_up},
+/* n*m*1*10** movx.w <DSP_REG_M>,@<REG_N>+ */   {"movx.w",{DSP_REG_A_M,AX_INC_N},{PPI,MOVX,HEX_A}, arch_sh_dsp_up},
+/* n*m*1*11** movx.w <DSP_REG_M>,@<REG_N>+r8 */ {"movx.w",{DSP_REG_A_M,AX_PMOD_N},{PPI,MOVX,HEX_B}, arch_sh_dsp_up},
+
+/* nnmm000100 movx.w @<REG_Axy>,<DSP_REG_XY> */ {"movx.w",{AXY_IND_N,DSP_REG_XY},{PPI,MOVX_NOPY,HEX_0,HEX_4}, arch_sh4al_dsp_up},
+/* nnmm001000 movx.w @<REG_Axy>+,<DSP_REG_XY> */{"movx.w",{AXY_INC_N,DSP_REG_XY},{PPI,MOVX_NOPY,HEX_0,HEX_8}, arch_sh4al_dsp_up},
+/* nnmm001100 movx.w @<REG_Axy>+r8,<DSP_REG_XY> */{"movx.w",{AXY_PMOD_N,DSP_REG_XY},{PPI,MOVX_NOPY,HEX_0,HEX_C}, arch_sh4al_dsp_up},
+/* nnmm100100 movx.w <DSP_REG_AX>,@<REG_Axy> */ {"movx.w",{DSP_REG_AX,AXY_IND_N},{PPI,MOVX_NOPY,HEX_2,HEX_4}, arch_sh4al_dsp_up},
+/* nnmm101000 movx.w <DSP_REG_AX>,@<REG_Axy>+ */{"movx.w",{DSP_REG_AX,AXY_INC_N},{PPI,MOVX_NOPY,HEX_2,HEX_8}, arch_sh4al_dsp_up},
+/* nnmm101100 movx.w <DSP_REG_AX>,@<REG_Axy>+r8 */{"movx.w",{DSP_REG_AX,AXY_PMOD_N},{PPI,MOVX_NOPY,HEX_2,HEX_C}, arch_sh4al_dsp_up},
+
+/* nnmm010100 movx.l @<REG_Axy>,<DSP_REG_XY> */ {"movx.l",{AXY_IND_N,DSP_REG_XY},{PPI,MOVX_NOPY,HEX_1,HEX_4}, arch_sh4al_dsp_up},
+/* nnmm011000 movx.l @<REG_Axy>+,<DSP_REG_XY> */{"movx.l",{AXY_INC_N,DSP_REG_XY},{PPI,MOVX_NOPY,HEX_1,HEX_8}, arch_sh4al_dsp_up},
+/* nnmm011100 movx.l @<REG_Axy>+r8,<DSP_REG_XY> */{"movx.l",{AXY_PMOD_N,DSP_REG_XY},{PPI,MOVX_NOPY,HEX_1,HEX_C}, arch_sh4al_dsp_up},
+/* nnmm110100 movx.l <DSP_REG_AX>,@<REG_Axy> */ {"movx.l",{DSP_REG_AX,AXY_IND_N},{PPI,MOVX_NOPY,HEX_3,HEX_4}, arch_sh4al_dsp_up},
+/* nnmm111000 movx.l <DSP_REG_AX>,@<REG_Axy>+ */{"movx.l",{DSP_REG_AX,AXY_INC_N},{PPI,MOVX_NOPY,HEX_3,HEX_8}, arch_sh4al_dsp_up},
+/* nnmm111100 movx.l <DSP_REG_AX>,@<REG_Axy>+r8 */{"movx.l",{DSP_REG_AX,AXY_PMOD_N},{PPI,MOVX_NOPY,HEX_3,HEX_C}, arch_sh4al_dsp_up},
+
+/* *n*m*0**01 movy.w @<REG_N>,<DSP_REG_Y> */    {"movy.w",{AY_IND_N,DSP_REG_Y},{PPI,MOVY,HEX_1}, arch_sh_dsp_up},
+/* *n*m*0**10 movy.w @<REG_N>+,<DSP_REG_Y> */   {"movy.w",{AY_INC_N,DSP_REG_Y},{PPI,MOVY,HEX_2}, arch_sh_dsp_up},
+/* *n*m*0**11 movy.w @<REG_N>+r9,<DSP_REG_Y> */ {"movy.w",{AY_PMOD_N,DSP_REG_Y},{PPI,MOVY,HEX_3}, arch_sh_dsp_up},
+/* *n*m*1**01 movy.w <DSP_REG_M>,@<REG_N> */    {"movy.w",{DSP_REG_A_M,AY_IND_N},{PPI,MOVY,HEX_9}, arch_sh_dsp_up},
+/* *n*m*1**10 movy.w <DSP_REG_M>,@<REG_N>+ */   {"movy.w",{DSP_REG_A_M,AY_INC_N},{PPI,MOVY,HEX_A}, arch_sh_dsp_up},
+/* *n*m*1**11 movy.w <DSP_REG_M>,@<REG_N>+r9 */ {"movy.w",{DSP_REG_A_M,AY_PMOD_N},{PPI,MOVY,HEX_B}, arch_sh_dsp_up},
+
+/* nnmm000001 movy.w @<REG_Ayx>,<DSP_REG_YX> */ {"movy.w",{AYX_IND_N,DSP_REG_YX},{PPI,MOVY_NOPX,HEX_0,HEX_1}, arch_sh4al_dsp_up},
+/* nnmm000010 movy.w @<REG_Ayx>+,<DSP_REG_YX> */{"movy.w",{AYX_INC_N,DSP_REG_YX},{PPI,MOVY_NOPX,HEX_0,HEX_2}, arch_sh4al_dsp_up},
+/* nnmm000011 movy.w @<REG_Ayx>+r8,<DSP_REG_YX> */{"movy.w",{AYX_PMOD_N,DSP_REG_YX},{PPI,MOVY_NOPX,HEX_0,HEX_3}, arch_sh4al_dsp_up},
+/* nnmm010001 movy.w <DSP_REG_AY>,@<REG_Ayx> */ {"movy.w",{DSP_REG_AY,AYX_IND_N},{PPI,MOVY_NOPX,HEX_1,HEX_1}, arch_sh4al_dsp_up},
+/* nnmm010010 movy.w <DSP_REG_AY>,@<REG_Ayx>+ */{"movy.w",{DSP_REG_AY,AYX_INC_N},{PPI,MOVY_NOPX,HEX_1,HEX_2}, arch_sh4al_dsp_up},
+/* nnmm010011 movy.w <DSP_REG_AY>,@<REG_Ayx>+r8 */{"movy.w",{DSP_REG_AY,AYX_PMOD_N},{PPI,MOVY_NOPX,HEX_1,HEX_3}, arch_sh4al_dsp_up},
+
+/* nnmm100001 movy.l @<REG_Ayx>,<DSP_REG_YX> */ {"movy.l",{AYX_IND_N,DSP_REG_YX},{PPI,MOVY_NOPX,HEX_2,HEX_1}, arch_sh4al_dsp_up},
+/* nnmm100010 movy.l @<REG_Ayx>+,<DSP_REG_YX> */{"movy.l",{AYX_INC_N,DSP_REG_YX},{PPI,MOVY_NOPX,HEX_2,HEX_2}, arch_sh4al_dsp_up},
+/* nnmm100011 movy.l @<REG_Ayx>+r8,<DSP_REG_YX> */{"movy.l",{AYX_PMOD_N,DSP_REG_YX},{PPI,MOVY_NOPX,HEX_2,HEX_3}, arch_sh4al_dsp_up},
+/* nnmm110001 movy.l <DSP_REG_AY>,@<REG_Ayx> */ {"movy.l",{DSP_REG_AY,AYX_IND_N},{PPI,MOVY_NOPX,HEX_3,HEX_1}, arch_sh4al_dsp_up},
+/* nnmm110010 movy.l <DSP_REG_AY>,@<REG_Ayx>+ */{"movy.l",{DSP_REG_AY,AYX_INC_N},{PPI,MOVY_NOPX,HEX_3,HEX_2}, arch_sh4al_dsp_up},
+/* nnmm110011 movy.l <DSP_REG_AY>,@<REG_Ayx>+r8 */{"movy.l",{DSP_REG_AY,AYX_PMOD_N},{PPI,MOVY_NOPX,HEX_3,HEX_3}, arch_sh4al_dsp_up},
+
+/* 01aaeeffxxyyggnn pmuls Se,Sf,Dg */ {"pmuls",{DSP_REG_E,DSP_REG_F,DSP_REG_G},{PPI,PMUL}, arch_sh_dsp_up},
+/* 10100000xxyynnnn psubc <DSP_REG_X>,<DSP_REG_Y>,<DSP_REG_N> */
+{"psubc",{DSP_REG_X,DSP_REG_Y,DSP_REG_N},{PPI,PPI3,HEX_A,HEX_0}, arch_sh_dsp_up},
+/* 10110000xxyynnnn paddc <DSP_REG_X>,<DSP_REG_Y>,<DSP_REG_N> */
+{"paddc",{DSP_REG_X,DSP_REG_Y,DSP_REG_N},{PPI,PPI3,HEX_B,HEX_0}, arch_sh_dsp_up},
+/* 10000100xxyynnnn pcmp <DSP_REG_X>,<DSP_REG_Y> */
+{"pcmp", {DSP_REG_X,DSP_REG_Y},{PPI,PPI3,HEX_8,HEX_4}, arch_sh_dsp_up},
+/* 10100100xxyynnnn pwsb <DSP_REG_X>,<DSP_REG_Y>,<DSP_REG_N> */
+{"pwsb", {DSP_REG_X,DSP_REG_Y,DSP_REG_N},{PPI,PPI3,HEX_A,HEX_4}, arch_sh_dsp_up},
+/* 10110100xxyynnnn pwad <DSP_REG_X>,<DSP_REG_Y>,<DSP_REG_N> */
+{"pwad", {DSP_REG_X,DSP_REG_Y,DSP_REG_N},{PPI,PPI3,HEX_B,HEX_4}, arch_sh_dsp_up},
+/* 10001000xxyynnnn pabs <DSP_REG_X>,<DSP_REG_N> */
+{"pabs", {DSP_REG_X,DSP_REG_N},{PPI,PPI3NC,HEX_8,HEX_8}, arch_sh_dsp_up},
+/* 1000100!xx01nnnn pabs <DSP_REG_X>,<DSP_REG_N> */
+{"pabs", {DSP_REG_X,DSP_REG_N},{PPI,PPIC,HEX_8,HEX_9,HEX_1}, arch_sh4al_dsp_up},
+/* 10101000xxyynnnn pabs <DSP_REG_Y>,<DSP_REG_N> */
+{"pabs", {DSP_REG_Y,DSP_REG_N},{PPI,PPI3NC,HEX_A,HEX_8}, arch_sh_dsp_up},
+/* 1010100!01yynnnn pabs <DSP_REG_Y>,<DSP_REG_N> */
+{"pabs", {DSP_REG_Y,DSP_REG_N},{PPI,PPIC,HEX_A,HEX_9,HEX_4}, arch_sh4al_dsp_up},
+/* 10011000xxyynnnn prnd <DSP_REG_X>,<DSP_REG_N> */
+{"prnd", {DSP_REG_X,DSP_REG_N},{PPI,PPI3NC,HEX_9,HEX_8}, arch_sh_dsp_up},
+/* 1001100!xx01nnnn prnd <DSP_REG_X>,<DSP_REG_N> */
+{"prnd", {DSP_REG_X,DSP_REG_N},{PPI,PPIC,HEX_9,HEX_9,HEX_1}, arch_sh4al_dsp_up},
+/* 10111000xxyynnnn prnd <DSP_REG_Y>,<DSP_REG_N> */
+{"prnd", {DSP_REG_Y,DSP_REG_N},{PPI,PPI3NC,HEX_B,HEX_8}, arch_sh_dsp_up},
+/* 1011100!01yynnnn prnd <DSP_REG_Y>,<DSP_REG_N> */
+{"prnd", {DSP_REG_Y,DSP_REG_N},{PPI,PPIC,HEX_B,HEX_9,HEX_4}, arch_sh4al_dsp_up},
+
+{"dct",{0},{PPI,PDC,HEX_1}, arch_sh_dsp_up},
+{"dcf",{0},{PPI,PDC,HEX_2}, arch_sh_dsp_up},
+
+/* 10000001xxyynnnn pshl <DSP_REG_X>,<DSP_REG_Y>,<DSP_REG_N> */
+{"pshl", {DSP_REG_X,DSP_REG_Y,DSP_REG_N},{PPI,PPIC,HEX_8,HEX_1}, arch_sh_dsp_up},
+/* 00000iiiiiiinnnn pshl #<imm>,<DSP_REG_N> */ {"pshl",{A_IMM,DSP_REG_N},{PPI,PSH,HEX_0}, arch_sh_dsp_up},
+/* 10010001xxyynnnn psha <DSP_REG_X>,<DSP_REG_Y>,<DSP_REG_N> */
+{"psha", {DSP_REG_X,DSP_REG_Y,DSP_REG_N},{PPI,PPIC,HEX_9,HEX_1}, arch_sh_dsp_up},
+/* 00010iiiiiiinnnn psha #<imm>,<DSP_REG_N> */ {"psha",{A_IMM,DSP_REG_N},{PPI,PSH,HEX_1}, arch_sh_dsp_up},
+/* 10100001xxyynnnn psub <DSP_REG_X>,<DSP_REG_Y>,<DSP_REG_N> */
+{"psub", {DSP_REG_X,DSP_REG_Y,DSP_REG_N},{PPI,PPIC,HEX_A,HEX_1}, arch_sh_dsp_up},
+/* 10000101xxyynnnn psub <DSP_REG_Y>,<DSP_REG_X>,<DSP_REG_N> */
+{"psub", {DSP_REG_Y,DSP_REG_X,DSP_REG_N},{PPI,PPIC,HEX_8,HEX_5}, arch_sh4al_dsp_up},
+/* 10110001xxyynnnn padd <DSP_REG_X>,<DSP_REG_Y>,<DSP_REG_N> */
+{"padd", {DSP_REG_X,DSP_REG_Y,DSP_REG_N},{PPI,PPIC,HEX_B,HEX_1}, arch_sh_dsp_up},
+/* 10010101xxyynnnn pand <DSP_REG_X>,<DSP_REG_Y>,<DSP_REG_N> */
+{"pand", {DSP_REG_X,DSP_REG_Y,DSP_REG_N},{PPI,PPIC,HEX_9,HEX_5}, arch_sh_dsp_up},
+/* 10100101xxyynnnn pxor <DSP_REG_X>,<DSP_REG_Y>,<DSP_REG_N> */
+{"pxor", {DSP_REG_X,DSP_REG_Y,DSP_REG_N},{PPI,PPIC,HEX_A,HEX_5}, arch_sh_dsp_up},
+/* 10110101xxyynnnn por  <DSP_REG_X>,<DSP_REG_Y>,<DSP_REG_N> */
+{"por",  {DSP_REG_X,DSP_REG_Y,DSP_REG_N},{PPI,PPIC,HEX_B,HEX_5}, arch_sh_dsp_up},
+/* 10001001xxyynnnn pdec <DSP_REG_X>,<DSP_REG_N> */
+{"pdec", {DSP_REG_X,DSP_REG_N},{PPI,PPIC,HEX_8,HEX_9}, arch_sh_dsp_up},
+/* 10101001xxyynnnn pdec <DSP_REG_Y>,<DSP_REG_N> */
+{"pdec", {DSP_REG_Y,DSP_REG_N},{PPI,PPIC,HEX_A,HEX_9}, arch_sh_dsp_up},
+/* 10011001xx00nnnn pinc <DSP_REG_X>,<DSP_REG_N> */
+{"pinc", {DSP_REG_X,DSP_REG_N},{PPI,PPIC,HEX_9,HEX_9,HEX_XX00}, arch_sh_dsp_up},
+/* 1011100100yynnnn pinc <DSP_REG_Y>,<DSP_REG_N> */
+{"pinc", {DSP_REG_Y,DSP_REG_N},{PPI,PPIC,HEX_B,HEX_9,HEX_00YY}, arch_sh_dsp_up},
+/* 10001101xxyynnnn pclr <DSP_REG_N> */
+{"pclr", {DSP_REG_N},{PPI,PPIC,HEX_8,HEX_D}, arch_sh_dsp_up},
+/* 10011101xx00nnnn pdmsb <DSP_REG_X>,<DSP_REG_N> */
+{"pdmsb", {DSP_REG_X,DSP_REG_N},{PPI,PPIC,HEX_9,HEX_D,HEX_XX00}, arch_sh_dsp_up},
+/* 1011110100yynnnn pdmsb <DSP_REG_Y>,<DSP_REG_N> */
+{"pdmsb", {DSP_REG_Y,DSP_REG_N},{PPI,PPIC,HEX_B,HEX_D,HEX_00YY}, arch_sh_dsp_up},
+/* 11001001xxyynnnn pneg  <DSP_REG_X>,<DSP_REG_N> */
+{"pneg",  {DSP_REG_X,DSP_REG_N},{PPI,PPIC,HEX_C,HEX_9}, arch_sh_dsp_up},
+/* 11101001xxyynnnn pneg  <DSP_REG_Y>,<DSP_REG_N> */
+{"pneg",  {DSP_REG_Y,DSP_REG_N},{PPI,PPIC,HEX_E,HEX_9}, arch_sh_dsp_up},
+/* 11011001xxyynnnn pcopy <DSP_REG_X>,<DSP_REG_N> */
+{"pcopy", {DSP_REG_X,DSP_REG_N},{PPI,PPIC,HEX_D,HEX_9}, arch_sh_dsp_up},
+/* 11111001xxyynnnn pcopy <DSP_REG_Y>,<DSP_REG_N> */
+{"pcopy", {DSP_REG_Y,DSP_REG_N},{PPI,PPIC,HEX_F,HEX_9}, arch_sh_dsp_up},
+/* 11001101xxyynnnn psts MACH,<DSP_REG_N> */
+{"psts", {A_MACH,DSP_REG_N},{PPI,PPIC,HEX_C,HEX_D}, arch_sh_dsp_up},
+/* 11011101xxyynnnn psts MACL,<DSP_REG_N> */
+{"psts", {A_MACL,DSP_REG_N},{PPI,PPIC,HEX_D,HEX_D}, arch_sh_dsp_up},
+/* 11101101xxyynnnn plds <DSP_REG_N>,MACH */
+{"plds", {DSP_REG_N,A_MACH},{PPI,PPIC,HEX_E,HEX_D}, arch_sh_dsp_up},
+/* 11111101xxyynnnn plds <DSP_REG_N>,MACL */
+{"plds", {DSP_REG_N,A_MACL},{PPI,PPIC,HEX_F,HEX_D}, arch_sh_dsp_up},
+/* 10011101xx01zzzz pswap <DSP_REG_X>,<DSP_REG_N> */
+{"pswap", {DSP_REG_X,DSP_REG_N},{PPI,PPIC,HEX_9,HEX_D,HEX_1}, arch_sh4al_dsp_up},
+/* 1011110101yyzzzz pswap <DSP_REG_Y>,<DSP_REG_N> */
+{"pswap", {DSP_REG_Y,DSP_REG_N},{PPI,PPIC,HEX_B,HEX_D,HEX_4}, arch_sh4al_dsp_up},
+
+/* 1111nnnn01011101 fabs <F_REG_N>     */{"fabs",{F_REG_N},{HEX_F,REG_N,HEX_5,HEX_D}, arch_sh2e_up},
+/* 1111nnn001011101 fabs <D_REG_N>     */{"fabs",{D_REG_N},{HEX_F,REG_N,HEX_5,HEX_D}, arch_sh4_up | arch_sh2a_up},
+
+/* 1111nnnnmmmm0000 fadd <F_REG_M>,<F_REG_N>*/{"fadd",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_0}, arch_sh2e_up},
+/* 1111nnn0mmm00000 fadd <D_REG_M>,<D_REG_N>*/{"fadd",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_0}, arch_sh4_up | arch_sh2a_up},
+
+/* 1111nnnnmmmm0100 fcmp/eq <F_REG_M>,<F_REG_N>*/{"fcmp/eq",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_4}, arch_sh2e_up},
+/* 1111nnn0mmm00100 fcmp/eq <D_REG_M>,<D_REG_N>*/{"fcmp/eq",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_4}, arch_sh4_up | arch_sh2a_up},
+
+/* 1111nnnnmmmm0101 fcmp/gt <F_REG_M>,<F_REG_N>*/{"fcmp/gt",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_5}, arch_sh2e_up},
+/* 1111nnn0mmm00101 fcmp/gt <D_REG_M>,<D_REG_N>*/{"fcmp/gt",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_5}, arch_sh4_up | arch_sh2a_up},
+
+/* 1111nnn010111101 fcnvds <D_REG_N>,FPUL*/{"fcnvds",{D_REG_N,FPUL_M},{HEX_F,REG_N_D,HEX_B,HEX_D}, arch_sh4_up | arch_sh2a_up},
+
+/* 1111nnn010101101 fcnvsd FPUL,<D_REG_N>*/{"fcnvsd",{FPUL_M,D_REG_N},{HEX_F,REG_N_D,HEX_A,HEX_D}, arch_sh4_up | arch_sh2a_up},
+
+/* 1111nnnnmmmm0011 fdiv <F_REG_M>,<F_REG_N>*/{"fdiv",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_3}, arch_sh2e_up},
+/* 1111nnn0mmm00011 fdiv <D_REG_M>,<D_REG_N>*/{"fdiv",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_3}, arch_sh4_up | arch_sh2a_up},
+
+/* 1111nnmm11101101 fipr <V_REG_M>,<V_REG_N>*/{"fipr",{V_REG_M,V_REG_N},{HEX_F,REG_NM,HEX_E,HEX_D}, arch_sh4_up},
+
+/* 1111nnnn10001101 fldi0 <F_REG_N>    */{"fldi0",{F_REG_N},{HEX_F,REG_N,HEX_8,HEX_D}, arch_sh2e_up},
+
+/* 1111nnnn10011101 fldi1 <F_REG_N>    */{"fldi1",{F_REG_N},{HEX_F,REG_N,HEX_9,HEX_D}, arch_sh2e_up},
+
+/* 1111nnnn00011101 flds <F_REG_N>,FPUL*/{"flds",{F_REG_N,FPUL_M},{HEX_F,REG_N,HEX_1,HEX_D}, arch_sh2e_up},
+
+/* 1111nnnn00101101 float FPUL,<F_REG_N>*/{"float",{FPUL_M,F_REG_N},{HEX_F,REG_N,HEX_2,HEX_D}, arch_sh2e_up},
+/* 1111nnn000101101 float FPUL,<D_REG_N>*/{"float",{FPUL_M,D_REG_N},{HEX_F,REG_N,HEX_2,HEX_D}, arch_sh4_up | arch_sh2a_up},
+
+/* 1111nnnnmmmm1110 fmac FR0,<F_REG_M>,<F_REG_N>*/{"fmac",{F_FR0,F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_E}, arch_sh2e_up},
+
+/* 1111nnnnmmmm1100 fmov <F_REG_M>,<F_REG_N>*/{"fmov",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_C}, arch_sh2e_up},
+/* 1111nnn1mmmm1100 fmov <DX_REG_M>,<DX_REG_N>*/{"fmov",{DX_REG_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_C}, arch_sh4_up | arch_sh2a_up},
+
+/* 1111nnnnmmmm1000 fmov @<REG_M>,<F_REG_N>*/{"fmov",{A_IND_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_8}, arch_sh2e_up},
+/* 1111nnn1mmmm1000 fmov @<REG_M>,<DX_REG_N>*/{"fmov",{A_IND_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_8}, arch_sh4_up | arch_sh2a_up},
+
+/* 1111nnnnmmmm1010 fmov <F_REG_M>,@<REG_N>*/{"fmov",{F_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}, arch_sh2e_up},
+/* 1111nnnnmmm11010 fmov <DX_REG_M>,@<REG_N>*/{"fmov",{DX_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}, arch_sh4_up | arch_sh2a_up},
+
+/* 1111nnnnmmmm1001 fmov @<REG_M>+,<F_REG_N>*/{"fmov",{A_INC_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_9}, arch_sh2e_up},
+/* 1111nnn1mmmm1001 fmov @<REG_M>+,<DX_REG_N>*/{"fmov",{A_INC_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_9}, arch_sh4_up | arch_sh2a_up},
+
+/* 1111nnnnmmmm1011 fmov <F_REG_M>,@-<REG_N>*/{"fmov",{F_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}, arch_sh2e_up},
+/* 1111nnnnmmm11011 fmov <DX_REG_M>,@-<REG_N>*/{"fmov",{DX_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}, arch_sh4_up | arch_sh2a_up},
+
+/* 1111nnnnmmmm0110 fmov @(R0,<REG_M>),<F_REG_N>*/{"fmov",{A_IND_R0_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_6}, arch_sh2e_up},
+/* 1111nnn1mmmm0110 fmov @(R0,<REG_M>),<DX_REG_N>*/{"fmov",{A_IND_R0_REG_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_6}, arch_sh4_up | arch_sh2a_up},
+
+/* 1111nnnnmmmm0111 fmov <F_REG_M>,@(R0,<REG_N>)*/{"fmov",{F_REG_M,A_IND_R0_REG_N},{HEX_F,REG_N,REG_M,HEX_7}, arch_sh2e_up},
+/* 1111nnnnmmm10111 fmov <DX_REG_M>,@(R0,<REG_N>)*/{"fmov",{DX_REG_M,A_IND_R0_REG_N},{HEX_F,REG_N,REG_M,HEX_7}, arch_sh4_up | arch_sh2a_up},
+
+/* 1111nnn1mmmm1000 fmov.d @<REG_M>,<DX_REG_N>*/{"fmov.d",{A_IND_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_8}, arch_sh4_up | arch_sh2a_up},
+
+/* 1111nnnnmmm11010 fmov.d <DX_REG_M>,@<REG_N>*/{"fmov.d",{DX_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}, arch_sh4_up | arch_sh2a_up},
+
+/* 1111nnn1mmmm1001 fmov.d @<REG_M>+,<DX_REG_N>*/{"fmov.d",{A_INC_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_9}, arch_sh4_up | arch_sh2a_up},
+
+/* 1111nnnnmmm11011 fmov.d <DX_REG_M>,@-<REG_N>*/{"fmov.d",{DX_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}, arch_sh4_up | arch_sh2a_up},
+
+/* 1111nnn1mmmm0110 fmov.d @(R0,<REG_M>),<DX_REG_N>*/{"fmov.d",{A_IND_R0_REG_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_6}, arch_sh4_up | arch_sh2a_up},
+
+/* 1111nnnnmmm10111 fmov.d <DX_REG_M>,@(R0,<REG_N>)*/{"fmov.d",{DX_REG_M,A_IND_R0_REG_N},{HEX_F,REG_N,REG_M,HEX_7}, arch_sh4_up | arch_sh2a_up},
+/* 0011nnnnmmmm0001 0011dddddddddddd fmov.d <F_REG_M>,@(<DISP12>,<REG_N>) */
+{"fmov.d",{DX_REG_M,A_DISP_REG_N},{HEX_3,REG_N,REG_M,HEX_1,HEX_3,DISP1_12BY8}, arch_sh2a_up | arch_op32},
+/* 0011nnnnmmmm0001 0111dddddddddddd fmov.d @(<DISP12>,<REG_M>),F_REG_N */
+{"fmov.d",{A_DISP_REG_M,DX_REG_N},{HEX_3,REG_N,REG_M,HEX_1,HEX_7,DISP0_12BY8}, arch_sh2a_up | arch_op32},
+
+/* 1111nnnnmmmm1000 fmov.s @<REG_M>,<F_REG_N>*/{"fmov.s",{A_IND_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_8}, arch_sh2e_up},
+
+/* 1111nnnnmmmm1010 fmov.s <F_REG_M>,@<REG_N>*/{"fmov.s",{F_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}, arch_sh2e_up},
+
+/* 1111nnnnmmmm1001 fmov.s @<REG_M>+,<F_REG_N>*/{"fmov.s",{A_INC_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_9}, arch_sh2e_up},
+
+/* 1111nnnnmmmm1011 fmov.s <F_REG_M>,@-<REG_N>*/{"fmov.s",{F_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}, arch_sh2e_up},
+
+/* 1111nnnnmmmm0110 fmov.s @(R0,<REG_M>),<F_REG_N>*/{"fmov.s",{A_IND_R0_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_6}, arch_sh2e_up},
+
+/* 1111nnnnmmmm0111 fmov.s <F_REG_M>,@(R0,<REG_N>)*/{"fmov.s",{F_REG_M,A_IND_R0_REG_N},{HEX_F,REG_N,REG_M,HEX_7}, arch_sh2e_up},
+/* 0011nnnnmmmm0001 0011dddddddddddd fmov.s <F_REG_M>,@(<DISP12>,<REG_N>) */
+{"fmov.s",{F_REG_M,A_DISP_REG_N},{HEX_3,REG_N,REG_M,HEX_1,HEX_3,DISP1_12BY4}, arch_sh2a_up | arch_op32},
+/* 0011nnnnmmmm0001 0111dddddddddddd fmov.s @(<DISP12>,<REG_M>),F_REG_N */
+{"fmov.s",{A_DISP_REG_M,F_REG_N},{HEX_3,REG_N,REG_M,HEX_1,HEX_7,DISP0_12BY4}, arch_sh2a_up | arch_op32},
+
+/* 1111nnnnmmmm0010 fmul <F_REG_M>,<F_REG_N>*/{"fmul",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_2}, arch_sh2e_up},
+/* 1111nnn0mmm00010 fmul <D_REG_M>,<D_REG_N>*/{"fmul",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_2}, arch_sh4_up | arch_sh2a_up},
+
+/* 1111nnnn01001101 fneg <F_REG_N>     */{"fneg",{F_REG_N},{HEX_F,REG_N,HEX_4,HEX_D}, arch_sh2e_up},
+/* 1111nnn001001101 fneg <D_REG_N>     */{"fneg",{D_REG_N},{HEX_F,REG_N,HEX_4,HEX_D}, arch_sh4_up | arch_sh2a_up},
+
+/* 1111011111111101 fpchg               */{"fpchg",{0},{HEX_F,HEX_7,HEX_F,HEX_D}, arch_sh4a_up},
+
+/* 1111101111111101 frchg               */{"frchg",{0},{HEX_F,HEX_B,HEX_F,HEX_D}, arch_sh4_up},
+
+/* 1111nnn011111101 fsca FPUL,<D_REG_N> */{"fsca",{FPUL_M,D_REG_N},{HEX_F,REG_N_D,HEX_F,HEX_D}, arch_sh4_up},
+
+/* 1111001111111101 fschg               */{"fschg",{0},{HEX_F,HEX_3,HEX_F,HEX_D}, arch_sh4_up | arch_sh2a_up},
+
+/* 1111nnnn01101101 fsqrt <F_REG_N>    */{"fsqrt",{F_REG_N},{HEX_F,REG_N,HEX_6,HEX_D}, arch_sh3e_up | arch_sh2a_up},
+/* 1111nnn001101101 fsqrt <D_REG_N>    */{"fsqrt",{D_REG_N},{HEX_F,REG_N,HEX_6,HEX_D}, arch_sh4_up | arch_sh2a_up},
+
+/* 1111nnnn01111101 fsrra <F_REG_N>    */{"fsrra",{F_REG_N},{HEX_F,REG_N,HEX_7,HEX_D}, arch_sh4_up},
+
+/* 1111nnnn00001101 fsts FPUL,<F_REG_N>*/{"fsts",{FPUL_M,F_REG_N},{HEX_F,REG_N,HEX_0,HEX_D}, arch_sh2e_up},
+
+/* 1111nnnnmmmm0001 fsub <F_REG_M>,<F_REG_N>*/{"fsub",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_1}, arch_sh2e_up},
+/* 1111nnn0mmm00001 fsub <D_REG_M>,<D_REG_N>*/{"fsub",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_1}, arch_sh4_up | arch_sh2a_up},
+
+/* 1111nnnn00111101 ftrc <F_REG_N>,FPUL*/{"ftrc",{F_REG_N,FPUL_M},{HEX_F,REG_N,HEX_3,HEX_D}, arch_sh2e_up},
+/* 1111nnnn00111101 ftrc <D_REG_N>,FPUL*/{"ftrc",{D_REG_N,FPUL_M},{HEX_F,REG_N,HEX_3,HEX_D}, arch_sh4_up | arch_sh2a_up},
+
+/* 1111nn0111111101 ftrv XMTRX_M4,<V_REG_n>*/{"ftrv",{XMTRX_M4,V_REG_N},{HEX_F,REG_N_B01,HEX_F,HEX_D}, arch_sh4_up},
+
+  /* 10000110nnnn0iii bclr #<imm>, <REG_N> */  {"bclr",{A_IMM, A_REG_N},{HEX_8,HEX_6,REG_N,IMM0_3c}, arch_sh2a_nofpu_up},
+  /* 0011nnnn0iii1001 0000dddddddddddd bclr.b #<imm>,@(<DISP12>,<REG_N>) */
+{"bclr.b",{A_IMM,A_DISP_REG_N},{HEX_3,REG_N,IMM0_3Uc,HEX_9,HEX_0,DISP1_12}, arch_sh2a_nofpu_up | arch_op32},
+  /* 10000111nnnn1iii bld #<imm>, <REG_N> */   {"bld",{A_IMM, A_REG_N},{HEX_8,HEX_7,REG_N,IMM0_3s}, arch_sh2a_nofpu_up},
+  /* 0011nnnn0iii1001 0011dddddddddddd bld.b #<imm>,@(<DISP12>,<REG_N>) */
+{"bld.b",{A_IMM,A_DISP_REG_N},{HEX_3,REG_N,IMM0_3Uc,HEX_9,HEX_3,DISP1_12}, arch_sh2a_nofpu_up | arch_op32},
+  /* 10000110nnnn1iii bset #<imm>, <REG_N> */  {"bset",{A_IMM, A_REG_N},{HEX_8,HEX_6,REG_N,IMM0_3s}, arch_sh2a_nofpu_up},
+  /* 0011nnnn0iii1001 0001dddddddddddd bset.b #<imm>,@(<DISP12>,<REG_N>) */
+{"bset.b",{A_IMM,A_DISP_REG_N},{HEX_3,REG_N,IMM0_3Uc,HEX_9,HEX_1,DISP1_12}, arch_sh2a_nofpu_up | arch_op32},
+  /* 10000111nnnn0iii bst #<imm>, <REG_N> */   {"bst",{A_IMM, A_REG_N},{HEX_8,HEX_7,REG_N,IMM0_3c}, arch_sh2a_nofpu_up},
+  /* 0011nnnn0iii1001 0010dddddddddddd bst.b #<imm>,@(<DISP12>,<REG_N>) */
+{"bst.b",{A_IMM,A_DISP_REG_N},{HEX_3,REG_N,IMM0_3Uc,HEX_9,HEX_2,DISP1_12}, arch_sh2a_nofpu_up | arch_op32},
+  /* 0100nnnn10010001 clips.b <REG_N> */       {"clips.b",{A_REG_N},{HEX_4,REG_N,HEX_9,HEX_1}, arch_sh2a_nofpu_up},
+  /* 0100nnnn10010101 clips.w <REG_N> */       {"clips.w",{A_REG_N},{HEX_4,REG_N,HEX_9,HEX_5}, arch_sh2a_nofpu_up},
+  /* 0100nnnn10000001 clipu.b <REG_N> */       {"clipu.b",{A_REG_N},{HEX_4,REG_N,HEX_8,HEX_1}, arch_sh2a_nofpu_up},
+  /* 0100nnnn10000101 clipu.w <REG_N> */       {"clipu.w",{A_REG_N},{HEX_4,REG_N,HEX_8,HEX_5}, arch_sh2a_nofpu_up},
+  /* 0100nnnn10010100 divs R0,<REG_N> */       {"divs",{A_R0,A_REG_N},{HEX_4,REG_N,HEX_9,HEX_4}, arch_sh2a_nofpu_up},
+  /* 0100nnnn10000100 divu R0,<REG_N> */       {"divu",{A_R0,A_REG_N},{HEX_4,REG_N,HEX_8,HEX_4}, arch_sh2a_nofpu_up},
+  /* 0100mmmm01001011 jsr/n @<REG_M>  */       {"jsr/n",{A_IND_M},{HEX_4,REG_M,HEX_4,HEX_B}, arch_sh2a_nofpu_up},
+  /* 10000011dddddddd jsr/n @@(<disp>,TBR) */  {"jsr/n",{A_DISP2_TBR},{HEX_8,HEX_3,IMM0_8BY4}, arch_sh2a_nofpu_up},
+  /* 0100mmmm11100101 ldbank @<REG_M>,R0 */    {"ldbank",{A_IND_M,A_R0},{HEX_4,REG_M,HEX_E,HEX_5}, arch_sh2a_nofpu_up},
+  /* 0100mmmm11110001 movml.l <REG_M>,@-R15 */ {"movml.l",{A_REG_M,A_DEC_R15},{HEX_4,REG_M,HEX_F,HEX_1}, arch_sh2a_nofpu_up},
+  /* 0100mmmm11110101 movml.l @R15+,<REG_M> */ {"movml.l",{A_INC_R15,A_REG_M},{HEX_4,REG_M,HEX_F,HEX_5}, arch_sh2a_nofpu_up},
+  /* 0100mmmm11110000 movml.l <REG_M>,@-R15 */ {"movmu.l",{A_REG_M,A_DEC_R15},{HEX_4,REG_M,HEX_F,HEX_0}, arch_sh2a_nofpu_up},
+  /* 0100mmmm11110100 movml.l @R15+,<REG_M> */ {"movmu.l",{A_INC_R15,A_REG_M},{HEX_4,REG_M,HEX_F,HEX_4}, arch_sh2a_nofpu_up},
+  /* 0000nnnn00111001 movrt <REG_N> */         {"movrt",{A_REG_N},{HEX_0,REG_N,HEX_3,HEX_9}, arch_sh2a_nofpu_up},
+  /* 0100nnnn10000000 mulr R0,<REG_N> */       {"mulr",{A_R0,A_REG_N},{HEX_4,REG_N,HEX_8,HEX_0}, arch_sh2a_nofpu_up},
+  /* 0000000001101000 nott */                  {"nott",{A_END},{HEX_0,HEX_0,HEX_6,HEX_8}, arch_sh2a_nofpu_up},
+  /* 0000000001011011 resbank */               {"resbank",{A_END},{HEX_0,HEX_0,HEX_5,HEX_B}, arch_sh2a_nofpu_up},
+  /* 0000000001101011 rts/n */                 {"rts/n",{A_END},{HEX_0,HEX_0,HEX_6,HEX_B}, arch_sh2a_nofpu_up},
+  /* 0000mmmm01111011 rtv/n <REG_M>*/          {"rtv/n",{A_REG_M},{HEX_0,REG_M,HEX_7,HEX_B}, arch_sh2a_nofpu_up},
+  /* 0100nnnn11100001 stbank R0,@<REG_N>*/     {"stbank",{A_R0,A_IND_N},{HEX_4,REG_N,HEX_E,HEX_1}, arch_sh2a_nofpu_up},
+
+/* 0011nnnn0iii1001 0100dddddddddddd band.b #<imm>,@(<DISP12>,<REG_N>) */
+{"band.b",{A_IMM,A_DISP_REG_N},{HEX_3,REG_N,IMM0_3Uc,HEX_9,HEX_4,DISP1_12}, arch_sh2a_nofpu_up | arch_op32},
+/* 0011nnnn0iii1001 1100dddddddddddd bandnot.b #<imm>,@(<DISP12>,<REG_N>) */
+{"bandnot.b",{A_IMM,A_DISP_REG_N},{HEX_3,REG_N,IMM0_3Uc,HEX_9,HEX_C,DISP1_12}, arch_sh2a_nofpu_up | arch_op32},
+/* 0011nnnn0iii1001 1011dddddddddddd bldnot.b #<imm>,@(<DISP12>,<REG_N>) */
+{"bldnot.b",{A_IMM,A_DISP_REG_N},{HEX_3,REG_N,IMM0_3Uc,HEX_9,HEX_B,DISP1_12}, arch_sh2a_nofpu_up | arch_op32},
+/* 0011nnnn0iii1001 0101dddddddddddd bor.b #<imm>,@(<DISP12>,<REG_N>) */
+{"bor.b",{A_IMM,A_DISP_REG_N},{HEX_3,REG_N,IMM0_3Uc,HEX_9,HEX_5,DISP1_12}, arch_sh2a_nofpu_up | arch_op32},
+/* 0011nnnn0iii1001 1101dddddddddddd bornot.b #<imm>,@(<DISP12>,<REG_N>) */
+{"bornot.b",{A_IMM,A_DISP_REG_N},{HEX_3,REG_N,IMM0_3Uc,HEX_9,HEX_D,DISP1_12}, arch_sh2a_nofpu_up | arch_op32},
+/* 0011nnnn0iii1001 0110dddddddddddd bxor.b #<imm>,@(<DISP12>,<REG_N>) */
+{"bxor.b",{A_IMM,A_DISP_REG_N},{HEX_3,REG_N,IMM0_3Uc,HEX_9,HEX_6,DISP1_12}, arch_sh2a_nofpu_up | arch_op32},
+/* 0000nnnniiii0000 iiiiiiiiiiiiiiii movi20 #<imm>,<REG_N> */
+{"movi20",{A_IMM,A_REG_N},{HEX_0,REG_N,IMM0_20_4,HEX_0,IMM0_20}, arch_sh2a_nofpu_up | arch_op32},
+/* 0000nnnniiii0001 iiiiiiiiiiiiiiii movi20s #<imm>,<REG_N> */
+{"movi20s",{A_IMM,A_REG_N},{HEX_0,REG_N,IMM0_20_4,HEX_1,IMM0_20BY8}, arch_sh2a_nofpu_up | arch_op32},
+/* 0011nnnnmmmm0001 1000dddddddddddd movu.b @(<DISP12>,<REG_M>),<REG_N> */
+{"movu.b",{A_DISP_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_1,HEX_8,DISP0_12}, arch_sh2a_nofpu_up | arch_op32},
+/* 0011nnnnmmmm0001 1001dddddddddddd movu.w @(<DISP12>,<REG_M>),<REG_N> */
+{"movu.w",{A_DISP_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_1,HEX_9,DISP0_12BY2}, arch_sh2a_nofpu_up | arch_op32},
+
+{ 0, {0}, {0}, 0 } 
+};
+
+#endif
+
+#ifdef ARCH_all
+#define INCLUDE_SHMEDIA
+#endif
+
+static void print_movxy
+  PARAMS ((const sh_opcode_info *, int, int, fprintf_ftype, void *));
+static void print_insn_ddt PARAMS ((int, struct disassemble_info *));
+static void print_dsp_reg PARAMS ((int, fprintf_ftype, void *));
+static void print_insn_ppi PARAMS ((int, struct disassemble_info *));
+
+static void
+print_movxy (op, rn, rm, fprintf_fn, stream)
+     const sh_opcode_info *op;
+     int rn, rm;
+     fprintf_ftype fprintf_fn;
+     void *stream;
+{
+  int n;
+
+  fprintf_fn (stream, "%s\t", op->name);
+  for (n = 0; n < 2; n++)
+    {
+      switch (op->arg[n])
+       {
+       case A_IND_N:
+       case AX_IND_N:
+       case AXY_IND_N:
+       case AY_IND_N:
+       case AYX_IND_N:
+         fprintf_fn (stream, "@r%d", rn);
+         break;
+       case A_INC_N:
+       case AX_INC_N:
+       case AXY_INC_N:
+       case AY_INC_N:
+       case AYX_INC_N:
+         fprintf_fn (stream, "@r%d+", rn);
+         break;
+       case AX_PMOD_N:
+       case AXY_PMOD_N:
+         fprintf_fn (stream, "@r%d+r8", rn);
+         break;
+       case AY_PMOD_N:
+       case AYX_PMOD_N:
+         fprintf_fn (stream, "@r%d+r9", rn);
+         break;
+       case DSP_REG_A_M:
+         fprintf_fn (stream, "a%c", '0' + rm);
+         break;
+       case DSP_REG_X:
+         fprintf_fn (stream, "x%c", '0' + rm);
+         break;
+       case DSP_REG_Y:
+         fprintf_fn (stream, "y%c", '0' + rm);
+         break;
+       case DSP_REG_AX:
+         fprintf_fn (stream, "%c%c",
+                     (rm & 1) ? 'x' : 'a',
+                     (rm & 2) ? '1' : '0');
+         break;
+       case DSP_REG_XY:
+         fprintf_fn (stream, "%c%c",
+                     (rm & 1) ? 'y' : 'x',
+                     (rm & 2) ? '1' : '0');
+         break;
+       case DSP_REG_AY:
+         fprintf_fn (stream, "%c%c",
+                     (rm & 2) ? 'y' : 'a',
+                     (rm & 1) ? '1' : '0');
+         break;
+       case DSP_REG_YX:
+         fprintf_fn (stream, "%c%c",
+                     (rm & 2) ? 'x' : 'y',
+                     (rm & 1) ? '1' : '0');
+         break;
+       default:
+         abort ();
+       }
+      if (n == 0)
+       fprintf_fn (stream, ",");
+    }
+}
+
+/* Print a double data transfer insn.  INSN is just the lower three
+   nibbles of the insn, i.e. field a and the bit that indicates if
+   a parallel processing insn follows.
+   Return nonzero if a field b of a parallel processing insns follows.  */
+
+static void
+print_insn_ddt (insn, info)
+     int insn;
+     struct disassemble_info *info;
+{
+  fprintf_ftype fprintf_fn = info->fprintf_func;
+  void *stream = info->stream;
+
+  /* If this is just a nop, make sure to emit something.  */
+  if (insn == 0x000)
+    fprintf_fn (stream, "nopx\tnopy");
+
+  /* If a parallel processing insn was printed before,
+     and we got a non-nop, emit a tab.  */
+  if ((insn & 0x800) && (insn & 0x3ff))
+    fprintf_fn (stream, "\t");
+
+  /* Check if either the x or y part is invalid.  */
+  if (((insn & 0xc) == 0 && (insn & 0x2a0))
+      || ((insn & 3) == 0 && (insn & 0x150)))
+    if (info->mach != bfd_mach_sh_dsp
+        && info->mach != bfd_mach_sh3_dsp)
+      {
+       static const sh_opcode_info *first_movx, *first_movy;
+       const sh_opcode_info *op;
+       int is_movy;
+
+       if (! first_movx)
+         {
+           for (first_movx = sh_table; first_movx->nibbles[1] != MOVX_NOPY;)
+             first_movx++;
+           for (first_movy = first_movx; first_movy->nibbles[1] != MOVY_NOPX;)
+             first_movy++;
+         }
+
+       is_movy = ((insn & 3) != 0);
+
+       if (is_movy)
+         op = first_movy;
+       else
+         op = first_movx;
+
+       while (op->nibbles[2] != (unsigned) ((insn >> 4) & 3)
+              || op->nibbles[3] != (unsigned) (insn & 0xf))
+         op++;
+       
+       print_movxy (op,
+                    (4 * ((insn & (is_movy ? 0x200 : 0x100)) == 0)
+                     + 2 * is_movy
+                     + 1 * ((insn & (is_movy ? 0x100 : 0x200)) != 0)),
+                    (insn >> 6) & 3,
+                    fprintf_fn, stream);
+      }
+    else
+      fprintf_fn (stream, ".word 0x%x", insn);
+  else
+    {
+      static const sh_opcode_info *first_movx, *first_movy;
+      const sh_opcode_info *opx, *opy;
+      unsigned int insn_x, insn_y;
+
+      if (! first_movx)
+       {
+         for (first_movx = sh_table; first_movx->nibbles[1] != MOVX;)
+           first_movx++;
+         for (first_movy = first_movx; first_movy->nibbles[1] != MOVY;)
+           first_movy++;
+       }
+      insn_x = (insn >> 2) & 0xb;
+      if (insn_x)
+       {
+         for (opx = first_movx; opx->nibbles[2] != insn_x;)
+           opx++;
+         print_movxy (opx, ((insn >> 9) & 1) + 4, (insn >> 7) & 1,
+                      fprintf_fn, stream);
+       }
+      insn_y = (insn & 3) | ((insn >> 1) & 8);
+      if (insn_y)
+       {
+         if (insn_x)
+           fprintf_fn (stream, "\t");
+         for (opy = first_movy; opy->nibbles[2] != insn_y;)
+           opy++;
+         print_movxy (opy, ((insn >> 8) & 1) + 6, (insn >> 6) & 1,
+                      fprintf_fn, stream);
+       }
+    }
+}
+
+static void
+print_dsp_reg (rm, fprintf_fn, stream)
+     int rm;
+     fprintf_ftype fprintf_fn;
+     void *stream;
+{
+  switch (rm)
+    {
+    case A_A1_NUM:
+      fprintf_fn (stream, "a1");
+      break;
+    case A_A0_NUM:
+      fprintf_fn (stream, "a0");
+      break;
+    case A_X0_NUM:
+      fprintf_fn (stream, "x0");
+      break;
+    case A_X1_NUM:
+      fprintf_fn (stream, "x1");
+      break;
+    case A_Y0_NUM:
+      fprintf_fn (stream, "y0");
+      break;
+    case A_Y1_NUM:
+      fprintf_fn (stream, "y1");
+      break;
+    case A_M0_NUM:
+      fprintf_fn (stream, "m0");
+      break;
+    case A_A1G_NUM:
+      fprintf_fn (stream, "a1g");
+      break;
+    case A_M1_NUM:
+      fprintf_fn (stream, "m1");
+      break;
+    case A_A0G_NUM:
+      fprintf_fn (stream, "a0g");
+      break;
+    default:
+      fprintf_fn (stream, "0x%x", rm);
+      break;
+    }
+}
+
+static void
+print_insn_ppi (field_b, info)
+     int field_b;
+     struct disassemble_info *info;
+{
+  static char *sx_tab[] = { "x0", "x1", "a0", "a1" };
+  static char *sy_tab[] = { "y0", "y1", "m0", "m1" };
+  fprintf_ftype fprintf_fn = info->fprintf_func;
+  void *stream = info->stream;
+  unsigned int nib1, nib2, nib3;
+  unsigned int altnib1, nib4;
+  char *dc = NULL;
+  const sh_opcode_info *op;
+
+  if ((field_b & 0xe800) == 0)
+    {
+      fprintf_fn (stream, "psh%c\t#%d,",
+                 field_b & 0x1000 ? 'a' : 'l',
+                 (field_b >> 4) & 127);
+      print_dsp_reg (field_b & 0xf, fprintf_fn, stream);
+      return;
+    }
+  if ((field_b & 0xc000) == 0x4000 && (field_b & 0x3000) != 0x1000)
+    {
+      static char *du_tab[] = { "x0", "y0", "a0", "a1" };
+      static char *se_tab[] = { "x0", "x1", "y0", "a1" };
+      static char *sf_tab[] = { "y0", "y1", "x0", "a1" };
+      static char *sg_tab[] = { "m0", "m1", "a0", "a1" };
+
+      if (field_b & 0x2000)
+       {
+         fprintf_fn (stream, "p%s %s,%s,%s\t",
+                     (field_b & 0x1000) ? "add" : "sub",
+                     sx_tab[(field_b >> 6) & 3],
+                     sy_tab[(field_b >> 4) & 3],
+                     du_tab[(field_b >> 0) & 3]);
+       }
+      else if ((field_b & 0xf0) == 0x10
+              && info->mach != bfd_mach_sh_dsp
+              && info->mach != bfd_mach_sh3_dsp)
+       {
+         fprintf_fn (stream, "pclr %s \t", du_tab[(field_b >> 0) & 3]);
+       }
+      else if ((field_b & 0xf3) != 0)
+       {
+         fprintf_fn (stream, ".word 0x%x\t", field_b);
+       }
+      fprintf_fn (stream, "pmuls%c%s,%s,%s",
+                 field_b & 0x2000 ? ' ' : '\t',
+                 se_tab[(field_b >> 10) & 3],
+                 sf_tab[(field_b >>  8) & 3],
+                 sg_tab[(field_b >>  2) & 3]);
+      return;
+    }
+
+  nib1 = PPIC;
+  nib2 = field_b >> 12 & 0xf;
+  nib3 = field_b >> 8 & 0xf;
+  nib4 = field_b >> 4 & 0xf;
+  switch (nib3 & 0x3)
+    {
+    case 0:
+      dc = "";
+      nib1 = PPI3;
+      break;
+    case 1:
+      dc = "";
+      break;
+    case 2:
+      dc = "dct ";
+      nib3 -= 1;
+      break;
+    case 3:
+      dc = "dcf ";
+      nib3 -= 2;
+      break;
+    }
+  if (nib1 == PPI3)
+    altnib1 = PPI3NC;
+  else
+    altnib1 = nib1;
+  for (op = sh_table; op->name; op++)
+    {
+      if ((op->nibbles[1] == nib1 || op->nibbles[1] == altnib1)
+         && op->nibbles[2] == nib2
+         && op->nibbles[3] == nib3)
+       {
+         int n;
+
+         switch (op->nibbles[4])
+           {
+           case HEX_0:
+             break;
+           case HEX_XX00:
+             if ((nib4 & 3) != 0)
+               continue;
+             break;
+           case HEX_1:
+             if ((nib4 & 3) != 1)
+               continue;
+             break;
+           case HEX_00YY:
+             if ((nib4 & 0xc) != 0)
+               continue;
+             break;
+           case HEX_4:
+             if ((nib4 & 0xc) != 4)
+               continue;
+             break;
+           default:
+             abort ();
+           }
+         fprintf_fn (stream, "%s%s\t", dc, op->name);
+         for (n = 0; n < 3 && op->arg[n] != A_END; n++)
+           {
+             if (n && op->arg[1] != A_END)
+               fprintf_fn (stream, ",");
+             switch (op->arg[n])
+               {
+               case DSP_REG_N:
+                 print_dsp_reg (field_b & 0xf, fprintf_fn, stream);
+                 break;
+               case DSP_REG_X:
+                 fprintf_fn (stream, sx_tab[(field_b >> 6) & 3]);
+                 break;
+               case DSP_REG_Y:
+                 fprintf_fn (stream, sy_tab[(field_b >> 4) & 3]);
+                 break;
+               case A_MACH:
+                 fprintf_fn (stream, "mach");
+                 break;
+               case A_MACL:
+                 fprintf_fn (stream, "macl");
+                 break;
+               default:
+                 abort ();
+               }
+           }
+         return;
+       }
+    }
+  /* Not found.  */
+  fprintf_fn (stream, ".word 0x%x", field_b);
+}
+
+/* FIXME mvs: movx insns print as ".word 0x%03x", insn & 0xfff
+   (ie. the upper nibble is missing).  */
+int
+print_insn_sh (memaddr, info)
+     bfd_vma memaddr;
+     struct disassemble_info *info;
+{
+  fprintf_ftype fprintf_fn = info->fprintf_func;
+  void *stream = info->stream;
+  unsigned char insn[4];
+  unsigned char nibs[8];
+  int status;
+  bfd_vma relmask = ~(bfd_vma) 0;
+  const sh_opcode_info *op;
+  unsigned int target_arch;
+  int allow_op32;
+
+  switch (info->mach)
+    {
+    case bfd_mach_sh:
+      target_arch = arch_sh1;
+      break;
+    case bfd_mach_sh4:
+      target_arch = arch_sh4;
+      break;
+    case bfd_mach_sh5:
+#ifdef INCLUDE_SHMEDIA
+      status = print_insn_sh64 (memaddr, info);
+      if (status != -2)
+       return status;
+#endif
+      /* When we get here for sh64, it's because we want to disassemble
+        SHcompact, i.e. arch_sh4.  */
+      target_arch = arch_sh4;
+      break;
+    default:
+      fprintf (stderr, "sh architecture not supported\n");
+      return -1;
+    }
+
+  status = info->read_memory_func (memaddr, insn, 2, info);
+
+  if (status != 0)
+    {
+      info->memory_error_func (status, memaddr, info);
+      return -1;
+    }
+
+  if (info->endian == BFD_ENDIAN_LITTLE)
+    {
+      nibs[0] = (insn[1] >> 4) & 0xf;
+      nibs[1] = insn[1] & 0xf;
+
+      nibs[2] = (insn[0] >> 4) & 0xf;
+      nibs[3] = insn[0] & 0xf;
+    }
+  else
+    {
+      nibs[0] = (insn[0] >> 4) & 0xf;
+      nibs[1] = insn[0] & 0xf;
+
+      nibs[2] = (insn[1] >> 4) & 0xf;
+      nibs[3] = insn[1] & 0xf;
+    }
+  status = info->read_memory_func (memaddr + 2, insn + 2, 2, info);
+  if (status != 0)
+    allow_op32 = 0;
+  else
+    {
+      allow_op32 = 1;
+
+      if (info->endian == BFD_ENDIAN_LITTLE)
+       {
+         nibs[4] = (insn[3] >> 4) & 0xf;
+         nibs[5] = insn[3] & 0xf;
+
+         nibs[6] = (insn[2] >> 4) & 0xf;
+         nibs[7] = insn[2] & 0xf;
+       }
+      else
+       {
+         nibs[4] = (insn[2] >> 4) & 0xf;
+         nibs[5] = insn[2] & 0xf;
+
+         nibs[6] = (insn[3] >> 4) & 0xf;
+         nibs[7] = insn[3] & 0xf;
+       }
+    }
+
+  if (nibs[0] == 0xf && (nibs[1] & 4) == 0
+      && SH_MERGE_ARCH_SET_VALID (target_arch, arch_sh_dsp_up))
+    {
+      if (nibs[1] & 8)
+       {
+         int field_b;
+
+         status = info->read_memory_func (memaddr + 2, insn, 2, info);
+
+         if (status != 0)
+           {
+             info->memory_error_func (status, memaddr + 2, info);
+             return -1;
+           }
+
+         if (info->endian == BFD_ENDIAN_LITTLE)
+           field_b = insn[1] << 8 | insn[0];
+         else
+           field_b = insn[0] << 8 | insn[1];
+
+         print_insn_ppi (field_b, info);
+         print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
+         return 4;
+       }
+      print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
+      return 2;
+    }
+  for (op = sh_table; op->name; op++)
+    {
+      int n;
+      int imm = 0;
+      int rn = 0;
+      int rm = 0;
+      int rb = 0;
+      int disp_pc;
+      bfd_vma disp_pc_addr = 0;
+      int disp = 0;
+      int has_disp = 0;
+      int max_n = SH_MERGE_ARCH_SET (op->arch, arch_op32) ? 8 : 4;
+
+      if (!allow_op32
+         && SH_MERGE_ARCH_SET (op->arch, arch_op32))
+       goto fail;
+
+      if (!SH_MERGE_ARCH_SET_VALID (op->arch, target_arch))
+       goto fail;
+      for (n = 0; n < max_n; n++)
+       {
+         int i = op->nibbles[n];
+
+         if (i < 16)
+           {
+             if (nibs[n] == i)
+               continue;
+             goto fail;
+           }
+         switch (i)
+           {
+           case BRANCH_8:
+             imm = (nibs[2] << 4) | (nibs[3]);
+             if (imm & 0x80)
+               imm |= ~0xff;
+             imm = ((char) imm) * 2 + 4;
+             goto ok;
+           case BRANCH_12:
+             imm = ((nibs[1]) << 8) | (nibs[2] << 4) | (nibs[3]);
+             if (imm & 0x800)
+               imm |= ~0xfff;
+             imm = imm * 2 + 4;
+             goto ok;
+           case IMM0_3c:
+             if (nibs[3] & 0x8)
+               goto fail;
+             imm = nibs[3] & 0x7;
+             break;
+           case IMM0_3s:
+             if (!(nibs[3] & 0x8))
+               goto fail;
+             imm = nibs[3] & 0x7;
+             break;
+           case IMM0_3Uc:
+             if (nibs[2] & 0x8)
+               goto fail;
+             imm = nibs[2] & 0x7;
+             break;
+           case IMM0_3Us:
+             if (!(nibs[2] & 0x8))
+               goto fail;
+             imm = nibs[2] & 0x7;
+             break;
+           case DISP0_12:
+           case DISP1_12:
+             disp = (nibs[5] << 8) | (nibs[6] << 4) | nibs[7];
+             has_disp = 1;
+             goto ok;
+           case DISP0_12BY2:
+           case DISP1_12BY2:
+             disp = ((nibs[5] << 8) | (nibs[6] << 4) | nibs[7]) << 1;
+             relmask = ~(bfd_vma) 1;
+             has_disp = 1;
+             goto ok;
+           case DISP0_12BY4:
+           case DISP1_12BY4:
+             disp = ((nibs[5] << 8) | (nibs[6] << 4) | nibs[7]) << 2;
+             relmask = ~(bfd_vma) 3;
+             has_disp = 1;
+             goto ok;
+           case DISP0_12BY8:
+           case DISP1_12BY8:
+             disp = ((nibs[5] << 8) | (nibs[6] << 4) | nibs[7]) << 3;
+             relmask = ~(bfd_vma) 7;
+             has_disp = 1;
+             goto ok;
+           case IMM0_20_4:
+             break;
+           case IMM0_20:
+             imm = ((nibs[2] << 16) | (nibs[4] << 12) | (nibs[5] << 8)
+                    | (nibs[6] << 4) | nibs[7]);
+             if (imm & 0x80000)
+               imm -= 0x100000;
+             goto ok;
+           case IMM0_20BY8:
+             imm = ((nibs[2] << 16) | (nibs[4] << 12) | (nibs[5] << 8)
+                    | (nibs[6] << 4) | nibs[7]);
+             imm <<= 8;
+             if (imm & 0x8000000)
+               imm -= 0x10000000;
+             goto ok;
+           case IMM0_4:
+           case IMM1_4:
+             imm = nibs[3];
+             goto ok;
+           case IMM0_4BY2:
+           case IMM1_4BY2:
+             imm = nibs[3] << 1;
+             goto ok;
+           case IMM0_4BY4:
+           case IMM1_4BY4:
+             imm = nibs[3] << 2;
+             goto ok;
+           case IMM0_8:
+           case IMM1_8:
+             imm = (nibs[2] << 4) | nibs[3];
+             disp = imm;
+             has_disp = 1;
+             if (imm & 0x80)
+               imm -= 0x100;
+             goto ok;
+           case PCRELIMM_8BY2:
+             imm = ((nibs[2] << 4) | nibs[3]) << 1;
+             relmask = ~(bfd_vma) 1;
+             goto ok;
+           case PCRELIMM_8BY4:
+             imm = ((nibs[2] << 4) | nibs[3]) << 2;
+             relmask = ~(bfd_vma) 3;
+             goto ok;
+           case IMM0_8BY2:
+           case IMM1_8BY2:
+             imm = ((nibs[2] << 4) | nibs[3]) << 1;
+             goto ok;
+           case IMM0_8BY4:
+           case IMM1_8BY4:
+             imm = ((nibs[2] << 4) | nibs[3]) << 2;
+             goto ok;
+           case REG_N_D:
+             if ((nibs[n] & 1) != 0)
+               goto fail;
+             /* fall through */
+           case REG_N:
+             rn = nibs[n];
+             break;
+           case REG_M:
+             rm = nibs[n];
+             break;
+           case REG_N_B01:
+             if ((nibs[n] & 0x3) != 1 /* binary 01 */)
+               goto fail;
+             rn = (nibs[n] & 0xc) >> 2;
+             break;
+           case REG_NM:
+             rn = (nibs[n] & 0xc) >> 2;
+             rm = (nibs[n] & 0x3);
+             break;
+           case REG_B:
+             rb = nibs[n] & 0x07;
+             break;
+           case SDT_REG_N:
+             /* sh-dsp: single data transfer.  */
+             rn = nibs[n];
+             if ((rn & 0xc) != 4)
+               goto fail;
+             rn = rn & 0x3;
+             rn |= (!(rn & 2)) << 2;
+             break;
+           case PPI:
+           case REPEAT:
+             goto fail;
+           default:
+             abort ();
+           }
+       }
+
+    ok:
+      /* sh2a has D_REG but not X_REG.  We don't know the pattern
+        doesn't match unless we check the output args to see if they
+        make sense.  */
+      if (target_arch == arch_sh2a
+         && ((op->arg[0] == DX_REG_M && (rm & 1) != 0)
+             || (op->arg[1] == DX_REG_N && (rn & 1) != 0)))
+       goto fail;
+
+      fprintf_fn (stream, "%s\t", op->name);
+      disp_pc = 0;
+      for (n = 0; n < 3 && op->arg[n] != A_END; n++)
+       {
+         if (n && op->arg[1] != A_END)
+           fprintf_fn (stream, ",");
+         switch (op->arg[n])
+           {
+           case A_IMM:
+             fprintf_fn (stream, "#%d", imm);
+             break;
+           case A_R0:
+             fprintf_fn (stream, "r0");
+             break;
+           case A_REG_N:
+             fprintf_fn (stream, "r%d", rn);
+             break;
+           case A_INC_N:
+           case AS_INC_N:
+             fprintf_fn (stream, "@r%d+", rn);
+             break;
+           case A_DEC_N:
+           case AS_DEC_N:
+             fprintf_fn (stream, "@-r%d", rn);
+             break;
+           case A_IND_N:
+           case AS_IND_N:
+             fprintf_fn (stream, "@r%d", rn);
+             break;
+           case A_DISP_REG_N:
+             fprintf_fn (stream, "@(%d,r%d)", has_disp?disp:imm, rn);
+             break;
+           case AS_PMOD_N:
+             fprintf_fn (stream, "@r%d+r8", rn);
+             break;
+           case A_REG_M:
+             fprintf_fn (stream, "r%d", rm);
+             break;
+           case A_INC_M:
+             fprintf_fn (stream, "@r%d+", rm);
+             break;
+           case A_DEC_M:
+             fprintf_fn (stream, "@-r%d", rm);
+             break;
+           case A_IND_M:
+             fprintf_fn (stream, "@r%d", rm);
+             break;
+           case A_DISP_REG_M:
+             fprintf_fn (stream, "@(%d,r%d)", has_disp?disp:imm, rm);
+             break;
+           case A_REG_B:
+             fprintf_fn (stream, "r%d_bank", rb);
+             break;
+           case A_DISP_PC:
+             disp_pc = 1;
+             disp_pc_addr = imm + 4 + (memaddr & relmask);
+             (*info->print_address_func) (disp_pc_addr, info);
+             break;
+           case A_IND_R0_REG_N:
+             fprintf_fn (stream, "@(r0,r%d)", rn);
+             break;
+           case A_IND_R0_REG_M:
+             fprintf_fn (stream, "@(r0,r%d)", rm);
+             break;
+           case A_DISP_GBR:
+             fprintf_fn (stream, "@(%d,gbr)", has_disp?disp:imm);
+             break;
+           case A_TBR:
+             fprintf_fn (stream, "tbr");
+             break;
+           case A_DISP2_TBR:
+             fprintf_fn (stream, "@@(%d,tbr)", has_disp?disp:imm);
+             break;
+           case A_INC_R15:
+             fprintf_fn (stream, "@r15+");
+             break;
+           case A_DEC_R15:
+             fprintf_fn (stream, "@-r15");
+             break;
+           case A_R0_GBR:
+             fprintf_fn (stream, "@(r0,gbr)");
+             break;
+           case A_BDISP12:
+           case A_BDISP8:
+                {
+                    bfd_vma addr;
+                    addr = imm + memaddr;
+                    (*info->print_address_func) (addr, info);
+                }
+             break;
+           case A_SR:
+             fprintf_fn (stream, "sr");
+             break;
+           case A_GBR:
+             fprintf_fn (stream, "gbr");
+             break;
+           case A_VBR:
+             fprintf_fn (stream, "vbr");
+             break;
+           case A_DSR:
+             fprintf_fn (stream, "dsr");
+             break;
+           case A_MOD:
+             fprintf_fn (stream, "mod");
+             break;
+           case A_RE:
+             fprintf_fn (stream, "re");
+             break;
+           case A_RS:
+             fprintf_fn (stream, "rs");
+             break;
+           case A_A0:
+             fprintf_fn (stream, "a0");
+             break;
+           case A_X0:
+             fprintf_fn (stream, "x0");
+             break;
+           case A_X1:
+             fprintf_fn (stream, "x1");
+             break;
+           case A_Y0:
+             fprintf_fn (stream, "y0");
+             break;
+           case A_Y1:
+             fprintf_fn (stream, "y1");
+             break;
+           case DSP_REG_M:
+             print_dsp_reg (rm, fprintf_fn, stream);
+             break;
+           case A_SSR:
+             fprintf_fn (stream, "ssr");
+             break;
+           case A_SPC:
+             fprintf_fn (stream, "spc");
+             break;
+           case A_MACH:
+             fprintf_fn (stream, "mach");
+             break;
+           case A_MACL:
+             fprintf_fn (stream, "macl");
+             break;
+           case A_PR:
+             fprintf_fn (stream, "pr");
+             break;
+           case A_SGR:
+             fprintf_fn (stream, "sgr");
+             break;
+           case A_DBR:
+             fprintf_fn (stream, "dbr");
+             break;
+           case F_REG_N:
+             fprintf_fn (stream, "fr%d", rn);
+             break;
+           case F_REG_M:
+             fprintf_fn (stream, "fr%d", rm);
+             break;
+           case DX_REG_N:
+             if (rn & 1)
+               {
+                 fprintf_fn (stream, "xd%d", rn & ~1);
+                 break;
+               }
+           case D_REG_N:
+             fprintf_fn (stream, "dr%d", rn);
+             break;
+           case DX_REG_M:
+             if (rm & 1)
+               {
+                 fprintf_fn (stream, "xd%d", rm & ~1);
+                 break;
+               }
+           case D_REG_M:
+             fprintf_fn (stream, "dr%d", rm);
+             break;
+           case FPSCR_M:
+           case FPSCR_N:
+             fprintf_fn (stream, "fpscr");
+             break;
+           case FPUL_M:
+           case FPUL_N:
+             fprintf_fn (stream, "fpul");
+             break;
+           case F_FR0:
+             fprintf_fn (stream, "fr0");
+             break;
+           case V_REG_N:
+             fprintf_fn (stream, "fv%d", rn * 4);
+             break;
+           case V_REG_M:
+             fprintf_fn (stream, "fv%d", rm * 4);
+             break;
+           case XMTRX_M4:
+             fprintf_fn (stream, "xmtrx");
+             break;
+           default:
+             abort ();
+           }
+       }
+
+#if 0
+      /* This code prints instructions in delay slots on the same line
+         as the instruction which needs the delay slots.  This can be
+         confusing, since other disassembler don't work this way, and
+         it means that the instructions are not all in a line.  So I
+         disabled it.  Ian.  */
+      if (!(info->flags & 1)
+         && (op->name[0] == 'j'
+             || (op->name[0] == 'b'
+                 && (op->name[1] == 'r'
+                     || op->name[1] == 's'))
+             || (op->name[0] == 'r' && op->name[1] == 't')
+             || (op->name[0] == 'b' && op->name[2] == '.')))
+       {
+         info->flags |= 1;
+         fprintf_fn (stream, "\t(slot ");
+         print_insn_sh (memaddr + 2, info);
+         info->flags &= ~1;
+         fprintf_fn (stream, ")");
+         return 4;
+       }
+#endif
+
+      if (disp_pc && strcmp (op->name, "mova") != 0)
+       {
+         int size;
+         bfd_byte bytes[4];
+
+         if (relmask == ~(bfd_vma) 1)
+           size = 2;
+         else
+           size = 4;
+         status = info->read_memory_func (disp_pc_addr, bytes, size, info);
+         if (status == 0)
+           {
+             unsigned int val;
+
+             if (size == 2)
+               {
+                 if (info->endian == BFD_ENDIAN_LITTLE)
+                   val = bfd_getl16 (bytes);
+                 else
+                   val = bfd_getb16 (bytes);
+               }
+             else
+               {
+                 if (info->endian == BFD_ENDIAN_LITTLE)
+                   val = bfd_getl32 (bytes);
+                 else
+                   val = bfd_getb32 (bytes);
+               }
+             if ((*info->symbol_at_address_func) (val, info))
+               {
+                 fprintf_fn (stream, "\t! 0x");
+                 (*info->print_address_func) (val, info);
+               }
+             else
+               fprintf_fn (stream, "\t! 0x%x", val);
+           }
+       }
+
+      return SH_MERGE_ARCH_SET (op->arch, arch_op32) ? 4 : 2;
+    fail:
+      ;
+
+    }
+  fprintf_fn (stream, ".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);
+  return 2;
+}
index e79592f..d5b3deb 100644 (file)
@@ -61,6 +61,8 @@
 #define CPU_MEM_INDEX ((env->psrs) == 0)
 #elif defined (TARGET_ARM)
 #define CPU_MEM_INDEX ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR)
+#elif defined (TARGET_SH4)
+#define CPU_MEM_INDEX ((env->sr & SR_MD) == 0)
 #else
 #error unsupported CPU
 #endif
@@ -78,6 +80,8 @@
 #define CPU_MEM_INDEX ((env->psrs) == 0)
 #elif defined (TARGET_ARM)
 #define CPU_MEM_INDEX ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR)
+#elif defined (TARGET_SH4)
+#define CPU_MEM_INDEX ((env->sr & SR_MD) == 0)
 #else
 #error unsupported CPU
 #endif
diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
new file mode 100644 (file)
index 0000000..d99ff8e
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ *  SH4 emulation
+ * 
+ *  Copyright (c) 2005 Samuel Tardieu
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef _CPU_SH4_H
+#define _CPU_SH4_H
+
+#include "config.h"
+
+#define TARGET_LONG_BITS 32
+#define TARGET_HAS_ICE 1
+
+#include "cpu-defs.h"
+
+#define TARGET_PAGE_BITS 12    /* 4k XXXXX */
+
+#define SR_MD (1 << 30)
+#define SR_RB (1 << 29)
+#define SR_BL (1 << 28)
+#define SR_FD (1 << 15)
+#define SR_M  (1 << 9)
+#define SR_Q  (1 << 8)
+#define SR_S  (1 << 1)
+#define SR_T  (1 << 0)
+
+#define FPSCR_FR (1 << 21)
+#define FPSCR_SZ (1 << 20)
+#define FPSCR_PR (1 << 19)
+#define FPSCR_DN (1 << 18)
+
+#define DELAY_SLOT             (1 << 0)
+#define DELAY_SLOT_CONDITIONAL (1 << 1)
+/* Those are used in contexts only */
+#define BRANCH                 (1 << 2)
+#define BRANCH_CONDITIONAL     (1 << 3)
+#define MODE_CHANGE            (1 << 4)        /* Potential MD|RB change */
+#define BRANCH_EXCEPTION       (1 << 5)        /* Branch after exception */
+
+/* XXXXX The structure could be made more compact */
+typedef struct tlb_t {
+    uint8_t asid;              /* address space identifier */
+    uint32_t vpn;              /* virtual page number */
+    uint8_t v;                 /* validity */
+    uint32_t ppn;              /* physical page number */
+    uint8_t sz;                        /* page size */
+    uint32_t size;             /* cached page size in bytes */
+    uint8_t sh;                        /* share status */
+    uint8_t c;                 /* cacheability */
+    uint8_t pr;                        /* protection key */
+    uint8_t d;                 /* dirty */
+    uint8_t wt;                        /* write through */
+    uint8_t sa;                        /* space attribute (PCMCIA) */
+    uint8_t tc;                        /* timing control */
+} tlb_t;
+
+#define UTLB_SIZE 64
+#define ITLB_SIZE 4
+
+typedef struct CPUSH4State {
+    uint32_t flags;            /* general execution flags */
+    uint32_t gregs[24];                /* general registers */
+    uint32_t fregs[32];                /* floating point registers */
+    uint32_t sr;               /* status register */
+    uint32_t ssr;              /* saved status register */
+    uint32_t spc;              /* saved program counter */
+    uint32_t gbr;              /* global base register */
+    uint32_t vbr;              /* vector base register */
+    uint32_t sgr;              /* saved global register 15 */
+    uint32_t dbr;              /* debug base register */
+    uint32_t pc;               /* program counter */
+    uint32_t delayed_pc;       /* target of delayed jump */
+    uint32_t mach;             /* multiply and accumulate high */
+    uint32_t macl;             /* multiply and accumulate low */
+    uint32_t pr;               /* procedure register */
+    uint32_t fpscr;            /* floating point status/control register */
+    uint32_t fpul;             /* floating point communication register */
+
+    /* Those belong to the specific unit (SH7750) but are handled here */
+    uint32_t mmucr;            /* MMU control register */
+    uint32_t pteh;             /* page table entry high register */
+    uint32_t ptel;             /* page table entry low register */
+    uint32_t ptea;             /* page table entry assistance register */
+    uint32_t ttb;              /* tranlation table base register */
+    uint32_t tea;              /* TLB exception address register */
+    uint32_t tra;              /* TRAPA exception register */
+    uint32_t expevt;           /* exception event register */
+    uint32_t intevt;           /* interrupt event register */
+
+    jmp_buf jmp_env;
+    int user_mode_only;
+    int interrupt_request;
+    int exception_index;
+     CPU_COMMON tlb_t utlb[UTLB_SIZE]; /* unified translation table */
+    tlb_t itlb[ITLB_SIZE];     /* instruction translation table */
+} CPUSH4State;
+
+CPUSH4State *cpu_sh4_init(void);
+int cpu_sh4_exec(CPUSH4State * s);
+struct siginfo;
+int cpu_sh4_signal_handler(int hostsignum, struct siginfo *info,
+                          void *puc);
+
+#include "softfloat.h"
+
+#include "cpu-all.h"
+
+/* Memory access type */
+enum {
+    /* Privilege */
+    ACCESS_PRIV = 0x01,
+    /* Direction */
+    ACCESS_WRITE = 0x02,
+    /* Type of instruction */
+    ACCESS_CODE = 0x10,
+    ACCESS_INT = 0x20
+};
+
+/* MMU control register */
+#define MMUCR    0x1F000010
+#define MMUCR_AT (1<<0)
+#define MMUCR_SV (1<<8)
+
+#endif                         /* _CPU_SH4_H */
diff --git a/target-sh4/exec.h b/target-sh4/exec.h
new file mode 100644 (file)
index 0000000..c219fef
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ *  SH4 emulation
+ * 
+ *  Copyright (c) 2005 Samuel Tardieu
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef _EXEC_SH4_H
+#define _EXEC_SH4_H
+
+#include "config.h"
+#include "dyngen-exec.h"
+
+register struct CPUSH4State *env asm(AREG0);
+register uint32_t T0 asm(AREG1);
+register uint32_t T1 asm(AREG2);
+register uint32_t T2 asm(AREG3);
+
+#include "cpu.h"
+#include "exec-all.h"
+
+#ifndef CONFIG_USER_ONLY
+#include "softmmu_exec.h"
+#endif
+
+#define RETURN() __asm__ __volatile__("")
+
+static inline void regs_to_env(void)
+{
+    /* XXXXX */
+}
+
+static inline void env_to_regs(void)
+{
+    /* XXXXX */
+}
+
+int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
+                            int is_user, int is_softmmu);
+
+int find_itlb_entry(CPUState * env, target_ulong address,
+                   int use_asid, int update);
+int find_utlb_entry(CPUState * env, target_ulong address, int use_asid);
+
+void helper_addc_T0_T1(void);
+void helper_addv_T0_T1(void);
+void helper_div1_T0_T1(void);
+void helper_dmulsl_T0_T1(void);
+void helper_dmulul_T0_T1(void);
+void helper_macl_T0_T1(void);
+void helper_macw_T0_T1(void);
+void helper_negc_T0(void);
+void helper_subc_T0_T1(void);
+void helper_subv_T0_T1(void);
+void helper_rotcl(uint32_t * addr);
+void helper_rotcr(uint32_t * addr);
+
+void do_interrupt(CPUState * env);
+
+void cpu_loop_exit(void);
+void do_raise_exception(void);
+
+#endif                         /* _EXEC_SH4_H */
diff --git a/target-sh4/helper.c b/target-sh4/helper.c
new file mode 100644 (file)
index 0000000..5ab505a
--- /dev/null
@@ -0,0 +1,398 @@
+/*
+ *  SH4 emulation
+ * 
+ *  Copyright (c) 2005 Samuel Tardieu
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <signal.h>
+#include <assert.h>
+
+#include "cpu.h"
+#include "exec-all.h"
+
+#define MMU_OK                   0
+#define MMU_ITLB_MISS            (-1)
+#define MMU_ITLB_MULTIPLE        (-2)
+#define MMU_ITLB_VIOLATION       (-3)
+#define MMU_DTLB_MISS_READ       (-4)
+#define MMU_DTLB_MISS_WRITE      (-5)
+#define MMU_DTLB_INITIAL_WRITE   (-6)
+#define MMU_DTLB_VIOLATION_READ  (-7)
+#define MMU_DTLB_VIOLATION_WRITE (-8)
+#define MMU_DTLB_MULTIPLE        (-9)
+#define MMU_DTLB_MISS            (-10)
+
+void do_interrupt(CPUState * env)
+{
+    if (loglevel & CPU_LOG_INT) {
+       const char *expname;
+       switch (env->exception_index) {
+       case 0x0e0:
+           expname = "addr_error";
+           break;
+       case 0x040:
+           expname = "tlb_miss";
+           break;
+       case 0x0a0:
+           expname = "tlb_violation";
+           break;
+       case 0x180:
+           expname = "illegal_instruction";
+           break;
+       case 0x1a0:
+           expname = "slot_illegal_instruction";
+           break;
+       case 0x800:
+           expname = "fpu_disable";
+           break;
+       case 0x820:
+           expname = "slot_fpu";
+           break;
+       case 0x100:
+           expname = "data_write";
+           break;
+       case 0x060:
+           expname = "dtlb_miss_write";
+           break;
+       case 0x0c0:
+           expname = "dtlb_violation_write";
+           break;
+       case 0x120:
+           expname = "fpu_exception";
+           break;
+       case 0x080:
+           expname = "initial_page_write";
+           break;
+       case 0x160:
+           expname = "trapa";
+           break;
+       default:
+           expname = "???";
+           break;
+       }
+       fprintf(logfile, "exception 0x%03x [%s] raised\n",
+               env->exception_index, expname);
+       cpu_dump_state(env, logfile, fprintf, 0);
+    }
+
+    env->ssr = env->sr;
+    env->spc = env->spc;
+    env->sgr = env->gregs[15];
+    env->sr |= SR_BL | SR_MD | SR_RB;
+
+    env->expevt = env->exception_index & 0x7ff;
+    switch (env->exception_index) {
+    case 0x040:
+    case 0x060:
+    case 0x080:
+       env->pc = env->vbr + 0x400;
+       break;
+    case 0x140:
+       env->pc = 0xa0000000;
+       break;
+    default:
+       env->pc = env->vbr + 0x100;
+       break;
+    }
+}
+
+static void update_itlb_use(CPUState * env, int itlbnb)
+{
+    uint8_t or_mask = 0, and_mask = (uint8_t) - 1;
+
+    switch (itlbnb) {
+    case 0:
+       and_mask = 0x7f;
+       break;
+    case 1:
+       and_mask = 0xe7;
+       or_mask = 0x80;
+       break;
+    case 2:
+       and_mask = 0xfb;
+       or_mask = 0x50;
+       break;
+    case 3:
+       or_mask = 0x2c;
+       break;
+    }
+
+    env->mmucr &= (and_mask << 24);
+    env->mmucr |= (or_mask << 24);
+}
+
+static int itlb_replacement(CPUState * env)
+{
+    if ((env->mmucr & 0xe0000000) == 0xe0000000)
+       return 0;
+    if ((env->mmucr & 0x98000000) == 0x08000000)
+       return 1;
+    if ((env->mmucr & 0x54000000) == 0x04000000)
+       return 2;
+    if ((env->mmucr & 0x2c000000) == 0x00000000)
+       return 3;
+    assert(0);
+}
+
+/* Find the corresponding entry in the right TLB
+   Return entry, MMU_DTLB_MISS or MMU_DTLB_MULTIPLE
+*/
+static int find_tlb_entry(CPUState * env, target_ulong address,
+                         tlb_t * entries, uint8_t nbtlb, int use_asid)
+{
+    int match = MMU_DTLB_MISS;
+    uint32_t start, end;
+    uint8_t asid;
+    int i;
+
+    asid = env->pteh & 0xff;
+
+    for (i = 0; i < nbtlb; i++) {
+       if (!entries[i].v)
+           continue;           /* Invalid entry */
+       if (use_asid && entries[i].asid != asid && !entries[i].sh)
+           continue;           /* Bad ASID */
+#if 0
+       switch (entries[i].sz) {
+       case 0:
+           size = 1024;        /* 1kB */
+           break;
+       case 1:
+           size = 4 * 1024;    /* 4kB */
+           break;
+       case 2:
+           size = 64 * 1024;   /* 64kB */
+           break;
+       case 3:
+           size = 1024 * 1024; /* 1MB */
+           break;
+       default:
+           assert(0);
+       }
+#endif
+       start = (entries[i].vpn << 10) & ~(entries[i].size - 1);
+       end = start + entries[i].size - 1;
+       if (address >= start && address <= end) {       /* Match */
+           if (match != -1)
+               return MMU_DTLB_MULTIPLE;       /* Multiple match */
+           match = i;
+       }
+    }
+    return match;
+}
+
+/* Find itlb entry - update itlb from utlb if necessary and asked for
+   Return entry, MMU_ITLB_MISS, MMU_ITLB_MULTIPLE or MMU_DTLB_MULTIPLE
+   Update the itlb from utlb if update is not 0
+*/
+int find_itlb_entry(CPUState * env, target_ulong address,
+                   int use_asid, int update)
+{
+    int e, n;
+
+    e = find_tlb_entry(env, address, env->itlb, ITLB_SIZE, use_asid);
+    if (e == MMU_DTLB_MULTIPLE)
+       e = MMU_ITLB_MULTIPLE;
+    else if (e == MMU_DTLB_MISS && update) {
+       e = find_tlb_entry(env, address, env->utlb, UTLB_SIZE, use_asid);
+       if (e >= 0) {
+           n = itlb_replacement(env);
+           env->itlb[n] = env->utlb[e];
+           e = n;
+       }
+    }
+    if (e >= 0)
+       update_itlb_use(env, e);
+    return e;
+}
+
+/* Find utlb entry
+   Return entry, MMU_DTLB_MISS, MMU_DTLB_MULTIPLE */
+int find_utlb_entry(CPUState * env, target_ulong address, int use_asid)
+{
+    uint8_t urb, urc;
+
+    /* Increment URC */
+    urb = ((env->mmucr) >> 18) & 0x3f;
+    urc = ((env->mmucr) >> 10) & 0x3f;
+    urc++;
+    if (urc == urb || urc == UTLB_SIZE - 1)
+       urc = 0;
+    env->mmucr = (env->mmucr & 0xffff03ff) | (urc << 10);
+
+    /* Return entry */
+    return find_tlb_entry(env, address, env->utlb, UTLB_SIZE, use_asid);
+}
+
+/* Match address against MMU
+   Return MMU_OK, MMU_DTLB_MISS_READ, MMU_DTLB_MISS_WRITE,
+   MMU_DTLB_INITIAL_WRITE, MMU_DTLB_VIOLATION_READ,
+   MMU_DTLB_VIOLATION_WRITE, MMU_ITLB_MISS,
+   MMU_ITLB_MULTIPLE, MMU_ITLB_VIOLATION
+*/
+static int get_mmu_address(CPUState * env, target_ulong * physical,
+                          int *prot, target_ulong address,
+                          int rw, int access_type)
+{
+    int use_asid, is_code, n;
+    tlb_t *matching = NULL;
+
+    use_asid = (env->mmucr & MMUCR_SV) == 0 && (env->sr & SR_MD) == 0;
+    is_code = env->pc == address;      /* Hack */
+
+    /* Use a hack to find if this is an instruction or data access */
+    if (env->pc == address && !(rw & PAGE_WRITE)) {
+       n = find_itlb_entry(env, address, use_asid, 1);
+       if (n >= 0) {
+           matching = &env->itlb[n];
+           if ((env->sr & SR_MD) & !(matching->pr & 2))
+               n = MMU_ITLB_VIOLATION;
+           else
+               *prot = PAGE_READ;
+       }
+    } else {
+       n = find_utlb_entry(env, address, use_asid);
+       if (n >= 0) {
+           matching = &env->utlb[n];
+           switch ((matching->pr << 1) | ((env->sr & SR_MD) ? 1 : 0)) {
+           case 0:             /* 000 */
+           case 2:             /* 010 */
+               n = (rw & PAGE_WRITE) ? MMU_DTLB_VIOLATION_WRITE :
+                   MMU_DTLB_VIOLATION_READ;
+               break;
+           case 1:             /* 001 */
+           case 4:             /* 100 */
+           case 5:             /* 101 */
+               if (rw & PAGE_WRITE)
+                   n = MMU_DTLB_VIOLATION_WRITE;
+               else
+                   *prot = PAGE_READ;
+               break;
+           case 3:             /* 011 */
+           case 6:             /* 110 */
+           case 7:             /* 111 */
+               *prot = rw & (PAGE_READ | PAGE_WRITE);
+               break;
+           }
+       } else if (n == MMU_DTLB_MISS) {
+           n = (rw & PAGE_WRITE) ? MMU_DTLB_MISS_WRITE :
+               MMU_DTLB_MISS_READ;
+       }
+    }
+    if (n >= 0) {
+       *physical = ((matching->ppn << 10) & ~(matching->size - 1)) |
+           (address & (matching->size - 1));
+       if ((rw & PAGE_WRITE) & !matching->d)
+           n = MMU_DTLB_INITIAL_WRITE;
+       else
+           n = MMU_OK;
+    }
+    return n;
+}
+
+int get_physical_address(CPUState * env, target_ulong * physical,
+                        int *prot, target_ulong address,
+                        int rw, int access_type)
+{
+    /* P1, P2 and P4 areas do not use translation */
+    if ((address >= 0x80000000 && address < 0xc0000000) ||
+       address >= 0xe0000000) {
+       if (!(env->sr & SR_MD)
+           && (address < 0xe0000000 || address > 0xe4000000)) {
+           /* Unauthorized access in user mode (only store queues are available) */
+           fprintf(stderr, "Unauthorized access\n");
+           return (rw & PAGE_WRITE) ? MMU_DTLB_MISS_WRITE :
+               MMU_DTLB_MISS_READ;
+       }
+       /* Mask upper 3 bits */
+       *physical = address & 0x1FFFFFFF;
+       *prot = PAGE_READ | PAGE_WRITE;
+       return MMU_OK;
+    }
+
+    /* If MMU is disabled, return the corresponding physical page */
+    if (!env->mmucr & MMUCR_AT) {
+       *physical = address & 0x1FFFFFFF;
+       *prot = PAGE_READ | PAGE_WRITE;
+       return MMU_OK;
+    }
+
+    /* We need to resort to the MMU */
+    return get_mmu_address(env, physical, prot, address, rw, access_type);
+}
+
+int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
+                            int is_user, int is_softmmu)
+{
+    target_ulong physical, page_offset, page_size;
+    int prot, ret, access_type;
+
+    /* XXXXX */
+#if 0
+    fprintf(stderr, "%s pc %08x ad %08x rw %d is_user %d smmu %d\n",
+           __func__, env->pc, address, rw, is_user, is_softmmu);
+#endif
+
+    access_type = ACCESS_INT;
+    ret =
+       get_physical_address(env, &physical, &prot, address, rw,
+                            access_type);
+
+    if (ret != MMU_OK) {
+       env->tea = address;
+       switch (ret) {
+       case MMU_ITLB_MISS:
+       case MMU_DTLB_MISS_READ:
+           env->exception_index = 0x040;
+           break;
+       case MMU_DTLB_MULTIPLE:
+       case MMU_ITLB_MULTIPLE:
+           env->exception_index = 0x140;
+           break;
+       case MMU_ITLB_VIOLATION:
+           env->exception_index = 0x0a0;
+           break;
+       case MMU_DTLB_MISS_WRITE:
+           env->exception_index = 0x060;
+           break;
+       case MMU_DTLB_INITIAL_WRITE:
+           env->exception_index = 0x080;
+           break;
+       case MMU_DTLB_VIOLATION_READ:
+           env->exception_index = 0x0a0;
+           break;
+       case MMU_DTLB_VIOLATION_WRITE:
+           env->exception_index = 0x0c0;
+           break;
+       default:
+           assert(0);
+       }
+       return 1;
+    }
+
+    page_size = TARGET_PAGE_SIZE;
+    page_offset =
+       (address - (address & TARGET_PAGE_MASK)) & ~(page_size - 1);
+    address = (address & TARGET_PAGE_MASK) + page_offset;
+    physical = (physical & TARGET_PAGE_MASK) + page_offset;
+
+    return tlb_set_page(env, address, physical, prot, is_user, is_softmmu);
+}
diff --git a/target-sh4/op.c b/target-sh4/op.c
new file mode 100644 (file)
index 0000000..dbab658
--- /dev/null
@@ -0,0 +1,882 @@
+/*
+ *  SH4 emulation
+ * 
+ *  Copyright (c) 2005 Samuel Tardieu
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include "exec.h"
+
+static inline void set_flag(uint32_t flag)
+{
+    env->flags |= flag;
+}
+
+static inline void clr_flag(uint32_t flag)
+{
+    env->flags &= ~flag;
+}
+
+static inline void set_t(void)
+{
+    env->sr |= SR_T;
+}
+
+static inline void clr_t(void)
+{
+    env->sr &= ~SR_T;
+}
+
+static inline void cond_t(int cond)
+{
+    if (cond)
+       set_t();
+    else
+       clr_t();
+}
+
+void OPPROTO op_movl_imm_T0(void)
+{
+    T0 = (uint32_t) PARAM1;
+    RETURN();
+}
+
+void OPPROTO op_movl_imm_T1(void)
+{
+    T0 = (uint32_t) PARAM1;
+    RETURN();
+}
+
+void OPPROTO op_movl_imm_T2(void)
+{
+    T0 = (uint32_t) PARAM1;
+    RETURN();
+}
+
+void OPPROTO op_cmp_eq_imm_T0(void)
+{
+    cond_t((int32_t) T0 == (int32_t) PARAM1);
+    RETURN();
+}
+
+void OPPROTO op_cmd_eq_T0_T1(void)
+{
+    cond_t(T0 == T1);
+    RETURN();
+}
+
+void OPPROTO op_cmd_hs_T0_T1(void)
+{
+    cond_t((uint32_t) T0 <= (uint32_t) T1);
+    RETURN();
+}
+
+void OPPROTO op_cmd_ge_T0_T1(void)
+{
+    cond_t((int32_t) T0 <= (int32_t) T1);
+    RETURN();
+}
+
+void OPPROTO op_cmd_hi_T0_T1(void)
+{
+    cond_t((uint32_t) T0 < (uint32_t) T1);
+    RETURN();
+}
+
+void OPPROTO op_cmd_gt_T0_T1(void)
+{
+    cond_t((int32_t) T0 < (int32_t) T1);
+    RETURN();
+}
+
+void OPPROTO op_not_T0(void)
+{
+    T0 = ~T0;
+    RETURN();
+}
+
+void OPPROTO op_bf_s(void)
+{
+    T2 = ~env->sr;
+    env->delayed_pc = PARAM1;
+    set_flag(DELAY_SLOT_CONDITIONAL);
+    RETURN();
+}
+
+void OPPROTO op_bt_s(void)
+{
+    T2 = env->sr;
+    env->delayed_pc = PARAM1;
+    set_flag(DELAY_SLOT_CONDITIONAL);
+    RETURN();
+}
+
+void OPPROTO op_bra(void)
+{
+    env->delayed_pc = PARAM1;
+    set_flag(DELAY_SLOT);
+    RETURN();
+}
+
+void OPPROTO op_braf_T0(void)
+{
+    env->delayed_pc = PARAM1 + T0;
+    set_flag(DELAY_SLOT);
+    RETURN();
+}
+
+void OPPROTO op_bsr(void)
+{
+    env->pr = PARAM1;
+    env->delayed_pc = PARAM2;
+    set_flag(DELAY_SLOT);
+    RETURN();
+}
+
+void OPPROTO op_bsrf_T0(void)
+{
+    env->pr = PARAM1;
+    env->delayed_pc = PARAM1 + T0;
+    set_flag(DELAY_SLOT);
+    RETURN();
+}
+
+void OPPROTO op_jsr_T0(void)
+{
+    env->pr = PARAM1;
+    env->delayed_pc = T0;
+    set_flag(DELAY_SLOT);
+    RETURN();
+}
+
+void OPPROTO op_rts(void)
+{
+    env->delayed_pc = env->pr;
+    set_flag(DELAY_SLOT);
+    RETURN();
+}
+
+void OPPROTO op_clr_delay_slot(void)
+{
+    clr_flag(DELAY_SLOT);
+    RETURN();
+}
+
+void OPPROTO op_clr_delay_slot_conditional(void)
+{
+    clr_flag(DELAY_SLOT_CONDITIONAL);
+    RETURN();
+}
+
+void OPPROTO op_exit_tb(void)
+{
+    EXIT_TB();
+    RETURN();
+}
+
+void OPPROTO op_addl_imm_T0(void)
+{
+    T0 += PARAM1;
+    RETURN();
+}
+
+void OPPROTO op_addl_imm_T1(void)
+{
+    T1 += PARAM1;
+    RETURN();
+}
+
+void OPPROTO op_clrmac(void)
+{
+    env->mach = env->macl = 0;
+    RETURN();
+}
+
+void OPPROTO op_clrs(void)
+{
+    env->sr &= ~SR_S;
+    RETURN();
+}
+
+void OPPROTO op_clrt(void)
+{
+    env->sr &= ~SR_T;
+    RETURN();
+}
+
+void OPPROTO op_sets(void)
+{
+    env->sr |= SR_S;
+    RETURN();
+}
+
+void OPPROTO op_sett(void)
+{
+    env->sr |= SR_T;
+    RETURN();
+}
+
+void OPPROTO op_rte(void)
+{
+    env->sr = env->ssr;
+    env->delayed_pc = env->spc;
+    set_flag(DELAY_SLOT);
+    RETURN();
+}
+
+void OPPROTO op_swapb_T0(void)
+{
+    T0 = (T0 & 0xffff0000) | ((T0 & 0xff) << 8) | ((T0 >> 8) & 0xff);
+    RETURN();
+}
+
+void OPPROTO op_swapw_T0(void)
+{
+    T0 = ((T0 & 0xffff) << 16) | ((T0 >> 16) & 0xffff);
+    RETURN();
+}
+
+void OPPROTO op_xtrct_T0_T1(void)
+{
+    T1 = ((T0 & 0xffff) << 16) | ((T1 >> 16) & 0xffff);
+    RETURN();
+}
+
+void OPPROTO op_addc_T0_T1(void)
+{
+    helper_addc_T0_T1();
+    RETURN();
+}
+
+void OPPROTO op_addv_T0_T1(void)
+{
+    helper_addv_T0_T1();
+    RETURN();
+}
+
+void OPPROTO op_cmp_eq_T0_T1(void)
+{
+    cond_t(T1 == T0);
+    RETURN();
+}
+
+void OPPROTO op_cmp_ge_T0_T1(void)
+{
+    cond_t((int32_t) T1 >= (int32_t) T0);
+    RETURN();
+}
+
+void OPPROTO op_cmp_gt_T0_T1(void)
+{
+    cond_t((int32_t) T1 > (int32_t) T0);
+    RETURN();
+}
+
+void OPPROTO op_cmp_hi_T0_T1(void)
+{
+    cond_t((uint32_t) T1 > (uint32_t) T0);
+    RETURN();
+}
+
+void OPPROTO op_cmp_hs_T0_T1(void)
+{
+    cond_t((uint32_t) T1 >= (uint32_t) T0);
+    RETURN();
+}
+
+void OPPROTO op_cmp_str_T0_T1(void)
+{
+    cond_t((T0 & 0x000000ff) == (T1 & 0x000000ff) ||
+          (T0 & 0x0000ff00) == (T1 & 0x0000ff00) ||
+          (T0 & 0x00ff0000) == (T1 & 0x00ff0000) ||
+          (T0 & 0xff000000) == (T1 & 0xff000000));
+    RETURN();
+}
+
+void OPPROTO op_tst_T0_T1(void)
+{
+    cond_t((T1 & T0) == 0);
+    RETURN();
+}
+
+void OPPROTO op_div0s_T0_T1(void)
+{
+    if (T1 & 0x80000000)
+       env->sr |= SR_Q;
+    else
+       env->sr &= ~SR_Q;
+    if (T0 & 0x80000000)
+       env->sr |= SR_M;
+    else
+       env->sr &= ~SR_M;
+    cond_t((T1 ^ T0) & 0x80000000);
+    RETURN();
+}
+
+void OPPROTO op_div0u(void)
+{
+    env->sr &= ~(SR_M | SR_Q | SR_T);
+    RETURN();
+}
+
+void OPPROTO op_div1_T0_T1(void)
+{
+    helper_div1_T0_T1();
+    RETURN();
+}
+
+void OPPROTO op_dmulsl_T0_T1(void)
+{
+    helper_dmulsl_T0_T1();
+    RETURN();
+}
+
+void OPPROTO op_dmulul_T0_T1(void)
+{
+    helper_dmulul_T0_T1();
+    RETURN();
+}
+
+void OPPROTO op_macl_T0_T1(void)
+{
+    helper_macl_T0_T1();
+    RETURN();
+}
+
+void OPPROTO op_macw_T0_T1(void)
+{
+    helper_macw_T0_T1();
+    RETURN();
+}
+
+void OPPROTO op_mull_T0_T1(void)
+{
+    env->macl = (T0 * T1) & 0xffffffff;
+    RETURN();
+}
+
+void OPPROTO op_mulsw_T0_T1(void)
+{
+    env->macl = (int32_t) T0 *(int32_t) T1;
+    RETURN();
+}
+
+void OPPROTO op_muluw_T0_T1(void)
+{
+    env->macl = (uint32_t) T0 *(uint32_t) T1;
+    RETURN();
+}
+
+void OPPROTO op_neg_T0(void)
+{
+    T0 = -T0;
+    RETURN();
+}
+
+void OPPROTO op_negc_T0(void)
+{
+    helper_negc_T0();
+    RETURN();
+}
+
+void OPPROTO op_shad_T0_T1(void)
+{
+    if ((T0 & 0x80000000) == 0)
+       T1 <<= (T0 & 0x1f);
+    else if ((T0 & 0x1f) == 0)
+       T1 = 0;
+    else
+       T1 = ((int32_t) T1) >> ((~T0 & 0x1f) + 1);
+    RETURN();
+}
+
+void OPPROTO op_shld_T0_T1(void)
+{
+    if ((T0 & 0x80000000) == 0)
+       T1 <<= (T0 & 0x1f);
+    else if ((T0 & 0x1f) == 0)
+       T1 = 0;
+    else
+       T1 = ((uint32_t) T1) >> ((~T0 & 0x1f) + 1);
+    RETURN();
+}
+
+void OPPROTO op_subc_T0_T1(void)
+{
+    helper_subc_T0_T1();
+    RETURN();
+}
+
+void OPPROTO op_subv_T0_T1(void)
+{
+    helper_subv_T0_T1();
+    RETURN();
+}
+
+void OPPROTO op_trapa(void)
+{
+    env->tra = PARAM1 * 2;
+    env->exception_index = 0x160;
+    do_raise_exception();
+    RETURN();
+}
+
+void OPPROTO op_cmp_pl_T0(void)
+{
+    cond_t((int32_t) T0 > 0);
+    RETURN();
+}
+
+void OPPROTO op_cmp_pz_T0(void)
+{
+    cond_t((int32_t) T0 >= 0);
+    RETURN();
+}
+
+void OPPROTO op_jmp_T0(void)
+{
+    env->delayed_pc = T0;
+    set_flag(DELAY_SLOT);
+    RETURN();
+}
+
+void OPPROTO op_movl_rN_rN(void)
+{
+    env->gregs[PARAM2] = env->gregs[PARAM1];
+    RETURN();
+}
+
+void OPPROTO op_ldcl_rMplus_rN_bank(void)
+{
+    env->gregs[PARAM2] = env->gregs[PARAM1];
+    env->gregs[PARAM1] += 4;
+    RETURN();
+}
+
+#define LDSTOPS(target,load,store) \
+void OPPROTO op_##load##_T0_##target (void) \
+{ env ->target = T0;   RETURN(); \
+} \
+void OPPROTO op_##store##_##target##_T0 (void) \
+{ T0 = env->target;   RETURN(); \
+} \
+
+LDSTOPS(sr, ldc, stc)
+    LDSTOPS(gbr, ldc, stc)
+    LDSTOPS(vbr, ldc, stc)
+    LDSTOPS(ssr, ldc, stc)
+    LDSTOPS(spc, ldc, stc)
+    LDSTOPS(sgr, ldc, stc)
+    LDSTOPS(dbr, ldc, stc)
+    LDSTOPS(mach, lds, sts)
+    LDSTOPS(macl, lds, sts)
+    LDSTOPS(pr, lds, sts)
+
+void OPPROTO op_movt_rN(void)
+{
+    env->gregs[PARAM1] = env->sr & SR_T;
+    RETURN();
+}
+
+void OPPROTO op_rotcl_Rn(void)
+{
+    helper_rotcl(&env->gregs[PARAM1]);
+    RETURN();
+}
+
+void OPPROTO op_rotcr_Rn(void)
+{
+    helper_rotcr(&env->gregs[PARAM1]);
+    RETURN();
+}
+
+void OPPROTO op_rotl_Rn(void)
+{
+    cond_t(env->gregs[PARAM1] & 0x80000000);
+    env->gregs[PARAM1] = (env->gregs[PARAM1] << 1) | (env->sr & SR_T);
+    RETURN();
+}
+
+void OPPROTO op_rotr_Rn(void)
+{
+    cond_t(env->gregs[PARAM1] & 1);
+    env->gregs[PARAM1] = (env->gregs[PARAM1] >> 1) |
+       ((env->sr & SR_T) ? 0x80000000 : 0);
+    RETURN();
+}
+
+void OPPROTO op_shal_Rn(void)
+{
+    cond_t(env->gregs[PARAM1] & 0x80000000);
+    env->gregs[PARAM1] <<= 1;
+    RETURN();
+}
+
+void OPPROTO op_shar_Rn(void)
+{
+    cond_t(env->gregs[PARAM1] & 1);
+    *(int32_t *) & env->gregs[PARAM1] >>= 1;
+    RETURN();
+}
+
+void OPPROTO op_shlr_Rn(void)
+{
+    cond_t(env->gregs[PARAM1] & 1);
+    *(uint32_t *) & env->gregs[PARAM1] >>= 1;
+    RETURN();
+}
+
+void OPPROTO op_shll2_Rn(void)
+{
+    env->gregs[PARAM1] <<= 2;
+    RETURN();
+}
+
+void OPPROTO op_shll8_Rn(void)
+{
+    env->gregs[PARAM1] <<= 8;
+    RETURN();
+}
+
+void OPPROTO op_shll16_Rn(void)
+{
+    env->gregs[PARAM1] <<= 16;
+    RETURN();
+}
+
+void OPPROTO op_shlr2_Rn(void)
+{
+    *(uint32_t *) & env->gregs[PARAM1] >>= 2;
+    RETURN();
+}
+
+void OPPROTO op_shlr8_Rn(void)
+{
+    *(uint32_t *) & env->gregs[PARAM1] >>= 8;
+    RETURN();
+}
+
+void OPPROTO op_shlr16_Rn(void)
+{
+    *(uint32_t *) & env->gregs[PARAM1] >>= 16;
+    RETURN();
+}
+
+void OPPROTO op_tasb_rN(void)
+{
+    cond_t(*(int8_t *) env->gregs[PARAM1] == 0);
+    *(int8_t *) env->gregs[PARAM1] |= 0x80;
+    RETURN();
+}
+
+void OPPROTO op_movl_T0_rN(void)
+{
+    env->gregs[PARAM1] = T0;
+    RETURN();
+}
+
+void OPPROTO op_movl_T1_rN(void)
+{
+    env->gregs[PARAM1] = T1;
+    RETURN();
+}
+
+void OPPROTO op_movb_rN_T0(void)
+{
+    T0 = (int32_t) (int8_t) (env->gregs[PARAM1] & 0xff);
+    RETURN();
+}
+
+void OPPROTO op_movub_rN_T0(void)
+{
+    T0 = env->gregs[PARAM1] & 0xff;
+    RETURN();
+}
+
+void OPPROTO op_movw_rN_T0(void)
+{
+    T0 = (int32_t) (int16_t) (env->gregs[PARAM1] & 0xffff);
+    RETURN();
+}
+
+void OPPROTO op_movuw_rN_T0(void)
+{
+    T0 = env->gregs[PARAM1] & 0xffff;
+    RETURN();
+}
+
+void OPPROTO op_movl_rN_T0(void)
+{
+    T0 = env->gregs[PARAM1];
+    RETURN();
+}
+
+void OPPROTO op_movb_rN_T1(void)
+{
+    T1 = (int32_t) (int8_t) (env->gregs[PARAM1] & 0xff);
+    RETURN();
+}
+
+void OPPROTO op_movub_rN_T1(void)
+{
+    T1 = env->gregs[PARAM1] & 0xff;
+    RETURN();
+}
+
+void OPPROTO op_movw_rN_T1(void)
+{
+    T1 = (int32_t) (int16_t) (env->gregs[PARAM1] & 0xffff);
+    RETURN();
+}
+
+void OPPROTO op_movuw_rN_T1(void)
+{
+    T1 = env->gregs[PARAM1] & 0xffff;
+    RETURN();
+}
+
+void OPPROTO op_movl_rN_T1(void)
+{
+    T1 = env->gregs[PARAM1];
+    RETURN();
+}
+
+void OPPROTO op_movl_imm_rN(void)
+{
+    env->gregs[PARAM2] = PARAM1;
+    RETURN();
+}
+
+void OPPROTO op_dec1_rN(void)
+{
+    env->gregs[PARAM1] -= 1;
+    RETURN();
+}
+
+void OPPROTO op_dec2_rN(void)
+{
+    env->gregs[PARAM1] -= 2;
+    RETURN();
+}
+
+void OPPROTO op_dec4_rN(void)
+{
+    env->gregs[PARAM1] -= 4;
+    RETURN();
+}
+
+void OPPROTO op_inc1_rN(void)
+{
+    env->gregs[PARAM1] += 1;
+    RETURN();
+}
+
+void OPPROTO op_inc2_rN(void)
+{
+    env->gregs[PARAM1] += 2;
+    RETURN();
+}
+
+void OPPROTO op_inc4_rN(void)
+{
+    env->gregs[PARAM1] += 4;
+    RETURN();
+}
+
+void OPPROTO op_add_T0_rN(void)
+{
+    env->gregs[PARAM1] += T0;
+    RETURN();
+}
+
+void OPPROTO op_sub_T0_rN(void)
+{
+    env->gregs[PARAM1] -= T0;
+    RETURN();
+}
+
+void OPPROTO op_and_T0_rN(void)
+{
+    env->gregs[PARAM1] &= T0;
+    RETURN();
+}
+
+void OPPROTO op_or_T0_rN(void)
+{
+    env->gregs[PARAM1] |= T0;
+    RETURN();
+}
+
+void OPPROTO op_xor_T0_rN(void)
+{
+    env->gregs[PARAM1] ^= T0;
+    RETURN();
+}
+
+void OPPROTO op_add_rN_T0(void)
+{
+    T0 += env->gregs[PARAM1];
+    RETURN();
+}
+
+void OPPROTO op_add_rN_T1(void)
+{
+    T1 += env->gregs[PARAM1];
+    RETURN();
+}
+
+void OPPROTO op_add_imm_rN(void)
+{
+    env->gregs[PARAM2] += PARAM1;
+    RETURN();
+}
+
+void OPPROTO op_and_imm_rN(void)
+{
+    env->gregs[PARAM2] &= PARAM1;
+    RETURN();
+}
+
+void OPPROTO op_or_imm_rN(void)
+{
+    env->gregs[PARAM2] |= PARAM1;
+    RETURN();
+}
+
+void OPPROTO op_xor_imm_rN(void)
+{
+    env->gregs[PARAM2] ^= PARAM1;
+    RETURN();
+}
+
+void OPPROTO op_dt_rN(void)
+{
+    cond_t((--env->gregs[PARAM1]) == 0);
+    RETURN();
+}
+
+void OPPROTO op_tst_imm_rN(void)
+{
+    cond_t((env->gregs[PARAM2] & PARAM1) == 0);
+    RETURN();
+}
+
+void OPPROTO op_movl_T0_T1(void)
+{
+    T1 = T0;
+    RETURN();
+}
+
+void OPPROTO op_goto_tb0(void)
+{
+    GOTO_TB(op_goto_tb0, PARAM1, 0);
+    RETURN();
+}
+
+void OPPROTO op_goto_tb1(void)
+{
+    GOTO_TB(op_goto_tb1, PARAM1, 1);
+    RETURN();
+}
+
+void OPPROTO op_movl_imm_PC(void)
+{
+    env->pc = PARAM1;
+    RETURN();
+}
+
+void OPPROTO op_jT(void)
+{
+    if (env->sr & SR_T)
+       GOTO_LABEL_PARAM(1);
+    RETURN();
+}
+
+void OPPROTO op_jTT2(void)
+{
+    if (T2 & SR_T)
+       GOTO_LABEL_PARAM(1);
+    RETURN();
+}
+
+void OPPROTO op_movl_delayed_pc_PC(void)
+{
+    env->pc = env->delayed_pc;
+    RETURN();
+}
+
+void OPPROTO op_addl_GBR_T0(void)
+{
+    T0 += env->gbr;
+    RETURN();
+}
+
+void OPPROTO op_and_imm_T0(void)
+{
+    T0 &= PARAM1;
+    RETURN();
+}
+
+void OPPROTO op_or_imm_T0(void)
+{
+    T0 |= PARAM1;
+    RETURN();
+}
+
+void OPPROTO op_xor_imm_T0(void)
+{
+    T0 ^= PARAM1;
+    RETURN();
+}
+
+void OPPROTO op_tst_imm_T0(void)
+{
+    cond_t((T0 & PARAM1) == 0);
+    RETURN();
+}
+
+void OPPROTO op_raise_illegal_instruction(void)
+{
+    env->exception_index = 0x180;
+    do_raise_exception();
+    RETURN();
+}
+
+void OPPROTO op_raise_slot_illegal_instruction(void)
+{
+    env->exception_index = 0x1a0;
+    do_raise_exception();
+    RETURN();
+}
+
+void OPPROTO op_debug(void)
+{
+    env->exception_index = EXCP_DEBUG;
+    cpu_loop_exit();
+}
+
+/* Load and store */
+#define MEMSUFFIX _raw
+#include "op_mem.c"
+#undef MEMSUFFIX
+#if !defined(CONFIG_USER_ONLY)
+#define MEMSUFFIX _user
+#include "op_mem.c"
+#undef MEMSUFFIX
+
+#define MEMSUFFIX _kernel
+#include "op_mem.c"
+#undef MEMSUFFIX
+#endif
diff --git a/target-sh4/op_helper.c b/target-sh4/op_helper.c
new file mode 100644 (file)
index 0000000..1c63fe5
--- /dev/null
@@ -0,0 +1,372 @@
+/*
+ *  SH4 emulation
+ * 
+ *  Copyright (c) 2005 Samuel Tardieu
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <assert.h>
+#include "exec.h"
+
+void cpu_loop_exit(void)
+{
+    longjmp(env->jmp_env, 1);
+}
+
+void do_raise_exception(void)
+{
+    cpu_loop_exit();
+}
+
+#ifndef CONFIG_USER_ONLY
+
+#define MMUSUFFIX _mmu
+#define GETPC() (__builtin_return_address(0))
+
+#define SHIFT 0
+#include "softmmu_template.h"
+
+#define SHIFT 1
+#include "softmmu_template.h"
+
+#define SHIFT 2
+#include "softmmu_template.h"
+
+#define SHIFT 3
+#include "softmmu_template.h"
+
+void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
+{
+    TranslationBlock *tb;
+    CPUState *saved_env;
+    unsigned long pc;
+    int ret;
+
+    /* XXX: hack to restore env in all cases, even if not called from
+       generated code */
+    saved_env = env;
+    env = cpu_single_env;
+    ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, is_user, 1);
+    if (ret) {
+       if (retaddr) {
+           /* now we have a real cpu fault */
+           pc = (unsigned long) retaddr;
+           tb = tb_find_pc(pc);
+           if (tb) {
+               /* the PC is inside the translated code. It means that we have
+                  a virtual CPU fault */
+               cpu_restore_state(tb, env, pc, NULL);
+           }
+       }
+       do_raise_exception();
+    }
+    env = saved_env;
+}
+
+#endif
+
+void helper_addc_T0_T1(void)
+{
+    uint32_t tmp0, tmp1;
+
+    tmp1 = T0 + T1;
+    tmp0 = T1;
+    T1 = tmp1 + (env->sr & 1);
+    if (tmp0 > tmp1)
+       env->sr |= SR_T;
+    else
+       env->sr &= ~SR_T;
+    if (tmp1 > T1)
+       env->sr |= SR_T;
+}
+
+void helper_addv_T0_T1(void)
+{
+    uint32_t dest, src, ans;
+
+    if ((int32_t) T1 >= 0)
+       dest = 0;
+    else
+       dest = 1;
+    if ((int32_t) T0 >= 0)
+       src = 0;
+    else
+       src = 1;
+    src += dest;
+    T1 += T0;
+    if ((int32_t) T1 >= 0)
+       ans = 0;
+    else
+       ans = 1;
+    ans += dest;
+    if (src == 0 || src == 2) {
+       if (ans == 1)
+           env->sr |= SR_T;
+       else
+           env->sr &= ~SR_T;
+    } else
+       env->sr &= ~SR_T;
+}
+
+#define T (env->sr & SR_T)
+#define Q (env->sr & SR_Q ? 1 : 0)
+#define M (env->sr & SR_M ? 1 : 0)
+#define SETT env->sr |= SR_T
+#define CLRT env->sr &= ~SR_T
+#define SETQ env->sr |= SR_Q
+#define CLRQ env->sr &= ~SR_Q
+#define SETM env->sr |= SR_M
+#define CLRM env->sr &= ~SR_M
+
+void helper_div1_T0_T1(void)
+{
+    uint32_t tmp0, tmp2;
+    uint8_t old_q, tmp1 = 0xff;
+
+    printf("div1 T0=0x%08x T1=0x%08x M=%d Q=%d T=%d\n", T0, T1, M, Q, T);
+    old_q = Q;
+    if ((0x80000000 & T1) != 0)
+       SETQ;
+    else
+       CLRQ;
+    tmp2 = T0;
+    T1 <<= 1;
+    T1 |= T;
+    switch (old_q) {
+    case 0:
+       switch (M) {
+       case 0:
+           tmp0 = T1;
+           T1 -= tmp2;
+           tmp1 = T1 > tmp0;
+           switch (Q) {
+           case 0:
+               if (tmp1)
+                   SETQ;
+               else
+                   CLRQ;
+               break;
+           case 1:
+               if (tmp1 == 0)
+                   SETQ;
+               else
+                   CLRQ;
+               break;
+           }
+           break;
+       case 1:
+           tmp0 = T1;
+           T1 += tmp2;
+           tmp1 = T1 < tmp0;
+           switch (Q) {
+           case 0:
+               if (tmp1 == 0)
+                   SETQ;
+               else
+                   CLRQ;
+               break;
+           case 1:
+               if (tmp1)
+                   SETQ;
+               else
+                   CLRQ;
+               break;
+           }
+           break;
+       }
+       break;
+    case 1:
+       switch (M) {
+       case 0:
+           tmp0 = T1;
+           T1 += tmp2;
+           tmp1 = T1 < tmp0;
+           switch (Q) {
+           case 0:
+               if (tmp1)
+                   SETQ;
+               else
+                   CLRQ;
+               break;
+           case 1:
+               if (tmp1 == 0)
+                   SETQ;
+               else
+                   CLRQ;
+               break;
+           }
+           break;
+       case 1:
+           tmp0 = T1;
+           T1 -= tmp2;
+           tmp1 = T1 > tmp0;
+           switch (Q) {
+           case 0:
+               if (tmp1 == 0)
+                   SETQ;
+               else
+                   CLRQ;
+               break;
+           case 1:
+               if (tmp1)
+                   SETQ;
+               else
+                   CLRQ;
+               break;
+           }
+           break;
+       }
+       break;
+    }
+    if (Q == M)
+       SETT;
+    else
+       CLRT;
+    printf("Output: T1=0x%08x M=%d Q=%d T=%d\n", T1, M, Q, T);
+}
+
+void helper_dmulsl_T0_T1()
+{
+    int64_t res;
+
+    res = (int64_t) (int32_t) T0 *(int64_t) (int32_t) T1;
+    env->mach = (res >> 32) & 0xffffffff;
+    env->macl = res & 0xffffffff;
+}
+
+void helper_dmulul_T0_T1()
+{
+    uint64_t res;
+
+    res = (uint64_t) (uint32_t) T0 *(uint64_t) (uint32_t) T1;
+    env->mach = (res >> 32) & 0xffffffff;
+    env->macl = res & 0xffffffff;
+}
+
+void helper_macl_T0_T1()
+{
+    int64_t res;
+
+    res = ((uint64_t) env->mach << 32) | env->macl;
+    res += (int64_t) (int32_t) T0 *(int64_t) (int32_t) T1;
+    env->mach = (res >> 32) & 0xffffffff;
+    env->macl = res & 0xffffffff;
+    if (env->sr & SR_S) {
+       if (res < 0)
+           env->mach |= 0xffff0000;
+       else
+           env->mach &= 0x00007fff;
+    }
+}
+
+void helper_macw_T0_T1()
+{
+    int64_t res;
+
+    res = ((uint64_t) env->mach << 32) | env->macl;
+    res += (int64_t) (int16_t) T0 *(int64_t) (int16_t) T1;
+    env->mach = (res >> 32) & 0xffffffff;
+    env->macl = res & 0xffffffff;
+    if (env->sr & SR_S) {
+       if (res < -0x80000000) {
+           env->mach = 1;
+           env->macl = 0x80000000;
+       } else if (res > 0x000000007fffffff) {
+           env->mach = 1;
+           env->macl = 0x7fffffff;
+       }
+    }
+}
+
+void helper_negc_T0()
+{
+    uint32_t temp;
+
+    temp = -T0;
+    T0 = temp - (env->sr & SR_T);
+    if (0 < temp)
+       env->sr |= SR_T;
+    else
+       env->sr &= ~SR_T;
+    if (temp < T0)
+       env->sr |= SR_T;
+}
+
+void helper_subc_T0_T1()
+{
+    uint32_t tmp0, tmp1;
+
+    tmp1 = T1 - T0;
+    tmp0 = T1;
+    T1 = tmp1 - (env->sr & SR_T);
+    if (tmp0 < tmp1)
+       env->sr |= SR_T;
+    else
+       env->sr &= ~SR_T;
+    if (tmp1 < T1)
+       env->sr |= SR_T;
+}
+
+void helper_subv_T0_T1()
+{
+    int32_t dest, src, ans;
+
+    if ((int32_t) T1 >= 0)
+       dest = 0;
+    else
+       dest = 1;
+    if ((int32_t) T0 >= 0)
+       src = 0;
+    else
+       src = 1;
+    src += dest;
+    T1 -= T0;
+    if ((int32_t) T1 >= 0)
+       ans = 0;
+    else
+       ans = 1;
+    ans += dest;
+    if (src == 1) {
+       if (ans == 1)
+           env->sr |= SR_T;
+       else
+           env->sr &= ~SR_T;
+    } else
+       env->sr &= ~SR_T;
+}
+
+void helper_rotcl(uint32_t * addr)
+{
+    uint32_t new;
+
+    new = (*addr << 1) | (env->sr & SR_T);
+    if (*addr & 0x80000000)
+       env->sr |= SR_T;
+    else
+       env->sr &= ~SR_T;
+    *addr = new;
+}
+
+void helper_rotcr(uint32_t * addr)
+{
+    uint32_t new;
+
+    new = (*addr >> 1) | ((env->sr & SR_T) ? 0x80000000 : 0);
+    if (*addr & 1)
+       env->sr |= SR_T;
+    else
+       env->sr &= ~SR_T;
+    *addr = new;
+}
diff --git a/target-sh4/op_mem.c b/target-sh4/op_mem.c
new file mode 100644 (file)
index 0000000..9ab75f4
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ *  SH4 emulation
+ * 
+ *  Copyright (c) 2005 Samuel Tardieu
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+void glue(op_ldb_T0_T0, MEMSUFFIX) (void) {
+    T0 = glue(ldsb, MEMSUFFIX) (T0);
+    RETURN();
+}
+
+void glue(op_ldub_T0_T0, MEMSUFFIX) (void) {
+    T0 = glue(ldub, MEMSUFFIX) (T0);
+    RETURN();
+}
+
+void glue(op_stb_T0_T1, MEMSUFFIX) (void) {
+    glue(stb, MEMSUFFIX) (T1, T0);
+    RETURN();
+}
+
+void glue(op_ldw_T0_T0, MEMSUFFIX) (void) {
+    T0 = glue(ldsw, MEMSUFFIX) (T0);
+    RETURN();
+}
+
+void glue(op_lduw_T0_T0, MEMSUFFIX) (void) {
+    T0 = glue(lduw, MEMSUFFIX) (T0);
+    RETURN();
+}
+
+void glue(op_stw_T0_T1, MEMSUFFIX) (void) {
+    glue(stw, MEMSUFFIX) (T1, T0);
+    RETURN();
+}
+
+void glue(op_ldl_T0_T0, MEMSUFFIX) (void) {
+    T0 = glue(ldl, MEMSUFFIX) (T0);
+    RETURN();
+}
+
+void glue(op_stl_T0_T1, MEMSUFFIX) (void) {
+    glue(stl, MEMSUFFIX) (T1, T0);
+    RETURN();
+}
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
new file mode 100644 (file)
index 0000000..0013e49
--- /dev/null
@@ -0,0 +1,1073 @@
+/*
+ *  SH4 translation
+ * 
+ *  Copyright (c) 2005 Samuel Tardieu
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <assert.h>
+
+#define DEBUG_DISAS
+#define SH4_DEBUG_DISAS
+//#define SH4_SINGLE_STEP
+
+#include "cpu.h"
+#include "exec-all.h"
+#include "disas.h"
+
+enum {
+#define DEF(s, n, copy_size) INDEX_op_ ## s,
+#include "opc.h"
+#undef DEF
+    NB_OPS,
+};
+
+#ifdef USE_DIRECT_JUMP
+#define TBPARAM(x)
+#else
+#define TBPARAM(x) ((long)(x))
+#endif
+
+static uint16_t *gen_opc_ptr;
+static uint32_t *gen_opparam_ptr;
+
+#include "gen-op.h"
+
+typedef struct DisasContext {
+    struct TranslationBlock *tb;
+    target_ulong pc;
+    uint32_t sr;
+    uint16_t opcode;
+    uint32_t flags;
+    int memidx;
+    uint32_t delayed_pc;
+    int singlestep_enabled;
+} DisasContext;
+
+#ifdef CONFIG_USER_ONLY
+
+#define GEN_OP_LD(width) \
+  void gen_op_ld##width##_T0_T0 (DisasContext *ctx) { \
+    gen_op_ld##width##_T0_T0_raw(); \
+  }
+#define GEN_OP_ST(width) \
+  void gen_op_st##width##_T0_T1 (DisasContext *ctx) { \
+    gen_op_st##width##_T0_T1_raw(); \
+  }
+
+#else
+
+#define GEN_OP_LD(width) \
+  void gen_op_ld##width##_T0_T0 (DisasContext *ctx) { \
+    if (ctx->memidx) gen_op_ld##width##_T0_T0_kernel(); \
+    else gen_op_ld##width##_T0_T0_user();\
+  }
+#define GEN_OP_ST(width) \
+  void gen_op_st##width##_T0_T1 (DisasContext *ctx) { \
+    if (ctx->memidx) gen_op_st##width##_T0_T1_kernel(); \
+    else gen_op_st##width##_T0_T1_user();\
+  }
+
+#endif
+
+GEN_OP_LD(ub)
+    GEN_OP_LD(b)
+    GEN_OP_ST(b)
+    GEN_OP_LD(uw)
+    GEN_OP_LD(w)
+    GEN_OP_ST(w)
+    GEN_OP_LD(l)
+    GEN_OP_ST(l)
+
+void cpu_dump_state(CPUState * env, FILE * f,
+                   int (*cpu_fprintf) (FILE * f, const char *fmt, ...),
+                   int flags)
+{
+    int i;
+    cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x\n",
+               env->pc, env->sr, env->pr);
+    for (i = 0; i < 24; i += 4) {
+       cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
+                   i, env->gregs[i], i + 1, env->gregs[i + 1],
+                   i + 2, env->gregs[i + 2], i + 3, env->gregs[i + 3]);
+    }
+    if (env->flags & DELAY_SLOT) {
+       cpu_fprintf(f, "in delay slot (delayed_pc=0x%08x)\n",
+                   env->delayed_pc);
+    } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
+       cpu_fprintf(f, "in conditional delay slot (delayed_pc=0x%08x)\n",
+                   env->delayed_pc);
+    }
+}
+
+void cpu_sh4_reset(CPUSH4State * env)
+{
+    env->sr = 0x700000F0;      /* MD, RB, BL, I3-I0 */
+    env->vbr = 0;
+    env->pc = 0xA0000000;
+    env->fpscr = 0x00040001;
+    env->mmucr = 0;
+}
+
+CPUSH4State *cpu_sh4_init(void)
+{
+    CPUSH4State *env;
+
+    env = qemu_mallocz(sizeof(CPUSH4State));
+    if (!env)
+       return NULL;
+    cpu_exec_init(env);
+    cpu_sh4_reset(env);
+    tlb_flush(env, 1);
+    return env;
+}
+
+#ifdef CONFIG_USER_ONLY
+target_ulong cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
+{
+    return addr;
+}
+#else
+target_ulong cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
+{
+    target_ulong physical;
+    int prot;
+
+    get_physical_address(env, &physical, &prot, addr, PAGE_READ, 0);
+    return physical;
+}
+#endif
+
+static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
+{
+    TranslationBlock *tb;
+    tb = ctx->tb;
+
+    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
+       !ctx->singlestep_enabled) {
+       /* Use a direct jump if in same page and singlestep not enabled */
+       if (n == 0)
+           gen_op_goto_tb0(TBPARAM(tb));
+       else
+           gen_op_goto_tb1(TBPARAM(tb));
+       gen_op_movl_imm_T0((long) tb + n);
+    } else {
+       gen_op_movl_imm_T0(0);
+    }
+    gen_op_movl_imm_PC(dest);
+    if (ctx->singlestep_enabled)
+       gen_op_debug();
+    gen_op_exit_tb();
+}
+
+/* Jump to pc after an exception */
+static void gen_jump_exception(DisasContext * ctx)
+{
+    gen_op_movl_imm_T0(0);
+    if (ctx->singlestep_enabled)
+       gen_op_debug();
+    gen_op_exit_tb();
+}
+
+static void gen_jump(DisasContext * ctx)
+{
+    if (ctx->delayed_pc == (uint32_t) - 1) {
+       /* Target is not statically known, it comes necessarily from a
+          delayed jump as immediate jump are conditinal jumps */
+       gen_op_movl_delayed_pc_PC();
+       gen_op_movl_imm_T0(0);
+       if (ctx->singlestep_enabled)
+           gen_op_debug();
+       gen_op_exit_tb();
+    } else {
+       gen_goto_tb(ctx, 0, ctx->delayed_pc);
+    }
+}
+
+/* Immediate conditional jump (bt or bf) */
+static void gen_conditional_jump(DisasContext * ctx,
+                                target_ulong ift, target_ulong ifnott)
+{
+    int l1;
+
+    l1 = gen_new_label();
+    gen_op_jT(l1);
+    gen_goto_tb(ctx, 0, ifnott);
+    gen_set_label(l1);
+    gen_goto_tb(ctx, 1, ift);
+}
+
+/* Delayed conditional jump (bt or bf) */
+static void gen_delayed_conditional_jump(DisasContext * ctx)
+{
+    int l1;
+
+    l1 = gen_new_label();
+    gen_op_jTT2(l1);
+    gen_goto_tb(ctx, 0, ctx->pc);
+    gen_set_label(l1);
+    gen_goto_tb(ctx, 1, ctx->delayed_pc);
+}
+
+#define B3_0 (ctx->opcode & 0xf)
+#define B6_4 ((ctx->opcode >> 4) & 0x7)
+#define B7_4 ((ctx->opcode >> 4) & 0xf)
+#define B7_0 (ctx->opcode & 0xff)
+#define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
+#define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
+  (ctx->opcode & 0xfff))
+#define B11_8 ((ctx->opcode >> 8) & 0xf)
+#define B15_12 ((ctx->opcode >> 12) & 0xf)
+
+#define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \
+               (x) + 16 : (x))
+
+#define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
+               ? (x) + 16 : (x))
+
+#define CHECK_NOT_DELAY_SLOT \
+  if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
+  {gen_op_raise_slot_illegal_instruction (); ctx->flags |= BRANCH_EXCEPTION; \
+   return;}
+
+void decode_opc(DisasContext * ctx)
+{
+#if 0
+    fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
+#endif
+    switch (ctx->opcode) {
+    case 0x0019:               /* div0u */
+       printf("div0u\n");
+       gen_op_div0u();
+       return;
+    case 0x000b:               /* rts */
+       CHECK_NOT_DELAY_SLOT gen_op_rts();
+       ctx->flags |= DELAY_SLOT;
+       ctx->delayed_pc = (uint32_t) - 1;
+       return;
+    case 0x0028:               /* clrmac */
+       gen_op_clrmac();
+       return;
+    case 0x0048:               /* clrs */
+       gen_op_clrs();
+       return;
+    case 0x0008:               /* clrt */
+       gen_op_clrt();
+       return;
+    case 0x0038:               /* ldtlb */
+       assert(0);              /* XXXXX */
+       return;
+    case 0x004b:               /* rte */
+       CHECK_NOT_DELAY_SLOT gen_op_rte();
+       ctx->flags |= DELAY_SLOT;
+       ctx->delayed_pc = (uint32_t) - 1;
+       return;
+    case 0x0058:               /* sets */
+       gen_op_sets();
+       return;
+    case 0x0018:               /* sett */
+       gen_op_sett();
+       return;
+    case 0xfbfb:               /* frchg */
+       assert(0);              /* XXXXX */
+       return;
+    case 0xf3fb:               /* fschg */
+       assert(0);              /* XXXXX */
+       return;
+    case 0x0009:               /* nop */
+       return;
+    case 0x001b:               /* sleep */
+       assert(0);              /* XXXXX */
+       return;
+    }
+
+    switch (ctx->opcode & 0xf000) {
+    case 0x1000:               /* mov.l Rm,@(disp,Rn) */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_addl_imm_T1(B3_0 * 4);
+       gen_op_stl_T0_T1(ctx);
+       return;
+    case 0x5000:               /* mov.l @(disp,Rm),Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_addl_imm_T0(B3_0 * 4);
+       gen_op_ldl_T0_T0(ctx);
+       gen_op_movl_T0_rN(REG(B11_8));
+       return;
+    case 0xe000:               /* mov.l #imm,Rn */
+       gen_op_movl_imm_rN(B7_0s, REG(B11_8));
+       return;
+    case 0x9000:               /* mov.w @(disp,PC),Rn */
+       gen_op_movl_imm_T0(ctx->pc + 4 + B7_0 * 2);
+       gen_op_ldw_T0_T0(ctx);
+       gen_op_movl_T0_rN(REG(B11_8));
+       return;
+    case 0xd000:               /* mov.l @(disp,PC),Rn */
+       gen_op_movl_imm_T0((ctx->pc + 4 + B7_0 * 4) & ~3);
+       gen_op_ldl_T0_T0(ctx);
+       gen_op_movl_T0_rN(REG(B11_8));
+       return;
+    case 0x7000:               /* add.l #imm,Rn */
+       gen_op_add_imm_rN(B7_0s, REG(B11_8));
+       return;
+    case 0xa000:               /* bra disp */
+       CHECK_NOT_DELAY_SLOT
+           gen_op_bra(ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2);
+       ctx->flags |= DELAY_SLOT;
+       return;
+    case 0xb000:               /* bsr disp */
+       CHECK_NOT_DELAY_SLOT
+           gen_op_bsr(ctx->pc + 4, ctx->delayed_pc =
+                      ctx->pc + 4 + B11_0s * 2);
+       ctx->flags |= DELAY_SLOT;
+       return;
+    }
+
+    switch (ctx->opcode & 0xf00f) {
+    case 0x6003:               /* mov Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_T0_rN(REG(B11_8));
+       return;
+    case 0x2000:               /* mov.b Rm,@Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_stb_T0_T1(ctx);
+       return;
+    case 0x2001:               /* mov.w Rm,@Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_stw_T0_T1(ctx);
+       return;
+    case 0x2002:               /* mov.l Rm,@Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_stl_T0_T1(ctx);
+       return;
+    case 0x6000:               /* mov.b @Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_ldb_T0_T0(ctx);
+       gen_op_movl_T0_rN(REG(B11_8));
+       return;
+    case 0x6001:               /* mov.w @Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_ldw_T0_T0(ctx);
+       gen_op_movl_T0_rN(REG(B11_8));
+       return;
+    case 0x6002:               /* mov.l @Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_ldl_T0_T0(ctx);
+       gen_op_movl_T0_rN(REG(B11_8));
+       return;
+    case 0x2004:               /* mov.b Rm,@-Rn */
+       gen_op_dec1_rN(REG(B11_8));
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_stb_T0_T1(ctx);
+       return;
+    case 0x2005:               /* mov.w Rm,@-Rn */
+       gen_op_dec2_rN(REG(B11_8));
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_stw_T0_T1(ctx);
+       return;
+    case 0x2006:               /* mov.l Rm,@-Rn */
+       gen_op_dec4_rN(REG(B11_8));
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_stl_T0_T1(ctx);
+       return;
+    case 0x6004:               /* mov.l @Rm+,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_ldb_T0_T0(ctx);
+       gen_op_movl_T0_rN(REG(B11_8));
+       gen_op_inc1_rN(REG(B7_4));
+       return;
+    case 0x6005:               /* mov.w @Rm+,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_ldw_T0_T0(ctx);
+       gen_op_movl_T0_rN(REG(B11_8));
+       gen_op_inc2_rN(REG(B7_4));
+       return;
+    case 0x6006:               /* mov.l @Rm+,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_ldl_T0_T0(ctx);
+       gen_op_movl_T0_rN(REG(B11_8));
+       gen_op_inc4_rN(REG(B7_4));
+       return;
+    case 0x0004:               /* mov.b Rm,@(R0,Rn) */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_add_rN_T1(REG(0));
+       gen_op_stb_T0_T1(ctx);
+       return;
+    case 0x0005:               /* mov.w Rm,@(R0,Rn) */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_add_rN_T1(REG(0));
+       gen_op_stw_T0_T1(ctx);
+       return;
+    case 0x0006:               /* mov.l Rm,@(R0,Rn) */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_add_rN_T1(REG(0));
+       gen_op_stl_T0_T1(ctx);
+       return;
+    case 0x000c:               /* mov.b @(R0,Rm),Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_add_rN_T0(REG(0));
+       gen_op_ldb_T0_T0(ctx);
+       gen_op_movl_T0_rN(REG(B11_8));
+       return;
+    case 0x000d:               /* mov.w @(R0,Rm),Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_add_rN_T0(REG(0));
+       gen_op_ldw_T0_T0(ctx);
+       gen_op_movl_T0_rN(REG(B11_8));
+       return;
+    case 0x000e:               /* mov.l @(R0,Rm),Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_add_rN_T0(REG(0));
+       gen_op_ldl_T0_T0(ctx);
+       gen_op_movl_T0_rN(REG(B11_8));
+       return;
+    case 0x6008:               /* swap.b Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_swapb_T0();
+       gen_op_movl_T0_rN(REG(B11_8));
+       return;
+    case 0x6009:               /* swap.w Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_swapw_T0();
+       gen_op_movl_T0_rN(REG(B11_8));
+       return;
+    case 0x200d:               /* xtrct Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_xtrct_T0_T1();
+       gen_op_movl_T1_rN(REG(B11_8));
+       return;
+    case 0x300c:               /* add Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_add_T0_rN(REG(B11_8));
+       return;
+    case 0x300e:               /* addc Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_addc_T0_T1();
+       gen_op_movl_T1_rN(REG(B11_8));
+       return;
+    case 0x300f:               /* addv Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_addv_T0_T1();
+       gen_op_movl_T1_rN(REG(B11_8));
+       return;
+    case 0x2009:               /* and Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_and_T0_rN(REG(B11_8));
+       return;
+    case 0x3000:               /* cmp/eq Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_cmp_eq_T0_T1();
+       return;
+    case 0x3003:               /* cmp/ge Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_cmp_ge_T0_T1();
+       return;
+    case 0x3007:               /* cmp/gt Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_cmp_gt_T0_T1();
+       return;
+    case 0x3006:               /* cmp/hi Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_cmp_hi_T0_T1();
+       return;
+    case 0x3002:               /* cmp/hs Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_cmp_hs_T0_T1();
+       return;
+    case 0x200c:               /* cmp/str Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_cmp_str_T0_T1();
+       return;
+    case 0x2007:               /* div0s Rm,Rn */
+       printf("div0s\n");
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_div0s_T0_T1();
+       gen_op_movl_T1_rN(REG(B11_8));
+       return;
+    case 0x3004:               /* div1 Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_div1_T0_T1();
+       gen_op_movl_T1_rN(REG(B11_8));
+       return;
+    case 0x300d:               /* dmuls.l Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_dmulsl_T0_T1();
+       return;
+    case 0x3005:               /* dmulu.l Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_dmulul_T0_T1();
+       return;
+    case 0x600e:               /* exts.b Rm,Rn */
+       gen_op_movb_rN_T0(REG(B7_4));
+       gen_op_movl_T0_rN(REG(B11_8));
+       return;
+    case 0x600f:               /* exts.w Rm,Rn */
+       gen_op_movw_rN_T0(REG(B7_4));
+       gen_op_movl_T0_rN(REG(B11_8));
+       return;
+    case 0x600c:               /* extu.b Rm,Rn */
+       gen_op_movub_rN_T0(REG(B7_4));
+       gen_op_movl_T0_rN(REG(B11_8));
+       return;
+    case 0x600d:               /* extu.w Rm,Rn */
+       gen_op_movuw_rN_T0(REG(B7_4));
+       gen_op_movl_T0_rN(REG(B11_8));
+       return;
+    case 0x000f:               /* mac.l @Rm+,@Rn- */
+       gen_op_movl_rN_T0(REG(B11_8));
+       gen_op_ldl_T0_T0(ctx);
+       gen_op_movl_T0_T1();
+       gen_op_movl_rN_T1(REG(B7_4));
+       gen_op_ldl_T0_T0(ctx);
+       gen_op_macl_T0_T1();
+       gen_op_inc4_rN(REG(B7_4));
+       gen_op_inc4_rN(REG(B11_8));
+       return;
+    case 0x400f:               /* mac.w @Rm+,@Rn+ */
+       gen_op_movl_rN_T0(REG(B11_8));
+       gen_op_ldl_T0_T0(ctx);
+       gen_op_movl_T0_T1();
+       gen_op_movl_rN_T1(REG(B7_4));
+       gen_op_ldl_T0_T0(ctx);
+       gen_op_macw_T0_T1();
+       gen_op_inc2_rN(REG(B7_4));
+       gen_op_inc2_rN(REG(B11_8));
+       return;
+    case 0x0007:               /* mul.l Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_mull_T0_T1();
+       return;
+    case 0x200f:               /* muls.w Rm,Rn */
+       gen_op_movw_rN_T0(REG(B7_4));
+       gen_op_movw_rN_T1(REG(B11_8));
+       gen_op_mulsw_T0_T1();
+       return;
+    case 0x200e:               /* mulu.w Rm,Rn */
+       gen_op_movuw_rN_T0(REG(B7_4));
+       gen_op_movuw_rN_T1(REG(B11_8));
+       gen_op_muluw_T0_T1();
+       return;
+    case 0x600b:               /* neg Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_neg_T0();
+       gen_op_movl_T0_rN(REG(B11_8));
+       return;
+    case 0x600a:               /* negc Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_negc_T0();
+       gen_op_movl_T0_rN(REG(B11_8));
+       return;
+    case 0x6007:               /* not Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_not_T0();
+       gen_op_movl_T0_rN(REG(B11_8));
+       return;
+    case 0x200b:               /* or Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_or_T0_rN(REG(B11_8));
+       return;
+    case 0x400c:               /* shad Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_shad_T0_T1();
+       gen_op_movl_T1_rN(REG(B11_8));
+       return;
+    case 0x400d:               /* shld Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_shld_T0_T1();
+       gen_op_movl_T1_rN(REG(B11_8));
+       return;
+    case 0x3008:               /* sub Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_sub_T0_rN(REG(B11_8));
+       return;
+    case 0x300a:               /* subc Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_subc_T0_T1();
+       gen_op_movl_T1_rN(REG(B11_8));
+       return;
+    case 0x300b:               /* subv Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_subv_T0_T1();
+       gen_op_movl_T1_rN(REG(B11_8));
+       return;
+    case 0x2008:               /* tst Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_tst_T0_T1();
+       return;
+    case 0x200a:               /* xor Rm,Rn */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_xor_T0_rN(REG(B11_8));
+       return;
+    }
+
+    switch (ctx->opcode & 0xff00) {
+    case 0xc900:               /* and #imm,R0 */
+       gen_op_and_imm_rN(B7_0, REG(0));
+       return;
+    case 0xcd00:               /* and.b #imm,@(R0+GBR) */
+       gen_op_movl_rN_T0(REG(0));
+       gen_op_addl_GBR_T0();
+       gen_op_movl_T0_T1();
+       gen_op_ldb_T0_T0(ctx);
+       gen_op_and_imm_T0(B7_0);
+       gen_op_stb_T0_T1(ctx);
+       return;
+    case 0x8b00:               /* bf label */
+       CHECK_NOT_DELAY_SLOT
+           gen_conditional_jump(ctx, ctx->pc + 2,
+                                ctx->pc + 4 + B7_0s * 2);
+       ctx->flags |= BRANCH_CONDITIONAL;
+       return;
+    case 0x8f00:               /* bf/s label */
+       CHECK_NOT_DELAY_SLOT
+           gen_op_bf_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
+       ctx->flags |= DELAY_SLOT_CONDITIONAL;
+       return;
+    case 0x8900:               /* bt label */
+       CHECK_NOT_DELAY_SLOT
+           gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
+                                ctx->pc + 2);
+       ctx->flags |= BRANCH_CONDITIONAL;
+       return;
+    case 0x8d00:               /* bt/s label */
+       CHECK_NOT_DELAY_SLOT
+           gen_op_bt_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
+       ctx->flags |= DELAY_SLOT_CONDITIONAL;
+       return;
+    case 0x8800:               /* cmp/eq #imm,R0 */
+       gen_op_movl_rN_T0(REG(0));
+       gen_op_cmp_eq_imm_T0(B7_0s);
+       return;
+    case 0xc400:               /* mov.b @(disp,GBR),R0 */
+       gen_op_stc_gbr_T0();
+       gen_op_addl_imm_T0(B7_0);
+       gen_op_ldb_T0_T0(ctx);
+       gen_op_movl_T0_rN(REG(0));
+       return;
+    case 0xc500:               /* mov.w @(disp,GBR),R0 */
+       gen_op_stc_gbr_T0();
+       gen_op_addl_imm_T0(B7_0);
+       gen_op_ldw_T0_T0(ctx);
+       gen_op_movl_T0_rN(REG(0));
+       return;
+    case 0xc600:               /* mov.l @(disp,GBR),R0 */
+       gen_op_stc_gbr_T0();
+       gen_op_addl_imm_T0(B7_0);
+       gen_op_ldl_T0_T0(ctx);
+       gen_op_movl_T0_rN(REG(0));
+       return;
+    case 0xc000:               /* mov.b R0,@(disp,GBR) */
+       gen_op_stc_gbr_T0();
+       gen_op_addl_imm_T0(B7_0);
+       gen_op_movl_T0_T1();
+       gen_op_movl_rN_T0(REG(0));
+       gen_op_stb_T0_T1(ctx);
+       return;
+    case 0xc100:               /* mov.w R0,@(disp,GBR) */
+       gen_op_stc_gbr_T0();
+       gen_op_addl_imm_T0(B7_0);
+       gen_op_movl_T0_T1();
+       gen_op_movl_rN_T0(REG(0));
+       gen_op_stw_T0_T1(ctx);
+       return;
+    case 0xc200:               /* mov.l R0,@(disp,GBR) */
+       gen_op_stc_gbr_T0();
+       gen_op_addl_imm_T0(B7_0);
+       gen_op_movl_T0_T1();
+       gen_op_movl_rN_T0(REG(0));
+       gen_op_stl_T0_T1(ctx);
+       return;
+    case 0x8000:               /* mov.b R0,@(disp,Rn) */
+       gen_op_movl_rN_T0(REG(0));
+       gen_op_movl_rN_T1(REG(B7_4));
+       gen_op_addl_imm_T1(B3_0);
+       gen_op_stb_T0_T1(ctx);
+       return;
+    case 0x8100:               /* mov.w R0,@(disp,Rn) */
+       gen_op_movl_rN_T0(REG(0));
+       gen_op_movl_rN_T1(REG(B7_4));
+       gen_op_addl_imm_T1(B3_0 * 2);
+       gen_op_stw_T0_T1(ctx);
+       return;
+    case 0x8400:               /* mov.b @(disp,Rn),R0 */
+       gen_op_movl_rN_T0(REG(0));
+       gen_op_movl_rN_T1(REG(B7_4));
+       gen_op_addl_imm_T1(B3_0);
+       gen_op_stb_T0_T1(ctx);
+       return;
+    case 0x8500:               /* mov.w @(disp,Rn),R0 */
+       gen_op_movl_rN_T0(REG(B7_4));
+       gen_op_addl_imm_T0(B3_0 * 2);
+       gen_op_ldw_T0_T0(ctx);
+       gen_op_movl_T0_rN(REG(0));
+       return;
+    case 0xc700:               /* mova @(disp,PC),R0 */
+       gen_op_movl_imm_rN(((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3,
+                          REG(0));
+       return;
+    case 0xcb00:               /* or #imm,R0 */
+       gen_op_or_imm_rN(B7_0, REG(0));
+       return;
+    case 0xcf00:               /* or.b #imm,@(R0+GBR) */
+       gen_op_movl_rN_T0(REG(0));
+       gen_op_addl_GBR_T0();
+       gen_op_movl_T0_T1();
+       gen_op_ldb_T0_T0(ctx);
+       gen_op_or_imm_T0(B7_0);
+       gen_op_stb_T0_T1(ctx);
+       return;
+    case 0xc300:               /* trapa #imm */
+       CHECK_NOT_DELAY_SLOT gen_op_movl_imm_PC(ctx->pc);
+       gen_op_trapa(B7_0);
+       ctx->flags |= BRANCH;
+       return;
+    case 0xc800:               /* tst #imm,R0 */
+       gen_op_tst_imm_rN(B7_0, REG(0));
+       return;
+    case 0xcc00:               /* tst #imm,@(R0+GBR) */
+       gen_op_movl_rN_T0(REG(0));
+       gen_op_addl_GBR_T0();
+       gen_op_ldb_T0_T0(ctx);
+       gen_op_tst_imm_T0(B7_0);
+       return;
+    case 0xca00:               /* xor #imm,R0 */
+       gen_op_xor_imm_rN(B7_0, REG(0));
+       return;
+    case 0xce00:               /* xor.b #imm,@(R0+GBR) */
+       gen_op_movl_rN_T0(REG(0));
+       gen_op_addl_GBR_T0();
+       gen_op_movl_T0_T1();
+       gen_op_ldb_T0_T0(ctx);
+       gen_op_xor_imm_T0(B7_0);
+       gen_op_stb_T0_T1(ctx);
+       return;
+    }
+
+    switch (ctx->opcode & 0xf08f) {
+    case 0x408e:               /* ldc Rm,Rn_BANK */
+       gen_op_movl_rN_rN(REG(B11_8), ALTREG(B6_4));
+       return;
+    case 0x4087:               /* ldc.l @Rm+,Rn_BANK */
+       gen_op_movl_rN_T0(REG(B11_8));
+       gen_op_ldl_T0_T0(ctx);
+       gen_op_movl_T0_rN(ALTREG(B6_4));
+       gen_op_inc4_rN(REG(B11_8));
+       return;
+    case 0x0082:               /* stc Rm_BANK,Rn */
+       gen_op_movl_rN_rN(ALTREG(B6_4), REG(B11_8));
+       return;
+    case 0x4083:               /* stc.l Rm_BANK,@-Rn */
+       gen_op_dec4_rN(REG(B11_8));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_movl_rN_T0(ALTREG(B6_4));
+       gen_op_stl_T0_T1(ctx);
+       return;
+    }
+
+    switch (ctx->opcode & 0xf0ff) {
+    case 0x0023:               /* braf Rn */
+       CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
+       gen_op_braf_T0(ctx->pc + 4);
+       ctx->flags |= DELAY_SLOT;
+       ctx->delayed_pc = (uint32_t) - 1;
+       return;
+    case 0x0003:               /* bsrf Rn */
+       CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
+       gen_op_bsrf_T0(ctx->pc + 4);
+       ctx->flags |= DELAY_SLOT;
+       ctx->delayed_pc = (uint32_t) - 1;
+       return;
+    case 0x4015:               /* cmp/pl Rn */
+       gen_op_movl_rN_T0(REG(B11_8));
+       gen_op_cmp_pl_T0();
+       return;
+    case 0x4011:               /* cmp/pz Rn */
+       gen_op_movl_rN_T0(REG(B11_8));
+       gen_op_cmp_pz_T0();
+       return;
+    case 0x4010:               /* dt Rn */
+       gen_op_dt_rN(REG(B11_8));
+       return;
+    case 0x402b:               /* jmp @Rn */
+       CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
+       gen_op_jmp_T0();
+       ctx->flags |= DELAY_SLOT;
+       ctx->delayed_pc = (uint32_t) - 1;
+       return;
+    case 0x400b:               /* jsr @Rn */
+       CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
+       gen_op_jsr_T0(ctx->pc + 4);
+       ctx->flags |= DELAY_SLOT;
+       ctx->delayed_pc = (uint32_t) - 1;
+       return;
+#define LDST(reg,ldnum,ldpnum,ldop,stnum,stpnum,stop,extrald)  \
+  case ldnum:                                                  \
+    gen_op_movl_rN_T0 (REG(B11_8));                            \
+    gen_op_##ldop##_T0_##reg ();                               \
+    extrald                                                    \
+    return;                                                    \
+  case ldpnum:                                                 \
+    gen_op_movl_rN_T0 (REG(B11_8));                            \
+    gen_op_ldl_T0_T0 (ctx);                                    \
+    gen_op_inc4_rN (REG(B11_8));                               \
+    gen_op_##ldop##_T0_##reg ();                               \
+    extrald                                                    \
+    return;                                                    \
+  case stnum:                                                  \
+    gen_op_##stop##_##reg##_T0 ();                                     \
+    gen_op_movl_T0_rN (REG(B11_8));                            \
+    return;                                                    \
+  case stpnum:                                                 \
+    gen_op_##stop##_##reg##_T0 ();                             \
+    gen_op_dec4_rN (REG(B11_8));                               \
+    gen_op_movl_rN_T1 (REG(B11_8));                            \
+    gen_op_stl_T0_T1 (ctx);                                    \
+    return;
+       LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->flags |=
+            MODE_CHANGE;
+           )
+           LDST(gbr, 0x401e, 0x4017, ldc, 0x0012, 0x4013, stc,)
+           LDST(vbr, 0x402e, 0x4027, ldc, 0x0022, 0x4023, stc,)
+           LDST(ssr, 0x403e, 0x4037, ldc, 0x0032, 0x4033, stc,)
+           LDST(spc, 0x404e, 0x4047, ldc, 0x0042, 0x4043, stc,)
+           LDST(dbr, 0x40fa, 0x40f6, ldc, 0x00fa, 0x40f2, stc,)
+           LDST(mach, 0x400a, 0x4006, lds, 0x000a, 0x4002, sts,)
+           LDST(macl, 0x401a, 0x4016, lds, 0x001a, 0x4012, sts,)
+           LDST(pr, 0x402a, 0x4026, lds, 0x002a, 0x4022, sts,)
+    case 0x00c3:               /* movca.l R0,@Rm */
+       gen_op_movl_rN_T0(REG(0));
+       gen_op_movl_rN_T1(REG(B11_8));
+       gen_op_stl_T0_T1(ctx);
+       return;
+    case 0x0029:               /* movt Rn */
+       gen_op_movt_rN(REG(B11_8));
+       return;
+    case 0x0093:               /* ocbi @Rn */
+       gen_op_movl_rN_T0(REG(B11_8));
+       gen_op_ldl_T0_T0(ctx);
+       return;
+    case 0x00a2:               /* ocbp @Rn */
+       gen_op_movl_rN_T0(REG(B11_8));
+       gen_op_ldl_T0_T0(ctx);
+       return;
+    case 0x00b3:               /* ocbwb @Rn */
+       gen_op_movl_rN_T0(REG(B11_8));
+       gen_op_ldl_T0_T0(ctx);
+       return;
+    case 0x0083:               /* pref @Rn */
+       return;
+    case 0x4024:               /* rotcl Rn */
+       gen_op_rotcl_Rn(REG(B11_8));
+       return;
+    case 0x4025:               /* rotcr Rn */
+       gen_op_rotcr_Rn(REG(B11_8));
+       return;
+    case 0x4004:               /* rotl Rn */
+       gen_op_rotl_Rn(REG(B11_8));
+       return;
+    case 0x4005:               /* rotr Rn */
+       gen_op_rotr_Rn(REG(B11_8));
+       return;
+    case 0x4000:               /* shll Rn */
+    case 0x4020:               /* shal Rn */
+       gen_op_shal_Rn(REG(B11_8));
+       return;
+    case 0x4021:               /* shar Rn */
+       gen_op_shar_Rn(REG(B11_8));
+       return;
+    case 0x4001:               /* shlr Rn */
+       gen_op_shlr_Rn(REG(B11_8));
+       return;
+    case 0x4008:               /* shll2 Rn */
+       gen_op_shll2_Rn(REG(B11_8));
+       return;
+    case 0x4018:               /* shll8 Rn */
+       gen_op_shll8_Rn(REG(B11_8));
+       return;
+    case 0x4028:               /* shll16 Rn */
+       gen_op_shll16_Rn(REG(B11_8));
+       return;
+    case 0x4009:               /* shlr2 Rn */
+       gen_op_shlr2_Rn(REG(B11_8));
+       return;
+    case 0x4019:               /* shlr8 Rn */
+       gen_op_shlr8_Rn(REG(B11_8));
+       return;
+    case 0x4029:               /* shlr16 Rn */
+       gen_op_shlr16_Rn(REG(B11_8));
+       return;
+    case 0x401b:               /* tas.b @Rn */
+       gen_op_tasb_rN(REG(B11_8));
+       return;
+    }
+
+    fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
+           ctx->opcode, ctx->pc);
+    gen_op_raise_illegal_instruction();
+    ctx->flags |= BRANCH_EXCEPTION;
+}
+
+int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
+                                  int search_pc)
+{
+    DisasContext ctx;
+    target_ulong pc_start;
+    static uint16_t *gen_opc_end;
+    uint32_t old_flags;
+    int i;
+
+    pc_start = tb->pc;
+    gen_opc_ptr = gen_opc_buf;
+    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
+    gen_opparam_ptr = gen_opparam_buf;
+    ctx.pc = pc_start;
+    ctx.flags = env->flags;
+    old_flags = 0;
+    ctx.sr = env->sr;
+    ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
+    ctx.delayed_pc = env->delayed_pc;
+    ctx.tb = tb;
+    ctx.singlestep_enabled = env->singlestep_enabled;
+    nb_gen_labels = 0;
+
+#ifdef DEBUG_DISAS
+    if (loglevel & CPU_LOG_TB_CPU) {
+       fprintf(logfile,
+               "------------------------------------------------\n");
+       cpu_dump_state(env, logfile, fprintf, 0);
+    }
+#endif
+
+    while ((old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) == 0 &&
+          (ctx.flags & (BRANCH | BRANCH_CONDITIONAL | MODE_CHANGE |
+                        BRANCH_EXCEPTION)) == 0 &&
+          gen_opc_ptr < gen_opc_end && ctx.sr == env->sr) {
+       old_flags = ctx.flags;
+       if (env->nb_breakpoints > 0) {
+           for (i = 0; i < env->nb_breakpoints; i++) {
+               if (ctx.pc == env->breakpoints[i]) {
+                   /* We have hit a breakpoint - make sure PC is up-to-date */
+                   gen_op_movl_imm_PC(ctx.pc);
+                   gen_op_debug();
+                   ctx.flags |= BRANCH_EXCEPTION;
+                   break;
+               }
+           }
+       }
+#if 0
+       fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
+       fflush(stderr);
+#endif
+       ctx.opcode = lduw_code(ctx.pc);
+       decode_opc(&ctx);
+       ctx.pc += 2;
+       if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
+           break;
+       if (env->singlestep_enabled)
+           break;
+#ifdef SH4_SINGLE_STEP
+       break;
+#endif
+    }
+
+    switch (old_flags & (DELAY_SLOT_CONDITIONAL | DELAY_SLOT)) {
+    case DELAY_SLOT_CONDITIONAL:
+       gen_op_clr_delay_slot_conditional();
+       gen_delayed_conditional_jump(&ctx);
+       break;
+    case DELAY_SLOT:
+       gen_op_clr_delay_slot();
+       gen_jump(&ctx);
+       break;
+    case 0:
+       if (ctx.flags & BRANCH_EXCEPTION) {
+           gen_jump_exception(&ctx);
+       } else if ((ctx.flags & (BRANCH | BRANCH_CONDITIONAL)) == 0) {
+           gen_goto_tb(&ctx, 0, ctx.pc);
+       }
+       break;
+    default:
+       /* Both cannot be set at the same time */
+       assert(0);
+    }
+
+    if (env->singlestep_enabled) {
+       gen_op_debug();
+    }
+    *gen_opc_ptr = INDEX_op_end;
+    tb->size = ctx.pc - pc_start;
+
+#ifdef DEBUG_DISAS
+#ifdef SH4_DEBUG_DISAS
+    if (loglevel & CPU_LOG_TB_IN_ASM)
+       fprintf(logfile, "\n");
+#endif
+    if (loglevel & CPU_LOG_TB_IN_ASM) {
+       fprintf(logfile, "IN:\n");      /* , lookup_symbol(pc_start)); */
+       target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
+       fprintf(logfile, "\n");
+    }
+    if (loglevel & CPU_LOG_TB_OP) {
+       fprintf(logfile, "OP:\n");
+       dump_ops(gen_opc_buf, gen_opparam_buf);
+       fprintf(logfile, "\n");
+    }
+#endif
+    return 0;
+}
+
+int gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
+{
+    return gen_intermediate_code_internal(env, tb, 0);
+}
+
+int gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
+{
+    assert(0);
+    return gen_intermediate_code_internal(env, tb, 1);
+}