bfd:
authorJoern Rennecke <joern.rennecke@embecosm.com>
Thu, 17 Feb 2000 00:33:36 +0000 (00:33 +0000)
committerJoern Rennecke <joern.rennecke@embecosm.com>
Thu, 17 Feb 2000 00:33:36 +0000 (00:33 +0000)
Reinstate bits of sh4 support that got accidentally deleted.
Add sh-dsp support.

bfd:

* archures.c (bfd_mach_sh2, bfd_mach_sh_dsp): New macros.
(bfd_mach_sh3_dsp): Likewise.
(bfd_mach_sh4): Reinstate.
(bfd_default_scan): Recognize 7410, 7708, 7729 and 7750.
* bfd-in2.h: Regenerate.
* coff-sh.c (struct sh_opcode): flags is no longer short.
(USESAS, USESAS_REG, USESR8, SETSAS, SETSAS_REG): New macros.
(sh_opcode41, sh_opcode42): Integrate as sh_opcode41.
(sh_opcode01, sh_opcode02, sh_opcode40): Add sh-dsp opcodes.
(sh_opcode41, sh_opcode4, sh_opcode80): Likewise.
(sh_opcodes): No longer const.
(sh_dsp_opcodef0, sh_dsp_opcodef): New arrays.
(sh_insn_uses_reg): Check for USESAS and USESR8.
(sh_insn_sets_reg, sh_insns_conflict): Check for SETSAS.
(_bfd_sh_align_load_span): Return early for SH4.
Modify sh_opcodes lookup table for sh-dsp / sh3-dsp.
Take into account that field b of a parallel processing insn
could be mistaken for a separate insn.
* cpu-sh.c (arch_info_struct): New array elements for
sh2, sh-dsp and sh3-dsp.
Reinstate element for sh4.
(SH2_NEXT, SH_DSP_NEXT, SH3_DSP_NEXT): New macros.
(SH4_NEXT): Reinstate.
(SH3_NEXT, SH3E_NEXT): Adjust.
* elf-bfd.h (_sh_elf_set_mach_from_flags): Declare.
* elf32-sh.c (sh_elf_set_private_flags): New function.
(sh_elf_copy_private_data, sh_elf_set_mach_from_flags): Likewise.
(sh_elf_merge_private_data): New function.
(elf_backend_object_p, bfd_elf32_bfd_set_private_bfd_flags): Define.
(bfd_elf32_bfd_copy_private_bfd_data): Define.
(bfd_elf32_bfd_merge_private_bfd_data): Change to
sh_elf_merge_private_data.

gas:

* config/tc-sh.c ("elf/sh.h"): Include.
(sh_dsp, valid_arch, reg_x, reg_y, reg_efg): New static variables.
(md.begin): Initialize target_arch.
Only include opcodes in has table that match selected architecture.
(parse_reg): Recognize register names for sh-dsp.
(parse_at): Recognize post-modify addressing.
(get_operands): The leading space is now optional.
(get_specific): Remove FDREG_N support.  Add support for sh-dsp
arguments.  Update valid_arch.
(build_Mytes): Add support for SDT_REG_N.
(find_cooked_opcode): New function, broken out of md_assemble.
(assemble_ppi, sh_elf_final_processing): New functions.
(md_assemble): Use find_cooked_opcode and assemble_ppi.
(md_longopts, md_parse_option): New option: -dsp.
* config/tc-sh.h (elf_tc_final_processing): Define.
(sh_elf_final_processing): Declare.

include/elf:

* sh.h: (EF_SH_MACH_MASK, EF_SH_UNKNOWN, EF_SH1, EF_SH2): New macros.
(EF_SH3, EF_SH_HAS_DSP, EF_SH_DSP, EF_SH3_DSP): Likewise.
(EF_SH_HAS_FP, EF_SH3E, EF_SH4, EF_SH_MERGE_MACH): Likewise.

opcodes:

* sh-dis.c (print_movxy, print_insn_ddt, print_dsp_reg): New functions.
(print_insn_ppi): Likewise.
(print_insn_shx): Use info->mach to select appropriate insn set.
Add support for sh-dsp.  Remove FD_REG_N support.
* sh-opc.h (sh_nibble_type): Add new values for sh-dsp support.
(sh_arg_type): Likewise.  Remove FD_REG_N.
(sh_dsp_reg_nums): New enum.
(arch_sh1, arch_sh2, arch_sh3, arch_sh3e, arch_sh4): New macros.
(arch_sh_dsp, arch_sh3_dsp, arch_sh1_up, arch_sh2_up): Likewise.
(arch_sh3_up, arch_sh3e_up, arch_sh4_up, arch_sh_dsp_up): Likewise.
(arch_sh3_dsp_up): Likewise.
(sh_opcode_info): New field: arch.
(sh_table): Split up insn with FD_REG_N into ones with F_REG_N and
D_REG_N.  Fill in arch field.  Add sh-dsp insns.

15 files changed:
bfd/ChangeLog
bfd/archures.c
bfd/bfd-in2.h
bfd/coff-sh.c
bfd/cpu-sh.c
bfd/elf-bfd.h
bfd/elf32-sh.c
gas/ChangeLog
gas/config/tc-sh.c
gas/config/tc-sh.h
include/elf/ChangeLog
include/elf/sh.h
opcodes/ChangeLog
opcodes/sh-dis.c
opcodes/sh-opc.h

index c3425db..7cd1a34 100644 (file)
@@ -1,3 +1,38 @@
+Thu Feb 17 00:04:48 2000  J"orn Rennecke <amylaar@cygnus.co.uk>
+
+       * archures.c (bfd_mach_sh2, bfd_mach_sh_dsp): New macros.
+       (bfd_mach_sh3_dsp): Likewise.
+       (bfd_mach_sh4): Reinstate.
+       (bfd_default_scan): Recognize 7410, 7708, 7729 and 7750.
+       * bfd-in2.h: Regenerate.
+       * coff-sh.c (struct sh_opcode): flags is no longer short.
+       (USESAS, USESAS_REG, USESR8, SETSAS, SETSAS_REG): New macros.
+       (sh_opcode41, sh_opcode42): Integrate as sh_opcode41.
+       (sh_opcode01, sh_opcode02, sh_opcode40): Add sh-dsp opcodes.
+       (sh_opcode41, sh_opcode4, sh_opcode80): Likewise.
+       (sh_opcodes): No longer const.
+       (sh_dsp_opcodef0, sh_dsp_opcodef): New arrays.
+       (sh_insn_uses_reg): Check for USESAS and USESR8.
+       (sh_insn_sets_reg, sh_insns_conflict): Check for SETSAS.
+       (_bfd_sh_align_load_span): Return early for SH4.
+       Modify sh_opcodes lookup table for sh-dsp / sh3-dsp.
+       Take into account that field b of a parallel processing insn
+       could be mistaken for a separate insn.
+       * cpu-sh.c (arch_info_struct): New array elements for
+       sh2, sh-dsp and sh3-dsp.
+       Reinstate element for sh4.
+       (SH2_NEXT, SH_DSP_NEXT, SH3_DSP_NEXT): New macros.
+       (SH4_NEXT): Reinstate.
+       (SH3_NEXT, SH3E_NEXT): Adjust.
+       * elf-bfd.h (_sh_elf_set_mach_from_flags): Declare.
+       * elf32-sh.c (sh_elf_set_private_flags): New function.
+       (sh_elf_copy_private_data, sh_elf_set_mach_from_flags): Likewise.
+       (sh_elf_merge_private_data): New function.
+       (elf_backend_object_p, bfd_elf32_bfd_set_private_bfd_flags): Define.
+       (bfd_elf32_bfd_copy_private_bfd_data): Define.
+       (bfd_elf32_bfd_merge_private_bfd_data): Change to
+       sh_elf_merge_private_data.
+
 2000-02-13  Richard Henderson  <rth@cygnus.com>
 
        * elf-bfd.h (struct elf_link_hash_table): Add copy_indirect and
index 95d5d39..3c7dc13 100644 (file)
@@ -1,5 +1,6 @@
 /* BFD library support routines for architectures.
-   Copyright (C) 1990, 91-98, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999, 2000
+   Free Software Foundation, Inc.
    Hacked by John Gilmore and Steve Chamberlain of Cygnus Support.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -157,8 +158,12 @@ DESCRIPTION
 .  bfd_arch_h8500,     {* Hitachi H8/500 *}
 .  bfd_arch_sh,        {* Hitachi SH *}
 .#define bfd_mach_sh            0
+.#define bfd_mach_sh2        0x20
+.#define bfd_mach_sh_dsp     0x2d
 .#define bfd_mach_sh3        0x30
+.#define bfd_mach_sh3_dsp    0x3d
 .#define bfd_mach_sh3e       0x3e
+.#define bfd_mach_sh4        0x40
 .  bfd_arch_alpha,     {* Dec Alpha *}
 .#define bfd_mach_alpha_ev4  0x10
 .#define bfd_mach_alpha_ev5  0x20
@@ -805,6 +810,26 @@ bfd_default_scan (info, string)
       arch = bfd_arch_rs6000;
       break;
 
+    case 7410:
+      arch = bfd_arch_sh;
+      number = bfd_mach_sh_dsp;
+      break;
+
+    case 7708:
+      arch = bfd_arch_sh;
+      number = bfd_mach_sh3;
+      break;
+
+    case 7729:
+      arch = bfd_arch_sh;
+      number = bfd_mach_sh3_dsp;
+      break;
+
+    case 7750:
+      arch = bfd_arch_sh;
+      number = bfd_mach_sh4;
+      break;
+
     default:  
       return false;
     }
index 7ec5d70..d7b52db 100644 (file)
@@ -1362,8 +1362,12 @@ enum bfd_architecture
   bfd_arch_h8500,      /* Hitachi H8/500 */
   bfd_arch_sh,         /* Hitachi SH */
 #define bfd_mach_sh            0
+#define bfd_mach_sh2        0x20
+#define bfd_mach_sh_dsp     0x2d
 #define bfd_mach_sh3        0x30
+#define bfd_mach_sh3_dsp    0x3d
 #define bfd_mach_sh3e       0x3e
+#define bfd_mach_sh4        0x40
   bfd_arch_alpha,      /* Dec Alpha */
 #define bfd_mach_alpha_ev4  0x10
 #define bfd_mach_alpha_ev5  0x20
index 7a3af1a..e505a1a 100644 (file)
@@ -1364,7 +1364,7 @@ struct sh_opcode
      mask value in the sh_major_opcode structure.  */
   unsigned short opcode;
   /* Flags for this instruction.  */
-  unsigned short flags;
+  unsigned flags;
 };
 
 /* Flag which appear in the sh_opcode structure.  */
@@ -1431,6 +1431,12 @@ struct sh_opcode
 #define SETSF1 (0x8000)
 #define SETSF1_REG(x) ((x & 0x0f00) >> 8)
 
+#define USESAS (0x10000)
+#define USESAS_REG(x) (((((x) >> 8) - 2) & 3) + 2)
+#define USESR8 (0x20000)
+#define SETSAS (0x40000)
+#define SETSAS_REG(x) USESAS_REG (x)
+
 static boolean sh_insn_uses_reg
   PARAMS ((unsigned int, const struct sh_opcode *, unsigned int));
 static boolean sh_insn_sets_reg
@@ -1471,21 +1477,33 @@ static const struct sh_opcode sh_opcode00[] =
 
 static const struct sh_opcode sh_opcode01[] =
 {
-  { 0x0002, SETS1 | USESSP },                  /* stc sr,rn */
   { 0x0003, BRANCH | DELAY | USES1 | SETSSP }, /* bsrf rn */
   { 0x000a, SETS1 | USESSP },                  /* sts mach,rn */
-  { 0x0012, SETS1 | USESSP },                  /* stc gbr,rn */
   { 0x001a, SETS1 | USESSP },                  /* sts macl,rn */
-  { 0x0022, SETS1 | USESSP },                  /* stc vbr,rn */
   { 0x0023, BRANCH | DELAY | USES1 },          /* braf rn */
   { 0x0029, SETS1 | USESSP },                  /* movt rn */
   { 0x002a, SETS1 | USESSP },                  /* sts pr,rn */
+  { 0x005a, SETS1 | USESSP },                  /* sts fpul,rn */
+  { 0x006a, SETS1 | USESSP },                  /* sts fpscr,rn / sts dsr,rn */
+  { 0x0083, LOAD | USES1 },                    /* pref @rn */
+  { 0x007a, SETS1 | USESSP },                  /* sts a0,rn */
+  { 0x008a, SETS1 | USESSP },                  /* sts x0,rn */
+  { 0x009a, SETS1 | USESSP },                  /* sts x1,rn */
+  { 0x00aa, SETS1 | USESSP },                  /* sts y0,rn */
+  { 0x00ba, SETS1 | USESSP }                   /* sts y1,rn */
+};
+
+/* These sixteen instructions can be handled with one table entry below.  */
+#if 0
+  { 0x0002, SETS1 | USESSP },                  /* stc sr,rn */
+  { 0x0012, SETS1 | USESSP },                  /* stc gbr,rn */
+  { 0x0022, SETS1 | USESSP },                  /* stc vbr,rn */
   { 0x0032, SETS1 | USESSP },                  /* stc ssr,rn */
   { 0x0042, SETS1 | USESSP },                  /* stc spc,rn */
-  { 0x005a, SETS1 | USESSP },                  /* sts fpul,rn */
-  { 0x006a, SETS1 | USESSP },                  /* sts fpscr,rn */
+  { 0x0052, SETS1 | USESSP },                  /* stc mod,rn */
+  { 0x0062, SETS1 | USESSP },                  /* stc rs,rn */
+  { 0x0072, SETS1 | USESSP },                  /* stc re,rn */
   { 0x0082, SETS1 | USESSP },                  /* stc r0_bank,rn */
-  { 0x0083, LOAD | USES1 },                    /* pref @rn */
   { 0x0092, SETS1 | USESSP },                  /* stc r1_bank,rn */
   { 0x00a2, SETS1 | USESSP },                  /* stc r2_bank,rn */
   { 0x00b2, SETS1 | USESSP },                  /* stc r3_bank,rn */
@@ -1493,10 +1511,11 @@ static const struct sh_opcode sh_opcode01[] =
   { 0x00d2, SETS1 | USESSP },                  /* stc r5_bank,rn */
   { 0x00e2, SETS1 | USESSP },                  /* stc r6_bank,rn */
   { 0x00f2, SETS1 | USESSP }                   /* stc r7_bank,rn */
