OpenCores
URL https://opencores.org/ocsvn/zipcpu/zipcpu/trunk

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [sw/] [gas-zippatch.patch] - Diff between revs 202 and 206

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 202 Rev 206
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/archures.c binutils-2.27-zip/bfd/archures.c
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/archures.c binutils-2.27-zip/bfd/archures.c
--- binutils-2.27/bfd/archures.c        2016-08-03 03:36:50.000000000 -0400
--- binutils-2.27/bfd/archures.c        2016-08-03 03:36:50.000000000 -0400
+++ binutils-2.27-zip/bfd/archures.c    2017-01-04 14:22:45.000000000 -0500
+++ binutils-2.27-zip/bfd/archures.c    2017-01-04 14:22:45.000000000 -0500
@@ -525,6 +525,8 @@
@@ -525,6 +525,8 @@
 .#define bfd_mach_nios2r2      2
 .#define bfd_mach_nios2r2      2
 .  bfd_arch_visium,    {* Visium *}
 .  bfd_arch_visium,    {* Visium *}
 .#define bfd_mach_visium       1
 .#define bfd_mach_visium       1
+.  bfd_arch_zip,       {* ZipCPU *}
+.  bfd_arch_zip,       {* ZipCPU *}
+.#define bfd_mach_zip          0
+.#define bfd_mach_zip          0
 .  bfd_arch_last
 .  bfd_arch_last
 .  };
 .  };
 */
 */
@@ -655,6 +657,7 @@
@@ -655,6 +657,7 @@
 extern const bfd_arch_info_type bfd_xgate_arch;
 extern const bfd_arch_info_type bfd_xgate_arch;
 extern const bfd_arch_info_type bfd_z80_arch;
 extern const bfd_arch_info_type bfd_z80_arch;
 extern const bfd_arch_info_type bfd_z8k_arch;
 extern const bfd_arch_info_type bfd_z8k_arch;
+extern const bfd_arch_info_type bfd_zip_arch;
+extern const bfd_arch_info_type bfd_zip_arch;
 
 
 static const bfd_arch_info_type * const bfd_archures_list[] =
 static const bfd_arch_info_type * const bfd_archures_list[] =
   {
   {
@@ -744,6 +747,7 @@
@@ -744,6 +747,7 @@
     &bfd_xgate_arch,
     &bfd_xgate_arch,
     &bfd_z80_arch,
     &bfd_z80_arch,
     &bfd_z8k_arch,
     &bfd_z8k_arch,
+    &bfd_zip_arch,
+    &bfd_zip_arch,
 #endif
 #endif
   0
   0
 };
 };
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/bfd-in2.h binutils-2.27-zip/bfd/bfd-in2.h
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/bfd-in2.h binutils-2.27-zip/bfd/bfd-in2.h
--- binutils-2.27/bfd/bfd-in2.h 2016-08-03 03:36:50.000000000 -0400
--- binutils-2.27/bfd/bfd-in2.h 2016-08-03 03:36:50.000000000 -0400
+++ binutils-2.27-zip/bfd/bfd-in2.h     2017-01-04 22:04:11.000000000 -0500
+++ binutils-2.27-zip/bfd/bfd-in2.h     2017-01-04 22:04:11.000000000 -0500
@@ -2336,6 +2336,8 @@
@@ -2336,6 +2336,8 @@
 #define bfd_mach_nios2r2       2
 #define bfd_mach_nios2r2       2
   bfd_arch_visium,     /* Visium */
   bfd_arch_visium,     /* Visium */
 #define bfd_mach_visium        1
 #define bfd_mach_visium        1
+  bfd_arch_zip,        /* ZipCPU */
+  bfd_arch_zip,        /* ZipCPU */
+#define bfd_mach_zip           0
+#define bfd_mach_zip           0
   bfd_arch_last
   bfd_arch_last
   };
   };
 
 
@@ -6335,6 +6337,22 @@
@@ -6335,6 +6337,22 @@
   BFD_RELOC_VISIUM_HI16_PCREL,
   BFD_RELOC_VISIUM_HI16_PCREL,
   BFD_RELOC_VISIUM_LO16_PCREL,
   BFD_RELOC_VISIUM_LO16_PCREL,
   BFD_RELOC_VISIUM_IM16_PCREL,
   BFD_RELOC_VISIUM_IM16_PCREL,
+
+
+/* ZipCPU - 32 bit absolute value for LJMP instruction  */
+/* ZipCPU - 32 bit absolute value for LJMP instruction  */
+  BFD_RELOC_ZIP_VALUE,
+  BFD_RELOC_ZIP_VALUE,
+
+
+/* ZipCPU - 18-bit PC-relative offset for BRA (ADD #x,PC) instructions  */
+/* ZipCPU - 18-bit PC-relative offset for BRA (ADD #x,PC) instructions  */
+  BFD_RELOC_ZIP_BRANCH,
+  BFD_RELOC_ZIP_BRANCH,
+
+
+/* ZipCPU value relocations  */
+/* ZipCPU value relocations  */
+  BFD_RELOC_ZIP_OPB_IMM,
+  BFD_RELOC_ZIP_OPB_IMM,
+  BFD_RELOC_ZIP_OPB_OFFSET,
+  BFD_RELOC_ZIP_OPB_OFFSET,
+  BFD_RELOC_ZIP_OPB_PCREL,
+  BFD_RELOC_ZIP_OPB_PCREL,
+  BFD_RELOC_ZIP_MOV_OFFSET,
+  BFD_RELOC_ZIP_MOV_OFFSET,
+  BFD_RELOC_ZIP_MOV_PCREL,
+  BFD_RELOC_ZIP_MOV_PCREL,
+  BFD_RELOC_ZIP_LDI,
+  BFD_RELOC_ZIP_LDI,
+  BFD_RELOC_ZIP_LLO,
+  BFD_RELOC_ZIP_LLO,
+  BFD_RELOC_ZIP_BREV,
+  BFD_RELOC_ZIP_BREV,
   BFD_RELOC_UNUSED };
   BFD_RELOC_UNUSED };
 
 
 typedef enum bfd_reloc_code_real bfd_reloc_code_real_type;
 typedef enum bfd_reloc_code_real bfd_reloc_code_real_type;
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/config.bfd binutils-2.27-zip/bfd/config.bfd
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/config.bfd binutils-2.27-zip/bfd/config.bfd
--- binutils-2.27/bfd/config.bfd        2016-08-03 03:36:50.000000000 -0400
--- binutils-2.27/bfd/config.bfd        2016-08-03 03:36:50.000000000 -0400
+++ binutils-2.27-zip/bfd/config.bfd    2016-12-31 17:11:00.961307172 -0500
+++ binutils-2.27-zip/bfd/config.bfd    2016-12-31 17:11:00.961307172 -0500
@@ -1742,6 +1742,10 @@
@@ -1742,6 +1742,10 @@
     targ_underscore=yes
     targ_underscore=yes
     ;;
     ;;
 
 
+  zip*)
+  zip*)
+    targ_defvec=zip_elf32_vec
+    targ_defvec=zip_elf32_vec
+    ;;
+    ;;
+
+
   *-*-ieee*)
   *-*-ieee*)
     targ_defvec=ieee_vec
     targ_defvec=ieee_vec
     ;;
     ;;
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/configure binutils-2.27-zip/bfd/configure
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/configure binutils-2.27-zip/bfd/configure
--- binutils-2.27/bfd/configure 2016-08-03 04:33:36.000000000 -0400
--- binutils-2.27/bfd/configure 2016-08-03 04:33:36.000000000 -0400
+++ binutils-2.27-zip/bfd/configure     2016-12-31 17:12:22.360697343 -0500
+++ binutils-2.27-zip/bfd/configure     2016-12-31 17:12:22.360697343 -0500
@@ -14542,6 +14542,7 @@
@@ -14542,6 +14542,7 @@
     xtensa_elf32_le_vec)        tb="$tb xtensa-isa.lo xtensa-modules.lo elf32-xtensa.lo elf32.lo $elf" ;;
     xtensa_elf32_le_vec)        tb="$tb xtensa-isa.lo xtensa-modules.lo elf32-xtensa.lo elf32.lo $elf" ;;
     z80_coff_vec)               tb="$tb coff-z80.lo reloc16.lo $coffgen" ;;
     z80_coff_vec)               tb="$tb coff-z80.lo reloc16.lo $coffgen" ;;
     z8k_coff_vec)               tb="$tb coff-z8k.lo reloc16.lo $coff" ;;
     z8k_coff_vec)               tb="$tb coff-z8k.lo reloc16.lo $coff" ;;
+    zip_elf32_vec)              tb="$tb elf32-zip.lo elf32.lo $elf" ;;
+    zip_elf32_vec)              tb="$tb elf32-zip.lo elf32.lo $elf" ;;
 
 
     # These appear out of order in targets.c
     # These appear out of order in targets.c
     srec_vec)                   tb="$tb srec.lo" ;;
     srec_vec)                   tb="$tb srec.lo" ;;
@@ -14924,6 +14925,9 @@
@@ -14924,6 +14925,9 @@
   x86_64-*-netbsd* | x86_64-*-openbsd*)
   x86_64-*-netbsd* | x86_64-*-openbsd*)
        COREFILE=netbsd-core.lo
        COREFILE=netbsd-core.lo
        ;;
        ;;
+  zip*)
+  zip*)
+       COREFILE=netbsd-core.lo
+       COREFILE=netbsd-core.lo
+       ;;
+       ;;
   esac
   esac
 
 
   case "$COREFILE" in
   case "$COREFILE" in
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/configure.ac binutils-2.27-zip/bfd/configure.ac
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/configure.ac binutils-2.27-zip/bfd/configure.ac
--- binutils-2.27/bfd/configure.ac      2016-08-03 03:36:50.000000000 -0400
--- binutils-2.27/bfd/configure.ac      2016-08-03 03:36:50.000000000 -0400
+++ binutils-2.27-zip/bfd/configure.ac  2016-12-31 17:13:38.600136486 -0500
+++ binutils-2.27-zip/bfd/configure.ac  2016-12-31 17:13:38.600136486 -0500
@@ -717,6 +717,7 @@
@@ -717,6 +717,7 @@
     xtensa_elf32_le_vec)        tb="$tb xtensa-isa.lo xtensa-modules.lo elf32-xtensa.lo elf32.lo $elf" ;;
     xtensa_elf32_le_vec)        tb="$tb xtensa-isa.lo xtensa-modules.lo elf32-xtensa.lo elf32.lo $elf" ;;
     z80_coff_vec)               tb="$tb coff-z80.lo reloc16.lo $coffgen" ;;
     z80_coff_vec)               tb="$tb coff-z80.lo reloc16.lo $coffgen" ;;
     z8k_coff_vec)               tb="$tb coff-z8k.lo reloc16.lo $coff" ;;
     z8k_coff_vec)               tb="$tb coff-z8k.lo reloc16.lo $coff" ;;
+    zip_elf32_vec)              tb="$tb elf32-zip.lo elf32.lo $elf" ;;
+    zip_elf32_vec)              tb="$tb elf32-zip.lo elf32.lo $elf" ;;
 
 
     # These appear out of order in targets.c
     # These appear out of order in targets.c
     srec_vec)                   tb="$tb srec.lo" ;;
     srec_vec)                   tb="$tb srec.lo" ;;
@@ -1092,6 +1093,9 @@
@@ -1092,6 +1093,9 @@
   x86_64-*-netbsd* | x86_64-*-openbsd*)
   x86_64-*-netbsd* | x86_64-*-openbsd*)
        COREFILE=netbsd-core.lo
        COREFILE=netbsd-core.lo
        ;;
        ;;
+  zip*)
+  zip*)
+       COREFILE=netbsd-core.lo
+       COREFILE=netbsd-core.lo
+       ;;
+       ;;
   esac
   esac
 
 
   case "$COREFILE" in
   case "$COREFILE" in
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/cpu-zip.c binutils-2.27-zip/bfd/cpu-zip.c
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/cpu-zip.c binutils-2.27-zip/bfd/cpu-zip.c
--- binutils-2.27/bfd/cpu-zip.c 1969-12-31 19:00:00.000000000 -0500
--- binutils-2.27/bfd/cpu-zip.c 1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/bfd/cpu-zip.c     2017-01-04 14:26:27.000000000 -0500
+++ binutils-2.27-zip/bfd/cpu-zip.c     2017-01-04 14:26:27.000000000 -0500
@@ -0,0 +1,65 @@
@@ -0,0 +1,65 @@
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+//
+//
+// Filename:   tc-zip.c
+// Filename:   tc-zip.c
+//
+//
+// Project:    Zip CPU backend for GNU Binutils
+// Project:    Zip CPU backend for GNU Binutils
+//
+//
+// Purpose:    BFD support for the Zip CPU architecture.
+// Purpose:    BFD support for the Zip CPU architecture.
+//
+//
+//             This file is part of BFD, the Binary File Descriptor library.
+//             This file is part of BFD, the Binary File Descriptor library.
+//
+//
+// Creator:    Dan Gisselquist, Ph.D.
+// Creator:    Dan Gisselquist, Ph.D.
+//             Gisselquist Technology, LLC
+//             Gisselquist Technology, LLC
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+//
+//
+// Copyright (C) 2016-2017, Gisselquist Technology, LLC
+// Copyright (C) 2016-2017, Gisselquist Technology, LLC
+//
+//
+// This program is free software (firmware): you can redistribute it and/or
+// This program is free software (firmware): you can redistribute it and/or
+// modify it under the terms of  the GNU General Public License as published
+// modify it under the terms of  the GNU General Public License as published
+// by the Free Software Foundation, either version 3 of the License, or (at
+// by the Free Software Foundation, either version 3 of the License, or (at
+// your option) any later version.
+// your option) any later version.
+//
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
+// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+// for more details.
+//
+//
+// You should have received a copy of the GNU General Public License along
+// You should have received a copy of the GNU General Public License along
+// with this program.  (It's in the $(ROOT)/doc directory, run make with no
+// with this program.  (It's in the $(ROOT)/doc directory, run make with no
+// target there if the PDF file isn't present.)  If not, see
+// target there if the PDF file isn't present.)  If not, see
+// <http://www.gnu.org/licenses/> for a copy.
+// <http://www.gnu.org/licenses/> for a copy.
+//
+//
+// License:    GPL, v3, as defined and found on www.gnu.org,
+// License:    GPL, v3, as defined and found on www.gnu.org,
+//             http://www.gnu.org/licenses/gpl.html
+//             http://www.gnu.org/licenses/gpl.html
+//
+//
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+#include "sysdep.h"
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "libbfd.h"
+
+
+const bfd_arch_info_type
+const bfd_arch_info_type
+bfd_zip_arch =
+bfd_zip_arch =
+{
+{
+  32,                          // There's 32 bits_per_word.
+  32,                          // There's 32 bits_per_word.
+  32,                          // There's 34 bits_per_address.
+  32,                          // There's 34 bits_per_address.
+  8,                           // There's 32 bits_per_byte.
+  8,                           // There's 32 bits_per_byte.
+  bfd_arch_zip,                        // One of enum bfd_architecture, defined
+  bfd_arch_zip,                        // One of enum bfd_architecture, defined
+                               // in archures.c and provided in
+                               // in archures.c and provided in
+                               // generated header files.
+                               // generated header files.
+  bfd_mach_zip,                        // Random BFD-internal number for this
+  bfd_mach_zip,                        // Random BFD-internal number for this
+                               // machine, similarly listed in
+                               // machine, similarly listed in
+                               // archures.c.  Not emitted in output.
+                               // archures.c.  Not emitted in output.
+  "zip",                       // The arch_name.
+  "zip",                       // The arch_name.
+  "zip",                       // The printable name is the same.
+  "zip",                       // The printable name is the same.
+  2,                           // Section alignment power; each section
+  2,                           // Section alignment power; each section
+                               // is aligned to (only) 2^2 (i.e. 4) bytes.
+                               // is aligned to (only) 2^2 (i.e. 4) bytes.
+  TRUE,                                // This is the default "machine".
+  TRUE,                                // This is the default "machine".
+  bfd_default_compatible,      // Architecture comparison function
+  bfd_default_compatible,      // Architecture comparison function
+  bfd_default_scan,            // String to architecture conversion
+  bfd_default_scan,            // String to architecture conversion
+  bfd_arch_default_fill,       // Default fill.
+  bfd_arch_default_fill,       // Default fill.
+  NULL                         // Pointer to next bfd_arch_info_type in
+  NULL                         // Pointer to next bfd_arch_info_type in
+                               // the same family.
+                               // the same family.
+};
+};
+
+
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/doc/archures.texi binutils-2.27-zip/bfd/doc/archures.texi
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/doc/archures.texi binutils-2.27-zip/bfd/doc/archures.texi
--- binutils-2.27/bfd/doc/archures.texi 2016-08-03 04:36:22.000000000 -0400
--- binutils-2.27/bfd/doc/archures.texi 2016-08-03 04:36:22.000000000 -0400
+++ binutils-2.27-zip/bfd/doc/archures.texi     2016-12-31 17:14:43.103668704 -0500
+++ binutils-2.27-zip/bfd/doc/archures.texi     2016-12-31 17:14:43.103668704 -0500
@@ -492,6 +492,8 @@
@@ -492,6 +492,8 @@
 #define bfd_mach_nios2r2       2
 #define bfd_mach_nios2r2       2
   bfd_arch_visium,     /* Visium */
   bfd_arch_visium,     /* Visium */
 #define bfd_mach_visium        1
 #define bfd_mach_visium        1
+  bfd_mach_zip,
+  bfd_mach_zip,
+#define bfd_mach_zip           0
+#define bfd_mach_zip           0
   bfd_arch_last
   bfd_arch_last
   @};
   @};
 @end example
 @end example
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/doc/bfd.info binutils-2.27-zip/bfd/doc/bfd.info
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/doc/bfd.info binutils-2.27-zip/bfd/doc/bfd.info
--- binutils-2.27/bfd/doc/bfd.info      2016-08-03 04:36:22.000000000 -0400
--- binutils-2.27/bfd/doc/bfd.info      2016-08-03 04:36:22.000000000 -0400
+++ binutils-2.27-zip/bfd/doc/bfd.info  2017-01-04 14:40:21.000000000 -0500
+++ binutils-2.27-zip/bfd/doc/bfd.info  2017-01-04 14:40:21.000000000 -0500
@@ -8466,6 +8466,8 @@
@@ -8466,6 +8466,8 @@
      #define bfd_mach_nios2r2       2
      #define bfd_mach_nios2r2       2
        bfd_arch_visium,     /* Visium */
        bfd_arch_visium,     /* Visium */
      #define bfd_mach_visium        1
      #define bfd_mach_visium        1
+       bfd_arch_zip,        /* ZipCPU */
+       bfd_arch_zip,        /* ZipCPU */
+     #define bfd_mach_zip           0
+     #define bfd_mach_zip           0
        bfd_arch_last
        bfd_arch_last
        };
        };
 
 
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/doc/reloc.texi binutils-2.27-zip/bfd/doc/reloc.texi
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/doc/reloc.texi binutils-2.27-zip/bfd/doc/reloc.texi
--- binutils-2.27/bfd/doc/reloc.texi    2016-08-03 04:36:22.000000000 -0400
--- binutils-2.27/bfd/doc/reloc.texi    2016-08-03 04:36:22.000000000 -0400
+++ binutils-2.27-zip/bfd/doc/reloc.texi        2016-12-31 17:17:15.950640091 -0500
+++ binutils-2.27-zip/bfd/doc/reloc.texi        2016-12-31 17:17:15.950640091 -0500
@@ -4214,6 +4214,19 @@
@@ -4214,6 +4214,19 @@
 @deffnx {} BFD_RELOC_VISIUM_IM16_PCREL
 @deffnx {} BFD_RELOC_VISIUM_IM16_PCREL
 Visium Relocations.
 Visium Relocations.
 @end deffn
 @end deffn
+@deffn {} BFD_RELOC_ZIP_VALUE
+@deffn {} BFD_RELOC_ZIP_VALUE
+@deffnx {} BFD_RELOC_OPB_IMM
+@deffnx {} BFD_RELOC_OPB_IMM
+@deffnx {} BFD_RELOC_OPB_OFFSET
+@deffnx {} BFD_RELOC_OPB_OFFSET
+@deffnx {} BFD_RELOC_OPB_PCREL
+@deffnx {} BFD_RELOC_OPB_PCREL
+@deffnx {} BFD_RELOC_OPB_GOTREL
+@deffnx {} BFD_RELOC_OPB_GOTREL
+@deffnx {} BFD_RELOC_MOV_OFFSET
+@deffnx {} BFD_RELOC_MOV_OFFSET
+@deffnx {} BFD_RELOC_MOV_PCREL
+@deffnx {} BFD_RELOC_MOV_PCREL
+@deffnx {} BFD_RELOC_MOV_GOTREL
+@deffnx {} BFD_RELOC_MOV_GOTREL
+@deffnx {} BFD_RELOC_ZIP_LDI
+@deffnx {} BFD_RELOC_ZIP_LDI
+@deffnx {} BFD_RELOC_ZIP_LLO
+@deffnx {} BFD_RELOC_ZIP_LLO
+@deffnx {} BFD_RELOC_ZIP_LHI
+@deffnx {} BFD_RELOC_ZIP_LHI
+ZipCPU relocations
+ZipCPU relocations
+@end deffn
+@end deffn
 
 
 @example
 @example
 
 
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/elf32-zip.c binutils-2.27-zip/bfd/elf32-zip.c
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/elf32-zip.c binutils-2.27-zip/bfd/elf32-zip.c
--- binutils-2.27/bfd/elf32-zip.c       1969-12-31 19:00:00.000000000 -0500
--- binutils-2.27/bfd/elf32-zip.c       1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/bfd/elf32-zip.c   2017-01-24 13:54:25.214097101 -0500
+++ binutils-2.27-zip/bfd/elf32-zip.c   2017-01-24 13:54:25.214097101 -0500
@@ -0,0 +1,1134 @@
@@ -0,0 +1,1134 @@
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+//
+//
+// Filename:   tc-zip.c
+// Filename:   tc-zip.c
+//
+//
+// Project:    Zip CPU backend for GNU Binutils
+// Project:    Zip CPU backend for GNU Binutils
+//
+//
+// Purpose:    Zip-specific support for 32-bit ELF.
+// Purpose:    Zip-specific support for 32-bit ELF.
+//
+//
+//     This file is part of BFD, the Binary File Descriptor library.
+//     This file is part of BFD, the Binary File Descriptor library.
+//
+//
+// Creator:    Dan Gisselquist, Ph.D.
+// Creator:    Dan Gisselquist, Ph.D.
+//             Gisselquist Technology, LLC
+//             Gisselquist Technology, LLC
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+//
+//
+// Copyright (C) 2016, Gisselquist Technology, LLC
+// Copyright (C) 2016, Gisselquist Technology, LLC
+//
+//
+// This program is free software (firmware): you can redistribute it and/or
+// This program is free software (firmware): you can redistribute it and/or
+// modify it under the terms of  the GNU General Public License as published
+// modify it under the terms of  the GNU General Public License as published
+// by the Free Software Foundation, either version 3 of the License, or (at
+// by the Free Software Foundation, either version 3 of the License, or (at
+// your option) any later version.
+// your option) any later version.
+//
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
+// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+// for more details.
+//
+//
+// You should have received a copy of the GNU General Public License along
+// You should have received a copy of the GNU General Public License along
+// with this program.  (It's in the $(ROOT)/doc directory, run make with no
+// with this program.  (It's in the $(ROOT)/doc directory, run make with no
+// target there if the PDF file isn't present.)  If not, see
+// target there if the PDF file isn't present.)  If not, see
+// <http://www.gnu.org/licenses/> for a copy.
+// <http://www.gnu.org/licenses/> for a copy.
+//
+//
+// License:    GPL, v3, as defined and found on www.gnu.org,
+// License:    GPL, v3, as defined and found on www.gnu.org,
+//             http://www.gnu.org/licenses/gpl.html
+//             http://www.gnu.org/licenses/gpl.html
+//
+//
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+#include "sysdep.h"
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf-bfd.h"
+#include "elf/zip.h"
+#include "elf/zip.h"
+#include <limits.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdint.h>
+
+
+#define        zip_relocation  bfd_elf_generic_reloc
+#define        zip_relocation  bfd_elf_generic_reloc
+
+
+static bfd_reloc_status_type
+static bfd_reloc_status_type
+zip_brev_relocation(bfd *, arelent *, asymbol *, void *, asection *,
+zip_brev_relocation(bfd *, arelent *, asymbol *, void *, asection *,
+               bfd *, char **error_messsage);
+               bfd *, char **error_messsage);
+static uint32_t zip_bitreverse(uint32_t v);
+static uint32_t zip_bitreverse(uint32_t v);
+
+
+/* Forward declarations.  */
+/* Forward declarations.  */
+static reloc_howto_type zip_elf_howto_table [] =
+static reloc_howto_type zip_elf_howto_table [] =
+{
+{
+  /* This reloc does nothing.  */
+  /* This reloc does nothing.  */
+  HOWTO (R_ZIP_NONE,           /* type */
+  HOWTO (R_ZIP_NONE,           /* type */
+        0,                     /* rightshift */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        32,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        complain_overflow_dont, /* complain_on_overflow */
+        zip_relocation,        /* special_function */
+        zip_relocation,        /* special_function */
+        "R_ZIP_NONE",          /* name */
+        "R_ZIP_NONE",          /* name */
+        FALSE,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0,                     /* src_mask */
+        0,                     /* dst_mask */
+        0,                     /* dst_mask */
+        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
+
+
+  /* A 32 bit absolute relocation.  */
+  /* A 32 bit absolute relocation.  */
+  HOWTO (R_ZIP_VALUE,          /* type */
+  HOWTO (R_ZIP_VALUE,          /* type */
+        0,                     /* rightshift */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        32,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        complain_overflow_dont, /* complain_on_overflow */
+        zip_relocation,        /* special_function */
+        zip_relocation,        /* special_function */
+        "R_ZIP_VALUE",         /* name */
+        "R_ZIP_VALUE",         /* name */
+        FALSE,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
+        0x00000000,            /* src_mask */
+        0x00000000,            /* src_mask */
+        0xffffffff,            /* dst_mask */
+        0xffffffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
+
+
+  HOWTO (R_ZIP_BREV,           /* type -- LDIHI, but with bitreverse */
+  HOWTO (R_ZIP_BREV,           /* type -- LDIHI, but with bitreverse */
+        0,                     /* rightshift */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        16,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        0,                     /* bitpos */
+        complain_overflow_bitfield, /* complain_on_overflow */
+        complain_overflow_bitfield, /* complain_on_overflow */
+        zip_brev_relocation,    /* special_function--needed for the bitreverse */
+        zip_brev_relocation,    /* special_function--needed for the bitreverse */
+        "R_ZIP_BREV",          /* name */
+        "R_ZIP_BREV",          /* name */
+        FALSE,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0,                     /* src_mask */
+        0x0003ffff,            /* dst_mask */
+        0x0003ffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
+
+
+  HOWTO (R_ZIP_LLO,            /* type */
+  HOWTO (R_ZIP_LLO,            /* type */
+        0,                     /* rightshift */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        23,                    /* bitsize */
+        23,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* don't complain_on_overflow */
+        complain_overflow_dont, /* don't complain_on_overflow */
+        zip_relocation,         /* special_function */
+        zip_relocation,         /* special_function */
+        "R_ZIP_LLO",           /* name */
+        "R_ZIP_LLO",           /* name */
+        FALSE,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0,                     /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        0x0000ffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
+
+
+  HOWTO (R_ZIP_LDI,            /* type */
+  HOWTO (R_ZIP_LDI,            /* type */
+        0,                     /* rightshift */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        23,                    /* bitsize */
+        23,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        0,                     /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
+        zip_relocation,         /* special_function */
+        zip_relocation,         /* special_function */
+        "R_ZIP_LDI",           /* name */
+        "R_ZIP_LDI",           /* name */
+        FALSE,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0,                     /* src_mask */
+        0x007fffff,            /* dst_mask */
+        0x007fffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
+
+
+  /* An 18 bit pc-relative relocation.  */
+  /* An 18 bit pc-relative relocation.  */
+  HOWTO (R_ZIP_BRANCH,         /* type */
+  HOWTO (R_ZIP_BRANCH,         /* type */
+        0,                     /* rightshift */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        18,                    /* bitsize */
+        18,                    /* bitsize */
+        TRUE,                  /* pc_relative */
+        TRUE,                  /* pc_relative */
+        0,                     /* bitpos */
+        0,                     /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
+        zip_relocation,        /* special_function */
+        zip_relocation,        /* special_function */
+        "R_ZIP_BRANCH",        /* name */
+        "R_ZIP_BRANCH",        /* name */
+        FALSE,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
+        0x00000000,            /* src_mask */
+        0x00000000,            /* src_mask */
+        0x0003fffc,            /* dst_mask */
+        0x0003fffc,            /* dst_mask */
+        TRUE),         /* pcrel_offset */
+        TRUE),         /* pcrel_offset */
+
+
+  /* An 18 bit operand B immediate.  */
+  /* An 18 bit operand B immediate.  */
+  HOWTO (R_ZIP_OPB_IMM,        /* type */
+  HOWTO (R_ZIP_OPB_IMM,        /* type */
+        0,                     /* rightshift */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        18,                    /* bitsize */
+        18,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        0,                     /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
+        zip_relocation,        /* special_function */
+        zip_relocation,        /* special_function */
+        "R_ZIP_OPB_IMM",       /* name */
+        "R_ZIP_OPB_IMM",       /* name */
+        FALSE,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
+        0x00000000,            /* src_mask */
+        0x00000000,            /* src_mask */
+        0x0003ffff,            /* dst_mask */
+        0x0003ffff,            /* dst_mask */
+        FALSE),                        /* pcrel_offset */
+        FALSE),                        /* pcrel_offset */
+
+
+  /* An 18 bit relocation.  */
+  /* An 18 bit relocation.  */
+  HOWTO (R_ZIP_OPB_OFFSET,     /* type */
+  HOWTO (R_ZIP_OPB_OFFSET,     /* type */
+        0,                     /* rightshift */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        14,                    /* bitsize */
+        14,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        0,                     /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
+        zip_relocation,        /* special_function */
+        zip_relocation,        /* special_function */
+        "R_ZIP_OPB_OFFSET",    /* name */
+        "R_ZIP_OPB_OFFSET",    /* name */
+        FALSE,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
+        0x00000000,            /* src_mask */
+        0x00000000,            /* src_mask */
+        0x00003fff,            /* dst_mask-14 bits */
+        0x00003fff,            /* dst_mask-14 bits */
+        FALSE),                        /* pcrel_offset */
+        FALSE),                        /* pcrel_offset */
+
+
+  /* An 18 bit operand B immediate, but relative to the current PC.  */
+  /* An 18 bit operand B immediate, but relative to the current PC.  */
+  HOWTO (R_ZIP_OPB_PCREL,      /* type */
+  HOWTO (R_ZIP_OPB_PCREL,      /* type */
+        2,                     /* rightshift */
+        2,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        14,                    /* bitsize */
+        14,                    /* bitsize */
+        TRUE,                  /* pc_relative */
+        TRUE,                  /* pc_relative */
+        0,                     /* bitpos */
+        0,                     /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
+        zip_relocation,        /* special_function */
+        zip_relocation,        /* special_function */
+        "R_ZIP_OPB_PCREL",     /* name */
+        "R_ZIP_OPB_PCREL",     /* name */
+        FALSE,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
+        0x00000000,            /* src_mask */
+        0x00000000,            /* src_mask */
+        0x00003fff,            /* dst_mask-14 bits */
+        0x00003fff,            /* dst_mask-14 bits */
+        TRUE),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
+
+
+  /* An 18 bit operand B immediate, but relative to the Global Offset Table. */
+  /* An 18 bit operand B immediate, but relative to the Global Offset Table. */
+  //HOWTO (R_ZIP_OPB_GOTREL,   /* type */
+  //HOWTO (R_ZIP_OPB_GOTREL,   /* type */
+        //0,                   /* rightshift */
+        //0,                   /* rightshift */
+        //2,                   /* size (0 = byte, 1 = short, 2 = long) */
+        //2,                   /* size (0 = byte, 1 = short, 2 = long) */
+        //18,                  /* bitsize */
+        //18,                  /* bitsize */
+        //FALSE,                       /* pc_relative */
+        //FALSE,                       /* pc_relative */
+        //0,                   /* bitpos */
+        //0,                   /* bitpos */
+        //complain_overflow_signed, /* complain_on_overflow */
+        //complain_overflow_signed, /* complain_on_overflow */
+        //zip_relocation,      /* special_function */
+        //zip_relocation,      /* special_function */
+        //"R_ZIP_OPB_GOTREL",  /* name */
+        //"R_ZIP_OPB_GOTREL",  /* name */
+        //FALSE,                       /* partial_inplace */
+        //FALSE,                       /* partial_inplace */
+        //0x00000000,          /* src_mask */
+        //0x00000000,          /* src_mask */
+        //0x0003ffff,          /* dst_mask-14 bits */
+        //0x0003ffff,          /* dst_mask-14 bits */
+        //FALSE),              /* pcrel_offset */
+        //FALSE),              /* pcrel_offset */
+
+
+  /* */
+  /* */
+  HOWTO (R_ZIP_MOV_OFFSET,     /* type */
+  HOWTO (R_ZIP_MOV_OFFSET,     /* type */
+        0,                     /* rightshift */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        13,                    /* bitsize */
+        13,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        0,                     /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
+        zip_relocation,         /* special_function */
+        zip_relocation,         /* special_function */
+        "R_ZIP_MOV_OFFSET",    /* name */
+        "R_ZIP_MOV_OFFSET",    /* name */
+        FALSE,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0,                     /* src_mask */
+        0x00001fff,            /* dst_mask */
+        0x00001fff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
+
+
+  /* */
+  /* */
+  HOWTO (R_ZIP_MOV_PCREL,      /* type */
+  HOWTO (R_ZIP_MOV_PCREL,      /* type */
+        2,                     /* rightshift */
+        2,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        13,                    /* bitsize */
+        13,                    /* bitsize */
+        TRUE,                  /* pc_relative */
+        TRUE,                  /* pc_relative */
+        0,                     /* bitpos */
+        0,                     /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
+        zip_relocation,         /* special_function */
+        zip_relocation,         /* special_function */
+        "R_ZIP_MOV_PCREL",     /* name */
+        "R_ZIP_MOV_PCREL",     /* name */
+        FALSE,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0,                     /* src_mask */
+        0x00001fff,            /* dst_mask */
+        0x00001fff,            /* dst_mask */
+        TRUE)                  /* pcrel_offset */
+        TRUE)                  /* pcrel_offset */
+
+
+  /* */
+  /* */
+  //HOWTO (R_ZIP_MOV_GOTREL,   /* type */
+  //HOWTO (R_ZIP_MOV_GOTREL,   /* type */
+        //0,                   /* rightshift */
+        //0,                   /* rightshift */
+        //2,                   /* size (0 = byte, 1 = short, 2 = long) */
+        //2,                   /* size (0 = byte, 1 = short, 2 = long) */
+        //13,                  /* bitsize */
+        //13,                  /* bitsize */
+        //FALSE,                       /* pc_relative */
+        //FALSE,                       /* pc_relative */
+        //0,                   /* bitpos */
+        //0,                   /* bitpos */
+        //complain_overflow_signed, /* complain_on_overflow */
+        //complain_overflow_signed, /* complain_on_overflow */
+        //zip_relocation,       /* special_function */
+        //zip_relocation,       /* special_function */
+        //"R_ZIP_MOV_GOTREL",  /* name */
+        //"R_ZIP_MOV_GOTREL",  /* name */
+        //FALSE,                       /* partial_inplace */
+        //FALSE,                       /* partial_inplace */
+        //0,                   /* src_mask */
+        //0,                   /* src_mask */
+        //0x00001fff,          /* dst_mask */
+        //0x00001fff,          /* dst_mask */
+        //FALSE),              /* pcrel_offset */
+        //FALSE),              /* pcrel_offset */
+
+
+};
+};
+
+
+/* This structure is used to map BFD reloc codes to Zip ELF relocations */
+/* This structure is used to map BFD reloc codes to Zip ELF relocations */
+
+
+struct elf_reloc_map
+struct elf_reloc_map
+{
+{
+  bfd_reloc_code_real_type bfd_reloc_val;
+  bfd_reloc_code_real_type bfd_reloc_val;
+  unsigned int elf_reloc_val;
+  unsigned int elf_reloc_val;
+};
+};
+
+
+static const struct elf_reloc_map zip_reloc_map [] =
+static const struct elf_reloc_map zip_reloc_map [] =
+{
+{
+  { BFD_RELOC_NONE,            R_ZIP_NONE },
+  { BFD_RELOC_NONE,            R_ZIP_NONE },
+  { BFD_RELOC_ZIP_VALUE,       R_ZIP_VALUE },
+  { BFD_RELOC_ZIP_VALUE,       R_ZIP_VALUE },
+  { BFD_RELOC_ZIP_BRANCH,      R_ZIP_BRANCH },
+  { BFD_RELOC_ZIP_BRANCH,      R_ZIP_BRANCH },
+  { BFD_RELOC_ZIP_OPB_IMM,     R_ZIP_OPB_IMM },
+  { BFD_RELOC_ZIP_OPB_IMM,     R_ZIP_OPB_IMM },
+  { BFD_RELOC_ZIP_OPB_OFFSET,  R_ZIP_OPB_OFFSET },
+  { BFD_RELOC_ZIP_OPB_OFFSET,  R_ZIP_OPB_OFFSET },
+  { BFD_RELOC_ZIP_MOV_OFFSET,  R_ZIP_MOV_OFFSET },
+  { BFD_RELOC_ZIP_MOV_OFFSET,  R_ZIP_MOV_OFFSET },
+  { BFD_RELOC_ZIP_LDI,         R_ZIP_LDI },
+  { BFD_RELOC_ZIP_LDI,         R_ZIP_LDI },
+  { BFD_RELOC_ZIP_LLO,         R_ZIP_LLO },
+  { BFD_RELOC_ZIP_LLO,         R_ZIP_LLO },
+  { BFD_RELOC_ZIP_BREV,                R_ZIP_BREV },
+  { BFD_RELOC_ZIP_BREV,                R_ZIP_BREV },
+  { BFD_RELOC_14,              R_ZIP_OPB_OFFSET },
+  { BFD_RELOC_14,              R_ZIP_OPB_OFFSET },
+  { BFD_RELOC_16,              R_ZIP_LLO },
+  { BFD_RELOC_16,              R_ZIP_LLO },
+  { BFD_RELOC_32,              R_ZIP_VALUE },
+  { BFD_RELOC_32,              R_ZIP_VALUE },
+  { BFD_RELOC_ZIP_OPB_PCREL,   R_ZIP_OPB_PCREL },
+  { BFD_RELOC_ZIP_OPB_PCREL,   R_ZIP_OPB_PCREL },
+  { BFD_RELOC_ZIP_MOV_PCREL,   R_ZIP_MOV_PCREL }
+  { BFD_RELOC_ZIP_MOV_PCREL,   R_ZIP_MOV_PCREL }
+  // { BFD_RELOC_ZIP_OPB_GOTREL,       R_ZIP_OPB_GOTREL },
+  // { BFD_RELOC_ZIP_OPB_GOTREL,       R_ZIP_OPB_GOTREL },
+  // { BFD_RELOC_ZIP_MOV_GOTREL,       R_ZIP_MOV_GOTREL },
+  // { BFD_RELOC_ZIP_MOV_GOTREL,       R_ZIP_MOV_GOTREL },
+};
+};
+
+
+/* Given a BFD reloc code, return the howto structure for the corresponding
+/* Given a BFD reloc code, return the howto structure for the corresponding
+ * Zip ELF relocation. */
+ * Zip ELF relocation. */
+static reloc_howto_type *
+static reloc_howto_type *
+zip_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+zip_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+                       bfd_reloc_code_real_type code)
+                       bfd_reloc_code_real_type code)
+{
+{
+  unsigned int i;
+  unsigned int i;
+
+
+  for (i = 0; i < sizeof (zip_reloc_map) / sizeof (zip_reloc_map[0]); i++)
+  for (i = 0; i < sizeof (zip_reloc_map) / sizeof (zip_reloc_map[0]); i++)
+    if (zip_reloc_map [i].bfd_reloc_val == code)
+    if (zip_reloc_map [i].bfd_reloc_val == code)
+      return & zip_elf_howto_table [(int)zip_reloc_map[i].elf_reloc_val];
+      return & zip_elf_howto_table [(int)zip_reloc_map[i].elf_reloc_val];
+
+
+  return NULL;
+  return NULL;
+}
+}
+
+
+static reloc_howto_type *
+static reloc_howto_type *
+zip_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
+zip_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
+{
+{
+  unsigned int i;
+  unsigned int i;
+
+
+  for (i = 0;
+  for (i = 0;
+       i < sizeof (zip_elf_howto_table) / sizeof (zip_elf_howto_table[0]);
+       i < sizeof (zip_elf_howto_table) / sizeof (zip_elf_howto_table[0]);
+       i++)
+       i++)
+    if (zip_elf_howto_table[i].name != NULL
+    if (zip_elf_howto_table[i].name != NULL
+       && strcasecmp (zip_elf_howto_table[i].name, r_name) == 0)
+       && strcasecmp (zip_elf_howto_table[i].name, r_name) == 0)
+      return &zip_elf_howto_table[i];
+      return &zip_elf_howto_table[i];
+
+
+  return NULL;
+  return NULL;
+}
+}
+
+
+/* Given an ELF reloc, fill in the howto field of a relent. */
+/* Given an ELF reloc, fill in the howto field of a relent. */
+static void
+static void
+zip_elf_info_to_howto(bfd * abfd ATTRIBUTE_UNUSED,
+zip_elf_info_to_howto(bfd * abfd ATTRIBUTE_UNUSED,
+                        arelent * cache_ptr,
+                        arelent * cache_ptr,
+                        Elf_Internal_Rela * dst)
+                        Elf_Internal_Rela * dst)
+{
+{
+       unsigned int r;
+       unsigned int r;
+
+
+       r = ELF32_R_TYPE(dst->r_info);
+       r = ELF32_R_TYPE(dst->r_info);
+       BFD_ASSERT (r < (unsigned int) R_ZIP_max);
+       BFD_ASSERT (r < (unsigned int) R_ZIP_max);
+       cache_ptr->howto = &zip_elf_howto_table [r];
+       cache_ptr->howto = &zip_elf_howto_table [r];
+}
+}
+
+
+static bfd_boolean
+static bfd_boolean
+zip_elf_relocate_section(bfd *output_bfd,
+zip_elf_relocate_section(bfd *output_bfd,
+                       struct bfd_link_info *info,
+                       struct bfd_link_info *info,
+                       bfd *input_bfd,
+                       bfd *input_bfd,
+                       asection *input_section,
+                       asection *input_section,
+                       bfd_byte *contents,
+                       bfd_byte *contents,
+                       Elf_Internal_Rela *relocs,
+                       Elf_Internal_Rela *relocs,
+                       Elf_Internal_Sym *local_syms,
+                       Elf_Internal_Sym *local_syms,
+                       asection **local_sections)
+                       asection **local_sections)
+{
+{
+       Elf_Internal_Shdr               *symtab_hdr;
+       Elf_Internal_Shdr               *symtab_hdr;
+       struct  elf_link_hash_entry     **sym_hashes;
+       struct  elf_link_hash_entry     **sym_hashes;
+       Elf_Internal_Rela               *rel, *relend;
+       Elf_Internal_Rela               *rel, *relend;
+
+
+       symtab_hdr = &elf_tdata(input_bfd)->symtab_hdr;
+       symtab_hdr = &elf_tdata(input_bfd)->symtab_hdr;
+       sym_hashes = elf_sym_hashes(input_bfd);
+       sym_hashes = elf_sym_hashes(input_bfd);
+       relend     = relocs+input_section->reloc_count;
+       relend     = relocs+input_section->reloc_count;
+
+
+       for(rel=relocs; rel<relend; rel++) {
+       for(rel=relocs; rel<relend; rel++) {
+               reloc_howto_type                *howto;
+               reloc_howto_type                *howto;
+               unsigned long                   r_symndx;
+               unsigned long                   r_symndx;
+               Elf_Internal_Sym                *sym;
+               Elf_Internal_Sym                *sym;
+               asection                        *sec;
+               asection                        *sec;
+               struct elf_link_hash_entry      *h;
+               struct elf_link_hash_entry      *h;
+               bfd_vma                         relocation;
+               bfd_vma                         relocation;
+               bfd_reloc_status_type           r;
+               bfd_reloc_status_type           r;
+               const char                      *name = NULL;
+               const char                      *name = NULL;
+               int                             r_type;
+               int                             r_type;
+
+
+               r_type = ELF32_R_TYPE(rel->r_info);
+               r_type = ELF32_R_TYPE(rel->r_info);
+               r_symndx = ELF32_R_SYM(rel->r_info);
+               r_symndx = ELF32_R_SYM(rel->r_info);
+
+
+               if ((r_type < 0) || (r_type >= (int)R_ZIP_max))
+               if ((r_type < 0) || (r_type >= (int)R_ZIP_max))
+               {
+               {
+                       bfd_set_error(bfd_error_bad_value);
+                       bfd_set_error(bfd_error_bad_value);
+                       return FALSE;
+                       return FALSE;
+               }
+               }
+
+
+               howto = zip_elf_howto_table + ELF32_R_TYPE(rel->r_info);
+               howto = zip_elf_howto_table + ELF32_R_TYPE(rel->r_info);
+               h = NULL;
+               h = NULL;
+               sym = NULL;
+               sym = NULL;
+               sec = NULL;
+               sec = NULL;
+
+
+               if (r_symndx < symtab_hdr->sh_info)
+               if (r_symndx < symtab_hdr->sh_info)
+               {
+               {
+                       sym = local_syms + r_symndx;
+                       sym = local_syms + r_symndx;
+                       sec = local_sections[r_symndx];
+                       sec = local_sections[r_symndx];
+                       relocation = _bfd_elf_rela_local_sym(output_bfd, sym, &sec, rel);
+                       relocation = _bfd_elf_rela_local_sym(output_bfd, sym, &sec, rel);
+                       name = bfd_elf_string_from_elf_section
+                       name = bfd_elf_string_from_elf_section
+                               (input_bfd, symtab_hdr->sh_link, sym->st_name);
+                               (input_bfd, symtab_hdr->sh_link, sym->st_name);
+                       name = (name == NULL) ? bfd_section_name(input_bfd, sec)
+                       name = (name == NULL) ? bfd_section_name(input_bfd, sec)
+                                       : name;
+                                       : name;
+               } else {
+               } else {
+                       bfd_boolean unresolved_reloc, warned, ignored;
+                       bfd_boolean unresolved_reloc, warned, ignored;
+
+
+                       RELOC_FOR_GLOBAL_SYMBOL(info, input_bfd, input_section,
+                       RELOC_FOR_GLOBAL_SYMBOL(info, input_bfd, input_section,
+                               rel, r_symndx, symtab_hdr, sym_hashes, h, sec,
+                               rel, r_symndx, symtab_hdr, sym_hashes, h, sec,
+                               relocation, unresolved_reloc, warned, ignored);
+                               relocation, unresolved_reloc, warned, ignored);
+               }
+               }
+
+
+               if ((sec != NULL)&&(discarded_section(sec))) {
+               if ((sec != NULL)&&(discarded_section(sec))) {
+                       RELOC_AGAINST_DISCARDED_SECTION(info, input_bfd,
+                       RELOC_AGAINST_DISCARDED_SECTION(info, input_bfd,
+                               input_section, rel, 1, relend, howto, 0,
+                               input_section, rel, 1, relend, howto, 0,
+                               contents);
+                               contents);
+               }
+               }
+
+
+               if (bfd_link_relocatable(info))
+               if (bfd_link_relocatable(info))
+                       continue;
+                       continue;
+
+
+               if (howto->type == R_ZIP_BREV) {
+               if (howto->type == R_ZIP_BREV) {
+                       if (rel->r_offset > bfd_get_section_limit(input_bfd, input_section)) {
+                       if (rel->r_offset > bfd_get_section_limit(input_bfd, input_section)) {
+                               r = bfd_reloc_outofrange;
+                               r = bfd_reloc_outofrange;
+                       } else {
+                       } else {
+                               uint32_t        brev_reloc;
+                               uint32_t        brev_reloc;
+                               bfd_byte        *location;
+                               bfd_byte        *location;
+                               bfd_vma         insn;
+                               bfd_vma         insn;
+
+
+                               location = contents + rel->r_offset * bfd_octets_per_byte(input_bfd);
+                               location = contents + rel->r_offset * bfd_octets_per_byte(input_bfd);
+
+
+                               relocation += rel->r_addend;
+                               relocation += rel->r_addend;
+                               brev_reloc= zip_bitreverse(relocation);
+                               brev_reloc= zip_bitreverse(relocation);
+                               insn = bfd_get_32(input_bfd, location);
+                               insn = bfd_get_32(input_bfd, location);
+                               insn = ((insn & ~howto->dst_mask)
+                               insn = ((insn & ~howto->dst_mask)
+                               |(((insn & howto->src_mask)+brev_reloc)&howto->dst_mask));
+                               |(((insn & howto->src_mask)+brev_reloc)&howto->dst_mask));
+                               bfd_put_32(input_bfd, insn, location);
+                               bfd_put_32(input_bfd, insn, location);
+                               r = bfd_reloc_ok;
+                               r = bfd_reloc_ok;
+                       }
+                       }
+               } else {
+               } else {
+                       r = _bfd_final_link_relocate(howto, input_bfd,
+                       r = _bfd_final_link_relocate(howto, input_bfd,
+                               input_section,
+                               input_section,
+                               contents, rel->r_offset,
+                               contents, rel->r_offset,
+                               relocation,
+                               relocation,
+                               rel->r_addend);
+                               rel->r_addend);
+               }
+               }
+
+
+
+
+               if (r != bfd_reloc_ok)
+               if (r != bfd_reloc_ok)
+               {
+               {
+                       const char *msg = NULL;
+                       const char *msg = NULL;
+
+
+                       switch(r)
+                       switch(r)
+                       {
+                       {
+                               case bfd_reloc_overflow:
+                               case bfd_reloc_overflow:
+                                       info->callbacks->reloc_overflow(
+                                       info->callbacks->reloc_overflow(
+                                               info, (h?&h->root:NULL),
+                                               info, (h?&h->root:NULL),
+                                               name, howto->name,
+                                               name, howto->name,
+                                               (bfd_vma)0, input_bfd,
+                                               (bfd_vma)0, input_bfd,
+                                               input_section, rel->r_offset);
+                                               input_section, rel->r_offset);
+                                       break;
+                                       break;
+                               case bfd_reloc_undefined:
+                               case bfd_reloc_undefined:
+                                       info->callbacks->undefined_symbol(
+                                       info->callbacks->undefined_symbol(
+                                               info, name, input_bfd,
+                                               info, name, input_bfd,
+                                               input_section, rel->r_offset,
+                                               input_section, rel->r_offset,
+                                               TRUE);
+                                               TRUE);
+                                       break;
+                                       break;
+                               case bfd_reloc_outofrange:
+                               case bfd_reloc_outofrange:
+                                       msg = _("internal error: out of range error");
+                                       msg = _("internal error: out of range error");
+                                       break;
+                                       break;
+                               case bfd_reloc_notsupported:
+                               case bfd_reloc_notsupported:
+                                       msg = _("internal error: unsupported relocation");
+                                       msg = _("internal error: unsupported relocation");
+                                       break;
+                                       break;
+                               case bfd_reloc_dangerous:
+                               case bfd_reloc_dangerous:
+                                       msg = _("internal error: dangerous relocation");
+                                       msg = _("internal error: dangerous relocation");
+                                       break;
+                                       break;
+                               default:
+                               default:
+                                       msg = _("internal error: unknown error");
+                                       msg = _("internal error: unknown error");
+                                       break;
+                                       break;
+                       }
+                       }
+
+
+                       if (msg)
+                       if (msg)
+                               info->callbacks->warning(info, msg, name,
+                               info->callbacks->warning(info, msg, name,
+                                       input_bfd, input_section,
+                                       input_bfd, input_section,
+                                       rel->r_offset);
+                                       rel->r_offset);
+
+
+                       if (!r)
+                       if (!r)
+                               return FALSE;
+                               return FALSE;
+               }
+               }
+       }
+       }
+       return TRUE;
+       return TRUE;
+}
+}
+
+
+static uint32_t
+static uint32_t
+zip_bitreverse(uint32_t v) {
+zip_bitreverse(uint32_t v) {
+       unsigned r = 0, b;
+       unsigned r = 0, b;
+
+
+       for(b=0; b<32; b++, v>>=1)
+       for(b=0; b<32; b++, v>>=1)
+               r = (r<<1)|(v&1);
+               r = (r<<1)|(v&1);
+
+
+       return r;
+       return r;
+}
+}
+
+
+static bfd_reloc_status_type
+static bfd_reloc_status_type
+zip_brev_relocation(bfd *abfd,
+zip_brev_relocation(bfd *abfd,
+               arelent *reloc_entry,
+               arelent *reloc_entry,
+               asymbol *symbol,
+               asymbol *symbol,
+               void *data,
+               void *data,
+               asection *input_section,
+               asection *input_section,
+               bfd *output_bfd,
+               bfd *output_bfd,
+               char **error_message)
+               char **error_message)
+{
+{
+       bfd_vma relocation;
+       bfd_vma relocation;
+       bfd_size_type octets = reloc_entry->address * bfd_octets_per_byte(abfd);
+       bfd_size_type octets = reloc_entry->address * bfd_octets_per_byte(abfd);
+       bfd_vma output_base = 0;
+       bfd_vma output_base = 0;
+       reloc_howto_type *howto = reloc_entry->howto;
+       reloc_howto_type *howto = reloc_entry->howto;
+
+
+       // If this isn't a final relocation, then just use the generic
+       // If this isn't a final relocation, then just use the generic
+       // relocation function.
+       // relocation function.
+       if (output_bfd != NULL) {
+       if (output_bfd != NULL) {
+               return zip_relocation(abfd, reloc_entry, symbol, data,
+               return zip_relocation(abfd, reloc_entry, symbol, data,
+                       input_section, output_bfd, error_message);
+                       input_section, output_bfd, error_message);
+       }
+       }
+
+
+       // Otherwise, we need to adjust our file itself with this value ...
+       // Otherwise, we need to adjust our file itself with this value ...
+       // Check that our relocation lies within the file, and particularly
+       // Check that our relocation lies within the file, and particularly
+       // the section we think it should.  (This should really be an assert...)
+       // the section we think it should.  (This should really be an assert...)
+       if (reloc_entry->address > bfd_get_section_limit(abfd, input_section))
+       if (reloc_entry->address > bfd_get_section_limit(abfd, input_section))
+               return bfd_reloc_outofrange;
+               return bfd_reloc_outofrange;
+
+
+       // Get symbol value
+       // Get symbol value
+       if (bfd_is_com_section(symbol->section))
+       if (bfd_is_com_section(symbol->section))
+               relocation = 0;
+               relocation = 0;
+       else
+       else
+               relocation = symbol->value;
+               relocation = symbol->value;
+
+
+       /* Convert input-section relative symbol value to absolute */
+       /* Convert input-section relative symbol value to absolute */
+       if ((!howto->partial_inplace)
+       if ((!howto->partial_inplace)
+                       ||(symbol->section->output_section == NULL))
+                       ||(symbol->section->output_section == NULL))
+               output_base = 0;
+               output_base = 0;
+       else
+       else
+               output_base = symbol->section->output_section->vma;
+               output_base = symbol->section->output_section->vma;
+
+
+       relocation += output_base + symbol->section->output_offset;
+       relocation += output_base + symbol->section->output_offset;
+
+
+       /* Add in supplied addend. */
+       /* Add in supplied addend. */
+       relocation += reloc_entry->addend;
+       relocation += reloc_entry->addend;
+
+
+       // BREV does not handle PC relative offsets
+       // BREV does not handle PC relative offsets
+
+
+       // Ignore overflow checking ... BREV handles the top 18 bits of a 32-bit
+       // Ignore overflow checking ... BREV handles the top 18 bits of a 32-bit
+       // number.  Overflow would mean overflowing the 32-bit address space--
+       // number.  Overflow would mean overflowing the 32-bit address space--
+       // not possible.
+       // not possible.
+       //
+       //
+       // if howto->complain_on_overflow ...
+       // if howto->complain_on_overflow ...
+
+
+       // relocation >>= howto->rightshift;    // = 0
+       // relocation >>= howto->rightshift;    // = 0
+       // relocation <<= howto->bitpos;        // = 0
+       // relocation <<= howto->bitpos;        // = 0
+
+
+       // Logic (nearly) copied from reloc.c:bfd_perform_relocation
+       // Logic (nearly) copied from reloc.c:bfd_perform_relocation
+       unsigned        insn = bfd_get_32(abfd, (bfd_byte *)data + octets);
+       unsigned        insn = bfd_get_32(abfd, (bfd_byte *)data + octets);
+
+
+       // Here's why we are going through this pain!
+       // Here's why we are going through this pain!
+       insn = zip_bitreverse((unsigned)insn);
+       insn = zip_bitreverse((unsigned)insn);
+
+
+       // Now we can continue as before....
+       // Now we can continue as before....
+       insn = ((insn&(~howto->dst_mask))
+       insn = ((insn&(~howto->dst_mask))
+               |(((insn&howto->src_mask)+relocation)&howto->dst_mask));
+               |(((insn&howto->src_mask)+relocation)&howto->dst_mask));
+       bfd_put_32(abfd, (bfd_vma)insn, (bfd_byte *)data + octets);
+       bfd_put_32(abfd, (bfd_vma)insn, (bfd_byte *)data + octets);
+
+
+       return bfd_reloc_ok;
+       return bfd_reloc_ok;
+}
+}
+
+
+// Zip Defines
+// Zip Defines
+#define        TARGET_BIG_SYM  zip_elf32_vec
+#define        TARGET_BIG_SYM  zip_elf32_vec
+#define        TARGET_BIG_NAME "elf32-zip"
+#define        TARGET_BIG_NAME "elf32-zip"
+
+
+#define        ELF_ARCH        bfd_arch_zip
+#define        ELF_ARCH        bfd_arch_zip
+// #define ELF_TARGET_ID               ZIP_ELF_DATA
+// #define ELF_TARGET_ID               ZIP_ELF_DATA
+#define        ELF_MACHINE_CODE        EM_ZIP
+#define        ELF_MACHINE_CODE        EM_ZIP
+
+
+#define        ELF_MAXPAGESIZE         0x1000
+#define        ELF_MAXPAGESIZE         0x1000
+#define        ARCH_SIZE               32
+#define        ARCH_SIZE               32
+
+
+
+
+#define bfd_elf32_bfd_define_common_symbol     bfd_generic_define_common_symbol
+#define bfd_elf32_bfd_define_common_symbol     bfd_generic_define_common_symbol
+
+
+
+
+#define        bfd_elf32_bfd_reloc_type_lookup zip_elf_reloc_type_lookup
+#define        bfd_elf32_bfd_reloc_type_lookup zip_elf_reloc_type_lookup
+#define        bfd_elf32_bfd_reloc_name_lookup zip_elf_reloc_name_lookup
+#define        bfd_elf32_bfd_reloc_name_lookup zip_elf_reloc_name_lookup
+#define        elf_info_to_howto_rel   0
+#define        elf_info_to_howto_rel   0
+#define        elf_info_to_howto       zip_elf_info_to_howto
+#define        elf_info_to_howto       zip_elf_info_to_howto
+#define        elf_backend_relocate_section    zip_elf_relocate_section
+#define        elf_backend_relocate_section    zip_elf_relocate_section
+#define        elf_backend_rela_normal         1
+#define        elf_backend_rela_normal         1
+
+
+// Default ELF32 defines from elf32-target.h that we would've normally included
+// Default ELF32 defines from elf32-target.h that we would've normally included
+// here, had we not been a OCTETS_PER_BYTE=4 machine
+// here, had we not been a OCTETS_PER_BYTE=4 machine
+
+
+#define        bfd_elf32_close_and_cleanup _bfd_elf_close_and_cleanup
+#define        bfd_elf32_close_and_cleanup _bfd_elf_close_and_cleanup
+#define bfd_elf32_bfd_free_cached_info _bfd_free_cached_info
+#define bfd_elf32_bfd_free_cached_info _bfd_free_cached_info
+#define bfd_elf32_get_section_contents _bfd_generic_get_section_contents
+#define bfd_elf32_get_section_contents _bfd_generic_get_section_contents
+#define bfd_elf32_canonicalize_dynamic_symtab \
+#define bfd_elf32_canonicalize_dynamic_symtab \
+  _bfd_elf_canonicalize_dynamic_symtab
+  _bfd_elf_canonicalize_dynamic_symtab
+#define bfd_elf32_get_synthetic_symtab _bfd_elf_get_synthetic_symtab
+#define bfd_elf32_get_synthetic_symtab _bfd_elf_get_synthetic_symtab
+#define bfd_elf32_canonicalize_reloc   _bfd_elf_canonicalize_reloc
+#define bfd_elf32_canonicalize_reloc   _bfd_elf_canonicalize_reloc
+#define bfd_elf32_find_nearest_line    _bfd_elf_find_nearest_line
+#define bfd_elf32_find_nearest_line    _bfd_elf_find_nearest_line
+#define bfd_elf32_find_line            _bfd_elf_find_line
+#define bfd_elf32_find_line            _bfd_elf_find_line
+#define bfd_elf32_find_inliner_info    _bfd_elf_find_inliner_info
+#define bfd_elf32_find_inliner_info    _bfd_elf_find_inliner_info
+#define bfd_elf32_read_minisymbols     _bfd_elf_read_minisymbols
+#define bfd_elf32_read_minisymbols     _bfd_elf_read_minisymbols
+#define bfd_elf32_minisymbol_to_symbol _bfd_elf_minisymbol_to_symbol
+#define bfd_elf32_minisymbol_to_symbol _bfd_elf_minisymbol_to_symbol
+#define bfd_elf32_get_dynamic_symtab_upper_bound \
+#define bfd_elf32_get_dynamic_symtab_upper_bound \
+  _bfd_elf_get_dynamic_symtab_upper_bound
+  _bfd_elf_get_dynamic_symtab_upper_bound
+#define bfd_elf32_get_lineno           _bfd_elf_get_lineno
+#define bfd_elf32_get_lineno           _bfd_elf_get_lineno
+#define bfd_elf32_get_reloc_upper_bound _bfd_elf_get_reloc_upper_bound
+#define bfd_elf32_get_reloc_upper_bound _bfd_elf_get_reloc_upper_bound
+#define bfd_elf32_get_symbol_info      _bfd_elf_get_symbol_info
+#define bfd_elf32_get_symbol_info      _bfd_elf_get_symbol_info
+#define bfd_elf32_get_symbol_version_string    _bfd_elf_get_symbol_version_string
+#define bfd_elf32_get_symbol_version_string    _bfd_elf_get_symbol_version_string
+#define bfd_elf32_canonicalize_symtab  _bfd_elf_canonicalize_symtab
+#define bfd_elf32_canonicalize_symtab  _bfd_elf_canonicalize_symtab
+#define bfd_elf32_get_symtab_upper_bound _bfd_elf_get_symtab_upper_bound
+#define bfd_elf32_get_symtab_upper_bound _bfd_elf_get_symtab_upper_bound
+#define bfd_elf32_make_empty_symbol    _bfd_elf_make_empty_symbol
+#define bfd_elf32_make_empty_symbol    _bfd_elf_make_empty_symbol
+#define bfd_elf32_new_section_hook     _bfd_elf_new_section_hook
+#define bfd_elf32_new_section_hook     _bfd_elf_new_section_hook
+#define bfd_elf32_set_arch_mach                _bfd_elf_set_arch_mach
+#define bfd_elf32_set_arch_mach                _bfd_elf_set_arch_mach
+#define bfd_elf32_set_section_contents _bfd_elf_set_section_contents
+#define bfd_elf32_set_section_contents _bfd_elf_set_section_contents
+#define bfd_elf32_sizeof_headers       _bfd_elf_sizeof_headers
+#define bfd_elf32_sizeof_headers       _bfd_elf_sizeof_headers
+#define bfd_elf32_write_object_contents _bfd_elf_write_object_contents
+#define bfd_elf32_write_object_contents _bfd_elf_write_object_contents
+#define bfd_elf32_write_corefile_contents _bfd_elf_write_corefile_contents
+#define bfd_elf32_write_corefile_contents _bfd_elf_write_corefile_contents
+
+
+#define bfd_elf32_get_section_contents_in_window \
+#define bfd_elf32_get_section_contents_in_window \
+  _bfd_generic_get_section_contents_in_window
+  _bfd_generic_get_section_contents_in_window
+
+
+#define elf_backend_can_refcount 0
+#define elf_backend_can_refcount 0
+#define elf_backend_want_got_plt 0
+#define elf_backend_want_got_plt 0
+#define elf_backend_plt_readonly 0
+#define elf_backend_plt_readonly 0
+#define elf_backend_want_plt_sym 0
+#define elf_backend_want_plt_sym 0
+#define elf_backend_plt_not_loaded 0
+#define elf_backend_plt_not_loaded 0
+#define elf_backend_plt_alignment 2
+#define elf_backend_plt_alignment 2
+#define elf_backend_want_dynbss 1
+#define elf_backend_want_dynbss 1
+#define elf_backend_want_p_paddr_set_to_zero 0
+#define elf_backend_want_p_paddr_set_to_zero 0
+#define elf_backend_default_execstack 1
+#define elf_backend_default_execstack 1
+#define elf_backend_caches_rawsize 0
+#define elf_backend_caches_rawsize 0
+#define elf_backend_extern_protected_data 0
+#define elf_backend_extern_protected_data 0
+#define elf_backend_stack_align 4
+#define elf_backend_stack_align 4
+#define elf_backend_strtab_flags 0
+#define elf_backend_strtab_flags 0
+
+
+#define bfd_elf32_bfd_debug_info_start bfd_void
+#define bfd_elf32_bfd_debug_info_start bfd_void
+#define bfd_elf32_bfd_debug_info_end   bfd_void
+#define bfd_elf32_bfd_debug_info_end   bfd_void
+#define bfd_elf32_bfd_debug_info_accumulate \
+#define bfd_elf32_bfd_debug_info_accumulate \
+  ((void (*) (bfd*, struct bfd_section *)) bfd_void)
+  ((void (*) (bfd*, struct bfd_section *)) bfd_void)
+
+
+#define bfd_elf32_bfd_get_relocated_section_contents \
+#define bfd_elf32_bfd_get_relocated_section_contents \
+  bfd_generic_get_relocated_section_contents
+  bfd_generic_get_relocated_section_contents
+
+
+#define bfd_elf32_bfd_relax_section bfd_generic_relax_section
+#define bfd_elf32_bfd_relax_section bfd_generic_relax_section
+
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 0
+#define elf_backend_can_refcount 0
+#define elf_backend_want_got_sym 1
+#define elf_backend_want_got_sym 1
+#define elf_backend_gc_keep            _bfd_elf_gc_keep
+#define elf_backend_gc_keep            _bfd_elf_gc_keep
+#define elf_backend_gc_mark_dynamic_ref        bfd_elf_gc_mark_dynamic_ref_symbol
+#define elf_backend_gc_mark_dynamic_ref        bfd_elf_gc_mark_dynamic_ref_symbol
+#define elf_backend_gc_mark_hook       _bfd_elf_gc_mark_hook
+#define elf_backend_gc_mark_hook       _bfd_elf_gc_mark_hook
+#define elf_backend_gc_mark_extra_sections _bfd_elf_gc_mark_extra_sections
+#define elf_backend_gc_mark_extra_sections _bfd_elf_gc_mark_extra_sections
+#define elf_backend_gc_sweep_hook      NULL
+#define elf_backend_gc_sweep_hook      NULL
+#define bfd_elf32_bfd_gc_sections bfd_elf_gc_sections
+#define bfd_elf32_bfd_gc_sections bfd_elf_gc_sections
+
+
+#ifndef bfd_elf32_bfd_merge_sections
+#ifndef bfd_elf32_bfd_merge_sections
+#define bfd_elf32_bfd_merge_sections _bfd_elf_merge_sections
+#define bfd_elf32_bfd_merge_sections _bfd_elf_merge_sections
+#endif
+#endif
+
+
+#ifndef bfd_elf32_bfd_is_group_section
+#ifndef bfd_elf32_bfd_is_group_section
+#define bfd_elf32_bfd_is_group_section bfd_elf_is_group_section
+#define bfd_elf32_bfd_is_group_section bfd_elf_is_group_section
+#endif
+#endif
+
+
+#ifndef bfd_elf32_bfd_discard_group
+#ifndef bfd_elf32_bfd_discard_group
+#define bfd_elf32_bfd_discard_group bfd_generic_discard_group
+#define bfd_elf32_bfd_discard_group bfd_generic_discard_group
+#endif
+#endif
+
+
+#ifndef bfd_elf32_section_already_linked
+#ifndef bfd_elf32_section_already_linked
+#define bfd_elf32_section_already_linked _bfd_elf_section_already_linked
+#define bfd_elf32_section_already_linked _bfd_elf_section_already_linked
+#endif
+#endif
+
+
+#ifndef bfd_elf32_bfd_define_common_symbol
+#ifndef bfd_elf32_bfd_define_common_symbol
+#define bfd_elf32_bfd_define_common_symbol bfd_generic_define_common_symbol
+#define bfd_elf32_bfd_define_common_symbol bfd_generic_define_common_symbol
+#endif
+#endif
+
+
+#ifndef bfd_elf32_bfd_lookup_section_flags
+#ifndef bfd_elf32_bfd_lookup_section_flags
+#define bfd_elf32_bfd_lookup_section_flags bfd_elf_lookup_section_flags
+#define bfd_elf32_bfd_lookup_section_flags bfd_elf_lookup_section_flags
+#endif
+#endif
+
+
+#ifndef bfd_elf32_bfd_make_debug_symbol
+#ifndef bfd_elf32_bfd_make_debug_symbol
+#define bfd_elf32_bfd_make_debug_symbol \
+#define bfd_elf32_bfd_make_debug_symbol \
+  ((asymbol * (*) (bfd *, void *, unsigned long)) bfd_nullvoidptr)
+  ((asymbol * (*) (bfd *, void *, unsigned long)) bfd_nullvoidptr)
+#endif
+#endif
+
+
+#ifndef bfd_elf32_bfd_copy_private_symbol_data
+#ifndef bfd_elf32_bfd_copy_private_symbol_data
+#define bfd_elf32_bfd_copy_private_symbol_data _bfd_elf_copy_private_symbol_data
+#define bfd_elf32_bfd_copy_private_symbol_data _bfd_elf_copy_private_symbol_data
+#endif
+#endif
+
+
+#ifndef bfd_elf32_bfd_copy_private_section_data
+#ifndef bfd_elf32_bfd_copy_private_section_data
+#define bfd_elf32_bfd_copy_private_section_data \
+#define bfd_elf32_bfd_copy_private_section_data \
+  _bfd_elf_copy_private_section_data
+  _bfd_elf_copy_private_section_data
+#endif
+#endif
+#ifndef bfd_elf32_bfd_copy_private_header_data
+#ifndef bfd_elf32_bfd_copy_private_header_data
+#define bfd_elf32_bfd_copy_private_header_data \
+#define bfd_elf32_bfd_copy_private_header_data \
+  _bfd_elf_copy_private_header_data
+  _bfd_elf_copy_private_header_data
+#endif
+#endif
+#ifndef bfd_elf32_bfd_copy_private_bfd_data
+#ifndef bfd_elf32_bfd_copy_private_bfd_data
+#define bfd_elf32_bfd_copy_private_bfd_data \
+#define bfd_elf32_bfd_copy_private_bfd_data \
+  _bfd_elf_copy_private_bfd_data
+  _bfd_elf_copy_private_bfd_data
+#endif
+#endif
+#ifndef bfd_elf32_bfd_print_private_bfd_data
+#ifndef bfd_elf32_bfd_print_private_bfd_data
+#define bfd_elf32_bfd_print_private_bfd_data \
+#define bfd_elf32_bfd_print_private_bfd_data \
+  _bfd_elf_print_private_bfd_data
+  _bfd_elf_print_private_bfd_data
+#endif
+#endif
+#ifndef bfd_elf32_bfd_merge_private_bfd_data
+#ifndef bfd_elf32_bfd_merge_private_bfd_data
+#define bfd_elf32_bfd_merge_private_bfd_data \
+#define bfd_elf32_bfd_merge_private_bfd_data \
+  ((bfd_boolean (*) (bfd *, bfd *)) bfd_true)
+  ((bfd_boolean (*) (bfd *, bfd *)) bfd_true)
+#endif
+#endif
+#ifndef bfd_elf32_bfd_set_private_flags
+#ifndef bfd_elf32_bfd_set_private_flags
+#define bfd_elf32_bfd_set_private_flags \
+#define bfd_elf32_bfd_set_private_flags \
+  ((bfd_boolean (*) (bfd *, flagword)) bfd_true)
+  ((bfd_boolean (*) (bfd *, flagword)) bfd_true)
+#endif
+#endif
+#ifndef bfd_elf32_bfd_is_local_label_name
+#ifndef bfd_elf32_bfd_is_local_label_name
+#define bfd_elf32_bfd_is_local_label_name _bfd_elf_is_local_label_name
+#define bfd_elf32_bfd_is_local_label_name _bfd_elf_is_local_label_name
+#endif
+#endif
+#ifndef bfd_elf32_bfd_is_target_special_symbol
+#ifndef bfd_elf32_bfd_is_target_special_symbol
+#define bfd_elf32_bfd_is_target_special_symbol \
+#define bfd_elf32_bfd_is_target_special_symbol \
+  ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+  ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#endif
+#endif
+
+
+#ifndef bfd_elf32_get_dynamic_reloc_upper_bound
+#ifndef bfd_elf32_get_dynamic_reloc_upper_bound
+#define bfd_elf32_get_dynamic_reloc_upper_bound \
+#define bfd_elf32_get_dynamic_reloc_upper_bound \
+  _bfd_elf_get_dynamic_reloc_upper_bound
+  _bfd_elf_get_dynamic_reloc_upper_bound
+#endif
+#endif
+#ifndef bfd_elf32_canonicalize_dynamic_reloc
+#ifndef bfd_elf32_canonicalize_dynamic_reloc
+#define bfd_elf32_canonicalize_dynamic_reloc _bfd_elf_canonicalize_dynamic_reloc
+#define bfd_elf32_canonicalize_dynamic_reloc _bfd_elf_canonicalize_dynamic_reloc
+#endif
+#endif
+
+
+#define bfd_elf32_bfd_link_hash_table_create _bfd_elf_link_hash_table_create
+#define bfd_elf32_bfd_link_hash_table_create _bfd_elf_link_hash_table_create
+#define bfd_elf32_bfd_link_add_symbols bfd_elf_link_add_symbols
+#define bfd_elf32_bfd_link_add_symbols bfd_elf_link_add_symbols
+#define bfd_elf32_bfd_final_link       bfd_elf_final_link
+#define bfd_elf32_bfd_final_link       bfd_elf_final_link
+
+
+#define bfd_elf32_bfd_link_just_syms   _bfd_elf_link_just_syms
+#define bfd_elf32_bfd_link_just_syms   _bfd_elf_link_just_syms
+
+
+#define bfd_elf32_bfd_copy_link_hash_symbol_type \
+#define bfd_elf32_bfd_copy_link_hash_symbol_type \
+  _bfd_elf_copy_link_hash_symbol_type
+  _bfd_elf_copy_link_hash_symbol_type
+
+
+#define bfd_elf32_bfd_link_split_section _bfd_generic_link_split_section
+#define bfd_elf32_bfd_link_split_section _bfd_generic_link_split_section
+#define bfd_elf32_bfd_link_check_relocs _bfd_generic_link_check_relocs
+#define bfd_elf32_bfd_link_check_relocs _bfd_generic_link_check_relocs
+#define bfd_elf32_archive_p bfd_generic_archive_p
+#define bfd_elf32_archive_p bfd_generic_archive_p
+#define bfd_elf32_write_archive_contents _bfd_write_archive_contents
+#define bfd_elf32_write_archive_contents _bfd_write_archive_contents
+#define bfd_elf32_mkobject bfd_elf_make_object
+#define bfd_elf32_mkobject bfd_elf_make_object
+#define bfd_elf32_mkcorefile bfd_elf_mkcorefile
+#define bfd_elf32_mkcorefile bfd_elf_mkcorefile
+#define bfd_elf32_mkarchive _bfd_generic_mkarchive
+#define bfd_elf32_mkarchive _bfd_generic_mkarchive
+#define bfd_elf32_print_symbol bfd_elf_print_symbol
+#define bfd_elf32_print_symbol bfd_elf_print_symbol
+#define elf_symbol_leading_char 0
+#define elf_symbol_leading_char 0
+
+
+#define elf_backend_arch_data NULL
+#define elf_backend_arch_data NULL
+
+
+#ifndef ELF_TARGET_ID
+#ifndef ELF_TARGET_ID
+#define ELF_TARGET_ID  GENERIC_ELF_DATA
+#define ELF_TARGET_ID  GENERIC_ELF_DATA
+#endif
+#endif
+
+
+#ifndef ELF_OSABI
+#ifndef ELF_OSABI
+#define ELF_OSABI ELFOSABI_NONE
+#define ELF_OSABI ELFOSABI_NONE
+#endif
+#endif
+
+
+#define ELF_COMMONPAGESIZE ELF_MAXPAGESIZE
+#define ELF_COMMONPAGESIZE ELF_MAXPAGESIZE
+#define ELF_MINPAGESIZE ELF_COMMONPAGESIZE
+#define ELF_MINPAGESIZE ELF_COMMONPAGESIZE
+
+
+#if ELF_COMMONPAGESIZE > ELF_MAXPAGESIZE
+#if ELF_COMMONPAGESIZE > ELF_MAXPAGESIZE
+# error ELF_COMMONPAGESIZE > ELF_MAXPAGESIZE
+# error ELF_COMMONPAGESIZE > ELF_MAXPAGESIZE
+#endif
+#endif
+#if ELF_MINPAGESIZE > ELF_COMMONPAGESIZE
+#if ELF_MINPAGESIZE > ELF_COMMONPAGESIZE
+# error ELF_MINPAGESIZE > ELF_COMMONPAGESIZE
+# error ELF_MINPAGESIZE > ELF_COMMONPAGESIZE
+#endif
+#endif
+
+
+#ifndef ELF_DYNAMIC_SEC_FLAGS
+#ifndef ELF_DYNAMIC_SEC_FLAGS
+/* Note that we set the SEC_IN_MEMORY flag for these sections.  */
+/* Note that we set the SEC_IN_MEMORY flag for these sections.  */
+#define ELF_DYNAMIC_SEC_FLAGS                  \
+#define ELF_DYNAMIC_SEC_FLAGS                  \
+  (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS     \
+  (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS     \
+   | SEC_IN_MEMORY | SEC_LINKER_CREATED)
+   | SEC_IN_MEMORY | SEC_LINKER_CREATED)
+#endif
+#endif
+
+
+#define elf_backend_collect FALSE
+#define elf_backend_collect FALSE
+#define elf_backend_type_change_ok FALSE
+#define elf_backend_type_change_ok FALSE
+
+
+#define elf_backend_sym_is_global      0
+#define elf_backend_sym_is_global      0
+#define elf_backend_object_p           0
+#define elf_backend_object_p           0
+#define elf_backend_symbol_processing  0
+#define elf_backend_symbol_processing  0
+#define elf_backend_symbol_table_processing    0
+#define elf_backend_symbol_table_processing    0
+#define elf_backend_get_symbol_type 0
+#define elf_backend_get_symbol_type 0
+#define elf_backend_archive_symbol_lookup _bfd_elf_archive_symbol_lookup
+#define elf_backend_archive_symbol_lookup _bfd_elf_archive_symbol_lookup
+#define elf_backend_name_local_section_symbols 0
+#define elf_backend_name_local_section_symbols 0
+#define elf_backend_section_processing 0
+#define elf_backend_section_processing 0
+#define elf_backend_section_from_shdr  _bfd_elf_make_section_from_shdr
+#define elf_backend_section_from_shdr  _bfd_elf_make_section_from_shdr
+#define elf_backend_section_flags      0
+#define elf_backend_section_flags      0
+#define elf_backend_get_sec_type_attr  _bfd_elf_get_sec_type_attr
+#define elf_backend_get_sec_type_attr  _bfd_elf_get_sec_type_attr
+#define elf_backend_section_from_phdr  _bfd_elf_make_section_from_phdr
+#define elf_backend_section_from_phdr  _bfd_elf_make_section_from_phdr
+#define elf_backend_fake_sections      0
+#define elf_backend_fake_sections      0
+#define elf_backend_section_from_bfd_section   0
+#define elf_backend_section_from_bfd_section   0
+#define elf_backend_add_symbol_hook    0
+#define elf_backend_add_symbol_hook    0
+#define elf_backend_link_output_symbol_hook 0
+#define elf_backend_link_output_symbol_hook 0
+#define elf_backend_create_dynamic_sections 0
+#define elf_backend_create_dynamic_sections 0
+#define elf_backend_omit_section_dynsym _bfd_elf_link_omit_section_dynsym
+#define elf_backend_omit_section_dynsym _bfd_elf_link_omit_section_dynsym
+#define elf_backend_relocs_compatible _bfd_elf_default_relocs_compatible
+#define elf_backend_relocs_compatible _bfd_elf_default_relocs_compatible
+#define elf_backend_check_relocs       0
+#define elf_backend_check_relocs       0
+#define elf_backend_check_directives   0
+#define elf_backend_check_directives   0
+#define elf_backend_notice_as_needed   _bfd_elf_notice_as_needed
+#define elf_backend_notice_as_needed   _bfd_elf_notice_as_needed
+#define elf_backend_adjust_dynamic_symbol 0
+#define elf_backend_adjust_dynamic_symbol 0
+#define elf_backend_always_size_sections 0
+#define elf_backend_always_size_sections 0
+#define elf_backend_size_dynamic_sections 0
+#define elf_backend_size_dynamic_sections 0
+#define elf_backend_init_index_section \
+#define elf_backend_init_index_section \
+ ((void (*) (bfd *, struct bfd_link_info *)) bfd_void)
+ ((void (*) (bfd *, struct bfd_link_info *)) bfd_void)
+#define elf_backend_finish_dynamic_symbol      0
+#define elf_backend_finish_dynamic_symbol      0
+#define elf_backend_finish_dynamic_sections    0
+#define elf_backend_finish_dynamic_sections    0
+#define elf_backend_begin_write_processing     0
+#define elf_backend_begin_write_processing     0
+#define elf_backend_final_write_processing     0
+#define elf_backend_final_write_processing     0
+#define elf_backend_additional_program_headers 0
+#define elf_backend_additional_program_headers 0
+#define elf_backend_modify_segment_map 0
+#define elf_backend_modify_segment_map 0
+#ifndef elf_backend_modify_program_headers
+#ifndef elf_backend_modify_program_headers
+#define elf_backend_modify_program_headers     0
+#define elf_backend_modify_program_headers     0
+#endif
+#endif
+#ifndef elf_backend_ecoff_debug_swap
+#ifndef elf_backend_ecoff_debug_swap
+#define elf_backend_ecoff_debug_swap   0
+#define elf_backend_ecoff_debug_swap   0
+#endif
+#endif
+#ifndef elf_backend_bfd_from_remote_memory
+#ifndef elf_backend_bfd_from_remote_memory
+#define elf_backend_bfd_from_remote_memory _bfd_elf32_bfd_from_remote_memory
+#define elf_backend_bfd_from_remote_memory _bfd_elf32_bfd_from_remote_memory
+#endif
+#endif
+#ifndef elf_backend_got_header_size
+#ifndef elf_backend_got_header_size
+#define elf_backend_got_header_size    0
+#define elf_backend_got_header_size    0
+#endif
+#endif
+#ifndef elf_backend_got_elt_size
+#ifndef elf_backend_got_elt_size
+#define elf_backend_got_elt_size _bfd_elf_default_got_elt_size
+#define elf_backend_got_elt_size _bfd_elf_default_got_elt_size
+#endif
+#endif
+#ifndef elf_backend_obj_attrs_vendor
+#ifndef elf_backend_obj_attrs_vendor
+#define elf_backend_obj_attrs_vendor           NULL
+#define elf_backend_obj_attrs_vendor           NULL
+#endif
+#endif
+#ifndef elf_backend_obj_attrs_section
+#ifndef elf_backend_obj_attrs_section
+#define elf_backend_obj_attrs_section          NULL
+#define elf_backend_obj_attrs_section          NULL
+#endif
+#endif
+#ifndef elf_backend_obj_attrs_arg_type
+#ifndef elf_backend_obj_attrs_arg_type
+#define elf_backend_obj_attrs_arg_type         NULL
+#define elf_backend_obj_attrs_arg_type         NULL
+#endif
+#endif
+#ifndef elf_backend_obj_attrs_section_type
+#ifndef elf_backend_obj_attrs_section_type
+#define elf_backend_obj_attrs_section_type             SHT_GNU_ATTRIBUTES
+#define elf_backend_obj_attrs_section_type             SHT_GNU_ATTRIBUTES
+#endif
+#endif
+#ifndef elf_backend_obj_attrs_order
+#ifndef elf_backend_obj_attrs_order
+#define elf_backend_obj_attrs_order            NULL
+#define elf_backend_obj_attrs_order            NULL
+#endif
+#endif
+#define elf_backend_obj_attrs_handle_unknown   NULL
+#define elf_backend_obj_attrs_handle_unknown   NULL
+#define elf_backend_static_tls_alignment       1
+#define elf_backend_static_tls_alignment       1
+#define elf_backend_post_process_headers       _bfd_elf_post_process_headers
+#define elf_backend_post_process_headers       _bfd_elf_post_process_headers
+#define elf_backend_print_symbol_all           NULL
+#define elf_backend_print_symbol_all           NULL
+#define elf_backend_output_arch_local_syms     NULL
+#define elf_backend_output_arch_local_syms     NULL
+#define elf_backend_output_arch_syms           NULL
+#define elf_backend_output_arch_syms           NULL
+#define elf_backend_copy_indirect_symbol  _bfd_elf_link_hash_copy_indirect
+#define elf_backend_copy_indirect_symbol  _bfd_elf_link_hash_copy_indirect
+#define elf_backend_hide_symbol                _bfd_elf_link_hash_hide_symbol
+#define elf_backend_hide_symbol                _bfd_elf_link_hash_hide_symbol
+#define elf_backend_fixup_symbol               NULL
+#define elf_backend_fixup_symbol               NULL
+#define elf_backend_merge_symbol_attribute     NULL
+#define elf_backend_merge_symbol_attribute     NULL
+#define elf_backend_get_target_dtag            NULL
+#define elf_backend_get_target_dtag            NULL
+#define elf_backend_ignore_undef_symbol                NULL
+#define elf_backend_ignore_undef_symbol                NULL
+#define elf_backend_emit_relocs                        _bfd_elf_link_output_relocs
+#define elf_backend_emit_relocs                        _bfd_elf_link_output_relocs
+#define elf_backend_count_relocs               NULL
+#define elf_backend_count_relocs               NULL
+#define elf_backend_count_additional_relocs    NULL
+#define elf_backend_count_additional_relocs    NULL
+#define elf_backend_sort_relocs_p              NULL
+#define elf_backend_sort_relocs_p              NULL
+#define elf_backend_grok_prstatus              NULL
+#define elf_backend_grok_prstatus              NULL
+#define elf_backend_grok_psinfo                        NULL
+#define elf_backend_grok_psinfo                        NULL
+#define elf_backend_write_core_note            NULL
+#define elf_backend_write_core_note            NULL
+#define elf_backend_lookup_section_flags_hook  NULL
+#define elf_backend_lookup_section_flags_hook  NULL
+#define elf_backend_reloc_type_class           _bfd_elf_reloc_type_class
+#define elf_backend_reloc_type_class           _bfd_elf_reloc_type_class
+#define elf_backend_discard_info               NULL
+#define elf_backend_discard_info               NULL
+#define elf_backend_ignore_discarded_relocs    NULL
+#define elf_backend_ignore_discarded_relocs    NULL
+#define elf_backend_action_discarded _bfd_elf_default_action_discarded
+#define elf_backend_action_discarded _bfd_elf_default_action_discarded
+#define elf_backend_eh_frame_address_size _bfd_elf_eh_frame_address_size
+#define elf_backend_eh_frame_address_size _bfd_elf_eh_frame_address_size
+#define elf_backend_can_make_relative_eh_frame _bfd_elf_can_make_relative
+#define elf_backend_can_make_relative_eh_frame _bfd_elf_can_make_relative
+#define elf_backend_can_make_lsda_relative_eh_frame    _bfd_elf_can_make_relative
+#define elf_backend_can_make_lsda_relative_eh_frame    _bfd_elf_can_make_relative
+#define elf_backend_encode_eh_address          _bfd_elf_encode_eh_address
+#define elf_backend_encode_eh_address          _bfd_elf_encode_eh_address
+#define elf_backend_write_section              NULL
+#define elf_backend_write_section              NULL
+#define elf_backend_mips_irix_compat           NULL
+#define elf_backend_mips_irix_compat           NULL
+#define elf_backend_mips_rtype_to_howto                NULL
+#define elf_backend_mips_rtype_to_howto                NULL
+
+
+/* Previously, backends could only use SHT_REL or SHT_RELA relocation
+/* Previously, backends could only use SHT_REL or SHT_RELA relocation
+   sections, but not both.  They defined USE_REL to indicate SHT_REL
+   sections, but not both.  They defined USE_REL to indicate SHT_REL
+   sections, and left it undefined to indicated SHT_RELA sections.
+   sections, and left it undefined to indicated SHT_RELA sections.
+   For backwards compatibility, we still support this usage.  */
+   For backwards compatibility, we still support this usage.  */
+#ifndef USE_REL
+#ifndef USE_REL
+#define USE_REL 0
+#define USE_REL 0
+#endif
+#endif
+
+
+/* Use these in new code.  */
+/* Use these in new code.  */
+#define elf_backend_may_use_rel_p USE_REL
+#define elf_backend_may_use_rel_p USE_REL
+#define elf_backend_may_use_rela_p !USE_REL
+#define elf_backend_may_use_rela_p !USE_REL
+#define elf_backend_default_use_rela_p !USE_REL
+#define elf_backend_default_use_rela_p !USE_REL
+#define elf_backend_rela_plts_and_copies_p elf_backend_default_use_rela_p
+#define elf_backend_rela_plts_and_copies_p elf_backend_default_use_rela_p
+
+
+#ifndef elf_backend_rela_normal
+#ifndef elf_backend_rela_normal
+#define elf_backend_rela_normal 0
+#define elf_backend_rela_normal 0
+#endif
+#endif
+
+
+#define elf_backend_plt_sym_val NULL
+#define elf_backend_plt_sym_val NULL
+#define elf_backend_relplt_name NULL
+#define elf_backend_relplt_name NULL
+
+
+#define ELF_MACHINE_ALT1 0
+#define ELF_MACHINE_ALT1 0
+#define ELF_MACHINE_ALT2 0
+#define ELF_MACHINE_ALT2 0
+
+
+#ifndef elf_backend_size_info
+#ifndef elf_backend_size_info
+#define elf_backend_size_info _bfd_elf32_size_info
+#define elf_backend_size_info _bfd_elf32_size_info
+#endif
+#endif
+
+
+#define elf_backend_special_sections NULL
+#define elf_backend_special_sections NULL
+#define elf_backend_sign_extend_vma 0
+#define elf_backend_sign_extend_vma 0
+#define elf_backend_link_order_error_handler _bfd_default_error_handler
+#define elf_backend_link_order_error_handler _bfd_default_error_handler
+#define elf_backend_common_definition _bfd_elf_common_definition
+#define elf_backend_common_definition _bfd_elf_common_definition
+#define elf_backend_common_section_index _bfd_elf_common_section_index
+#define elf_backend_common_section_index _bfd_elf_common_section_index
+#define elf_backend_common_section _bfd_elf_common_section
+#define elf_backend_common_section _bfd_elf_common_section
+
+
+#define elf_backend_merge_symbol NULL
+#define elf_backend_merge_symbol NULL
+#define elf_backend_hash_symbol _bfd_elf_hash_symbol
+#define elf_backend_hash_symbol _bfd_elf_hash_symbol
+#define elf_backend_is_function_type _bfd_elf_is_function_type
+#define elf_backend_is_function_type _bfd_elf_is_function_type
+#define elf_backend_maybe_function_sym _bfd_elf_maybe_function_sym
+#define elf_backend_maybe_function_sym _bfd_elf_maybe_function_sym
+#define elf_backend_get_reloc_section _bfd_elf_get_reloc_section
+#define elf_backend_get_reloc_section _bfd_elf_get_reloc_section
+#define elf_backend_copy_special_section_fields NULL
+#define elf_backend_copy_special_section_fields NULL
+#define elf_backend_compact_eh_encoding NULL
+#define elf_backend_compact_eh_encoding NULL
+#define elf_backend_cant_unwind_opcode 0
+#define elf_backend_cant_unwind_opcode 0
+
+
+#define elf_match_priority \
+#define elf_match_priority \
+  (ELF_ARCH == bfd_arch_unknown ? 2 : ELF_OSABI == ELFOSABI_NONE ? 1 : 0)
+  (ELF_ARCH == bfd_arch_unknown ? 2 : ELF_OSABI == ELFOSABI_NONE ? 1 : 0)
+
+
+extern const struct elf_size_info _bfd_elf32_size_info;
+extern const struct elf_size_info _bfd_elf32_size_info;
+
+
+static struct elf_backend_data elf32_bed =
+static struct elf_backend_data elf32_bed =
+{
+{
+  ELF_ARCH,                    /* arch */
+  ELF_ARCH,                    /* arch */
+  ELF_TARGET_ID,               /* target_id */
+  ELF_TARGET_ID,               /* target_id */
+  ELF_MACHINE_CODE,            /* elf_machine_code */
+  ELF_MACHINE_CODE,            /* elf_machine_code */
+  ELF_OSABI,                   /* elf_osabi  */
+  ELF_OSABI,                   /* elf_osabi  */
+  ELF_MAXPAGESIZE,             /* maxpagesize */
+  ELF_MAXPAGESIZE,             /* maxpagesize */
+  ELF_MINPAGESIZE,             /* minpagesize */
+  ELF_MINPAGESIZE,             /* minpagesize */
+  ELF_COMMONPAGESIZE,          /* commonpagesize */
+  ELF_COMMONPAGESIZE,          /* commonpagesize */
+  ELF_DYNAMIC_SEC_FLAGS,       /* dynamic_sec_flags */
+  ELF_DYNAMIC_SEC_FLAGS,       /* dynamic_sec_flags */
+  elf_backend_arch_data,
+  elf_backend_arch_data,
+  elf_info_to_howto,
+  elf_info_to_howto,
+  elf_info_to_howto_rel,
+  elf_info_to_howto_rel,
+  elf_backend_sym_is_global,
+  elf_backend_sym_is_global,
+  elf_backend_object_p,
+  elf_backend_object_p,
+  elf_backend_symbol_processing,
+  elf_backend_symbol_processing,
+  elf_backend_symbol_table_processing,
+  elf_backend_symbol_table_processing,
+  elf_backend_get_symbol_type,
+  elf_backend_get_symbol_type,
+  elf_backend_archive_symbol_lookup,
+  elf_backend_archive_symbol_lookup,
+  elf_backend_name_local_section_symbols,
+  elf_backend_name_local_section_symbols,
+  elf_backend_section_processing,
+  elf_backend_section_processing,
+  elf_backend_section_from_shdr,
+  elf_backend_section_from_shdr,
+  elf_backend_section_flags,
+  elf_backend_section_flags,
+  elf_backend_get_sec_type_attr,
+  elf_backend_get_sec_type_attr,
+  elf_backend_section_from_phdr,
+  elf_backend_section_from_phdr,
+  elf_backend_fake_sections,
+  elf_backend_fake_sections,
+  elf_backend_section_from_bfd_section,
+  elf_backend_section_from_bfd_section,
+  elf_backend_add_symbol_hook,
+  elf_backend_add_symbol_hook,
+  elf_backend_link_output_symbol_hook,
+  elf_backend_link_output_symbol_hook,
+  elf_backend_create_dynamic_sections,
+  elf_backend_create_dynamic_sections,
+  elf_backend_omit_section_dynsym,
+  elf_backend_omit_section_dynsym,
+  elf_backend_relocs_compatible,
+  elf_backend_relocs_compatible,
+  elf_backend_check_relocs,
+  elf_backend_check_relocs,
+  elf_backend_check_directives,
+  elf_backend_check_directives,
+  elf_backend_notice_as_needed,
+  elf_backend_notice_as_needed,
+  elf_backend_adjust_dynamic_symbol,
+  elf_backend_adjust_dynamic_symbol,
+  elf_backend_always_size_sections,
+  elf_backend_always_size_sections,
+  elf_backend_size_dynamic_sections,
+  elf_backend_size_dynamic_sections,
+  elf_backend_init_index_section,
+  elf_backend_init_index_section,
+  elf_backend_relocate_section,
+  elf_backend_relocate_section,
+  elf_backend_finish_dynamic_symbol,
+  elf_backend_finish_dynamic_symbol,
+  elf_backend_finish_dynamic_sections,
+  elf_backend_finish_dynamic_sections,
+  elf_backend_begin_write_processing,
+  elf_backend_begin_write_processing,
+  elf_backend_final_write_processing,
+  elf_backend_final_write_processing,
+  elf_backend_additional_program_headers,
+  elf_backend_additional_program_headers,
+  elf_backend_modify_segment_map,
+  elf_backend_modify_segment_map,
+  elf_backend_modify_program_headers,
+  elf_backend_modify_program_headers,
+  elf_backend_gc_keep,
+  elf_backend_gc_keep,
+  elf_backend_gc_mark_dynamic_ref,
+  elf_backend_gc_mark_dynamic_ref,
+  elf_backend_gc_mark_hook,
+  elf_backend_gc_mark_hook,
+  elf_backend_gc_mark_extra_sections,
+  elf_backend_gc_mark_extra_sections,
+  elf_backend_gc_sweep_hook,
+  elf_backend_gc_sweep_hook,
+  elf_backend_post_process_headers,
+  elf_backend_post_process_headers,
+  elf_backend_print_symbol_all,
+  elf_backend_print_symbol_all,
+  elf_backend_output_arch_local_syms,
+  elf_backend_output_arch_local_syms,
+  elf_backend_output_arch_syms,
+  elf_backend_output_arch_syms,
+  elf_backend_copy_indirect_symbol,
+  elf_backend_copy_indirect_symbol,
+  elf_backend_hide_symbol,
+  elf_backend_hide_symbol,
+  elf_backend_fixup_symbol,
+  elf_backend_fixup_symbol,
+  elf_backend_merge_symbol_attribute,
+  elf_backend_merge_symbol_attribute,
+  elf_backend_get_target_dtag,
+  elf_backend_get_target_dtag,
+  elf_backend_ignore_undef_symbol,
+  elf_backend_ignore_undef_symbol,
+  elf_backend_emit_relocs,
+  elf_backend_emit_relocs,
+  elf_backend_count_relocs,
+  elf_backend_count_relocs,
+  elf_backend_count_additional_relocs,
+  elf_backend_count_additional_relocs,
+  elf_backend_sort_relocs_p,
+  elf_backend_sort_relocs_p,
+  elf_backend_grok_prstatus,
+  elf_backend_grok_prstatus,
+  elf_backend_grok_psinfo,
+  elf_backend_grok_psinfo,
+  elf_backend_write_core_note,
+  elf_backend_write_core_note,
+  elf_backend_lookup_section_flags_hook,
+  elf_backend_lookup_section_flags_hook,
+  elf_backend_reloc_type_class,
+  elf_backend_reloc_type_class,
+  elf_backend_discard_info,
+  elf_backend_discard_info,
+  elf_backend_ignore_discarded_relocs,
+  elf_backend_ignore_discarded_relocs,
+  elf_backend_action_discarded,
+  elf_backend_action_discarded,
+  elf_backend_eh_frame_address_size,
+  elf_backend_eh_frame_address_size,
+  elf_backend_can_make_relative_eh_frame,
+  elf_backend_can_make_relative_eh_frame,
+  elf_backend_can_make_lsda_relative_eh_frame,
+  elf_backend_can_make_lsda_relative_eh_frame,
+  elf_backend_encode_eh_address,
+  elf_backend_encode_eh_address,
+  elf_backend_write_section,
+  elf_backend_write_section,
+  elf_backend_mips_irix_compat,
+  elf_backend_mips_irix_compat,
+  elf_backend_mips_rtype_to_howto,
+  elf_backend_mips_rtype_to_howto,
+  elf_backend_ecoff_debug_swap,
+  elf_backend_ecoff_debug_swap,
+  elf_backend_bfd_from_remote_memory,
+  elf_backend_bfd_from_remote_memory,
+  elf_backend_plt_sym_val,
+  elf_backend_plt_sym_val,
+  elf_backend_common_definition,
+  elf_backend_common_definition,
+  elf_backend_common_section_index,
+  elf_backend_common_section_index,
+  elf_backend_common_section,
+  elf_backend_common_section,
+  elf_backend_merge_symbol,
+  elf_backend_merge_symbol,
+  elf_backend_hash_symbol,
+  elf_backend_hash_symbol,
+  elf_backend_is_function_type,
+  elf_backend_is_function_type,
+  elf_backend_maybe_function_sym,
+  elf_backend_maybe_function_sym,
+  elf_backend_get_reloc_section,
+  elf_backend_get_reloc_section,
+  elf_backend_copy_special_section_fields,
+  elf_backend_copy_special_section_fields,
+  elf_backend_link_order_error_handler,
+  elf_backend_link_order_error_handler,
+  elf_backend_relplt_name,
+  elf_backend_relplt_name,
+  ELF_MACHINE_ALT1,
+  ELF_MACHINE_ALT1,
+  ELF_MACHINE_ALT2,
+  ELF_MACHINE_ALT2,
+  &elf_backend_size_info,
+  &elf_backend_size_info,
+  elf_backend_special_sections,
+  elf_backend_special_sections,
+  elf_backend_got_header_size,
+  elf_backend_got_header_size,
+  elf_backend_got_elt_size,
+  elf_backend_got_elt_size,
+  elf_backend_obj_attrs_vendor,
+  elf_backend_obj_attrs_vendor,
+  elf_backend_obj_attrs_section,
+  elf_backend_obj_attrs_section,
+  elf_backend_obj_attrs_arg_type,
+  elf_backend_obj_attrs_arg_type,
+  elf_backend_obj_attrs_section_type,
+  elf_backend_obj_attrs_section_type,
+  elf_backend_obj_attrs_order,
+  elf_backend_obj_attrs_order,
+  elf_backend_obj_attrs_handle_unknown,
+  elf_backend_obj_attrs_handle_unknown,
+  elf_backend_compact_eh_encoding,
+  elf_backend_compact_eh_encoding,
+  elf_backend_cant_unwind_opcode,
+  elf_backend_cant_unwind_opcode,
+  elf_backend_static_tls_alignment,
+  elf_backend_static_tls_alignment,
+  elf_backend_stack_align,
+  elf_backend_stack_align,
+  elf_backend_strtab_flags,
+  elf_backend_strtab_flags,
+  elf_backend_collect,
+  elf_backend_collect,
+  elf_backend_type_change_ok,
+  elf_backend_type_change_ok,
+  elf_backend_may_use_rel_p,
+  elf_backend_may_use_rel_p,
+  elf_backend_may_use_rela_p,
+  elf_backend_may_use_rela_p,
+  elf_backend_default_use_rela_p,
+  elf_backend_default_use_rela_p,
+  elf_backend_rela_plts_and_copies_p,
+  elf_backend_rela_plts_and_copies_p,
+  elf_backend_rela_normal,
+  elf_backend_rela_normal,
+  elf_backend_sign_extend_vma,
+  elf_backend_sign_extend_vma,
+  elf_backend_want_got_plt,
+  elf_backend_want_got_plt,
+  elf_backend_plt_readonly,
+  elf_backend_plt_readonly,
+  elf_backend_want_plt_sym,
+  elf_backend_want_plt_sym,
+  elf_backend_plt_not_loaded,
+  elf_backend_plt_not_loaded,
+  elf_backend_plt_alignment,
+  elf_backend_plt_alignment,
+  elf_backend_can_gc_sections,
+  elf_backend_can_gc_sections,
+  elf_backend_can_refcount,
+  elf_backend_can_refcount,
+  elf_backend_want_got_sym,
+  elf_backend_want_got_sym,
+  elf_backend_want_dynbss,
+  elf_backend_want_dynbss,
+  elf_backend_want_p_paddr_set_to_zero,
+  elf_backend_want_p_paddr_set_to_zero,
+  elf_backend_default_execstack,
+  elf_backend_default_execstack,
+  elf_backend_caches_rawsize,
+  elf_backend_caches_rawsize,
+  elf_backend_extern_protected_data
+  elf_backend_extern_protected_data
+};
+};
+
+
+/* Forward declaration for use when initialising alternative_target field.  */
+/* Forward declaration for use when initialising alternative_target field.  */
+
+
+#ifdef TARGET_BIG_SYM
+#ifdef TARGET_BIG_SYM
+const bfd_target TARGET_BIG_SYM =
+const bfd_target TARGET_BIG_SYM =
+{
+{
+  /* name: identify kind of target */
+  /* name: identify kind of target */
+  TARGET_BIG_NAME,
+  TARGET_BIG_NAME,
+
+
+  /* flavour: general indication about file */
+  /* flavour: general indication about file */
+  bfd_target_elf_flavour,
+  bfd_target_elf_flavour,
+
+
+  /* byteorder: data is big endian */
+  /* byteorder: data is big endian */
+  BFD_ENDIAN_BIG,
+  BFD_ENDIAN_BIG,
+
+
+  /* header_byteorder: header is also big endian */
+  /* header_byteorder: header is also big endian */
+  BFD_ENDIAN_BIG,
+  BFD_ENDIAN_BIG,
+
+
+  /* object_flags: mask of all file flags */
+  /* object_flags: mask of all file flags */
+  (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS
+  (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS
+   | DYNAMIC | WP_TEXT | D_PAGED | BFD_COMPRESS | BFD_DECOMPRESS
+   | DYNAMIC | WP_TEXT | D_PAGED | BFD_COMPRESS | BFD_DECOMPRESS
+   | BFD_COMPRESS_GABI | BFD_CONVERT_ELF_COMMON | BFD_USE_ELF_STT_COMMON),
+   | BFD_COMPRESS_GABI | BFD_CONVERT_ELF_COMMON | BFD_USE_ELF_STT_COMMON),
+
+
+  /* section_flags: mask of all section flags */
+  /* section_flags: mask of all section flags */
+  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY
+  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY
+   | SEC_CODE | SEC_DATA | SEC_DEBUGGING | SEC_EXCLUDE | SEC_SORT_ENTRIES
+   | SEC_CODE | SEC_DATA | SEC_DEBUGGING | SEC_EXCLUDE | SEC_SORT_ENTRIES
+   | SEC_SMALL_DATA | SEC_MERGE | SEC_STRINGS | SEC_GROUP),
+   | SEC_SMALL_DATA | SEC_MERGE | SEC_STRINGS | SEC_GROUP),
+
+
+   /* leading_symbol_char: is the first char of a user symbol
+   /* leading_symbol_char: is the first char of a user symbol
+      predictable, and if so what is it */
+      predictable, and if so what is it */
+  elf_symbol_leading_char,
+  elf_symbol_leading_char,
+
+
+  /* ar_pad_char: pad character for filenames within an archive header
+  /* ar_pad_char: pad character for filenames within an archive header
+     FIXME:  this really has nothing to do with ELF, this is a characteristic
+     FIXME:  this really has nothing to do with ELF, this is a characteristic
+     of the archiver and/or os and should be independently tunable */
+     of the archiver and/or os and should be independently tunable */
+  '/',
+  '/',
+
+
+  /* ar_max_namelen: maximum number of characters in an archive header
+  /* ar_max_namelen: maximum number of characters in an archive header
+     FIXME:  this really has nothing to do with ELF, this is a characteristic
+     FIXME:  this really has nothing to do with ELF, this is a characteristic
+     of the archiver and should be independently tunable.  The System V ABI,
+     of the archiver and should be independently tunable.  The System V ABI,
+     Chapter 7 (Formats & Protocols), Archive section sets this as 15.  */
+     Chapter 7 (Formats & Protocols), Archive section sets this as 15.  */
+  15,
+  15,
+
+
+  elf_match_priority,
+  elf_match_priority,
+
+
+  /* Routines to byte-swap various sized integers from the data sections */
+  /* Routines to byte-swap various sized integers from the data sections */
+  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+    bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+    bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+    bfd_getb16, bfd_getb_signed_16, bfd_putb16,
+    bfd_getb16, bfd_getb_signed_16, bfd_putb16,
+
+
+  /* Routines to byte-swap various sized integers from the file headers */
+  /* Routines to byte-swap various sized integers from the file headers */
+  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+    bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+    bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+    bfd_getb16, bfd_getb_signed_16, bfd_putb16,
+    bfd_getb16, bfd_getb_signed_16, bfd_putb16,
+
+
+  /* bfd_check_format: check the format of a file being read */
+  /* bfd_check_format: check the format of a file being read */
+  { _bfd_dummy_target,         /* unknown format */
+  { _bfd_dummy_target,         /* unknown format */
+    bfd_elf32_object_p,                /* assembler/linker output (object file) */
+    bfd_elf32_object_p,                /* assembler/linker output (object file) */
+    bfd_elf32_archive_p,       /* an archive */
+    bfd_elf32_archive_p,       /* an archive */
+    bfd_elf32_core_file_p      /* a core file */
+    bfd_elf32_core_file_p      /* a core file */
+  },
+  },
+
+
+  /* bfd_set_format: set the format of a file being written */
+  /* bfd_set_format: set the format of a file being written */
+  { bfd_false,
+  { bfd_false,
+    bfd_elf32_mkobject,
+    bfd_elf32_mkobject,
+    bfd_elf32_mkarchive,
+    bfd_elf32_mkarchive,
+    bfd_elf32_mkcorefile
+    bfd_elf32_mkcorefile
+  },
+  },
+
+
+  /* bfd_write_contents: write cached information into a file being written */
+  /* bfd_write_contents: write cached information into a file being written */
+  { bfd_false,
+  { bfd_false,
+    bfd_elf32_write_object_contents,
+    bfd_elf32_write_object_contents,
+    bfd_elf32_write_archive_contents,
+    bfd_elf32_write_archive_contents,
+    bfd_elf32_write_corefile_contents,
+    bfd_elf32_write_corefile_contents,
+  },
+  },
+
+
+  BFD_JUMP_TABLE_GENERIC (bfd_elf32),
+  BFD_JUMP_TABLE_GENERIC (bfd_elf32),
+  BFD_JUMP_TABLE_COPY (bfd_elf32),
+  BFD_JUMP_TABLE_COPY (bfd_elf32),
+  BFD_JUMP_TABLE_CORE (bfd_elf32),
+  BFD_JUMP_TABLE_CORE (bfd_elf32),
+#ifdef bfd_elf32_archive_functions
+#ifdef bfd_elf32_archive_functions
+  BFD_JUMP_TABLE_ARCHIVE (bfd_elf32_archive),
+  BFD_JUMP_TABLE_ARCHIVE (bfd_elf32_archive),
+#else
+#else
+  BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+  BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+#endif
+#endif
+  BFD_JUMP_TABLE_SYMBOLS (bfd_elf32),
+  BFD_JUMP_TABLE_SYMBOLS (bfd_elf32),
+  BFD_JUMP_TABLE_RELOCS (bfd_elf32),
+  BFD_JUMP_TABLE_RELOCS (bfd_elf32),
+  BFD_JUMP_TABLE_WRITE (bfd_elf32),
+  BFD_JUMP_TABLE_WRITE (bfd_elf32),
+  BFD_JUMP_TABLE_LINK (bfd_elf32),
+  BFD_JUMP_TABLE_LINK (bfd_elf32),
+  BFD_JUMP_TABLE_DYNAMIC (bfd_elf32),
+  BFD_JUMP_TABLE_DYNAMIC (bfd_elf32),
+
+
+  /* Alternative endian target.  */
+  /* Alternative endian target.  */
+#ifdef TARGET_LITTLE_SYM
+#ifdef TARGET_LITTLE_SYM
+  & TARGET_LITTLE_SYM,
+  & TARGET_LITTLE_SYM,
+#else
+#else
+  NULL,
+  NULL,
+#endif
+#endif
+
+
+  /* backend_data: */
+  /* backend_data: */
+  &elf32_bed
+  &elf32_bed
+};
+};
+#endif
+#endif
+
+
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/libbfd.h binutils-2.27-zip/bfd/libbfd.h
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/libbfd.h binutils-2.27-zip/bfd/libbfd.h
--- binutils-2.27/bfd/libbfd.h  2016-08-03 03:36:51.000000000 -0400
--- binutils-2.27/bfd/libbfd.h  2016-08-03 03:36:51.000000000 -0400
+++ binutils-2.27-zip/bfd/libbfd.h      2017-01-04 22:04:11.000000000 -0500
+++ binutils-2.27-zip/bfd/libbfd.h      2017-01-04 22:04:11.000000000 -0500
@@ -3125,6 +3125,16 @@
@@ -3125,6 +3125,16 @@
   "BFD_RELOC_VISIUM_HI16_PCREL",
   "BFD_RELOC_VISIUM_HI16_PCREL",
   "BFD_RELOC_VISIUM_LO16_PCREL",
   "BFD_RELOC_VISIUM_LO16_PCREL",
   "BFD_RELOC_VISIUM_IM16_PCREL",
   "BFD_RELOC_VISIUM_IM16_PCREL",
+  "BFD_RELOC_ZIP_VALUE",
+  "BFD_RELOC_ZIP_VALUE",
+  "BFD_RELOC_ZIP_BRANCH",
+  "BFD_RELOC_ZIP_BRANCH",
+  "BFD_RELOC_ZIP_OPB_IMM",
+  "BFD_RELOC_ZIP_OPB_IMM",
+  "BFD_RELOC_ZIP_OPB_OFFSET",
+  "BFD_RELOC_ZIP_OPB_OFFSET",
+  "BFD_RELOC_ZIP_OPB_PCREL",
+  "BFD_RELOC_ZIP_OPB_PCREL",
+  "BFD_RELOC_ZIP_MOV_OFFSET",
+  "BFD_RELOC_ZIP_MOV_OFFSET",
+  "BFD_RELOC_ZIP_MOV_PCREL",
+  "BFD_RELOC_ZIP_MOV_PCREL",
+  "BFD_RELOC_ZIP_LDI",
+  "BFD_RELOC_ZIP_LDI",
+  "BFD_RELOC_ZIP_LLO",
+  "BFD_RELOC_ZIP_LLO",
+  "BFD_RELOC_ZIP_BREV",
+  "BFD_RELOC_ZIP_BREV",
  "@@overflow: BFD_RELOC_UNUSED@@",
  "@@overflow: BFD_RELOC_UNUSED@@",
 };
 };
 #endif
 #endif
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/Makefile.am binutils-2.27-zip/bfd/Makefile.am
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/Makefile.am binutils-2.27-zip/bfd/Makefile.am
--- binutils-2.27/bfd/Makefile.am       2016-08-03 03:36:50.000000000 -0400
--- binutils-2.27/bfd/Makefile.am       2016-08-03 03:36:50.000000000 -0400
+++ binutils-2.27-zip/bfd/Makefile.am   2016-12-31 17:26:07.151146300 -0500
+++ binutils-2.27-zip/bfd/Makefile.am   2016-12-31 17:26:07.151146300 -0500
@@ -173,7 +173,8 @@
@@ -173,7 +173,8 @@
        cpu-xstormy16.lo \
        cpu-xstormy16.lo \
        cpu-xtensa.lo \
        cpu-xtensa.lo \
        cpu-z80.lo \
        cpu-z80.lo \
-       cpu-z8k.lo
-       cpu-z8k.lo
+       cpu-z8k.lo \
+       cpu-z8k.lo \
+       cpu-zip.lo
+       cpu-zip.lo
 
 
 ALL_MACHINES_CFILES = \
 ALL_MACHINES_CFILES = \
        cpu-aarch64.c \
        cpu-aarch64.c \
@@ -260,7 +261,8 @@
@@ -260,7 +261,8 @@
        cpu-xstormy16.c \
        cpu-xstormy16.c \
        cpu-xtensa.c \
        cpu-xtensa.c \
        cpu-z80.c \
        cpu-z80.c \
-       cpu-z8k.c
-       cpu-z8k.c
+       cpu-z8k.c \
+       cpu-z8k.c \
+       cpu-zip.c
+       cpu-zip.c
 
 
 # The .o files needed by all of the 32 bit vectors that are configured into
 # The .o files needed by all of the 32 bit vectors that are configured into
 # target_vector in targets.c if configured with --enable-targets=all.
 # target_vector in targets.c if configured with --enable-targets=all.
@@ -382,6 +384,7 @@
@@ -382,6 +384,7 @@
        elf32-xgate.lo \
        elf32-xgate.lo \
        elf32-xstormy16.lo \
        elf32-xstormy16.lo \
        elf32-xtensa.lo \
        elf32-xtensa.lo \
+       elf32-zip.lo \
+       elf32-zip.lo \
        elf32.lo \
        elf32.lo \
        elflink.lo \
        elflink.lo \
        elfxx-sparc.lo \
        elfxx-sparc.lo \
@@ -574,6 +577,7 @@
@@ -574,6 +577,7 @@
        elf32-xgate.c \
        elf32-xgate.c \
        elf32-xstormy16.c \
        elf32-xstormy16.c \
        elf32-xtensa.c \
        elf32-xtensa.c \
+       elf32-zip.c \
+       elf32-zip.c \
        elf32.c \
        elf32.c \
        elflink.c \
        elflink.c \
        elfxx-sparc.c \
        elfxx-sparc.c \
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/Makefile.in binutils-2.27-zip/bfd/Makefile.in
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/Makefile.in binutils-2.27-zip/bfd/Makefile.in
--- binutils-2.27/bfd/Makefile.in       2016-08-03 04:06:27.000000000 -0400
--- binutils-2.27/bfd/Makefile.in       2016-08-03 04:06:27.000000000 -0400
+++ binutils-2.27-zip/bfd/Makefile.in   2017-01-04 14:29:55.000000000 -0500
+++ binutils-2.27-zip/bfd/Makefile.in   2017-01-04 14:29:55.000000000 -0500
@@ -505,7 +505,8 @@
@@ -505,7 +505,8 @@
        cpu-xstormy16.lo \
        cpu-xstormy16.lo \
        cpu-xtensa.lo \
        cpu-xtensa.lo \
        cpu-z80.lo \
        cpu-z80.lo \
-       cpu-z8k.lo
-       cpu-z8k.lo
+       cpu-z8k.lo \
+       cpu-z8k.lo \
+       cpu-zip.lo
+       cpu-zip.lo
 
 
 ALL_MACHINES_CFILES = \
 ALL_MACHINES_CFILES = \
        cpu-aarch64.c \
        cpu-aarch64.c \
@@ -592,7 +593,8 @@
@@ -592,7 +593,8 @@
        cpu-xstormy16.c \
        cpu-xstormy16.c \
        cpu-xtensa.c \
        cpu-xtensa.c \
        cpu-z80.c \
        cpu-z80.c \
-       cpu-z8k.c
-       cpu-z8k.c
+       cpu-z8k.c \
+       cpu-z8k.c \
+       cpu-zip.c
+       cpu-zip.c
 
 
 
 
 # The .o files needed by all of the 32 bit vectors that are configured into
 # The .o files needed by all of the 32 bit vectors that are configured into
@@ -715,6 +717,7 @@
@@ -715,6 +717,7 @@
        elf32-xgate.lo \
        elf32-xgate.lo \
        elf32-xstormy16.lo \
        elf32-xstormy16.lo \
        elf32-xtensa.lo \
        elf32-xtensa.lo \
+       elf32-zip.lo \
+       elf32-zip.lo \
        elf32.lo \
        elf32.lo \
        elflink.lo \
        elflink.lo \
        elfxx-sparc.lo \
        elfxx-sparc.lo \
@@ -907,6 +910,7 @@
@@ -907,6 +910,7 @@
        elf32-xgate.c \
        elf32-xgate.c \
        elf32-xstormy16.c \
        elf32-xstormy16.c \
        elf32-xtensa.c \
        elf32-xtensa.c \
+       elf32-zip.c \
+       elf32-zip.c \
        elf32.c \
        elf32.c \
        elflink.c \
        elflink.c \
        elfxx-sparc.c \
        elfxx-sparc.c \
@@ -1437,6 +1441,7 @@
@@ -1437,6 +1441,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-xtensa.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-xtensa.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-z80.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-z80.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-z8k.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-z8k.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-zip.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-zip.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo64.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo64.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf1.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf1.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf2.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf2.Plo@am__quote@
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/merge.c binutils-2.27-zip/bfd/merge.c
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/merge.c binutils-2.27-zip/bfd/merge.c
--- binutils-2.27/bfd/merge.c   2016-08-03 03:36:51.000000000 -0400
--- binutils-2.27/bfd/merge.c   2016-08-03 03:36:51.000000000 -0400
+++ binutils-2.27-zip/bfd/merge.c       2017-01-02 14:48:54.000000000 -0500
+++ binutils-2.27-zip/bfd/merge.c       2017-01-02 14:48:54.000000000 -0500
@@ -826,7 +826,7 @@
@@ -826,7 +826,7 @@
   else
   else
     {
     {
       contents = NULL;
       contents = NULL;
-      pos = sec->output_section->filepos + sec->output_offset;
-      pos = sec->output_section->filepos + sec->output_offset;
+      pos = sec->output_section->filepos + sec->output_offset * bfd_octets_per_byte(output_bfd);
+      pos = sec->output_section->filepos + sec->output_offset * bfd_octets_per_byte(output_bfd);
       if (bfd_seek (output_bfd, pos, SEEK_SET) != 0)
       if (bfd_seek (output_bfd, pos, SEEK_SET) != 0)
        return FALSE;
        return FALSE;
     }
     }
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/reloc.c binutils-2.27-zip/bfd/reloc.c
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/reloc.c binutils-2.27-zip/bfd/reloc.c
--- binutils-2.27/bfd/reloc.c   2016-08-03 03:36:51.000000000 -0400
--- binutils-2.27/bfd/reloc.c   2016-08-03 03:36:51.000000000 -0400
+++ binutils-2.27-zip/bfd/reloc.c       2017-01-04 22:03:52.000000000 -0500
+++ binutils-2.27-zip/bfd/reloc.c       2017-01-04 22:03:52.000000000 -0500
@@ -7697,7 +7697,32 @@
@@ -7697,7 +7697,32 @@
   BFD_RELOC_VISIUM_IM16_PCREL
   BFD_RELOC_VISIUM_IM16_PCREL
 ENUMDOC
 ENUMDOC
   Visium Relocations.
   Visium Relocations.
-
-
+ENUM
+ENUM
+  BFD_RELOC_ZIP_VALUE
+  BFD_RELOC_ZIP_VALUE
+ENUMDOC
+ENUMDOC
+  ZipCPU - 32 bit absolute value for LJMP instruction
+  ZipCPU - 32 bit absolute value for LJMP instruction
+ENUM
+ENUM
+  BFD_RELOC_ZIP_BRANCH
+  BFD_RELOC_ZIP_BRANCH
+ENUMDOC
+ENUMDOC
+  ZipCPU - 18-bit PC-relative offset for BRA (ADD #x,PC) instructions
+  ZipCPU - 18-bit PC-relative offset for BRA (ADD #x,PC) instructions
+ENUM
+ENUM
+  BFD_RELOC_ZIP_OPB_IMM
+  BFD_RELOC_ZIP_OPB_IMM
+ENUMX
+ENUMX
+  BFD_RELOC_ZIP_OPB_OFFSET
+  BFD_RELOC_ZIP_OPB_OFFSET
+ENUMX
+ENUMX
+  BFD_RELOC_ZIP_OPB_PCREL
+  BFD_RELOC_ZIP_OPB_PCREL
+ENUMX
+ENUMX
+  BFD_RELOC_ZIP_MOV_OFFSET
+  BFD_RELOC_ZIP_MOV_OFFSET
+ENUMX
+ENUMX
+  BFD_RELOC_ZIP_MOV_PCREL
+  BFD_RELOC_ZIP_MOV_PCREL
+ENUMX
+ENUMX
+  BFD_RELOC_ZIP_LDI
+  BFD_RELOC_ZIP_LDI
+ENUMX
+ENUMX
+  BFD_RELOC_ZIP_LLO
+  BFD_RELOC_ZIP_LLO
+ENUMX
+ENUMX
+  BFD_RELOC_ZIP_BREV
+  BFD_RELOC_ZIP_BREV
+ENUMDOC
+ENUMDOC
+  ZipCPU value relocations
+  ZipCPU value relocations
 ENDSENUM
 ENDSENUM
   BFD_RELOC_UNUSED
   BFD_RELOC_UNUSED
 CODE_FRAGMENT
 CODE_FRAGMENT
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/targets.c binutils-2.27-zip/bfd/targets.c
diff -Naur '--exclude=*.swp' binutils-2.27/bfd/targets.c binutils-2.27-zip/bfd/targets.c
--- binutils-2.27/bfd/targets.c 2016-08-03 03:36:51.000000000 -0400
--- binutils-2.27/bfd/targets.c 2016-08-03 03:36:51.000000000 -0400
+++ binutils-2.27-zip/bfd/targets.c     2016-12-31 17:37:14.021847080 -0500
+++ binutils-2.27-zip/bfd/targets.c     2016-12-31 17:37:14.021847080 -0500
@@ -910,6 +910,7 @@
@@ -910,6 +910,7 @@
 extern const bfd_target xtensa_elf32_le_vec;
 extern const bfd_target xtensa_elf32_le_vec;
 extern const bfd_target z80_coff_vec;
 extern const bfd_target z80_coff_vec;
 extern const bfd_target z8k_coff_vec;
 extern const bfd_target z8k_coff_vec;
+extern const bfd_target zip_elf32_vec;
+extern const bfd_target zip_elf32_vec;
 
 
 /* These are always included.  */
 /* These are always included.  */
 extern const bfd_target srec_vec;
 extern const bfd_target srec_vec;
@@ -1441,6 +1442,8 @@
@@ -1441,6 +1442,8 @@
        &z80_coff_vec,
        &z80_coff_vec,
 
 
        &z8k_coff_vec,
        &z8k_coff_vec,
+
+
+       &zip_elf32_vec,
+       &zip_elf32_vec,
 #endif /* not SELECT_VECS */
 #endif /* not SELECT_VECS */
 
 
 /* Always support S-records, for convenience.  */
 /* Always support S-records, for convenience.  */
diff -Naur '--exclude=*.swp' binutils-2.27/binutils/readelf.c binutils-2.27-zip/binutils/readelf.c
diff -Naur '--exclude=*.swp' binutils-2.27/binutils/readelf.c binutils-2.27-zip/binutils/readelf.c
--- binutils-2.27/binutils/readelf.c    2016-08-03 03:36:51.000000000 -0400
--- binutils-2.27/binutils/readelf.c    2016-08-03 03:36:51.000000000 -0400
+++ binutils-2.27-zip/binutils/readelf.c        2016-12-31 17:40:19.908241961 -0500
+++ binutils-2.27-zip/binutils/readelf.c        2016-12-31 17:40:19.908241961 -0500
@@ -154,6 +154,7 @@
@@ -154,6 +154,7 @@
 #include "elf/xgate.h"
 #include "elf/xgate.h"
 #include "elf/xstormy16.h"
 #include "elf/xstormy16.h"
 #include "elf/xtensa.h"
 #include "elf/xtensa.h"
+#include "elf/zip.h"
+#include "elf/zip.h"
 
 
 #include "getopt.h"
 #include "getopt.h"
 #include "libiberty.h"
 #include "libiberty.h"
@@ -800,6 +801,7 @@
@@ -800,6 +801,7 @@
     case EM_XTENSA_OLD:
     case EM_XTENSA_OLD:
     case EM_MICROBLAZE:
     case EM_MICROBLAZE:
     case EM_MICROBLAZE_OLD:
     case EM_MICROBLAZE_OLD:
+    case EM_ZIP:
+    case EM_ZIP:
       return TRUE;
       return TRUE;
 
 
     case EM_68HC05:
     case EM_68HC05:
@@ -1476,6 +1478,10 @@
@@ -1476,6 +1478,10 @@
        case EM_ALTERA_NIOS2:
        case EM_ALTERA_NIOS2:
          rtype = elf_nios2_reloc_type (type);
          rtype = elf_nios2_reloc_type (type);
          break;
          break;
+
+
+       case EM_ZIP:
+       case EM_ZIP:
+         rtype = elf_zip_reloc_type (type);
+         rtype = elf_zip_reloc_type (type);
+         break;
+         break;
        }
        }
 
 
       if (rtype == NULL)
       if (rtype == NULL)
@@ -2339,6 +2345,7 @@
@@ -2339,6 +2345,7 @@
     case EM_TILEGX:            return "Tilera TILE-Gx multicore architecture family";
     case EM_TILEGX:            return "Tilera TILE-Gx multicore architecture family";
     case EM_CUDA:              return "NVIDIA CUDA architecture";
     case EM_CUDA:              return "NVIDIA CUDA architecture";
     case EM_XGATE:             return "Motorola XGATE embedded processor";
     case EM_XGATE:             return "Motorola XGATE embedded processor";
+    case EM_ZIP:               return "Gisselquist Technology ZipCPU";
+    case EM_ZIP:               return "Gisselquist Technology ZipCPU";
     default:
     default:
       snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
       snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
       return buff;
       return buff;
@@ -11659,6 +11666,8 @@
@@ -11659,6 +11666,8 @@
     case EM_XTENSA_OLD:
     case EM_XTENSA_OLD:
     case EM_XTENSA:
     case EM_XTENSA:
       return reloc_type == 1; /* R_XTENSA_32.  */
       return reloc_type == 1; /* R_XTENSA_32.  */
+    case EM_ZIP:
+    case EM_ZIP:
+      return reloc_type == 1; /* R_ZIP_32.  */
+      return reloc_type == 1; /* R_ZIP_32.  */
     default:
     default:
       {
       {
        static unsigned int prev_warn = 0;
        static unsigned int prev_warn = 0;
@@ -11735,6 +11744,8 @@
@@ -11735,6 +11744,8 @@
     case EM_XTENSA_OLD:
     case EM_XTENSA_OLD:
     case EM_XTENSA:
     case EM_XTENSA:
       return reloc_type == 14; /* R_XTENSA_32_PCREL.  */
       return reloc_type == 14; /* R_XTENSA_32_PCREL.  */
+    case EM_ZIP:
+    case EM_ZIP:
+      return FALSE; /*  */
+      return FALSE; /*  */
     default:
     default:
       /* Do not abort or issue an error message here.  Not all targets use
       /* Do not abort or issue an error message here.  Not all targets use
         pc-relative 32-bit relocs in their DWARF debug information and we
         pc-relative 32-bit relocs in their DWARF debug information and we
@@ -11944,6 +11955,7 @@
@@ -11944,6 +11955,7 @@
     case EM_TI_C6000:/* R_C6000_NONE.  */
     case EM_TI_C6000:/* R_C6000_NONE.  */
     case EM_X86_64:  /* R_X86_64_NONE.  */
     case EM_X86_64:  /* R_X86_64_NONE.  */
     case EM_XC16X:
     case EM_XC16X:
+    case EM_ZIP:
+    case EM_ZIP:
       return reloc_type == 0;
       return reloc_type == 0;
 
 
     case EM_AARCH64:
     case EM_AARCH64:
diff -Naur '--exclude=*.swp' binutils-2.27/config.sub binutils-2.27-zip/config.sub
diff -Naur '--exclude=*.swp' binutils-2.27/config.sub binutils-2.27-zip/config.sub
--- binutils-2.27/config.sub    2016-08-03 03:36:51.000000000 -0400
--- binutils-2.27/config.sub    2016-08-03 03:36:51.000000000 -0400
+++ binutils-2.27-zip/config.sub        2017-01-11 14:20:34.804049801 -0500
+++ binutils-2.27-zip/config.sub        2017-01-11 14:20:34.804049801 -0500
@@ -316,7 +316,7 @@
@@ -316,7 +316,7 @@
        | visium \
        | visium \
        | we32k \
        | we32k \
        | x86 | xc16x | xstormy16 | xtensa \
        | x86 | xc16x | xstormy16 | xtensa \
-       | z8k | z80)
-       | z8k | z80)
+       | z8k | z80 )
+       | z8k | z80 )
                basic_machine=$basic_machine-unknown
                basic_machine=$basic_machine-unknown
                ;;
                ;;
        c54x)
        c54x)
@@ -355,6 +355,14 @@
@@ -355,6 +355,14 @@
        xscaleel)
        xscaleel)
                basic_machine=armel-unknown
                basic_machine=armel-unknown
                ;;
                ;;
+       zip-*-linux*)
+       zip-*-linux*)
+               basic_machine=zip
+               basic_machine=zip
+               os=-linux
+               os=-linux
+               ;;
+               ;;
+       zip*)
+       zip*)
+               basic_machine=zip-unknown
+               basic_machine=zip-unknown
+               os=-elf
+               os=-elf
+               ;;
+               ;;
 
 
        # We use `pc' rather than `unknown'
        # We use `pc' rather than `unknown'
        # because (1) that's what they normally are, and
        # because (1) that's what they normally are, and
diff -Naur '--exclude=*.swp' binutils-2.27/configure binutils-2.27-zip/configure
diff -Naur '--exclude=*.swp' binutils-2.27/configure binutils-2.27-zip/configure
--- binutils-2.27/configure     2016-08-03 03:54:55.000000000 -0400
--- binutils-2.27/configure     2016-08-03 03:54:55.000000000 -0400
+++ binutils-2.27-zip/configure 2017-01-08 20:37:33.566336786 -0500
+++ binutils-2.27-zip/configure 2017-01-08 20:37:33.566336786 -0500
@@ -3548,6 +3548,9 @@
@@ -3548,6 +3548,9 @@
   ft32-*-*)
   ft32-*-*)
     noconfigdirs="$noconfigdirs ${libgcj}"
     noconfigdirs="$noconfigdirs ${libgcj}"
     ;;
     ;;
+  zip*)
+  zip*)
+    noconfigdirs="$noconfigdirs ${libgcj}"
+    noconfigdirs="$noconfigdirs ${libgcj}"
+    ;;
+    ;;
   *-*-lynxos*)
   *-*-lynxos*)
     noconfigdirs="$noconfigdirs ${libgcj}"
     noconfigdirs="$noconfigdirs ${libgcj}"
     ;;
     ;;
@@ -3575,6 +3578,9 @@
@@ -3575,6 +3578,9 @@
     *-*-aix*)
     *-*-aix*)
        noconfigdirs="$noconfigdirs target-libgo"
        noconfigdirs="$noconfigdirs target-libgo"
        ;;
        ;;
+    zip*)
+    zip*)
+       noconfigdirs="$noconfigdirs target-libgo"
+       noconfigdirs="$noconfigdirs target-libgo"
+       ;;
+       ;;
     esac
     esac
 fi
 fi
 
 
@@ -3974,6 +3980,9 @@
@@ -3974,6 +3980,9 @@
   vax-*-*)
   vax-*-*)
     noconfigdirs="$noconfigdirs target-newlib target-libgloss"
     noconfigdirs="$noconfigdirs target-newlib target-libgloss"
     ;;
     ;;
+  zip*)
+  zip*)
+    noconfigdirs="$noconfigdirs gdb gprof"
+    noconfigdirs="$noconfigdirs gdb gprof"
+    ;;
+    ;;
 esac
 esac
 
 
 # If we aren't building newlib, then don't build libgloss, since libgloss
 # If we aren't building newlib, then don't build libgloss, since libgloss
diff -Naur '--exclude=*.swp' binutils-2.27/configure.ac binutils-2.27-zip/configure.ac
diff -Naur '--exclude=*.swp' binutils-2.27/configure.ac binutils-2.27-zip/configure.ac
--- binutils-2.27/configure.ac  2016-08-03 04:37:38.000000000 -0400
--- binutils-2.27/configure.ac  2016-08-03 04:37:38.000000000 -0400
+++ binutils-2.27-zip/configure.ac      2017-01-08 20:41:54.836485336 -0500
+++ binutils-2.27-zip/configure.ac      2017-01-08 20:41:54.836485336 -0500
@@ -884,6 +884,9 @@
@@ -884,6 +884,9 @@
   ft32-*-*)
   ft32-*-*)
     noconfigdirs="$noconfigdirs ${libgcj}"
     noconfigdirs="$noconfigdirs ${libgcj}"
     ;;
     ;;
+  zip*)
+  zip*)
+    noconfigdirs="$noconfigdirs ${libgcj}"
+    noconfigdirs="$noconfigdirs ${libgcj}"
+    ;;
+    ;;
   *-*-lynxos*)
   *-*-lynxos*)
     noconfigdirs="$noconfigdirs ${libgcj}"
     noconfigdirs="$noconfigdirs ${libgcj}"
     ;;
     ;;
@@ -911,6 +914,9 @@
@@ -911,6 +914,9 @@
     *-*-aix*)
     *-*-aix*)
        noconfigdirs="$noconfigdirs target-libgo"
        noconfigdirs="$noconfigdirs target-libgo"
        ;;
        ;;
+    zip*)
+    zip*)
+       noconfigdirs="$noconfigdirs target-libgo"
+       noconfigdirs="$noconfigdirs target-libgo"
+       ;;
+       ;;
     esac
     esac
 fi
 fi
 
 
@@ -1310,6 +1316,9 @@
@@ -1310,6 +1316,9 @@
   vax-*-*)
   vax-*-*)
     noconfigdirs="$noconfigdirs target-newlib target-libgloss"
     noconfigdirs="$noconfigdirs target-newlib target-libgloss"
     ;;
     ;;
+  zip*)
+  zip*)
+    noconfigdirs="$noconfigdirs ${libgcj} gdb sim gprof"
+    noconfigdirs="$noconfigdirs ${libgcj} gdb sim gprof"
+    ;;
+    ;;
 esac
 esac
 
 
 # If we aren't building newlib, then don't build libgloss, since libgloss
 # If we aren't building newlib, then don't build libgloss, since libgloss
diff -Naur '--exclude=*.swp' binutils-2.27/gas/config/tc-zip.c binutils-2.27-zip/gas/config/tc-zip.c
diff -Naur '--exclude=*.swp' binutils-2.27/gas/config/tc-zip.c binutils-2.27-zip/gas/config/tc-zip.c
--- binutils-2.27/gas/config/tc-zip.c   1969-12-31 19:00:00.000000000 -0500
--- binutils-2.27/gas/config/tc-zip.c   1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/gas/config/tc-zip.c       2017-03-08 17:57:01.048791909 -0500
+++ binutils-2.27-zip/gas/config/tc-zip.c       2017-03-15 23:03:15.801504568 -0400
@@ -0,0 +1,3329 @@
@@ -0,0 +1,3340 @@
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+//
+//
+// Filename:   tc-zip.c
+// Filename:   tc-zip.c
+//
+//
+// Project:    Zip CPU backend for GNU Binutils
+// Project:    Zip CPU backend for GNU Binutils
+//
+//
+// Purpose:    This is the main file associated with the Zip Assembler.  By
+// Purpose:    This is the main file associated with the Zip Assembler.  By
+//             that I mean that it handles all of the ZipCPU specifics.  The
+//             that I mean that it handles all of the ZipCPU specifics.  The
+//     rest of the files you find in this directory, mostly tc-cpuname.c and
+//     rest of the files you find in this directory, mostly tc-cpuname.c and
+//     such, handle other CPUs.  This one handles the ZipCPU.  The goal in
+//     such, handle other CPUs.  This one handles the ZipCPU.  The goal in
+//     doing this is so that nothing else changes when changes need to be made
+//     doing this is so that nothing else changes when changes need to be made
+//     to a CPU, and that changes to the assembler in general shouldn't impact
+//     to a CPU, and that changes to the assembler in general shouldn't impact
+//     the CPU specific processing.
+//     the CPU specific processing.
+//
+//
+//     I'll let you be the judge as to how well this file meets that goal.
+//     I'll let you be the judge as to how well this file meets that goal.
+//
+//
+// Creator:    Dan Gisselquist, Ph.D.
+// Creator:    Dan Gisselquist, Ph.D.
+//             Gisselquist Technology, LLC
+//             Gisselquist Technology, LLC
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+//
+//
+// Copyright (C) 2016-2017, Gisselquist Technology, LLC
+// Copyright (C) 2016-2017, Gisselquist Technology, LLC
+//
+//
+// This program is free software (firmware): you can redistribute it and/or
+// This program is free software (firmware): you can redistribute it and/or
+// modify it under the terms of  the GNU General Public License as published
+// modify it under the terms of  the GNU General Public License as published
+// by the Free Software Foundation, either version 3 of the License, or (at
+// by the Free Software Foundation, either version 3 of the License, or (at
+// your option) any later version.
+// your option) any later version.
+//
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
+// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+// for more details.
+//
+//
+// You should have received a copy of the GNU General Public License along
+// You should have received a copy of the GNU General Public License along
+// with this program.  (It's in the $(ROOT)/doc directory, run make with no
+// with this program.  (It's in the $(ROOT)/doc directory, run make with no
+// target there if the PDF file isn't present.)  If not, see
+// target there if the PDF file isn't present.)  If not, see
+// <http://www.gnu.org/licenses/> for a copy.
+// <http://www.gnu.org/licenses/> for a copy.
+//
+//
+// License:    GPL, v3, as defined and found on www.gnu.org,
+// License:    GPL, v3, as defined and found on www.gnu.org,
+//             http://www.gnu.org/licenses/gpl.html
+//             http://www.gnu.org/licenses/gpl.html
+//
+//
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+#include "as.h"
+#include "as.h"
+
+
+#include <stdlib.h>
+#include <stdlib.h>
+#include <string.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdint.h>
+#include <ctype.h>
+#include <ctype.h>
+
+
+#include "frags.h"
+#include "frags.h"
+#include "struc-symbol.h"
+#include "struc-symbol.h"
+#include "symbols.h"
+#include "symbols.h"
+#include "config/tc-zip.h"
+#include "config/tc-zip.h"
+#include "elf/zip.h"
+#include "elf/zip.h"
+
+
+// #define     ZIP_DEBUG
+// #define     ZIP_DEBUG
+
+
+const  char    comment_chars[] = ";#";
+const  char    comment_chars[] = ";#";
+const  char    line_comment_chars[] = ";#";
+const  char    line_comment_chars[] = ";#";
+// Characters which separate lines (newline need to be listed)
+// Characters which separate lines (newline need to be listed)
+const  char    line_separator_chars[] = "";
+const  char    line_separator_chars[] = "";
+
+
+// Characters defining floating point numbers, such as 0f<floatingpt#>
+// Characters defining floating point numbers, such as 0f<floatingpt#>
+const  char    FLT_CHARS[] = "fFrR";
+const  char    FLT_CHARS[] = "fFrR";
+
+
+// Characters that may be used for an exponent in floating point numbers
+// Characters that may be used for an exponent in floating point numbers
+const  char    EXP_CHARS[] = "eE";
+const  char    EXP_CHARS[] = "eE";
+
+
+static int     cis_mergable = 0; // tc_check_label, tc_frob_label
+static int     cis_mergable = 0; // tc_check_label, tc_frob_label
+
+
+// zip_param_got is a flag that we'll set to know if we need to reference a
+// zip_param_got is a flag that we'll set to know if we need to reference a
+// global offset table.  Since nothing we've done has yet needed that table,
+// global offset table.  Since nothing we've done has yet needed that table,
+// we'll keep this undefined for now.
+// we'll keep this undefined for now.
+//
+//
+// static int  zip_param_got = 0;
+// static int  zip_param_got = 0;
+static int     zip_param_cis = 1;
+static int     zip_param_cis = 1;
+static int     zip_param_small = 0;
+static int     zip_param_small = 0;
+static int     zip_param_use_machine  = 1;
+static int     zip_param_use_machine  = 1;
+
+
+typedef        struct  {
+typedef        struct  {
+       int     m_known;
+       int     m_known;
+       int32_t m_value;
+       int32_t m_value;
+       symbolS *m_addsy, *m_subsy;
+       symbolS *m_addsy, *m_subsy;
+} MACHINEVALUE;
+} MACHINEVALUE;
+
+
+typedef        struct  {
+typedef        struct  {
+       MACHINEVALUE    r[ZIP_USER_REGS];
+       MACHINEVALUE    r[ZIP_USER_REGS];
+} MACHINEREGS;
+} MACHINEREGS;
+
+
+MACHINEREGS    zipm;
+MACHINEREGS    zipm;
+
+
+static void zip_clear_machine(MACHINEREGS *pzipm);
+static void zip_clear_machine(MACHINEREGS *pzipm);
+
+
+void   md_begin(void) {
+void   md_begin(void) {
+       cis_mergable = FALSE;
+       cis_mergable = FALSE;
+       //
+       //
+       record_alignment(text_section, 2);
+       record_alignment(text_section, 2);
+       record_alignment(data_section, 2);
+       record_alignment(data_section, 2);
+       //
+       //
+       lex_type['['] = lex_type['A'];
+       lex_type['['] = lex_type['A'];
+       //
+       //
+       zip_clear_machine(&zipm);
+       zip_clear_machine(&zipm);
+}
+}
+
+
+void   md_end(void) { }
+void   md_end(void) { }
+
+
+void   zip_cons_align(int n) {
+void   zip_cons_align(int n) {
+       int     lg;
+       int     lg;
+       for(lg=0; ((1<<lg)<n)&&(lg<2); lg++)
+       for(lg=0; ((1<<lg)<n)&&(lg<2); lg++)
+               ;
+               ;
+       do_align(lg, NULL, 0, (1<<lg)-1);
+       do_align(lg, NULL, 0, (1<<lg)-1);
+}
+}
+
+
+void   zip_flush_pending_output(void) {
+void   zip_flush_pending_output(void) {
+       // If the Assembler is going to stuff things into our output stream,
+       // If the Assembler is going to stuff things into our output stream,
+       // then we need to make certain that any instructions that follow
+       // then we need to make certain that any instructions that follow
+       // dont try to merge with anything previous.  i.e., CIS = false.
+       // dont try to merge with anything previous.  i.e., CIS = false.
+       cis_mergable = FALSE;
+       cis_mergable = FALSE;
+}
+}
+
+
+int    zip_address_bytes(void) { return 4; }
+int    zip_address_bytes(void) { return 4; }
+
+
+const  pseudo_typeS    md_pseudo_table[] =
+const  pseudo_typeS    md_pseudo_table[] =
+{
+{
+       { "word", cons, 4 },    // ZipCPU word size is 4, not 2
+       { "word", cons, 4 },    // ZipCPU word size is 4, not 2
+       { "long", cons, 8 },    // ZipCPU longs are 64-bits, not 32
+       { "long", cons, 8 },    // ZipCPU longs are 64-bits, not 32
+       { "quad", cons,16 },    // ZipCPU QUAD-words are 128-bits, not 64
+       { "quad", cons,16 },    // ZipCPU QUAD-words are 128-bits, not 64
+       { NULL, NULL, 0 }
+       { NULL, NULL, 0 }
+};
+};
+
+
+#define        ZIP_CC_SLEEP    0x010
+#define        ZIP_CC_SLEEP    0x010
+#define        ZIP_CC_GIE      0x020
+#define        ZIP_CC_GIE      0x020
+#define        ZIP_CC_STEP     0x040
+#define        ZIP_CC_STEP     0x040
+
+
+#define        SIM_OPCODE      0x77800000      // 0111.x111.1000. .... 0_111.x_111.10....
+#define        SIM_OPCODE      0x77800000      // 0111.x111.1000. .... 0_111.x_111.10....
+#define        NOOP_OPCODE     0x77c00000      // 0111.x111.1100. .... 0_111.x_111.11....
+#define        NOOP_OPCODE     0x77c00000      // 0111.x111.1100. .... 0_111.x_111.11....
+
+
+typedef  struct {
+typedef  struct {
+       bfd_reloc_code_real_type        r_type;
+       bfd_reloc_code_real_type        r_type;
+       symbolS                         *r_sym;
+       symbolS                         *r_sym;
+       int                             r_pcrel;
+       int                             r_pcrel;
+       long                            r_fr_offset;
+       long                            r_fr_offset;
+       fixS                            *r_fix;
+       fixS                            *r_fix;
+       // Could also be char *name and bfd_reloc_code_real_type
+       // Could also be char *name and bfd_reloc_code_real_type
+} ZIPRELOC;
+} ZIPRELOC;
+
+
+// In case the instruction ...
+// In case the instruction ...
+#define        ZIP_MAX_NAUX    3 // Number of auxilliary instruction codes used
+#define        ZIP_MAX_NAUX    3 // Number of auxilliary instruction codes used
+typedef        struct {
+typedef        struct {
+       int             i_naux;
+       int             i_naux;
+       unsigned        i_code, // The actual machine language instruction
+       unsigned        i_code, // The actual machine language instruction
+                       i_aux[ZIP_MAX_NAUX];
+                       i_aux[ZIP_MAX_NAUX];
+       ZIP_OPCODE      i_op;
+       ZIP_OPCODE      i_op;
+       ZIP_CONDITION   i_cnd;
+       ZIP_CONDITION   i_cnd;
+       ZIP_REG         i_areg; // = ZIP_RNONE for no register
+       ZIP_REG         i_areg; // = ZIP_RNONE for no register
+       ZIP_REG         i_breg;
+       ZIP_REG         i_breg;
+       int             i_imm;
+       int             i_imm;
+       ZIPRELOC        *i_rp;
+       ZIPRELOC        *i_rp;
+} ZIPIS;
+} ZIPIS;
+
+
+static ZIPIS *
+static ZIPIS *
+zip_copy_insn(const ZIPIS *old) {
+zip_copy_insn(const ZIPIS *old) {
+       ZIPIS *nw = (ZIPIS *)xmalloc(sizeof(ZIPIS));
+       ZIPIS *nw = (ZIPIS *)xmalloc(sizeof(ZIPIS));
+
+
+       memcpy((char *)nw, (char *)old, sizeof(ZIPIS));
+       memcpy((char *)nw, (char *)old, sizeof(ZIPIS));
+
+
+       return nw;
+       return nw;
+}
+}
+
+
+static uint32_t
+static uint32_t
+zip_brev(uint32_t v) {
+zip_brev(uint32_t v) {
+       unsigned r=0, b;
+       unsigned r=0, b;
+
+
+       for(b=0; b<32; b++, v>>=1)
+       for(b=0; b<32; b++, v>>=1)
+               r = (r<<1)|(v&1);
+               r = (r<<1)|(v&1);
+
+
+       return r;
+       return r;
+}
+}
+
+
+static const   int MACH_VUNKNOWN = 0, MACH_VKNOWN = 1, MACH_VUPPERKNOWN = 2,
+static const   int MACH_VUNKNOWN = 0, MACH_VKNOWN = 1, MACH_VUPPERKNOWN = 2,
+                       MACH_VSYMKNOWN = 3;
+                       MACH_VSYMKNOWN = 3;
+
+
+static void
+static void
+zip_clear_machine(MACHINEREGS *pzipm) {
+zip_clear_machine(MACHINEREGS *pzipm) {
+       int     i;
+       int     i;
+
+
+#ifdef ZIP_DEBUG
+#ifdef ZIP_DEBUG
+       fprintf(stderr, "MACHINE, CLEAR\n");
+       fprintf(stderr, "MACHINE, CLEAR\n");
+#endif
+#endif
+       for(i=0; i<ZIP_USER_REGS; i++)
+       for(i=0; i<ZIP_USER_REGS; i++)
+               pzipm->r[i].m_known = MACH_VUNKNOWN;
+               pzipm->r[i].m_known = MACH_VUNKNOWN;
+       for(i=0; i<ZIP_USER_REGS; i++)
+       for(i=0; i<ZIP_USER_REGS; i++)
+               pzipm->r[i].m_addsy = NULL;
+               pzipm->r[i].m_addsy = NULL;
+       for(i=0; i<ZIP_USER_REGS; i++)
+       for(i=0; i<ZIP_USER_REGS; i++)
+               pzipm->r[i].m_subsy = NULL;
+               pzipm->r[i].m_subsy = NULL;
+}
+}
+
+
+static void
+static void
+zip_advance_machine(MACHINEREGS *pzipm, ZIPIS *insn) {
+zip_advance_machine(MACHINEREGS *pzipm, ZIPIS *insn) {
+       int             bval = insn->i_imm;
+       int             bval = insn->i_imm;
+       int             bknown;
+       int             bknown;
+       MACHINEVALUE    *av, *bv;
+       MACHINEVALUE    *av, *bv;
+
+
+       if (!zip_param_use_machine) {
+       if (!zip_param_use_machine) {
+               // zip_clear_machine(pzipm);
+               // zip_clear_machine(pzipm);
+               return;
+               return;
+       }
+       }
+
+
+       // The next three instructions don't change any machine values
+       // The next three instructions don't change any machine values
+       if((insn->i_op == ZIPO_SW)||(insn->i_op == ZIPO_SH)
+       if((insn->i_op == ZIPO_SW)||(insn->i_op == ZIPO_SH)
+               ||(insn->i_op==ZIPO_SB)
+               ||(insn->i_op==ZIPO_SB)
+               ||(insn->i_op == ZIPO_CMP)||(insn->i_op == ZIPO_TST))
+               ||(insn->i_op == ZIPO_CMP)||(insn->i_op == ZIPO_TST))
+               return;
+               return;
+
+
+       //
+       //
+       // What remains to be done is to include symbols into the machine
+       // What remains to be done is to include symbols into the machine
+       // state.  For now, we state that anything with a symbol becomes
+       // state.  For now, we state that anything with a symbol becomes
+       // unknown.
+       // unknown.
+       //
+       //
+       if ((insn->i_op == ZIPO_LJSR)||(insn->i_op == ZIPO_JSR)) {
+       if ((insn->i_op == ZIPO_LJSR)||(insn->i_op == ZIPO_JSR)) {
+               zip_clear_machine(pzipm);
+               zip_clear_machine(pzipm);
+               return;
+               return;
+       }
+       }
+       if ((insn->i_rp)&&(insn->i_areg<ZIP_CC)) {
+       if ((insn->i_rp)&&(insn->i_areg<ZIP_CC)) {
+               bknown = MACH_VUNKNOWN;
+               bknown = MACH_VUNKNOWN;
+               if((insn->i_op==ZIPO_LDI)&&(insn->i_cnd == ZIPC_ALWAYS)) {
+               if((insn->i_op==ZIPO_LDI)&&(insn->i_cnd == ZIPC_ALWAYS)) {
+                       pzipm->r[insn->i_areg].m_known = MACH_VSYMKNOWN;
+                       pzipm->r[insn->i_areg].m_known = MACH_VSYMKNOWN;
+                       pzipm->r[insn->i_areg].m_value = insn->i_imm;
+                       pzipm->r[insn->i_areg].m_value = insn->i_imm;
+                       pzipm->r[insn->i_areg].m_addsy = insn->i_rp->r_sym;
+                       pzipm->r[insn->i_areg].m_addsy = insn->i_rp->r_sym;
+                       pzipm->r[insn->i_areg].m_subsy = NULL;
+                       pzipm->r[insn->i_areg].m_subsy = NULL;
+                       return;
+                       return;
+               } else if ((insn->i_breg == ZIP_PC)&&(insn->i_op == ZIPO_MOV)
+               } else if ((insn->i_breg == ZIP_PC)&&(insn->i_op == ZIPO_MOV)
+                               &&(insn->i_cnd == ZIPC_ALWAYS)) {
+                               &&(insn->i_cnd == ZIPC_ALWAYS)) {
+                       pzipm->r[insn->i_areg].m_known = MACH_VSYMKNOWN;
+                       pzipm->r[insn->i_areg].m_known = MACH_VSYMKNOWN;
+                       pzipm->r[insn->i_areg].m_value = insn->i_imm;
+                       pzipm->r[insn->i_areg].m_value = insn->i_imm;
+                       pzipm->r[insn->i_areg].m_addsy = insn->i_rp->r_sym;
+                       pzipm->r[insn->i_areg].m_addsy = insn->i_rp->r_sym;
+                       pzipm->r[insn->i_areg].m_subsy = NULL;
+                       pzipm->r[insn->i_areg].m_subsy = NULL;
+                       return;
+                       return;
+               }
+               }
+       } else if (insn->i_rp) {
+       } else if (insn->i_rp) {
+               bknown = MACH_VUNKNOWN;
+               bknown = MACH_VUNKNOWN;
+       } else if (ZIP_RNONE == insn->i_breg)
+       } else if (ZIP_RNONE == insn->i_breg)
+               // B-Op is an immediate only
+               // B-Op is an immediate only
+               bknown = MACH_VKNOWN;
+               bknown = MACH_VKNOWN;
+       else if (insn->i_breg >= ZIP_CC)
+       else if (insn->i_breg >= ZIP_CC)
+               bknown = MACH_VUNKNOWN;
+               bknown = MACH_VUNKNOWN;
+       else if (insn->i_imm == 0)
+       else if (insn->i_imm == 0)
+               bknown = (pzipm->r[insn->i_breg].m_known);
+               bknown = (pzipm->r[insn->i_breg].m_known);
+       else // If we have an immediate plus a value, can't know UPPER anymore
+       else // If we have an immediate plus a value, can't know UPPER anymore
+               bknown = (pzipm->r[insn->i_breg].m_known == MACH_VKNOWN)
+               bknown = (pzipm->r[insn->i_breg].m_known == MACH_VKNOWN)
+                                       ? MACH_VKNOWN : MACH_VUNKNOWN;
+                                       ? MACH_VKNOWN : MACH_VUNKNOWN;
+
+
+       if (insn->i_breg < ZIP_USER_REGS)
+       if (insn->i_breg < ZIP_USER_REGS)
+               bval += pzipm->r[insn->i_breg].m_value;
+               bval += pzipm->r[insn->i_breg].m_value;
+
+
+       if (insn->i_areg >= ZIP_USER_REGS) {
+       if (insn->i_areg >= ZIP_USER_REGS) {
+#ifdef ZIP_DEBUG
+#ifdef ZIP_DEBUG
+               fprintf(stderr, "MACHINE, A-REG[%02x] out of bounds\n", insn->i_areg);
+               fprintf(stderr, "MACHINE, A-REG[%02x] out of bounds\n", insn->i_areg);
+#endif
+#endif
+               return; // Nothing to do -- no change to machine
+               return; // Nothing to do -- no change to machine
+       } else if (insn->i_areg == ZIP_PC) {
+       } else if (insn->i_areg == ZIP_PC) {
+#ifdef ZIP_DEBUG
+#ifdef ZIP_DEBUG
+               fprintf(stderr, "MACHINE, CLEAR ON JUMP\n");
+               fprintf(stderr, "MACHINE, CLEAR ON JUMP\n");
+#endif
+#endif
+               zip_clear_machine(pzipm);
+               zip_clear_machine(pzipm);
+               return;
+               return;
+       } else if ((insn->i_areg == ZIP_CC)&&(insn->i_op == ZIPO_AND)) {
+       } else if ((insn->i_areg == ZIP_CC)&&(insn->i_op == ZIPO_AND)) {
+#ifdef ZIP_DEBUG
+#ifdef ZIP_DEBUG
+               fprintf(stderr, "MACHINE, CLEAR ON ANDing to CC\n");
+               fprintf(stderr, "MACHINE, CLEAR ON ANDing to CC\n");
+#endif
+#endif
+               zip_clear_machine(pzipm);
+               zip_clear_machine(pzipm);
+       } else if ((insn->i_areg == ZIP_CC)&&(
+       } else if ((insn->i_areg == ZIP_CC)&&(
+                       (insn->i_op == ZIPO_LDI)
+                       (insn->i_op == ZIPO_LDI)
+                       ||(insn->i_op == ZIPO_LW)
+                       ||(insn->i_op == ZIPO_LW)
+                       ||(insn->i_op == ZIPO_CLR)
+                       ||(insn->i_op == ZIPO_CLR)
+                       ||(insn->i_op == ZIPO_LDILO))) {
+                       ||(insn->i_op == ZIPO_LDILO))) {
+#ifdef ZIP_DEBUG
+#ifdef ZIP_DEBUG
+               fprintf(stderr, "MACHINE, CLEAR ON setting CC\n");
+               fprintf(stderr, "MACHINE, CLEAR ON setting CC\n");
+#endif
+#endif
+               zip_clear_machine(pzipm);
+               zip_clear_machine(pzipm);
+               return;
+               return;
+       } else if (insn->i_areg >= ZIP_CC) {
+       } else if (insn->i_areg >= ZIP_CC) {
+#ifdef ZIP_DEBUG
+#ifdef ZIP_DEBUG
+               fprintf(stderr, "MACHINE, Not tracking CC or PC changes\n");
+               fprintf(stderr, "MACHINE, Not tracking CC or PC changes\n");
+#endif
+#endif
+               pzipm->r[insn->i_areg].m_known = MACH_VUNKNOWN;
+               pzipm->r[insn->i_areg].m_known = MACH_VUNKNOWN;
+               return;
+               return;
+       }
+       }
+
+
+       av = &pzipm->r[insn->i_areg];
+       av = &pzipm->r[insn->i_areg];
+       if (insn->i_breg < ZIP_CC)
+       if (insn->i_breg < ZIP_CC)
+               bv = &pzipm->r[insn->i_breg];
+               bv = &pzipm->r[insn->i_breg];
+       else
+       else
+               bv = NULL;
+               bv = NULL;
+
+
+       if (ZIPC_ALWAYS != insn->i_cnd) {
+       if (ZIPC_ALWAYS != insn->i_cnd) {
+#ifdef ZIP_DEBUG
+#ifdef ZIP_DEBUG
+               fprintf(stderr, "MACHINE, CONDITIONAL\n");
+               fprintf(stderr, "MACHINE, CONDITIONAL\n");
+#endif
+#endif
+               if ((ZIPO_LDILO == insn->i_op)
+               if ((ZIPO_LDILO == insn->i_op)
+                               &&((av->m_known == MACH_VKNOWN)
+                               &&((av->m_known == MACH_VKNOWN)
+                                       ||(av->m_known == MACH_VUPPERKNOWN)))
+                                       ||(av->m_known == MACH_VUPPERKNOWN)))
+                       av->m_known = MACH_VUPPERKNOWN;
+                       av->m_known = MACH_VUPPERKNOWN;
+               else if ((ZIPO_LDI == insn->i_op)||(ZIPO_LDIn == insn->i_op))
+               else if ((ZIPO_LDI == insn->i_op)||(ZIPO_LDIn == insn->i_op))
+                       ; // We'll catch this in a moment
+                       ; // We'll catch this in a moment
+               else
+               else
+                       av->m_known = MACH_VUNKNOWN;
+                       av->m_known = MACH_VUNKNOWN;
+       } switch(insn->i_op) {
+       } switch(insn->i_op) {
+               case    ZIPO_SUB:
+               case    ZIPO_SUB:
+                       av->m_known = (av->m_known==MACH_VKNOWN)
+                       av->m_known = (av->m_known==MACH_VKNOWN)
+                                       ? MACH_VKNOWN:MACH_VUNKNOWN;
+                                       ? MACH_VKNOWN:MACH_VUNKNOWN;
+                       av->m_value -= bval;
+                       av->m_value -= bval;
+                       if (bknown != MACH_VKNOWN)
+                       if (bknown != MACH_VKNOWN)
+                               av->m_known = MACH_VUNKNOWN;
+                               av->m_known = MACH_VUNKNOWN;
+                       break;
+                       break;
+               case    ZIPO_AND:
+               case    ZIPO_AND:
+                       av->m_value &= bval;
+                       av->m_value &= bval;
+                       if ((bknown == MACH_VUPPERKNOWN)&&(bval == 0)) {
+                       if ((bknown == MACH_VUPPERKNOWN)&&(bval == 0)) {
+                               if (av->m_known == MACH_VKNOWN)
+                               if (av->m_known == MACH_VKNOWN)
+                                       av->m_known = MACH_VUPPERKNOWN;
+                                       av->m_known = MACH_VUPPERKNOWN;
+                               else if (av->m_known != MACH_VUPPERKNOWN)
+                               else if (av->m_known != MACH_VUPPERKNOWN)
+                                       av->m_known = MACH_VUNKNOWN;
+                                       av->m_known = MACH_VUNKNOWN;
+                       } else if (bknown != MACH_VKNOWN)
+                       } else if (bknown != MACH_VKNOWN)
+                               av->m_known = MACH_VUNKNOWN;
+                               av->m_known = MACH_VUNKNOWN;
+                       break;
+                       break;
+               case    ZIPO_ADD:
+               case    ZIPO_ADD:
+                       av->m_value += bval;
+                       av->m_value += bval;
+                       if (bknown != MACH_VKNOWN)
+                       if (bknown != MACH_VKNOWN)
+                               av->m_known = MACH_VUNKNOWN;
+                               av->m_known = MACH_VUNKNOWN;
+                       break;
+                       break;
+               case    ZIPO_OR:
+               case    ZIPO_OR:
+                       av->m_value |= bval;
+                       av->m_value |= bval;
+                       if (bknown == MACH_VUPPERKNOWN) {
+                       if (bknown == MACH_VUPPERKNOWN) {
+                               if (av->m_known == MACH_VKNOWN)
+                               if (av->m_known == MACH_VKNOWN)
+                                       av->m_known = MACH_VUPPERKNOWN;
+                                       av->m_known = MACH_VUPPERKNOWN;
+                               else if (av->m_known != MACH_VUPPERKNOWN)
+                               else if (av->m_known != MACH_VUPPERKNOWN)
+                                       av->m_known = MACH_VUNKNOWN;
+                                       av->m_known = MACH_VUNKNOWN;
+                       } else if (bknown != MACH_VKNOWN)
+                       } else if (bknown != MACH_VKNOWN)
+                               av->m_known = MACH_VUNKNOWN;
+                               av->m_known = MACH_VUNKNOWN;
+                       break;
+                       break;
+               case    ZIPO_XOR:
+               case    ZIPO_XOR:
+                       av->m_value ^= bval;
+                       av->m_value ^= bval;
+                       if (bknown == MACH_VUPPERKNOWN) {
+                       if (bknown == MACH_VUPPERKNOWN) {
+                               if (av->m_known == MACH_VKNOWN)
+                               if (av->m_known == MACH_VKNOWN)
+                                       av->m_known = MACH_VUPPERKNOWN;
+                                       av->m_known = MACH_VUPPERKNOWN;
+                               else if (av->m_known != MACH_VUPPERKNOWN)
+                               else if (av->m_known != MACH_VUPPERKNOWN)
+                                       av->m_known = MACH_VUNKNOWN;
+                                       av->m_known = MACH_VUNKNOWN;
+                       } else if (bknown != MACH_VKNOWN)
+                       } else if (bknown != MACH_VKNOWN)
+                               av->m_known = MACH_VUNKNOWN;
+                               av->m_known = MACH_VUNKNOWN;
+                       break;
+                       break;
+               case    ZIPO_LDI: case ZIPO_LDIn:
+               case    ZIPO_LDI: case ZIPO_LDIn:
+                       // Although the h/w instruction has no conditions, our
+                       // Although the h/w instruction has no conditions, our
+                       // decoding may have conditions until we finish
+                       // decoding may have conditions until we finish
+                       // working out what the actual result is.  Hence, we
+                       // working out what the actual result is.  Hence, we
+                       // need to be aware of any conditions from above.
+                       // need to be aware of any conditions from above.
+#ifdef ZIP_DEBUG
+#ifdef ZIP_DEBUG
+                       fprintf(stderr, "MACHINE, LDI -> %02x\n", insn->i_areg);
+                       fprintf(stderr, "MACHINE, LDI -> %02x\n", insn->i_areg);
+#endif
+#endif
+                       av->m_value = bval;
+                       av->m_value = bval;
+                       if (insn->i_cnd != ZIPC_ALWAYS) {
+                       if (insn->i_cnd != ZIPC_ALWAYS) {
+                               // if ((bknown)&&(bvalue == insn->i_imm))
+                               // if ((bknown)&&(bvalue == insn->i_imm))
+                                       // pzipm->r[insn->i_areg].m_known = MACH_VKNOWN;
+                                       // pzipm->r[insn->i_areg].m_known = MACH_VKNOWN;
+                       } else {
+                       } else {
+                               av->m_known = MACH_VKNOWN;
+                               av->m_known = MACH_VKNOWN;
+                       } break;
+                       } break;
+               case    ZIPO_LDILO:
+               case    ZIPO_LDILO:
+#ifdef ZIP_DEBUG
+#ifdef ZIP_DEBUG
+                       fprintf(stderr, "MACHINE, LDILO -> %02x\n", insn->i_areg);
+                       fprintf(stderr, "MACHINE, LDILO -> %02x\n", insn->i_areg);
+#endif
+#endif
+                       av->m_value &= ~0x0ffff;
+                       av->m_value &= ~0x0ffff;
+                       av->m_value |= bval &0x0ffff;
+                       av->m_value |= bval &0x0ffff;
+                       if ((av->m_known == MACH_VUPPERKNOWN)
+                       if ((av->m_known == MACH_VUPPERKNOWN)
+                                       &&(bknown == MACH_VKNOWN)
+                                       &&(bknown == MACH_VKNOWN)
+                                       &&(ZIPC_ALWAYS == insn->i_cnd))
+                                       &&(ZIPC_ALWAYS == insn->i_cnd))
+                               av->m_known = MACH_VKNOWN;
+                               av->m_known = MACH_VKNOWN;
+                       break;
+                       break;
+               case    ZIPO_BREV:
+               case    ZIPO_BREV:
+                       av->m_value = zip_brev(bval);
+                       av->m_value = zip_brev(bval);
+                       if (ZIPC_ALWAYS == insn->i_cnd)
+                       if (ZIPC_ALWAYS == insn->i_cnd)
+                               av->m_known = (bknown == MACH_VKNOWN)?MACH_VKNOWN:MACH_VUNKNOWN;
+                               av->m_known = (bknown == MACH_VKNOWN)?MACH_VKNOWN:MACH_VUNKNOWN;
+                       else if ((bknown == MACH_VKNOWN)
+                       else if ((bknown == MACH_VKNOWN)
+                               &&(  (av->m_known == MACH_VKNOWN)
+                               &&(  (av->m_known == MACH_VKNOWN)
+                                  ||(av->m_known == MACH_VUPPERKNOWN))
+                                  ||(av->m_known == MACH_VUPPERKNOWN))
+                               &&((((zip_brev(bval)^av->m_value)&0x0ffff)==0)))
+                               &&((((zip_brev(bval)^av->m_value)&0x0ffff)==0)))
+                               av->m_known = MACH_VUPPERKNOWN;
+                               av->m_known = MACH_VUPPERKNOWN;
+                       break;
+                       break;
+               case    ZIPO_MOV:
+               case    ZIPO_MOV:
+#ifdef ZIP_DEBUG
+#ifdef ZIP_DEBUG
+                       fprintf(stderr, "MACHINE, MOV -> %02x\n", insn->i_areg);
+                       fprintf(stderr, "MACHINE, MOV -> %02x\n", insn->i_areg);
+#endif
+#endif
+                       av->m_value = bval;
+                       av->m_value = bval;
+                       if (ZIPC_ALWAYS == insn->i_cnd) {
+                       if (ZIPC_ALWAYS == insn->i_cnd) {
+                               av->m_known = bknown;
+                               av->m_known = bknown;
+                               if (bknown == MACH_VSYMKNOWN) {
+                               if (bknown == MACH_VSYMKNOWN) {
+                                       if (!bv) { av->m_known = MACH_VUNKNOWN;}
+                                       if (!bv) { av->m_known = MACH_VUNKNOWN;}
+                                       else {
+                                       else {
+                                       av->m_value = bv->m_value + insn->i_imm;
+                                       av->m_value = bv->m_value + insn->i_imm;
+                                       av->m_addsy = bv->m_addsy;
+                                       av->m_addsy = bv->m_addsy;
+                                       av->m_subsy = bv->m_subsy;
+                                       av->m_subsy = bv->m_subsy;
+                                       }
+                                       }
+                               }
+                               }
+                       } else if (
+                       } else if (
+                               ((av->m_known == MACH_VKNOWN)
+                               ((av->m_known == MACH_VKNOWN)
+                                 ||(av->m_known == MACH_VUPPERKNOWN))
+                                 ||(av->m_known == MACH_VUPPERKNOWN))
+                               &&((bknown == MACH_VKNOWN)
+                               &&((bknown == MACH_VKNOWN)
+                                 ||(bknown == MACH_VUPPERKNOWN))
+                                 ||(bknown == MACH_VUPPERKNOWN))
+                               &&(((bval^av->m_value)&0xffff0000)==0))
+                               &&(((bval^av->m_value)&0xffff0000)==0))
+                               av->m_known = MACH_VUPPERKNOWN;
+                               av->m_known = MACH_VUPPERKNOWN;
+                       else
+                       else
+                               av->m_known = MACH_VUNKNOWN;
+                               av->m_known = MACH_VUNKNOWN;
+                       av->m_value = bval;
+                       av->m_value = bval;
+                       break;
+                       break;
+               case    ZIPO_CLR:
+               case    ZIPO_CLR:
+                       if (insn->i_cnd == ZIPC_ALWAYS)
+                       if (insn->i_cnd == ZIPC_ALWAYS)
+                               av->m_known = MACH_VKNOWN;
+                               av->m_known = MACH_VKNOWN;
+                       else if ((av->m_value & 0xffff0000)==0) {
+                       else if ((av->m_value & 0xffff0000)==0) {
+                               if (((av->m_known == MACH_VKNOWN)
+                               if (((av->m_known == MACH_VKNOWN)
+                                       ||(av->m_known == MACH_VUPPERKNOWN))
+                                       ||(av->m_known == MACH_VUPPERKNOWN))
+                                       &&(((av->m_value ^ bval)&0xffff0000)==0))
+                                       &&(((av->m_value ^ bval)&0xffff0000)==0))
+                                       av->m_known = MACH_VUPPERKNOWN;
+                                       av->m_known = MACH_VUPPERKNOWN;
+                               else
+                               else
+                                       av->m_known = MACH_VUNKNOWN;
+                                       av->m_known = MACH_VUNKNOWN;
+                       } av->m_value = 0;
+                       } av->m_value = 0;
+                       break;
+                       break;
+               // Store's don't change any regs
+               // Store's don't change any regs
+               case    ZIPO_SW: case ZIPO_SH: case ZIPO_SB:
+               case    ZIPO_SW: case ZIPO_SH: case ZIPO_SB:
+               case    ZIPO_SIM: case ZIPO_NOOP:
+               case    ZIPO_SIM: case ZIPO_NOOP:
+               case    ZIPO_SDUMP: case ZIPO_NDUMP:
+               case    ZIPO_SDUMP: case ZIPO_NDUMP:
+               case    ZIPO_BREAK: case ZIPO_LOCK:
+               case    ZIPO_BREAK: case ZIPO_LOCK:
+               case    ZIPO_CMP:  case ZIPO_TST:
+               case    ZIPO_CMP:  case ZIPO_TST:
+                       // These don't change any registers
+                       // These don't change any registers
+                       break;
+                       break;
+               // Result of loading a byte or halfword always clears the upper
+               // Result of loading a byte or halfword always clears the upper
+               // half word
+               // half word
+               case    ZIPO_LB: case   ZIPO_LH:
+               case    ZIPO_LB: case   ZIPO_LH:
+                       if (insn->i_cnd == ZIPC_ALWAYS) {
+                       if (insn->i_cnd == ZIPC_ALWAYS) {
+                               av->m_known = MACH_VUPPERKNOWN;
+                               av->m_known = MACH_VUPPERKNOWN;
+                               av->m_value = 0;
+                               av->m_value = 0;
+                       } else
+                       } else
+                               av->m_known = MACH_VUNKNOWN;
+                               av->m_known = MACH_VUNKNOWN;
+                       break;
+                       break;
+               case    ZIPO_LW:
+               case    ZIPO_LW:
+               default:
+               default:
+#ifdef ZIP_DEBUG
+#ifdef ZIP_DEBUG
+                       fprintf(stderr, "MACHINE, DEFAULT, %02x -> unknown\n", insn->i_areg);
+                       fprintf(stderr, "MACHINE, DEFAULT, %02x -> unknown\n", insn->i_areg);
+#endif
+#endif
+                       av->m_known = MACH_VUNKNOWN;
+                       av->m_known = MACH_VUNKNOWN;
+                       break;
+                       break;
+       }
+       }
+
+
+       pzipm->r[ZIP_CC].m_known = MACH_VUNKNOWN;
+       pzipm->r[ZIP_CC].m_known = MACH_VUNKNOWN;
+       pzipm->r[ZIP_PC].m_known = MACH_VUNKNOWN;
+       pzipm->r[ZIP_PC].m_known = MACH_VUNKNOWN;
+}
+}
+
+
+#ifdef ZIP_DEBUG
+#ifdef ZIP_DEBUG
+static void
+static void
+zip_debug_machine(MACHINEREGS *pzipm) {
+zip_debug_machine(MACHINEREGS *pzipm) {
+       int     i;
+       int     i;
+       for(i=0; i<ZIP_USER_REGS; i++) {
+       for(i=0; i<ZIP_USER_REGS; i++) {
+               if (pzipm->r[i].m_known == MACH_VKNOWN)
+               if (pzipm->r[i].m_known == MACH_VKNOWN)
+                       fprintf(stderr, "MACH-KNOW[Y][%2x] = %08x\n",
+                       fprintf(stderr, "MACH-KNOW[Y][%2x] = %08x\n",
+                               i, pzipm->r[i].m_value);
+                               i, pzipm->r[i].m_value);
+               else if (pzipm->r[i].m_known == MACH_VUPPERKNOWN)
+               else if (pzipm->r[i].m_known == MACH_VUPPERKNOWN)
+                       fprintf(stderr, "MACH-KNOW[U][%2x] = %04x\n",
+                       fprintf(stderr, "MACH-KNOW[U][%2x] = %04x\n",
+                               i, (pzipm->r[i].m_value>>16)&0x0ffff);
+                               i, (pzipm->r[i].m_value>>16)&0x0ffff);
+       }
+       }
+}
+}
+#endif
+#endif
+
+
+
+
+/*
+/*
+ * Option processing
+ * Option processing
+ *
+ *
+ * While not yet implemented, we do have a need for multiple options.  These
+ * While not yet implemented, we do have a need for multiple options.  These
+ * include:
+ * include:
+ *
+ *
+ *     (not yet supported)
+ *     (not yet supported)
+ *     -got    Use a global offset table to place unknown jump locations into.
+ *     -got    Use a global offset table to place unknown jump locations into.
+ *
+ *
+ *     (not yet supported)
+ *     (not yet supported)
+ *     -relax  Implement only relaxed instructions.  This implies that all
+ *     -relax  Implement only relaxed instructions.  This implies that all
+ *             branches fit within 18-bits of the current PC, or equivalently
+ *             branches fit within 18-bits of the current PC, or equivalently
+ *             that all of the code fits within 1MB.
+ *             that all of the code fits within 1MB.
+ *
+ *
+ *     (not yet supported)
+ *     (not yet supported)
+ *     -no-relax       Don't relax any instructions.  That means that all
+ *     -no-relax       Don't relax any instructions.  That means that all
+ *             branches will be implemented as LOD (PC),PC ; .int #Address
+ *             branches will be implemented as LOD (PC),PC ; .int #Address
+ *             and all conditional branches as LOD 1(PC),PC; BRA 1; .int #addr.
+ *             and all conditional branches as LOD 1(PC),PC; BRA 1; .int #addr.
+ *             This also implies LDI's of unknown values will always be
+ *             This also implies LDI's of unknown values will always be
+ *             converted to LDILO/LDIHI pairs and never converted back to
+ *             converted to LDILO/LDIHI pairs and never converted back to
+ *             LDI's--even when the final value is known.
+ *             LDI's--even when the final value is known.
+ *
+ *
+ *     -cis    Attempt to compress instructions into the CIS instruction
+ *     -cis    Attempt to compress instructions into the CIS instruction
+ *             set.
+ *             set.
+ *
+ *
+ *     (Something for stating the starting address of the routine in memory...)
+ *     (Something for stating the starting address of the routine in memory...)
+ *
+ *
+ *     Other (not yet supported) long options
+ *     Other (not yet supported) long options
+ *
+ *
+ *     -nopipe Attempts to use a lock instruction will result in an error.
+ *     -nopipe Attempts to use a lock instruction will result in an error.
+ *     -nomul  Attempts to use multiply instructions will result in an error.
+ *     -nomul  Attempts to use multiply instructions will result in an error.
+ *     -nodiv  Attempts to use divide instructions will result in an error.
+ *     -nodiv  Attempts to use divide instructions will result in an error.
+ *     -nofpu  Attempts to use floating point unit insn will cause an error.
+ *     -nofpu  Attempts to use floating point unit insn will cause an error.
+ *
+ *
+ *
+ *
+ */
+ */
+#define        OPTION_CIS      (OPTION_MD_BASE+1)
+#define        OPTION_CIS      (OPTION_MD_BASE+1)
+#define        OPTION_NOCIS    (OPTION_MD_BASE+2)
+#define        OPTION_NOCIS    (OPTION_MD_BASE+2)
+#define        OPTION_ZIPM     (OPTION_MD_BASE+3)
+#define        OPTION_ZIPM     (OPTION_MD_BASE+3)
+#define        OPTION_NOZIPM   (OPTION_MD_BASE+4)
+#define        OPTION_NOZIPM   (OPTION_MD_BASE+4)
+#define        OPTION_GOT      (OPTION_MD_BASE+5)
+#define        OPTION_GOT      (OPTION_MD_BASE+5)
+#define        OPTION_SMALL    (OPTION_MD_BASE+6)      // No LW(PC),PC insns
+#define        OPTION_SMALL    (OPTION_MD_BASE+6)      // No LW(PC),PC insns
+
+
+const char     *md_shortopts = "";
+const char     *md_shortopts = "";
+struct option  md_longopts[] =
+struct option  md_longopts[] =
+{
+{
+       { "cis",   no_argument, NULL, OPTION_CIS },
+       { "cis",   no_argument, NULL, OPTION_CIS },
+       { "nocis", no_argument, NULL, OPTION_NOCIS },
+       { "nocis", no_argument, NULL, OPTION_NOCIS },
+       { "zipm",   no_argument, NULL, OPTION_ZIPM },
+       { "zipm",   no_argument, NULL, OPTION_ZIPM },
+       { "nozipm", no_argument, NULL, OPTION_NOZIPM },
+       { "nozipm", no_argument, NULL, OPTION_NOZIPM },
+       { "small",  no_argument, NULL, OPTION_SMALL },
+       { "small",  no_argument, NULL, OPTION_SMALL },
+       // { "got",  no_argument, NULL, OPTION_GOT },
+       // { "got",  no_argument, NULL, OPTION_GOT },
+       { NULL, no_argument, NULL, 0}
+       { NULL, no_argument, NULL, 0}
+};
+};
+size_t md_longopts_size = sizeof(md_longopts);
+size_t md_longopts_size = sizeof(md_longopts);
+
+
+/* We have no target specific options yet, so these next two fucntions are
+/* We have no target specific options yet, so these next two fucntions are
+ * are empty.
+ * are empty.
+ */
+ */
+int
+int
+md_parse_option(int c, const char *arg ATTRIBUTE_UNUSED)
+md_parse_option(int c, const char *arg ATTRIBUTE_UNUSED)
+{
+{
+       // printf("Option %d, %s\n", c, (arg)?arg : "(Null)");
+       // printf("Option %d, %s\n", c, (arg)?arg : "(Null)");
+       if (c==0)
+       if (c==0)
+               return 1;
+               return 1;
+       switch(c) {
+       switch(c) {
+               case 0: return 1;
+               case 0: return 1;
+               case OPTION_CIS:   zip_param_cis = 1; return 1; break;
+               case OPTION_CIS:   zip_param_cis = 1; return 1; break;
+               case OPTION_NOCIS: zip_param_cis = 0; return 1; break;
+               case OPTION_NOCIS: zip_param_cis = 0; return 1; break;
+               case OPTION_ZIPM:   zip_param_use_machine = 1; return 1; break;
+               case OPTION_ZIPM:   zip_param_use_machine = 1; return 1; break;
+               case OPTION_NOZIPM: zip_param_use_machine = 0; return 1; break;
+               case OPTION_NOZIPM: zip_param_use_machine = 0; return 1; break;
+               // case OPTION_GOT : zip_param_got  = 1; return 1; break;
+               // case OPTION_GOT : zip_param_got  = 1; return 1; break;
+               default: break;
+               default: break;
+       }
+       }
+       return 0; // We didn't handle this option
+       return 0; // We didn't handle this option
+}
+}
+
+
+void
+void
+md_show_usage(FILE *stream ATTRIBUTE_UNUSED)
+md_show_usage(FILE *stream ATTRIBUTE_UNUSED)
+{
+{
+       fprintf(stream, _("Zip CPU options:\n"));
+       fprintf(stream, _("Zip CPU options:\n"));
+       fprintf(stream, _("\n"
+       fprintf(stream, _("\n"
+"-cis\t\tAttempt to compress instructions into two instructions per word.\n"));
+"-cis\t\tAttempt to compress instructions into two instructions per word.\n"));
+       //fprintf(stream, _(
+       //fprintf(stream, _(
+// "-got\t\tGenerate position independent code by referencing all symbols\n"
+// "-got\t\tGenerate position independent code by referencing all symbols\n"
+// "\t\tthrough a Global Offset Table.\n"));
+// "\t\tthrough a Global Offset Table.\n"));
+}
+}
+
+
+
+
+symbolS *
+symbolS *
+md_undefined_symbol(char *name ATTRIBUTE_UNUSED)
+md_undefined_symbol(char *name ATTRIBUTE_UNUSED)
+{
+{
+//#warning "This is where other architectures check for any GOT references"
+//#warning "This is where other architectures check for any GOT references"
+       return NULL;
+       return NULL;
+}
+}
+
+
+void
+void
+md_operand(expressionS *op ATTRIBUTE_UNUSED)
+md_operand(expressionS *op ATTRIBUTE_UNUSED)
+{
+{
+       /* Empty for now -- what is this for? */
+       /* Empty for now -- what is this for? */
+}
+}
+
+
+#ifdef ZIP_DEBUG
+#ifdef ZIP_DEBUG
+static void
+static void
+zip_dump_sym(symbolS *sym)
+zip_dump_sym(symbolS *sym)
+{
+{
+       if (!sym) {
+       if (!sym) {
+               fprintf(stderr, "SYM(NULL)");
+               fprintf(stderr, "SYM(NULL)");
+       } else {
+       } else {
+               fprintf(stderr, "Dumping symbol fields\n");
+               fprintf(stderr, "Dumping symbol fields\n");
+               fprintf(stderr, "SYM(%s) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s - 0x%08x\n",
+               fprintf(stderr, "SYM(%s) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s - 0x%08x\n",
+                       S_GET_NAME(sym),
+                       S_GET_NAME(sym),
+                       (S_IS_LOCAL(sym))?"Local ":"",
+                       (S_IS_LOCAL(sym))?"Local ":"",
+                       (S_IS_DEFINED(sym))?"Defined ":"",
+                       (S_IS_DEFINED(sym))?"Defined ":"",
+                       (S_IS_EXTERNAL(sym))?"extern ":"",
+                       (S_IS_EXTERNAL(sym))?"extern ":"",
+                       (S_IS_FUNCTION(sym))?"(func) ":"",
+                       (S_IS_FUNCTION(sym))?"(func) ":"",
+                       (S_IS_WEAK(sym))?"Weak ":"",
+                       (S_IS_WEAK(sym))?"Weak ":"",
+                       (S_IS_WEAKREFD(sym))?"(Weak Ref-D) ":"",
+                       (S_IS_WEAKREFD(sym))?"(Weak Ref-D) ":"",
+                       (S_IS_WEAKREFR(sym))?"(Weak Refr) ":"",
+                       (S_IS_WEAKREFR(sym))?"(Weak Refr) ":"",
+                       (S_IS_DEBUG(sym))?"DEBUG ":"",
+                       (S_IS_DEBUG(sym))?"DEBUG ":"",
+                       (S_IS_VOLATILE(sym))?"Volatile ":"",
+                       (S_IS_VOLATILE(sym))?"Volatile ":"",
+                       (S_IS_FORWARD_REF(sym))?"Fwd Ref ":"",
+                       (S_IS_FORWARD_REF(sym))?"Fwd Ref ":"",
+                       (S_IS_COMMON(sym))?"Common ":"",
+                       (S_IS_COMMON(sym))?"Common ":"",
+                       (S_GET_SEGMENT(sym)==absolute_section)?"AbsoluteS ":"",
+                       (S_GET_SEGMENT(sym)==absolute_section)?"AbsoluteS ":"",
+                       (S_GET_SEGMENT(sym)==expr_section)?"ExpressionS ":"",
+                       (S_GET_SEGMENT(sym)==expr_section)?"ExpressionS ":"",
+                       (S_GET_SEGMENT(sym)==reg_section)?"RegisterS ":"",
+                       (S_GET_SEGMENT(sym)==reg_section)?"RegisterS ":"",
+                       (S_GET_SEGMENT(sym)==undefined_section)?"UndefinedS ":"",
+                       (S_GET_SEGMENT(sym)==undefined_section)?"UndefinedS ":"",
+                       (symbol_resolved_p(sym))?"Resolved ":"",
+                       (symbol_resolved_p(sym))?"Resolved ":"",
+                       (unsigned)S_GET_VALUE(sym));
+                       (unsigned)S_GET_VALUE(sym));
+       }
+       }
+}
+}
+
+
+static void
+static void
+zip_dump_insn(ZIPIS *insn) {
+zip_dump_insn(ZIPIS *insn) {
+       fprintf(stderr, "INSN:DUMP ");
+       fprintf(stderr, "INSN:DUMP ");
+       switch(insn->i_op) {
+       switch(insn->i_op) {
+               case ZIPO_SUB:   fprintf(stderr, "%7s", "SUB"); break;
+               case ZIPO_SUB:   fprintf(stderr, "%7s", "SUB"); break;
+               case ZIPO_AND:   fprintf(stderr, "%7s", "AND"); break;
+               case ZIPO_AND:   fprintf(stderr, "%7s", "AND"); break;
+               case ZIPO_ADD:   fprintf(stderr, "%7s", "ADD"); break;
+               case ZIPO_ADD:   fprintf(stderr, "%7s", "ADD"); break;
+               case ZIPO_OR:    fprintf(stderr, "%7s", "OR"); break;
+               case ZIPO_OR:    fprintf(stderr, "%7s", "OR"); break;
+               case ZIPO_XOR:   fprintf(stderr, "%7s", "XOR"); break;
+               case ZIPO_XOR:   fprintf(stderr, "%7s", "XOR"); break;
+               case ZIPO_LSR:   fprintf(stderr, "%7s", "LSR"); break;
+               case ZIPO_LSR:   fprintf(stderr, "%7s", "LSR"); break;
+               case ZIPO_LSL:   fprintf(stderr, "%7s", "LSL"); break;
+               case ZIPO_LSL:   fprintf(stderr, "%7s", "LSL"); break;
+               case ZIPO_ASR:   fprintf(stderr, "%7s", "ASR"); break;
+               case ZIPO_ASR:   fprintf(stderr, "%7s", "ASR"); break;
+               case ZIPO_LDI:   fprintf(stderr, "%7s", "LDI"); break;
+               case ZIPO_LDI:   fprintf(stderr, "%7s", "LDI"); break;
+               case ZIPO_MPYUHI:fprintf(stderr, "%7s", "MPYUHI");break;
+               case ZIPO_MPYUHI:fprintf(stderr, "%7s", "MPYUHI");break;
+               case ZIPO_MPYSHI:fprintf(stderr, "%7s", "MPYSHI");break;
+               case ZIPO_MPYSHI:fprintf(stderr, "%7s", "MPYSHI");break;
+               case ZIPO_LDILO: fprintf(stderr, "%7s", "LDILO"); break;
+               case ZIPO_LDILO: fprintf(stderr, "%7s", "LDILO"); break;
+               case ZIPO_BREV:  fprintf(stderr, "%7s", "BREV");  break;
+               case ZIPO_BREV:  fprintf(stderr, "%7s", "BREV");  break;
+               case ZIPO_MOV:   fprintf(stderr, "%7s", "MOV");   break;
+               case ZIPO_MOV:   fprintf(stderr, "%7s", "MOV");   break;
+               case ZIPO_CMP:   fprintf(stderr, "%7s", "CMP");   break;
+               case ZIPO_CMP:   fprintf(stderr, "%7s", "CMP");   break;
+               case ZIPO_TST:   fprintf(stderr, "%7s", "TST");   break;
+               case ZIPO_TST:   fprintf(stderr, "%7s", "TST");   break;
+               case ZIPO_LW:    fprintf(stderr, "%7s", "LW");    break;
+               case ZIPO_LW:    fprintf(stderr, "%7s", "LW");    break;
+               case ZIPO_SW:    fprintf(stderr, "%7s", "SW");    break;
+               case ZIPO_SW:    fprintf(stderr, "%7s", "SW");    break;
+               case ZIPO_LH:    fprintf(stderr, "%7s", "LH");    break;
+               case ZIPO_LH:    fprintf(stderr, "%7s", "LH");    break;
+               case ZIPO_SH:    fprintf(stderr, "%7s", "SH");    break;
+               case ZIPO_SH:    fprintf(stderr, "%7s", "SH");    break;
+               case ZIPO_LB:    fprintf(stderr, "%7s", "LB");    break;
+               case ZIPO_LB:    fprintf(stderr, "%7s", "LB");    break;
+               case ZIPO_SB:    fprintf(stderr, "%7s", "SB");    break;
+               case ZIPO_SB:    fprintf(stderr, "%7s", "SB");    break;
+               case ZIPO_DIVU:  fprintf(stderr, "%7s", "DIVU");  break;
+               case ZIPO_DIVU:  fprintf(stderr, "%7s", "DIVU");  break;
+               case ZIPO_DIVS:  fprintf(stderr, "%7s", "DIVS");  break;
+               case ZIPO_DIVS:  fprintf(stderr, "%7s", "DIVS");  break;
+               case ZIPO_FPADD: fprintf(stderr, "%7s", "FPADD"); break;
+               case ZIPO_FPADD: fprintf(stderr, "%7s", "FPADD"); break;
+               case ZIPO_FPSUB: fprintf(stderr, "%7s", "FPSUB"); break;
+               case ZIPO_FPSUB: fprintf(stderr, "%7s", "FPSUB"); break;
+               //
+               //
+               case ZIPO_NOOP:  fprintf(stderr, "%7s", "NOOP");  break;
+               case ZIPO_NOOP:  fprintf(stderr, "%7s", "NOOP");  break;
+               case ZIPO_BREAK: fprintf(stderr, "%7s", "BREAK"); break;
+               case ZIPO_BREAK: fprintf(stderr, "%7s", "BREAK"); break;
+               case ZIPO_LOCK:  fprintf(stderr, "%7s", "LOCK");  break;
+               case ZIPO_LOCK:  fprintf(stderr, "%7s", "LOCK");  break;
+               case ZIPO_TRAP:  fprintf(stderr, "%7s", "TRAP");  break;
+               case ZIPO_TRAP:  fprintf(stderr, "%7s", "TRAP");  break;
+               case ZIPO_CLR:   fprintf(stderr, "%7s", "CLR");   break;
+               case ZIPO_CLR:   fprintf(stderr, "%7s", "CLR");   break;
+               case ZIPO_HALT:  fprintf(stderr, "%7s", "HALT");  break;
+               case ZIPO_HALT:  fprintf(stderr, "%7s", "HALT");  break;
+               case ZIPO_WAIT:  fprintf(stderr, "%7s", "WAIT");  break;
+               case ZIPO_WAIT:  fprintf(stderr, "%7s", "WAIT");  break;
+               case ZIPO_STEP:  fprintf(stderr, "%7s", "STEP");  break;
+               case ZIPO_STEP:  fprintf(stderr, "%7s", "STEP");  break;
+               case ZIPO_RTU:   fprintf(stderr, "%7s", "RTU");   break;
+               case ZIPO_RTU:   fprintf(stderr, "%7s", "RTU");   break;
+               case ZIPO_BRA:   fprintf(stderr, "%7s", "BRA");   break;
+               case ZIPO_BRA:   fprintf(stderr, "%7s", "BRA");   break;
+               case ZIPO_BUSY:  fprintf(stderr, "%7s", "BUSY");  break;
+               case ZIPO_BUSY:  fprintf(stderr, "%7s", "BUSY");  break;
+               case ZIPO_JMP:   fprintf(stderr, "%7s", "JMP");   break;
+               case ZIPO_JMP:   fprintf(stderr, "%7s", "JMP");   break;
+               case ZIPO_NOT:   fprintf(stderr, "%7s", "NOT");   break;
+               case ZIPO_NOT:   fprintf(stderr, "%7s", "NOT");   break;
+               case ZIPO_NEG:   fprintf(stderr, "%7s", "NEG");   break;
+               case ZIPO_NEG:   fprintf(stderr, "%7s", "NEG");   break;
+               //
+               //
+               case ZIPO_SIM:   fprintf(stderr, "%7s", "SIM");   break;
+               case ZIPO_SIM:   fprintf(stderr, "%7s", "SIM");   break;
+               case ZIPO_SDUMP: fprintf(stderr, "%7s", "SDUMP"); break;
+               case ZIPO_SDUMP: fprintf(stderr, "%7s", "SDUMP"); break;
+               case ZIPO_SEXIT: fprintf(stderr, "%7s", "SEXIT"); break;
+               case ZIPO_SEXIT: fprintf(stderr, "%7s", "SEXIT"); break;
+               case ZIPO_SOUT:  fprintf(stderr, "%7s", "SOUT");  break;
+               case ZIPO_SOUT:  fprintf(stderr, "%7s", "SOUT");  break;
+               case ZIPO_NDUMP: fprintf(stderr, "%7s", "NDUMP"); break;
+               case ZIPO_NDUMP: fprintf(stderr, "%7s", "NDUMP"); break;
+               case ZIPO_NEXIT: fprintf(stderr, "%7s", "NEXIT"); break;
+               case ZIPO_NEXIT: fprintf(stderr, "%7s", "NEXIT"); break;
+               case ZIPO_NOUT:  fprintf(stderr, "%7s", "OUT");   break;
+               case ZIPO_NOUT:  fprintf(stderr, "%7s", "OUT");   break;
+               //
+               //
+               case ZIPO_LJMP: fprintf(stderr, "%7s", "LJMP"); break;
+               case ZIPO_LJMP: fprintf(stderr, "%7s", "LJMP"); break;
+               case ZIPO_LJSR: fprintf(stderr, "%7s", "LJSR");   break;
+               case ZIPO_LJSR: fprintf(stderr, "%7s", "LJSR");   break;
+               //
+               //
+               case ZIPO_SEXTH:fprintf(stderr, "%7s", "SEXTH");   break;
+               case ZIPO_SEXTH:fprintf(stderr, "%7s", "SEXTH");   break;
+               case ZIPO_SEXTB:fprintf(stderr, "%7s", "SEXTB");   break;
+               case ZIPO_SEXTB:fprintf(stderr, "%7s", "SEXTB");   break;
+               default:
+               default:
+                       fprintf(stderr, "%d", insn->i_op); break;
+                       fprintf(stderr, "%d", insn->i_op); break;
+       }
+       }
+       switch(insn->i_cnd) {
+       switch(insn->i_cnd) {
+               case ZIPC_Z: fprintf(stderr, "%-3s", ".Z"); break;
+               case ZIPC_Z: fprintf(stderr, "%-3s", ".Z"); break;
+               case ZIPC_LT: fprintf(stderr, "%-3s", ".LT"); break;
+               case ZIPC_LT: fprintf(stderr, "%-3s", ".LT"); break;
+               case ZIPC_C: fprintf(stderr, "%-3s", ".C"); break;
+               case ZIPC_C: fprintf(stderr, "%-3s", ".C"); break;
+               case ZIPC_V: fprintf(stderr, "%-3s", ".V"); break;
+               case ZIPC_V: fprintf(stderr, "%-3s", ".V"); break;
+               case ZIPC_NZ: fprintf(stderr, "%-3s", ".NE"); break;
+               case ZIPC_NZ: fprintf(stderr, "%-3s", ".NE"); break;
+               case ZIPC_GE: fprintf(stderr, "%-3s", ".GE"); break;
+               case ZIPC_GE: fprintf(stderr, "%-3s", ".GE"); break;
+               case ZIPC_NC: fprintf(stderr, "%-3s", ".NC"); break;
+               case ZIPC_NC: fprintf(stderr, "%-3s", ".NC"); break;
+               case ZIPC_ALWAYS:
+               case ZIPC_ALWAYS:
+               default:
+               default:
+                       break;
+                       break;
+       } fprintf(stderr, " %d", (int)insn->i_cnd);
+       } fprintf(stderr, " %d", (int)insn->i_cnd);
+
+
+       fprintf(stderr, "\n\tAREG = %d\n\tB = ", insn->i_areg);
+       fprintf(stderr, "\n\tAREG = %d\n\tB = ", insn->i_areg);
+       if (insn->i_rp) {
+       if (insn->i_rp) {
+               if (insn->i_imm != 0)
+               if (insn->i_imm != 0)
+                       fprintf(stderr, "$%d + ", insn->i_imm);
+                       fprintf(stderr, "$%d + ", insn->i_imm);
+               fprintf(stderr, "%s ", (insn->i_rp->r_sym) ?
+               fprintf(stderr, "%s ", (insn->i_rp->r_sym) ?
+                       S_GET_NAME(insn->i_rp->r_sym) : "(null)");
+                       S_GET_NAME(insn->i_rp->r_sym) : "(null)");
+       } else
+       } else
+               fprintf(stderr, "%d[%08x] (no sym)", insn->i_imm, insn->i_imm);
+               fprintf(stderr, "%d[%08x] (no sym)", insn->i_imm, insn->i_imm);
+       if (insn->i_breg != ZIP_RNONE)
+       if (insn->i_breg != ZIP_RNONE)
+               fprintf(stderr, "+ R%d", insn->i_breg);
+               fprintf(stderr, "+ R%d", insn->i_breg);
+       fprintf(stderr, "\n");
+       fprintf(stderr, "\n");
+       if (insn->i_rp)
+       if (insn->i_rp)
+               fprintf(stderr, "\t@%ld (offset w/in instruction frag)\n", insn->i_rp->r_fr_offset);
+               fprintf(stderr, "\t@%ld (offset w/in instruction frag)\n", insn->i_rp->r_fr_offset);
+       fprintf(stderr, "\tINSN:CODE %08x", insn->i_code);
+       fprintf(stderr, "\tINSN:CODE %08x", insn->i_code);
+       {
+       {
+               int     i;
+               int     i;
+               for(i=0; (i<insn->i_naux)&&(i<ZIP_MAX_NAUX); i++)
+               for(i=0; (i<insn->i_naux)&&(i<ZIP_MAX_NAUX); i++)
+                       fprintf(stderr, ":%08x", insn->i_aux[i]);
+                       fprintf(stderr, ":%08x", insn->i_aux[i]);
+       }
+       }
+       fprintf(stderr, "\n\tDUMPED\n");
+       fprintf(stderr, "\n\tDUMPED\n");
+}
+}
+#endif
+#endif
+
+
+static ZIP_CONDITION
+static ZIP_CONDITION
+zip_negate_condition(ZIP_CONDITION c) {
+zip_negate_condition(ZIP_CONDITION c) {
+       switch(c) {
+       switch(c) {
+               case ZIPC_Z:    return ZIPC_NZ; break;
+               case ZIPC_Z:    return ZIPC_NZ; break;
+               case ZIPC_LT:   return ZIPC_GE; break;
+               case ZIPC_LT:   return ZIPC_GE; break;
+               case ZIPC_C:    return ZIPC_NC; break;
+               case ZIPC_C:    return ZIPC_NC; break;
+               case ZIPC_NZ:   return ZIPC_Z; break;
+               case ZIPC_NZ:   return ZIPC_Z; break;
+               case ZIPC_GE:   return ZIPC_LT; break;
+               case ZIPC_GE:   return ZIPC_LT; break;
+               case ZIPC_NC:   return ZIPC_C; break;
+               case ZIPC_NC:   return ZIPC_C; break;
+               case ZIPC_ALWAYS:       return ZIPC_ALWAYS; break;
+               case ZIPC_ALWAYS:       return ZIPC_ALWAYS; break;
+               default:
+               default:
+                       break;
+                       break;
+       } gas_assert((0)&&("Cannot negate condition\n"));
+       } gas_assert((0)&&("Cannot negate condition\n"));
+       return ZIPC_ALWAYS;
+       return ZIPC_ALWAYS;
+}
+}
+
+
+static const char *zip_skip_white_spaces(const char *str) {
+static const char *zip_skip_white_spaces(const char *str) {
+       if (!str)
+       if (!str)
+               return NULL;
+               return NULL;
+       while((*str)&&(isspace(*str)))
+       while((*str)&&(isspace(*str)))
+               str++;
+               str++;
+       return str;
+       return str;
+}
+}
+
+
+static const char *
+static const char *
+zip_parse_condition(const char *str, ZIP_CONDITION *condn) {
+zip_parse_condition(const char *str, ZIP_CONDITION *condn) {
+       if ((strcasecmp(str, "Z")==0)
+       if ((strcasecmp(str, "Z")==0)
+                       ||(strcasecmp(str, "EQ")==0)) {
+                       ||(strcasecmp(str, "EQ")==0)) {
+               *condn = ZIPC_Z;
+               *condn = ZIPC_Z;
+       } else if ((strcasecmp(str, "LT")==0)
+       } else if ((strcasecmp(str, "LT")==0)
+                       ||(strcasecmp(str, "N")==0)) {
+                       ||(strcasecmp(str, "N")==0)) {
+               *condn = ZIPC_LT;
+               *condn = ZIPC_LT;
+       } else if ((strcasecmp(str, "C")==0)
+       } else if ((strcasecmp(str, "C")==0)
+                       ||(strcasecmp(str, "LTU")==0)) {
+                       ||(strcasecmp(str, "LTU")==0)) {
+               *condn = ZIPC_C;
+               *condn = ZIPC_C;
+       } else if (strcasecmp(str, "V")==0) {
+       } else if (strcasecmp(str, "V")==0) {
+               *condn = ZIPC_V;
+               *condn = ZIPC_V;
+       } else if((strcasecmp(str, "NZ")==0)
+       } else if((strcasecmp(str, "NZ")==0)
+                       ||(strcasecmp(str, "NE")==0)) {
+                       ||(strcasecmp(str, "NE")==0)) {
+               *condn = ZIPC_NZ;
+               *condn = ZIPC_NZ;
+       } else if ((strcasecmp(str, "GE")==0)
+       } else if ((strcasecmp(str, "GE")==0)
+                       ||(strcasecmp(str, "GTE")==0)) {
+                       ||(strcasecmp(str, "GTE")==0)) {
+               *condn = ZIPC_GE;
+               *condn = ZIPC_GE;
+       } else if ((strcasecmp(str, "NC")==0)
+       } else if ((strcasecmp(str, "NC")==0)
+                       ||(strcasecmp(str, "GEU")==0)) {
+                       ||(strcasecmp(str, "GEU")==0)) {
+               *condn = ZIPC_NC;
+               *condn = ZIPC_NC;
+       } else {
+       } else {
+               return "Unrecognized condition";
+               return "Unrecognized condition";
+       }
+       }
+
+
+       return NULL;
+       return NULL;
+}
+}
+
+
+static const char *zip_parse_reg(const char *str, ZIP_REG *regid) {
+static const char *zip_parse_reg(const char *str, ZIP_REG *regid) {
+       const char *ustr = str;
+       const char *ustr = str;
+       int     userreg = 0;
+       int     userreg = 0;
+
+
 
+       if ((!str)||(str[0]=='\0'))
 
+               return "No register given";
+       ustr = zip_skip_white_spaces(str);
+       ustr = zip_skip_white_spaces(str);
+
+
+       if (toupper(ustr[0]) == 'U') {
+       if (toupper(ustr[0]) == 'U') {
+               ustr = str+1;
+               ustr = str+1;
+               userreg = 0x10;
+               userreg = 0x10;
+       } else if ((toupper(ustr[0]) == 'S')&&(strcasecmp(ustr, "SP")!=0)) {
+       } else if ((toupper(ustr[0]) == 'S')&&(strcasecmp(ustr, "SP")!=0)) {
+               ustr = str+1;
+               ustr = str+1;
+       }
+       }
+
+
+       /*
+       /*
+       if (strcasecmp(ustr, "GBL")==0) {
+       if (strcasecmp(ustr, "GBL")==0) {
+               *regid = userreg + 11;
+               *regid = userreg + 11;
+               ustr += 3;
+               ustr += 3;
+       } else
+       } else
+       */
+       */
+       if (strcasecmp(ustr, "LR")==0) {
+       if (strcasecmp(ustr, "LR")==0) {
+               *regid = userreg + 0;
+               *regid = userreg + 0;
+               ustr += 2;
+               ustr += 2;
+       } else if (strcasecmp(ustr, "FP")==0) {
+       } else if (strcasecmp(ustr, "FP")==0) {
+               *regid = userreg + 12;
+               *regid = userreg + 12;
+               ustr += 2;
+               ustr += 2;
+       } else if (strcasecmp(ustr, "SP")==0) {
+       } else if (strcasecmp(ustr, "SP")==0) {
+               *regid = userreg + 13;
+               *regid = userreg + 13;
+               ustr += 2;
+               ustr += 2;
+       } else if (strcasecmp(ustr, "CC")==0) {
+       } else if (strcasecmp(ustr, "CC")==0) {
+               *regid = userreg + 14;
+               *regid = userreg + 14;
+               ustr += 2;
+               ustr += 2;
+       } else if (strcasecmp(ustr, "PC")==0) {
+       } else if (strcasecmp(ustr, "PC")==0) {
+               *regid = userreg + 15;
+               *regid = userreg + 15;
+               ustr += 2;
+               ustr += 2;
+       } else if (('r' == tolower(ustr[0]))
+       } else if (('r' == tolower(ustr[0]))
+                       &&(isdigit(ustr[1]))
+                       &&(isdigit(ustr[1]))
+                       &&((!isdigit(ustr[2]))
+                       &&((!isdigit(ustr[2]))
+                               ||(!isdigit(ustr[3])))) {
+                               ||(!isdigit(ustr[3])))) {
+               *regid = atoi(ustr+1);
+               *regid = atoi(ustr+1);
+               if ((*regid > 15)||(*regid < 0))
+               if ((*regid > 15)||(*regid < 0))
+                       return "Register does not exist";
+                       return "Register does not exist";
+               *regid += userreg;
+               *regid += userreg;
+
+
+               if (!isdigit(ustr[2]))
+               if (!isdigit(ustr[2]))
+                       ustr+=2;
+                       ustr+=2;
+               else
+               else
+                       ustr+=3;
+                       ustr+=3;
+       } else {
+       } else {
+               *regid = ZIP_RNONE;
+               *regid = ZIP_RNONE;
+               return "Unknown register";
+               return "Unknown register";
+       }
+       }
+
+
+       // Registers names are terminated by something other than letters
+       // Registers names are terminated by something other than letters
+       // and numbers.  Things like ')', ',', or '\0' should terminate a
+       // and numbers.  Things like ')', ',', or '\0' should terminate a
+       // register.  Here, we only double check that the register is not
+       // register.  Here, we only double check that the register is not
+       // terminated by another letter or a number.
+       // terminated by another letter or a number.
+       if ((*ustr)&&((isalpha(*ustr))||(isdigit(*ustr))))
+       if ((*ustr)&&((isalpha(*ustr))||(isdigit(*ustr))))
+               return "Unrecognized register";
+               return "Unrecognized register";
+
+
+       return NULL;
+       return NULL;
+}
+}
+
+
+// Parse a 'B' operand
+// Parse a 'B' operand
+static const char *
+static const char *
+zip_parse_bop(const char *bop, ZIPIS *insn) {
+zip_parse_bop(const char *bop, ZIPIS *insn) {
+       // There are a couple forms for what we can expect in a B operand:
+       // There are a couple forms for what we can expect in a B operand:
+       //      The first three require no relocations ...
+       //      The first three require no relocations ...
+       //              1. A simple number
+       //              1. A simple number
+       //              2. Number + Register
+       //              2. Number + Register
+       //              3. Number(Register)
+       //              3. Number(Register)
+       //              4. Register by itself
+       //              4. Register by itself
+       //              Good form is to replace this number with the possibility
+       //              Good form is to replace this number with the possibility
+       //              of a constant expression ...  The number may be any of
+       //              of a constant expression ...  The number may be any of
+       //              [+-](0[xX][0-9a-fA-F]+|(0[0-7]+)|(0-9)+)
+       //              [+-](0[xX][0-9a-fA-F]+|(0[0-7]+)|(0-9)+)
+       //      The next four may require a relocation
+       //      The next four may require a relocation
+       //              4. Label + Register
+       //              4. Label + Register
+       //              5. Label(Register)
+       //              5. Label(Register)
+       //              6. Label (Register is implied: PC, if moving or jumping
+       //              6. Label (Register is implied: PC, if moving or jumping
+       //                      to the PC, or GBL if loading a value or if
+       //                      to the PC, or GBL if loading a value or if
+       //                      the offset ends up being unknown)
+       //                      the offset ends up being unknown)
+       //              Good form allows an expression instead of a label,
+       //              Good form allows an expression instead of a label,
+       //              that can be evaluated at ... sometime.
+       //              that can be evaluated at ... sometime.
+       //              7. Number(Label)
+       //              7. Number(Label)
+       //
+       //
+       // We will support:
+       // We will support:
+       //      (Number|Label)?( "("Register")" | "+"Register )
+       //      (Number|Label)?( "("Register")" | "+"Register )
+       //
+       //
+       char    lbl[512], *lblp = lbl;
+       char    lbl[512], *lblp = lbl;
+       const char      *ptr;
+       const char      *ptr;
+       insn->i_imm = 0;
+       insn->i_imm = 0;
+       *lblp = '\0';
+       *lblp = '\0';
+
+
+       if (strlen(bop)>sizeof(lbl)-1)
+       if (strlen(bop)>sizeof(lbl)-1)
+               as_fatal( _("Label length too long"));
+               as_fatal( _("Label length too long"));
+       // printf("RAW-OP-B: %s %s\n", bop, (insn->i_rp)?"(i_rp != NULL)":"");
+       // printf("RAW-OP-B: %s %s\n", bop, (insn->i_rp)?"(i_rp != NULL)":"");
+
+
+       // Do we start with a number?
+       // Do we start with a number?
+       {
+       {
+               int     sgn = 0;
+               int     sgn = 0;
+
+
+               ptr = zip_skip_white_spaces(bop);
+               ptr = zip_skip_white_spaces(bop);
+               if ('$' == *ptr)
+               if ('$' == *ptr)
+                       ptr = zip_skip_white_spaces(ptr+1);
+                       ptr = zip_skip_white_spaces(ptr+1);
+
+
+               if ('+' == *ptr)
+               if ('+' == *ptr)
+                       ptr++;
+                       ptr++;
+               else if ('-' == *ptr) {
+               else if ('-' == *ptr) {
+                       sgn = 1;
+                       sgn = 1;
+                       ptr++;
+                       ptr++;
+               }
+               }
+
+
+               if ('$' == *ptr)
+               if ('$' == *ptr)
+                       ptr = zip_skip_white_spaces(ptr+1);
+                       ptr = zip_skip_white_spaces(ptr+1);
+               ptr = zip_skip_white_spaces(ptr);
+               ptr = zip_skip_white_spaces(ptr);
+               if ('$' == *ptr)
+               if ('$' == *ptr)
+                       ptr = zip_skip_white_spaces(ptr+1);
+                       ptr = zip_skip_white_spaces(ptr+1);
+
+
+               if ((*ptr)&&(isdigit(*ptr))) {
+               if ((*ptr)&&(isdigit(*ptr))) {
+                       char *end = (char *)ptr;
+                       char *end = (char *)ptr;
+                       unsigned long v = strtoul(ptr, &end, 0);
+                       unsigned long v = strtoul(ptr, &end, 0);
+                       // We start with a number
+                       // We start with a number
+                       if (sgn)
+                       if (sgn)
+                               insn->i_imm = (int)(-v);
+                               insn->i_imm = (int)(-v);
+                       else
+                       else
+                               insn->i_imm = (int)(v);
+                               insn->i_imm = (int)(v);
+                       ptr = (const char *)end;
+                       ptr = (const char *)end;
+
+
+                       // Permit a string of Num [[+-] Num]*
+                       // Permit a string of Num [[+-] Num]*
+                       // This is necessary for the DI instructions within the
+                       // This is necessary for the DI instructions within the
+                       // compiler.
+                       // compiler.
+                       while( ((*ptr == '+')||(*ptr == '-'))
+                       while( ((*ptr == '+')||(*ptr == '-'))
+                               &&(isdigit(ptr[1])) ) {
+                               &&(isdigit(ptr[1])) ) {
+                               sgn = (*ptr == '-');
+                               sgn = (*ptr == '-');
+                               v = strtoul(&ptr[1], &end, 0);
+                               v = strtoul(&ptr[1], &end, 0);
+                               if (sgn) v = -v;
+                               if (sgn) v = -v;
+                               insn->i_imm += (int)v;
+                               insn->i_imm += (int)v;
+                               ptr = (const char *)end;
+                               ptr = (const char *)end;
+                       }
+                       }
+               } else if ((*ptr)&&(
+               } else if ((*ptr)&&(
+                               (isalpha(*ptr))
+                               (isalpha(*ptr))
+                               ||('*'==*ptr)
+                               ||('*'==*ptr)
+                               ||('.'==*ptr)
+                               ||('.'==*ptr)
+                               ||('_'==*ptr))) {
+                               ||('_'==*ptr))) {
+                       // We start with an identifier
+                       // We start with an identifier
+                       // printf("OP-B ( \'%s\' ) starts with an identifier (%c)\n",
+                       // printf("OP-B ( \'%s\' ) starts with an identifier (%c)\n",
+                               // bop, *ptr);
+                               // bop, *ptr);
+
+
+                       // Skip any compiler inserted prefix (if present)
+                       // Skip any compiler inserted prefix (if present)
+                       if ('*' == *ptr)
+                       if ('*' == *ptr)
+                               ptr++;
+                               ptr++;
+                       while((*ptr)&&(
+                       while((*ptr)&&(
+                                       (isalpha(*ptr))
+                                       (isalpha(*ptr))
+                                       ||(isdigit(*ptr))
+                                       ||(isdigit(*ptr))
+                                       ||('_' == *ptr)
+                                       ||('_' == *ptr)
+                                       ||('$' == *ptr)
+                                       ||('$' == *ptr)
+                                       ||('.' == *ptr)))
+                                       ||('.' == *ptr)))
+                               *lblp++ = *ptr++;
+                               *lblp++ = *ptr++;
+                       *lblp = '\0';
+                       *lblp = '\0';
+                       // printf("LBL was %s\n", lbl);
+                       // printf("LBL was %s\n", lbl);
+
+
+                       // This could still be a register ... can't tell yet
+                       // This could still be a register ... can't tell yet
+                       if (sgn)
+                       if (sgn)
+                               return "ERR: Not expecting a signed label!";
+                               return "ERR: Not expecting a signed label!";
+
+
+                       ptr = zip_skip_white_spaces(ptr);
+                       ptr = zip_skip_white_spaces(ptr);
+               }
+               }
+       }
+       }
+
+
+       ptr = zip_skip_white_spaces(ptr);
+       ptr = zip_skip_white_spaces(ptr);
+
+
+       const   char *err = NULL;
+       const   char *err = NULL;
+
+
+       if ((*ptr == '+')&&(ptr[1] == '('))
+       if ((*ptr == '+')&&(ptr[1] == '('))
+               ptr++;
+               ptr++;
+       if ((*ptr)&&(*ptr == '(')) {
+       if ((*ptr)&&(*ptr == '(')) {
+               // Form #3: Number(register)
+               // Form #3: Number(register)
+               char *end = strchr(ptr+1, ')');
+               char *end = strchr(ptr+1, ')');
+               if (NULL == end)
+               if (NULL == end)
+                       return "Un-matched \'(\', cannot find \')\'";
+                       return "Un-matched \'(\', cannot find \')\'";
+               *end = '\0';
+               *end = '\0';
+               // printf("Looking for a register in %s\n", ptr+1);
+               // printf("Looking for a register in %s\n", ptr+1);
+               err = zip_parse_reg(ptr+1, &insn->i_breg);
+               err = zip_parse_reg(ptr+1, &insn->i_breg);
+               if (err) {
+               if (err) {
+                       // Must've been a symbol
+                       // Must've been a symbol
+                       if (lbl[0] != '\0') // Already have a symbol in this
+                       if (lbl[0] != '\0') // Already have a symbol in this
+                               return err;     // expression!
+                               return err;     // expression!
+                       ptr++;
+                       ptr++;
+                       while((*ptr)&&(
+                       while((*ptr)&&(
+                                       (isalpha(*ptr))
+                                       (isalpha(*ptr))
+                                       ||(isdigit(*ptr))
+                                       ||(isdigit(*ptr))
+                                       ||('_' == *ptr)
+                                       ||('_' == *ptr)
+                                       ||('$' == *ptr)
+                                       ||('$' == *ptr)
+                                       ||('.' == *ptr)))
+                                       ||('.' == *ptr)))
+                               *lblp++ = *ptr++;
+                               *lblp++ = *ptr++;
+                       *lblp = '\0';
+                       *lblp = '\0';
+                       insn->i_breg = ZIP_RNONE;
+                       insn->i_breg = ZIP_RNONE;
+                       ptr = zip_skip_white_spaces(ptr);
+                       ptr = zip_skip_white_spaces(ptr);
+                       if (*ptr != '\0')
+                       if (*ptr != '\0')
+                               return "ERR: Expression within parenthesis not supported";
+                               return "ERR: Expression within parenthesis not supported";
+                       err = NULL;
+                       err = NULL;
+               }
+               }
+               // printf("Found a register, %s -> %d\n", ptr+1, insn->i_breg);
+               // printf("Found a register, %s -> %d\n", ptr+1, insn->i_breg);
+       } else if ((*ptr)&&((*ptr == '+')||(*ptr == '-'))) {
+       } else if ((*ptr)&&((*ptr == '+')||(*ptr == '-'))) {
+               if ((*lbl)&&(zip_parse_reg(lbl, &insn->i_breg) == NULL)) {
+               if ((*lbl)&&(zip_parse_reg(lbl, &insn->i_breg) == NULL)) {
+                       // Register+Number
+                       // Register+Number
+                       // Skip to the end to process what follows
+                       // Skip to the end to process what follows
+                       *lbl = '\0'; // Label wasn't a symbol, so let's clear it
+                       *lbl = '\0'; // Label wasn't a symbol, so let's clear it
+               } else {
+               } else {
+                       // Number/label+Register
+                       // Number/label+Register
+                       while((('+' == *ptr)||('-' == *ptr))
+                       while((('+' == *ptr)||('-' == *ptr))
+                                       &&(ptr[1])
+                                       &&(ptr[1])
+                                       &&((isdigit(ptr[1]))
+                                       &&((isdigit(ptr[1]))
+                                       ||((ptr[0] == '+')
+                                       ||((ptr[0] == '+')
+                                               &&(ptr[1] == '-')
+                                               &&(ptr[1] == '-')
+                                               &&(ptr[2])
+                                               &&(ptr[2])
+                                               &&(isdigit(ptr[2]))))) {
+                                               &&(isdigit(ptr[2]))))) {
+                               char *end;
+                               char *end;
+
+
+                               if ((*ptr == '+')&&(isdigit(ptr[1])))
+                               if ((*ptr == '+')&&(isdigit(ptr[1])))
+                                       insn->i_imm += strtoul(ptr, &end, 0);
+                                       insn->i_imm += strtoul(ptr, &end, 0);
+                               else if ((*ptr == '+')&&(ptr[1] == '-')
+                               else if ((*ptr == '+')&&(ptr[1] == '-')
+                                               &&(isdigit(ptr[2])))
+                                               &&(isdigit(ptr[2])))
+                                       insn->i_imm -= strtoul(ptr+2, &end, 0);
+                                       insn->i_imm -= strtoul(ptr+2, &end, 0);
+                               else if ((*ptr == '-')&&(isdigit(ptr[1])))
+                               else if ((*ptr == '-')&&(isdigit(ptr[1])))
+                                       insn->i_imm -= strtoul(ptr+1, &end, 0);
+                                       insn->i_imm -= strtoul(ptr+1, &end, 0);
+                               else {
+                               else {
+                                       fprintf(stderr, "GAS: Cannot comprehend %s\n", ptr);
+                                       fprintf(stderr, "GAS: Cannot comprehend %s\n", ptr);
+                                       gas_assert((0)&&("Should never get here"));
+                                       gas_assert((0)&&("Should never get here"));
+                               }
+                               }
+                               ptr = (const char *)end;
+                               ptr = (const char *)end;
+                       }
+                       }
+                       if (('+' == *ptr)&&((err = zip_parse_reg(ptr+1, &insn->i_breg))==NULL)) {
+                       if (('+' == *ptr)&&((err = zip_parse_reg(ptr+1, &insn->i_breg))==NULL)) {
+                               // Let's skip to the end of the register
+                               // Let's skip to the end of the register
+                               ptr++;
+                               ptr++;
+                               while(isalpha(*ptr))
+                               while(isalpha(*ptr))
+                                       ptr++;
+                                       ptr++;
+                               while(isdigit(*ptr))
+                               while(isdigit(*ptr))
+                                       ptr++;
+                                       ptr++;
+                       } else if (('(' == *ptr)&&((err = zip_parse_reg(ptr+1, &insn->i_breg))==NULL)) {
+                       } else if (('(' == *ptr)&&((err = zip_parse_reg(ptr+1, &insn->i_breg))==NULL)) {
+                               ptr++;
+                               ptr++;
+                               while((*ptr)&&(')' != *ptr))
+                               while((*ptr)&&(')' != *ptr))
+                                       ptr++;
+                                       ptr++;
+                               ptr++;
+                               ptr++;
+                       } else {
+                       } else {
+                               // OOps!! Must've been a label + number
+                               // OOps!! Must've been a label + number
+                               err = NULL;
+                               err = NULL;
+                       }
+                       }
+               }
+               }
+       } else if ((*lbl)&&(NULL == zip_parse_reg(lbl, &insn->i_breg))) {
+       } else if ((*lbl)&&(NULL == zip_parse_reg(lbl, &insn->i_breg))) {
+               // Form: Register (only)
+               // Form: Register (only)
+               insn->i_imm = 0;
+               insn->i_imm = 0;
+               // printf("OP-B ( \'%s\' ) Had a register, %s -> %d\n", bop,
+               // printf("OP-B ( \'%s\' ) Had a register, %s -> %d\n", bop,
+                       // lbl, insn->i_breg);
+                       // lbl, insn->i_breg);
+               *lbl = '\0';
+               *lbl = '\0';
+       } else if (*lbl) {
+       } else if (*lbl) {
+               // Form: Label or Number (only)
+               // Form: Label or Number (only)
+               insn->i_breg = ZIP_RNONE;
+               insn->i_breg = ZIP_RNONE;
+       }
+       }
+
+
+       // Look for a +number at the end
+       // Look for a +number at the end
+       if ((*ptr)&&((*ptr == '+')||(*ptr == '-'))) {
+       if ((*ptr)&&((*ptr == '+')||(*ptr == '-'))) {
+               // printf("Looking at a plus: %s\n", ptr);
+               // printf("Looking at a plus: %s\n", ptr);
+               int     sgn = (*ptr == '-')?1:0;
+               int     sgn = (*ptr == '-')?1:0;
+
+
+               if (sgn) {
+               if (sgn) {
+                       // printf("... I meant a minus\n");
+                       // printf("... I meant a minus\n");
+                       ptr++;
+                       ptr++;
+               }
+               }
+
+
+               ptr = zip_skip_white_spaces(ptr);
+               ptr = zip_skip_white_spaces(ptr);
+               if ('$' == *ptr)
+               if ('$' == *ptr)
+                       ptr = zip_skip_white_spaces(ptr+1);
+                       ptr = zip_skip_white_spaces(ptr+1);
+
+
+               if ('+' == *ptr)
+               if ('+' == *ptr)
+                       ptr++;
+                       ptr++;
+               if ('-' == *ptr) {
+               if ('-' == *ptr) {
+                       sgn = !sgn;
+                       sgn = !sgn;
+                       ptr++;
+                       ptr++;
+               }
+               }
+
+
+               ptr = zip_skip_white_spaces(ptr);
+               ptr = zip_skip_white_spaces(ptr);
+               if ('$' == *ptr)
+               if ('$' == *ptr)
+                       ptr = zip_skip_white_spaces(ptr+1);
+                       ptr = zip_skip_white_spaces(ptr+1);
+               if ('-' == *ptr) {
+               if ('-' == *ptr) {
+                       sgn = !sgn;
+                       sgn = !sgn;
+                       ptr++;
+                       ptr++;
+               }
+               }
+
+
+               if ((*ptr)&&(isdigit(*ptr))) {
+               if ((*ptr)&&(isdigit(*ptr))) {
+                       char *end = (char *)ptr;
+                       char *end = (char *)ptr;
+
+
+                       // printf("Parsing #: %s\n", ptr);
+                       // printf("Parsing #: %s\n", ptr);
+                       // While the following might make the most sense,
+                       // While the following might make the most sense,
+                       //    if (sgn) *--ptr = '-';
+                       //    if (sgn) *--ptr = '-';
+                       // the string is read-only, so we can't change it.
+                       // the string is read-only, so we can't change it.
+                       // Instead we do ...
+                       // Instead we do ...
+                       unsigned long v = (sgn)?
+                       unsigned long v = (sgn)?
+                               -strtoul(ptr, &end, 0) : strtoul(ptr, &end, 0);
+                               -strtoul(ptr, &end, 0) : strtoul(ptr, &end, 0);
+                       insn->i_imm += v;
+                       insn->i_imm += v;
+                       ptr = (const char *)end;
+                       ptr = (const char *)end;
+               }
+               }
+       }
+       }
+
+
+       if (*lbl) {
+       if (*lbl) {
+               // printf("i_rp = %s\n", (insn->i_rp)?"(Null)":"not NULL");
+               // printf("i_rp = %s\n", (insn->i_rp)?"(Null)":"not NULL");
+               symbolS *sym = symbol_find_or_make(lbl);
+               symbolS *sym = symbol_find_or_make(lbl);
+               sym->sy_flags.sy_used = TRUE;
+               sym->sy_flags.sy_used = TRUE;
+               // segT seg = S_GET_SEGMENT(sym);
+               // segT seg = S_GET_SEGMENT(sym);
+#ifdef ZIP_DEBUG
+#ifdef ZIP_DEBUG
+               zip_dump_sym(sym);
+               zip_dump_sym(sym);
+#endif
+#endif
+               if (insn->i_breg == ZIP_PC) {
+               if (insn->i_breg == ZIP_PC) {
+                       // New pc-relative relocation,
+                       // New pc-relative relocation,
+                       // ???
+                       // ???
+                       // symbolP = symbol_create(FAKE_LABEL_NAME,
+                       // symbolP = symbol_create(FAKE_LABEL_NAME,
+                               // absolute_section, 0 &zero_address_frag);
+                               // absolute_section, 0 &zero_address_frag);
+                       // symbol_set_value_expression(symbolP, expressionP);
+                       // symbol_set_value_expression(symbolP, expressionP);
+                       // resolve_symbol_value(symbolP);
+                       // resolve_symbol_value(symbolP);
+                       insn->i_rp =(ZIPRELOC *)xmalloc(sizeof(ZIPRELOC));
+                       insn->i_rp =(ZIPRELOC *)xmalloc(sizeof(ZIPRELOC));
+                       insn->i_rp->r_sym = sym;
+                       insn->i_rp->r_sym = sym;
+                       insn->i_rp->r_pcrel = TRUE;
+                       insn->i_rp->r_pcrel = TRUE;
+                       insn->i_rp->r_fr_offset = 0;
+                       insn->i_rp->r_fr_offset = 0;
+                       insn->i_rp->r_fix = NULL;
+                       insn->i_rp->r_fix = NULL;
+                       insn->i_rp->r_type = BFD_RELOC_ZIP_OPB_PCREL;
+                       insn->i_rp->r_type = BFD_RELOC_ZIP_OPB_PCREL;
+                       // symbol_make(name??)
+                       // symbol_make(name??)
+                       // symbol_find_or_make(name)
+                       // symbol_find_or_make(name)
+                       // symbol_relc_make_sym
+                       // symbol_relc_make_sym
+                       // symbol_relc_make_value
+                       // symbol_relc_make_value
+                       // symbol_find(name)
+                       // symbol_find(name)
+                       // symbol_find_noref(name, noref)
+                       // symbol_find_noref(name, noref)
+                       // symbol_find_exact(name)
+                       // symbol_find_exact(name)
+                       // symbol_find_exact_noref(name, noref)
+                       // symbol_find_exact_noref(name, noref)
+                       // symbol_find_or_make(name)
+                       // symbol_find_or_make(name)
+                       // symbol_make(name)
+                       // symbol_make(name)
+                       // symbol_new(name, seg, value, frag)
+                       // symbol_new(name, seg, value, frag)
+                       //      preferred call over symbol create
+                       //      preferred call over symbol create
+                       //      calls symbol_create internal
+                       //      calls symbol_create internal
+                       // symbol_create(name, segment, value, frag)
+                       // symbol_create(name, segment, value, frag)
+                       //
+                       //
+                       // local_symbol_make(name, section, value, frag)
+                       // local_symbol_make(name, section, value, frag)
+                       // symbol_clone(sym, int)
+                       // symbol_clone(sym, int)
+                       // symbol_temp_new(seg, value, frag)
+                       // symbol_temp_new(seg, value, frag)
+                       // symbol_temp_new_now(void)
+                       // symbol_temp_new_now(void)
+                       // symbol_temp_make(void)
+                       // symbol_temp_make(void)
+                       // colon(void)
+                       // colon(void)
+                       //      Called when symbol: starts a line
+                       //      Called when symbol: starts a line
+                       //      Calls symbol_new(name, now_seg, frag_now_fix(),
+                       //      Calls symbol_new(name, now_seg, frag_now_fix(),
+                       //              frag_now);
+                       //              frag_now);
+                       //              symbol_table_insert(symbolP)
+                       //              symbol_table_insert(symbolP)
+                       //
+                       //
+                       // expr_build_dot returns a symbol pointing to the
+                       // expr_build_dot returns a symbol pointing to the
+                       //      current location ...
+                       //      current location ...
+                       //
+                       //
+                       // Useful:
+                       // Useful:
+                       //      frag_now is current frag
+                       //      frag_now is current frag
+                       //      S_SET_VALUE(symbolP, frag_now_fix()) ???
+                       //      S_SET_VALUE(symbolP, frag_now_fix()) ???
+                       //      now_seg must be the current segment
+                       //      now_seg must be the current segment
+                       //      S_SET_SETGMENT(symbolP, now_seg);
+                       //      S_SET_SETGMENT(symbolP, now_seg);
+               /*
+               /*
+               } else if((zip_param_got)&&(insn->i_breg == ZIP_GBL)) {
+               } else if((zip_param_got)&&(insn->i_breg == ZIP_GBL)) {
+                       // New GOT-relative relocation
+                       // New GOT-relative relocation
+                       insn->i_rp =(ZIPRELOC *)xmalloc(sizeof(ZIPRELOC));
+                       insn->i_rp =(ZIPRELOC *)xmalloc(sizeof(ZIPRELOC));
+                       insn->i_rp->r_sym = sym;
+                       insn->i_rp->r_sym = sym;
+                       insn->i_rp->r_pcrel = FALSE;
+                       insn->i_rp->r_pcrel = FALSE;
+                       insn->i_rp->r_fr_offset = 0;
+                       insn->i_rp->r_fr_offset = 0;
+                       insn->i_rp->r_fix = NULL;
+                       insn->i_rp->r_fix = NULL;
+               */
+               */
+               } else {
+               } else {
+                       insn->i_rp =(ZIPRELOC *)xmalloc(sizeof(ZIPRELOC));
+                       insn->i_rp =(ZIPRELOC *)xmalloc(sizeof(ZIPRELOC));
+                       insn->i_rp->r_sym = sym;
+                       insn->i_rp->r_sym = sym;
+                       insn->i_rp->r_pcrel = FALSE;
+                       insn->i_rp->r_pcrel = FALSE;
+                       insn->i_rp->r_fr_offset = 0;
+                       insn->i_rp->r_fr_offset = 0;
+                       insn->i_rp->r_fix = NULL;
+                       insn->i_rp->r_fix = NULL;
+                       if (insn->i_breg != ZIP_RNONE)
+                       if (insn->i_breg != ZIP_RNONE)
+                               insn->i_rp->r_type = BFD_RELOC_ZIP_OPB_OFFSET;
+                               insn->i_rp->r_type = BFD_RELOC_ZIP_OPB_OFFSET;
+                       else
+                       else
+                               insn->i_rp->r_type = BFD_RELOC_ZIP_OPB_IMM;
+                               insn->i_rp->r_type = BFD_RELOC_ZIP_OPB_IMM;
+               }
+               }
+       }
+       }
+
+
+       return  err;
+       return  err;
+}
+}
+
+
+static int     fits_within(int nbits, int value) {
+static int     fits_within(int nbits, int value) {
+       // -2 fits_within two bits
+       // -2 fits_within two bits
+       // -1 fits_within two bits
+       // -1 fits_within two bits
+       //  1 fits_within two bits
+       //  1 fits_within two bits
+       //  2 does not
+       //  2 does not
+       //
+       //
+       if (value > 0)
+       if (value > 0)
+               return (value <   (1l<<(nbits-1))) ? 1:0;
+               return (value <   (1l<<(nbits-1))) ? 1:0;
+       else
+       else
+               return (value >= -(1l<<(nbits-1))) ? 1:0;
+               return (value >= -(1l<<(nbits-1))) ? 1:0;
+}
+}
+
+
+static const char *zip_parse(const char *line, ZIPIS *insn) {
+static const char *zip_parse(const char *line, ZIPIS *insn) {
+       const char      *err = NULL, *opstr = NULL;
+       const char      *err = NULL, *opstr = NULL;
+       char    *alt;
+       char    *alt;
+       int     i;
+       int     i;
+       char *cndp = NULL;
+       char *cndp = NULL;
+       // Two (possible) tokens left:
+       // Two (possible) tokens left:
+       //      the left of the comma, and the right of the comma
+       //      the left of the comma, and the right of the comma
+       const char      *left, *right, *eol;
+       const char      *left, *right, *eol;
+       typedef enum    {
+       typedef enum    {
+               TWO_OP,         // Standard for most instructions
+               TWO_OP,         // Standard for most instructions
+               IMM_OP,         // Immediate operand only
+               IMM_OP,         // Immediate operand only
+               BACKWARDS_TWO,  // Only used by STO REG,Off(REG)
+               BACKWARDS_TWO,  // Only used by STO REG,Off(REG)
+               NO_OP,          // Used by NOOP, BUSY, HALT, RTU, LOCK, etc
+               NO_OP,          // Used by NOOP, BUSY, HALT, RTU, LOCK, etc
+               ONE_OR_TWO_OP,  // Only used by TST
+               ONE_OR_TWO_OP,  // Only used by TST
+               MAYBE_ONE_IMM,  // Only used by BREAK, NOOP, SIM
+               MAYBE_ONE_IMM,  // Only used by BREAK, NOOP, SIM
+               MAYBE_ONE_REG,  // Only used by SDUMP, NDUMP
+               MAYBE_ONE_REG,  // Only used by SDUMP, NDUMP
+               MAYBE_ONE_IMM_OR_REG,   // Only used by SEXIT, NEXIT, SOUT, NOUT
+               MAYBE_ONE_IMM_OR_REG,   // Only used by SEXIT, NEXIT, SOUT, NOUT
+               MAYBE_OPB,      // Only used by TRAP
+               MAYBE_OPB,      // Only used by TRAP
+               ONE_REGISTER,   // Only used by CLR, CLRF, and NOT
+               ONE_REGISTER,   // Only used by CLR, CLRF, and NOT
+               OP_ADDRESS,     // Only used by BRA, BRA.C, and LINK
+               OP_ADDRESS,     // Only used by BRA, BRA.C, and LINK
+               OP_B,           // Only used by JMP
+               OP_B,           // Only used by JMP
+               TWO_REGISTER,   // Only used by FP instructions
+               TWO_REGISTER,   // Only used by FP instructions
+               ILLEGAL_FORM    // Never used, for debugging only
+               ILLEGAL_FORM    // Never used, for debugging only
+       } FORMTYPE;
+       } FORMTYPE;
+
+
+       FORMTYPE        insn_form = ILLEGAL_FORM; // Make sure we set this
+       FORMTYPE        insn_form = ILLEGAL_FORM; // Make sure we set this
+
+
+
+
+
+
+#ifdef ZIP_DEBUG
+#ifdef ZIP_DEBUG
+       fprintf(stderr, "**** Parsing %s\n", line);
+       fprintf(stderr, "**** Parsing %s\n", line);
+#endif
+#endif
+
+
+       insn->i_naux = 0;
+       insn->i_naux = 0;
+       insn->i_op   = ZIPO_NOOP;
+       insn->i_op   = ZIPO_NOOP;
+       insn->i_cnd  = ZIPC_ALWAYS;
+       insn->i_cnd  = ZIPC_ALWAYS;
+       insn->i_areg = ZIP_RNONE;
+       insn->i_areg = ZIP_RNONE;
+       insn->i_breg = ZIP_RNONE;
+       insn->i_breg = ZIP_RNONE;
+       insn->i_imm  = 0;
+       insn->i_imm  = 0;
+       insn->i_rp   = NULL;
+       insn->i_rp   = NULL;
+       insn->i_code = NOOP_OPCODE;
+       insn->i_code = NOOP_OPCODE;
+       for(i=0; i<ZIP_MAX_NAUX; i++)
+       for(i=0; i<ZIP_MAX_NAUX; i++)
+               insn->i_aux[i]  = NOOP_OPCODE;
+               insn->i_aux[i]  = NOOP_OPCODE;
+
+
+       // The opcode is given between whitespace and a period, or whitespace
+       // The opcode is given between whitespace and a period, or whitespace
+       // and whitespace
+       // and whitespace
+       alt = strdup(zip_skip_white_spaces(line));
+       alt = strdup(zip_skip_white_spaces(line));
+       if ((*alt)=='[') {
+       if ((*alt)=='[') {
+               // Instruction starts with condition codes-- a feature we
+               // Instruction starts with condition codes-- a feature we
+               // needed to add in order to support GCC conditional execution
+               // needed to add in order to support GCC conditional execution
+               // macro
+               // macro
+               cndp = strtok(alt,"] \t")+1;
+               cndp = strtok(alt,"] \t")+1;
+               if (!cndp)
+               if (!cndp)
+                       return "Mismatched parenthesis--an attempt at a condition?";
+                       return "Mismatched parenthesis--an attempt at a condition?";
+               if (strlen(cndp) > 3)
+               if (strlen(cndp) > 3)
+                       return "Invalid condition (too long)";
+                       return "Invalid condition (too long)";
+
+
+               opstr = strtok(NULL, " \t");
+               opstr = strtok(NULL, " \t");
+               if (!opstr)
+               if (!opstr)
+                       return "Condition not followed by valid opcode";
+                       return "Condition not followed by valid opcode";
+       } else {
+       } else {
+               opstr = strtok(alt, " \t"); // Get our opcode
+               opstr = strtok(alt, " \t"); // Get our opcode
+               if (!opstr) {
+               if (!opstr) {
+                       free(alt);
+                       free(alt);
+                       return "Invalid Instruction";
+                       return "Invalid Instruction";
+               }
+               }
+       }
+       }
+       // See if our token contains a '.' within it
+       // See if our token contains a '.' within it
+       //      GCC allows conditions beginning a line, as in ...
+       //      GCC allows conditions beginning a line, as in ...
+       //              (CND)   Opcode  B,A
+       //              (CND)   Opcode  B,A
+       //      such a condition, if present, was detected above.
+       //      such a condition, if present, was detected above.
+       //
+       //
+       //      If not, we now look for a condition written in our original
+       //      If not, we now look for a condition written in our original
+       //      format of ...
+       //      format of ...
+       //              Opcode.CND B,A
+       //              Opcode.CND B,A
+       //      and we look for it here.
+       //      and we look for it here.
+       //
+       //
+       if (!cndp) {
+       if (!cndp) {
+               cndp = strchr(opstr, '.');
+               cndp = strchr(opstr, '.');
+               // If we found such a condition, we need to fix the opstr
+               // If we found such a condition, we need to fix the opstr
+               // so that it no longer includes the condition.  Hence, let's
+               // so that it no longer includes the condition.  Hence, let's
+               // place a NULL within the alt string and push our condition
+               // place a NULL within the alt string and push our condition
+               // forward to the first non '.' value.
+               // forward to the first non '.' value.
+               if (cndp)
+               if (cndp)
+                       *cndp++ = '\0';
+                       *cndp++ = '\0';
+       }
+       }
+       if (strcasecmp(opstr, "SUB")==0) {
+       if (strcasecmp(opstr, "SUB")==0) {
+               insn->i_op = ZIPO_SUB;
+               insn->i_op = ZIPO_SUB;
+               insn_form = TWO_OP;
+               insn_form = TWO_OP;
+       } else if (strcasecmp(opstr, "AND")==0) {
+       } else if (strcasecmp(opstr, "AND")==0) {
+               insn->i_op = ZIPO_AND;
+               insn->i_op = ZIPO_AND;
+               insn_form = TWO_OP;
+               insn_form = TWO_OP;
+       } else if (strcasecmp(opstr, "ADD")==0) {
+       } else if (strcasecmp(opstr, "ADD")==0) {
+               insn->i_op = ZIPO_ADD;
+               insn->i_op = ZIPO_ADD;
+               insn_form = TWO_OP;
+               insn_form = TWO_OP;
+       } else if (strcasecmp(opstr, "OR")==0) {
+       } else if (strcasecmp(opstr, "OR")==0) {
+               insn->i_op = ZIPO_OR;
+               insn->i_op = ZIPO_OR;
+               insn_form = TWO_OP;
+               insn_form = TWO_OP;
+       } else if (strcasecmp(opstr, "XOR")==0) {
+       } else if (strcasecmp(opstr, "XOR")==0) {
+               insn->i_op = ZIPO_XOR;
+               insn->i_op = ZIPO_XOR;
+               insn_form = TWO_OP;
+               insn_form = TWO_OP;
+       } else if (strcasecmp(opstr, "LSR")==0) {
+       } else if (strcasecmp(opstr, "LSR")==0) {
+               insn->i_op = ZIPO_LSR;
+               insn->i_op = ZIPO_LSR;
+               insn_form = TWO_OP;
+               insn_form = TWO_OP;
+       } else if (strcasecmp(opstr, "LSL")==0) {
+       } else if (strcasecmp(opstr, "LSL")==0) {
+               insn->i_op = ZIPO_LSL;
+               insn->i_op = ZIPO_LSL;
+               insn_form = TWO_OP;
+               insn_form = TWO_OP;
+       } else if (strcasecmp(opstr, "ASR")==0) {
+       } else if (strcasecmp(opstr, "ASR")==0) {
+               insn->i_op = ZIPO_ASR;
+               insn->i_op = ZIPO_ASR;
+               insn_form = TWO_OP;
+               insn_form = TWO_OP;
+       } else if (strcasecmp(opstr, "BREV")==0) {
+       } else if (strcasecmp(opstr, "BREV")==0) {
+               insn->i_op = ZIPO_BREV;                 // BREV b+Rb,Ra, or
+               insn->i_op = ZIPO_BREV;                 // BREV b+Rb,Ra, or
+               insn_form = ONE_OR_TWO_OP;              // BREV Rx -> BREV Rx,Rx
+               insn_form = ONE_OR_TWO_OP;              // BREV Rx -> BREV Rx,Rx
+       } else if((strcasecmp(opstr, "LDILO")==0)
+       } else if((strcasecmp(opstr, "LDILO")==0)
+                       ||(strcasecmp(opstr, "LLO")==0)) {
+                       ||(strcasecmp(opstr, "LLO")==0)) {
+               insn->i_op = ZIPO_LDILO;
+               insn->i_op = ZIPO_LDILO;
+               insn_form = TWO_OP;
+               insn_form = TWO_OP;
+       } else if (strcasecmp(opstr, "MPYUHI")==0) {    // MPUHI
+       } else if (strcasecmp(opstr, "MPYUHI")==0) {    // MPUHI
+               insn->i_op = ZIPO_MPYUHI;
+               insn->i_op = ZIPO_MPYUHI;
+               insn_form = TWO_OP;
+               insn_form = TWO_OP;
+       } else if (strcasecmp(opstr, "MPYSHI")==0) {    // MPSHI
+       } else if (strcasecmp(opstr, "MPYSHI")==0) {    // MPSHI
+               insn->i_op = ZIPO_MPYSHI;
+               insn->i_op = ZIPO_MPYSHI;
+               insn_form = TWO_OP;
+               insn_form = TWO_OP;
+       } else if (strcasecmp(opstr, "MPY")==0) {
+       } else if (strcasecmp(opstr, "MPY")==0) {
+               insn_form = TWO_OP;
+               insn_form = TWO_OP;
+               insn->i_op = ZIPO_MPY;
+               insn->i_op = ZIPO_MPY;
+       } else if (strcasecmp(opstr, "MOV")==0) {
+       } else if (strcasecmp(opstr, "MOV")==0) {
+               insn->i_op = ZIPO_MOV;
+               insn->i_op = ZIPO_MOV;
+               insn_form = TWO_OP;
+               insn_form = TWO_OP;
+       } else if (strcasecmp(opstr, "DIVU")==0) {
+       } else if (strcasecmp(opstr, "DIVU")==0) {
+               insn->i_op = ZIPO_DIVU;
+               insn->i_op = ZIPO_DIVU;
+               insn_form = TWO_OP;
+               insn_form = TWO_OP;
+       } else if (strcasecmp(opstr, "DIVS")==0) {
+       } else if (strcasecmp(opstr, "DIVS")==0) {
+               insn->i_op = ZIPO_DIVS;
+               insn->i_op = ZIPO_DIVS;
+               insn_form = TWO_OP;
+               insn_form = TWO_OP;
+       } else if (strcasecmp(opstr, "CMP")==0) {
+       } else if (strcasecmp(opstr, "CMP")==0) {
+               insn->i_op = ZIPO_CMP;
+               insn->i_op = ZIPO_CMP;
+               insn_form = TWO_OP;
+               insn_form = TWO_OP;
+       } else if ((strcasecmp(opstr, "TST")==0)
+       } else if ((strcasecmp(opstr, "TST")==0)
+               ||(strcasecmp(opstr, "TEST")==0)) {
+               ||(strcasecmp(opstr, "TEST")==0)) {
+               insn->i_op = ZIPO_TST;                  // TST b+Rb,Ra, or
+               insn->i_op = ZIPO_TST;                  // TST b+Rb,Ra, or
+               insn_form = ONE_OR_TWO_OP;              // TST Rx -> TST -1,Rx
+               insn_form = ONE_OR_TWO_OP;              // TST Rx -> TST -1,Rx
+       } else if (strcasecmp(opstr, "LW")==0) {
+       } else if (strcasecmp(opstr, "LW")==0) {
+               insn->i_op = ZIPO_LW;
+               insn->i_op = ZIPO_LW;
+               insn_form = TWO_OP;
+               insn_form = TWO_OP;
+       } else if (strcasecmp(opstr, "SW")==0) {
+       } else if (strcasecmp(opstr, "SW")==0) {
+               insn->i_op = ZIPO_SW;
+               insn->i_op = ZIPO_SW;
+               insn_form = BACKWARDS_TWO;
+               insn_form = BACKWARDS_TWO;
+       } else if (strcasecmp(opstr, "LH")==0) {
+       } else if (strcasecmp(opstr, "LH")==0) {
+               insn->i_op = ZIPO_LH;
+               insn->i_op = ZIPO_LH;
+               insn_form = TWO_OP;
+               insn_form = TWO_OP;
+       } else if (strcasecmp(opstr, "SH")==0) {
+       } else if (strcasecmp(opstr, "SH")==0) {
+               insn->i_op = ZIPO_SH;
+               insn->i_op = ZIPO_SH;
+               insn_form = BACKWARDS_TWO;
+               insn_form = BACKWARDS_TWO;
+       } else if (strcasecmp(opstr, "LB")==0) {
+       } else if (strcasecmp(opstr, "LB")==0) {
+               insn->i_op = ZIPO_LB;
+               insn->i_op = ZIPO_LB;
+               insn_form = TWO_OP;
+               insn_form = TWO_OP;
+       } else if (strcasecmp(opstr, "SB")==0) {
+       } else if (strcasecmp(opstr, "SB")==0) {
+               insn->i_op = ZIPO_SB;
+               insn->i_op = ZIPO_SB;
+               insn_form = BACKWARDS_TWO;
+               insn_form = BACKWARDS_TWO;
+       } else if (strcasecmp(opstr, "LDI")==0) {
+       } else if (strcasecmp(opstr, "LDI")==0) {
+               insn->i_op = ZIPO_LDI;
+               insn->i_op = ZIPO_LDI;
+               insn_form = IMM_OP;
+               insn_form = IMM_OP;
+       } else if (strcasecmp(opstr, "FPADD")==0) {
+       } else if (strcasecmp(opstr, "FPADD")==0) {
+               insn->i_op = ZIPO_FPADD;
+               insn->i_op = ZIPO_FPADD;
+               insn_form = TWO_REGISTER;
+               insn_form = TWO_REGISTER;
+       } else if (strcasecmp(opstr, "FPSUB")==0) {
+       } else if (strcasecmp(opstr, "FPSUB")==0) {
+               insn->i_op = ZIPO_FPSUB;
+               insn->i_op = ZIPO_FPSUB;
+               insn_form = TWO_REGISTER;
+               insn_form = TWO_REGISTER;
+       } else if (strcasecmp(opstr, "FPMUL")==0) {
+       } else if (strcasecmp(opstr, "FPMUL")==0) {
+               insn->i_op = ZIPO_FPMPY;
+               insn->i_op = ZIPO_FPMPY;
+               insn_form = TWO_REGISTER;
+               insn_form = TWO_REGISTER;
+       } else if (strcasecmp(opstr, "FPDIV")==0) {
+       } else if (strcasecmp(opstr, "FPDIV")==0) {
+               insn->i_op = ZIPO_FPDIV;
+               insn->i_op = ZIPO_FPDIV;
+               insn_form = TWO_REGISTER;
+               insn_form = TWO_REGISTER;
+       } else if (strcasecmp(opstr, "FPI2F")==0) {
+       } else if (strcasecmp(opstr, "FPI2F")==0) {
+               insn->i_op = ZIPO_FPI2F;
+               insn->i_op = ZIPO_FPI2F;
+               insn_form = TWO_OP;
+               insn_form = TWO_OP;
+       } else if (strcasecmp(opstr, "FPF2I")==0) {
+       } else if (strcasecmp(opstr, "FPF2I")==0) {
+               insn->i_op = ZIPO_FPF2I;
+               insn->i_op = ZIPO_FPF2I;
+               insn_form = TWO_REGISTER;
+               insn_form = TWO_REGISTER;
+       } else if ((strcasecmp(opstr, "BRK")==0)
+       } else if ((strcasecmp(opstr, "BRK")==0)
+               ||(strcasecmp(opstr, "BREAK")==0)) {
+               ||(strcasecmp(opstr, "BREAK")==0)) {
+               insn->i_op = ZIPO_BREAK;
+               insn->i_op = ZIPO_BREAK;
+               insn->i_imm= 0;
+               insn->i_imm= 0;
+               insn_form = MAYBE_ONE_IMM;
+               insn_form = MAYBE_ONE_IMM;
+       } else if (strcasecmp(opstr, "LOCK")==0) {
+       } else if (strcasecmp(opstr, "LOCK")==0) {
+               insn->i_op = ZIPO_LOCK;
+               insn->i_op = ZIPO_LOCK;
+               insn_form = NO_OP;
+               insn_form = NO_OP;
+       // Now for some derived instructions
+       // Now for some derived instructions
+       } else if (strcasecmp(opstr, "TRAP")==0) {
+       } else if (strcasecmp(opstr, "TRAP")==0) {
+               insn->i_op = ZIPO_TRAP;
+               insn->i_op = ZIPO_TRAP;
+               insn_form = MAYBE_OPB;
+               insn_form = MAYBE_OPB;
+       } else if (strcasecmp(opstr, "CLR")==0) {
+       } else if (strcasecmp(opstr, "CLR")==0) {
+               insn->i_op = ZIPO_CLR;
+               insn->i_op = ZIPO_CLR;
+               insn_form = ONE_REGISTER;
+               insn_form = ONE_REGISTER;
+       } else if (strcasecmp(opstr, "BRA")==0) {
+       } else if (strcasecmp(opstr, "BRA")==0) {
+               insn->i_op = ZIPO_BRA;
+               insn->i_op = ZIPO_BRA;
+               insn_form = OP_ADDRESS;
+               insn_form = OP_ADDRESS;
+       } else if (strcasecmp(opstr, "LJMP")==0) {
+       } else if (strcasecmp(opstr, "LJMP")==0) {
+               insn->i_op = ZIPO_LJMP;
+               insn->i_op = ZIPO_LJMP;
+               insn->i_breg = ZIP_RNONE;
+               insn->i_breg = ZIP_RNONE;
+               insn->i_imm  = 0;
+               insn->i_imm  = 0;
+               insn_form = OP_ADDRESS;
+               insn_form = OP_ADDRESS;
+       } else if (strcasecmp(opstr, "BZ")==0) {
+       } else if (strcasecmp(opstr, "BZ")==0) {
+               insn->i_op = ZIPO_BRA;
+               insn->i_op = ZIPO_BRA;
+               insn->i_cnd = ZIPC_Z;
+               insn->i_cnd = ZIPC_Z;
+               insn_form = OP_ADDRESS;
+               insn_form = OP_ADDRESS;
+       } else if (strcasecmp(opstr, "BLT")==0) {
+       } else if (strcasecmp(opstr, "BLT")==0) {
+               insn->i_op = ZIPO_BRA;
+               insn->i_op = ZIPO_BRA;
+               insn->i_cnd = ZIPC_LT;
+               insn->i_cnd = ZIPC_LT;
+               insn_form = OP_ADDRESS;
+               insn_form = OP_ADDRESS;
+       } else if (strcasecmp(opstr, "BC")==0) {
+       } else if (strcasecmp(opstr, "BC")==0) {
+               insn->i_op = ZIPO_BRA;
+               insn->i_op = ZIPO_BRA;
+               insn->i_cnd = ZIPC_C;
+               insn->i_cnd = ZIPC_C;
+               insn_form = OP_ADDRESS;
+               insn_form = OP_ADDRESS;
+       } else if (strcasecmp(opstr, "BV")==0) {
+       } else if (strcasecmp(opstr, "BV")==0) {
+               insn->i_op = ZIPO_BRA;
+               insn->i_op = ZIPO_BRA;
+               insn->i_cnd = ZIPC_V;
+               insn->i_cnd = ZIPC_V;
+               insn_form = OP_ADDRESS;
+               insn_form = OP_ADDRESS;
+       } else if (strcasecmp(opstr, "BNZ")==0) {
+       } else if (strcasecmp(opstr, "BNZ")==0) {
+               insn->i_op = ZIPO_BRA;
+               insn->i_op = ZIPO_BRA;
+               insn->i_cnd = ZIPC_NZ;
+               insn->i_cnd = ZIPC_NZ;
+               insn_form = OP_ADDRESS;
+               insn_form = OP_ADDRESS;
+       } else if (strcasecmp(opstr, "BGE")==0) {
+       } else if (strcasecmp(opstr, "BGE")==0) {
+               insn->i_op = ZIPO_BRA;
+               insn->i_op = ZIPO_BRA;
+               insn->i_cnd = ZIPC_GE;
+               insn->i_cnd = ZIPC_GE;
+               insn_form = OP_ADDRESS;
+               insn_form = OP_ADDRESS;
+       } else if (strcasecmp(opstr, "BNC")==0) {
+       } else if (strcasecmp(opstr, "BNC")==0) {
+               insn->i_op = ZIPO_BRA;
+               insn->i_op = ZIPO_BRA;
+               insn->i_cnd = ZIPC_NC;
+               insn->i_cnd = ZIPC_NC;
+               insn_form = OP_ADDRESS;
+               insn_form = OP_ADDRESS;
+       } else if (strcasecmp(opstr, "HALT")==0) {
+       } else if (strcasecmp(opstr, "HALT")==0) {
+               insn->i_op = ZIPO_HALT;
+               insn->i_op = ZIPO_HALT;
+               insn->i_imm = ZIP_CC_SLEEP;
+               insn->i_imm = ZIP_CC_SLEEP;
+               insn->i_areg= ZIP_CC;
+               insn->i_areg= ZIP_CC;
+               insn_form = NO_OP;
+               insn_form = NO_OP;
+       } else if (strcasecmp(opstr, "WAIT")==0) {
+       } else if (strcasecmp(opstr, "WAIT")==0) {
+               insn->i_op = ZIPO_WAIT;
+               insn->i_op = ZIPO_WAIT;
+               insn->i_imm = ZIP_CC_SLEEP | ZIP_CC_GIE;
+               insn->i_imm = ZIP_CC_SLEEP | ZIP_CC_GIE;
+               insn->i_areg= ZIP_CC;
+               insn->i_areg= ZIP_CC;
+               insn_form = NO_OP;
+               insn_form = NO_OP;
+       } else if (strcasecmp(opstr, "STEP")==0) {
+       } else if (strcasecmp(opstr, "STEP")==0) {
+               insn->i_op = ZIPO_STEP;
+               insn->i_op = ZIPO_STEP;
+               insn->i_imm = ZIP_CC_STEP | ZIP_CC_GIE;
+               insn->i_imm = ZIP_CC_STEP | ZIP_CC_GIE;
+               insn->i_areg= ZIP_CC;
+               insn->i_areg= ZIP_CC;
+               insn_form = NO_OP;
+               insn_form = NO_OP;
+       } else if ((strcasecmp(opstr, "RTU")==0)
+       } else if ((strcasecmp(opstr, "RTU")==0)
+                       ||(strcasecmp(opstr, "IRET")==0)) {
+                       ||(strcasecmp(opstr, "IRET")==0)) {
+               insn->i_op = ZIPO_RTU;
+               insn->i_op = ZIPO_RTU;
+               insn->i_imm = ZIP_CC_GIE;
+               insn->i_imm = ZIP_CC_GIE;
+               insn->i_areg = ZIP_CC;
+               insn->i_areg = ZIP_CC;
+               insn_form = NO_OP;
+               insn_form = NO_OP;
+       } else if (strcasecmp(opstr, "BUSY")==0) {
+       } else if (strcasecmp(opstr, "BUSY")==0) {
+               insn->i_op = ZIPO_BUSY;
+               insn->i_op = ZIPO_BUSY;
+               insn->i_imm= -4;
+               insn->i_imm= -4;
+               insn->i_areg = ZIP_PC;
+               insn->i_areg = ZIP_PC;
+               insn->i_breg = ZIP_RNONE;
+               insn->i_breg = ZIP_RNONE;
+               insn_form = NO_OP;
+               insn_form = NO_OP;
+       } else if (strcasecmp(opstr, "JMP")==0) {
+       } else if (strcasecmp(opstr, "JMP")==0) {
+               insn->i_op = ZIPO_JMP;
+               insn->i_op = ZIPO_JMP;
+               insn->i_areg = ZIP_PC;
+               insn->i_areg = ZIP_PC;
+               insn_form = OP_B;
+               insn_form = OP_B;
+       } else if ((strcasecmp(opstr, "RETN")==0)
+       } else if ((strcasecmp(opstr, "RETN")==0)
+                       ||(strcasecmp(opstr, "RTN")==0)) {
+                       ||(strcasecmp(opstr, "RTN")==0)) {
+               insn->i_op = ZIPO_JMP;
+               insn->i_op = ZIPO_JMP;
+               insn->i_areg = ZIP_PC;
+               insn->i_areg = ZIP_PC;
+               insn->i_breg = ZIP_LR;
+               insn->i_breg = ZIP_LR;
+               insn->i_imm  = 0;
+               insn->i_imm  = 0;
+               insn_form = NO_OP;
+               insn_form = NO_OP;
+       } else if (strcasecmp(opstr, "NOT")==0) {
+       } else if (strcasecmp(opstr, "NOT")==0) {
+               insn->i_op = ZIPO_NOT;
+               insn->i_op = ZIPO_NOT;
+               insn->i_imm = -1;
+               insn->i_imm = -1;
+               insn_form = ONE_REGISTER;
+               insn_form = ONE_REGISTER;
+       } else if (strcasecmp(opstr, "NEG")==0) {
+       } else if (strcasecmp(opstr, "NEG")==0) {
+               insn->i_op = ZIPO_NEG;
+               insn->i_op = ZIPO_NEG;
+               insn->i_imm = 0;
+               insn->i_imm = 0;
+               insn_form = ONE_OR_TWO_OP;
+               insn_form = ONE_OR_TWO_OP;
+       } else if (strcasecmp(opstr, "LJSR")==0) {
+       } else if (strcasecmp(opstr, "LJSR")==0) {
+               insn->i_op   = ZIPO_LJSR;
+               insn->i_op   = ZIPO_LJSR;
+               insn->i_breg = ZIP_RNONE;
+               insn->i_breg = ZIP_RNONE;
+               insn->i_imm  = 0;
+               insn->i_imm  = 0;
+               insn_form    = OP_ADDRESS;
+               insn_form    = OP_ADDRESS;
+       } else if (strcasecmp(opstr, "JSR")==0) {
+       } else if (strcasecmp(opstr, "JSR")==0) {
+               insn->i_op = ZIPO_JSR;
+               insn->i_op = ZIPO_JSR;
+               insn->i_imm = 0;
+               insn->i_imm = 0;
+               insn_form = OP_ADDRESS;
+               insn_form = OP_ADDRESS;
+       } else if ((strcasecmp(opstr, "NOP")==0)
+       } else if ((strcasecmp(opstr, "NOP")==0)
+                       ||(strcasecmp(opstr, "NOOP")==0)) {
+                       ||(strcasecmp(opstr, "NOOP")==0)) {
+               insn->i_op = ZIPO_NOOP;
+               insn->i_op = ZIPO_NOOP;
+               insn_form = MAYBE_ONE_IMM;
+               insn_form = MAYBE_ONE_IMM;
+       } else if (strcasecmp(opstr, "SIM")==0) {
+       } else if (strcasecmp(opstr, "SIM")==0) {
+               insn->i_op = ZIPO_SIM;
+               insn->i_op = ZIPO_SIM;
+               insn->i_imm= 0;
+               insn->i_imm= 0;
+               insn_form = MAYBE_ONE_IMM;
+               insn_form = MAYBE_ONE_IMM;
+       } else if (strcasecmp(opstr, "SNOOP")==0) {
+       } else if (strcasecmp(opstr, "SNOOP")==0) {
+               insn->i_op = ZIPO_SIM;
+               insn->i_op = ZIPO_SIM;
+               insn->i_imm= 0;
+               insn->i_imm= 0;
+               insn_form = MAYBE_ONE_IMM;
+               insn_form = MAYBE_ONE_IMM;
+       } else if (strcasecmp(opstr, "SDUMP")==0) {
+       } else if (strcasecmp(opstr, "SDUMP")==0) {
+               insn->i_op = ZIPO_SDUMP;
+               insn->i_op = ZIPO_SDUMP;
+               insn->i_imm= 0;
+               insn->i_imm= 0;
+               insn_form = MAYBE_ONE_REG;
+               insn_form = MAYBE_ONE_REG;
+       } else if (strcasecmp(opstr, "SEXIT")==0) {
+       } else if (strcasecmp(opstr, "SEXIT")==0) {
+               insn->i_op = ZIPO_SEXIT;
+               insn->i_op = ZIPO_SEXIT;
+               insn->i_imm= 0;
+               insn->i_imm= 0;
+               insn_form = MAYBE_ONE_IMM_OR_REG;
+               insn_form = MAYBE_ONE_IMM_OR_REG;
+       } else if (strcasecmp(opstr, "SOUT")==0) {
+       } else if (strcasecmp(opstr, "SOUT")==0) {
+               insn->i_op = ZIPO_SOUT;
+               insn->i_op = ZIPO_SOUT;
+               insn->i_imm= 0;
+               insn->i_imm= 0;
+               insn_form = MAYBE_ONE_IMM_OR_REG;
+               insn_form = MAYBE_ONE_IMM_OR_REG;
+       } else if (strcasecmp(opstr, "NDUMP")==0) {
+       } else if (strcasecmp(opstr, "NDUMP")==0) {
+               insn->i_op = ZIPO_NDUMP;
+               insn->i_op = ZIPO_NDUMP;
+               insn->i_imm= 0;
+               insn->i_imm= 0;
+               insn_form = MAYBE_ONE_REG;
+               insn_form = MAYBE_ONE_REG;
+       } else if (strcasecmp(opstr, "NEXIT")==0) {
+       } else if (strcasecmp(opstr, "NEXIT")==0) {
+               insn->i_op = ZIPO_NEXIT;
+               insn->i_op = ZIPO_NEXIT;
+               insn->i_imm= 0;
+               insn->i_imm= 0;
+               insn_form = MAYBE_ONE_IMM_OR_REG;
+               insn_form = MAYBE_ONE_IMM_OR_REG;
+       } else if (strcasecmp(opstr, "SEXTB")==0) {
+       } else if (strcasecmp(opstr, "SEXTB")==0) {
+               insn->i_op = ZIPO_SEXTB;
+               insn->i_op = ZIPO_SEXTB;
+               insn->i_imm= 0;
+               insn->i_imm= 0;
+               insn_form = ONE_REGISTER;
+               insn_form = ONE_REGISTER;
+       } else if (strcasecmp(opstr, "SEXTH")==0) {
+       } else if (strcasecmp(opstr, "SEXTH")==0) {
+               insn->i_op = ZIPO_SEXTH;
+               insn->i_op = ZIPO_SEXTH;
+               insn->i_imm= 0;
+               insn->i_imm= 0;
+               insn_form = ONE_REGISTER;
+               insn_form = ONE_REGISTER;
+       } else if (strcasecmp(opstr, "NOUT")==0) {
+       } else if (strcasecmp(opstr, "NOUT")==0) {
+               insn->i_op = ZIPO_NOUT;
+               insn->i_op = ZIPO_NOUT;
+               insn->i_imm= 0;
+               insn->i_imm= 0;
+               insn_form = MAYBE_ONE_IMM_OR_REG;
+               insn_form = MAYBE_ONE_IMM_OR_REG;
+       } else {
+       } else {
+               free(alt);
+               free(alt);
+               return "Unrecognized op-code";
+               return "Unrecognized op-code";
+       }
+       }
+
+
+       if (cndp) {
+       if (cndp) {
+               // We have a condition
+               // We have a condition
+               if (insn->i_cnd != ZIPC_ALWAYS) {
+               if (insn->i_cnd != ZIPC_ALWAYS) {
+                       err = "Instruction cannot take an additional condition";
+                       err = "Instruction cannot take an additional condition";
+               } else {
+               } else {
+                       err = zip_parse_condition(cndp, &insn->i_cnd);
+                       err = zip_parse_condition(cndp, &insn->i_cnd);
+               }
+               }
+       } if (err) {
+       } if (err) {
+               free(alt);
+               free(alt);
+               return err;
+               return err;
+       }
+       }
+
+
+       if (strchr(line, ',')!=NULL)
+       if (strchr(line, ',')!=NULL)
+               left = strtok(NULL, ",");
+               left = strtok(NULL, ",");
+       else
+       else
+               left  = strtok(NULL, " \t,");
+               left  = strtok(NULL, " \t,");
+       right = (left)  ? strtok(NULL, " \t") : NULL;
+       right = (left)  ? strtok(NULL, " \t") : NULL;
+       eol   = (right) ? strtok(NULL, " \t") : NULL;
+       eol   = (right) ? strtok(NULL, " \t") : NULL;
+       if (eol != NULL) {
+       if (eol != NULL) {
+               free(alt);
+               free(alt);
+               return "Too many tokens on one line";
+               return "Too many tokens on one line";
+       }
+       }
+
+
+       switch(insn_form) {
+       switch(insn_form) {
+               case TWO_OP:
+               case TWO_OP:
+                       err = zip_parse_bop(left,insn);
+                       err = zip_parse_bop(left,insn);
+                       if (!err)
+                       if (!err)
+                               err = zip_parse_reg(right,&insn->i_areg);
+                               err = zip_parse_reg(right,&insn->i_areg);
+                       break;
+                       break;
+               case IMM_OP:
+               case IMM_OP:
+                       err = zip_parse_bop(left,insn);
+                       err = zip_parse_bop(left,insn);
+                       if ((!err)&&(insn->i_breg == ZIP_RNONE))
+                       if ((!err)&&(insn->i_breg == ZIP_RNONE))
+                               err = zip_parse_reg(right,&insn->i_areg);
+                               err = zip_parse_reg(right,&insn->i_areg);
+                       else if (!err)
+                       else if (!err)
+                               err = "LDI can only load immediates, not registers";
+                               err = "LDI can only load immediates, not registers";
+                       break;
+                       break;
+               case BACKWARDS_TWO:
+               case BACKWARDS_TWO:
+                       err = zip_parse_reg(left,&insn->i_areg);
+                       err = zip_parse_reg(left,&insn->i_areg);
+                       if (!err)
+                       if (!err)
+                               err = zip_parse_bop(right,insn);
+                               err = zip_parse_bop(right,insn);
+                       break;
+                       break;
+               case MAYBE_ONE_IMM:
+               case MAYBE_ONE_IMM:
+                       if (NULL != right)
+                       if (NULL != right)
+                               err = "Wrong number of operands!";
+                               err = "Wrong number of operands!";
+                       else if (left) {
+                       else if (left) {
+                               err = zip_parse_bop(left,insn);
+                               err = zip_parse_bop(left,insn);
+                               if ((!err)&&(insn->i_breg != ZIP_RNONE))
+                               if ((!err)&&(insn->i_breg != ZIP_RNONE))
+                                       err = "BREAK arguments can only be immediates";
+                                       err = "BREAK arguments can only be immediates";
+                       }
+                       }
+                       break;
+                       break;
+               case MAYBE_ONE_IMM_OR_REG:
+               case MAYBE_ONE_IMM_OR_REG:
+                       if (NULL != right)
+                       if (NULL != right)
+                               err = "Wrong number of operands!";
+                               err = "Wrong number of operands!";
+                       else if (left) {
+                       else if (left) {
+                               err = zip_parse_bop(left,insn);
+                               err = zip_parse_bop(left,insn);
+                               if ((!err)&&(insn->i_breg != ZIP_RNONE)
+                               if ((!err)&&(insn->i_breg != ZIP_RNONE)
+                                       &&(insn->i_imm != 0))
+                                       &&(insn->i_imm != 0))
+                                       err = "EXIT arguments can only be immediates or register, not both";
+                                       err = "EXIT arguments can only be immediates or register, not both";
+                       }
+                       }
+                       break;
+                       break;
+               case MAYBE_ONE_REG:
+               case MAYBE_ONE_REG:
+                       if (NULL != right)
+                       if (NULL != right)
+                               err = "Wrong number of operands!";
+                               err = "Wrong number of operands!";
+                       else if (left) {
+                       else if (left) {
+                               err = zip_parse_bop(left,insn);
+                               err = zip_parse_bop(left,insn);
+                               if ((!err)&&(insn->i_breg != ZIP_RNONE)&&(insn->i_imm))
+                               if ((!err)&&(insn->i_breg != ZIP_RNONE)&&(insn->i_imm))
+                                       err = "xDUMP instructions can handle immediates or registers, not both";
+                                       err = "xDUMP instructions can handle immediates or registers, not both";
+                       } else {
+                       } else {
+                               insn->i_breg = ZIP_RNONE;
+                               insn->i_breg = ZIP_RNONE;
+                               insn->i_imm  = 0;
+                               insn->i_imm  = 0;
+                       } break;
+                       } break;
+               case NO_OP:
+               case NO_OP:
+                       if ((NULL != left)||(NULL != right))
+                       if ((NULL != left)||(NULL != right))
+                               err = "Wrong number of operands!";
+                               err = "Wrong number of operands!";
+                       break;
+                       break;
+               case ONE_OR_TWO_OP:
+               case ONE_OR_TWO_OP:
+                       // This is a reference to the test instruction, which
+                       // This is a reference to the test instruction, which
+                       // can either be
+                       // can either be
+                       //      A. TEST a,Rx, or TEST Rx,.
+                       //      A. TEST a,Rx, or TEST Rx,.
+                       // or   B. BRA  a,Rx, or BRA Rx,.
+                       // or   B. BRA  a,Rx, or BRA Rx,.
+                       if (NULL != right) {
+                       if (NULL != right) {
+                               err = zip_parse_bop(left,insn);
+                               err = zip_parse_bop(left,insn);
+                               if (!err)
+                               if (!err)
+                                       err = zip_parse_reg(right,&insn->i_areg);
+                                       err = zip_parse_reg(right,&insn->i_areg);
+                               if (!err)
+                               if (!err)
+                                       err = zip_parse_bop(left,insn);
+                                       err = zip_parse_bop(left,insn);
+                       } else {
+                       } else {
+                               zip_parse_reg(left, &insn->i_areg);
+                               zip_parse_reg(left, &insn->i_areg);
+                               if (insn->i_op == ZIPO_BREV) {
+                               if (insn->i_op == ZIPO_BREV) {
+                                       insn->i_breg = insn->i_areg;
+                                       insn->i_breg = insn->i_areg;
+                                       insn->i_imm = 0;
+                                       insn->i_imm = 0;
+                               } else {
+                               } else {
+                                       insn->i_breg = ZIP_RNONE;
+                                       insn->i_breg = ZIP_RNONE;
+                                       insn->i_imm = -1;
+                                       insn->i_imm = -1;
+                               }
+                               }
+                       } break;
+                       } break;
+               case ONE_REGISTER:
+               case ONE_REGISTER:
+                       // CLR, CLRF, or NOT
+                       // CLR, CLRF, or NOT
+                       insn->i_breg = ZIP_RNONE;
+                       insn->i_breg = ZIP_RNONE;
+                       if (NULL != right)
+                       if (NULL != right)
+                               err = "Instruction opcode expects only one operand";
+                               err = "Instruction opcode expects only one operand";
+                       else
+                       else
+                               err = zip_parse_reg(left,&insn->i_areg);
+                               err = zip_parse_reg(left,&insn->i_areg);
+                       break;
+                       break;
+               case OP_ADDRESS:
+               case OP_ADDRESS:
+                       // JSR or BRA instruction
+                       // JSR or BRA instruction
+                       //      This is different from OP_B below, in that this
+                       //      This is different from OP_B below, in that this
+                       //      form implies a PC relative addressing, which
+                       //      form implies a PC relative addressing, which
+                       //      may not be clear from the operands given
+                       //      may not be clear from the operands given
+                       if (NULL != right)
+                       if (NULL != right)
+                               err = "Instruction opcode expects only one operand";
+                               err = "Instruction opcode expects only one operand";
+                       else {
+                       else {
+                               if ((NULL == strchr(left,'('))
+                               if ((NULL == left)||(left[0] == '\0')) {
 
+                                       err = "No address given";
 
+                               } else if ((NULL == strchr(left,'('))
+                                       &&(NULL == strchr(left,'+'))) {
+                                       &&(NULL == strchr(left,'+'))) {
+                                       char    *longerstr = (char *)xmalloc(strlen(left)+6);
+                                       char    *longerstr = (char *)xmalloc(strlen(left)+6);
+                                       // If not stated, assume PC relative
+                                       // If not stated, assume PC relative
+                                       strcpy(longerstr,left);
+                                       strcpy(longerstr,left);
+                                       strcat(longerstr, "(PC)");
+                                       strcat(longerstr, "(PC)");
+                                       err = zip_parse_bop(longerstr, insn);
+                                       err = zip_parse_bop(longerstr, insn);
+                                       free(longerstr);
+                                       free(longerstr);
+                               } else
+                               } else
+                                       err = zip_parse_bop(left, insn);
+                                       err = zip_parse_bop(left, insn);
+                       }
+                       }
+
+
+                       break;
+                       break;
+               case MAYBE_OPB:
+               case MAYBE_OPB:
+                       // JMP or TRAP instruction
+                       // JMP or TRAP instruction
+                       if (NULL != right)
+                       if (NULL != right)
+                               err = "Instruction opcode expects only one operand";
+                               err = "Instruction opcode expects only one operand";
+                       else if (NULL == left) {
+                       else if (NULL == left) {
+                               insn->i_breg = ZIP_RNONE;
+                               insn->i_breg = ZIP_RNONE;
+                               insn->i_imm = 0;
+                               insn->i_imm = 0;
+                               break;
+                               break;
+                       } // Fall through
+                       } // Fall through
+               case OP_B: // Operand B only (A is implied)
+               case OP_B: // Operand B only (A is implied)
+                       // JMP or TRAP instruction
+                       // JMP or TRAP instruction
+                       if (NULL != right)
+                       if (NULL != right)
+                               err = "Instruction opcode expects only one operand";
+                               err = "Instruction opcode expects only one operand";
+                       else
+                       else
+                               err = zip_parse_bop(left, insn);
+                               err = zip_parse_bop(left, insn);
+                       if (insn->i_op == ZIPO_JMP)
+                       if (insn->i_op == ZIPO_JMP)
+                               insn->i_areg = ZIP_PC;
+                               insn->i_areg = ZIP_PC;
+                       else // if insn->i_op == TRAP
+                       else // if insn->i_op == TRAP
+                               insn->i_areg = ZIP_CC;
+                               insn->i_areg = ZIP_CC;
+                       break;
+                       break;
+               case TWO_REGISTER:
+               case TWO_REGISTER:
+                       // These are the floating point instructions, which
+                       // These are the floating point instructions, which
+                       // can't handle immediate offsets.
+                       // can't handle immediate offsets.
+                       err = zip_parse_reg(right, &insn->i_areg);
+                       err = zip_parse_reg(right, &insn->i_areg);
+                       if (!err)
+                       if (!err)
+                               err = zip_parse_reg(left, &insn->i_breg);
+                               err = zip_parse_reg(left, &insn->i_breg);
+                       break;
+                       break;
+               default:        // case ILLEGAL_FORM
+               default:        // case ILLEGAL_FORM
+                       err = "Unknown instruction format!";
+                       err = "Unknown instruction format!";
+                       break;
+                       break;
+       }
+       }
+
+
+       if (err)
+       if (err)
+               return (err);
+               return (err);
+
+
+       switch(insn->i_op) {
+       switch(insn->i_op) {
+               case ZIPO_SUB:  case ZIPO_AND: case ZIPO_ADD: case ZIPO_OR:
+               case ZIPO_SUB:  case ZIPO_AND: case ZIPO_ADD: case ZIPO_OR:
+               case ZIPO_XOR:  case ZIPO_LSR: case ZIPO_LSL: case ZIPO_ASR:
+               case ZIPO_XOR:  case ZIPO_LSR: case ZIPO_LSL: case ZIPO_ASR:
+               case ZIPO_BREV:
+               case ZIPO_BREV:
+               case ZIPO_MPYUHI: case ZIPO_MPYSHI:
+               case ZIPO_MPYUHI: case ZIPO_MPYSHI:
+               case ZIPO_MPY:
+               case ZIPO_MPY:
+                       break;
+                       break;
+               case ZIPO_LDILO:
+               case ZIPO_LDILO:
+                       if (!fits_within(16, insn->i_imm))
+                       if (!fits_within(16, insn->i_imm))
+                               gas_assert((insn->i_imm & (~0x0ffff))==0);
+                               gas_assert((insn->i_imm & (~0x0ffff))==0);
+                       insn->i_imm &= 0x0ffff;
+                       insn->i_imm &= 0x0ffff;
+                       break;
+                       break;
+               case ZIPO_DIVU: case ZIPO_DIVS:
+               case ZIPO_DIVU: case ZIPO_DIVS:
+                       if (0x0e == (insn->i_areg & 0x0f))
+                       if (0x0e == (insn->i_areg & 0x0f))
+                               err = "Divide instructions cannot result in CC or PC regs";
+                               err = "Divide instructions cannot result in CC or PC regs";
+                       else if (insn->i_rp)
+                       else if (insn->i_rp)
+                               err = "Relocations not applicable for divides";
+                               err = "Relocations not applicable for divides";
+                       break;
+                       break;
+                       break;
+                       break;
+               case ZIPO_MOV:
+               case ZIPO_MOV:
+                       if (insn->i_breg == ZIP_RNONE)
+                       if (insn->i_breg == ZIP_RNONE)
+                               insn->i_op = ZIPO_LDI;
+                               insn->i_op = ZIPO_LDI;
+                       break;
+                       break;
+               case ZIPO_CMP: case ZIPO_TST:
+               case ZIPO_CMP: case ZIPO_TST:
+                       break;
+                       break;
+               case ZIPO_LW: case ZIPO_SW:
+               case ZIPO_LW: case ZIPO_SW:
+               case ZIPO_LH: case ZIPO_SH:
+               case ZIPO_LH: case ZIPO_SH:
+               case ZIPO_LB: case ZIPO_SB:
+               case ZIPO_LB: case ZIPO_SB:
+                       break;
+                       break;
+               case ZIPO_LDI: case ZIPO_LDIn:
+               case ZIPO_LDI: case ZIPO_LDIn:
+                       break;
+                       break;
+               case ZIPO_FPADD: case ZIPO_FPSUB:
+               case ZIPO_FPADD: case ZIPO_FPSUB:
+               case ZIPO_FPMPY: case ZIPO_FPDIV:
+               case ZIPO_FPMPY: case ZIPO_FPDIV:
+               case ZIPO_FPF2I: case ZIPO_FPI2F:
+               case ZIPO_FPF2I: case ZIPO_FPI2F:
+                       if (0x0e == (insn->i_areg & 0x0f))
+                       if (0x0e == (insn->i_areg & 0x0f))
+                               err = "Floating point operations cannot result in CC or PC regs";
+                               err = "Floating point operations cannot result in CC or PC regs";
+                       else if (insn->i_rp)
+                       else if (insn->i_rp)
+                               err = "Relocations not applicable for floating point ops";
+                               err = "Relocations not applicable for floating point ops";
+                       break;
+                       break;
+               case ZIPO_TRAP:
+               case ZIPO_TRAP:
+                       insn->i_areg = ZIP_CC;
+                       insn->i_areg = ZIP_CC;
+                       if (insn->i_breg == ZIP_RNONE) {
+                       if (insn->i_breg == ZIP_RNONE) {
+                               if (insn->i_cnd == ZIPC_ALWAYS)
+                               if (insn->i_cnd == ZIPC_ALWAYS)
+                                       insn->i_op = ZIPO_LDI;
+                                       insn->i_op = ZIPO_LDI;
+                               else if (fits_within(16, insn->i_imm))
+                               else if (fits_within(16, insn->i_imm))
+                                       insn->i_op = ZIPO_LDILO;
+                                       insn->i_op = ZIPO_LDILO;
+                               else if (fits_within(18, zip_brev(insn->i_imm)))
+                               else if (fits_within(18, zip_brev(insn->i_imm)))
+                                       insn->i_op = ZIPO_BREV;
+                                       insn->i_op = ZIPO_BREV;
+                               else
+                               else
+                                       err = "TRAP immediate not supported";
+                                       err = "TRAP immediate not supported";
+                       } else
+                       } else
+                               insn->i_op = ZIPO_MOV;
+                               insn->i_op = ZIPO_MOV;
+                       break;
+                       break;
+               case ZIPO_CLR:
+               case ZIPO_CLR:
+                       insn->i_op = ZIPO_LDI;
+                       insn->i_op = ZIPO_LDI;
+                       insn->i_imm = 0;
+                       insn->i_imm = 0;
+                       break;
+                       break;
+               case ZIPO_JMP:
+               case ZIPO_JMP:
+                       if (insn->i_breg != ZIP_RNONE)
+                       if (insn->i_breg != ZIP_RNONE)
+                               insn->i_op = ZIPO_MOV;  // JMP A+Rx
+                               insn->i_op = ZIPO_MOV;  // JMP A+Rx
+                       else
+                       else
+                               insn->i_op = ZIPO_BRA;  // JMP lbl = BRA lbl
+                               insn->i_op = ZIPO_BRA;  // JMP lbl = BRA lbl
+                       // Fall through
+                       // Fall through
+               case ZIPO_BRA: // Leave as ZIPO_BRA until we assemble it
+               case ZIPO_BRA: // Leave as ZIPO_BRA until we assemble it
+                       insn->i_areg = ZIP_PC;
+                       insn->i_areg = ZIP_PC;
+                       break;
+                       break;
+               case ZIPO_HALT: case ZIPO_WAIT: case ZIPO_RTU: case ZIPO_STEP:
+               case ZIPO_HALT: case ZIPO_WAIT: case ZIPO_RTU: case ZIPO_STEP:
+                       insn->i_op = ZIPO_OR;
+                       insn->i_op = ZIPO_OR;
+                       break;
+                       break;
+               case ZIPO_BUSY:
+               case ZIPO_BUSY:
+                       insn->i_op = ZIPO_ADD;
+                       insn->i_op = ZIPO_ADD;
+                       break;
+                       break;
+               case ZIPO_NOT:
+               case ZIPO_NOT:
+                       insn->i_op = ZIPO_XOR;
+                       insn->i_op = ZIPO_XOR;
+                       insn->i_imm  = -1;
+                       insn->i_imm  = -1;
+                       insn->i_breg = ZIP_RNONE;
+                       insn->i_breg = ZIP_RNONE;
+                       break;
+                       break;
+               case ZIPO_NEG:
+               case ZIPO_NEG:
+                       if (insn->i_breg == ZIP_RNONE) {
+                       if (insn->i_breg == ZIP_RNONE) {
+                               insn->i_breg = insn->i_areg;
+                               insn->i_breg = insn->i_areg;
+                               // This would've been set to -1 by the ONE or
+                               // This would've been set to -1 by the ONE or
+                               // TWO op code.  Here, we set it back to zero.
+                               // TWO op code.  Here, we set it back to zero.
+                               insn->i_imm  = 0;
+                               insn->i_imm  = 0;
+                       }
+                       }
+                       // insn->i_op = ZIPO_NEG; /// Can't collapse this yet
+                       // insn->i_op = ZIPO_NEG; /// Can't collapse this yet
+                       break;
+                       break;
+               case ZIPO_BREAK:
+               case ZIPO_BREAK:
+                       insn->i_op = ZIPO_BREAK;
+                       insn->i_op = ZIPO_BREAK;
+                       insn->i_areg = ZIP_RNONE;
+                       insn->i_areg = ZIP_RNONE;
+                       insn->i_breg = ZIP_RNONE;
+                       insn->i_breg = ZIP_RNONE;
+                       // insn->i_imm  = ... whatever it was set to
+                       // insn->i_imm  = ... whatever it was set to
+                       break;
+                       break;
+               case ZIPO_LOCK:
+               case ZIPO_LOCK:
+                       insn->i_op = ZIPO_LOCK;
+                       insn->i_op = ZIPO_LOCK;
+                       insn->i_areg = ZIP_RNONE;
+                       insn->i_areg = ZIP_RNONE;
+                       insn->i_breg = ZIP_RNONE;
+                       insn->i_breg = ZIP_RNONE;
+                       insn->i_imm  = 0;
+                       insn->i_imm  = 0;
+                       break;
+                       break;
+               case ZIPO_SDUMP:
+               case ZIPO_SDUMP:
+                       insn->i_op = ZIPO_SIM;
+                       insn->i_op = ZIPO_SIM;
+                       if (insn->i_breg != ZIP_RNONE) {
+                       if (insn->i_breg != ZIP_RNONE) {
+                               insn->i_imm = (int)insn->i_breg + 0x0200;
+                               insn->i_imm = (int)insn->i_breg + 0x0200;
+                               insn->i_breg = ZIP_RNONE;
+                               insn->i_breg = ZIP_RNONE;
+                       } else
+                       } else
+                               insn->i_imm = 0x2ff;
+                               insn->i_imm = 0x2ff;
+                       break;
+                       break;
+               case ZIPO_NDUMP:
+               case ZIPO_NDUMP:
+                       insn->i_op = ZIPO_NOOP;
+                       insn->i_op = ZIPO_NOOP;
+                       if (insn->i_breg != ZIP_RNONE) {
+                       if (insn->i_breg != ZIP_RNONE) {
+                               insn->i_imm = (int)insn->i_breg + 0x0200;
+                               insn->i_imm = (int)insn->i_breg + 0x0200;
+                               insn->i_breg = ZIP_RNONE;
+                               insn->i_breg = ZIP_RNONE;
+                       } else
+                       } else
+                               insn->i_imm = 0x2ff;
+                               insn->i_imm = 0x2ff;
+                       break;
+                       break;
+               case ZIPO_SEXIT:
+               case ZIPO_SEXIT:
+                       insn->i_op = ZIPO_SIM;
+                       insn->i_op = ZIPO_SIM;
+                       if (insn->i_breg != ZIP_RNONE)
+                       if (insn->i_breg != ZIP_RNONE)
+                               insn->i_imm = 0x300 + (insn->i_breg & 0x01f);
+                               insn->i_imm = 0x300 + (insn->i_breg & 0x01f);
+                       else
+                       else
+                               insn->i_imm = 0x100 + (insn->i_imm & 0x0ff);
+                               insn->i_imm = 0x100 + (insn->i_imm & 0x0ff);
+                       insn->i_breg = ZIP_RNONE;
+                       insn->i_breg = ZIP_RNONE;
+                       break;
+                       break;
+               case ZIPO_NEXIT:
+               case ZIPO_NEXIT:
+                       insn->i_op = ZIPO_NOOP;
+                       insn->i_op = ZIPO_NOOP;
+                       if (insn->i_breg != ZIP_RNONE)
+                       if (insn->i_breg != ZIP_RNONE)
+                               insn->i_imm = 0x300 + (insn->i_breg & 0x01f);
+                               insn->i_imm = 0x300 + (insn->i_breg & 0x01f);
+                       else
+                       else
+                               insn->i_imm = 0x100 + (insn->i_imm & 0x0ff);
+                               insn->i_imm = 0x100 + (insn->i_imm & 0x0ff);
+                       insn->i_breg = ZIP_RNONE;
+                       insn->i_breg = ZIP_RNONE;
+                       break;
+                       break;
+               case ZIPO_SOUT:
+               case ZIPO_SOUT:
+                       insn->i_op = ZIPO_SIM;
+                       insn->i_op = ZIPO_SIM;
+                       if (insn->i_breg != ZIP_RNONE)
+                       if (insn->i_breg != ZIP_RNONE)
+                               insn->i_imm = 0x220 + (insn->i_breg & 0x01f);
+                               insn->i_imm = 0x220 + (insn->i_breg & 0x01f);
+                       else
+                       else
+                               insn->i_imm = 0x400 + (insn->i_imm & 0x0ff);
+                               insn->i_imm = 0x400 + (insn->i_imm & 0x0ff);
+                       insn->i_breg = ZIP_RNONE;
+                       insn->i_breg = ZIP_RNONE;
+                       break;
+                       break;
+               case ZIPO_NOUT:
+               case ZIPO_NOUT:
+                       insn->i_op = ZIPO_NOOP;
+                       insn->i_op = ZIPO_NOOP;
+                       if (insn->i_breg != ZIP_RNONE)
+                       if (insn->i_breg != ZIP_RNONE)
+                               insn->i_imm = 0x220 + (insn->i_breg & 0x01f);
+                               insn->i_imm = 0x220 + (insn->i_breg & 0x01f);
+                       else
+                       else
+                               insn->i_imm = 0x400 + (insn->i_imm & 0x0ff);
+                               insn->i_imm = 0x400 + (insn->i_imm & 0x0ff);
+                       insn->i_breg = ZIP_RNONE;
+                       insn->i_breg = ZIP_RNONE;
+                       break;
+                       break;
+               case ZIPO_SIM:
+               case ZIPO_SIM:
+               case ZIPO_NOOP:
+               case ZIPO_NOOP:
+                       break;
+                       break;
+               case ZIPO_LJMP: case ZIPO_LJSR:
+               case ZIPO_LJMP: case ZIPO_LJSR:
+                       if (insn->i_breg == ZIP_PC)
+                       if (insn->i_breg == ZIP_PC)
+                               insn->i_breg = ZIP_RNONE;
+                               insn->i_breg = ZIP_RNONE;
+                       if (insn->i_breg != ZIP_RNONE) {
+                       if (insn->i_breg != ZIP_RNONE) {
+                               err = "Indirect long jumps and long JSRs are not supported";
+                               err = "Indirect long jumps and long JSRs are not supported";
+                       } break;
+                       } break;
+               case ZIPO_JSR:
+               case ZIPO_JSR:
+                       break;
+                       break;
+               case ZIPO_SEXTB: case ZIPO_SEXTH:
+               case ZIPO_SEXTB: case ZIPO_SEXTH:
+                       break;
+                       break;
+               default:
+               default:
+                       return "Internal error -- unrecognized internal opcode";
+                       return "Internal error -- unrecognized internal opcode";
+                       break;
+                       break;
+       } if (err) {
+       } if (err) {
+               free(alt);
+               free(alt);
+               return err;
+               return err;
+       }
+       }
+
+
+       if ((insn->i_op != ZIPO_MOV)&&(
+       if ((insn->i_op != ZIPO_MOV)&&(
+                       ((insn->i_areg != ZIP_RNONE)&&(insn->i_areg >= 0x10))
+                       ((insn->i_areg != ZIP_RNONE)&&(insn->i_areg >= 0x10))
+                       ||((insn->i_breg != ZIP_RNONE)&&(insn->i_breg >= 0x10)))) {
+                       ||((insn->i_breg != ZIP_RNONE)&&(insn->i_breg >= 0x10)))) {
+               if (insn->i_rp)
+               if (insn->i_rp)
+                       free(insn->i_rp);
+                       free(insn->i_rp);
+               insn->i_rp = NULL;
+               insn->i_rp = NULL;
+               free(alt);
+               free(alt);
+               return "Only MOV instructions can reference explicit user registers";
+               return "Only MOV instructions can reference explicit user registers";
+       }
+       }
+
+
+       free(alt);
+       free(alt);
+
+
+       // We do nothing more to build the opcode here --- all we are doing
+       // We do nothing more to build the opcode here --- all we are doing
+       // is parsing.
+       // is parsing.
+       return err;
+       return err;
+}
+}
+
+
+#define        NOOPGROUP(OP,IMM) ((0x78000000)|((((OP)+0x1c-ZIPO_BREAK)&0x01f)<<22)|((IMM) & 0x003fffff))
+#define        NOOPGROUP(OP,IMM) ((0x78000000)|((((OP)+0x1c-ZIPO_BREAK)&0x01f)<<22)|((IMM) & 0x003fffff))
+#define        DBLREGOP(OP,CND,IMM,B,A) ((((OP)&0x01f)<<22)|(((A)&0x0f)<<27)   \
+#define        DBLREGOP(OP,CND,IMM,B,A) ((((OP)&0x01f)<<22)|(((A)&0x0f)<<27)   \
+                       | (((CND)&0x07)<<19)|(1<<18)|(((B)&0x0f)<<14)   \
+                       | (((CND)&0x07)<<19)|(1<<18)|(((B)&0x0f)<<14)   \
+                       | ((IMM) & 0x03fff))
+                       | ((IMM) & 0x03fff))
+#define        SMPLMOV(CND,IMM,B,A)    (((ZIPO_MOV&0x01f)<<22)|(((A)&0x0f)<<27)        \
+#define        SMPLMOV(CND,IMM,B,A)    (((ZIPO_MOV&0x01f)<<22)|(((A)&0x0f)<<27)        \
+                       | (((CND)&0x07)<<19)|(((B)&0x0f)<<14)|((IMM) & 0x01fff))
+                       | (((CND)&0x07)<<19)|(((B)&0x0f)<<14)|((IMM) & 0x01fff))
+#define        IMMOP(OP,CND,IMM,A)     ((((OP)&0x01f)<<22)|(((A)&0x0f)<<27)    \
+#define        IMMOP(OP,CND,IMM,A)     ((((OP)&0x01f)<<22)|(((A)&0x0f)<<27)    \
+                       | (((CND)&0x07)<<19)|((IMM) & 0x03ffff))
+                       | (((CND)&0x07)<<19)|((IMM) & 0x03ffff))
+#define        LDIOP(IMM,A)    ((ZIPO_LDI<<22)|(((A)&0x0f)<<27)|((IMM) & 0x07fffff))
+#define        LDIOP(IMM,A)    ((ZIPO_LDI<<22)|(((A)&0x0f)<<27)|((IMM) & 0x07fffff))
+
+
+
+
+/*
+/*
+ *     CIS support code
+ *     CIS support code
+ *
+ *
+ *     Assuming that the instruction (a) is not a CIS instruction, this looks
+ *     Assuming that the instruction (a) is not a CIS instruction, this looks
+ *     up the immediate value encoded in the instruction.  The purpose is to
+ *     up the immediate value encoded in the instruction.  The purpose is to
+ *     determine whether or not this instruction can be merged with the
+ *     determine whether or not this instruction can be merged with the
+ *     previous (or next) instruction in CIS mode.
+ *     previous (or next) instruction in CIS mode.
+ *
+ *
+ */
+ */
+static int
+static int
+zip_non_cis_immediate(const unsigned a)
+zip_non_cis_immediate(const unsigned a)
+{
+{
+       ZIP_OPCODE      op = (ZIP_OPCODE)((a>>22)&0x1f);
+       ZIP_OPCODE      op = (ZIP_OPCODE)((a>>22)&0x1f);
+       int             imm;
+       int             imm;
+
+
+       switch(op) {
+       switch(op) {
+               case    ZIPO_MOV:
+               case    ZIPO_MOV:
+                       imm = (a & 0x01fff); if (a&0x1000) imm |= -0x1000; break;
+                       imm = (a & 0x01fff); if (a&0x1000) imm |= -0x1000; break;
+               case    ZIPO_LDI:
+               case    ZIPO_LDI:
+                       imm = (a & 0x03fffff); break;
+                       imm = (a & 0x03fffff); break;
+               case    ZIPO_LDIn:
+               case    ZIPO_LDIn:
+                       imm = (a & 0x03fffff); imm |= -0x0200000; break;
+                       imm = (a & 0x03fffff); imm |= -0x0200000; break;
+/*
+/*
+ * While this makes conceptual sense, it doesn't match the CPU.  Hence let's
+ * While this makes conceptual sense, it doesn't match the CPU.  Hence let's
+ * comment it out and make certain things still work.
+ * comment it out and make certain things still work.
+               case    ZIPO_LDILO:
+               case    ZIPO_LDILO:
+#ifndef        LONG_MPY
+#ifndef        LONG_MPY
+               case ZIPO_LDIHI: // BREVx would rm LDIHI
+               case ZIPO_LDIHI: // BREVx would rm LDIHI
+#endif
+#endif
+                       imm = (a & 0x0ffff); break;
+                       imm = (a & 0x0ffff); break;
+*/
+*/
+               default:
+               default:
+                       if (a & 0x040000) {
+                       if (a & 0x040000) {
+                               imm = (a & 0x03fff);
+                               imm = (a & 0x03fff);
+                               if (a & 0x2000) imm |= -0x02000;
+                               if (a & 0x2000) imm |= -0x02000;
+                       } else {
+                       } else {
+                               imm = (a & 0x03ffff);
+                               imm = (a & 0x03ffff);
+                               if (a & 0x020000)
+                               if (a & 0x020000)
+                                       imm |= -0x020000;
+                                       imm |= -0x020000;
+                       }
+                       }
+       }
+       }
+
+
+       return imm;
+       return imm;
+}
+}
+
+
+static int
+static int
+zip_can_merge(const unsigned a, const unsigned b)
+zip_can_merge(const unsigned a, const unsigned b)
+{
+{
+       // Can't merge instructions if merging isnt turned on
+       // Can't merge instructions if merging isnt turned on
+       if (!zip_param_cis)
+       if (!zip_param_cis)
+               return 0;
+               return 0;
+
+
+       // 1. Can't merge anything that's already merged
+       // 1. Can't merge anything that's already merged
+       if ((a|b) & 0x80000000)
+       if ((a|b) & 0x80000000)
+               return 0;
+               return 0;
+       ZIP_OPCODE      opa, opb;
+       ZIP_OPCODE      opa, opb;
+       ZIP_CONDITION   ac, bc;
+       ZIP_CONDITION   ac, bc;
+       int     imma, immb;
+       int     imma, immb;
+
+
+       // Get the 5-bit operands for each
+       // Get the 5-bit operands for each
+       opa = (a>>22)&0x1f;
+       opa = (a>>22)&0x1f;
+       opb = (b>>22)&0x1f;
+       opb = (b>>22)&0x1f;
+
+
+       // 2. Can only merge if both are unconditional
+       // 2. Can only merge if both are unconditional
+       ac = ((a>>19)&0x07);
+       ac = ((a>>19)&0x07);
+       bc = ((b>>19)&0x07);
+       bc = ((b>>19)&0x07);
+       if ((opa != ZIPO_LDI)&&(opa != ZIPO_LDIn)&&(ac != ZIPC_ALWAYS))
+       if ((opa != ZIPO_LDI)&&(opa != ZIPO_LDIn)&&(ac != ZIPC_ALWAYS))
+               return 0;
+               return 0;
+       if ((opb != ZIPO_LDI)&&(opb != ZIPO_LDIn)&&(bc != ZIPC_ALWAYS))
+       if ((opb != ZIPO_LDI)&&(opb != ZIPO_LDIn)&&(bc != ZIPC_ALWAYS))
+               return 0;
+               return 0;
+
+
+       // Only some instructions can be merged
+       // Only some instructions can be merged
+       switch(opa) {
+       switch(opa) {
+               case ZIPO_SUB: case ZIPO_AND: case ZIPO_ADD: case ZIPO_CMP:
+               case ZIPO_SUB: case ZIPO_AND: case ZIPO_ADD: case ZIPO_CMP:
+               case ZIPO_LW:  case ZIPO_SW:  case ZIPO_LDI: case ZIPO_MOV:
+               case ZIPO_LW:  case ZIPO_SW:  case ZIPO_LDI: case ZIPO_MOV:
+               case ZIPO_LDIn:
+               case ZIPO_LDIn:
+                       break;
+                       break;
+               default:
+               default:
+                       return 0;
+                       return 0;
+       } switch(opb) {
+       } switch(opb) {
+               case ZIPO_SUB: case ZIPO_AND: case ZIPO_ADD: case ZIPO_CMP:
+               case ZIPO_SUB: case ZIPO_AND: case ZIPO_ADD: case ZIPO_CMP:
+               case ZIPO_LW:  case ZIPO_SW:  case ZIPO_LDI: case ZIPO_MOV:
+               case ZIPO_LW:  case ZIPO_SW:  case ZIPO_LDI: case ZIPO_MOV:
+               case ZIPO_LDIn:
+               case ZIPO_LDIn:
+                       break;
+                       break;
+               default:
+               default:
+                       return 0;
+                       return 0;
+       }
+       }
+
+
+       // Prohibit moves to/from user regs to merge
+       // Prohibit moves to/from user regs to merge
+       if ((opa == ZIPO_MOV)&&(a & 0x44000))
+       if ((opa == ZIPO_MOV)&&(a & 0x44000))
+               return 0;
+               return 0;
+       if ((opb == ZIPO_MOV)&&(b & 0x44000))
+       if ((opb == ZIPO_MOV)&&(b & 0x44000))
+               return 0;
+               return 0;
 
+
+       imma = zip_non_cis_immediate(a);
+       imma = zip_non_cis_immediate(a);
+       immb = zip_non_cis_immediate(b);
+       immb = zip_non_cis_immediate(b);
+
+
+       if (!fits_within(8,imma)) {
+       if (!fits_within(8,imma)) {
+               // fprintf(stderr, "As immediate is out of range\n");
+               // fprintf(stderr, "As immediate is out of range\n");
+               return 0;
+               return 0;
+       } if (!fits_within(8,immb)) {
+       } if (!fits_within(8,immb)) {
+               // fprintf(stderr, "Bs immediate is out of range\n");
+               // fprintf(stderr, "Bs immediate is out of range\n");
+               return 0;
+               return 0;
+       }
+       }
+
+
+       // if abreg & 0x010, or bbreg & 0x010, then the register is being
+       // if abreg & 0x010, or bbreg & 0x010, then the register is being
+       // used.
+       // used.
+       int aareg = (a>>27)&0x00f;
+       int aareg = (a>>27)&0x00f;
+       int abreg = (a>>14)&0x01f;
+       int abreg = (a>>14)&0x01f;
+       int bbreg = (b>>14)&0x01f;
+       int bbreg = (b>>14)&0x01f;
+
+
+       switch(opa) {
+       switch(opa) {
+               case ZIPO_MOV:
+               case ZIPO_MOV:
+                       if (!fits_within(3,imma))
+                       if (!fits_within(3,imma))
+                               return 0;
+                               return 0;
+                       if (aareg == ZIP_CC)
+                       // Prohibit a MOV x(PC),Ry to move into a first
 
+                       // instruction position.  While the CPU supports it,
 
+                       // making sure x remains valid isn't yet supported
 
+                       // here.
 
+                       if ((ZIP_PC == aareg)||(ZIP_CC == aareg))
+                               return 0;
+                               return 0;
+                       break;
+                       break;
+               case ZIPO_LDI: case ZIPO_LDIn:
+               case ZIPO_LDI: case ZIPO_LDIn:
+                       if (!fits_within(8,imma))
+                       if (!fits_within(8,imma))
+                               return 0;
+                               return 0;
+                       if (aareg == ZIP_CC)
+                       if (aareg == ZIP_CC)
+                               return 0;
+                               return 0;
+                       break;
+                       break;
+               case ZIPO_ADD: case ZIPO_SUB: case ZIPO_AND:
+               case ZIPO_ADD: case ZIPO_SUB: case ZIPO_AND:
+                       if (aareg == ZIP_CC)
+                       if (aareg == ZIP_CC)
+                               return 0;
+                               return 0;
+               case ZIPO_CMP:
+               case ZIPO_CMP:
+                       if ((abreg&0x10)==0) {
+                       if ((abreg&0x10)==0) {
+                               if (!fits_within(7,imma)) {
+                               if (!fits_within(7,imma)) {
+                                       return 0;
+                                       return 0;
+                               }
+                               }
+                       } else { // if (abreg&0x10)
+                       } else { // if (abreg&0x10)
+                               if (!fits_within(3,imma))
+                               if (!fits_within(3,imma))
+                                       return 0;
+                                       return 0;
+                       } break;
+                       } break;
+               case ZIPO_LW: case ZIPO_SW:
+               case ZIPO_LW: case ZIPO_SW:
+                       if (aareg == ZIP_CC)
+                       if (aareg == ZIP_CC)
+                               return 0;
+                               return 0;
+                       if ((abreg&0x010)==0) {
+                       if ((abreg&0x010)==0) {
+                               return 0;
+                               return 0;
+                       } else if (abreg== 0x10 + ZIP_SP) {
+                       } else if (abreg== 0x10 + ZIP_SP) {
+                               if (!fits_within(7,imma))
+                               if (!fits_within(7,imma))
+                                       return 0;
+                                       return 0;
+                       } else {
+                       } else {
+                               if (!fits_within(3,imma))
+                               if (!fits_within(3,imma))
+                                       return 0;
+                                       return 0;
+                       } break;
+                       } break;
+               default:
+               default:
+                       fprintf(stderr, "Unknown op, %d\n", opa);
+                       fprintf(stderr, "Unknown op, %d\n", opa);
+                       return 0;
+                       return 0;
+       }
+       }
+
+
+       switch(opb) {
+       switch(opb) {
+               case ZIPO_MOV:
+               case ZIPO_MOV:
+                       if (!fits_within(3,immb)) {
+                       if (!fits_within(3,immb)) {
+                               return 0;
+                               return 0;
+                       } break;
+                       } break;
+               case ZIPO_LDI: case ZIPO_LDIn:
+               case ZIPO_LDI: case ZIPO_LDIn:
+                       if (!fits_within(8,immb)) {
+                       if (!fits_within(8,immb)) {
+                               return 0;
+                               return 0;
+                       } break;
+                       } break;
+               case ZIPO_ADD: case ZIPO_SUB: case ZIPO_CMP: case ZIPO_AND:
+               case ZIPO_ADD: case ZIPO_SUB: case ZIPO_CMP: case ZIPO_AND:
+                       if ((bbreg&0x10)==0) {
+                       if ((bbreg&0x10)==0) {
+                               if (!fits_within(7,immb))
+                               if (!fits_within(7,immb))
+                                       return 0;
+                                       return 0;
+                       } else { // if (bbreg&0x10)
+                       } else { // if (bbreg&0x10)
+                               if (!fits_within(3,immb))
+                               if (!fits_within(3,immb))
+                                       return 0;
+                                       return 0;
+                       } break;
+                       } break;
+               case ZIPO_LW: case ZIPO_SW:
+               case ZIPO_LW: case ZIPO_SW:
+                       if ((bbreg&0x010)==0) {
+                       if ((bbreg&0x010)==0) {
+                               return 0;
+                               return 0;
+                       } else if (bbreg== 0x10+ZIP_SP) {
+                       } else if (bbreg== 0x10+ZIP_SP) {
+                               if (!fits_within(7,immb))
+                               if (!fits_within(7,immb))
+                                       return 0;
+                                       return 0;
+                       } else {
+                       } else {
+                               if (!fits_within(3,immb))
+                               if (!fits_within(3,immb))
+                                       return 0;
+                                       return 0;
+                       } break;
+                       } break;
+               default:
+               default:
+                       return 0;
+                       return 0;
+       }
+       }
+
+
+       return 1;
+       return 1;
+}
+}
+
+
+static unsigned
+static unsigned
+zip_insn_merge(const unsigned a, const unsigned b)
+zip_insn_merge(const unsigned a, const unsigned b)
+{
+{
+       // 1. We already know we can merge these, so skip our can-merge checks
+       // 1. We already know we can merge these, so skip our can-merge checks
+       ZIP_OPCODE      opa, opb;
+       ZIP_OPCODE      opa, opb;
+       unsigned int    retv = 0;
+       unsigned int    retv = 0;
+
+
+       // Get our two opcodes
+       // Get our two opcodes
+       opa = (a>>22)&0x1f; opb = (b>>22)&0x1f;
+       opa = (a>>22)&0x1f; opb = (b>>22)&0x1f;
+
+
+       // Truncate LDI opcodes back to their original values
+       // Truncate LDI opcodes back to their original values
+       if (opa == 0x019) opa = 0x018;
+       if (opa == 0x019) opa = 0x018;
+       if (opb == 0x019) opb = 0x018;
+       if (opb == 0x019) opb = 0x018;
+       retv = 0x80008000;
+       retv = 0x80008000;
+
+
+       // Start with the destination registers
+       // Start with the destination registers
+       retv |= (a & 0x78000000);
+       retv |= (a & 0x78000000);
+       retv |= (b & 0x78000000) >> (27-11);
+       retv |= (b & 0x78000000) >> (27-11);
+
+
+       // Then the new OpCodes
+       // Then the new OpCodes
+       switch(opa) {
+       switch(opa) {
+       case ZIPO_SUB:  retv |= (ZIPV_SUB<<24); break;
+       case ZIPO_SUB:  retv |= (ZIPV_SUB<<24); break;
+       case ZIPO_AND:  retv |= (ZIPV_AND<<24); break;
+       case ZIPO_AND:  retv |= (ZIPV_AND<<24); break;
+       case ZIPO_ADD:  retv |= (ZIPV_ADD<<24); break;
+       case ZIPO_ADD:  retv |= (ZIPV_ADD<<24); break;
+       case ZIPO_CMP:  retv |= (ZIPV_CMP<<24); break;
+       case ZIPO_CMP:  retv |= (ZIPV_CMP<<24); break;
+       case ZIPO_LW:   retv |= (ZIPV_LW <<24); break;
+       case ZIPO_LW:   retv |= (ZIPV_LW <<24); break;
+       case ZIPO_SW:   retv |= (ZIPV_SW <<24); break;
+       case ZIPO_SW:   retv |= (ZIPV_SW <<24); break;
+// 8e40
+// 8e40
+// 1.0001.110_0100_0000
+// 1.0001.110_0100_0000
+       case ZIPO_LDI:  retv |= (ZIPV_LDI<<24); break;
+       case ZIPO_LDI:  retv |= (ZIPV_LDI<<24); break;
+       case ZIPO_MOV:  retv |= (ZIPV_MOV<<24); break;
+       case ZIPO_MOV:  retv |= (ZIPV_MOV<<24); break;
+       default: gas_assert(0);
+       default: gas_assert(0);
+       }
+       }
+
+
+       switch(opb) {
+       switch(opb) {
+       case ZIPO_SUB:  retv |= (ZIPV_SUB<<8); break;
+       case ZIPO_SUB:  retv |= (ZIPV_SUB<<8); break;
+       case ZIPO_AND:  retv |= (ZIPV_AND<<8); break;
+       case ZIPO_AND:  retv |= (ZIPV_AND<<8); break;
+       case ZIPO_ADD:  retv |= (ZIPV_ADD<<8); break;
+       case ZIPO_ADD:  retv |= (ZIPV_ADD<<8); break;
+       case ZIPO_CMP:  retv |= (ZIPV_CMP<<8); break;
+       case ZIPO_CMP:  retv |= (ZIPV_CMP<<8); break;
+       case ZIPO_LW:   retv |= (ZIPV_LW <<8); break;
+       case ZIPO_LW:   retv |= (ZIPV_LW <<8); break;
+       case ZIPO_SW:   retv |= (ZIPV_SW <<8); break;
+       case ZIPO_SW:   retv |= (ZIPV_SW <<8); break;
+       case ZIPO_LDI:  retv |= (ZIPV_LDI<<8); break;
+       case ZIPO_LDI:  retv |= (ZIPV_LDI<<8); break;
+       case ZIPO_MOV:  retv |= (ZIPV_MOV<<8); break;
+       case ZIPO_MOV:  retv |= (ZIPV_MOV<<8); break;
+       default: gas_assert(0);
+       default: gas_assert(0);
+       }
+       }
+
+
+       // The new CIS has no condition codes
+       // The new CIS has no condition codes
+
+
+       // Now for OpB, instruction A
+       // Now for OpB, instruction A
+       if (opa == ZIPO_LDI)
+       if (opa == ZIPO_LDI)
+               retv |= (a & 0xff)<<16;
+               retv |= (a & 0xff)<<16;
+       else if (opa == ZIPO_MOV) {
+       else if (opa == ZIPO_MOV) {
+               retv |= 1<<23;                  // Using a register? always4mov
+               retv |= 1<<23;                  // Using a register? always4mov
+               retv |= ((a>>14)&0x0f)<<19;     // OpB register
+               retv |= ((a>>14)&0x0f)<<19;     // OpB register
+               retv |= (a & 0x7)<<16;          // Offset
+               retv |= (a & 0x7)<<16;          // Offset
+       } else if(((opa == ZIPO_LW)||(opa == ZIPO_SW))
+       } else if(((opa == ZIPO_LW)||(opa == ZIPO_SW))
+                       &&(((a>>14)&0x1f)==0x10 + ZIP_SP)) {
+                       &&(((a>>14)&0x1f)==0x10 + ZIP_SP)) {
+               // 7-bit immediate for loads or stores referencing the stack
+               // 7-bit immediate for loads or stores referencing the stack
+               retv |= (a & 0x07f)<<16;
+               retv |= (a & 0x07f)<<16;
+       } else if ((a>>18)&1) {
+       } else if ((a>>18)&1) {
+               // OpB ... with a register
+               // OpB ... with a register
+               retv |= 1<<23;                  // Using a register?
+               retv |= 1<<23;                  // Using a register?
+               retv |= ((a>>14)&0x0f)<<19;     // OpB register
+               retv |= ((a>>14)&0x0f)<<19;     // OpB register
+               retv |= (a&0x07)<<16;           // OpB constant
+               retv |= (a&0x07)<<16;           // OpB constant
+       } else {
+       } else {
+               // OpB ... with constant offsets only
+               // OpB ... with constant offsets only
+               retv |= (a&0x07f)<<16;
+               retv |= (a&0x07f)<<16;
+       }
+       }
+
+
+
+
+       // Now for OpB, instruction B
+       // Now for OpB, instruction B
+       if (opb == ZIPO_LDI)
+       if (opb == ZIPO_LDI)
+               retv |= (b & 0xff);
+               retv |= (b & 0xff);
+       else if (opb == ZIPO_MOV) {
+       else if (opb == ZIPO_MOV) {
+               retv |= (1<<7);                 // Using a register? always4mov
+               retv |= (1<<7);                 // Using a register? always4mov
+               retv |= ((b>>14)&0x0f)<<3;      // OpB register
+               retv |= ((b>>14)&0x0f)<<3;      // OpB register
+               retv |= (b & 0x7);              // Offset
+               retv |= (b & 0x7);              // Offset
+       } else if(((opb == ZIPO_LW)||(opb == ZIPO_SW))
+       } else if(((opb == ZIPO_LW)||(opb == ZIPO_SW))
+                       &&(((b>>14)&0x1f)==0x10 + ZIP_SP)) {
+                       &&(((b>>14)&0x1f)==0x10 + ZIP_SP)) {
+               retv |= (b & 0x07f);
+               retv |= (b & 0x07f);
+       } else if ((b>>18)&1) {
+       } else if ((b>>18)&1) {
+               // OpB ... with a register
+               // OpB ... with a register
+               retv |= 1<<7;                   // Using a register?
+               retv |= 1<<7;                   // Using a register?
+               retv |= ((b>>14)&0x0f)<<3;      // OpB register
+               retv |= ((b>>14)&0x0f)<<3;      // OpB register
+               retv |= (b&0x07);               // OpB constant
+               retv |= (b&0x07);               // OpB constant
+       } else {
+       } else {
+               // OpB ... with constant offsets only
+               // OpB ... with constant offsets only
+               retv |= (b&0x07f);
+               retv |= (b&0x07f);
+       }
+       }
+
+
+       return retv;
+       return retv;
+}
+}
+
+
+void
+void
+zip_check_label(symbolS *label ATTRIBUTE_UNUSED)
+zip_check_label(symbolS *label ATTRIBUTE_UNUSED)
+{
+{
+       // On any symbol, we need to make sure that we can jump to this
+       // On any symbol, we need to make sure that we can jump to this
+       // address, therefore we cannot merge the previous instruction with
+       // address, therefore we cannot merge the previous instruction with
+       // another one that might follow.
+       // another one that might follow.
+       cis_mergable = FALSE;
+       cis_mergable = FALSE;
+       //
+       //
+       // Likewise, our shadow virtual machine values may be ... unknown
+       // Likewise, our shadow virtual machine values may be ... unknown
+       // upon any jump to this location.  Hence, we declare them unknown
+       // upon any jump to this location.  Hence, we declare them unknown
+       // here.
+       // here.
+       zip_clear_machine(&zipm);
+       zip_clear_machine(&zipm);
+}
+}
+
+
+// UNITS:
+// UNITS:
+//     Offset  (target byte units)
+//     Offset  (target byte units)
+//     Address (host byte units)
+//     Address (host byte units)
+//     Sym     (target byte units)
+//     Sym     (target byte units)
+//     Stretch (target byte units)
+//     Stretch (target byte units)
+//
+//
+static void
+static void
+zip_assemble_insn_words(fragS *fragP, segT seg, ZIPIS *insn, int relax_state,
+zip_assemble_insn_words(fragS *fragP, segT seg, ZIPIS *insn, int relax_state,
+               long stretch, MACHINEREGS *pzipm)
+               long stretch, MACHINEREGS *pzipm)
+{
+{
+#ifdef ZIP_DEBUG
+#ifdef ZIP_DEBUG
+fprintf(stderr, "ZIP-ASSEMBLE-INSN-WORDS\n");
+fprintf(stderr, "ZIP-ASSEMBLE-INSN-WORDS\n");
+       zip_dump_insn(insn);
+       zip_dump_insn(insn);
+       if ((insn->i_rp)||(relax_state))
+       if ((insn->i_rp)||(relax_state))
+               zip_dump_sym(insn->i_rp->r_sym);
+               zip_dump_sym(insn->i_rp->r_sym);
+#endif
+#endif
+       unsigned long   symv = 0;
+       unsigned long   symv = 0;
+       int     sym_defined = 0, this_segment = 0, sym_known = 0;
+       int     sym_defined = 0, this_segment = 0, sym_known = 0;
+       symbolS *sym = NULL;
+       symbolS *sym = NULL;
+       unsigned        immv = insn->i_imm;
+       unsigned        immv = insn->i_imm;
+
+
+       if (insn->i_rp) {
+       if (insn->i_rp) {
+               fragS   *sym_frag;
+               fragS   *sym_frag;
+
+
+               sym = insn->i_rp->r_sym;
+               sym = insn->i_rp->r_sym;
+               symv = ((sym)&&(S_IS_DEFINED(sym))) ? (S_GET_VALUE(sym)) : 0;
+               symv = ((sym)&&(S_IS_DEFINED(sym))) ? (S_GET_VALUE(sym)) : 0;
+               sym_frag = symbol_get_frag(sym);
+               sym_frag = symbol_get_frag(sym);
+               this_segment = (S_GET_SEGMENT(sym) == seg);
+               this_segment = (S_GET_SEGMENT(sym) == seg);
+
+
+#ifdef ZIP_DEBUG
+#ifdef ZIP_DEBUG
+               fprintf(stderr, "SYMV(%s) = %08lx + %08lx -> %08lx\n",
+               fprintf(stderr, "SYMV(%s) = %08lx + %08lx -> %08lx\n",
+                       S_GET_NAME(sym),
+                       S_GET_NAME(sym),
+                       S_GET_VALUE(sym), fragP->fr_offset,
+                       S_GET_VALUE(sym), fragP->fr_offset,
+                       S_GET_VALUE(sym) + fragP->fr_offset);
+                       S_GET_VALUE(sym) + fragP->fr_offset);
+#endif
+#endif
+               symv += fragP->fr_offset;
+               symv += fragP->fr_offset;
+               // The immediate value has been included in the fragP->fr_offset
+               // The immediate value has been included in the fragP->fr_offset
+               // So, to keep us from applying it twice, we'll zero it here.
+               // So, to keep us from applying it twice, we'll zero it here.
+               immv = 0;
+               immv = 0;
+
+
+#ifdef ZIP_DEBUG
+#ifdef ZIP_DEBUG
+               { int this_frag = (sym_frag == fragP);
+               { int this_frag = (sym_frag == fragP);
+               fprintf(stderr, "Determined symbol is %sin this frag, and %sin this segment\n", (this_frag)?"":"not ", (this_segment)?"":"not ");
+               fprintf(stderr, "Determined symbol is %sin this frag, and %sin this segment\n", (this_frag)?"":"not ", (this_segment)?"":"not ");
+               }
+               }
+#endif
+#endif
+
+
+               if ((stretch != 0)
+               if ((stretch != 0)
+                       &&( sym_frag->relax_marker != fragP->relax_marker)
+                       &&( sym_frag->relax_marker != fragP->relax_marker)
+                       &&(this_segment)) {
+                       &&(this_segment)) {
+                       if ((stretch < 0)
+                       if ((stretch < 0)
+                               ||(sym_frag->region == fragP->region))
+                               ||(sym_frag->region == fragP->region))
+                               symv += stretch;
+                               symv += stretch;
+                       else if (symv < fragP->fr_address)
+                       else if (symv < fragP->fr_address)
+                               symv = fragP->fr_next->fr_address;
+                               symv = fragP->fr_next->fr_address;
+               }
+               }
+       }
+       }
+
+
+       // At this point, if the symbol is "defined" that only means that
+       // At this point, if the symbol is "defined" that only means that
+       // the address is known--not that we can know it via GET_VALUE above
+       // the address is known--not that we can know it via GET_VALUE above
+       // here.  There are a couple of possibilities: it could be a known
+       // here.  There are a couple of possibilities: it could be a known
+       // offset into a fragment, it could be a known offset into a segment,
+       // offset into a fragment, it could be a known offset into a segment,
+       // it could be a known memory address, or it could be a known value.
+       // it could be a known memory address, or it could be a known value.
+       //
+       //
+       // If the value is an offset into our current fragment, then we can
+       // If the value is an offset into our current fragment, then we can
+       // get at it via PC relative addressing.
+       // get at it via PC relative addressing.
+       //
+       //
+       // If the symbol is an offset into our current segment, often the
+       // If the symbol is an offset into our current segment, often the
+       // .text segment, we may also be able to get to it via PC relative
+       // .text segment, we may also be able to get to it via PC relative
+       // addressing.  However, we won't know until the fragment's are placed
+       // addressing.  However, we won't know until the fragment's are placed
+       // together to create this segment.  This will be before writing
+       // together to create this segment.  This will be before writing
+       // the file to disk.
+       // the file to disk.
+       //
+       //
+       // If the symbol is in the absolute segment, then we should try to
+       // If the symbol is in the absolute segment, then we should try to
+       // get to it via an absolute 32-bit offset reference--since we don't
+       // get to it via an absolute 32-bit offset reference--since we don't
+       // know (and won't know until the final link) where we are currently
+       // know (and won't know until the final link) where we are currently
+       // located within memory.
+       // located within memory.
+       //
+       //
+       // The same is true of the undefined segment--we just don't know any
+       // The same is true of the undefined segment--we just don't know any
+       // PC offsets to that segment.
+       // PC offsets to that segment.
+       //
+       //
+       // But if the address is to a GOT segment, we should be able to assume
+       // But if the address is to a GOT segment, we should be able to assume
+       // it's offset from the beginning of that segment.
+       // it's offset from the beginning of that segment.
+       //
+       //
+       //
+       //
+       if ((relax_state)&&(insn->i_rp))
+       if ((relax_state)&&(insn->i_rp))
+               sym_defined = S_IS_DEFINED(insn->i_rp->r_sym);
+               sym_defined = S_IS_DEFINED(insn->i_rp->r_sym);
+
+
+       /*
+       /*
+       sym_known = (sym_defined)&&
+       sym_known = (sym_defined)&&
+                       ((S_GET_SEGMENT(sym) == absolute_section)
+                       ((S_GET_SEGMENT(sym) == absolute_section)
+                       ||(S_GET_SEGMENT(sym) == expr_section)
+                       ||(S_GET_SEGMENT(sym) == expr_section)
+                       ||(this_frag)
+                       ||(this_frag)
+                       ||((this_segment)&&(fragP->fr_address != 0))
+                       ||((this_segment)&&(fragP->fr_address != 0))
+                       );
+                       );
+       */
+       */
+       sym_known = (sym_defined)&&(insn->i_rp->r_pcrel)&&(this_segment);
+       sym_known = (sym_defined)&&(insn->i_rp->r_pcrel)&&(this_segment);
+       if ((!sym_known)&&(sym_defined)&&(!S_FORCE_RELOC(sym, 0))) {
+       if ((!sym_known)&&(sym_defined)&&(!S_FORCE_RELOC(sym, 0))) {
+               if (this_segment)
+               if (this_segment)
+                       sym_known = 1;
+                       sym_known = 1;
+               else if (S_GET_SEGMENT(sym)==absolute_section)
+               else if (S_GET_SEGMENT(sym)==absolute_section)
+                       sym_known = 1;
+                       sym_known = 1;
+       }
+       }
+#ifdef ZIP_DEBUG
+#ifdef ZIP_DEBUG
+       if (sym_known)
+       if (sym_known)
+               fprintf(stderr, "%08lx@%08lx/%08lx - SYM(%s)-KNOWN %s%s%s%s%s\n",
+               fprintf(stderr, "%08lx@%08lx/%08lx - SYM(%s)-KNOWN %s%s%s%s%s\n",
+                       (unsigned long)fragP->fr_literal,
+                       (unsigned long)fragP->fr_literal,
+                       fragP->fr_address,
+                       fragP->fr_address,
+                       (unsigned long)symv, S_GET_NAME(sym),
+                       (unsigned long)symv, S_GET_NAME(sym),
+                       (S_GET_SEGMENT(sym) == absolute_section)?" abs":"",
+                       (S_GET_SEGMENT(sym) == absolute_section)?" abs":"",
+                       (S_GET_SEGMENT(sym) == expr_section)?" expr":"",
+                       (S_GET_SEGMENT(sym) == expr_section)?" expr":"",
+                       (symbol_get_frag(sym)==fragP)?" this-frag ":"",
+                       (symbol_get_frag(sym)==fragP)?" this-frag ":"",
+                       ((this_segment)&&(fragP->fr_address != 0))?" this-seg ":"",
+                       ((this_segment)&&(fragP->fr_address != 0))?" this-seg ":"",
+                       insn->i_rp->r_pcrel?" (PC-REL)":" (ABS)");
+                       insn->i_rp->r_pcrel?" (PC-REL)":" (ABS)");
+       else if (insn->i_rp)
+       else if (insn->i_rp)
+               fprintf(stderr, "%08lx@%08lx/%08lx - SYM(%s) -- not known (yet) %s%s%s%s%s%s\n",
+               fprintf(stderr, "%08lx@%08lx/%08lx - SYM(%s) -- not known (yet) %s%s%s%s%s%s\n",
+                       (unsigned long)fragP->fr_literal, fragP->fr_address,
+                       (unsigned long)fragP->fr_literal, fragP->fr_address,
+                       (unsigned long)symv, S_GET_NAME(sym),
+                       (unsigned long)symv, S_GET_NAME(sym),
+                       (!sym_defined)?"-- not defined":"",
+                       (!sym_defined)?"-- not defined":"",
+                       (S_GET_SEGMENT(sym) == absolute_section)?" abs":"",
+                       (S_GET_SEGMENT(sym) == absolute_section)?" abs":"",
+                       (S_GET_SEGMENT(sym) == expr_section)?" expr":"",
+                       (S_GET_SEGMENT(sym) == expr_section)?" expr":"",
+                       (symbol_get_frag(sym)==fragP)?" this-frag ":"",
+                       (symbol_get_frag(sym)==fragP)?" this-frag ":"",
+                       (this_segment)?" this-seg ":"",
+                       (this_segment)?" this-seg ":"",
+                       ((this_segment)&&(fragP->fr_address != 0))?" this-off ":""
+                       ((this_segment)&&(fragP->fr_address != 0))?" this-off ":""
+                       );
+                       );
+
+
+       fprintf(stderr, "SYM-DEF %d,%d,%d,%d, IMM = %08x\n",
+       fprintf(stderr, "SYM-DEF %d,%d,%d,%d, IMM = %08x\n",
+               sym_defined, sym_known,
+               sym_defined, sym_known,
+               (insn->i_rp)&&(symbol_get_frag(insn->i_rp->r_sym)==fragP)?1:0,
+               (insn->i_rp)&&(symbol_get_frag(insn->i_rp->r_sym)==fragP)?1:0,
+               this_segment, insn->i_imm);
+               this_segment, insn->i_imm);
+#endif
+#endif
+       switch(insn->i_op) {
+       switch(insn->i_op) {
+       case ZIPO_LDI: // May or may not be conditional
+       case ZIPO_LDI: // May or may not be conditional
+               if ((sym_known)&&(this_segment)
+               if ((sym_known)&&(this_segment)
+                       &&(fits_within(13,immv+symv-fragP->fr_address-insn->i_rp->r_fr_offset-sizeof(uint32_t)))) {
+                       &&(fits_within(15,immv+symv-fragP->fr_address-insn->i_rp->r_fr_offset-sizeof(uint32_t)))) {
+                       // Turn this into a MOV x(PC),Rx
+                       // Turn this into a MOV x(PC),Rx
 
+                       //
 
+                       // Although moves can normally only handle 13 bits,
 
+                       // when the immediate is an offset to the PC, the bottom
 
+                       // two bits are always zero, and so the immediate
 
+                       // gets an extra two free bits--hence the test for
 
+                       // fitting into 15 bits above.
+                       insn->i_breg = ZIP_PC;
+                       insn->i_breg = ZIP_PC;
+                       insn->i_op = ZIPO_MOV;
+                       insn->i_op = ZIPO_MOV;
+                       insn->i_naux = 0;
+                       insn->i_naux = 0;
+                       zip_assemble_insn_words(fragP, seg, insn, relax_state,
+                       zip_assemble_insn_words(fragP, seg, insn, relax_state,
+                               stretch, pzipm);
+                               stretch, pzipm);
+                       // Tested--this works
+                       // Tested--this works
+                       return;
+                       return;
+               }
+               }
+
+
+               // 0.111.x111.11
+               // 0.111.x111.11
+               insn->i_aux[0] = 0x7fc00000; // NOOP -- if never used.
+               insn->i_aux[0] = 0x7fc00000; // NOOP -- if never used.
+               immv += symv;
+               immv += symv;
+               if (((!insn->i_rp)||(sym_known))
+               if ((!insn->i_rp)&&(insn->i_cnd == ZIPC_ALWAYS)
+                               &&(insn->i_cnd == ZIPC_ALWAYS)
 
+                               &&(fits_within(23, immv))) {
+                               &&(fits_within(23, immv))) {
+                       insn->i_naux = 0;
+                       insn->i_naux = 0;
+                       insn->i_code = LDIOP(immv,insn->i_areg);
+                       insn->i_code = LDIOP(immv,insn->i_areg);
+               } else if (((!insn->i_rp)||(sym_known))
+               } else if (((!insn->i_rp)||(sym_known))
+                               &&(fits_within(18, zip_brev(immv)))) {
+                               &&(fits_within(18, zip_brev(immv)))) {
+                       // Can we do this with a BREV instruction using an
+                       // Can we do this with a BREV instruction using an
+                       // immediate?  If so, we can then conditionally load
+                       // immediate?  If so, we can then conditionally load
+                       // the top 18 bist of any value ...
+                       // the top 18 bist of any value ...
+                       //
+                       //
+                       insn->i_naux = 0;
+                       insn->i_naux = 0;
+                       insn->i_code = IMMOP(ZIPO_BREV, insn->i_cnd,
+                       insn->i_code = IMMOP(ZIPO_BREV, insn->i_cnd,
+                                       zip_brev(immv),
+                                       zip_brev(immv),
+                                       insn->i_areg&0x0f);
+                                       insn->i_areg&0x0f);
+                       if (insn->i_rp)
+                       if (insn->i_rp)
+                               insn->i_rp->r_type = BFD_RELOC_NONE;
+                               insn->i_rp->r_type = BFD_RELOC_NONE;
+// 0000 1110 0000 0000 0000 0000 0100 0000
+// 0000 1110 0000 0000 0000 0000 0100 0000
+               } else if (((!insn->i_rp)||(sym_known))
 
+                               &&(insn->i_cnd == ZIPC_ALWAYS)
 
+                               &&(fits_within(23, immv))) {
 
+                       insn->i_naux = 0;
 
+                       insn->i_code = LDIOP(immv,insn->i_areg);
 
+               } else if ((zip_param_use_machine)&&(pzipm)&&((!insn->i_rp)||(sym_known))
+               } else if ((zip_param_use_machine)&&(pzipm)&&((!insn->i_rp)||(sym_known))
+                       &&(pzipm->r[insn->i_areg].m_known)
+                       &&(pzipm->r[insn->i_areg].m_known)
+                       &&(0==((immv^pzipm->r[insn->i_areg].m_value)
+                       &&(0==((immv^pzipm->r[insn->i_areg].m_value)
+                                       & 0x0ffff0000))) {
+                                       & 0x0ffff0000))) {
+                       // Replace LDI with LDILO
+                       // Replace LDI with LDILO
+                       insn->i_naux = 0;
+                       insn->i_naux = 0;
+                       insn->i_code=IMMOP(ZIPO_LDILO, insn->i_cnd,
+                       insn->i_code=IMMOP(ZIPO_LDILO, insn->i_cnd,
+                                       (immv&0x0ffff), insn->i_areg);
+                                       (immv&0x0ffff), insn->i_areg);
+
+
+                       pzipm->r[insn->i_areg].m_value = immv;
+                       pzipm->r[insn->i_areg].m_value = immv;
+                       if (ZIPC_ALWAYS == insn->i_cnd) {
+                       if (ZIPC_ALWAYS == insn->i_cnd) {
+                               // Henceforth, we only know the bottom 16bits
+                               // Henceforth, we only know the bottom 16bits
+                               // of this register
+                               // of this register
+                               pzipm->r[insn->i_areg].m_known = MACH_VUPPERKNOWN;
+                               pzipm->r[insn->i_areg].m_known = MACH_VUPPERKNOWN;
+                       } else
+                       } else
+                               pzipm->r[insn->i_areg].m_known = MACH_VKNOWN;
+                               pzipm->r[insn->i_areg].m_known = MACH_VKNOWN;
+               } else {
+               } else {
+                       //
+                       //
+                       // If the symbol isn't defined, then any immv value
+                       // If the symbol isn't defined, then any immv value
+                       // will work--we have to come back anyway.
+                       // will work--we have to come back anyway.
+                       //
+                       //
+                       int known_bypass = 0, i;
+                       int known_bypass = 0, i;
+
+
+                       if ((zip_param_use_machine)&&(pzipm)&&(
+                       if ((zip_param_use_machine)&&(pzipm)&&(
+                                       ((!insn->i_rp)
+                                       ((!insn->i_rp)
+                                               &&(!fits_within(4,immv)))
+                                               &&(!fits_within(4,immv)))
+                                       ||((insn->i_rp)&&(sym_known)))) {
+                                       ||((insn->i_rp)&&(sym_known)))) {
+                               for(i=0; i<14; i++) {
+                               for(i=0; i<14; i++) {
+                                       int offset = immv-pzipm->r[i].m_value;
+                                       int offset = immv-pzipm->r[i].m_value;
+                                       if ((pzipm->r[i].m_known==MACH_VKNOWN)
+                                       if ((pzipm->r[i].m_known==MACH_VKNOWN)
+                                               &&(fits_within(13, offset))
+                                               &&(fits_within(13, offset))
+                                               &&((insn->i_rp)
+                                               &&((insn->i_rp)
+                                                       ||(!fits_within(4, immv)))
+                                                       ||(!fits_within(4, immv)))
+                                               ) {
+                                               ) {
+                                               // Pick the closest value ... if
+                                               // Pick the closest value ... if
+                                               // there's a choice
+                                               // there's a choice
+                                               if ((!known_bypass)
+                                               if ((!known_bypass)
+                                                       ||(abs(offset)<known_bypass))
+                                                       ||(abs(offset)<known_bypass))
+                                                       continue;
+                                                       continue;
+                                               insn->i_naux = 0;
+                                               insn->i_naux = 0;
+                                               insn->i_op = ZIPO_MOV;
+                                               insn->i_op = ZIPO_MOV;
+                                               insn->i_breg = i;
+                                               insn->i_breg = i;
+                                               insn->i_imm = offset;
+                                               insn->i_imm = offset;
+
+
+                                               insn->i_code = SMPLMOV(
+                                               insn->i_code = SMPLMOV(
+                                                       insn->i_cnd, offset,
+                                                       insn->i_cnd, offset,
+                                                       i, insn->i_areg);
+                                                       i, insn->i_areg);
+                                               known_bypass = abs(offset);
+                                               known_bypass = abs(offset);
+                                               if (known_bypass==0)
+                                               if (known_bypass==0)
+                                                       known_bypass = 1;
+                                                       known_bypass = 1;
+                                       }
+                                       }
+                               } known_bypass = (known_bypass)?1:0;
+                               } known_bypass = (known_bypass)?1:0;
+                       } if (!known_bypass) {
+                       } if (!known_bypass) {
+                               // BREV Extension would modify this statement
+                               // BREV Extension would modify this statement
+                               insn->i_naux = 1;
+                               insn->i_naux = 1;
+                               insn->i_code = IMMOP(ZIPO_BREV, insn->i_cnd,
+                               insn->i_code = IMMOP(ZIPO_BREV, insn-