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