-};
+#endif
 
 static const struct sh_opcode sh_opcode02[] =
 {
+  { 0x0002, SETS1 | USESSP },                  /* stc <special_reg>,rn */
   { 0x0004, STORE | USES1 | USES2 | USESR0 },  /* mov.b rm,@(r0,rn) */
   { 0x0005, STORE | USES1 | USES2 | USESR0 },  /* mov.w rm,@(r0,rn) */
   { 0x0006, STORE | USES1 | USES2 | USESR0 },  /* mov.l rm,@(r0,rn) */
@@ -1576,74 +1595,108 @@ static const struct sh_opcode sh_opcode40[] =
   { 0x4000, SETS1 | SETSSP | USES1 },          /* shll rn */
   { 0x4001, SETS1 | SETSSP | USES1 },          /* shlr rn */
   { 0x4002, STORE | SETS1 | USES1 | USESSP },  /* sts.l mach,@-rn */
-  { 0x4003, STORE | SETS1 | USES1 | USESSP },  /* stc.l sr,@-rn */
   { 0x4004, SETS1 | SETSSP | USES1 },          /* rotl rn */
   { 0x4005, SETS1 | SETSSP | USES1 },          /* rotr rn */
   { 0x4006, LOAD | SETS1 | SETSSP | USES1 },   /* lds.l @rm+,mach */
-  { 0x4007, LOAD | SETS1 | SETSSP | USES1 },   /* ldc.l @rm+,sr */
   { 0x4008, SETS1 | USES1 },                   /* shll2 rn */
   { 0x4009, SETS1 | USES1 },                   /* shlr2 rn */
   { 0x400a, SETSSP | USES1 },                  /* lds rm,mach */
   { 0x400b, BRANCH | DELAY | USES1 },          /* jsr @rn */
-  { 0x400e, SETSSP | USES1 },                  /* ldc rm,sr */
   { 0x4010, SETS1 | SETSSP | USES1 },          /* dt rn */
   { 0x4011, SETSSP | USES1 },                  /* cmp/pz rn */
   { 0x4012, STORE | SETS1 | USES1 | USESSP },  /* sts.l macl,@-rn */
-  { 0x4013, STORE | SETS1 | USES1 | USESSP },  /* stc.l gbr,@-rn */
+  { 0x4014, SETSSP | USES1 },                  /* setrc rm */
   { 0x4015, SETSSP | USES1 },                  /* cmp/pl rn */
   { 0x4016, LOAD | SETS1 | SETSSP | USES1 },   /* lds.l @rm+,macl */
-  { 0x4017, LOAD | SETS1 | SETSSP | USES1 },   /* ldc.l @rm+,gbr */
   { 0x4018, SETS1 | USES1 },                   /* shll8 rn */
   { 0x4019, SETS1 | USES1 },                   /* shlr8 rn */
   { 0x401a, SETSSP | USES1 },                  /* lds rm,macl */
   { 0x401b, LOAD | SETSSP | USES1 },           /* tas.b @rn */
-  { 0x401e, SETSSP | USES1 },                  /* ldc rm,gbr */
   { 0x4020, SETS1 | SETSSP | USES1 },          /* shal rn */
   { 0x4021, SETS1 | SETSSP | USES1 },          /* shar rn */
   { 0x4022, STORE | SETS1 | USES1 | USESSP },  /* sts.l pr,@-rn */
-  { 0x4023, STORE | SETS1 | USES1 | USESSP },  /* stc.l vbr,@-rn */
   { 0x4024, SETS1 | SETSSP | USES1 | USESSP }, /* rotcl rn */
   { 0x4025, SETS1 | SETSSP | USES1 | USESSP }, /* rotcr rn */
   { 0x4026, LOAD | SETS1 | SETSSP | USES1 },   /* lds.l @rm+,pr */
-  { 0x4027, LOAD | SETS1 | SETSSP | USES1 },   /* ldc.l @rm+,vbr */
   { 0x4028, SETS1 | USES1 },                   /* shll16 rn */
   { 0x4029, SETS1 | USES1 },                   /* shlr16 rn */
   { 0x402a, SETSSP | USES1 },                  /* lds rm,pr */
   { 0x402b, BRANCH | DELAY | USES1 },          /* jmp @rn */
-  { 0x402e, SETSSP | USES1 },                  /* ldc rm,vbr */
+  { 0x4052, STORE | SETS1 | USES1 | USESSP },  /* sts.l fpul,@-rn */
+  { 0x4056, LOAD | SETS1 | SETSSP | USES1 },   /* lds.l @rm+,fpul */
+  { 0x405a, SETSSP | USES1 },                  /* lds.l rm,fpul */
+  { 0x4062, STORE | SETS1 | USES1 | USESSP },  /* sts.l fpscr / dsr,@-rn */
+  { 0x4066, LOAD | SETS1 | SETSSP | USES1 },   /* lds.l @rm+,fpscr / dsr */
+  { 0x406a, SETSSP | USES1 },                  /* lds rm,fpscr / lds rm,dsr */
+  { 0x4072, STORE | SETS1 | USES1 | USESSP },  /* sts.l a0,@-rn */
+  { 0x4076, LOAD | SETS1 | SETSSP | USES1 },   /* lds.l @rm+,a0 */
+  { 0x407a, SETSSP | USES1 },                  /* lds.l rm,a0 */
+  { 0x4082, STORE | SETS1 | USES1 | USESSP },  /* sts.l x0,@-rn */
+  { 0x4086, LOAD | SETS1 | SETSSP | USES1 },   /* lds.l @rm+,x0 */
+  { 0x408a, SETSSP | USES1 },                  /* lds.l rm,x0 */
+  { 0x4092, STORE | SETS1 | USES1 | USESSP },  /* sts.l x1,@-rn */
+  { 0x4096, LOAD | SETS1 | SETSSP | USES1 },   /* lds.l @rm+,x1 */
+  { 0x409a, SETSSP | USES1 },                  /* lds.l rm,x1 */
+  { 0x40a2, STORE | SETS1 | USES1 | USESSP },  /* sts.l y0,@-rn */
+  { 0x40a6, LOAD | SETS1 | SETSSP | USES1 },   /* lds.l @rm+,y0 */
+  { 0x40aa, SETSSP | USES1 },                  /* lds.l rm,y0 */
+  { 0x40b2, STORE | SETS1 | USES1 | USESSP },  /* sts.l y1,@-rn */
+  { 0x40b6, LOAD | SETS1 | SETSSP | USES1 },   /* lds.l @rm+,y1 */
+  { 0x40ba, SETSSP | USES1 }                   /* lds.l rm,y1 */
+#if 0 /* These groups sixteen insns can be
+         handled with one table entry each below.  */
+  { 0x4003, STORE | SETS1 | USES1 | USESSP },  /* stc.l sr,@-rn */
+  { 0x4013, STORE | SETS1 | USES1 | USESSP },  /* stc.l gbr,@-rn */
+  { 0x4023, STORE | SETS1 | USES1 | USESSP },  /* stc.l vbr,@-rn */
   { 0x4033, STORE | SETS1 | USES1 | USESSP },  /* stc.l ssr,@-rn */
-  { 0x4037, LOAD | SETS1 | SETSSP | USES1 },   /* ldc.l @rm+,ssr */
-  { 0x403e, SETSSP | USES1 },                  /* ldc rm,ssr */
   { 0x4043, STORE | SETS1 | USES1 | USESSP },  /* stc.l spc,@-rn */
+  { 0x4053, STORE | SETS1 | USES1 | USESSP },  /* stc.l mod,@-rn */
+  { 0x4063, STORE | SETS1 | USES1 | USESSP },  /* stc.l rs,@-rn */
+  { 0x4073, STORE | SETS1 | USES1 | USESSP },  /* stc.l re,@-rn */
+  { 0x4083, STORE | SETS1 | USES1 | USESSP },  /* stc.l r0_bank,@-rn */
+  ..
+  { 0x40f3, STORE | SETS1 | USES1 | USESSP },  /* stc.l r7_bank,@-rn */
+
+  { 0x4007, LOAD | SETS1 | SETSSP | USES1 },   /* ldc.l @rm+,sr */
+  { 0x4017, LOAD | SETS1 | SETSSP | USES1 },   /* ldc.l @rm+,gbr */
+  { 0x4027, LOAD | SETS1 | SETSSP | USES1 },   /* ldc.l @rm+,vbr */
+  { 0x4037, LOAD | SETS1 | SETSSP | USES1 },   /* ldc.l @rm+,ssr */
   { 0x4047, LOAD | SETS1 | SETSSP | USES1 },   /* ldc.l @rm+,spc */
+  { 0x4057, LOAD | SETS1 | SETSSP | USES1 },   /* ldc.l @rm+,mod */
+  { 0x4067, LOAD | SETS1 | SETSSP | USES1 },   /* ldc.l @rm+,rs */
+  { 0x4077, LOAD | SETS1 | SETSSP | USES1 },   /* ldc.l @rm+,re */
+  { 0x4087, LOAD | SETS1 | SETSSP | USES1 },   /* ldc.l @rm+,r0_bank */
+  ..
+  { 0x40f7, LOAD | SETS1 | SETSSP | USES1 },   /* ldc.l @rm+,r7_bank */
+
+  { 0x400e, SETSSP | USES1 },                  /* ldc rm,sr */
+  { 0x401e, SETSSP | USES1 },                  /* ldc rm,gbr */
+  { 0x402e, SETSSP | USES1 },                  /* ldc rm,vbr */
+  { 0x403e, SETSSP | USES1 },                  /* ldc rm,ssr */
   { 0x404e, SETSSP | USES1 },                  /* ldc rm,spc */
-  { 0x4052, STORE | SETS1 | USES1 | USESSP },  /* sts.l fpul,@-rn */
-  { 0x4056, LOAD | SETS1 | SETSSP | USES1 },   /* lds.l @rm+,fpul */
-  { 0x405a, SETSSP | USES1 },                  /* lds.l rm,fpul */
-  { 0x4062, STORE | SETS1 | USES1 | USESSP },  /* sts.l fpscr,@-rn */
-  { 0x4066, LOAD | SETS1 | SETSSP | USES1 },   /* lds.l @rm+,fpscr */
-  { 0x406a, SETSSP | USES1 }                   /* lds rm,fpscr */
+  { 0x405e, SETSSP | USES1 },                  /* ldc rm,mod */
+  { 0x406e, SETSSP | USES1 },                  /* ldc rm,rs */
+  { 0x407e, SETSSP | USES1 }                   /* ldc rm,re */
+  { 0x408e, SETSSP | USES1 }                   /* ldc rm,r0_bank */
+  ..
+  { 0x40fe, SETSSP | USES1 }                   /* ldc rm,r7_bank */
+#endif
 };
 
 static const struct sh_opcode sh_opcode41[] =
 {
-  { 0x4083, STORE | SETS1 | USES1 | USESSP },  /* stc.l rx_bank,@-rn */
-  { 0x4087, LOAD | SETS1 | SETSSP | USES1 },   /* ldc.l @rm+,rx_bank */
-  { 0x408e, SETSSP | USES1 }                   /* ldc rm,rx_bank */
-};
-
-static const struct sh_opcode sh_opcode42[] =
-{
-  { 0x400c, SETS1 | USES1 | USES2 },                   /* shad rm,rn */
-  { 0x400d, SETS1 | USES1 | USES2 },                   /* shld rm,rn */
+  { 0x4003, STORE | SETS1 | USES1 | USESSP },  /* stc.l <special_reg>,@-rn */
+  { 0x4007, LOAD | SETS1 | SETSSP | USES1 },   /* ldc.l @rm+,<special_reg> */
+  { 0x400c, SETS1 | USES1 | USES2 },           /* shad rm,rn */
+  { 0x400d, SETS1 | USES1 | USES2 },           /* shld rm,rn */
+  { 0x400e, SETSSP | USES1 },                  /* ldc rm,<special_reg> */
   { 0x400f, LOAD|SETS1|SETS2|SETSSP|USES1|USES2|USESSP }, /* mac.w @rm+,@rn+ */
 };
 
 static const struct sh_minor_opcode sh_opcode4[] =
 {
   { MAP (sh_opcode40), 0xf0ff },
-  { MAP (sh_opcode41), 0xf08f },
-  { MAP (sh_opcode42), 0xf00f }
+  { MAP (sh_opcode41), 0xf00f }
 };
 
 static const struct sh_opcode sh_opcode50[] =
@@ -1695,12 +1748,15 @@ static const struct sh_opcode sh_opcode80[] =
 {
   { 0x8000, STORE | USES2 | USESR0 },  /* mov.b r0,@(disp,rn) */
   { 0x8100, STORE | USES2 | USESR0 },  /* mov.w r0,@(disp,rn) */
+  { 0x8200, SETSSP },                  /* setrc #imm */
   { 0x8400, LOAD | SETSR0 | USES2 },   /* mov.b @(disp,rm),r0 */
   { 0x8500, LOAD | SETSR0 | USES2 },   /* mov.w @(disp,rn),r0 */
   { 0x8800, SETSSP | USESR0 },         /* cmp/eq #imm,r0 */
   { 0x8900, BRANCH | USESSP },         /* bt label */
   { 0x8b00, BRANCH | USESSP },         /* bf label */
+  { 0x8c00, SETSSP },                  /* ldrs @(disp,pc) */
   { 0x8d00, BRANCH | DELAY | USESSP }, /* bt/s label */
+  { 0x8e00, SETSSP },                  /* ldre @(disp,pc) */
   { 0x8f00, BRANCH | DELAY | USESSP }  /* bf/s label */
 };
 
@@ -1822,7 +1878,7 @@ static const struct sh_minor_opcode sh_opcodef[] =
   { MAP (sh_opcodef1), 0xf0ff }
 };
 
-static const struct sh_major_opcode sh_opcodes[] =
+static struct sh_major_opcode sh_opcodes[] =
 {
   { MAP (sh_opcode0) },
   { MAP (sh_opcode1) },
@@ -1842,6 +1898,26 @@ static const struct sh_major_opcode sh_opcodes[] =
   { MAP (sh_opcodef) }
 };
 
+/* The double data transfer / parallel processing insns are not
+   described here.  This will cause sh_align_load_span to leave them alone.  */
+
+static const struct sh_opcode sh_dsp_opcodef0[] =
+{
+  { 0xf400, USESAS | SETSAS | LOAD | SETSSP }, /* movs.x @-as,ds */
+  { 0xf401, USESAS | SETSAS | STORE | USESSP },        /* movs.x ds,@-as */
+  { 0xf404, USESAS | LOAD | SETSSP },          /* movs.x @as,ds */
+  { 0xf405, USESAS | STORE | USESSP },         /* movs.x ds,@as */
+  { 0xf408, USESAS | SETSAS | LOAD | SETSSP }, /* movs.x @as+,ds */
+  { 0xf409, USESAS | SETSAS | STORE | USESSP },        /* movs.x ds,@as+ */
+  { 0xf40c, USESAS | SETSAS | LOAD | SETSSP | USESR8 },        /* movs.x @as+r8,ds */
+  { 0xf40d, USESAS | SETSAS | STORE | USESSP | USESR8 }        /* movs.x ds,@as+r8 */
+};
+
+static const struct sh_minor_opcode sh_dsp_opcodef[] =
+{
+  { MAP (sh_dsp_opcodef0), 0xfc0d }
+};
+
 /* Given an instruction, return a pointer to the corresponding
    sh_opcode structure.  Return NULL if the instruction is not
    recognized.  */
@@ -1910,6 +1986,10 @@ sh_insn_uses_reg (insn, op, reg)
   if ((f & USESR0) != 0
       && reg == 0)
     return true;
+  if ((f & USESAS) && reg == USESAS_REG (insn))
+    return true;
+  if ((f & USESR8) && reg == 8)
+    return true;
 
   return false;
 }
@@ -1934,6 +2014,8 @@ sh_insn_sets_reg (insn, op, reg)
   if ((f & SETSR0) != 0
       && reg == 0)
     return true;
+  if ((f & SETSAS) && reg == SETSAS_REG (insn))
+    return true;
 
   return false;
 }
@@ -2055,6 +2137,9 @@ sh_insns_conflict (i1, op1, i2, op2)
   if ((f1 & SETSR0) != 0
       && sh_insn_uses_or_sets_reg (i2, op2, 0))
     return true;
+  if ((f1 & SETSAS)
+      && sh_insn_uses_or_sets_reg (i2, op2, SETSAS_REG (i1)))
+    return true;
   if ((f1 & SETSF1) != 0
       && sh_insn_uses_or_sets_freg (i2, op2, SETSF1_REG (i1)))
     return true;
@@ -2068,6 +2153,9 @@ sh_insns_conflict (i1, op1, i2, op2)
   if ((f2 & SETSR0) != 0
       && sh_insn_uses_or_sets_reg (i1, op1, 0))
     return true;
+  if ((f2 & SETSAS)
+      && sh_insn_uses_or_sets_reg (i1, op1, SETSAS_REG (i2)))
+    return true;
   if ((f2 & SETSF1) != 0
       && sh_insn_uses_or_sets_freg (i1, op1, SETSF1_REG (i2)))
     return true;
