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

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [sw/] [gas-zippatch.patch] - Rev 209

Compare with Previous | Blame | View Log

diff -Naur '--exclude=*.swp' binutils-2.27-original/bfd/archures.c binutils-2.27-zip/bfd/archures.c
--- binutils-2.27-original/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
@@ -525,6 +525,8 @@
 .#define bfd_mach_nios2r2	2
 .  bfd_arch_visium,	{* Visium *}
 .#define bfd_mach_visium	1
+.  bfd_arch_zip,	{* ZipCPU *}
+.#define bfd_mach_zip		0
 .  bfd_arch_last
 .  };
 */
@@ -655,6 +657,7 @@
 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_z8k_arch;
+extern const bfd_arch_info_type bfd_zip_arch;
 
 static const bfd_arch_info_type * const bfd_archures_list[] =
   {
@@ -744,6 +747,7 @@
     &bfd_xgate_arch,
     &bfd_z80_arch,
     &bfd_z8k_arch,
+    &bfd_zip_arch,
 #endif
   0
 };
diff -Naur '--exclude=*.swp' binutils-2.27-original/bfd/bfd-in2.h binutils-2.27-zip/bfd/bfd-in2.h
--- binutils-2.27-original/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
@@ -2336,6 +2336,8 @@
 #define bfd_mach_nios2r2       2
   bfd_arch_visium,     /* Visium */
 #define bfd_mach_visium        1
+  bfd_arch_zip,        /* ZipCPU */
+#define bfd_mach_zip           0
   bfd_arch_last
   };
 
@@ -6335,6 +6337,22 @@
   BFD_RELOC_VISIUM_HI16_PCREL,
   BFD_RELOC_VISIUM_LO16_PCREL,
   BFD_RELOC_VISIUM_IM16_PCREL,
+
+/* ZipCPU - 32 bit absolute value for LJMP instruction  */
+  BFD_RELOC_ZIP_VALUE,
+
+/* ZipCPU - 18-bit PC-relative offset for BRA (ADD #x,PC) instructions  */
+  BFD_RELOC_ZIP_BRANCH,
+
+/* ZipCPU value relocations  */
+  BFD_RELOC_ZIP_OPB_IMM,
+  BFD_RELOC_ZIP_OPB_OFFSET,
+  BFD_RELOC_ZIP_OPB_PCREL,
+  BFD_RELOC_ZIP_MOV_OFFSET,
+  BFD_RELOC_ZIP_MOV_PCREL,
+  BFD_RELOC_ZIP_LDI,
+  BFD_RELOC_ZIP_LLO,
+  BFD_RELOC_ZIP_BREV,
   BFD_RELOC_UNUSED };
 
 typedef enum bfd_reloc_code_real bfd_reloc_code_real_type;
diff -Naur '--exclude=*.swp' binutils-2.27-original/bfd/config.bfd binutils-2.27-zip/bfd/config.bfd
--- binutils-2.27-original/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
@@ -1742,6 +1742,10 @@
     targ_underscore=yes
     ;;
 
+  zip*)
+    targ_defvec=zip_elf32_vec
+    ;;
+
   *-*-ieee*)
     targ_defvec=ieee_vec
     ;;
diff -Naur '--exclude=*.swp' binutils-2.27-original/bfd/configure binutils-2.27-zip/bfd/configure
--- binutils-2.27-original/bfd/configure	2016-08-03 04:33:36.000000000 -0400
+++ binutils-2.27-zip/bfd/configure	2016-12-31 17:12:22.360697343 -0500
@@ -14542,6 +14542,7 @@
     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" ;;
     z8k_coff_vec)		 tb="$tb coff-z8k.lo reloc16.lo $coff" ;;
+    zip_elf32_vec)		 tb="$tb elf32-zip.lo elf32.lo $elf" ;;
 
     # These appear out of order in targets.c
     srec_vec)			 tb="$tb srec.lo" ;;
@@ -14924,6 +14925,9 @@
   x86_64-*-netbsd* | x86_64-*-openbsd*)
 	COREFILE=netbsd-core.lo
 	;;
+  zip*)
+	COREFILE=netbsd-core.lo
+	;;
   esac
 
   case "$COREFILE" in
diff -Naur '--exclude=*.swp' binutils-2.27-original/bfd/configure.ac binutils-2.27-zip/bfd/configure.ac
--- binutils-2.27-original/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
@@ -717,6 +717,7 @@
     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" ;;
     z8k_coff_vec)		 tb="$tb coff-z8k.lo reloc16.lo $coff" ;;
+    zip_elf32_vec)		 tb="$tb elf32-zip.lo elf32.lo $elf" ;;
 
     # These appear out of order in targets.c
     srec_vec)			 tb="$tb srec.lo" ;;
@@ -1092,6 +1093,9 @@
   x86_64-*-netbsd* | x86_64-*-openbsd*)
 	COREFILE=netbsd-core.lo
 	;;
+  zip*)
+	COREFILE=netbsd-core.lo
+	;;
   esac
 
   case "$COREFILE" in
diff -Naur '--exclude=*.swp' binutils-2.27-original/bfd/cpu-zip.c binutils-2.27-zip/bfd/cpu-zip.c
--- binutils-2.27-original/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
@@ -0,0 +1,65 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Filename: 	tc-zip.c
+//
+// Project:	Zip CPU backend for GNU Binutils
+//
+// Purpose:	BFD support for the Zip CPU architecture.
+//
+//		This file is part of BFD, the Binary File Descriptor library.
+//
+// Creator:	Dan Gisselquist, Ph.D.
+//		Gisselquist Technology, LLC
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2016-2017, Gisselquist Technology, LLC
+//
+// 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
+// by the Free Software Foundation, either version 3 of the License, or (at
+// your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program.  (It's in the $(ROOT)/doc directory, run make with no
+// target there if the PDF file isn't present.)  If not, see
+// <http://www.gnu.org/licenses/> for a copy.
+//
+// License:	GPL, v3, as defined and found on www.gnu.org,
+//		http://www.gnu.org/licenses/gpl.html
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type
+bfd_zip_arch =
+{
+  32,				// There's 32 bits_per_word.
+  32,				// There's 34 bits_per_address.
+  8,				// There's 32 bits_per_byte.
+  bfd_arch_zip,			// One of enum bfd_architecture, defined
+				// in archures.c and provided in
+				// generated header files.
+  bfd_mach_zip,			// Random BFD-internal number for this
+				// machine, similarly listed in
+				// archures.c.  Not emitted in output.
+  "zip",			// The arch_name.
+  "zip",			// The printable name is the same.
+  2,				// Section alignment power; each section
+				// is aligned to (only) 2^2 (i.e. 4) bytes.
+  TRUE,				// This is the default "machine".
+  bfd_default_compatible,	// Architecture comparison function
+  bfd_default_scan,		// String to architecture conversion
+  bfd_arch_default_fill,	// Default fill.
+  NULL				// Pointer to next bfd_arch_info_type in
+				// the same family. 
+};
+
diff -Naur '--exclude=*.swp' binutils-2.27-original/bfd/doc/archures.texi binutils-2.27-zip/bfd/doc/archures.texi
--- binutils-2.27-original/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
@@ -492,6 +492,8 @@
 #define bfd_mach_nios2r2       2
   bfd_arch_visium,     /* Visium */
 #define bfd_mach_visium        1
+  bfd_mach_zip,
+#define bfd_mach_zip           0
   bfd_arch_last
   @};
 @end example
diff -Naur '--exclude=*.swp' binutils-2.27-original/bfd/doc/bfd.info binutils-2.27-zip/bfd/doc/bfd.info
--- binutils-2.27-original/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
@@ -8466,6 +8466,8 @@
      #define bfd_mach_nios2r2       2
        bfd_arch_visium,     /* Visium */
      #define bfd_mach_visium        1
+       bfd_arch_zip,        /* ZipCPU */
+     #define bfd_mach_zip           0
        bfd_arch_last
        };
 
diff -Naur '--exclude=*.swp' binutils-2.27-original/bfd/doc/reloc.texi binutils-2.27-zip/bfd/doc/reloc.texi
--- binutils-2.27-original/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
@@ -4214,6 +4214,19 @@
 @deffnx {} BFD_RELOC_VISIUM_IM16_PCREL
 Visium Relocations.
 @end deffn
+@deffn {} BFD_RELOC_ZIP_VALUE
+@deffnx {} BFD_RELOC_OPB_IMM
+@deffnx {} BFD_RELOC_OPB_OFFSET
+@deffnx {} BFD_RELOC_OPB_PCREL
+@deffnx {} BFD_RELOC_OPB_GOTREL
+@deffnx {} BFD_RELOC_MOV_OFFSET
+@deffnx {} BFD_RELOC_MOV_PCREL
+@deffnx {} BFD_RELOC_MOV_GOTREL
+@deffnx {} BFD_RELOC_ZIP_LDI
+@deffnx {} BFD_RELOC_ZIP_LLO
+@deffnx {} BFD_RELOC_ZIP_LHI
+ZipCPU relocations
+@end deffn
 
 @example
 
diff -Naur '--exclude=*.swp' binutils-2.27-original/bfd/elf32-zip.c binutils-2.27-zip/bfd/elf32-zip.c
--- binutils-2.27-original/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
@@ -0,0 +1,1134 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Filename: 	tc-zip.c
+//
+// Project:	Zip CPU backend for GNU Binutils
+//
+// Purpose:	Zip-specific support for 32-bit ELF.
+//
+//	This file is part of BFD, the Binary File Descriptor library.
+//
+// Creator:	Dan Gisselquist, Ph.D.
+//		Gisselquist Technology, LLC
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2016, Gisselquist Technology, LLC
+//
+// 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
+// by the Free Software Foundation, either version 3 of the License, or (at
+// your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program.  (It's in the $(ROOT)/doc directory, run make with no
+// target there if the PDF file isn't present.)  If not, see
+// <http://www.gnu.org/licenses/> for a copy.
+//
+// License:	GPL, v3, as defined and found on www.gnu.org,
+//		http://www.gnu.org/licenses/gpl.html
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/zip.h"
+#include <limits.h>
+#include <stdint.h>
+
+#define	zip_relocation	bfd_elf_generic_reloc
+
+static bfd_reloc_status_type
+zip_brev_relocation(bfd *, arelent *, asymbol *, void *, asection *,
+		bfd *, char **error_messsage);
+static uint32_t zip_bitreverse(uint32_t v);
+
+/* Forward declarations.  */
+static reloc_howto_type zip_elf_howto_table [] =
+{
+  /* This reloc does nothing.  */
+  HOWTO (R_ZIP_NONE,		/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont, /* complain_on_overflow */
+	 zip_relocation,	/* special_function */
+	 "R_ZIP_NONE",		/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0,			/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  /* A 32 bit absolute relocation.  */
+  HOWTO (R_ZIP_VALUE,		/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont, /* complain_on_overflow */
+	 zip_relocation,	/* special_function */
+	 "R_ZIP_VALUE",		/* name */
+	 FALSE,			/* partial_inplace */
+	 0x00000000,		/* src_mask */
+	 0xffffffff,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  HOWTO (R_ZIP_BREV,		/* type -- LDIHI, but with bitreverse */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 16,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_bitfield, /* complain_on_overflow */
+	 zip_brev_relocation,	 /* special_function--needed for the bitreverse */
+	 "R_ZIP_BREV",		/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0x0003ffff,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  HOWTO (R_ZIP_LLO,		/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 23,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont, /* don't complain_on_overflow */
+	 zip_relocation,	 /* special_function */
+	 "R_ZIP_LLO",		/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0x0000ffff,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  HOWTO (R_ZIP_LDI,		/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 23,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_signed, /* complain_on_overflow */
+	 zip_relocation,	 /* special_function */
+	 "R_ZIP_LDI",		/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0x007fffff,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  /* An 18 bit pc-relative relocation.  */
+  HOWTO (R_ZIP_BRANCH,		/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 18,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_signed, /* complain_on_overflow */
+	 zip_relocation,	/* special_function */
+	 "R_ZIP_BRANCH",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0x00000000,		/* src_mask */
+	 0x0003fffc,		/* dst_mask */
+	 TRUE),		/* pcrel_offset */
+
+  /* An 18 bit operand B immediate.  */
+  HOWTO (R_ZIP_OPB_IMM,	/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 18,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_signed, /* complain_on_overflow */
+	 zip_relocation,	/* special_function */
+	 "R_ZIP_OPB_IMM",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0x00000000,		/* src_mask */
+	 0x0003ffff,		/* dst_mask */
+	 FALSE),			/* pcrel_offset */
+
+  /* An 18 bit relocation.  */
+  HOWTO (R_ZIP_OPB_OFFSET,	/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 14,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_signed, /* complain_on_overflow */
+	 zip_relocation,	/* special_function */
+	 "R_ZIP_OPB_OFFSET",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0x00000000,		/* src_mask */
+	 0x00003fff,		/* dst_mask-14 bits */
+	 FALSE),			/* pcrel_offset */
+
+  /* An 18 bit operand B immediate, but relative to the current PC.  */
+  HOWTO (R_ZIP_OPB_PCREL,	/* type */
+	 2,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 14,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_signed, /* complain_on_overflow */
+	 zip_relocation,	/* special_function */
+	 "R_ZIP_OPB_PCREL",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0x00000000,		/* src_mask */
+	 0x00003fff,		/* dst_mask-14 bits */
+	 TRUE),			/* pcrel_offset */
+
+  /* An 18 bit operand B immediate, but relative to the Global Offset Table. */
+  //HOWTO (R_ZIP_OPB_GOTREL,	/* type */
+	 //0,			/* rightshift */
+	 //2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 //18,			/* bitsize */
+	 //FALSE,			/* pc_relative */
+	 //0,			/* bitpos */
+	 //complain_overflow_signed, /* complain_on_overflow */
+	 //zip_relocation,	/* special_function */
+	 //"R_ZIP_OPB_GOTREL",	/* name */
+	 //FALSE,			/* partial_inplace */
+	 //0x00000000,		/* src_mask */
+	 //0x0003ffff,		/* dst_mask-14 bits */
+	 //FALSE),		/* pcrel_offset */
+
+  /* */
+  HOWTO (R_ZIP_MOV_OFFSET,	/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 13,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_signed, /* complain_on_overflow */
+	 zip_relocation,	 /* special_function */
+	 "R_ZIP_MOV_OFFSET",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0x00001fff,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  /* */
+  HOWTO (R_ZIP_MOV_PCREL,	/* type */
+	 2,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 13,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_signed, /* complain_on_overflow */
+	 zip_relocation,	 /* special_function */
+	 "R_ZIP_MOV_PCREL",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0x00001fff,		/* dst_mask */
+	 TRUE)			/* pcrel_offset */
+
+  /* */
+  //HOWTO (R_ZIP_MOV_GOTREL,	/* type */
+	 //0,			/* rightshift */
+	 //2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 //13,			/* bitsize */
+	 //FALSE,			/* pc_relative */
+	 //0,			/* bitpos */
+	 //complain_overflow_signed, /* complain_on_overflow */
+	 //zip_relocation,	 /* special_function */
+	 //"R_ZIP_MOV_GOTREL",	/* name */
+	 //FALSE,			/* partial_inplace */
+	 //0,			/* src_mask */
+	 //0x00001fff,		/* dst_mask */
+	 //FALSE),		/* pcrel_offset */
+
+};
+
+/* This structure is used to map BFD reloc codes to Zip ELF relocations */
+
+struct elf_reloc_map
+{
+  bfd_reloc_code_real_type bfd_reloc_val;
+  unsigned int elf_reloc_val;
+};
+
+static const struct elf_reloc_map zip_reloc_map [] =
+{
+  { BFD_RELOC_NONE,		R_ZIP_NONE },
+  { BFD_RELOC_ZIP_VALUE,	R_ZIP_VALUE },
+  { BFD_RELOC_ZIP_BRANCH,	R_ZIP_BRANCH },
+  { BFD_RELOC_ZIP_OPB_IMM,	R_ZIP_OPB_IMM },
+  { BFD_RELOC_ZIP_OPB_OFFSET,	R_ZIP_OPB_OFFSET },
+  { BFD_RELOC_ZIP_MOV_OFFSET,	R_ZIP_MOV_OFFSET },
+  { BFD_RELOC_ZIP_LDI,		R_ZIP_LDI },
+  { BFD_RELOC_ZIP_LLO,		R_ZIP_LLO },
+  { BFD_RELOC_ZIP_BREV,		R_ZIP_BREV },
+  { BFD_RELOC_14,		R_ZIP_OPB_OFFSET },
+  { BFD_RELOC_16,		R_ZIP_LLO },
+  { BFD_RELOC_32,		R_ZIP_VALUE },
+  { BFD_RELOC_ZIP_OPB_PCREL,	R_ZIP_OPB_PCREL },
+  { BFD_RELOC_ZIP_MOV_PCREL,	R_ZIP_MOV_PCREL }
+  // { BFD_RELOC_ZIP_OPB_GOTREL,	R_ZIP_OPB_GOTREL },
+  // { BFD_RELOC_ZIP_MOV_GOTREL,	R_ZIP_MOV_GOTREL },
+};
+
+/* Given a BFD reloc code, return the howto structure for the corresponding
+ * Zip ELF relocation. */
+static reloc_howto_type *
+zip_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+			bfd_reloc_code_real_type code)
+{
+  unsigned int i;
+
+  for (i = 0; i < sizeof (zip_reloc_map) / sizeof (zip_reloc_map[0]); i++)
+    if (zip_reloc_map [i].bfd_reloc_val == code)
+      return & zip_elf_howto_table [(int)zip_reloc_map[i].elf_reloc_val];
+
+  return NULL;
+}
+
+static reloc_howto_type *
+zip_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
+{
+  unsigned int i;
+
+  for (i = 0;
+       i < sizeof (zip_elf_howto_table) / sizeof (zip_elf_howto_table[0]);
+       i++)
+    if (zip_elf_howto_table[i].name != NULL
+	&& strcasecmp (zip_elf_howto_table[i].name, r_name) == 0)
+      return &zip_elf_howto_table[i];
+
+  return NULL;
+}
+
+/* Given an ELF reloc, fill in the howto field of a relent. */
+static void
+zip_elf_info_to_howto(bfd * abfd ATTRIBUTE_UNUSED,
+			 arelent * cache_ptr,
+			 Elf_Internal_Rela * dst)
+{
+	unsigned int r;
+
+	r = ELF32_R_TYPE(dst->r_info);
+  	BFD_ASSERT (r < (unsigned int) R_ZIP_max);
+  	cache_ptr->howto = &zip_elf_howto_table [r];
+}
+
+static bfd_boolean
+zip_elf_relocate_section(bfd *output_bfd,
+			struct bfd_link_info *info,
+			bfd *input_bfd,
+			asection *input_section,
+			bfd_byte *contents,
+			Elf_Internal_Rela *relocs,
+			Elf_Internal_Sym *local_syms,
+			asection **local_sections)
+{
+	Elf_Internal_Shdr		*symtab_hdr;
+	struct	elf_link_hash_entry	**sym_hashes;
+	Elf_Internal_Rela		*rel, *relend;
+
+	symtab_hdr = &elf_tdata(input_bfd)->symtab_hdr;
+	sym_hashes = elf_sym_hashes(input_bfd);
+	relend     = relocs+input_section->reloc_count;
+
+	for(rel=relocs; rel<relend; rel++) {
+		reloc_howto_type		*howto;
+		unsigned long			r_symndx;
+		Elf_Internal_Sym		*sym;
+		asection			*sec;
+		struct elf_link_hash_entry	*h;
+		bfd_vma				relocation;
+		bfd_reloc_status_type		r;
+		const char 			*name = NULL;
+		int				r_type;
+
+		r_type = ELF32_R_TYPE(rel->r_info);
+		r_symndx = ELF32_R_SYM(rel->r_info);
+
+		if ((r_type < 0) || (r_type >= (int)R_ZIP_max))
+		{
+			bfd_set_error(bfd_error_bad_value);
+			return FALSE;
+		}
+
+		howto = zip_elf_howto_table + ELF32_R_TYPE(rel->r_info);
+		h = NULL;
+		sym = NULL;
+		sec = NULL;
+
+		if (r_symndx < symtab_hdr->sh_info)
+		{
+			sym = local_syms + r_symndx;
+			sec = local_sections[r_symndx];
+			relocation = _bfd_elf_rela_local_sym(output_bfd, sym, &sec, rel);
+			name = bfd_elf_string_from_elf_section
+				(input_bfd, symtab_hdr->sh_link, sym->st_name);
+			name = (name == NULL) ? bfd_section_name(input_bfd, sec)
+					: name;
+		} else {
+			bfd_boolean unresolved_reloc, warned, ignored;
+
+			RELOC_FOR_GLOBAL_SYMBOL(info, input_bfd, input_section,
+				rel, r_symndx, symtab_hdr, sym_hashes, h, sec,
+				relocation, unresolved_reloc, warned, ignored);
+		}
+
+		if ((sec != NULL)&&(discarded_section(sec))) {
+			RELOC_AGAINST_DISCARDED_SECTION(info, input_bfd,
+				input_section, rel, 1, relend, howto, 0,
+				contents);
+		}
+
+		if (bfd_link_relocatable(info))
+			continue;
+
+		if (howto->type == R_ZIP_BREV) {
+			if (rel->r_offset > bfd_get_section_limit(input_bfd, input_section)) {
+				r = bfd_reloc_outofrange;
+			} else {
+				uint32_t	brev_reloc;
+				bfd_byte	*location;
+				bfd_vma		insn;
+
+				location = contents + rel->r_offset * bfd_octets_per_byte(input_bfd);
+
+				relocation += rel->r_addend;
+				brev_reloc= zip_bitreverse(relocation);
+				insn = bfd_get_32(input_bfd, location);
+				insn = ((insn & ~howto->dst_mask)
+				|(((insn & howto->src_mask)+brev_reloc)&howto->dst_mask));
+				bfd_put_32(input_bfd, insn, location);
+				r = bfd_reloc_ok;
+			}
+		} else {
+			r = _bfd_final_link_relocate(howto, input_bfd,
+				input_section,
+				contents, rel->r_offset,
+				relocation,
+				rel->r_addend);
+		}
+
+
+		if (r != bfd_reloc_ok)
+		{
+			const char *msg = NULL;
+
+			switch(r)
+			{
+				case bfd_reloc_overflow:
+					info->callbacks->reloc_overflow(
+						info, (h?&h->root:NULL),
+						name, howto->name, 
+						(bfd_vma)0, input_bfd,
+						input_section, rel->r_offset);
+					break;
+				case bfd_reloc_undefined:
+					info->callbacks->undefined_symbol(
+						info, name, input_bfd,
+						input_section, rel->r_offset,
+						TRUE);
+					break;
+				case bfd_reloc_outofrange:
+					msg = _("internal error: out of range error");
+					break;
+				case bfd_reloc_notsupported:
+					msg = _("internal error: unsupported relocation");
+					break;
+				case bfd_reloc_dangerous:
+					msg = _("internal error: dangerous relocation");
+					break;
+				default:
+					msg = _("internal error: unknown error");
+					break;
+			}
+
+			if (msg)
+				info->callbacks->warning(info, msg, name,
+					input_bfd, input_section,
+					rel->r_offset);
+
+			if (!r)
+				return FALSE;
+		}
+	}
+	return TRUE;
+}
+
+static uint32_t
+zip_bitreverse(uint32_t v) {
+	unsigned r = 0, b;
+
+	for(b=0; b<32; b++, v>>=1)
+		r = (r<<1)|(v&1);
+
+	return r;
+}
+
+static bfd_reloc_status_type
+zip_brev_relocation(bfd *abfd,
+		arelent *reloc_entry,
+		asymbol *symbol,
+		void *data,
+		asection *input_section,
+		bfd *output_bfd,
+		char **error_message)
+{
+	bfd_vma	relocation;
+	bfd_size_type octets = reloc_entry->address * bfd_octets_per_byte(abfd);
+	bfd_vma output_base = 0;
+	reloc_howto_type *howto = reloc_entry->howto;
+
+	// If this isn't a final relocation, then just use the generic
+	// relocation function.
+	if (output_bfd != NULL) {
+		return zip_relocation(abfd, reloc_entry, symbol, data,
+			input_section, output_bfd, error_message);
+	}
+
+	// Otherwise, we need to adjust our file itself with this value ...
+	// Check that our relocation lies within the file, and particularly
+	// the section we think it should.  (This should really be an assert...)
+	if (reloc_entry->address > bfd_get_section_limit(abfd, input_section))
+		return bfd_reloc_outofrange;
+
+	// Get symbol value
+	if (bfd_is_com_section(symbol->section))
+		relocation = 0;
+	else
+		relocation = symbol->value;
+
+	/* Convert input-section relative symbol value to absolute */
+	if ((!howto->partial_inplace)
+			||(symbol->section->output_section == NULL))
+		output_base = 0;
+	else
+		output_base = symbol->section->output_section->vma;
+
+	relocation += output_base + symbol->section->output_offset;
+
+	/* Add in supplied addend. */
+	relocation += reloc_entry->addend;
+
+	// BREV does not handle PC relative offsets
+
+	// Ignore overflow checking ... BREV handles the top 18 bits of a 32-bit
+	// number.  Overflow would mean overflowing the 32-bit address space--
+	// not possible.
+	//
+	// if howto->complain_on_overflow ...
+
+	// relocation >>= howto->rightshift;	// = 0
+	// relocation <<= howto->bitpos;	// = 0
+
+	// Logic (nearly) copied from reloc.c:bfd_perform_relocation
+	unsigned	insn = bfd_get_32(abfd, (bfd_byte *)data + octets);
+
+	// Here's why we are going through this pain!
+	insn = zip_bitreverse((unsigned)insn);
+
+	// Now we can continue as before....
+	insn = ((insn&(~howto->dst_mask))
+		|(((insn&howto->src_mask)+relocation)&howto->dst_mask));
+	bfd_put_32(abfd, (bfd_vma)insn, (bfd_byte *)data + octets);
+
+	return bfd_reloc_ok;
+}
+
+// Zip Defines
+#define	TARGET_BIG_SYM	zip_elf32_vec
+#define	TARGET_BIG_NAME	"elf32-zip"
+
+#define	ELF_ARCH	bfd_arch_zip
+// #define ELF_TARGET_ID		ZIP_ELF_DATA
+#define	ELF_MACHINE_CODE	EM_ZIP
+
+#define	ELF_MAXPAGESIZE		0x1000
+#define	ARCH_SIZE		32
+
+
+#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_name_lookup	zip_elf_reloc_name_lookup
+#define	elf_info_to_howto_rel	0
+#define	elf_info_to_howto	zip_elf_info_to_howto
+#define	elf_backend_relocate_section	zip_elf_relocate_section
+#define	elf_backend_rela_normal		1
+
+// Default ELF32 defines from elf32-target.h that we would've normally included
+// 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_bfd_free_cached_info _bfd_free_cached_info
+#define bfd_elf32_get_section_contents _bfd_generic_get_section_contents
+#define bfd_elf32_canonicalize_dynamic_symtab \
+  _bfd_elf_canonicalize_dynamic_symtab
+#define bfd_elf32_get_synthetic_symtab _bfd_elf_get_synthetic_symtab
+#define bfd_elf32_canonicalize_reloc	_bfd_elf_canonicalize_reloc
+#define bfd_elf32_find_nearest_line	_bfd_elf_find_nearest_line
+#define bfd_elf32_find_line		_bfd_elf_find_line
+#define bfd_elf32_find_inliner_info	_bfd_elf_find_inliner_info
+#define bfd_elf32_read_minisymbols	_bfd_elf_read_minisymbols
+#define bfd_elf32_minisymbol_to_symbol	_bfd_elf_minisymbol_to_symbol
+#define bfd_elf32_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_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_version_string	_bfd_elf_get_symbol_version_string
+#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_make_empty_symbol	_bfd_elf_make_empty_symbol
+#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_section_contents	_bfd_elf_set_section_contents
+#define bfd_elf32_sizeof_headers	_bfd_elf_sizeof_headers
+#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_get_section_contents_in_window \
+  _bfd_generic_get_section_contents_in_window
+
+#define elf_backend_can_refcount 0
+#define elf_backend_want_got_plt 0
+#define elf_backend_plt_readonly 0
+#define elf_backend_want_plt_sym 0
+#define elf_backend_plt_not_loaded 0
+#define elf_backend_plt_alignment 2
+#define elf_backend_want_dynbss 1
+#define elf_backend_want_p_paddr_set_to_zero 0
+#define elf_backend_default_execstack 1
+#define elf_backend_caches_rawsize 0
+#define elf_backend_extern_protected_data 0
+#define elf_backend_stack_align 4
+#define elf_backend_strtab_flags 0
+
+#define bfd_elf32_bfd_debug_info_start	bfd_void
+#define bfd_elf32_bfd_debug_info_end	bfd_void
+#define bfd_elf32_bfd_debug_info_accumulate \
+  ((void (*) (bfd*, struct bfd_section *)) bfd_void)
+
+#define bfd_elf32_bfd_get_relocated_section_contents \
+  bfd_generic_get_relocated_section_contents
+
+#define bfd_elf32_bfd_relax_section bfd_generic_relax_section
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 0
+#define elf_backend_want_got_sym 1
+#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_hook	_bfd_elf_gc_mark_hook
+#define elf_backend_gc_mark_extra_sections _bfd_elf_gc_mark_extra_sections
+#define elf_backend_gc_sweep_hook	NULL
+#define bfd_elf32_bfd_gc_sections bfd_elf_gc_sections
+
+#ifndef bfd_elf32_bfd_merge_sections
+#define bfd_elf32_bfd_merge_sections _bfd_elf_merge_sections
+#endif
+
+#ifndef bfd_elf32_bfd_is_group_section
+#define bfd_elf32_bfd_is_group_section bfd_elf_is_group_section
+#endif
+
+#ifndef bfd_elf32_bfd_discard_group
+#define bfd_elf32_bfd_discard_group bfd_generic_discard_group
+#endif
+
+#ifndef bfd_elf32_section_already_linked
+#define bfd_elf32_section_already_linked _bfd_elf_section_already_linked
+#endif
+
+#ifndef bfd_elf32_bfd_define_common_symbol
+#define bfd_elf32_bfd_define_common_symbol bfd_generic_define_common_symbol
+#endif
+
+#ifndef bfd_elf32_bfd_lookup_section_flags
+#define bfd_elf32_bfd_lookup_section_flags bfd_elf_lookup_section_flags
+#endif
+
+#ifndef bfd_elf32_bfd_make_debug_symbol
+#define bfd_elf32_bfd_make_debug_symbol \
+  ((asymbol * (*) (bfd *, void *, unsigned long)) bfd_nullvoidptr)
+#endif
+
+#ifndef bfd_elf32_bfd_copy_private_symbol_data
+#define bfd_elf32_bfd_copy_private_symbol_data _bfd_elf_copy_private_symbol_data
+#endif
+
+#ifndef bfd_elf32_bfd_copy_private_section_data
+#define bfd_elf32_bfd_copy_private_section_data \
+  _bfd_elf_copy_private_section_data
+#endif
+#ifndef bfd_elf32_bfd_copy_private_header_data
+#define bfd_elf32_bfd_copy_private_header_data \
+  _bfd_elf_copy_private_header_data
+#endif
+#ifndef bfd_elf32_bfd_copy_private_bfd_data
+#define bfd_elf32_bfd_copy_private_bfd_data \
+  _bfd_elf_copy_private_bfd_data
+#endif
+#ifndef bfd_elf32_bfd_print_private_bfd_data
+#define bfd_elf32_bfd_print_private_bfd_data \
+  _bfd_elf_print_private_bfd_data
+#endif
+#ifndef bfd_elf32_bfd_merge_private_bfd_data
+#define bfd_elf32_bfd_merge_private_bfd_data \
+  ((bfd_boolean (*) (bfd *, bfd *)) bfd_true)
+#endif
+#ifndef bfd_elf32_bfd_set_private_flags
+#define bfd_elf32_bfd_set_private_flags \
+  ((bfd_boolean (*) (bfd *, flagword)) bfd_true)
+#endif
+#ifndef bfd_elf32_bfd_is_local_label_name
+#define bfd_elf32_bfd_is_local_label_name _bfd_elf_is_local_label_name
+#endif
+#ifndef bfd_elf32_bfd_is_target_special_symbol
+#define bfd_elf32_bfd_is_target_special_symbol \
+  ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#endif
+
+#ifndef bfd_elf32_get_dynamic_reloc_upper_bound
+#define bfd_elf32_get_dynamic_reloc_upper_bound \
+  _bfd_elf_get_dynamic_reloc_upper_bound
+#endif
+#ifndef bfd_elf32_canonicalize_dynamic_reloc
+#define bfd_elf32_canonicalize_dynamic_reloc _bfd_elf_canonicalize_dynamic_reloc
+#endif
+
+#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_final_link	bfd_elf_final_link
+
+#define bfd_elf32_bfd_link_just_syms	_bfd_elf_link_just_syms
+
+#define bfd_elf32_bfd_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_check_relocs _bfd_generic_link_check_relocs
+#define bfd_elf32_archive_p bfd_generic_archive_p
+#define bfd_elf32_write_archive_contents _bfd_write_archive_contents
+#define bfd_elf32_mkobject bfd_elf_make_object
+#define bfd_elf32_mkcorefile bfd_elf_mkcorefile
+#define bfd_elf32_mkarchive _bfd_generic_mkarchive
+#define bfd_elf32_print_symbol bfd_elf_print_symbol
+#define elf_symbol_leading_char 0
+
+#define elf_backend_arch_data NULL
+
+#ifndef ELF_TARGET_ID
+#define ELF_TARGET_ID	GENERIC_ELF_DATA
+#endif
+
+#ifndef ELF_OSABI
+#define ELF_OSABI ELFOSABI_NONE
+#endif
+
+#define ELF_COMMONPAGESIZE ELF_MAXPAGESIZE
+#define ELF_MINPAGESIZE ELF_COMMONPAGESIZE
+
+#if ELF_COMMONPAGESIZE > ELF_MAXPAGESIZE
+# error ELF_COMMONPAGESIZE > ELF_MAXPAGESIZE
+#endif
+#if ELF_MINPAGESIZE > ELF_COMMONPAGESIZE
+# error ELF_MINPAGESIZE > ELF_COMMONPAGESIZE
+#endif
+
+#ifndef ELF_DYNAMIC_SEC_FLAGS
+/* Note that we set the SEC_IN_MEMORY flag for these sections.  */
+#define ELF_DYNAMIC_SEC_FLAGS			\
+  (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS	\
+   | SEC_IN_MEMORY | SEC_LINKER_CREATED)
+#endif
+
+#define elf_backend_collect FALSE
+#define elf_backend_type_change_ok FALSE
+
+#define elf_backend_sym_is_global	0
+#define elf_backend_object_p		0
+#define elf_backend_symbol_processing	0
+#define elf_backend_symbol_table_processing	0
+#define elf_backend_get_symbol_type 0
+#define elf_backend_archive_symbol_lookup _bfd_elf_archive_symbol_lookup
+#define elf_backend_name_local_section_symbols	0
+#define elf_backend_section_processing	0
+#define elf_backend_section_from_shdr	_bfd_elf_make_section_from_shdr
+#define elf_backend_section_flags	0
+#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_fake_sections	0
+#define elf_backend_section_from_bfd_section	0
+#define elf_backend_add_symbol_hook	0
+#define elf_backend_link_output_symbol_hook 0
+#define elf_backend_create_dynamic_sections 0
+#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_check_relocs	0
+#define elf_backend_check_directives	0
+#define elf_backend_notice_as_needed	_bfd_elf_notice_as_needed
+#define elf_backend_adjust_dynamic_symbol 0
+#define elf_backend_always_size_sections 0
+#define elf_backend_size_dynamic_sections 0
+#define elf_backend_init_index_section \
+ ((void (*) (bfd *, struct bfd_link_info *)) bfd_void)
+#define elf_backend_finish_dynamic_symbol	0
+#define elf_backend_finish_dynamic_sections	0
+#define elf_backend_begin_write_processing	0
+#define elf_backend_final_write_processing	0
+#define elf_backend_additional_program_headers	0
+#define elf_backend_modify_segment_map	0
+#ifndef elf_backend_modify_program_headers
+#define elf_backend_modify_program_headers	0
+#endif
+#ifndef elf_backend_ecoff_debug_swap
+#define elf_backend_ecoff_debug_swap	0
+#endif
+#ifndef elf_backend_bfd_from_remote_memory
+#define elf_backend_bfd_from_remote_memory _bfd_elf32_bfd_from_remote_memory
+#endif
+#ifndef elf_backend_got_header_size
+#define elf_backend_got_header_size	0
+#endif
+#ifndef elf_backend_got_elt_size
+#define elf_backend_got_elt_size _bfd_elf_default_got_elt_size
+#endif
+#ifndef elf_backend_obj_attrs_vendor
+#define elf_backend_obj_attrs_vendor		NULL
+#endif
+#ifndef elf_backend_obj_attrs_section
+#define elf_backend_obj_attrs_section		NULL
+#endif
+#ifndef elf_backend_obj_attrs_arg_type
+#define elf_backend_obj_attrs_arg_type		NULL
+#endif
+#ifndef elf_backend_obj_attrs_section_type
+#define elf_backend_obj_attrs_section_type		SHT_GNU_ATTRIBUTES
+#endif
+#ifndef elf_backend_obj_attrs_order
+#define elf_backend_obj_attrs_order		NULL
+#endif
+#define elf_backend_obj_attrs_handle_unknown	NULL
+#define elf_backend_static_tls_alignment	1
+#define elf_backend_post_process_headers	_bfd_elf_post_process_headers
+#define elf_backend_print_symbol_all		NULL
+#define elf_backend_output_arch_local_syms	NULL
+#define elf_backend_output_arch_syms		NULL
+#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_fixup_symbol		NULL
+#define elf_backend_merge_symbol_attribute	NULL
+#define elf_backend_get_target_dtag		NULL
+#define elf_backend_ignore_undef_symbol		NULL
+#define elf_backend_emit_relocs			_bfd_elf_link_output_relocs
+#define elf_backend_count_relocs		NULL
+#define elf_backend_count_additional_relocs	NULL
+#define elf_backend_sort_relocs_p		NULL
+#define elf_backend_grok_prstatus		NULL
+#define elf_backend_grok_psinfo			NULL
+#define elf_backend_write_core_note		NULL
+#define elf_backend_lookup_section_flags_hook	NULL
+#define elf_backend_reloc_type_class		_bfd_elf_reloc_type_class
+#define elf_backend_discard_info		NULL
+#define elf_backend_ignore_discarded_relocs	NULL
+#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_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_encode_eh_address		_bfd_elf_encode_eh_address
+#define elf_backend_write_section		NULL
+#define elf_backend_mips_irix_compat		NULL
+#define elf_backend_mips_rtype_to_howto		NULL
+
+/* Previously, backends could only use SHT_REL or SHT_RELA relocation
+   sections, but not both.  They defined USE_REL to indicate SHT_REL
+   sections, and left it undefined to indicated SHT_RELA sections.
+   For backwards compatibility, we still support this usage.  */
+#ifndef USE_REL
+#define USE_REL 0
+#endif
+
+/* Use these in new code.  */
+#define elf_backend_may_use_rel_p USE_REL
+#define elf_backend_may_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
+
+#ifndef elf_backend_rela_normal
+#define elf_backend_rela_normal 0
+#endif
+
+#define elf_backend_plt_sym_val NULL
+#define elf_backend_relplt_name NULL
+
+#define ELF_MACHINE_ALT1 0
+#define ELF_MACHINE_ALT2 0
+
+#ifndef elf_backend_size_info
+#define elf_backend_size_info _bfd_elf32_size_info
+#endif
+
+#define elf_backend_special_sections NULL
+#define elf_backend_sign_extend_vma 0
+#define elf_backend_link_order_error_handler _bfd_default_error_handler
+#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 _bfd_elf_common_section
+
+#define elf_backend_merge_symbol NULL
+#define elf_backend_hash_symbol _bfd_elf_hash_symbol
+#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_get_reloc_section _bfd_elf_get_reloc_section
+#define elf_backend_copy_special_section_fields NULL
+#define elf_backend_compact_eh_encoding NULL
+#define elf_backend_cant_unwind_opcode 0
+
+#define elf_match_priority \
+  (ELF_ARCH == bfd_arch_unknown ? 2 : ELF_OSABI == ELFOSABI_NONE ? 1 : 0)
+
+extern const struct elf_size_info _bfd_elf32_size_info;
+
+static struct elf_backend_data elf32_bed =
+{
+  ELF_ARCH,			/* arch */
+  ELF_TARGET_ID,		/* target_id */
+  ELF_MACHINE_CODE,		/* elf_machine_code */
+  ELF_OSABI,			/* elf_osabi  */
+  ELF_MAXPAGESIZE,		/* maxpagesize */
+  ELF_MINPAGESIZE,		/* minpagesize */
+  ELF_COMMONPAGESIZE,		/* commonpagesize */
+  ELF_DYNAMIC_SEC_FLAGS,	/* dynamic_sec_flags */
+  elf_backend_arch_data,
+  elf_info_to_howto,
+  elf_info_to_howto_rel,
+  elf_backend_sym_is_global,
+  elf_backend_object_p,
+  elf_backend_symbol_processing,
+  elf_backend_symbol_table_processing,
+  elf_backend_get_symbol_type,
+  elf_backend_archive_symbol_lookup,
+  elf_backend_name_local_section_symbols,
+  elf_backend_section_processing,
+  elf_backend_section_from_shdr,
+  elf_backend_section_flags,
+  elf_backend_get_sec_type_attr,
+  elf_backend_section_from_phdr,
+  elf_backend_fake_sections,
+  elf_backend_section_from_bfd_section,
+  elf_backend_add_symbol_hook,
+  elf_backend_link_output_symbol_hook,
+  elf_backend_create_dynamic_sections,
+  elf_backend_omit_section_dynsym,
+  elf_backend_relocs_compatible,
+  elf_backend_check_relocs,
+  elf_backend_check_directives,
+  elf_backend_notice_as_needed,
+  elf_backend_adjust_dynamic_symbol,
+  elf_backend_always_size_sections,
+  elf_backend_size_dynamic_sections,
+  elf_backend_init_index_section,
+  elf_backend_relocate_section,
+  elf_backend_finish_dynamic_symbol,
+  elf_backend_finish_dynamic_sections,
+  elf_backend_begin_write_processing,
+  elf_backend_final_write_processing,
+  elf_backend_additional_program_headers,
+  elf_backend_modify_segment_map,
+  elf_backend_modify_program_headers,
+  elf_backend_gc_keep,
+  elf_backend_gc_mark_dynamic_ref,
+  elf_backend_gc_mark_hook,
+  elf_backend_gc_mark_extra_sections,
+  elf_backend_gc_sweep_hook,
+  elf_backend_post_process_headers,
+  elf_backend_print_symbol_all,
+  elf_backend_output_arch_local_syms,
+  elf_backend_output_arch_syms,
+  elf_backend_copy_indirect_symbol,
+  elf_backend_hide_symbol,
+  elf_backend_fixup_symbol,
+  elf_backend_merge_symbol_attribute,
+  elf_backend_get_target_dtag,
+  elf_backend_ignore_undef_symbol,
+  elf_backend_emit_relocs,
+  elf_backend_count_relocs,
+  elf_backend_count_additional_relocs,
+  elf_backend_sort_relocs_p,
+  elf_backend_grok_prstatus,
+  elf_backend_grok_psinfo,
+  elf_backend_write_core_note,
+  elf_backend_lookup_section_flags_hook,
+  elf_backend_reloc_type_class,
+  elf_backend_discard_info,
+  elf_backend_ignore_discarded_relocs,
+  elf_backend_action_discarded,
+  elf_backend_eh_frame_address_size,
+  elf_backend_can_make_relative_eh_frame,
+  elf_backend_can_make_lsda_relative_eh_frame,
+  elf_backend_encode_eh_address,
+  elf_backend_write_section,
+  elf_backend_mips_irix_compat,
+  elf_backend_mips_rtype_to_howto,
+  elf_backend_ecoff_debug_swap,
+  elf_backend_bfd_from_remote_memory,
+  elf_backend_plt_sym_val,
+  elf_backend_common_definition,
+  elf_backend_common_section_index,
+  elf_backend_common_section,
+  elf_backend_merge_symbol,
+  elf_backend_hash_symbol,
+  elf_backend_is_function_type,
+  elf_backend_maybe_function_sym,
+  elf_backend_get_reloc_section,
+  elf_backend_copy_special_section_fields,
+  elf_backend_link_order_error_handler,
+  elf_backend_relplt_name,
+  ELF_MACHINE_ALT1,
+  ELF_MACHINE_ALT2,
+  &elf_backend_size_info,
+  elf_backend_special_sections,
+  elf_backend_got_header_size,
+  elf_backend_got_elt_size,
+  elf_backend_obj_attrs_vendor,
+  elf_backend_obj_attrs_section,
+  elf_backend_obj_attrs_arg_type,
+  elf_backend_obj_attrs_section_type,
+  elf_backend_obj_attrs_order,
+  elf_backend_obj_attrs_handle_unknown,
+  elf_backend_compact_eh_encoding,
+  elf_backend_cant_unwind_opcode,
+  elf_backend_static_tls_alignment,
+  elf_backend_stack_align,
+  elf_backend_strtab_flags,
+  elf_backend_collect,
+  elf_backend_type_change_ok,
+  elf_backend_may_use_rel_p,
+  elf_backend_may_use_rela_p,
+  elf_backend_default_use_rela_p,
+  elf_backend_rela_plts_and_copies_p,
+  elf_backend_rela_normal,
+  elf_backend_sign_extend_vma,
+  elf_backend_want_got_plt,
+  elf_backend_plt_readonly,
+  elf_backend_want_plt_sym,
+  elf_backend_plt_not_loaded,
+  elf_backend_plt_alignment,
+  elf_backend_can_gc_sections,
+  elf_backend_can_refcount,
+  elf_backend_want_got_sym,
+  elf_backend_want_dynbss,
+  elf_backend_want_p_paddr_set_to_zero,
+  elf_backend_default_execstack,
+  elf_backend_caches_rawsize,
+  elf_backend_extern_protected_data
+};
+
+/* Forward declaration for use when initialising alternative_target field.  */
+
+#ifdef TARGET_BIG_SYM
+const bfd_target TARGET_BIG_SYM =
+{
+  /* name: identify kind of target */
+  TARGET_BIG_NAME,
+
+  /* flavour: general indication about file */
+  bfd_target_elf_flavour,
+
+  /* byteorder: data is big endian */
+  BFD_ENDIAN_BIG,
+
+  /* header_byteorder: header is also big endian */
+  BFD_ENDIAN_BIG,
+
+  /* object_flags: mask of all file flags */
+  (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS
+   | DYNAMIC | WP_TEXT | D_PAGED | BFD_COMPRESS | BFD_DECOMPRESS
+   | BFD_COMPRESS_GABI | BFD_CONVERT_ELF_COMMON | BFD_USE_ELF_STT_COMMON),
+
+  /* section_flags: mask of all section flags */
+  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY
+   | SEC_CODE | SEC_DATA | SEC_DEBUGGING | SEC_EXCLUDE | SEC_SORT_ENTRIES
+   | SEC_SMALL_DATA | SEC_MERGE | SEC_STRINGS | SEC_GROUP),
+
+   /* leading_symbol_char: is the first char of a user symbol
+      predictable, and if so what is it */
+  elf_symbol_leading_char,
+
+  /* ar_pad_char: pad character for filenames within an archive header
+     FIXME:  this really has nothing to do with ELF, this is a characteristic
+     of the archiver and/or os and should be independently tunable */
+  '/',
+
+  /* ar_max_namelen: maximum number of characters in an archive header
+     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,
+     Chapter 7 (Formats & Protocols), Archive section sets this as 15.  */
+  15,
+
+  elf_match_priority,
+
+  /* Routines to byte-swap various sized integers from the data sections */
+  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+    bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+    bfd_getb16, bfd_getb_signed_16, bfd_putb16,
+
+  /* Routines to byte-swap various sized integers from the file headers */
+  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+    bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+    bfd_getb16, bfd_getb_signed_16, bfd_putb16,
+
+  /* bfd_check_format: check the format of a file being read */
+  { _bfd_dummy_target,		/* unknown format */
+    bfd_elf32_object_p,		/* assembler/linker output (object file) */
+    bfd_elf32_archive_p,	/* an archive */
+    bfd_elf32_core_file_p	/* a core file */
+  },
+
+  /* bfd_set_format: set the format of a file being written */
+  { bfd_false,
+    bfd_elf32_mkobject,
+    bfd_elf32_mkarchive,
+    bfd_elf32_mkcorefile
+  },
+
+  /* bfd_write_contents: write cached information into a file being written */
+  { bfd_false,
+    bfd_elf32_write_object_contents,
+    bfd_elf32_write_archive_contents,
+    bfd_elf32_write_corefile_contents,
+  },
+
+  BFD_JUMP_TABLE_GENERIC (bfd_elf32),
+  BFD_JUMP_TABLE_COPY (bfd_elf32),
+  BFD_JUMP_TABLE_CORE (bfd_elf32),
+#ifdef bfd_elf32_archive_functions
+  BFD_JUMP_TABLE_ARCHIVE (bfd_elf32_archive),
+#else
+  BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+#endif
+  BFD_JUMP_TABLE_SYMBOLS (bfd_elf32),
+  BFD_JUMP_TABLE_RELOCS (bfd_elf32),
+  BFD_JUMP_TABLE_WRITE (bfd_elf32),
+  BFD_JUMP_TABLE_LINK (bfd_elf32),
+  BFD_JUMP_TABLE_DYNAMIC (bfd_elf32),
+
+  /* Alternative endian target.  */
+#ifdef TARGET_LITTLE_SYM
+  & TARGET_LITTLE_SYM,
+#else
+  NULL,
+#endif
+
+  /* backend_data: */
+  &elf32_bed
+};
+#endif
+
diff -Naur '--exclude=*.swp' binutils-2.27-original/bfd/libbfd.h binutils-2.27-zip/bfd/libbfd.h
--- binutils-2.27-original/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
@@ -3125,6 +3125,16 @@
   "BFD_RELOC_VISIUM_HI16_PCREL",
   "BFD_RELOC_VISIUM_LO16_PCREL",
   "BFD_RELOC_VISIUM_IM16_PCREL",
+  "BFD_RELOC_ZIP_VALUE",
+  "BFD_RELOC_ZIP_BRANCH",
+  "BFD_RELOC_ZIP_OPB_IMM",
+  "BFD_RELOC_ZIP_OPB_OFFSET",
+  "BFD_RELOC_ZIP_OPB_PCREL",
+  "BFD_RELOC_ZIP_MOV_OFFSET",
+  "BFD_RELOC_ZIP_MOV_PCREL",
+  "BFD_RELOC_ZIP_LDI",
+  "BFD_RELOC_ZIP_LLO",
+  "BFD_RELOC_ZIP_BREV",
  "@@overflow: BFD_RELOC_UNUSED@@",
 };
 #endif
diff -Naur '--exclude=*.swp' binutils-2.27-original/bfd/Makefile.am binutils-2.27-zip/bfd/Makefile.am
--- binutils-2.27-original/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
@@ -173,7 +173,8 @@
 	cpu-xstormy16.lo \
 	cpu-xtensa.lo \
 	cpu-z80.lo \
-	cpu-z8k.lo
+	cpu-z8k.lo \
+	cpu-zip.lo
 
 ALL_MACHINES_CFILES = \
 	cpu-aarch64.c \
@@ -260,7 +261,8 @@
 	cpu-xstormy16.c \
 	cpu-xtensa.c \
 	cpu-z80.c \
-	cpu-z8k.c
+	cpu-z8k.c \
+	cpu-zip.c
 
 # 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.
@@ -382,6 +384,7 @@
 	elf32-xgate.lo \
 	elf32-xstormy16.lo \
 	elf32-xtensa.lo \
+	elf32-zip.lo \
 	elf32.lo \
 	elflink.lo \
 	elfxx-sparc.lo \
@@ -574,6 +577,7 @@
 	elf32-xgate.c \
 	elf32-xstormy16.c \
 	elf32-xtensa.c \
+	elf32-zip.c \
 	elf32.c \
 	elflink.c \
 	elfxx-sparc.c \
diff -Naur '--exclude=*.swp' binutils-2.27-original/bfd/Makefile.in binutils-2.27-zip/bfd/Makefile.in
--- binutils-2.27-original/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
@@ -505,7 +505,8 @@
 	cpu-xstormy16.lo \
 	cpu-xtensa.lo \
 	cpu-z80.lo \
-	cpu-z8k.lo
+	cpu-z8k.lo \
+	cpu-zip.lo
 
 ALL_MACHINES_CFILES = \
 	cpu-aarch64.c \
@@ -592,7 +593,8 @@
 	cpu-xstormy16.c \
 	cpu-xtensa.c \
 	cpu-z80.c \
-	cpu-z8k.c
+	cpu-z8k.c \
+	cpu-zip.c
 
 
 # The .o files needed by all of the 32 bit vectors that are configured into
@@ -715,6 +717,7 @@
 	elf32-xgate.lo \
 	elf32-xstormy16.lo \
 	elf32-xtensa.lo \
+	elf32-zip.lo \
 	elf32.lo \
 	elflink.lo \
 	elfxx-sparc.lo \
@@ -907,6 +910,7 @@
 	elf32-xgate.c \
 	elf32-xstormy16.c \
 	elf32-xtensa.c \
+	elf32-zip.c \
 	elf32.c \
 	elflink.c \
 	elfxx-sparc.c \
@@ -1437,6 +1441,7 @@
 @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-z8k.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)/dwarf1.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf2.Plo@am__quote@
diff -Naur '--exclude=*.swp' binutils-2.27-original/bfd/merge.c binutils-2.27-zip/bfd/merge.c
--- binutils-2.27-original/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
@@ -826,7 +826,7 @@
   else
     {
       contents = NULL;
-      pos = sec->output_section->filepos + sec->output_offset;
+      pos = sec->output_section->filepos + sec->output_offset * bfd_octets_per_byte(output_bfd);
       if (bfd_seek (output_bfd, pos, SEEK_SET) != 0)
 	return FALSE;
     }
diff -Naur '--exclude=*.swp' binutils-2.27-original/bfd/reloc.c binutils-2.27-zip/bfd/reloc.c
--- binutils-2.27-original/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
@@ -7697,7 +7697,32 @@
   BFD_RELOC_VISIUM_IM16_PCREL
 ENUMDOC
   Visium Relocations.
-
+ENUM
+  BFD_RELOC_ZIP_VALUE
+ENUMDOC
+  ZipCPU - 32 bit absolute value for LJMP instruction
+ENUM
+  BFD_RELOC_ZIP_BRANCH
+ENUMDOC
+  ZipCPU - 18-bit PC-relative offset for BRA (ADD #x,PC) instructions
+ENUM
+  BFD_RELOC_ZIP_OPB_IMM
+ENUMX
+  BFD_RELOC_ZIP_OPB_OFFSET
+ENUMX
+  BFD_RELOC_ZIP_OPB_PCREL
+ENUMX
+  BFD_RELOC_ZIP_MOV_OFFSET
+ENUMX
+  BFD_RELOC_ZIP_MOV_PCREL
+ENUMX
+  BFD_RELOC_ZIP_LDI
+ENUMX
+  BFD_RELOC_ZIP_LLO
+ENUMX
+  BFD_RELOC_ZIP_BREV
+ENUMDOC
+  ZipCPU value relocations
 ENDSENUM
   BFD_RELOC_UNUSED
 CODE_FRAGMENT
diff -Naur '--exclude=*.swp' binutils-2.27-original/bfd/targets.c binutils-2.27-zip/bfd/targets.c
--- binutils-2.27-original/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
@@ -910,6 +910,7 @@
 extern const bfd_target xtensa_elf32_le_vec;
 extern const bfd_target z80_coff_vec;
 extern const bfd_target z8k_coff_vec;
+extern const bfd_target zip_elf32_vec;
 
 /* These are always included.  */
 extern const bfd_target srec_vec;
@@ -1441,6 +1442,8 @@
 	&z80_coff_vec,
 
 	&z8k_coff_vec,
+
+	&zip_elf32_vec,
 #endif /* not SELECT_VECS */
 
 /* Always support S-records, for convenience.  */
diff -Naur '--exclude=*.swp' binutils-2.27-original/binutils/readelf.c binutils-2.27-zip/binutils/readelf.c
--- binutils-2.27-original/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
@@ -154,6 +154,7 @@
 #include "elf/xgate.h"
 #include "elf/xstormy16.h"
 #include "elf/xtensa.h"
+#include "elf/zip.h"
 
 #include "getopt.h"
 #include "libiberty.h"
@@ -800,6 +801,7 @@
     case EM_XTENSA_OLD:
     case EM_MICROBLAZE:
     case EM_MICROBLAZE_OLD:
+    case EM_ZIP:
       return TRUE;
 
     case EM_68HC05:
@@ -1476,6 +1478,10 @@
 	case EM_ALTERA_NIOS2:
 	  rtype = elf_nios2_reloc_type (type);
 	  break;
+
+	case EM_ZIP:
+	  rtype = elf_zip_reloc_type (type);
+	  break;
 	}
 
       if (rtype == NULL)
@@ -2339,6 +2345,7 @@
     case EM_TILEGX:		return "Tilera TILE-Gx multicore architecture family";
     case EM_CUDA:		return "NVIDIA CUDA architecture";
     case EM_XGATE:		return "Motorola XGATE embedded processor";
+    case EM_ZIP:		return "Gisselquist Technology ZipCPU";
     default:
       snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
       return buff;
@@ -11659,6 +11666,8 @@
     case EM_XTENSA_OLD:
     case EM_XTENSA:
       return reloc_type == 1; /* R_XTENSA_32.  */
+    case EM_ZIP:
+      return reloc_type == 1; /* R_ZIP_32.  */
     default:
       {
 	static unsigned int prev_warn = 0;
@@ -11735,6 +11744,8 @@
     case EM_XTENSA_OLD:
     case EM_XTENSA:
       return reloc_type == 14; /* R_XTENSA_32_PCREL.  */
+    case EM_ZIP:
+      return FALSE; /*  */
     default:
       /* 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
@@ -11944,6 +11955,7 @@
     case EM_TI_C6000:/* R_C6000_NONE.  */
     case EM_X86_64:  /* R_X86_64_NONE.  */
     case EM_XC16X:
+    case EM_ZIP:
       return reloc_type == 0;
 
     case EM_AARCH64:
diff -Naur '--exclude=*.swp' binutils-2.27-original/config.sub binutils-2.27-zip/config.sub
--- binutils-2.27-original/config.sub	2016-08-03 03:36:51.000000000 -0400
+++ binutils-2.27-zip/config.sub	2017-01-11 14:20:34.804049801 -0500
@@ -316,7 +316,7 @@
 	| visium \
 	| we32k \
 	| x86 | xc16x | xstormy16 | xtensa \
-	| z8k | z80)
+	| z8k | z80 )
 		basic_machine=$basic_machine-unknown
 		;;
 	c54x)
@@ -355,6 +355,14 @@
 	xscaleel)
 		basic_machine=armel-unknown
 		;;
+	zip-*-linux*)
+		basic_machine=zip
+		os=-linux
+		;;
+	zip*)
+		basic_machine=zip-unknown
+		os=-elf
+		;;
 
 	# We use `pc' rather than `unknown'
 	# because (1) that's what they normally are, and
diff -Naur '--exclude=*.swp' binutils-2.27-original/configure binutils-2.27-zip/configure
--- binutils-2.27-original/configure	2016-08-03 03:54:55.000000000 -0400
+++ binutils-2.27-zip/configure	2017-01-08 20:37:33.566336786 -0500
@@ -3548,6 +3548,9 @@
   ft32-*-*)
     noconfigdirs="$noconfigdirs ${libgcj}"
     ;;
+  zip*)
+    noconfigdirs="$noconfigdirs ${libgcj}"
+    ;;
   *-*-lynxos*)
     noconfigdirs="$noconfigdirs ${libgcj}"
     ;;
@@ -3575,6 +3578,9 @@
     *-*-aix*)
 	noconfigdirs="$noconfigdirs target-libgo"
 	;;
+    zip*)
+	noconfigdirs="$noconfigdirs target-libgo"
+	;;
     esac
 fi
 
@@ -3974,6 +3980,9 @@
   vax-*-*)
     noconfigdirs="$noconfigdirs target-newlib target-libgloss"
     ;;
+  zip*)
+    noconfigdirs="$noconfigdirs gdb gprof"
+    ;;
 esac
 
 # If we aren't building newlib, then don't build libgloss, since libgloss
diff -Naur '--exclude=*.swp' binutils-2.27-original/configure.ac binutils-2.27-zip/configure.ac
--- binutils-2.27-original/configure.ac	2016-08-03 04:37:38.000000000 -0400
+++ binutils-2.27-zip/configure.ac	2017-01-08 20:41:54.836485336 -0500
@@ -884,6 +884,9 @@
   ft32-*-*)
     noconfigdirs="$noconfigdirs ${libgcj}"
     ;;
+  zip*)
+    noconfigdirs="$noconfigdirs ${libgcj}"
+    ;;
   *-*-lynxos*)
     noconfigdirs="$noconfigdirs ${libgcj}"
     ;;
@@ -911,6 +914,9 @@
     *-*-aix*)
 	noconfigdirs="$noconfigdirs target-libgo"
 	;;
+    zip*)
+	noconfigdirs="$noconfigdirs target-libgo"
+	;;
     esac
 fi
 
@@ -1310,6 +1316,9 @@
   vax-*-*)
     noconfigdirs="$noconfigdirs target-newlib target-libgloss"
     ;;
+  zip*)
+    noconfigdirs="$noconfigdirs ${libgcj} gdb sim gprof"
+    ;;
 esac
 
 # If we aren't building newlib, then don't build libgloss, since libgloss
diff -Naur '--exclude=*.swp' binutils-2.27-original/gas/config/tc-zip.c binutils-2.27-zip/gas/config/tc-zip.c
--- binutils-2.27-original/gas/config/tc-zip.c	1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/gas/config/tc-zip.c	2019-02-14 20:54:05.341671631 -0500
@@ -0,0 +1,3403 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Filename: 	tc-zip.c
+//
+// Project:	Zip CPU backend for GNU Binutils
+//
+// Purpose:	This is the main file associated with the Zip Assembler.  By
+//		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
+//	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
+//	to a CPU, and that changes to the assembler in general shouldn't impact
+//	the CPU specific processing.
+//
+//	I'll let you be the judge as to how well this file meets that goal.
+//
+// Creator:	Dan Gisselquist, Ph.D.
+//		Gisselquist Technology, LLC
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2016-2018, Gisselquist Technology, LLC
+//
+// 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
+// by the Free Software Foundation, either version 3 of the License, or (at
+// your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program.  (It's in the $(ROOT)/doc directory, run make with no
+// target there if the PDF file isn't present.)  If not, see
+// <http://www.gnu.org/licenses/> for a copy.
+//
+// License:	GPL, v3, as defined and found on www.gnu.org,
+//		http://www.gnu.org/licenses/gpl.html
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+#include "as.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <ctype.h>
+
+#include "frags.h"
+#include "struc-symbol.h"
+#include "symbols.h"
+#include "config/tc-zip.h"
+#include "elf/zip.h"
+
+// #define	ZIP_DEBUG
+
+const	char	comment_chars[] = ";#";
+const	char	line_comment_chars[] = ";#";
+// Characters which separate lines (newline need to be listed)
+const	char	line_separator_chars[] = "";
+
+// Characters defining floating point numbers, such as 0f<floatingpt#>
+const	char	FLT_CHARS[] = "fFrR";
+
+// Characters that may be used for an exponent in floating point numbers
+const	char	EXP_CHARS[] = "eE";
+
+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 
+// global offset table.  Since nothing we've done has yet needed that table,
+// we'll keep this undefined for now.
+//
+// static int	zip_param_got = 0;
+static int	zip_param_cis = 1;
+static int	zip_param_small = 0;
+static int	zip_param_use_machine  = 1;
+
+typedef	struct	{
+	int	m_known;
+	int32_t	m_value;
+	symbolS *m_addsy, *m_subsy;
+} MACHINEVALUE;
+
+typedef	struct	{
+	MACHINEVALUE	r[ZIP_USER_REGS];
+} MACHINEREGS;
+
+MACHINEREGS	zipm;
+
+static void zip_clear_machine(MACHINEREGS *pzipm);
+
+void	md_begin(void) {
+	cis_mergable = FALSE;
+	//
+	record_alignment(text_section, 2);
+	record_alignment(data_section, 2);
+	//
+	lex_type['['] = lex_type['A'];
+	//
+	zip_clear_machine(&zipm);
+}
+
+void	md_end(void) { }
+
+void	zip_cons_align(int n) {
+	int	lg;
+	for(lg=0; ((1<<lg)<n)&&(lg<2); lg++)
+		;
+	do_align(lg, NULL, 0, (1<<lg)-1);
+}
+
+void	zip_flush_pending_output(void) {
+	// If the Assembler is going to stuff things into our output stream,
+	// then we need to make certain that any instructions that follow
+	// dont try to merge with anything previous.  i.e., CIS = false.
+	cis_mergable = FALSE;
+}
+
+int	zip_address_bytes(void) { return 4; }
+
+const	pseudo_typeS	md_pseudo_table[] = 
+{
+	{ "word", cons, 4 },	// ZipCPU word size is 4, not 2
+	{ "long", cons, 8 },	// ZipCPU longs are 64-bits, not 32
+	{ "quad", cons,16 },	// ZipCPU QUAD-words are 128-bits, not 64
+	{ NULL, NULL, 0 }
+};
+
+#define	ZIP_CC_SLEEP	0x010
+#define	ZIP_CC_GIE	0x020
+#define	ZIP_CC_STEP	0x040
+
+#define	SIM_OPCODE	0x77800000	// 0111.x111.1000. .... 0_111.x_111.10....
+#define	NOOP_OPCODE	0x77c00000	// 0111.x111.1100. .... 0_111.x_111.11....
+
+typedef  struct {
+	bfd_reloc_code_real_type	r_type;
+	symbolS				*r_sym;
+	int				r_pcrel;
+	long				r_fr_offset;
+	fixS				*r_fix;
+	// Could also be char *name and bfd_reloc_code_real_type
+} ZIPRELOC;
+
+// In case the instruction ...
+#define	ZIP_MAX_NAUX	3 // Number of auxilliary instruction codes used
+typedef	struct {
+	int		i_naux;
+	unsigned	i_code,	// The actual machine language instruction
+			i_aux[ZIP_MAX_NAUX];
+	ZIP_OPCODE	i_op;
+	ZIP_CONDITION	i_cnd;
+	ZIP_REG		i_areg;	// = ZIP_RNONE for no register
+	ZIP_REG		i_breg;
+	int		i_imm;
+	ZIPRELOC	*i_rp;
+} ZIPIS;
+
+static ZIPIS *
+zip_copy_insn(const ZIPIS *old) {
+	ZIPIS *nw = (ZIPIS *)xmalloc(sizeof(ZIPIS));
+
+	memcpy((char *)nw, (char *)old, sizeof(ZIPIS));
+
+	return nw;
+}
+
+static	int	fits_within(int nbits, int value) {
+	// -2 fits_within two bits
+	// -1 fits_within two bits
+	//  1 fits_within two bits
+	//  2 does not
+	//
+	if (value > 0)
+		return (value <   (1l<<(nbits-1))) ? 1:0;
+	else
+		return (value >= -(1l<<(nbits-1))) ? 1:0;
+}
+
+static uint32_t
+zip_brev(uint32_t v) {
+	unsigned r=0, b;
+
+	for(b=0; b<32; b++, v>>=1)
+		r = (r<<1)|(v&1);
+
+	return r;
+}
+
+static	const	int MACH_VUNKNOWN = 0, MACH_VKNOWN = 1, MACH_VUPPERKNOWN = 2,
+			MACH_VSYMKNOWN = 3;
+
+static void
+zip_clear_machine(MACHINEREGS *pzipm) {
+	int	i;
+
+#ifdef	ZIP_DEBUG
+	fprintf(stderr, "MACHINE, CLEAR\n");
+#endif
+	for(i=0; i<ZIP_USER_REGS; i++)
+		pzipm->r[i].m_known = MACH_VUNKNOWN;
+	for(i=0; i<ZIP_USER_REGS; i++)
+		pzipm->r[i].m_addsy = NULL;
+	for(i=0; i<ZIP_USER_REGS; i++)
+		pzipm->r[i].m_subsy = NULL;
+}
+
+static void
+zip_advance_machine(MACHINEREGS *pzipm, ZIPIS *insn) {
+	int		bval = insn->i_imm;
+	int		bknown;
+	MACHINEVALUE	*av, *bv;
+
+	if (!zip_param_use_machine) {
+		// zip_clear_machine(pzipm);
+		return;
+	}
+
+	// The next three instructions don't change any machine values
+	if((insn->i_op == ZIPO_SW)||(insn->i_op == ZIPO_SH)
+		||(insn->i_op==ZIPO_SB)
+		||(insn->i_op == ZIPO_CMP)||(insn->i_op == ZIPO_TST))
+		return;
+
+	//
+	// What remains to be done is to include symbols into the machine
+	// state.  For now, we state that anything with a symbol becomes
+	// unknown.
+	//
+	if ((insn->i_op == ZIPO_LJSR)||(insn->i_op == ZIPO_JSR)) {
+		zip_clear_machine(pzipm);
+		return;
+	}
+	if ((insn->i_rp)&&(insn->i_areg<ZIP_CC)) {
+		bknown = MACH_VUNKNOWN;
+		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_value = insn->i_imm;
+			pzipm->r[insn->i_areg].m_addsy = insn->i_rp->r_sym;
+			pzipm->r[insn->i_areg].m_subsy = NULL;
+			return;
+		} else if ((insn->i_breg == ZIP_PC)&&(insn->i_op == ZIPO_MOV)
+				&&(insn->i_cnd == ZIPC_ALWAYS)) {
+			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_addsy = insn->i_rp->r_sym;
+			pzipm->r[insn->i_areg].m_subsy = NULL;
+			return;
+		}
+	} else if (insn->i_rp)
+		bknown = MACH_VUNKNOWN;
+	else if (ZIP_RNONE == insn->i_breg)
+		// B-Op is an immediate only
+		bknown = MACH_VKNOWN;
+	else if (insn->i_breg >= ZIP_CC)
+		bknown = MACH_VUNKNOWN;
+	else if (insn->i_imm == 0)
+		bknown = (pzipm->r[insn->i_breg].m_known);
+	else // If we have an immediate plus a value, can't know UPPER anymore
+		bknown = (pzipm->r[insn->i_breg].m_known == MACH_VKNOWN)
+					? MACH_VKNOWN : MACH_VUNKNOWN;
+
+	if (insn->i_breg < ZIP_USER_REGS)
+		bval += pzipm->r[insn->i_breg].m_value;
+
+	if (insn->i_areg >= ZIP_USER_REGS) {
+#ifdef	ZIP_DEBUG
+		fprintf(stderr, "MACHINE, A-REG[%02x] out of bounds\n", insn->i_areg);
+#endif
+		return; // Nothing to do -- no change to machine
+	} else if (insn->i_areg == ZIP_PC) {
+#ifdef	ZIP_DEBUG
+		fprintf(stderr, "MACHINE, CLEAR ON JUMP\n");
+#endif
+		zip_clear_machine(pzipm);
+		return;
+	} else if ((insn->i_areg == ZIP_CC)&&(insn->i_op == ZIPO_AND)) {
+#ifdef	ZIP_DEBUG
+		fprintf(stderr, "MACHINE, CLEAR ON ANDing to CC\n");
+#endif
+		zip_clear_machine(pzipm);
+	} else if ((insn->i_areg == ZIP_CC)&&(
+			(insn->i_op == ZIPO_LDI)
+			||(insn->i_op == ZIPO_LW)
+			||(insn->i_op == ZIPO_CLR)
+			||(insn->i_op == ZIPO_LDILO))) {
+#ifdef	ZIP_DEBUG
+		fprintf(stderr, "MACHINE, CLEAR ON setting CC\n");
+#endif
+		zip_clear_machine(pzipm);
+		return;
+	} else if (insn->i_areg >= ZIP_CC) {
+#ifdef	ZIP_DEBUG
+		fprintf(stderr, "MACHINE, Not tracking CC or PC changes\n");
+#endif
+		pzipm->r[insn->i_areg].m_known = MACH_VUNKNOWN;
+		return;
+	}
+
+	av = &pzipm->r[insn->i_areg];
+	if (insn->i_breg < ZIP_CC)
+		bv = &pzipm->r[insn->i_breg];
+	else
+		bv = NULL;
+
+	if (ZIPC_ALWAYS != insn->i_cnd) {
+#ifdef	ZIP_DEBUG
+		fprintf(stderr, "\tMACHINE, CONDITIONAL operation\n");
+#endif
+		if ((ZIPO_LDILO == insn->i_op)
+				&&((av->m_known == MACH_VKNOWN)
+					||(av->m_known == MACH_VUPPERKNOWN))) {
+			av->m_known = MACH_VUPPERKNOWN;
+		} else if ((ZIPO_LDI == insn->i_op)||(ZIPO_LDIn == insn->i_op)){
+			if (((av->m_known == MACH_VKNOWN)
+				||(av->m_known == MACH_VUPPERKNOWN))
+			    &&(((insn->i_imm ^ av->m_value)&& ~0x0ffff)==0)) {
+				av->m_known = MACH_VUPPERKNOWN;
+			} else
+				av->m_known = MACH_VUNKNOWN;
+		} else {
+			av->m_known = MACH_VUNKNOWN;
+}
+	} switch(insn->i_op) {
+		case	ZIPO_SUB:
+			av->m_known = (av->m_known==MACH_VKNOWN)
+					? MACH_VKNOWN:MACH_VUNKNOWN;
+			av->m_value -= bval;
+			if (bknown != MACH_VKNOWN)
+				av->m_known = MACH_VUNKNOWN;
+			break;
+		case	ZIPO_AND:
+			av->m_value &= bval;
+			if ((bknown == MACH_VUPPERKNOWN)&&(bval == 0)) {
+				if (av->m_known == MACH_VKNOWN)
+					av->m_known = MACH_VUPPERKNOWN;
+				else if (av->m_known != MACH_VUPPERKNOWN)
+					av->m_known = MACH_VUNKNOWN;
+			} else if (bknown != MACH_VKNOWN)
+				av->m_known = MACH_VUNKNOWN;
+			break;
+		case	ZIPO_ADD:
+			av->m_value += bval;
+			if (bknown != MACH_VKNOWN)
+				av->m_known = MACH_VUNKNOWN;
+			break;
+		case	ZIPO_OR:
+			av->m_value |= bval;
+			if (bknown == MACH_VUPPERKNOWN) {
+				if (av->m_known == MACH_VKNOWN)
+					av->m_known = MACH_VUPPERKNOWN;
+				else if (av->m_known != MACH_VUPPERKNOWN)
+					av->m_known = MACH_VUNKNOWN;
+			} else if (bknown != MACH_VKNOWN)
+				av->m_known = MACH_VUNKNOWN;
+			break;
+		case	ZIPO_XOR:
+			av->m_value ^= bval;
+			if (bknown == MACH_VUPPERKNOWN) {
+				if (av->m_known == MACH_VKNOWN)
+					av->m_known = MACH_VUPPERKNOWN;
+				else if (av->m_known != MACH_VUPPERKNOWN)
+					av->m_known = MACH_VUNKNOWN;
+			} else if (bknown != MACH_VKNOWN)
+				av->m_known = MACH_VUNKNOWN;
+			break;
+		case	ZIPO_LDI: case ZIPO_LDIn:
+			// Although the h/w instruction has no conditions, our
+			// decoding may have conditions until we finish
+			// working out what the actual result is.  Hence, we
+			// need to be aware of any conditions from above.
+#ifdef	ZIP_DEBUG
+			fprintf(stderr, "MACHINE, LDI -> %02x\n", insn->i_areg);
+#endif
+			av->m_value = bval;
+			if (insn->i_cnd != ZIPC_ALWAYS) {
+				// if ((bknown)&&(bvalue == insn->i_imm))
+					// pzipm->r[insn->i_areg].m_known = MACH_VKNOWN;
+			} else {
+				av->m_known = MACH_VKNOWN;
+			} break;
+		case	ZIPO_LDILO:
+#ifdef	ZIP_DEBUG
+			fprintf(stderr, "MACHINE, LDILO -> %02x\n", insn->i_areg);
+#endif
+			av->m_value &= ~0x0ffff;
+			av->m_value |= bval &0x0ffff;
+			if ((av->m_known == MACH_VUPPERKNOWN)
+					&&(bknown == MACH_VKNOWN)
+					&&(ZIPC_ALWAYS == insn->i_cnd))
+				av->m_known = MACH_VKNOWN;
+			break;
+		case	ZIPO_BREV:
+			av->m_value = zip_brev(bval);
+			if (ZIPC_ALWAYS == insn->i_cnd)
+				av->m_known = (bknown == MACH_VKNOWN)?MACH_VKNOWN:MACH_VUNKNOWN;
+			else if ((bknown == MACH_VKNOWN)
+				&&(  (av->m_known == MACH_VKNOWN)
+				   ||(av->m_known == MACH_VUPPERKNOWN))
+				&&((((zip_brev(bval)^av->m_value)&0x0ffff)==0)))
+				av->m_known = MACH_VUPPERKNOWN;
+			break;
+		case	ZIPO_MOV:
+#ifdef	ZIP_DEBUG
+			fprintf(stderr, "MACHINE, MOV -> %02x\n", insn->i_areg);
+#endif
+			av->m_value = bval;
+			if (ZIPC_ALWAYS == insn->i_cnd) {
+				av->m_known = bknown;
+				if (bknown == MACH_VSYMKNOWN) {
+					if (!bv) { av->m_known = MACH_VUNKNOWN;}
+					else {
+					av->m_value = bv->m_value + insn->i_imm;
+					av->m_addsy = bv->m_addsy;
+					av->m_subsy = bv->m_subsy;
+					}
+				}
+			} else if (
+				((av->m_known == MACH_VKNOWN)
+				  ||(av->m_known == MACH_VUPPERKNOWN))
+				&&((bknown == MACH_VKNOWN)
+				  ||(bknown == MACH_VUPPERKNOWN))
+				&&(((bval^av->m_value)&0xffff0000)==0))
+				av->m_known = MACH_VUPPERKNOWN;
+			else
+				av->m_known = MACH_VUNKNOWN;
+			av->m_value = bval;
+			break;
+		case	ZIPO_CLR:
+			if (insn->i_cnd == ZIPC_ALWAYS)
+				av->m_known = MACH_VKNOWN;
+			else if ((av->m_value & 0xffff0000)==0) {
+				if (((av->m_known == MACH_VKNOWN)
+					||(av->m_known == MACH_VUPPERKNOWN))
+					&&(((av->m_value ^ bval)&0xffff0000)==0))
+					av->m_known = MACH_VUPPERKNOWN;
+				else
+					av->m_known = MACH_VUNKNOWN;
+			} av->m_value = 0;
+			break;
+		// Store's don't change any regs
+		case	ZIPO_SW: case ZIPO_SH: case ZIPO_SB:
+		case	ZIPO_SIM: case ZIPO_NOOP:
+		case	ZIPO_SDUMP: case ZIPO_NDUMP:
+		case	ZIPO_BREAK: case ZIPO_LOCK:
+		case	ZIPO_CMP:  case	ZIPO_TST:
+			// These don't change any registers
+			break;
+		// Result of loading a byte or halfword always clears the upper
+		// half word
+		case	ZIPO_LB: case	ZIPO_LH:
+			if (insn->i_cnd == ZIPC_ALWAYS) {
+				av->m_known = MACH_VUPPERKNOWN;
+				av->m_value = 0;
+			} else
+				av->m_known = MACH_VUNKNOWN;
+			break;
+		case	ZIPO_LW:
+		default:
+#ifdef	ZIP_DEBUG
+			fprintf(stderr, "MACHINE, DEFAULT, %02x -> unknown\n", insn->i_areg);
+#endif
+			av->m_known = MACH_VUNKNOWN;
+			break;
+	}
+
+	pzipm->r[ZIP_CC].m_known = MACH_VUNKNOWN;
+	pzipm->r[ZIP_PC].m_known = MACH_VUNKNOWN;
+}
+
+static	int	zip_findnearreg_machine(MACHINEREGS *pzipm, unsigned  value) {
+	int	bestrg = ZIP_RNONE, bestd, d;
+	int	rg;
+
+	bestd = 0x7fffffff;
+	bestrg= ZIP_RNONE;
+
+	for(rg=0; rg<ZIP_CC; rg++) {
+		if (pzipm->r[rg].m_known == MACH_VUNKNOWN)
+			continue;
+		if (pzipm->r[rg].m_known == MACH_VSYMKNOWN)
+			continue;
+		if (pzipm->r[rg].m_known == MACH_VUPPERKNOWN)
+			continue;
+		gas_assert(pzipm->r[rg].m_known == MACH_VKNOWN);
+	
+		if (pzipm->r[rg].m_addsy)
+			continue;
+		if (pzipm->r[rg].m_subsy)
+			continue;
+
+		d = abs(pzipm->r[rg].m_value - value);
+		if (d < bestd) {
+			bestd = d;
+			bestrg = rg;
+		}
+	}
+
+	if (fits_within(18,bestd))
+		return bestrg;
+	return ZIP_RNONE;
+}
+
+#ifdef	ZIP_DEBUG
+static void
+zip_debug_machine(MACHINEREGS *pzipm) {
+	int	i;
+	for(i=0; i<ZIP_USER_REGS; i++) {
+		if (pzipm->r[i].m_known == MACH_VKNOWN)
+			fprintf(stderr, "MACH-KNOW[Y][%2x] = %08x\n", 
+				i, pzipm->r[i].m_value);
+		else if (pzipm->r[i].m_known == MACH_VUPPERKNOWN)
+			fprintf(stderr, "MACH-KNOW[U][%2x] = %04x\n", 
+				i, (pzipm->r[i].m_value>>16)&0x0ffff);
+	}
+}
+#endif
+
+
+/*
+ * Option processing
+ *
+ * While not yet implemented, we do have a need for multiple options.  These
+ * include:
+ *
+ *	(not yet supported)
+ *	-got	Use a global offset table to place unknown jump locations into.
+ *
+ *	(not yet supported)
+ *	-relax	Implement only relaxed instructions.  This implies that all
+ *		branches fit within 18-bits of the current PC, or equivalently
+ *		that all of the code fits within 1MB.  
+ *
+ *	(not yet supported)
+ *	-no-relax	Don't relax any instructions.  That means that all
+ *		branches will be implemented as LOD (PC),PC ; .int #Address
+ *		and all conditional branches as LOD 1(PC),PC; BRA 1; .int #addr.
+ *		This also implies LDI's of unknown values will always be
+ *		converted to LDILO/LDIHI pairs and never converted back to
+ *		LDI's--even when the final value is known.
+ *
+ *	-cis	Attempt to compress instructions into the CIS instruction
+ *		set.
+ *
+ *	(Something for stating the starting address of the routine in memory...)
+ *
+ *	Other (not yet supported) long options
+ *
+ *	-nopipe	Attempts to use a lock instruction 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.
+ *	-nofpu	Attempts to use floating point unit insn will cause an error.
+ *	
+ *
+ */
+#define	OPTION_CIS	(OPTION_MD_BASE+1)
+#define	OPTION_NOCIS	(OPTION_MD_BASE+2)
+#define	OPTION_ZIPM	(OPTION_MD_BASE+3)
+#define	OPTION_NOZIPM	(OPTION_MD_BASE+4)
+#define	OPTION_GOT	(OPTION_MD_BASE+5)
+#define	OPTION_SMALL	(OPTION_MD_BASE+6)	// No LW(PC),PC insns
+
+const char	*md_shortopts = "";
+struct	option	md_longopts[] =
+{
+	{ "cis",   no_argument, NULL, OPTION_CIS },
+	{ "nocis", no_argument, NULL, OPTION_NOCIS },
+	{ "zipm",   no_argument, NULL, OPTION_ZIPM },
+	{ "nozipm", no_argument, NULL, OPTION_NOZIPM },
+	{ "small",  no_argument, NULL, OPTION_SMALL },
+	// { "got",  no_argument, NULL, OPTION_GOT },
+	{ NULL, no_argument, NULL, 0}
+};
+size_t	md_longopts_size = sizeof(md_longopts);
+
+/* We have no target specific options yet, so these next two fucntions are
+ * are empty.
+ */
+int
+md_parse_option(int c, const char *arg ATTRIBUTE_UNUSED)
+{
+	// printf("Option %d, %s\n", c, (arg)?arg : "(Null)");
+	if (c==0)
+		return 1;
+	switch(c) {
+		case 0: return 1;
+		case OPTION_CIS:    zip_param_cis = 1; 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_NOZIPM: zip_param_use_machine = 0; return 1; break;
+		// case OPTION_GOT : zip_param_got  = 1; return 1; break;
+		default: break;
+	}
+	return 0; // We didn't handle this option
+}
+
+void
+md_show_usage(FILE *stream ATTRIBUTE_UNUSED)
+{
+	fprintf(stream, _("Zip CPU options:\n"));
+	fprintf(stream, _("\n"
+"-cis\t\tAttempt to compress instructions into two instructions per word.\n"));
+	//fprintf(stream, _(
+// "-got\t\tGenerate position independent code by referencing all symbols\n"
+// "\t\tthrough a Global Offset Table.\n"));
+}
+
+
+symbolS *
+md_undefined_symbol(char *name ATTRIBUTE_UNUSED)
+{
+//#warning "This is where other architectures check for any GOT references"
+	return NULL;
+}
+
+void
+md_operand(expressionS *op ATTRIBUTE_UNUSED)
+{
+	/* Empty for now -- what is this for? */
+}
+
+#ifdef	ZIP_DEBUG
+static void
+zip_dump_sym(symbolS *sym)
+{
+	if (!sym) {
+		fprintf(stderr, "SYM(NULL)");
+	} else {
+		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",
+			S_GET_NAME(sym),
+			(S_IS_LOCAL(sym))?"Local ":"",
+			(S_IS_DEFINED(sym))?"Defined ":"",
+			(S_IS_EXTERNAL(sym))?"extern ":"",
+			(S_IS_FUNCTION(sym))?"(func) ":"",
+			(S_IS_WEAK(sym))?"Weak ":"",
+			(S_IS_WEAKREFD(sym))?"(Weak Ref-D) ":"",
+			(S_IS_WEAKREFR(sym))?"(Weak Refr) ":"",
+			(S_IS_DEBUG(sym))?"DEBUG ":"",
+			(S_IS_VOLATILE(sym))?"Volatile ":"",
+			(S_IS_FORWARD_REF(sym))?"Fwd Ref ":"",
+			(S_IS_COMMON(sym))?"Common ":"",
+			(S_GET_SEGMENT(sym)==absolute_section)?"AbsoluteS ":"",
+			(S_GET_SEGMENT(sym)==expr_section)?"ExpressionS ":"",
+			(S_GET_SEGMENT(sym)==reg_section)?"RegisterS ":"",
+			(S_GET_SEGMENT(sym)==undefined_section)?"UndefinedS ":"",
+			(symbol_resolved_p(sym))?"Resolved ":"",
+			(unsigned)S_GET_VALUE(sym));
+	}
+}
+
+static void
+zip_dump_insn(ZIPIS *insn) {
+	fprintf(stderr, "INSN:DUMP ");
+	switch(insn->i_op) {
+		case ZIPO_SUB:   fprintf(stderr, "%7s", "SUB"); break;
+		case ZIPO_AND:   fprintf(stderr, "%7s", "AND"); break;
+		case ZIPO_ADD:   fprintf(stderr, "%7s", "ADD"); break;
+		case ZIPO_OR:    fprintf(stderr, "%7s", "OR"); break;
+		case ZIPO_XOR:   fprintf(stderr, "%7s", "XOR"); break;
+		case ZIPO_LSR:   fprintf(stderr, "%7s", "LSR"); break;
+		case ZIPO_LSL:   fprintf(stderr, "%7s", "LSL"); break;
+		case ZIPO_ASR:   fprintf(stderr, "%7s", "ASR"); break;
+		case ZIPO_LDI:   fprintf(stderr, "%7s", "LDI"); break;
+		case ZIPO_MPYUHI:fprintf(stderr, "%7s", "MPYUHI");break;
+		case ZIPO_MPYSHI:fprintf(stderr, "%7s", "MPYSHI");break;
+		case ZIPO_LDILO: fprintf(stderr, "%7s", "LDILO"); break;
+		case ZIPO_BREV:  fprintf(stderr, "%7s", "BREV");  break;
+		case ZIPO_MOV:   fprintf(stderr, "%7s", "MOV");   break;
+		case ZIPO_CMP:   fprintf(stderr, "%7s", "CMP");   break;
+		case ZIPO_TST:   fprintf(stderr, "%7s", "TST");   break;
+		case ZIPO_LW:    fprintf(stderr, "%7s", "LW");    break;
+		case ZIPO_SW:    fprintf(stderr, "%7s", "SW");    break;
+		case ZIPO_LH:    fprintf(stderr, "%7s", "LH");    break;
+		case ZIPO_SH:    fprintf(stderr, "%7s", "SH");    break;
+		case ZIPO_LB:    fprintf(stderr, "%7s", "LB");    break;
+		case ZIPO_SB:    fprintf(stderr, "%7s", "SB");    break;
+		case ZIPO_DIVU:  fprintf(stderr, "%7s", "DIVU");  break;
+		case ZIPO_DIVS:  fprintf(stderr, "%7s", "DIVS");  break;
+		case ZIPO_FPADD: fprintf(stderr, "%7s", "FPADD"); break;
+		case ZIPO_FPSUB: fprintf(stderr, "%7s", "FPSUB"); break;
+		//
+		case ZIPO_NOOP:  fprintf(stderr, "%7s", "NOOP");  break;
+		case ZIPO_BREAK: fprintf(stderr, "%7s", "BREAK"); break;
+		case ZIPO_LOCK:  fprintf(stderr, "%7s", "LOCK");  break;
+		case ZIPO_TRAP:  fprintf(stderr, "%7s", "TRAP");  break;
+		case ZIPO_CLR:   fprintf(stderr, "%7s", "CLR");   break;
+		case ZIPO_HALT:  fprintf(stderr, "%7s", "HALT");  break;
+		case ZIPO_WAIT:  fprintf(stderr, "%7s", "WAIT");  break;
+		case ZIPO_STEP:  fprintf(stderr, "%7s", "STEP");  break;
+		case ZIPO_RTU:   fprintf(stderr, "%7s", "RTU");   break;
+		case ZIPO_BRA:   fprintf(stderr, "%7s", "BRA");   break;
+		case ZIPO_BUSY:  fprintf(stderr, "%7s", "BUSY");  break;
+		case ZIPO_JMP:   fprintf(stderr, "%7s", "JMP");   break;
+		case ZIPO_NOT:   fprintf(stderr, "%7s", "NOT");   break;
+		case ZIPO_NEG:   fprintf(stderr, "%7s", "NEG");   break;
+		//
+		case ZIPO_SIM:   fprintf(stderr, "%7s", "SIM");   break;
+		case ZIPO_SDUMP: fprintf(stderr, "%7s", "SDUMP"); break;
+		case ZIPO_SEXIT: fprintf(stderr, "%7s", "SEXIT"); break;
+		case ZIPO_SOUT:  fprintf(stderr, "%7s", "SOUT");  break;
+		case ZIPO_NDUMP: fprintf(stderr, "%7s", "NDUMP"); break;
+		case ZIPO_NEXIT: fprintf(stderr, "%7s", "NEXIT"); break;
+		case ZIPO_NOUT:  fprintf(stderr, "%7s", "NOUT");  break;
+		//
+		case ZIPO_LJMP:	fprintf(stderr, "%7s", "LJMP"); break;
+		case ZIPO_LJSR:	fprintf(stderr, "%7s", "LJSR");   break;
+		//
+		case ZIPO_SEXTH:fprintf(stderr, "%7s", "SEXTH");   break;
+		case ZIPO_SEXTB:fprintf(stderr, "%7s", "SEXTB");   break;
+		default:
+			fprintf(stderr, "%d", insn->i_op); break;
+	}
+	switch(insn->i_cnd) {
+		case ZIPC_Z: fprintf(stderr, "%-3s", ".Z"); break;
+		case ZIPC_LT: fprintf(stderr, "%-3s", ".LT"); break;
+		case ZIPC_C: fprintf(stderr, "%-3s", ".C"); break;
+		case ZIPC_V: fprintf(stderr, "%-3s", ".V"); break;
+		case ZIPC_NZ: fprintf(stderr, "%-3s", ".NE"); break;
+		case ZIPC_GE: fprintf(stderr, "%-3s", ".GE"); break;
+		case ZIPC_NC: fprintf(stderr, "%-3s", ".NC"); break;
+		case ZIPC_ALWAYS:
+		default:
+			break;
+	} fprintf(stderr, " %d", (int)insn->i_cnd);
+
+	fprintf(stderr, "\n\tAREG = %d\n\tB = ", insn->i_areg);
+	if (insn->i_rp) {
+		if (insn->i_imm != 0)
+			fprintf(stderr, "$%d + ", insn->i_imm);
+		fprintf(stderr, "%s ", (insn->i_rp->r_sym) ?
+			S_GET_NAME(insn->i_rp->r_sym) : "(null)");
+	} else
+		fprintf(stderr, "%d[%08x] (no sym)", insn->i_imm, insn->i_imm);
+	if (insn->i_breg != ZIP_RNONE)
+		fprintf(stderr, "+ R%d", insn->i_breg);
+	fprintf(stderr, "\n");
+	if (insn->i_rp)
+		fprintf(stderr, "\t@%ld (offset w/in instruction frag)\n", insn->i_rp->r_fr_offset);
+	fprintf(stderr, "\tINSN:CODE %08x", insn->i_code);
+	{
+		int	i;
+		for(i=0; (i<insn->i_naux)&&(i<ZIP_MAX_NAUX); i++)
+			fprintf(stderr, ":%08x", insn->i_aux[i]);
+	}
+	fprintf(stderr, "\n\tDUMPED\n");
+}
+#endif
+
+static	ZIP_CONDITION
+zip_negate_condition(ZIP_CONDITION c) {
+	switch(c) {
+		case ZIPC_Z:	return ZIPC_NZ; break;
+		case ZIPC_LT:	return ZIPC_GE; break;
+		case ZIPC_C:	return ZIPC_NC; break;
+		case ZIPC_NZ:	return ZIPC_Z; break;
+		case ZIPC_GE:	return ZIPC_LT; break;
+		case ZIPC_NC:	return ZIPC_C; break;
+		case ZIPC_ALWAYS:	return ZIPC_ALWAYS; break;
+		default:
+			break;
+	} gas_assert((0)&&("Cannot negate condition\n"));
+	return ZIPC_ALWAYS;
+}
+
+static const char *zip_skip_white_spaces(const char *str) {
+	if (!str)
+		return NULL;
+	while((*str)&&(isspace(*str)))
+		str++;
+	return str;
+}
+
+static const char *
+zip_parse_condition(const char *str, ZIP_CONDITION *condn) {
+	if ((strcasecmp(str, "Z")==0)
+			||(strcasecmp(str, "EQ")==0)) {
+		*condn = ZIPC_Z;
+	} else if ((strcasecmp(str, "LT")==0)
+			||(strcasecmp(str, "N")==0)) {
+		*condn = ZIPC_LT;
+	} else if ((strcasecmp(str, "C")==0)
+			||(strcasecmp(str, "LTU")==0)) {
+		*condn = ZIPC_C;
+	} else if (strcasecmp(str, "V")==0) {
+		*condn = ZIPC_V;
+	} else if((strcasecmp(str, "NZ")==0)
+			||(strcasecmp(str, "NE")==0)) {
+		*condn = ZIPC_NZ;
+	} else if ((strcasecmp(str, "GE")==0)
+			||(strcasecmp(str, "GTE")==0)) {
+		*condn = ZIPC_GE;
+	} else if ((strcasecmp(str, "NC")==0)
+			||(strcasecmp(str, "GEU")==0)) {
+		*condn = ZIPC_NC;
+	} else {
+		return "Unrecognized condition";
+	}
+
+	return NULL;
+}
+
+static const char *zip_parse_reg(const char *str, ZIP_REG *regid) {
+	const char *ustr = str;
+	int	userreg = 0;
+
+	if ((!str)||(str[0]=='\0'))
+		return "No register given";
+	ustr = zip_skip_white_spaces(str);
+
+	if (toupper(ustr[0]) == 'U') {
+		ustr = str+1;
+		userreg = 0x10;
+	} else if ((toupper(ustr[0]) == 'S')&&(strcasecmp(ustr, "SP")!=0)) {
+		ustr = str+1;
+	}
+
+	/*
+	if (strcasecmp(ustr, "GBL")==0) {
+		*regid = userreg + 11;
+		ustr += 3;
+	} else
+	*/
+	if (strcasecmp(ustr, "LR")==0) {
+		*regid = userreg + 0;
+		ustr += 2;
+	} else if (strcasecmp(ustr, "FP")==0) {
+		*regid = userreg + 12;
+		ustr += 2;
+	} else if (strcasecmp(ustr, "SP")==0) {
+		*regid = userreg + 13;
+		ustr += 2;
+	} else if (strcasecmp(ustr, "CC")==0) {
+		*regid = userreg + 14;
+		ustr += 2;
+	} else if (strcasecmp(ustr, "PC")==0) {
+		*regid = userreg + 15;
+		ustr += 2;
+	} else if (('r' == tolower(ustr[0]))
+			&&(isdigit(ustr[1]))
+			&&((!isdigit(ustr[2]))
+				||(!isdigit(ustr[3])))) {
+		*regid = atoi(ustr+1);
+		if ((*regid > 15)||(*regid < 0))
+			return "Register does not exist";
+		*regid += userreg;
+
+		if (!isdigit(ustr[2]))
+			ustr+=2;
+		else
+			ustr+=3;
+	} else {
+		*regid = ZIP_RNONE;
+		return "Unknown register";
+	}
+
+	// Registers names are terminated by something other than letters
+	// and numbers.  Things like ')', ',', or '\0' should terminate a 
+	// register.  Here, we only double check that the register is not
+	// terminated by another letter or a number.
+	if ((*ustr)&&((isalpha(*ustr))||(isdigit(*ustr))))
+		return "Unrecognized register";
+
+	return NULL;
+}
+
+// Parse a 'B' operand
+static const char *
+zip_parse_bop(const char *bop, ZIPIS *insn) {
+	// There are a couple forms for what we can expect in a B operand:
+	//	The first three require no relocations ...
+	//		1. A simple number
+	//		2. Number + Register
+	//		3. Number(Register)
+	//		4. Register by itself
+	//		Good form is to replace this number with the possibility
+	//		of a constant expression ...  The number may be any of
+	//		[+-](0[xX][0-9a-fA-F]+|(0[0-7]+)|(0-9)+)
+	//	The next four may require a relocation
+	//		4. Label + Register
+	//		5. Label(Register)
+	//		6. Label (Register is implied: PC, if moving or jumping
+	//			to the PC, or GBL if loading a value or if
+	//			the offset ends up being unknown)
+	//		Good form allows an expression instead of a label,
+	//		that can be evaluated at ... sometime.
+	//		7. Number(Label)
+	//
+	// We will support:
+	//	(Number|Label)?( "("Register")" | "+"Register )
+	//
+	char	lbl[512], *lblp = lbl;
+	const char	*ptr;
+	insn->i_imm = 0;
+	*lblp = '\0';
+
+	if (strlen(bop)>sizeof(lbl)-1)
+		as_fatal( _("Label length too long"));
+	// printf("RAW-OP-B: %s %s\n", bop, (insn->i_rp)?"(i_rp != NULL)":"");
+
+	// Do we start with a number?
+	{
+		int	sgn = 0;
+
+		ptr = zip_skip_white_spaces(bop);
+		if ('$' == *ptr)
+			ptr = zip_skip_white_spaces(ptr+1);
+
+		if ('+' == *ptr)
+			ptr++;
+		else if ('-' == *ptr) {
+			sgn = 1;
+			ptr++;
+		}
+
+		if ('$' == *ptr)
+			ptr = zip_skip_white_spaces(ptr+1);
+		ptr = zip_skip_white_spaces(ptr);
+		if ('$' == *ptr)
+			ptr = zip_skip_white_spaces(ptr+1);
+
+		if ((*ptr)&&(isdigit(*ptr))) {
+			char *end = (char *)ptr;
+			unsigned long v = strtoul(ptr, &end, 0);
+			// We start with a number
+			if (sgn)
+				insn->i_imm = (int)(-v);
+			else
+				insn->i_imm = (int)(v);
+			ptr = (const char *)end;
+
+			// Permit a string of Num [[+-] Num]*
+			// This is necessary for the DI instructions within the
+			// compiler.
+			while( ((*ptr == '+')||(*ptr == '-'))
+				&&(isdigit(ptr[1])) ) {
+				sgn = (*ptr == '-');
+				v = strtoul(&ptr[1], &end, 0);
+				if (sgn) v = -v;
+				insn->i_imm += (int)v;
+				ptr = (const char *)end;
+			}
+		} else if ((*ptr)&&(
+				(isalpha(*ptr))
+				||('*'==*ptr)
+				||('.'==*ptr)
+				||('_'==*ptr))) {
+			// We start with an identifier
+			// printf("OP-B ( \'%s\' ) starts with an identifier (%c)\n",
+				// bop, *ptr);
+
+			// Skip any compiler inserted prefix (if present)
+			if ('*' == *ptr)
+				ptr++;
+			while((*ptr)&&(
+					(isalpha(*ptr))
+					||(isdigit(*ptr))
+					||('_' == *ptr)
+					||('$' == *ptr)
+					||('.' == *ptr)))
+				*lblp++ = *ptr++;
+			*lblp = '\0';
+			// printf("LBL was %s\n", lbl);
+
+			// This could still be a register ... can't tell yet
+			if (sgn)
+				return "ERR: Not expecting a signed label!";
+
+			ptr = zip_skip_white_spaces(ptr);
+		}
+	}
+
+	ptr = zip_skip_white_spaces(ptr);
+
+	const	char *err = NULL;
+
+	if ((*ptr == '+')&&(ptr[1] == '('))
+		ptr++;
+	if ((*ptr)&&(*ptr == '(')) {
+		// Form #3: Number(register)
+		char *end = strchr(ptr+1, ')');
+		if (NULL == end)
+			return "Un-matched \'(\', cannot find \')\'";
+		*end = '\0';
+		// printf("Looking for a register in %s\n", ptr+1);
+		err = zip_parse_reg(ptr+1, &insn->i_breg);
+		if (err) {
+			// Must've been a symbol
+			if (lbl[0] != '\0') // Already have a symbol in this
+				return err;	// expression!
+			ptr++;
+			while((*ptr)&&(
+					(isalpha(*ptr))
+					||(isdigit(*ptr))
+					||('_' == *ptr)
+					||('$' == *ptr)
+					||('.' == *ptr)))
+				*lblp++ = *ptr++;
+			*lblp = '\0';
+			insn->i_breg = ZIP_RNONE;
+			ptr = zip_skip_white_spaces(ptr);
+			if (*ptr != '\0')
+				return "ERR: Expression within parenthesis not supported";
+			err = NULL;
+		}
+		// printf("Found a register, %s -> %d\n", ptr+1, insn->i_breg);
+	} else if ((*ptr)&&((*ptr == '+')||(*ptr == '-'))) {
+		if ((*lbl)&&(zip_parse_reg(lbl, &insn->i_breg) == NULL)) {
+			// Register+Number
+			// Skip to the end to process what follows
+			*lbl = '\0'; // Label wasn't a symbol, so let's clear it
+		} else {
+			// Number/label+Register
+			while((('+' == *ptr)||('-' == *ptr))
+					&&(ptr[1])
+					&&((isdigit(ptr[1]))
+					||((ptr[0] == '+')
+						&&(ptr[1] == '-')
+						&&(ptr[2])
+						&&(isdigit(ptr[2]))))) {
+				char *end;
+
+				if ((*ptr == '+')&&(isdigit(ptr[1])))
+					insn->i_imm += strtoul(ptr, &end, 0);
+				else if ((*ptr == '+')&&(ptr[1] == '-')
+						&&(isdigit(ptr[2])))
+					insn->i_imm -= strtoul(ptr+2, &end, 0);
+				else if ((*ptr == '-')&&(isdigit(ptr[1])))
+					insn->i_imm -= strtoul(ptr+1, &end, 0);
+				else {
+					fprintf(stderr, "GAS: Cannot comprehend %s\n", ptr);
+					gas_assert((0)&&("Should never get here"));
+				}
+				ptr = (const char *)end;
+			}
+			if (('+' == *ptr)&&((err = zip_parse_reg(ptr+1, &insn->i_breg))==NULL)) {
+				// Let's skip to the end of the register
+				ptr++;
+				while(isalpha(*ptr))
+					ptr++;
+				while(isdigit(*ptr))
+					ptr++;
+			} else if (('(' == *ptr)&&((err = zip_parse_reg(ptr+1, &insn->i_breg))==NULL)) {
+				ptr++;
+				while((*ptr)&&(')' != *ptr))
+					ptr++;
+				ptr++;
+			} else {
+				// OOps!! Must've been a label + number
+				err = NULL;
+			}
+		}
+	} else if ((*lbl)&&(NULL == zip_parse_reg(lbl, &insn->i_breg))) {
+		// Form: Register (only)
+		insn->i_imm = 0;
+		// printf("OP-B ( \'%s\' ) Had a register, %s -> %d\n", bop,
+			// lbl, insn->i_breg);
+		*lbl = '\0';
+	} else if (*lbl) {
+		// Form: Label or Number (only)
+		insn->i_breg = ZIP_RNONE;
+	}
+
+	// Look for a +number at the end
+	if ((*ptr)&&((*ptr == '+')||(*ptr == '-'))) {
+		// printf("Looking at a plus: %s\n", ptr);
+		int	sgn = (*ptr == '-')?1:0;
+
+		if (sgn) {
+			// printf("... I meant a minus\n");
+			ptr++;
+		}
+
+		ptr = zip_skip_white_spaces(ptr);
+		if ('$' == *ptr)
+			ptr = zip_skip_white_spaces(ptr+1);
+
+		if ('+' == *ptr)
+			ptr++;
+		if ('-' == *ptr) {
+			sgn = !sgn;
+			ptr++;
+		}
+
+		ptr = zip_skip_white_spaces(ptr);
+		if ('$' == *ptr)
+			ptr = zip_skip_white_spaces(ptr+1);
+		if ('-' == *ptr) {
+			sgn = !sgn;
+			ptr++;
+		}
+
+		if ((*ptr)&&(isdigit(*ptr))) {
+			char *end = (char *)ptr;
+
+			// printf("Parsing #: %s\n", ptr);
+			// While the following might make the most sense,
+			//    if (sgn) *--ptr = '-';
+			// the string is read-only, so we can't change it.
+			// Instead we do ...
+			unsigned long v = (sgn)?
+				-strtoul(ptr, &end, 0) : strtoul(ptr, &end, 0);
+			insn->i_imm += v;
+			ptr = (const char *)end;
+		}
+	}
+
+	if (*lbl) {
+		// printf("i_rp = %s\n", (insn->i_rp)?"(Null)":"not NULL");
+		symbolS *sym = symbol_find_or_make(lbl);
+		sym->sy_flags.sy_used = TRUE;
+		// segT seg = S_GET_SEGMENT(sym);
+#ifdef	ZIP_DEBUG
+		zip_dump_sym(sym);
+#endif
+		if (insn->i_breg == ZIP_PC) {
+			// New pc-relative relocation,
+			// ???
+			// symbolP = symbol_create(FAKE_LABEL_NAME,
+				// absolute_section, 0 &zero_address_frag);
+			// symbol_set_value_expression(symbolP, expressionP);
+			// resolve_symbol_value(symbolP);
+			insn->i_rp =(ZIPRELOC *)xmalloc(sizeof(ZIPRELOC));
+			insn->i_rp->r_sym = sym;
+			insn->i_rp->r_pcrel = TRUE;
+			insn->i_rp->r_fr_offset = 0;
+			insn->i_rp->r_fix = NULL;
+			insn->i_rp->r_type = BFD_RELOC_ZIP_OPB_PCREL;
+			// symbol_make(name??)
+			// symbol_find_or_make(name)
+			// symbol_relc_make_sym
+			// symbol_relc_make_value
+			// symbol_find(name)
+			// symbol_find_noref(name, noref)
+			// symbol_find_exact(name)
+			// symbol_find_exact_noref(name, noref)
+			// symbol_find_or_make(name)
+			// symbol_make(name)
+			// symbol_new(name, seg, value, frag)
+			//	preferred call over symbol create
+			//	calls symbol_create internal
+			// symbol_create(name, segment, value, frag)
+			//
+			// local_symbol_make(name, section, value, frag)
+			// symbol_clone(sym, int)
+			// symbol_temp_new(seg, value, frag)
+			// symbol_temp_new_now(void)
+			// symbol_temp_make(void)
+			// colon(void)
+			//	Called when symbol: starts a line
+			//	Calls symbol_new(name, now_seg, frag_now_fix(),
+			//		frag_now);
+			//		symbol_table_insert(symbolP)
+			//
+			// expr_build_dot returns a symbol pointing to the 
+			//	current location ...
+			//
+			// Useful:
+			//	frag_now is current frag
+			//	S_SET_VALUE(symbolP, frag_now_fix()) ???
+			//	now_seg must be the current segment	
+			//	S_SET_SETGMENT(symbolP, now_seg);
+		/*
+		} else if((zip_param_got)&&(insn->i_breg == ZIP_GBL)) {
+			// New GOT-relative relocation
+			insn->i_rp =(ZIPRELOC *)xmalloc(sizeof(ZIPRELOC));
+			insn->i_rp->r_sym = sym;
+			insn->i_rp->r_pcrel = FALSE;
+			insn->i_rp->r_fr_offset = 0;
+			insn->i_rp->r_fix = NULL;
+		*/
+		} else {
+			insn->i_rp =(ZIPRELOC *)xmalloc(sizeof(ZIPRELOC));
+			insn->i_rp->r_sym = sym;
+			insn->i_rp->r_pcrel = FALSE;
+			insn->i_rp->r_fr_offset = 0;
+			insn->i_rp->r_fix = NULL;
+			if (insn->i_breg != ZIP_RNONE)
+				insn->i_rp->r_type = BFD_RELOC_ZIP_OPB_OFFSET;
+			else
+				insn->i_rp->r_type = BFD_RELOC_ZIP_OPB_IMM;
+		}
+	}
+
+	return 	err;
+}
+
+static const char *zip_parse(const char *line, ZIPIS *insn) {
+	const char	*err = NULL, *opstr = NULL;
+	char	*alt;
+	int	i;
+	char *cndp = NULL;
+	// Two (possible) tokens left:
+	//	the left of the comma, and the right of the comma
+	const char	*left, *right, *eol;
+	typedef enum	{
+		TWO_OP,		// Standard for most instructions
+		IMM_OP,		// Immediate operand only
+		BACKWARDS_TWO,	// Only used by STO REG,Off(REG)
+		NO_OP,		// Used by NOOP, BUSY, HALT, RTU, LOCK, etc
+		ONE_OR_TWO_OP,	// Only used by TST
+		MAYBE_ONE_IMM,	// Only used by BREAK, NOOP, SIM
+		MAYBE_ONE_REG,	// Only used by SDUMP, NDUMP
+		MAYBE_ONE_IMM_OR_REG,	// Only used by SEXIT, NEXIT, SOUT, NOUT
+		MAYBE_OPB,	// Only used by TRAP
+		ONE_REGISTER,	// Only used by CLR, CLRF, and NOT
+		OP_ADDRESS,	// Only used by BRA, BRA.C, and LINK
+		OP_B,		// Only used by JMP
+		TWO_REGISTER,	// Only used by FP instructions
+		ILLEGAL_FORM	// Never used, for debugging only
+	} FORMTYPE;
+
+	FORMTYPE	insn_form = ILLEGAL_FORM; // Make sure we set this
+
+
+
+#ifdef	ZIP_DEBUG
+	fprintf(stderr, "\n**** Parsing %s\n", line);
+#endif
+
+	insn->i_naux = 0;
+	insn->i_op   = ZIPO_NOOP;
+	insn->i_cnd  = ZIPC_ALWAYS;
+	insn->i_areg = ZIP_RNONE;
+	insn->i_breg = ZIP_RNONE;
+	insn->i_imm  = 0;
+	insn->i_rp   = NULL;
+	insn->i_code = NOOP_OPCODE;
+	for(i=0; i<ZIP_MAX_NAUX; i++)
+		insn->i_aux[i]  = NOOP_OPCODE;
+
+	// The opcode is given between whitespace and a period, or whitespace
+	// and whitespace
+	alt = strdup(zip_skip_white_spaces(line));
+	if ((*alt)=='[') {
+		// Instruction starts with condition codes-- a feature we
+		// needed to add in order to support GCC conditional execution
+		// macro
+		cndp = strtok(alt,"] \t")+1;
+		if (!cndp)
+			return "Mismatched parenthesis--an attempt at a condition?";
+		if (strlen(cndp) > 3)
+			return "Invalid condition (too long)";
+
+		opstr = strtok(NULL, " \t");
+		if (!opstr)
+			return "Condition not followed by valid opcode";
+	} else {
+		opstr = strtok(alt, " \t"); // Get our opcode
+		if (!opstr) {
+			free(alt);
+			return "Invalid Instruction";
+		}
+	}
+	// See if our token contains a '.' within it
+	//	GCC allows conditions beginning a line, as in ...
+	//		(CND)	Opcode	B,A
+	//	such a condition, if present, was detected above.
+	//
+	//	If not, we now look for a condition written in our original
+	//	format of ...
+	//		Opcode.CND B,A
+	//	and we look for it here.
+	//
+	if (!cndp) {
+		cndp = strchr(opstr, '.');
+		// If we found such a condition, we need to fix the opstr
+		// so that it no longer includes the condition.  Hence, let's
+		// place a NULL within the alt string and push our condition
+		// forward to the first non '.' value.
+		if (cndp)
+			*cndp++ = '\0';
+	}
+	if (strcasecmp(opstr, "SUB")==0) {
+		insn->i_op = ZIPO_SUB;
+		insn_form = TWO_OP;
+	} else if (strcasecmp(opstr, "AND")==0) {
+		insn->i_op = ZIPO_AND;
+		insn_form = TWO_OP;
+	} else if (strcasecmp(opstr, "ADD")==0) {
+		insn->i_op = ZIPO_ADD;
+		insn_form = TWO_OP;
+	} else if (strcasecmp(opstr, "OR")==0) {
+		insn->i_op = ZIPO_OR;
+		insn_form = TWO_OP;
+	} else if (strcasecmp(opstr, "XOR")==0) {
+		insn->i_op = ZIPO_XOR;
+		insn_form = TWO_OP;
+	} else if (strcasecmp(opstr, "LSR")==0) {
+		insn->i_op = ZIPO_LSR;
+		insn_form = TWO_OP;
+	} else if (strcasecmp(opstr, "LSL")==0) {
+		insn->i_op = ZIPO_LSL;
+		insn_form = TWO_OP;
+	} else if (strcasecmp(opstr, "ASR")==0) {
+		insn->i_op = ZIPO_ASR;
+		insn_form = TWO_OP;
+	} else if (strcasecmp(opstr, "BREV")==0) {
+		insn->i_op = ZIPO_BREV;			// BREV b+Rb,Ra, or
+		insn_form = ONE_OR_TWO_OP;		// BREV Rx -> BREV Rx,Rx
+	} else if((strcasecmp(opstr, "LDILO")==0)
+			||(strcasecmp(opstr, "LLO")==0)) {
+		insn->i_op = ZIPO_LDILO;
+		insn_form = TWO_OP;
+	} else if (strcasecmp(opstr, "MPYUHI")==0) {	// MPUHI
+		insn->i_op = ZIPO_MPYUHI;
+		insn_form = TWO_OP;
+	} else if (strcasecmp(opstr, "MPYSHI")==0) {	// MPSHI
+		insn->i_op = ZIPO_MPYSHI;
+		insn_form = TWO_OP;
+	} else if (strcasecmp(opstr, "MPY")==0) {
+		insn_form = TWO_OP;
+		insn->i_op = ZIPO_MPY;
+	} else if (strcasecmp(opstr, "MOV")==0) {
+		insn->i_op = ZIPO_MOV;
+		insn_form = TWO_OP;
+	} else if (strcasecmp(opstr, "DIVU")==0) {
+		insn->i_op = ZIPO_DIVU;
+		insn_form = TWO_OP;
+	} else if (strcasecmp(opstr, "DIVS")==0) {
+		insn->i_op = ZIPO_DIVS;
+		insn_form = TWO_OP;
+	} else if (strcasecmp(opstr, "CMP")==0) {
+		insn->i_op = ZIPO_CMP;
+		insn_form = TWO_OP;
+	} else if ((strcasecmp(opstr, "TST")==0)
+		||(strcasecmp(opstr, "TEST")==0)) {
+		insn->i_op = ZIPO_TST;			// TST b+Rb,Ra, or
+		insn_form = ONE_OR_TWO_OP;		// TST Rx -> TST -1,Rx
+	} else if (strcasecmp(opstr, "LW")==0) {
+		insn->i_op = ZIPO_LW;
+		insn_form = TWO_OP;
+	} else if (strcasecmp(opstr, "SW")==0) {
+		insn->i_op = ZIPO_SW;
+		insn_form = BACKWARDS_TWO;
+	} else if (strcasecmp(opstr, "LH")==0) {
+		insn->i_op = ZIPO_LH;
+		insn_form = TWO_OP;
+	} else if (strcasecmp(opstr, "SH")==0) {
+		insn->i_op = ZIPO_SH;
+		insn_form = BACKWARDS_TWO;
+	} else if (strcasecmp(opstr, "LB")==0) {
+		insn->i_op = ZIPO_LB;
+		insn_form = TWO_OP;
+	} else if (strcasecmp(opstr, "SB")==0) {
+		insn->i_op = ZIPO_SB;
+		insn_form = BACKWARDS_TWO;
+	} else if (strcasecmp(opstr, "LDI")==0) {
+		insn->i_op = ZIPO_LDI;
+		insn_form = IMM_OP;
+	} else if (strcasecmp(opstr, "FPADD")==0) {
+		insn->i_op = ZIPO_FPADD;
+		insn_form = TWO_REGISTER;
+	} else if (strcasecmp(opstr, "FPSUB")==0) {
+		insn->i_op = ZIPO_FPSUB;
+		insn_form = TWO_REGISTER;
+	} else if (strcasecmp(opstr, "FPMUL")==0) {
+		insn->i_op = ZIPO_FPMPY;
+		insn_form = TWO_REGISTER;
+	} else if (strcasecmp(opstr, "FPDIV")==0) {
+		insn->i_op = ZIPO_FPDIV;
+		insn_form = TWO_REGISTER;
+	} else if (strcasecmp(opstr, "FPI2F")==0) {
+		insn->i_op = ZIPO_FPI2F;
+		insn_form = TWO_OP;
+	} else if (strcasecmp(opstr, "FPF2I")==0) {
+		insn->i_op = ZIPO_FPF2I;
+		insn_form = TWO_REGISTER;
+	} else if ((strcasecmp(opstr, "BRK")==0)
+		||(strcasecmp(opstr, "BREAK")==0)) {
+		insn->i_op = ZIPO_BREAK;
+		insn->i_imm= 0;
+		insn_form = MAYBE_ONE_IMM;
+	} else if (strcasecmp(opstr, "LOCK")==0) {
+		insn->i_op = ZIPO_LOCK;
+		insn_form = NO_OP;
+	// Now for some derived instructions
+	} else if (strcasecmp(opstr, "TRAP")==0) {
+		insn->i_op = ZIPO_TRAP;
+		insn_form = MAYBE_OPB;
+	} else if (strcasecmp(opstr, "CLR")==0) {
+		insn->i_op = ZIPO_CLR;
+		insn_form = ONE_REGISTER;
+	} else if (strcasecmp(opstr, "BRA")==0) {
+		insn->i_op = ZIPO_BRA;
+		insn_form = OP_ADDRESS;
+	} else if (strcasecmp(opstr, "LJMP")==0) {
+		insn->i_op = ZIPO_LJMP;
+		insn->i_breg = ZIP_RNONE;
+		insn->i_imm  = 0;
+		insn_form = OP_ADDRESS;
+	} else if (strcasecmp(opstr, "BZ")==0) {
+		insn->i_op = ZIPO_BRA;
+		insn->i_cnd = ZIPC_Z;
+		insn_form = OP_ADDRESS;
+	} else if (strcasecmp(opstr, "BLT")==0) {
+		insn->i_op = ZIPO_BRA;
+		insn->i_cnd = ZIPC_LT;
+		insn_form = OP_ADDRESS;
+	} else if (strcasecmp(opstr, "BC")==0) {
+		insn->i_op = ZIPO_BRA;
+		insn->i_cnd = ZIPC_C;
+		insn_form = OP_ADDRESS;
+	} else if (strcasecmp(opstr, "BV")==0) {
+		insn->i_op = ZIPO_BRA;
+		insn->i_cnd = ZIPC_V;
+		insn_form = OP_ADDRESS;
+	} else if (strcasecmp(opstr, "BNZ")==0) {
+		insn->i_op = ZIPO_BRA;
+		insn->i_cnd = ZIPC_NZ;
+		insn_form = OP_ADDRESS;
+	} else if (strcasecmp(opstr, "BGE")==0) {
+		insn->i_op = ZIPO_BRA;
+		insn->i_cnd = ZIPC_GE;
+		insn_form = OP_ADDRESS;
+	} else if (strcasecmp(opstr, "BNC")==0) {
+		insn->i_op = ZIPO_BRA;
+		insn->i_cnd = ZIPC_NC;
+		insn_form = OP_ADDRESS;
+	} else if (strcasecmp(opstr, "HALT")==0) {
+		insn->i_op = ZIPO_HALT;
+		insn->i_imm = ZIP_CC_SLEEP;
+		insn->i_areg= ZIP_CC;
+		insn_form = NO_OP;
+	} else if (strcasecmp(opstr, "WAIT")==0) {
+		insn->i_op = ZIPO_WAIT;
+		insn->i_imm = ZIP_CC_SLEEP | ZIP_CC_GIE;
+		insn->i_areg= ZIP_CC;
+		insn_form = NO_OP;
+	} else if (strcasecmp(opstr, "STEP")==0) {
+		insn->i_op = ZIPO_STEP;
+		insn->i_imm = ZIP_CC_STEP | ZIP_CC_GIE;
+		insn->i_areg= ZIP_CC;
+		insn_form = NO_OP;
+	} else if ((strcasecmp(opstr, "RTU")==0)
+			||(strcasecmp(opstr, "IRET")==0)) {
+		insn->i_op = ZIPO_RTU;
+		insn->i_imm = ZIP_CC_GIE;
+		insn->i_areg = ZIP_CC;
+		insn_form = NO_OP;
+	} else if (strcasecmp(opstr, "BUSY")==0) {
+		insn->i_op = ZIPO_BUSY;
+		insn->i_imm= -4;
+		insn->i_areg = ZIP_PC;
+		insn->i_breg = ZIP_RNONE;
+		insn_form = NO_OP;
+	} else if (strcasecmp(opstr, "JMP")==0) {
+		insn->i_op = ZIPO_JMP;
+		insn->i_areg = ZIP_PC;
+		insn_form = OP_B;
+	} else if ((strcasecmp(opstr, "RETN")==0)
+			||(strcasecmp(opstr, "RTN")==0)) {
+		insn->i_op = ZIPO_JMP;
+		insn->i_areg = ZIP_PC;
+		insn->i_breg = ZIP_LR;
+		insn->i_imm  = 0;
+		insn_form = NO_OP;
+	} else if (strcasecmp(opstr, "NOT")==0) {
+		insn->i_op = ZIPO_NOT;
+		insn->i_imm = -1;
+		insn_form = ONE_REGISTER;
+	} else if (strcasecmp(opstr, "NEG")==0) {
+		insn->i_op = ZIPO_NEG;
+		insn->i_imm = 0;
+		insn_form = ONE_OR_TWO_OP;
+	} else if (strcasecmp(opstr, "LJSR")==0) {
+		insn->i_op   = ZIPO_LJSR;
+		insn->i_breg = ZIP_RNONE;
+		insn->i_imm  = 0;
+		insn_form    = OP_ADDRESS;
+	} else if (strcasecmp(opstr, "JSR")==0) {
+		insn->i_op = ZIPO_JSR;
+		insn->i_imm = 0;
+		insn_form = OP_ADDRESS;
+	} else if ((strcasecmp(opstr, "NOP")==0)
+			||(strcasecmp(opstr, "NOOP")==0)) {
+		insn->i_op = ZIPO_NOOP;
+		insn_form = MAYBE_ONE_IMM;
+	} else if (strcasecmp(opstr, "SIM")==0) {
+		insn->i_op = ZIPO_SIM;
+		insn->i_imm= 0;
+		insn_form = MAYBE_ONE_IMM;
+	} else if (strcasecmp(opstr, "SNOOP")==0) {
+		insn->i_op = ZIPO_SIM;
+		insn->i_imm= 0;
+		insn_form = MAYBE_ONE_IMM;
+	} else if (strcasecmp(opstr, "SDUMP")==0) {
+		insn->i_op = ZIPO_SDUMP;
+		insn->i_imm= 0;
+		insn_form = MAYBE_ONE_REG;
+	} else if (strcasecmp(opstr, "SEXIT")==0) {
+		insn->i_op = ZIPO_SEXIT;
+		insn->i_imm= 0;
+		insn_form = MAYBE_ONE_IMM_OR_REG;
+	} else if (strcasecmp(opstr, "SOUT")==0) {
+		insn->i_op = ZIPO_SOUT;
+		insn->i_imm= 0;
+		insn_form = MAYBE_ONE_IMM_OR_REG;
+	} else if (strcasecmp(opstr, "NDUMP")==0) {
+		insn->i_op = ZIPO_NDUMP;
+		insn->i_imm= 0;
+		insn_form = MAYBE_ONE_REG;
+	} else if (strcasecmp(opstr, "NEXIT")==0) {
+		insn->i_op = ZIPO_NEXIT;
+		insn->i_imm= 0;
+		insn_form = MAYBE_ONE_IMM_OR_REG;
+	} else if (strcasecmp(opstr, "SEXTB")==0) {
+		insn->i_op = ZIPO_SEXTB;
+		insn->i_imm= 0;
+		insn_form = ONE_REGISTER;
+	} else if (strcasecmp(opstr, "SEXTH")==0) {
+		insn->i_op = ZIPO_SEXTH;
+		insn->i_imm= 0;
+		insn_form = ONE_REGISTER;
+	} else if (strcasecmp(opstr, "NOUT")==0) {
+		insn->i_op = ZIPO_NOUT;
+		insn->i_imm= 0;
+		insn_form = MAYBE_ONE_IMM_OR_REG;
+	} else {
+		free(alt);
+		return "Unrecognized op-code";
+	}
+
+	if (cndp) {
+		// We have a condition
+		if (insn->i_cnd != ZIPC_ALWAYS) {
+			err = "Instruction cannot take an additional condition";
+		} else {
+			err = zip_parse_condition(cndp, &insn->i_cnd);
+		}
+	} if (err) {
+		free(alt);
+		return err;
+	}
+
+	if (strchr(line, ',')!=NULL)
+		left = strtok(NULL, ",");
+	else
+		left  = strtok(NULL, " \t,");
+	right = (left)  ? strtok(NULL, " \t") : NULL;
+	eol   = (right) ? strtok(NULL, " \t") : NULL;
+	if (eol != NULL) {
+		free(alt);
+		return "Too many tokens on one line";
+	}
+
+	switch(insn_form) {
+		case TWO_OP:
+			err = zip_parse_bop(left,insn);
+			if (!err)
+				err = zip_parse_reg(right,&insn->i_areg);
+			break;
+		case IMM_OP:
+			err = zip_parse_bop(left,insn);
+			if ((!err)&&(insn->i_breg == ZIP_RNONE))
+				err = zip_parse_reg(right,&insn->i_areg);
+			else if (!err)
+				err = "LDI can only load immediates, not registers";
+			break;
+		case BACKWARDS_TWO:
+			err = zip_parse_reg(left,&insn->i_areg);
+			if (!err)
+				err = zip_parse_bop(right,insn);
+			break;
+		case MAYBE_ONE_IMM:
+			if (NULL != right)
+				err = "Wrong number of operands!";
+			else if (left) {
+				err = zip_parse_bop(left,insn);
+				if ((!err)&&(insn->i_breg != ZIP_RNONE))
+					err = "BREAK arguments can only be immediates";
+			}
+			break;
+		case MAYBE_ONE_IMM_OR_REG:
+			if (NULL != right)
+				err = "Wrong number of operands!";
+			else if (left) {
+				err = zip_parse_bop(left,insn);
+				if ((!err)&&(insn->i_breg != ZIP_RNONE)
+					&&(insn->i_imm != 0))
+					err = "EXIT arguments can only be immediates or register, not both";
+			}
+			break;
+		case MAYBE_ONE_REG:
+			if (NULL != right)
+				err = "Wrong number of operands!";
+			else if (left) {
+				err = zip_parse_bop(left,insn);
+				if ((!err)&&(insn->i_breg != ZIP_RNONE)&&(insn->i_imm))
+					err = "xDUMP instructions can handle immediates or registers, not both";
+			} else {
+				insn->i_breg = ZIP_RNONE;
+				insn->i_imm  = 0;
+			} break;
+		case NO_OP:
+			if ((NULL != left)||(NULL != right))
+				err = "Wrong number of operands!";
+			break;
+		case ONE_OR_TWO_OP:
+			// This is a reference to the test instruction, which
+			// can either be
+			//	A. TEST a,Rx, or TEST Rx,.
+			// or	B. BRA  a,Rx, or BRA Rx,.
+			if (NULL != right) {
+				err = zip_parse_bop(left,insn);
+				if (!err)
+					err = zip_parse_reg(right,&insn->i_areg);
+				if (!err)
+					err = zip_parse_bop(left,insn);
+			} else {
+				zip_parse_reg(left, &insn->i_areg);
+				if (insn->i_op == ZIPO_BREV) {
+					insn->i_breg = insn->i_areg;
+					insn->i_imm = 0;
+				} else {
+					insn->i_breg = ZIP_RNONE;
+					insn->i_imm = -1;
+				}
+			} break;
+		case ONE_REGISTER:
+			// CLR, CLRF, or NOT
+			insn->i_breg = ZIP_RNONE;
+			if (NULL != right)
+				err = "Instruction opcode expects only one operand";
+			else
+				err = zip_parse_reg(left,&insn->i_areg);
+			break;
+		case OP_ADDRESS:
+			// JSR or BRA instruction
+			//	This is different from OP_B below, in that this
+			//	form implies a PC relative addressing, which
+			//	may not be clear from the operands given
+			if (NULL != right)
+				err = "Instruction opcode expects only one operand";
+			else {
+				if ((NULL == left)||(left[0] == '\0')) {
+					err = "No address given";
+				} else if ((NULL == strchr(left,'('))
+					&&(NULL == strchr(left,'+'))) {
+					char	*longerstr = (char *)xmalloc(strlen(left)+6);
+					// If not stated, assume PC relative
+					strcpy(longerstr,left);
+					strcat(longerstr, "(PC)");
+					err = zip_parse_bop(longerstr, insn);
+					free(longerstr);
+				} else
+					err = zip_parse_bop(left, insn);
+			}
+			
+			break;
+		case MAYBE_OPB:
+			// JMP or TRAP instruction
+			if (NULL != right)
+				err = "Instruction opcode expects only one operand";
+			else if (NULL == left) {
+				insn->i_breg = ZIP_RNONE;
+				insn->i_imm = 0;
+				break;
+			} // Fall through
+		case OP_B: // Operand B only (A is implied)
+			// JMP or TRAP instruction
+			if (NULL != right)
+				err = "Instruction opcode expects only one operand";
+			else
+				err = zip_parse_bop(left, insn);
+			if (insn->i_op == ZIPO_JMP)
+				insn->i_areg = ZIP_PC;
+			else // if insn->i_op == TRAP
+				insn->i_areg = ZIP_CC;
+			break;
+		case TWO_REGISTER:
+			// These are the floating point instructions, which
+			// can't handle immediate offsets.
+			err = zip_parse_reg(right, &insn->i_areg);
+			if (!err)
+				err = zip_parse_reg(left, &insn->i_breg);
+			break;
+		default:	// case ILLEGAL_FORM
+			err = "Unknown instruction format!";
+			break;
+	}
+
+	if (err)
+		return (err);
+
+	switch(insn->i_op) {
+		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_BREV:
+		case ZIPO_MPYUHI: case ZIPO_MPYSHI:
+		case ZIPO_MPY:
+			break;
+		case ZIPO_LDILO:
+			if (!fits_within(16, insn->i_imm))
+				gas_assert((insn->i_imm & (~0x0ffff))==0);
+			insn->i_imm &= 0x0ffff;
+			break;
+		case ZIPO_DIVU: case ZIPO_DIVS:
+			if (0x0e == (insn->i_areg & 0x0f))
+				err = "Divide instructions cannot result in CC or PC regs";
+			else if (insn->i_rp)
+				err = "Relocations not applicable for divides";
+			break;
+			break;
+		case ZIPO_MOV:
+			if (insn->i_breg == ZIP_RNONE)
+				insn->i_op = ZIPO_LDI;
+			break;
+		case ZIPO_CMP: case ZIPO_TST:
+			break;
+		case ZIPO_LW: case ZIPO_SW:
+		case ZIPO_LH: case ZIPO_SH:
+		case ZIPO_LB: case ZIPO_SB:
+			break;
+		case ZIPO_LDI: case ZIPO_LDIn:
+			break;
+		case ZIPO_FPADD: case ZIPO_FPSUB:
+		case ZIPO_FPMPY: case ZIPO_FPDIV:
+		case ZIPO_FPF2I: case ZIPO_FPI2F:
+			if (0x0e == (insn->i_areg & 0x0f))
+				err = "Floating point operations cannot result in CC or PC regs";
+			else if (insn->i_rp)
+				err = "Relocations not applicable for floating point ops";
+			break;
+		case ZIPO_TRAP:
+			insn->i_areg = ZIP_CC;
+			if (insn->i_breg == ZIP_RNONE) {
+				// TRAP instructions *ALWAYS* clear the GIE bit
+				insn->i_imm &= (~0x0020);
+				if (insn->i_cnd == ZIPC_ALWAYS)
+					insn->i_op = ZIPO_LDI;
+				else if (fits_within(16, insn->i_imm))
+					insn->i_op = ZIPO_LDILO;
+				else if (fits_within(18, zip_brev(insn->i_imm)))
+					insn->i_op = ZIPO_BREV;
+				else
+					err = "TRAP 18+ bit immediate not supported";
+			} else
+				insn->i_op = ZIPO_MOV;
+			break;
+		case ZIPO_CLR:
+			insn->i_op = ZIPO_LDI;
+			insn->i_imm = 0;
+			break;
+		case ZIPO_JMP:
+			if (insn->i_breg != ZIP_RNONE)
+				insn->i_op = ZIPO_MOV;	// JMP A+Rx
+			else
+				insn->i_op = ZIPO_BRA;	// JMP lbl = BRA lbl
+			// Fall through
+		case ZIPO_BRA: // Leave as ZIPO_BRA until we assemble it
+			insn->i_areg = ZIP_PC;
+			break;
+		case ZIPO_HALT: case ZIPO_WAIT: case ZIPO_RTU: case ZIPO_STEP:
+			insn->i_op = ZIPO_OR;
+			break;
+		case ZIPO_BUSY:
+			insn->i_op = ZIPO_ADD;
+			break;
+		case ZIPO_NOT:
+			insn->i_op = ZIPO_XOR;
+			insn->i_imm  = -1;
+			insn->i_breg = ZIP_RNONE;
+			break;
+		case ZIPO_NEG:
+			if (insn->i_breg == ZIP_RNONE) {
+				insn->i_breg = insn->i_areg;
+				// This would've been set to -1 by the ONE or
+				// TWO op code.  Here, we set it back to zero.
+				insn->i_imm  = 0;
+			}
+			// insn->i_op = ZIPO_NEG; /// Can't collapse this yet
+			break;
+		case ZIPO_BREAK:
+			insn->i_op = ZIPO_BREAK;
+			insn->i_areg = ZIP_RNONE;
+			insn->i_breg = ZIP_RNONE;
+			// insn->i_imm  = ... whatever it was set to
+			break;
+		case ZIPO_LOCK:
+			insn->i_op = ZIPO_LOCK;
+			insn->i_areg = ZIP_RNONE;
+			insn->i_breg = ZIP_RNONE;
+			insn->i_imm  = 0;
+			break;
+		case ZIPO_SDUMP:
+			insn->i_op = ZIPO_SIM;
+			if (insn->i_breg != ZIP_RNONE) {
+				insn->i_imm = (int)insn->i_breg + 0x0200;
+				insn->i_breg = ZIP_RNONE;
+			} else
+				insn->i_imm = 0x2ff;
+			break;
+		case ZIPO_NDUMP:
+			insn->i_op = ZIPO_NOOP;
+			if (insn->i_breg != ZIP_RNONE) {
+				insn->i_imm = (int)insn->i_breg + 0x0200;
+				insn->i_breg = ZIP_RNONE;
+			} else
+				insn->i_imm = 0x2ff;
+			break;
+		case ZIPO_SEXIT:
+			insn->i_op = ZIPO_SIM;
+			if (insn->i_breg != ZIP_RNONE)
+				insn->i_imm = 0x300 + (insn->i_breg & 0x01f);
+			else
+				insn->i_imm = 0x100 + (insn->i_imm & 0x0ff);
+			insn->i_breg = ZIP_RNONE;
+			break;
+		case ZIPO_NEXIT:
+			insn->i_op = ZIPO_NOOP;
+			if (insn->i_breg != ZIP_RNONE)
+				insn->i_imm = 0x300 + (insn->i_breg & 0x01f);
+			else
+				insn->i_imm = 0x100 + (insn->i_imm & 0x0ff);
+			insn->i_breg = ZIP_RNONE;
+			break;
+		case ZIPO_SOUT:
+			insn->i_op = ZIPO_SIM;
+			if (insn->i_breg != ZIP_RNONE)
+				insn->i_imm = 0x220 + (insn->i_breg & 0x01f);
+			else
+				insn->i_imm = 0x400 + (insn->i_imm & 0x0ff);
+			insn->i_breg = ZIP_RNONE;
+			break;
+		case ZIPO_NOUT:
+			insn->i_op = ZIPO_NOOP;
+			if (insn->i_breg != ZIP_RNONE)
+				insn->i_imm = 0x220 + (insn->i_breg & 0x01f);
+			else
+				insn->i_imm = 0x400 + (insn->i_imm & 0x0ff);
+			insn->i_breg = ZIP_RNONE;
+			break;
+		case ZIPO_SIM:
+		case ZIPO_NOOP:
+			break;
+		case ZIPO_LJMP: case ZIPO_LJSR:
+			if (insn->i_breg == ZIP_PC)
+				insn->i_breg = ZIP_RNONE;
+			if (insn->i_breg != ZIP_RNONE) {
+				err = "Indirect long jumps and long JSRs are not supported";
+			} break;
+		case ZIPO_JSR:
+			break;
+		case ZIPO_SEXTB: case ZIPO_SEXTH:
+			break;
+		default:
+			return "Internal error -- unrecognized internal opcode";
+			break;
+	} if (err) {
+		free(alt);
+		return err;
+	}
+
+	if ((insn->i_op != ZIPO_MOV)&&(
+			((insn->i_areg != ZIP_RNONE)&&(insn->i_areg >= 0x10))
+			||((insn->i_breg != ZIP_RNONE)&&(insn->i_breg >= 0x10)))) {
+		if (insn->i_rp)
+			free(insn->i_rp);
+		insn->i_rp = NULL;
+		free(alt);
+		return "Only MOV instructions can reference explicit user registers";
+	}
+
+	free(alt);
+
+	// We do nothing more to build the opcode here --- all we are doing
+	// is parsing.
+	return err;
+}
+
+#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)	\
+			| (((CND)&0x07)<<19)|(1<<18)|(((B)&0x0f)<<14)	\
+			| ((IMM) & 0x03fff))
+#define	SMPLMOV(CND,IMM,B,A)	(((ZIPO_MOV&0x01f)<<22)|(((A)&0x0f)<<27)	\
+			| (((CND)&0x07)<<19)|(((B)&0x0f)<<14)|((IMM) & 0x01fff))
+#define	IMMOP(OP,CND,IMM,A)	((((OP)&0x01f)<<22)|(((A)&0x0f)<<27)	\
+			| (((CND)&0x07)<<19)|((IMM) & 0x03ffff))
+#define	LDIOP(IMM,A)	((ZIPO_LDI<<22)|(((A)&0x0f)<<27)|((IMM) & 0x07fffff))
+
+
+/*
+ *	CIS support code
+ *
+ *	Assuming that the instruction (a) is not a CIS instruction, this looks
+ *	up the immediate value encoded in the instruction.  The purpose is to
+ *	determine whether or not this instruction can be merged with the 
+ *	previous (or next) instruction in CIS mode.
+ *
+ */
+static int
+zip_non_cis_immediate(const unsigned a)
+{
+	ZIP_OPCODE	op = (ZIP_OPCODE)((a>>22)&0x1f);
+	int		imm;
+
+	switch(op) {
+		case	ZIPO_MOV:
+			imm = (a & 0x01fff); if (a&0x1000) imm |= -0x1000; break;
+		case	ZIPO_LDI: 
+			imm = (a & 0x03fffff); break;
+		case	ZIPO_LDIn:
+			imm = (a & 0x03fffff); imm |= -0x0200000; break;
+/*
+ * While this makes conceptual sense, it doesn't match the CPU.  Hence let's
+ * comment it out and make certain things still work.
+		case	ZIPO_LDILO:
+#ifndef	LONG_MPY
+		case ZIPO_LDIHI: // BREVx would rm LDIHI
+#endif
+			imm = (a & 0x0ffff); break;
+*/
+		default:
+			if (a & 0x040000) {
+				imm = (a & 0x03fff);
+				if (a & 0x2000) imm |= -0x02000;
+			} else {
+				imm = (a & 0x03ffff);
+				if (a & 0x020000)
+					imm |= -0x020000;
+			}
+	}
+
+	return imm;
+}
+
+static int
+zip_can_merge(const unsigned a, const unsigned b)
+{
+	// Can't merge instructions if merging isnt turned on
+	if (!zip_param_cis)
+		return 0;
+
+	// 1. Can't merge anything that's already merged
+	if ((a|b) & 0x80000000)
+		return 0;
+
+	ZIP_OPCODE	opa, opb;
+	ZIP_CONDITION	ac, bc;
+	int	imma, immb;
+
+	// Get the 5-bit operands for each
+	opa = (a>>22)&0x1f;
+	opb = (b>>22)&0x1f;
+
+	// 2. Can only merge if both are unconditional
+	ac = ((a>>19)&0x07);
+	bc = ((b>>19)&0x07);
+	if ((opa != ZIPO_LDI)&&(opa != ZIPO_LDIn)&&(ac != ZIPC_ALWAYS))
+		return 0;
+	if ((opb != ZIPO_LDI)&&(opb != ZIPO_LDIn)&&(bc != ZIPC_ALWAYS))
+		return 0;
+
+	// Only some instructions can be merged
+	switch(opa) {
+		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_LDIn:
+			break;
+		default:
+			return 0;
+	} switch(opb) {
+		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_LDIn:
+			break;
+		default:
+			return 0;
+	}
+
+	// Prohibit moves to/from user regs to merge
+	if ((opa == ZIPO_MOV)&&(a & 0x42000))
+		return 0;
+	if ((opb == ZIPO_MOV)&&(b & 0x42000))
+		return 0;
+
+	imma = zip_non_cis_immediate(a);
+	immb = zip_non_cis_immediate(b);
+
+	if (!fits_within(8,imma)) {
+		return 0;
+	} if (!fits_within(8,immb)) {
+		return 0;
+	}
+
+	// if abreg & 0x010, or bbreg & 0x010, then the register is being
+	// used.
+	int aareg = (a>>27)&0x00f;
+	int abreg = (a>>14)&0x01f;
+	int bbreg = (b>>14)&0x01f;
+
+	switch(opa) {
+		case ZIPO_MOV:
+			if (!fits_within(3,imma))
+				return 0;
+			// 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;
+			break;
+		case ZIPO_LDI: case ZIPO_LDIn:
+			if (!fits_within(8,imma))
+				return 0;
+			if (aareg == ZIP_CC)
+				return 0;
+			break;
+		case ZIPO_ADD: case ZIPO_SUB: case ZIPO_AND:
+			if (aareg == ZIP_CC)
+				return 0;
+		case ZIPO_CMP:
+			if ((abreg&0x10)==0) {
+				if (!fits_within(7,imma)) {
+					return 0;
+				}
+			} else { // if (abreg&0x10)
+				if (!fits_within(3,imma))
+					return 0;
+			} break;
+		case ZIPO_LW: case ZIPO_SW:
+			if (aareg == ZIP_CC)
+				return 0;
+			if ((abreg&0x010)==0) {
+				return 0;
+			} else if (abreg== 0x10 + ZIP_SP) {
+				if (!fits_within(7,imma))
+					return 0;
+			} else {
+				if (!fits_within(3,imma))
+					return 0;
+			} break; 
+		default:
+			fprintf(stderr, "Unknown op, %d\n", opa);
+			return 0;
+	}
+
+	switch(opb) {
+		case ZIPO_MOV:
+			if (!fits_within(3,immb)) {
+				return 0;
+			} break;
+		case ZIPO_LDI: case ZIPO_LDIn:
+			if (!fits_within(8,immb)) {
+				return 0;
+			} break;
+		case ZIPO_ADD: case ZIPO_SUB: case ZIPO_CMP: case ZIPO_AND:
+			if ((bbreg&0x10)==0) {
+				if (!fits_within(7,immb))
+					return 0;
+			} else { // if (bbreg&0x10)
+				if (!fits_within(3,immb))
+					return 0;
+			} break;
+		case ZIPO_LW: case ZIPO_SW:
+			if ((bbreg&0x010)==0) {
+				return 0;
+			} else if (bbreg== 0x10+ZIP_SP) {
+				if (!fits_within(7,immb))
+					return 0;
+			} else { 
+				if (!fits_within(3,immb))
+					return 0;
+			} break;
+		default:
+			return 0;
+	}
+
+	return 1;
+}
+
+static unsigned
+zip_insn_merge(const unsigned a, const unsigned b)
+{
+	// 1. We already know we can merge these, so skip our can-merge checks
+	ZIP_OPCODE	opa, opb;
+	unsigned int	retv = 0;
+
+	// Get our two opcodes
+	opa = (a>>22)&0x1f; opb = (b>>22)&0x1f;
+
+	// Truncate LDI opcodes back to their original values
+	if (opa == 0x019) opa = 0x018;
+	if (opb == 0x019) opb = 0x018;
+	retv = 0x80008000;
+
+	// Start with the destination registers
+	retv |= (a & 0x78000000);
+	retv |= (b & 0x78000000) >> (27-11);
+
+	// Then the new OpCodes
+	switch(opa) {
+	case ZIPO_SUB:	retv |= (ZIPV_SUB<<24); break;
+	case ZIPO_AND:	retv |= (ZIPV_AND<<24); break;
+	case ZIPO_ADD:	retv |= (ZIPV_ADD<<24); break;
+	case ZIPO_CMP:	retv |= (ZIPV_CMP<<24); break;
+	case ZIPO_LW:	retv |= (ZIPV_LW <<24); break;
+	case ZIPO_SW:	retv |= (ZIPV_SW <<24); break;
+// 8e40
+// 1.0001.110_0100_0000
+	case ZIPO_LDI:	retv |= (ZIPV_LDI<<24); break;
+	case ZIPO_MOV:	retv |= (ZIPV_MOV<<24); break;
+	default: gas_assert(0);
+	}
+
+	switch(opb) {
+	case ZIPO_SUB:	retv |= (ZIPV_SUB<<8); break;
+	case ZIPO_AND:	retv |= (ZIPV_AND<<8); break;
+	case ZIPO_ADD:	retv |= (ZIPV_ADD<<8); break;
+	case ZIPO_CMP:	retv |= (ZIPV_CMP<<8); break;
+	case ZIPO_LW:	retv |= (ZIPV_LW <<8); break;
+	case ZIPO_SW:	retv |= (ZIPV_SW <<8); break;
+	case ZIPO_LDI:	retv |= (ZIPV_LDI<<8); break;
+	case ZIPO_MOV:	retv |= (ZIPV_MOV<<8); break;
+	default: gas_assert(0);
+	}
+
+	// The new CIS has no condition codes
+
+	// Now for OpB, instruction A
+	if (opa == ZIPO_LDI)
+		retv |= (a & 0xff)<<16;
+	else if (opa == ZIPO_MOV) {
+		retv |= 1<<23;			// Using a register? always4mov
+		retv |= ((a>>14)&0x0f)<<19;	// OpB register
+		retv |= (a & 0x7)<<16;		// Offset
+	} else if(((opa == ZIPO_LW)||(opa == ZIPO_SW))
+			&&(((a>>14)&0x1f)==0x10 + ZIP_SP)) {
+		// 7-bit immediate for loads or stores referencing the stack
+		retv |= (a & 0x07f)<<16;
+	} else if ((a>>18)&1) {
+		// OpB ... with a register
+		retv |= 1<<23;			// Using a register?
+		retv |= ((a>>14)&0x0f)<<19;	// OpB register
+		retv |= (a&0x07)<<16;		// OpB constant
+	} else {
+		// OpB ... with constant offsets only
+		retv |= (a&0x07f)<<16;
+	}
+
+
+	// Now for OpB, instruction B
+	if (opb == ZIPO_LDI)
+		retv |= (b & 0xff);
+	else if (opb == ZIPO_MOV) {
+		retv |= (1<<7);			// Using a register? always4mov
+		retv |= ((b>>14)&0x0f)<<3;	// OpB register
+		retv |= (b & 0x7);		// Offset
+	} else if(((opb == ZIPO_LW)||(opb == ZIPO_SW))
+			&&(((b>>14)&0x1f)==0x10 + ZIP_SP)) {
+		retv |= (b & 0x07f);
+	} else if ((b>>18)&1) {
+		// OpB ... with a register
+		retv |= 1<<7;			// Using a register?
+		retv |= ((b>>14)&0x0f)<<3;	// OpB register
+		retv |= (b&0x07);		// OpB constant
+	} else {
+		// OpB ... with constant offsets only
+		retv |= (b&0x07f);
+	}
+
+	return retv;
+}
+
+void
+zip_check_label(symbolS *label ATTRIBUTE_UNUSED)
+{
+	// On any symbol, we need to make sure that we can jump to this
+	// address, therefore we cannot merge the previous instruction with
+	// another one that might follow.
+	cis_mergable = FALSE;
+	//
+	// Likewise, our shadow virtual machine values may be ... unknown
+	// upon any jump to this location.  Hence, we declare them unknown
+	// here.
+	zip_clear_machine(&zipm);
+}
+
+// UNITS:
+//	Offset	(target byte units)
+//	Address	(host byte units)
+//	Sym	(target byte units)
+//	Stretch	(target byte units)
+//
+static void
+zip_assemble_insn_words(fragS *fragP, segT seg, ZIPIS *insn, int relax_state,
+		long stretch, MACHINEREGS *pzipm)
+{
+#ifdef	ZIP_DEBUG
+fprintf(stderr, "ZIP-ASSEMBLE-INSN-WORDS\n");
+	zip_dump_insn(insn);
+	if ((insn->i_rp)||(relax_state))
+		zip_dump_sym(insn->i_rp->r_sym);
+#endif
+	unsigned long	symv = 0;
+	int	sym_defined = 0, this_segment = 0, sym_known = 0;
+	symbolS	*sym = NULL;
+	unsigned	immv = insn->i_imm;
+
+	if (insn->i_rp) {
+		fragS	*sym_frag;
+
+		sym = insn->i_rp->r_sym;
+		symv = ((sym)&&(S_IS_DEFINED(sym))) ? (S_GET_VALUE(sym)) : 0;
+		sym_frag = symbol_get_frag(sym);
+		this_segment = (S_GET_SEGMENT(sym) == seg);
+
+#ifdef	ZIP_DEBUG
+		fprintf(stderr, "SYMV(%s) = %08lx + %08lx -> %08lx\n",
+			S_GET_NAME(sym),
+			S_GET_VALUE(sym), fragP->fr_offset, 
+			S_GET_VALUE(sym) + fragP->fr_offset);
+#endif
+		symv += 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.
+		immv = 0;
+
+#ifdef	ZIP_DEBUG
+		{ 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 ");
+		}
+#endif
+
+		if ((stretch != 0)
+			&&( sym_frag->relax_marker != fragP->relax_marker)
+			&&(this_segment)) {
+			if ((stretch < 0)
+				||(sym_frag->region == fragP->region))
+				symv += stretch;
+			else if (symv < fragP->fr_address)
+				symv = fragP->fr_next->fr_address;
+		}
+	}
+
+	// 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
+	// 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,
+	// 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
+	// get at it via PC relative addressing.
+	//
+	// 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
+	// addressing.  However, we won't know until the fragment's are placed
+	// together to create this segment.  This will be before writing
+	// the file to disk.
+	//
+	// 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
+	// know (and won't know until the final link) where we are currently
+	// located within memory.
+	//
+	// The same is true of the undefined segment--we just don't know any
+	// PC offsets to that segment.
+	//
+	// But if the address is to a GOT segment, we should be able to assume
+	// it's offset from the beginning of that segment.
+	//
+	//
+	if ((relax_state)&&(insn->i_rp))
+		sym_defined = S_IS_DEFINED(insn->i_rp->r_sym);
+
+	/*
+	sym_known = (sym_defined)&&
+			((S_GET_SEGMENT(sym) == absolute_section)
+			||(S_GET_SEGMENT(sym) == expr_section)
+			||(this_frag)
+			||((this_segment)&&(fragP->fr_address != 0))
+			);
+	*/
+	sym_known = (sym_defined)&&(insn->i_rp->r_pcrel)&&(this_segment);
+	if ((!sym_known)&&(sym_defined)&&(!S_FORCE_RELOC(sym, 0))) {
+		if (this_segment)
+			sym_known = 1;
+		else if (S_GET_SEGMENT(sym)==absolute_section)
+			sym_known = 1;
+	}
+#ifdef	ZIP_DEBUG
+	if (sym_known)
+		fprintf(stderr, "%08lx@%08lx/%08lx - SYM(%s)-KNOWN %s%s%s%s%s\n",
+			(unsigned long)fragP->fr_literal,
+			fragP->fr_address,
+			(unsigned long)symv, S_GET_NAME(sym),
+			(S_GET_SEGMENT(sym) == absolute_section)?" abs":"",
+			(S_GET_SEGMENT(sym) == expr_section)?" expr":"",
+			(symbol_get_frag(sym)==fragP)?" this-frag ":"",
+			((this_segment)&&(fragP->fr_address != 0))?" this-seg ":"",
+			insn->i_rp->r_pcrel?" (PC-REL)":" (ABS)");
+	else if (insn->i_rp)
+		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)symv, S_GET_NAME(sym),
+			(!sym_defined)?"-- not defined":"",
+			(S_GET_SEGMENT(sym) == absolute_section)?" abs":"",
+			(S_GET_SEGMENT(sym) == expr_section)?" expr":"",
+			(symbol_get_frag(sym)==fragP)?" this-frag ":"",
+			(this_segment)?" this-seg ":"",
+			((this_segment)&&(fragP->fr_address != 0))?" this-off ":""
+			);
+
+	fprintf(stderr, "SYM-DEF %d,%d,%d,%d, IMM = %08x\n",
+		sym_defined, sym_known,
+		(insn->i_rp)&&(symbol_get_frag(insn->i_rp->r_sym)==fragP)?1:0,
+		this_segment, insn->i_imm);
+#endif
+	int	rg;
+
+	switch(insn->i_op) {
+	case ZIPO_LDI: // May or may not be conditional
+		if ((sym_known)&&(this_segment)
+			&&(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
+			//
+			// 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_op = ZIPO_MOV;
+			insn->i_naux = 0;
+			zip_assemble_insn_words(fragP, seg, insn, relax_state,
+				stretch, pzipm);
+			// Tested--this works
+			return;
+		} 
+
+		// 0.111.x111.11
+		insn->i_aux[0] = 0x7fc00000; // NOOP -- if never used.
+		immv += symv;
+		if ((insn->i_cnd == ZIPC_ALWAYS)
+			&&(zip_param_cis)
+			&&(zip_param_use_machine)&&(pzipm)
+			&&(!fits_within(8,immv))) {
+			// Convert an LDI instruction to a MOV instruction if
+			// it would make that instruction CIS-able.
+
+			if ((rg=zip_findnearreg_machine(pzipm, immv))
+					!= ZIP_RNONE) {
+				int	d;
+				d = immv - pzipm->r[rg].m_value;
+				if (fits_within(3,d)) {
+					insn->i_op = ZIPO_MOV;
+					insn->i_breg = rg;
+					insn->i_naux = 0;
+					insn->i_imm  = d;
+					zip_assemble_insn_words(fragP,
+						seg, insn, relax_state,
+						stretch, pzipm);
+					return;
+				}
+			}
+		}
+
+		if ((!insn->i_rp)&&(insn->i_cnd == ZIPC_ALWAYS)
+				&&(fits_within(23, immv))) {
+			// Can we do this with an ordinary load immediate
+			// instruction?
+			//
+			// If we do this, we'll avoid any opportunity to use
+			// the ZipMachine and move something into this address
+			insn->i_naux = 0;
+			insn->i_code = LDIOP(immv,insn->i_areg);
+		} else if (((!insn->i_rp)||(sym_known))
+				&&(fits_within(18, zip_brev(immv)))) {
+			// Can we do this with a BREV instruction using an
+			// immediate?  If so, we can then conditionally load
+			// the top 18 bist of any value ...
+			//
+			insn->i_naux = 0;
+			insn->i_code = IMMOP(ZIPO_BREV, insn->i_cnd,
+					zip_brev(immv),
+					insn->i_areg&0x0f);
+			if (insn->i_rp)
+				insn->i_rp->r_type = BFD_RELOC_NONE;
+// 0000 1110 0000 0000 0000 0000 0100 0000
+		} else if ((zip_param_use_machine)&&(pzipm)
+			&&((!insn->i_rp)||(sym_known))
+			&&(pzipm->r[insn->i_areg].m_known)
+			&&(0==((immv^pzipm->r[insn->i_areg].m_value)
+					& 0x0ffff0000))) {
+			// Replace LDI with LDILO
+			insn->i_naux = 0;
+			insn->i_code=IMMOP(ZIPO_LDILO, insn->i_cnd,
+					(immv&0x0ffff), insn->i_areg);
+
+			pzipm->r[insn->i_areg].m_value = immv;
+			if (ZIPC_ALWAYS == insn->i_cnd) {
+				// Henceforth, we only know the bottom 16bits
+				// of this register
+				pzipm->r[insn->i_areg].m_known = MACH_VUPPERKNOWN;
+			} else
+				pzipm->r[insn->i_areg].m_known = MACH_VKNOWN;
+		} else if ((zip_param_use_machine)&&(pzipm)
+			&&((!insn->i_rp)||(sym_known))
+			&&(pzipm->r[insn->i_areg].m_known)
+			&&((rg=zip_findnearreg_machine(pzipm, immv))!= ZIP_RNONE)
+			&&(fits_within(13,pzipm->r[rg].m_value - immv))) {
+				// Replace LDI with a MOV instruction
+				insn->i_op = ZIPO_MOV;
+				insn->i_breg = rg;
+				insn->i_naux = 0;
+				insn->i_imm  = pzipm->r[rg].m_value - immv;
+				zip_assemble_insn_words(fragP, seg, insn,
+					relax_state, stretch, pzipm);
+				return;
+		} else if ((zip_param_use_machine)&&(pzipm)
+			&&((!insn->i_rp)||(sym_known))
+			&&(pzipm->r[insn->i_areg].m_known)
+			&&((rg=zip_findnearreg_machine(pzipm, zip_brev(immv)))!= ZIP_RNONE)
+			&&(fits_within(14,zip_brev(pzipm->r[rg].m_value - immv)))) {
+				// Replace LDI with a MOV instruction
+				insn->i_op = ZIPO_BREV;
+				insn->i_breg = rg;
+				insn->i_naux = 0;
+				insn->i_imm  = zip_brev(pzipm->r[rg].m_value - immv);
+				zip_assemble_insn_words(fragP, seg, insn,
+					relax_state, stretch, pzipm);
+				return;
+		} else {
+			//
+			// If the symbol isn't defined, then any immv value
+			// will work--we have to come back anyway.
+			//
+			// BREV Extension would modify this statement
+			insn->i_naux = 1;
+			insn->i_code = IMMOP(ZIPO_BREV, insn->i_cnd,
+				zip_brev(immv)&0x01ffff, insn->i_areg);
+			insn->i_aux[0]=IMMOP(ZIPO_LDILO, insn->i_cnd,
+				(immv&0x0ffff), insn->i_areg);
+			if (insn->i_rp)
+				insn->i_rp->r_type = BFD_RELOC_ZIP_LDI;
+			else if ((zip_param_cis)&&(zip_can_merge(insn->i_code, insn->i_aux[0]))) {
+				insn->i_code = zip_insn_merge(insn->i_code, insn->i_aux[0]);
+				insn->i_naux = 0;
+			}
+		}
+#ifdef	ZIP_DEBUG
+		fprintf(stderr, "LDI %04x:%04x,%d Instruction assembled into %08x : %08x\n",
+			(immv>>16)&0x0ffff,
+			immv & 0x0ffff, insn->i_areg,
+			insn->i_code, insn->i_aux[0]);
+#endif
+		break;
+	case ZIPO_BRA: // Includes both conditional and unconditional branches
+#ifdef	ZIP_DEBUG
+		fprintf(stderr, "ZIPO--BRA (ADDR = %08lx, OFFSET = %08lx)\n",
+				fragP->fr_address,
+				(insn->i_rp)?insn->i_rp->r_fr_offset:0);
+#endif
+		if (insn->i_rp)
+			immv += (int)(symv
+				- fragP->fr_address
+				- (insn->i_rp->r_fr_offset+sizeof(uint32_t)));
+
+#ifdef	ZIP_DEBUG
+		if (!fits_within(18,immv))
+			fprintf(stderr, "doesn't fit in 18 bits\n");
+#endif
+		if (zip_param_small) {
+			//
+			// We can fit (or so we are told), so short jump code
+			// to an unknown location ...
+			//
+			insn->i_naux = 0;
+			insn->i_aux[0] = NOOP_OPCODE;
+			insn->i_aux[1] = NOOP_OPCODE;
+			insn->i_code = IMMOP(ZIPO_ADD, insn->i_cnd,
+				immv, ZIP_PC); // Add value to PC
+			insn->i_rp->r_pcrel = TRUE;
+			// No relocation is required--we just did it
+			insn->i_rp->r_type = BFD_RELOC_ZIP_OPB_PCREL;
+			// Tested--this works
+		} else if ((!sym_known)||(!fits_within(18,immv))) {
+			insn->i_op = ZIPO_LJMP;
+
+			zip_assemble_insn_words(fragP, seg, insn, relax_state, stretch, pzipm);			
+			insn->i_op = ZIPO_BRA;
+		} else {
+			//
+			// We can fit, so short jump code ...
+			//
+			insn->i_naux = 0;
+			insn->i_aux[0] = NOOP_OPCODE;
+			insn->i_aux[1] = NOOP_OPCODE;
+			insn->i_code = IMMOP(ZIPO_ADD, insn->i_cnd,
+				immv, ZIP_PC); // Add value to PC
+			insn->i_rp->r_pcrel = TRUE;
+			// No relocation is required--we just did it
+			insn->i_rp->r_type = BFD_RELOC_NONE;
+		}
+#ifdef	ZIP_DEBUG
+		fprintf(stderr, "BRA %08lx->%08x(%d,%d) assembled into(%d) %08x : %08x : %08x\n",
+			symv, immv, sym_defined, relax_state,
+			insn->i_naux, insn->i_code,
+			insn->i_aux[0], insn->i_aux[1]);
+#endif
+		break;
+	case	ZIPO_LJMP:
+		//
+		// Long jump code
+		// 
+		// I expect this to be true, since we should always
+		// be branching (or jumping) to a location defined by a
+		// symbol.
+		if (insn->i_rp) {
+			insn->i_rp->r_pcrel = FALSE;
+			insn->i_rp->r_type = BFD_RELOC_ZIP_VALUE;
+		} insn->i_breg = ZIP_RNONE;
+#ifdef	ZIP_DEBUG
+		fprintf(stderr, "LJMP IMM = %08x = %d\n", immv, immv);
+#endif
+		if (insn->i_cnd == ZIPC_ALWAYS) {
+			insn->i_naux = 1;
+			insn->i_code=DBLREGOP(ZIPO_LW,ZIPC_ALWAYS,
+				0,ZIP_PC,ZIP_PC); // Load into PC register
+			insn->i_aux[0] = 0; // Value to load
+		} else {
+			// A conditional long jump
+			insn->i_naux = 2;
+			insn->i_code=DBLREGOP(ZIPO_LW,insn->i_cnd,
+				1,ZIP_PC,ZIP_PC); // Conditional load to PC
+			insn->i_aux[0]=IMMOP(ZIPO_ADD,ZIPC_ALWAYS,
+				1,ZIP_PC); // Skip an instruction
+			insn->i_aux[1] = 0;
+		} if (!insn->i_rp)
+			insn->i_aux[insn->i_naux-1] = immv;
+		break;
+	case ZIPO_MOV:
+		//
+		// We could go a little wild here:
+		//	MOV val,Rx
+		// Could be quietly compiled into
+		//	LDI val,Rx	(if Rx is not a user register)
+		// whereas
+		//	MOV BIGVAL(Ry),Rx
+		// could be quietly compiled into
+		//	LDI BIGVAL,Rx
+		//	ADD.Z Ry,Rx	(Note the contortions to avoid adjusting
+		//	ADD.NZ Ry,Rx	... the flag bits)
+		// This would give us access to full 32-bit offsets ...
+		// as long as neither Rx nor Ry was a user register.  On the
+		// other hand, if we knew the flag bits would be set between
+		// now and the next conditional instruction, we could do a
+		//	LDI BIGVAL,Rx
+		//	ADD Ry,Rx
+		// and be okay with it.
+		//
+		// For now we just handle our normal 13 bit signed immediate
+		//	offsets.
+		//		
+		if (insn->i_rp) {
+			// MOV label(Rb),Ra
+			insn->i_rp->r_pcrel = (insn->i_breg == ZIP_PC);
+			immv += symv;
+			if (insn->i_breg == ZIP_PC) {
+				immv +=(int)(-fragP->fr_address
+						-insn->i_rp->r_fr_offset-sizeof(uint32_t));
+				immv >>= 2;
+				if ((sym_known)&&(this_segment)) {
+					// Tested--this works
+					insn->i_rp->r_type = BFD_RELOC_NONE;
+				} else {
+#ifdef	ZIP_DEBUG
+					fprintf(stderr, "ZIP_MOV_PCREL relocation needed for %s, pcrel = %d\n", S_GET_NAME(sym), insn->i_rp->r_pcrel);
+#endif
+					insn->i_rp->r_type = BFD_RELOC_ZIP_MOV_PCREL;
+				}
+
+
+//			} else if((zip_param_got)&&(insn->i_breg == ZIP_GBL)) {
+//				immv = symv;
+//				insn->i_rp->r_type = BFD_RELOC_ZIP_MOV_GOTREL;
+//				as_bad("MOV x(GOT),Ry not yet implemented");
+			} else {
+				// Do we really want to assume this is an
+				// address?
+				insn->i_rp->r_type = BFD_RELOC_ZIP_MOV_OFFSET;
+			}
+		} else if ((zip_param_use_machine)&&(pzipm)
+				&&(insn->i_breg<ZIP_CC)&&(insn->i_areg<ZIP_CC)
+				&&(ZIPC_ALWAYS == insn->i_cnd)
+				&&(pzipm->r[insn->i_breg].m_known==MACH_VKNOWN)
+				&&(fits_within(4,pzipm->r[insn->i_breg].m_value
+					+immv))) {
+			// MOV Rb,Ra
+			// turn this into an LDI instruction, rather than a
+			// move instruction
+			insn->i_op = ZIPO_LDI;
+			insn->i_imm += pzipm->r[insn->i_breg].m_value;
+			insn->i_breg = ZIP_RNONE;
+
+			insn->i_code = LDIOP(insn->i_imm, insn->i_areg);
+			insn->i_naux = 0;
+		}
+		/*
+		// Handle offsets greater than 13 bits --- up to 32 bits
+		// Only works if we have no symbol in question, and when the
+		// target isn't the PC register (or CC for that matter).
+		else if ((!fits_within(13,insn->i_imm))
+				&&(insn->i_areg < ZIP_CC)
+				&&(insn->i_breg < ZIP_CC)) {
+			// Alternate instruction sequence:
+			//	but .... these make conditional insns from
+			//		unconditional!!
+			//	MOV.always A,Rx -> LDI A,Rx
+			//	MOV.always A(Ry),Rx -> LDI A,Rx, ADD Ry,Rx
+			// this works for conditional moves, since ADD.C
+			// doesn't set conditions
+			//	MOV.C A(Ry),Rx -> LDI.C A,Rx, ADD.C Ry,Rx
+			
+			return;
+		}
+		*/
+
+		if (insn->i_op == ZIPO_MOV) { // If we haven't changed insns,
+			gas_assert(fits_within(13, insn->i_imm));
+			insn->i_code = SMPLMOV(insn->i_cnd, immv, insn->i_breg,
+					insn->i_areg);
+			//
+			// Now for the extra two register bits only present
+			// in move instructions
+			//
+			insn->i_code |= (insn->i_areg&0x10)?0x40000:0;
+			insn->i_code |= (insn->i_breg&0x10)?0x02000:0;
+		}
+#ifdef	ZIP_DEBUG
+		fprintf(stderr, "MOV Instruction assembled into %08x\n", insn->i_code);
+#endif
+		break;
+	case ZIPO_NEG:
+		insn->i_naux = 1;
+		if (insn->i_rp)
+			as_bad("NEG cannot handle symbols");
+		gas_assert(fits_within(13, -1+insn->i_imm));
+		insn->i_code = SMPLMOV(insn->i_cnd,
+			(-1+immv), insn->i_breg, insn->i_areg);
+		insn->i_code &= 0xfffbdfff;
+		insn->i_aux[0] = IMMOP(ZIPO_XOR, insn->i_cnd, -1,
+			insn->i_areg);
+		// printf("NEG Instruction assembled into %08x:%08x\n",
+			// insn->i_code, insn->i_aux[0]);
+		break;
+	case ZIPO_BREAK: case ZIPO_LOCK: case ZIPO_SIM: case ZIPO_NOOP:
+		if (insn->i_cnd != ZIPC_ALWAYS)
+			as_bad("NOOP/BREAK/LOCK/SIM instructions cannot handle conditions\n");
+		insn->i_code = NOOPGROUP(insn->i_op, insn->i_imm);
+		insn->i_naux = 0;
+		break;
+	case	ZIPO_SDUMP: case ZIPO_NDUMP: case ZIPO_SEXIT: case ZIPO_NEXIT:
+	case	ZIPO_SOUT:  case ZIPO_NOUT:
+		// These instructions *should*ve been turned into NOOP and SIM
+		// instructions by now.  Getting here with them is therefore
+		// an error.
+		gas_assert(0);
+	case ZIPO_SEXTB: {
+		insn->i_naux = 1;
+		insn->i_code   = IMMOP(ZIPO_LSL, insn->i_cnd, 24, insn->i_areg);
+		insn->i_aux[0] = IMMOP(ZIPO_ASR, insn->i_cnd, 24, insn->i_areg);
+		} break;
+	case ZIPO_SEXTH: {
+		insn->i_naux = 1;
+		insn->i_code   = IMMOP(ZIPO_LSL, insn->i_cnd, 16, insn->i_areg);
+		insn->i_aux[0] = IMMOP(ZIPO_ASR, insn->i_cnd, 16, insn->i_areg);
+		} break;
+	case ZIPO_JSR:
+		if ((zip_param_cis)&&(insn->i_cnd == ZIPC_ALWAYS)
+				&&(insn->i_rp)) {
+			insn->i_op = ZIPO_LJSR;
+			zip_assemble_insn_words(fragP, seg, insn, relax_state, stretch, pzipm);			
+			insn->i_op = ZIPO_JSR;
+		} else if ((zip_param_cis)&&(insn->i_cnd == ZIPC_ALWAYS)
+				&&(insn->i_breg != ZIP_RNONE)
+				&&(insn->i_imm == 0)) {
+			// JSR (Register)
+			insn->i_naux = 0;
+			insn->i_code = 0x80008000
+				| (ZIPV_MOV<<24)
+				| 0x00f90000	// MOV OpB = PC+1
+				| 0x0f880	// MOV into PC
+				| ((insn->i_breg&0x0f)<<3)
+				| (ZIPV_MOV << 8); // The LW instruction
+
+			gas_assert(!insn->i_rp);
+		} else if ((!insn->i_rp)&&(insn->i_breg != ZIP_RNONE)) {
+			gas_assert(fits_within(13,immv));
+			// JSR offset+register, implemented as two moves
+			insn->i_naux = 1;
+			insn->i_code = SMPLMOV(insn->i_cnd, 1, ZIP_PC, ZIP_LR);
+			insn->i_aux[0] = SMPLMOV(insn->i_cnd, immv, insn->i_breg, ZIP_PC);
+			insn->i_aux[1] = NOOP_OPCODE;
+		} else {
+			if (insn->i_rp)
+				immv += (int)(symv
+					- fragP->fr_address
+					- (insn->i_rp->r_fr_offset+sizeof(uint32_t)));
+			if ((zip_param_small)||((sym_known)&&(fits_within(18,immv-4)))) {
+				// MOV.C 1(PC),R0
+				// BRA.C _somewhere_
+				insn->i_naux = 1;
+				insn->i_code = SMPLMOV(insn->i_cnd, 1, ZIP_PC,
+					ZIP_LR);
+				// Bias the branch by -4, since we're one word
+				// into this instruction
+				insn->i_aux[0] = IMMOP(ZIPO_ADD, insn->i_cnd,
+					immv-4, ZIP_PC);
+				insn->i_aux[1] = NOOP_OPCODE;
+				insn->i_rp->r_pcrel = TRUE;
+				insn->i_rp->r_type = BFD_RELOC_NONE;
+			} else {
+				// If all else fails, call for a long JSR
+				insn->i_op = ZIPO_LJSR;
+				zip_assemble_insn_words(fragP, seg, insn,
+					relax_state, stretch, pzipm);
+				insn->i_op = ZIPO_JSR;
+			}
+		} break;
+	case ZIPO_LJSR:
+		if (insn->i_rp)
+			immv += (int)(symv
+				- fragP->fr_address
+				- (insn->i_rp->r_fr_offset+sizeof(uint32_t)));
+		if (insn->i_rp) {
+			insn->i_rp->r_pcrel = FALSE;
+			insn->i_rp->r_type = BFD_RELOC_ZIP_VALUE;
+		} insn->i_breg = ZIP_RNONE;
+		if (insn->i_cnd == ZIPC_ALWAYS) {
+			if (zip_param_cis) {
+				insn->i_naux = 1;
+				insn->i_code = 0x80008000
+					| (ZIPV_MOV<<24)
+					| 0x00fa0000	// MOV OpB = PC+2
+					| 0x0f8f8	// (LW) into PC
+					| (ZIPV_LW << 8); // The LW instruction
+				insn->i_aux[0] = 0; // To be filled in with address value
+			} else { // If unconditional
+				// MOV 1(PC),R0
+				// LW (PC),PC
+				// _somewhere_
+				insn->i_naux = 2;
+				insn->i_code = SMPLMOV(insn->i_cnd, 2, ZIP_PC,
+					ZIP_LR);
+				insn->i_aux[0] = DBLREGOP(ZIPO_LW,ZIPC_ALWAYS,
+					0,ZIP_PC,ZIP_PC); // Load into PC register
+				insn->i_aux[1] = 0;
+			}
+		} else {
+			// If conditional, naux = 3
+			// BRA.!cnd (for whatever condition) +3
+			// MOV 4(PC),R0
+			// LW (PC),PC
+			// address
+			insn->i_naux = 3;
+			insn->i_aux[2] = 0;
+			if (insn->i_cnd != ZIPC_V) {
+				ZIP_CONDITION cnd =
+					zip_negate_condition(insn->i_cnd);
+				insn->i_code = IMMOP(ZIPO_ADD, cnd, 12, ZIP_PC);
+				insn->i_aux[0] = SMPLMOV(ZIPC_ALWAYS, 2, ZIP_PC,
+					ZIP_LR);
+				insn->i_aux[1] = DBLREGOP(ZIPO_LW, ZIPC_ALWAYS,
+					0,ZIP_PC,ZIP_PC); // Load into PC register
+			} else {
+				insn->i_code = SMPLMOV(ZIPC_V, 3, ZIP_PC,
+					ZIP_LR);
+				insn->i_aux[0] = DBLREGOP(ZIPO_LW, ZIPC_V,
+					0,ZIP_PC,ZIP_PC); // Load into PC register
+				insn->i_aux[1] = IMMOP(ZIPO_ADD, ZIPC_ALWAYS, 4, ZIP_PC);
+			}
+		} if (!insn->i_rp)
+			insn->i_aux[insn->i_naux-1] = immv;
+		break;
+	default:
+		if (insn->i_rp) {
+			insn->i_rp->r_pcrel = FALSE;
+			immv += symv;
+			if (insn->i_breg == ZIP_PC) {
+				immv+=(int)(-fragP->fr_address
+						-insn->i_rp->r_fr_offset-sizeof(uint32_t));
+				insn->i_rp->r_pcrel= TRUE;
+				insn->i_rp->r_type = BFD_RELOC_ZIP_OPB_PCREL;
+				if ((sym_known)&&(this_segment))
+					insn->i_rp->r_type = BFD_RELOC_NONE;
+//			} else if((zip_param_got)&&(insn->i_breg == ZIP_GBL)) {
+//				as_bad("<OP> x(GOT),Ry not yet implemented");
+//				immv += symv;
+//				insn->i_rp->r_type = BFD_RELOC_ZIP_OPB_GOTREL;
+			} else {
+				// Do we really want to assume this is an
+				// address?
+				immv += symv;
+				insn->i_rp->r_type = BFD_RELOC_ZIP_OPB_OFFSET;
+			}
+		} if (insn->i_breg != ZIP_RNONE) {
+			if (insn->i_breg == ZIP_PC)
+				immv >>= 2;
+			if (!fits_within(14, insn->i_imm)) {
+				fprintf(stderr, "ERR: (%d) 0x%08x does not fit within 18 bits!\n", insn->i_imm, insn->i_imm);
+				gas_assert(fits_within(14, insn->i_imm));
+			}
+			insn->i_code = DBLREGOP(insn->i_op, insn->i_cnd,
+				immv, insn->i_breg, insn->i_areg);
+			if (insn->i_rp) {
+				if (insn->i_breg == ZIP_PC) {
+					insn->i_rp->r_type = BFD_RELOC_ZIP_OPB_PCREL;
+					insn->i_rp->r_pcrel = TRUE;
+//				} else if((zip_param_got)&&(insn->i_breg == ZIP_GBL)) {
+//					insn->i_rp->r_type = BFD_RELOC_ZIP_OPB_GOTREL;
+				} else
+					insn->i_rp->r_type = BFD_RELOC_ZIP_OPB_OFFSET;
+			}
+		} else {
+			if (!fits_within(18, insn->i_imm)) {
+				fprintf(stderr, "ERR: (%d) 0x%08x does not fit within 18 bits!\n", insn->i_imm, insn->i_imm);
+				gas_assert(fits_within(18, insn->i_imm));
+			}
+			insn->i_code = IMMOP(insn->i_op, insn->i_cnd,
+				immv, insn->i_areg);
+			if (insn->i_rp)
+				insn->i_rp->r_type  = BFD_RELOC_ZIP_OPB_IMM;
+		}
+#ifdef	ZIP_DEBUG
+		fprintf(stderr, "Instruction assembled into %08x%s\n", insn->i_code,
+			(insn->i_rp)?" w/ Symbol":"");
+#endif
+		break;
+	}
+}
+
+void
+md_assemble(char *line) {
+	const char *linep;
+	char	*p;
+
+	linep = (char *)zip_skip_white_spaces(line);
+	if ((strncasecmp(linep, "nstr", 4)==0)
+		||(strncasecmp(linep, "sstr", 4)==0)) {
+		uint32_t	base;
+		const char	*sbeg;
+
+		if ((linep[0] =='n')||(linep[0] == 'N'))
+			base = 0x0400 + NOOP_OPCODE;
+		else
+			base = 0x0400 + SIM_OPCODE;
+
+		sbeg = strchr(line, '\"');
+		if (!sbeg)
+			as_bad("String instruction with no quotes found");
+		sbeg++;
+		while(*sbeg != '\"') {
+			unsigned v = *sbeg++;
+			if (v == '\\') {
+				switch(*sbeg++) {
+				case 'a':	v = '\a'; break;
+				case 'b':	v = '\b'; break;
+				case 'f':	v = '\f'; break;
+				case 'n':	v = '\n'; break;
+				case 'r':	v = '\r'; break;
+				case 't':	v = '\t'; break;
+				case '\\':	v = '\\'; break;
+				case '\"':	v = '\"'; break;
+				case '\'':	v = '\''; break;
+				default: sbeg--;
+				}
+			}
+			p = frag_more(sizeof(uint32_t));
+			md_number_to_chars(p,base+(v&0x0ff),sizeof(uint32_t));
+		}
+
+		return;
+	}
+
+
+	// Decode an instruction from op_str
+	//	Determine the opcode
+	//		any conditions
+	//		the result register
+	//		any immediate
+	//		any "B" register
+	ZIPIS	insnv, *insn = &insnv;
+	const char *error = zip_parse(line, insn);
+
+#ifdef	ZIP_DEBUG
+	fprintf(stderr, "ZIP-ASSEMBLE %s\n", line);
+#endif
+
+	if (error) {
+		as_bad("%s \'%s\'", error, line);
+		return;
+	}
+
+	zip_assemble_insn_words(frag_now, now_seg, insn, 0, 0, &zipm);
+	if (zip_param_use_machine)
+		zip_advance_machine(&zipm, insn);
+#ifdef	ZIP_DEBUG
+	zip_debug_machine(&zipm);
+#endif
+
+	// Then, if the instruction is valid we ...
+	//	for branches ...
+	//	  symbolS *symp = reloc->reloc_expression.X_add_symbol;
+	//	  offsetT offset = reloc->reloc_expression.X_add_number;
+	//	  char *f;
+	//	  f = frag_var(?, 4, 4, BRANCH_SUBTYPE, symp, offset, NULL);
+	//	  md_number_to_chars(f, insn->insn_code, 4); // ???
+	//
+	//
+	if ((!insn->i_rp)&&(cis_mergable)&&(insn->i_naux == 0)
+			&&(frag_now_fix_octets()>=4)) {
+		// ZIPI	lcode = md_number_from_chars(p, 4);
+		unsigned int	last_iword;
+		char	*buf;
+
+		buf = &frag_now->fr_literal[frag_now_fix_octets() - 4];
+		last_iword = (buf[3]&0x0ff)|((buf[2]&0x0ff)<<8)
+			|((buf[1]&0x0ff)<<16)|((buf[0]&0x0ff)<<24);
+		if ((buf >= frag_now->fr_literal)
+				&&(zip_can_merge(last_iword,insn->i_code))) {
+			p = buf;
+			insn->i_code =zip_insn_merge(last_iword, insn->i_code);
+			md_number_to_chars(p, insn->i_code, sizeof(uint32_t));
+		} else {
+			p = frag_more(sizeof(uint32_t)*(1+insn->i_naux));
+			md_number_to_chars(p, insn->i_code, sizeof(uint32_t));
+		}
+	} else {
+		int	i;
+		ZIPRELOC	*rp = insn->i_rp;
+
+		if ((insn->i_naux == 0)||(NULL == insn->i_rp)) {
+			// If we have no need of any symbols, we come here.
+			// If we have no need of any extra 4-byte instructions,
+			// we come here.
+			p = frag_more(sizeof(uint32_t)*(1+insn->i_naux));
+
+			if (insn->i_rp) {
+				// Generate a fixup for when we finally
+				// know where this symbol links to
+				insn->i_rp->r_fr_offset =
+					(p - frag_now->fr_literal);
+				insn->i_rp->r_fix = fix_new(frag_now,
+					insn->i_rp->r_fr_offset, // where w/in frag?
+					4,		// 1,2, or 4 usually ... ??
+					insn->i_rp->r_sym, // Add symbol,
+					insn->i_imm, // Fixed/known offset to the symbol
+					insn->i_rp->r_pcrel, // T if PC-Relative reloc
+					insn->i_rp->r_type); // Reloc type
+				insn->i_rp = NULL;
+			}
+		} else {
+			// First, grow our fragment so we know we have the
+			// size we'll need.
+			frag_grow(sizeof(uint32_t)*(1+insn->i_naux));
+
+			// Then p, the place where we'd get more from, is
+			// where our instruction will be installed.  We know
+			// there's room for it there now.
+			p = frag_more(0);
+			// Record where in the frag our relaxable instruction
+			// will be installed
+			insn->i_rp->r_fr_offset = ( p - frag_now->fr_literal );
+			// Now tell the assembler about what we've done. 
+			// This'll close off the frag as well, so this is the
+			// last we'll see of this frag--even though frag_now
+			// may yet point to it (or not) for a while.
+			frag_var(rs_machine_dependent, // Relaxation type
+				sizeof(uint32_t)*(1+insn->i_naux),
+				sizeof(uint32_t)*(1+insn->i_naux),
+				rs_machine_dependent,	// Subtype
+				insn->i_rp->r_sym,	// Symbol
+				insn->i_imm,	// Offset (to be added to symbol)
+				(char *)zip_copy_insn(insn));	// Opcode
+
+		}
+		md_number_to_chars(p, insn->i_code, sizeof(uint32_t));
+		for(i=0; i< insn->i_naux; i++)
+			md_number_to_chars(&p[sizeof(uint32_t)*(1+i)], insn->i_aux[i], sizeof(uint32_t));
+
+		if (rp) {
+			cis_mergable = FALSE;
+		} else {
+			cis_mergable = (zip_param_cis)&&(insn->i_naux == 0);
+		}
+	}
+#ifdef	ZIP_DEBUG
+	zip_dump_insn(insn);
+#endif
+}
+
+/* Turn a string in input_line_pointer into a floating point constant
+ * of type type, and store the appropriate bytes in *LITP.  The number of
+ * LIITTLENUMS emitted is stored in *SIZEP.  An error message is returned, or
+ * NULL on OK.
+ */
+const char	*
+md_atof(int type, char *litP, int *sizeP) {
+	int	prec;
+	LITTLENUM_TYPE	words[4];
+	char	*t;
+	int	i;
+
+	switch(type) {
+	case 'f':
+		prec = 2; break;
+	case 'd':
+		prec = 4; break;
+	default:
+		*sizeP = 0;
+		return _("Unsupported floating point format");
+	}
+
+	t = atof_ieee(input_line_pointer, type, words);
+	if (t)
+		input_line_pointer = t;
+
+	*sizeP = prec * 2;
+
+	for(i=prec-1; i>= 0; i--) {
+		md_number_to_chars(litP, (valueT)words[i], 2);
+		litP += 2;
+	}
+
+	return NULL;
+}
+#define	AS_BAD_FIX(FXP,STR) as_bad_where(FXP->fx_file,FXP->fx_line,_(STR))
+
+/* Apply a fixup to the object file
+ *
+ * This function will only be called once all of the details of the fixup are
+ * known, before the object file heads to the linker (if at all).
+ */
+void
+md_apply_fix(fixS *fixP, valueT *val, segT seg ATTRIBUTE_UNUSED)
+{
+	unsigned int	iword, mask, final_fix;
+
+	final_fix = (fixP->fx_addsy == NULL) ? TRUE : FALSE;
+
+	bfd_byte *buf = (bfd_byte *)&fixP->fx_frag->fr_literal[fixP->fx_where];
+	iword = (buf[3]&0x0ff)|((buf[2]&0x0ff)<<8)
+			|((buf[1]&0x0ff)<<16)|((buf[0]&0x0ff)<<24);
+	(*val) &= 0x0ffffffff;
+
+#ifdef	ZIP_DEBUG
+	fprintf(stderr, "MD-APPLY-FIX: FRAG=%08x@%08x+%08x(%d), IWORD = %08x Val=%08x (RTYP=%d->%s)%s%s, ADDEND=%08lx\n",
+		((unsigned)((unsigned long)fixP->fx_frag->fr_literal)),
+		((unsigned)((unsigned long)fixP->fx_frag->fr_address)),
+		((unsigned)((unsigned long)fixP->fx_where)),
+		((unsigned)((unsigned long)fixP->fx_size)),
+		iword, (unsigned)(*val), fixP->fx_r_type,
+		bfd_get_reloc_code_name(fixP->fx_r_type),
+		(fixP->fx_pcrel)?" PC-Rel ":" std ",
+		(fixP->fx_addsy)?"":"(Null Sym)",
+		fixP->fx_offset);
+#endif
+	switch(fixP->fx_r_type) {
+	case BFD_RELOC_NONE:
+		fixP->fx_done = final_fix;
+		break;
+	case BFD_RELOC_ZIP_OPB_IMM:
+		// printf("\tMD-APPLY-FIX: BFD_RELOC_ZIP_OPB_IMM\n");
+		mask = 0x3ffff; iword = (iword &(~mask))|((*val)&mask);
+		(*val) &= 0x03ffff;
+		md_number_to_chars((char *)buf, iword, sizeof(uint32_t));
+		fixP->fx_done = final_fix;
+		break;
+	case BFD_RELOC_ZIP_OPB_PCREL:
+		{
+		uint32_t	oval;
+		oval = *val;
+		oval = (*val>>2);
+		oval &= 0x03fff;
+		mask = 0x3fff; iword = (iword &(~mask))|((oval)&mask);
+		*val = oval;
+		md_number_to_chars((char *)buf, iword, sizeof(uint32_t));
+		fixP->fx_done = final_fix;
+		} break;
+	case BFD_RELOC_ZIP_OPB_OFFSET:
+//	case BFD_RELOC_ZIP_OPB_GOTREL:
+	case BFD_RELOC_14:
+		// if (fixP->fx_r_type == BFD_RELOC_ZIP_OPB_OFFSET)
+			// printf("\tMD-APPLY-FIX: BFD_RELOC_ZIP_OPB_OFFSET\n");
+		// else if (fixP->fx_r_type == BFD_RELOC_ZIP_OPB_PCREL)
+			// printf("\tMD-APPLY-FIX: BFD_RELOC_ZIP_OPB_PCREL\n");
+		// else
+			// printf("\tMD-APPLY-FIX: BFD_RELOC_ZIP_OPB_GOTREL\n");
+		mask = 0x3fff; iword = (iword &(~mask))|((*val)&mask);
+		(*val) &= 0x03fff;
+		md_number_to_chars((char *)buf, iword, sizeof(uint32_t));
+		fixP->fx_done = final_fix;
+		break;
+	case BFD_RELOC_ZIP_MOV_PCREL:
+		(*val) &= 0x07fff; (*val)>>=2;
+		mask = 0x1fff; iword = (iword &(~mask))|((*val)&mask);
+		md_number_to_chars((char *)buf, iword, sizeof(uint32_t));
+		fixP->fx_done = final_fix;
+		break;
+	case BFD_RELOC_ZIP_MOV_OFFSET:
+	// case BFD_RELOC_ZIP_MOV_GOTREL:
+#ifdef	ZIP_DEBUG
+		if (fixP->fx_r_type == BFD_RELOC_ZIP_MOV_OFFSET)
+			fprintf(stderr, "\tMD-APPLY-FIX: BFD_RELOC_ZIP_MOV_OFFSET\n");
+		//else if (fixP->fx_r_type == BFD_RELOC_ZIP_MOV_PCREL)
+		//	fprintf(stderr, "\tMD-APPLY-FIX: BFD_RELOC_ZIP_MOV_PCREL\n");
+		// else
+		//	fprintf(stderr, "\tMD-APPLY-FIX: BFD_RELOC_ZIP_MOV_GOTREL\n");
+		fprintf(stderr, "Final-fix = %d\n", final_fix);
+#endif
+		mask = 0x1fff; iword = (iword &(~mask))|((*val)&mask);
+		(*val) &= 0x01fff;
+		md_number_to_chars((char *)buf, iword, sizeof(uint32_t));
+		fixP->fx_done = final_fix;
+		break;
+	case BFD_RELOC_ZIP_LDI:
+		// If the value were known at build time, we wouldn't need
+		// to drop the lower two address bits.  However, since we're
+		// doing a fixup, we know val must reference an address,
+		// hence we shift down two bits.
+		// printf("\tMD-APPLY-FIX: BFD_RELOC_ZIP_LDI\n");
+		iword |= (*val)&0x03fffff;
+		(*val) &= 0x03fffff;
+		md_number_to_chars((char *)buf, iword, sizeof(uint32_t));
+		fixP->fx_done = final_fix;
+		break;
+	case BFD_RELOC_ZIP_LLO:
+		// printf("\tMD-APPLY-FIX: BFD_RELOC_ZIP_LLO\n");
+		iword |= (*val)&0x0ffff;
+		(*val) &= 0x0ffff;
+		md_number_to_chars((char *)buf, iword, sizeof(uint32_t));
+		fixP->fx_done = final_fix;
+		break;
+	case BFD_RELOC_ZIP_BREV:
+		// (*val) &= 0x0fffe0000;
+		iword &= (~0x1ffff);
+		iword |= zip_brev(*val)&0x01ffff;
+		md_number_to_chars((char *)buf, iword, sizeof(uint32_t));
+		fixP->fx_done = final_fix;
+		break;
+#ifdef	USE_R_ZIP_LHI
+	case BFD_RELOC_ZIP_LHI:
+		// printf("\tMD-APPLY-FIX: BFD_RELOC_ZIP_LHI\n");
+		iword |= ((*val)>>16)&0x0ffff;
+		(*val) &= 0x0ffff0000;
+		md_number_to_chars((char *)buf, iword, sizeof(uint32_t));
+		fixP->fx_done = final_fix;
+		break;
+#endif
+	case BFD_RELOC_32:
+	case BFD_RELOC_ZIP_VALUE:
+		// printf("\tMD-APPLY-FIX: BFD_RELOC_ZIP_VALUE/32\n");
+		iword = (*val);
+		(*val) &= 0x0ffffffff;
+		md_number_to_chars((char *)buf, iword, sizeof(uint32_t));
+		fixP->fx_done = final_fix;
+		break;
+	case BFD_RELOC_16:
+		iword = (*val)&0x0ffff;
+		(*val) &= 0x0ffff;
+		md_number_to_chars((char *)buf, iword, sizeof(uint16_t));
+		fixP->fx_done = final_fix;
+		break;
+	case BFD_RELOC_8:
+		iword = buf[0] & 0x0ff;
+		iword |= (*val)&0x0ff; (*val) &= 0x0ff;
+		md_number_to_chars((char *)buf, iword, sizeof(uint8_t));
+		fixP->fx_done = final_fix;
+		break;
+	default:
+		fprintf(stderr, "RELOC #\%d not supported\n", fixP->fx_r_type);
+		// abort();
+		break;
+	}
+}
+
+/* Generate a machine-dependent relocation. */
+arelent *
+tc_gen_reloc(asection *section ATTRIBUTE_UNUSED, fixS *fixP)
+{
+#ifdef	ZIP_DEBUG
+	fprintf(stderr, "Call to TC-GEN-RELOC(%s,FIX,%s,+%ld);\n", segment_name(section),
+			S_GET_NAME(fixP->fx_addsy),fixP->fx_offset);
+#endif
+
+	arelent	*relP;
+
+	relP = xmalloc(sizeof(arelent));
+	gas_assert(relP != 0);
+	relP->sym_ptr_ptr  = (asymbol **)xmalloc(sizeof(asymbol *));
+	*relP->sym_ptr_ptr = symbol_get_bfdsym(fixP->fx_addsy);
+	relP->address      = (fixP->fx_frag->fr_address + fixP->fx_where);
+	// The addend value is added to the symbols value after the value is
+	// is resolved.  It is useful for PC relative addressing, as well as
+	// instructions giving offsets to symbols, such as LDI .x+50,R0. 
+	relP->addend = fixP->fx_offset;
+	if (fixP->fx_r_type == BFD_RELOC_ZIP_OPB_PCREL)
+		relP->addend -= 4;
+	else if (fixP->fx_r_type == BFD_RELOC_ZIP_MOV_PCREL)
+		relP->addend -= 4;
+#ifdef	ZIP_DEBUG
+	fprintf(stderr, "ADDEND = %08lx\n", relP->addend);
+#endif
+	relP->howto = bfd_reloc_type_lookup(stdoutput, fixP->fx_r_type);
+	if (! relP->howto) {
+		const char *name;
+		name = S_GET_NAME(fixP->fx_addsy);
+		if (name == NULL)
+			name = _("<unknown>");
+		as_fatal( _("Cannot generate relocation type for symbol %s, code %s"),
+			name, bfd_get_reloc_code_name(fixP->fx_r_type));
+	}
+#ifdef	ZIP_DEBUG
+	else {
+		const char *name;
+		name = S_GET_NAME(fixP->fx_addsy);
+		if (name == NULL)
+			name = _("<unknown>");
+		fprintf(stderr, "GENERATING-RELOC(%20s, %4d=0x%04x) for %s\n",
+			bfd_get_reloc_code_name(fixP->fx_r_type),
+			fixP->fx_r_type, fixP->fx_r_type, name);
+	}
+#endif
+	return relP;
+}
+
+// Size is estimated in host bytes (octets)
+int
+zip_estimate_size_before_relax(fragS *fragP, segT seg) {
+	ZIPIS	*insn = (ZIPIS *)(fragP->fr_opcode);
+	offsetT last_fix = fragP->fr_fix;
+
+	zip_assemble_insn_words(fragP, seg, insn, 1, 0, NULL);
+
+	// Goal is to estimate the total size of the fragment before any
+	// relaxations.  We need to return the difference between that
+	// new estimate of total size and the current value of fragP->fr_fix.
+#ifdef	ZIP_DEBUG
+	fprintf(stderr, "(%s): SZ-ESTIMATE %3ld + %d*(1+%d) - %3ld = %3ld\n",
+		S_GET_NAME(insn->i_rp->r_sym),
+		insn->i_rp->r_fr_offset, OCTETS_PER_BYTE, insn->i_naux,
+		fragP->fr_fix,
+		insn->i_rp->r_fr_offset + (1+insn->i_naux)*sizeof(uint32_t) - fragP->fr_fix);
+#endif
+	// zip_dump_insn(insn);
+	fragP->fr_fix =  insn->i_rp->r_fr_offset + (1+insn->i_naux) * sizeof(uint32_t);
+	return fragP->fr_fix - last_fix;
+}
+
+#define	RELAX_STATE(FRAG)	(FRAG->fr_subtype)
+long
+zip_relax_frag(segT seg, fragS *fragP, long stretch)
+{
+	ZIPIS	*insn = (ZIPIS *)(fragP->fr_opcode);
+	char	*p =&fragP->fr_literal[insn->i_rp->r_fr_offset];
+	long	growth;
+	int	i, old_naux = insn->i_naux;
+
+#ifdef	ZIP_DEBUG
+	fprintf(stderr, "--- FIX --- @%08x/%08x, Sym %s (zip_relax_frag), stretch = %ld/offset = %08lx, addr=%08x\n",
+			(int)((long)(fragP->fr_literal)),
+			(unsigned)fragP->fr_address,
+			(insn->i_rp->r_sym)?  S_GET_NAME(insn->i_rp->r_sym)
+				:"(Null)",
+			stretch, insn->i_rp->r_fr_offset,
+			insn->i_imm);
+	// zip_dump_insn(insn);
+#endif
+
+	{
+		fragS	*lclfP;
+		for(lclfP = fragP; lclfP; lclfP = lclfP->fr_next)
+			gas_assert(lclfP->fr_type < 256);
+	}
+
+	// We need to rebuild the instruction since we could relax it
+	// multiple times
+	zip_assemble_insn_words(fragP, seg, insn, 1, stretch, NULL);
+	{
+		fragS	*lclfP;
+		for(lclfP = fragP; lclfP; lclfP = lclfP->fr_next)
+			gas_assert(lclfP->fr_type < 256);
+	}
+
+	md_number_to_chars(p, insn->i_code, sizeof(uint32_t));
+	{
+		fragS	*lclfP;
+		for(lclfP = fragP; lclfP; lclfP = lclfP->fr_next)
+			gas_assert(lclfP->fr_type < 256);
+	}
+
+	for(i=0; i< insn->i_naux; i++)
+		md_number_to_chars(&p[sizeof(uint32_t)*(1+i)], insn->i_aux[i],
+				sizeof(uint32_t));
+
+	{
+		fragS	*lclfP;
+		for(lclfP = fragP; lclfP; lclfP = lclfP->fr_next)
+			gas_assert(lclfP->fr_type < 256);
+	}
+
+	// The change in size of this fragment
+	growth = (insn->i_naux - old_naux) * sizeof(uint32_t);
+#ifdef	ZIP_DEBUG
+	fprintf(stderr, "GROWING BY %3ld bytes (insn->i_naux = %d->%d, fr_fix was %ld)\n",
+		growth, old_naux, insn->i_naux, fragP->fr_fix);
+	gas_assert(fragP->fr_fix >= 0);
+	gas_assert(fragP->fr_fix + growth>= 0);
+#endif
+	{
+		fragS	*lclfP;
+		for(lclfP = fragP; lclfP; lclfP = lclfP->fr_next)
+			gas_assert(lclfP->fr_type < 256);
+	}
+
+	return growth;
+}
+
+void
+zip_convert_frag(bfd *headers ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED,
+		fragS *fragP ATTRIBUTE_UNUSED)
+{
+	ZIPIS	*insn = (ZIPIS *)fragP->fr_opcode;
+	// char	*p = fragP->fr_literal+ insn->i_rp->r_fr_offset;
+
+#ifdef	ZIP_DEBUG
+	fprintf(stderr, "CVT-FRAG: ADDR = %08lx, FIX = %3ld, VAR = %3ld\n",
+		fragP->fr_address, fragP->fr_fix, fragP->fr_var);
+
+	zip_dump_insn(insn);
+#endif
+
+	if ((insn->i_rp)&&(insn->i_rp->r_type != BFD_RELOC_NONE)
+			&&(!insn->i_rp->r_fix)) {
+		if (insn->i_op == ZIPO_LDI) {
+			if (insn->i_naux == 1) {
+				// BREV extension would go here
+				//
+				fix_new(fragP,
+					insn->i_rp->r_fr_offset, // where w/in frag?
+					4,		// 1,2, or 4 usually ... ??
+					insn->i_rp->r_sym, // Add symbol,
+					insn->i_imm,// Fixed/known offset to the symbol
+					insn->i_rp->r_pcrel, // T if PC-Relative reloc
+					BFD_RELOC_ZIP_BREV); // Reloc type
+				fix_new(fragP,
+					(insn->i_rp->r_fr_offset+sizeof(uint32_t)), // where w/in frag?
+					4,		// 1,2, or 4 usually ... ??
+					insn->i_rp->r_sym, // Add symbol,
+					insn->i_imm,// Fixed/known offset to the symbol
+					insn->i_rp->r_pcrel, // T if PC-Relative reloc
+					BFD_RELOC_ZIP_LLO); // Reloc type
+			} else {
+				insn->i_rp->r_fix = fix_new(fragP,
+					(insn->i_rp->r_fr_offset), // where w/in frag?
+					4,		// 1,2, or 4 usually ... ??
+					insn->i_rp->r_sym, // Add symbol,
+					insn->i_imm, // Fixed/known offset to the symbol
+					insn->i_rp->r_pcrel, // T if PC-Relative reloc
+					BFD_RELOC_ZIP_LDI); // Reloc type
+			}
+		} else if ((insn->i_op == ZIPO_BRA)&&(insn->i_naux >= 1)) {
+#ifdef	ZIP_DEBUG
+			fprintf(stderr, "--- CVT-FRAG --- Creating a BRA fixup\n");
+#endif
+			fix_new(fragP,
+				insn->i_rp->r_fr_offset +insn->i_naux*sizeof(uint32_t),
+				4,		// 1,2, or 4 usually ... ??
+				insn->i_rp->r_sym, // Add symbol,
+				insn->i_imm, // Fixed/known offset to the symbol
+				insn->i_rp->r_pcrel, // T if PC-Relative reloc
+				BFD_RELOC_ZIP_VALUE); // Reloc type
+		} else if (insn->i_rp->r_type == BFD_RELOC_ZIP_VALUE) {
+				// Use the CIS LW (PC),PC method
+				fix_new(fragP,
+				insn->i_rp->r_fr_offset
+					+ insn->i_naux*sizeof(uint32_t),
+				4,		// 1,2, or 4 usually ... ??
+				insn->i_rp->r_sym, // Add symbol,
+				insn->i_imm, // Fixed/known offset to the symbol
+				insn->i_rp->r_pcrel, // T if PC-Relative reloc
+				BFD_RELOC_ZIP_VALUE); // Reloc type
+		} else {
+#ifdef	ZIP_DEBUG
+			fprintf(stderr, "--- CVT-FRAG --- Creating a more generic fixup (%d)\n",
+				insn->i_rp->r_type);
+#endif
+			fix_new(fragP,
+				// where w/in frag?
+				insn->i_rp->r_fr_offset+insn->i_naux * sizeof(uint32_t),
+				4,	// 1,2, or 4 usually ... ??
+				insn->i_rp->r_sym, // Add symbol,
+				insn->i_imm, // Fixed/known offset to the symbol
+				insn->i_rp->r_pcrel, // T if PC-Relative reloc
+				insn->i_rp->r_type); // Reloc type
+		}
+	}
+}
diff -Naur '--exclude=*.swp' binutils-2.27-original/gas/config/tc-zip.h binutils-2.27-zip/gas/config/tc-zip.h
--- binutils-2.27-original/gas/config/tc-zip.h	1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/gas/config/tc-zip.h	2017-03-03 09:35:34.527310651 -0500
@@ -0,0 +1,191 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Filename: 	tc-zip.h
+//
+// Project:	Zip CPU backend for GNU Binutils
+//
+// Purpose:	
+//
+// Creator:	Dan Gisselquist, Ph.D.
+//		Gisselquist Technology, LLC
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2016-2017, Gisselquist Technology, LLC
+//
+// 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
+// by the Free Software Foundation, either version 3 of the License, or (at
+// your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program.  (It's in the $(ROOT)/doc directory, run make with no
+// target there if the PDF file isn't present.)  If not, see
+// <http://www.gnu.org/licenses/> for a copy.
+//
+// License:	GPL, v3, as defined and found on www.gnu.org,
+//		http://www.gnu.org/licenses/gpl.html
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+#ifndef	TC_ZIPCPU
+#define	TC_ZIPCPU
+
+#define	TC_ZIP	1
+
+/* This macro, when defined as zero, means our target in little endian like a
+ * PC.  A 1 would mean it was big endian.  Since the Zip CPU is big endian, we
+ * set this to one here..
+ */
+#define	TARGET_BYTES_BIG_ENDIAN	1
+
+/* If WORKING_DOT_WORD is defined, GAS will not do broken word processing
+ * (*note Broken Words ...).  Otherwise, you should set 'md_short_jump_size'
+ * to the size of a short jump (a jump that is just long enough to jump
+ * around a long jmp) and 'md_long_jump_size' to the size of a long jump
+ * (a jump that can go anywhere in the function).  You should define 
+ * md_create_short_jump to create a short jump around a long jump, and define
+ * md_create_long_jump to creat a long jump.  Here, we'll just skip these
+ * and so we define WORKING_DOT_WORD.
+ */
+#define	WORKING_DOT_WORD
+
+/* TC_ADDRESS_BYTES ... Define this macro to specify the number of bytes used
+ * to store an address.  Used to implement dc.a.  The target must have a reloc
+ * for this size.
+ */
+#define	TC_ADDRESS_BYTES	zip_address_bytes
+
+/* TC_PREDICATE_START_CHAR ... I can't find this in the documentation, but I'm
+ * guessing if a line begins with this character, the line beginning will be
+ * taken care of specially.
+ */
+#define	TC_PREDICATE_START_CHAR	'['
+#define	TC_PREDICATE_END_CHAR	']'
+
+
+/* md_cons_align ... You may define this macro to do any special alignment
+ * before a data allocation pseudo-op.
+ *
+ */
+#define	md_cons_align(N)	zip_cons_align(N)
+extern	void	zip_cons_align(int);
+
+#define	md_flush_pending_output	zip_flush_pending_output
+extern	void	zip_flush_pending_output(void);
+
+
+/* This macro is the BFD target name to use when creating the output
+* file.  This will normally depend upon the OBJ_FMT macro. */
+#define TARGET_FORMAT "elf32-zip"
+#define	TARGET_ARCH	bfd_arch_zip
+
+#define md_estimate_size_before_relax	zip_estimate_size_before_relax
+#define	md_relax_frag			zip_relax_frag
+#define md_convert_frag			zip_convert_frag
+extern long zip_relax_frag(segT, fragS *, long);
+extern int  zip_estimate_size_before_relax(fragS *, segT);
+extern void zip_convert_frag(bfd *, segT, fragS *);
+extern	int	zip_address_bytes(void);
+
+/* These macros must be defined, but it will be a fatal assembler error if we
+* ever hit them. */
+// #define md_estimate_size_before_relax(A, B) (as_fatal (_("estimate size\n")),0)
+#define md_pcrel_from(FIX) (((FIX)->fx_where+(FIX)->fx_frag->fr_address+4)>>OCTETS_PER_BYTE_POWER)
+
+// What do we need to define here to align on 32-bit boundaries?
+#define	md_section_align(SEGMENT, SIZE) (SIZE)
+
+// Check label is called right after any label (lbl: ) is found in the 
+// assembly of the program.  We need to make certain this is called, so that
+// in VLIW mode we don't try to merge an instruction pair into a new
+// instruction sequence where the label calls for jumping into the middle
+// of that sequence.
+//
+#define	tc_check_label	zip_check_label
+extern void	zip_check_label(symbolS *);
+
+
+extern	void	md_assemble(char *op_str);
+extern	void	md_end(void);
+extern	void	md_begin(void);
+// extern	symbolS *md_undefined_symbol(char *name);
+// extern	void md_operand(expressionS *name);
+
+#if (TARGET_BYTES_BIG_ENDIAN==0)
+#define	md_number_to_chars	number_to_chars_littleendian
+#else
+#define	md_number_to_chars	number_to_chars_bigendian
+#endif
+
+
+#define	GLOBAL_OFFSET_TABLE_NAME	"_GLOBAL_OFFSET_TABLE_"
+
+//	typedef	uint32_t ZIPI, ZIPA;
+//	typedef	int	ZIPIMM;
+
+// LR = Link Register, R0
+// FP = Frame Pointer, R12
+// SP = Stack Pointer, R13
+// CC = Condition Codes, R14
+// PC = Program Counter, R15
+typedef	enum {
+	ZIP_LR=0, ZIP_R1, ZIP_R2, ZIP_R3, ZIP_R4, ZIP_R5, ZIP_R6, ZIP_R7,
+	ZIP_R8, ZIP_R9, ZIP_R10, ZIP_R11, ZIP_FP,
+		ZIP_SP, ZIP_CC, ZIP_PC,
+	ZIP_uLR, ZIP_uR1, ZIP_uR2, ZIP_uR3, ZIP_uR4, ZIP_uR5, ZIP_uR6, ZIP_uR7,
+	ZIP_uR8, ZIP_uR9, ZIP_uR10, ZIP_uR11, ZIP_uFP,
+		ZIP_uSP, ZIP_uCC, ZIP_uPC,
+	ZIP_RNONE=48
+} ZIP_REG;
+
+#define	ZIP_USER_REGS	16
+
+typedef	enum {
+	ZIPC_ALWAYS, ZIPC_Z,  ZIPC_LT,  ZIPC_C,
+	ZIPC_V,      ZIPC_NZ, ZIPC_GE, ZIPC_NC
+} ZIP_CONDITION;
+
+typedef	enum {
+	// 16 ALU instructions
+	ZIPO_SUB=0, ZIPO_AND, ZIPO_ADD, ZIPO_OR,	//  5'h000xx
+	ZIPO_XOR, ZIPO_LSR, ZIPO_LSL, ZIPO_ASR,		//  5'h001xx
+	ZIPO_BREV, ZIPO_LDILO, ZIPO_MPYUHI, ZIPO_MPYSHI,//  5'h010xx
+	ZIPO_MPY, ZIPO_MOV, ZIPO_DIVU, ZIPO_DIVS,	//  5'h011xx
+//
+	ZIPO_CMP, ZIPO_TST,				//  5'h1000x
+	ZIPO_LW, ZIPO_SW, ZIPO_LH, ZIPO_SH, ZIPO_LB, ZIPO_SB,	//  5'h10xxw
+	ZIPO_LDI, ZIPO_LDIn,				//  5'h1100x
+	ZIPO_FPADD=0x1a, ZIPO_FPSUB,			//  5'h1101x
+	ZIPO_FPMPY, ZIPO_FPDIV,				//  5'h1110x
+	ZIPO_FPI2F, ZIPO_FPF2I,				//  5'h1111x
+	// Pseudo-ops
+	ZIPO_BREAK, ZIPO_LOCK, ZIPO_SIM, ZIPO_NOOP,
+	ZIPO_TRAP, ZIPO_CLR,
+	//
+	ZIPO_BRA,  ZIPO_BLT,  ZIPO_BZ, ZIPO_BC,
+	ZIPO_BV,   ZIPO_BGE,  ZIPO_BNZ, ZIPO_BNC,
+	//
+	ZIPO_HALT, ZIPO_WAIT, ZIPO_RTU, ZIPO_BUSY,
+	ZIPO_STEP, ZIPO_JMP,  ZIPO_NOT, ZIPO_NEG,
+	//
+	ZIPO_SDUMP, ZIPO_NDUMP,
+	ZIPO_SOUT,  ZIPO_NOUT,
+	ZIPO_SEXIT, ZIPO_NEXIT,
+	ZIPO_SEXTB, ZIPO_SEXTH,
+	ZIPO_JSR,   ZIPO_LJSR, ZIPO_LJMP
+} ZIP_OPCODE;
+
+typedef	enum {
+	// 8 instructions
+	ZIPV_SUB=0, ZIPV_AND, ZIPV_ADD, ZIPV_CMP,	// 3'h0xx
+	ZIPV_LW, ZIPV_SW, ZIPV_LDI, ZIPV_MOV,		// 3'h1xx
+} ZIP_VLIWCODE;
+
+#endif
+
diff -Naur '--exclude=*.swp' binutils-2.27-original/gas/configure.tgt binutils-2.27-zip/gas/configure.tgt
--- binutils-2.27-original/gas/configure.tgt	2016-08-03 03:36:51.000000000 -0400
+++ binutils-2.27-zip/gas/configure.tgt	2016-12-31 17:44:37.270167826 -0500
@@ -112,6 +112,7 @@
   x86_64*)		cpu_type=i386 arch=x86_64;;
   xgate)		cpu_type=xgate ;;
   xtensa*)		cpu_type=xtensa arch=xtensa ;;
+  zip*)			cpu_type=zip endian=big ;;
   *)			cpu_type=${cpu} ;;
 esac
 
@@ -472,6 +473,8 @@
 
   z8k-*-coff | z8k-*-sim)		fmt=coff ;;
 
+  zip*)					fmt=elf ;;
+
   *-*-aout | *-*-scout)			fmt=aout ;;
   *-*-cloudabi*)			fmt=elf ;;
   *-*-dragonfly*)			fmt=elf em=dragonfly ;;
diff -Naur '--exclude=*.swp' binutils-2.27-original/gas/Makefile.am binutils-2.27-zip/gas/Makefile.am
--- binutils-2.27-original/gas/Makefile.am	2016-08-03 03:36:51.000000000 -0400
+++ binutils-2.27-zip/gas/Makefile.am	2016-12-31 17:45:17.941851449 -0500
@@ -200,6 +200,7 @@
 	config/tc-xtensa.c \
 	config/tc-z80.c \
 	config/tc-z8k.c \
+	config/tc-zip.c \
 	config/xtensa-relax.c
 
 TARGET_CPU_HFILES = \
@@ -273,6 +274,7 @@
 	config/tc-xtensa.h \
 	config/tc-z80.h \
 	config/tc-z8k.h \
+	config/tc-zip.h \
 	config/xtensa-relax.h
 
 # OBJ files in config
diff -Naur '--exclude=*.swp' binutils-2.27-original/gas/Makefile.in binutils-2.27-zip/gas/Makefile.in
--- binutils-2.27-original/gas/Makefile.in	2016-08-03 04:16:28.000000000 -0400
+++ binutils-2.27-zip/gas/Makefile.in	2016-12-31 17:49:43.603837948 -0500
@@ -494,6 +494,7 @@
 	config/tc-xtensa.c \
 	config/tc-z80.c \
 	config/tc-z8k.c \
+	config/tc-zip.c \
 	config/xtensa-relax.c
 
 TARGET_CPU_HFILES = \
@@ -567,6 +568,7 @@
 	config/tc-xtensa.h \
 	config/tc-z80.h \
 	config/tc-z8k.h \
+	config/tc-zip.h \
 	config/xtensa-relax.h
 
 
@@ -922,6 +924,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-xtensa.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-z80.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-z8k.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-zip.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/te-vms.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/write.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xtensa-relax.Po@am__quote@
@@ -1941,6 +1944,20 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tc-z8k.obj `if test -f 'config/tc-z8k.c'; then $(CYGPATH_W) 'config/tc-z8k.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-z8k.c'; fi`
 
+tc-zip.o: config/tc-zip.c
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-zip.o -MD -MP -MF $(DEPDIR)/tc-zip.Tpo -c -o tc-zip.o `test -f 'config/tc-zip.c' || echo '$(srcdir)/'`config/tc-zip.c
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/tc-zip.Tpo $(DEPDIR)/tc-zip.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='config/tc-zip.c' object='tc-zip.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tc-zip.o `test -f 'config/tc-zip.c' || echo '$(srcdir)/'`config/tc-zip.c
+
+tc-zip.obj: config/tc-zip.c
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-zip.obj -MD -MP -MF $(DEPDIR)/tc-zip.Tpo -c -o tc-zip.obj `if test -f 'config/tc-zip.c'; then $(CYGPATH_W) 'config/tc-zip.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-zip.c'; fi`
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/tc-zip.Tpo $(DEPDIR)/tc-zip.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='config/tc-zip.c' object='tc-zip.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tc-zip.obj `if test -f 'config/tc-zip.c'; then $(CYGPATH_W) 'config/tc-zip.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-zip.c'; fi`
+
 xtensa-relax.o: config/xtensa-relax.c
 @am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xtensa-relax.o -MD -MP -MF $(DEPDIR)/xtensa-relax.Tpo -c -o xtensa-relax.o `test -f 'config/xtensa-relax.c' || echo '$(srcdir)/'`config/xtensa-relax.c
 @am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/xtensa-relax.Tpo $(DEPDIR)/xtensa-relax.Po
diff -Naur '--exclude=*.swp' binutils-2.27-original/gas/testsuite/gas/zip/zip.exp binutils-2.27-zip/gas/testsuite/gas/zip/zip.exp
--- binutils-2.27-original/gas/testsuite/gas/zip/zip.exp	1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/gas/testsuite/gas/zip/zip.exp	2017-01-12 22:12:40.839206088 -0500
@@ -0,0 +1,17 @@
+# ZipCPU assembler testsuite
+
+if [istarget zip*] {
+  run_dump_test "zip_insn_add"
+  run_dump_test "zip_insn_bratest"
+  run_dump_test "zip_insn_ctest"
+  run_dump_test "zip_insn_lditest"
+  run_dump_test "zip_insn_prologue"
+  run_dump_test "zip_insn_prologuev"
+  run_dump_test "zip_insn_specials"
+  run_dump_test "zip_insn_optest"
+  run_dump_test "zip_insn_mov"
+  run_dump_test "zip_insn_vliw"
+  # run_dump_test "zip_insn_fpu"
+  # run_dump_test "zip_insn_jsr"
+  # run_dump_test "zip_insn_jsrv"
+}
diff -Naur '--exclude=*.swp' binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_add.d binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_add.d
--- binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_add.d	1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_add.d	2017-01-12 22:01:30.790982203 -0500
@@ -0,0 +1,41 @@
+#as: -novliw
+#objdump: -dr
+#name: Generic OpB instruction test
+
+.*: +file format elf32-zip
+
+
+Disassembly of section .text:
+
+00000000 <add_insn_test>:
+   0:	00 83 e0 00 	ADD +\$-8192,R0
+   4:	00 84 a0 00 	ADD +\$-8192\+R2,R0
+   8:	08 82 00 00 	ADD +\$-131072,R1
+   c:	00 80 1f ff 	ADD +\$8191,R0
+  10:	00 84 a0 01 	ADD +\$-8191\+R2,R0
+  14:	08 81 ff ff 	ADD +\$131071,R1
+  18:	18 80 00 01 	ADD +\$1,R3
+  1c:	18 85 00 01 	ADD +\$1\+R4,R3
+  20:	30 87 c0 01 	ADD +\$4\+PC,R6
+  24:	30 87 c0 01 	ADD +\$4\+PC,R6
+  28:	30 87 c0 01 	ADD +\$4\+PC,R6
+  2c:	30 87 c0 01 	ADD +\$4\+PC,R6
+  30:	50 88 00 04 	ADD.Z +\$4,R10
+  34:	50 a8 00 04 	ADD.NZ +.4,R10
+  38:	50 90 00 04 	ADD.LT +.4,R10
+  3c:	50 b0 00 04 	ADD.GE +.4,R10
+  40:	50 98 00 04 	ADD.C +.4,R10
+  44:	50 b8 00 04 	ADD.NC +.4,R10
+  48:	50 a0 00 04 	ADD.V +.4,R10
+  4c:	50 88 00 04 	ADD.Z +.4,R10
+  50:	58 a8 00 04 	ADD.NZ +.4,R11
+  54:	60 90 00 04 	ADD.LT +.4,R12
+  58:	68 b0 00 04 	ADD.GE +.4,SP
+  5c:	70 98 00 04 	ADD.C +.4,CC
+  60:	78 b8 00 04 	BNC +@0x00000068.*$
+  64:	68 a0 00 04 	ADD.V +.4,SP
+  68:	70 80 00 04 	ADD +.4,CC
+  6c:	78 80 00 04 	BRA +@0x00000074.*$
+  70:	78 89 ff ff 	BZ +@0x00020073.*$
+  74:	78 aa 00 00 	BNZ +@0xfffe0078.*$
+
diff -Naur '--exclude=*.swp' binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_add.s binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_add.s
--- binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_add.s	1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_add.s	2017-01-10 12:00:50.870044337 -0500
@@ -0,0 +1,33 @@
+	.text
+
+add_insn_test:
+	add	-8192,R0
+	add	-8192+R2,R0
+	add	-131072,R1
+	add	8191,R0
+	add	-8191+R2,R0
+	add	131071,R1
+	add	1,R3
+	add	1(R4),R3
+	add	5+pc,R6
+	add	5+r15,R6
+	add	5+spc,R6
+	add	5+sr15,R6
+	add.z	4,R10
+	add.nz	4,R10
+	add.lt	4,R10
+	add.ge	4,R10
+	add.c	4,R10
+	add.nc	4,R10
+	add.v	4,R10
+	[z]  add	4,R10
+	[nz] add	4,R11
+	[lt] add	4,R12
+	[ge] add	4,R13
+	[c]  add	4,R14
+	[nc] add	4,R15
+	[v]  add	4,sp
+	add	4,cc
+	add	4,pc
+	add.z	131071,pc
+	add.nz	-131072,pc
diff -Naur '--exclude=*.swp' binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_bratest.d binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_bratest.d
--- binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_bratest.d	1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_bratest.d	2017-01-10 10:46:16.957469423 -0500
@@ -0,0 +1,22 @@
+#as:
+#objdump: -dr
+#name: Local branch (BRA) and conditional branch testing
+
+.*: +file format elf32-zip
+
+
+Disassembly of section .text:
+
+00000000 <bra_insn_test>:
+   0:	78 80 00 20 	BRA        \$32
+   4:	78 88 00 1c 	BZ         @0x00000024	// .. <bra_target>
+   8:	78 a8 00 18 	BNZ        @0x00000024	// .. <bra_target>
+   c:	78 98 00 14 	BC         @0x00000024	// .. <bra_target>
+  10:	78 b8 00 10 	BNC        @0x00000024	// .. <bra_target>
+  14:	78 90 00 0c 	BLT        @0x00000024	// .. <bra_target>
+  18:	78 b0 00 08 	BGE        @0x00000024	// .. <bra_target>
+  1c:	78 a0 00 04 	BV         @0x00000024	// .. <bra_target>
+  20:	06 7f ff ff 	LDI        \$-1,R0
+
+00000024 <bra_target>:
+  24:	7f c0 00 00 	NOOP       
diff -Naur '--exclude=*.swp' binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_bratest.s binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_bratest.s
--- binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_bratest.s	1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_bratest.s	2017-01-09 10:28:54.983992877 -0500
@@ -0,0 +1,14 @@
+	.text
+
+bra_insn_test:
+	bra	bra_target
+	bz	bra_target
+	bnz	bra_target
+	bc	bra_target
+	bnc	bra_target
+	blt	bra_target
+	bge	bra_target
+	bv	bra_target
+	ldi -1,r0
+bra_target:
+	noop
diff -Naur '--exclude=*.swp' binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_ctest.d binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_ctest.d
--- binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_ctest.d	1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_ctest.d	2017-01-16 11:02:02.344009430 -0500
@@ -0,0 +1,39 @@
+#as:
+#objdump: -dr
+#name: Conditional predicate test(s)
+
+.*: +file format elf32-zip
+
+
+Disassembly of section .text:
+
+00000000 <conditional_tests>:
+   0:	00 80 00 01 	ADD +\$1,R0
+   4:	00 88 00 01 	ADD.Z +\$1,R0
+   8:	00 88 00 01 	ADD.Z +\$1,R0
+   c:	00 a8 00 01 	ADD.NZ +\$1,R0
+  10:	00 a8 00 01 	ADD.NZ +\$1,R0
+  14:	00 b0 00 01 	ADD.GE +\$1,R0
+  18:	00 b0 00 01 	ADD.GE +\$1,R0
+  1c:	00 90 00 01 	ADD.LT +\$1,R0
+  20:	00 90 00 01 	ADD.LT +\$1,R0
+  24:	00 a0 00 01 	ADD.V +\$1,R0
+  28:	00 98 00 01 	ADD.C +\$1,R0
+  2c:	00 98 00 01 	ADD.C +\$1,R0
+  30:	00 b8 00 01 	ADD.NC +\$1,R0
+  34:	00 b8 00 01 	ADD.NC +\$1,R0
+  38:	00 80 00 01 	ADD +\$1,R0
+  3c:	00 88 00 01 	ADD.Z +\$1,R0
+  40:	28 8b ff e0 	ADD.Z +\$-32,R5
+  44:	00 88 00 01 	ADD.Z +\$1,R0
+  48:	00 a8 00 01 	ADD.NZ +\$1,R0
+  4c:	00 a8 00 01 	ADD.NZ +\$1,R0
+  50:	00 b0 00 01 	ADD.GE +\$1,R0
+  54:	00 b0 00 01 	ADD.GE +\$1,R0
+  58:	00 90 00 01 	ADD.LT +\$1,R0
+  5c:	00 90 00 01 	ADD.LT +\$1,R0
+  60:	00 a0 00 01 	ADD.V  +\$1,R0
+  64:	00 98 00 01 	ADD.C  +\$1,R0
+  68:	00 98 00 01 	ADD.C  +\$1,R0
+  6c:	00 b8 00 01 	ADD.NC +\$1,R0
+  70:	00 b8 00 01 	ADD.NC +\$1,R0
diff -Naur '--exclude=*.swp' binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_ctest.s binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_ctest.s
--- binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_ctest.s	1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_ctest.s	2017-01-16 10:55:53.054697861 -0500
@@ -0,0 +1,34 @@
+	.text
+
+conditional_tests:
+	add	1,R0
+	add.z	1,R0
+	add.eq	1,R0
+	add.nz	1,R0
+	add.ne	1,R0
+	add.ge	1,R0
+	add.gte	1,R0
+	add.lt	1,R0
+	add.n	1,R0
+	add.v	1,R0
+	add.c	1,R0
+	add.ltu	1,R0
+	add.nc	1,R0
+	add.geu	1,R0
+	; 
+	add	1,R0
+	[z]	add	1,R0
+	[z]	add	-32,R5
+	[EQ]	add	1,R0
+	[nz]	add	1,R0
+	[ne]	add	1,R0
+	[ge]	add	1,R0
+	[gte]	add	1,R0
+	[lt]	add	1,R0
+	[n]	add	1,R0
+	[v]	add	1,R0
+	[c]	add	1,R0
+	[ltu]	add	1,R0
+	[nc]	add	1,R0
+	[geu]	add	1,R0
+
diff -Naur '--exclude=*.swp' binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_lditest.d binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_lditest.d
--- binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_lditest.d	1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_lditest.d	2017-01-10 11:31:45.633275455 -0500
@@ -0,0 +1,24 @@
+#as: -nozipm
+#objdump: -dr
+#name: Load-Immediate test
+
+.*: +file format elf32-zip
+
+
+Disassembly of section .text:
+
+00000000 <ldi_insn_test>:
+   0:	06 00 00 00 	CLR +R0
+   4:	0a 08 00 00 	CLR.Z +\$0,R1
+   8:	16 00 20 00 	LDI +\$8192,R2
+   c:	1a 08 00 00 	LDI.Z +0x00002000,R3.*
+  10:	1a 48 20 00 
+  14:	22 29 ff ff 	LDI.NZ +0xffffe000,R4.*
+  18:	22 68 e0 00 
+  1c:	2a 03 fe 00 	BREV +\$-512,R5
+  20:	32 00 01 ff 	LDI +0xff800001,R6.*
+  24:	32 40 00 01 
+  28:	3a 00 01 ff 	BREV +\$511,R7
+  2c:	42 03 fe ff 	BREV +\$-257,R8
+  30:	4a 01 fe ff 	LDI +0xff7ffffe,R9.*
+  34:	4a 40 ff fe 
diff -Naur '--exclude=*.swp' binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_lditest.s binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_lditest.s
--- binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_lditest.s	1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_lditest.s	2017-01-09 10:28:37.472119620 -0500
@@ -0,0 +1,13 @@
+	.text
+
+ldi_insn_test:
+	ldi	0,R0
+	ldi.z	0,r1
+	ldi	8192,r2
+	ldi.z	8192,r3
+	ldi.nz	-8192,r4
+	ldi	8388607,r5
+	ldi	-8388607,r6
+	ldi	-8388608,r7
+	ldi	-8388609,r8
+	ldi	-8388610,r9
diff -Naur '--exclude=*.swp' binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_mov.d binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_mov.d
--- binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_mov.d	1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_mov.d	2017-01-12 22:09:54.925246052 -0500
@@ -0,0 +1,86 @@
+#as: -novliw -nozipm
+#objdump: -dr
+#name: Mov instruction special test
+
+.*: +file format elf32-zip
+
+
+Disassembly of section .text:
+
+00000000 <mov_insn_test>:
+   0:	0b 40 10 00 	MOV +\$-4096\+R0,R1
+   4:	1b 40 90 01 	MOV +\$-4095\+R2,R3
+   8:	2b 41 0f ff 	MOV +\$4095\+R4,R5
+   c:	3b 41 80 00 	MOV +R6,R7
+
+00000010 <mov_to_user>:
+  10:	0b 44 10 00 	MOV +\$-4096\+R0,uR1
+  14:	1b 44 90 01 	MOV +\$-4095\+R2,uR3
+  18:	2b 45 0f ff 	MOV +\$4095\+R4,uR5
+  1c:	3b 45 80 00 	MOV +R6,uR7
+
+00000020 <mov_from_user>:
+  20:	0b 40 30 00 	MOV +\$-4096\+uR0,R1
+  24:	1b 40 b0 01 	MOV +\$-4095\+uR2,R3
+  28:	2b 41 2f ff 	MOV +\$4095\+uR4,R5
+  2c:	3b 41 a0 00 	MOV +uR6,R7
+
+00000030 <mov_user_to_user>:
+  30:	0b 44 30 00 	MOV +\$-4096\+uR0,uR1
+  34:	1b 44 b0 01 	MOV +\$-4095\+uR2,uR3
+  38:	2b 45 2f ff 	MOV +\$4095\+uR4,uR5
+  3c:	3b 45 a0 00 	MOV +uR6,uR7
+
+00000040 <move_from_upc>:
+  40:	0b 47 f0 00 	MOV +\$-4096\+uPC,uR1
+  44:	1b 47 f0 01 	MOV +\$-4095\+uPC,uR3
+  48:	2b 47 ef ff 	MOV +\$4095\+uPC,uR5
+  4c:	3b 47 e0 00 	MOV +uPC,uR7
+
+00000050 <move_from_usp>:
+  50:	0b 47 70 00 	MOV +\$-4096\+uSP,uR1
+  54:	1b 47 70 01 	MOV +\$-4095\+uSP,uR3
+  58:	2b 47 6f ff 	MOV +\$4095\+uSP,uR5
+  5c:	3b 47 60 00 	MOV +uSP,uR7
+
+00000060 <move_from_ucc>:
+  60:	0b 47 b0 00 	MOV +\$-4096\+uCC,uR1
+  64:	1b 47 b0 01 	MOV +\$-4095\+uCC,uR3
+  68:	2b 47 af ff 	MOV +\$4095\+uCC,uR5
+  6c:	3b 47 a0 00 	MOV +uCC,uR7
+
+00000070 <move_to_upc>:
+  70:	7b 44 10 00 	MOV +\$-4096\+R0,uPC
+  74:	7b 44 90 01 	MOV +\$-4095\+R2,uPC
+  78:	7b 45 0f ff 	MOV +\$4095\+R4,uPC
+  7c:	7b 45 80 00 	MOV +R6,uPC
+
+00000080 <move_to_usp>:
+  80:	6b 44 10 00 	MOV +\$-4096\+R0,uSP
+  84:	6b 44 90 01 	MOV +\$-4095\+R2,uSP
+  88:	6b 45 0f ff 	MOV +\$4095\+R4,uSP
+  8c:	6b 45 80 00 	MOV +R6,uSP
+
+00000090 <move_to_ucc>:
+  90:	73 44 10 00 	MOV +\$-4096\+R0,uCC
+  94:	73 44 90 01 	MOV +\$-4095\+R2,uCC
+  98:	73 45 0f ff 	MOV +\$4095\+R4,uCC
+  9c:	73 45 80 00 	MOV +R6,uCC
+
+000000a0 <move_to_pc>:
+  a0:	7b 40 10 00 	JMP +\$-4096\+R0
+  a4:	7b 40 90 01 	JMP +\$-4095\+R2
+  a8:	7b 41 0f ff 	JMP +\$4095\+R4
+  ac:	7b 41 80 00 	JMP +R6
+
+000000b0 <move_to_sp>:
+  b0:	6b 40 10 00 	MOV +\$-4096\+R0,SP
+  b4:	6b 40 90 01 	MOV +\$-4095\+R2,SP
+  b8:	6b 41 0f ff 	MOV +\$4095\+R4,SP
+  bc:	6b 41 80 00 	MOV +R6,SP
+
+000000c0 <move_to_cc>:
+  c0:	73 40 10 00 	MOV +\$-4096\+R0,CC
+  c4:	73 40 90 01 	MOV +\$-4095\+R2,CC
+  c8:	73 41 0f ff 	MOV +\$4095\+R4,CC
+  cc:	73 41 80 00 	MOV +R6,CC
diff -Naur '--exclude=*.swp' binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_mov.s binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_mov.s
--- binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_mov.s	1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_mov.s	2017-01-12 16:45:17.027962005 -0500
@@ -0,0 +1,93 @@
+	.text
+
+mov_insn_test:
+	mov	-4096+R0,R1
+	mov	-4095+R2,R3
+	mov	4095+R4,R5
+	mov	R6,R7
+	;
+mov_to_user:
+	;
+	mov	-4096+R0,uR1
+	mov	-4095+R2,uR3
+	mov	4095+R4,uR5
+	mov	R6,uR7
+	;
+mov_from_user:
+	;
+	mov	-4096+uR0,R1
+	mov	-4095+uR2,R3
+	mov	4095+uR4,R5
+	mov	uR6,R7
+	;
+mov_user_to_user:
+	;
+	mov	-4096+uR0,uR1
+	mov	-4095+uR2,uR3
+	mov	4095+uR4,uR5
+	mov	uR6,uR7
+	;
+	;
+move_from_upc:
+	;
+	mov	-4096+upc,uR1
+	mov	-4095+upc,uR3
+	mov	4095+upc,uR5
+	mov	upc,uR7
+	;
+move_from_usp:
+	;
+	mov	-4096+usp,uR1
+	mov	-4095+usp,uR3
+	mov	4095+usp,uR5
+	mov	usp,uR7
+	;
+move_from_ucc:
+	;
+	mov	-4096+ucc,uR1
+	mov	-4095+ucc,uR3
+	mov	4095+ucc,uR5
+	mov	ucc,uR7
+	;
+move_to_upc:
+	;
+	mov	-4096+r0,upc
+	mov	-4095+r2,upc
+	mov	4095+r4,upc
+	mov	r6,upc
+	;
+move_to_usp:
+	;
+	mov	-4096+r0,usp
+	mov	-4095+r2,usp
+	mov	4095+r4,usp
+	mov	r6,usp
+	;
+move_to_ucc:
+	;
+	mov	-4096+r0,ucc
+	mov	-4095+r2,ucc
+	mov	4095+r4,ucc
+	mov	r6,ucc
+	;
+move_to_pc:
+	;
+	mov	-4096+r0,pc
+	mov	-4095+r2,pc
+	mov	4095+r4,pc
+	mov	r6,pc
+	;
+move_to_sp:
+	;
+	mov	-4096+r0,sp
+	mov	-4095+r2,sp
+	mov	4095+r4,sp
+	mov	r6,sp
+	;
+move_to_cc:
+	;
+	mov	-4096+r0,cc
+	mov	-4095+r2,cc
+	mov	4095+r4,cc
+	mov	r6,cc
+	;
diff -Naur '--exclude=*.swp' binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_optest.d binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_optest.d
--- binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_optest.d	1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_optest.d	2017-01-12 22:12:11.497444662 -0500
@@ -0,0 +1,98 @@
+#as: -novliw -nozipm
+#objdump: -dr
+#name: OpCode generation test
+
+.*: +file format elf32-zip
+
+
+Disassembly of section .text:
+
+00000000 <optest>:
+   0:	00 00 00 04 	SUB +\$4,R0
+   4:	08 40 00 04 	AND +\$4,R1
+   8:	10 80 00 04 	ADD +\$4,R2
+   c:	19 00 00 04 	XOR +\$4,R3
+  10:	20 c0 00 04 	OR +\$4,R4
+  14:	29 40 00 04 	LSR +\$4,R5
+  18:	31 80 00 04 	LSL +\$4,R6
+  1c:	39 c0 00 04 	ASR +\$4,R7
+  20:	02 40 00 03 	LDILO +\$3,R0
+  24:	0a 00 00 02 	BREV +\$2,R1
+  28:	12 80 00 03 	MPYUHI +\$3,R2
+  2c:	1a c0 00 03 	MPYSHI +\$3,R3
+  30:	23 00 00 03 	MPY +\$3,R4
+  34:	2b 80 00 07 	DIVU +\$7,R5
+  38:	33 c0 00 09 	DIVS +\$9,R6
+  3c:	04 00 00 05 	CMP +\$5,R0
+  40:	0c 40 00 05 	TST +\$5,R1
+  44:	1c 43 ff ff 	TST +\$-1,R3
+  48:	24 43 ff ff 	TST +\$-1,R4
+  4c:	14 40 00 04 	TST +\$4,R2
+  50:	0d 84 00 04 	LB +4\(R0\),R1
+  54:	15 c4 40 04 	SB +R2,\$4\(R1\)
+  58:	1d 04 80 04 	LH +4\(R2\),R3
+  5c:	25 44 c0 04 	SH +R4,\$4\(R3\)
+  60:	2c 85 00 04 	LW +4\(R4\),R5
+  64:	34 c5 40 04 	SW +R6,\$4\(R5\)
+  68:	17 80 00 07 	FPI2F +\$7,R2
+  6c:	17 84 40 03 	FPI2F +\$3\+R1,R2
+  70:	16 84 c0 00 	FPADD +R3,R2
+  74:	27 05 c0 00 	FPMPY +R7,R4
+  78:	4f 45 80 00 	FPDIV +R6,R9
+  7c:	57 c6 00 00 	FPF2I +R8,R10
+  80:	00 07 00 07 	SUB +\$7\+R12,R0
+  84:	08 47 00 07 	AND +\$7\+R12,R1
+  88:	10 87 00 07 	ADD +\$7\+R12,R2
+  8c:	19 07 00 07 	XOR +\$7\+R12,R3
+  90:	20 c7 00 07 	OR +\$7\+R12,R4
+  94:	29 47 00 07 	LSR +\$7\+R12,R5
+  98:	31 87 00 07 	LSL +\$7\+R12,R6
+  9c:	39 c7 00 07 	ASR +\$7\+R12,R7
+  a0:	00 07 3f fd 	SUB +\$-3\+R12,R0
+  a4:	08 47 3f fd 	AND +\$-3\+R12,R1
+  a8:	10 87 3f fd 	ADD +\$-3\+R12,R2
+  ac:	19 07 3f fd 	XOR +\$-3\+R12,R3
+  b0:	20 c7 3f fd 	OR +\$-3\+R12,R4
+  b4:	29 47 3f fd 	LSR +\$-3\+R12,R5
+  b8:	31 87 3f fd 	LSL +\$-3\+R12,R6
+  bc:	39 c7 3f fd 	ASR +\$-3\+R12,R7
+  c0:	02 47 01 66 	LDILO +\$358\+R12,R0
+  c4:	0a 04 7e 9a 	BREV +\$-358\+R1,R1
+  c8:	12 84 7e 9a 	MPYUHI +\$-358\+R1,R2
+  cc:	1a c4 7e 9a 	MPYSHI +\$-358\+R1,R3
+  d0:	23 04 7e 9a 	MPY +\$-358\+R1,R4
+  d4:	2b 84 7e 9a 	DIVU +\$-358\+R1,R5
+  d8:	33 c4 7e 9a 	DIVS +\$-358\+R1,R6
+  dc:	04 04 bf ed 	CMP +\$-19\+R2,R0
+  e0:	0c 44 bf ed 	TST +\$-19\+R2,R1
+  e4:	0d 80 01 04 	LB +\(\$260\),R1
+  e8:	15 c0 01 06 	SB +R2,\(\$262\)
+  ec:	1d 00 01 10 	LH +\(\$272\),R3
+  f0:	25 40 01 12 	SH +R4,\(\$274\)
+  f4:	2c 80 01 19 	LW +\(\$281\),R5
+  f8:	34 c0 01 ab 	SW +R6,\(\$427\)
+  fc:	00 02 00 00 	SUB +\$-131072,R0
+ 100:	00 02 00 00 	SUB +\$-131072,R0
+ 104:	08 42 00 00 	AND +\$-131072,R1
+ 108:	10 82 00 00 	ADD +\$-131072,R2
+ 10c:	19 02 00 00 	XOR +\$-131072,R3
+ 110:	20 c2 00 00 	OR +\$-131072,R4
+ 114:	29 42 00 00 	LSR +\$-131072,R5
+ 118:	31 82 00 00 	LSL +\$-131072,R6
+ 11c:	39 c2 00 00 	ASR +\$-131072,R7
+ 120:	02 40 14 85 	LDILO +\$5253,R0
+ 124:	0a 02 00 00 	BREV +\$-131072,R1
+ 128:	12 82 00 00 	MPYUHI +\$-131072,R2
+ 12c:	1a c2 00 00 	MPYSHI +\$-131072,R3
+ 130:	23 02 00 00 	MPY +\$-131072,R4
+ 134:	2b 82 00 00 	DIVU +\$-131072,R5
+ 138:	33 c2 00 00 	DIVS +\$-131072,R6
+ 13c:	04 02 00 00 	CMP +\$-131072,R0
+ 140:	0c 42 00 00 	TST +\$-131072,R1
+ 144:	0d 82 00 00 	LB +\(\$-131072\),R1
+ 148:	15 c2 00 00 	SB +R2,\(\$-131072\)
+ 14c:	1d 02 00 00 	LH +\(\$-131072\),R3
+ 150:	25 42 00 00 	SH +R4,\(\$-131072\)
+ 154:	2c 82 00 00 	LW +\(\$-131072\),R5
+ 158:	34 c2 00 00 	SW +R6,\(\$-131072\)
+ 15c:	17 82 00 00 	FPI2F +\$-131072,R2
diff -Naur '--exclude=*.swp' binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_optest.s binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_optest.s
--- binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_optest.s	1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_optest.s	2017-01-12 16:28:47.212542071 -0500
@@ -0,0 +1,119 @@
+	.text
+
+optest:
+	sub	4,R0
+	and	4,R1
+	add	4,R2
+	xor	4,R3
+	or	4,R4
+	lsr	4,R5
+	lsl	4,R6
+	asr	4,R7
+	;
+	ldilo	3,R0
+	brev	2,R1
+	mpyuhi	3,R2
+	mpyshi	3,R3
+	mpy	3,R4
+	divu	7,R5
+	divs	9,r6
+	; mov	R1,R2
+
+	;
+	cmp	5,R0
+	test	5,R1
+	test	R3
+	tst	R4
+	tst	4,R2
+	;
+	lb	4(r0),r1
+	sb	r2,4(r1)
+	lh	4(r2),r3
+	sh	r4,4(r3)
+	lw	4(r4),r5
+	sw	r6,4(r5)
+	; ldi
+	fpi2f	7,r2
+	fpi2f	3(r1),r2
+	fpadd	r3,r2
+	; fpmpy	r7,r4
+	fpmul	r7,r4
+	fpdiv	r6,r9
+	fpf2i	r8,r10
+	;
+	;
+; Now repeat, with Reg + Imm
+	sub	7(r12),R0
+	and	7(r12),R1
+	add	7(r12),R2
+	xor	7(r12),R3
+	or	7(r12),R4
+	lsr	7(r12),R5
+	lsl	7(r12),R6
+	asr	7(r12),R7
+	;
+	sub	-3+r12,R0
+	and	-3+r12,R1
+	add	-3+r12,R2
+	xor	-3+r12,R3
+	or	-3+r12,R4
+	lsr	-3+r12,R5
+	lsl	-3+r12,R6
+	asr	-3+r12,R7
+	;
+	ldilo	358+r12,R0
+	brev	-358+r1,R1
+	mpyuhi	-358+r1,R2
+	mpyshi	-358+r1,R3
+	mpy	-358+r1,R4
+	divu	-358+r1,R5
+	divs	-358+r1,r6
+	; mov	R1,R2
+
+	;
+	cmp	-19+r2,R0
+	test	-19+r2,R1
+	;
+	lb	0x104,r1
+	sb	r2,0x106
+	lh	0x110,r3
+	sh	r4,0x112
+	lw	0x119,r5
+	sw	r6,0x1ab
+	; ldi
+	; floating point --- already done
+
+
+; Ops with the minimum integer
+	sub	-0x20000,R0
+	sub	-131072,R0
+	and	-131072,R1
+	add	-131072,R2
+	xor	-0x20000,R3
+	or	-131072,R4
+	lsr	-131072,R5
+	lsl	-131072,R6
+	asr	-131072,R7
+	;
+	ldilo	0x21485,R0
+	brev	-0x20000,R1
+	mpyuhi	-0x20000,R2
+	mpyshi	-0x20000,R3
+	mpy	-0x20000,R4
+	divu	-0x20000,R5
+	divs	-0x20000,r6
+	; mov	R1,R2
+
+	;
+	cmp	-0x20000,R0
+	test	-0x20000,R1
+	;
+	lb	-0x20000,r1
+	sb	r2,-0x20000
+	lh	-0x20000,r3
+	sh	r4,-0x20000
+	lw	-0x20000,r5
+	sw	r6,-0x20000
+	; ldi
+	fpi2f	-0x20000,r2
+	;
diff -Naur '--exclude=*.swp' binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_prologue.d binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_prologue.d
--- binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_prologue.d	1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_prologue.d	2017-01-10 11:09:36.301473902 -0500
@@ -0,0 +1,32 @@
+#as: -novliw
+#objdump: -dr
+#name: Prologue test - Non-thumb
+
+.*: +file format elf32-zip
+
+
+Disassembly of section .text:
+
+00000000 <some_function>:
+   0:	68 00 00 30 	SUB +\$48,SP
+   4:	04 c7 40 00 	SW +R0,\(SP\)
+   8:	2c c7 40 04 	SW +R5,\$4\(SP\)
+   c:	34 c7 40 08 	SW +R6,\$8\(SP\)
+  10:	3c c7 40 0c 	SW +R7,\$12\(SP\)
+  14:	44 c7 40 10 	SW +R8,\$16\(SP\)
+  18:	4c c7 40 14 	SW +R9,\$20\(SP\)
+  1c:	54 c7 40 18 	SW +R10,\$24\(SP\)
+  20:	5c c7 40 1c 	SW +R11,\$28\(SP\)
+  24:	64 c7 40 20 	SW +R12,\$32\(SP\)
+  28:	38 84 80 00 	ADD +R2,R7
+  2c:	04 87 40 00 	LW +\(SP\),R0
+  30:	04 87 40 04 	LW +4\(SP\),R0
+  34:	04 87 40 08 	LW +8\(SP\),R0
+  38:	04 87 40 0c 	LW +12\(SP\),R0
+  3c:	04 87 40 10 	LW +16\(SP\),R0
+  40:	04 87 40 14 	LW +20\(SP\),R0
+  44:	04 87 40 18 	LW +24\(SP\),R0
+  48:	04 87 40 1c 	LW +28\(SP\),R0
+  4c:	04 87 40 20 	LW +32\(SP\),R0
+  50:	68 80 00 30 	ADD +\$48,SP
+  54:	7b 40 00 00 	RTN +
diff -Naur '--exclude=*.swp' binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_prologue.s binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_prologue.s
--- binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_prologue.s	1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_prologue.s	2017-01-09 07:25:40.495644200 -0500
@@ -0,0 +1,24 @@
+some_function:
+	SUB	48,SP
+	SW	R0,(SP)
+	SW	R5,4(SP)
+	SW	R6,8(SP)
+	SW	R7,12(SP)
+	SW	R8,16(SP)
+	SW	R9,20(SP)
+	SW	R10,24(SP)
+	SW	R11,28(SP)
+	SW	R12,32(SP)
+	ADD	R2,R7
+	LW	(SP),R0
+	LW	4(SP),R0
+	LW	8(SP),R0
+	LW	12(SP),R0
+	LW	16(SP),R0
+	LW	20(SP),R0
+	LW	24(SP),R0
+	LW	28(SP),R0
+	LW	32(SP),R0
+	ADD	48,SP
+	RETN
+
diff -Naur '--exclude=*.swp' binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_prologuev.d binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_prologuev.d
--- binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_prologuev.d	1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_prologuev.d	2017-01-12 21:58:59.513900839 -0500
@@ -0,0 +1,21 @@
+#as: -nozipm -vliw
+#objdump: -dr
+#name: Prologue test - thumb
+
+.*: +file format elf32-zip
+
+
+Disassembly of section .text:
+
+00000000 <some_function>:
+   0:	e8 30 85 00 	SUB +\$48,SP +| SW +R0,\(SP\)       
+   4:	ad 04 b5 08 	SW +R5,\$4\(SP\) +| SW +R6,$8\(SP\)     
+   8:	bd 0c c5 10 	SW +R7,\$12\(SP\) +| SW +R8,$16\(SP\)    
+   c:	cd 14 d5 18 	SW +R9,\$20\(SP\) +| SW +R10,$24\(SP\)   
+  10:	dd 1c e5 20 	SW +R11,\$28\(SP\) +| SW +R12,$32\(SP\)   
+  14:	ba 90 84 00 	ADD +R2,R7 +| LW +\(SP\),R0       
+  18:	84 04 84 08 	LW +4\(SP\),R0 +| LW +8\(SP\),R0      
+  1c:	84 0c 84 10 	LW +12\(SP\),R0 +| LW +16\(SP\),R0     
+  20:	84 14 84 18 	LW +20\(SP\),R0 +| LW +24\(SP\),R0     
+  24:	84 1c 84 20 	LW +28\(SP\),R0 +| LW +32\(SP\),R0     
+  28:	ea 30 ff 80 	ADD +\$48,SP +| MOV +R0,PC         
diff -Naur '--exclude=*.swp' binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_prologuev.s binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_prologuev.s
--- binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_prologuev.s	1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_prologuev.s	2017-01-10 11:29:18.612449601 -0500
@@ -0,0 +1,24 @@
+some_function:
+	SUB	48,SP
+	SW	R0,(SP)
+	SW	R5,4(SP)
+	SW	R6,8(SP)
+	SW	R7,12(SP)
+	SW	R8,16(SP)
+	SW	R9,20(SP)
+	SW	R10,24(SP)
+	SW	R11,28(SP)
+	SW	R12,32(SP)
+	ADD	R2,R7
+	LW	(SP),R0
+	LW	4(SP),R0
+	LW	8(SP),R0
+	LW	12(SP),R0
+	LW	16(SP),R0
+	LW	20(SP),R0
+	LW	24(SP),R0
+	LW	28(SP),R0
+	LW	32(SP),R0
+	ADD	48,SP
+	RETN
+
diff -Naur '--exclude=*.swp' binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_specials.d binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_specials.d
--- binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_specials.d	1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_specials.d	2017-01-24 08:03:32.892847657 -0500
@@ -0,0 +1,41 @@
+#as:
+#objdump: -dr
+#name: Special instruction(s) test
+
+.*: +file format elf32-zip
+
+
+Disassembly of section .text:
+
+00000000 <specials_test>:
+   0:	7f 00 00 00 	BRK        
+   4:	7f 00 00 11 	BRK        \$17
+   8:	7f c0 00 00 	NOOP       
+   c:	7f c0 02 ff 	NDUMP *$
+  10:	7f c0 02 07 	NDUMP      R7
+  14:	7f c0 02 03 	NDUMP      R3
+  18:	7f c0 02 14 	NDUMP      uR4
+  1c:	7f c0 01 00 	NEXIT      
+  20:	7f c0 01 00 	NEXIT      
+  24:	7f c0 01 fc 	NEXIT      \$-4
+  28:	7f c0 01 f0 	NEXIT      \$-16
+  2c:	7f c0 03 07 	NEXIT      R7
+  30:	7f c4 00 23 	NSIM       \$262179
+  34:	7f 80 00 00 	SIM +$
+  38:	7f 80 02 ff 	SDUMP *$
+  3c:	7f 80 02 07 	SDUMP      R7
+  40:	7f 80 02 03 	SDUMP      R3
+  44:	7f 80 02 14 	SDUMP      uR4
+  48:	7f 80 01 17 	SEXIT      \$23
+  4c:	7f 80 01 e9 	SEXIT      \$-23
+  50:	7f 80 01 00 	SEXIT      
+  54:	7f 80 03 0f 	SEXIT      PC
+  58:	7f 80 03 0e 	SEXIT      CC
+  5c:	7f 84 00 23 	SIM        \$262179
+  60:	7f 87 0f 23 	SIM        \$462627
+  64:	7f 80 04 61 	SOUT       \$97
+  68:	7f c0 04 62 	NOUT       \$98
+  6c:	7f 80 02 22 	SOUT       R2
+  70:	7f c0 02 27 	NOUT       R7
+  74:	7f 80 02 33 	SOUT       uR3
+  78:	7f c0 02 38 	NOUT       uR8
diff -Naur '--exclude=*.swp' binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_specials.s binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_specials.s
--- binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_specials.s	1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_specials.s	2017-01-19 07:18:13.405003668 -0500
@@ -0,0 +1,35 @@
+	.text
+
+specials_test:
+	break
+	break	17
+	noop
+	ndump
+	ndump	R7
+	ndump	sR3
+	ndump	uR4
+	nexit
+	nexit	0
+	nexit	-4
+	nexit	240
+	nexit	R7
+	noop	0x40023
+	snoop
+	sdump
+	sdump	R7
+	sdump	sR3
+	sdump	uR4
+	sexit	23
+	sexit	-23
+	sexit	0
+	sexit	PC
+	sexit	CC
+	snoop	0x40023
+	sim	0x70f23
+	sout	'a'
+	nout	'b'
+	sout	R2
+	nout	R7
+	sout	uR3
+	nout	uR8
+
diff -Naur '--exclude=*.swp' binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_vliw.d binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_vliw.d
--- binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_vliw.d	1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_vliw.d	2017-01-12 21:50:28.719237156 -0500
@@ -0,0 +1,77 @@
+#as: -vliw
+#objdump: -dr
+#name: Thumb instruction set test
+
+.*: +file format elf32-zip
+
+
+Disassembly of section .text:
+
+00000000 <vliw_merge_test>:
+   0:	82 01 8a 01 	ADD +\$1,R0 +| ADD +$1,R1         
+   4:	10 88 00 01 	ADD.Z +\$1,R2
+   8:	18 a8 00 01 	ADD.NZ +\$1,R3
+   c:	20 a0 00 01 	ADD.V +\$1,R4
+  10:	00 80 00 7f 	ADD +\$127,R0
+  14:	00 80 00 80 	ADD +\$128,R0
+  18:	00 80 00 81 	ADD +\$129,R0
+  1c:	82 3e 82 3f 	ADD +\$62,R0 +| ADD +\$63,R0 *
+  20:	00 80 00 40 	ADD +\$64,R0
+  24:	00 80 00 41 	ADD +\$65,R0
+  28:	82 88 82 89 	ADD +R1,R0 +| ADD +\$1+R1,R0 *
+  2c:	82 89 82 8a 	ADD +\$1\+R1,R0 +| ADD +\$2\+R1,R0 *
+  30:	82 8a 82 8a 	ADD +\$2\+R1,R0 +| ADD +\$2\+R1,R0 *
+  34:	00 84 40 03 	ADD +\$3\+R1,R0
+  38:	00 84 40 04 	ADD +\$4\+R1,R0
+  3c:	00 84 40 05 	ADD +\$5\+R1,R0
+  40:	00 84 7f fb 	ADD +\$-5\+R1,R0
+  44:	82 8c 82 8d 	ADD +\$-4\+R1,R0 +| ADD +$-3+R1,R0 *
+  48:	82 8e 82 8f 	ADD +\$-2\+R1,R0 +| ADD +$-1+R1,R0 *
+  4c:	82 88 84 88 	ADD +R1,R0 +| LW +(R1),R0 *
+  50:	94 89 9c 8a 	LW  +1\(R1\),R2 +| LW +2(R1),R3 *
+  54:	24 84 40 03 	LW  +3\(R1\),R4
+  58:	2c 84 40 04 	LW  +4\(R1\),R5
+  5c:	84 00 94 01 	LW  +\(SP\),R0 +| LW +1\(SP\),R2 *
+  60:	9c 02 a4 03 	LW  +2\(SP\),R3 +| LW +3\(SP\),R4 *
+  64:	ac 04 b4 3d 	LW +4\(SP\),R5 +| LW +61\(SP\),R6 *
+  68:	bc 3e c4 3f 	LW +62\(SP\),R7 +| LW +63\(SP\),R8 *
+  6c:	4c 87 40 40 	LW +64\(SP\),R9
+  70:	54 87 40 41 	LW +65\(SP\),R10
+  74:	54 c7 7f bf 	SW +R10,\$-65\(SP\)
+  78:	cd 40 c5 41 	SW +R9,\$-64\(SP\) +| SW +R8,$-63\(SP\) *
+  7c:	bd 42 b5 43 	SW +R7,\$-62\(SP\) +| SW +R6,$-61\(SP\) *
+  80:	b5 44 87 f8 	SW +R6,\$-60\(SP\) +| MOV +PC,R0 *
+  84:	8f f9 97 fa 	MOV +\$4\+PC,R1 +| MOV +$8\+PC,R2 *
+  88:	97 fa 9f fb 	MOV +\$8\+PC,R2 +| MOV +$12\+PC,R3 *
+  8c:	23 43 c0 04 	MOV +0x000000a0,R4.*$
+  90:	2b 43 c0 05 	MOV +0x000000a8,R5.*$
+  94:	33 43 df fb 	MOV +0x00000084,R6.*$
+  98:	bf fc c7 fd 	MOV +\$-16\+PC,R7 +| MOV +$-12\+PC,R8 *
+  9c:	cf fe 87 ff 	MOV +\$-8\+PC,R9 +| MOV +$-4\+PC,R0 *
+  a0:	13 43 c0 00 	MOV +0x000000a4,R2.*$
+
+000000a4 <vliw_ldi_test>:
+  a4:	86 00 8e 40 	CLR +R0 +| LDI +\$64,R1
+  a8:	16 00 00 7f 	LDI +\$127,R2
+  ac:	1e 00 00 80 	LDI +\$128,R3
+  b0:	26 00 00 81 	LDI +\$129,R4
+  b4:	2e 00 00 82 	LDI +\$130,R5
+  b8:	36 7f ff 7e 	LDI +\$-130,R6
+  bc:	3e 7f ff 7f 	LDI +\$-129,R7
+  c0:	c6 80 ce 81 	LDI +\$-128,R8 +| LDI +\$-127,R9
+  c4:	d6 82 de 83 	LDI +\$-126,R10 +| LDI +\$-125,R11
+
+000000c8 <vliw_op_test>:
+  c8:	88 80 99 90 	SUB +R0,R1 +| AND +R2,R3 *$
+  cc:	aa a0 bb b0 	ADD +R4,R5 +| CMP +R6,uR7 *$
+  d0:	c4 b8 cd d0 	LW +\(R7\),R8 +| SW +R9,\$-48\(SP\) *$
+  d4:	de 7c 9f 89 	LDI +\$124,R11 +| MOV +$1+R1,R3 *$
+  d8:	c8 05 88 80 	SUB +\$5,R9 +| SUB +R0,R1 *$
+  dc:	99 90 aa a0 	AND +R2,R3 +| ADD +R4,R5 *$
+  e0:	bb b0 c4 b8 	CMP +R6,uR7 +| LW +(R7),R8 *$
+  e4:	cd d0 de 7c 	SW +R9,\$-48\(SP\) +| LDI +\$124,R11 *$
+  e8:	9f 89 c8 0e 	MOV +\$1\+R1,R3 +| SUB +\$14,R9 *$
+  ec:	99 11 aa 13 	AND +\$17,R3 +| ADD +\$19,R5 *$
+  f0:	bb 3f c4 18 	CMP +\$63\+R7,R7 +| LW         24\(SP\),R8 *$
+  f4:	cd 1c de 7c 	SW +R9,\$28\(SP\) +| LDI +\$124,R11 *$
+  f8:	1b 40 40 01 	MOV +\$1\+R1,R3
diff -Naur '--exclude=*.swp' binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_vliw.s binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_vliw.s
--- binutils-2.27-original/gas/testsuite/gas/zip/zip_insn_vliw.s	1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/gas/testsuite/gas/zip/zip_insn_vliw.s	2017-01-12 16:55:54.690241718 -0500
@@ -0,0 +1,110 @@
+	.text
+
+vliw_merge_test:
+	; Simple: are merges enabled?
+	add	1,R0
+	add	1,R1
+	; These should not merge with any neighbor
+	add.z	1,R2
+	add.nz	1,R3
+	add.v	1,R4
+	add	127,R0
+	add	128,R0
+	add	129,R0
+	add	62,R0
+	add	63,R0
+	add	64,R0
+	add	65,R0
+	add	0(R1),R0
+	add	1(R1),R0
+	add	1(R1),R0
+	add	2(R1),R0
+	add	2(R1),R0
+	add	2(R1),R0
+	add	3(R1),R0
+	add	4(R1),R0
+	add	5(R1),R0
+	add	-5(R1),R0
+	add	-4(R1),R0
+	add	-3(R1),R0
+	add	-2(R1),R0
+	add	-1(R1),R0
+	add	0(R1),R0
+	lw	(r1),r0
+	lw	1(r1),r2
+	lw	2(r1),r3
+	lw	3(r1),r4
+	lw	4(r1),r5
+	lw	(sp),r0
+	lw	1(sp),r2
+	lw	2(sp),r3
+	lw	3(sp),r4
+	lw	4(sp),r5
+	lw	61(sp),r6
+	lw	62(sp),r7
+	lw	63(sp),r8
+	lw	64(sp),r9
+	lw	65(sp),r10
+	sw	r10,-65(sp)
+	sw	r9,-64(sp)
+	sw	r8,-63(sp)
+	sw	r7,-62(sp)
+	sw	r6,-61(sp)
+	sw	r6,-60(sp)
+	mov	(PC),R0
+	mov	1(PC),R1
+	mov	2(PC),R2
+	mov	2(PC),R2
+	mov	3(PC),R3
+	mov	4(PC),R4
+	mov	5(PC),R5
+	mov	-5(PC),R6
+	mov	-4(PC),R7
+	mov	-3(PC),R8
+	mov	-2(PC),R9
+	mov	-1(PC),R0
+	mov	0(PC),R2
+	# LDI's
+vliw_ldi_test:
+	LDI	0,R0
+	LDI	64,R1
+	LDI	127,R2
+	LDI	128,R3
+	LDI	129,R4
+	LDI	130,R5
+	LDI	-130,R6
+	LDI	-129,R7
+	LDI	-128,R8
+	LDI	-127,R9
+	LDI	-126,R10
+	LDI	-125,R11
+vliw_op_test:
+	sub	r0,r1
+	and	r2,r3
+	add	r4,r5
+	cmp	r6,r7
+	lw	(r7),r8
+	sw	r9,(r10)
+	ldi	124,r11
+	mov	1+r1,r3
+	# and with a touch of offset
+	sub	5,r9
+	sub	r0,r1
+	and	r2,r3
+	add	r4,r5
+	cmp	r6,r7
+	lw	(r7),r8
+	sw	r9,(r10)
+	ldi	124,r11
+	mov	1+r1,r3
+	# And now, so that they all have immediates instead of register
+	sub	14,r9
+	and	17,r3
+	add	19,r5
+	cmp	63,r7
+	lw	24(sp),r8
+	sw	r9,28(sp)
+	ldi	124,r11
+	mov	1+r1,r3
+
+
diff -Naur '--exclude=*.swp' binutils-2.27-original/gas/write.c binutils-2.27-zip/gas/write.c
--- binutils-2.27-original/gas/write.c	2016-08-03 03:36:51.000000000 -0400
+++ binutils-2.27-zip/gas/write.c	2016-12-31 17:51:52.470985149 -0500
@@ -2676,7 +2676,7 @@
 
 	      case rs_org:
 		{
-		  addressT target = offset;
+		  addressT target = offset * OCTETS_PER_BYTE;
 		  addressT after;
 
 		  if (symbolP)
diff -Naur '--exclude=*.swp' binutils-2.27-original/include/dis-asm.h binutils-2.27-zip/include/dis-asm.h
--- binutils-2.27-original/include/dis-asm.h	2016-08-03 03:36:53.000000000 -0400
+++ binutils-2.27-zip/include/dis-asm.h	2016-12-31 17:52:29.022758231 -0500
@@ -318,10 +318,12 @@
 extern int print_insn_rl78_g10		(bfd_vma, disassemble_info *);
 extern int print_insn_rl78_g13		(bfd_vma, disassemble_info *);
 extern int print_insn_rl78_g14		(bfd_vma, disassemble_info *);
+extern int print_insn_zip		(bfd_vma, disassemble_info *);
 
 extern disassembler_ftype arc_get_disassembler (bfd *);
 extern disassembler_ftype cris_get_disassembler (bfd *);
 extern disassembler_ftype rl78_get_disassembler (bfd *);
+extern disassembler_ftype zip_get_disassembler (bfd *);
 
 extern void print_aarch64_disassembler_options (FILE *);
 extern void print_i386_disassembler_options (FILE *);
diff -Naur '--exclude=*.swp' binutils-2.27-original/include/elf/common.h binutils-2.27-zip/include/elf/common.h
--- binutils-2.27-original/include/elf/common.h	2016-08-03 03:36:53.000000000 -0400
+++ binutils-2.27-zip/include/elf/common.h	2016-12-31 17:53:58.942198950 -0500
@@ -411,6 +411,9 @@
 /* Old constant that might be in use by some software. */
 #define EM_OPENRISC		EM_OR1K
 
+/* ZipCPU vs instruction set -- Use this until we get an official number */
+#define EM_ZIP			0xdad1
+
 /* See the above comment before you add a new EM_* value here.  */
 
 /* Values for e_version.  */
diff -Naur '--exclude=*.swp' binutils-2.27-original/include/elf/zip.h binutils-2.27-zip/include/elf/zip.h
--- binutils-2.27-original/include/elf/zip.h	1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/include/elf/zip.h	2017-01-18 18:19:33.764898333 -0500
@@ -0,0 +1,58 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Filename: 	zip.h
+//
+// Project:	Zip CPU backend for GNU Binutils
+//
+// Purpose:	
+//
+// Creator:	Dan Gisselquist, Ph.D.
+//		Gisselquist Technology, LLC
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2016-2017, Gisselquist Technology, LLC
+//
+// 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
+// by the Free Software Foundation, either version 3 of the License, or (at
+// your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program.  (It's in the $(ROOT)/doc directory, run make with no
+// target there if the PDF file isn't present.)  If not, see
+// <http://www.gnu.org/licenses/> for a copy.
+//
+// License:	GPL, v3, as defined and found on www.gnu.org,
+//		http://www.gnu.org/licenses/gpl.html
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+#ifndef	_ELF_ZIP_H
+#define	_ELF_ZIP_H
+
+#include "elf/reloc-macros.h"
+
+/* Relocations.  */
+START_RELOC_NUMBERS(elf_zip_reloc_type)
+  RELOC_NUMBER (R_ZIP_NONE,        0)
+  RELOC_NUMBER (R_ZIP_VALUE,       1)
+  RELOC_NUMBER (R_ZIP_BREV,        2)
+  RELOC_NUMBER (R_ZIP_LLO,         3)
+  RELOC_NUMBER (R_ZIP_LDI,         4)
+  RELOC_NUMBER (R_ZIP_BRANCH,      5)
+  RELOC_NUMBER (R_ZIP_OPB_IMM,     6)
+  RELOC_NUMBER (R_ZIP_OPB_OFFSET,  7)
+  RELOC_NUMBER (R_ZIP_OPB_PCREL,   8)
+  RELOC_NUMBER (R_ZIP_MOV_OFFSET,  9)
+  RELOC_NUMBER (R_ZIP_MOV_PCREL,  10)
+  // RELOC_NUMBER (R_ZIP_OPB_GOTREL, 11)
+  // RELOC_NUMBER (R_ZIP_MOV_GOTREL, 12)
+END_RELOC_NUMBERS(R_ZIP_max)
+
+#endif /* _ELF_ZIP_H */
diff -Naur '--exclude=*.swp' binutils-2.27-original/ld/configure.tgt binutils-2.27-zip/ld/configure.tgt
--- binutils-2.27-original/ld/configure.tgt	2016-08-03 03:36:54.000000000 -0400
+++ binutils-2.27-zip/ld/configure.tgt	2016-12-31 17:55:04.013793303 -0500
@@ -816,6 +816,8 @@
 			;;
 z8k-*-coff) 		targ_emul=z8002; targ_extra_emuls=z8001
 			;;
+zip*)	 		targ_emul=elf32zip;
+			;;
 *-*-ieee*)		targ_emul=vanilla
 			;;
 *-tandem-none)		targ_emul=st2000
diff -Naur '--exclude=*.swp' binutils-2.27-original/ld/emulparams/elf32zip.sh binutils-2.27-zip/ld/emulparams/elf32zip.sh
--- binutils-2.27-original/ld/emulparams/elf32zip.sh	1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/ld/emulparams/elf32zip.sh	2017-01-05 08:22:45.000000000 -0500
@@ -0,0 +1,50 @@
+################################################################################
+#
+# Filename:	elf32zip.sh
+#
+# Project:	Zip CPU backend for GNU Binutils
+#
+# Purpose:	This is a simple shell script providing some variables used
+#		later and elsewhere by the ZipCPU linker.  Some things to note
+#	are: 1) the TEXT_START_ADDR is set for the Basys-3 board I am using and
+#	will likely need to change as your platform changes, 2) there currently
+#	aren't any "pages" since the ZipCPU doesn't yet	support a memory
+#	management unit, 3) the ENTRY point only works if a separate loader
+#	is loading the ZipCPU into RAM.  In all other cases, place your startup
+#	code directly at the top of the .start segment, and set the ZipCPU
+#	to run from there.  It'll start then at the first address loaded in
+#	memory.
+#
+# Creator:	Dan Gisselquist, Ph.D.
+#		Gisselquist Technology, LLC
+#
+################################################################################
+#
+# Copyright (C) 2016, Gisselquist Technology, LLC
+#
+# 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
+# by the Free Software Foundation, either version 3 of the License, or (at
+# your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# License:	GPL, v3, as defined and found on www.gnu.org,
+#		http://www.gnu.org/licenses/gpl.html
+#
+#
+################################################################################
+
+SCRIPT_NAME=elf
+TEMPLATE_NAME=elf32
+ARCH=zip
+OUTPUT_FORMAT="elf32-zip"
+ENTRY="_start"
+TEXT_START_ADDR="0x08000"
+MAXPAGESIZE=0x01000
+COMMONPAGESIZE=0x1000
+EMBEDDED=yes
+
diff -Naur '--exclude=*.swp' binutils-2.27-original/ld/Makefile.am binutils-2.27-zip/ld/Makefile.am
--- binutils-2.27-original/ld/Makefile.am	2016-08-03 03:36:54.000000000 -0400
+++ binutils-2.27-zip/ld/Makefile.am	2016-12-31 17:57:39.684819835 -0500
@@ -286,6 +286,7 @@
 	eelf32xc16xs.c \
 	eelf32xstormy16.c \
 	eelf32xtensa.c \
+	eelf32zip.c \
 	eelf_i386.c \
 	eelf_i386_be.c \
 	eelf_i386_chaos.c \
@@ -1309,6 +1310,9 @@
   $(BFDDIR)/elf-bfd.h $(BFDDIR)/libbfd.h $(INCDIR)/elf/xtensa.h \
   $(srcdir)/scripttempl/elfxtensa.sc ${GEN_DEPENDS}
 
+eelf32zip.c: $(srcdir)/emulparams/elf32zip.sh $(ELF_DEPS) \
+  $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+
 eelf_i386.c: $(srcdir)/emulparams/elf_i386.sh \
   $(ELF_X86_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 
diff -Naur '--exclude=*.swp' binutils-2.27-original/ld/Makefile.in binutils-2.27-zip/ld/Makefile.in
--- binutils-2.27-original/ld/Makefile.in	2016-08-03 03:36:54.000000000 -0400
+++ binutils-2.27-zip/ld/Makefile.in	2016-12-31 17:59:30.788122513 -0500
@@ -654,6 +654,7 @@
 	eelf32xc16xs.c \
 	eelf32xstormy16.c \
 	eelf32xtensa.c \
+	eelf32zip.c \
 	eelf_i386.c \
 	eelf_i386_be.c \
 	eelf_i386_chaos.c \
@@ -1314,6 +1315,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32xc16xs.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32xstormy16.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32xtensa.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32zip.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_aix.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_ia64.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_ia64_fbsd.Po@am__quote@
@@ -2897,6 +2899,9 @@
   $(BFDDIR)/elf-bfd.h $(BFDDIR)/libbfd.h $(INCDIR)/elf/xtensa.h \
   $(srcdir)/scripttempl/elfxtensa.sc ${GEN_DEPENDS}
 
+eelf32zip.c: $(srcdir)/emulparams/elf32zip.sh $(ELF_DEPS) \
+  $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+
 eelf_i386.c: $(srcdir)/emulparams/elf_i386.sh \
   $(ELF_X86_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 
diff -Naur '--exclude=*.swp' binutils-2.27-original/opcodes/configure binutils-2.27-zip/opcodes/configure
--- binutils-2.27-original/opcodes/configure	2016-08-03 04:33:39.000000000 -0400
+++ binutils-2.27-zip/opcodes/configure	2017-01-05 08:50:32.000000000 -0500
@@ -12685,7 +12685,7 @@
 	bfd_xtensa_arch)	ta="$ta xtensa-dis.lo" ;;
 	bfd_z80_arch)		ta="$ta z80-dis.lo" ;;
 	bfd_z8k_arch)		ta="$ta z8k-dis.lo" ;;
-
+	bfd_zip_arch)		ta="$ta zip-dis.lo zip-opc.lo" ;;
 	"")			;;
 	*)		as_fn_error "*** unknown target architecture $arch" "$LINENO" 5 ;;
 	esac
diff -Naur '--exclude=*.swp' binutils-2.27-original/opcodes/configure.ac binutils-2.27-zip/opcodes/configure.ac
--- binutils-2.27-original/opcodes/configure.ac	2016-08-03 03:36:54.000000000 -0400
+++ binutils-2.27-zip/opcodes/configure.ac	2017-01-05 08:49:53.000000000 -0500
@@ -353,7 +353,7 @@
 	bfd_xtensa_arch)	ta="$ta xtensa-dis.lo" ;;
 	bfd_z80_arch)		ta="$ta z80-dis.lo" ;;
 	bfd_z8k_arch)		ta="$ta z8k-dis.lo" ;;
-
+	bfd_zip_arch)		ta="$ta zip-dis.lo zip-opc.lo" ;;
 	"")			;;
 	*)		AC_MSG_ERROR(*** unknown target architecture $arch) ;;
 	esac
diff -Naur '--exclude=*.swp' binutils-2.27-original/opcodes/disassemble.c binutils-2.27-zip/opcodes/disassemble.c
--- binutils-2.27-original/opcodes/disassemble.c	2016-08-03 03:36:54.000000000 -0400
+++ binutils-2.27-zip/opcodes/disassemble.c	2016-12-31 18:02:03.139162969 -0500
@@ -98,6 +98,7 @@
 #define ARCH_xtensa
 #define ARCH_z80
 #define ARCH_z8k
+#define ARCH_zip
 #define INCLUDE_SHMEDIA
 #endif
 
@@ -495,6 +496,11 @@
 	disassemble = print_insn_z8002;
       break;
 #endif
+#ifdef ARCH_zip
+    case bfd_arch_zip:
+	disassemble = zip_get_disassembler(abfd);
+	break;
+#endif
 #ifdef ARCH_vax
     case bfd_arch_vax:
       disassemble = print_insn_vax;
diff -Naur '--exclude=*.swp' binutils-2.27-original/opcodes/Makefile.am binutils-2.27-zip/opcodes/Makefile.am
--- binutils-2.27-original/opcodes/Makefile.am	2016-08-03 03:36:54.000000000 -0400
+++ binutils-2.27-zip/opcodes/Makefile.am	2017-01-05 08:28:32.000000000 -0500
@@ -86,7 +86,9 @@
 	w65-opc.h \
 	xc16x-desc.h xc16x-opc.h \
 	xstormy16-desc.h xstormy16-opc.h \
-	z8k-opc.h
+	z8k-opc.h \
+	zip-opc.h \
+	zip-dis.h
 
 # C source files that correspond to .o's ending up in libopcodes
 # for all machines.
@@ -269,7 +271,9 @@
 	xgate-dis.c \
 	xgate-opc.c \
 	z80-dis.c \
-	z8k-dis.c
+	z8k-dis.c \
+	zip-dis.c \
+	zip-opc.c
 
 # C source files that correspond to .o's ending up in libopcodes.
 LIBOPCODES_CFILES = \
@@ -346,7 +350,6 @@
 	touch stamp-lib
 
 libopcodes.a: stamp-lib ; @true
-
 POTFILES = $(HFILES) $(CFILES)
 po/POTFILES.in: @MAINT@ Makefile
 	for f in $(POTFILES); do echo $$f; done | LC_ALL=C sort > tmp \
diff -Naur '--exclude=*.swp' binutils-2.27-original/opcodes/Makefile.in binutils-2.27-zip/opcodes/Makefile.in
--- binutils-2.27-original/opcodes/Makefile.in	2016-08-03 03:36:54.000000000 -0400
+++ binutils-2.27-zip/opcodes/Makefile.in	2017-01-05 08:28:04.000000000 -0500
@@ -386,7 +386,9 @@
 	w65-opc.h \
 	xc16x-desc.h xc16x-opc.h \
 	xstormy16-desc.h xstormy16-opc.h \
-	z8k-opc.h
+	z8k-opc.h \
+	zip-opc.h \
+	zip-dis.h
 
 
 # C source files that correspond to .o's ending up in libopcodes
@@ -570,7 +572,9 @@
 	xgate-dis.c \
 	xgate-opc.c \
 	z80-dis.c \
-	z8k-dis.c
+	z8k-dis.c \
+	zip-dis.c \
+	zip-opc.c
 
 
 # C source files that correspond to .o's ending up in libopcodes.
@@ -974,6 +978,8 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xtensa-dis.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/z80-dis.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/z8k-dis.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zip-dis.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zip-opc.Plo@am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
diff -Naur '--exclude=*.swp' binutils-2.27-original/opcodes/zip-dis.c binutils-2.27-zip/opcodes/zip-dis.c
--- binutils-2.27-original/opcodes/zip-dis.c	1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/opcodes/zip-dis.c	2018-03-22 17:57:34.688834861 -0400
@@ -0,0 +1,527 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Filename: 	zip-dis.c
+//
+// Project:	Zip CPU backend for GNU Binutils
+//
+// Purpose:	
+//
+// Creator:	Dan Gisselquist, Ph.D.
+//		Gisselquist Technology, LLC
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2016-2017, Gisselquist Technology, LLC
+//
+// 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
+// by the Free Software Foundation, either version 3 of the License, or (at
+// your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program.  (It's in the $(ROOT)/doc directory.  Run make with no
+// target there if the PDF file isn't present.)  If not, see
+// <http://www.gnu.org/licenses/> for a copy.
+//
+// License:	GPL, v3, as defined and found on www.gnu.org,
+//		http://www.gnu.org/licenses/gpl.html
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+#include "config.h"
+
+#include <stdio.h>
+#include <stdint.h>
+#include <ctype.h>
+#include <strings.h>
+#include <string.h>
+#include <assert.h>
+
+#include "zip-opc.h"
+#include "zip-dis.h"
+
+static inline	int
+TWOWORD_LOAD(uint32_t one, uint32_t two) {
+	// BREV followed by LODILO
+	if (((one&0x87c40000)==0x02000000)&&((two&0x87c40000)==0x02400000)
+		// Must be to the same register too, and on the same condition
+		&&(((one^two)&0xf8380000)==0))
+		return 1;
+	return 0;
+}
+
+static	inline	int
+OFFSET_PC_MOV(uint32_t ins) {
+	// 0.xxxx.01101.ccc.0.1111.0.iiiiiiiiiiiii
+	// 0xxx.x011.01cc.c011.110i.iiii.iiii.iiii
+	//
+	return ((ins & 0x87c7e000)==0x0343c000);
+}
+
+static	inline	int
+TWOWORD_LJMP(uint32_t iword) {
+	// LJMP a long jump instruction, for which the address of the target
+	// is found in the next word
+	if (iword==0x7c87c000)
+		return 1;
+	// Now, the CIS form ... an
+	// Unconditional LJMP in the second half word
+	if ((iword&0x80007fff)==0x80007cf8)
+		return 1;
+	return 0;
+}
+
+
+static	inline	int
+TWOWORD_JSR(uint32_t iword, uint32_t nxtword) {
+	// First word moves the return address to R0
+	if (iword != 0x0343c001)
+		return 0;
+	// Second word is a BRA statement to ... anywhere
+	// 0.1111.00010.ccc.0.iiiiiiiiiiiiiiiiii
+	// 0111.1000.10cc.c0ii.iiii.iiii.iiii.iiii
+	if ((nxtword&0xffc40000) == 0x78800000)
+		return 1;
+	// OR ... the second word could be a
+	// load into the PC
+	// 0.1111.10010.ccc.0.iiiiiiiiiiiiiiiiii	LW.X #imm,PC
+	// 0.1111.10010.ccc.1.rrrr.iiiiiiiiiiiiii	LW.X #(R),PC
+	//
+	// These must be unconditional, since the MOV above is
+	// also unconditional
+	// 0111.1100.10cc.cxxxxx....	LW.X #(R),PC
+	if ((nxtword&0xfff80000) == 0x7c800000)
+		return 1;
+	//
+	// OR ... the second word could be a
+	// Register move into the PC from the current
+	// register set
+	// 0.1111.01101.ccc.0.rrrr.0.iiiiiiiiiiiii	MOV #(R),PC
+	// 0111.1011.01cc.c0rr.rr0i.iiiiiiiiiiii	MOV #(R),PC
+	if ((nxtword&0xfffc2000) == 0x7b400000)
+		return 1;
+	//
+	return 0;
+}
+
+static	inline	int
+THREEWORD_LJSR(uint32_t iword, uint32_t nxtword) {
+	// First word moves the return address to R0
+	if (iword!=0x0343c002)
+		return 0;
+	// Second word is an LJMP statement
+	if (nxtword==0x7c87c000)
+		return 1;
+	return 0;
+}
+
+static	inline	int
+TWOWORD_CIS_LJSR(uint32_t iword) {
+	// MOV 2(PC) | LOD (PC),PC
+	//
+	// 1.0000.111.1.1111.010
+	//			1.1111.100.1.1111.000
+	if (iword == 0x87fafcf8)
+		return 1;
+	return 0;
+}
+
+static	inline	int
+CIS_JSR(uint32_t iword __attribute__((unused)) ) {
+	if (TWOWORD_CIS_LJSR(iword))
+		return 1;
+	// MOV 1(PC) | MOV Rx,PC
+	//
+	// 1.0000.111.1.1111.001
+	//			1.1111.111.1.xxxx.000
+	if ((iword&0xffffff87) == 0x87f9ff80)
+		return 1;
+	return 0;
+}
+
+static inline	int
+POSSIBLE_TWOWORD_BEGINNING(uint32_t iword) {
+	// Unconditional LJMP
+	if (TWOWORD_LJMP(iword))
+		return 1;
+	// MOV 1(PC),PC
+	if (iword == 0x0343c001)
+		return 1;
+	// MOV 2(PC),PC
+	if (iword == 0x0343c002)
+		return 1;
+	if (TWOWORD_CIS_LJSR(iword))
+		return 1;
+	// The conditional LJMP is three words, which we don't handle ...
+	// Any BREV command could be the beginning of a twoword instruction
+	//
+	// Of course, the point here is to determine whether we should (or need
+	// to) read a second word from our read-memory function.  Reading a 
+	// second word, given that the first is a BREV, isn't a problem since a
+	// program can't end on/with a BREV instruction.
+	//
+	// BREV #,Rx
+	if ((iword&0x87c40000)==0x02000000)
+		return 1;
+	return 0;
+}
+
+static uint32_t
+zip_bitreverse(uint32_t v) {
+	uint32_t r=0, b;
+	for(b=0; b<32; b++, v>>=1)
+		r = (r<<1)|(v&1);
+	return r;
+}
+
+static inline	uint32_t
+TWOWORD_VALUE(uint32_t one, uint32_t two) {
+	return ((two&0x0ffff)|(zip_bitreverse(one&0x0ffff)));
+}
+
+static long
+zip_sbits(const long val, const int bits) {
+	long	r;
+
+	r = val & ((1l<<bits)-1);
+	if (r & (1l << (bits-1)))
+		r |= (-1l << bits);
+	return r;
+}
+
+static unsigned long
+zip_ubits(const long val, const int bits) {
+	unsigned long r = val & ((1l<<bits)-1);
+	return r;
+}
+
+static	int
+zip_getbits(const ZIPI ins, const int which)
+{
+	if (which & 0x40000000) {
+		return zip_sbits(ins>>(which & 0x03f), (which>>8)&0x03f);
+	} else { // if (which &0x03f)
+		return zip_ubits(ins>>(which & 0x03f), (which>>8)&0x03f)
+			+ ((which>>16)&0x0ff);
+	}
+}
+
+static	void
+zipi_to_halfstring(const uint32_t addr, const ZIPI ins, const ZIPI nxtword, char *line, const ZOPCODE *listp, uint32_t *refaddr)
+{
+	*refaddr = 0;
+
+	if ((TWOWORD_LOAD(ins,nxtword))&&(listp==zip_oplist)) {
+		int cv = zip_getbits(ins, ZIP_BITFIELD(3,19)); // The condition
+		int dv = zip_getbits(ins, ZIP_REGFIELD(27)); // The destination
+		
+		*refaddr = TWOWORD_VALUE(ins,nxtword);
+
+		sprintf(line, "%s%s", "LDI", zip_ccstr[cv]);
+		sprintf(line, "%-11s", line);
+		sprintf(line, "%s0x%08x", line, *refaddr);
+		sprintf(&line[strlen(line)], ",%s", zip_regstr[dv]);
+
+		return;
+	} else if (TWOWORD_JSR(ins, nxtword)) {
+		if ((nxtword&0xffc40000) == 0x78800000) {
+			int cv = zip_getbits(nxtword, ZIP_BITFIELD(3,19));
+			int iv = zip_sbits(nxtword, 18);
+
+			*refaddr = iv + addr + 8;
+			sprintf(line, "%s%s", "JSR", zip_ccstr[cv]);
+			sprintf(line, "%-11s", line);
+			sprintf(line, "%s0x%08x", line, *refaddr);
+
+			return;
+		} else if ((nxtword&0xfff80000) == 0x7c800000) {
+			// OR ... the second word could be a load into the PC
+			if ((nxtword>>18)&1) {
+				// LW #(Rw),PC
+				int iv = zip_sbits(nxtword, 14);
+				int rb = zip_ubits(nxtword>>14, 4);
+
+				sprintf(line,"%-11s#%d(%s)", "IJSR", iv,
+					zip_regstr[rb]);
+				*refaddr = 0;
+			} else {
+				// LW (#),PC
+				int iv = zip_sbits(nxtword, 18);
+				sprintf(line,"%-11s(#%d)", "IJSR", iv);
+				*refaddr = iv;
+			}
+			return;
+		} else { // if ((nxtword&0xfffc2000) == 0x7b400000)
+			// OR ... the second word could be a register move into
+			// the PC from the current register set
+			int rb = zip_ubits(nxtword>>14, 4);
+			int iv = zip_sbits(nxtword, 13);
+
+			*refaddr = 0;
+			if (iv == 0)
+				sprintf(line, "%-11s %s", "JSR",
+						zip_regstr[rb]);
+			else
+				sprintf(line, "%-11s#%d+%s", "JSR",iv,
+						zip_regstr[rb]);
+
+			return;
+		}
+	} else if (TWOWORD_CIS_LJSR(ins)) {
+		*refaddr = nxtword;
+		sprintf(line, "%-11s", "LJSR");
+		sprintf(line, "%s0x%08x", line, *refaddr);
+		return;
+	} else if (CIS_JSR(ins)) {
+		int ra = zip_getbits(ins, ZIP_REGFIELD(3));
+		sprintf(line, "%-11s%s", "JSR", zip_regstr[ra]);
+		return;
+	} else if (OFFSET_PC_MOV(ins)) {
+		int	cv = zip_getbits(ins, ZIP_BITFIELD(3,19));
+		int	dv = zip_getbits(ins, ZIP_REGFIELD(27));
+		int	iv = zip_sbits(ins, 13);
+		uint32_t	ref;
+
+		ref = (iv<<2) + addr + 4;
+
+		sprintf(line, "%s%s", "MOV", zip_ccstr[cv]);
+		sprintf(line, "%-11s", line);
+		sprintf(line, "%s0x%08x", line, ref);
+		sprintf(line, "%s,%s", line, zip_regstr[dv]);
+
+		*refaddr = ref;
+		return;
+	}
+
+	int	i;
+	for(i=0; i<nzip_oplist; i++) {
+		if (((~zip_oplist[i].s_mask)&zip_oplist[i].s_val)!=0) {
+			printf("Instruction %d, %s, fails consistency check\n",
+				i, zip_oplist[i].s_opstr);
+			printf("%08x & %08x = %08x != %08x\n",
+				zip_oplist[i].s_mask,
+				zip_oplist[i].s_val,
+				(~zip_oplist[i].s_mask)&zip_oplist[i].s_val,
+				0);
+			assert(((~zip_oplist[i].s_mask)&zip_oplist[i].s_val)==0);
+		}
+	} line[0] = '\0';
+	for(i=0; (listp[i].s_mask != 0); i++) {
+		// printf("%2d: %6s %08x & %08x == %08x\n",
+			// i, zip_oplist[i].s_opstr, ins,
+			// zip_oplist[i].s_mask, zip_oplist[i].s_val);
+		if ((ins & listp[i].s_mask) == listp[i].s_val) {
+			// Write the opcode onto our line
+			sprintf(line, "%s", listp[i].s_opstr);
+			if (listp[i].s_cf != ZIP_OPUNUSED) {
+				int bv = zip_getbits(ins, listp[i].s_cf);
+				strcat(line, zip_ccstr[bv]);
+			} sprintf(line, "%-11s", line); // Pad it to 11 chars
+
+			int	ra = -1, rb = -1, rr = -1, imv = 0;
+
+			if (listp[i].s_result != ZIP_OPUNUSED)
+				rr = zip_getbits(ins, listp[i].s_result);
+			if (listp[i].s_ra != ZIP_OPUNUSED)
+				ra = zip_getbits(ins, listp[i].s_ra);
+			if (listp[i].s_rb != ZIP_OPUNUSED)
+				rb = zip_getbits(ins, listp[i].s_rb);
+			if (listp[i].s_i != ZIP_OPUNUSED)
+				imv = zip_getbits(ins, listp[i].s_i);
+
+			if ((listp[i].s_rb != ZIP_OPUNUSED)&&(rb == 15))
+				imv <<= 2;
+
+			// Treat stores special
+			if ((strncasecmp("SW",listp[i].s_opstr, 2)==0)
+				||(strncasecmp("SH",listp[i].s_opstr, 2)==0)
+				||(strncasecmp("SB",listp[i].s_opstr, 2)==0)) {
+				strcat(line, zip_regstr[ra]);
+				strcat(line, ",");
+					
+				if (listp[i].s_i != ZIP_OPUNUSED) {
+					if (listp[i].s_rb == ZIP_OPUNUSED)
+						sprintf(&line[strlen(line)],
+							"($%d)", imv);
+					else if (imv != 0)
+						sprintf(&line[strlen(line)],
+							"$%d", imv);
+				} if (listp[i].s_rb != ZIP_OPUNUSED) {
+					sprintf(&line[strlen(line)],
+						"(%s)", zip_regstr[rb]);
+				}
+			// Treat long jumps special
+			} else if (strncasecmp("LJMP",listp[i].s_opstr, 3)==0) {
+				sprintf(&line[strlen(line)], "@0x%08x", nxtword);
+				*refaddr = nxtword;
+			// Treat relative jumps (branches) specially as well
+			} else if ((toupper(listp[i].s_opstr[0]=='B'))
+				&&(strcasecmp(listp[i].s_opstr,"BUSY")!=0)
+				&&(strcasecmp(listp[i].s_opstr,"BREV")!=0)
+				&&(strcasecmp(listp[i].s_opstr,"BRK")!=0)
+				&&(addr != 0)) {
+				// Branch instruction: starts with B and isn't
+				// BREV (bit reverse), BRK (break), or 
+				// BUSY
+				uint32_t target = addr;
+
+				target += zip_getbits(ins, listp[i].s_i)+4;
+				sprintf(&line[strlen(line)], "@0x%08x", target);
+				*refaddr = target;
+			} else {
+				int memop = 0;
+				if (('L'==toupper(listp[i].s_opstr[0]))
+					&&(('W'==toupper(listp[i].s_opstr[1]))
+					 ||('H'==toupper(listp[i].s_opstr[1]))
+					 ||('B'==toupper(listp[i].s_opstr[1])))
+					&&(!listp[i].s_opstr[2]))
+					memop = 1;
+
+				if (listp[i].s_i != ZIP_OPUNUSED) {
+					if((memop)&&(listp[i].s_rb == ZIP_OPUNUSED))
+						sprintf(&line[strlen(line)],
+							"($%d)", imv);
+					else if((memop)&&(imv != 0))
+						sprintf(&line[strlen(line)],
+							"%d", imv);
+					else if((!memop)&&((imv != 0)||(listp[i].s_rb == ZIP_OPUNUSED)))
+						sprintf(&line[strlen(line)],
+							"$%d%s", imv,
+							(listp[i].s_rb!=ZIP_OPUNUSED)?"+":"");
+				} if (listp[i].s_rb != ZIP_OPUNUSED) {
+					if (memop)
+						sprintf(&line[strlen(line)],
+							"(%s)", zip_regstr[rb]);
+					else
+						strcat(line, zip_regstr[rb]);
+				} if(((listp[i].s_i != ZIP_OPUNUSED)||(listp[i].s_rb != ZIP_OPUNUSED))
+					&&((listp[i].s_ra != ZIP_OPUNUSED)||(listp[i].s_result != ZIP_OPUNUSED)))
+					strcat(line, ",");
+
+				if (listp[i].s_ra != ZIP_OPUNUSED) {
+					strcat(line, zip_regstr[ra]);
+				} else if (listp[i].s_result != ZIP_OPUNUSED) {
+					strcat(line, zip_regstr[rr]);
+				}
+			}
+			break;
+		}
+	} if (line[0] == '\0') {
+		sprintf(line, "ILL %08x", ins);
+	}
+}
+
+static void
+zipi_to_double_string(const uint32_t addr, const ZIPI ins, const ZIPI nxtword, char *la, char *lb, uint32_t *refaddr) {
+	zipi_to_halfstring(addr, ins, nxtword, la, zip_oplist, refaddr);
+	if (lb) {
+		if ((ins & 0x80000000)&&(!CIS_JSR(ins))) {
+			zipi_to_halfstring(addr, ins, nxtword,
+					lb, zip_opbottomlist, refaddr);
+			*refaddr = 0;
+		} else lb[0] = '\0';
+	}
+}
+
+static int
+print_zip_insn(bfd_vma vma, disassemble_info *info)
+{
+	ZIPI	iword, nxtword;
+	char	astr[80], bstr[80];
+	unsigned char ibytes[12];
+	uint32_t	refaddr = 0;
+
+	// Deal with misalignment ...
+	if ((vma & 3)!=0) {
+		int	consumed = 0;
+
+		// Consume up to four bytes, after a zero (possibly multiple),
+		// though, align ourselves
+		(*info->read_memory_func)(vma, ibytes, 4, info);
+		while((consumed<4)&&(ibytes[consumed]!=0))
+			consumed++;
+		while((consumed<4)&&(ibytes[consumed]==0))
+			consumed++;
+		if (consumed <= 1)
+			consumed = 1;
+		return consumed;
+	}
+
+	// Always read the first word
+	(*info->read_memory_func)(vma, ibytes, 4, info);
+	iword  = (ibytes[0]<<24)|(ibytes[1]<<16)|(ibytes[2]<<8)|(ibytes[3]);
+	// Only if we know we have a second do we read the second
+	if ((POSSIBLE_TWOWORD_BEGINNING(iword))
+		// We also test for reading past the end of the buffer
+		&&((*info->read_memory_func)(vma, ibytes, 8, info) ==0)) {
+		nxtword= (ibytes[4]<<24)|(ibytes[5]<<16)|(ibytes[6]<<8)|(ibytes[7]);
+	} else {
+		const int NOOP_CODE = 0x76000000;
+		nxtword = NOOP_CODE;
+	}
+
+	bstr[0] = '\0';
+
+	if (THREEWORD_LJSR(iword,nxtword)) {
+		sprintf(astr, "%-11s", "LJSR");
+		if ((*info->read_memory_func)(vma, ibytes, 12, info) ==0)
+			refaddr = (ibytes[8]<<24)|(ibytes[9]<<16)|(ibytes[10]<<8)|(ibytes[11]);
+		sprintf(&astr[strlen(astr)], "@0x%08x", refaddr);
+	} else if (TWOWORD_CIS_LJSR(iword)) {
+		refaddr = nxtword;
+		sprintf(astr, "%-11s0x%08x", "JSR", refaddr);
+	} else
+		zipi_to_double_string(vma, iword, nxtword, astr, bstr,&refaddr);
+
+	if (bstr[0])
+		sprintf(astr, "%-25s | %s", astr,bstr);
+
+	// Remove any trailing spaces
+	unsigned ln = strlen(astr);
+	while((ln > 0)&&(isspace(astr[ln-1])))
+		astr[--ln] = '\0';
+
+	(*info->fprintf_func)(info->stream, "%s", astr);
+
+	if ((info->print_address_func)&&(refaddr != 0)) {
+		if (ln < 25)
+			(*info->fprintf_func)(info->stream, "%*s", 25-ln, "");
+			
+		(*info->fprintf_func)(info->stream, " // ");
+		(*info->print_address_func)(refaddr, info);
+	}
+
+	// Normal LOD (PC),PC = 0x7c87c000
+	//	1'b0, 4'hf, 5'h12, 3'h0, 1'b1, 4'hf, 14'h00
+	//	0111 1100 1000 0111 1100 0000 0000 0000
+	// or CIS  x | LOD (PC),PC
+	//	1'b1, 4'hx 5'hx 1'b0 2'bx 5'hx 4'hf 5'h12 1'b1 4'hf
+	//	1xxx xxxx xx0x xxxx xx11 1110 0101 1111
+	//	0x80203fff mask, val = 0x80003e5f
+	if (THREEWORD_LJSR(iword,nxtword))
+		return 12;
+	if (TWOWORD_LJMP(iword))
+		return 8;
+	// Two word load: Destination registers and conditional execution bits
+	// must match as well.
+	if (TWOWORD_LOAD(iword,nxtword))
+		return 8;
+	if (TWOWORD_JSR(iword,nxtword))
+		return 8;
+	if (TWOWORD_CIS_LJSR(iword))
+		return 8;
+	return 4;
+}
+
+
+disassembler_ftype
+zip_get_disassembler(bfd *abfd ATTRIBUTE_UNUSED)
+{
+	return print_zip_insn;
+}
+
diff -Naur '--exclude=*.swp' binutils-2.27-original/opcodes/zip-dis.h binutils-2.27-zip/opcodes/zip-dis.h
--- binutils-2.27-original/opcodes/zip-dis.h	1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/opcodes/zip-dis.h	2016-12-31 18:10:03.512012534 -0500
@@ -0,0 +1,45 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Filename: 	zip-dis.h
+//
+// Project:	Zip CPU backend for GNU Binutils
+//
+// Purpose:	
+//
+// Creator:	Dan Gisselquist, Ph.D.
+//		Gisselquist Technology, LLC
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2016, Gisselquist Technology, LLC
+//
+// 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
+// by the Free Software Foundation, either version 3 of the License, or (at
+// your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program.  (It's in the $(ROOT)/doc directory, run make with no
+// target there if the PDF file isn't present.)  If not, see
+// <http://www.gnu.org/licenses/> for a copy.
+//
+// License:	GPL, v3, as defined and found on www.gnu.org,
+//		http://www.gnu.org/licenses/gpl.html
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+#ifndef	ZIP_DIS_H
+#define	ZIP_DIS_H
+
+#include "config.h"
+#include "dis-asm.h"
+
+extern disassembler_ftype
+zip_get_disassembler(bfd *abfd);
+
+#endif
diff -Naur '--exclude=*.swp' binutils-2.27-original/opcodes/zip-opc.c binutils-2.27-zip/opcodes/zip-opc.c
--- binutils-2.27-original/opcodes/zip-opc.c	1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/opcodes/zip-opc.c	2018-06-07 10:35:06.439245343 -0400
@@ -0,0 +1,362 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Filename: 	zip-opc.c
+//
+// Project:	Zip CPU backend for GNU Binutils
+//
+// Purpose:	
+//
+// Creator:	Dan Gisselquist, Ph.D.
+//		Gisselquist Technology, LLC
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2015-2017, Gisselquist Technology, LLC
+//
+// 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
+// by the Free Software Foundation, either version 3 of the License, or (at
+// your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program.  (It's in the $(ROOT)/doc directory.  Run make with no
+// target there if the PDF file isn't present.)  If not, see
+// <http://www.gnu.org/licenses/> for a copy.
+//
+// License:	GPL, v3, as defined and found on www.gnu.org,
+//		http://www.gnu.org/licenses/gpl.html
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+#include "zip-opc.h"
+
+const	char	*zip_regstr[49] = {
+	"R0", "R1", "R2", "R3",
+	"R4", "R5", "R6", "R7",
+	"R8", "R9", "R10","R11",
+	"R12","SP", "CC", "PC",
+	"uR0", "uR1", "uR2", "uR3",
+	"uR4", "uR5", "uR6", "uR7",
+	"uR8", "uR9", "uR10", "uR11",
+	"uR12", "uSP", "uCC", "uPC",
+	"sR0", "sR1", "sR2", "sR3",
+	"sR4", "sR5", "sR6", "sR7",
+	"sR8", "sR9", "sR10","sR11",
+	"sR12","sSP", "sCC", "sPC", "rILL"
+};
+
+const	char	*zip_ccstr[8] = {
+	"",  ".Z",  ".LT", ".C",
+	".V",".NZ", ".GE", ".NC"
+};
+
+static const ZOPCODE	zip_oplist_raw[] = {
+	// Special case instructions.  These are general instructions, but with
+	// special opcodes
+	// Conditional branches
+	//	0.1111.0111.ccc.0.111.10iiiii--
+	//	0111 1011 11cc c011 110i iiii iiii iiii
+	{ "BUSY", 0xffc7fffc, 0x7883fffc, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_BITFIELD(3,19) },
+	{ "BZ",  0xfffc0000, 0x78880000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_OPUNUSED },
+	{ "BLT", 0xfffc0000, 0x78900000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_OPUNUSED },
+	{ "BC",  0xfffc0000, 0x78980000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_OPUNUSED },
+	{ "BV",  0xfffc0000, 0x78a00000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_OPUNUSED },
+	{ "BNZ",  0xfffc0000, 0x78a80000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_OPUNUSED },
+	{ "BGE",  0xfffc0000, 0x78b00000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_OPUNUSED },
+	{ "BNC",  0xfffc0000, 0x78b80000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_OPUNUSED },
+	{ "BRA",  0xffc40000, 0x78800000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
+	// Changes/updates to CC, based upon LDI
+	{ "TRAP", 0xfffffff0, 0x76000000, ZIP_OPUNUSED,ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED },
+	{ "TRAP", 0xff800000, 0x76000000, ZIP_OPUNUSED,ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED },
+	// BREV based traps
+	{ "TRAP", 0xffc7ffff, 0x72000000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
+	// LDILO based traps
+	{ "TRAP",0xffc4ffff, 0x72400000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_BITFIELD(3,19) },
+	{ "TRAP",0xffc40000, 0x72400000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
+	// CLR -- a LDI of zero
+	//	0.rrrr.1100.iiiiiii--
+	//	0rrr r110 0...
+	{ "CLR",  0x87ffffff, 0x06000000, ZIP_REGFIELD(27),ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED },
+	// BREV based clears
+	{ "CLR", 0x87c7ffff, 0x02000000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
+	// HALT
+	//	0.1110.00011.ccc.0.0000000000010
+	//	0111.0000.11cc.c000.0000.0000.0000.0010
+	{ "HALT", 0xffc7ffff, 0x70c00010, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_BITFIELD(3,19) },
+	// The "wait" instruction is identical, with the only difference being
+	// the interrrupt context of the processor.  Well, almost.  To
+	// facilitate waits from supervisor mode, the wait instruction
+	// explicitly forces the CPU into user mode.
+	{ "WAIT", 0xffc7ffff, 0x70c00030, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_BITFIELD(3,19) },
+	// 1.0011.11000.000.0000...... 5f ? A carefully chosen illegal insn ??
+	// "INT", 0xff10007f, 0x9e00005f, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_BITFIELD(3,19),
+	// Return to user space
+	{ "RTU", 0xffc7ffff, 0x70c00020, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_BITFIELD(3,19) },
+	// The return instruction: JMP R0 (possibly conditional) = MOV R0,PC
+	{ "RTN", 0xffc7ffff, 0x7b400000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_BITFIELD(3,19) },
+	// JMP (possibly a conditional jump, if not covered by branches above)
+	// 0.1111.01101.ccc.a.rrrr.biiiiiiiiiiiiiiii
+	// 0111.1011.01cc.c0rr.rrbi.iiii.iiii.iiii		MOV x,PC
+	{ "JMP",  0xffc40000, 0x7b400000, ZIP_OPUNUSED,ZIP_OPUNUSED, ZIP_REGFIELD(14), ZIP_IMMFIELD(13,0), ZIP_BITFIELD(3,19) },
+	// 0.1111.1100.ii.iiii.iiii.iiii.iiii.iiii.iiii
+	// 0111.1110.0iii.iiii.iiii.iiii.iiii.iiii		LDI x,PC
+	{ "JMPI", 0xff800000, 0x7e000000, ZIP_REGFIELD(27),ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(23,0), ZIP_OPUNUSED },
+	// 0.1111.10010.000.1.1111.000000000000000
+	// 0111.1100.1000.0111.11ii.iiii.iiii.iiii		LOD (PC),PC
+	{ "LJMP", 0xffffffff, 0x7c87c000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED },
+	// NOT : XOR w/ -1
+	//	0.rrrr.00100.ccc.0111.11111111111
+	//	0rrr.r001.00cc.c011.f.f.f.f
+	// { "NOT", 0x87c7ffff, 0x0103ffff, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_BITFIELD(3,19) },
+	// General instructions
+	// 0rrr.rooo.oocc.cxrr.rrii.iiii.iiii.iiii
+	{ "SUB", 0x87c40000, 0x00000000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
+	{ "SUB", 0x87c40000, 0x00040000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
+	//
+	{ "AND", 0x87c40000, 0x00400000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
+	{ "AND", 0x87c40000, 0x00440000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
+	//
+	{ "ADD", 0x87c40000, 0x00800000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
+	{ "ADD", 0x87c40000, 0x00840000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
+	//
+	{ "OR",	0x87c40000, 0x00c00000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
+	{ "OR",	0x87c40000, 0x00c40000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
+	//
+	{ "XOR", 0x87c40000, 0x01000000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
+	{ "XOR", 0x87c40000, 0x01040000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
+	//
+	{ "LSR", 0x87c40000, 0x01400000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
+	{ "LSR", 0x87c40000, 0x01440000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
+	//
+	{ "LSL", 0x87c40000, 0x01800000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
+	{ "LSL", 0x87c40000, 0x01840000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
+	//
+	{ "ASR", 0x87c40000, 0x01c00000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
+	{ "ASR", 0x87c40000, 0x01c40000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
+	//
+	{ "BREV",0x87c40000, 0x02000000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
+	{ "BREV",0x87c40000, 0x02040000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
+	//
+	{ "LDILO",0x87c40000, 0x02400000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
+	{ "LDILO",0x87c40000, 0x02440000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
+	//
+	//
+	{ "MPYUHI", 0x87c40000, 0x02800000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
+	{ "MPYUHI", 0x87c40000, 0x02840000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
+	//
+	{ "MPYSHI", 0x87c40000, 0x02c00000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
+	{ "MPYSHI", 0x87c40000, 0x02c40000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
+	//
+	{ "MPY", 0x87c40000, 0x03000000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
+	{ "MPY", 0x87c40000, 0x03040000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
+	//
+	{ "MOV", 0x87c42000, 0x03400000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_REGFIELD(14), ZIP_IMMFIELD(13,0), ZIP_BITFIELD(3,19) },
+	{ "MOV", 0x87c42000, 0x03440000, ZIP_URGFIELD(27), ZIP_OPUNUSED, ZIP_REGFIELD(14), ZIP_IMMFIELD(13,0), ZIP_BITFIELD(3,19) },
+	{ "MOV", 0x87c42000, 0x03402000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_URGFIELD(14), ZIP_IMMFIELD(13,0), ZIP_BITFIELD(3,19) },
+	{ "MOV", 0x87c42000, 0x03442000, ZIP_URGFIELD(27), ZIP_OPUNUSED, ZIP_URGFIELD(14), ZIP_IMMFIELD(13,0), ZIP_BITFIELD(3,19) },
+	//
+	{ "DIVU", 0x87c40000, 0x03800000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
+	{ "DIVU", 0x87c40000, 0x03840000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
+	//
+	{ "DIVS", 0x87c40000, 0x03c00000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
+	{ "DIVS", 0x87c40000, 0x03c40000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
+	//
+	{ "CMP", 0x87c40000, 0x04000000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
+	{ "CMP", 0x87c40000, 0x04040000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
+	{ "TST", 0x87c40000, 0x04400000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
+	{ "TST", 0x87c40000, 0x04440000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
+	//
+	{ "LW", 0x87c40000, 0x04800000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
+	{ "LW", 0x87c40000, 0x04840000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
+	//
+	{ "SW", 0x87c40000, 0x04c00000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
+	{ "SW", 0x87c40000, 0x04c40000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
+	//
+	{ "LH", 0x87c40000, 0x05000000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
+	{ "LH", 0x87c40000, 0x05040000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
+	//
+	{ "SH", 0x87c40000, 0x05400000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
+	{ "SH", 0x87c40000, 0x05440000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
+	//
+	{ "LB", 0x87c40000, 0x05800000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
+	{ "LB", 0x87c40000, 0x05840000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
+	//
+	{ "SB", 0x87c40000, 0x05c00000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
+	{ "SB", 0x87c40000, 0x05c40000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
+	//
+	// 0rrr.r101.1
+	{ "LDI",  0x87800000, 0x06000000, ZIP_REGFIELD(27),ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(23,0), ZIP_OPUNUSED },
+	// 0111.x111.00.xxxxxxxx
+	{ "BREAK", 0xf7ffffff, 0x77000000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED },
+	{ "BREAK", 0xf7c00000, 0x77000000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(22,0), ZIP_OPUNUSED },
+	{ "LOCK",  0xf7ffffff, 0x77400000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED },
+	{ "LOCK",  0xf7c00000, 0x77400000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(22,0), ZIP_OPUNUSED },
+	// 0.111x.00000.xxx.xxx.xxxx.xxxx.xxxx.xxxx
+	// 0111.x111.11.xxx.xxx.xxxx.xxxx.xxxx.xxxx
+	// SNOOP = SIM w/ no argument(s)
+	{ "SIM",  0xf7ffffff, 0x77800000, ZIP_OPUNUSED, ZIP_OPUNUSED,    ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
+	{ "SEXIT",0xf7ffffff, 0x77800100, ZIP_OPUNUSED, ZIP_OPUNUSED,    ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
+	{ "SEXIT",0xf7fffff0, 0x77800310, ZIP_OPUNUSED, ZIP_URGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
+	{ "SEXIT",0xf7ffffe0, 0x77800300, ZIP_OPUNUSED, ZIP_REGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
+	{ "SEXIT",0xf7ffff00, 0x77800100, ZIP_OPUNUSED, ZIP_OPUNUSED,    ZIP_OPUNUSED, ZIP_IMMFIELD( 8,0), ZIP_OPUNUSED },
+	{ "SDUMP",0xf7ffffff, 0x778002ff, ZIP_OPUNUSED, ZIP_OPUNUSED,    ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
+	{ "SDUMP",0xf7fffff0, 0x77800200, ZIP_OPUNUSED, ZIP_REGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
+	{ "SDUMP",0xf7fffff0, 0x77800210, ZIP_OPUNUSED, ZIP_URGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
+	{ "SOUT", 0xf7fffff0, 0x77800230, ZIP_OPUNUSED, ZIP_URGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
+	{ "SOUT", 0xf7ffffe0, 0x77800220, ZIP_OPUNUSED, ZIP_REGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
+	{ "SOUT", 0xf7ffff00, 0x77800400, ZIP_OPUNUSED, ZIP_OPUNUSED,    ZIP_OPUNUSED, ZIP_IMMFIELD( 8,0), ZIP_OPUNUSED },
+	{ "SDUMP",0xf7ffff00, 0x77800200, ZIP_OPUNUSED, ZIP_OPUNUSED,    ZIP_OPUNUSED, ZIP_IMMFIELD( 8,0), ZIP_OPUNUSED },
+	{ "SIM",  0xf7c00000, 0x77800000, ZIP_OPUNUSED, ZIP_OPUNUSED,    ZIP_OPUNUSED, ZIP_IMMFIELD(22,0), ZIP_OPUNUSED },
+	{ "NOOP", 0xf7ffffff, 0x77c00000, ZIP_OPUNUSED, ZIP_OPUNUSED,    ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
+	{ "NEXIT",0xf7ffffff, 0x77c00100, ZIP_OPUNUSED, ZIP_OPUNUSED,    ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
+	{ "NEXIT",0xf7ffff00, 0x77c00100, ZIP_OPUNUSED, ZIP_OPUNUSED,    ZIP_OPUNUSED, ZIP_IMMFIELD( 8,0), ZIP_OPUNUSED },
+	{ "NEXIT",0xf7fffff0, 0x77c00310, ZIP_OPUNUSED, ZIP_URGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
+	{ "NEXIT",0xf7ffffe0, 0x77c00300, ZIP_OPUNUSED, ZIP_REGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
+	{ "NDUMP",0xf7ffffff, 0x77c002ff, ZIP_OPUNUSED, ZIP_OPUNUSED,    ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
+	{ "NDUMP",0xf7fffff0, 0x77c00200, ZIP_OPUNUSED, ZIP_REGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
+	{ "NDUMP",0xf7fffff0, 0x77c00210, ZIP_OPUNUSED, ZIP_URGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
+
+	{ "NOUT", 0xf7fffff0, 0x77c00230, ZIP_OPUNUSED, ZIP_URGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
+	{ "NOUT", 0xf7ffffe0, 0x77c00220, ZIP_OPUNUSED, ZIP_REGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
+	{ "NOUT", 0xf7ffff00, 0x77c00400, ZIP_OPUNUSED, ZIP_OPUNUSED,    ZIP_OPUNUSED, ZIP_IMMFIELD( 8,0), ZIP_OPUNUSED },
+	{ "NDUMP",0xf7ffff00, 0x77c00200, ZIP_OPUNUSED, ZIP_OPUNUSED,    ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
+	{ "NSIM", 0xf7c00000, 0x77c00000, ZIP_OPUNUSED, ZIP_OPUNUSED,    ZIP_OPUNUSED, ZIP_IMMFIELD(22,0), ZIP_OPUNUSED },
+	//
+	//
+	// 0rrr.r11f.ffcc.cxrr.rrii.iiii.iiii.iiii
+	{ "FPADD",0x87c43fff, 0x06840000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_OPUNUSED, ZIP_BITFIELD(3,19) },
+	{ "FPSUB",0x87c43fff, 0x06c40000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_OPUNUSED, ZIP_BITFIELD(3,19) },
+	{ "FPMPY",0x87c43fff, 0x07040000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_OPUNUSED, ZIP_BITFIELD(3,19) },
+	{ "FPDIV",0x87c43fff, 0x07440000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_OPUNUSED, ZIP_BITFIELD(3,19) },
+	{ "FPI2F",0x87c40000, 0x07800000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
+	{ "FPI2F",0x87c40000, 0x07840000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
+	{ "FPF2I",0x87c40000, 0x07c40000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
+	//
+	//
+	//
+	//
+	//
+	//	16-bit instructions, high side
+	//
+	// 
+	//	1.1111.00010.xcc.0iiii.xxxx.xxxxx.xxxxx
+	//	1111.1000.10xc.c0ii.iixx.xxxx.xxxx.xxxx
+	// Mask, val, result, Ra, Rb, I, condition (no conditions for OP_UNDER_TEST)
+	// BRA: 1.1111.011.0.sssssss
+	{ "BRA", 0xff800000, 0xf9000000, ZIP_OPUNUSED,     ZIP_OPUNUSED, ZIP_OPUNUSED,     ZIP_IMMFIELD(7,16), ZIP_OPUNUSED },
+	// CLR: 1.rrrr.110.00000000
+	{ "CLR", 0x87ff0000, 0x86000000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_OPUNUSED,     ZIP_OPUNUSED,       ZIP_OPUNUSED },
+	// RTN: 1.1111.111.0.0000.000, MOV R0,Pc
+	{ "RTN", 0xffff0000, 0xff800000, ZIP_OPUNUSED,     ZIP_OPUNUSED, ZIP_OPUNUSED,     ZIP_OPUNUSED,       ZIP_OPUNUSED },
+	// JMP: 1.1111.111.0.rrrrsss
+	{ "JMP", 0xff800000, 0xff000000, ZIP_REGFIELD(27),ZIP_OPUNUSED,  ZIP_REGFIELD(19), ZIP_IMMFIELD(3,16), ZIP_OPUNUSED },
+	// LJSR: 1.000_0.011_.0.111_1.001 ?.1111.110.1.1111.000
+	// { "LJSR",0xffffffff, 0x83797ef8, ZIP_REGFIELD(27),ZIP_OPUNUSED, ZIP_REGFIELD(19), ZIP_IMMFIELD(3,16), ZIP_OPUNUSED },
+	//
+	// 1.rrrr.000.0.sssssss
+	// 1rrr.r000.0sss.ssss
+	{ "SUB", 0x87800000, 0x80000000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED,     ZIP_IMMFIELD(7,16), ZIP_OPUNUSED },
+	// 1.rrrr.000.1.rrrrsss
+	{ "SUB", 0x87800000, 0x80800000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(19), ZIP_IMMFIELD(3,16), ZIP_OPUNUSED },
+	//
+	// 1.rrrr.001.0.sssssss
+	// 1.rrrr.001.1.rrrrsss
+	{ "AND", 0x87800000, 0x81000000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED,     ZIP_IMMFIELD(7,16), ZIP_OPUNUSED },
+	{ "AND", 0x87800000, 0x81800000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(19), ZIP_IMMFIELD(3,16), ZIP_OPUNUSED },
+	//
+	// 1.rrrr.010.0.sssssss
+	// 1.rrrr.010.1.rrrrsss
+	{ "ADD", 0x87800000, 0x82000000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED,     ZIP_IMMFIELD(7,16), ZIP_OPUNUSED },
+	{ "ADD", 0x87800000, 0x82800000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(19), ZIP_IMMFIELD(3,16), ZIP_OPUNUSED },
+	//
+	// 1.rrrr.011.a.rrrrsss
+	{ "CMP", 0x87800000, 0x83000000, ZIP_REGFIELD(27), ZIP_OPUNUSED,     ZIP_OPUNUSED,     ZIP_IMMFIELD(7,16), ZIP_OPUNUSED },
+	{ "CMP", 0x87800000, 0x83800000, ZIP_REGFIELD(27), ZIP_OPUNUSED,     ZIP_REGFIELD(19), ZIP_IMMFIELD(3,16), ZIP_OPUNUSED },
+	//
+	// 1.rrrr.100.0.sssssss
+	// 1.rrrr.100.1.rrrrsss
+	{ "LW", 0x87800000, 0x84000000,  ZIP_REGFIELD(27), ZIP_OPUNUSED,     ZIP_SP,            ZIP_IMMFIELD(7,16), ZIP_OPUNUSED },
+	{ "LW", 0x87800000, 0x84800000,  ZIP_REGFIELD(27), ZIP_OPUNUSED,     ZIP_REGFIELD(19),  ZIP_IMMFIELD(3,16), ZIP_OPUNUSED },
+	// 1.rrrr.101.ssssssss
+	{ "SW", 0x87800000, 0x85000000,  ZIP_OPUNUSED,     ZIP_REGFIELD(27), ZIP_SP,            ZIP_IMMFIELD(7,16), ZIP_OPUNUSED },
+	// 1.rrrr.110.0.sssssss
+	{ "SW", 0x87800000, 0x85800000,  ZIP_OPUNUSED,     ZIP_REGFIELD(27), ZIP_REGFIELD(19),  ZIP_IMMFIELD(3,16), ZIP_OPUNUSED },
+	// 1.rrrr.110.iiiiiiii
+	{ "LDI", 0x87000000, 0x86000000, ZIP_REGFIELD(27), ZIP_OPUNUSED,     ZIP_OPUNUSED,      ZIP_IMMFIELD(8,16), ZIP_OPUNUSED },
+	// 1.rrrr.111.1.sssssss
+	{ "MOV", 0x87800000, 0x87800000, ZIP_OPUNUSED,     ZIP_REGFIELD(27), ZIP_REGFIELD(19),  ZIP_IMMFIELD(3,16), ZIP_OPUNUSED },
+	//
+	// 1.rrrr.111.1.rrrrsss
+	// Illegal instruction !!
+	{ "ILLV", 0x80000000, 0x80000000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(32,16), ZIP_OPUNUSED },
+	// Global illegal instruction
+	{ "ILL", 0x00000000, 0x00000000,  ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(32,0),  ZIP_OPUNUSED }
+};
+
+static const ZOPCODE	zip_opbottomlist_raw[] = {
+	//
+	//
+	//
+	//	16-bit instructions, low side ... treat these as special
+	//
+	//
+	// Mask, val, result, Ra, Rb, I, condition (no conditions for OP_UNDER_TEST)
+	// BRA: 1.xxx_xxxx_xxxx_xxxx_?.111_1.011.0.sssssss
+	{ "BRA", 0x80007f80, 0x80007900, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(7,0), ZIP_OPUNUSED },
+	// CLR: 1.xxx_xxxx_xxxx_xxxx_?.rrr_r.101.0000_0000
+	{ "CLR", 0x800007ff, 0x80000600, ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED },
+	// RTN: 1.1111.111.0.0000.000, MOV R0,Pc
+	{ "RTN", 0x80007fff, 0x80007f80, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED },
+	// JMP: 1.1111.111.0.rrrrsss
+	{ "JMP", 0x80007f80, 0x80007f00, ZIP_REGFIELD(11),ZIP_OPUNUSED, ZIP_REGFIELD(3), ZIP_IMMFIELD(3,0), ZIP_OPUNUSED },
+	// LJMP: 1.xxx_xxxx_xxxx_xxxx_?.111_1.100._1.111_1.000
+	{ "LJMP", 0x80007fff, 0x80007cf8, ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_REGFIELD(3), ZIP_IMMFIELD(3,0), ZIP_OPUNUSED },
+	//
+	// 1.rrrr.000.0.sssssss
+	{ "SUB", 0x80000780, 0x80000000, ZIP_REGFIELD(11), ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_IMMFIELD(7,0), ZIP_OPUNUSED },
+	// 1.rrrr.000.1.rrrrsss
+	{ "SUB", 0x80000780, 0x80000080, ZIP_REGFIELD(11), ZIP_REGFIELD(11), ZIP_REGFIELD(3), ZIP_IMMFIELD(3,0), ZIP_OPUNUSED },
+	//
+	// 1.rrrr.001.0.sssssss
+	// 1.rrrr.001.1.rrrrsss
+	{ "AND", 0x80000780, 0x80000100, ZIP_REGFIELD(11), ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_IMMFIELD(7,0), ZIP_OPUNUSED },
+	{ "AND", 0x80000780, 0x80000180, ZIP_REGFIELD(11), ZIP_REGFIELD(11), ZIP_REGFIELD(3), ZIP_IMMFIELD(3,0), ZIP_OPUNUSED },
+	//
+	// 1.rrrr.010.0.sssssss
+	// 1.rrrr.010.1.rrrrsss
+	{ "ADD", 0x80000780, 0x80000200, ZIP_REGFIELD(11), ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_IMMFIELD(7,0), ZIP_OPUNUSED },
+	{ "ADD", 0x80000780, 0x80000280, ZIP_REGFIELD(11), ZIP_REGFIELD(11), ZIP_REGFIELD(3), ZIP_IMMFIELD(3,0), ZIP_OPUNUSED },
+	//
+	// 1.rrrr.011.a.rrrrsss
+	{ "CMP", 0x80000780, 0x80000300, ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(7,0), ZIP_OPUNUSED },
+	{ "CMP", 0x80000780, 0x80000380, ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_REGFIELD(3), ZIP_IMMFIELD(3,0), ZIP_OPUNUSED },
+	//
+	// 1.rrrr.100.0.sssssss
+	// 1.rrrr.100.1.rrrrsss
+	{ "LW", 0x80000780, 0x80000400, ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_SP, ZIP_IMMFIELD(7,0), ZIP_OPUNUSED },
+	{ "LW", 0x80000780, 0x80000480, ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_REGFIELD(3), ZIP_IMMFIELD(3,0), ZIP_OPUNUSED },
+	// 1.rrrr.101.ssssssss
+	{ "SW", 0x80000780, 0x80000500, ZIP_OPUNUSED, ZIP_REGFIELD(11), ZIP_SP, ZIP_IMMFIELD(7,0), ZIP_OPUNUSED },
+	{ "SW", 0x80000780, 0x80000580, ZIP_OPUNUSED, ZIP_REGFIELD(11), ZIP_REGFIELD(3), ZIP_IMMFIELD(3,0), ZIP_OPUNUSED },
+	// 1.rrr_r.110.ssssssss
+	{ "LDI", 0x80000700, 0x80000600, ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(8,0), ZIP_OPUNUSED },
+	// 1.rrr_r.111_.x.rrr_rsss
+	{ "MOV", 0x80000780, 0x80000780, ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_REGFIELD(3), ZIP_IMMFIELD(3,0), ZIP_OPUNUSED },
+	//
+	//
+	// Illegal instruction !!
+	{ "ILLV",	0x80000000, 0x80000000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(15,0), ZIP_OPUNUSED },
+	{ "ILL",	0x00000000, 0x00000000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(15,0), ZIP_OPUNUSED }
+};
+
+const ZOPCODE	*zip_oplist = zip_oplist_raw,
+		*zip_opbottomlist = zip_opbottomlist_raw;
+
+const int	nzip_oplist = (sizeof(zip_oplist_raw)/sizeof(ZOPCODE));
+const int	nzip_opbottom = (sizeof(zip_opbottomlist_raw)/sizeof(ZOPCODE));
+
diff -Naur '--exclude=*.swp' binutils-2.27-original/opcodes/zip-opc.h binutils-2.27-zip/opcodes/zip-opc.h
--- binutils-2.27-original/opcodes/zip-opc.h	1969-12-31 19:00:00.000000000 -0500
+++ binutils-2.27-zip/opcodes/zip-opc.h	2017-02-10 17:48:01.761470841 -0500
@@ -0,0 +1,77 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Filename: 	zip-opc.h
+//
+// Project:	Zip CPU backend for GNU Binutils
+//
+// Purpose:	
+//
+// Creator:	Dan Gisselquist, Ph.D.
+//		Gisselquist Technology, LLC
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2016, Gisselquist Technology, LLC
+//
+// 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
+// by the Free Software Foundation, either version 3 of the License, or (at
+// your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program.  (It's in the $(ROOT)/doc directory, run make with no
+// target there if the PDF file isn't present.)  If not, see
+// <http://www.gnu.org/licenses/> for a copy.
+//
+// License:	GPL, v3, as defined and found on www.gnu.org,
+//		http://www.gnu.org/licenses/gpl.html
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+#ifndef	ZIP_OPC_H
+#define	ZIP_OPC_H
+
+#include <stdint.h>
+
+// MACROS used in the instruction definition list.
+#define	ZIP_OPUNUSED	-1
+#define	ZIP_BITFIELD(LN,MN)	(((LN&0x0ff)<<8)+(MN&0x0ff)) // A generic bitfield
+#define	ZIP_REGFIELD(MN)	(0x00000400 +(MN&0x0ff)) // Normal register field
+#define	ZIP_URGFIELD(MN)	(0x0100400 +(MN&0x0ff))	// User register field
+#define	ZIP_IMMFIELD(LN,MN)	(0x40000000 + (((LN&0x0ff)<<8)+(MN&0x0ff))) // Sgn extnd
+#define	ZIP_SP	0xd0000
+
+typedef	uint32_t	ZIPI;	// A Zip CPU instruction
+
+typedef	struct {
+	char	s_opstr[8];	// OPCode name
+	ZIPI	s_mask,		// Bits that must match 4 this pattern to match
+		s_val;		// What those masked bits must be
+	//
+	// The following describe not the value, but the bits where there
+	// respective vaules will be found within the instruction.  For example,
+	// an instruction with no immediate will have an s_i value of -1
+	// (ZIP_OPUNUSED), whereas an instruction with an immediate value of -1
+	// might have an s_i value of ZIP_BITFIELD(14,0), or 0x0400.  The
+	// opcode itself will tell you what the value is--not this structure
+	// describing the opcode.
+	//
+	int	s_result,	// Register where the result will be placed
+		s_ra,		// A register, often the result
+		s_rb,		// B register, source operand (if used)
+		s_i,		// Immediate value, added to B if B is used
+		s_cf;		// Condition flags.
+} ZOPCODE;
+
+extern	const	char	*zip_regstr[49], *zip_ccstr[8];
+
+extern	const ZOPCODE	*zip_oplist, *zip_opbottomlist;
+extern	const int	nzip_oplist, nzip_opbottom;
+
+
+#endif
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.