Add support for v850E2 and v850E2V3
authorNick Clifton <nickc@redhat.com>
Fri, 23 Jul 2010 14:52:54 +0000 (14:52 +0000)
committerNick Clifton <nickc@redhat.com>
Fri, 23 Jul 2010 14:52:54 +0000 (14:52 +0000)
32 files changed:
bfd/ChangeLog
bfd/archures.c
bfd/bfd-in2.h
bfd/config.bfd
bfd/cpu-v850.c
bfd/elf32-v850.c
bfd/libbfd.h
bfd/reloc.c
binutils/ChangeLog
binutils/readelf.c
configure
configure.ac
gas/ChangeLog
gas/NEWS
gas/config/tc-v850.c
gas/configure.tgt
gas/doc/c-v850.texi
gas/testsuite/ChangeLog
gas/testsuite/gas/all/byte.d
gas/testsuite/gas/rx/rx-asm-good.d
gas/testsuite/gas/v850/split-lo16.d
gas/testsuite/gas/v850/v850e1.d
include/elf/ChangeLog
include/elf/v850.h
include/opcode/ChangeLog
include/opcode/v850.h
ld/ChangeLog
ld/testsuite/ChangeLog
ld/testsuite/ld-v850/split-lo16.d
opcodes/ChangeLog
opcodes/v850-dis.c
opcodes/v850-opc.c

index cdbf3a04d8861ed646a8802a0e70ba4511dcd687..47e98e79c1a7b36e23806e3ee6ae38105a0a7e08 100644 (file)
@@ -1,3 +1,41 @@
+2010-07-23  Naveen.H.S  <naveen.S@kpitcummins.com>
+           Ina Pandit  <ina.pandit@kpitcummins.com>
+
+       * archures.c (DESCRIPTION): Define bfd_mach_v850e2 and
+       bfd_mach_v850e2v3.
+       * reloc.c (bfd_architecture): Define bfd_mach_v850e2 and
+       bfd_mach_v850e2v3.
+       (BFD_RELOC_V850_16_PCREL, BFD_RELOC_V850_17_PCREL,
+       BFD_RELOC_V850_22_PCREL, BFD_RELOC_V850_23,
+       BFD_RELOC_V850_32_PCREL, BFD_RELOC_V850_32_ABS,
+       BFD_RELOC_V850_16_SPLIT_OFFSET, BFD_RELOC_V850_16_S1,
+       BFD_RELOC_V850_LO16_SPLIT_OFFSET, BFD_RELOC_V850_SDA_15_16_OFFSET,
+       BFD_RELOC_V850_ZDA_16_16_OFFSET, BFD_RELOC_V850_CALLT_15_16_OFFSET,
+       BFD_RELOC_V850_32_GOTPCREL, BFD_RELOC_V850_16_GOT,
+       BFD_RELOC_V850_32_GOT, BFD_RELOC_V850_22_PLT_PCREL,
+       BFD_RELOC_V850_32_PLT_PCREL, BFD_RELOC_V850_COPY,
+       BFD_RELOC_V850_GLOB_DAT, BFD_RELOC_V850_JMP_SLOT,
+       BFD_RELOC_V850_RELATIVE, BFD_RELOC_V850_16_GOTOFF,
+       BFD_RELOC_V850_32_GOTOFF, BFD_RELOC_V850_CODE,
+       BFD_RELOC_V850_DATA): New relocations for V850 target.
+       * config.bfd: Match all v850 targets.
+       * cpu-v850.c (arch_info_struct): Define V850e2 and V850e2v3.
+       * elf32-v850.c (v850_elf_check_relocs): Check the newly added
+       relocations.
+       (v850_elf_perform_relocation ): Update the newly added
+       relocations.
+       (v850_elf_howto_t): Update the specifications of added
+       relocations.
+       (v850_elf_reloc_map): Update the relocation mappings.
+       (v850_elf_final_link_relocate): Maps added relocation into the
+       appropriate howto structure.
+       (v850_elf_object_p): Add support for V850E2 and V850E2V3.
+       (v850_elf_final_write_processing): Likewise.
+       (v850_elf_merge_private_bfd_data): Likewise.
+       (v850_elf_print_private_bfd_data): Likewise.
+       * libbfd.h: Regenerate.
+       * bfd-in2.h: Regenerate.
+
 2010-07-23  Alan Modra  <amodra@gmail.com>
 
        * archive.c (_bfd_archive_bsd44_construct_extended_name_table):
index 0e085713b82136703f7f6356b794185e9f37cdae..1867154382141e67399d19415338ac1af995d789 100644 (file)
@@ -310,7 +310,9 @@ DESCRIPTION
 .  bfd_arch_v850,      {* NEC V850 *}
 .#define bfd_mach_v850          1
 .#define bfd_mach_v850e        'E'
-.#define bfd_mach_v850e1       '1'
+.#define bfd_mach_v850e1        '1'
+.#define bfd_mach_v850e2        0x4532
+.#define bfd_mach_v850e2v3      0x45325633
 .  bfd_arch_arc,       {* ARC Cores *}
 .#define bfd_mach_arc_5         5
 .#define bfd_mach_arc_6         6
index f97c67fd132859876b28aef9789cbf15148d7b3e..277d4322d2336eb4bb47198f983460918dfc9c63 100644 (file)
@@ -1977,6 +1977,8 @@ enum bfd_architecture
 #define bfd_mach_v850          1
 #define bfd_mach_v850e         'E'
 #define bfd_mach_v850e1        '1'
+#define bfd_mach_v850e2        0x4532   /* ('E'<<8|'2') */
+#define bfd_mach_v850e2v3      0x45325633 /* ('E'<<24|'2'<<16|'V'<<8|'3') */
   bfd_arch_arc,       /* ARC Cores */
 #define bfd_mach_arc_5         5
 #define bfd_mach_arc_6         6
@@ -3605,6 +3607,72 @@ bits placed non-contiguously in the instruction.  */
 instructions.  */
   BFD_RELOC_V850_LO16_SPLIT_OFFSET,
 
+/* This is a 16-bit reloc.  */
+  BFD_RELOC_V850_16_PCREL,
+
+/* This is a 17-bit reloc.  */
+  BFD_RELOC_V850_17_PCREL,
+
+/* This is a 23-bit reloc.  */
+  BFD_RELOC_V850_23,
+
+/* This is a 32-bit reloc.  */
+  BFD_RELOC_V850_32_PCREL,
+
+/* This is a 32-bit reloc.  */
+  BFD_RELOC_V850_32_ABS,
+
+/* This is a 16-bit reloc.  */
+  BFD_RELOC_V850_16_SPLIT_OFFSET,
+
+/* This is a 16-bit reloc.  */
+  BFD_RELOC_V850_16_S1,
+
+/* Low 16 bits. 16 bit shifted by 1.  */
+  BFD_RELOC_V850_LO16_S1,
+
+/* This is a 16 bit offset from the call table base pointer.  */
+  BFD_RELOC_V850_CALLT_15_16_OFFSET,
+
+/* DSO relocations.  */
+  BFD_RELOC_V850_32_GOTPCREL,
+
+/* DSO relocations.  */
+  BFD_RELOC_V850_16_GOT,
+
+/* DSO relocations.  */
+  BFD_RELOC_V850_32_GOT,
+
+/* DSO relocations.  */
+  BFD_RELOC_V850_22_PLT_PCREL,
+
+/* DSO relocations.  */
+  BFD_RELOC_V850_32_PLT_PCREL,
+
+/* DSO relocations.  */
+  BFD_RELOC_V850_COPY,
+
+/* DSO relocations.  */
+  BFD_RELOC_V850_GLOB_DAT,
+
+/* DSO relocations.  */
+  BFD_RELOC_V850_JMP_SLOT,
+
+/* DSO relocations.  */
+  BFD_RELOC_V850_RELATIVE,
+
+/* DSO relocations.  */
+  BFD_RELOC_V850_16_GOTOFF,
+
+/* DSO relocations.  */
+  BFD_RELOC_V850_32_GOTOFF,
+
+/* start code.  */
+  BFD_RELOC_V850_CODE,
+
+/* start data in text.  */
+  BFD_RELOC_V850_DATA,
+
 /* This is a 32bit pcrel reloc for the mn10300, offset by two bytes in the
 instruction.  */
   BFD_RELOC_MN10300_32_PCREL,
index 1015f3cc44556d54a93c2fbb888826f512ee9f0d..960d4d4408c7f4f792e18a4887fa3708bb8f9473 100644 (file)
@@ -1468,13 +1468,7 @@ case "${targ}" in
     targ_underscore=yes
     ;;
 
-  v850-*-*)
-    targ_defvec=bfd_elf32_v850_vec
-    ;;
-  v850e-*-*)
-    targ_defvec=bfd_elf32_v850_vec
-    ;;
-  v850ea-*-*)
+  v850*-*-*)
     targ_defvec=bfd_elf32_v850_vec
     ;;
 
index 77ca519ccb40f943f742c1a9ac9cd5d929dff8bb..6ebc96c8e82e2114fdb0b64693a6af575112e55f 100644 (file)
@@ -1,6 +1,6 @@
 /* BFD support for the NEC V850 processor
-   Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005, 2007
-   Free Software Foundation, Inc.
+   Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005, 2007,
+   2010  Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
 
 static const bfd_arch_info_type arch_info_struct[] =
 {
-  N (bfd_mach_v850e1, "v850e1", FALSE, & arch_info_struct[1]),
-  N (bfd_mach_v850e,  "v850e",  FALSE, NULL)
+  N (bfd_mach_v850e2v3, "v850e2v3",    FALSE, & arch_info_struct[1]),
+  N (bfd_mach_v850e2,   "v850e2",      FALSE, & arch_info_struct[2]),
+  N (bfd_mach_v850e1,   "v850e1",      FALSE, & arch_info_struct[3]),
+  N (bfd_mach_v850e,    "v850e",       FALSE, NULL)
 };
 
 #undef  NEXT
index 0ab7de8c10f70210a9d19ae5374dfff8b0e80fdb..e153e8305a89047d6935060c51050697806f6117 100644 (file)
 #include "elf/v850.h"
 #include "libiberty.h"
 
-/* Sign-extend a 24-bit number.  */
-#define SEXT24(x)      ((((x) & 0xffffff) ^ 0x800000) - 0x800000)
+/* Sign-extend a 17-bit number.  */
+#define SEXT17(x)      ((((x) & 0x1ffff) ^ 0x10000) - 0x10000)
+
+/* Sign-extend a 22-bit number.  */
+#define SEXT22(x)      ((((x) & 0x3fffff) ^ 0x200000) - 0x200000)
 
 static reloc_howto_type v850_elf_howto_table[];
 
@@ -89,16 +92,25 @@ v850_elf_check_relocs (bfd *abfd,
        default:
        case R_V850_NONE:
        case R_V850_9_PCREL:
+       case R_V850_16_PCREL:
+       case R_V850_17_PCREL:
        case R_V850_22_PCREL:
-       case R_V850_HI16_S:
+       case R_V850_32_PCREL:
+       case R_V850_32_ABS:
        case R_V850_HI16:
+       case R_V850_HI16_S:
        case R_V850_LO16:
+       case R_V850_LO16_S1:
        case R_V850_LO16_SPLIT_OFFSET:
+       case R_V850_23:
        case R_V850_ABS32:
        case R_V850_REL32:
        case R_V850_16:
+       case R_V850_16_S1:
+       case R_V850_16_SPLIT_OFFSET:
        case R_V850_8:
        case R_V850_CALLT_6_7_OFFSET:
+       case R_V850_CALLT_15_16_OFFSET:
        case R_V850_CALLT_16_16_OFFSET:
          break;
 
@@ -132,11 +144,11 @@ v850_elf_check_relocs (bfd *abfd,
          common = ".zcommon";
          goto small_data_common;
 
-       case R_V850_TDA_4_5_OFFSET:
        case R_V850_TDA_4_4_OFFSET:
+       case R_V850_TDA_4_5_OFFSET:
+       case R_V850_TDA_7_7_OFFSET:
        case R_V850_TDA_6_8_OFFSET:
        case R_V850_TDA_7_8_OFFSET:
-       case R_V850_TDA_7_7_OFFSET:
        case R_V850_TDA_16_16_OFFSET:
          other = V850_OTHER_TDA;
          common = ".tcommon";
@@ -315,15 +327,15 @@ find_remembered_hi16s_reloc (bfd_vma addend, bfd_boolean *already_found)
    will store 0 in the value fields for the MOVHI and MOVEA instructions
    and addend will be the address of fred, but for these instructions:
 
-       movhi hi( fred + 0x123456), r0, r1
-       movea lo( fred + 0x123456), r1, r1
+       movhi hi( fred + 0x123456 ), r0, r1
+       movea lo( fred + 0x123456 ), r1, r1
 
    the value stored in the MOVHI instruction will be 0x12 and the value
    stored in the MOVEA instruction will be 0x3456.  If however the
    instructions were:
 
-       movhi hi( fred + 0x10ffff), r0, r1
-       movea lo( fred + 0x10ffff), r1, r1
+       movhi hi( fred + 0x10ffff ), r0, r1
+       movea lo( fred + 0x10ffff ), r1, r1
 
    then the value stored in the MOVHI instruction would be 0x11 (not
    0x10) and the value stored in the MOVEA instruction would be 0xffff.
@@ -332,8 +344,8 @@ find_remembered_hi16s_reloc (bfd_vma addend, bfd_boolean *already_found)
    adds 0xffffffff (sign extension!) producing 0x10ffff.  Similarly if
    the instructions were:
 
-       movhi hi( fred - 1), r0, r1
-       movea lo( fred - 1), r1, r1
+       movhi hi( fred - 1 ), r0, r1
+       movea lo( fred - 1 ), r1, r1
 
    then 0 is stored in the MOVHI instruction and -1 is stored in the
    MOVEA instruction.
@@ -345,8 +357,8 @@ find_remembered_hi16s_reloc (bfd_vma addend, bfd_boolean *already_found)
    clear, the assembler will not have added 1 to the previous HI16S reloc
    to compensate for this effect.  For example:
 
-      movhi hi( fred + 0x123456), r0, r1
-      movea lo( fred + 0x123456), r1, r1
+      movhi hi( fred + 0x123456 ), r0, r1
+      movea lo( fred + 0x123456 ), r1, r1
 
    The value stored in HI16S reloc is 0x12, the value stored in the LO16
    reloc is 0x3456.  If we assume that the address of fred is 0x00007000
@@ -366,8 +378,8 @@ find_remembered_hi16s_reloc (bfd_vma addend, bfd_boolean *already_found)
    Note that if the 15th bit was set in the value stored in the LO16
    reloc, then we do not have to do anything:
 
-      movhi hi( fred + 0x10ffff), r0, r1
-      movea lo( fred + 0x10ffff), r1, r1
+      movhi hi( fred + 0x10ffff ), r0, r1
+      movea lo( fred + 0x10ffff ), r1, r1
 
       HI16S:  0x0011 + (0x00007000 >> 16)    = 0x11
       LO16:   0xffff + (0x00007000 & 0xffff) = 0x6fff
@@ -387,8 +399,8 @@ find_remembered_hi16s_reloc (bfd_vma addend, bfd_boolean *already_found)
 
    So, for example if fred is at address 0xf000:
 
-     movhi hi( fred + 0xffff), r0, r1    [bit 15 of the offset is set]
-     movea lo( fred + 0xffff), r1, r1
+     movhi hi( fred + 0xffff ), r0, r1    [bit 15 of the offset is set]
+     movea lo( fred + 0xffff ), r1, r1
 
      HI16S: 0x0001 + (0x0000f000 >> 16)    = 0x0001
      LO16:  0xffff + (0x0000f000 & 0xffff) = 0xefff   (carry into bit 16 is lost)
@@ -401,8 +413,8 @@ find_remembered_hi16s_reloc (bfd_vma addend, bfd_boolean *already_found)
    Similarly, if the 15th bit remains clear, but overflow occurs into
    the 16th bit then (assuming the address of fred is 0xf000):
 
-     movhi hi( fred + 0x7000), r0, r1    [bit 15 of the offset is clear]
-     movea lo( fred + 0x7000), r1, r1
+     movhi hi( fred + 0x7000 ), r0, r1    [bit 15 of the offset is clear]
+     movea lo( fred + 0x7000 ), r1, r1
 
      HI16S: 0x0000 + (0x0000f000 >> 16)    = 0x0000
      LO16:  0x7000 + (0x0000f000 & 0xffff) = 0x6fff  (carry into bit 16 is lost)
@@ -416,8 +428,8 @@ find_remembered_hi16s_reloc (bfd_vma addend, bfd_boolean *already_found)
    15th bit changes its value from being set to being clear, as the HI16S
    reloc will have already added in 1 to the high part for us:
 
-     movhi hi( fred + 0xffff), r0, r1     [bit 15 of the offset is set]
-     movea lo( fred + 0xffff), r1, r1
+     movhi hi( fred + 0xffff ), r0, r1     [bit 15 of the offset is set]
+     movea lo( fred + 0xffff ), r1, r1
 
      HI16S: 0x0001 + (0x00007000 >> 16)
      LO16:  0xffff + (0x00007000 & 0xffff) = 0x6fff  (carry into bit 16 is lost)
@@ -430,8 +442,8 @@ find_remembered_hi16s_reloc (bfd_vma addend, bfd_boolean *already_found)
    but if the 15th bit goes from being clear to being set, then we must
    once again handle overflow:
 
-     movhi hi( fred + 0x7000), r0, r1     [bit 15 of the offset is clear]
-     movea lo( fred + 0x7000), r1, r1
+     movhi hi( fred + 0x7000 ), r0, r1     [bit 15 of the offset is clear]
+     movea lo( fred + 0x7000 ), r1, r1
 
      HI16S: 0x0000 + (0x0000ffff >> 16)
      LO16:  0x7000 + (0x0000ffff & 0xffff) = 0x6fff  (carry into bit 16)
@@ -504,6 +516,13 @@ v850_elf_perform_relocation (bfd *abfd,
       bfd_put_32 (abfd, addend, address);
       return bfd_reloc_ok;
 
+    case R_V850_23:
+      insn  = bfd_get_32 (abfd, address);
+      insn &= ~((0x7f << 4) | (0x7fff80 << (16-7)));
+      insn |= ((addend & 0x7f) << 4) | ((addend & 0x7fff80) << (16-7));
+      bfd_put_32 (abfd, (bfd_vma) insn, address);
+      return bfd_reloc_ok;
+
     case R_V850_22_PCREL:
       if (saddend > 0x1fffff || saddend < -0x200000)
        return bfd_reloc_overflow;
@@ -517,6 +536,30 @@ v850_elf_perform_relocation (bfd *abfd,
       bfd_put_32 (abfd, (bfd_vma) insn, address);
       return bfd_reloc_ok;
 
+    case R_V850_17_PCREL:
+      if (saddend > 0xffff || saddend < -0x10000)
+       return bfd_reloc_overflow;
+
+      if ((addend % 2) != 0)
+       return bfd_reloc_dangerous;
+
+      insn  = bfd_get_32 (abfd, address);
+      insn &= ~ 0xfffe0010;
+      insn |= ((addend & 0xfffe) << 16) | ((addend & 0x10000) >> (16-4));
+      break;
+
+    case R_V850_16_PCREL:
+      if ((saddend < -0xffff) || (saddend > 0))
+       return bfd_reloc_overflow;
+
+      if ((addend % 2) != 0)
+       return bfd_reloc_dangerous;
+
+      insn  = bfd_get_16 (abfd, address);
+      insn &= ~0xfffe;
+      insn |= (-addend & 0xfffe);
+      break;
+
     case R_V850_9_PCREL:
       if (saddend > 0xff || saddend < -0x100)
        return bfd_reloc_overflow;
@@ -577,6 +620,36 @@ v850_elf_perform_relocation (bfd *abfd,
       insn = addend;
       break;
 
+    case R_V850_CALLT_15_16_OFFSET:
+      insn = bfd_get_16 (abfd, address);
+
+      addend += insn & 0xfffe;;
+
+      saddend = (bfd_signed_vma) addend;
+
+      if (saddend > 0xffff || saddend < 0)
+       return bfd_reloc_overflow;
+
+      insn = (0xfffe & addend)
+       | (insn & ~0xfffe);
+      break;
+
+    case R_V850_CALLT_6_7_OFFSET:
+      insn = bfd_get_16 (abfd, address);
+      addend += ((insn & 0x3f) << 1);
+
+      saddend = (bfd_signed_vma) addend;
+
+      if (saddend > 0x7e || saddend < 0)
+       return bfd_reloc_overflow;
+
+      if (addend & 1)
+       return bfd_reloc_dangerous;
+
+      insn &= 0xff80;
+      insn |= (addend >> 1);
+      break;
+
     case R_V850_16:
     case R_V850_SDA_16_16_OFFSET:
     case R_V850_ZDA_16_16_OFFSET:
@@ -591,6 +664,7 @@ v850_elf_perform_relocation (bfd *abfd,
       insn = addend;
       break;
 
+    case R_V850_16_S1:
     case R_V850_SDA_15_16_OFFSET:
     case R_V850_ZDA_15_16_OFFSET:
       insn = bfd_get_16 (abfd, address);
@@ -681,6 +755,18 @@ v850_elf_perform_relocation (bfd *abfd,
       insn |= addend;
       break;
 
+    case R_V850_LO16_S1:
+      insn = bfd_get_16 (abfd, address);
+      result = insn & 0xfffe;
+      if (! v850_elf_perform_lo16_relocation (abfd, &result, addend))
+       return bfd_reloc_overflow;
+      if (result & 1)
+       return bfd_reloc_overflow;
+      insn = (result & 0xfffe)
+       | (insn & ~0xfffe);
+       bfd_put_16 (abfd, insn, address);
+      return bfd_reloc_ok;
+
     case R_V850_LO16_SPLIT_OFFSET:
       insn = bfd_get_32 (abfd, address);
       result = ((insn & 0xfffe0000) >> 16) | ((insn & 0x20) >> 5);
@@ -692,8 +778,9 @@ v850_elf_perform_relocation (bfd *abfd,
       bfd_put_32 (abfd, insn, address);
       return bfd_reloc_ok;
 
-    case R_V850_ZDA_16_16_SPLIT_OFFSET:
+    case R_V850_16_SPLIT_OFFSET:
     case R_V850_SDA_16_16_SPLIT_OFFSET:
+    case R_V850_ZDA_16_16_SPLIT_OFFSET:
       insn = bfd_get_32 (abfd, address);
       addend += ((insn & 0xfffe0000) >> 16) + ((insn & 0x20) >> 5);
 
@@ -709,22 +796,6 @@ v850_elf_perform_relocation (bfd *abfd,
       bfd_put_32 (abfd, (bfd_vma) insn, address);
       return bfd_reloc_ok;
 
-    case R_V850_CALLT_6_7_OFFSET:
-      insn = bfd_get_16 (abfd, address);
-      addend += ((insn & 0x3f) << 1);
-
-      saddend = (bfd_signed_vma) addend;
-
-      if (saddend > 0x7e || saddend < 0)
-       return bfd_reloc_overflow;
-
-      if (addend & 1)
-       return bfd_reloc_dangerous;
-
-      insn &= 0xff80;
-      insn |= (addend >> 1);
-      break;
-
     case R_V850_GNU_VTINHERIT:
     case R_V850_GNU_VTENTRY:
       return bfd_reloc_ok;
@@ -813,7 +884,8 @@ v850_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED,
   return bfd_reloc_ok;
 }
 /* Note: It is REQUIRED that the 'type' value of each entry
-   in this array match the index of the entry in the array.  */
+   in this array match the index of the entry in the array.
+   SeeAlso: RELOC_NUBMER in include/elf/v850.h  */
 static reloc_howto_type v850_elf_howto_table[] =
 {
   /* This reloc does nothing.  */
@@ -833,9 +905,9 @@ static reloc_howto_type v850_elf_howto_table[] =
 
   /* A PC relative 9 bit branch.  */
   HOWTO (R_V850_9_PCREL,               /* Type.  */
-        2,                             /* Rightshift.  */
-        2,                             /* Size (0 = byte, 1 = short, 2 = long).  */
-        26,                            /* Bitsize.  */
+        0,                             /* Rightshift.  */
+        1,                             /* Size (0 = byte, 1 = short, 2 = long).  */
+        9,                             /* Bitsize.  */
         TRUE,                          /* PC_relative.  */
         0,                             /* Bitpos.  */
         complain_overflow_bitfield,    /* Complain_on_overflow.  */
@@ -848,11 +920,11 @@ static reloc_howto_type v850_elf_howto_table[] =
 
   /* A PC relative 22 bit branch.  */
   HOWTO (R_V850_22_PCREL,              /* Type.  */
-        2,                             /* Rightshift.  */
+        0,                             /* Rightshift.  */
         2,                             /* Size (0 = byte, 1 = short, 2 = long).  */
         22,                            /* Bitsize.  */
         TRUE,                          /* PC_relative.  */
-        7,                             /* Bitpos.  */
+        0,                             /* Bitpos.  */
         complain_overflow_signed,      /* Complain_on_overflow.  */
         v850_elf_reloc,                /* Special_function.  */
         "R_V850_22_PCREL",             /* Name.  */
@@ -1161,82 +1233,83 @@ static reloc_howto_type v850_elf_howto_table[] =
         0xffff,                        /* Dst_mask.  */
         FALSE),                        /* PCrel_offset.  */
 
+
   /* GNU extension to record C++ vtable hierarchy */
   HOWTO (R_V850_GNU_VTINHERIT, /* Type.  */
-         0,                     /* Rightshift.  */
-         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-         0,                     /* Bitsize.  */
-         FALSE,                 /* PC_relative.  */
-         0,                     /* Bitpos.  */
-         complain_overflow_dont, /* Complain_on_overflow.  */
-         NULL,                  /* Special_function.  */
-         "R_V850_GNU_VTINHERIT", /* Name.  */
-         FALSE,                 /* Partial_inplace.  */
-         0,                     /* Src_mask.  */
-         0,                     /* Dst_mask.  */
-         FALSE),                /* PCrel_offset.  */
-
-  /* GNU extension to record C++ vtable member usage */
+        0,                     /* Rightshift.  */
+        2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        0,                     /* Bitsize.  */
+        FALSE,                 /* PC_relative.  */
+        0,                     /* Bitpos.  */
+        complain_overflow_dont, /* Complain_on_overflow.  */
+        NULL,                  /* Special_function.  */
+        "R_V850_GNU_VTINHERIT", /* Name.  */
+        FALSE,                 /* Partial_inplace.  */
+        0,                     /* Src_mask.  */
+        0,                     /* Dst_mask.  */
+        FALSE),                /* PCrel_offset.  */
+
+  /* GNU extension to record C++ vtable member usage */
   HOWTO (R_V850_GNU_VTENTRY,     /* Type.  */
-         0,                     /* Rightshift.  */
-         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-         0,                     /* Bitsize.  */
-         FALSE,                 /* PC_relative.  */
-         0,                     /* Bitpos.  */
-         complain_overflow_dont, /* Complain_on_overflow.  */
-         _bfd_elf_rel_vtable_reloc_fn,  /* Special_function.  */
-         "R_V850_GNU_VTENTRY",   /* Name.  */
-         FALSE,                 /* Partial_inplace.  */
-         0,                     /* Src_mask.  */
-         0,                     /* Dst_mask.  */
-         FALSE),                /* PCrel_offset.  */
+        0,                     /* Rightshift.  */
+        2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        0,                     /* Bitsize.  */
+        FALSE,                 /* PC_relative.  */
+        0,                     /* Bitpos.  */
+        complain_overflow_dont, /* Complain_on_overflow.  */
+        _bfd_elf_rel_vtable_reloc_fn,  /* Special_function.  */
+        "R_V850_GNU_VTENTRY",   /* Name.  */
+        FALSE,                 /* Partial_inplace.  */
+        0,                     /* Src_mask.  */
+        0,                     /* Dst_mask.  */
+        FALSE),                /* PCrel_offset.  */
 
   /* Indicates a .longcall pseudo-op.  The compiler will generate a .longcall
      pseudo-op when it finds a function call which can be relaxed.  */
   HOWTO (R_V850_LONGCALL,     /* Type.  */
-       0,                     /* Rightshift.  */
-       2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-       32,                    /* Bitsize.  */
-       TRUE,                  /* PC_relative.  */
-       0,                     /* Bitpos.  */
-       complain_overflow_signed, /* Complain_on_overflow.  */
-       v850_elf_ignore_reloc, /* Special_function.  */
-       "R_V850_LONGCALL",     /* Name.  */
-       FALSE,                 /* Partial_inplace.  */
-       0,                     /* Src_mask.  */
-       0,                     /* Dst_mask.  */
-       TRUE),                 /* PCrel_offset.  */
+        0,                     /* Rightshift.  */
+        2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        32,                    /* Bitsize.  */
+        TRUE,                  /* PC_relative.  */
+        0,                     /* Bitpos.  */
+        complain_overflow_signed, /* Complain_on_overflow.  */
+        v850_elf_ignore_reloc, /* Special_function.  */
+        "R_V850_LONGCALL",     /* Name.  */
+        FALSE,                 /* Partial_inplace.  */
+        0,                     /* Src_mask.  */
+        0,                     /* Dst_mask.  */
+        TRUE),                 /* PCrel_offset.  */
 
   /* Indicates a .longjump pseudo-op.  The compiler will generate a
      .longjump pseudo-op when it finds a branch which can be relaxed.  */
   HOWTO (R_V850_LONGJUMP,     /* Type.  */
-       0,                     /* Rightshift.  */
-       2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-       32,                    /* Bitsize.  */
-       TRUE,                  /* PC_relative.  */
-       0,                     /* Bitpos.  */
-       complain_overflow_signed, /* Complain_on_overflow.  */
-       v850_elf_ignore_reloc, /* Special_function.  */
-       "R_V850_LONGJUMP",     /* Name.  */
-       FALSE,                 /* Partial_inplace.  */
-       0,                     /* Src_mask.  */
-       0,                     /* Dst_mask.  */
-       TRUE),                 /* PCrel_offset.  */
+        0,                     /* Rightshift.  */
+        2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        32,                    /* Bitsize.  */
+        TRUE,                  /* PC_relative.  */
+        0,                     /* Bitpos.  */
+        complain_overflow_signed, /* Complain_on_overflow.  */
+        v850_elf_ignore_reloc, /* Special_function.  */
+        "R_V850_LONGJUMP",     /* Name.  */
+        FALSE,                 /* Partial_inplace.  */
+        0,                     /* Src_mask.  */
+        0,                     /* Dst_mask.  */
+        TRUE),                 /* PCrel_offset.  */
 
   HOWTO (R_V850_ALIGN,        /* Type.  */
-       0,                     /* Rightshift.  */
-       1,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-       0,                     /* Bitsize.  */
-       FALSE,                 /* PC_relative.  */
-       0,                     /* Bitpos.  */
-       complain_overflow_unsigned, /* Complain_on_overflow.  */
-       v850_elf_ignore_reloc, /* Special_function.  */
-       "R_V850_ALIGN",        /* Name.  */
-       FALSE,                 /* Partial_inplace.  */
-       0,                     /* Src_mask.  */
-       0,                     /* Dst_mask.  */
-       TRUE),                 /* PCrel_offset.  */
-  
+        0,                     /* Rightshift.  */
+        1,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        0,                     /* Bitsize.  */
+        FALSE,                 /* PC_relative.  */
+        0,                     /* Bitpos.  */
+        complain_overflow_unsigned, /* Complain_on_overflow.  */
+        v850_elf_ignore_reloc, /* Special_function.  */
+        "R_V850_ALIGN",        /* Name.  */
+        FALSE,                 /* Partial_inplace.  */
+        0,                     /* Src_mask.  */
+        0,                     /* Dst_mask.  */
+        TRUE),                 /* PCrel_offset.  */
+
   /* Simple pc-relative 32bit reloc.  */
   HOWTO (R_V850_REL32,                 /* Type.  */
         0,                             /* Rightshift.  */
@@ -1266,6 +1339,341 @@ static reloc_howto_type v850_elf_howto_table[] =
         0xfffe0020,                    /* Src_mask.  */
         0xfffe0020,                    /* Dst_mask.  */
         FALSE),                        /* PCrel_offset.  */
+
+  /* A unsigned PC relative 16 bit loop.  */
+  HOWTO (R_V850_16_PCREL,              /* Type.  */
+        0,                             /* Rightshift.  */
+        1,                             /* Size (0 = byte, 1 = short, 2 = long).  */
+        16,                            /* Bitsize.  */
+        TRUE,                          /* PC_relative.  */
+        0,                             /* Bitpos.  */
+        complain_overflow_bitfield,    /* Complain_on_overflow.  */
+        v850_elf_reloc,                /* Special_function.  */
+        "R_V850_16_PCREL",             /* Name.  */
+        FALSE,                         /* Partial_inplace.  */
+        0xfffe,                        /* Src_mask.  */
+        0xfffe,                        /* Dst_mask.  */
+        TRUE),                         /* PCrel_offset.  */
+
+  /* A PC relative 17 bit branch.  */
+  HOWTO (R_V850_17_PCREL,              /* Type.  */
+        0,                             /* Rightshift.  */
+        2,                             /* Size (0 = byte, 1 = short, 2 = long).  */
+        17,                            /* Bitsize.  */
+        TRUE,                          /* PC_relative.  */
+        0,                             /* Bitpos.  */
+        complain_overflow_bitfield,    /* Complain_on_overflow.  */
+        v850_elf_reloc,                /* Special_function.  */
+        "R_V850_17_PCREL",             /* Name.  */
+        FALSE,                         /* Partial_inplace.  */
+        0x0010fffe,                    /* Src_mask.  */
+        0x0010fffe,                    /* Dst_mask.  */
+        TRUE),                         /* PCrel_offset.  */
+
+  /* A 23bit offset ld/st.  */
+  HOWTO (R_V850_23,                    /* type.  */
+        0,                             /* rightshift.  */
+        2,                             /* size (0 = byte, 1 = short, 2 = long).  */
+        23,                            /* bitsize.  */
+        FALSE,                         /* pc_relative.  */
+        0,                             /* bitpos.  */
+        complain_overflow_dont,        /* complain_on_overflow.  */
+        v850_elf_reloc,                /* special_function.  */
+        "R_V850_23",                   /* name.  */
+        FALSE,                         /* partial_inplace.  */
+        0xffff07f0,                    /* src_mask.  */
+        0xffff07f0,                    /* dst_mask.  */
+        FALSE),                        /* pcrel_offset.  */
+
+  /* A PC relative 32 bit branch.  */
+  HOWTO (R_V850_32_PCREL,              /* type.  */
+        1,                             /* rightshift.  */
+        2,                             /* size (0 = byte, 1 = short, 2 = long).  */
+        32,                            /* bitsize.  */
+        TRUE,                          /* pc_relative.  */
+        1,                             /* bitpos.  */
+        complain_overflow_signed,      /* complain_on_overflow.  */
+        v850_elf_reloc,                /* special_function.  */
+        "R_V850_32_PCREL",             /* name.  */
+        FALSE,                         /* partial_inplace.  */
+        0xfffffffe,                    /* src_mask.  */
+        0xfffffffe,                    /* dst_mask.  */
+        TRUE),                         /* pcrel_offset.  */
+
+  /* A absolute 32 bit branch. */
+  HOWTO (R_V850_32_ABS,                        /* type.  */
+        1,                             /* rightshift.  */
+        2,                             /* size (0 = byte, 1 = short, 2 = long).  */
+        32,                            /* bitsize.  */
+        TRUE,                          /* pc_relative.  */
+        1,                             /* bitpos.  */
+        complain_overflow_signed,      /* complain_on_overflow.  */
+        v850_elf_reloc,                /* special_function.  */
+        "R_V850_32_ABS",               /* name.  */
+        FALSE,                         /* partial_inplace.  */
+        0xfffffffe,                    /* src_mask.  */
+        0xfffffffe,                    /* dst_mask.  */
+        FALSE),                        /* pcrel_offset.  */
+
+  /* High 16 bits of symbol value.  */
+  HOWTO (R_V850_HI16,                  /* Type.  */
+        0,                             /* Rightshift.  */
+        1,                             /* Size (0 = byte, 1 = short, 2 = long).  */
+        16,                            /* Bitsize.  */
+        FALSE,                         /* PC_relative.  */
+        0,                             /* Bitpos.  */
+        complain_overflow_dont,        /* Complain_on_overflow.  */
+        v850_elf_reloc,                /* Special_function.  */
+        "R_V850_HI16",                 /* Name.  */
+        FALSE,                         /* Partial_inplace.  */
+        0xffff,                        /* Src_mask.  */
+        0xffff,                        /* Dst_mask.  */
+        FALSE),                        /* PCrel_offset.  */
+
+  /* Low 16 bits of symbol value.  */
+  HOWTO (R_V850_16_S1,                 /* type.  */
+        1,                             /* rightshift.  */
+        1,                             /* size (0 = byte, 1 = short, 2 = long).  */
+        16,                            /* bitsize.  */
+        FALSE,                         /* pc_relative.  */
+        1,                             /* bitpos.  */
+        complain_overflow_dont,        /* complain_on_overflow.  */
+        v850_elf_reloc,                /* special_function.  */
+        "R_V850_16_S1",                /* name.  */
+        FALSE,                         /* partial_inplace.  */
+        0xfffe,                        /* src_mask.  */
+        0xfffe,                        /* dst_mask.  */
+        FALSE),                        /* pcrel_offset.  */
+
+  /* Low 16 bits of symbol value.  */
+  HOWTO (R_V850_LO16_S1,               /* type.  */
+        1,                             /* rightshift.  */
+        1,                             /* size (0 = byte, 1 = short, 2 = long).  */
+        16,                            /* bitsize.  */
+        FALSE,                         /* pc_relative.  */
+        1,                             /* bitpos.  */
+        complain_overflow_dont,        /* complain_on_overflow.  */
+        v850_elf_reloc,                /* special_function.  */
+        "R_V850_LO16_S1",              /* name.  */
+        FALSE,                         /* partial_inplace.  */
+        0xfffe,                        /* src_mask.  */
+        0xfffe,                        /* dst_mask.  */
+        FALSE),                        /* pcrel_offset.  */
+
+  /* 16 bit offset from the call table base pointer.  */
+  HOWTO (R_V850_CALLT_15_16_OFFSET,    /* type.  */
+        1,                             /* rightshift.  */
+        1,                             /* size (0 = byte, 1 = short, 2 = long).  */
+        16,                            /* bitsize.  */
+        FALSE,                         /* pc_relative.  */
+        1,                             /* bitpos.  */
+        complain_overflow_dont,        /* complain_on_overflow.  */
+        v850_elf_reloc,                /* special_function.  */
+        "R_V850_CALLT_15_16_OFFSET",   /* name.  */
+        FALSE,                         /* partial_inplace.  */
+        0xfffe,                        /* src_mask.  */
+        0xfffe,                        /* dst_mask.  */
+        FALSE),                        /* pcrel_offset.  */
+
+  /* Like R_V850_32 PCREL, but referring to the GOT table entry for
+     the symbol.  */
+  HOWTO (R_V850_32_GOTPCREL,           /* type.  */
+        0,                             /* rightshift.  */
+        2,                             /* size (0 = byte, 1 = short, 2 = long).  */
+        32,                            /* bitsize.  */
+        TRUE,                          /* pc_relative.  */
+        0,                             /* bitpos.  */
+        complain_overflow_unsigned,    /* complain_on_overflow.  */
+        v850_elf_reloc,                /* special_function.  */
+        "R_V850_32_GOTPCREL",          /* name.  */
+        FALSE,                         /* partial_inplace.  */
+        0xffffffff,                    /* src_mask.  */
+        0xffffffff,                    /* dst_mask.  */
+        TRUE),                         /* pcrel_offset.  */
+
+  /* Like R_V850_SDA_, but referring to the GOT table entry for
+     the symbol.  */
+  HOWTO (R_V850_16_GOT,                        /* type.  */
+        0,                             /* rightshift.  */
+        2,                             /* size (0 = byte, 1 = short, 2 = long).  */
+        16,                            /* bitsize.  */
+        FALSE,                         /* pc_relative.  */
+        0,                             /* bitpos.  */
+        complain_overflow_unsigned,    /* complain_on_overflow.  */
+        bfd_elf_generic_reloc,         /* special_function.  */
+        "R_V850_16_GOT",               /* name.  */
+        FALSE,                         /* partial_inplace.  */
+        0xffff,                        /* src_mask.  */
+        0xffff,                        /* dst_mask.  */
+        FALSE),                        /* pcrel_offset.  */
+
+  HOWTO (R_V850_32_GOT,                        /* type.  */
+        0,                             /* rightshift.  */
+        2,                             /* size (0 = byte, 1 = short, 2 = long).  */
+        32,                            /* bitsize.  */
+        FALSE,                         /* pc_relative.  */
+        0,                             /* bitpos.  */
+        complain_overflow_unsigned,    /* complain_on_overflow.  */
+        bfd_elf_generic_reloc,         /* special_function.  */
+        "R_V850_32_GOT",               /* name.  */
+        FALSE,                         /* partial_inplace.  */
+        0xffffffff,                    /* src_mask.  */
+        0xffffffff,                    /* dst_mask.  */
+        FALSE),                        /* pcrel_offset.  */
+
+  /* Like R_V850_22_PCREL, but referring to the procedure linkage table
+     entry for the symbol.  */
+  HOWTO (R_V850_22_PLT,                        /* type.  */
+        1,                             /* rightshift.  */
+        2,                             /* size (0 = byte, 1 = short, 2 = long).  */
+        22,                            /* bitsize.  */
+        TRUE,                          /* pc_relative.  */
+        7,                             /* bitpos.  */
+        complain_overflow_signed,      /* complain_on_overflow.  */
+        bfd_elf_generic_reloc,         /* special_function.  */
+        "R_V850_22_PLT",               /* name.  */
+        FALSE,                         /* partial_inplace.  */
+        0x07ffff80,                    /* src_mask.  */
+        0x07ffff80,                    /* dst_mask.  */
+        TRUE),                         /* pcrel_offset.  */
+
+  HOWTO (R_V850_32_PLT,                        /* type.  */
+        1,                             /* rightshift.  */
+        2,                             /* size (0 = byte, 1 = short, 2 = long).  */
+        32,                            /* bitsize.  */
+        TRUE,                          /* pc_relative.  */
+        1,                             /* bitpos.  */
+        complain_overflow_signed,      /* complain_on_overflow.  */
+        bfd_elf_generic_reloc,         /* special_function.  */
+        "R_V850_32_PLT",               /* name.  */
+        FALSE,                         /* partial_inplace.  */
+        0xffffffff,                    /* src_mask.  */
+        0xffffffff,                    /* dst_mask.  */
+        TRUE),                         /* pcrel_offset.  */
+
+  /* This is used only by the dynamic linker.  The symbol should exist
+     both in the object being run and in some shared library.  The
+     dynamic linker copies the data addressed by the symbol from the
+     shared library into the object, because the object being
+     run has to have the data at some particular address.  */
+  HOWTO (R_V850_COPY,                  /* type.  */
+        0,                             /* rightshift.  */
+        2,                             /* size (0 = byte, 1 = short, 2 = long).  */
+        32,                            /* bitsize.  */
+        FALSE,                         /* pc_relative.  */
+        0,                             /* bitpos.  */
+        complain_overflow_bitfield,    /* complain_on_overflow.  */
+        bfd_elf_generic_reloc,         /* special_function.  */
+        "R_V850_COPY",                 /* name.  */
+        FALSE,                         /* partial_inplace.  */
+        0xffffffff,                    /* src_mask.  */
+        0xffffffff,                    /* dst_mask.  */
+        FALSE),                        /* pcrel_offset.  */
+
+  /* Like R_M32R_24, but used when setting global offset table
+     entries.  */
+  HOWTO (R_V850_GLOB_DAT,              /* type.  */
+        0,                             /* rightshift.  */
+        2,                             /* size (0 = byte, 1 = short, 2 = long) */
+        32,                            /* bitsize.  */
+        FALSE,                         /* pc_relative.  */
+        0,                             /* bitpos.  */
+        complain_overflow_bitfield,    /* complain_on_overflow.  */
+        bfd_elf_generic_reloc,         /* special_function.  */
+        "R_V850_GLOB_DAT",             /* name.  */
+        FALSE,                         /* partial_inplace.  */
+        0xffffffff,                    /* src_mask.  */
+        0xffffffff,                    /* dst_mask.  */
+        FALSE),                        /* pcrel_offset.  */
+
+  /* Marks a procedure linkage table entry for a symbol.  */
+  HOWTO (R_V850_JMP_SLOT,              /* type.  */
+        0,                             /* rightshift.  */
+        2,                             /* size (0 = byte, 1 = short, 2 = long) */
+        32,                            /* bitsize.  */
+        FALSE,                         /* pc_relative.  */
+        0,                             /* bitpos.  */
+        complain_overflow_bitfield,    /* complain_on_overflow.  */
+        bfd_elf_generic_reloc,         /* special_function.  */
+        "R_V850_JMP_SLOT",             /* name.  */
+        FALSE,                         /* partial_inplace.  */
+        0xffffffff,                    /* src_mask.  */
+        0xffffffff,                    /* dst_mask.  */
+        FALSE),                        /* pcrel_offset.  */
+
+  /* Used only by the dynamic linker.  When the object is run, this
+     longword is set to the load address of the object, plus the
+     addend.  */
+  HOWTO (R_V850_RELATIVE,              /* type.  */
+        0,                             /* rightshift.  */
+        2,                             /* size (0 = byte, 1 = short, 2 = long) */
+        32,                            /* bitsize.  */
+        FALSE,                         /* pc_relative.  */
+        0,                             /* bitpos.  */
+        complain_overflow_bitfield,    /* complain_on_overflow.  */
+        bfd_elf_generic_reloc,         /* special_function.  */
+        "R_V850_RELATIVE",             /* name.  */
+        FALSE,                         /* partial_inplace.  */
+        0xffffffff,                    /* src_mask.  */
+        0xffffffff,                    /* dst_mask.  */
+        FALSE),                        /* pcrel_offset.  */
+
+  HOWTO (R_V850_16_GOTOFF,             /* type.  */
+        0,                             /* rightshift.  */
+        2,                             /* size (0 = byte, 1 = short, 2 = long) */
+        16,                            /* bitsize.  */
+        FALSE,                         /* pc_relative.  */
+        0,                             /* bitpos.  */
+        complain_overflow_bitfield,    /* complain_on_overflow.  */
+        bfd_elf_generic_reloc,         /* special_function.  */
+        "R_V850_16_GOTOFF",            /* name.  */
+        FALSE,                         /* partial_inplace.  */
+        0xffff,                        /* src_mask.  */
+        0xffff,                        /* dst_mask.  */
+        FALSE),                        /* pcrel_offset.  */
+
+  HOWTO (R_V850_32_GOTOFF,             /* type.  */
+        0,                             /* rightshift.  */
+        2,                             /* size (0 = byte, 1 = short, 2 = long) */
+        32,                            /* bitsize.  */
+        FALSE,                         /* pc_relative.  */
+        0,                             /* bitpos.  */
+        complain_overflow_bitfield,    /* complain_on_overflow.  */
+        bfd_elf_generic_reloc,         /* special_function.  */
+        "R_V850_32_GOTOFF",            /* name.  */
+        FALSE,                         /* partial_inplace.  */
+        0xffffffff,                    /* src_mask.  */
+        0xffffffff,                    /* dst_mask.  */
+        FALSE),                        /* pcrel_offset.  */
+
+  HOWTO (R_V850_CODE,                  /* type.  */
+        0,                             /* rightshift.  */
+        1,                             /* size (0 = byte, 1 = short, 2 = long) */
+        0,                             /* bitsize.  */
+        FALSE,                         /* pc_relative.  */
+        0,                             /* bitpos.  */
+        complain_overflow_unsigned,    /* complain_on_overflow.  */
+        v850_elf_ignore_reloc,         /* special_function.  */
+        "R_V850_CODE",                 /* name.  */
+        FALSE,                         /* partial_inplace.  */
+        0,                             /* src_mask.  */
+        0,                             /* dst_mask.  */
+        TRUE),                         /* pcrel_offset.  */
+
+  HOWTO (R_V850_DATA,                  /* type.  */
+        0,                             /* rightshift.  */
+        1,                             /* size (0 = byte, 1 = short, 2 = long) */
+        0,                             /* bitsize.  */
+        FALSE,                         /* pc_relative.  */
+        0,                             /* bitpos.  */
+        complain_overflow_unsigned,    /* complain_on_overflow.  */
+        v850_elf_ignore_reloc,         /* special_function.  */
+        "R_V850_DATA",                 /* name.  */
+        FALSE,                         /* partial_inplace.  */
+        0,                             /* src_mask.  */
+        0,                             /* dst_mask.  */
+        TRUE),                         /* pcrel_offset.  */
+
 };
 
 /* Map BFD reloc types to V850 ELF reloc types.  */
@@ -1280,16 +1688,16 @@ struct v850_elf_reloc_map
 
 static const struct v850_elf_reloc_map v850_elf_reloc_map[] =
 {
-  { BFD_RELOC_NONE,                       R_V850_NONE                   },
-  { BFD_RELOC_V850_9_PCREL,               R_V850_9_PCREL                },
-  { BFD_RELOC_V850_22_PCREL,              R_V850_22_PCREL               },
-  { BFD_RELOC_HI16_S,                     R_V850_HI16_S                 },
-  { BFD_RELOC_HI16,                       R_V850_HI16                   },
-  { BFD_RELOC_LO16,                       R_V850_LO16                   },
-  { BFD_RELOC_32,                         R_V850_ABS32                  },
-  { BFD_RELOC_32_PCREL,                           R_V850_REL32                  },
-  { BFD_RELOC_16,                         R_V850_16                     },
-  { BFD_RELOC_8,                          R_V850_8                      },
+  { BFD_RELOC_NONE,                        R_V850_NONE                   },
+  { BFD_RELOC_V850_9_PCREL,                R_V850_9_PCREL                },
+  { BFD_RELOC_V850_22_PCREL,               R_V850_22_PCREL               },
+  { BFD_RELOC_HI16_S,                      R_V850_HI16_S                 },
+  { BFD_RELOC_HI16,                        R_V850_HI16                   },
+  { BFD_RELOC_LO16,                        R_V850_LO16                   },
+  { BFD_RELOC_32,                          R_V850_ABS32                  },
+  { BFD_RELOC_32_PCREL,                    R_V850_REL32                  },
+  { BFD_RELOC_16,                          R_V850_16                     },
+  { BFD_RELOC_8,                           R_V850_8                      },
   { BFD_RELOC_V850_SDA_16_16_OFFSET,       R_V850_SDA_16_16_OFFSET       },
   { BFD_RELOC_V850_SDA_15_16_OFFSET,       R_V850_SDA_15_16_OFFSET       },
   { BFD_RELOC_V850_ZDA_16_16_OFFSET,       R_V850_ZDA_16_16_OFFSET       },
@@ -1310,7 +1718,28 @@ static const struct v850_elf_reloc_map v850_elf_reloc_map[] =
   { BFD_RELOC_V850_LONGCALL,               R_V850_LONGCALL               },
   { BFD_RELOC_V850_LONGJUMP,               R_V850_LONGJUMP               },
   { BFD_RELOC_V850_ALIGN,                  R_V850_ALIGN                  },
-
+  { BFD_RELOC_V850_16_PCREL,               R_V850_16_PCREL               },
+  { BFD_RELOC_V850_17_PCREL,               R_V850_17_PCREL               },
+  { BFD_RELOC_V850_23,                     R_V850_23                     },
+  { BFD_RELOC_V850_32_PCREL,               R_V850_32_PCREL               },
+  { BFD_RELOC_V850_32_ABS,                 R_V850_32_ABS                 },
+  { BFD_RELOC_V850_16_SPLIT_OFFSET,        R_V850_HI16                   },
+  { BFD_RELOC_V850_16_S1,                  R_V850_16_S1                  },
+  { BFD_RELOC_V850_LO16_S1,                R_V850_LO16_S1                },
+  { BFD_RELOC_V850_CALLT_15_16_OFFSET,     R_V850_CALLT_15_16_OFFSET     },
+  { BFD_RELOC_V850_32_GOTPCREL,            R_V850_32_GOTPCREL            },
+  { BFD_RELOC_V850_16_GOT,                 R_V850_16_GOT                 },
+  { BFD_RELOC_V850_32_GOT,                 R_V850_32_GOT                 },
+  { BFD_RELOC_V850_22_PLT_PCREL,           R_V850_22_PLT                 },
+  { BFD_RELOC_V850_32_PLT_PCREL,           R_V850_32_PLT                 },
+  { BFD_RELOC_V850_COPY,                   R_V850_COPY                   },
+  { BFD_RELOC_V850_GLOB_DAT,               R_V850_GLOB_DAT               },
+  { BFD_RELOC_V850_JMP_SLOT,               R_V850_JMP_SLOT               },
+  { BFD_RELOC_V850_RELATIVE,               R_V850_RELATIVE               },
+  { BFD_RELOC_V850_16_GOTOFF,              R_V850_16_GOTOFF              },
+  { BFD_RELOC_V850_32_GOTOFF,              R_V850_32_GOTOFF              },
+  { BFD_RELOC_V850_CODE,                   R_V850_CODE                   },
+  { BFD_RELOC_V850_DATA,                   R_V850_DATA                   },
 };
 \f
 /* Map a bfd relocation into the appropriate howto structure.  */
@@ -1417,28 +1846,54 @@ v850_elf_final_link_relocate (reloc_howto_type *howto,
       value -= offset;
       break;
 
+    case R_V850_16_PCREL:
+      value -= (input_section->output_section->vma
+               + input_section->output_offset
+               + offset);
+
+      /* If the sign extension will corrupt the value then we have overflowed.  */
+      if ((value & 0xffff0000) != 0xffff0000)
+       return bfd_reloc_overflow;
+
+      break;
+
+    case R_V850_17_PCREL:
+      value -= (input_section->output_section->vma
+               + input_section->output_offset
+               + offset);
+
+      /* If the sign extension will corrupt the value then we have overflowed.  */
+      if (((value & 0xffff0000) != 0x0) && ((value & 0xffff0000) != 0xffff0000))
+       return bfd_reloc_overflow;
+
+      value = SEXT17 (value);
+      break;
+
     case R_V850_22_PCREL:
       value -= (input_section->output_section->vma
                + input_section->output_offset
                + offset);
 
       /* If the sign extension will corrupt the value then we have overflowed.  */
-      if (((value & 0xff000000) != 0x0) && ((value & 0xff000000) != 0xff000000))
+      if (((value & 0xffe00000) != 0x0) && ((value & 0xffe00000) != 0xffe00000))
        return bfd_reloc_overflow;
 
-      /* Only the bottom 24 bits of the PC are valid.  */
-      value = SEXT24 (value);
+      /* Only the bottom 22 bits of the PC are valid.  */
+      value = SEXT22 (value);
       break;
 
-    case R_V850_REL32:
+    case R_V850_32_PCREL:
       value -= (input_section->output_section->vma
                + input_section->output_offset
                + offset);
       break;
 
+    case R_V850_32_ABS:
+    case R_V850_23:
     case R_V850_HI16_S:
     case R_V850_HI16:
     case R_V850_LO16:
+    case R_V850_LO16_S1:
     case R_V850_LO16_SPLIT_OFFSET:
     case R_V850_16:
     case R_V850_ABS32:
@@ -1481,10 +1936,10 @@ v850_elf_final_link_relocate (reloc_howto_type *howto,
 
     case R_V850_TDA_4_4_OFFSET:
     case R_V850_TDA_4_5_OFFSET:
-    case R_V850_TDA_16_16_OFFSET:
     case R_V850_TDA_7_7_OFFSET:
     case R_V850_TDA_7_8_OFFSET:
     case R_V850_TDA_6_8_OFFSET:
+    case R_V850_TDA_16_16_OFFSET:
       {
        unsigned long                ep;
        struct bfd_link_hash_entry * h;
@@ -1521,6 +1976,7 @@ v850_elf_final_link_relocate (reloc_howto_type *howto,
       }
     break;
 
+    case R_V850_CALLT_15_16_OFFSET:
     case R_V850_CALLT_16_16_OFFSET:
       {
        unsigned long                ctbp;
@@ -1766,6 +2222,12 @@ v850_elf_object_p (bfd *abfd)
     case E_V850E1_ARCH:
       bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850e1);
       break;
+    case E_V850E2_ARCH:
+      bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850e2);
+      break;
+    case E_V850E2V3_ARCH:
+      bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850e2v3);
+      break;
     }
   return TRUE;
 }
@@ -1784,6 +2246,8 @@ v850_elf_final_write_processing (bfd *abfd,
     case bfd_mach_v850:   val = E_V850_ARCH; break;
     case bfd_mach_v850e:  val = E_V850E_ARCH; break;
     case bfd_mach_v850e1: val = E_V850E1_ARCH; break;
+    case bfd_mach_v850e2: val = E_V850E2_ARCH;  break;
+    case bfd_mach_v850e2v3: val = E_V850E2V3_ARCH;  break;
     }
 
   elf_elfheader (abfd)->e_flags &=~ EF_V850_ARCH;
@@ -1847,20 +2311,40 @@ v850_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
   if ((in_flags & EF_V850_ARCH) != (out_flags & EF_V850_ARCH)
       && (in_flags & EF_V850_ARCH) != E_V850_ARCH)
     {
+
       /* Allow v850e1 binaries to be linked with v850e binaries.
-        Set the output binary to v850e.  */
+         Set the output binary to v850e.  */
       if ((in_flags & EF_V850_ARCH) == E_V850E1_ARCH
-         && (out_flags & EF_V850_ARCH) == E_V850E_ARCH)
-       return TRUE;
+          && (out_flags & EF_V850_ARCH) == E_V850E_ARCH)
+        return TRUE;
 
-      if ((in_flags & EF_V850_ARCH) == E_V850E_ARCH
-         && (out_flags & EF_V850_ARCH) == E_V850E1_ARCH)
+      if ((in_flags & EF_V850_ARCH) == E_V850_ARCH
+         && (out_flags & EF_V850_ARCH) == E_V850E_ARCH)
        {
          elf_elfheader (obfd)->e_flags =
            ((out_flags & ~ EF_V850_ARCH) | E_V850E_ARCH);
          return TRUE;
        }
 
+      if (((in_flags & EF_V850_ARCH) == E_V850_ARCH
+          || (in_flags & EF_V850_ARCH) == E_V850E_ARCH)
+         && (out_flags & EF_V850_ARCH) == E_V850E2_ARCH)
+       {
+         elf_elfheader (obfd)->e_flags =
+           ((out_flags & ~ EF_V850_ARCH) | E_V850E2_ARCH);
+         return TRUE;
+       }
+
+      if (((in_flags & EF_V850_ARCH) == E_V850_ARCH
+          || (in_flags & EF_V850_ARCH) == E_V850E_ARCH
+          || (in_flags & EF_V850_ARCH) == E_V850E2_ARCH)
+         && (out_flags & EF_V850_ARCH) == E_V850E2V3_ARCH)
+       {
+         elf_elfheader (obfd)->e_flags =
+           ((out_flags & ~ EF_V850_ARCH) | E_V850E2V3_ARCH);
+         return TRUE;
+       }
+
       _bfd_error_handler (_("%B: Architecture mismatch with previous modules"),
                          ibfd);
     }
@@ -1879,7 +2363,7 @@ v850_elf_print_private_bfd_data (bfd *abfd, void * ptr)
 
   _bfd_elf_print_private_bfd_data (abfd, ptr);
 
-  /* xgettext:c-format */
+  /* xgettext:c-format */
   fprintf (file, _("private flags = %lx: "), elf_elfheader (abfd)->e_flags);
 
   switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
@@ -1888,6 +2372,8 @@ v850_elf_print_private_bfd_data (bfd *abfd, void * ptr)
     case E_V850_ARCH: fprintf (file, _("v850 architecture")); break;
     case E_V850E_ARCH: fprintf (file, _("v850e architecture")); break;
     case E_V850E1_ARCH: fprintf (file, _("v850e1 architecture")); break;
+    case E_V850E2_ARCH: fprintf (file, _("v850e2 architecture")); break;
+    case E_V850E2V3_ARCH: fprintf (file, _("v850e2v3 architecture")); break;
     }
 
   fputc ('\n', file);
@@ -1949,7 +2435,7 @@ v850_elf_symbol_processing (bfd *abfd, asymbol *asym)
      FIXME: Should we alter the st_shndx field as well ?  */
 
   if (indx < elf_numsections (abfd))
-    switch (elf_elfsections(abfd)[indx]->sh_type)
+    switch (elf_elfsections (abfd)[indx]->sh_type)
       {
       case SHT_V850_SCOMMON:
        indx = SHN_V850_SCOMMON;
@@ -2046,7 +2532,7 @@ v850_elf_add_symbol_hook (bfd *abfd,
      FIXME: Should we alter the st_shndx field as well ?  */
 
   if (indx < elf_numsections (abfd))
-    switch (elf_elfsections(abfd)[indx]->sh_type)
+    switch (elf_elfsections (abfd)[indx]->sh_type)
       {
       case SHT_V850_SCOMMON:
        indx = SHN_V850_SCOMMON;
@@ -2376,22 +2862,22 @@ v850_elf_relax_delete_bytes (bfd *abfd,
 }
 
 #define NOP_OPCODE     (0x0000)
-#define MOVHI          0x0640                          /* 4byte */
+#define MOVHI          0x0640                          /* 4byte */
 #define MOVHI_MASK     0x07e0
-#define MOVHI_R1(insn) ((insn) & 0x1f)                 /* 4byte */
+#define MOVHI_R1(insn) ((insn) & 0x1f)                 /* 4byte */
 #define MOVHI_R2(insn) ((insn) >> 11)
-#define MOVEA          0x0620                          /* 2byte */
+#define MOVEA          0x0620                          /* 2byte */
 #define MOVEA_MASK     0x07e0
 #define MOVEA_R1(insn) ((insn) & 0x1f)
 #define MOVEA_R2(insn) ((insn) >> 11)
-#define JARL_4         0x00040780                              /* 4byte */
+#define JARL_4         0x00040780                              /* 4byte */
 #define JARL_4_MASK    0xFFFF07FF
 #define JARL_R2(insn)  (int)(((insn) & (~JARL_4_MASK)) >> 11)
-#define ADD_I          0x0240                                  /* 2byte */
+#define ADD_I          0x0240                                  /* 2byte */
 #define ADD_I_MASK     0x07e0
-#define ADD_I5(insn)   ((((insn) & 0x001f) << 11) >> 11)       /* 2byte */
+#define ADD_I5(insn)   ((((insn) & 0x001f) << 11) >> 11)       /* 2byte */
 #define ADD_R2(insn)   ((insn) >> 11)
-#define JMP_R          0x0060                                  /* 2byte */
+#define JMP_R          0x0060                                  /* 2byte */
 #define JMP_R_MASK     0xFFE0
 #define JMP_R1(insn)   ((insn) & 0x1f)
 
index 3da79d9ddec2aac98ea4fa6284fb95a323ccbbb3..94bbd8ef5cd615807bcb509b8bcc366d55e6e106 100644 (file)
@@ -1636,6 +1636,28 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_V850_LONGJUMP",
   "BFD_RELOC_V850_ALIGN",
   "BFD_RELOC_V850_LO16_SPLIT_OFFSET",
+  "BFD_RELOC_V850_16_PCREL",
+  "BFD_RELOC_V850_17_PCREL",
+  "BFD_RELOC_V850_23",
+  "BFD_RELOC_V850_32_PCREL",
+  "BFD_RELOC_V850_32_ABS",
+  "BFD_RELOC_V850_16_SPLIT_OFFSET",
+  "BFD_RELOC_V850_16_S1",
+  "BFD_RELOC_V850_LO16_S1",
+  "BFD_RELOC_V850_CALLT_15_16_OFFSET",
+  "BFD_RELOC_V850_32_GOTPCREL",
+  "BFD_RELOC_V850_16_GOT",
+  "BFD_RELOC_V850_32_GOT",
+  "BFD_RELOC_V850_22_PLT_PCREL",
+  "BFD_RELOC_V850_32_PLT_PCREL",
+  "BFD_RELOC_V850_COPY",
+  "BFD_RELOC_V850_GLOB_DAT",
+  "BFD_RELOC_V850_JMP_SLOT",
+  "BFD_RELOC_V850_RELATIVE",
+  "BFD_RELOC_V850_16_GOTOFF",
+  "BFD_RELOC_V850_32_GOTOFF",
+  "BFD_RELOC_V850_CODE",
+  "BFD_RELOC_V850_DATA",
   "BFD_RELOC_MN10300_32_PCREL",
   "BFD_RELOC_MN10300_16_PCREL",
   "BFD_RELOC_TIC30_LDP",
index 7d16869263d8a84943dc5277dae6e9b074f1729f..f8a39c9aa02a29b7aed9d7896a0bf254ea3c06e6 100644 (file)
@@ -3722,6 +3722,94 @@ ENUM
 ENUMDOC
   This is a variation of BFD_RELOC_LO16 that can be used in v850e ld.bu
   instructions.
+ENUM
+  BFD_RELOC_V850_16_PCREL
+ENUMDOC
+  This is a 16-bit reloc.
+ENUM     
+  BFD_RELOC_V850_17_PCREL
+ENUMDOC
+  This is a 17-bit reloc.
+ENUM     
+  BFD_RELOC_V850_23
+ENUMDOC
+  This is a 23-bit reloc.
+ENUM     
+  BFD_RELOC_V850_32_PCREL
+ENUMDOC
+  This is a 32-bit reloc.
+ENUM     
+  BFD_RELOC_V850_32_ABS
+ENUMDOC
+  This is a 32-bit reloc.
+ENUM     
+  BFD_RELOC_V850_16_SPLIT_OFFSET
+ENUMDOC
+  This is a 16-bit reloc.
+ENUM     
+  BFD_RELOC_V850_16_S1
+ENUMDOC
+  This is a 16-bit reloc.
+ENUM     
+  BFD_RELOC_V850_LO16_S1
+ENUMDOC
+  Low 16 bits. 16 bit shifted by 1.
+ENUM     
+  BFD_RELOC_V850_CALLT_15_16_OFFSET
+ENUMDOC
+  This is a 16 bit offset from the call table base pointer.
+ENUM     
+  BFD_RELOC_V850_32_GOTPCREL
+ENUMDOC
+  DSO relocations.
+ENUM     
+  BFD_RELOC_V850_16_GOT
+ENUMDOC
+  DSO relocations.
+ENUM     
+  BFD_RELOC_V850_32_GOT
+ENUMDOC
+  DSO relocations.
+ENUM     
+  BFD_RELOC_V850_22_PLT_PCREL
+ENUMDOC
+  DSO relocations.
+ENUM     
+  BFD_RELOC_V850_32_PLT_PCREL
+ENUMDOC
+  DSO relocations.
+ENUM     
+  BFD_RELOC_V850_COPY
+ENUMDOC
+  DSO relocations.
+ENUM     
+  BFD_RELOC_V850_GLOB_DAT
+ENUMDOC
+  DSO relocations.
+ENUM     
+  BFD_RELOC_V850_JMP_SLOT
+ENUMDOC
+  DSO relocations.
+ENUM     
+  BFD_RELOC_V850_RELATIVE
+ENUMDOC
+  DSO relocations.
+ENUM     
+  BFD_RELOC_V850_16_GOTOFF
+ENUMDOC
+  DSO relocations.
+ENUM     
+  BFD_RELOC_V850_32_GOTOFF
+ENUMDOC
+  DSO relocations.
+ENUM     
+  BFD_RELOC_V850_CODE
+ENUMDOC
+  start code.
+ENUM     
+  BFD_RELOC_V850_DATA
+ENUMDOC
+  start data in text.
 ENUM
   BFD_RELOC_MN10300_32_PCREL
 ENUMDOC
index 302d31659053b71b21201fee295bd2661c01eff7..ae598c14d6a74b766a93e25f242463b8b55f78d9 100644 (file)
@@ -1,3 +1,8 @@
+2010-07-23  Naveen.H.S  <naveen.S@kpitcummins.com>
+           Ina Pandit  <ina.pandit@kpitcummins.com>
+
+       * binutils/readelf.c: Add support for V850E2 and V850E2V3.
+
 2010-07-22  Alan Modra  <amodra@gmail.com>
 
        * readelf.c: Add Moxie support.
index fd81d2db12be75f201fc5750fbe6a30eba26fe01..c2bb10de2f051e18a467125a9e1072a48a51f414 100644 (file)
@@ -2352,8 +2352,14 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
        case EM_CYGNUS_V850:
          switch (e_flags & EF_V850_ARCH)
            {
-           case E_V850E1_ARCH:
-             strcat (buf, ", v850e1");
+           case E_V850E2V3_ARCH:
+             strcat (buf, ", v850e2v3");
+             break;
+           case E_V850E2_ARCH:
+             strcat (buf, ", v850e2");
+             break;
+            case E_V850E1_ARCH:
+              strcat (buf, ", v850e1");
              break;
            case E_V850E_ARCH:
              strcat (buf, ", v850e");
index 8edfde3da4d753dd410214c5e75f5b53b91b9f3d..0904ffb741b7315d431e41bb425ec816ef4d457f 100755 (executable)
--- a/configure
+++ b/configure
@@ -3730,14 +3730,8 @@ case "${target}" in
   v810-*-*)
     noconfigdirs="$noconfigdirs bfd binutils gas gcc gdb ld target-libstdc++-v3 opcodes target-libgloss ${libgcj}"
     ;;
-  v850-*-*)
-    noconfigdirs="$noconfigdirs target-libgloss ${libgcj}"
-    ;;
-  v850e-*-*)
-    noconfigdirs="$noconfigdirs target-libgloss ${libgcj}"
-    ;;
-  v850ea-*-*)
-    noconfigdirs="$noconfigdirs target-libgloss ${libgcj}"
+  v850*-*-*)
+    noconfigdirs="$noconfigdirs ${libgcj}"
     ;;
   vax-*-vms)
     noconfigdirs="$noconfigdirs bfd binutils gdb ld target-newlib opcodes target-libgloss ${libgcj}"
index f78c5273084a06aa9299d8431b6745363815229e..2d39219a619a1ac6e24ecfdbd862f162ca41e8ea 100644 (file)
@@ -967,14 +967,8 @@ case "${target}" in
   v810-*-*)
     noconfigdirs="$noconfigdirs bfd binutils gas gcc gdb ld target-libstdc++-v3 opcodes target-libgloss ${libgcj}"
     ;;
-  v850-*-*)
-    noconfigdirs="$noconfigdirs target-libgloss ${libgcj}"
-    ;;
-  v850e-*-*)
-    noconfigdirs="$noconfigdirs target-libgloss ${libgcj}"
-    ;;
-  v850ea-*-*)
-    noconfigdirs="$noconfigdirs target-libgloss ${libgcj}"
+  v850*-*-*)
+    noconfigdirs="$noconfigdirs ${libgcj}"
     ;;
   vax-*-vms)
     noconfigdirs="$noconfigdirs bfd binutils gdb ld target-newlib opcodes target-libgloss ${libgcj}"
index a157d027683a1dd53cb1b0e579ab573bf986abe3..5ad0269b30d36316b001835b517b71ce0aaa07cb 100644 (file)
@@ -1,3 +1,50 @@
+2010-07-23  Naveen.H.S  <naveen.S@kpitcummins.com>
+           Ina Pandit  <ina.pandit@kpitcummins.com>
+
+       * config/tc-v850.c: Update processor_mask.
+       (reg_name): Update the structure to use processors field.
+       (md_relax_table): Define SUBYPTE_COND_9_22, SUBYPTE_SA_9_22,
+       SUBYPTE_UNCOND_9_22, SUBYPTE_COND_9_22_32, SUBYPTE_SA_9_22_32,
+       SUBYPTE_UNCOND_9_22_32, SUBYPTE_COND_9_17_22,
+       SUBYPTE_SA_9_17_22, SUBYPTE_COND_9_17_22_32 and
+       SUBYPTE_SA_9_17_22_32.
+       (set_machine): Add support for V850E2 and V850E2V3.
+       (md_pseudo_table): Likewise.
+       (pre_defined_registers): Update pre defined registers suitable
+       for each family of registers.
+       (system_registers): Likewise.
+       (cc_names): Update the condition code.
+       (float_cc_names): Update the condition code for float.
+       (reg_name_search): Update based on current modifications.
+       (register_name): Likewise.
+       (system_register_name): Update to support new system registers
+       and supported families.
+       (cc_name): Update to support new condition codes.
+       (float_cc_name): New function to support float condition codes.
+       (parse_register_list): Update to support newly added registers.
+       (md_show_usage): Define support for V850E2 and V850E2V3 targets.
+       Also support added for disp-size-default-22, disp-size-default-32,
+       mextension, mno-bcond17 and mno-stld23.
+       (md_parse_option): Implement the support for above options defined
+       in md_show-usage.
+       (md_convert_frag): Implement support for subtypes defined in
+       md_relax_table to support branch operations.
+       (md_begin): Add support for V850E2 and V850E2V3.
+       (handle_hi016, handle_hi16): new relocation handling functions
+       (handle_lo16, handle_ctoff, handle_sdaoff, handle_zdaoff,
+       handle_tdaoff): Updated relocation handling functions for newly
+       added relocations.
+       (v850_reloc_prefix): Update the relocation handling functions.
+       (v850_insert_operand): Updated the functions with error message
+       parameter and modified the function to use it.
+       (md_assemble): Update according to the latest modifications.
+       (md_apply_fix): Updated the functions with error message parameter
+       and modified the function to use it.
+       (v850_force_relocation): Update with newly added relocations.
+       * configure.tgt: Match all v850 targets.
+       * doc/c-v850.texi: Document the newly added targets.
+       * NEWS: Likewise.
+
 2010-07-23  Alan Modra  <amodra@gmail.com>
 
        PR gas/11834
index db6b6d4d05cb4fbc400144a1b34636b58fcb577e..c7280bb223134e32c2efa15e153e9d3bb984a57a 100644 (file)
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -16,6 +16,8 @@
 
 Changes in 2.20:
 
+* Added support for v850e2 and v850e2v3.
+
 * GNU/Linux targets now supports "gnu_unique_object" as a value in the .type
   pseudo op.  It marks the symbol as being globally unique in the entire
   process.
index e0ac162279a1068d1ff279f982484a7431d34894..d792769f99ccac5451dc4bf909f116a56599500f 100644 (file)
@@ -1,6 +1,6 @@
 /* tc-v850.c -- Assembler code for the NEC V850
    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-   2006, 2007, 2009  Free Software Foundation, Inc.
+   2006, 2007, 2009, 2010  Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
@@ -39,13 +39,14 @@ static bfd_boolean warn_unsigned_overflows = FALSE;
 static int machine = -1;
 
 /* Indicates the target processor(s) for the assemble.  */
-static int processor_mask = -1;
+static int processor_mask = 0;
 \f
 /* Structure to hold information about predefined registers.  */
 struct reg_name
 {
   const char *name;
   int value;
+  unsigned int processors;
 };
 
 /* Generic assembler global variables which must be defined by all
@@ -71,15 +72,67 @@ const char FLT_CHARS[] = "dD";
 \f
 const relax_typeS md_relax_table[] =
 {
-  /* Conditional branches.  */
-  {0xff,     -0x100,    2, 1},
-  {0x1fffff, -0x200000, 6, 0},
-  /* Unconditional branches.  */
-  {0xff,     -0x100,    2, 3},
-  {0x1fffff, -0x200000, 4, 0},
+  /* Conditional branches.(V850/V850E, max 22bit)  */
+#define SUBYPTE_COND_9_22      0
+  {0xfe,        -0x100,        2, SUBYPTE_COND_9_22 + 1},
+  {0x1ffffe + 2, -0x200000 + 2, 6, 0},
+  /* Conditional branches.(V850/V850E, max 22bit)  */
+#define SUBYPTE_SA_9_22        2
+  {0xfe,         -0x100,      2, SUBYPTE_SA_9_22 + 1},
+  {0x1ffffe + 4, -0x200000 + 4, 8, 0},
+  /* Unconditional branches.(V850/V850E, max 22bit)  */
+#define SUBYPTE_UNCOND_9_22    4
+  {0xfe,     -0x100,    2, SUBYPTE_UNCOND_9_22 + 1},
+  {0x1ffffe, -0x200000, 4, 0},
+  /* Conditional branches.(V850E2, max 32bit)  */
+#define SUBYPTE_COND_9_22_32   6
+  {0xfe,     -0x100,    2, SUBYPTE_COND_9_22_32 + 1},
+  {0x1fffff + 2, -0x200000 + 2, 6, SUBYPTE_COND_9_22_32 + 2},
+  {0x7ffffffe, -0x80000000, 8, 0},
+  /* Conditional branches.(V850E2, max 32bit)  */
+#define SUBYPTE_SA_9_22_32     9
+  {0xfe,     -0x100,    2, SUBYPTE_SA_9_22_32 + 1},
+  {0x1ffffe + 4, -0x200000 + 4, 8, SUBYPTE_SA_9_22_32 + 2},
+  {0x7ffffffe, -0x80000000, 10, 0},
+  /* Unconditional branches.(V850E2, max 32bit)  */
+#define SUBYPTE_UNCOND_9_22_32 12
+  {0xfe,     -0x100,    2, SUBYPTE_UNCOND_9_22_32 + 1},
+  {0x1ffffe, -0x200000, 4, SUBYPTE_UNCOND_9_22_32 + 2},
+  {0x7ffffffe, -0x80000000, 6, 0},
+  /* Conditional branches.(V850E2R max 22bit)  */
+#define SUBYPTE_COND_9_17_22   15
+  {0xfe,     -0x100,    2, SUBYPTE_COND_9_17_22 + 1},
+  {0xfffe, -0x10000,   4, SUBYPTE_COND_9_17_22 + 2},
+  {0x1ffffe + 2, -0x200000 + 2, 6, 0},
+  /* Conditional branches.(V850E2R max 22bit)  */
+#define SUBYPTE_SA_9_17_22     18
+  {0xfe,     -0x100,    2, SUBYPTE_SA_9_17_22 + 1},
+  {0xfffe, -0x10000,   4, SUBYPTE_SA_9_17_22 + 2},
+  {0x1ffffe + 4, -0x200000 + 4, 8, 0},
+  /* Conditional branches.(V850E2R max 32bit)  */
+#define SUBYPTE_COND_9_17_22_32        21
+  {0xfe,     -0x100,    2, SUBYPTE_COND_9_17_22_32 + 1},
+  {0xfffe, -0x10000,   4, SUBYPTE_COND_9_17_22_32 + 2},
+  {0x1ffffe + 2, -0x200000 + 2, 6, SUBYPTE_COND_9_17_22_32 + 3},
+  {0x7ffffffe, -0x80000000, 8, 0},
+  /* Conditional branches.(V850E2R max 32bit)  */
+#define SUBYPTE_SA_9_17_22_32  25
+  {0xfe,     -0x100,    2, SUBYPTE_SA_9_17_22_32 + 1},
+  {0xfffe, -0x10000,   4, SUBYPTE_SA_9_17_22_32 + 2},
+  {0x1ffffe + 4, -0x200000 + 4, 8, SUBYPTE_SA_9_17_22_32 + 3},
+  {0x7ffffffe, -0x80000000, 10, 0},
 };
 
-static int  v850_relax = 0;
+static int v850_relax = 0;
+
+/* Default branch disp size 22 or 32.  */
+static int default_disp_size = 22;
+
+/* Default no using bcond17.  */
+static int no_bcond17 = 0;
+
+/* Default no using ld/st 23bit offset.  */
+static int no_stld23 = 0;
 
 /* Fixups.  */
 #define MAX_INSN_FIXUPS   5
@@ -463,9 +516,12 @@ set_machine (int number)
 
   switch (machine)
     {
-    case 0:              processor_mask = PROCESSOR_V850;   break;
-    case bfd_mach_v850e:  processor_mask = PROCESSOR_V850E;  break;
-    case bfd_mach_v850e1: processor_mask = PROCESSOR_V850E;  break;
+    case 0:                SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850);    break;
+    case bfd_mach_v850:    SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850);    break;
+    case bfd_mach_v850e:   SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E);   break;
+    case bfd_mach_v850e1:  SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E);   break;
+    case bfd_mach_v850e2:  SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E2);  break;
+    case bfd_mach_v850e2v3:SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E2V3); break;
     }
 }
 
@@ -523,7 +579,9 @@ const pseudo_typeS md_pseudo_table[] =
   { "call_table_data", v850_seg,               CALL_TABLE_DATA_SECTION },
   { "call_table_text", v850_seg,               CALL_TABLE_TEXT_SECTION },
   { "v850e",           set_machine,            bfd_mach_v850e          },
-  { "v850e1",          set_machine,            bfd_mach_v850e1         },
+  { "v850e1",          set_machine,            bfd_mach_v850e1         },
+  { "v850e2",          set_machine,            bfd_mach_v850e2         },
+  { "v850e2v3",                set_machine,            bfd_mach_v850e2v3       },
   { "longcall",                v850_longcode,          1                       },
   { "longjump",                v850_longcode,          2                       },
   { NULL,              NULL,                   0                       }
@@ -535,45 +593,45 @@ static struct hash_control *v850_hash;
 /* This table is sorted.  Suitable for searching by a binary search.  */
 static const struct reg_name pre_defined_registers[] =
 {
-  { "ep",  30 },               /* ep - element ptr.  */
-  { "gp",   4 },               /* gp - global ptr.  */
-  { "hp",   2 },               /* hp - handler stack ptr.  */
-  { "lp",  31 },               /* lp - link ptr.  */
-  { "r0",   0 },
-  { "r1",   1 },
-  { "r10", 10 },
-  { "r11", 11 },
-  { "r12", 12 },
-  { "r13", 13 },
-  { "r14", 14 },
-  { "r15", 15 },
-  { "r16", 16 },
-  { "r17", 17 },
-  { "r18", 18 },
-  { "r19", 19 },
-  { "r2",   2 },
-  { "r20", 20 },
-  { "r21", 21 },
-  { "r22", 22 },
-  { "r23", 23 },
-  { "r24", 24 },
-  { "r25", 25 },
-  { "r26", 26 },
-  { "r27", 27 },
-  { "r28", 28 },
-  { "r29", 29 },
-  { "r3",   3 },
-  { "r30", 30 },
-  { "r31", 31 },
-  { "r4",   4 },
-  { "r5",   5 },
-  { "r6",   6 },
-  { "r7",   7 },
-  { "r8",   8 },
-  { "r9",   9 },
-  { "sp",   3 },               /* sp - stack ptr.  */
-  { "tp",   5 },               /* tp - text ptr.  */
-  { "zero", 0 },
+  { "ep",  30, PROCESSOR_ALL },                /* ep - element ptr.  */
+  { "gp",   4, PROCESSOR_ALL },                /* gp - global ptr.  */
+  { "hp",   2, PROCESSOR_ALL },                /* hp - handler stack ptr.  */
+  { "lp",  31, PROCESSOR_ALL },                /* lp - link ptr.  */
+  { "r0",   0, PROCESSOR_ALL },
+  { "r1",   1, PROCESSOR_ALL },
+  { "r10", 10, PROCESSOR_ALL },
+  { "r11", 11, PROCESSOR_ALL },
+  { "r12", 12, PROCESSOR_ALL },
+  { "r13", 13, PROCESSOR_ALL },
+  { "r14", 14, PROCESSOR_ALL },
+  { "r15", 15, PROCESSOR_ALL },
+  { "r16", 16, PROCESSOR_ALL },
+  { "r17", 17, PROCESSOR_ALL },
+  { "r18", 18, PROCESSOR_ALL },
+  { "r19", 19, PROCESSOR_ALL },
+  { "r2",   2, PROCESSOR_ALL },
+  { "r20", 20, PROCESSOR_ALL },
+  { "r21", 21, PROCESSOR_ALL },
+  { "r22", 22, PROCESSOR_ALL },
+  { "r23", 23, PROCESSOR_ALL },
+  { "r24", 24, PROCESSOR_ALL },
+  { "r25", 25, PROCESSOR_ALL },
+  { "r26", 26, PROCESSOR_ALL },
+  { "r27", 27, PROCESSOR_ALL },
+  { "r28", 28, PROCESSOR_ALL },
+  { "r29", 29, PROCESSOR_ALL },
+  { "r3",   3, PROCESSOR_ALL },
+  { "r30", 30, PROCESSOR_ALL },
+  { "r31", 31, PROCESSOR_ALL },
+  { "r4",   4, PROCESSOR_ALL },
+  { "r5",   5, PROCESSOR_ALL },
+  { "r6",   6, PROCESSOR_ALL },
+  { "r7",   7, PROCESSOR_ALL },
+  { "r8",   8, PROCESSOR_ALL },
+  { "r9",   9, PROCESSOR_ALL },
+  { "sp",   3, PROCESSOR_ALL },                /* sp - stack ptr.  */
+  { "tp",   5, PROCESSOR_ALL },                /* tp - text ptr.  */
+  { "zero", 0, PROCESSOR_ALL },
 };
 
 #define REG_NAME_CNT                                           \
@@ -581,67 +639,220 @@ static const struct reg_name pre_defined_registers[] =
 
 static const struct reg_name system_registers[] =
 {
-  { "asid",  23 },
-  { "bpc",   22 },
-  { "bpav",  24 },
-  { "bpam",  25 },
-  { "bpdv",  26 },
-  { "bpdm",  27 },
-  { "ctbp",  20 },
-  { "ctpc",  16 },
-  { "ctpsw", 17 },
-  { "dbpc",  18 },
-  { "dbpsw", 19 },
-  { "dir",   21 },
-  { "ecr",    4 },
-  { "eipc",   0 },
-  { "eipsw",  1 },
-  { "fepc",   2 },
-  { "fepsw",  3 },
-  { "psw",    5 },
+  { "asid",        23, PROCESSOR_NOT_V850 },
+  { "bpam",        25, PROCESSOR_NOT_V850 },
+  { "bpav",        24, PROCESSOR_NOT_V850 },
+  { "bpc",         22, PROCESSOR_NOT_V850 },
+  { "bpdm",        27, PROCESSOR_NOT_V850 },
+  { "bpdv",        26, PROCESSOR_NOT_V850 },
+  { "bsel",        31, PROCESSOR_V850E2_ALL },
+  { "cfg",          7, PROCESSOR_V850E2V3 },
+  { "ctbp",        20, PROCESSOR_NOT_V850 },
+  { "ctpc",        16, PROCESSOR_NOT_V850 },
+  { "ctpsw",       17, PROCESSOR_NOT_V850 },
+  { "dbic",        15, PROCESSOR_V850E2_ALL },
+  { "dbpc",        18, PROCESSOR_NOT_V850 },
+  { "dbpsw",       19, PROCESSOR_NOT_V850 },
+  { "dbwr",        30, PROCESSOR_V850E2_ALL },
+  { "dir",         21, PROCESSOR_NOT_V850 },
+  { "dpa0l",       16, PROCESSOR_V850E2V3 },
+  { "dpa0u",       17, PROCESSOR_V850E2V3 },
+  { "dpa1l",       18, PROCESSOR_V850E2V3 },
+  { "dpa1u",       19, PROCESSOR_V850E2V3 },
+  { "dpa2l",       20, PROCESSOR_V850E2V3 },
+  { "dpa2u",       21, PROCESSOR_V850E2V3 },
+  { "dpa3l",       22, PROCESSOR_V850E2V3 },
+  { "dpa3u",       23, PROCESSOR_V850E2V3 },
+  { "dpa4l",       24, PROCESSOR_V850E2V3 },
+  { "dpa4u",       25, PROCESSOR_V850E2V3 },
+  { "dpa5l",       26, PROCESSOR_V850E2V3 },
+  { "dpa5u",       27, PROCESSOR_V850E2V3 },
+  { "ecr",          4, PROCESSOR_ALL },
+  { "eh_base",      3, PROCESSOR_V850E2V3 },
+  { "eh_cfg",       1, PROCESSOR_V850E2V3 },
+  { "eh_reset",     2, PROCESSOR_V850E2V3 },
+  { "eiic",        13, PROCESSOR_V850E2_ALL },
+  { "eipc",         0, PROCESSOR_ALL },
+  { "eipsw",        1, PROCESSOR_ALL },
+  { "eiwr",        28, PROCESSOR_V850E2_ALL },
+  { "feic",        14, PROCESSOR_V850E2_ALL },
+  { "fepc",         2, PROCESSOR_ALL },
+  { "fepsw",        3, PROCESSOR_ALL },
+  { "fewr",        29, PROCESSOR_V850E2_ALL },
+  { "fpcc",         9, PROCESSOR_V850E2V3 },
+  { "fpcfg",       10, PROCESSOR_V850E2V3 },
+  { "fpec",        11, PROCESSOR_V850E2V3 },
+  { "fpepc",        7, PROCESSOR_V850E2V3 },
+  { "fpspc",       27, PROCESSOR_V850E2V3 },
+  { "fpsr",         6, PROCESSOR_V850E2V3 },
+  { "fpst",         8, PROCESSOR_V850E2V3 },
+  { "ipa0l",        6, PROCESSOR_V850E2V3 },
+  { "ipa0u",        7, PROCESSOR_V850E2V3 },
+  { "ipa1l",        8, PROCESSOR_V850E2V3 },
+  { "ipa1u",        9, PROCESSOR_V850E2V3 },
+  { "ipa2l",       10, PROCESSOR_V850E2V3 },
+  { "ipa2u",       11, PROCESSOR_V850E2V3 },
+  { "ipa3l",       12, PROCESSOR_V850E2V3 },
+  { "ipa3u",       13, PROCESSOR_V850E2V3 },
+  { "ipa4l",       14, PROCESSOR_V850E2V3 },
+  { "ipa4u",       15, PROCESSOR_V850E2V3 },
+  { "mca",         24, PROCESSOR_V850E2V3 },
+  { "mcc",         26, PROCESSOR_V850E2V3 },
+  { "mcr",         27, PROCESSOR_V850E2V3 },
+  { "mcs",         25, PROCESSOR_V850E2V3 },
+  { "mpc",          1, PROCESSOR_V850E2V3 },
+  { "mpm",          0, PROCESSOR_V850E2V3 },
+  { "mpu10_dpa0l", 16, PROCESSOR_V850E2V3 },
+  { "mpu10_dpa0u", 17, PROCESSOR_V850E2V3 },
+  { "mpu10_dpa1l", 18, PROCESSOR_V850E2V3 },
+  { "mpu10_dpa1u", 19, PROCESSOR_V850E2V3 },
+  { "mpu10_dpa2l", 20, PROCESSOR_V850E2V3 },
+  { "mpu10_dpa2u", 21, PROCESSOR_V850E2V3 },
+  { "mpu10_dpa3l", 22, PROCESSOR_V850E2V3 },
+  { "mpu10_dpa3u", 23, PROCESSOR_V850E2V3 },
+  { "mpu10_dpa4l", 24, PROCESSOR_V850E2V3 },
+  { "mpu10_dpa4u", 25, PROCESSOR_V850E2V3 },
+  { "mpu10_dpa5l", 26, PROCESSOR_V850E2V3 },
+  { "mpu10_dpa5u", 27, PROCESSOR_V850E2V3 },
+  { "mpu10_ipa0l",  6, PROCESSOR_V850E2V3 },
+  { "mpu10_ipa0u",  7, PROCESSOR_V850E2V3 },
+  { "mpu10_ipa1l",  8, PROCESSOR_V850E2V3 },
+  { "mpu10_ipa1u",  9, PROCESSOR_V850E2V3 },
+  { "mpu10_ipa2l", 10, PROCESSOR_V850E2V3 },
+  { "mpu10_ipa2u", 11, PROCESSOR_V850E2V3 },
+  { "mpu10_ipa3l", 12, PROCESSOR_V850E2V3 },
+  { "mpu10_ipa3u", 13, PROCESSOR_V850E2V3 },
+  { "mpu10_ipa4l", 14, PROCESSOR_V850E2V3 },
+  { "mpu10_ipa4u", 15, PROCESSOR_V850E2V3 },
+  { "mpu10_mpc",    1, PROCESSOR_V850E2V3 },
+  { "mpu10_mpm",    0, PROCESSOR_V850E2V3 },
+  { "mpu10_tid",    2, PROCESSOR_V850E2V3 },
+  { "mpu10_vmadr",  5, PROCESSOR_V850E2V3 },
+  { "mpu10_vmecr",  3, PROCESSOR_V850E2V3 },
+  { "mpu10_vmtid",  4, PROCESSOR_V850E2V3 },
+  { "pid",          6, PROCESSOR_V850E2V3 },
+  { "pmcr0",        4, PROCESSOR_V850E2V3 },
+  { "pmis2",       14, PROCESSOR_V850E2V3 },
+  { "psw",          5, PROCESSOR_ALL },
+  { "scbp",        12, PROCESSOR_V850E2V3 },
+  { "sccfg",       11, PROCESSOR_V850E2V3 },
+  { "sr0",          0, PROCESSOR_ALL },
+  { "sr1",          1, PROCESSOR_ALL },
+  { "sr10",        10, PROCESSOR_ALL },
+  { "sr11",        11, PROCESSOR_ALL },
+  { "sr12",        12, PROCESSOR_ALL },
+  { "sr13",        13, PROCESSOR_ALL },
+  { "sr14",        14, PROCESSOR_ALL },
+  { "sr15",        15, PROCESSOR_ALL },
+  { "sr16",        16, PROCESSOR_ALL },
+  { "sr17",        17, PROCESSOR_ALL },
+  { "sr18",        18, PROCESSOR_ALL },
+  { "sr19",        19, PROCESSOR_ALL },
+  { "sr2",          2, PROCESSOR_ALL },
+  { "sr20",        20, PROCESSOR_ALL },
+  { "sr21",        21, PROCESSOR_ALL },
+  { "sr22",        22, PROCESSOR_ALL },
+  { "sr23",        23, PROCESSOR_ALL },
+  { "sr24",        24, PROCESSOR_ALL },
+  { "sr25",        25, PROCESSOR_ALL },
+  { "sr26",        26, PROCESSOR_ALL },
+  { "sr27",        27, PROCESSOR_ALL },
+  { "sr28",        28, PROCESSOR_ALL },
+  { "sr29",        29, PROCESSOR_ALL },
+  { "sr3",          3, PROCESSOR_ALL },
+  { "sr30",        30, PROCESSOR_ALL },
+  { "sr31",        31, PROCESSOR_ALL },
+  { "sr4",          4, PROCESSOR_ALL },
+  { "sr5",          5, PROCESSOR_ALL },
+  { "sr6",          6, PROCESSOR_ALL },
+  { "sr7",          7, PROCESSOR_ALL },
+  { "sr8",          8, PROCESSOR_ALL },
+  { "sr9",          9, PROCESSOR_ALL },
+  { "sw_base",      3, PROCESSOR_V850E2V3 },
+  { "sw_cfg",       1, PROCESSOR_V850E2V3 },
+  { "sw_ctl",       0, PROCESSOR_V850E2V3 },
+  { "tid",          2, PROCESSOR_V850E2V3 },
+  { "vmadr",        6, PROCESSOR_V850E2V3 },
+  { "vmecr",        4, PROCESSOR_V850E2V3 },
+  { "vmtid",        5, PROCESSOR_V850E2V3 },
+  { "vsadr",        2, PROCESSOR_V850E2V3 },
+  { "vsecr",        0, PROCESSOR_V850E2V3 },
+  { "vstid",        1, PROCESSOR_V850E2V3 },
 };
 
 #define SYSREG_NAME_CNT                                                \
   (sizeof (system_registers) / sizeof (struct reg_name))
 
-static const struct reg_name system_list_registers[] =
-{
-  {"PS",      5 },
-  {"SR",      0 + 1}
-};
-
-#define SYSREGLIST_NAME_CNT                                    \
-  (sizeof (system_list_registers) / sizeof (struct reg_name))
 
 static const struct reg_name cc_names[] =
 {
-  { "c",  0x1 },
-  { "e",  0x2 },
-  { "ge", 0xe },
-  { "gt", 0xf },
-  { "h",  0xb },
-  { "l",  0x1 },
-  { "le", 0x7 },
-  { "lt", 0x6 },
-  { "n",  0x4 },
-  { "nc", 0x9 },
-  { "ne", 0xa },
-  { "nh", 0x3 },
-  { "nl", 0x9 },
-  { "ns", 0xc },
-  { "nv", 0x8 },
-  { "nz", 0xa },
-  { "p",  0xc },
-  { "s",  0x4 },
-  { "sa", 0xd },
-  { "t",  0x5 },
-  { "v",  0x0 },
-  { "z",  0x2 },
+  { "c",  0x1, PROCESSOR_ALL },
+  { "e",  0x2, PROCESSOR_ALL },
+  { "ge", 0xe, PROCESSOR_ALL },
+  { "gt", 0xf, PROCESSOR_ALL },
+  { "h",  0xb, PROCESSOR_ALL },
+  { "l",  0x1, PROCESSOR_ALL },
+  { "le", 0x7, PROCESSOR_ALL },
+  { "lt", 0x6, PROCESSOR_ALL },
+  { "n",  0x4, PROCESSOR_ALL },
+  { "nc", 0x9, PROCESSOR_ALL },
+  { "ne", 0xa, PROCESSOR_ALL },
+  { "nh", 0x3, PROCESSOR_ALL },
+  { "nl", 0x9, PROCESSOR_ALL },
+  { "ns", 0xc, PROCESSOR_ALL },
+  { "nv", 0x8, PROCESSOR_ALL },
+  { "nz", 0xa, PROCESSOR_ALL },
+  { "p",  0xc, PROCESSOR_ALL },
+  { "s",  0x4, PROCESSOR_ALL },
+#define COND_SA_NUM 0xd
+  { "sa", COND_SA_NUM, PROCESSOR_ALL },
+  { "t",  0x5, PROCESSOR_ALL },
+  { "v",  0x0, PROCESSOR_ALL },
+  { "z",  0x2, PROCESSOR_ALL },
 };
 
 #define CC_NAME_CNT                                    \
   (sizeof (cc_names) / sizeof (struct reg_name))
 
+static const struct reg_name float_cc_names[] =
+{
+  { "eq",  0x2, PROCESSOR_V850E2V3 },  /* true.  */
+  { "f",   0x0, PROCESSOR_V850E2V3 },  /* true.  */
+  { "ge",  0xd, PROCESSOR_V850E2V3 },  /* false.  */
+  { "gl",  0xb, PROCESSOR_V850E2V3 },  /* false.  */
+  { "gle", 0x9, PROCESSOR_V850E2V3 },  /* false.  */
+  { "gt",  0xf, PROCESSOR_V850E2V3 },  /* false.  */
+  { "le",  0xe, PROCESSOR_V850E2V3 },  /* true.  */
+  { "lt",  0xc, PROCESSOR_V850E2V3 },  /* true.  */
+  { "neq", 0x2, PROCESSOR_V850E2V3 },  /* false.  */
+  { "nge", 0xd, PROCESSOR_V850E2V3 },  /* true.  */
+  { "ngl", 0xb, PROCESSOR_V850E2V3 },  /* true.  */
+  { "ngle",0x9, PROCESSOR_V850E2V3 },  /* true.  */
+  { "ngt", 0xf, PROCESSOR_V850E2V3 },  /* true.  */
+  { "nle", 0xe, PROCESSOR_V850E2V3 },  /* false.  */
+  { "nlt", 0xc, PROCESSOR_V850E2V3 },  /* false.  */
+  { "oge", 0x5, PROCESSOR_V850E2V3 },  /* false.  */
+  { "ogl", 0x3, PROCESSOR_V850E2V3 },  /* false.  */
+  { "ogt", 0x7, PROCESSOR_V850E2V3 },  /* false.  */
+  { "ole", 0x6, PROCESSOR_V850E2V3 },  /* true.  */
+  { "olt", 0x4, PROCESSOR_V850E2V3 },  /* true.  */
+  { "or",  0x1, PROCESSOR_V850E2V3 },  /* false.  */
+  { "seq", 0xa, PROCESSOR_V850E2V3 },  /* true.  */
+  { "sf",  0x8, PROCESSOR_V850E2V3 },  /* true.  */
+  { "sne", 0xa, PROCESSOR_V850E2V3 },  /* false.  */
+  { "st",  0x8, PROCESSOR_V850E2V3 },  /* false.  */
+  { "t",   0x0, PROCESSOR_V850E2V3 },  /* false.  */
+  { "ueq", 0x3, PROCESSOR_V850E2V3 },  /* true.  */
+  { "uge", 0x4, PROCESSOR_V850E2V3 },  /* false.  */
+  { "ugt", 0x6, PROCESSOR_V850E2V3 },  /* false.  */
+  { "ule", 0x7, PROCESSOR_V850E2V3 },  /* true.  */
+  { "ult", 0x5, PROCESSOR_V850E2V3 },  /* true.  */
+  { "un",  0x1, PROCESSOR_V850E2V3 },  /* true.  */
+};
+
+#define FLOAT_CC_NAME_CNT                                      \
+  (sizeof (float_cc_names) / sizeof (struct reg_name))
+
 /* Do a binary search of the given register table to see if NAME is a
    valid regiter name.  Return the register number from the array on
    success, or -1 on failure.  */
@@ -667,9 +878,7 @@ reg_name_search (const struct reg_name *regs,
       else if (accept_numbers)
        {
          int reg = S_GET_VALUE (symbolP);
-
-         if (reg >= 0 && reg <= 31)
-           return reg;
+         return reg;
        }
 
       /* Otherwise drop through and try parsing name normally.  */
@@ -687,7 +896,9 @@ reg_name_search (const struct reg_name *regs,
       else if (cmp > 0)
        low = middle + 1;
       else
-       return regs[middle].value;
+       return ((regs[middle].processors & processor_mask)
+               ? regs[middle].value
+               : -1);
     }
   while (low <= high);
   return -1;
@@ -722,25 +933,24 @@ register_name (expressionS *expressionP)
   /* Put back the delimiting char.  */
   *input_line_pointer = c;
 
+  expressionP->X_add_symbol = NULL;
+  expressionP->X_op_symbol  = NULL;
+
   /* Look to see if it's in the register table.  */
   if (reg_number >= 0)
     {
       expressionP->X_op                = O_register;
       expressionP->X_add_number = reg_number;
 
-      /* Make the rest nice.  */
-      expressionP->X_add_symbol = NULL;
-      expressionP->X_op_symbol  = NULL;
-
       return TRUE;
     }
-  else
-    {
-      /* Reset the line as if we had not done anything.  */
-      input_line_pointer = start;
 
-      return FALSE;
-    }
+  /* Reset the line as if we had not done anything.  */
+  input_line_pointer = start;
+
+  expressionP->X_op = O_illegal;
+
+  return FALSE;
 }
 
 /* Summary of system_register_name().
@@ -748,8 +958,6 @@ register_name (expressionS *expressionP)
    in:  INPUT_LINE_POINTER points to 1st char of operand.
        EXPRESSIONP points to an expression structure to be filled in.
        ACCEPT_NUMBERS is true iff numerical register names may be used.
-       ACCEPT_LIST_NAMES is true iff the special names PS and SR may be
-       accepted.
 
    out: An expressionS structure in expressionP.
        The operand may have been a register: in this case, X_op == O_register,
@@ -759,8 +967,7 @@ register_name (expressionS *expressionP)
 
 static bfd_boolean
 system_register_name (expressionS *expressionP,
-                     bfd_boolean accept_numbers,
-                     bfd_boolean accept_list_names)
+                     bfd_boolean accept_numbers)
 {
   int reg_number;
   char *name;
@@ -785,44 +992,28 @@ system_register_name (expressionS *expressionP,
 
       if (ISDIGIT (*input_line_pointer))
        {
-         reg_number = strtol (input_line_pointer, &input_line_pointer, 10);
-
-         /* Make sure that the register number is allowable.  */
-         if (reg_number < 0
-             || (reg_number > 5 && reg_number < 16)
-             || reg_number > 27)
-           reg_number = -1;
-       }
-      else if (accept_list_names)
-       {
-         c = get_symbol_end ();
-         reg_number = reg_name_search (system_list_registers,
-                                       SYSREGLIST_NAME_CNT, name, FALSE);
-
-         /* Put back the delimiting char.  */
-         *input_line_pointer = c;
+         reg_number = strtol (input_line_pointer, &input_line_pointer, 0);
        }
     }
 
+  expressionP->X_add_symbol = NULL;
+  expressionP->X_op_symbol  = NULL;
+
   /* Look to see if it's in the register table.  */
   if (reg_number >= 0)
     {
       expressionP->X_op                = O_register;
       expressionP->X_add_number = reg_number;
 
-      /* Make the rest nice.  */
-      expressionP->X_add_symbol = NULL;
-      expressionP->X_op_symbol  = NULL;
-
       return TRUE;
     }
-  else
-    {
-      /* Reset the line as if we had not done anything.  */
-      input_line_pointer = start;
 
-      return FALSE;
-    }
+  /* Reset the line as if we had not done anything.  */
+  input_line_pointer = start;
+
+  expressionP->X_op = O_illegal;
+
+  return FALSE;
 }
 
 /* Summary of cc_name().
@@ -836,7 +1027,8 @@ system_register_name (expressionS *expressionP,
        its original state.  */
 
 static bfd_boolean
-cc_name (expressionS *expressionP)
+cc_name (expressionS *expressionP,
+        bfd_boolean accept_numbers)
 {
   int reg_number;
   char *name;
@@ -847,30 +1039,93 @@ cc_name (expressionS *expressionP)
   start = name = input_line_pointer;
 
   c = get_symbol_end ();
-  reg_number = reg_name_search (cc_names, CC_NAME_CNT, name, FALSE);
+  reg_number = reg_name_search (cc_names, CC_NAME_CNT, name, accept_numbers);
 
   /* Put back the delimiting char.  */
   *input_line_pointer = c;
 
+  if (reg_number < 0
+      && accept_numbers)
+    {
+      /* Reset input_line pointer.  */
+      input_line_pointer = start;
+
+      if (ISDIGIT (*input_line_pointer))
+       {
+         reg_number = strtol (input_line_pointer, &input_line_pointer, 0);
+       }
+    }
+
+  expressionP->X_add_symbol = NULL;
+  expressionP->X_op_symbol  = NULL;
+
   /* Look to see if it's in the register table.  */
   if (reg_number >= 0)
     {
       expressionP->X_op                = O_constant;
       expressionP->X_add_number = reg_number;
 
-      /* Make the rest nice.  */
-      expressionP->X_add_symbol = NULL;
-      expressionP->X_op_symbol  = NULL;
-
       return TRUE;
     }
-  else
+
+  /* Reset the line as if we had not done anything.  */
+  input_line_pointer = start;
+
+  expressionP->X_op = O_illegal;
+  expressionP->X_add_number = 0;
+
+  return FALSE;
+}
+
+static bfd_boolean
+float_cc_name (expressionS *expressionP,
+              bfd_boolean accept_numbers)
+{
+  int reg_number;
+  char *name;
+  char *start;
+  char c;
+
+  /* Find the spelling of the operand.  */
+  start = name = input_line_pointer;
+
+  c = get_symbol_end ();
+  reg_number = reg_name_search (float_cc_names, FLOAT_CC_NAME_CNT, name, accept_numbers);
+
+  /* Put back the delimiting char.  */
+  *input_line_pointer = c;
+
+  if (reg_number < 0
+      && accept_numbers)
     {
-      /* Reset the line as if we had not done anything.  */
+      /* Reset input_line pointer.  */
       input_line_pointer = start;
 
-      return FALSE;
+      if (ISDIGIT (*input_line_pointer))
+       {
+         reg_number = strtol (input_line_pointer, &input_line_pointer, 0);
+       }
+    }
+
+  expressionP->X_add_symbol = NULL;
+  expressionP->X_op_symbol  = NULL;
+
+  /* Look to see if it's in the register table.  */
+  if (reg_number >= 0)
+    {
+      expressionP->X_op                = O_constant;
+      expressionP->X_add_number = reg_number;
+
+      return TRUE;
     }
+
+  /* Reset the line as if we had not done anything.  */
+  input_line_pointer = start;
+
+  expressionP->X_op = O_illegal;
+  expressionP->X_add_number = 0;
+
+  return FALSE;
 }
 
 static void
@@ -915,16 +1170,7 @@ parse_register_list (unsigned long *insn,
     30,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
      0,  0,  0,  0,  0, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24
   };
-  static int type2_regs[32] =
-  {
-    19, 18, 17, 16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-     0,  0,  0,  0, 30, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24
-  };
-  static int type3_regs[32] =
-  {
-     3,  2,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-     0,  0,  0,  0, 14, 15, 13, 12,  7,  6,  5,  4, 11, 10,  9,  8
-  };
+
   int *regs;
   expressionS exp;
 
@@ -932,8 +1178,6 @@ parse_register_list (unsigned long *insn,
   switch (operand->shift)
     {
     case 0xffe00001: regs = type1_regs; break;
-    case 0xfff8000f: regs = type2_regs; break;
-    case 0xfff8001f: regs = type3_regs; break;
     default:
       as_bad (_("unknown operand shift: %x\n"), operand->shift);
       return _("internal failure in parse_register_list");
@@ -967,41 +1211,6 @@ parse_register_list (unsigned long *insn,
                    *insn |= (1 << i);
              }
        }
-      else if (regs == type2_regs)
-       {
-         if (exp.X_add_number & 0xFFFE0000)
-           return _("high bits set in register list expression");
-
-         for (reg = 1; reg < 16; reg++)
-           if (exp.X_add_number & (1 << (reg - 1)))
-             {
-               for (i = 0; i < 32; i++)
-                 if (regs[i] == reg)
-                   *insn |= (1 << i);
-             }
-
-         if (exp.X_add_number & (1 << 15))
-           *insn |= (1 << 3);
-
-         if (exp.X_add_number & (1 << 16))
-           *insn |= (1 << 19);
-       }
-      else /* regs == type3_regs  */
-       {
-         if (exp.X_add_number & 0xFFFE0000)
-           return _("high bits set in register list expression");
-
-         for (reg = 16; reg < 32; reg++)
-           if (exp.X_add_number & (1 << (reg - 16)))
-             {
-               for (i = 0; i < 32; i++)
-                 if (regs[i] == reg)
-                   *insn |= (1 << i);
-             }
-
-         if (exp.X_add_number & (1 << 16))
-           *insn |= (1 << 19);
-       }
 
       return NULL;
     }
@@ -1012,6 +1221,8 @@ parse_register_list (unsigned long *insn,
      new-line) is found.  */
   for (;;)
     {
+      skip_white_space ();
+
       if (register_name (&exp))
        {
          int i;
@@ -1030,25 +1241,15 @@ parse_register_list (unsigned long *insn,
          if (i == 32)
            return _("illegal register included in list");
        }
-      else if (system_register_name (&exp, TRUE, TRUE))
+      else if (system_register_name (&exp, TRUE))
        {
          if (regs == type1_regs)
            {
              return _("system registers cannot be included in list");
            }
-         else if (exp.X_add_number == 5)
-           {
-             if (regs == type2_regs)
-               return _("PSW cannot be included in list");
-             else
-               *insn |= 0x8;
-           }
-         else if (exp.X_add_number < 4)
-           *insn |= 0x80000;
-         else
-           return _("High value system registers cannot be included in list");
        }
-      else if (*input_line_pointer == '}')
+
+      if (*input_line_pointer == '}')
        {
          input_line_pointer++;
          break;
@@ -1071,7 +1272,11 @@ parse_register_list (unsigned long *insn,
          if (! register_name (&exp2))
            {
              return _("second register should follow dash in register list");
-             exp2.X_add_number = exp.X_add_number;
+           }
+
+         if (exp.X_add_number > exp2.X_add_number)
+           {
+             return _("second register should greater tahn first register");
            }
 
          /* Add the rest of the registers in the range.  */
@@ -1093,11 +1298,11 @@ parse_register_list (unsigned long *insn,
              if (i == 32)
                return _("illegal register included in list");
            }
+
+         exp = exp2;
        }
       else
        break;
-
-      skip_white_space ();
     }
 
   return NULL;
@@ -1107,6 +1312,10 @@ const char *md_shortopts = "m:";
 
 struct option md_longopts[] =
 {
+#define OPTION_DISP_SIZE_DEFAULT_22 (OPTION_MD_BASE)
+  {"disp-size-default-22", no_argument, NULL, OPTION_DISP_SIZE_DEFAULT_22},
+#define OPTION_DISP_SIZE_DEFAULT_32 (OPTION_MD_BASE + 1)
+  {"disp-size-default-32", no_argument, NULL, OPTION_DISP_SIZE_DEFAULT_32},
   {NULL, no_argument, NULL, 0}
 };
 
@@ -1121,15 +1330,33 @@ md_show_usage (FILE *stream)
   fprintf (stream, _("  -mv850                    The code is targeted at the v850\n"));
   fprintf (stream, _("  -mv850e                   The code is targeted at the v850e\n"));
   fprintf (stream, _("  -mv850e1                  The code is targeted at the v850e1\n"));
-  fprintf (stream, _("  -mv850any                 The code is generic, despite any processor specific instructions\n"));
+  fprintf (stream, _("  -mv850e2                  The code is targeted at the v850e2\n"));
+  fprintf (stream, _("  -mv850e2v3                The code is targeted at the v850e2v3\n"));
   fprintf (stream, _("  -mrelax                   Enable relaxation\n"));
+  fprintf (stream, _("  --disp-size-default-22    branch displacement with unknown size is 22 bits (default)\n"));
+  fprintf (stream, _("  --disp-size-default-32    branch displacement with unknown size is 32 bits\n"));
+  fprintf (stream, _("  -mextension               enable extension opcode support\n"));
+  fprintf (stream, _("  -mno-bcond17             disable b<cond> disp17 instruction\n"));
+  fprintf (stream, _("  -mno-stld23              disable st/ld offset23 instruction\n"));
 }
 
 int
 md_parse_option (int c, char *arg)
 {
   if (c != 'm')
-    return 0;
+    {
+      switch (c)
+        {
+        case OPTION_DISP_SIZE_DEFAULT_22:
+          default_disp_size = 22;
+          return 1;
+
+        case OPTION_DISP_SIZE_DEFAULT_32:
+          default_disp_size = 32;
+          return 1;
+        }
+      return 0;
+    }
 
   if (strcmp (arg, "warn-signed-overflow") == 0)
     warn_signed_overflows = TRUE;
@@ -1140,26 +1367,39 @@ md_parse_option (int c, char *arg)
   else if (strcmp (arg, "v850") == 0)
     {
       machine = 0;
-      processor_mask = PROCESSOR_V850;
+      SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850);
     }
   else if (strcmp (arg, "v850e") == 0)
     {
       machine = bfd_mach_v850e;
-      processor_mask = PROCESSOR_V850E;
+      SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E);
     }
   else if (strcmp (arg, "v850e1") == 0)
     {
       machine = bfd_mach_v850e1;
-      processor_mask = PROCESSOR_V850E1;
+      SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E1);
     }
-  else if (strcmp (arg, "v850any") == 0)
+  else if (strcmp (arg, "v850e2") == 0)
     {
-      /* Tell the world that this is for any v850 chip.  */
-      machine = 0;
-
-      /* But support instructions for the extended versions.  */
-      processor_mask = PROCESSOR_V850E;
-      processor_mask |= PROCESSOR_V850E1;
+      machine = bfd_mach_v850e2;
+      SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E2);
+    }
+  else if (strcmp (arg, "v850e2v3") == 0)
+    {
+      machine = bfd_mach_v850e2v3;
+      SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E2V3);
+    }
+  else if (strcmp (arg, "extension") == 0)
+    {
+      processor_mask |= PROCESSOR_OPTION_EXTENSION | PROCESSOR_OPTION_ALIAS;;
+    }
+  else if (strcmp (arg, "no-bcond17") == 0)
+    {
+      no_bcond17 = 1;
+    }
+  else if (strcmp (arg, "no-stld23") == 0)
+    {
+      no_stld23 = 1;
     }
   else if (strcmp (arg, "relax") == 0)
     v850_relax = 1;
@@ -1188,13 +1428,6 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
                 asection *sec,
                 fragS *fragP)
 {
-  /* This code performs some nasty type punning between the
-     fr_opcode field of the frag structure (a char *) and the
-     fx_r_type field of the fix structure (a bfd_reloc_code_real_type)
-     On a 64bit host this causes problems because these two fields
-     are not the same size, but since we know that we are only
-     ever storing small integers in the fields, it is safe to use
-     a union to convert between them.  */
   union u
   {
     bfd_reloc_code_real_type fx_r_type;
@@ -1204,17 +1437,52 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
   subseg_change (sec, 0);
 
   opcode_converter.fr_opcode = fragP->fr_opcode;
-      
+
+  subseg_change (sec, 0);
+
   /* In range conditional or unconditional branch.  */
-  if (fragP->fr_subtype == 0 || fragP->fr_subtype == 2)
+  if (fragP->fr_subtype == SUBYPTE_COND_9_22
+      || fragP->fr_subtype == SUBYPTE_UNCOND_9_22
+      || fragP->fr_subtype == SUBYPTE_COND_9_22_32
+      || fragP->fr_subtype == SUBYPTE_UNCOND_9_22_32
+      || fragP->fr_subtype == SUBYPTE_COND_9_17_22
+      || fragP->fr_subtype == SUBYPTE_COND_9_17_22_32
+      || fragP->fr_subtype == SUBYPTE_SA_9_22
+      || fragP->fr_subtype == SUBYPTE_SA_9_22_32
+      || fragP->fr_subtype == SUBYPTE_SA_9_17_22
+      || fragP->fr_subtype == SUBYPTE_SA_9_17_22_32)
+
     {
       fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
               fragP->fr_offset, 1,
               BFD_RELOC_UNUSED + opcode_converter.fx_r_type);
       fragP->fr_fix += 2;
     }
-  /* Out of range conditional branch.  Emit a branch around a jump.  */
-  else if (fragP->fr_subtype == 1)
+  /* V850e2r-v3 17bit conditional branch.  */
+  else if (fragP->fr_subtype == SUBYPTE_COND_9_17_22 + 1
+          || fragP->fr_subtype == SUBYPTE_COND_9_17_22_32 + 1
+          || fragP->fr_subtype == SUBYPTE_SA_9_17_22 + 1
+          || fragP->fr_subtype == SUBYPTE_SA_9_17_22_32 + 1)
+    {
+      unsigned char *buffer =
+       (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
+
+      buffer[0] &= 0x0f;       /* Use condition.  */
+      buffer[0] |= 0xe0;
+      buffer[1] = 0x07;
+
+      /* Now create the unconditional branch + fixup to the final
+        target.  */
+      md_number_to_chars ((char *) buffer + 2, 0x0001, 2);
+      fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol,
+              fragP->fr_offset, 1, BFD_RELOC_V850_17_PCREL);
+      fragP->fr_fix += 4;
+    }
+  /* Out of range conditional branch.  Emit a branch around a 22bit jump.  */
+  else if (fragP->fr_subtype == SUBYPTE_COND_9_22 + 1
+          || fragP->fr_subtype == SUBYPTE_COND_9_22_32 + 1
+          || fragP->fr_subtype == SUBYPTE_COND_9_17_22 + 2 
+          || fragP->fr_subtype == SUBYPTE_COND_9_17_22_32 + 2)
     {
       unsigned char *buffer =
        (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
@@ -1232,19 +1500,99 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
         target.  */
       md_number_to_chars ((char *) buffer + 2, 0x00000780, 4);
       fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
-              fragP->fr_offset, 1,
-              BFD_RELOC_UNUSED + opcode_converter.fx_r_type + 1);
+              fragP->fr_offset, 1, BFD_RELOC_V850_22_PCREL);
       fragP->fr_fix += 6;
     }
-  /* Out of range unconditional branch.  Emit a jump.  */
-  else if (fragP->fr_subtype == 3)
+  /* Out of range conditional branch.  Emit a branch around a 32bit jump.  */
+  else if (fragP->fr_subtype == SUBYPTE_COND_9_22_32 + 2
+          || fragP->fr_subtype == SUBYPTE_COND_9_17_22_32 + 3)
+    {
+      unsigned char *buffer =
+       (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
+
+      /* Reverse the condition of the first branch.  */
+      buffer[0] ^= 0x08;
+      /* Mask off all the displacement bits.  */
+      buffer[0] &= 0x8f;
+      buffer[1] &= 0x07;
+      /* Now set the displacement bits so that we branch
+        around the unconditional branch.  */
+      buffer[0] |= 0x40;
+
+      /* Now create the unconditional branch + fixup to the final
+        target.  */
+      md_number_to_chars ((char *) buffer + 2, 0x02e0, 2);
+      fix_new (fragP, fragP->fr_fix + 4, 4, fragP->fr_symbol,
+              fragP->fr_offset + 2, 1, BFD_RELOC_V850_32_PCREL);
+      fragP->fr_fix += 8;
+    }
+  /* Out of range unconditional branch.  Emit a 22bit jump.  */
+  else if (fragP->fr_subtype == SUBYPTE_UNCOND_9_22 + 1
+          || fragP->fr_subtype == SUBYPTE_UNCOND_9_22_32 + 1)
     {
       md_number_to_chars (fragP->fr_fix + fragP->fr_literal, 0x00000780, 4);
       fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol,
-              fragP->fr_offset, 1,
-              BFD_RELOC_UNUSED + opcode_converter.fx_r_type + 1);
+              fragP->fr_offset, 1, BFD_RELOC_V850_22_PCREL);
       fragP->fr_fix += 4;
     }
+  /* Out of range unconditional branch.  Emit a 32bit jump.  */
+  else if (fragP->fr_subtype == SUBYPTE_UNCOND_9_22_32 + 2)
+    {
+      md_number_to_chars (fragP->fr_fix + fragP->fr_literal, 0x02e0, 2);
+      fix_new (fragP, fragP->fr_fix + 4, 4, fragP->fr_symbol,
+              fragP->fr_offset + 2, 1, BFD_RELOC_V850_32_PCREL);
+      fragP->fr_fix += 6;
+    }
+  /* Out of range SA conditional branch.  Emit a branch to a 22bit jump.  */
+  else if (fragP->fr_subtype == SUBYPTE_SA_9_22 + 1
+          || fragP->fr_subtype == SUBYPTE_SA_9_22_32 + 1
+          || fragP->fr_subtype == SUBYPTE_SA_9_17_22 + 2
+          || fragP->fr_subtype == SUBYPTE_SA_9_17_22_32 + 2)
+    {
+      unsigned char *buffer =
+       (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
+
+      /* bsa .+4 */
+      buffer[0] &= 0x8f;
+      buffer[0] |= 0x20;
+      buffer[1] &= 0x07;
+
+      /* br .+6 */
+      md_number_to_chars ((char *) buffer + 2, 0x05b5, 2);
+
+      /* Now create the unconditional branch + fixup to the final
+        target.  */
+      /* jr SYM */
+      md_number_to_chars ((char *) buffer + 4, 0x00000780, 4);
+      fix_new (fragP, fragP->fr_fix + 4, 4, fragP->fr_symbol,
+              fragP->fr_offset, 1,
+              BFD_RELOC_V850_22_PCREL);
+      fragP->fr_fix += 8;
+    }
+  /* Out of range SA conditional branch.  Emit a branch around a 32bit jump.  */
+  else if (fragP->fr_subtype == SUBYPTE_SA_9_22_32 + 2
+          || fragP->fr_subtype == SUBYPTE_SA_9_17_22_32 + 3)
+    {
+      unsigned char *buffer =
+       (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
+
+      /* bsa .+2 */
+      buffer[0] &= 0x8f;
+      buffer[0] |= 0x20;
+      buffer[1] &= 0x07;
+
+      /* br .+8 */
+      md_number_to_chars ((char *) buffer + 2, 0x05c5, 2);
+
+      /* Now create the unconditional branch + fixup to the final
+        target.  */
+      /* jr SYM */
+      md_number_to_chars ((char *) buffer + 4, 0x02e0, 2);
+      fix_new (fragP, fragP->fr_fix + 6, 4, fragP->fr_symbol,
+              fragP->fr_offset + 2, 1, BFD_RELOC_V850_32_PCREL);
+
+      fragP->fr_fix += 10;
+    }
   else
     abort ();
 }
@@ -1262,29 +1610,45 @@ md_begin (void)
   char *prev_name = "";
   const struct v850_opcode *op;
 
-  if (strncmp (TARGET_CPU, "v850e1", 6) == 0)
+  if (strncmp (TARGET_CPU, "v850e2v3", 8) == 0)
+    {
+      if (machine == -1)
+        machine = bfd_mach_v850e2v3;
+
+      if (!processor_mask)
+        SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E2V3);
+    }
+  else if (strncmp (TARGET_CPU, "v850e2", 6) == 0)
+    {
+      if (machine == -1)
+       machine = bfd_mach_v850e2;
+
+      if (!processor_mask)
+       SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E2);
+    }
+  else if (strncmp (TARGET_CPU, "v850e1", 6) == 0)
     {
       if (machine == -1)
-       machine = bfd_mach_v850e1;
+        machine = bfd_mach_v850e1;
 
-      if (processor_mask == -1)
-       processor_mask = PROCESSOR_V850E1;
+      if (!processor_mask)
+        SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E1);
     }
   else if (strncmp (TARGET_CPU, "v850e", 5) == 0)
     {
       if (machine == -1)
        machine = bfd_mach_v850e;
 
-      if (processor_mask == -1)
-       processor_mask = PROCESSOR_V850E;
+      if (!processor_mask)
+       SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E);
     }
   else if (strncmp (TARGET_CPU, "v850", 4) == 0)
     {
       if (machine == -1)
        machine = 0;
 
-      if (processor_mask == -1)
-       processor_mask = PROCESSOR_V850;
+      if (!processor_mask)
+       SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850);
     }
   else
     /* xgettext:c-format  */
@@ -1312,152 +1676,192 @@ md_begin (void)
   bfd_set_arch_mach (stdoutput, TARGET_ARCH, machine);
 }
 
+
 static bfd_reloc_code_real_type
-handle_lo16 (const struct v850_operand *operand)
+handle_hi016 (const struct v850_operand *operand, const char **errmsg)
 {
-  if (operand != NULL)
-    {
-      if (operand->bits == -1)
-       return BFD_RELOC_V850_LO16_SPLIT_OFFSET;
+  if (operand == NULL)
+    return BFD_RELOC_HI16;
 
-      if (!(operand->bits == 16 && operand->shift == 16)
-         && !(operand->bits == 15 && operand->shift == 17))
-       {
-         as_bad (_("lo() relocation used on an instruction which does "
-                   "not support it"));
-         return BFD_RELOC_64;  /* Used to indicate an error condition.  */
-       }
-    }
-  return BFD_RELOC_LO16;
+  if (operand->default_reloc == BFD_RELOC_HI16)
+    return BFD_RELOC_HI16;
+
+  if (operand->default_reloc == BFD_RELOC_HI16_S)
+    return BFD_RELOC_HI16;
+
+  if (operand->default_reloc == BFD_RELOC_16)
+    return BFD_RELOC_HI16;
+
+  *errmsg = _("hi0() relocation used on an instruction which does "
+             "not support it");
+  return BFD_RELOC_64;  /* Used to indicate an error condition.  */
 }
 
 static bfd_reloc_code_real_type
-handle_ctoff (const struct v850_operand *operand)
+handle_hi16 (const struct v850_operand *operand, const char **errmsg)
 {
   if (operand == NULL)
-    return BFD_RELOC_V850_CALLT_16_16_OFFSET;
+    return BFD_RELOC_HI16_S;
 
-  if (operand->bits != 6
-      || operand->shift != 0)
-    {
-      as_bad (_("ctoff() relocation used on an instruction which does not support it"));
-      return BFD_RELOC_64;  /* Used to indicate an error condition.  */
-    }
+  if (operand->default_reloc == BFD_RELOC_HI16_S)
+    return BFD_RELOC_HI16_S;
+
+  if (operand->default_reloc == BFD_RELOC_HI16)
+    return BFD_RELOC_HI16_S;
+
+  if (operand->default_reloc == BFD_RELOC_16)
+    return BFD_RELOC_HI16_S;
 
-  return BFD_RELOC_V850_CALLT_6_7_OFFSET;
+  *errmsg = _("hi() relocation used on an instruction which does "
+             "not support it");
+  return BFD_RELOC_64;  /* Used to indicate an error condition.  */
 }
 
 static bfd_reloc_code_real_type
-handle_sdaoff (const struct v850_operand *operand)
+handle_lo16 (const struct v850_operand *operand, const char **errmsg)
 {
   if (operand == NULL)
-    return BFD_RELOC_V850_SDA_16_16_OFFSET;
+    return BFD_RELOC_LO16;
 
-  if (operand->bits == 15 && operand->shift == 17)
-    return BFD_RELOC_V850_SDA_15_16_OFFSET;
+  if (operand->default_reloc == BFD_RELOC_LO16)
+    return BFD_RELOC_LO16;
 
-  if (operand->bits == -1)
-    return BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET;
+  if (operand->default_reloc == BFD_RELOC_V850_16_SPLIT_OFFSET)
+    return BFD_RELOC_V850_LO16_SPLIT_OFFSET;
 
-  if (operand->bits != 16
-      || operand->shift != 16)
-    {
-      as_bad (_("sdaoff() relocation used on an instruction which does not support it"));
-      return BFD_RELOC_64;  /* Used to indicate an error condition.  */
-    }
+  if (operand->default_reloc == BFD_RELOC_V850_16_S1)
+    return BFD_RELOC_V850_LO16_S1;
+
+  if (operand->default_reloc == BFD_RELOC_16)
+    return BFD_RELOC_LO16;
 
-  return BFD_RELOC_V850_SDA_16_16_OFFSET;
+  *errmsg = _("lo() relocation used on an instruction which does "
+             "not support it");
+  return BFD_RELOC_64;  /* Used to indicate an error condition.  */
 }
 
 static bfd_reloc_code_real_type
-handle_zdaoff (const struct v850_operand *operand)
+handle_ctoff (const struct v850_operand *operand, const char **errmsg)
 {
   if (operand == NULL)
-    return BFD_RELOC_V850_ZDA_16_16_OFFSET;
+    return BFD_RELOC_V850_CALLT_16_16_OFFSET;
 
-  if (operand->bits == 15 && operand->shift == 17)
-    return BFD_RELOC_V850_ZDA_15_16_OFFSET;
+  if (operand->default_reloc == BFD_RELOC_V850_CALLT_6_7_OFFSET)
+    return operand->default_reloc;
 
-  if (operand->bits == -1)
-    return BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET;
+  if (operand->default_reloc == BFD_RELOC_V850_16_S1)
+    return BFD_RELOC_V850_CALLT_15_16_OFFSET;
 
-  if (operand->bits != 16
-      || operand->shift != 16)
-    {
-      as_bad (_("zdaoff() relocation used on an instruction which does not support it"));
-      /* Used to indicate an error condition.  */
-      return BFD_RELOC_64;
-    }
+  if (operand->default_reloc == BFD_RELOC_16)
+    return BFD_RELOC_V850_CALLT_16_16_OFFSET;
 
-  return BFD_RELOC_V850_ZDA_16_16_OFFSET;
+  *errmsg = _("ctoff() relocation used on an instruction which does not support it");
+  return BFD_RELOC_64;  /* Used to indicate an error condition.  */
 }
 
 static bfd_reloc_code_real_type
-handle_tdaoff (const struct v850_operand *operand)
+handle_sdaoff (const struct v850_operand *operand, const char **errmsg)
 {
   if (operand == NULL)
-    /* Data item, not an instruction.  */
-    return BFD_RELOC_V850_TDA_7_7_OFFSET;
-
-  if (operand->bits == 6 && operand->shift == 1)
-    /* sld.w/sst.w, operand: D8_6.  */
-    return BFD_RELOC_V850_TDA_6_8_OFFSET;
-
-  if (operand->bits == 4 && operand->insert != NULL)
-    /* sld.hu, operand: D5-4.  */
-    return BFD_RELOC_V850_TDA_4_5_OFFSET;
+    return BFD_RELOC_V850_SDA_16_16_OFFSET;
 
-  if (operand->bits == 4 && operand->insert == NULL)
-    /* sld.bu, operand: D4.   */
-    return BFD_RELOC_V850_TDA_4_4_OFFSET;
+  if (operand->default_reloc == BFD_RELOC_V850_16_SPLIT_OFFSET)
+    return BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET;
 
-  if (operand->bits == 16 && operand->shift == 16)
-    /* set1 & chums, operands: D16.  */
-    return BFD_RELOC_V850_TDA_16_16_OFFSET;
+  if (operand->default_reloc == BFD_RELOC_16)
+    return BFD_RELOC_V850_SDA_16_16_OFFSET;
 
-  if (operand->bits != 7)
-    {
-      as_bad (_("tdaoff() relocation used on an instruction which does not support it"));
-      /* Used to indicate an error condition.  */
-      return BFD_RELOC_64;
-    }
+  if (operand->default_reloc == BFD_RELOC_V850_16_S1)
+    return BFD_RELOC_V850_SDA_15_16_OFFSET;
 
-  return  operand->insert != NULL
-    ? BFD_RELOC_V850_TDA_7_8_OFFSET     /* sld.h/sst.h, operand: D8_7.  */
-    : BFD_RELOC_V850_TDA_7_7_OFFSET;    /* sld.b/sst.b, operand: D7.    */
+  *errmsg = _("sdaoff() relocation used on an instruction which does not support it");
+  return BFD_RELOC_64;  /* Used to indicate an error condition.  */
 }
 
-/* Warning: The code in this function relies upon the definitions
-   in the v850_operands[] array (defined in opcodes/v850-opc.c)
-   matching the hard coded values contained herein.  */
-
 static bfd_reloc_code_real_type
-v850_reloc_prefix (const struct v850_operand *operand)
+handle_zdaoff (const struct v850_operand *operand, const char **errmsg)
 {
-  bfd_boolean paren_skipped = FALSE;
+  if (operand == NULL)
+    return BFD_RELOC_V850_ZDA_16_16_OFFSET;
 
-  /* Skip leading opening parenthesis.  */
-  if (*input_line_pointer == '(')
-    {
-      ++input_line_pointer;
-      paren_skipped = TRUE;
-    }
+  if (operand->default_reloc == BFD_RELOC_V850_16_SPLIT_OFFSET)
+    return BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET;
 
-#define CHECK_(name, reloc)                                            \
+  if (operand->default_reloc == BFD_RELOC_16)
+    return BFD_RELOC_V850_ZDA_16_16_OFFSET;
+
+  if (operand->default_reloc == BFD_RELOC_V850_16_S1)
+    return BFD_RELOC_V850_ZDA_15_16_OFFSET;
+
+  *errmsg = _("zdaoff() relocation used on an instruction which does not support it");
+  return BFD_RELOC_64;  /* Used to indicate an error condition.  */
+}
+
+static bfd_reloc_code_real_type
+handle_tdaoff (const struct v850_operand *operand, const char **errmsg)
+{
+  if (operand == NULL)
+    /* Data item, not an instruction.  */
+    return BFD_RELOC_V850_TDA_16_16_OFFSET;
+
+  switch (operand->default_reloc)
+    {
+      /* sld.hu, operand: D5-4.  */
+    case BFD_RELOC_V850_TDA_4_5_OFFSET:
+      /* sld.bu, operand: D4.  */
+    case BFD_RELOC_V850_TDA_4_4_OFFSET:
+    /* sld.w/sst.w, operand: D8_6.  */
+    case BFD_RELOC_V850_TDA_6_8_OFFSET:
+    /* sld.h/sst.h, operand: D8_7.  */
+    case BFD_RELOC_V850_TDA_7_8_OFFSET:
+      /* sld.b/sst.b, operand: D7.  */
+    case BFD_RELOC_V850_TDA_7_7_OFFSET:
+      return operand->default_reloc;
+    default:
+      break;
+    }
+
+  if (operand->default_reloc == BFD_RELOC_16 && operand->shift == 16)
+    /* set1 & chums, operands: D16.  */
+    return BFD_RELOC_V850_TDA_16_16_OFFSET;
+
+  *errmsg = _("tdaoff() relocation used on an instruction which does not support it");
+  /* Used to indicate an error condition.  */
+  return BFD_RELOC_64;
+}
+
+/* Warning: The code in this function relies upon the definitions
+   in the v850_operands[] array (defined in opcodes/v850-opc.c)
+   matching the hard coded values contained herein.  */
+
+static bfd_reloc_code_real_type
+v850_reloc_prefix (const struct v850_operand *operand, const char **errmsg)
+{
+  bfd_boolean paren_skipped = FALSE;
+
+  /* Skip leading opening parenthesis.  */
+  if (*input_line_pointer == '(')
+    {
+      ++input_line_pointer;
+      paren_skipped = TRUE;
+    }
+
+#define CHECK_(name, reloc)                                            \
   if (strncmp (input_line_pointer, name "(", strlen (name) + 1) == 0)  \
     {                                                                  \
       input_line_pointer += strlen (name);                             \
       return reloc;                                                    \
     }
 
-  CHECK_ ("hi0",    BFD_RELOC_HI16        );
-  CHECK_ ("hi",            BFD_RELOC_HI16_S       );
-  CHECK_ ("lo",            handle_lo16 (operand)  );
-  CHECK_ ("sdaoff", handle_sdaoff (operand));
-  CHECK_ ("zdaoff", handle_zdaoff (operand));
-  CHECK_ ("tdaoff", handle_tdaoff (operand));
-  CHECK_ ("hilo",   BFD_RELOC_32          );
-  CHECK_ ("ctoff",  handle_ctoff (operand) );
+  CHECK_ ("hi0",    handle_hi016(operand, errmsg)  );
+  CHECK_ ("hi",            handle_hi16(operand, errmsg)   );
+  CHECK_ ("lo",            handle_lo16 (operand, errmsg)  );
+  CHECK_ ("sdaoff", handle_sdaoff (operand, errmsg));
+  CHECK_ ("zdaoff", handle_zdaoff (operand, errmsg));
+  CHECK_ ("tdaoff", handle_tdaoff (operand, errmsg));
+  CHECK_ ("hilo",   BFD_RELOC_32);
+  CHECK_ ("lo23",   BFD_RELOC_V850_23);
+  CHECK_ ("ctoff",  handle_ctoff (operand, errmsg) );
 
   /* Restore skipped parenthesis.  */
   if (paren_skipped)
@@ -1472,9 +1876,7 @@ static unsigned long
 v850_insert_operand (unsigned long insn,
                     const struct v850_operand *operand,
                     offsetT val,
-                    char *file,
-                    unsigned int line,
-                    char *str)
+                    const char **errmsg)
 {
   if (operand->insert)
     {
@@ -1485,35 +1887,33 @@ v850_insert_operand (unsigned long insn,
        {
          if ((operand->flags & V850_OPERAND_SIGNED)
              && ! warn_signed_overflows
-             && strstr (message, "out of range") != NULL)
+              && v850_msg_is_out_of_range (message))
            {
              /* Skip warning...  */
            }
          else if ((operand->flags & V850_OPERAND_SIGNED) == 0
                   && ! warn_unsigned_overflows
-                  && strstr (message, "out of range") != NULL)
+                  && v850_msg_is_out_of_range (message))
            {
              /* Skip warning...  */
            }
-         else if (str)
-           {
-             if (file == (char *) NULL)
-               as_warn ("%s: %s", str, message);
-             else
-               as_warn_where (file, line, "%s: %s", str, message);
-           }
          else
            {
-             if (file == (char *) NULL)
-               as_warn ("%s", message);
-             else
-               as_warn_where (file, line, "%s", message);
+             if (errmsg != NULL)
+               *errmsg = message;
            }
        }
     }
+  else if (operand->bits == -1
+          || operand->flags & V850E_IMMEDIATE16
+          || operand->flags & V850E_IMMEDIATE23
+          || operand->flags & V850E_IMMEDIATE32)
+    {
+      abort ();
+    }
   else
     {
-      if (operand->bits != 32)
+      if (operand->bits < 32)
        {
          long min, max;
 
@@ -1566,17 +1966,17 @@ v850_insert_operand (unsigned long insn,
                  && ! warn_unsigned_overflows)
                min = 0;
 
-             if (str)
-               sprintf (buf, "%s: ", str);
-             else
-               buf[0] = 0;
-             strcat (buf, _("operand"));
-
-             as_bad_value_out_of_range (buf, val, (offsetT) min, (offsetT) max, file, line);
+             sprintf (buf, _("operand out of range (%d is not between %d and %d)"),
+                      (int) val, (int) min, (int) max);
+             *errmsg = buf;
            }
-       }
 
-      insn |= (((long) val & ((1 << operand->bits) - 1)) << operand->shift);
+         insn |= (((long) val & ((1 << operand->bits) - 1)) << operand->shift);
+       }
+      else
+       {
+         insn |= (((long) val) << operand->shift);
+       }
     }
 
   return insn;
@@ -1603,8 +2003,11 @@ md_assemble (char *str)
   unsigned extra_data_len = 0;
   unsigned long extra_data = 0;
   char *saved_input_line_pointer;
+  char most_match_errmsg[1024];
+  int most_match_count = -1;
 
   strncpy (copy_of_instruction, str, sizeof (copy_of_instruction) - 1);
+  most_match_errmsg[0] = 0;
 
   /* Get the opcode.  */
   for (s = str; *s != '\0' && ! ISSPACE (*s); s++)
@@ -1634,10 +2037,26 @@ md_assemble (char *str)
   for (;;)
     {
       const char *errmsg = NULL;
+      const char *warningmsg = NULL;
 
       match = 0;
+      opindex_ptr = opcode->operands;
 
-      if ((opcode->processors & processor_mask) == 0)
+      if (no_stld23)
+       {
+         if ((strncmp (opcode->name, "st.", 3) == 0
+              && v850_operands[opcode->operands[1]].bits == 23)
+             || (strncmp (opcode->name, "ld.", 3) == 0
+                 && v850_operands[opcode->operands[0]].bits == 23))
+           {
+             errmsg = _("st/ld offset 23 instruction was disabled .");
+             goto error;
+           }
+       }
+
+      if ((opcode->processors & processor_mask & PROCESSOR_MASK) == 0
+         || (((opcode->processors & ~PROCESSOR_MASK) != 0)
+             && ((opcode->processors & processor_mask & ~PROCESSOR_MASK) == 0)))
        {
          errmsg = _("Target processor does not support this instruction.");
          goto error;
@@ -1647,6 +2066,7 @@ md_assemble (char *str)
       fc = 0;
       next_opindex = 0;
       insn = opcode->opcode;
+      extra_data_len = 0;
       extra_data_after_insn = FALSE;
 
       input_line_pointer = str = start_of_operands;
@@ -1668,7 +2088,20 @@ md_assemble (char *str)
 
          errmsg = NULL;
 
-         while (*str == ' ' || *str == ',' || *str == '[' || *str == ']')
+         while (*str == ' ')
+           ++str;
+
+         if (operand->flags & V850_OPERAND_BANG
+             && *str == '!')
+           ++str;
+         else if (operand->flags & V850_OPERAND_PERCENT
+                  && *str == '%')
+           ++str;
+
+         if (*str == ',' || *str == '[' || *str == ']')
+           ++str;
+
+         while (*str == ' ')
            ++str;
 
          if (operand->flags & V850_OPERAND_RELAX)
@@ -1679,12 +2112,12 @@ md_assemble (char *str)
          input_line_pointer = str;
 
          /* lo(), hi(), hi0(), etc...  */
-         if ((reloc = v850_reloc_prefix (operand)) != BFD_RELOC_UNUSED)
+         if ((reloc = v850_reloc_prefix (operand, &errmsg)) != BFD_RELOC_UNUSED)
            {
              /* This is a fake reloc, used to indicate an error condition.  */
              if (reloc == BFD_RELOC_64)
                {
-                 match = 1;
+                 /* match = 1;  */
                  goto error;
                }
 
@@ -1695,11 +2128,14 @@ md_assemble (char *str)
                  switch (reloc)
                    {
                    case BFD_RELOC_V850_ZDA_16_16_OFFSET:
+                   case BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET:
+                   case BFD_RELOC_V850_ZDA_15_16_OFFSET:
                      /* To cope with "not1 7, zdaoff(0xfffff006)[r0]"
                         and the like.  */
                      /* Fall through.  */
 
                    case BFD_RELOC_LO16:
+                   case BFD_RELOC_V850_LO16_S1:
                    case BFD_RELOC_V850_LO16_SPLIT_OFFSET:
                      {
                        /* Truncate, then sign extend the value.  */
@@ -1725,16 +2161,23 @@ md_assemble (char *str)
                        break;
                      }
 
+                   case BFD_RELOC_V850_23:
+                     if ((operand->flags & V850E_IMMEDIATE23) == 0)
+                       {
+                         errmsg = _("immediate operand is too large");
+                         goto error;
+                       }
+                     break;
+
                    case BFD_RELOC_32:
+                   case BFD_RELOC_V850_32_ABS:
+                   case BFD_RELOC_V850_32_PCREL:
                      if ((operand->flags & V850E_IMMEDIATE32) == 0)
                        {
                          errmsg = _("immediate operand is too large");
                          goto error;
                        }
 
-                     extra_data_after_insn = TRUE;
-                     extra_data_len        = 4;
-                     extra_data            = 0;
                      break;
 
                    default:
@@ -1743,6 +2186,45 @@ md_assemble (char *str)
                      break;
                    }
 
+                 if (operand->flags & V850E_IMMEDIATE32)
+                   {
+                     extra_data_after_insn = TRUE;
+                     extra_data_len        = 4;
+                     extra_data            = 0;
+                   }
+                 else if (operand->flags & V850E_IMMEDIATE23)
+                   {
+                     if (reloc != BFD_RELOC_V850_23)
+                       {
+                         errmsg = _("immediate operand is too large");
+                         goto error;
+                       }
+                     extra_data_after_insn = TRUE;
+                     extra_data_len        = 2;
+                     extra_data            = 0;
+                   }
+                 else if ((operand->flags & V850E_IMMEDIATE16)
+                          || (operand->flags & V850E_IMMEDIATE16HI))
+                   {
+                     if (operand->flags & V850E_IMMEDIATE16HI
+                         && reloc != BFD_RELOC_HI16
+                         && reloc != BFD_RELOC_HI16_S)
+                       {
+                         errmsg = _("immediate operand is too large");
+                         goto error;
+                       }
+                     else if (operand->flags & V850E_IMMEDIATE16
+                              && reloc != BFD_RELOC_LO16)
+                       {
+                         errmsg = _("immediate operand is too large");
+                         goto error;
+                       }
+
+                     extra_data_after_insn = TRUE;
+                     extra_data_len        = 2;
+                     extra_data            = 0;
+                   }
+
                  if (fc > MAX_INSN_FIXUPS)
                    as_fatal (_("too many fixups"));
 
@@ -1751,19 +2233,67 @@ md_assemble (char *str)
                  fixups[fc].reloc   = reloc;
                  fc++;
                }
-             else
+             else      /* ex.X_op != O_constant.  */
                {
-                 if (reloc == BFD_RELOC_32)
+                 if ((reloc == BFD_RELOC_32
+                      || reloc == BFD_RELOC_V850_32_ABS
+                      || reloc == BFD_RELOC_V850_32_PCREL)
+                     && operand->bits < 32)
                    {
-                     if ((operand->flags & V850E_IMMEDIATE32) == 0)
+                     errmsg = _("immediate operand is too large");
+                     goto error;
+                   }
+                 else if (reloc == BFD_RELOC_V850_23
+                          && (operand->flags & V850E_IMMEDIATE23) == 0)
+                   {
+                     errmsg = _("immediate operand is too large");
+                     goto error;
+                   }
+                 else if ((reloc == BFD_RELOC_HI16
+                           || reloc == BFD_RELOC_HI16_S)
+                          && operand->bits < 16)
+                   {
+                     errmsg = _("immediate operand is too large");
+                     goto error;
+                   }
+
+                 if (operand->flags & V850E_IMMEDIATE32)
+                   {
+                     extra_data_after_insn = TRUE;
+                     extra_data_len        = 4;
+                     extra_data            = 0;
+                   }
+                 else if (operand->flags & V850E_IMMEDIATE23)
+                   {
+                     if (reloc != BFD_RELOC_V850_23)
+                       {
+                         errmsg = _("immediate operand is too large");
+                         goto error;
+                       }
+                     extra_data_after_insn = TRUE;
+                     extra_data_len        = 2;
+                     extra_data            = 0;
+                   }
+                 else if ((operand->flags & V850E_IMMEDIATE16)
+                          || (operand->flags & V850E_IMMEDIATE16HI))
+                   {
+                     if (operand->flags & V850E_IMMEDIATE16HI
+                         && reloc != BFD_RELOC_HI16
+                         && reloc != BFD_RELOC_HI16_S)
+                       {
+                         errmsg = _("immediate operand is too large");
+                         goto error;
+                       }
+                     else if (operand->flags & V850E_IMMEDIATE16
+                              && reloc != BFD_RELOC_LO16)
                        {
                          errmsg = _("immediate operand is too large");
                          goto error;
                        }
 
                      extra_data_after_insn = TRUE;
-                     extra_data_len        = 4;
-                     extra_data            = ex.X_add_number;
+                     extra_data_len        = 2;
+                     extra_data            = 0;
                    }
 
                  if (fc > MAX_INSN_FIXUPS)
@@ -1775,6 +2305,140 @@ md_assemble (char *str)
                  fc++;
                }
            }
+         else if (operand->flags & V850E_IMMEDIATE16
+                  || operand->flags & V850E_IMMEDIATE16HI)
+           {
+             expression (&ex);
+
+             switch (ex.X_op)
+               {
+               case O_constant:
+                 if (operand->flags & V850E_IMMEDIATE16HI)
+                   {
+                     if (ex.X_add_number & 0xffff)
+                       {
+                         errmsg = _("constant too big to fit into instruction");
+                         goto error;
+                       }
+
+                     ex.X_add_number >>= 16;
+                   }
+                 if (operand->flags & V850E_IMMEDIATE16)
+                   {
+                     if (ex.X_add_number & 0xffff0000)
+                       {
+                         errmsg = _("constant too big to fit into instruction");
+                         goto error;
+                       }
+                   }
+                 break;
+
+               case O_illegal:
+                 errmsg = _("illegal operand");
+                 goto error;
+
+               case O_absent:
+                 errmsg = _("missing operand");
+                 goto error;
+
+               default:
+                 if (fc >= MAX_INSN_FIXUPS)
+                   as_fatal (_("too many fixups"));
+
+                 fixups[fc].exp     = ex;
+                 fixups[fc].opindex = *opindex_ptr;
+                 fixups[fc].reloc   = operand->default_reloc;
+                 ++fc;
+
+                 ex.X_add_number = 0;
+                 break;
+               }
+
+             extra_data_after_insn = TRUE;
+             extra_data_len        = 2;
+             extra_data            = ex.X_add_number;
+           }
+         else if (operand->flags & V850E_IMMEDIATE23)
+           {
+             expression (&ex);
+
+             switch (ex.X_op)
+               {
+               case O_constant:
+                 break;
+
+               case O_illegal:
+                 errmsg = _("illegal operand");
+                 goto error;
+
+               case O_absent:
+                 errmsg = _("missing operand");
+                 goto error;
+
+               default:
+                 break;
+               }
+
+             if (fc >= MAX_INSN_FIXUPS)
+               as_fatal (_("too many fixups"));
+
+             fixups[fc].exp     = ex;
+             fixups[fc].opindex = *opindex_ptr;
+             fixups[fc].reloc   = operand->default_reloc;
+             ++fc;
+
+             extra_data_after_insn = TRUE;
+             extra_data_len        = 2;
+             extra_data            = 0;
+           }
+         else if (operand->flags & V850E_IMMEDIATE32)
+           {
+             expression (&ex);
+
+             switch (ex.X_op)
+               {
+               case O_constant:
+                 if ((operand->default_reloc == BFD_RELOC_V850_32_ABS
+                      || operand->default_reloc == BFD_RELOC_V850_32_PCREL)
+                     && (ex.X_add_number & 1))
+                   {
+                     errmsg = _("odd number cannot be used here");
+                     goto error;
+                   }
+                 break;
+
+               case O_illegal:
+                 errmsg = _("illegal operand");
+                 goto error;
+
+               case O_absent:
+                 errmsg = _("missing operand");
+                 goto error;
+
+               default:
+                 if (fc >= MAX_INSN_FIXUPS)
+                   as_fatal (_("too many fixups"));
+
+                 fixups[fc].exp     = ex;
+                 fixups[fc].opindex = *opindex_ptr;
+                 fixups[fc].reloc   = operand->default_reloc;
+                 ++fc;
+
+                 ex.X_add_number = 0;
+                 break;
+               }
+
+             extra_data_after_insn = TRUE;
+             extra_data_len        = 4;
+             extra_data            = ex.X_add_number;
+           }
+         else if (operand->flags & V850E_OPERAND_REG_LIST)
+           {
+             errmsg = parse_register_list (&insn, operand);
+
+             if (errmsg)
+               goto error;
+           }
          else
            {
              errmsg = NULL;
@@ -1782,22 +2446,30 @@ md_assemble (char *str)
              if ((operand->flags & V850_OPERAND_REG) != 0)
                {
                  if (!register_name (&ex))
-                   errmsg = _("invalid register name");
-                 else if ((operand->flags & V850_NOT_R0)
+                   {
+                     errmsg = _("invalid register name");
+                   }
+
+                 if ((operand->flags & V850_NOT_R0)
                           && ex.X_add_number == 0)
                    {
                      errmsg = _("register r0 cannot be used here");
+                   }
 
-                     /* Force an error message to be generated by
-                        skipping over any following potential matches
-                        for this opcode.  */
-                     opcode += 3;
+                 if (operand->flags & V850_REG_EVEN)
+                   {
+                     if (ex.X_add_number % 2)
+                       errmsg = _("odd register cannot be used here");
+                     ex.X_add_number = ex.X_add_number / 2;
                    }
+
                }
              else if ((operand->flags & V850_OPERAND_SRG) != 0)
                {
-                 if (!system_register_name (&ex, TRUE, FALSE))
-                   errmsg = _("invalid system register name");
+                 if (!system_register_name (&ex, TRUE))
+                   {
+                     errmsg = _("invalid system register name");
+                   }
                }
              else if ((operand->flags & V850_OPERAND_EP) != 0)
                {
@@ -1824,53 +2496,26 @@ md_assemble (char *str)
                }
              else if ((operand->flags & V850_OPERAND_CC) != 0)
                {
-                 if (!cc_name (&ex))
-                   errmsg = _("invalid condition code name");
-               }
-             else if (operand->flags & V850E_PUSH_POP)
-               {
-                 errmsg = parse_register_list (&insn, operand);
-
-                 /* The parse_register_list() function has already done
-                    everything, so fake a dummy expression.  */
-                 ex.X_op         = O_constant;
-                 ex.X_add_number = 0;
-               }
-             else if (operand->flags & V850E_IMMEDIATE16)
-               {
-                 expression (&ex);
-
-                 if (ex.X_op != O_constant)
-                   errmsg = _("constant expression expected");
-                 else if (ex.X_add_number & 0xffff0000)
+                 if (!cc_name (&ex, TRUE))
                    {
-                     if (ex.X_add_number & 0xffff)
-                       errmsg = _("constant too big to fit into instruction");
-                     else if ((insn & 0x001fffc0) == 0x00130780)
-                       ex.X_add_number >>= 16;
-                     else
-                       errmsg = _("constant too big to fit into instruction");
+                     errmsg = _("invalid condition code name");
                    }
 
-                 extra_data_after_insn = TRUE;
-                 extra_data_len        = 2;
-                 extra_data            = ex.X_add_number;
-                 ex.X_add_number       = 0;
+                 if ((operand->flags & V850_NOT_SA)
+                     && ex.X_add_number == COND_SA_NUM)
+                   {
+                     errmsg = _("condition sa cannot be used here");
+                   }
                }
-             else if (operand->flags & V850E_IMMEDIATE32)
+             else if ((operand->flags & V850_OPERAND_FLOAT_CC) != 0)
                {
-                 expression (&ex);
-
-                 if (ex.X_op != O_constant)
-                   errmsg = _("constant expression expected");
-
-                 extra_data_after_insn = TRUE;
-                 extra_data_len        = 4;
-                 extra_data            = ex.X_add_number;
-                 ex.X_add_number       = 0;
+                 if (!float_cc_name (&ex, TRUE))
+                   {
+                     errmsg = _("invalid condition code name");
+                   }
                }
-             else if (register_name (&ex)
-                      && (operand->flags & V850_OPERAND_REG) == 0)
+             else if ((register_name (&ex)
+                       && (operand->flags & V850_OPERAND_REG) == 0))
                {
                  char c;
                  int exists = 0;
@@ -1900,8 +2545,10 @@ md_assemble (char *str)
                         the parsing of the instruction, (because another
                         field is missing) then report this.  */
                      if (opindex_ptr[1] != 0
-                         && (v850_operands[opindex_ptr[1]].flags
-                             & V850_OPERAND_REG))
+                         && ((v850_operands[opindex_ptr[1]].flags
+                              & V850_OPERAND_REG)
+                             ||(v850_operands[opindex_ptr[1]].flags
+                                & V850_OPERAND_VREG)))
                        errmsg = _("syntax error: value is missing before the register name");
                      else
                        errmsg = _("syntax error: register not expected");
@@ -1915,29 +2562,55 @@ md_assemble (char *str)
                                       &symbol_rootP, &symbol_lastP);
                    }
                }
-             else if (system_register_name (&ex, FALSE, FALSE)
+             else if (system_register_name (&ex, FALSE)
                       && (operand->flags & V850_OPERAND_SRG) == 0)
-               errmsg = _("syntax error: system register not expected");
-
-             else if (cc_name (&ex)
+               {
+                 errmsg = _("syntax error: system register not expected");
+               }
+             else if (cc_name (&ex, FALSE)
                       && (operand->flags & V850_OPERAND_CC) == 0)
-               errmsg = _("syntax error: condition code not expected");
-
+               {
+                 errmsg = _("syntax error: condition code not expected");
+               }
+             else if (float_cc_name (&ex, FALSE)
+                      && (operand->flags & V850_OPERAND_FLOAT_CC) == 0)
+               {
+                 errmsg = _("syntax error: condition code not expected");
+               }
              else
                {
                  expression (&ex);
+
+                 if ((operand->flags & V850_NOT_IMM0)
+                     && ex.X_op == O_constant
+                     && ex.X_add_number == 0)
+                   {
+                     errmsg = _("immediate 0 cannot be used here");
+                   }
+
                  /* Special case:
-                    If we are assembling a MOV instruction and the immediate
+                    If we are assembling a MOV/JARL/JR instruction and the immediate
                     value does not fit into the bits available then create a
-                    fake error so that the next MOV instruction will be
+                    fake error so that the next MOV/JARL/JR instruction will be
                     selected.  This one has a 32 bit immediate field.  */
 
-                 if (((insn & 0x07e0) == 0x0200)
-                     && operand->bits == 5 /* Do not match the CALLT instruction.  */
+                 if ((strcmp (opcode->name, "mov") == 0
+                      || strcmp (opcode->name, "jarl") == 0
+                      || strcmp (opcode->name, "jr") == 0)
                      && ex.X_op == O_constant
                      && (ex.X_add_number < (-(1 << (operand->bits - 1)))
                          || ex.X_add_number > ((1 << (operand->bits - 1)) - 1)))
-                   errmsg = _("immediate operand is too large");
+                   {
+                     errmsg = _("immediate operand is too large");
+                   }
+
+                 if ((strcmp (opcode->name, "jarl") == 0
+                      || strcmp (opcode->name, "jr") == 0)
+                     && ex.X_op != O_constant
+                     && operand->bits != default_disp_size)
+                   {
+                     errmsg = _("immediate operand is not match");
+                   }
                }
 
              if (errmsg)
@@ -1953,18 +2626,21 @@ md_assemble (char *str)
                  goto error;
                case O_register:
                  if ((operand->flags
-                      & (V850_OPERAND_REG | V850_OPERAND_SRG)) == 0)
+                      & (V850_OPERAND_REG | V850_OPERAND_SRG | V850_OPERAND_VREG)) == 0)
                    {
                      errmsg = _("invalid operand");
                      goto error;
                    }
-                 insn = v850_insert_operand (insn, operand, ex.X_add_number,
-                                             NULL, 0, copy_of_instruction);
+
+                 insn = v850_insert_operand (insn, operand,
+                                             ex.X_add_number,
+                                             &warningmsg);
+
                  break;
 
                case O_constant:
                  insn = v850_insert_operand (insn, operand, ex.X_add_number,
-                                             NULL, 0, copy_of_instruction);
+                                             &warningmsg);
                  break;
 
                default:
@@ -1987,11 +2663,23 @@ md_assemble (char *str)
                 || *str == ')')
            ++str;
        }
-      match = 1;
+
+      while (ISSPACE (*str))
+       ++str;
+
+      if (*str == '\0')
+       match = 1;
 
     error:
       if (match == 0)
        {
+         if ((opindex_ptr - opcode->operands) >= most_match_count)
+           {
+             most_match_count = opindex_ptr - opcode->operands;
+             if (errmsg != NULL)
+               strncpy (most_match_errmsg, errmsg, sizeof (most_match_errmsg)-1);
+           }
+
          next_opcode = opcode + 1;
          if (next_opcode->name != NULL
              && strcmp (next_opcode->name, opcode->name) == 0)
@@ -2006,7 +2694,11 @@ md_assemble (char *str)
              continue;
            }
 
-         as_bad ("%s: %s", copy_of_instruction, errmsg);
+         if (most_match_errmsg[0] == 0)
+           /* xgettext:c-format.  */
+           as_bad (_("junk at end of line: `%s'"), str);
+         else
+           as_bad ("%s: %s", copy_of_instruction, most_match_errmsg);
 
          if (*input_line_pointer == ']')
            ++input_line_pointer;
@@ -2015,16 +2707,12 @@ md_assemble (char *str)
          input_line_pointer = saved_input_line_pointer;
          return;
        }
+
+      if (warningmsg != NULL)
+       as_warn (warningmsg);
       break;
     }
 
-  while (ISSPACE (*str))
-    ++str;
-
-  if (*str != '\0')
-    /* xgettext:c-format  */
-    as_bad (_("junk at end of line: `%s'"), str);
-
   input_line_pointer = str;
 
   /* Tie dwarf2 debug info to the address at the start of the insn.
@@ -2036,40 +2724,124 @@ md_assemble (char *str)
 
   if (relaxable && fc > 0)
     {
-      /* On a 64-bit host the size of an 'int' is not the same
-        as the size of a pointer, so we need a union to convert
-        the opindex field of the fr_cgen structure into a char *
-        so that it can be stored in the frag.  We do not have
-        to worry about loosing accuracy as we are not going to
-        be even close to the 32bit limit of the int.  */
-      union
-      {
-       int opindex;
-       char * ptr;
-      }
-      opindex_converter;
-
-      opindex_converter.opindex = fixups[0].opindex;
       insn_size = 2;
       fc = 0;
 
-      if (!strcmp (opcode->name, "br"))
+      if (strcmp (opcode->name, "br") == 0
+         || strcmp (opcode->name, "jbr") == 0)
        {
-         f = frag_var (rs_machine_dependent, 4, 2, 2,
-                       fixups[0].exp.X_add_symbol,
-                       fixups[0].exp.X_add_number,
-                       opindex_converter.ptr);
-         md_number_to_chars (f, insn, insn_size);
-         md_number_to_chars (f + 2, 0, 2);
+         if ((processor_mask & PROCESSOR_V850E2_ALL) == 0 || default_disp_size == 22)
+           {
+             f = frag_var (rs_machine_dependent, 4, 2, SUBYPTE_UNCOND_9_22,
+                           fixups[0].exp.X_add_symbol,
+                           fixups[0].exp.X_add_number,
+                           (char *)(size_t) fixups[0].opindex);
+             md_number_to_chars (f, insn, insn_size);
+             md_number_to_chars (f + 2, 0, 2);
+           }
+         else
+           {
+             f = frag_var (rs_machine_dependent, 6, 4, SUBYPTE_UNCOND_9_22_32,
+                           fixups[0].exp.X_add_symbol,
+                           fixups[0].exp.X_add_number,
+                           (char *)(size_t) fixups[0].opindex);
+             md_number_to_chars (f, insn, insn_size);
+             md_number_to_chars (f + 2, 0, 4);
+           }
        }
-      else
+      else /* b<cond>, j<cond>.  */
        {
-         f = frag_var (rs_machine_dependent, 6, 4, 0,
-                       fixups[0].exp.X_add_symbol,
-                       fixups[0].exp.X_add_number,
-                       opindex_converter.ptr);
-         md_number_to_chars (f, insn, insn_size);
-         md_number_to_chars (f + 2, 0, 4);
+         if (default_disp_size == 22
+             || (processor_mask & PROCESSOR_V850E2_ALL) == 0)
+           {
+             if (processor_mask & PROCESSOR_V850E2V3 && !no_bcond17)
+               {
+                 if (strcmp (opcode->name, "bsa") == 0)
+                   {
+                     f = frag_var (rs_machine_dependent, 8, 6, SUBYPTE_SA_9_17_22,
+                                   fixups[0].exp.X_add_symbol,
+                                   fixups[0].exp.X_add_number,
+                                   (char *)(size_t) fixups[0].opindex);
+                     md_number_to_chars (f, insn, insn_size);
+                     md_number_to_chars (f + 2, 0, 6);
+                   }
+                 else
+                   {
+                     f = frag_var (rs_machine_dependent, 6, 4, SUBYPTE_COND_9_17_22,
+                                   fixups[0].exp.X_add_symbol,
+                                   fixups[0].exp.X_add_number,
+                                   (char *)(size_t) fixups[0].opindex);
+                     md_number_to_chars (f, insn, insn_size);
+                     md_number_to_chars (f + 2, 0, 4);
+                   }
+               }
+             else
+               {
+                 if (strcmp (opcode->name, "bsa") == 0)
+                   {
+                     f = frag_var (rs_machine_dependent, 8, 6, SUBYPTE_SA_9_22,
+                                   fixups[0].exp.X_add_symbol,
+                                   fixups[0].exp.X_add_number,
+                                   (char *)(size_t) fixups[0].opindex);
+                     md_number_to_chars (f, insn, insn_size);
+                     md_number_to_chars (f + 2, 0, 6);
+                   }
+                 else
+                   {
+                     f = frag_var (rs_machine_dependent, 6, 4, SUBYPTE_COND_9_22,
+                                   fixups[0].exp.X_add_symbol,
+                                   fixups[0].exp.X_add_number,
+                                   (char *)(size_t) fixups[0].opindex);
+                     md_number_to_chars (f, insn, insn_size);
+                     md_number_to_chars (f + 2, 0, 4);
+                   }
+               }
+           }
+         else
+           {
+             if (processor_mask & PROCESSOR_V850E2V3 && !no_bcond17)
+               {
+                 if (strcmp (opcode->name, "bsa") == 0)
+                   {
+                     f = frag_var (rs_machine_dependent, 10, 8, SUBYPTE_SA_9_17_22_32,
+                                   fixups[0].exp.X_add_symbol,
+                                   fixups[0].exp.X_add_number,
+                                   (char *)(size_t) fixups[0].opindex);
+                     md_number_to_chars (f, insn, insn_size);
+                     md_number_to_chars (f + 2, 0, 8);
+                   }
+                 else
+                   {
+                     f = frag_var (rs_machine_dependent, 8, 6, SUBYPTE_COND_9_17_22_32,
+                                   fixups[0].exp.X_add_symbol,
+                                   fixups[0].exp.X_add_number,
+                                   (char *)(size_t) fixups[0].opindex);
+                     md_number_to_chars (f, insn, insn_size);
+                     md_number_to_chars (f + 2, 0, 6);
+                   }
+               }
+             else
+               {
+                 if (strcmp (opcode->name, "bsa") == 0)
+                   {
+                     f = frag_var (rs_machine_dependent, 10, 8, SUBYPTE_SA_9_22_32,
+                                   fixups[0].exp.X_add_symbol,
+                                   fixups[0].exp.X_add_number,
+                                   (char *)(size_t) fixups[0].opindex);
+                     md_number_to_chars (f, insn, insn_size);
+                     md_number_to_chars (f + 2, 0, 8);
+                   }
+                 else
+                   {
+                     f = frag_var (rs_machine_dependent, 8, 6, SUBYPTE_COND_9_22_32,
+                                   fixups[0].exp.X_add_symbol,
+                                   fixups[0].exp.X_add_number,
+                                   (char *)(size_t) fixups[0].opindex);
+                     md_number_to_chars (f, insn, insn_size);
+                     md_number_to_chars (f + 2, 0, 6);
+                   }
+               }
+           }
        }
     }
   else
@@ -2084,6 +2856,12 @@ md_assemble (char *str)
       if ((insn & 0xffe0) == 0x0620)
        insn_size = 2;
 
+      /* Special case: 32 bit JARL,JMP,JR.  */
+      if ((insn & 0x1ffe0) == 0x2e0    /* JARL.  */
+         || (insn & 0x1ffe0) == 0x6e0  /* JMP.  */
+         || (insn & 0x1ffff) == 0x2e0) /* JR.  */
+       insn_size = 2;
+
       f = frag_more (insn_size);
       md_number_to_chars (f, insn, insn_size);
 
@@ -2129,11 +2907,26 @@ md_assemble (char *str)
          if (size != 2 && size != 4)
            abort ();
 
-         address = (f - frag_now->fr_literal) + insn_size - size;
+         if (extra_data_len == 0)
+           {
+             address = (f - frag_now->fr_literal) + insn_size - size;
+           }
+         else
+           {
+             address = (f - frag_now->fr_literal) + extra_data_len - size;
+           }
 
-         if (reloc == BFD_RELOC_32)
-           address += 2;
+         if ((operand->flags & V850E_IMMEDIATE32) && (operand->flags & V850_PCREL))
+           {
+             fixups[i].exp.X_add_number += 2;
+           }
+         else if (operand->default_reloc ==  BFD_RELOC_V850_16_PCREL)
+           {
+             fixups[i].exp.X_add_number += 2;
+             address += 2;
+           }
 
+         /* fprintf (stderr, "0x%x %d %ld\n", address, size, fixups[i].exp.X_add_number);  */
          fixP = fix_new_exp (frag_now, address, size,
                              &fixups[i].exp,
                              reloc_howto->pc_relative,
@@ -2144,6 +2937,7 @@ md_assemble (char *str)
          switch (reloc)
            {
            case BFD_RELOC_LO16:
+           case BFD_RELOC_V850_LO16_S1:
            case BFD_RELOC_V850_LO16_SPLIT_OFFSET:
            case BFD_RELOC_HI16:
            case BFD_RELOC_HI16_S:
@@ -2158,7 +2952,7 @@ md_assemble (char *str)
          fix_new_exp (frag_now,
                       f - frag_now->fr_literal, 4,
                       & fixups[i].exp,
-                      (operand->flags & V850_OPERAND_DISP) != 0,
+                      (operand->flags & V850_PCREL) != 0,
                       (bfd_reloc_code_real_type) (fixups[i].opindex
                                                   + (int) BFD_RELOC_UNUSED));
        }
@@ -2188,9 +2982,11 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
     reloc->addend = fixp->fx_offset;
   else
     {
+#if 0
       if (fixp->fx_r_type == BFD_RELOC_32
          && fixp->fx_pcrel)
        fixp->fx_r_type = BFD_RELOC_32_PCREL;
+#endif
 
       reloc->addend = fixp->fx_addnumber;
     }
@@ -2295,6 +3091,7 @@ md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED)
       int opindex;
       const struct v850_operand *operand;
       unsigned long insn;
+      const char *errmsg = NULL;
 
       opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
       operand = &v850_operands[opindex];
@@ -2306,10 +3103,20 @@ md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED)
         format!  */
       where = fixP->fx_frag->fr_literal + fixP->fx_where;
 
-      insn = bfd_getl32 ((unsigned char *) where);
+      if (fixP->fx_size > 2)
+       insn = bfd_getl32 ((unsigned char *) where);
+      else
+       insn = bfd_getl16 ((unsigned char *) where);
+
       insn = v850_insert_operand (insn, operand, (offsetT) value,
-                                 fixP->fx_file, fixP->fx_line, NULL);
-      bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
+                                 &errmsg);
+      if (errmsg)
+       as_warn_where (fixP->fx_file, fixP->fx_line, errmsg);
+
+      if (fixP->fx_size > 2)
+       bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
+      else
+       bfd_putl16 ((bfd_vma) insn, (unsigned char *) where);
 
       if (fixP->fx_done)
        /* Nothing else to do here.  */
@@ -2318,17 +3125,23 @@ md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED)
       /* Determine a BFD reloc value based on the operand information.
         We are only prepared to turn a few of the operands into relocs.  */
 
-      if (operand->bits == 22)
-       fixP->fx_r_type = BFD_RELOC_V850_22_PCREL;
-      else if (operand->bits == 9)
-       fixP->fx_r_type = BFD_RELOC_V850_9_PCREL;
-      else
+      if (operand->default_reloc == BFD_RELOC_NONE)
        {
          as_bad_where (fixP->fx_file, fixP->fx_line,
                        _("unresolved expression that must be resolved"));
          fixP->fx_done = 1;
          return;
        }
+
+      {
+       fixP->fx_r_type = operand->default_reloc;
+       if (operand->default_reloc ==  BFD_RELOC_V850_16_PCREL)
+         {
+           fixP->fx_where += 2;
+           fixP->fx_size = 2;
+           fixP->fx_addnumber += 2;
+         }
+      }
     }
   else if (fixP->fx_done)
     {
@@ -2336,54 +3149,140 @@ md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED)
       where = fixP->fx_frag->fr_literal + fixP->fx_where;
 
       if (fixP->tc_fix_data != NULL
-         && ((struct v850_operand *) fixP->tc_fix_data)->insert != NULL)
-       {
-         const char * message = NULL;
-         struct v850_operand * operand = (struct v850_operand *) fixP->tc_fix_data;
-         unsigned long insn;
-
-         /* The variable "where" currently points at the exact point inside
-            the insn where we need to insert the value.  But we need to
-            extract the entire insn so we probably need to move "where"
-            back a few bytes.  */
-         if (fixP->fx_size == 2)
-           where -= 2;
-         else if (fixP->fx_size == 1)
-           where -= 3;
-
-         insn = bfd_getl32 ((unsigned char *) where);
-
-         /* Use the operand's insertion procedure, if present, in order to
-            make sure that the value is correctly stored in the insn.  */
-         insn = operand->insert (insn, (offsetT) value, & message);
-         /* Ignore message even if it is set.  */
-
-         bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
-       }
+          && ((struct v850_operand *) fixP->tc_fix_data)->insert != NULL)
+        {
+          const char * message = NULL;
+          struct v850_operand * operand = (struct v850_operand *) fixP->tc_fix_data;
+          unsigned long insn;
+
+          /* The variable "where" currently points at the exact point inside
+             the insn where we need to insert the value.  But we need to
+             extract the entire insn so we probably need to move "where"
+             back a few bytes.  */
+
+          if (fixP->fx_size == 2)
+            where -= 2;
+          else if (fixP->fx_size == 1)
+            where -= 3;
+
+          insn = bfd_getl32 ((unsigned char *) where);
+
+          /* Use the operand's insertion procedure, if present, in order to
+             make sure that the value is correctly stored in the insn.  */
+          insn = operand->insert (insn, (offsetT) value, & message);
+          /* Ignore message even if it is set.  */
+
+          bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
+        }
       else
-       {
-         if (fixP->fx_r_type == BFD_RELOC_V850_LO16_SPLIT_OFFSET)
-           bfd_putl32 (((value << 16) & 0xfffe0000)
-                       | ((value << 5) & 0x20)
-                       | (bfd_getl32 (where) & ~0xfffe0020), where);
-         else if (fixP->fx_size == 1)
-           *where = value & 0xff;
-         else if (fixP->fx_size == 2)
-           bfd_putl16 (value & 0xffff, (unsigned char *) where);
-         else if (fixP->fx_size == 4)
-           bfd_putl32 (value, (unsigned char *) where);
-       }
+        {
+         switch (fixP->fx_r_type)
+           {
+           case BFD_RELOC_V850_32_ABS:
+           case BFD_RELOC_V850_32_PCREL:
+             bfd_putl32 (value & 0xfffffffe, (unsigned char *) where);
+             break;
+
+           case BFD_RELOC_32:
+             bfd_putl32 (value, (unsigned char *) where);
+             break;
+
+           case BFD_RELOC_V850_23:
+             bfd_putl32 (((value & 0x7f) << 4) | ((value & 0x7fff80) << (16-7))
+                         | (bfd_getl32 (where) & ~((0x7f << 4) | (0xffff << 16))),
+                         (unsigned char *) where);
+           break;
+
+           case BFD_RELOC_16:
+           case BFD_RELOC_HI16:
+           case BFD_RELOC_HI16_S:
+           case BFD_RELOC_LO16:
+           case BFD_RELOC_V850_ZDA_16_16_OFFSET:
+           case BFD_RELOC_V850_SDA_16_16_OFFSET:
+           case BFD_RELOC_V850_TDA_16_16_OFFSET:
+           case BFD_RELOC_V850_CALLT_16_16_OFFSET:
+             bfd_putl16 (value & 0xffff, (unsigned char *) where);
+             break;
+
+           case BFD_RELOC_8:
+             *where = value & 0xff;
+             break;
+
+           case BFD_RELOC_V850_9_PCREL:
+             bfd_putl16 (((value & 0x1f0) << 7) | ((value & 0x0e) << 3)
+                         | (bfd_getl16 (where) & ~((0x1f0 << 7) | (0x0e << 3))), where);
+             break;
+
+           case BFD_RELOC_V850_17_PCREL:
+             bfd_putl32 (((value & 0x10000) >> (16 - 4)) | ((value & 0xfffe) << 16)
+                         | (bfd_getl32 (where) & ~((0x10000 >> (16 - 4)) | (0xfffe << 16))), where);
+             break;
+
+           case BFD_RELOC_V850_16_PCREL:
+             bfd_putl16 (-value & 0xfffe, (unsigned char *) where);
+             break;
+
+           case BFD_RELOC_V850_22_PCREL:
+             bfd_putl32 (((value & 0xfffe) << 16) | ((value & 0x3f0000) >> 16)
+                         | (bfd_getl32 (where) & ~((0xfffe << 16) | (0x3f0000 >> 16))), where);
+             break;
+
+           case BFD_RELOC_V850_16_S1:
+           case BFD_RELOC_V850_LO16_S1:
+           case BFD_RELOC_V850_ZDA_15_16_OFFSET:
+           case BFD_RELOC_V850_SDA_15_16_OFFSET:
+             bfd_putl16 (value & 0xfffe, (unsigned char *) where);
+             break;
+
+           case BFD_RELOC_V850_16_SPLIT_OFFSET:
+           case BFD_RELOC_V850_LO16_SPLIT_OFFSET:
+           case BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET:
+           case BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET:
+             bfd_putl32 (((value << 16) & 0xfffe0000)
+                         | ((value << 5) & 0x20)
+                         | (bfd_getl32 (where) & ~0xfffe0020), where);
+             break;
+
+           case BFD_RELOC_V850_TDA_6_8_OFFSET:
+             *where = (*where & ~0x7e) | ((value >> 1) & 0x7e);
+             break;
+
+           case BFD_RELOC_V850_TDA_7_8_OFFSET:
+             *where = (*where & ~0x7f) | ((value >> 1) & 0x7f);
+             break;
+
+           case BFD_RELOC_V850_TDA_7_7_OFFSET:
+             *where = (*where & ~0x7f) | (value & 0x7f);
+             break;
+
+           case BFD_RELOC_V850_TDA_4_5_OFFSET:
+             *where = (*where & ~0xf) | ((value >> 1) & 0xf);
+             break;
+
+           case BFD_RELOC_V850_TDA_4_4_OFFSET:
+             *where = (*where & ~0xf) | (value & 0xf);
+             break;
+
+           case BFD_RELOC_V850_CALLT_6_7_OFFSET:
+             *where = (*where & ~0x3f) | (value & 0x3f);
+             break;
+
+           default:
+             abort ();
+           }
+        }
     }
 }
-\f
+
 /* Parse a cons expression.  We have to handle hi(), lo(), etc
    on the v850.  */
 
 void
 parse_cons_expression_v850 (expressionS *exp)
 {
+  const char *errmsg;
   /* See if there's a reloc prefix like hi() we have to handle.  */
-  hold_cons_reloc = v850_reloc_prefix (NULL);
+  hold_cons_reloc = v850_reloc_prefix (NULL, &errmsg);
 
   /* Do normal expression parsing.  */
   expression (exp);
@@ -2445,8 +3344,11 @@ v850_force_relocation (struct fix *fixP)
   if (v850_relax
       && (fixP->fx_pcrel
          || fixP->fx_r_type == BFD_RELOC_V850_ALIGN
-         || fixP->fx_r_type == BFD_RELOC_V850_22_PCREL
          || fixP->fx_r_type == BFD_RELOC_V850_9_PCREL
+         || fixP->fx_r_type == BFD_RELOC_V850_16_PCREL
+         || fixP->fx_r_type == BFD_RELOC_V850_17_PCREL
+         || fixP->fx_r_type == BFD_RELOC_V850_22_PCREL
+         || fixP->fx_r_type == BFD_RELOC_V850_32_PCREL
          || fixP->fx_r_type >= BFD_RELOC_UNUSED))
     return 1;
 
index 55be314c6b470b250800b5c8cf8c5f05d04ffa55..1909160e299ab848db944cfe6b87203dbfe9d0de 100644 (file)
@@ -400,9 +400,7 @@ case ${generic_target} in
   tic54x-*-* | c54x*-*-*)              fmt=coff bfd_gas=yes need_libm=yes;;
   tic6x-*-*)                           fmt=elf ;;
 
-  v850-*-*)                            fmt=elf ;;
-  v850e-*-*)                           fmt=elf ;;
-  v850ea-*-*)                          fmt=elf ;;
+  v850*-*-*)                           fmt=elf ;;
 
   vax-*-netbsdelf*)                    fmt=elf em=nbsd ;;
   vax-*-linux-*)                       fmt=elf em=linux ;;
index b641f8e11ccb692e5ac9fefe1238bdc43098aac5..e92fbed527da6c3e26a47ec62a39cb69f24898bc 100644 (file)
@@ -68,6 +68,18 @@ routines used by the code produced by GCC for all versions of the v850
 architecture, together with support routines only used by the V850E
 architecture.
 
+@cindex @code{-mv850e2} command line option, V850
+@item -mv850e2
+Specifies that the assembled code should be marked as being targeted at
+the V850E2 processor.  This allows the linker to detect attempts to link
+such code with code assembled for other processors.
+
+@cindex @code{-mv850e2v3} command line option, V850
+@item -mv850e2v3
+Specifies that the assembled code should be marked as being targeted at
+the V850E2V3 processor.  This allows the linker to detect attempts to link
+such code with code assembled for other processors.
+
 @cindex @code{-mrelax} command line option, V850
 @item -mrelax
 Enables relaxation.  This allows the .longcall and .longjump pseudo
@@ -245,6 +257,18 @@ Specifies that the assembled code should be marked as being targeted at
 the V850E1 processor.  This allows the linker to detect attempts to link
 such code with code assembled for other processors.
 
+@cindex @code{.v850e2} directive, V850
+@item .v850e2
+Specifies that the assembled code should be marked as being targeted at
+the V850E2 processor.  This allows the linker to detect attempts to link
+such code with code assembled for other processors.
+
+@cindex @code{.v850e2v3} directive, V850
+@item .v850e2v3
+Specifies that the assembled code should be marked as being targeted at
+the V850E2V3 processor.  This allows the linker to detect attempts to link
+such code with code assembled for other processors.
+
 @end table
 
 @node V850 Opcodes
index 63058013c37d015514ebe6d3cd4ba8fd62672ce7..70973c93cb468188844fbd118f983c32ffe97daa 100644 (file)
@@ -1,3 +1,10 @@
+2010-07-23  Naveen.H.S  <naveen.S@kpitcummins.com>
+           Ina Pandit  <ina.pandit@kpitcummins.com>
+
+       * gas/v850/split-lo16.d: Update the "ld" instructions with a space
+       for second operand.
+       * gas/v850/v850e1.d: Likewise.
+
 2010-07-22  Alan Modra  <amodra@gmail.com>
 
        * gas/arm/mapdir.s: Don't specify attr/type for .fini_array.
index 739b9ceadb2a364d4321d03a256395fcd22459ae..9e23feaae57aa881bd0d073fad5c142c17a5d6d2 100644 (file)
@@ -1,2 +1,5 @@
 #name: bad byte directive
 #error-output: byte.l
+# The RX target allows quoted ASCII strings inside .byte directives
+# for compatibily with the Renesas assembler.
+#skip: rx-*-*
index d515f24f75355b3f18e757abf3c23b687f623f41..6733bbf423e9664231c0d95dcb54cb523534a805 100644 (file)
@@ -10,8 +10,8 @@ Disassembly of section .text:
 0+0108 <mem\+0x8> 66 20[       ]+mov.l[        ]+#2, r0
 0+010a <mem\+0xa> 66 10[       ]+mov.l[        ]+#1, r0
 0+010c <mem\+0xc> 66 00[       ]+mov.l[        ]+#0, r0
-0+010e <mem\+0xe> 05 f2 fe ff[         ]+bsr.a[        ]+0+0000 <mem-0x100>
-0+0112 <mem\+0x12> 05 ee fe ff[          ]+bsr.a[      ]+0+0000 <mem-0x100>
+0+010e <mem\+0xe> 05 .. .. ..[         ]+bsr.a[        ]+[0-9a-f]+ <mem.0x[0-9a-f]+>
+0+0112 <mem\+0x12> 05 .. .. ..[          ]+bsr.a[      ]+[0-9a-f]+ <mem.0x[0-9a-f]+>
 0+0116 <mem\+0x16> 62 65[      ]+add[  ]+#6, r5
 0+0118 <mem\+0x18> 72 74 0b 2e[        ]+add[  ]+#0x2e0b, r7, r4
 0+011c <mem\+0x1c> ff 2e 00[   ]+add[  ]+r0, r0, r14
index 5ed195cb087ed94b2a9b34544d122630e45d562c..617dfd8ffb1ec02dd371bc8c6750cf01c5e934fd 100644 (file)
@@ -7,12 +7,12 @@
                        2: R_V850_HI16_S        foo
    4:  01 16 00 00     addi    0, r1, r2
                        6: R_V850_LO16  foo
-   8:  01 17 00 00     ld\.b   0\[r1\],r2
+   8:  01 17 00 00     ld\.b   0\[r1\], r2
                        a: R_V850_LO16  foo
-   c:  81 17 01 00     ld\.bu  0\[r1\],r2
+   c:  81 17 01 00     ld\.bu  0\[r1\], r2
                        c: R_V850_LO16_SPLIT_OFFSET     foo
-  10:  a1 17 45 23     ld\.bu  9029\[r1\],r2
-  14:  81 17 57 34     ld\.bu  13398\[r1\],r2
-  18:  20 57 01 00     ld.w    0\[r0\],r10
-  1c:  20 57 79 56     ld.w    22136\[r0\],r10
+  10:  a1 17 45 23     ld\.bu  9029\[r1\], r2
+  14:  81 17 57 34     ld\.bu  13398\[r1\], r2
+  18:  20 57 01 00     ld.w    0\[r0\], r10
+  1c:  20 57 79 56     ld.w    22136\[r0\], r10
 #pass
index 9fb689b5d3c73af778642e8ff74f31741c3587e7..8172b09747eb0147604ef894fd033b5b4ca280f5 100644 (file)
@@ -23,8 +23,8 @@ Disassembly of section .text:
 0x0+30 e7 47 82 4a [   ]*divhu r7, r8, r9
 0x0+34 ea 5f c2 62 [   ]*divu  r10, r11, r12
 0x0+38 e0 6f 44 73 [   ]*hsw   r13, r14
-0x0+3c a1 17 0d 00 [   ]*ld.bu 13\[r1\],r2
-0x0+40 e3 27 11 00 [   ]*ld.hu 16\[sp\],gp
+0x0+3c a1 17 0d 00 [   ]*ld.bu 13\[r1\], r2
+0x0+40 e3 27 11 00 [   ]*ld.hu 16\[sp\], gp
 0x0+44 21 06 78 56 34 12 [     ]*mov   0x12345678, r1
 0x0+4a e5 17 40 1a [   ]*mul   5, r2, sp
 0x0+4e e1 17 20 1a [   ]*mul   r1, r2, sp
@@ -35,8 +35,8 @@ Disassembly of section .text:
 0x0+62 a8 07 03 70 [   ]*prepare       {r25 - r27}, 20, sp
 0x0+66 e1 4f e0 00 [   ]*set1  r9, r1
 0x0+6a ea 47 00 02 [   ]*sasf  nz, r8
-0x0+6e 60 20  [        ]*sld.bu        0\[ep\],gp
-0x0+70 77 28  [        ]*sld.hu        14\[ep\],r5
+0x0+6e 60 20  [        ]*sld.bu        0\[ep\], gp
+0x0+70 77 28  [        ]*sld.hu        14\[ep\], r5
 0x0+72 a1 00  [        ]*sxb   r1
 0x0+74 e2 00  [        ]*sxh   r2
 0x0+76 ff 07 e6 00 [   ]*tst1  r0, lp
index edd9b48b003a11e29a800411f25e43320867e460..61bbf81db1d8e51088b89637fe97d05d6ccc56ff 100644 (file)
@@ -1,3 +1,9 @@
+2010-07-23  Naveen.H.S  <naveen.S@kpitcummins.com>
+           Ina Pandit  <ina.pandit@kpitcummins.com>
+
+       * v850.h: Add support for V850E2 and V850E2V3.
+       (v850_reloc_type): Update the newly added relocations
+
 2010-07-20  Alan Modra  <amodra@gmail.com>
 
        * internal.h (ELF_TBSS_SPECIAL): New macro, extracted from..
index 71ae1db4b497de91c4e64a6ff178d1176bf16e3c..2a0e03ef8229e093d2b3d5812224012cd70dbefb 100644 (file)
 /* v850e1 code.  */
 #define E_V850E1_ARCH          0x20000000
 
+/* v850e2 code.  */
+#define E_V850E2_ARCH          0x30000000
+
+/* v850e2v3 code.  */
+#define E_V850E2V3_ARCH                0x40000000
 
 /* Flags for the st_other field.  */
 #define V850_OTHER_SDA         0x10    /* Symbol had SDA relocations.  */
@@ -81,6 +86,29 @@ START_RELOC_NUMBERS (v850_reloc_type)
      RELOC_NUMBER (R_V850_ALIGN, 27)
      RELOC_NUMBER (R_V850_REL32, 28)
      RELOC_NUMBER (R_V850_LO16_SPLIT_OFFSET, 29)       /* For ld.bu */
+     RELOC_NUMBER (R_V850_16_PCREL, 30)                /* For loop */
+     RELOC_NUMBER (R_V850_17_PCREL, 31)                /* For br */
+     RELOC_NUMBER (R_V850_23, 32)                      /* For 23bit ld.[w,h,hu,b,bu],st.[w,h,b] */
+     RELOC_NUMBER (R_V850_32_PCREL, 33)                /* For jr32, jarl32 */
+     RELOC_NUMBER (R_V850_32_ABS, 34)                  /* For jmp32 */
+     RELOC_NUMBER (R_V850_16_SPLIT_OFFSET, 35)         /* For ld.bu */
+     RELOC_NUMBER (R_V850_16_S1, 36)                   /* For ld.w, ld.h st.w st.h */
+     RELOC_NUMBER (R_V850_LO16_S1, 37)                 /* For ld.w, ld.h st.w st.h */
+     RELOC_NUMBER (R_V850_CALLT_15_16_OFFSET, 38)      /* For ld.w, ld.h, ld.hu, st.w, st.h */
+     RELOC_NUMBER (R_V850_32_GOTPCREL, 39)             /* GLOBAL_OFFSET_TABLE from pc */
+     RELOC_NUMBER (R_V850_16_GOT, 40)                  /* GOT ENTRY from gp */
+     RELOC_NUMBER (R_V850_32_GOT, 41)                  
+     RELOC_NUMBER (R_V850_22_PLT, 42)                  /* For jr */
+     RELOC_NUMBER (R_V850_32_PLT, 43)                  /* For jr32 */
+     RELOC_NUMBER (R_V850_COPY, 44)                    
+     RELOC_NUMBER (R_V850_GLOB_DAT, 45)                
+     RELOC_NUMBER (R_V850_JMP_SLOT, 46)                
+     RELOC_NUMBER (R_V850_RELATIVE, 47)                
+     RELOC_NUMBER (R_V850_16_GOTOFF, 48)               /* From gp */
+     RELOC_NUMBER (R_V850_32_GOTOFF, 49)               
+     RELOC_NUMBER (R_V850_CODE, 50)                    
+     RELOC_NUMBER (R_V850_DATA, 51)                    /* For loop */
+
 END_RELOC_NUMBERS (R_V850_max)
 
 \f
index aa09a3a48ec3d5ea442a49fdff1d846504d16a27..f2e1345935947c5f23d19b35f8bd0a8df32177ca 100644 (file)
@@ -1,3 +1,21 @@
+2010-07-23  Naveen.H.S  <naveen.S@kpitcummins.com>
+           Ina Pandit  <ina.pandit@kpitcummins.com>
+
+       * v850.h: Define PROCESSOR_MASK, PROCESSOR_OPTION_EXTENSION,
+       PROCESSOR_OPTION_ALIAS, PROCESSOR_V850E2, PROCESSOR_V850E2V3 and
+       PROCESSOR_V850E2_ALL.
+       Remove PROCESSOR_V850EA support.
+       (v850_operand): Define V850_OPERAND_EP, V850_OPERAND_FLOAT_CC,
+       V850_OPERAND_VREG, V850E_IMMEDIATE16, V850E_IMMEDIATE16HI,
+       V850E_IMMEDIATE23, V850E_IMMEDIATE32, V850_OPERAND_SIGNED,
+       V850_OPERAND_DISP, V850_PCREL, V850_REG_EVEN, V850E_PUSH_POP,
+       V850_NOT_IMM0, V850_NOT_SA, V850_OPERAND_BANG and
+       V850_OPERAND_PERCENT.
+       Update V850_OPERAND_SRG, V850_OPERAND_CC, V850_OPERAND_RELAX and
+       V850_NOT_R0.
+       Remove V850_OPERAND_SIGNED, V850_OPERAND_EP, V850_OPERAND_DISP
+       and V850E_PUSH_POP
+
 2010-07-06  Maciej W. Rozycki  <macro@codesourcery.com>
 
        * mips.h (MIPS16_INSN_UNCOND_BRANCH): New macro.
index fcf96310fc69630834f3c96f7fcb8b62c5b4a7d5..59033059179d3f01a8858a6993b9bdba929c92bc 100644 (file)
@@ -55,12 +55,18 @@ struct v850_opcode
 };
 
 /* Values for the processors field in the v850_opcode structure.  */
+#define PROCESSOR_MASK         0x1f
+#define PROCESSOR_OPTION_EXTENSION     (1 << 5)        /* Enable extension opcodes.  */
+#define PROCESSOR_OPTION_ALIAS (1 << 6)                /* Enable alias opcodes.  */
 #define PROCESSOR_V850         (1 << 0)                /* Just the V850.  */
-#define PROCESSOR_ALL          -1                      /* Any processor.  */
-#define PROCESSOR_V850E                (1 << 1)                /* Just the V850E. */
-#define PROCESSOR_NOT_V850     (~ PROCESSOR_V850)      /* Any processor except the V850.  */
-#define PROCESSOR_V850EA       (1 << 2)                /* Just the V850EA. */
-#define PROCESSOR_V850E1       (1 << 3)                /* Just the V850E1. */
+#define PROCESSOR_ALL          PROCESSOR_MASK          /* Any processor.  */
+#define PROCESSOR_V850E                (1 << 1)                /* Just the V850E.  */
+#define PROCESSOR_NOT_V850     (PROCESSOR_ALL & (~ PROCESSOR_V850))    /* Any processor except the V850.  */
+#define PROCESSOR_V850E1       (1 << 2)                /* Just the V850E1.  */
+#define PROCESSOR_V850E2       (1 << 3)                /* Just the V850E2.  */
+#define PROCESSOR_V850E2V3     (1 << 4)                /* Just the V850E2V3.  */
+#define PROCESSOR_V850E2_ALL   (PROCESSOR_V850E2 | PROCESSOR_V850E2V3) /* V850E2 & V850E2V3.  */
+#define SET_PROCESSOR_MASK(mask,set)   ((mask) = ((mask) & ~PROCESSOR_MASK) | (set))
 
 /* The table itself is sorted by major opcode number, and is otherwise
    in the order in which the disassembler should consider
@@ -74,7 +80,8 @@ extern const int v850_num_opcodes;
 struct v850_operand
 {
   /* The number of bits in the operand.  */
-  /* If this value is -1 then the operand's bits are in a discontinous distribution in the instruction. */
+  /* If this value is -1 then the operand's bits are in a discontinous
+     distribution in the instruction. */
   int bits;
 
   /* (bits >= 0):  How far the operand is left shifted in the instruction.  */
@@ -120,6 +127,8 @@ struct v850_operand
 
   /* One bit syntax flags.  */
   int flags;
+
+  int default_reloc;
 };
 
 /* Elements in the table are retrieved by indexing with values from
@@ -129,39 +138,70 @@ extern const struct v850_operand v850_operands[];
 
 /* Values defined for the flags field of a struct v850_operand.  */
 
-/* This operand names a general purpose register */
+/* This operand names a general purpose register */
 #define V850_OPERAND_REG       0x01
 
-/* This operand names a system register */
-#define V850_OPERAND_SRG       0x02
+/* This operand is the ep register.  */
+#define V850_OPERAND_EP                0x02
 
-/* This operand names a condition code used in the setf instruction */
-#define V850_OPERAND_CC                0x04
+/* This operand names a system register.  */
+#define V850_OPERAND_SRG       0x04
 
-/* This operand takes signed values */
-#define V850_OPERAND_SIGNED    0x08
+/* Prologue eilogue type instruction, V850E specific.  */
+#define V850E_OPERAND_REG_LIST 0x08
 
-/* This operand is the ep register.  */
-#define V850_OPERAND_EP                0x10
+/* This operand names a condition code used in the setf instruction.  */
+#define V850_OPERAND_CC                0x10
 
-/* This operand is a PC displacement */
-#define V850_OPERAND_DISP      0x20
+#define V850_OPERAND_FLOAT_CC  0x20
 
-/* This is a relaxable operand.   Only used for D9->D22 branch relaxing
-   right now.  We may need others in the future (or maybe handle them like
-   promoted operands on the mn10300?)  */
-#define V850_OPERAND_RELAX     0x40
+/* This operand names a vector purpose register.  */
+#define V850_OPERAND_VREG      0x40
 
-/* The register specified must not be r0 */
-#define V850_NOT_R0            0x80
+/* 16 bit immediate follows instruction, V850E specific.  */
+#define V850E_IMMEDIATE16      0x80
 
-/* push/pop type instruction, V850E specific.  */
-#define V850E_PUSH_POP         0x100
+/* hi16 bit immediate follows instruction, V850E specific.  */
+#define V850E_IMMEDIATE16HI    0x100
 
-/* 16 bit immediate follows instruction, V850E specific.  */
-#define V850E_IMMEDIATE16      0x200
+/* 23 bit immediate follows instruction, V850E specific.  */
+#define V850E_IMMEDIATE23      0x200
 
 /* 32 bit immediate follows instruction, V850E specific.  */
 #define V850E_IMMEDIATE32      0x400
 
+/* This is a relaxable operand.   Only used for D9->D22 branch relaxing
+   right now.  We may need others in the future (or maybe handle them like
+   promoted operands on the mn10300?).  */
+#define V850_OPERAND_RELAX     0x800
+
+/* This operand takes signed values.  */
+#define V850_OPERAND_SIGNED    0x1000
+
+/* This operand is a displacement.  */
+#define V850_OPERAND_DISP      0x2000
+
+/* This operand is a PC displacement.  */
+#define V850_PCREL             0x4000
+
+/* The register specified must be even number.  */
+#define V850_REG_EVEN          0x8000
+
+/* The register specified must not be r0.  */
+#define V850_NOT_R0            0x20000
+
+/* The register specified must not be 0.  */
+#define V850_NOT_IMM0          0x40000
+
+/* The condition code must not be SA CONDITION.  */
+#define V850_NOT_SA            0x80000
+
+/* The operand has '!' prefix.  */
+#define V850_OPERAND_BANG      0x100000
+
+/* The operand has '%' prefix.  */
+#define V850_OPERAND_PERCENT   0x200000
+
+extern int v850_msg_is_out_of_range (const char * msg);
+
 #endif /* V850_H */
index 24d2cfd74a90a84f7fdc1e46ae794d50b67f0015..7635da40d920cad05a86f948594e951670c5e917 100644 (file)
@@ -1,3 +1,8 @@
+2010-07-23  Naveen.H.S  <naveen.S@kpitcummins.com>
+           Ina Pandit  <ina.pandit@kpitcummins.com>
+
+       * configure.tgt: Match all v850 targets.
+
 2010-07-20  Mike Frysinger  <vapier@gentoo.org>
 
        * ld.texinfo (VERSION): Remove "int" from example script and add ";".
index 6ec6d55f44d030f076293a323045acf0da0439a6..b407ab66f18f74d4d2662e5ca52fa81b8118637f 100644 (file)
@@ -1,3 +1,9 @@
+2010-07-23  Naveen.H.S  <naveen.S@kpitcummins.com>
+           Ina Pandit  <ina.pandit@kpitcummins.com>
+
+       * ld-v850/split-lo16.d: Update the "ld" instructions with a space
+       for second operand.
+
 2010-07-20  Alan Modra  <amodra@gmail.com>
 
        * ld-powerpc/tlsexe.r: Update.
index c5668ffaf73e19a25f0f868d4e26f71cd040281a..fbc325cb7488c4442c4148d7647a13e181e408fe 100644 (file)
@@ -5,22 +5,22 @@
 00010000 <.*>:
    10000:      40 0e 34 12     movhi   4660, r0, r1
    10004:      01 16 78 56     addi    22136, r1, r2
-   10008:      81 17 79 56     ld\.bu  22136\[r1\],r2
+   10008:      81 17 79 56     ld\.bu  22136\[r1\], r2
    1000c:      40 0e 36 12     movhi   4662, r0, r1
    10010:      01 16 78 d8     addi    -10120, r1, r2
-   10014:      81 17 79 d8     ld\.bu  -10120\[r1\],r2
+   10014:      81 17 79 d8     ld\.bu  -10120\[r1\], r2
    10018:      40 0e 12 00     movhi   18, r0, r1
-   1001c:      81 17 57 34     ld\.bu  13398\[r1\],r2
+   1001c:      81 17 57 34     ld\.bu  13398\[r1\], r2
    10020:      01 16 56 34     addi    13398, r1, r2
    10024:      40 0e 14 00     movhi   20, r0, r1
-   10028:      81 17 57 b6     ld\.bu  -18858\[r1\],r2
+   10028:      81 17 57 b6     ld\.bu  -18858\[r1\], r2
    1002c:      01 16 56 b6     addi    -18858, r1, r2
    10030:      40 0e 79 56     movhi   22137, r0, r1
    10034:      01 16 bc 9a     addi    -25924, r1, r2
-   10038:      81 17 bd 9a     ld\.bu  -25924\[r1\],r2
+   10038:      81 17 bd 9a     ld\.bu  -25924\[r1\], r2
    1003c:      40 0e 9b 78     movhi   30875, r0, r1
-   10040:      81 17 df bc     ld\.bu  -17186\[r1\],r2
+   10040:      81 17 df bc     ld\.bu  -17186\[r1\], r2
    10044:      01 16 de bc     addi    -17186, r1, r2
    10048:      40 0e 45 23     movhi   9029, r0, r1
-   1004c:      a1 17 89 67     ld\.bu  26505\[r1\],r2
+   1004c:      a1 17 89 67     ld\.bu  26505\[r1\], r2
 #pass
index c0c9835c106ba6ef4d8a6a25d6f4e780ea8b0ee2..b47aa3ddc703f15c967b34a4ca34a9e71533330e 100644 (file)
@@ -1,3 +1,26 @@
+2010-07-23  Naveen.H.S  <naveen.S@kpitcummins.com>
+           Ina Pandit  <ina.pandit@kpitcummins.com>
+
+       * v850-dis.c (v850_sreg_names): Updated structure for system
+       registers.
+       (float_cc_names): new structure for condition codes.
+       (print_value): Update the function that prints value.
+       (get_operand_value): New function to get the operand value.
+       (disassemble): Updated to handle the disassembly of instructions.
+       (print_insn_v850): Updated function to print instruction for different
+       families.
+       * opcodes/v850-opc.c (v850_msg_is_out_of_range, insert_i5div1,
+       extract_i5div1, insert_i5div2, extract_i5div2, insert_i5div3,
+       extract_i5div3, insert_d5_4, extract_d5_4, extract_d8_6,
+       insert_d8_7, extract_d8_7, insert_v8, extract_v8, insert_u16_loop,
+       extract_u16_loop, insert_d16_15, extract_d16_15, insert_d16_16,
+       extract_d16_16, nsert_d17_16, extract_d17_16, insert_d22,
+       extract_d22, insert_d23, extract_d23, insert_i9, extract_i9,
+       insert_u9, extract_u9, extract_spe, insert_r4, extract_r4): New.
+       (insert_d8_7, insert_d5_4, insert_i5div): Remove.
+       (v850_operands): Update with the relocation name. Also update
+       the instructions with specific set of processors.
+
 2010-07-08 Tejas Belagod <tejas.belagod@arm.com>
 
        * arm-dis.c (print_insn_arm): Add cases for printing more
index 6cf90296658ac84851c5e8a20e534eea00ad8745..c3624b21f4be92934709788980aab351220c5cd7 100644 (file)
@@ -1,5 +1,5 @@
 /* Disassemble V850 instructions.
-   Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005, 2007
+   Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005, 2007, 2010
    Free Software Foundation, Inc.
 
    This file is part of the GNU opcodes library.
 #include "opintl.h"
 
 static const char *const v850_reg_names[] =
-{ "r0", "r1", "r2", "sp", "gp", "r5", "r6", "r7",
+{
+  "r0", "r1", "r2", "sp", "gp", "r5", "r6", "r7",
   "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
   "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
-  "r24", "r25", "r26", "r27", "r28", "r29", "ep", "lp" };
+  "r24", "r25", "r26", "r27", "r28", "r29", "ep", "lp"
+};
 
 static const char *const v850_sreg_names[] =
-{ "eipc", "eipsw", "fepc", "fepsw", "ecr", "psw", "sr6", "sr7",
-  "sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15",
-  "ctpc", "ctpsw", "dbpc", "dbpsw", "ctbp", "sr21", "sr22", "sr23",
-  "sr24", "sr25", "sr26", "sr27", "sr28", "sr29", "sr30", "sr31",
-  "sr16", "sr17", "sr18", "sr19", "sr20", "sr21", "sr22", "sr23",
-  "sr24", "sr25", "sr26", "sr27", "sr28", "sr29", "sr30", "sr31" };
+{
+  "eipc/vip/mpm", "eipsw/mpc", "fepc/tid", "fepsw/ppa", "ecr/vmecr", "psw/vmtid",
+  "sr6/fpsr/vmadr/dcc", "sr7/fpepc/dc0",
+  "sr8/fpst/vpecr/dcv1", "sr9/fpcc/vptid", "sr10/fpcfg/vpadr/spal", "sr11/spau",
+  "sr12/vdecr/ipa0l", "eiic/vdtid/ipa0u", "feic/ipa1l", "dbic/ipa1u",
+  "ctpc/ipa2l", "ctpsw/ipa2u", "dbpc/ipa3l", "dbpsw/ipa3u", "ctbp/dpa0l",
+  "dir/dpa0u", "bpc/dpa0u", "asid/dpa1l",
+  "bpav/dpa1u", "bpam/dpa2l", "bpdv/dpa2u", "bpdm/dpa3l", "eiwr/dpa3u",
+  "fewr", "dbwr", "bsel"
+};
 
 static const char *const v850_cc_names[] =
-{ "v", "c/l", "z", "nh", "s/n", "t", "lt", "le",
-  "nv", "nc/nl", "nz", "h", "ns/p", "sa", "ge", "gt" };
+{
+  "v", "c/l", "z", "nh", "s/n", "t", "lt", "le",
+  "nv", "nc/nl", "nz", "h", "ns/p", "sa", "ge", "gt"
+};
 
-static int
-disassemble (bfd_vma memaddr,
-            struct disassemble_info * info,
-            unsigned long insn)
+static const char *const v850_float_cc_names[] =
 {
-  struct v850_opcode * op = (struct v850_opcode *) v850_opcodes;
-  const struct v850_operand * operand;
-  int match = 0;
-  int short_op = ((insn & 0x0600) != 0x0600);
-  int bytes_read;
-  int target_processor;
+  "f/t", "un/or", "eq/neq", "ueq/ogl", "olt/uge", "ult/oge", "ole/ugt", "ule/ogt",
+  "sf/st", "ngle/gle", "seq/sne", "ngl/gl", "lt/nlt", "nge/ge", "le/nle", "ngt/gt"
+};
 
-  /* Special case: 32 bit MOV.  */
-  if ((insn & 0xffe0) == 0x0620)
-    short_op = 1;
 
-  bytes_read = short_op ? 2 : 4;
+static void
+print_value (int flags, bfd_vma memaddr, struct disassemble_info *info, long value)
+{
+  if (flags & V850_PCREL)
+    {
+      bfd_vma addr = value + memaddr;
+      info->print_address_func (addr, info);
+    }
+  else if (flags & V850_OPERAND_DISP)
+    {
+      if (flags & V850_OPERAND_SIGNED)
+        {
+          info->fprintf_func (info->stream, "%ld", value);
+        }
+      else
+        {
+          info->fprintf_func (info->stream, "%lu", value);
+        }
+    }
+  else if (flags & V850E_IMMEDIATE32)
+    {
+      info->fprintf_func (info->stream, "0x%lx", value);
+    }
+  else
+    {
+      if (flags & V850_OPERAND_SIGNED)
+       {
+         info->fprintf_func (info->stream, "%ld", value);
+       }
+      else
+       {
+         info->fprintf_func (info->stream, "%lu", value);
+       }
+    }
+}
 
-  /* If this is a two byte insn, then mask off the high bits.  */
-  if (short_op)
-    insn &= 0xffff;
+static long
+get_operand_value (const struct v850_operand *operand,
+                  unsigned long insn,
+                  int bytes_read,
+                  bfd_vma memaddr,
+                  struct disassemble_info * info,
+                  bfd_boolean noerror,
+                  int *invalid)
+{
+  long value;
+  bfd_byte buffer[4];
+
+  if ((operand->flags & V850E_IMMEDIATE16)
+      || (operand->flags & V850E_IMMEDIATE16HI))
+    {
+      int status = info->read_memory_func (memaddr + bytes_read, buffer, 2, info);
+
+      if (status == 0)
+       {
+         value = bfd_getl16 (buffer);
+
+         if (operand->flags & V850E_IMMEDIATE16HI)
+           value <<= 16;
+
+         return value;
+       }
+
+      if (!noerror)
+       info->memory_error_func (status, memaddr + bytes_read, info);
+
+      return 0;
+    }
+
+  if (operand->flags & V850E_IMMEDIATE23)
+    {
+      int status = info->read_memory_func (memaddr + 2, buffer, 4, info);
+
+      if (status == 0)
+       {
+         value = bfd_getl32 (buffer);
+
+         value = (operand->extract) (value, invalid);
+
+         return value;
+       }
+
+      if (!noerror)
+       info->memory_error_func (status, memaddr + bytes_read, info);
+
+      return 0;
+    }
+
+  if (operand->flags & V850E_IMMEDIATE32)
+    {
+      int status = info->read_memory_func (memaddr + bytes_read, buffer, 4, info);
+
+      if (status == 0)
+       {
+         bytes_read += 4;
+         value = bfd_getl32 (buffer);
+
+         return value;
+       }
+
+      if (!noerror)
+       info->memory_error_func (status, memaddr + bytes_read, info);
+
+      return 0;
+    }
+
+  if (operand->extract)
+    value = (operand->extract) (insn, invalid);
+  else
+    {
+      if (operand->bits == -1)
+       value = (insn & operand->shift);
+      else
+       value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
+
+      if (operand->flags & V850_OPERAND_SIGNED)
+       value = ((long)(value << (sizeof (long)*8 - operand->bits))
+                >> (sizeof (long)*8 - operand->bits));
+    }
+
+  return value;
+}
+
+
+static int
+disassemble (bfd_vma memaddr, struct disassemble_info *info, int bytes_read, unsigned long insn)
+{
+  struct v850_opcode *op = (struct v850_opcode *)v850_opcodes;
+  const struct v850_operand *operand;
+  int match = 0;
+  int target_processor;
 
   switch (info->mach)
     {
@@ -79,22 +204,66 @@ disassemble (bfd_vma memaddr,
       break;
 
     case bfd_mach_v850e1:
-      target_processor = PROCESSOR_V850E1;
+      target_processor = PROCESSOR_V850E;
+      break;
+
+    case bfd_mach_v850e2:
+      target_processor = PROCESSOR_V850E2;
+      break;
+
+    case bfd_mach_v850e2v3:
+      target_processor = PROCESSOR_V850E2V3;
       break;
     }
 
+  /* If this is a two byte insn, then mask off the high bits.  */
+  if (bytes_read == 2)
+    insn &= 0xffff;
+
   /* Find the opcode.  */
   while (op->name)
     {
       if ((op->mask & insn) == op->opcode
-         && (op->processors & target_processor))
+         && (op->processors & target_processor)
+         && !(op->processors & PROCESSOR_OPTION_ALIAS))
        {
+         /* Code check start.  */
          const unsigned char *opindex_ptr;
          unsigned int opnum;
          unsigned int memop;
 
+         for (opindex_ptr = op->operands, opnum = 1;
+              *opindex_ptr != 0;
+              opindex_ptr++, opnum++)
+           {
+             int invalid = 0;
+             long value;
+
+             operand = &v850_operands[*opindex_ptr];
+
+             value = get_operand_value (operand, insn, bytes_read, memaddr, info, 1, &invalid);
+
+             if (invalid)
+               goto next_opcode;
+
+              if ((operand->flags & V850_NOT_R0) && value == 0 && (op->memop) <=2)
+               goto next_opcode;
+
+             if ((operand->flags & V850_NOT_SA) && value == 0xd)
+               goto next_opcode;
+
+             if ((operand->flags & V850_NOT_IMM0) && value == 0)
+               goto next_opcode;
+           }
+
+         /* Code check end.  */
+
          match = 1;
          (*info->fprintf_func) (info->stream, "%s\t", op->name);
+#if 0
+         fprintf (stderr, "match: insn: %lx, mask: %lx, opcode: %lx, name: %s\n",
+                  insn, op->mask, op->opcode, op->name );
+#endif
 
          memop = op->memop;
          /* Now print the operands.
@@ -116,24 +285,11 @@ disassemble (bfd_vma memaddr,
            {
              long value;
              int flag;
-             int status;
-             bfd_byte buffer[4];
+             char *prefix;
 
              operand = &v850_operands[*opindex_ptr];
 
-             if (operand->extract)
-               value = (operand->extract) (insn, 0);
-             else
-               {
-                 if (operand->bits == -1)
-                   value = (insn & operand->shift);
-                 else
-                   value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
-
-                 if (operand->flags & V850_OPERAND_SIGNED)
-                   value = ((long)(value << (32 - operand->bits))
-                            >> (32 - operand->bits));
-               }
+             value = get_operand_value (operand, insn, bytes_read, memaddr, info, 0, 0);
 
              /* The first operand is always output without any
                 special handling.
@@ -156,88 +312,57 @@ disassemble (bfd_vma memaddr,
                   The exception (and there's always an exception) is the
                   "jmp" insn which needs square brackets around it's only
                   register argument.  */
+             prefix = "";
+             if (operand->flags & V850_OPERAND_BANG)
+               {
+                 prefix = "!";
+               }
+             else if (operand->flags & V850_OPERAND_PERCENT)
+               {
+                 prefix = "%";
+               }
 
-                  if (memop && opnum == memop + 1)
-                    info->fprintf_func (info->stream, "[");
-                  else if (memop && opnum == memop + 2)
-                    info->fprintf_func (info->stream, "],");
-                  else if (memop == 1 && opnum == 1
-                           && (operand->flags & V850_OPERAND_REG))
-                    info->fprintf_func (info->stream, "[");
-                  else if (opnum > 1)
-                    info->fprintf_func (info->stream, ", ");
-
-             /* Extract the flags, ignorng ones which
-                do not effect disassembly output. */
-             flag = operand->flags;
-             flag &= ~ V850_OPERAND_SIGNED;
-             flag &= ~ V850_OPERAND_RELAX;
-             flag &= - flag;
+             if (opnum == 1 && opnum == memop)
+               info->fprintf_func (info->stream, "%s[", prefix);
+             else if (opnum > 1
+                      && (v850_operands[*(opindex_ptr - 1)].flags & V850_OPERAND_DISP) != 0
+                      && opnum == memop)
+               info->fprintf_func (info->stream, "%s[", prefix);
+             else if (opnum > 1)
+               info->fprintf_func (info->stream, ", %s", prefix);
+
+             /* Extract the flags, ignoring ones which do not effect disassembly output.  */
+             flag = operand->flags & (V850_OPERAND_REG
+                                      | V850_REG_EVEN
+                                      | V850_OPERAND_EP
+                                      | V850_OPERAND_SRG
+                                      | V850E_OPERAND_REG_LIST
+                                      | V850_OPERAND_CC
+                                      | V850_OPERAND_FLOAT_CC);
 
              switch (flag)
                {
-               case V850_OPERAND_REG:
-                 info->fprintf_func (info->stream, "%s", v850_reg_names[value]);
-                 break;
-               case V850_OPERAND_SRG:
-                 info->fprintf_func (info->stream, "%s", v850_sreg_names[value]);
-                 break;
-               case V850_OPERAND_CC:
-                 info->fprintf_func (info->stream, "%s", v850_cc_names[value]);
-                 break;
-               case V850_OPERAND_EP:
-                 info->fprintf_func (info->stream, "ep");
-                 break;
-               default:
-                 info->fprintf_func (info->stream, "%ld", value);
-                 break;
-               case V850_OPERAND_DISP:
-                 {
-                   bfd_vma addr = value + memaddr;
-
-                   /* On the v850 the top 8 bits of an address are used by an
-                      overlay manager.  Thus it may happen that when we are
-                      looking for a symbol to match against an address with
-                      some of its top bits set, the search fails to turn up an
-                      exact match.  In this case we try to find an exact match
-                      against a symbol in the lower address space, and if we
-                      find one, we use that address.   We only do this for
-                      JARL instructions however, as we do not want to
-                      misinterpret branch instructions.  */
-                   if (operand->bits == 22)
-                     {
-                       if ( ! info->symbol_at_address_func (addr, info)
-                           && ((addr & 0xFF000000) != 0)
-                           && info->symbol_at_address_func (addr & 0x00FFFFFF, info))
-                         addr &= 0x00FFFFFF;
-                     }
-                   info->print_address_func (addr, info);
-                   break;
-                 }
+               case V850_OPERAND_REG:  info->fprintf_func (info->stream, "%s", v850_reg_names[value]); break;
+               case (V850_OPERAND_REG|V850_REG_EVEN):  info->fprintf_func (info->stream, "%s", v850_reg_names[value*2]); break;
+               case V850_OPERAND_EP:   info->fprintf_func (info->stream, "ep"); break;
+               case V850_OPERAND_SRG:  info->fprintf_func (info->stream, "%s", v850_sreg_names[value]); break;
 
-               case V850E_PUSH_POP:
+               case V850E_OPERAND_REG_LIST:
                  {
-                   static int list12_regs[32]   = { 30,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24 };
-                   static int list18_h_regs[32] = { 19, 18, 17, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 30, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24 };
-                   static int list18_l_regs[32] = {  3,  2,  1, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 14, 15, 13, 12,  7,  6,  5,  4, 11, 10,  9,  8 };
+                   static int list12_regs[32]   = { 30, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+                                                    0,  0, 0, 0, 0, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24 };
                    int *regs;
                    int i;
                    unsigned long int mask = 0;
                    int pc = 0;
-                   int sr = 0;
+
 
                    switch (operand->shift)
                      {
                      case 0xffe00001: regs = list12_regs; break;
-                     case 0xfff8000f: regs = list18_h_regs; break;
-                     case 0xfff8001f:
-                       regs = list18_l_regs;
-                       value &= ~0x10;  /* Do not include magic bit.  */
-                         break;
                      default:
                        /* xgettext:c-format */
-                       fprintf (stderr, _("unknown operand shift: %x\n"),
-                                operand->shift);
+                       fprintf (stderr, _("unknown operand shift: %x\n"), operand->shift );
                        abort ();
                      }
 
@@ -249,18 +374,15 @@ disassemble (bfd_vma memaddr,
                              {
                              default: mask |= (1 << regs[ i ]); break;
                                /* xgettext:c-format */
-                             case 0:
-                               fprintf (stderr, _("unknown pop reg: %d\n"), i );
-                               abort ();
+                             case 0:  fprintf (stderr, _("unknown reg: %d\n"), i ); abort ();
                              case -1: pc = 1; break;
-                             case -2: sr = 1; break;
                              }
                          }
                      }
 
                    info->fprintf_func (info->stream, "{");
 
-                   if (mask || pc || sr)
+                   if (mask || pc)
                      {
                        if (mask)
                          {
@@ -278,8 +400,7 @@ disassemble (bfd_vma memaddr,
                                  else
                                    shown_one = 1;
 
-                                 info->fprintf_func (info->stream,
-                                                     v850_reg_names[first]);
+                                 info->fprintf_func (info->stream, v850_reg_names[first]);
 
                                  for (bit++; bit < 32; bit++)
                                    if ((mask & (1 << bit)) == 0)
@@ -288,113 +409,227 @@ disassemble (bfd_vma memaddr,
                                  last = bit;
 
                                  if (last > first + 1)
-                                   info->fprintf_func (info->stream, " - %s",
-                                                       v850_reg_names[last - 1]);
+                                   {
+                                     info->fprintf_func (info->stream, " - %s", v850_reg_names[ last - 1 ]);
+                                   }
                                }
                          }
 
                        if (pc)
                          info->fprintf_func (info->stream, "%sPC", mask ? ", " : "");
-                       if (sr)
-                         info->fprintf_func (info->stream, "%sSR", (mask || pc) ? ", " : "");
                      }
 
                    info->fprintf_func (info->stream, "}");
                  }
-               break;
-
-               case V850E_IMMEDIATE16:
-                 status = info->read_memory_func (memaddr + bytes_read,
-                                                  buffer, 2, info);
-                 if (status == 0)
-                   {
-                     bytes_read += 2;
-                     value = bfd_getl16 (buffer);
-
-                     /* If this is a DISPOSE instruction with ff
-                        set to 0x10, then shift value up by 16.  */
-                     if ((insn & 0x001fffc0) == 0x00130780)
-                       value <<= 16;
-
-                     info->fprintf_func (info->stream, "0x%lx", value);
-                   }
-                 else
-                   info->memory_error_func (status, memaddr + bytes_read,
-                                            info);
                  break;
 
-               case V850E_IMMEDIATE32:
-                 status = info->read_memory_func (memaddr + bytes_read,
-                                                  buffer, 4, info);
-                 if (status == 0)
-                   {
-                     bytes_read += 4;
-                     value = bfd_getl32 (buffer);
-                     info->fprintf_func (info->stream, "0x%lx", value);
-                   }
-                 else
-                   info->memory_error_func (status, memaddr + bytes_read,
-                                            info);
+               case V850_OPERAND_CC:   info->fprintf_func (info->stream, "%s", v850_cc_names[value]); break;
+               case V850_OPERAND_FLOAT_CC:   info->fprintf_func (info->stream, "%s", v850_float_cc_names[value]); break;
+
+               default:
+                 print_value (operand->flags, memaddr, info, value);
                  break;
                }
 
-             /* Handle jmp correctly.  */
-             if (memop == 1 && opnum == 1
-                 && ((operand->flags & V850_OPERAND_REG) != 0))
+             if (opnum == 2 && opnum == memop)
                (*info->fprintf_func) (info->stream, "]");
            }
 
-         /* Close any square bracket we left open.  */
-         if (memop && opnum == memop + 2)
-           (*info->fprintf_func) (info->stream, "]");
-
          /* All done. */
          break;
        }
+    next_opcode:
       op++;
     }
 
-  if (!match)
-    {
-      if (short_op)
-       info->fprintf_func (info->stream, ".short\t0x%04lx", insn);
-      else
-       info->fprintf_func (info->stream, ".long\t0x%08lx", insn);
-    }
-
-  return bytes_read;
+  return match;
 }
 
 int
 print_insn_v850 (bfd_vma memaddr, struct disassemble_info * info)
 {
-  int status;
-  bfd_byte buffer[4];
-  unsigned long insn = 0;
+  int status, status2, match;
+  bfd_byte buffer[8];
+  int length = 0, code_length = 0;
+  unsigned long insn = 0, insn2 = 0;
+  int target_processor;
+
+  switch (info->mach)
+    {
+    case 0:
+    default:
+      target_processor = PROCESSOR_V850;
+      break;
+
+    case bfd_mach_v850e:
+      target_processor = PROCESSOR_V850E;
+      break;
+
+    case bfd_mach_v850e1:
+      target_processor = PROCESSOR_V850E;
+      break;
+
+    case bfd_mach_v850e2:
+      target_processor = PROCESSOR_V850E2;
+      break;
+
+    case bfd_mach_v850e2v3:
+      target_processor = PROCESSOR_V850E2V3;
+      break;
+    }
 
-  /* First figure out how big the opcode is.  */
   status = info->read_memory_func (memaddr, buffer, 2, info);
-  if (status == 0)
+
+  if (status)
+    {
+      info->memory_error_func (status, memaddr, info);
+      return -1;
+    }
+
+  insn = bfd_getl16 (buffer);
+
+  status2 = info->read_memory_func (memaddr+2, buffer, 2 , info);
+
+  if (!status2)
     {
-      insn = bfd_getl16 (buffer);
+      insn2 = bfd_getl16 (buffer);
+      /* fprintf (stderr, "insn2 0x%08lx\n", insn2); */
+    }
 
-      if (   (insn & 0x0600) == 0x0600
-         && (insn & 0xffe0) != 0x0620)
+  /* Special case.  */
+  if (length == 0
+      && (target_processor == PROCESSOR_V850E2
+         || target_processor == PROCESSOR_V850E2V3))
+    {
+      if ((insn & 0xffff) == 0x02e0            /* jr 32bit */
+         && !status2 && (insn2 & 0x1) == 0)
+       {
+         length = 2;
+         code_length = 6;
+       }
+      else if ((insn & 0xffe0) == 0x02e0       /* jarl 32bit */
+              && !status2 && (insn2 & 0x1) == 0)
+       {
+         length = 2;
+         code_length = 6;
+       }
+      else if ((insn & 0xffe0) == 0x06e0       /* jmp 32bit */
+              && !status2 && (insn2 & 0x1) == 0)
        {
-         /* If this is a 4 byte insn, read 4 bytes of stuff.  */
-         status = info->read_memory_func (memaddr, buffer, 4, info);
+         length = 2;
+         code_length = 6;
+       }
+    }
 
-         if (status == 0)
-           insn = bfd_getl32 (buffer);
+  if (length == 0
+      && target_processor == PROCESSOR_V850E2V3)
+    {
+      if (((insn & 0xffe0) == 0x0780           /* ld.b 23bit */
+          && !status2 && (insn2 & 0x000f) == 0x0005)
+         || ((insn & 0xffe0) == 0x07a0         /* ld.bu 23bit */
+             && !status2 && (insn2 & 0x000f) == 0x0005)
+         || ((insn & 0xffe0) == 0x0780         /* ld.h 23bit */
+             && !status2 && (insn2 & 0x000f) == 0x0007)
+         || ((insn & 0xffe0) == 0x07a0         /* ld.hu 23bit */
+             && !status2 && (insn2 & 0x000f) == 0x0007)
+         || ((insn & 0xffe0) == 0x0780         /* ld.w 23bit */
+             && !status2 && (insn2 & 0x000f) == 0x0009))
+       {
+         length = 4;
+         code_length = 6;
+       }
+      else if (((insn & 0xffe0) == 0x0780      /* st.b 23bit */
+              && !status2 && (insn2 & 0x000f) == 0x000d)
+             || ((insn & 0xffe0) == 0x07a0     /* st.h 23bit */
+                 && !status2 && (insn2 & 0x000f) == 0x000d)
+             || ((insn & 0xffe0) == 0x0780     /* st.w 23bit */
+                 && !status2 && (insn2 & 0x000f) == 0x000f))
+       {
+         length = 4;
+         code_length = 6;
        }
     }
 
-  if (status != 0)
+  if (length == 0
+      && target_processor != PROCESSOR_V850)
     {
-      info->memory_error_func (status, memaddr, info);
-      return -1;
+      if ((insn & 0xffe0) == 0x0620)           /* 32 bit MOV */
+       {
+         length = 2;
+         code_length = 6;
+       }
+      else if ((insn & 0xffc0) == 0x0780       /* prepare {list}, imm5, imm16<<16 */
+              && !status2 && (insn2 & 0x001f) == 0x0013)
+       {
+         length = 4;
+         code_length = 6;
+       }
+      else if ((insn & 0xffc0) == 0x0780       /* prepare {list}, imm5, imm16 */
+              && !status2 && (insn2 & 0x001f) == 0x000b)
+       {
+         length = 4;
+         code_length = 6;
+       }
+      else if ((insn & 0xffc0) == 0x0780       /* prepare {list}, imm5, imm32 */
+              && !status2 && (insn2 & 0x001f) == 0x001b)
+       {
+         length = 4;
+         code_length = 8;
+       }
+    }
+
+  if (length == 4
+      || (length == 0
+         && (insn & 0x0600) == 0x0600))
+    {
+      /* This is a 4 byte insn.  */
+      status = info->read_memory_func (memaddr, buffer, 4, info);
+      if (!status)
+       {
+         insn = bfd_getl32 (buffer);
+
+         if (!length)
+           length = code_length = 4;
+       }
+    }
+
+  if (code_length > length)
+    {
+      status = info->read_memory_func (memaddr + length, buffer, code_length - length, info);
+      if (status)
+       length = 0;
+    }
+
+  if (length == 0 && !status)
+    length = code_length = 2;
+
+  if (length == 2)
+    insn &= 0xffff;
+
+  match = disassemble (memaddr, info, length, insn);
+
+  if (!match)
+    {
+      int l = 0;
+
+      status = info->read_memory_func (memaddr, buffer, code_length, info);
+
+      while (l < code_length)
+       {
+         if (code_length - l == 2)
+           {
+             insn = bfd_getl16 (buffer + l) & 0xffff;
+             info->fprintf_func (info->stream, ".short\t0x%04lx", insn);
+             l += 2;
+           }
+         else
+           {
+             insn = bfd_getl32 (buffer + l);
+             info->fprintf_func (info->stream, ".long\t0x%08lx", insn);
+             l += 4;
+           }
+       }
     }
 
-  /* Make sure we tell our caller how many bytes we consumed.  */
-  return disassemble (memaddr, info, insn);
+  return code_length;
 }
index 99c168b5d7886feaea1757792fe3b7efc637ddf2..eea427c881fdb0f2f7e37c4bea04d395159e879d 100644 (file)
@@ -1,5 +1,5 @@
 /* Assemble V850 instructions.
-   Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005, 2007
+   Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005, 2007, 2010
    Free Software Foundation, Inc.
 
    This file is part of the GNU opcodes library.
    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
    MA 02110-1301, USA.  */
 
+#include <stdio.h>
 #include "sysdep.h"
 #include "opcode/v850.h"
-#include <stdio.h>
+#include "bfd.h"
 #include "opintl.h"
 
+
 /* Regular opcodes.  */
 #define OP(x)          ((x & 0x3f) << 5)
 #define OP_MASK                OP (0x3f)
 
-/* Conditional branch opcodes.  */
-#define BOP(x)         ((0x0b << 7) | (x & 0x0f))
-#define BOP_MASK       ((0x0f << 7) | 0x0f)
+/* Conditional branch opcodes (Format III).  */
+#define BOP(x)         ((0x58 << 4) | (x & 0x0f))
+#define BOP_MASK       ((0x78 << 4) | 0x0f)
+
+/* Conditional branch opcodes (Format VII).  */
+#define BOP7(x)                (0x107e0 | (x & 0xf))
+#define BOP7_MASK      (0x1ffe0 | 0xf)
 
 /* One-word opcodes.  */
 #define one(x)         ((unsigned int) (x))
 
 /* Two-word opcodes.  */
 #define two(x,y)       ((unsigned int) (x) | ((unsigned int) (y) << 16))
+
 \f
 /* The functions used to insert and extract complicated operands.  */
 
@@ -50,106 +57,134 @@ static const char * out_of_range = N_ ("displacement value is out of range");
 static const char * not_aligned  = N_ ("displacement value is not aligned");
 
 static const char * immediate_out_of_range = N_ ("immediate value is out of range");
+static const char * branch_out_of_range = N_ ("branch value out of range");
+static const char * branch_out_of_range_and_odd_offset = N_ ("branch value not in range and to odd offset");
+static const char * branch_to_odd_offset = N_ ("branch to odd offset");
+
+
+int
+v850_msg_is_out_of_range (const char* msg)
+{
+  return msg == out_of_range
+    || msg == immediate_out_of_range
+    || msg == branch_out_of_range;
+}
 
 static unsigned long
-insert_d9 (unsigned long insn, long value, const char ** errmsg)
+insert_i5div1 (unsigned long insn, long value, const char ** errmsg)
 {
-  if (value > 0xff || value < -0x100)
+  if (value > 30 || value < 2)
     {
-      if ((value % 2) != 0)
-       * errmsg = _("branch value not in range and to odd offset");
+      if (value & 1)
+       * errmsg = _(not_valid);
       else
-       * errmsg = _("branch value out of range");
+       * errmsg = _(out_of_range);
     }
-  else if ((value % 2) != 0)
-    * errmsg = _("branch to odd offset");
+  else if (value & 1)
+    * errmsg = _(not_aligned);
 
-  return insn | ((value & 0x1f0) << 7) | ((value & 0x0e) << 3);
+  value = (32 - value)/2;
+
+  return (insn | ((value << (2+16)) & 0x3c0000));
 }
 
 static unsigned long
-extract_d9 (unsigned long insn, int * invalid ATTRIBUTE_UNUSED)
+extract_i5div1 (unsigned long insn, int * invalid)
 {
-  unsigned long ret = ((insn & 0xf800) >> 7) | ((insn & 0x0070) >> 3);
-
-  if ((insn & 0x8000) != 0)
-    ret -= 0x0200;
+  unsigned long ret = (insn & 0x003c0000) >> (16+2);
+  ret = 32 - (ret * 2);
 
+  if (invalid != 0)
+    *invalid = (ret > 30 || ret < 2) ? 1 : 0;
   return ret;
 }
 
 static unsigned long
-insert_d22 (unsigned long insn, long value, const char ** errmsg)
+insert_i5div2 (unsigned long insn, long value, const char ** errmsg)
 {
-  if (value > 0x1fffff || value < -0x200000)
+  if (value > 30 || value < 4)
     {
-      if ((value % 2) != 0)
-       * errmsg = _("branch value not in range and to an odd offset");
+      if (value & 1)
+       * errmsg = _(not_valid);
       else
-       * errmsg = _("branch value out of range");
+       * errmsg = _(out_of_range);
     }
-  else if ((value % 2) != 0)
-    * errmsg = _("branch to odd offset");
+  else if (value & 1)
+    * errmsg = _(not_aligned);
 
-  return insn | ((value & 0xfffe) << 16) | ((value & 0x3f0000) >> 16);
+  value = (32 - value)/2;
+
+  return (insn | ((value << (2+16)) & 0x3c0000));
 }
 
 static unsigned long
-extract_d22 (unsigned long insn, int * invalid ATTRIBUTE_UNUSED)
+extract_i5div2 (unsigned long insn, int * invalid)
 {
-  signed long ret = ((insn & 0xfffe0000) >> 16) | ((insn & 0x3f) << 16);
+  unsigned long ret = (insn & 0x003c0000) >> (16+2);
+  ret = 32 - (ret * 2);
 
-  return (unsigned long) ((ret << 10) >> 10);
+  if (invalid != 0)
+    *invalid = (ret > 30 || ret < 4) ? 1 : 0;
+  return ret;
 }
 
 static unsigned long
-insert_d16_15 (unsigned long insn, long value, const char ** errmsg)
+insert_i5div3 (unsigned long insn, long value, const char ** errmsg)
 {
-  if (value > 0x7fff || value < -0x8000)
+  if (value > 32 || value < 2)
     {
-      if ((value % 2) != 0)
+      if (value & 1)
        * errmsg = _(not_valid);
       else
        * errmsg = _(out_of_range);
     }
-  else if ((value % 2) != 0)
+  else if (value & 1)
     * errmsg = _(not_aligned);
 
-  return insn | ((value & 0xfffe) << 16);
+  value = (32 - value)/2;
+
+  return (insn | ((value << (2+16)) & 0x3c0000));
 }
 
 static unsigned long
-extract_d16_15 (unsigned long insn, int * invalid ATTRIBUTE_UNUSED)
+extract_i5div3 (unsigned long insn, int * invalid)
 {
-  signed long ret = (insn & 0xfffe0000);
+  unsigned long ret = (insn & 0x003c0000) >> (16+2);
+  ret = 32 - (ret * 2);
 
-  return ret >> 16;
+  if (invalid != 0)
+    *invalid = (ret > 32 || ret < 2) ? 1 : 0;
+  return ret;
 }
 
 static unsigned long
-insert_d8_7 (unsigned long insn, long value, const char ** errmsg)
+insert_d5_4 (unsigned long insn, long value, const char ** errmsg)
 {
-  if (value > 0xff || value < 0)
+  if (value > 0x1f || value < 0)
     {
-      if ((value % 2) != 0)
+      if (value & 1)
        * errmsg = _(not_valid);
       else
        * errmsg = _(out_of_range);
     }
-  else if ((value % 2) != 0)
+  else if (value & 1)
     * errmsg = _(not_aligned);
 
   value >>= 1;
 
-  return insn | (value & 0x7f);
+  return insn | (value & 0x0f);
 }
 
 static unsigned long
-extract_d8_7 (unsigned long insn, int * invalid ATTRIBUTE_UNUSED)
+extract_d5_4 (unsigned long insn, int * invalid)
 {
-  unsigned long ret = (insn & 0x7f);
+  unsigned long ret = (insn & 0x0f);
+
+  ret <<= 1;
 
-  return ret << 1;
+  if (invalid != 0)
+    *invalid = 0;
+  return ret;
 }
 
 static unsigned long
@@ -158,7 +193,7 @@ insert_d8_6 (unsigned long insn, long value, const char ** errmsg)
   if (value > 0xff || value < 0)
     {
       if ((value % 4) != 0)
-       *errmsg = _(not_valid);
+       * errmsg = _(not_valid);
       else
        * errmsg = _(out_of_range);
     }
@@ -171,37 +206,147 @@ insert_d8_6 (unsigned long insn, long value, const char ** errmsg)
 }
 
 static unsigned long
-extract_d8_6 (unsigned long insn, int * invalid ATTRIBUTE_UNUSED)
+extract_d8_6 (unsigned long insn, int * invalid)
 {
   unsigned long ret = (insn & 0x7e);
 
-  return ret << 1;
+  ret <<= 1;
+
+  if (invalid != 0)
+    *invalid = 0;
+  return ret;
 }
 
 static unsigned long
-insert_d5_4 (unsigned long insn, long value, const char ** errmsg)
+insert_d8_7 (unsigned long insn, long value, const char ** errmsg)
 {
-  if (value > 0x1f || value < 0)
+  if (value > 0xff || value < 0)
     {
-      if (value & 1)
+      if ((value % 2) != 0)
        * errmsg = _(not_valid);
       else
-       *errmsg = _(out_of_range);
+       * errmsg = _(out_of_range);
     }
-  else if (value & 1)
+  else if ((value % 2) != 0)
     * errmsg = _(not_aligned);
 
   value >>= 1;
 
-  return insn | (value & 0x0f);
+  return insn | (value & 0x7f);
 }
 
 static unsigned long
-extract_d5_4 (unsigned long insn, int * invalid ATTRIBUTE_UNUSED)
+extract_d8_7 (unsigned long insn, int * invalid)
 {
-  unsigned long ret = (insn & 0x0f);
+  unsigned long ret = (insn & 0x7f);
+
+  ret <<= 1;
+
+  if (invalid != 0)
+    *invalid = 0;
+  return ret;
+}
+
+static unsigned long
+insert_v8 (unsigned long insn, long value, const char ** errmsg)
+{
+  if (value > 0xff || value < 0)
+    * errmsg = _(immediate_out_of_range);
+
+  return insn | (value & 0x1f) | ((value & 0xe0) << (27-5));
+}
+
+static unsigned long
+extract_v8 (unsigned long insn, int * invalid)
+{
+  unsigned long ret = (insn & 0x1f) | ((insn & 0x38000000) >> (27-5));
+
+  if (invalid != 0)
+    *invalid = 0;
+  return ret;
+}
+
+static unsigned long
+insert_d9 (unsigned long insn, long value, const char ** errmsg)
+{
+  if (value > 0xff || value < -0x100)
+    {
+      if ((value % 2) != 0)
+       * errmsg = branch_out_of_range_and_odd_offset;
+      else
+       * errmsg = branch_out_of_range;
+    }
+  else if ((value % 2) != 0)
+    * errmsg = branch_to_odd_offset;
+
+  return insn | ((value & 0x1f0) << 7) | ((value & 0x0e) << 3);
+}
+
+static unsigned long
+extract_d9 (unsigned long insn, int * invalid)
+{
+  unsigned long ret = ((insn & 0xf800) >> 7) | ((insn & 0x0070) >> 3);
+
+  if ((insn & 0x8000) != 0)
+    ret -= 0x0200;
+
+  if (invalid != 0)
+    *invalid = 0;
+  return ret;
+}
+
+static unsigned long
+insert_u16_loop (unsigned long insn, long value, const char ** errmsg)
+{
+  if (value < -0xffff || value > 0)
+    {
+      if ((value % 2) != 0)
+       * errmsg = branch_out_of_range_and_odd_offset;
+      else
+       * errmsg = branch_out_of_range;
+    }
+  else if ((value % 2) != 0)
+    * errmsg = branch_to_odd_offset;
+
+  return insn | ((-value & 0xfffe) << 16);
+}
+
+static unsigned long
+extract_u16_loop (unsigned long insn, int * invalid)
+{
+  long ret = (insn >> 16) & 0xfffe;
+  ret = -ret;
+
+  if (invalid != 0)
+    *invalid = 0;
+  return ret;
+}
+
+static unsigned long
+insert_d16_15 (unsigned long insn, long value, const char ** errmsg)
+{
+  if (value > 0x7fff || value < -0x8000)
+    {
+      if ((value % 2) != 0)
+       * errmsg = _(not_valid);
+      else
+       * errmsg = _(out_of_range);
+    }
+  else if ((value % 2) != 0)
+    * errmsg = _(not_aligned);
+
+  return insn | ((value & 0xfffe) << 16);
+}
+
+static unsigned long
+extract_d16_15 (unsigned long insn, int * invalid)
+{
+  signed long ret = (insn & 0xfffe0000);
+  ret >>= 16;
 
-  return ret << 1;
+  if (invalid != 0)
+    *invalid = 0;
+  return ret;
 }
 
 static unsigned long
@@ -214,17 +359,87 @@ insert_d16_16 (unsigned long insn, signed long value, const char ** errmsg)
 }
 
 static unsigned long
-extract_d16_16 (unsigned long insn, int * invalid ATTRIBUTE_UNUSED)
+extract_d16_16 (unsigned long insn, int * invalid)
 {
   signed long ret = insn & 0xfffe0000;
-
   ret >>= 16;
-
   ret |= ((insn & 0x20) >> 5);
 
+  if (invalid != 0)
+    *invalid = 0;
   return ret;
 }
 
+static unsigned long
+insert_d17_16 (unsigned long insn, long value, const char ** errmsg)
+{
+  if (value > 0xffff || value < -0x10000)
+    * errmsg = _(out_of_range);
+
+  return insn | ((value & 0xfffe) << 16) | ((value & 0x10000) >> (16 - 4));
+}
+
+static unsigned long
+extract_d17_16 (unsigned long insn, int * invalid)
+{
+  signed long ret = (insn >> 16) & 0xfffe;
+  ret |= (insn << (16 - 4)) & 0x10000;
+  ret = (ret << ((sizeof ret)*8 - 17)) >> ((sizeof ret)*8 - 17);
+
+  if (invalid != 0)
+    *invalid = 0;
+  return (unsigned long)ret;
+}
+
+static unsigned long
+insert_d22 (unsigned long insn, long value, const char ** errmsg)
+{
+  if (value > 0x1fffff || value < -0x200000)
+    {
+      if ((value % 2) != 0)
+       * errmsg = branch_out_of_range_and_odd_offset;
+      else
+       * errmsg = branch_out_of_range;
+    }
+  else if ((value % 2) != 0)
+    * errmsg = branch_to_odd_offset;
+
+  return insn | ((value & 0xfffe) << 16) | ((value & 0x3f0000) >> 16);
+}
+
+static unsigned long
+extract_d22 (unsigned long insn, int * invalid)
+{
+  signed long ret = ((insn & 0xfffe0000) >> 16) | ((insn & 0x3f) << 16);
+
+  ret = (ret << ((sizeof ret)*8 - 22)) >> ((sizeof ret)*8 - 22);
+
+  if (invalid != 0)
+    *invalid = 0;
+  return (unsigned long) ret;
+}
+
+static unsigned long
+insert_d23 (unsigned long insn, long value, const char ** errmsg)
+{
+  if (value > 0x3fffff || value < -0x400000)
+       * errmsg = out_of_range;
+
+  return insn | ((value & 0x7f) << 4) | ((value & 0x7fff80) << (16-7));
+}
+
+static unsigned long
+extract_d23 (unsigned long insn, int * invalid)
+{
+  signed long ret = ((insn >> 4) & 0x7f) | ((insn >> (16-7)) & 0x7fffff80);
+
+  ret = ((ret << ((sizeof ret)*8 - 23)) >> ((sizeof ret)*8 - 23));
+
+  if (invalid != 0)
+    *invalid = 0;
+  return (unsigned long) ret;
+}
+
 static unsigned long
 insert_i9 (unsigned long insn, signed long value, const char ** errmsg)
 {
@@ -235,15 +450,16 @@ insert_i9 (unsigned long insn, signed long value, const char ** errmsg)
 }
 
 static unsigned long
-extract_i9 (unsigned long insn, int * invalid ATTRIBUTE_UNUSED)
+extract_i9 (unsigned long insn, int * invalid)
 {
   signed long ret = insn & 0x003c0000;
 
   ret <<= 10;
   ret >>= 23;
-
   ret |= (insn & 0x1f);
 
+  if (invalid != 0)
+    *invalid = 0;
   return ret;
 }
 
@@ -259,7 +475,7 @@ insert_u9 (unsigned long insn, long v, const char ** errmsg)
 }
 
 static unsigned long
-extract_u9 (unsigned long insn, int * invalid ATTRIBUTE_UNUSED)
+extract_u9 (unsigned long insn, int * invalid)
 {
   unsigned long ret = insn & 0x003c0000;
 
@@ -267,6 +483,8 @@ extract_u9 (unsigned long insn, int * invalid ATTRIBUTE_UNUSED)
 
   ret |= (insn & 0x1f);
 
+  if (invalid != 0)
+    *invalid = 0;
   return ret;
 }
 
@@ -282,44 +500,38 @@ insert_spe (unsigned long insn, long v, const char ** errmsg)
 }
 
 static unsigned long
-extract_spe (unsigned long insn ATTRIBUTE_UNUSED,
-            int * invalid ATTRIBUTE_UNUSED)
+extract_spe (unsigned long insn ATTRIBUTE_UNUSED, int * invalid)
 {
+  if (invalid != 0)
+    *invalid = 0;
+
   return 3;
 }
 
 static unsigned long
-insert_i5div (unsigned long insn, long v, const char ** errmsg)
+insert_r4 (unsigned long insn, long v, const char ** errmsg)
 {
   unsigned long value = (unsigned long) v;
 
-  if (value > 0x1ff)
+  if (value >= 32)
     {
-      if (value & 1)
-       * errmsg = _("immediate value not in range and not even");
-      else
-       * errmsg = _(immediate_out_of_range);
+      * errmsg = _("invalid register name");
     }
-  else if (value & 1)
-    * errmsg = _("immediate value must be even");
-
-  value = 32 - value;
 
-  return insn | ((value & 0x1e) << 17);
+  return insn | ((value & 0x10) << (23-4)) | ((value & 0x0f) << (17));
 }
 
 static unsigned long
-extract_i5div (unsigned long insn, int * invalid ATTRIBUTE_UNUSED)
+extract_r4 (unsigned long insn, int * invalid)
 {
-  unsigned long ret = insn & 0x3c0000;
-
-  ret >>= 17;
-
-  ret = 32 - ret;
+  unsigned long ret;
+  ret = (insn >> 17) & 0xf;
+  ret |= (insn >> (23-4)) & 0x10;
 
+  if (invalid != 0)
+    *invalid = 0;
   return ret;
 }
-
 \f
 /* Warning: code in gas/config/tc-v850.c examines the contents of this array.
    If you change any of the values here, be sure to look for side effects in
@@ -327,169 +539,284 @@ extract_i5div (unsigned long insn, int * invalid ATTRIBUTE_UNUSED)
 const struct v850_operand v850_operands[] =
 {
 #define UNUSED 0
-  { 0, 0, NULL, NULL, 0 },
+  { 0, 0, NULL, NULL, 0, BFD_RELOC_NONE },
 
-/* The R1 field in a format 1, 6, 7, or 9 insn.  */
+/* The R1 field in a format 1, 6, 7, 9, C insn.  */
 #define R1     (UNUSED + 1)
-  { 5, 0, NULL, NULL, V850_OPERAND_REG },
+  { 5, 0, NULL, NULL, V850_OPERAND_REG, BFD_RELOC_NONE },
 
 /* As above, but register 0 is not allowed.  */
 #define R1_NOTR0 (R1 + 1)
-  { 5, 0, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0 },
+  { 5, 0, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0, BFD_RELOC_NONE },
+
+/* Even register is allowed.  */
+#define R1_EVEN (R1_NOTR0 + 1)
+  { 4, 1, NULL, NULL, V850_OPERAND_REG | V850_REG_EVEN, BFD_RELOC_NONE },
+
+/* Bang (bit reverse).  */
+#define R1_BANG (R1_EVEN + 1)
+  { 5, 0, NULL, NULL, V850_OPERAND_REG | V850_OPERAND_BANG, BFD_RELOC_NONE },
+
+/* Percent (modulo).  */
+#define R1_PERCENT (R1_BANG + 1)
+  { 5, 0, NULL, NULL, V850_OPERAND_REG | V850_OPERAND_PERCENT, BFD_RELOC_NONE },
 
-/* The R2 field in a format 1, 2, 4, 5, 6, 7, 9 insn.  */
-#define R2     (R1_NOTR0 + 1)
-  { 5, 11, NULL, NULL, V850_OPERAND_REG },
+/* The R2 field in a format 1, 2, 4, 5, 6, 7, 9, C insn.  */
+#define R2 (R1_PERCENT + 1)
+  { 5, 11, NULL, NULL, V850_OPERAND_REG, BFD_RELOC_NONE },
 
 /* As above, but register 0 is not allowed.  */
 #define R2_NOTR0 (R2 + 1)
-  { 5, 11, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0 },
+  { 5, 11, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0, BFD_RELOC_NONE },
 
-/* The imm5 field in a format 2 insn.  */
-#define I5     (R2_NOTR0 + 1)
-  { 5, 0, NULL, NULL, V850_OPERAND_SIGNED },
-
-/* The unsigned imm5 field in a format 2 insn.  */
-#define I5U    (I5 + 1)
-  { 5, 0, NULL, NULL, 0 },
+/* Even register is allowed.  */
+#define R2_EVEN (R2_NOTR0 + 1)
+  { 4, 12, NULL, NULL, V850_OPERAND_REG | V850_REG_EVEN, BFD_RELOC_NONE },
 
-/* The imm16 field in a format 6 insn.  */
-#define I16    (I5U + 1)
-  { 16, 16, NULL, NULL, V850_OPERAND_SIGNED },
+/* Reg2 in dispose instruction.  */
+#define R2_DISPOSE     (R2_EVEN + 1)
+  { 5, 16, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0, BFD_RELOC_NONE },
 
-/* The signed disp7 field in a format 4 insn.  */
-#define D7     (I16 + 1)
-  { 7, 0, NULL, NULL, 0},
+/* The R3 field in a format 11, 12, C insn.  */
+#define R3     (R2_DISPOSE + 1)
+  { 5, 27, NULL, NULL, V850_OPERAND_REG, BFD_RELOC_NONE },
 
-/* The disp16 field in a format 6 insn.  */
-#define D16_15 (D7 + 1)
-  { 15, 17, insert_d16_15, extract_d16_15, V850_OPERAND_SIGNED },
+/* As above, but register 0 is not allowed.  */
+#define R3_NOTR0       (R3 + 1)
+  { 5, 27, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0, BFD_RELOC_NONE },
 
-/* The 3 bit immediate field in format 8 insn.  */
-#define B3     (D16_15 + 1)
-  { 3, 11, NULL, NULL, 0 },
+/* As above, but odd number registers are not allowed.  */
+#define R3_EVEN        (R3_NOTR0 + 1)
+  { 4, 28, NULL, NULL, V850_OPERAND_REG | V850_REG_EVEN, BFD_RELOC_NONE },
 
-/* The 4 bit condition code in a setf instruction */
-#define CCCC   (B3 + 1)
-  { 4, 0, NULL, NULL, V850_OPERAND_CC },
+/* As above, but register 0 is not allowed.  */
+#define R3_EVEN_NOTR0  (R3_EVEN + 1)
+  { 4, 28, NULL, NULL, V850_OPERAND_REG | V850_REG_EVEN | V850_NOT_R0, BFD_RELOC_NONE },
 
-/* The unsigned DISP8 field in a format 4 insn.  */
-#define D8_7   (CCCC + 1)
-  { 7, 0, insert_d8_7, extract_d8_7, 0 },
+/* Forth register in FPU Instruction.  */
+#define R4     (R3_EVEN_NOTR0 + 1)
+  { 5, 0, insert_r4, extract_r4, V850_OPERAND_REG, BFD_RELOC_NONE },
 
-/* The unsigned DISP8 field in a format 4 insn.  */
-#define D8_6   (D8_7 + 1)
-  { 6, 1, insert_d8_6, extract_d8_6, 0 },
+/* As above, but odd number registers are not allowed.  */
+#define R4_EVEN        (R4 + 1)
+  { 4, 17, NULL, NULL, V850_OPERAND_REG | V850_REG_EVEN, BFD_RELOC_NONE },
 
-/* System register operands.  */
-#define SR1    (D8_6 + 1)
-  { 5, 0, NULL, NULL, V850_OPERAND_SRG },
+/* Stack pointer in prepare instruction.  */
+#define SP     (R4_EVEN + 1)
+  { 2, 0, insert_spe, extract_spe, V850_OPERAND_REG, BFD_RELOC_NONE },
 
 /* EP Register.  */
-#define EP     (SR1 + 1)
-  { 0, 0, NULL, NULL, V850_OPERAND_EP },
+#define EP     (SP + 1)
+  { 0, 0, NULL, NULL, V850_OPERAND_EP, BFD_RELOC_NONE },
+
+/* A list of registers in a prepare/dispose instruction.  */
+#define LIST12 (EP + 1)
+  { -1, 0xffe00001, NULL, NULL, V850E_OPERAND_REG_LIST, BFD_RELOC_NONE },
 
-/* The imm16 field (unsigned) in a format 6 insn.  */
-#define I16U   (EP + 1)
-  { 16, 16, NULL, NULL, 0},
+/* System register operands.  */
+#define SR1    (LIST12 + 1)
+  { 5, 0, NULL, NULL, V850_OPERAND_SRG, BFD_RELOC_NONE },
 
 /* The R2 field as a system register.  */
-#define SR2    (I16U + 1)
-  { 5, 11, NULL, NULL, V850_OPERAND_SRG },
+#define SR2    (SR1 + 1)
+  { 5, 11, NULL, NULL, V850_OPERAND_SRG, BFD_RELOC_NONE },
 
-/* The disp16 field in a format 8 insn.  */
-#define D16    (SR2 + 1)
-  { 16, 16, NULL, NULL, V850_OPERAND_SIGNED },
+/* FPU CC bit position.  */
+#define FFF (SR2 + 1)
+  { 3, 17, NULL, NULL, 0, BFD_RELOC_NONE },
 
-/* The DISP9 field in a format 3 insn, relaxable.  */
-#define D9_RELAX       (D16 + 1)
-  { 9, 0, insert_d9, extract_d9, V850_OPERAND_RELAX | V850_OPERAND_SIGNED | V850_OPERAND_DISP },
+/* The 4 bit condition code in a setf instruction.  */
+#define CCCC   (FFF + 1)
+  { 4, 0, NULL, NULL, V850_OPERAND_CC, BFD_RELOC_NONE },
 
-/* The DISP22 field in a format 4 insn, relaxable.
-   This _must_ follow D9_RELAX; the assembler assumes that the longer
-   version immediately follows the shorter version for relaxing.  */
-#define D22    (D9_RELAX + 1)
-  { 22, 0, insert_d22, extract_d22, V850_OPERAND_SIGNED | V850_OPERAND_DISP },
+/* Condition code in adf,sdf.  */
+#define CCCC_NOTSA     (CCCC + 1)
+  { 4, 17, NULL, NULL, V850_OPERAND_CC|V850_NOT_SA, BFD_RELOC_NONE },
 
-/* The signed disp4 field in a format 4 insn.  */
-#define D4     (D22 + 1)
-  { 4, 0, NULL, NULL, 0},
+/* Condition code in conditional moves.  */
+#define MOVCC  (CCCC_NOTSA + 1)
+  { 4, 17, NULL, NULL, V850_OPERAND_CC, BFD_RELOC_NONE },
 
-/* The unsigned disp5 field in a format 4 insn.  */
-#define D5_4   (D4 + 1)
-  { 4, 0, insert_d5_4, extract_d5_4, 0 },
+/* Condition code in FPU.  */
+#define FLOAT_CCCC     (MOVCC + 1)
+  { 4, 27, NULL, NULL, V850_OPERAND_FLOAT_CC, BFD_RELOC_NONE },
 
-/* The disp16 field in an format 7 unsigned byte load insn.  */
-#define D16_16 (D5_4 + 1)
-  { -1, 0xfffe0020, insert_d16_16, extract_d16_16, 0 },
+/* The 1 bit immediate field in format C insn.  */
+#define VI1    (FLOAT_CCCC + 1)
+  { 1, 3, NULL, NULL, 0, BFD_RELOC_NONE },
 
-/* Third register in conditional moves.  */
-#define R3     (D16_16 + 1)
-  { 5, 27, NULL, NULL, V850_OPERAND_REG },
+/* The 1 bit immediate field in format C insn.  */
+#define VC1    (VI1 + 1)
+  { 1, 0, NULL, NULL, 0, BFD_RELOC_NONE },
 
-/* Condition code in conditional moves.  */
-#define MOVCC  (R3 + 1)
-  { 4, 17, NULL, NULL, V850_OPERAND_CC },
+/* The 2 bit immediate field in format C insn.  */
+#define DI2    (VC1 + 1)
+  { 2, 17, NULL, NULL, 0, BFD_RELOC_NONE },
 
-/* The imm9 field in a multiply word.  */
-#define I9     (MOVCC + 1)
-  { 9, 0, insert_i9, extract_i9, V850_OPERAND_SIGNED },
+/* The 2 bit immediate field in format C insn.  */
+#define VI2    (DI2 + 1)
+  { 2, 0, NULL, NULL, 0, BFD_RELOC_NONE },
 
-/* The unsigned imm9 field in a multiply word.  */
-#define U9     (I9 + 1)
-  { 9, 0, insert_u9, extract_u9, 0 },
+/* The 2 bit immediate field in format C - DUP insn.  */
+#define VI2DUP (VI2 + 1)
+  { 2, 2, NULL, NULL, 0, BFD_RELOC_NONE },
 
-/* A list of registers in a prepare/dispose instruction.  */
-#define LIST12 (U9 + 1)
-  { -1, 0xffe00001, NULL, NULL, V850E_PUSH_POP },
+/* The 3 bit immediate field in format 8 insn.  */
+#define B3     (VI2DUP + 1)
+  { 3, 11, NULL, NULL, 0, BFD_RELOC_NONE },
 
-/* The IMM6 field in a call instruction.  */
-#define I6     (LIST12 + 1)
-  { 6, 0, NULL, NULL, 0 },
+/* The 3 bit immediate field in format C insn.  */
+#define DI3    (B3 + 1)
+  { 3, 17, NULL, NULL, 0, BFD_RELOC_NONE },
 
-/* The 16 bit immediate following a 32 bit instruction.  */
-#define IMM16  (I6 + 1)
-  { 16, 16, NULL, NULL, V850_OPERAND_SIGNED | V850E_IMMEDIATE16 },
+/* The 3 bit immediate field in format C insn.  */
+#define I3U    (DI3 + 1)
+  { 3, 0, NULL, NULL, 0, BFD_RELOC_NONE },
 
-/* The 32 bit immediate following a 32 bit instruction.  */
-#define IMM32  (IMM16 + 1)
-  { 0, 0, NULL, NULL, V850E_IMMEDIATE32 },
+/* The 4 bit immediate field in format C insn.  */
+#define I4U    (I3U + 1)
+  { 4, 0, NULL, NULL, 0, BFD_RELOC_NONE },
 
-/* The imm5 field in a push/pop instruction.  */
-#define IMM5   (IMM32 + 1)
-  { 5, 1, NULL, NULL, 0 },
+/* The 4 bit immediate field in fetrap.  */
+#define I4U_NOTIMM0    (I4U + 1)
+  { 4, 11, NULL, NULL, V850_NOT_IMM0, BFD_RELOC_NONE },
 
-/* Reg2 in dispose instruction.  */
-#define R2DISPOSE      (IMM5 + 1)
-  { 5, 16, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0 },
+/* The unsigned disp4 field in a sld.bu.  */
+#define D4U    (I4U_NOTIMM0 + 1)
+  { 4, 0, NULL, NULL, V850_OPERAND_DISP, BFD_RELOC_V850_TDA_4_4_OFFSET },
 
-/* Stack pointer in prepare instruction.  */
-#define SP     (R2DISPOSE + 1)
-  { 2, 19, insert_spe, extract_spe, V850_OPERAND_REG },
+/* The imm5 field in a format 2 insn.  */
+#define I5     (D4U + 1)
+  { 5, 0, NULL, NULL, V850_OPERAND_SIGNED, BFD_RELOC_NONE },
 
-/* The IMM5 field in a divide N step instruction.  */
-#define I5DIV  (SP + 1)
-  { 9, 0, insert_i5div, extract_i5div, V850_OPERAND_SIGNED },
+/* The imm5 field in a format 11 insn.  */
+#define I5DIV1 (I5 + 1)
+  { 5, 0, insert_i5div1, extract_i5div1, 0, BFD_RELOC_NONE },
 
-  /* The list of registers in a PUSHMH/POPMH instruction.  */
-#define LIST18_H (I5DIV + 1)
-  { -1, 0xfff8000f, NULL, NULL, V850E_PUSH_POP },
+#define I5DIV2 (I5DIV1 + 1)
+  { 5, 0, insert_i5div2, extract_i5div2, 0, BFD_RELOC_NONE },
 
-  /* The list of registers in a PUSHML/POPML instruction.  */
-#define LIST18_L (LIST18_H + 1)
-  /* The setting of the 4th bit is a flag to disassmble() in v850-dis.c.  */
-  { -1, 0xfff8001f, NULL, NULL, V850E_PUSH_POP },
-};
+#define I5DIV3 (I5DIV2 + 1)
+  { 5, 0, insert_i5div3, extract_i5div3, 0, BFD_RELOC_NONE },
 
-\f
-/* Reg - Reg instruction format (Format I).  */
-#define IF1    {R1, R2}
+/* The unsigned imm5 field in a format 2 insn.  */
+#define I5U    (I5DIV3 + 1)
+  { 5, 0, NULL, NULL, 0, BFD_RELOC_NONE },
 
-/* Imm - Reg instruction format (Format II).  */
-#define IF2    {I5, R2}
+/* The imm5 field in a prepare/dispose instruction.  */
+#define IMM5   (I5U + 1)
+  { 5, 1, NULL, NULL, 0, BFD_RELOC_NONE },
 
-/* Conditional branch instruction format (Format III).  */
-#define IF3    {D9_RELAX}
+/* The unsigned disp5 field in a sld.hu.  */
+#define D5_4U  (IMM5 + 1)
+  { 5, 0, insert_d5_4, extract_d5_4, V850_OPERAND_DISP, BFD_RELOC_V850_TDA_4_5_OFFSET },
+
+/* The IMM6 field in a callt instruction.  */
+#define IMM6   (D5_4U + 1)
+  { 6, 0, NULL, NULL, 0, BFD_RELOC_V850_CALLT_6_7_OFFSET },
+
+/* The signed disp7 field in a format 4 insn.  */
+#define D7U    (IMM6 + 1)
+  { 7, 0, NULL, NULL, V850_OPERAND_DISP, BFD_RELOC_V850_TDA_7_7_OFFSET },
+
+/* The unsigned DISP8 field in a format 4 insn.  */
+#define D8_7U  (D7U + 1)
+  { 8, 0, insert_d8_7, extract_d8_7, V850_OPERAND_DISP, BFD_RELOC_V850_TDA_7_8_OFFSET },
+
+/* The unsigned DISP8 field in a format 4 insn.  */
+#define D8_6U  (D8_7U + 1)
+  { 8, 0, insert_d8_6, extract_d8_6, V850_OPERAND_DISP, BFD_RELOC_V850_TDA_6_8_OFFSET },
+
+/* The unsigned DISP8 field in a format 4 insn.  */
+#define V8     (D8_6U + 1)
+  { 8, 0, insert_v8, extract_v8, 0, BFD_RELOC_NONE },
+
+/* The imm9 field in a multiply word.  */
+#define I9     (V8 + 1)
+  { 9, 0, insert_i9, extract_i9, V850_OPERAND_SIGNED, BFD_RELOC_NONE },
+
+/* The unsigned imm9 field in a multiply word.  */
+#define U9     (I9 + 1)
+  { 9, 0, insert_u9, extract_u9, 0, BFD_RELOC_NONE },
+
+/* The DISP9 field in a format 3 insn.  */
+#define D9     (U9 + 1)
+  { 9, 0, insert_d9, extract_d9, V850_OPERAND_SIGNED | V850_OPERAND_DISP | V850_PCREL, BFD_RELOC_V850_9_PCREL },
+
+/* The DISP9 field in a format 3 insn, relaxable.  */
+#define D9_RELAX       (D9 + 1)
+  { 9, 0, insert_d9, extract_d9, V850_OPERAND_RELAX | V850_OPERAND_SIGNED | V850_OPERAND_DISP | V850_PCREL, BFD_RELOC_V850_9_PCREL },
+
+/* The imm16 field in a format 6 insn.  */
+#define I16    (D9_RELAX + 1)
+  { 16, 16, NULL, NULL, V850_OPERAND_SIGNED, BFD_RELOC_16 },
+
+/* The 16 bit immediate following a 32 bit instruction.  */
+#define IMM16  (I16 + 1)
+  { 16, 32, NULL, NULL, V850E_IMMEDIATE16, BFD_RELOC_16 },
+
+/* The 16 bit immediate following a 32 bit instruction.  */
+#define IMM16LO        (IMM16 + 1)
+  { 16, 32, NULL, NULL, V850E_IMMEDIATE16, BFD_RELOC_LO16 },
+
+/* The hi 16 bit immediate following a 32 bit instruction.  */
+#define IMM16HI        (IMM16LO + 1)
+  { 16, 16, NULL, NULL, V850E_IMMEDIATE16HI, BFD_RELOC_HI16 },
+
+/* The unsigned imm16 in a format 6 insn.  */
+#define I16U   (IMM16HI + 1)
+  { 16, 16, NULL, NULL, 0, BFD_RELOC_16 },
+
+/* The disp16 field in a format 8 insn.  */
+#define D16    (I16U + 1)
+  { 16, 16, NULL, NULL, V850_OPERAND_SIGNED | V850_OPERAND_DISP, BFD_RELOC_16 },
+
+/* The disp16 field in an format 7 unsigned byte load insn.  */
+#define D16_16 (D16 + 1)
+  { 16, 0, insert_d16_16, extract_d16_16, V850_OPERAND_SIGNED | V850_OPERAND_DISP, BFD_RELOC_V850_16_SPLIT_OFFSET },
+
+/* The disp16 field in a format 6 insn.  */
+#define D16_15 (D16_16 + 1)
+  { 16, 0, insert_d16_15, extract_d16_15, V850_OPERAND_SIGNED | V850_OPERAND_DISP , BFD_RELOC_V850_16_S1 },
+
+/* The unsigned DISP16 field in a format 7 insn.  */
+#define D16_LOOP       (D16_15 + 1)
+  { 16, 0, insert_u16_loop, extract_u16_loop, V850_OPERAND_DISP | V850_PCREL, BFD_RELOC_V850_16_PCREL },
+
+/* The DISP17 field in a format 7 insn.  */
+#define D17_16 (D16_LOOP + 1)
+  { 17, 0, insert_d17_16, extract_d17_16, V850_OPERAND_SIGNED | V850_OPERAND_DISP | V850_PCREL, BFD_RELOC_V850_17_PCREL },
+
+/* The DISP22 field in a format 4 insn, relaxable.
+   This _must_ follow D9_RELAX; the assembler assumes that the longer
+   version immediately follows the shorter version for relaxing.  */
+#define D22    (D17_16 + 1)
+  { 22, 0, insert_d22, extract_d22, V850_OPERAND_SIGNED | V850_OPERAND_DISP | V850_PCREL, BFD_RELOC_V850_22_PCREL },
+
+#define D23    (D22 + 1)
+  { 23, 0, insert_d23, extract_d23, V850E_IMMEDIATE23 | V850_OPERAND_SIGNED | V850_OPERAND_DISP, BFD_RELOC_V850_23 },
+
+/* The 32 bit immediate following a 32 bit instruction.  */
+#define IMM32  (D23 + 1)
+  { 32, 32, NULL, NULL, V850E_IMMEDIATE32, BFD_RELOC_32 },
+
+#define D32_31 (IMM32 + 1)
+  { 32, 32, NULL, NULL, V850E_IMMEDIATE32 | V850_OPERAND_SIGNED | V850_OPERAND_DISP, BFD_RELOC_V850_32_ABS },
+
+#define D32_31_PCREL   (D32_31 + 1)
+  { 32, 32, NULL, NULL, V850E_IMMEDIATE32 | V850_OPERAND_SIGNED | V850_OPERAND_DISP | V850_PCREL, BFD_RELOC_V850_32_PCREL },
+
+};
+
+\f
+/* Reg - Reg instruction format (Format I).  */
+#define IF1    {R1, R2}
+
+/* Imm - Reg instruction format (Format II).  */
+#define IF2    {I5, R2}
+
+/* Conditional branch instruction format (Format III).  */
+#define IF3    {D9_RELAX}
 
 /* 3 operand instruction (Format VI).  */
 #define IF6    {I16, R1, R2}
@@ -497,6 +824,8 @@ const struct v850_operand v850_operands[] =
 /* 3 operand instruction (Format VI).  */
 #define IF6U   {I16U, R1, R2}
 
+/* Conditional branch instruction format (Format VII).  */
+#define IF7    {D17_16}
 
 \f
 /* The opcode table.
@@ -531,150 +860,131 @@ const struct v850_operand v850_operands[] =
 
 const struct v850_opcode v850_opcodes[] =
 {
-{ "breakpoint",        0xffff,                 0xffff,                 {UNUSED},               0, PROCESSOR_ALL },
-{ "dbtrap",    one (0xf840),           one (0xffff),           {UNUSED},               0, PROCESSOR_V850E1 },
-
-{ "jmp",       one (0x0060),           one (0xffe0),           {R1},                   1, PROCESSOR_ALL },
-
-/* Load/store instructions.  */
-{ "sld.bu",     one (0x0060),          one (0x07f0),           {D4,   EP,   R2_NOTR0}, 1, PROCESSOR_V850E1 },
-{ "sld.bu",     one (0x0060),          one (0x07f0),           {D4,   EP,   R2_NOTR0}, 1, PROCESSOR_V850E },
-
-{ "sld.hu",     one (0x0070),          one (0x07f0),           {D5_4, EP,   R2_NOTR0}, 1, PROCESSOR_V850E1 },
-{ "sld.hu",     one (0x0070),          one (0x07f0),           {D5_4, EP,   R2_NOTR0}, 1, PROCESSOR_V850E },
-
-{ "sld.b",     one (0x0300),           one (0x0780),           {D7,   EP,   R2},       1, PROCESSOR_V850E1 },
-{ "sld.b",     one (0x0300),           one (0x0780),           {D7,   EP,   R2},       1, PROCESSOR_V850E },
-{ "sld.b",     one (0x0300),           one (0x0780),           {D7,   EP,   R2},       1, PROCESSOR_V850 },
-
-{ "sld.h",     one (0x0400),           one (0x0780),           {D8_7, EP,   R2},       1, PROCESSOR_V850E1 },
-{ "sld.h",     one (0x0400),           one (0x0780),           {D8_7, EP,   R2},       1, PROCESSOR_V850E },
-{ "sld.h",     one (0x0400),           one (0x0780),           {D8_7, EP,   R2},       1, PROCESSOR_V850 },
-{ "sld.w",     one (0x0500),           one (0x0781),           {D8_6, EP,   R2},       1, PROCESSOR_ALL },
-{ "sst.b",     one (0x0380),           one (0x0780),           {R2,   D7,   EP},       2, PROCESSOR_ALL },
-{ "sst.h",     one (0x0480),           one (0x0780),           {R2,   D8_7, EP},       2, PROCESSOR_ALL },
-{ "sst.w",     one (0x0501),           one (0x0781),           {R2,   D8_6, EP},       2, PROCESSOR_ALL },
-
-{ "prepare",    two (0x0780, 0x0003),  two (0xffc0, 0x001f),   {LIST12, IMM5, SP},     0, PROCESSOR_NOT_V850 },
-{ "prepare",    two (0x0780, 0x000b),  two (0xffc0, 0x001f),   {LIST12, IMM5, IMM16},  0, PROCESSOR_NOT_V850 },
-{ "prepare",    two (0x0780, 0x0013),  two (0xffc0, 0x001f),   {LIST12, IMM5, IMM16},  0, PROCESSOR_NOT_V850 },
-{ "prepare",    two (0x0780, 0x001b),  two (0xffc0, 0x001f),   {LIST12, IMM5, IMM32},  0, PROCESSOR_NOT_V850 },
-{ "prepare",    two (0x0780, 0x0001),  two (0xffc0, 0x001f),   {LIST12, IMM5},         0, PROCESSOR_NOT_V850 },
-{ "dispose",   one (0x0640),           one (0xffc0),           {IMM5, LIST12, R2DISPOSE},0, PROCESSOR_NOT_V850 },
-{ "dispose",   two (0x0640, 0x0000),   two (0xffc0, 0x001f),   {IMM5, LIST12},         0, PROCESSOR_NOT_V850 },
-
-{ "ld.b",      two (0x0700, 0x0000),   two (0x07e0, 0x0000),   {D16, R1, R2},          1, PROCESSOR_ALL },
-{ "ld.h",      two (0x0720, 0x0000),   two (0x07e0, 0x0001),   {D16_15, R1, R2},       1, PROCESSOR_ALL },
-{ "ld.w",      two (0x0720, 0x0001),   two (0x07e0, 0x0001),   {D16_15, R1, R2},       1, PROCESSOR_ALL },
-{ "ld.bu",     two (0x0780, 0x0001),   two (0x07c0, 0x0001),   {D16_16, R1, R2_NOTR0}, 1, PROCESSOR_NOT_V850 },
-{ "ld.hu",     two (0x07e0, 0x0001),   two (0x07e0, 0x0001),   {D16_15, R1, R2_NOTR0}, 1, PROCESSOR_NOT_V850 },
-{ "st.b",      two (0x0740, 0x0000),   two (0x07e0, 0x0000),   {R2, D16, R1},          2, PROCESSOR_ALL },
-{ "st.h",      two (0x0760, 0x0000),   two (0x07e0, 0x0001),   {R2, D16_15, R1},       2, PROCESSOR_ALL },
-{ "st.w",      two (0x0760, 0x0001),   two (0x07e0, 0x0001),   {R2, D16_15, R1},       2, PROCESSOR_ALL },
-
-/* Byte swap/extend instructions.  */
-{ "zxb",       one (0x0080),           one (0xffe0),           {R1_NOTR0},             0, PROCESSOR_NOT_V850 },
-{ "zxh",       one (0x00c0),           one (0xffe0),           {R1_NOTR0},             0, PROCESSOR_NOT_V850 },
-{ "sxb",       one (0x00a0),           one (0xffe0),           {R1_NOTR0},             0, PROCESSOR_NOT_V850 },
-{ "sxh",       one (0x00e0),           one (0xffe0),           {R1_NOTR0},             0, PROCESSOR_NOT_V850 },
-{ "bsh",       two (0x07e0, 0x0342),   two (0x07ff, 0x07ff),   {R2, R3},               0, PROCESSOR_NOT_V850 },
-{ "bsw",       two (0x07e0, 0x0340),   two (0x07ff, 0x07ff),   {R2, R3},               0, PROCESSOR_NOT_V850 },
-{ "hsw",       two (0x07e0, 0x0344),   two (0x07ff, 0x07ff),   {R2, R3},               0, PROCESSOR_NOT_V850 },
-
-/* Jump table instructions.  */
-{ "switch",    one (0x0040),           one (0xffe0),           {R1},                   1, PROCESSOR_NOT_V850 },
-{ "callt",     one (0x0200),           one (0xffc0),           {I6},                   0, PROCESSOR_NOT_V850 },
-{ "ctret",     two (0x07e0, 0x0144),   two (0xffff, 0xffff),   {0},                    0, PROCESSOR_NOT_V850 },
-
-/* Arithmetic operation instructions.  */
-{ "setf",      two (0x07e0, 0x0000),   two (0x07f0, 0xffff),   {CCCC, R2},             0, PROCESSOR_ALL },
-{ "cmov",      two (0x07e0, 0x0320),   two (0x07e0, 0x07e1),   {MOVCC, R1, R2, R3},    0, PROCESSOR_NOT_V850 },
-{ "cmov",      two (0x07e0, 0x0300),   two (0x07e0, 0x07e1),   {MOVCC, I5, R2, R3},    0, PROCESSOR_NOT_V850 },
-
-{ "mul",       two (0x07e0, 0x0220),   two (0x07e0, 0x07ff),   {R1, R2, R3},           0, PROCESSOR_NOT_V850 },
-{ "mul",       two (0x07e0, 0x0240),   two (0x07e0, 0x07c3),   {I9, R2, R3},           0, PROCESSOR_NOT_V850 },
-{ "mulu",      two (0x07e0, 0x0222),   two (0x07e0, 0x07ff),   {R1, R2, R3},           0, PROCESSOR_NOT_V850 },
-{ "mulu",      two (0x07e0, 0x0242),   two (0x07e0, 0x07c3),   {U9, R2, R3},           0, PROCESSOR_NOT_V850 },
-
-{ "div",       two (0x07e0, 0x02c0),   two (0x07e0, 0x07ff),   {R1, R2, R3},           0, PROCESSOR_NOT_V850 },
-{ "divu",      two (0x07e0, 0x02c2),   two (0x07e0, 0x07ff),   {R1, R2, R3},           0, PROCESSOR_NOT_V850 },
-{ "divhu",     two (0x07e0, 0x0282),   two (0x07e0, 0x07ff),   {R1, R2, R3},           0, PROCESSOR_NOT_V850 },
-{ "divh",      two (0x07e0, 0x0280),   two (0x07e0, 0x07ff),   {R1, R2, R3},           0, PROCESSOR_NOT_V850 },
-{ "divh",      OP  (0x02),             OP_MASK,                {R1, R2_NOTR0},         0, PROCESSOR_ALL },
-
-{ "nop",       one (0x00),             one (0xffff),           {0},                    0, PROCESSOR_ALL },
-{ "mov",       OP  (0x10),             OP_MASK,                {I5, R2_NOTR0},         0, PROCESSOR_ALL },
-{ "mov",       one (0x0620),           one (0xffe0),           {IMM32, R1_NOTR0},      0, PROCESSOR_NOT_V850 },
-{ "mov",        OP  (0x00),            OP_MASK,                {R1, R2_NOTR0},         0, PROCESSOR_ALL },
-{ "movea",     OP  (0x31),             OP_MASK,                {I16, R1, R2_NOTR0},    0, PROCESSOR_ALL },
-{ "movhi",     OP  (0x32),             OP_MASK,                {I16U, R1, R2_NOTR0},   0, PROCESSOR_ALL },
+/* Standard instructions.  */
 { "add",       OP  (0x0e),             OP_MASK,                IF1,                    0, PROCESSOR_ALL },
 { "add",       OP  (0x12),             OP_MASK,                IF2,                    0, PROCESSOR_ALL },
+
 { "addi",      OP  (0x30),             OP_MASK,                IF6,                    0, PROCESSOR_ALL },
-{ "sub",       OP  (0x0d),             OP_MASK,                IF1,                    0, PROCESSOR_ALL },
-{ "subr",      OP  (0x0c),             OP_MASK,                IF1,                    0, PROCESSOR_ALL },
-{ "mulh",      OP  (0x17),             OP_MASK,                {I5, R2_NOTR0},         0, PROCESSOR_ALL },
-{ "mulh",      OP  (0x07),             OP_MASK,                {R1, R2_NOTR0},         0, PROCESSOR_ALL },
-{ "mulhi",     OP  (0x37),             OP_MASK,                {I16, R1, R2_NOTR0},    0, PROCESSOR_ALL },
-{ "cmp",       OP  (0x0f),             OP_MASK,                IF1,                    0, PROCESSOR_ALL },
-{ "cmp",       OP  (0x13),             OP_MASK,                IF2,                    0, PROCESSOR_ALL },
 
-/* Saturated operation instructions.  */
-{ "satadd",    OP (0x11),              OP_MASK,                {I5, R2_NOTR0},         0, PROCESSOR_ALL },
-{ "satadd",    OP (0x06),              OP_MASK,                {R1, R2_NOTR0},         0, PROCESSOR_ALL },
-{ "satsub",    OP (0x05),              OP_MASK,                {R1, R2_NOTR0},         0, PROCESSOR_ALL },
-{ "satsubi",   OP (0x33),              OP_MASK,                {I16, R1, R2_NOTR0},    0, PROCESSOR_ALL },
-{ "satsubr",   OP (0x04),              OP_MASK,                {R1, R2_NOTR0},         0, PROCESSOR_ALL },
+{ "adf",       two (0x07e0, 0x03a0),   two (0x07e0, 0x07e1),   {CCCC_NOTSA, R1, R2, R3},       0, PROCESSOR_V850E2_ALL },
 
-/* Logical operation instructions.  */
-{ "tst",       OP (0x0b),              OP_MASK,                IF1,                    0, PROCESSOR_ALL },
-{ "or",                OP (0x08),              OP_MASK,                IF1,                    0, PROCESSOR_ALL },
-{ "ori",       OP (0x34),              OP_MASK,                IF6U,                   0, PROCESSOR_ALL },
 { "and",       OP (0x0a),              OP_MASK,                IF1,                    0, PROCESSOR_ALL },
+
 { "andi",      OP (0x36),              OP_MASK,                IF6U,                   0, PROCESSOR_ALL },
-{ "xor",       OP (0x09),              OP_MASK,                IF1,                    0, PROCESSOR_ALL },
-{ "xori",      OP (0x35),              OP_MASK,                IF6U,                   0, PROCESSOR_ALL },
-{ "not",       OP (0x01),              OP_MASK,                IF1,                    0, PROCESSOR_ALL },
-{ "sar",       OP (0x15),              OP_MASK,                {I5U, R2},              0, PROCESSOR_ALL },
-{ "sar",       two (0x07e0, 0x00a0),   two (0x07e0, 0xffff),   {R1,  R2},              0, PROCESSOR_ALL },
-{ "shl",       OP  (0x16),             OP_MASK,                {I5U, R2},              0, PROCESSOR_ALL },
-{ "shl",       two (0x07e0, 0x00c0),   two (0x07e0, 0xffff),   {R1,  R2},              0, PROCESSOR_ALL },
-{ "shr",       OP  (0x14),             OP_MASK,                {I5U, R2},              0, PROCESSOR_ALL },
-{ "shr",       two (0x07e0, 0x0080),   two (0x07e0, 0xffff),   {R1,  R2},              0, PROCESSOR_ALL },
-{ "sasf",       two (0x07e0, 0x0200),  two (0x07f0, 0xffff),   {CCCC, R2},             0, PROCESSOR_NOT_V850 },
 
-/* Branch instructions.  */
        /* Signed integer.  */
-{ "bgt",       BOP (0xf),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
 { "bge",       BOP (0xe),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
-{ "blt",       BOP (0x6),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
+{ "bgt",       BOP (0xf),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
 { "ble",       BOP (0x7),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
+{ "blt",       BOP (0x6),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
        /* Unsigned integer.  */
 { "bh",                BOP (0xb),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
-{ "bnh",       BOP (0x3),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
 { "bl",                BOP (0x1),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
+{ "bnh",       BOP (0x3),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
 { "bnl",       BOP (0x9),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
        /* Common.  */
 { "be",                BOP (0x2),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
 { "bne",       BOP (0xa),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
        /* Others.  */
-{ "bv",                BOP (0x0),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
-{ "bnv",       BOP (0x8),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
-{ "bn",                BOP (0x4),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
-{ "bp",                BOP (0xc),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
 { "bc",                BOP (0x1),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
+{ "bf",                BOP (0xa),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
+{ "bn",                BOP (0x4),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
 { "bnc",       BOP (0x9),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
-{ "bz",                BOP (0x2),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
+{ "bnv",       BOP (0x8),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
 { "bnz",       BOP (0xa),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
+{ "bp",                BOP (0xc),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
 { "br",                BOP (0x5),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
 { "bsa",       BOP (0xd),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
+{ "bt",                BOP (0x2),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
+{ "bv",                BOP (0x0),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
+{ "bz",                BOP (0x2),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
 
-/* Branch macros.
+{ "bsh",       two (0x07e0, 0x0342),   two (0x07ff, 0x07ff),   {R2, R3},               0, PROCESSOR_NOT_V850 },
 
-   We use the short form in the opcode/mask fields.  The assembler
-   will twiddle bits as necessary if the long form is needed.  */
+{ "bsw",       two (0x07e0, 0x0340),   two (0x07ff, 0x07ff),   {R2, R3},               0, PROCESSOR_NOT_V850 },
 
-       /* Signed integer.  */
+{ "callt",     one (0x0200),           one (0xffc0),           {IMM6},                 0, PROCESSOR_NOT_V850 },
+
+{ "caxi",      two (0x07e0, 0x00ee),   two (0x07e0, 0x07ff),   {R1, R2, R3},           1, PROCESSOR_V850E2_ALL },
+
+{ "clr1",      two (0x87c0, 0x0000),   two (0xc7e0, 0x0000),   {B3, D16, R1},          3, PROCESSOR_ALL },
+{ "clr1",      two (0x07e0, 0x00e4),   two (0x07e0, 0xffff),   {R2, R1},               3, PROCESSOR_NOT_V850 },
+
+{ "cmov",      two (0x07e0, 0x0320),   two (0x07e0, 0x07e1),   {MOVCC, R1, R2, R3},    0, PROCESSOR_NOT_V850 },
+{ "cmov",      two (0x07e0, 0x0300),   two (0x07e0, 0x07e1),   {MOVCC, I5, R2, R3},    0, PROCESSOR_NOT_V850 },
+
+{ "cmp",       OP  (0x0f),             OP_MASK,                IF1,                    0, PROCESSOR_ALL },
+{ "cmp",       OP  (0x13),             OP_MASK,                IF2,                    0, PROCESSOR_ALL },
+
+{ "ctret",     two (0x07e0, 0x0144),   two (0xffff, 0xffff),   {0},                    0, PROCESSOR_NOT_V850 },
+
+{ "dbret",     two (0x07e0, 0x0146),   two (0xffff, 0xffff),   {0},                    0, PROCESSOR_NOT_V850 },
+
+{ "dbtrap",    one (0xf840),           one (0xffff),           {0},                    0, PROCESSOR_NOT_V850 },
+
+{ "di",                two (0x07e0, 0x0160),   two (0xffff, 0xffff),   {0},                    0, PROCESSOR_ALL },
+
+{ "dispose",   two (0x0640, 0x0000),   two (0xffc0, 0x0000),   {IMM5, LIST12, R2_DISPOSE},3, PROCESSOR_NOT_V850 },
+{ "dispose",   two (0x0640, 0x0000),   two (0xffc0, 0x001f),   {IMM5, LIST12},         0, PROCESSOR_NOT_V850 },
+
+{ "div",       two (0x07e0, 0x02c0),   two (0x07e0, 0x07ff),   {R1, R2, R3},           0, PROCESSOR_NOT_V850 },
+
+{ "divh",      two (0x07e0, 0x0280),   two (0x07e0, 0x07ff),   {R1, R2, R3},           0, PROCESSOR_NOT_V850 },
+{ "divh",      OP  (0x02),             OP_MASK,                {R1_NOTR0, R2_NOTR0},   0, PROCESSOR_ALL },
+
+{ "divhn",     two (0x07e0, 0x0280),   two (0x07e0, 0x07c3),   {I5DIV1, R1, R2, R3},   0, PROCESSOR_NOT_V850 | PROCESSOR_OPTION_EXTENSION },
+
+{ "divhu",     two (0x07e0, 0x0282),   two (0x07e0, 0x07ff),   {R1, R2, R3},           0, PROCESSOR_NOT_V850 },
+
+{ "divhun",    two (0x07e0, 0x0282),   two (0x07e0, 0x07c3),   {I5DIV1, R1, R2, R3},   0, PROCESSOR_NOT_V850 | PROCESSOR_OPTION_EXTENSION },
+{ "divn",      two (0x07e0, 0x02c0),   two (0x07e0, 0x07c3),   {I5DIV2, R1, R2, R3},   0, PROCESSOR_NOT_V850 | PROCESSOR_OPTION_EXTENSION },
+
+{ "divq",      two (0x07e0, 0x02fc),   two (0x07e0, 0x07ff),   {R1, R2, R3},           0, PROCESSOR_V850E2_ALL },
+
+{ "divqu",     two (0x07e0, 0x02fe),   two (0x07e0, 0x07ff),   {R1, R2, R3},           0, PROCESSOR_V850E2_ALL },
+
+{ "divu",      two (0x07e0, 0x02c2),   two (0x07e0, 0x07ff),   {R1, R2, R3},           0, PROCESSOR_NOT_V850 },
+
+{ "divun",     two (0x07e0, 0x02c2),   two (0x07e0, 0x07c3),   {I5DIV2, R1, R2, R3},   0, PROCESSOR_NOT_V850 | PROCESSOR_OPTION_EXTENSION },
+
+{ "ei",                two (0x87e0, 0x0160),   two (0xffff, 0xffff),   {0},                    0, PROCESSOR_ALL },
+
+{ "eiret",     two (0x07e0, 0x0148),   two (0xffff, 0xffff),   {0},                    0, PROCESSOR_V850E2_ALL },
+
+{ "feret",     two (0x07e0, 0x014a),   two (0xffff, 0xffff),   {0},                    0, PROCESSOR_V850E2_ALL },
+
+{ "fetrap",    one (0x0040),           one (0x87ff),           {I4U_NOTIMM0},          0, PROCESSOR_V850E2_ALL },
+
+{ "halt",      two (0x07e0, 0x0120),   two (0xffff, 0xffff),   {0},                    0, PROCESSOR_ALL },
+
+{ "hsh",       two (0x07e0, 0x0346),   two (0x07ff, 0x07ff),   {R2, R3},               0, PROCESSOR_V850E2_ALL },
+
+{ "hsw",       two (0x07e0, 0x0344),   two (0x07ff, 0x07ff),   {R2, R3},               0, PROCESSOR_NOT_V850 },
+
+{ "jarl",      two (0x0780, 0x0000),   two (0x07c0, 0x0001),   {D22, R2_NOTR0},        0, PROCESSOR_ALL},
+{ "jarl",      one (0x02e0),           one (0xffe0),           {D32_31_PCREL, R1_NOTR0},       0, PROCESSOR_V850E2_ALL },
+/* Gas local alias of mov imm22(not defined in spec).  */
+{ "jarl22",    two (0x0780, 0x0000),   two (0x07c0, 0x0001),   {D22, R2_NOTR0},        0, PROCESSOR_ALL | PROCESSOR_OPTION_ALIAS},
+/* Gas local alias of mov imm32(not defined in spec).  */
+{ "jarl32",    one (0x02e0),           one (0xffe0),           {D32_31_PCREL, R1_NOTR0},       0, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_ALIAS },
+{ "jarlw",     one (0x02e0),           one (0xffe0),           {D32_31_PCREL, R1_NOTR0},       0, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_ALIAS },
+
+{ "jmp",       one (0x06e0),           one (0xffe0),           {D32_31, R1},           2, PROCESSOR_V850E2_ALL },
+{ "jmp",       one (0x0060),           one (0xffe0),           {R1},                   1, PROCESSOR_ALL },
+/* Gas local alias of jmp disp22(not defined in spec).  */
+{ "jmp22",     one (0x0060),           one (0xffe0),           {R1},                   1, PROCESSOR_ALL | PROCESSOR_OPTION_ALIAS },
+/* Gas local alias of jmp disp32(not defined in spec).  */
+{ "jmp32",     one (0x06e0),           one (0xffe0),           {D32_31, R1},           2, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_ALIAS },
+{ "jmpw",      one (0x06e0),           one (0xffe0),           {D32_31, R1},           2, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_ALIAS },
+
+{ "jr",                two (0x0780, 0x0000),   two (0xffc0, 0x0001),   {D22},                  0, PROCESSOR_ALL },
+{ "jr",                one (0x02e0),           one (0xffff),           {D32_31_PCREL},         0, PROCESSOR_V850E2_ALL },
+/* Gas local alias of mov imm22(not defined in spec).  */
+{ "jr22",      two (0x0780, 0x0000),   two (0xffc0, 0x0001),   {D22},                  0, PROCESSOR_ALL | PROCESSOR_OPTION_ALIAS },
+/* Gas local alias of mov imm32(not defined in spec).  */
+{ "jr32",      one (0x02e0),           one (0xffff),           {D32_31_PCREL},         0, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_ALIAS },
+
+/* Alias of bcond (same as CA850).  */
 { "jgt",       BOP (0xf),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
 { "jge",       BOP (0xe),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
 { "jlt",       BOP (0x6),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
@@ -696,33 +1006,295 @@ const struct v850_opcode v850_opcodes[] =
 { "jnc",       BOP (0x9),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
 { "jz",                BOP (0x2),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
 { "jnz",       BOP (0xa),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
-{ "jsa",       BOP (0xd),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
 { "jbr",       BOP (0x5),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
 
-{ "jr",                one (0x0780),           two (0xffc0, 0x0001),   {D22},                  0, PROCESSOR_ALL },
-{ "jarl",      one (0x0780),           two (0x07c0, 0x0001),   {D22, R2},              0, PROCESSOR_ALL },
 
-/* Bit manipulation instructions.  */
-{ "set1",      two (0x07c0, 0x0000),   two (0xc7e0, 0x0000),   {B3, D16, R1},          2, PROCESSOR_ALL },
-{ "set1",      two (0x07e0, 0x00e0),   two (0x07e0, 0xffff),   {R2, R1},               2, PROCESSOR_NOT_V850 },
-{ "not1",      two (0x47c0, 0x0000),   two (0xc7e0, 0x0000),   {B3, D16, R1},          2, PROCESSOR_ALL },
-{ "not1",      two (0x07e0, 0x00e2),   two (0x07e0, 0xffff),   {R2, R1},               2, PROCESSOR_NOT_V850 },
-{ "clr1",      two (0x87c0, 0x0000),   two (0xc7e0, 0x0000),   {B3, D16, R1},          2, PROCESSOR_ALL },
-{ "clr1",      two (0x07e0, 0x00e4),   two (0x07e0, 0xffff),   {R2, R1},               2, PROCESSOR_NOT_V850 },
-{ "tst1",      two (0xc7c0, 0x0000),   two (0xc7e0, 0x0000),   {B3, D16, R1},          2, PROCESSOR_ALL },
-{ "tst1",      two (0x07e0, 0x00e6),   two (0x07e0, 0xffff),   {R2, R1},               2, PROCESSOR_NOT_V850 },
+{ "ldacc",     two (0x07e0, 0x0bc4),   two (0x07e0, 0xffff),   {R1, R2},               0, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_EXTENSION },
+
+{ "ld.b",      two (0x0700, 0x0000),   two (0x07e0, 0x0000),   {D16, R1, R2},          2, PROCESSOR_ALL },
+{ "ld.b",      two (0x0780, 0x0005),   two (0x07e0, 0x000f),   {D23, R1, R3},          2, PROCESSOR_V850E2_ALL },
+{ "ld.b23",    two (0x0780, 0x0005),   two (0x07e0, 0x000f),   {D23, R1, R3},          2, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_ALIAS },
+
+{ "ld.bu",     two (0x0780, 0x0001),   two (0x07c0, 0x0001),   {D16_16, R1, R2_NOTR0}, 2, PROCESSOR_NOT_V850 },
+{ "ld.bu",     two (0x07a0, 0x0005),   two (0x07e0, 0x000f),   {D23, R1, R3},          2, PROCESSOR_V850E2_ALL },
+{ "ld.bu23",   two (0x07a0, 0x0005),   two (0x07e0, 0x000f),   {D23, R1, R3},          2, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_ALIAS },
+
+{ "ld.h",      two (0x0720, 0x0000),   two (0x07e0, 0x0001),   {D16_15, R1, R2},       2, PROCESSOR_ALL },
+{ "ld.h",      two (0x0780, 0x0007),   two (0x07e0, 0x000f),   {D23, R1, R3},          2, PROCESSOR_V850E2_ALL },
+{ "ld.h23",    two (0x0780, 0x0007),   two (0x07e0, 0x000f),   {D23, R1, R3},          2, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_ALIAS },
+
+{ "ld.hu",     two (0x07e0, 0x0001),   two (0x07e0, 0x0001),   {D16_15, R1, R2_NOTR0}, 2, PROCESSOR_NOT_V850 },
+{ "ld.hu",     two (0x07a0, 0x0007),   two (0x07e0, 0x000f),   {D23, R1, R3},          2, PROCESSOR_V850E2_ALL },
+{ "ld.hu23",   two (0x07a0, 0x0007),   two (0x07e0, 0x000f),   {D23, R1, R3},          2, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_ALIAS },
+
+
+{ "ld.w",      two (0x0720, 0x0001),   two (0x07e0, 0x0001),   {D16_15, R1, R2},       2, PROCESSOR_ALL },
+{ "ld.w",      two (0x0780, 0x0009),   two (0x07e0, 0x000f),   {D23, R1, R3},          2, PROCESSOR_V850E2_ALL },
+{ "ld.w23",    two (0x0780, 0x0009),   two (0x07e0, 0x000f),   {D23, R1, R3},          2, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_ALIAS },
 
-/* Special instructions.  */
-{ "di",                two (0x07e0, 0x0160),   two (0xffff, 0xffff),   {0},                    0, PROCESSOR_ALL },
-{ "ei",                two (0x87e0, 0x0160),   two (0xffff, 0xffff),   {0},                    0, PROCESSOR_ALL },
-{ "halt",      two (0x07e0, 0x0120),   two (0xffff, 0xffff),   {0},                    0, PROCESSOR_ALL },
-{ "reti",      two (0x07e0, 0x0140),   two (0xffff, 0xffff),   {0},                    0, PROCESSOR_ALL },
-{ "trap",      two (0x07e0, 0x0100),   two (0xffe0, 0xffff),   {I5U},                  0, PROCESSOR_ALL },
 { "ldsr",      two (0x07e0, 0x0020),   two (0x07e0, 0xffff),   {R1, SR2},              0, PROCESSOR_ALL },
+
+{ "macacc",    two (0x07e0, 0x0bc0),   two (0x07e0, 0xffff),   {R1, R2},               0, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_EXTENSION },
+
+{ "mac",       two (0x07e0, 0x03c0),   two (0x07e0, 0x0fe1),   {R1, R2, R3_EVEN, R4_EVEN},     0, PROCESSOR_V850E2_ALL },
+
+{ "macu",      two (0x07e0, 0x03e0),   two (0x07e0, 0x0fe1),   {R1, R2, R3_EVEN, R4_EVEN},     0, PROCESSOR_V850E2_ALL },
+
+{ "macuacc",   two (0x07e0, 0x0bc2),   two (0x07e0, 0xffff),   {R1, R2},               0, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_EXTENSION },
+
+{ "mov",        OP  (0x00),            OP_MASK,                {R1, R2_NOTR0},         0, PROCESSOR_ALL },
+{ "mov",       OP  (0x10),             OP_MASK,                {I5, R2_NOTR0},         0, PROCESSOR_ALL },
+{ "mov",       one (0x0620),           one (0xffe0),           {IMM32, R1},            0, PROCESSOR_NOT_V850 },
+/* Gas local alias of mov imm32(not defined in spec).  */
+{ "movl",      one (0x0620),           one (0xffe0),           {IMM32, R1},            0, PROCESSOR_NOT_V850 | PROCESSOR_OPTION_ALIAS },
+
+{ "movea",     OP  (0x31),             OP_MASK,                {I16, R1, R2_NOTR0},    0, PROCESSOR_ALL },
+
+{ "movhi",     OP  (0x32),             OP_MASK,                {I16, R1, R2_NOTR0},    0, PROCESSOR_ALL },
+
+{ "mul",       two (0x07e0, 0x0220),   two (0x07e0, 0x07ff),   {R1, R2, R3},           0, PROCESSOR_NOT_V850 },
+{ "mul",       two (0x07e0, 0x0240),   two (0x07e0, 0x07c3),   {I9, R2, R3},           0, PROCESSOR_NOT_V850 },
+
+{ "mulh",      OP  (0x17),             OP_MASK,                {I5, R2_NOTR0},         0, PROCESSOR_ALL },
+{ "mulh",      OP  (0x07),             OP_MASK,                {R1, R2_NOTR0},         0, PROCESSOR_ALL },
+
+{ "mulhi",     OP  (0x37),             OP_MASK,                {I16, R1, R2_NOTR0},    0, PROCESSOR_ALL },
+
+{ "mulu",      two (0x07e0, 0x0222),   two (0x07e0, 0x07ff),   {R1, R2, R3},           0, PROCESSOR_NOT_V850 },
+{ "mulu",      two (0x07e0, 0x0242),   two (0x07e0, 0x07c3),   {U9, R2, R3},           0, PROCESSOR_NOT_V850 },
+
+{ "nop",       one (0x00),             one (0xffff),           {0},                    0, PROCESSOR_ALL },
+
+{ "not",       OP (0x01),              OP_MASK,                IF1,                    0, PROCESSOR_ALL },
+
+{ "not1",      two (0x47c0, 0x0000),   two (0xc7e0, 0x0000),   {B3, D16, R1},          3, PROCESSOR_ALL },
+{ "not1",      two (0x07e0, 0x00e2),   two (0x07e0, 0xffff),   {R2, R1},               3, PROCESSOR_NOT_V850 },
+
+{ "or",                OP (0x08),              OP_MASK,                IF1,                    0, PROCESSOR_ALL },
+
+{ "ori",       OP (0x34),              OP_MASK,                IF6U,                   0, PROCESSOR_ALL },
+
+{ "prepare",    two (0x0780, 0x0003),  two (0xffc0, 0x001f),   {LIST12, IMM5, SP},     0, PROCESSOR_NOT_V850 },
+{ "prepare",    two (0x0780, 0x000b),  two (0xffc0, 0x001f),   {LIST12, IMM5, IMM16LO},0, PROCESSOR_NOT_V850 },
+{ "prepare",    two (0x0780, 0x0013),  two (0xffc0, 0x001f),   {LIST12, IMM5, IMM16HI},0, PROCESSOR_NOT_V850 },
+{ "prepare",    two (0x0780, 0x001b),  two (0xffc0, 0x001f),   {LIST12, IMM5, IMM32},  0, PROCESSOR_NOT_V850 },
+{ "prepare",    two (0x0780, 0x0001),  two (0xffc0, 0x001f),   {LIST12, IMM5},         0, PROCESSOR_NOT_V850 },
+
+{ "reti",      two (0x07e0, 0x0140),   two (0xffff, 0xffff),   {0},                    0, PROCESSOR_ALL },
+
+{ "sar",       two (0x07e0, 0x00a2),   two (0x07e0, 0x07ff),   {R1, R2, R3},           0, PROCESSOR_V850E2_ALL },
+{ "sar",       OP (0x15),              OP_MASK,                {I5U, R2},              0, PROCESSOR_ALL },
+{ "sar",       two (0x07e0, 0x00a0),   two (0x07e0, 0xffff),   {R1,  R2},              0, PROCESSOR_ALL },
+
+{ "sasf",       two (0x07e0, 0x0200),  two (0x07f0, 0xffff),   {CCCC, R2},             0, PROCESSOR_NOT_V850 },
+
+{ "satadd",    two (0x07e0, 0x03ba),   two (0x07e0, 0x07ff),   {R1, R2, R3},           0, PROCESSOR_V850E2_ALL },
+{ "satadd",    OP (0x11),              OP_MASK,                {I5, R2_NOTR0},         0, PROCESSOR_ALL },
+{ "satadd",    OP (0x06),              OP_MASK,                {R1, R2_NOTR0},         0, PROCESSOR_ALL },
+
+{ "satsub",    two (0x07e0, 0x039a),   two (0x07e0, 0x07ff),   {R1, R2, R3},           0, PROCESSOR_V850E2_ALL },
+{ "satsub",    OP (0x05),              OP_MASK,                {R1, R2_NOTR0},         0, PROCESSOR_ALL },
+
+{ "satsubi",   OP (0x33),              OP_MASK,                {I16, R1, R2_NOTR0},    0, PROCESSOR_ALL },
+
+{ "satsubr",   OP (0x04),              OP_MASK,                {R1, R2_NOTR0},         0, PROCESSOR_ALL },
+
+{ "sbf",       two (0x07e0, 0x0380),   two (0x07e0, 0x07e1),   {CCCC_NOTSA, R1, R2, R3},       0, PROCESSOR_V850E2_ALL },
+
+{ "sch0l",     two (0x07e0, 0x0364),   two (0x07ff, 0x07ff),   {R2, R3},               0, PROCESSOR_V850E2_ALL },
+
+{ "sch0r",     two (0x07e0, 0x0360),   two (0x07ff, 0x07ff),   {R2, R3},               0, PROCESSOR_V850E2_ALL },
+
+{ "sch1l",     two (0x07e0, 0x0366),   two (0x07ff, 0x07ff),   {R2, R3},               0, PROCESSOR_V850E2_ALL },
+
+{ "sch1r",     two (0x07e0, 0x0362),   two (0x07ff, 0x07ff),   {R2, R3},               0, PROCESSOR_V850E2_ALL },
+
+{ "sdivhn",    two (0x07e0, 0x0180),   two (0x07e0, 0x07c3),   {I5DIV3, R1, R2, R3},   0, PROCESSOR_NOT_V850 | PROCESSOR_OPTION_EXTENSION },
+{ "sdivhun",   two (0x07e0, 0x0182),   two (0x07e0, 0x07c3),   {I5DIV3, R1, R2, R3},   0, PROCESSOR_NOT_V850 | PROCESSOR_OPTION_EXTENSION },
+{ "sdivn",     two (0x07e0, 0x01c0),   two (0x07e0, 0x07c3),   {I5DIV3, R1, R2, R3},   0, PROCESSOR_NOT_V850 | PROCESSOR_OPTION_EXTENSION },
+{ "sdivun",    two (0x07e0, 0x01c2),   two (0x07e0, 0x07c3),   {I5DIV3, R1, R2, R3},   0, PROCESSOR_NOT_V850 | PROCESSOR_OPTION_EXTENSION },
+
+{ "set1",      two (0x07c0, 0x0000),   two (0xc7e0, 0x0000),   {B3, D16, R1},          3, PROCESSOR_ALL },
+{ "set1",      two (0x07e0, 0x00e0),   two (0x07e0, 0xffff),   {R2, R1},               3, PROCESSOR_NOT_V850 },
+
+{ "setf",      two (0x07e0, 0x0000),   two (0x07f0, 0xffff),   {CCCC, R2},             0, PROCESSOR_ALL },
+
+{ "shl",       two (0x07e0, 0x00c2),   two (0x07e0, 0x07ff),   {R1, R2, R3},           0, PROCESSOR_V850E2_ALL },
+{ "shl",       OP  (0x16),             OP_MASK,                {I5U, R2},              0, PROCESSOR_ALL },
+{ "shl",       two (0x07e0, 0x00c0),   two (0x07e0, 0xffff),   {R1,  R2},              0, PROCESSOR_ALL },
+
+{ "shr",       two (0x07e0, 0x0082),   two (0x07e0, 0x07ff),   {R1, R2, R3},           0, PROCESSOR_V850E2_ALL },
+{ "shr",       OP  (0x14),             OP_MASK,                {I5U, R2},              0, PROCESSOR_ALL },
+{ "shr",       two (0x07e0, 0x0080),   two (0x07e0, 0xffff),   {R1,  R2},              0, PROCESSOR_ALL },
+
+{ "sld.b",     one (0x0300),           one (0x0780),           {D7U,  EP,   R2},       2, PROCESSOR_ALL },
+
+{ "sld.bu",     one (0x0060),          one (0x07f0),           {D4U,  EP,   R2_NOTR0}, 2, PROCESSOR_NOT_V850 },
+
+{ "sld.h",     one (0x0400),           one (0x0780),           {D8_7U,EP,   R2},       2, PROCESSOR_ALL },
+
+{ "sld.hu",     one (0x0070),          one (0x07f0),           {D5_4U,EP,   R2_NOTR0}, 2, PROCESSOR_NOT_V850 },
+
+{ "sld.w",     one (0x0500),           one (0x0781),           {D8_6U,EP,   R2},       2, PROCESSOR_ALL },
+
+{ "sst.b",     one (0x0380),           one (0x0780),           {R2,   D7U,  EP},       3, PROCESSOR_ALL },
+
+{ "sst.h",     one (0x0480),           one (0x0780),           {R2,   D8_7U,EP},       3, PROCESSOR_ALL },
+
+{ "sst.w",     one (0x0501),           one (0x0781),           {R2,   D8_6U,EP},       3, PROCESSOR_ALL },
+
+{ "stacch",    two (0x07e0, 0x0bca),   two (0x07ff, 0xffff),   {R2},                   0, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_EXTENSION },
+{ "staccl",    two (0x07e0, 0x0bc8),   two (0x07ff, 0xffff),   {R2},                   0, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_EXTENSION },
+
+{ "st.b",      two (0x0740, 0x0000),   two (0x07e0, 0x0000),   {R2, D16, R1},          3, PROCESSOR_ALL },
+{ "st.b",      two (0x0780, 0x000d),   two (0x07e0, 0x000f),   {R3, D23, R1},          3, PROCESSOR_V850E2_ALL },
+{ "st.b23",    two (0x0780, 0x000d),   two (0x07e0, 0x000f),   {R3, D23, R1},          3, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_ALIAS },
+
+{ "st.h",      two (0x0760, 0x0000),   two (0x07e0, 0x0001),   {R2, D16_15, R1},       3, PROCESSOR_ALL },
+{ "st.h",      two (0x07a0, 0x000d),   two (0x07e0, 0x000f),   {R3, D23, R1},          3, PROCESSOR_V850E2_ALL },
+{ "st.h23",    two (0x07a0, 0x000d),   two (0x07e0, 0x000f),   {R3, D23, R1},          3, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_ALIAS },
+
+{ "st.w",      two (0x0760, 0x0001),   two (0x07e0, 0x0001),   {R2, D16_15, R1},       3, PROCESSOR_ALL },
+{ "st.w",      two (0x0780, 0x000f),   two (0x07e0, 0x000f),   {R3, D23, R1},          3, PROCESSOR_V850E2_ALL },
+{ "st.w23",    two (0x0780, 0x000f),   two (0x07e0, 0x000f),   {R3, D23, R1},          3, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_ALIAS },
+
 { "stsr",      two (0x07e0, 0x0040),   two (0x07e0, 0xffff),   {SR1, R2},              0, PROCESSOR_ALL },
-{ "dbret",     two (0x07e0, 0x0146),   two (0xffff, 0xffff),   {UNUSED},               0, PROCESSOR_V850E1 },
-{ 0, 0, 0, {0}, 0, 0 },
 
+{ "sub",       OP  (0x0d),             OP_MASK,                IF1,                    0, PROCESSOR_ALL },
+
+{ "subr",      OP  (0x0c),             OP_MASK,                IF1,                    0, PROCESSOR_ALL },
+
+{ "switch",    one (0x0040),           one (0xffe0),           {R1_NOTR0},             0, PROCESSOR_NOT_V850 },
+
+{ "sxb",       one (0x00a0),           one (0xffe0),           {R1},                   0, PROCESSOR_NOT_V850 },
+
+{ "sxh",       one (0x00e0),           one (0xffe0),           {R1},                   0, PROCESSOR_NOT_V850 },
+
+{ "trap",      two (0x07e0, 0x0100),   two (0xffe0, 0xffff),   {I5U},                  0, PROCESSOR_ALL },
+
+{ "tst",       OP (0x0b),              OP_MASK,                IF1,                    0, PROCESSOR_ALL },
+
+{ "tst1",      two (0xc7c0, 0x0000),   two (0xc7e0, 0x0000),   {B3, D16, R1},          3, PROCESSOR_ALL },
+{ "tst1",      two (0x07e0, 0x00e6),   two (0x07e0, 0xffff),   {R2, R1},               3, PROCESSOR_NOT_V850 },
+
+{ "xor",       OP (0x09),              OP_MASK,                IF1,                    0, PROCESSOR_ALL },
+
+{ "xori",      OP (0x35),              OP_MASK,                IF6U,                   0, PROCESSOR_ALL },
+
+{ "zxb",       one (0x0080),           one (0xffe0),           {R1},                   0, PROCESSOR_NOT_V850 },
+
+{ "zxh",       one (0x00c0),           one (0xffe0),           {R1},                   0, PROCESSOR_NOT_V850 },
+
+/* Floating point operation.  */
+{ "absf.d",    two (0x07e0, 0x0458),   two (0x0fff, 0x0fff),   {R2_EVEN, R3_EVEN},                     0, PROCESSOR_V850E2V3 },
+{ "absf.s",    two (0x07e0, 0x0448),   two (0x07ff, 0x07ff),   {R2, R3},                               0, PROCESSOR_V850E2V3 },
+{ "addf.d",    two (0x07e0, 0x0470),   two (0x0fe1, 0x0fff),   {R1_EVEN, R2_EVEN, R3_EVEN},            0, PROCESSOR_V850E2V3 },
+{ "addf.s",    two (0x07e0, 0x0460),   two (0x07e0, 0x07ff),   {R1, R2, R3},                           0, PROCESSOR_V850E2V3 },
+{ "ceilf.dl",  two (0x07e2, 0x0454),   two (0x0fff, 0x0fff),   {R2_EVEN, R3_EVEN},                     0, PROCESSOR_V850E2V3 },
+{ "ceilf.dul", two (0x07f2, 0x0454),   two (0x0fff, 0x0fff),   {R2_EVEN, R3_EVEN},                     0, PROCESSOR_V850E2V3 },
+{ "ceilf.duw", two (0x07f2, 0x0450),   two (0x0fff, 0x07ff),   {R2_EVEN, R3},                          0, PROCESSOR_V850E2V3 },
+{ "ceilf.dw",  two (0x07e2, 0x0450),   two (0x0fff, 0x07ff),   {R2_EVEN, R3},                          0, PROCESSOR_V850E2V3 },
+{ "ceilf.sl",  two (0x07e2, 0x0444),   two (0x07ff, 0x0fff),   {R2, R3_EVEN},                          0, PROCESSOR_V850E2V3 },
+{ "ceilf.sul", two (0x07f2, 0x0444),   two (0x07ff, 0x0fff),   {R2, R3_EVEN},                          0, PROCESSOR_V850E2V3 },
+{ "ceilf.suw", two (0x07f2, 0x0440),   two (0x07ff, 0x07ff),   {R2, R3},                               0, PROCESSOR_V850E2V3 },
+{ "ceilf.sw",  two (0x07e2, 0x0440),   two (0x07ff, 0x07ff),   {R2, R3},                               0, PROCESSOR_V850E2V3 },
+{ "ceilf.sw",  two (0x07e2, 0x0440),   two (0x07ff, 0x07ff),   {R2, R3},                               0, PROCESSOR_V850E2V3 },
+{ "cmovf.d",   two (0x07e0, 0x0410),   two (0x0fe1, 0x0ff1),   {FFF, R1_EVEN, R2_EVEN, R3_EVEN_NOTR0}, 0, PROCESSOR_V850E2V3 },
+/* Default value for FFF is 0(not defined in spec).  */
+{ "cmovf.d",   two (0x07e0, 0x0410),   two (0x0fe1, 0x0fff),   {R1_EVEN, R2_EVEN, R3_EVEN_NOTR0},      0, PROCESSOR_V850E2V3 },
+{ "cmovf.s",   two (0x07e0, 0x0400),   two (0x07e0, 0x07f1),   {FFF, R1, R2, R3_NOTR0},                0, PROCESSOR_V850E2V3 },
+/* Default value for FFF is 0(not defined in spec).  */
+{ "cmovf.s",   two (0x07e0, 0x0400),   two (0x07e0, 0x07ff),   {R1, R2, R3_NOTR0},                     0, PROCESSOR_V850E2V3 },
+{ "cmpf.d",    two (0x07e0, 0x0430),   two (0x0fe1, 0x87f1),   {FLOAT_CCCC, R1_EVEN, R2_EVEN, FFF},    0, PROCESSOR_V850E2V3 },
+{ "cmpf.d",    two (0x07e0, 0x0430),   two (0x0fe1, 0x87ff),   {FLOAT_CCCC, R1_EVEN, R2_EVEN},         0, PROCESSOR_V850E2V3 },
+{ "cmpf.s",    two (0x07e0, 0x0420),   two (0x07e0, 0x87f1),   {FLOAT_CCCC, R1, R2, FFF},              0, PROCESSOR_V850E2V3 },
+{ "cmpf.s",    two (0x07e0, 0x0420),   two (0x07e0, 0x87ff),   {FLOAT_CCCC, R1, R2},                   0, PROCESSOR_V850E2V3 },
+{ "cvtf.dl",   two (0x07e4, 0x0454),   two (0x0fff, 0x0fff),   {R2_EVEN, R3_EVEN},                     0, PROCESSOR_V850E2V3 },
+{ "cvtf.ds",   two (0x07e3, 0x0452),   two (0x0fff, 0x07ff),   {R2_EVEN, R3},                          0, PROCESSOR_V850E2V3 },
+{ "cvtf.dul",  two (0x07f4, 0x0454),   two (0x0fff, 0x0fff),   {R2_EVEN, R3_EVEN},                     0, PROCESSOR_V850E2V3 },
+{ "cvtf.duw",  two (0x07f4, 0x0450),   two (0x0fff, 0x07ff),   {R2_EVEN, R3},                          0, PROCESSOR_V850E2V3 },
+{ "cvtf.dw",   two (0x07e4, 0x0450),   two (0x0fff, 0x07ff),   {R2_EVEN, R3},                          0, PROCESSOR_V850E2V3 },
+{ "cvtf.ld",   two (0x07e1, 0x0452),   two (0x0fff, 0x0fff),   {R2_EVEN, R3_EVEN},                     0, PROCESSOR_V850E2V3 },
+{ "cvtf.ls",   two (0x07e1, 0x0442),   two (0x0fff, 0x07ff),   {R2_EVEN, R3},                          0, PROCESSOR_V850E2V3 },
+{ "cvtf.sd",   two (0x07e2, 0x0452),   two (0x07ff, 0x0fff),   {R2, R3_EVEN},                          0, PROCESSOR_V850E2V3 },
+{ "cvtf.sl",   two (0x07e4, 0x0444),   two (0x07ff, 0x0fff),   {R2, R3_EVEN},                          0, PROCESSOR_V850E2V3 },
+{ "cvtf.sul",  two (0x07f4, 0x0444),   two (0x07ff, 0x0fff),   {R2, R3_EVEN},                          0, PROCESSOR_V850E2V3 },
+{ "cvtf.suw",  two (0x07f4, 0x0440),   two (0x07ff, 0x07ff),   {R2, R3},                               0, PROCESSOR_V850E2V3 },
+{ "cvtf.sw",   two (0x07e4, 0x0440),   two (0x07ff, 0x07ff),   {R2, R3},                               0, PROCESSOR_V850E2V3 },
+{ "cvtf.uld",  two (0x07f1, 0x0452),   two (0x0fff, 0x0fff),   {R2_EVEN, R3_EVEN},                     0, PROCESSOR_V850E2V3 },
+{ "cvtf.uls",  two (0x07f1, 0x0442),   two (0x0fff, 0x07ff),   {R2_EVEN, R3},                          0, PROCESSOR_V850E2V3 },
+{ "cvtf.uwd",  two (0x07f0, 0x0452),   two (0x07ff, 0x0fff),   {R2, R3_EVEN},                          0, PROCESSOR_V850E2V3 },
+{ "cvtf.uws",  two (0x07f0, 0x0442),   two (0x07ff, 0x07ff),   {R2, R3},                               0, PROCESSOR_V850E2V3 },
+{ "cvtf.wd",   two (0x07e0, 0x0452),   two (0x07ff, 0x0fff),   {R2, R3_EVEN},                          0, PROCESSOR_V850E2V3 },
+{ "cvtf.ws",   two (0x07e0, 0x0442),   two (0x07ff, 0x07ff),   {R2, R3},                               0, PROCESSOR_V850E2V3 },
+{ "divf.d",    two (0x07e0, 0x047e),   two (0x0fe1, 0x0fff),   {R1_EVEN, R2_EVEN, R3_EVEN},            0, PROCESSOR_V850E2V3 },
+{ "divf.s",    two (0x07e0, 0x046e),   two (0x07e0, 0x07ff),   {R1_NOTR0, R2, R3},                     0, PROCESSOR_V850E2V3 },
+{ "floorf.dl", two (0x07e3, 0x0454),   two (0x0fff, 0x0fff),   {R2_EVEN, R3_EVEN},                     0, PROCESSOR_V850E2V3 },
+{ "floorf.dul",        two (0x07f3, 0x0454),   two (0x0fff, 0x0fff),   {R2_EVEN, R3_EVEN},                     0, PROCESSOR_V850E2V3 },
+{ "floorf.duw",        two (0x07f3, 0x0450),   two (0x0fff, 0x07ff),   {R2_EVEN, R3},                          0, PROCESSOR_V850E2V3 },
+{ "floorf.dw", two (0x07e3, 0x0450),   two (0x0fff, 0x07ff),   {R2_EVEN, R3},                          0, PROCESSOR_V850E2V3 },
+{ "floorf.sl", two (0x07e3, 0x0444),   two (0x07ff, 0x0fff),   {R2, R3_EVEN},                          0, PROCESSOR_V850E2V3 },
+{ "floorf.sul",        two (0x07f3, 0x0444),   two (0x07ff, 0x0fff),   {R2, R3_EVEN},                          0, PROCESSOR_V850E2V3 },
+{ "floorf.suw",        two (0x07f3, 0x0440),   two (0x07ff, 0x07ff),   {R2, R3},                               0, PROCESSOR_V850E2V3 },
+{ "floorf.sw", two (0x07e3, 0x0440),   two (0x07ff, 0x07ff),   {R2, R3},                               0, PROCESSOR_V850E2V3 },
+{ "maddf.s",   two (0x07e0, 0x0500),   two (0x07e0, 0x0761),   {R1, R2, R3, R4},                       0, PROCESSOR_V850E2V3 },
+{ "maxf.d",    two (0x07e0, 0x0478),   two (0x0fe1, 0x0fff),   {R1_EVEN, R2_EVEN, R3_EVEN},            0, PROCESSOR_V850E2V3 },
+{ "maxf.s",    two (0x07e0, 0x0468),   two (0x07e0, 0x07ff),   {R1, R2, R3},                           0, PROCESSOR_V850E2V3 },
+{ "minf.d",    two (0x07e0, 0x047a),   two (0x0fe1, 0x0fff),   {R1_EVEN, R2_EVEN, R3_EVEN},            0, PROCESSOR_V850E2V3 },
+{ "minf.s",    two (0x07e0, 0x046a),   two (0x07e0, 0x07ff),   {R1, R2, R3},                           0, PROCESSOR_V850E2V3 },
+{ "msubf.s",   two (0x07e0, 0x0520),   two (0x07e0, 0x0761),   {R1, R2, R3, R4},                       0, PROCESSOR_V850E2V3 },
+{ "mulf.d",    two (0x07e0, 0x0474),   two (0x0fe1, 0x0fff),   {R1_EVEN, R2_EVEN, R3_EVEN},            0, PROCESSOR_V850E2V3 },
+{ "mulf.s",    two (0x07e0, 0x0464),   two (0x07e0, 0x07ff),   {R1, R2, R3},                           0, PROCESSOR_V850E2V3 },
+{ "negf.d",    two (0x07e1, 0x0458),   two (0x0fff, 0x0fff),   {R2_EVEN, R3_EVEN},                     0, PROCESSOR_V850E2V3 },
+{ "negf.s",    two (0x07e1, 0x0448),   two (0x07ff, 0x07ff),   {R2, R3},                               0, PROCESSOR_V850E2V3 },
+{ "nmaddf.s",  two (0x07e0, 0x0540),   two (0x07e0, 0x0761),   {R1, R2, R3, R4},                       0, PROCESSOR_V850E2V3 },
+{ "nmsubf.s",  two (0x07e0, 0x0560),   two (0x07e0, 0x0761),   {R1, R2, R3, R4},                       0, PROCESSOR_V850E2V3 },
+{ "recipf.d",  two (0x07e1, 0x045e),   two (0x0fff, 0x0fff),   {R2_EVEN, R3_EVEN},                     0, PROCESSOR_V850E2V3 },
+{ "recipf.s",  two (0x07e1, 0x044e),   two (0x07ff, 0x07ff),   {R2, R3},                               0, PROCESSOR_V850E2V3 },
+
+{ "roundf.dl", two (0x07e0, 0x0454),   two (0x0fff, 0x0fff),   {R2_EVEN, R3_EVEN},                     0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_EXTENSION },
+{ "roundf.dul",        two (0x07f0, 0x0454),   two (0x0fff, 0x0fff),   {R2_EVEN, R3_EVEN},                     0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_EXTENSION },
+{ "roundf.duw",        two (0x07f0, 0x0450),   two (0x0fff, 0x07ff),   {R2_EVEN, R3},                          0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_EXTENSION },
+{ "roundf.dw", two (0x07e0, 0x0450),   two (0x0fff, 0x07ff),   {R2_EVEN, R3},                          0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_EXTENSION },
+{ "roundf.sl", two (0x07e0, 0x0444),   two (0x07ff, 0x0fff),   {R2, R3_EVEN},                          0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_EXTENSION },
+{ "roundf.sul",        two (0x07f0, 0x0444),   two (0x07ff, 0x0fff),   {R2, R3_EVEN},                          0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_EXTENSION },
+{ "roundf.suw",        two (0x07f0, 0x0440),   two (0x07ff, 0x07ff),   {R2, R3},                               0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_EXTENSION },
+{ "roundf.sw", two (0x07e0, 0x0440),   two (0x07ff, 0x07ff),   {R2, R3},                               0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_EXTENSION },
+
+{ "rsqrtf.d",  two (0x07e2, 0x045e),   two (0x0fff, 0x0fff),   {R2_EVEN, R3_EVEN},                     0, PROCESSOR_V850E2V3 },
+{ "rsqrtf.s",  two (0x07e2, 0x044e),   two (0x07ff, 0x07ff),   {R2, R3},                               0, PROCESSOR_V850E2V3 },
+{ "sqrtf.d",   two (0x07e0, 0x045e),   two (0x0fff, 0x0fff),   {R2_EVEN, R3_EVEN},                     0, PROCESSOR_V850E2V3 },
+{ "sqrtf.s",   two (0x07e0, 0x044e),   two (0x07ff, 0x07ff),   {R2, R3},                               0, PROCESSOR_V850E2V3 },
+{ "subf.d",    two (0x07e0, 0x0472),   two (0x0fe1, 0x0fff),   {R1_EVEN, R2_EVEN, R3_EVEN},            0, PROCESSOR_V850E2V3 },
+{ "subf.s",    two (0x07e0, 0x0462),   two (0x07e0, 0x07ff),   {R1, R2, R3},                           0, PROCESSOR_V850E2V3 },
+{ "trfsr",     two (0x07e0, 0x0400),   two (0xffff, 0xfff1),   {FFF},                                  0, PROCESSOR_V850E2V3 },
+{ "trfsr",     two (0x07e0, 0x0400),   two (0xffff, 0xffff),   {0},                                    0, PROCESSOR_V850E2V3 },
+{ "trncf.dl",  two (0x07e1, 0x0454),   two (0x0fff, 0x0fff),   {R2_EVEN, R3_EVEN},                     0, PROCESSOR_V850E2V3 },
+{ "trncf.dul", two (0x07f1, 0x0454),   two (0x0fff, 0x0fff),   {R2_EVEN, R3_EVEN},                     0, PROCESSOR_V850E2V3 },
+{ "trncf.duw", two (0x07f1, 0x0450),   two (0x0fff, 0x07ff),   {R2_EVEN, R3},                          0, PROCESSOR_V850E2V3 },
+{ "trncf.dw",  two (0x07e1, 0x0450),   two (0x0fff, 0x07ff),   {R2_EVEN, R3},                          0, PROCESSOR_V850E2V3 },
+{ "trncf.sl",  two (0x07e1, 0x0444),   two (0x07ff, 0x0fff),   {R2, R3_EVEN},                          0, PROCESSOR_V850E2V3 },
+{ "trncf.sul", two (0x07f1, 0x0444),   two (0x07ff, 0x07ff),   {R2, R3},                       0, PROCESSOR_V850E2V3 },
+{ "trncf.suw", two (0x07f1, 0x0440),   two (0x07ff, 0x07ff),   {R2, R3},                               0, PROCESSOR_V850E2V3 },
+{ "trncf.sw",  two (0x07e1, 0x0440),   two (0x07ff, 0x07ff),   {R2, R3},                               0, PROCESSOR_V850E2V3 },
+
+  /* Special instruction (from gdb) mov 1, r0.  */
+{ "breakpoint",        one (0x0001),           one (0xffff),           {UNUSED},                               0, PROCESSOR_ALL },
+
+  /* V850e2-v3.  */
+{ "synce",     one (0x001d),           one (0xffff),           {0},                                    0, PROCESSOR_V850E2V3 },
+{ "syncm",     one (0x001e),           one (0xffff),           {0},                                    0, PROCESSOR_V850E2V3 },
+{ "syncp",     one (0x001f),           one (0xffff),           {0},                                    0, PROCESSOR_V850E2V3 },
+{ "syscall",   two (0xd7e0, 0x0160),   two (0xffe0, 0xc7ff),   {V8},                                   0, PROCESSOR_V850E2V3 },
+  /* Alias of syncp.  */
+{ "sync",      one (0x001f),           one (0xffff),           {0},                                    0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_ALIAS },
+{ "rmtrap",    one (0xf040),           one (0xffff),           {0},                                    0, PROCESSOR_V850E2V3 },
+
+
+{ "rie",       one (0x0040),           one (0xffff),           {0},                                    0, PROCESSOR_V850E2V3 },
+{ "rie",       two (0x07f0, 0x0000),   two (0x07f0, 0xffff),   {0},                                    0, PROCESSOR_V850E2V3 },
+
+{ 0, 0, 0, {0}, 0, 0 },
 } ;
 
 const int v850_num_opcodes =