@@ -2136,8 +2224,24 @@ _bfd_sh_align_load_span (abfd, sec, contents, swap, relocs,
      bfd_vma stop;
      boolean *pswapped;
 {
+  int dsp = (abfd->arch_info->mach == bfd_mach_sh_dsp
+            || abfd->arch_info->mach == bfd_mach_sh3_dsp);
   bfd_vma i;
 
+  /* The SH4 has a Harvard architecture, hence aligning loads is not
+     desirable.  In fact, it is counter-productive, since it interferes
+     with the schedules generated by the compiler.  */
+  if (abfd->arch_info->mach == bfd_mach_sh4)
+    return true;
+
+  /* If we are linking sh[3]-dsp code, swap the FPU instructions for DSP
+     instructions.  */
+  if (dsp)
+    {
+      sh_opcodes[0xf].minor_opcodes = sh_dsp_opcodef;
+      sh_opcodes[0xf].count = sizeof sh_dsp_opcodef / sizeof sh_dsp_opcodef;
+    }
+
   /* Instructions should be aligned on 2 byte boundaries.  */
   if ((start & 1) == 1)
     ++start;
@@ -2167,7 +2271,28 @@ _bfd_sh_align_load_span (abfd, sec, contents, swap, relocs,
       if (i > start)
        {
          prev_insn = bfd_get_16 (abfd, contents + i - 2);
-         prev_op = sh_insn_info (prev_insn);
+         /* If INSN is the field b of a parallel processing insn, it is not
+            a load / store after all.  Note that the test here might mistake
+            the field_b of a pcopy insn for the starting code of a parallel
+            processing insn; this might miss a swapping opportunity, but at
+            least we're on the safe side.  */
+         if (dsp && (prev_insn & 0xfc00) == 0xf800)
+           continue;
+
+         /* Check if prev_insn is actually the field b of a parallel
+            processing insn.  Again, this can give a spurious match
+            after a pcopy.  */
+         if (dsp && i - 2 > start)
+           {
+             unsigned pprev_insn = bfd_get_16 (abfd, contents + i - 4);
+       
+             if ((pprev_insn & 0xfc00) == 0xf800)
+               prev_op = NULL;
+             else
+               prev_op = sh_insn_info (prev_insn);
+           }
+         else
+           prev_op = sh_insn_info (prev_insn);
 
          /* If the load/store instruction is in a delay slot, we
             can't swap.  */
index 44adf92..cb54e7d 100644 (file)
@@ -1,5 +1,5 @@
 /* BFD library support routines for the Hitachi-SH architecture.
-   Copyright (C) 1993 Free Software Foundation, Inc.
+   Copyright (C) 1993, 97, 1998, 2000 Free Software Foundation, Inc.
    Hacked by Steve Chamberlain of Cygnus Support.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -50,8 +50,12 @@ compatible (a,b)
 #endif
 
 #define SH_NEXT &arch_info_struct[0]
-#define SH3_NEXT &arch_info_struct[1]
-#define SH3E_NEXT NULL
+#define SH2_NEXT &arch_info_struct[1]
+#define SH_DSP_NEXT &arch_info_struct[2]
+#define SH3_NEXT &arch_info_struct[3]
+#define SH3_DSP_NEXT &arch_info_struct[4]
+#define SH3E_NEXT &arch_info_struct[5]
+#define SH4_NEXT NULL
 
 static const bfd_arch_info_type arch_info_struct[] = 
 {
@@ -60,6 +64,34 @@ static const bfd_arch_info_type arch_info_struct[] =
     32,                                /* 32 bits in an address */
     8,                         /* 8 bits in a byte */
     bfd_arch_sh,
+    bfd_mach_sh2,
+    "sh",                      /* arch_name  */
+    "sh2",                     /* printable name */
+    1,
+    false,                     /* not the default */
+    bfd_default_compatible,
+    scan_mach,
+    SH2_NEXT
+  },
+  {
+    32,                                /* 32 bits in a word */
+    32,                                /* 32 bits in an address */
+    8,                         /* 8 bits in a byte */
+    bfd_arch_sh,
+    bfd_mach_sh_dsp,
+    "sh",                      /* arch_name  */
+    "sh-dsp",                  /* printable name */
+    1,
+    false,                     /* not the default */
+    bfd_default_compatible,
+    scan_mach,
+    SH_DSP_NEXT
+  },
+  {
+    32,                                /* 32 bits in a word */
+    32,                                /* 32 bits in an address */
+    8,                         /* 8 bits in a byte */
+    bfd_arch_sh,
     bfd_mach_sh3,
     "sh",                      /* arch_name  */
     "sh3",                     /* printable name */
@@ -74,6 +106,20 @@ static const bfd_arch_info_type arch_info_struct[] =
     32,                                /* 32 bits in an address */
     8,                         /* 8 bits in a byte */
     bfd_arch_sh,
+    bfd_mach_sh3_dsp,
+    "sh",                      /* arch_name  */
+    "sh3-dsp",                 /* printable name */
+    1,
+    false,                     /* not the default */
+    bfd_default_compatible,
+    scan_mach,
+    SH3_DSP_NEXT
+  },
+  {
+    32,                                /* 32 bits in a word */
+    32,                                /* 32 bits in an address */
+    8,                         /* 8 bits in a byte */
+    bfd_arch_sh,
     bfd_mach_sh3e,
     "sh",                      /* arch_name  */
     "sh3e",                    /* printable name */
@@ -83,6 +129,20 @@ static const bfd_arch_info_type arch_info_struct[] =
     scan_mach,
     SH3E_NEXT
   },
+  {
+    32,                                /* 32 bits in a word */
+    32,                                /* 32 bits in an address */
+    8,                         /* 8 bits in a byte */
+    bfd_arch_sh,
+    bfd_mach_sh4,
+    "sh",                      /* arch_name  */
+    "sh4",                     /* printable name */
+    1,
+    false,                     /* not the default */
+    bfd_default_compatible,
+    scan_mach,
+    SH4_NEXT
+  },
 };
 
 const bfd_arch_info_type bfd_sh_arch =
index 6f0624e..0a438ef 100644 (file)
@@ -1,5 +1,5 @@
 /* BFD back-end data structures for ELF files.
-   Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 1999 Free Software
+   Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 1999, 2000 Free Software
    Foundation, Inc.
    Written by Cygnus Support.
 
@@ -1304,4 +1304,8 @@ extern boolean _bfd_mips_elf_relocate_section
   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
           Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
 
+/* SH ELF specific routine.  */
+
+extern boolean _sh_elf_set_mach_from_flags PARAMS ((bfd *));
+
 #endif /* _LIBELF_H_ */
index ea5bd9f..ea0426e 100644 (file)
@@ -1,5 +1,5 @@
 /* Hitachi SH specific support for 32-bit ELF
-   Copyright 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+   Copyright 1996, 97, 98, 1999, 2000 Free Software Foundation, Inc.
    Contributed by Ian Lance Taylor, Cygnus Support.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -33,6 +33,14 @@ static reloc_howto_type *sh_elf_reloc_type_lookup
   PARAMS ((bfd *, bfd_reloc_code_real_type));
 static void sh_elf_info_to_howto
   PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
+static boolean sh_elf_set_private_flags
+  PARAMS ((bfd *, flagword));
+static boolean sh_elf_copy_private_data
+  PARAMS ((bfd *, bfd *));
+static boolean sh_elf_merge_private_data
+  PARAMS ((bfd *, bfd *));
+boolean sh_elf_set_mach_from_flags
+  PARAMS ((bfd *));
 static boolean sh_elf_relax_section
   PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *));
 static boolean sh_elf_relax_delete_bytes
@@ -2087,6 +2095,109 @@ sh_elf_check_relocs (abfd, info, sec, relocs)
   return true;
 }
 
+boolean
+sh_elf_set_mach_from_flags (abfd)
+     bfd *    abfd;
+{
+  flagword flags = elf_elfheader (abfd)->e_flags;
+
+  switch (elf_elfheader (abfd)->e_flags & EF_SH_MACH_MASK)
+    {
+    case EF_SH1:
+      bfd_default_set_arch_mach (abfd, bfd_arch_sh, bfd_mach_sh);
+      break;
+    case EF_SH2:
+      bfd_default_set_arch_mach (abfd, bfd_arch_sh, bfd_mach_sh2);
+      break;
+    case EF_SH_DSP:
+      bfd_default_set_arch_mach (abfd, bfd_arch_sh, bfd_mach_sh_dsp);
+      break;
+    case EF_SH3:
+      bfd_default_set_arch_mach (abfd, bfd_arch_sh, bfd_mach_sh3);
+      break;
+    case EF_SH3_DSP:
+      bfd_default_set_arch_mach (abfd, bfd_arch_sh, bfd_mach_sh3_dsp);
+      break;
+    case EF_SH3E:
+      bfd_default_set_arch_mach (abfd, bfd_arch_sh, bfd_mach_sh3e);
+      break;
+    case EF_SH_UNKNOWN:
+    case EF_SH4:
+      bfd_default_set_arch_mach (abfd, bfd_arch_sh, bfd_mach_sh4);
+      break;
+    default:
+      return false;
+    }
+  return true;
+}
+
+/* Function to keep SH specific file flags. */
+static boolean
+sh_elf_set_private_flags (abfd, flags)
+     bfd *    abfd;
+     flagword flags;
+{
+  BFD_ASSERT (! elf_flags_init (abfd)
+             || elf_elfheader (abfd)->e_flags == flags);
+
+  elf_elfheader (abfd)->e_flags = flags;
+  elf_flags_init (abfd) = true;
+  return sh_elf_set_mach_from_flags (abfd);
+}
+
+/* Copy backend specific data from one object module to another */
+static boolean
+sh_elf_copy_private_data (ibfd, obfd)
+     bfd * ibfd;
+     bfd * obfd;
+{
+  if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+    return true;
+
+  return sh_elf_set_private_flags (obfd, elf_elfheader (ibfd)->e_flags);
+}
+
+/* This routine checks for linking big and little endian objects
+   together, and for linking sh-dsp with sh3e / sh4 objects.  */
+
+static boolean
+sh_elf_merge_private_data (ibfd, obfd)
+     bfd *ibfd;
+     bfd *obfd;
+{
+  flagword old_flags, new_flags;
+
+  if (_bfd_generic_verify_endian_match (ibfd, obfd) == false)
+    return false;
+
+  if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+    return true;
+
+  if (! elf_flags_init (obfd))
+    {
+      elf_flags_init (obfd) = true;
+      elf_elfheader (obfd)->e_flags = 0;
+    }
+  old_flags = elf_elfheader (obfd)->e_flags;
+  new_flags = elf_elfheader (ibfd)->e_flags;
+  if ((EF_SH_HAS_DSP (old_flags) && EF_SH_HAS_FP (new_flags))
+      || (EF_SH_HAS_DSP (new_flags) && EF_SH_HAS_FP (old_flags)))
+    {
+      (*_bfd_error_handler)
+       ("%s: uses %s instructions while previous modules use %s instructions",
+        bfd_get_filename (ibfd),
+        EF_SH_HAS_DSP (new_flags) ? "dsp" : "floating point",
+        EF_SH_HAS_DSP (new_flags) ? "floating point" : "dsp");
+      bfd_set_error (bfd_error_bad_value);
+      return false;
+    }
+  elf_elfheader (obfd)->e_flags = EF_SH_MERGE_MACH (old_flags, new_flags);
+
+  return sh_elf_set_mach_from_flags (obfd);
+}
+
 #define TARGET_BIG_SYM         bfd_elf32_sh_vec
 #define TARGET_BIG_NAME                "elf32-sh"
 #define TARGET_LITTLE_SYM      bfd_elf32_shl_vec
@@ -2103,8 +2214,13 @@ sh_elf_check_relocs (abfd, info, sec, relocs)
 #define elf_backend_relocate_section   sh_elf_relocate_section
 #define bfd_elf32_bfd_get_relocated_section_contents \
                                        sh_elf_get_relocated_section_contents
+#define elf_backend_object_p           sh_elf_set_mach_from_flags
+#define bfd_elf32_bfd_set_private_bfd_flags \
+                                       sh_elf_set_private_flags
+#define bfd_elf32_bfd_copy_private_bfd_data \
+                                       sh_elf_copy_private_data
 #define bfd_elf32_bfd_merge_private_bfd_data \
-                                       _bfd_generic_verify_endian_match
+                                       sh_elf_merge_private_data
 
 #define elf_backend_gc_mark_hook        sh_elf_gc_mark_hook
 #define elf_backend_gc_sweep_hook       sh_elf_gc_sweep_hook
index 912e31c..08c005e 100644 (file)
@@ -1,3 +1,22 @@
+Thu Feb 17 00:11:08 2000  J"orn Rennecke <amylaar@cygnus.co.uk>
+
+       * config/tc-sh.c ("elf/sh.h"): Include.
+       (sh_dsp, valid_arch, reg_x, reg_y, reg_efg): New static variables.
+       (md.begin): Initialize target_arch.
+       Only include opcodes in has table that match selected architecture.
+       (parse_reg): Recognize register names for sh-dsp.
+       (parse_at): Recognize post-modify addressing.
+       (get_operands): The leading space is now optional.
+       (get_specific): Remove FDREG_N support.  Add support for sh-dsp
+       arguments.  Update valid_arch.
+       (build_Mytes): Add support for SDT_REG_N.
+       (find_cooked_opcode): New function, broken out of md_assemble.
+       (assemble_ppi, sh_elf_final_processing): New functions.
+       (md_assemble): Use find_cooked_opcode and assemble_ppi.
+       (md_longopts, md_parse_option): New option: -dsp.
+       * config/tc-sh.h (elf_tc_final_processing): Define.
+       (sh_elf_final_processing): Declare.
+
 Fri Feb 11 14:21:51 2000  Jeffrey A Law  (law@cygnus.com)
 
        * config/tc-hppa.c (pa_build_unwind_subspace): Use subseg_new to create
index 9f7a6c1..777d76c 100644 (file)
 #define DEFINE_TABLE
 #include "opcodes/sh-opc.h"
 #include <ctype.h>
+
+#ifdef OBJ_ELF
+#include "elf/sh.h"
+#endif
+
 const char comment_chars[] = "!";
 const char line_separator_chars[] = ";";
 const char line_comment_chars[] = "!#";
@@ -39,16 +44,11 @@ static void s_uses PARAMS ((int));
 static void sh_count_relocs PARAMS ((bfd *, segT, PTR));
 static void sh_frob_section PARAMS ((bfd *, segT, PTR));
 
-/* This table describes all the machine specific pseudo-ops the assembler
-   has to support.  The fields are:
-   pseudo-op name without dot
-   function to call to execute this pseudo-op
-   Integer arg to pass to the function
- */
-
 void cons ();
 void s_align_bytes ();
 static void s_uacons PARAMS ((int));
+static sh_opcode_info *find_cooked_opcode PARAMS ((char **));
+static void assemble_ppi PARAMS ((char *, sh_opcode_info *));
 
 int shl = 0;
 
@@ -60,6 +60,13 @@ little (ignore)
   target_big_endian = 0;
 }
 
+/* This table describes all the machine specific pseudo-ops the assembler
+   has to support.  The fields are:
+   pseudo-op name without dot
+   function to call to execute this pseudo-op
+   Integer arg to pass to the function
+ */
+
 const pseudo_typeS md_pseudo_table[] =
 {
   {"int", cons, 4},
@@ -84,6 +91,14 @@ int sh_relax;                /* set if -relax seen */
 
 int sh_small;
 
+/* Whether -dsp was seen.  */
+
+static int sh_dsp;
+
+/* The bit mask of architectures that could
+   accomodate the insns seen so far.  */
+static int valid_arch;
+
 const char EXP_CHARS[] = "eE";
 
 /* Chars that mean this number is a floating point constant */
@@ -189,16 +204,20 @@ md_begin ()
 {
   sh_opcode_info *opcode;
   char *prev_name = "";
+  int target_arch;
 
   if (! shl)
     target_big_endian = 1;
 
+  target_arch = arch_sh1_up & ~(sh_dsp ? arch_sh3e_up : arch_sh_dsp_up);
+  valid_arch = target_arch;
+
   opcode_hash_control = hash_new ();
 
   /* Insert unique names into hash table */
   for (opcode = sh_table; opcode->name; opcode++)
     {
-      if (strcmp (prev_name, opcode->name))
+      if (opcode->arch & target_arch && strcmp (prev_name, opcode->name))
        {
          prev_name = opcode->name;
          hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
@@ -214,6 +233,8 @@ md_begin ()
 
 static int reg_m;
 static int reg_n;
+static int reg_x, reg_y;
+static int reg_efg;
 static int reg_b;
 
 static expressionS immediate;  /* absolute expression */
@@ -239,6 +260,23 @@ parse_reg (src, mode, reg)
 
   if (src[0] == 'r')
     {
+      if (src[1] == '1')
+       {
+         if (src[2] >= '0' && src[2] <= '5'
+             && ! isalnum ((unsigned char) src[3]))
+           {
+             *mode = A_REG_N;
+             *reg = 10 + src[2] - '0';
+             return 3;
+           }
+       }
+      if (src[1] >= '0' && src[1] <= '9'
+         && ! isalnum ((unsigned char) src[2]))
+       {
+         *mode = A_REG_N;
+         *reg = (src[1] - '0');
+         return 2;
+       }
       if (src[1] >= '0' && src[1] <= '7' && strncmp(&src[2], "_bank", 5) == 0
          && ! isalnum ((unsigned char) src[7]))
        {
@@ -246,27 +284,121 @@ parse_reg (src, mode, reg)
          *reg  = (src[1] - '0');
          return 7;
        }
+
+      if (src[1] == 'e' && ! isalnum ((unsigned char) src[2]))
+       {
+         *mode = A_RE;
+         return 2;
+       }
+      if (src[1] == 's' && ! isalnum ((unsigned char) src[2]))
+       {
+         *mode = A_RS;
+         return 2;
+       }
     }
 
-  if (src[0] == 'r')
+  if (src[0] == 'a')
     {
+      if (src[1] == '0')
+       {
+         if (! isalnum ((unsigned char) src[2]))
+           {
+             *mode = DSP_REG_N;
+             *reg = A_A0_NUM;
+             return 2;
+           }
+         if (src[2] == 'g' && ! isalnum ((unsigned char) src[3]))
+           {
+             *mode = DSP_REG_N;
+             *reg = A_A0G_NUM;
+             return 3;
+           }
+       }
       if (src[1] == '1')
        {
-         if (src[2] >= '0' && src[2] <= '5'
-             && ! isalnum ((unsigned char) src[3]))
+         if (! isalnum ((unsigned char) src[2]))
            {
-             *mode = A_REG_N;
-             *reg = 10 + src[2] - '0';
+             *mode = DSP_REG_N;
+             *reg = A_A1_NUM;
+             return 2;
+           }
+         if (src[2] == 'g' && ! isalnum ((unsigned char) src[3]))
+           {
+             *mode = DSP_REG_N;
+             *reg = A_A1G_NUM;
              return 3;
            }
        }
-      if (src[1] >= '0' && src[1] <= '9'
-         && ! isalnum ((unsigned char) src[2]))
+
+      if (src[1] == 'x' && src[2] >= '0' && src[2] <= '1'
+         && ! isalnum ((unsigned char) src[3]))
        {
          *mode = A_REG_N;
-         *reg = (src[1] - '0');
+         *reg = 4 + (src[1] - '0');
+         return 3;
+       }
+      if (src[1] == 'y' && src[2] >= '0' && src[2] <= '1'
+         && ! isalnum ((unsigned char) src[3]))
+       {
+         *mode = A_REG_N;
+         *reg = 6 + (src[1] - '0');
+         return 3;
+       }
+      if (src[1] == 's' && src[2] >= '0' && src[2] <= '3'
+         && ! isalnum ((unsigned char) src[3]))
+       {
+         int n = src[1] - '0';
+
+         *mode = A_REG_N;
+         *reg = n | ((~n & 2) << 1);
+         return 3;
+       }
+    }
+
+  if (src[0] == 'i' && src[1] && ! isalnum ((unsigned char) src[3]))
+    {
+      if (src[1] == 's')
+       {
+         *mode = A_REG_N;
+         *reg = 8;
          return 2;
        }
+      if (src[1] == 'x')
+       {
+         *mode = A_REG_N;
+         *reg = 8;
+         return 2;
+       }
+      if (src[1] == 'y')
+       {
+         *mode = A_REG_N;
+         *reg = 9;
+         return 2;
+       }
+    }
+
+  if (src[0] == 'x' && src[1] >= '0' && src[1] <= '1'
+      && ! isalnum ((unsigned char) src[2]))
+    {
+      *mode = DSP_REG_N;
+      *reg = A_X0_NUM + src[1] - '0';
+      return 2;
+    }
+
+  if (src[0] == 'y' && src[1] >= '0' && src[1] <= '1'
+      && ! isalnum ((unsigned char) src[2]))
+    {
+      *mode = DSP_REG_N;
+      *reg = A_Y0_NUM + src[1] - '0';
+      return 2;
+    }
+
+  if (src[0] == 'm' && src[1] >= '0' && src[1] <= '1'
+      && ! isalnum ((unsigned char) src[2]))
+    {
+      *mode = DSP_REG_N;
+      *reg = src[1] == '0' ? A_M0_NUM : A_M1_NUM;
+      return 2;
     }
 
   if (src[0] == 's'
@@ -291,6 +423,13 @@ parse_reg (src, mode, reg)
       return 3;
     }
 
+  if (src[0] == 'd' && src[1] == 's' && src[2] == 'r'
+      && ! isalnum ((unsigned char) src[3]))
+    {
+      *mode = A_DSR;
+      return 3;
+    }
+
   if (src[0] == 'd' && src[1] == 'b' && src[2] == 'r'
       && ! isalnum ((unsigned char) src[3]))
     {
@@ -348,6 +487,12 @@ parse_reg (src, mode, reg)
          return 4;
        }
     }
+  if (src[0] == 'm' && src[1] == 'o' && src[2] == 'd'
+      && ! isalnum ((unsigned char) src[4]))
+    {
+      *mode = A_MOD;
+      return 3;
+    }
   if (src[0] == 'f' && src[1] == 'r')
     {
       if (src[2] == '1')
@@ -605,8 +750,21 @@ parse_at (src, op)
        }
       if (src[0] == '+')
        {
-         op->type = A_INC_N;
          src++;
+         if ((src[0] == 'r' && src[1] == '8')
+             || (src[0] == 'i' && (src[1] == 'x' || src[1] == 's')))
+           {
+             src += 2;
+             op->type = A_PMOD_N;
+           }
+         if ((src[0] == 'r' && src[1] == '9')
+             || (src[0] == 'i' && src[1] == 'y'))
+           {
+             src += 2;
+             op->type = A_PMODY_N;
+           }
+         else
+           op->type = A_INC_N;
        }
       else
        {
@@ -665,7 +823,11 @@ get_operands (info, args, operand)
   char *ptr = args;
   if (info->arg[0])
     {
-      ptr++;
+      /* The pre-processor will eliminate whitespace in front of '@'
+        after the first argument; we may be called multiple times
+        from assemble_ppi, so don't insist on finding whitespace here.  */
+      if (*ptr == ' ')
+       ptr++;
 
       get_operand (&ptr, operand + 0);
       if (info->arg[1])
@@ -774,16 +936,14 @@ get_specific (opcode, operands)
            case V_REG_N:
            case FPUL_N:
            case FPSCR_N:
+           case A_PMOD_N:
+           case A_PMODY_N:
+           case DSP_REG_N:
              /* Opcode needs rn */
              if (user->type != arg)
                goto fail;
              reg_n = user->reg;
              break;
-           case FD_REG_N:
-             if (user->type != F_REG_N && user->type != D_REG_N)
-               goto fail;
-             reg_n = user->reg;
-             break;
            case DX_REG_N:
              if (user->type != D_REG_N && user->type != X_REG_N)
                goto fail;
@@ -792,6 +952,10 @@ get_specific (opcode, operands)
            case A_GBR:
            case A_SR:
            case A_VBR:
+           case A_DSR:
+           case A_MOD:
+           case A_RE:
+           case A_RS:
            case A_SSR:
            case A_SPC:
            case A_SGR:
@@ -812,12 +976,144 @@ get_specific (opcode, operands)
            case A_IND_M:
            case A_IND_R0_REG_M:
            case A_DISP_REG_M:
+           case DSP_REG_M:
              /* Opcode needs rn */
              if (user->type != arg - A_REG_M + A_REG_N)
                goto fail;
              reg_m = user->reg;
              break;
 
+           case DSP_REG_X:
+             if (user->type != DSP_REG_N)
+               goto fail;
+             switch (user->reg)
+               {
+               case A_X0_NUM:
+                 reg_x = 0;
+                 break;
+               case A_X1_NUM:
+                 reg_x = 1;
+                 break;
+               case A_A0_NUM:
+                 reg_x = 2;
+                 break;
+               case A_A1_NUM:
+                 reg_x = 3;
+                 break;
+               default:
+                 goto fail;
+               }
+             break;
+
+           case DSP_REG_Y:
+             if (user->type != DSP_REG_N)
+               goto fail;
+             switch (user->reg)
+               {
+               case A_Y0_NUM:
+                 reg_y = 0;
+                 break;
+               case A_Y1_NUM:
+                 reg_y = 1;
+                 break;
+               case A_M0_NUM:
+                 reg_y = 2;
+                 break;
+               case A_M1_NUM:
+                 reg_y = 3;
+                 break;
+               default:
+                 goto fail;
+               }
+             break;
+
+           case DSP_REG_E:
+             if (user->type != DSP_REG_N)
+               goto fail;
+             switch (user->reg)
+               {
+               case A_X0_NUM:
+                 reg_efg = 0 << 10;
+                 break;
+               case A_X1_NUM:
+                 reg_efg = 1 << 10;
+                 break;
+               case A_Y0_NUM:
+                 reg_efg = 2 << 10;
+                 break;
+               case A_A1_NUM:
+                 reg_efg = 3 << 10;
+                 break;
+               default:
+                 goto fail;
+               }
+             break;
+
+           case DSP_REG_F:
+             if (user->type != DSP_REG_N)
+               goto fail;
+             switch (user->reg)
+               {
+               case A_Y0_NUM:
+                 reg_efg |= 0 << 8;
+                 break;
+               case A_Y1_NUM:
+                 reg_efg |= 1 << 8;
+                 break;
+               case A_X0_NUM:
+                 reg_efg |= 2 << 8;
+                 break;
+               case A_A1_NUM:
+                 reg_efg |= 3 << 8;
+                 break;
+               default:
+                 goto fail;
+               }
+             break;
+
+           case DSP_REG_G:
+             if (user->type != DSP_REG_N)
+               goto fail;
+             switch (user->reg)
+               {
+               case A_M0_NUM:
+                 reg_efg |= 0 << 2;
+                 break;
+               case A_M1_NUM:
+                 reg_efg |= 1 << 2;
+                 break;
+               case A_A0_NUM:
+                 reg_efg |= 2 << 2;
+                 break;
+               case A_A1_NUM:
+                 reg_efg |= 3 << 2;
+                 break;
+               default:
+                 goto fail;
+               }
+             break;
+
+           case A_A0:
+             if (user->type != DSP_REG_N || user->reg != A_A0_NUM)
+               goto fail;
+             break;
+           case A_X0:
+             if (user->type != DSP_REG_N || user->reg != A_X0_NUM)
+               goto fail;
+             break;
+           case A_X1:
+             if (user->type != DSP_REG_N || user->reg != A_X1_NUM)
+               goto fail;
+             break;
+           case A_Y0:
+             if (user->type != DSP_REG_N || user->reg != A_Y0_NUM)
+               goto fail;
+             break;
+           case A_Y1:
+             if (user->type != DSP_REG_N || user->reg != A_Y1_NUM)
+               goto fail;
+             break;
+
            case F_REG_M:
            case D_REG_M:
            case X_REG_M:
@@ -845,6 +1141,7 @@ get_specific (opcode, operands)
              goto fail;
            }
        }
+      valid_arch &= this_try->arch;
       return this_try;
     fail:;
     }
@@ -949,6 +1246,11 @@ build_Mytes (opcode, operand)
            case REG_M:
              nbuf[index] = reg_m;
              break;
+           case SDT_REG_N:
+             if (reg_n < 2 || reg_n > 5)
+               as_bad (_("Invalid register: 'r%d'"), reg_n);
+             nbuf[index] = (reg_n & 3) | 4;
+             break;
            case REG_NM:
              nbuf[index] = reg_n | (reg_m >> 2);
              break;
@@ -997,50 +1299,274 @@ build_Mytes (opcode, operand)
   }
 }
 
-/* This is the guts of the machine-dependent assembler.  STR points to a
-   machine dependent instruction.  This function is supposed to emit
-   the frags/bytes it assembles to.
- */
+/* Find an opcode at the start of *STR_P in the hash table, and set
+   *STR_P to the first character after the last one read.  */
 
-void
-md_assemble (str)
-     char *str;
+static sh_opcode_info *
+find_cooked_opcode (str_p)
+     char **str_p;
 {
+  char *str = *str_p;
   unsigned char *op_start;
   unsigned char *op_end;
-  sh_operand_info operand[3];
-  sh_opcode_info *opcode;
   char name[20];
   int nlen = 0;
   /* Drop leading whitespace */
   while (*str == ' ')
     str++;
 
-  /* find the op code end */
+  /* Find the op code end.
+     The pre-processor will eliminate whitespace in front of
+     any '@' after the first argument; we may be called from
+     assemble_ppi, so the opcode might be terminated by an '@'.  */
   for (op_start = op_end = (unsigned char *) (str);
        *op_end
        && nlen < 20
-       && !is_end_of_line[*op_end] && *op_end != ' ';
+       && !is_end_of_line[*op_end] && *op_end != ' ' && *op_end != '@';
        op_end++)
     {
       unsigned char c = op_start[nlen];
 
       /* The machine independent code will convert CMP/EQ into cmp/EQ
-        because it thinks the '/' is the end of the symbol.  Instead of
-        hacking up the machine independent code, we just deal with it
-        here.  */
+        because it thinks the '/' is the end of the symbol.  Moreover,
+        all but the first sub-insn is a parallel processing insn won't
+        be capitailzed.  Instead of hacking up the machine independent
+        code, we just deal with it here.  */
       c = isupper (c) ? tolower (c) : c;
       name[nlen] = c;
       nlen++;
     }
   name[nlen] = 0;
+  *str_p = op_end;
 
   if (nlen == 0)
     {
       as_bad (_("can't find opcode "));
     }
 
-  opcode = (sh_opcode_info *) hash_find (opcode_hash_control, name);
+  return (sh_opcode_info *) hash_find (opcode_hash_control, name);
+}
+
+/* Assemble a parallel processing insn.  */
+#define DDT_BASE 0xf000 /* Base value for double data transfer insns */
+static void
+assemble_ppi (op_end, opcode)
+     char *op_end;
+     sh_opcode_info *opcode;
+{
+  int movx = 0;
+  int movy = 0;
+  int cond = 0;
+  int field_b = 0;
+  char *output;
+  int move_code;
+
+  /* Some insn ignore one or more register fields, e.g. psts machl,a0.
+     Make sure we encode a defined insn pattern.  */
+  reg_x = 0;
+  reg_y = 0;
+
+  for (;;)
+    {
+      sh_operand_info operand[3];
+
+      if (opcode->arg[0] != A_END)
+       op_end = get_operands (opcode, op_end, operand);
+      opcode = get_specific (opcode, operand);
+      if (opcode == 0)
+       {
+         /* Couldn't find an opcode which matched the operands */
+         char *where = frag_more (2);
+
+         where[0] = 0x0;
+         where[1] = 0x0;
+         as_bad (_("invalid operands for opcode"));
+         return;
+       }
+      if (opcode->nibbles[0] != PPI)
+       as_bad (_("insn can't be combined with parallel processing insn"));
+
+      switch (opcode->nibbles[1])
+       {
+
+       case NOPX:
+         if (movx)
+           as_bad (_("multiple movx specifications"));
+         movx = DDT_BASE;
+         break;
+       case NOPY:
+         if (movy)
+           as_bad (_("multiple movy specifications"));
+         movy = DDT_BASE;
+         break;
+
+       case MOVX:
+         if (movx)
+           as_bad (_("multiple movx specifications"));
+         if (reg_n < 4 || reg_n > 5)
+           as_bad (_("invalid movx address register"));
+         if (opcode->nibbles[2] & 8)
+           {
+             if (reg_m == A_A1_NUM)
+               movx = 1 << 7;
+             else if (reg_m != A_A0_NUM)
+               as_bad (_("invalid movx dsp register"));
+           }
+         else
+           {
+             if (reg_x > 1)
+               as_bad (_("invalid movx dsp register"));
+             movx = reg_x << 7;
+           }
+         movx += ((reg_n - 4) << 9) + (opcode->nibbles[2] << 2) + DDT_BASE;
+         break;
+
+       case MOVY:
+         if (movy)
+           as_bad (_("multiple movy specifications"));
+         if (opcode->nibbles[2] & 8)
+           {
+             /* Bit 3 in nibbles[2] is intended for bit 4 of the opcode,
+                so add 8 more.  */
+             movy = 8;
+             if (reg_m == A_A1_NUM)
+               movy += 1 << 6;
+             else if (reg_m != A_A0_NUM)
+               as_bad (_("invalid movy dsp register"));
+           }
+         else
+           {
+             if (reg_y > 1)
+               as_bad (_("invalid movy dsp register"));
+             movy = reg_y << 6;
+           }
+         if (reg_n < 6 || reg_n > 7)
+           as_bad (_("invalid movy address register"));
+         movy += ((reg_n - 6) << 8) + opcode->nibbles[2] + DDT_BASE;
+         break;
+
+       case PSH:
+         if (immediate.X_op != O_constant)
+           as_bad (_("dsp immediate shift value not constant"));
+         field_b = ((opcode->nibbles[2] << 12)
+                    | (immediate.X_add_number & 127) << 4
+                    | reg_n);
+         break;
+       case PPI3:
+         if (field_b)
+           as_bad (_("multiple parallel processing specifications"));
+         field_b = ((opcode->nibbles[2] << 12) + (opcode->nibbles[3] << 8)
+                    + (reg_x << 6) + (reg_y << 4) + reg_n);
+         break;
+       case PDC:
+         if (cond)
+           as_bad (_("multiple condition specifications"));
+         cond = opcode->nibbles[2] << 8;
+         if (*op_end)
+           goto skip_cond_check;
+         break;
+       case PPIC:
+         if (field_b)
+           as_bad (_("multiple parallel processing specifications"));
+         field_b = ((opcode->nibbles[2] << 12) + (opcode->nibbles[3] << 8)
+                    + cond + (reg_x << 6) + (reg_y << 4) + reg_n);
+         cond = 0;
+         break;
+       case PMUL:
+         if (field_b)
+           {
+             if ((field_b & 0xef00) != 0xa100)
+               as_bad (_("insn cannot be combined with pmuls"));
+             field_b -= 0x8100;
+             switch (field_b & 0xf)
+               {
+               case A_X0_NUM:
+                 field_b += 0 - A_X0_NUM;
+                 break;
+               case A_Y0_NUM:
+                 field_b += 1 - A_Y0_NUM;
+                 break;
+               case A_A0_NUM:
+                 field_b += 2 - A_A0_NUM;
+                 break;
+               case A_A1_NUM:
+                 field_b += 3 - A_A1_NUM;
+                 break;
+               default:
+                 as_bad (_("bad padd / psub pmuls output operand"));
+               }
+           }
+         field_b += 0x4000 + reg_efg;
+         break;
+       default:
+         abort ();
+       }
+      if (cond)
+       {
+         as_bad (_("condition not followed by conditionalizable insn"));
+         cond = 0;
+       }
+      if (! *op_end)
+       break;
+    skip_cond_check:
+      opcode = find_cooked_opcode (&op_end);
+      if (opcode == NULL)
+       {
+         (as_bad
+          (_("unrecognized characters at end of parallel processing insn")));
+         break;
+       }
+    }
+
+  move_code = movx | movy;
+  if (field_b)
+    {
+      /* Parallel processing insn.  */
+      unsigned long ppi_code = (movx | movy | 0xf800) << 16 | field_b;
+
+      output = frag_more (4);
+      if (! target_big_endian)
+       {
+         output[3] = ppi_code >> 8;
+         output[2] = ppi_code;
+       }
+      else
+       {
+         output[2] = ppi_code >> 8;
+         output[3] = ppi_code;
+       }
+      move_code |= 0xf800;
+    }
+  else
+    /* Just a double data transfer.  */
+    output = frag_more (2);
+  if (! target_big_endian)
+    {
+      output[1] = move_code >> 8;
+      output[0] = move_code;
+    }
+  else
+    {
+      output[0] = move_code >> 8;
+      output[1] = move_code;
+    }
+}
+
+/* This is the guts of the machine-dependent assembler.  STR points to a
+   machine dependent instruction.  This function is supposed to emit
+   the frags/bytes it assembles to.
+ */
+
+void
+md_assemble (str)
+     char *str;
+{
+  unsigned char *op_end;
+  sh_operand_info operand[3];
+  sh_opcode_info *opcode;
+
+  opcode = find_cooked_opcode (&str);
+  op_end = str;
 
   if (opcode == NULL)
     {
@@ -1058,6 +1584,12 @@ md_assemble (str)
       seg_info (now_seg)->tc_segment_info_data.in_code = 1;
     }
 
+  if (opcode->nibbles[0] == PPI)
+    {
+      assemble_ppi (op_end, opcode);
+      return;
+    }
+
   if (opcode->arg[0] == A_BDISP12
       || opcode->arg[0] == A_BDISP8)
     {
@@ -1257,10 +1789,12 @@ struct option md_longopts[] = {
 #define OPTION_RELAX  (OPTION_MD_BASE)
 #define OPTION_LITTLE (OPTION_MD_BASE + 1)
 #define OPTION_SMALL (OPTION_LITTLE + 1)
+#define OPTION_DSP (OPTION_SMALL + 1)
 
   {"relax", no_argument, NULL, OPTION_RELAX},
   {"little", no_argument, NULL, OPTION_LITTLE},
   {"small", no_argument, NULL, OPTION_SMALL},
+  {"dsp", no_argument, NULL, OPTION_DSP},
   {NULL, no_argument, NULL, 0}
 };
 size_t md_longopts_size = sizeof(md_longopts);
@@ -1285,6 +1819,10 @@ md_parse_option (c, arg)
       sh_small = 1;
       break;
 
+    case OPTION_DSP:
+      sh_dsp = 1;
+      break;
+
     default:
       return 0;
     }
@@ -1886,6 +2424,33 @@ sh_fix_adjustable (fixP)
 
   return 1;
 }
+
+void sh_elf_final_processing()
+{
+  int val;
+
+  /* Set file-specific flags to indicate if this code needs
+     a processor with the sh-dsp / sh3e ISA to execute.  */
+  if (valid_arch & arch_sh1)
+    val = EF_SH1;
+  else if (valid_arch & arch_sh2)
+    val = EF_SH2;
+  else if (valid_arch & arch_sh_dsp)
+    val = EF_SH_DSP;
+  else if (valid_arch & arch_sh3)
+    val = EF_SH3;
+  else if (valid_arch & arch_sh3_dsp)
+    val = EF_SH_DSP;
+  else if (valid_arch & arch_sh3e)
+    val = EF_SH3E;
+  else if (valid_arch & arch_sh4)
+    val = EF_SH4;
+  else
+    abort ();
+
+  elf_elfheader (stdoutput)->e_flags &= ~EF_SH_MACH_MASK;
+  elf_elfheader (stdoutput)->e_flags |= val;
+}
 #endif
 
 /* Apply a fixup to the object file.  */
index f4278c2..90129c2 100644 (file)
@@ -149,6 +149,9 @@ extern int target_big_endian;
 
 #define TARGET_FORMAT (shl ? "elf32-shl" : "elf32-sh")
 
+#define elf_tc_final_processing sh_elf_final_processing
+extern void sh_elf_final_processing PARAMS ((void));
+
 #endif /* OBJ_ELF */
 
 /* end of tc-sh.h */
index bac124d..84c11b0 100644 (file)
@@ -1,3 +1,9 @@
+Thu Feb 17 00:18:33 2000  J"orn Rennecke <amylaar@cygnus.co.uk>
+
+       * sh.h: (EF_SH_MACH_MASK, EF_SH_UNKNOWN, EF_SH1, EF_SH2): New macros.
+       (EF_SH3, EF_SH_HAS_DSP, EF_SH_DSP, EF_SH3_DSP): Likewise.
+       (EF_SH_HAS_FP, EF_SH3E, EF_SH4, EF_SH_MERGE_MACH): Likewise.
+
 2000-02-03  H.J. Lu  <hjl@gnu.org>
 
        * arm-oabi.h: Duplicate changes made to arm.h on Jan. 27,
index 4a47667..faee509 100644 (file)
 #ifndef _ELF_SH_H
 #define _ELF_SH_H
 
+/* Processor specific flags for the ELF header e_flags field.  */
+
+#define EF_SH_MACH_MASK        0x1f
+#define EF_SH_UNKNOWN     0 /* For backwards compatibility.  */
+#define EF_SH1            1
+#define EF_SH2            2
+#define EF_SH3            3
+#define EF_SH_HAS_DSP(flags) ((flags) & 4)
+#define EF_SH_DSP         4
+#define EF_SH3_DSP        5
+#define EF_SH_HAS_FP(flags) ((flags) & 8)
+#define EF_SH3E                   8
+#define EF_SH4            9
+
+#define EF_SH_MERGE_MACH(mach1, mach2) \
+  (((((mach1) == EF_SH3 || (mach1) == EF_SH_UNKNOWN) && (mach2) == EF_SH_DSP) \
+    || ((mach1) == EF_SH_DSP \
+       && ((mach2) == EF_SH3 || (mach2) == EF_SH_UNKNOWN))) \
+   ? EF_SH3_DSP \
+   : (((mach1) < EF_SH3 && (mach2) == EF_SH_UNKNOWN) \
+      || ((mach2) < EF_SH3 && (mach1) == EF_SH_UNKNOWN)) \
+   ? EF_SH3 \
+   : (((mach1) == EF_SH3E && (mach2) == EF_SH_UNKNOWN) \
+      || ((mach2) == EF_SH3E && (mach1) == EF_SH_UNKNOWN)) \
+   ? EF_SH4 \
+   : ((mach1) > (mach2) ? (mach1) : (mach2)))
+
 #include "elf/reloc-macros.h"
 
 /* Relocations.  */
index 33dea54..2c7e9f5 100644 (file)
@@ -1,3 +1,20 @@
+Thu Feb 17 00:18:12 2000  J"orn Rennecke <amylaar@cygnus.co.uk>
+
+       * sh-dis.c (print_movxy, print_insn_ddt, print_dsp_reg): New functions.
+       (print_insn_ppi): Likewise.
+       (print_insn_shx): Use info->mach to select appropriate insn set.
+       Add support for sh-dsp.  Remove FD_REG_N support.
+       * sh-opc.h (sh_nibble_type): Add new values for sh-dsp support.
+       (sh_arg_type): Likewise.  Remove FD_REG_N.
+       (sh_dsp_reg_nums): New enum.
+       (arch_sh1, arch_sh2, arch_sh3, arch_sh3e, arch_sh4): New macros.
+       (arch_sh_dsp, arch_sh3_dsp, arch_sh1_up, arch_sh2_up): Likewise.
+       (arch_sh3_up, arch_sh3e_up, arch_sh4_up, arch_sh_dsp_up): Likewise.
+       (arch_sh3_dsp_up): Likewise.
+       (sh_opcode_info): New field: arch.
+       (sh_table): Split up insn with FD_REG_N into ones with F_REG_N and
+       D_REG_N.  Fill in arch field.  Add sh-dsp insns.
+
 2000-02-14  Fernando Nasser  <fnasser@totem.to.cygnus.com>
 
        * arm-dis.c: Change flavor name from atpcs-special to
index 2ebfdb6..bef6518 100644 (file)
@@ -24,6 +24,256 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #define LITTLE_BIT 2
 
+static void
+print_movxy (op, rn, rm, fprintf_fn, stream)
+     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:
+         fprintf_fn (stream, "@r%d", rn);      
+         break;
+       case A_INC_N:
+         fprintf_fn (stream, "@r%d+", rn);     
+         break;
+       case A_PMOD_N:
+         fprintf_fn (stream, "@r%d+r8", rn);   
+         break;
+       case A_PMODY_N:
+         fprintf_fn (stream, "@r%d+r9", rn);   
+         break;
+       case DSP_REG_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;
+       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)))
+    fprintf_fn (stream, ".word 0x%x", insn);
+  else
+    {
+      static sh_opcode_info *first_movx, *first_movy;
+      sh_opcode_info *opx, *opy;
+      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;
+  int nib1, nib2, nib3;
+  char *dc;
+  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]);
+       }
+      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;
+  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;
+    }
+  for (op = sh_table; op->name; op++)
+    {
+      if (op->nibbles[1] == nib1
+         && op->nibbles[2] == nib2
+         && op->nibbles[3] == nib3)
+       {
+         int n;
+
+         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);
+}
+
 static int 
 print_insn_shx (memaddr, info)
      bfd_vma memaddr;
@@ -36,6 +286,34 @@ print_insn_shx (memaddr, info)
   int status;
   bfd_vma relmask = ~ (bfd_vma) 0;
   sh_opcode_info *op;
+  int target_arch;
+
+  switch (info->mach)
+    {
+    case bfd_mach_sh:
+      target_arch = arch_sh1;
+      break;
+    case bfd_mach_sh2:
+      target_arch = arch_sh2;
+      break;
+    case bfd_mach_sh_dsp:
+      target_arch = arch_sh_dsp;
+      break;
+    case bfd_mach_sh3:
+      target_arch = arch_sh3;
+      break;
+    case bfd_mach_sh3_dsp:
+      target_arch = arch_sh3_dsp;
+      break;
+    case bfd_mach_sh3e:
+      target_arch = arch_sh3e;
+      break;
+    case bfd_mach_sh4:
+      target_arch = arch_sh4;
+      break;
+    default:
+      abort ();
+    }
 
   status = info->read_memory_func (memaddr, insn, 2, info);
 
@@ -62,6 +340,32 @@ print_insn_shx (memaddr, info)
       nibs[3] = insn[1] & 0xf;
     }
 
+  if (nibs[0] == 0xf && (nibs[1] & 4) == 0 && 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->flags & LITTLE_BIT) 
+           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;
@@ -72,6 +376,8 @@ print_insn_shx (memaddr, info)
       int disp_pc;
       bfd_vma disp_pc_addr = 0;
 
+      if ((op->arch & target_arch) == 0)
+       goto fail;
       for (n = 0; n < 4; n++)
        {
          int i = op->nibbles[n];
@@ -141,6 +447,16 @@ print_insn_shx (memaddr, info)
            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) << 1;
+             break;
+           case PPI:
+             goto fail;
            default:
              abort();
            }
@@ -176,6 +492,9 @@ print_insn_shx (memaddr, info)
            case A_DISP_REG_N:
              fprintf_fn (stream, "@(%d,r%d)", imm, rn);        
              break;
+           case A_PMOD_N:
+             fprintf_fn (stream, "@r%d+r8", rn);       
+             break;
            case A_REG_M:
              fprintf_fn (stream, "r%d", rm);
              break;
@@ -224,6 +543,36 @@ print_insn_shx (memaddr, info)
            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;
@@ -245,9 +594,6 @@ print_insn_shx (memaddr, info)
            case A_DBR:
              fprintf_fn (stream, "dbr");
              break;
-           case FD_REG_N:
-             if (0)
-               goto d_reg_n;
            case F_REG_N:
              fprintf_fn (stream, "fr%d", rn);
              break;
index fcfe0ef..dd6d8ec 100644 (file)
@@ -34,6 +34,7 @@ typedef enum {
        HEX_F,
        REG_N,
        REG_M,
+       SDT_REG_N,
        REG_NM,
         REG_B,
        BRANCH_12,
@@ -47,7 +48,17 @@ typedef enum {
        PCRELIMM_8BY4,
        IMM_8,
        IMM_8BY2,
-       IMM_8BY4
+       IMM_8BY4,
+       PPI,
+       NOPX,
+       NOPY,
+       MOVX,
+       MOVY,
+       PSH,
+       PMUL,
+       PPI3,
+       PDC,
+       PPIC
 } sh_nibble_type;
 
 typedef enum {
@@ -66,6 +77,8 @@ typedef enum {
        A_INC_N,
        A_IND_M,
        A_IND_N,
+       A_PMOD_N,
+       A_PMODY_N,
        A_IND_R0_REG_M,
        A_IND_R0_REG_N,
        A_MACH,
@@ -78,6 +91,22 @@ typedef enum {
        A_REG_B,
        A_SR,
        A_VBR,
+       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,
+       A_A0,
+       A_X0,
+       A_X1,
+       A_Y0,
+       A_Y1,
        A_SSR,
        A_SPC,
        A_SGR,
@@ -92,7 +121,6 @@ typedef enum {
        DX_REG_M,
        V_REG_N,
        V_REG_M,
-       FD_REG_N,
        XMTRX_M4,
        F_FR0,
        FPUL_N,
@@ -101,473 +129,700 @@ typedef enum {
        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     0x0001
+#define arch_sh2     0x0002
+#define arch_sh3     0x0004
+#define arch_sh3e    0x0008
+#define arch_sh4     0x0010
+#define arch_sh_dsp  0x0100
+#define arch_sh3_dsp 0x0200
+
+#define arch_sh1_up (arch_sh1 | arch_sh2_up)
+#define arch_sh2_up (arch_sh2 | arch_sh3_up | arch_sh_dsp)
+#define arch_sh3_up (arch_sh3 | arch_sh3e_up | arch_sh3_dsp)
+#define arch_sh3e_up (arch_sh3e | arch_sh4_up)
+#define arch_sh4_up arch_sh4
+
+#define arch_sh_dsp_up (arch_sh_dsp | arch_sh3_dsp_up)
+#define arch_sh3_dsp_up arch_sh3_dsp
+
 typedef struct {
   char *name;
   sh_arg_type arg[4];
   sh_nibble_type nibbles[4];
+  int arch;
 } sh_opcode_info;
 
 #ifdef DEFINE_TABLE
 
 sh_opcode_info sh_table[] = {
 
-/* 0111nnnni8*1.... add #<imm>,<REG_N>  */{"add",{A_IMM,A_REG_N},{HEX_7,REG_N,IMM_8}},
+/* 0111nnnni8*1.... add #<imm>,<REG_N>  */{"add",{A_IMM,A_REG_N},{HEX_7,REG_N,IMM_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,IMM_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,IMM_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},
+
+/* 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,IMM_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},
+
+/* 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},
+
+/* 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_up},
+
+/* 0100nnnn01001110 ldc <REG_N>,SPC     */{"ldc",{A_REG_N,A_SPC},{HEX_4,REG_N,HEX_4,HEX_E}, arch_sh3_up},
+
+/* 0100nnnn11111010 ldc <REG_N>,DBR     */{"ldc",{A_REG_N,A_DBR},{HEX_4,REG_N,HEX_F,HEX_A}, arch_sh4_up},
+
+/* 0100nnnn1xxx1110 ldc <REG_N>,Rn_BANK */{"ldc",{A_REG_N,A_REG_B},{HEX_4,REG_N,REG_B,HEX_E}, arch_sh3_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},
+
+/* 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_up},
+
+/* 0100nnnn01000111 ldc.l @<REG_N>+,SPC */{"ldc.l",{A_INC_N,A_SPC},{HEX_4,REG_N,HEX_4,HEX_7}, arch_sh3_up},
+
+/* 0100nnnn11110110 ldc.l @<REG_N>+,DBR */{"ldc.l",{A_INC_N,A_DBR},{HEX_4,REG_N,HEX_F,HEX_6}, arch_sh4_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_up},
+
+/* 10001110i8p4.... ldre @(<disp>,PC)  */{"ldre",{A_DISP_PC},{HEX_8,HEX_E,PCRELIMM_8BY2}, arch_sh_dsp_up},
 
-/* 0011nnnnmmmm1100 add <REG_M>,<REG_N> */{"add",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_C}},
+/* 10001100i8p4.... ldrs @(<disp>,PC)  */{"ldre",{A_DISP_PC},{HEX_8,HEX_C,PCRELIMM_8BY2}, arch_sh_dsp_up},
 
-/* 0011nnnnmmmm1110 addc <REG_M>,<REG_N>*/{"addc",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_E}},
+/* 0100nnnn00001010 lds <REG_N>,MACH    */{"lds",{A_REG_N,A_MACH},{HEX_4,REG_N,HEX_0,HEX_A}, arch_sh1_up},
 
-/* 0011nnnnmmmm1111 addv <REG_M>,<REG_N>*/{"addv",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_F}},
+/* 0100nnnn00011010 lds <REG_N>,MACL    */{"lds",{A_REG_N,A_MACL},{HEX_4,REG_N,HEX_1,HEX_A}, arch_sh1_up},
 
-/* 11001001i8*1.... and #<imm>,R0       */{"and",{A_IMM,A_R0},{HEX_C,HEX_9,IMM_8}},
+/* 0100nnnn00101010 lds <REG_N>,PR      */{"lds",{A_REG_N,A_PR},{HEX_4,REG_N,HEX_2,HEX_A}, arch_sh1_up},
 
-/* 0010nnnnmmmm1001 and <REG_M>,<REG_N> */{"and",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_9}},
+/* 0100nnnn01101010 lds <REG_N>,DSR    */{"lds",{A_REG_N,A_DSR},{HEX_4,REG_N,HEX_6,HEX_A}, arch_sh_dsp_up},
 
-/* 11001101i8*1.... and.b #<imm>,@(R0,GBR)*/{"and.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_D,IMM_8}},
+/* 0100nnnn01111010 lds <REG_N>,A0     */{"lds",{A_REG_N,A_A0},{HEX_4,REG_N,HEX_7,HEX_A}, arch_sh_dsp_up},
 
-/* 1010i12......... bra <bdisp12>       */{"bra",{A_BDISP12},{HEX_A,BRANCH_12}},
+/* 0100nnnn10001010 lds <REG_N>,X0     */{"lds",{A_REG_N,A_X0},{HEX_4,REG_N,HEX_8,HEX_A}, arch_sh_dsp_up},
 
-/* 1011i12......... bsr <bdisp12>       */{"bsr",{A_BDISP12},{HEX_B,BRANCH_12}},
+/* 0100nnnn10011010 lds <REG_N>,X1     */{"lds",{A_REG_N,A_X1},{HEX_4,REG_N,HEX_9,HEX_A}, arch_sh_dsp_up},
 
-/* 10001001i8p1.... bt <bdisp8>         */{"bt",{A_BDISP8},{HEX_8,HEX_9,BRANCH_8}},
+/* 0100nnnn10101010 lds <REG_N>,Y0     */{"lds",{A_REG_N,A_Y0},{HEX_4,REG_N,HEX_A,HEX_A}, arch_sh_dsp_up},
 
-/* 10001011i8p1.... bf <bdisp8>         */{"bf",{A_BDISP8},{HEX_8,HEX_B,BRANCH_8}},
+/* 0100nnnn10111010 lds <REG_N>,Y1     */{"lds",{A_REG_N,A_Y1},{HEX_4,REG_N,HEX_B,HEX_A}, arch_sh_dsp_up},
 
-/* 10001101i8p1.... bt.s <bdisp8>       */{"bt.s",{A_BDISP8},{HEX_8,HEX_D,BRANCH_8}},
+/* 0100nnnn01011010 lds <REG_N>,FPUL    */{"lds",{A_REG_M,FPUL_N},{HEX_4,REG_M,HEX_5,HEX_A}, arch_sh3e_up},
 
-/* 10001101i8p1.... bt/s <bdisp8>       */{"bt/s",{A_BDISP8},{HEX_8,HEX_D,BRANCH_8}},
+/* 0100nnnn01101010 lds <REG_M>,FPSCR   */{"lds",{A_REG_M,FPSCR_N},{HEX_4,REG_M,HEX_6,HEX_A}, arch_sh3e_up},
 
-/* 10001111i8p1.... bf.s <bdisp8>       */{"bf.s",{A_BDISP8},{HEX_8,HEX_F,BRANCH_8}},
+/* 0100nnnn00000110 lds.l @<REG_N>+,MACH*/{"lds.l",{A_INC_N,A_MACH},{HEX_4,REG_N,HEX_0,HEX_6}, arch_sh1_up},
 
-/* 10001111i8p1.... bf/s <bdisp8>       */{"bf/s",{A_BDISP8},{HEX_8,HEX_F,BRANCH_8}},
+/* 0100nnnn00010110 lds.l @<REG_N>+,MACL*/{"lds.l",{A_INC_N,A_MACL},{HEX_4,REG_N,HEX_1,HEX_6}, arch_sh1_up},
 
-/* 0000000000101000 clrmac              */{"clrmac",{0},{HEX_0,HEX_0,HEX_2,HEX_8}},
+/* 0100nnnn00100110 lds.l @<REG_N>+,PR  */{"lds.l",{A_INC_N,A_PR},{HEX_4,REG_N,HEX_2,HEX_6}, arch_sh1_up},
 
-/* 0000000001001000 clrs                */{"clrs",{0},{HEX_0,HEX_0,HEX_4,HEX_8}},
+/* 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},
 
-/* 0000000000001000 clrt                */{"clrt",{0},{HEX_0,HEX_0,HEX_0,HEX_8}},
+/* 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},
 
-/* 10001000i8*1.... cmp/eq #<imm>,R0    */{"cmp/eq",{A_IMM,A_R0},{HEX_8,HEX_8,IMM_8}},
+/* 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},
 
-/* 0011nnnnmmmm0000 cmp/eq <REG_M>,<REG_N>*/{"cmp/eq",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_0}},
+/* 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},
 
-/* 0011nnnnmmmm0011 cmp/ge <REG_M>,<REG_N>*/{"cmp/ge",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_3}},
+/* 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},
 
-/* 0011nnnnmmmm0111 cmp/gt <REG_M>,<REG_N>*/{"cmp/gt",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_7}},
+/* 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},
 
-/* 0011nnnnmmmm0110 cmp/hi <REG_M>,<REG_N>*/{"cmp/hi",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_6}},
+/* 0100nnnn01010110 lds.l @<REG_M>+,FPUL*/{"lds.l",{A_INC_M,FPUL_N},{HEX_4,REG_M,HEX_5,HEX_6}, arch_sh3e_up},
 
-/* 0011nnnnmmmm0010 cmp/hs <REG_M>,<REG_N>*/{"cmp/hs",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_2}},
+/* 0100nnnn01100110 lds.l @<REG_M>+,FPSCR*/{"lds.l",{A_INC_M,FPSCR_N},{HEX_4,REG_M,HEX_6,HEX_6}, arch_sh3e_up},
 
-/* 0100nnnn00010101 cmp/pl <REG_N>      */{"cmp/pl",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_5}},
+/* 0000000000111000 ldtlb               */{"ldtlb",{0},{HEX_0,HEX_0,HEX_3,HEX_8}, arch_sh3_up},
 
-/* 0100nnnn00010001 cmp/pz <REG_N>      */{"cmp/pz",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_1}},
+/* 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},
 
-/* 0010nnnnmmmm1100 cmp/str <REG_M>,<REG_N>*/{"cmp/str",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_C}},
+/* 1110nnnni8*1.... mov #<imm>,<REG_N>  */{"mov",{A_IMM,A_REG_N},{HEX_E,REG_N,IMM_8}, arch_sh1_up},
 
-/* 0010nnnnmmmm0111 div0s <REG_M>,<REG_N>*/{"div0s",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_7}},
+/* 0110nnnnmmmm0011 mov <REG_M>,<REG_N> */{"mov",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_3}, arch_sh1_up},
 
-/* 0000000000011001 div0u               */{"div0u",{0},{HEX_0,HEX_0,HEX_1,HEX_9}},
+/* 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},
 
-/* 0011nnnnmmmm0100 div1 <REG_M>,<REG_N>*/{"div1",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_4}},
+/* 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},
 
-/* 0110nnnnmmmm1110 exts.b <REG_M>,<REG_N>*/{"exts.b",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_E}},
+/* 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},
 
-/* 0110nnnnmmmm1111 exts.w <REG_M>,<REG_N>*/{"exts.w",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_F}},
+/* 10000100mmmmi4*1 mov.b @(<disp>,<REG_M>),R0*/{"mov.b",{A_DISP_REG_M,A_R0},{HEX_8,HEX_4,REG_M,IMM_4}, 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}},
+/* 11000100i8*1.... mov.b @(<disp>,GBR),R0*/{"mov.b",{A_DISP_GBR,A_R0},{HEX_C,HEX_4,IMM_8}, 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}},
+/* 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},
 
-/* 0100nnnn00101011 jmp @<REG_N>        */{"jmp",{A_IND_N},{HEX_4,REG_N,HEX_2,HEX_B}},
+/* 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},
 
-/* 0100nnnn00001011 jsr @<REG_N>        */{"jsr",{A_IND_N},{HEX_4,REG_N,HEX_0,HEX_B}},
+/* 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},
 
-/* 0100nnnn00001110 ldc <REG_N>,SR      */{"ldc",{A_REG_N,A_SR},{HEX_4,REG_N,HEX_0,HEX_E}},
+/* 10000000mmmmi4*1 mov.b R0,@(<disp>,<REG_M>)*/{"mov.b",{A_R0,A_DISP_REG_M},{HEX_8,HEX_0,REG_M,IMM_4}, arch_sh1_up},
 
-/* 0100nnnn00011110 ldc <REG_N>,GBR     */{"ldc",{A_REG_N,A_GBR},{HEX_4,REG_N,HEX_1,HEX_E}},
+/* 11000000i8*1.... mov.b R0,@(<disp>,GBR)*/{"mov.b",{A_R0,A_DISP_GBR},{HEX_C,HEX_0,IMM_8}, arch_sh1_up},
 
-/* 0100nnnn00101110 ldc <REG_N>,VBR     */{"ldc",{A_REG_N,A_VBR},{HEX_4,REG_N,HEX_2,HEX_E}},
+/* 0001nnnnmmmmi4*4 mov.l <REG_M>,@(<disp>,<REG_N>)*/{"mov.l",{ A_REG_M,A_DISP_REG_N},{HEX_1,REG_N,REG_M,IMM_4BY4}, arch_sh1_up},
 
-/* 0100nnnn00111110 ldc <REG_N>,SSR     */{"ldc",{A_REG_N,A_SSR},{HEX_4,REG_N,HEX_3,HEX_E}},
+/* 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},
 
-/* 0100nnnn01001110 ldc <REG_N>,SPC     */{"ldc",{A_REG_N,A_SPC},{HEX_4,REG_N,HEX_4,HEX_E}},
+/* 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},
 
-/* 0100nnnn11111010 ldc <REG_N>,DBR     */{"ldc",{A_REG_N,A_DBR},{HEX_4,REG_N,HEX_F,HEX_A}},
+/* 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},
 
-/* 0100nnnn1xxx1110 ldc <REG_N>,Rn_BANK */{"ldc",{A_REG_N,A_REG_B},{HEX_4,REG_N,REG_B,HEX_E}},
+/* 0101nnnnmmmmi4*4 mov.l @(<disp>,<REG_M>),<REG_N>*/{"mov.l",{A_DISP_REG_M,A_REG_N},{HEX_5,REG_N,REG_M,IMM_4BY4}, arch_sh1_up},
 
-/* 0100nnnn00000111 ldc.l @<REG_N>+,SR  */{"ldc.l",{A_INC_N,A_SR},{HEX_4,REG_N,HEX_0,HEX_7}},
+/* 11000110i8*4.... mov.l @(<disp>,GBR),R0*/{"mov.l",{A_DISP_GBR,A_R0},{HEX_C,HEX_6,IMM_8BY4}, arch_sh1_up},
 
-/* 0100nnnn00010111 ldc.l @<REG_N>+,GBR */{"ldc.l",{A_INC_N,A_GBR},{HEX_4,REG_N,HEX_1,HEX_7}},
+/* 1101nnnni8p4.... mov.l @(<disp>,PC),<REG_N>*/{"mov.l",{A_DISP_PC,A_REG_N},{HEX_D,REG_N,PCRELIMM_8BY4}, arch_sh1_up},
 
-/* 0100nnnn00100111 ldc.l @<REG_N>+,VBR */{"ldc.l",{A_INC_N,A_VBR},{HEX_4,REG_N,HEX_2,HEX_7}},
+/* 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},
 
-/* 0100nnnn00110111 ldc.l @<REG_N>+,SSR */{"ldc.l",{A_INC_N,A_SSR},{HEX_4,REG_N,HEX_3,HEX_7}},
+/* 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},
 
-/* 0100nnnn01000111 ldc.l @<REG_N>+,SPC */{"ldc.l",{A_INC_N,A_SPC},{HEX_4,REG_N,HEX_4,HEX_7}},
+/* 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},
 
-/* 0100nnnn11110110 ldc.l @<REG_N>+,DBR */{"ldc.l",{A_INC_N,A_DBR},{HEX_4,REG_N,HEX_F,HEX_6}},
+/* 11000010i8*4.... mov.l R0,@(<disp>,GBR)*/{"mov.l",{A_R0,A_DISP_GBR},{HEX_C,HEX_2,IMM_8BY4}, arch_sh1_up},
 
-/* 0100nnnn1xxx0111 ldc.l <REG_N>,Rn_BANK */{"ldc.l",{A_INC_N,A_REG_B},{HEX_4,REG_N,REG_B,HEX_7}},
+/* 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},
 
-/* 0100nnnn00001010 lds <REG_N>,MACH    */{"lds",{A_REG_N,A_MACH},{HEX_4,REG_N,HEX_0,HEX_A}},
+/* 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},
 
-/* 0100nnnn00011010 lds <REG_N>,MACL    */{"lds",{A_REG_N,A_MACL},{HEX_4,REG_N,HEX_1,HEX_A}},
+/* 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},
 
-/* 0100nnnn00101010 lds <REG_N>,PR      */{"lds",{A_REG_N,A_PR},{HEX_4,REG_N,HEX_2,HEX_A}},
+/* 10000101mmmmi4*2 mov.w @(<disp>,<REG_M>),R0*/{"mov.w",{A_DISP_REG_M,A_R0},{HEX_8,HEX_5,REG_M,IMM_4BY2}, arch_sh1_up},
 
-/* 0100nnnn01011010 lds <REG_N>,FPUL    */{"lds",{A_REG_M,FPUL_N},{HEX_4,REG_M,HEX_5,HEX_A}},
+/* 11000101i8*2.... mov.w @(<disp>,GBR),R0*/{"mov.w",{A_DISP_GBR,A_R0},{HEX_C,HEX_5,IMM_8BY2}, arch_sh1_up},
 
-/* 0100nnnn01101010 lds <REG_M>,FPSCR   */{"lds",{A_REG_M,FPSCR_N},{HEX_4,REG_M,HEX_6,HEX_A}},
+/* 1001nnnni8p2.... mov.w @(<disp>,PC),<REG_N>*/{"mov.w",{A_DISP_PC,A_REG_N},{HEX_9,REG_N,PCRELIMM_8BY2}, arch_sh1_up},
 
-/* 0100nnnn00000110 lds.l @<REG_N>+,MACH*/{"lds.l",{A_INC_N,A_MACH},{HEX_4,REG_N,HEX_0,HEX_6}},
+/* 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},
 
-/* 0100nnnn00010110 lds.l @<REG_N>+,MACL*/{"lds.l",{A_INC_N,A_MACL},{HEX_4,REG_N,HEX_1,HEX_6}},
+/* 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},
 
-/* 0100nnnn00100110 lds.l @<REG_N>+,PR  */{"lds.l",{A_INC_N,A_PR},{HEX_4,REG_N,HEX_2,HEX_6}},
+/* 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},
 
-/* 0100nnnn01010110 lds.l @<REG_M>+,FPUL*/{"lds.l",{A_INC_M,FPUL_N},{HEX_4,REG_M,HEX_5,HEX_6}},
+/* 10000001mmmmi4*2 mov.w R0,@(<disp>,<REG_M>)*/{"mov.w",{A_R0,A_DISP_REG_M},{HEX_8,HEX_1,REG_M,IMM_4BY2}, arch_sh1_up},
 
-/* 0100nnnn01100110 lds.l @<REG_M>+,FPSCR*/{"lds.l",{A_INC_M,FPSCR_N},{HEX_4,REG_M,HEX_6,HEX_6}},
+/* 11000001i8*2.... mov.w R0,@(<disp>,GBR)*/{"mov.w",{A_R0,A_DISP_GBR},{HEX_C,HEX_1,IMM_8BY2}, arch_sh1_up},
 
-/* 0000000000111000 ldtlb               */{"ldtlb",{0},{HEX_0,HEX_0,HEX_3,HEX_8}},
+/* 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_up},
 
-/* 0100nnnnmmmm1111 mac.w @<REG_M>+,@<REG_N>+*/{"mac.w",{A_INC_M,A_INC_N},{HEX_4,REG_N,REG_M,HEX_F}},
 
-/* 1110nnnni8*1.... mov #<imm>,<REG_N>  */{"mov",{A_IMM,A_REG_N},{HEX_E,REG_N,IMM_8}},
+/* 0000nnnn00101001 movt <REG_N>        */{"movt",{A_REG_N},{HEX_0,REG_N,HEX_2,HEX_9}, arch_sh1_up},
 
-/* 0110nnnnmmmm0011 mov <REG_M>,<REG_N> */{"mov",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_3}},
+/* 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},
 
-/* 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}},
+/* 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},
 
-/* 0010nnnnmmmm0100 mov.b <REG_M>,@-<REG_N>*/{"mov.b",{ A_REG_M,A_DEC_N},{HEX_2,REG_N,REG_M,HEX_4}},
+/* 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},
 
-/* 0010nnnnmmmm0000 mov.b <REG_M>,@<REG_N>*/{"mov.b",{ A_REG_M,A_IND_N},{HEX_2,REG_N,REG_M,HEX_0}},
+/* 0110nnnnmmmm1011 neg <REG_M>,<REG_N> */{"neg",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_B}, 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,IMM_4}},
+/* 0110nnnnmmmm1010 negc <REG_M>,<REG_N>*/{"negc",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_A}, arch_sh1_up},
 
-/* 11000100i8*1.... mov.b @(<disp>,GBR),R0*/{"mov.b",{A_DISP_GBR,A_R0},{HEX_C,HEX_4,IMM_8}},
+/* 0000000000001001 nop                 */{"nop",{0},{HEX_0,HEX_0,HEX_0,HEX_9}, 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}},
+/* 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_up},
 
-/* 0110nnnnmmmm0100 mov.b @<REG_M>+,<REG_N>*/{"mov.b",{A_INC_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_4}},
+/* 0000nnnn10100011 ocbp @<REG_N>       */{"ocbp",{A_IND_N},{HEX_0,REG_N,HEX_A,HEX_3}, arch_sh4_up},
 
-/* 0110nnnnmmmm0000 mov.b @<REG_M>,<REG_N>*/{"mov.b",{A_IND_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_0}},
+/* 0000nnnn10110011 ocbwb @<REG_N>      */{"ocbwb",{A_IND_N},{HEX_0,REG_N,HEX_B,HEX_3}, arch_sh4_up},
 
-/* 10000000mmmmi4*1 mov.b R0,@(<disp>,<REG_M>)*/{"mov.b",{A_R0,A_DISP_REG_M},{HEX_8,HEX_0,REG_M,IMM_4}},
 
-/* 11000000i8*1.... mov.b R0,@(<disp>,GBR)*/{"mov.b",{A_R0,A_DISP_GBR},{HEX_C,HEX_0,IMM_8}},
+/* 11001011i8*1.... or #<imm>,R0        */{"or",{A_IMM,A_R0},{HEX_C,HEX_B,IMM_8}, arch_sh1_up},
 
-/* 0001nnnnmmmmi4*4 mov.l <REG_M>,@(<disp>,<REG_N>)*/{"mov.l",{ A_REG_M,A_DISP_REG_N},{HEX_1,REG_N,REG_M,IMM_4BY4}},
+/* 0010nnnnmmmm1011 or <REG_M>,<REG_N>  */{"or",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_B}, 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}},
+/* 11001111i8*1.... or.b #<imm>,@(R0,GBR)*/{"or.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_F,IMM_8}, 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}},
+/* 0000nnnn10000011 pref @<REG_N>       */{"pref",{A_IND_N},{HEX_0,REG_N,HEX_8,HEX_3}, arch_sh4_up},
 
-/* 0010nnnnmmmm0010 mov.l <REG_M>,@<REG_N>*/{"mov.l",{ A_REG_M,A_IND_N},{HEX_2,REG_N,REG_M,HEX_2}},
+/* 0100nnnn00100100 rotcl <REG_N>       */{"rotcl",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_4}, 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,IMM_4BY4}},
+/* 0100nnnn00100101 rotcr <REG_N>       */{"rotcr",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_5}, arch_sh1_up},
 
-/* 11000110i8*4.... mov.l @(<disp>,GBR),R0*/{"mov.l",{A_DISP_GBR,A_R0},{HEX_C,HEX_6,IMM_8BY4}},
+/* 0100nnnn00000100 rotl <REG_N>        */{"rotl",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_4}, arch_sh1_up},
 
-/* 1101nnnni8p4.... mov.l @(<disp>,PC),<REG_N>*/{"mov.l",{A_DISP_PC,A_REG_N},{HEX_D,REG_N,PCRELIMM_8BY4}},
+/* 0100nnnn00000101 rotr <REG_N>        */{"rotr",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_5}, 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}},
+/* 0000000000101011 rte                 */{"rte",{0},{HEX_0,HEX_0,HEX_2,HEX_B}, 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}},
+/* 0000000000001011 rts                 */{"rts",{0},{HEX_0,HEX_0,HEX_0,HEX_B}, 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}},
+/* 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},
 
-/* 11000010i8*4.... mov.l R0,@(<disp>,GBR)*/{"mov.l",{A_R0,A_DISP_GBR},{HEX_C,HEX_2,IMM_8BY4}},
+/* 0100nnnn00010100 setrc <REG_N>       */{"setrc",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_4}, arch_sh_dsp_up},
 
-/* 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}},
+/* 10000010i8*1.... setrc #<imm>        */{"setrc",{A_IMM},{HEX_8,HEX_2,IMM_8}, arch_sh_dsp_up},
 
-/* 0010nnnnmmmm0101 mov.w <REG_M>,@-<REG_N>*/{"mov.w",{ A_REG_M,A_DEC_N},{HEX_2,REG_N,REG_M,HEX_5}},
+/* 0100nnnnmmmm1100 shad <REG_M>,<REG_N>*/{"shad",{ A_REG_M,A_REG_N},{HEX_4,REG_N,REG_M,HEX_C}, arch_sh3_up},
 
-/* 0010nnnnmmmm0001 mov.w <REG_M>,@<REG_N>*/{"mov.w",{ A_REG_M,A_IND_N},{HEX_2,REG_N,REG_M,HEX_1}},
+/* 0100nnnnmmmm1101 shld <REG_M>,<REG_N>*/{"shld",{ A_REG_M,A_REG_N},{HEX_4,REG_N,REG_M,HEX_D}, arch_sh3_up},
 
-/* 10000101mmmmi4*2 mov.w @(<disp>,<REG_M>),R0*/{"mov.w",{A_DISP_REG_M,A_R0},{HEX_8,HEX_5,REG_M,IMM_4BY2}},
+/* 0100nnnn00100000 shal <REG_N>        */{"shal",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_0}, arch_sh1_up},
 
-/* 11000101i8*2.... mov.w @(<disp>,GBR),R0*/{"mov.w",{A_DISP_GBR,A_R0},{HEX_C,HEX_5,IMM_8BY2}},
+/* 0100nnnn00100001 shar <REG_N>        */{"shar",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_1}, arch_sh1_up},
 
-/* 1001nnnni8p2.... mov.w @(<disp>,PC),<REG_N>*/{"mov.w",{A_DISP_PC,A_REG_N},{HEX_9,REG_N,PCRELIMM_8BY2}},
+/* 0100nnnn00000000 shll <REG_N>        */{"shll",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_0}, 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}},
+/* 0100nnnn00101000 shll16 <REG_N>      */{"shll16",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_8}, 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}},
+/* 0100nnnn00001000 shll2 <REG_N>       */{"shll2",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_8}, 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}},
+/* 0100nnnn00011000 shll8 <REG_N>       */{"shll8",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_8}, 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,IMM_4BY2}},
+/* 0100nnnn00000001 shlr <REG_N>        */{"shlr",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_1}, arch_sh1_up},
 
-/* 11000001i8*2.... mov.w R0,@(<disp>,GBR)*/{"mov.w",{A_R0,A_DISP_GBR},{HEX_C,HEX_1,IMM_8BY2}},
+/* 0100nnnn00101001 shlr16 <REG_N>      */{"shlr16",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_9}, arch_sh1_up},
 
-/* 11000111i8p4.... mova @(<disp>,PC),R0*/{"mova",{A_DISP_PC,A_R0},{HEX_C,HEX_7,PCRELIMM_8BY4}},
-/* 0000nnnn11000011 movca.l R0,@<REG_N> */{"movca.l",{A_R0,A_IND_N},{HEX_0,REG_N,HEX_C,HEX_3}},
+/* 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},
 
-/* 0000nnnn00101001 movt <REG_N>        */{"movt",{A_REG_N},{HEX_0,REG_N,HEX_2,HEX_9}},
+/* 0000000000011011 sleep               */{"sleep",{0},{HEX_0,HEX_0,HEX_1,HEX_B}, arch_sh1_up},
 
-/* 0010nnnnmmmm1111 muls.w <REG_M>,<REG_N>*/{"muls.w",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_F}},
-/* 0010nnnnmmmm1111 muls <REG_M>,<REG_N>*/{"muls",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_F}},
+/* 0000nnnn00000010 stc SR,<REG_N>      */{"stc",{A_SR,A_REG_N},{HEX_0,REG_N,HEX_0,HEX_2}, 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}},
+/* 0000nnnn00010010 stc GBR,<REG_N>     */{"stc",{A_GBR,A_REG_N},{HEX_0,REG_N,HEX_1,HEX_2}, arch_sh1_up},
 
-/* 0010nnnnmmmm1110 mulu.w <REG_M>,<REG_N>*/{"mulu.w",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_E}},
-/* 0010nnnnmmmm1110 mulu <REG_M>,<REG_N>*/{"mulu",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_E}},
+/* 0000nnnn00100010 stc VBR,<REG_N>     */{"stc",{A_VBR,A_REG_N},{HEX_0,REG_N,HEX_2,HEX_2}, arch_sh1_up},
 
-/* 0110nnnnmmmm1011 neg <REG_M>,<REG_N> */{"neg",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_B}},
+/* 0000nnnn01010010 stc MOD,<REG_N>     */{"stc",{A_MOD,A_REG_N},{HEX_0,REG_N,HEX_5,HEX_2}, arch_sh_dsp_up},
 
-/* 0110nnnnmmmm1010 negc <REG_M>,<REG_N>*/{"negc",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_A}},
+/* 0000nnnn01110010 stc RE,<REG_N>     */{"stc",{A_RE,A_REG_N},{HEX_0,REG_N,HEX_7,HEX_2}, arch_sh_dsp_up},
 
-/* 0000000000001001 nop                 */{"nop",{0},{HEX_0,HEX_0,HEX_0,HEX_9}},
+/* 0000nnnn01100010 stc RS,<REG_N>     */{"stc",{A_RS,A_REG_N},{HEX_0,REG_N,HEX_6,HEX_2}, arch_sh_dsp_up},
 
-/* 0110nnnnmmmm0111 not <REG_M>,<REG_N> */{"not",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_7}},
-/* 0000nnnn10010011 ocbi @<REG_N>       */{"ocbi",{A_IND_N},{HEX_0,REG_N,HEX_9,HEX_3}},
+/* 0000nnnn00110010 stc SSR,<REG_N>     */{"stc",{A_SSR,A_REG_N},{HEX_0,REG_N,HEX_3,HEX_2}, arch_sh3_up},
 
-/* 0000nnnn10100011 ocbp @<REG_N>       */{"ocbp",{A_IND_N},{HEX_0,REG_N,HEX_A,HEX_3}},
+/* 0000nnnn01000010 stc SPC,<REG_N>     */{"stc",{A_SPC,A_REG_N},{HEX_0,REG_N,HEX_4,HEX_2}, arch_sh3_up},
 
-/* 0000nnnn10110011 ocbwb @<REG_N>      */{"ocbwb",{A_IND_N},{HEX_0,REG_N,HEX_B,HEX_3}},
+/* 0000nnnn00111010 stc SGR,<REG_N>     */{"stc",{A_SGR,A_REG_N},{HEX_0,REG_N,HEX_3,HEX_A}, arch_sh4_up},
 
+/* 0000nnnn11111010 stc DBR,<REG_N>     */{"stc",{A_DBR,A_REG_N},{HEX_0,REG_N,HEX_F,HEX_A}, arch_sh4_up},
 
-/* 11001011i8*1.... or #<imm>,R0        */{"or",{A_IMM,A_R0},{HEX_C,HEX_B,IMM_8}},
+/* 0000nnnn1xxx0010 stc Rn_BANK,<REG_N> */{"stc",{A_REG_B,A_REG_N},{HEX_0,REG_N,REG_B,HEX_2}, arch_sh3_up},
 
-/* 0010nnnnmmmm1011 or <REG_M>,<REG_N>  */{"or",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_B}},
+/* 0100nnnn00000011 stc.l SR,@-<REG_N>  */{"stc.l",{A_SR,A_DEC_N},{HEX_4,REG_N,HEX_0,HEX_3}, arch_sh1_up},
 
-/* 11001111i8*1.... or.b #<imm>,@(R0,GBR)*/{"or.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_F,IMM_8}},
+/* 0100nnnn00100011 stc.l VBR,@-<REG_N> */{"stc.l",{A_VBR,A_DEC_N},{HEX_4,REG_N,HEX_2,HEX_3}, arch_sh1_up},
 
-/* 0000nnnn10000011 pref @<REG_N>       */{"pref",{A_IND_N},{HEX_0,REG_N,HEX_8,HEX_3}},
+/* 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},
 
-/* 0100nnnn00100100 rotcl <REG_N>       */{"rotcl",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_4}},
+/* 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},
 
-/* 0100nnnn00100101 rotcr <REG_N>       */{"rotcr",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_5}},
+/* 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},
 
-/* 0100nnnn00000100 rotl <REG_N>        */{"rotl",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_4}},
+/* 0100nnnn00110011 stc.l SSR,@-<REG_N> */{"stc.l",{A_SSR,A_DEC_N},{HEX_4,REG_N,HEX_3,HEX_3}, arch_sh3_up},
 
-/* 0100nnnn00000101 rotr <REG_N>        */{"rotr",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_5}},
+/* 0100nnnn01000011 stc.l SPC,@-<REG_N> */{"stc.l",{A_SPC,A_DEC_N},{HEX_4,REG_N,HEX_4,HEX_3}, arch_sh3_up},
 
-/* 0000000000101011 rte                 */{"rte",{0},{HEX_0,HEX_0,HEX_2,HEX_B}},
+/* 0100nnnn00010011 stc.l GBR,@-<REG_N> */{"stc.l",{A_GBR,A_DEC_N},{HEX_4,REG_N,HEX_1,HEX_3}, arch_sh4_up},
 
-/* 0000000000001011 rts                 */{"rts",{0},{HEX_0,HEX_0,HEX_0,HEX_B}},
+/* 0100nnnn00110010 stc.l SGR,@-<REG_N> */{"stc.l",{A_SGR,A_DEC_N},{HEX_4,REG_N,HEX_3,HEX_2}, arch_sh4_up},
 
-/* 0000000001011000 sets                */{"sets",{0},{HEX_0,HEX_0,HEX_5,HEX_8}},
-/* 0000000000011000 sett                */{"sett",{0},{HEX_0,HEX_0,HEX_1,HEX_8}},
+/* 0100nnnn11110010 stc.l DBR,@-<REG_N> */{"stc.l",{A_DBR,A_DEC_N},{HEX_4,REG_N,HEX_F,HEX_2}, arch_sh4_up},
 
-/* 0100nnnnmmmm1100 shad <REG_M>,<REG_N>*/{"shad",{ A_REG_M,A_REG_N},{HEX_4,REG_N,REG_M,HEX_C}},
+/* 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_up},
 
-/* 0100nnnnmmmm1101 shld <REG_M>,<REG_N>*/{"shld",{ A_REG_M,A_REG_N},{HEX_4,REG_N,REG_M,HEX_D}},
+/* 0000nnnn00001010 sts MACH,<REG_N>    */{"sts",{A_MACH,A_REG_N},{HEX_0,REG_N,HEX_0,HEX_A}, arch_sh1_up},
 
-/* 0100nnnn00100000 shal <REG_N>        */{"shal",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_0}},
+/* 0000nnnn00011010 sts MACL,<REG_N>    */{"sts",{A_MACL,A_REG_N},{HEX_0,REG_N,HEX_1,HEX_A}, arch_sh1_up},
 
-/* 0100nnnn00100001 shar <REG_N>        */{"shar",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_1}},
+/* 0000nnnn00101010 sts PR,<REG_N>      */{"sts",{A_PR,A_REG_N},{HEX_0,REG_N,HEX_2,HEX_A}, arch_sh1_up},
 
-/* 0100nnnn00000000 shll <REG_N>        */{"shll",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_0}},
+/* 0000nnnn01101010 sts DSR,<REG_N>    */{"sts",{A_DSR,A_REG_N},{HEX_0,REG_N,HEX_6,HEX_A}, arch_sh_dsp_up},
 
-/* 0100nnnn00101000 shll16 <REG_N>      */{"shll16",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_8}},
+/* 0000nnnn01111010 sts A0,<REG_N>     */{"sts",{A_A0,A_REG_N},{HEX_0,REG_N,HEX_7,HEX_A}, arch_sh_dsp_up},
 
-/* 0100nnnn00001000 shll2 <REG_N>       */{"shll2",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_8}},
+/* 0000nnnn10001010 sts X0,<REG_N>     */{"sts",{A_X0,A_REG_N},{HEX_0,REG_N,HEX_8,HEX_A}, arch_sh_dsp_up},
 
-/* 0100nnnn00011000 shll8 <REG_N>       */{"shll8",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_8}},
+/* 0000nnnn10011010 sts X1,<REG_N>     */{"sts",{A_X1,A_REG_N},{HEX_0,REG_N,HEX_9,HEX_A}, arch_sh_dsp_up},
 
-/* 0100nnnn00000001 shlr <REG_N>        */{"shlr",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_1}},
+/* 0000nnnn10101010 sts Y0,<REG_N>     */{"sts",{A_Y0,A_REG_N},{HEX_0,REG_N,HEX_A,HEX_A}, arch_sh_dsp_up},
 
-/* 0100nnnn00101001 shlr16 <REG_N>      */{"shlr16",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_9}},
+/* 0000nnnn10111010 sts Y1,<REG_N>     */{"sts",{A_Y1,A_REG_N},{HEX_0,REG_N,HEX_B,HEX_A}, arch_sh_dsp_up},
 
-/* 0100nnnn00001001 shlr2 <REG_N>       */{"shlr2",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_9}},
+/* 0000nnnn01011010 sts FPUL,<REG_N>    */{"sts",{FPUL_M,A_REG_N},{HEX_0,REG_N,HEX_5,HEX_A}, arch_sh3e_up},
 
-/* 0100nnnn00011001 shlr8 <REG_N>       */{"shlr8",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_9}},
+/* 0000nnnn01101010 sts FPSCR,<REG_N>   */{"sts",{FPSCR_M,A_REG_N},{HEX_0,REG_N,HEX_6,HEX_A}, arch_sh3e_up},
 
-/* 0000000000011011 sleep               */{"sleep",{0},{HEX_0,HEX_0,HEX_1,HEX_B}},
+/* 0100nnnn00000010 sts.l MACH,@-<REG_N>*/{"sts.l",{A_MACH,A_DEC_N},{HEX_4,REG_N,HEX_0,HEX_2}, arch_sh1_up},
 
-/* 0000nnnn00000010 stc SR,<REG_N>      */{"stc",{A_SR,A_REG_N},{HEX_0,REG_N,HEX_0,HEX_2}},
+/* 0100nnnn00010010 sts.l MACL,@-<REG_N>*/{"sts.l",{A_MACL,A_DEC_N},{HEX_4,REG_N,HEX_1,HEX_2}, arch_sh1_up},
 
-/* 0000nnnn00010010 stc GBR,<REG_N>     */{"stc",{A_GBR,A_REG_N},{HEX_0,REG_N,HEX_1,HEX_2}},
+/* 0100nnnn00100010 sts.l PR,@-<REG_N>  */{"sts.l",{A_PR,A_DEC_N},{HEX_4,REG_N,HEX_2,HEX_2}, arch_sh1_up},
 
-/* 0000nnnn00100010 stc VBR,<REG_N>     */{"stc",{A_VBR,A_REG_N},{HEX_0,REG_N,HEX_2,HEX_2}},
+/* 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},
 
-/* 0000nnnn00110010 stc SSR,<REG_N>     */{"stc",{A_SSR,A_REG_N},{HEX_0,REG_N,HEX_3,HEX_2}},
+/* 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},
 
-/* 0000nnnn01000010 stc SPC,<REG_N>     */{"stc",{A_SPC,A_REG_N},{HEX_0,REG_N,HEX_4,HEX_2}},
+/* 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},
 
-/* 0000nnnn00111010 stc SGR,<REG_N>     */{"stc",{A_SGR,A_REG_N},{HEX_0,REG_N,HEX_3,HEX_A}},
+/* 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},
 
-/* 0000nnnn11111010 stc DBR,<REG_N>     */{"stc",{A_DBR,A_REG_N},{HEX_0,REG_N,HEX_F,HEX_A}},
+/* 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},
 
-/* 0000nnnn1xxx0010 stc Rn_BANK,<REG_N> */{"stc",{A_REG_B,A_REG_N},{HEX_0,REG_N,REG_B,HEX_2}},
+/* 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},
 
-/* 0100nnnn00000011 stc.l SR,@-<REG_N>  */{"stc.l",{A_SR,A_DEC_N},{HEX_4,REG_N,HEX_0,HEX_3}},
+/* 0100nnnn01010010 sts.l FPUL,@-<REG_N>*/{"sts.l",{FPUL_M,A_DEC_N},{HEX_4,REG_N,HEX_5,HEX_2}, arch_sh3e_up},
 
-/* 0100nnnn00010011 stc.l GBR,@-<REG_N> */{"stc.l",{A_GBR,A_DEC_N},{HEX_4,REG_N,HEX_1,HEX_3}},
+/* 0100nnnn01100010 sts.l FPSCR,@-<REG_N>*/{"sts.l",{FPSCR_M,A_DEC_N},{HEX_4,REG_N,HEX_6,HEX_2}, arch_sh3e_up},
 
-/* 0100nnnn00100011 stc.l VBR,@-<REG_N> */{"stc.l",{A_VBR,A_DEC_N},{HEX_4,REG_N,HEX_2,HEX_3}},
+/* 0011nnnnmmmm1000 sub <REG_M>,<REG_N> */{"sub",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_8}, arch_sh1_up},
 
-/* 0100nnnn00110011 stc.l SSR,@-<REG_N> */{"stc.l",{A_SSR,A_DEC_N},{HEX_4,REG_N,HEX_3,HEX_3}},
+/* 0011nnnnmmmm1010 subc <REG_M>,<REG_N>*/{"subc",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_A}, arch_sh1_up},
 
-/* 0100nnnn01000011 stc.l SPC,@-<REG_N> */{"stc.l",{A_SPC,A_DEC_N},{HEX_4,REG_N,HEX_4,HEX_3}},
+/* 0011nnnnmmmm1011 subv <REG_M>,<REG_N>*/{"subv",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_B}, arch_sh1_up},
 
-/* 0100nnnn00110010 stc.l SGR,@-<REG_N> */{"stc.l",{A_SGR,A_DEC_N},{HEX_4,REG_N,HEX_3,HEX_2}},
+/* 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},
 
-/* 0100nnnn11110010 stc.l DBR,@-<REG_N> */{"stc.l",{A_DBR,A_DEC_N},{HEX_4,REG_N,HEX_F,HEX_2}},
+/* 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},
 
-/* 0100nnnn1xxx0011 stc.l Rn_BANK,@-<REG_N> */{"stc.l",{A_REG_B,A_DEC_N},{HEX_4,REG_N,REG_B,HEX_3}},
+/* 0100nnnn00011011 tas.b @<REG_N>      */{"tas.b",{A_IND_N},{HEX_4,REG_N,HEX_1,HEX_B}, arch_sh1_up},
 
-/* 0000nnnn00001010 sts MACH,<REG_N>    */{"sts",{A_MACH,A_REG_N},{HEX_0,REG_N,HEX_0,HEX_A}},
+/* 11000011i8*1.... trapa #<imm>        */{"trapa",{A_IMM},{HEX_C,HEX_3,IMM_8}, arch_sh1_up},
 
-/* 0000nnnn00011010 sts MACL,<REG_N>    */{"sts",{A_MACL,A_REG_N},{HEX_0,REG_N,HEX_1,HEX_A}},
+/* 11001000i8*1.... tst #<imm>,R0       */{"tst",{A_IMM,A_R0},{HEX_C,HEX_8,IMM_8}, arch_sh1_up},
 
-/* 0000nnnn00101010 sts PR,<REG_N>      */{"sts",{A_PR,A_REG_N},{HEX_0,REG_N,HEX_2,HEX_A}},
+/* 0010nnnnmmmm1000 tst <REG_M>,<REG_N> */{"tst",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_8}, arch_sh1_up},
 
-/* 0000nnnn01011010 sts FPUL,<REG_N>    */{"sts",{FPUL_M,A_REG_N},{HEX_0,REG_N,HEX_5,HEX_A}},
+/* 11001100i8*1.... tst.b #<imm>,@(R0,GBR)*/{"tst.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_C,IMM_8}, arch_sh1_up},
 
-/* 0000nnnn01101010 sts FPSCR,<REG_N>   */{"sts",{FPSCR_M,A_REG_N},{HEX_0,REG_N,HEX_6,HEX_A}},
+/* 11001010i8*1.... xor #<imm>,R0       */{"xor",{A_IMM,A_R0},{HEX_C,HEX_A,IMM_8}, arch_sh1_up},
 
-/* 0100nnnn00000010 sts.l MACH,@-<REG_N>*/{"sts.l",{A_MACH,A_DEC_N},{HEX_4,REG_N,HEX_0,HEX_2}},
+/* 0010nnnnmmmm1010 xor <REG_M>,<REG_N> */{"xor",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_A}, arch_sh1_up},
 
-/* 0100nnnn00010010 sts.l MACL,@-<REG_N>*/{"sts.l",{A_MACL,A_DEC_N},{HEX_4,REG_N,HEX_1,HEX_2}},
+/* 11001110i8*1.... xor.b #<imm>,@(R0,GBR)*/{"xor.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_E,IMM_8}, arch_sh1_up},
 
-/* 0100nnnn00100010 sts.l PR,@-<REG_N>  */{"sts.l",{A_PR,A_DEC_N},{HEX_4,REG_N,HEX_2,HEX_2}},
+/* 0010nnnnmmmm1101 xtrct <REG_M>,<REG_N>*/{"xtrct",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_D}, arch_sh1_up},
 
-/* 0100nnnn01010010 sts.l FPUL,@-<REG_N>*/{"sts.l",{FPUL_M,A_DEC_N},{HEX_4,REG_N,HEX_5,HEX_2}},
+/* 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},
 
-/* 0100nnnn01100010 sts.l FPSCR,@-<REG_N>*/{"sts.l",{FPSCR_M,A_DEC_N},{HEX_4,REG_N,HEX_6,HEX_2}},
+/* 0100nnnn00010000 dt <REG_N>          */{"dt",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_0}, arch_sh2_up},
 
-/* 0011nnnnmmmm1000 sub <REG_M>,<REG_N> */{"sub",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_8}},
+/* 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},
 
-/* 0011nnnnmmmm1010 subc <REG_M>,<REG_N>*/{"subc",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_A}},
+/* 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},
 
-/* 0011nnnnmmmm1011 subv <REG_M>,<REG_N>*/{"subv",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_B}},
+/* 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},
 
-/* 0110nnnnmmmm1000 swap.b <REG_M>,<REG_N>*/{"swap.b",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_8}},
+/* 0000nnnn00100011 braf <REG_N>       */{"braf",{A_REG_N},{HEX_0,REG_N,HEX_2,HEX_3}, arch_sh2_up},
 
-/* 0110nnnnmmmm1001 swap.w <REG_M>,<REG_N>*/{"swap.w",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_9}},
+/* 0000nnnn00000011 bsrf <REG_N>       */{"bsrf",{A_REG_N},{HEX_0,REG_N,HEX_0,HEX_3}, arch_sh2_up},
 
-/* 0100nnnn00011011 tas.b @<REG_N>      */{"tas.b",{A_IND_N},{HEX_4,REG_N,HEX_1,HEX_B}},
+/* 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},
 
-/* 11000011i8*1.... trapa #<imm>        */{"trapa",{A_IMM},{HEX_C,HEX_3,IMM_8}},
+/* 111101nnmmmm0001 movs.w @<REG_N>,<DSP_REG_M> */    {"movs.w",{A_IND_N,DSP_REG_M},{HEX_F,SDT_REG_N,REG_M,HEX_1}, arch_sh_dsp_up},
 
-/* 11001000i8*1.... tst #<imm>,R0       */{"tst",{A_IMM,A_R0},{HEX_C,HEX_8,IMM_8}},
+/* 111101nnmmmm0010 movs.w @<REG_N>+,<DSP_REG_M> */   {"movs.w",{A_INC_N,DSP_REG_M},{HEX_F,SDT_REG_N,REG_M,HEX_2}, arch_sh_dsp_up},
 
-/* 0010nnnnmmmm1000 tst <REG_M>,<REG_N> */{"tst",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_8}},
+/* 111101nnmmmm0011 movs.w @<REG_N>+r8,<DSP_REG_M> */ {"movs.w",{A_PMOD_N,DSP_REG_M},{HEX_F,SDT_REG_N,REG_M,HEX_3}, arch_sh_dsp_up},
 
-/* 11001100i8*1.... tst.b #<imm>,@(R0,GBR)*/{"tst.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_C,IMM_8}},
+/* 111101nnmmmm0100 movs.w <DSP_REG_M>,@-<REG_N> */   {"movs.w",{DSP_REG_M,A_DEC_N},{HEX_F,SDT_REG_N,REG_M,HEX_4}, arch_sh_dsp_up},
 
-/* 11001010i8*1.... xor #<imm>,R0       */{"xor",{A_IMM,A_R0},{HEX_C,HEX_A,IMM_8}},
+/* 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},
 
-/* 0010nnnnmmmm1010 xor <REG_M>,<REG_N> */{"xor",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_A}},
+/* 111101nnmmmm0110 movs.w <DSP_REG_M>,@<REG_N>+ */   {"movs.w",{DSP_REG_M,A_INC_N},{HEX_F,SDT_REG_N,REG_M,HEX_6}, arch_sh_dsp_up},
 
-/* 11001110i8*1.... xor.b #<imm>,@(R0,GBR)*/{"xor.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_E,IMM_8}},
+/* 111101nnmmmm0111 movs.w <DSP_REG_M>,@<REG_N>+r8 */ {"movs.w",{DSP_REG_M,A_PMOD_N},{HEX_F,SDT_REG_N,REG_M,HEX_7}, arch_sh_dsp_up},
 
-/* 0010nnnnmmmm1101 xtrct <REG_M>,<REG_N>*/{"xtrct",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_D}},
+/* 111101nnmmmm1000 movs.l @-<REG_N>,<DSP_REG_M> */   {"movs.l",{A_DEC_N,DSP_REG_M},{HEX_F,SDT_REG_N,REG_M,HEX_8}, arch_sh_dsp_up},
 
-/* 0000nnnnmmmm0111 mul.l <REG_M>,<REG_N>*/{"mul.l",{ A_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_7}},
+/* 111101nnmmmm1001 movs.l @<REG_N>,<DSP_REG_M> */    {"movs.l",{A_IND_N,DSP_REG_M},{HEX_F,SDT_REG_N,REG_M,HEX_9}, arch_sh_dsp_up},
 
-/* 0100nnnn00010000 dt <REG_N>          */{"dt",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_0}},
+/* 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},
 
-/* 0011nnnnmmmm1101 dmuls.l <REG_M>,<REG_N>*/{"dmuls.l",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_D}},
+/* 111101nnmmmm1011 movs.l @<REG_N>+r8,<DSP_REG_M> */ {"movs.l",{A_PMOD_N,DSP_REG_M},{HEX_F,SDT_REG_N,REG_M,HEX_B}, arch_sh_dsp_up},
 
-/* 0011nnnnmmmm0101 dmulu.l <REG_M>,<REG_N>*/{"dmulu.l",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_5}},
+/* 111101nnmmmm1100 movs.l <DSP_REG_M>,@-<REG_N> */   {"movs.l",{DSP_REG_M,A_DEC_N},{HEX_F,SDT_REG_N,REG_M,HEX_C}, arch_sh_dsp_up},
 
-/* 0000nnnnmmmm1111 mac.l @<REG_M>+,@<REG_N>+*/{"mac.l",{A_INC_M,A_INC_N},{HEX_0,REG_N,REG_M,HEX_F}},
+/* 111101nnmmmm1101 movs.l <DSP_REG_M>,@<REG_N> */    {"movs.l",{DSP_REG_M,A_IND_N},{HEX_F,SDT_REG_N,REG_M,HEX_D}, arch_sh_dsp_up},
 
-/* 0000nnnn00100011 braf <REG_N>       */{"braf",{A_REG_N},{HEX_0,REG_N,HEX_2,HEX_3}},
+/* 111101nnmmmm1110 movs.l <DSP_REG_M>,@<REG_N>+ */   {"movs.l",{DSP_REG_M,A_INC_N},{HEX_F,SDT_REG_N,REG_M,HEX_E}, arch_sh_dsp_up},
 
-/* 0000nnnn00000011 bsrf <REG_N>       */{"bsrf",{A_REG_N},{HEX_0,REG_N,HEX_0,HEX_3}},
+/* 111101nnmmmm1111 movs.l <DSP_REG_M>,@<REG_N>+r8 */ {"movs.l",{DSP_REG_M,A_PMOD_N},{HEX_F,SDT_REG_N,REG_M,HEX_F}, arch_sh_dsp_up},
 
-/* 1111nnnn01011101 fabs <F_REG_N>     */{"fabs",{FD_REG_N},{HEX_F,REG_N,HEX_5,HEX_D}},
+/* 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",{A_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",{A_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",{A_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_M,A_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_M,A_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_M,A_PMOD_N},{PPI,MOVX,HEX_B}, arch_sh_dsp_up},
+/* *n*m*0**01 movy.w @<REG_N>,<DSP_REG_Y> */    {"movy.w",{A_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",{A_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",{A_PMODY_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_M,A_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_M,A_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_M,A_PMODY_N},{PPI,MOVY,HEX_B}, arch_sh_dsp_up},
 
-/* 1111nnnnmmmm0000 fadd <F_REG_M>,<F_REG_N>*/{"fadd",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_0}},
-/* 1111nnn0mmm00000 fadd <D_REG_M>,<D_REG_N>*/{"fadd",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_0}},
+/* 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,PPI3,HEX_8,HEX_8}, arch_sh_dsp_up},
+/* 10011000xxyynnnn prnd <DSP_REG_X>,<DSP_REG_N> */
+{"prnd", {DSP_REG_X,DSP_REG_N},{PPI,PPI3,HEX_9,HEX_8}, arch_sh_dsp_up},
+/* 10101000xxyynnnn pabs <DSP_REG_Y>,<DSP_REG_N> */
+{"pabs", {DSP_REG_Y,DSP_REG_N},{PPI,PPI3,HEX_A,HEX_8}, arch_sh_dsp_up},
+/* 10111000xxyynnnn prnd <DSP_REG_Y>,<DSP_REG_N> */
+{"prnd", {DSP_REG_Y,DSP_REG_N},{PPI,PPI3,HEX_B,HEX_8}, arch_sh_dsp_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}},
-/* 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}},
+{"dct",{0},{PPI,PDC,HEX_1}, arch_sh_dsp_up},
+{"dcf",{0},{PPI,PDC,HEX_2}, arch_sh_dsp_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}},
-/* 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}},
+/* 00000iiiiiiinnnn pshl #<imm>,<DSP_REG_N> */ {"pshl",{A_IMM,DSP_REG_N},{PPI,PSH,HEX_0}, 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},
+/* 00010iiiiiiinnnn psha #<imm>,<DSP_REG_N> */ {"psha",{A_IMM,DSP_REG_N},{PPI,PSH,HEX_1}, 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},
+/* 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},
+/* 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},
+/* 10011001xxyynnnn pinc <DSP_REG_X>,<DSP_REG_N> */
+{"pinc", {DSP_REG_X,DSP_REG_N},{PPI,PPIC,HEX_9,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},
+/* 10111001xxyynnnn pinc <DSP_REG_Y>,<DSP_REG_N> */
+{"pinc", {DSP_REG_Y,DSP_REG_N},{PPI,PPIC,HEX_B,HEX_9}, arch_sh_dsp_up},
+/* 10001101xxyynnnn pclr <DSP_REG_N> */
+{"pclr", {DSP_REG_N},{PPI,PPIC,HEX_8,HEX_D}, arch_sh_dsp_up},
+/* 10011101xxyynnnn pdmsb <DSP_REG_X>,<DSP_REG_N> */
+{"pdmsb", {DSP_REG_X,DSP_REG_N},{PPI,PPIC,HEX_9,HEX_D}, arch_sh_dsp_up},
+/* 10111101xxyynnnn pdmsb <DSP_REG_Y>,<DSP_REG_N> */
+{"pdmsb", {DSP_REG_Y,DSP_REG_N},{PPI,PPIC,HEX_B,HEX_D}, 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},
+/* 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},
+/* 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},
+/* 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},
 
-/* 1111nnn010111101 fcnvds <D_REG_N>,FPUL*/{"fcnvds",{D_REG_N,FPUL_M},{HEX_F,REG_N,HEX_B,HEX_D}},
+/* 1111nnnn01011101 fabs <F_REG_N>     */{"fabs",{F_REG_N},{HEX_F,REG_N,HEX_5,HEX_D}, arch_sh3e_up},
+/* 1111nnnn01011101 fabs <D_REG_N>     */{"fabs",{D_REG_N},{HEX_F,REG_N,HEX_5,HEX_D}, arch_sh4_up},
 
-/* 1111nnn010101101 fcnvsd FPUL,<D_REG_N>*/{"fcnvsd",{FPUL_M,D_REG_N},{HEX_F,REG_N,HEX_A,HEX_D}},
+/* 1111nnnnmmmm0000 fadd <F_REG_M>,<F_REG_N>*/{"fadd",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_0}, arch_sh3e_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},
 
-/* 1111nnnnmmmm0011 fdiv <F_REG_M>,<F_REG_N>*/{"fdiv",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_3}},
-/* 1111nnn0mmm00011 fdiv <D_REG_M>,<D_REG_N>*/{"fdiv",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_3}},
+/* 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_sh3e_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},
 
-/* 1111nnmm11101101 fipr <V_REG_M>,<V_REG_N>*/{"fipr",{V_REG_M,V_REG_N},{HEX_F,REG_NM,HEX_E,HEX_D}},
+/* 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_sh3e_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},
+
+/* 1111nnn010111101 fcnvds <D_REG_N>,FPUL*/{"fcnvds",{D_REG_N,FPUL_M},{HEX_F,REG_N,HEX_B,HEX_D}, arch_sh4_up},
+
+/* 1111nnn010101101 fcnvsd FPUL,<D_REG_N>*/{"fcnvsd",{FPUL_M,D_REG_N},{HEX_F,REG_N,HEX_A,HEX_D}, arch_sh4_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_sh3e_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},
+
+/* 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}},
+/* 1111nnnn10001101 fldi0 <F_REG_N>    */{"fldi0",{F_REG_N},{HEX_F,REG_N,HEX_8,HEX_D}, arch_sh3e_up},
 
-/* 1111nnnn10011101 fldi1 <F_REG_N>    */{"fldi1",{F_REG_N},{HEX_F,REG_N,HEX_9,HEX_D}},
+/* 1111nnnn10011101 fldi1 <F_REG_N>    */{"fldi1",{F_REG_N},{HEX_F,REG_N,HEX_9,HEX_D}, arch_sh3e_up},
 
-/* 1111nnnn00011101 flds <F_REG_N>,FPUL*/{"flds",{F_REG_N,FPUL_M},{HEX_F,REG_N,HEX_1,HEX_D}},
+/* 1111nnnn00011101 flds <F_REG_N>,FPUL*/{"flds",{F_REG_N,FPUL_M},{HEX_F,REG_N,HEX_1,HEX_D}, arch_sh3e_up},
 
-/* 1111nnnn00101101 float FPUL,<FD_REG_N>*/{"float",{FPUL_M,FD_REG_N},{HEX_F,REG_N,HEX_2,HEX_D}},
+/* 1111nnnn00101101 float FPUL,<F_REG_N>*/{"float",{FPUL_M,F_REG_N},{HEX_F,REG_N,HEX_2,HEX_D}, arch_sh3e_up},
+/* 1111nnnn00101101 float FPUL,<D_REG_N>*/{"float",{FPUL_M,D_REG_N},{HEX_F,REG_N,HEX_2,HEX_D}, arch_sh4_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}},
+/* 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_sh3e_up},
 
-/* 1111nnnnmmmm1100 fmov <F_REG_M>,<F_REG_N>*/{"fmov",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_C}},
-/* 1111nnnnmmmm1100 fmov <DX_REG_M>,<DX_REG_N>*/{"fmov",{DX_REG_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_C}},
+/* 1111nnnnmmmm1100 fmov <F_REG_M>,<F_REG_N>*/{"fmov",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_C}, arch_sh3e_up},
+/* 1111nnnnmmmm1100 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},
 
-/* 1111nnnnmmmm1000 fmov @<REG_M>,<F_REG_N>*/{"fmov",{A_IND_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_8}},
-/* 1111nnnnmmmm1000 fmov @<REG_M>,<DX_REG_N>*/{"fmov",{A_IND_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_8}},
+/* 1111nnnnmmmm1000 fmov @<REG_M>,<F_REG_N>*/{"fmov",{A_IND_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_8}, arch_sh3e_up},
+/* 1111nnnnmmmm1000 fmov @<REG_M>,<DX_REG_N>*/{"fmov",{A_IND_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_8}, arch_sh4_up},
 
-/* 1111nnnnmmmm1010 fmov <F_REG_M>,@<REG_N>*/{"fmov",{F_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}},
-/* 1111nnnnmmmm1010 fmov <DX_REG_M>,@<REG_N>*/{"fmov",{DX_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}},
+/* 1111nnnnmmmm1010 fmov <F_REG_M>,@<REG_N>*/{"fmov",{F_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}, arch_sh3e_up},
+/* 1111nnnnmmmm1010 fmov <DX_REG_M>,@<REG_N>*/{"fmov",{DX_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}, arch_sh4_up},
 
-/* 1111nnnnmmmm1001 fmov @<REG_M>+,<F_REG_N>*/{"fmov",{A_INC_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_9}},
-/* 1111nnnnmmmm1001 fmov @<REG_M>+,<DX_REG_N>*/{"fmov",{A_INC_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_9}},
+/* 1111nnnnmmmm1001 fmov @<REG_M>+,<F_REG_N>*/{"fmov",{A_INC_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_9}, arch_sh3e_up},
+/* 1111nnnnmmmm1001 fmov @<REG_M>+,<DX_REG_N>*/{"fmov",{A_INC_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_9}, arch_sh4_up},
 
-/* 1111nnnnmmmm1011 fmov <F_REG_M>,@-<REG_N>*/{"fmov",{F_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}},
-/* 1111nnnnmmmm1011 fmov <DX_REG_M>,@-<REG_N>*/{"fmov",{DX_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}},
+/* 1111nnnnmmmm1011 fmov <F_REG_M>,@-<REG_N>*/{"fmov",{F_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}, arch_sh3e_up},
+/* 1111nnnnmmmm1011 fmov <DX_REG_M>,@-<REG_N>*/{"fmov",{DX_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}, arch_sh4_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}},
-/* 1111nnnnmmmm0110 fmov @(R0,<REG_M>),<DX_REG_N>*/{"fmov",{A_IND_R0_REG_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_6}},
+/* 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_sh3e_up},
+/* 1111nnnnmmmm0110 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},
 
-/* 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}},
-/* 1111nnnnmmmm0111 fmov <DX_REG_M>,@(R0,<REG_N>)*/{"fmov",{DX_REG_M,A_IND_R0_REG_N},{HEX_F,REG_N,REG_M,HEX_7}},
+/* 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_sh3e_up},
+/* 1111nnnnmmmm0111 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},
 
-/* 1111nnnnmmmm1000 fmov.d @<REG_M>,<DX_REG_N>*/{"fmov.d",{A_IND_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_8}},
+/* 1111nnnnmmmm1000 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},
 
-/* 1111nnnnmmmm1010 fmov.d <DX_REG_M>,@<REG_N>*/{"fmov.d",{DX_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}},
+/* 1111nnnnmmmm1010 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},
 
-/* 1111nnnnmmmm1001 fmov.d @<REG_M>+,<DX_REG_N>*/{"fmov.d",{A_INC_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_9}},
+/* 1111nnnnmmmm1001 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},
 
-/* 1111nnnnmmmm1011 fmov.d <DX_REG_M>,@-<REG_N>*/{"fmov.d",{DX_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}},
+/* 1111nnnnmmmm1011 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},
 
-/* 1111nnnnmmmm0110 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}},
+/* 1111nnnnmmmm0110 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},
 
-/* 1111nnnnmmmm0111 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}},
+/* 1111nnnnmmmm0111 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},
 
-/* 1111nnnnmmmm1000 fmov.s @<REG_M>,<F_REG_N>*/{"fmov.s",{A_IND_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_8}},
+/* 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_sh3e_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}},
+/* 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_sh3e_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}},
+/* 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_sh3e_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}},
+/* 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_sh3e_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}},
+/* 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_sh3e_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}},
+/* 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_sh3e_up},
 
-/* 1111nnnnmmmm0010 fmul <F_REG_M>,<F_REG_N>*/{"fmul",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_2}},
-/* 1111nnn0mmm00010 fmul <D_REG_M>,<D_REG_N>*/{"fmul",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_2}},
+/* 1111nnnnmmmm0010 fmul <F_REG_M>,<F_REG_N>*/{"fmul",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_2}, arch_sh3e_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},
 
-/* 1111nnnn01001101 fneg <FD_REG_N>     */{"fneg",{FD_REG_N},{HEX_F,REG_N,HEX_4,HEX_D}},
+/* 1111nnnn01001101 fneg <F_REG_N>     */{"fneg",{F_REG_N},{HEX_F,REG_N,HEX_4,HEX_D}, arch_sh3e_up},
+/* 1111nnnn01001101 fneg <D_REG_N>     */{"fneg",{D_REG_N},{HEX_F,REG_N,HEX_4,HEX_D}, arch_sh4_up},
 
-/* 1111101111111101 frchg               */{"frchg",{0},{HEX_F,HEX_B,HEX_F,HEX_D}},
+/* 1111101111111101 frchg               */{"frchg",{0},{HEX_F,HEX_B,HEX_F,HEX_D}, arch_sh4_up},
 
-/* 1111001111111101 fschg               */{"fschg",{0},{HEX_F,HEX_3,HEX_F,HEX_D}},
+/* 1111001111111101 fschg               */{"fschg",{0},{HEX_F,HEX_3,HEX_F,HEX_D}, arch_sh4_up},
 
-/* 1111nnnn01101101 fsqrt <FD_REG_N>    */{"fsqrt",{FD_REG_N},{HEX_F,REG_N,HEX_6,HEX_D}},
+/* 1111nnnn01101101 fsqrt <F_REG_N>    */{"fsqrt",{F_REG_N},{HEX_F,REG_N,HEX_6,HEX_D}, arch_sh3e_up},
+/* 1111nnnn01101101 fsqrt <D_REG_N>    */{"fsqrt",{D_REG_N},{HEX_F,REG_N,HEX_6,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}},
+/* 1111nnnn00001101 fsts FPUL,<F_REG_N>*/{"fsts",{FPUL_M,F_REG_N},{HEX_F,REG_N,HEX_0,HEX_D}, arch_sh3e_up},
 
-/* 1111nnnnmmmm0001 fsub <F_REG_M>,<F_REG_N>*/{"fsub",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_1}},
-/* 1111nnn0mmm00001 fsub <D_REG_M>,<D_REG_N>*/{"fsub",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_1}},
+/* 1111nnnnmmmm0001 fsub <F_REG_M>,<F_REG_N>*/{"fsub",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_1}, arch_sh3e_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},
 
-/* 1111nnnn00111101 ftrc <FD_REG_N>,FPUL*/{"ftrc",{FD_REG_N,FPUL_M},{HEX_F,REG_N,HEX_3,HEX_D}},
+/* 1111nnnn00111101 ftrc <F_REG_N>,FPUL*/{"ftrc",{F_REG_N,FPUL_M},{HEX_F,REG_N,HEX_3,HEX_D}, arch_sh3e_up},
+/* 1111nnnn00111101 ftrc <D_REG_N>,FPUL*/{"ftrc",{D_REG_N,FPUL_M},{HEX_F,REG_N,HEX_3,HEX_D}, arch_sh4_up},
 
-/* 1111nn0111111101 ftrv XMTRX_M4,<V_REG_n>*/{"ftrv",{XMTRX_M4,V_REG_N},{HEX_F,REG_NM,HEX_F,HEX_D}},
+/* 1111nn0111111101 ftrv XMTRX_M4,<V_REG_n>*/{"ftrv",{XMTRX_M4,V_REG_N},{HEX_F,REG_NM,HEX_F,HEX_D}, arch_sh4_up},
 
 { 0 } 
 };