This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
| Other format: | [Raw text] | |
opcodes/ChangeLog: 2002-06-11 Dave Brolley <brolley@redhat.com> * po/POTFILES.in: Add frv-*.[ch]. * disassemble.c (ARCH_frv): New macro. (disassembler): Handle bfd_arch_frv. * configure.in: Support frv_bfd_arch. * Makefile.am (HFILES): Add frv-*.h. (CFILES): Add frv-*.c (ALL_MACHINES): Add frv-*.lo. (CLEANFILES): Add stamp-frv. (FRV_DEPS): New variable. (stamp-frv): New target. (frv-asm.lo): New target. (frv-desc.lo): New target. (frv-dis.lo): New target. (frv-ibld.lo): New target. (frv-opc.lo): New target. (frv-*.[ch]): New files. ld/ChangeLog: 2002-06-11 Dave Brolley <brolley@redhat.com> From Catherine Moore, Michael Meissner, Jim Blandy: * emulparams/elf32frv.sh: New file. * configure.tgt: Support frv-*-*. * Makefile.am (ALL_EMULATIONS): Add eelf32frv.o. (eelf32frv.c): New target. include/elf/ChangeLog: 2002-06-11 Dave Brolley <brolley@redhat.com> From Catherine Moore, Michael Meissner, Dave Brolley: * common.h (EM_CYGNUS_FRV): New macro. * frv.h: New file. include/ChangeLog: 2002-06-11 Dave Brolley <brolley@redhat.com> From Catherine Moore: * dis-asm.h (print_insn_frv): New prototype. gas/ChangeLog: 2002-06-11 Dave Brolley <brolley@redhat.com> From Catherine Moore, Michael Meissner, Richard Sandiford, Dave Brolley: * po/POTFILES.in: Add tc-frv.c, tc-frv.h. * configure.in: Support frv-*-*. * Makefile.am (CPU_TYPES): Add frv. (TARGET_CPU_CFILES): Add tc-frv.c. (TARGET_CPU_HFILES): Add tc-frv.h. (DEPTC_frv_coff): New variable. (DEPTC_frv_elf): New variable. (DEPOBJ_frv_coff): New variable. (DEPOBJ_frv_elf): New variable. (DEP_frv_coff): New variable. (DEP_frv_elf): New variable. * tc-frv.c: New file. * tc-frv.h: New file. binutils/ChangeLog: 2002-06-11 Dave Brolley <brolley@redhat.com> From Caherine Moore: * readelf.c (elf/frv.h): #include it. (guess_is_rela): Support EM_CYGNUS_FRV. (dump_relocations): Ditto. (get_machine_name): Ditto. * Makefile.am (readelf.o): add dependency on $(INCDIR)/elf/frv.h. bfd/ChangeLog: 2002-06-11 Dave Brolley <brolley@redhat.com> From Catherine Moore, Michael Meissner, Dave Brolley: * po/SRC-POTFILES.in: Add cpu-frv.c and elf32-frv.c * targets.c: Support bfd_elf32_frv_vec. * reloc.c: Add FRV relocs. * configure.in: Add support for bfd-elf32-frv-vec. * config.bfd (targ_cpu): Add support for frv-*-elf. * archures.c: Add frv arch and machines. * Makefile.am (ALL_MACHINES): Add cpu-frv.lo. (ALL_MACHINES_CFILES): Add cpu-frv.c. (BFD32_BACKENDS): Add elf32-frv.lo. (BFD32_BACKENDS_CFILES): Add elf32-frv.c (cpu-frv.lo): New target. (elf32-frv.lo): New target. * cpu-frv.c: New file. * elf32-frv.c: New file.
Index: bfd/Makefile.am
===================================================================
RCS file: /cvs/src/src/bfd/Makefile.am,v
retrieving revision 1.90
diff -c -p -d -u -p -r1.90 Makefile.am
--- bfd/Makefile.am 8 Jun 2002 23:23:08 -0000 1.90
+++ bfd/Makefile.am 10 Jun 2002 22:02:36 -0000
@@ -58,6 +58,7 @@ ALL_MACHINES = \
cpu-d30v.lo \
cpu-dlx.lo \
cpu-fr30.lo \
+ cpu-frv.lo \
cpu-h8300.lo \
cpu-h8500.lo \
cpu-hppa.lo \
@@ -107,6 +108,7 @@ ALL_MACHINES_CFILES = \
cpu-d30v.c \
cpu-dlx.c \
cpu-fr30.c \
+ cpu-frv.c \
cpu-h8300.c \
cpu-h8500.c \
cpu-hppa.c \
@@ -202,6 +204,7 @@ BFD32_BACKENDS = \
elf32-d30v.lo \
elf32-dlx.lo \
elf32-fr30.lo \
+ elf32-frv.lo \
elf32-gen.lo \
elf32-h8300.lo \
elf32-hppa.lo \
@@ -357,6 +360,7 @@ BFD32_BACKENDS_CFILES = \
elf32-d30v.c \
elf32-dlx.c \
elf32-fr30.c \
+ elf32-frv.c \
elf32-gen.c \
elf32-h8300.c \
elf32-hppa.c \
@@ -830,7 +834,6 @@ DISTCLEANFILES = $(BUILD_CFILES) $(BUILD
config.status: $(srcdir)/configure $(srcdir)/config.bfd $(srcdir)/configure.host
$(SHELL) ./config.status --recheck
-
# What appears below is generated by a hacked mkdep using gcc -MM.
# DO NOT DELETE THIS LINE -- mkdep uses it.
@@ -886,6 +889,7 @@ cpu-d10v.lo: cpu-d10v.c $(INCDIR)/filena
cpu-d30v.lo: cpu-d30v.c $(INCDIR)/filenames.h
cpu-dlx.lo: cpu-dlx.c $(INCDIR)/filenames.h
cpu-fr30.lo: cpu-fr30.c $(INCDIR)/filenames.h
+cpu-frv.lo: cpu-frv.c $(INCDIR)/filenames.h
cpu-h8300.lo: cpu-h8300.c $(INCDIR)/filenames.h
cpu-h8500.lo: cpu-h8500.c $(INCDIR)/filenames.h
cpu-hppa.lo: cpu-hppa.c $(INCDIR)/filenames.h
@@ -1108,6 +1112,10 @@ elf32-dlx.lo: elf32-dlx.c $(INCDIR)/file
elf32-fr30.lo: elf32-fr30.c $(INCDIR)/filenames.h elf-bfd.h \
$(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
$(INCDIR)/bfdlink.h $(INCDIR)/elf/fr30.h $(INCDIR)/elf/reloc-macros.h \
+ elf32-target.h
+elf32-frv.lo: elf32-frv.c elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/elf/frv.h $(INCDIR)/elf/reloc-macros.h \
elf32-target.h
elf32-gen.lo: elf32-gen.c $(INCDIR)/filenames.h elf-bfd.h \
$(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
Index: bfd/archures.c
===================================================================
RCS file: /cvs/src/src/bfd/archures.c,v
retrieving revision 1.50
diff -c -p -d -u -p -r1.50 archures.c
--- bfd/archures.c 28 May 2002 14:05:10 -0000 1.50
+++ bfd/archures.c 10 Jun 2002 22:02:36 -0000
@@ -247,6 +247,13 @@ DESCRIPTION
.#define bfd_mach_am33 330
. bfd_arch_fr30,
.#define bfd_mach_fr30 0x46523330
+. bfd_arch_frv,
+.#define bfd_mach_frv 0
+.#define bfd_mach_frvsimple 1
+.#define bfd_mach_fr300 300
+.#define bfd_mach_fr400 400
+.#define bfd_mach_frvtomcat 499 {* fr500 prototype *}
+.#define bfd_mach_fr500 500
. bfd_arch_mcore,
. bfd_arch_ia64, {* HP/Intel ia64 *}
.#define bfd_mach_ia64_elf64 0
@@ -315,6 +322,7 @@ extern const bfd_arch_info_type bfd_d10v
extern const bfd_arch_info_type bfd_d30v_arch;
extern const bfd_arch_info_type bfd_dlx_arch;
extern const bfd_arch_info_type bfd_fr30_arch;
+extern const bfd_arch_info_type bfd_frv_arch;
extern const bfd_arch_info_type bfd_h8300_arch;
extern const bfd_arch_info_type bfd_h8500_arch;
extern const bfd_arch_info_type bfd_hppa_arch;
@@ -369,6 +377,7 @@ static const bfd_arch_info_type * const
&bfd_d30v_arch,
&bfd_dlx_arch,
&bfd_fr30_arch,
+ &bfd_frv_arch,
&bfd_h8300_arch,
&bfd_h8500_arch,
&bfd_hppa_arch,
Index: bfd/config.bfd
===================================================================
RCS file: /cvs/src/src/bfd/config.bfd,v
retrieving revision 1.100
diff -c -p -d -u -p -r1.100 config.bfd
--- bfd/config.bfd 8 Jun 2002 23:23:08 -0000 1.100
+++ bfd/config.bfd 10 Jun 2002 22:02:37 -0000
@@ -281,6 +281,10 @@ case "${targ}" in
targ_defvec=bfd_elf32_fr30_vec
;;
+ frv-*-elf)
+ targ_defvec=bfd_elf32_frv_vec
+ ;;
+
h8300*-*-elf)
targ_defvec=bfd_elf32_h8300_vec
Index: bfd/configure.in
===================================================================
RCS file: /cvs/src/src/bfd/configure.in,v
retrieving revision 1.101
diff -c -p -d -u -p -r1.101 configure.in
--- bfd/configure.in 8 Jun 2002 23:23:08 -0000 1.101
+++ bfd/configure.in 10 Jun 2002 22:02:38 -0000
@@ -534,6 +534,7 @@ do
# This list is alphabetized to make it easy to compare
# with the two vector lists in targets.c. For the same reason,
# use one entry per line, even though this leads to long lines.
+ bfd_elf32_frv_vec) tb="$tb elf32-frv.lo elf32.lo $elf" ;;
a29kcoff_big_vec) tb="$tb coff-a29k.lo cofflink.lo" ;;
a_out_adobe_vec) tb="$tb aout-adobe.lo aout32.lo" ;;
aout0_big_vec) tb="$tb aout0.lo aout32.lo" ;;
Index: bfd/cpu-frv.c
===================================================================
RCS file: bfd/cpu-frv.c
diff -N bfd/cpu-frv.c
--- bfd/cpu-frv.c 1 Jan 1970 00:00:00 -0000
+++ bfd/cpu-frv.c 10 Jun 2002 22:02:38 -0000
@@ -0,0 +1,64 @@
+/* BFD support for the FRV processor.
+ Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+enum {
+ I_frv_generic,
+ I_frv_simple,
+ I_frv_500,
+ I_frv_300,
+};
+
+#define FRV_ARCH(MACHINE, NAME, DEFAULT, NEXT) \
+{ \
+ 32, /* 32 bits in a word */ \
+ 32, /* 32 bits in an address */ \
+ 8, /* 8 bits in a byte */ \
+ bfd_arch_frv, /* architecture */ \
+ MACHINE, /* which machine */ \
+ "frv", /* architecture name */ \
+ NAME, /* machine name */ \
+ 4, /* default alignment */ \
+ DEFAULT, /* is this the default? */ \
+ bfd_default_compatible, /* architecture comparison fn */ \
+ bfd_default_scan, /* string to architecture convert fn */ \
+ NEXT /* next in list */ \
+}
+
+static const bfd_arch_info_type arch_info_300
+ = FRV_ARCH (bfd_mach_fr300, "fr300", false, (bfd_arch_info_type *)0);
+
+static const bfd_arch_info_type arch_info_400
+ = FRV_ARCH (bfd_mach_fr400, "fr400", false, &arch_info_300);
+
+static const bfd_arch_info_type arch_info_500
+ = FRV_ARCH (bfd_mach_fr500, "fr500", false, &arch_info_400);
+
+static const bfd_arch_info_type arch_info_simple
+ = FRV_ARCH (bfd_mach_frvsimple, "simple", false, &arch_info_500);
+
+static const bfd_arch_info_type arch_info_tomcat
+ = FRV_ARCH (bfd_mach_frvtomcat, "tomcat", false, &arch_info_simple);
+
+const bfd_arch_info_type bfd_frv_arch
+ = FRV_ARCH (bfd_mach_frv, "frv", true, &arch_info_tomcat);
+
Index: bfd/elf32-frv.c
===================================================================
RCS file: bfd/elf32-frv.c
diff -N bfd/elf32-frv.c
--- bfd/elf32-frv.c 1 Jan 1970 00:00:00 -0000
+++ bfd/elf32-frv.c 10 Jun 2002 22:02:38 -0000
@@ -0,0 +1,1406 @@
+/* FRV-specific support for 32-bit ELF.
+ Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/frv.h"
+
+/* Forward declarations. */
+static bfd_reloc_status_type elf32_frv_relocate_lo16
+ PARAMS ((bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
+static bfd_reloc_status_type elf32_frv_relocate_hi16
+ PARAMS ((bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
+static bfd_reloc_status_type elf32_frv_relocate_label24
+ PARAMS ((bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
+static bfd_reloc_status_type elf32_frv_relocate_gprel12
+ PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
+static bfd_reloc_status_type elf32_frv_relocate_gprelu12
+ PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
+static bfd_reloc_status_type elf32_frv_relocate_gprello
+ PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
+static bfd_reloc_status_type elf32_frv_relocate_gprelhi
+ PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
+static reloc_howto_type *frv_reloc_type_lookup
+ PARAMS ((bfd *, bfd_reloc_code_real_type));
+static void frv_info_to_howto_rela
+ PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
+static boolean elf32_frv_relocate_section
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
+static boolean elf32_frv_add_symbol_hook
+ PARAMS (( bfd *, struct bfd_link_info *, const Elf_Internal_Sym *, const char **, flagword *, asection **, bfd_vma *));
+static bfd_reloc_status_type frv_final_link_relocate
+ PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, bfd_vma));
+static boolean elf32_frv_gc_sweep_hook
+ PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *));
+static asection * elf32_frv_gc_mark_hook
+ PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *));
+static boolean elf32_frv_check_relocs
+ PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *));
+static int elf32_frv_machine PARAMS ((bfd *));
+static boolean elf32_frv_object_p PARAMS ((bfd *));
+static boolean frv_elf_set_private_flags PARAMS ((bfd *, flagword));
+static boolean frv_elf_copy_private_bfd_data PARAMS ((bfd *, bfd *));
+static boolean frv_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *));
+static boolean frv_elf_print_private_bfd_data PARAMS ((bfd *, PTR));
+
+static reloc_howto_type elf32_frv_howto_table [] =
+{
+ /* This reloc does nothing. */
+ HOWTO (R_FRV_NONE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_FRV_NONE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 32 bit absolute relocation. */
+ HOWTO (R_FRV_32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_FRV_32", /* name */
+ false, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 16 bit pc-relative relocation. */
+ HOWTO (R_FRV_LABEL16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_FRV_LABEL16", /* name */
+ false, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* A 24-bit pc-relative relocation. */
+ HOWTO (R_FRV_LABEL24, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 26, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_FRV_LABEL24", /* name */
+ false, /* partial_inplace */
+ 0x7e03ffff, /* src_mask */
+ 0x7e03ffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ HOWTO (R_FRV_LO16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_FRV_LO16", /* name */
+ false, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_FRV_HI16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_FRV_HI16", /* name */
+ false, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_FRV_GPREL12, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_FRV_GPREL12", /* name */
+ false, /* partial_inplace */
+ 0xfff, /* src_mask */
+ 0xfff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_FRV_GPRELU12, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_FRV_GPRELU12", /* name */
+ false, /* partial_inplace */
+ 0xfff, /* src_mask */
+ 0x3f03f, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_FRV_GPREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_FRV_GPREL32", /* name */
+ false, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_FRV_GPRELHI, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_FRV_GPRELHI", /* name */
+ false, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_FRV_GPRELLO, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_FRV_GPRELLO", /* name */
+ false, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+};
+
+/* GNU extension to record C++ vtable hierarchy. */
+static reloc_howto_type elf32_frv_vtinherit_howto =
+ HOWTO (R_FRV_GNU_VTINHERIT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ NULL, /* special_function */
+ "R_FRV_GNU_VTINHERIT", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false); /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable member usage. */
+static reloc_howto_type elf32_frv_vtentry_howto =
+ HOWTO (R_FRV_GNU_VTENTRY, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_elf_rel_vtable_reloc_fn, /* special_function */
+ "R_FRV_GNU_VTENTRY", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false); /* pcrel_offset */
+
+/* Map BFD reloc types to FRV ELF reloc types. */
+#if 0
+struct frv_reloc_map
+{
+ unsigned int bfd_reloc_val;
+ unsigned int frv_reloc_val;
+};
+
+static const struct frv_reloc_map frv_reloc_map [] =
+{
+ { BFD_RELOC_NONE, R_FRV_NONE },
+ { BFD_RELOC_32, R_FRV_32 },
+ { BFD_RELOC_FRV_LABEL16, R_FRV_LABEL16 },
+ { BFD_RELOC_FRV_LABEL24, R_FRV_LABEL24 },
+ { BFD_RELOC_FRV_LO16, R_FRV_LO16 },
+ { BFD_RELOC_FRV_HI16, R_FRV_HI16 },
+ { BFD_RELOC_FRV_GPREL12, R_FRV_GPREL12 },
+ { BFD_RELOC_FRV_GPRELU12, R_FRV_GPRELU12 },
+ { BFD_RELOC_FRV_GPREL32, R_FRV_GPREL32 },
+ { BFD_RELOC_FRV_GPRELHI, R_FRV_GPRELHI },
+ { BFD_RELOC_FRV_GPRELLO, R_FRV_GPRELLO },
+ { BFD_RELOC_VTABLE_INHERIT, R_FRV_GNU_VTINHERIT },
+ { BFD_RELOC_VTABLE_ENTRY, R_FRV_GNU_VTENTRY },
+};
+#endif
+
+/* Handle an FRV small data reloc. */
+
+static bfd_reloc_status_type
+elf32_frv_relocate_gprel12 (info, input_bfd, input_section, relocation, contents, value)
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ Elf_Internal_Rela *relocation;
+ bfd_byte *contents;
+ bfd_vma value;
+{
+ bfd_vma insn;
+ bfd_vma gp;
+ struct bfd_link_hash_entry *h;
+
+ h = bfd_link_hash_lookup (info->hash, "_gp", false, false, true);
+
+ gp = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+
+ value -= input_section->output_section->vma;
+ value -= (gp - input_section->output_section->vma);
+
+ insn = bfd_get_32 (input_bfd, contents + relocation->r_offset);
+
+ value += relocation->r_addend;
+
+ if ((long) value > 0x7ff || (long) value < -0x800)
+ return bfd_reloc_overflow;
+
+ bfd_put_32 (input_bfd,
+ (insn & 0xfffff000) | (value & 0xfff),
+ contents + relocation->r_offset);
+
+ return bfd_reloc_ok;
+}
+
+/* Handle an FRV small data reloc. for the u12 field. */
+
+static bfd_reloc_status_type
+elf32_frv_relocate_gprelu12 (info, input_bfd, input_section, relocation, contents, value)
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ Elf_Internal_Rela *relocation;
+ bfd_byte *contents;
+ bfd_vma value;
+{
+ bfd_vma insn;
+ bfd_vma gp;
+ struct bfd_link_hash_entry *h;
+ bfd_vma mask;
+
+ h = bfd_link_hash_lookup (info->hash, "_gp", false, false, true);
+
+ gp = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+
+ value -= input_section->output_section->vma;
+ value -= (gp - input_section->output_section->vma);
+
+ insn = bfd_get_32 (input_bfd, contents + relocation->r_offset);
+
+ value += relocation->r_addend;
+
+ if ((long) value > 0x7ff || (long) value < -0x800)
+ return bfd_reloc_overflow;
+
+ /* The high 6 bits go into bits 17-12. The low 6 bits go into bits 5-0. */
+ mask = 0x3f03f;
+ insn = (insn & ~mask) | ((value & 0xfc0) << 12) | (value & 0x3f);
+
+ bfd_put_32 (input_bfd, insn, contents + relocation->r_offset);
+
+ return bfd_reloc_ok;
+}
+
+/* Handle an FRV ELF HI16 reloc. */
+
+static bfd_reloc_status_type
+elf32_frv_relocate_hi16 (input_bfd, relhi, contents, value)
+ bfd *input_bfd;
+ Elf_Internal_Rela *relhi;
+ bfd_byte *contents;
+ bfd_vma value;
+{
+ bfd_vma insn;
+
+ insn = bfd_get_32 (input_bfd, contents + relhi->r_offset);
+
+ value += relhi->r_addend;
+ value = ((value >> 16) & 0xffff);
+
+ insn = (insn & 0xffff0000) | value;
+
+ if ((long) value > 0xffff || (long) value < -0x10000)
+ return bfd_reloc_overflow;
+
+ bfd_put_32 (input_bfd, insn, contents + relhi->r_offset);
+ return bfd_reloc_ok;
+
+}
+static bfd_reloc_status_type
+elf32_frv_relocate_lo16 (input_bfd, rello, contents, value)
+ bfd *input_bfd;
+ Elf_Internal_Rela *rello;
+ bfd_byte *contents;
+ bfd_vma value;
+{
+ bfd_vma insn;
+
+ insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
+
+ value += rello->r_addend;
+ value = value & 0xffff;
+
+ insn = (insn & 0xffff0000) | value;
+
+ if ((long) value > 0xffff || (long) value < -0x10000)
+ return bfd_reloc_overflow;
+
+ bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
+ return bfd_reloc_ok;
+}
+
+/* Perform the relocation for the CALL label24 instruction. */
+
+static bfd_reloc_status_type
+elf32_frv_relocate_label24 (input_bfd, input_section, rello, contents, value)
+ bfd *input_bfd;
+ asection *input_section;
+ Elf_Internal_Rela *rello;
+ bfd_byte *contents;
+ bfd_vma value;
+{
+ bfd_vma insn;
+ bfd_vma label6;
+ bfd_vma label18;
+
+ /* The format for the call instruction is:
+
+ 0 000000 0001111 000000000000000000
+ label6 opcode label18
+
+ The branch calculation is: pc + (4*label24)
+ where label24 is the concatenation of label6 and label18. */
+
+ /* Grab the instruction. */
+ insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
+
+ value -= input_section->output_section->vma + input_section->output_offset;
+ value -= rello->r_offset;
+ value += rello->r_addend;
+
+ value = value >> 2;
+
+ label6 = value & 0xfc0000;
+ label6 = label6 << 7;
+
+ label18 = value & 0x3ffff;
+
+ insn = insn & 0x803c0000;
+ insn = insn | label6;
+ insn = insn | label18;
+
+ bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
+
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+elf32_frv_relocate_gprelhi (info, input_bfd, input_section, relocation, contents, value)
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ Elf_Internal_Rela *relocation;
+ bfd_byte *contents;
+ bfd_vma value;
+{
+ bfd_vma insn;
+ bfd_vma gp;
+ struct bfd_link_hash_entry *h;
+
+ h = bfd_link_hash_lookup (info->hash, "_gp", false, false, true);
+
+ gp = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+
+ value -= input_section->output_section->vma;
+ value -= (gp - input_section->output_section->vma);
+ value += relocation->r_addend;
+ value = ((value >> 16) & 0xffff);
+
+ if ((long) value > 0xffff || (long) value < -0x10000)
+ return bfd_reloc_overflow;
+
+ insn = bfd_get_32 (input_bfd, contents + relocation->r_offset);
+ insn = (insn & 0xffff0000) | value;
+
+ bfd_put_32 (input_bfd, insn, contents + relocation->r_offset);
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+elf32_frv_relocate_gprello (info, input_bfd, input_section, relocation, contents, value)
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ Elf_Internal_Rela *relocation;
+ bfd_byte *contents;
+ bfd_vma value;
+{
+ bfd_vma insn;
+ bfd_vma gp;
+ struct bfd_link_hash_entry *h;
+
+ h = bfd_link_hash_lookup (info->hash, "_gp", false, false, true);
+
+ gp = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+
+ value -= input_section->output_section->vma;
+ value -= (gp - input_section->output_section->vma);
+ value += relocation->r_addend;
+ value = value & 0xffff;
+
+ if ((long) value > 0xffff || (long) value < -0x10000)
+ return bfd_reloc_overflow;
+
+ insn = bfd_get_32 (input_bfd, contents + relocation->r_offset);
+ insn = (insn & 0xffff0000) | value;
+
+ bfd_put_32 (input_bfd, insn, contents + relocation->r_offset);
+
+ return bfd_reloc_ok;
+}
+
+static reloc_howto_type *
+frv_reloc_type_lookup (abfd, code)
+ bfd * abfd ATTRIBUTE_UNUSED;
+ bfd_reloc_code_real_type code;
+{
+ switch (code)
+ {
+ default:
+ break;
+
+ case BFD_RELOC_NONE:
+ return &elf32_frv_howto_table[ (int) R_FRV_NONE];
+
+ case BFD_RELOC_32:
+ case BFD_RELOC_CTOR:
+ return &elf32_frv_howto_table[ (int) R_FRV_32];
+
+ case BFD_RELOC_FRV_LABEL16:
+ return &elf32_frv_howto_table[ (int) R_FRV_LABEL16];
+
+ case BFD_RELOC_FRV_LABEL24:
+ return &elf32_frv_howto_table[ (int) R_FRV_LABEL24];
+
+ case BFD_RELOC_FRV_LO16:
+ return &elf32_frv_howto_table[ (int) R_FRV_LO16];
+
+ case BFD_RELOC_FRV_HI16:
+ return &elf32_frv_howto_table[ (int) R_FRV_HI16];
+
+ case BFD_RELOC_FRV_GPREL12:
+ return &elf32_frv_howto_table[ (int) R_FRV_GPREL12];
+
+ case BFD_RELOC_FRV_GPRELU12:
+ return &elf32_frv_howto_table[ (int) R_FRV_GPRELU12];
+
+ case BFD_RELOC_FRV_GPREL32:
+ return &elf32_frv_howto_table[ (int) R_FRV_GPREL32];
+
+ case BFD_RELOC_FRV_GPRELHI:
+ return &elf32_frv_howto_table[ (int) R_FRV_GPRELHI];
+
+ case BFD_RELOC_FRV_GPRELLO:
+ return &elf32_frv_howto_table[ (int) R_FRV_GPRELLO];
+
+ case BFD_RELOC_VTABLE_INHERIT:
+ return &elf32_frv_vtinherit_howto;
+
+ case BFD_RELOC_VTABLE_ENTRY:
+ return &elf32_frv_vtentry_howto;
+ }
+
+ return NULL;
+}
+
+/* Set the howto pointer for an FRV ELF reloc. */
+
+static void
+frv_info_to_howto_rela (abfd, cache_ptr, dst)
+ bfd * abfd ATTRIBUTE_UNUSED;
+ arelent * cache_ptr;
+ Elf32_Internal_Rela * dst;
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ switch (r_type)
+ {
+ case R_FRV_GNU_VTINHERIT:
+ cache_ptr->howto = &elf32_frv_vtinherit_howto;
+ break;
+
+ case R_FRV_GNU_VTENTRY:
+ cache_ptr->howto = &elf32_frv_vtentry_howto;
+ break;
+
+ default:
+ cache_ptr->howto = & elf32_frv_howto_table [r_type];
+ break;
+ }
+}
+
+/* Perform a single relocation. By default we use the standard BFD
+ routines, but a few relocs, we have to do them ourselves. */
+
+static bfd_reloc_status_type
+frv_final_link_relocate (howto, input_bfd, input_section, contents, rel, relocation)
+ reloc_howto_type * howto;
+ bfd * input_bfd;
+ asection * input_section;
+ bfd_byte * contents;
+ Elf_Internal_Rela * rel;
+ bfd_vma relocation;
+{
+ return _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset, relocation,
+ rel->r_addend);
+}
+
+
+/* Relocate an FRV ELF section.
+ There is some attempt to make this function usable for many architectures,
+ both USE_REL and USE_RELA ['twould be nice if such a critter existed],
+ if only to serve as a learning tool.
+
+ The RELOCATE_SECTION function is called by the new ELF backend linker
+ to handle the relocations for a section.
+
+ The relocs are always passed as Rela structures; if the section
+ actually uses Rel structures, the r_addend field will always be
+ zero.
+
+ This function is responsible for adjusting the section contents as
+ necessary, and (if using Rela relocs and generating a relocateable
+ output file) adjusting the reloc addend as necessary.
+
+ This function does not have to worry about setting the reloc
+ address or the reloc symbol index.
+
+ LOCAL_SYMS is a pointer to the swapped in local symbols.
+
+ LOCAL_SECTIONS is an array giving the section in the input file
+ corresponding to the st_shndx field of each local symbol.
+
+ The global hash table entry for the global symbols can be found
+ via elf_sym_hashes (input_bfd).
+
+ When generating relocateable output, this function must handle
+ STB_LOCAL/STT_SECTION symbols specially. The output symbol is
+ going to be the section symbol corresponding to the output
+ section, which means that the addend must be adjusted
+ accordingly. */
+
+static boolean
+elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
+ contents, relocs, local_syms, local_sections)
+ bfd * output_bfd ATTRIBUTE_UNUSED;
+ struct bfd_link_info * info;
+ bfd * input_bfd;
+ asection * input_section;
+ bfd_byte * contents;
+ Elf_Internal_Rela * relocs;
+ Elf_Internal_Sym * local_syms;
+ asection ** local_sections;
+{
+ Elf_Internal_Shdr * symtab_hdr;
+ struct elf_link_hash_entry ** sym_hashes;
+ Elf_Internal_Rela * rel;
+ Elf_Internal_Rela * relend;
+
+ symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
+ relend = relocs + input_section->reloc_count;
+
+ for (rel = relocs; rel < relend; rel ++)
+ {
+ reloc_howto_type * howto;
+ unsigned long r_symndx;
+ Elf_Internal_Sym * sym;
+ asection * sec;
+ struct elf_link_hash_entry * h;
+ bfd_vma relocation;
+ bfd_reloc_status_type r;
+ const char * name = NULL;
+ int r_type;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ if ( r_type == R_FRV_GNU_VTINHERIT
+ || r_type == R_FRV_GNU_VTENTRY)
+ continue;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ if (info->relocateable)
+ {
+ /* This is a relocateable link. We don't have to change
+ anything, unless the reloc is against a section symbol,
+ in which case we have to adjust according to where the
+ section symbol winds up in the output section. */
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+
+ if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ {
+ sec = local_sections [r_symndx];
+ rel->r_addend += sec->output_offset + sym->st_value;
+ }
+ }
+
+ continue;
+ }
+
+ /* This is a final link. */
+ howto = elf32_frv_howto_table + ELF32_R_TYPE (rel->r_info);
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections [r_symndx];
+ relocation = (sec->output_section->vma
+ + sec->output_offset
+ + sym->st_value);
+
+ name = bfd_elf_string_from_elf_section
+ (input_bfd, symtab_hdr->sh_link, sym->st_name);
+ name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
+ }
+ else
+ {
+ h = sym_hashes [r_symndx - symtab_hdr->sh_info];
+
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ name = h->root.root.string;
+
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ sec = h->root.u.def.section;
+ relocation = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ else if (h->root.type == bfd_link_hash_undefweak)
+ {
+ relocation = 0;
+ }
+ else
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd,
+ input_section, rel->r_offset, true)))
+ return false;
+ relocation = 0;
+ }
+ }
+
+ if (r_type == R_FRV_HI16)
+ r = elf32_frv_relocate_hi16 (input_bfd, rel, contents, relocation);
+
+ else if (r_type == R_FRV_LO16)
+ r = elf32_frv_relocate_lo16 (input_bfd, rel, contents, relocation);
+
+ else if (r_type == R_FRV_LABEL24)
+ r = elf32_frv_relocate_label24 (input_bfd, input_section, rel, contents, relocation);
+
+ else if (r_type == R_FRV_GPREL12)
+ r = elf32_frv_relocate_gprel12 (info, input_bfd, input_section, rel, contents, relocation);
+
+ else if (r_type == R_FRV_GPRELU12)
+ r = elf32_frv_relocate_gprelu12 (info, input_bfd, input_section, rel, contents, relocation);
+
+ else if (r_type == R_FRV_GPRELLO)
+ r = elf32_frv_relocate_gprello (info, input_bfd, input_section, rel, contents, relocation);
+
+ else if (r_type == R_FRV_GPRELHI)
+ r = elf32_frv_relocate_gprelhi (info, input_bfd, input_section, rel, contents, relocation);
+
+ else
+ r = frv_final_link_relocate (howto, input_bfd, input_section, contents, rel, relocation);
+
+ if (r != bfd_reloc_ok)
+ {
+ const char * msg = (const char *) NULL;
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ r = info->callbacks->reloc_overflow
+ (info, name, howto->name, (bfd_vma) 0,
+ input_bfd, input_section, rel->r_offset);
+ break;
+
+ case bfd_reloc_undefined:
+ r = info->callbacks->undefined_symbol
+ (info, name, input_bfd, input_section, rel->r_offset, true);
+ break;
+
+ case bfd_reloc_outofrange:
+ msg = _("internal error: out of range error");
+ break;
+
+ case bfd_reloc_notsupported:
+ msg = _("internal error: unsupported relocation error");
+ break;
+
+ case bfd_reloc_dangerous:
+ msg = _("internal error: dangerous relocation");
+ break;
+
+ default:
+ msg = _("internal error: unknown error");
+ break;
+ }
+
+ if (msg)
+ r = info->callbacks->warning
+ (info, msg, name, input_bfd, input_section, rel->r_offset);
+
+ if (! r)
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* Return the section that should be marked against GC for a given
+ relocation. */
+
+static asection *
+elf32_frv_gc_mark_hook (abfd, info, rel, h, sym)
+ bfd * abfd;
+ struct bfd_link_info * info ATTRIBUTE_UNUSED;
+ Elf_Internal_Rela * rel;
+ struct elf_link_hash_entry * h;
+ Elf_Internal_Sym * sym;
+{
+ if (h != NULL)
+ {
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_FRV_GNU_VTINHERIT:
+ case R_FRV_GNU_VTENTRY:
+ break;
+
+ default:
+ switch (h->root.type)
+ {
+ default:
+ break;
+
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ return h->root.u.def.section;
+
+ case bfd_link_hash_common:
+ return h->root.u.c.p->section;
+ }
+ }
+ }
+ else
+ {
+ if (!(elf_bad_symtab (abfd)
+ && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
+ && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
+ && sym->st_shndx != SHN_COMMON))
+ return bfd_section_from_elf_index (abfd, sym->st_shndx);
+ }
+
+ return NULL;
+}
+
+/* Update the got entry reference counts for the section being removed. */
+
+static boolean
+elf32_frv_gc_sweep_hook (abfd, info, sec, relocs)
+ bfd * abfd ATTRIBUTE_UNUSED;
+ struct bfd_link_info * info ATTRIBUTE_UNUSED;
+ asection * sec ATTRIBUTE_UNUSED;
+ const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED;
+{
+ return true;
+}
+
+
+/* Hook called by the linker routine which adds symbols from an object
+ file. We use it to put .comm items in .scomm, and not .comm. */
+
+/*ARGSUSED*/
+static boolean
+elf32_frv_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ const Elf_Internal_Sym *sym;
+ const char **namep ATTRIBUTE_UNUSED;
+ flagword *flagsp ATTRIBUTE_UNUSED;
+ asection **secp;
+ bfd_vma *valp;
+{
+ if (sym->st_shndx == SHN_COMMON
+ && !info->relocateable
+ && (int)sym->st_size <= (int)bfd_get_gp_size (abfd))
+ {
+ /* Common symbols less than or equal to -G nn bytes are
+ automatically put into .sbss. */
+
+ asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
+
+ if (scomm == NULL)
+ {
+ scomm = bfd_make_section (abfd, ".scommon");
+ if (scomm == NULL
+ || !bfd_set_section_flags (abfd, scomm, (SEC_ALLOC
+ | SEC_IS_COMMON
+ | SEC_LINKER_CREATED)))
+ return false;
+ }
+
+ *secp = scomm;
+ *valp = sym->st_size;
+ }
+
+ return true;
+}
+/* Look through the relocs for a section during the first phase.
+ Since we don't do .gots or .plts, we just need to consider the
+ virtual table relocs for gc. */
+
+static boolean
+elf32_frv_check_relocs (abfd, info, sec, relocs)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *sec;
+ const Elf_Internal_Rela *relocs;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+
+ if (info->relocateable)
+ return true;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+ sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf32_External_Sym);
+ if (!elf_bad_symtab (abfd))
+ sym_hashes_end -= symtab_hdr->sh_info;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ struct elf_link_hash_entry *h;
+ unsigned long r_symndx;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx < symtab_hdr->sh_info)
+ h = NULL;
+ else
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_FRV_GNU_VTINHERIT:
+ if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+ return false;
+ break;
+
+ /* This relocation describes which C++ vtable entries are actually
+ used. Record for later use during GC. */
+ case R_FRV_GNU_VTENTRY:
+ if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return false;
+ break;
+ }
+ }
+
+ return true;
+}
+
+
+/* Return the machine subcode from the ELF e_flags header. */
+
+static int
+elf32_frv_machine (abfd)
+ bfd *abfd;
+{
+ switch (elf_elfheader (abfd)->e_flags & EF_FRV_CPU_MASK)
+ {
+ default: break;
+ case EF_FRV_CPU_FR500: return bfd_mach_fr500;
+ case EF_FRV_CPU_FR400: return bfd_mach_fr400;
+ case EF_FRV_CPU_FR300: return bfd_mach_fr300;
+ case EF_FRV_CPU_SIMPLE: return bfd_mach_frvsimple;
+ case EF_FRV_CPU_TOMCAT: return bfd_mach_frvtomcat;
+ }
+
+ return bfd_mach_frv;
+}
+
+/* Set the right machine number for a FRV ELF file. */
+
+static boolean
+elf32_frv_object_p (abfd)
+ bfd *abfd;
+{
+ bfd_default_set_arch_mach (abfd, bfd_arch_frv, elf32_frv_machine (abfd));
+ return true;
+}
+
+/* Function to set the ELF flag bits. */
+
+static boolean
+frv_elf_set_private_flags (abfd, flags)
+ bfd *abfd;
+ flagword flags;
+{
+ elf_elfheader (abfd)->e_flags = flags;
+ elf_flags_init (abfd) = true;
+ return true;
+}
+
+/* Copy backend specific data from one object module to another. */
+
+static boolean
+frv_elf_copy_private_bfd_data (ibfd, obfd)
+ bfd *ibfd;
+ bfd *obfd;
+{
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return true;
+
+ BFD_ASSERT (!elf_flags_init (obfd)
+ || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
+
+ elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
+ elf_flags_init (obfd) = true;
+ return true;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+static boolean
+frv_elf_merge_private_bfd_data (ibfd, obfd)
+ bfd *ibfd;
+ bfd *obfd;
+{
+ flagword old_flags, old_partial;
+ flagword new_flags, new_partial;
+ boolean error = false;
+ char new_opt[80];
+ char old_opt[80];
+
+ new_opt[0] = old_opt[0] = '\0';
+ new_flags = elf_elfheader (ibfd)->e_flags;
+ old_flags = elf_elfheader (obfd)->e_flags;
+
+#ifdef DEBUG
+ (*_bfd_error_handler) ("old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s, filename = %s",
+ old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no",
+ bfd_get_filename (ibfd));
+#endif
+
+ if (!elf_flags_init (obfd)) /* First call, no flags set. */
+ {
+ elf_flags_init (obfd) = true;
+ old_flags = new_flags;
+ }
+
+ else if (new_flags == old_flags) /* Compatible flags are ok. */
+ ;
+
+ else /* Possibly incompatible flags. */
+ {
+ /* Warn if different # of gprs are used. Note, 0 means nothing is
+ said about the size of gprs. */
+ new_partial = (new_flags & EF_FRV_GPR_MASK);
+ old_partial = (old_flags & EF_FRV_GPR_MASK);
+ if (new_partial == old_partial)
+ ;
+
+ else if (new_partial == 0)
+ ;
+
+ else if (old_partial == 0)
+ old_flags |= new_partial;
+
+ else
+ {
+ switch (new_partial)
+ {
+ default: strcat (new_opt, " -mgpr-??"); break;
+ case EF_FRV_GPR_32: strcat (new_opt, " -mgpr-32"); break;
+ case EF_FRV_GPR_64: strcat (new_opt, " -mgpr-64"); break;
+ }
+
+ switch (old_partial)
+ {
+ default: strcat (old_opt, " -mgpr-??"); break;
+ case EF_FRV_GPR_32: strcat (old_opt, " -mgpr-32"); break;
+ case EF_FRV_GPR_64: strcat (old_opt, " -mgpr-64"); break;
+ }
+ }
+
+ /* Warn if different # of fprs are used. Note, 0 means nothing is
+ said about the size of fprs. */
+ new_partial = (new_flags & EF_FRV_FPR_MASK);
+ old_partial = (old_flags & EF_FRV_FPR_MASK);
+ if (new_partial == old_partial)
+ ;
+
+ else if (new_partial == 0)
+ ;
+
+ else if (old_partial == 0)
+ old_flags |= new_partial;
+
+ else
+ {
+ switch (new_partial)
+ {
+ default: strcat (new_opt, " -mfpr-?"); break;
+ case EF_FRV_FPR_32: strcat (new_opt, " -mfpr-32"); break;
+ case EF_FRV_FPR_64: strcat (new_opt, " -mfpr-64"); break;
+ case EF_FRV_FPR_NONE: strcat (new_opt, " -msoft-float"); break;
+ }
+
+ switch (old_partial)
+ {
+ default: strcat (old_opt, " -mfpr-?"); break;
+ case EF_FRV_FPR_32: strcat (old_opt, " -mfpr-32"); break;
+ case EF_FRV_FPR_64: strcat (old_opt, " -mfpr-64"); break;
+ case EF_FRV_FPR_NONE: strcat (old_opt, " -msoft-float"); break;
+ }
+ }
+
+ /* Warn if different dword support was used. Note, 0 means nothing is
+ said about the dword support. */
+ new_partial = (new_flags & EF_FRV_DWORD_MASK);
+ old_partial = (old_flags & EF_FRV_DWORD_MASK);
+ if (new_partial == old_partial)
+ ;
+
+ else if (new_partial == 0)
+ ;
+
+ else if (old_partial == 0)
+ old_flags |= new_partial;
+
+ else
+ {
+ switch (new_partial)
+ {
+ default: strcat (new_opt, " -mdword-?"); break;
+ case EF_FRV_DWORD_YES: strcat (new_opt, " -mdword"); break;
+ case EF_FRV_DWORD_NO: strcat (new_opt, " -mno-dword"); break;
+ }
+
+ switch (old_partial)
+ {
+ default: strcat (old_opt, " -mdword-?"); break;
+ case EF_FRV_DWORD_YES: strcat (old_opt, " -mdword"); break;
+ case EF_FRV_DWORD_NO: strcat (old_opt, " -mno-dword"); break;
+ }
+ }
+
+ /* Or in flags that accumulate (ie, if one module uses it, mark that the
+ feature is used. */
+ old_flags |= new_flags & (EF_FRV_DOUBLE
+ | EF_FRV_MEDIA
+ | EF_FRV_MULADD
+ | EF_FRV_NON_PIC_RELOCS);
+
+ /* If any module was compiled without -G0, clear the G0 bit. */
+ old_flags = ((old_flags & ~ EF_FRV_G0)
+ | (old_flags & new_flags & EF_FRV_G0));
+
+ /* If any module was compiled without -mnopack, clear the mnopack bit. */
+ old_flags = ((old_flags & ~ EF_FRV_NOPACK)
+ | (old_flags & new_flags & EF_FRV_NOPACK));
+
+ /* We don't have to do anything if the pic flags are the same, or the new
+ module(s) were compiled with -mlibrary-pic. */
+ new_partial = (new_flags & EF_FRV_PIC_FLAGS);
+ old_partial = (old_flags & EF_FRV_PIC_FLAGS);
+ if ((new_partial == old_partial) || ((new_partial & EF_FRV_LIBPIC) != 0))
+ ;
+
+ /* If the old module(s) were compiled with -mlibrary-pic, copy in the pic
+ flags if any from the new module. */
+ else if ((old_partial & EF_FRV_LIBPIC) != 0)
+ old_flags = (old_flags & ~ EF_FRV_PIC_FLAGS) | new_partial;
+
+ /* If we have mixtures of -fpic and -fPIC, or in both bits. */
+ else if (new_partial != 0 && old_partial != 0)
+ old_flags |= new_partial;
+
+ /* One module was compiled for pic and the other was not, see if we have
+ had any relocations that are not pic-safe. */
+ else
+ {
+ if ((old_flags & EF_FRV_NON_PIC_RELOCS) == 0)
+ old_flags |= new_partial;
+ else
+ {
+ old_flags &= ~ EF_FRV_PIC_FLAGS;
+#ifndef FRV_NO_PIC_ERROR
+ error = true;
+ (*_bfd_error_handler)
+ (_("%s: compiled with %s and linked with modules that use non-pic relocations"),
+ bfd_get_filename (ibfd),
+ (new_flags & EF_FRV_BIGPIC) ? "-fPIC" : "-fpic");
+#endif
+ }
+ }
+
+ /* Warn if different cpu is used (allow a specific cpu to override
+ the generic cpu). */
+ new_partial = (new_flags & EF_FRV_CPU_MASK);
+ old_partial = (old_flags & EF_FRV_CPU_MASK);
+ if (new_partial == old_partial)
+ ;
+
+ else if (new_partial == EF_FRV_CPU_GENERIC)
+ ;
+
+ else if (old_partial == EF_FRV_CPU_GENERIC)
+ old_flags = (old_flags & ~EF_FRV_CPU_MASK) | new_partial;
+
+ else
+ {
+ switch (new_partial)
+ {
+ default: strcat (new_opt, " -mcpu=?"); break;
+ case EF_FRV_CPU_GENERIC: strcat (new_opt, " -mcpu=frv"); break;
+ case EF_FRV_CPU_SIMPLE: strcat (new_opt, " -mcpu=simple"); break;
+ case EF_FRV_CPU_FR500: strcat (new_opt, " -mcpu=fr500"); break;
+ case EF_FRV_CPU_FR400: strcat (new_opt, " -mcpu=fr400"); break;
+ case EF_FRV_CPU_FR300: strcat (new_opt, " -mcpu=fr300"); break;
+ case EF_FRV_CPU_TOMCAT: strcat (new_opt, " -mcpu=tomcat"); break;
+ }
+
+ switch (old_partial)
+ {
+ default: strcat (old_opt, " -mcpu=?"); break;
+ case EF_FRV_CPU_GENERIC: strcat (old_opt, " -mcpu=frv"); break;
+ case EF_FRV_CPU_SIMPLE: strcat (old_opt, " -mcpu=simple"); break;
+ case EF_FRV_CPU_FR500: strcat (old_opt, " -mcpu=fr500"); break;
+ case EF_FRV_CPU_FR400: strcat (old_opt, " -mcpu=fr400"); break;
+ case EF_FRV_CPU_FR300: strcat (old_opt, " -mcpu=fr300"); break;
+ case EF_FRV_CPU_TOMCAT: strcat (old_opt, " -mcpu=tomcat"); break;
+ }
+ }
+
+ /* Print out any mismatches from above. */
+ if (new_opt[0])
+ {
+ error = true;
+ (*_bfd_error_handler)
+ (_("%s: compiled with %s and linked with modules compiled with %s"),
+ bfd_get_filename (ibfd), new_opt, old_opt);
+ }
+
+ /* Warn about any other mismatches */
+ new_partial = (new_flags & ~ EF_FRV_ALL_FLAGS);
+ old_partial = (old_flags & ~ EF_FRV_ALL_FLAGS);
+ if (new_partial != old_partial)
+ {
+ old_flags |= new_partial;
+ error = true;
+ (*_bfd_error_handler)
+ (_("%s: uses different unknown e_flags (0x%lx) fields than previous modules (0x%lx)"),
+ bfd_get_filename (ibfd), (long)new_partial, (long)old_partial);
+ }
+ }
+
+ /* If the cpu is -mcpu=simple, then set the -mnopack bit. */
+ if ((old_flags & EF_FRV_CPU_MASK) == EF_FRV_CPU_SIMPLE)
+ old_flags |= EF_FRV_NOPACK;
+
+ /* Update the old flags now with changes made above. */
+ old_partial = elf_elfheader (obfd)->e_flags & EF_FRV_CPU_MASK;
+ elf_elfheader (obfd)->e_flags = old_flags;
+ if (old_partial != (old_flags & EF_FRV_CPU_MASK))
+ bfd_default_set_arch_mach (obfd, bfd_arch_frv, elf32_frv_machine (obfd));
+
+ if (error)
+ bfd_set_error (bfd_error_bad_value);
+
+ return !error;
+}
+
+
+boolean
+frv_elf_print_private_bfd_data (abfd, ptr)
+ bfd *abfd;
+ PTR ptr;
+{
+ FILE *file = (FILE *) ptr;
+ flagword flags;
+
+ BFD_ASSERT (abfd != NULL && ptr != NULL);
+
+ /* Print normal ELF private data. */
+ _bfd_elf_print_private_bfd_data (abfd, ptr);
+
+ flags = elf_elfheader (abfd)->e_flags;
+ fprintf (file, _("private flags = 0x%lx:"), (long)flags);
+
+ switch (flags & EF_FRV_CPU_MASK)
+ {
+ default: break;
+ case EF_FRV_CPU_SIMPLE: fprintf (file, " -mcpu=simple"); break;
+ case EF_FRV_CPU_FR500: fprintf (file, " -mcpu=fr500"); break;
+ case EF_FRV_CPU_FR400: fprintf (file, " -mcpu=fr400"); break;
+ case EF_FRV_CPU_FR300: fprintf (file, " -mcpu=fr300"); break;
+ case EF_FRV_CPU_TOMCAT: fprintf (file, " -mcpu=tomcat"); break;
+ }
+
+ switch (flags & EF_FRV_GPR_MASK)
+ {
+ default: break;
+ case EF_FRV_GPR_32: fprintf (file, " -mgpr-32"); break;
+ case EF_FRV_GPR_64: fprintf (file, " -mgpr-64"); break;
+ }
+
+ switch (flags & EF_FRV_FPR_MASK)
+ {
+ default: break;
+ case EF_FRV_FPR_32: fprintf (file, " -mfpr-32"); break;
+ case EF_FRV_FPR_64: fprintf (file, " -mfpr-64"); break;
+ case EF_FRV_FPR_NONE: fprintf (file, " -msoft-float"); break;
+ }
+
+ switch (flags & EF_FRV_DWORD_MASK)
+ {
+ default: break;
+ case EF_FRV_DWORD_YES: fprintf (file, " -mdword"); break;
+ case EF_FRV_DWORD_NO: fprintf (file, " -mno-dword"); break;
+ }
+
+ if (flags & EF_FRV_DOUBLE)
+ fprintf (file, " -mdouble");
+
+ if (flags & EF_FRV_MEDIA)
+ fprintf (file, " -mmedia");
+
+ if (flags & EF_FRV_MULADD)
+ fprintf (file, " -mmuladd");
+
+ if (flags & EF_FRV_PIC)
+ fprintf (file, " -fpic");
+
+ if (flags & EF_FRV_BIGPIC)
+ fprintf (file, " -fPIC");
+
+ if (flags & EF_FRV_NON_PIC_RELOCS)
+ fprintf (file, " non-pic relocations");
+
+ if (flags & EF_FRV_G0)
+ fprintf (file, " -G0");
+
+ fputc ('\n', file);
+ return true;
+}
+
+
+#define ELF_ARCH bfd_arch_frv
+#define ELF_MACHINE_CODE EM_CYGNUS_FRV
+#define ELF_MAXPAGESIZE 0x1000
+
+#define TARGET_BIG_SYM bfd_elf32_frv_vec
+#define TARGET_BIG_NAME "elf32-frv"
+
+#define elf_info_to_howto_rel NULL
+#define elf_info_to_howto frv_info_to_howto_rela
+#define elf_backend_relocate_section elf32_frv_relocate_section
+#define elf_backend_gc_mark_hook elf32_frv_gc_mark_hook
+#define elf_backend_gc_sweep_hook elf32_frv_gc_sweep_hook
+#define elf_backend_check_relocs elf32_frv_check_relocs
+#define elf_backend_object_p elf32_frv_object_p
+#define elf_backend_add_symbol_hook elf32_frv_add_symbol_hook
+
+#define elf_backend_can_gc_sections 1
+
+#define bfd_elf32_bfd_reloc_type_lookup frv_reloc_type_lookup
+#define bfd_elf32_bfd_set_private_flags frv_elf_set_private_flags
+#define bfd_elf32_bfd_copy_private_bfd_data frv_elf_copy_private_bfd_data
+#define bfd_elf32_bfd_merge_private_bfd_data frv_elf_merge_private_bfd_data
+#define bfd_elf32_bfd_print_private_bfd_data frv_elf_print_private_bfd_data
+
+#include "elf32-target.h"
Index: bfd/reloc.c
===================================================================
RCS file: /cvs/src/src/bfd/reloc.c,v
retrieving revision 1.60
diff -c -p -d -u -p -r1.60 reloc.c
--- bfd/reloc.c 30 May 2002 22:01:28 -0000 1.60
+++ bfd/reloc.c 10 Jun 2002 22:02:38 -0000
@@ -2079,6 +2079,27 @@ ENUMX
ENUMX
BFD_RELOC_MIPS_JALR
COMMENT
+ENUM
+ BFD_RELOC_FRV_LABEL16
+ENUMX
+ BFD_RELOC_FRV_LABEL24
+ENUMX
+ BFD_RELOC_FRV_LO16
+ENUMX
+ BFD_RELOC_FRV_HI16
+ENUMX
+ BFD_RELOC_FRV_GPREL12
+ENUMX
+ BFD_RELOC_FRV_GPRELU12
+ENUMX
+ BFD_RELOC_FRV_GPREL32
+ENUMX
+ BFD_RELOC_FRV_GPRELHI
+ENUMX
+ BFD_RELOC_FRV_GPRELLO
+ENUMDOC
+ Fujitsu Frv Relocations.
+COMMENT
COMMENT
ENUMDOC
MIPS ELF relocations.
Index: bfd/targets.c
===================================================================
RCS file: /cvs/src/src/bfd/targets.c,v
retrieving revision 1.66
diff -c -p -d -u -p -r1.66 targets.c
--- bfd/targets.c 8 Jun 2002 23:23:08 -0000 1.66
+++ bfd/targets.c 10 Jun 2002 22:02:38 -0000
@@ -513,6 +513,7 @@ extern const bfd_target bfd_elf32_d10v_v
extern const bfd_target bfd_elf32_d30v_vec;
extern const bfd_target bfd_elf32_dlx_big_vec;
extern const bfd_target bfd_elf32_fr30_vec;
+extern const bfd_target bfd_elf32_frv_vec;
extern const bfd_target bfd_elf32_h8300_vec;
extern const bfd_target bfd_elf32_hppa_linux_vec;
extern const bfd_target bfd_elf32_hppa_vec;
@@ -772,6 +773,7 @@ static const bfd_target * const _bfd_tar
&bfd_elf32_d30v_vec,
&bfd_elf32_dlx_big_vec,
&bfd_elf32_fr30_vec,
+ &bfd_elf32_frv_vec,
&bfd_elf32_h8300_vec,
&bfd_elf32_hppa_linux_vec,
&bfd_elf32_hppa_vec,
Index: bfd/po/SRC-POTFILES.in
===================================================================
RCS file: /cvs/src/src/bfd/po/SRC-POTFILES.in,v
retrieving revision 1.13
diff -c -p -d -u -p -r1.13 SRC-POTFILES.in
--- bfd/po/SRC-POTFILES.in 6 Jun 2002 00:29:22 -0000 1.13
+++ bfd/po/SRC-POTFILES.in 10 Jun 2002 22:02:38 -0000
@@ -67,6 +67,7 @@ cpu-d10v.c
cpu-d30v.c
cpu-dlx.c
cpu-fr30.c
+cpu-frv.c
cpu-h8300.c
cpu-h8500.c
cpu-hppa.c
@@ -127,6 +128,7 @@ elf32-d10v.c
elf32-d30v.c
elf32-dlx.c
elf32-fr30.c
+elf32-frv.c
elf32-gen.c
elf32-h8300.c
elf32-hppa.c
Index: binutils/NEWS
===================================================================
RCS file: /cvs/src/src/binutils/NEWS,v
retrieving revision 1.24
diff -c -p -d -u -p -r1.24 NEWS
--- binutils/NEWS 20 Feb 2002 10:46:54 -0000 1.24
+++ binutils/NEWS 11 Jun 2002 20:44:57 -0000
@@ -1,4 +1,6 @@
-*- text -*-
+Support for the Fujitsu FRV architecture added by Red Hat. Models for FR400 and
+FR500 included.
Changes in version 2.12:
Index: binutils/Makefile.am
===================================================================
RCS file: /cvs/src/src/binutils/Makefile.am,v
retrieving revision 1.33
diff -c -p -d -u -p -r1.33 Makefile.am
--- binutils/Makefile.am 8 Jun 2002 08:44:16 -0000 1.33
+++ binutils/Makefile.am 10 Jun 2002 22:02:38 -0000
@@ -501,6 +501,7 @@ readelf.o: readelf.c ../bfd/bfd.h $(INCD
$(INCDIR)/elf/reloc-macros.h $(INCDIR)/elf/arc.h $(INCDIR)/elf/arm.h \
$(INCDIR)/elf/avr.h $(INCDIR)/elf/cris.h $(INCDIR)/elf/d10v.h \
$(INCDIR)/elf/d30v.h $(INCDIR)/elf/dlx.h $(INCDIR)/elf/fr30.h \
+ $(INCDIR)/elf/frv.h \
$(INCDIR)/elf/h8.h $(INCDIR)/elf/hppa.h $(INCDIR)/elf/i386.h \
$(INCDIR)/elf/i860.h $(INCDIR)/elf/i960.h $(INCDIR)/elf/ia64.h \
$(INCDIR)/elf/m32r.h $(INCDIR)/elf/m68k.h $(INCDIR)/elf/mcore.h \
Index: binutils/readelf.c
===================================================================
RCS file: /cvs/src/src/binutils/readelf.c,v
retrieving revision 1.161
diff -c -p -d -u -p -r1.161 readelf.c
--- binutils/readelf.c 7 Jun 2002 16:42:31 -0000 1.161
+++ binutils/readelf.c 10 Jun 2002 22:02:39 -0000
@@ -58,6 +58,7 @@
#include "elf/d30v.h"
#include "elf/dlx.h"
#include "elf/fr30.h"
+#include "elf/frv.h"
#include "elf/h8.h"
#include "elf/hppa.h"
#include "elf/i386.h"
@@ -633,6 +634,7 @@ guess_is_rela (e_machine)
case EM_CYGNUS_MN10300:
case EM_FR30:
case EM_CYGNUS_FR30:
+ case EM_CYGNUS_FRV:
case EM_SH:
case EM_ALPHA:
case EM_MCORE:
@@ -1031,6 +1033,10 @@ dump_relocations (file, rel_offset, rel_
rtype = elf_fr30_reloc_type (type);
break;
+ case EM_CYGNUS_FRV:
+ rtype = elf_frv_reloc_type (type);
+ break;
+
case EM_MCORE:
rtype = elf_mcore_reloc_type (type);
break;
@@ -1508,6 +1514,7 @@ get_machine_name (e_machine)
case EM_MN10200: return "mn10200";
case EM_CYGNUS_FR30:
case EM_FR30: return "Fujitsu FR30";
+ case EM_CYGNUS_FRV: return "Fujitsu FR-V";
case EM_PJ_OLD:
case EM_PJ: return "picoJava";
case EM_MMA: return "Fujitsu Multimedia Accelerator";
Index: gas/NEWS
===================================================================
RCS file: /cvs/src/src/gas/NEWS,v
retrieving revision 1.28
diff -c -p -d -u -p -r1.28 NEWS
--- gas/NEWS 28 May 2002 14:20:42 -0000 1.28
+++ gas/NEWS 11 Jun 2002 20:44:57 -0000
@@ -1,4 +1,7 @@
-*- text -*-
+Support for the Fujitsu FRV architecture added by Red Hat. Models for FR400 and
+FR500 included.
+
Support for DLX processor added.
GASP has now been deprecated and will be removed in a future release. Use the
Index: gas/Makefile.am
===================================================================
RCS file: /cvs/src/src/gas/Makefile.am,v
retrieving revision 1.59
diff -c -p -d -u -p -r1.59 Makefile.am
--- gas/Makefile.am 8 Jun 2002 08:45:03 -0000 1.59
+++ gas/Makefile.am 10 Jun 2002 22:02:39 -0000
@@ -47,6 +47,7 @@ CPU_TYPES = \
d30v \
dlx \
fr30 \
+ frv \
h8300 \
h8500 \
hppa \
@@ -236,6 +237,7 @@ TARGET_CPU_CFILES = \
config/tc-d30v.c \
config/tc-dlx.c \
config/tc-fr30.c \
+ config/tc-frv.c \
config/tc-h8300.c \
config/tc-h8500.c \
config/tc-hppa.c \
@@ -284,6 +286,7 @@ TARGET_CPU_HFILES = \
config/tc-d30v.h \
config/tc-dlx.h \
config/tc-fr30.h \
+ config/tc-frv.h \
config/tc-h8300.h \
config/tc-h8500.h \
config/tc-hppa.h \
@@ -1067,6 +1070,18 @@ DEPTC_fr30_elf = $(INCDIR)/symcat.h $(sr
$(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
$(srcdir)/../opcodes/fr30-desc.h $(INCDIR)/opcode/cgen.h \
$(srcdir)/../opcodes/fr30-opc.h cgen.h
+DEPTC_frv_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-frv.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/frv-desc.h \
+ $(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/frv-opc.h \
+ cgen.h
+DEPTC_frv_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-frv.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(srcdir)/../opcodes/frv-desc.h $(INCDIR)/opcode/cgen.h \
+ $(srcdir)/../opcodes/frv-opc.h cgen.h
DEPTC_h8300_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
$(srcdir)/config/tc-h8300.h $(INCDIR)/coff/internal.h \
$(INCDIR)/coff/h8300.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
@@ -1577,6 +1592,15 @@ DEPOBJ_fr30_elf = $(INCDIR)/symcat.h $(s
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-fr30.h \
$(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
struc-symbol.h $(INCDIR)/aout/aout64.h
+DEPOBJ_frv_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-frv.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+DEPOBJ_frv_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-frv.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h $(INCDIR)/aout/aout64.h
DEPOBJ_h8300_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
$(srcdir)/config/tc-h8300.h $(INCDIR)/coff/internal.h \
$(INCDIR)/coff/h8300.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
@@ -2015,6 +2039,12 @@ DEP_fr30_coff = $(srcdir)/config/obj-cof
DEP_fr30_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
$(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-fr30.h
+DEP_frv_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-frv.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_frv_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-frv.h
DEP_h8300_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-h8300.h \
$(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/h8300.h \
$(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
Index: gas/configure.in
===================================================================
RCS file: /cvs/src/src/gas/configure.in,v
retrieving revision 1.107
diff -c -p -d -u -p -r1.107 configure.in
--- gas/configure.in 9 Jun 2002 00:45:41 -0000 1.107
+++ gas/configure.in 10 Jun 2002 22:02:40 -0000
@@ -218,6 +218,7 @@ changequote([,])dnl
fr30-*-*) fmt=elf bfd_gas=yes ;;
+ frv-*-*) fmt=elf bfd_gas=yes ;;
hppa-*-linux-gnu*) case ${cpu} in
hppa*64*)
@@ -580,6 +581,9 @@ changequote([,])dnl
using_cgen=yes
;;
+ frv)
+ using_cgen=yes
+ ;;
m68k)
case ${extra_objects} in
*m68k-parse.o*) ;;
Index: gas/config/tc-frv.c
===================================================================
RCS file: gas/config/tc-frv.c
diff -N gas/config/tc-frv.c
--- gas/config/tc-frv.c 1 Jan 1970 00:00:00 -0000
+++ gas/config/tc-frv.c 10 Jun 2002 22:02:41 -0000
@@ -0,0 +1,1606 @@
+/* tc-frv.c -- Assembler for the Fujitsu FRV.
+ Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include "as.h"
+#include "dwarf2dbg.h"
+#include "subsegs.h"
+#include "symcat.h"
+#include "opcodes/frv-desc.h"
+#include "opcodes/frv-opc.h"
+#include "cgen.h"
+#include "libbfd.h"
+#include "elf/common.h"
+#include "elf/frv.h"
+
+/* Structure to hold all of the different components describing
+ an individual instruction. */
+typedef struct
+{
+ const CGEN_INSN * insn;
+ const CGEN_INSN * orig_insn;
+ CGEN_FIELDS fields;
+#if CGEN_INT_INSN_P
+ CGEN_INSN_INT buffer [1];
+#define INSN_VALUE(buf) (*(buf))
+#else
+ unsigned char buffer [CGEN_MAX_INSN_SIZE];
+#define INSN_VALUE(buf) (buf)
+#endif
+ char * addr;
+ fragS * frag;
+ int num_fixups;
+ fixS * fixups [GAS_CGEN_MAX_FIXUPS];
+ int indices [MAX_OPERAND_INSTANCES];
+}
+frv_insn;
+
+enum vliw_insn_type
+{
+ VLIW_GENERIC_TYPE, /* Don't care about this insn. */
+ VLIW_BRANCH_TYPE, /* A Branch. */
+ VLIW_LABEL_TYPE, /* A Label. */
+ VLIW_NOP_TYPE, /* A NOP. */
+ VLIW_BRANCH_HAS_NOPS /* A Branch that requires NOPS. */
+};
+
+/* We're going to use these in the fr_subtype field to mark
+ whether to keep inserted nops. */
+
+#define NOP_KEEP 1 /* Keep these NOPS. */
+#define NOP_DELETE 2 /* Delete these NOPS. */
+
+#define DO_COUNT true
+#define DONT_COUNT false
+
+/* A list of insns within a VLIW insn. */
+struct vliw_insn_list
+{
+ /* The type of this insn. */
+ enum vliw_insn_type type;
+
+ /* The corresponding gas insn information. */
+ const CGEN_INSN *insn;
+
+ /* For branches and labels, the symbol that is referenced. */
+ symbolS *sym;
+
+ /* For branches, the frag containing the single nop that was generated. */
+ fragS *snop_frag;
+
+ /* For branches, the frag containing the double nop that was generated. */
+ fragS *dnop_frag;
+
+ /* Pointer to raw data for this insn. */
+ char *address;
+
+ /* Next insn in list. */
+ struct vliw_insn_list *next;
+};
+
+static struct vliw_insn_list single_nop_insn = {
+ VLIW_NOP_TYPE, NULL, NULL, NULL, NULL, NULL, NULL };
+
+static struct vliw_insn_list double_nop_insn = {
+ VLIW_NOP_TYPE, NULL, NULL, NULL, NULL, NULL, NULL };
+
+struct vliw_chain
+{
+ int num;
+ int insn_count;
+ struct vliw_insn_list *insn_list;
+ struct vliw_chain *next;
+};
+
+static struct vliw_chain *vliw_chain_top;
+static struct vliw_chain *current_vliw_chain;
+static struct vliw_chain *previous_vliw_chain;
+static struct vliw_insn_list *current_vliw_insn;
+
+const char comment_chars[] = ";";
+const char line_comment_chars[] = "#";
+const char line_separator_chars[] = "";
+const char EXP_CHARS[] = "eE";
+const char FLT_CHARS[] = "dD";
+
+static FRV_VLIW vliw;
+
+/* Default machine */
+
+#ifdef DEFAULT_CPU_FRV
+#define DEFAULT_MACHINE bfd_mach_frv
+#define DEFAULT_FLAGS EF_FRV_CPU_GENERIC
+
+#else
+#ifdef DEFAULT_CPU_FR300
+#define DEFAULT_MACHINE bfd_mach_fr300
+#define DEFAULT_FLAGS EF_FRV_CPU_FR300
+
+#else
+#ifdef DEFAULT_CPU_SIMPLE
+#define DEFAULT_MACHINE bfd_mach_frvsimple
+#define DEFAULT_FLAGS EF_FRV_CPU_SIMPLE
+
+#else
+#ifdef DEFAULT_CPU_TOMCAT
+#define DEFAULT_MACHINE bfd_mach_frvtomcat
+#define DEFAULT_FLAGS EF_FRV_CPU_TOMCAT
+
+#else
+#ifdef DEFAULT_CPU_FR400
+#define DEFAULT_MACHINE bfd_mach_fr400
+#define DEFAULT_FLAGS EF_FRV_CPU_FR400
+
+#else
+#define DEFAULT_MACHINE bfd_mach_fr500
+#define DEFAULT_FLAGS EF_FRV_CPU_FR500
+#endif
+#endif
+#endif
+#endif
+#endif
+
+static unsigned long frv_mach = bfd_mach_frv;
+
+/* Flags to set in the elf header */
+static flagword frv_flags = DEFAULT_FLAGS;
+
+static int frv_user_set_flags_p = 0;
+static int frv_pic_p = 0;
+static const char *frv_pic_flag = (const char *)0;
+
+/* Print tomcat-specific debugging info. */
+static int tomcat_debug = 0;
+
+/* Tomcat-specific NOP statistics. */
+static int tomcat_stats = 0;
+static int tomcat_doubles = 0;
+static int tomcat_singles = 0;
+
+/* Forward reference to static functions */
+static void frv_set_flags PARAMS ((int));
+static void frv_pic_ptr PARAMS ((int));
+static void frv_frob_file_section PARAMS ((bfd *, asection *, PTR));
+
+/* The target specific pseudo-ops which we support. */
+const pseudo_typeS md_pseudo_table[] =
+{
+ { "eflags", frv_set_flags, 0 },
+ { "word", cons, 4 },
+ { "picptr", frv_pic_ptr, 4 },
+ { "file", dwarf2_directive_file, 0 },
+ { "loc", dwarf2_directive_loc, 0 },
+ { NULL, NULL, 0 }
+};
+
+
+#define FRV_SHORTOPTS "G:"
+const char * md_shortopts = FRV_SHORTOPTS;
+
+#define OPTION_GPR_32 (OPTION_MD_BASE)
+#define OPTION_GPR_64 (OPTION_MD_BASE + 1)
+#define OPTION_FPR_32 (OPTION_MD_BASE + 2)
+#define OPTION_FPR_64 (OPTION_MD_BASE + 3)
+#define OPTION_SOFT_FLOAT (OPTION_MD_BASE + 4)
+#define OPTION_DWORD_YES (OPTION_MD_BASE + 5)
+#define OPTION_DWORD_NO (OPTION_MD_BASE + 6)
+#define OPTION_DOUBLE (OPTION_MD_BASE + 7)
+#define OPTION_NO_DOUBLE (OPTION_MD_BASE + 8)
+#define OPTION_MEDIA (OPTION_MD_BASE + 9)
+#define OPTION_NO_MEDIA (OPTION_MD_BASE + 10)
+#define OPTION_CPU (OPTION_MD_BASE + 11)
+#define OPTION_PIC (OPTION_MD_BASE + 12)
+#define OPTION_BIGPIC (OPTION_MD_BASE + 13)
+#define OPTION_LIBPIC (OPTION_MD_BASE + 14)
+#define OPTION_MULADD (OPTION_MD_BASE + 15)
+#define OPTION_NO_MULADD (OPTION_MD_BASE + 16)
+#define OPTION_TOMCAT_DEBUG (OPTION_MD_BASE + 17)
+#define OPTION_TOMCAT_STATS (OPTION_MD_BASE + 18)
+#define OPTION_PACK (OPTION_MD_BASE + 19)
+#define OPTION_NO_PACK (OPTION_MD_BASE + 20)
+
+struct option md_longopts[] =
+{
+ { "mgpr-32", no_argument, NULL, OPTION_GPR_32 },
+ { "mgpr-64", no_argument, NULL, OPTION_GPR_64 },
+ { "mfpr-32", no_argument, NULL, OPTION_FPR_32 },
+ { "mfpr-64", no_argument, NULL, OPTION_FPR_64 },
+ { "mhard-float", no_argument, NULL, OPTION_FPR_64 },
+ { "msoft-float", no_argument, NULL, OPTION_SOFT_FLOAT },
+ { "mdword", no_argument, NULL, OPTION_DWORD_YES },
+ { "mno-dword", no_argument, NULL, OPTION_DWORD_NO },
+ { "mdouble", no_argument, NULL, OPTION_DOUBLE },
+ { "mno-double", no_argument, NULL, OPTION_NO_DOUBLE },
+ { "mmedia", no_argument, NULL, OPTION_MEDIA },
+ { "mno-media", no_argument, NULL, OPTION_NO_MEDIA },
+ { "mcpu", required_argument, NULL, OPTION_CPU },
+ { "mpic", no_argument, NULL, OPTION_PIC },
+ { "mPIC", no_argument, NULL, OPTION_BIGPIC },
+ { "mlibrary-pic", no_argument, NULL, OPTION_LIBPIC },
+ { "mmuladd", no_argument, NULL, OPTION_MULADD },
+ { "mno-muladd", no_argument, NULL, OPTION_NO_MULADD },
+ { "mtomcat-debug", no_argument, NULL, OPTION_TOMCAT_DEBUG },
+ { "mtomcat-stats", no_argument, NULL, OPTION_TOMCAT_STATS },
+ { "mpack", no_argument, NULL, OPTION_PACK },
+ { "mno-pack", no_argument, NULL, OPTION_NO_PACK },
+ { NULL, no_argument, NULL, 0 },
+};
+
+size_t md_longopts_size = sizeof (md_longopts);
+
+/* What value to give to bfd_set_gp_size. */
+static int g_switch_value = 8;
+
+int
+md_parse_option (c, arg)
+ int c;
+ char * arg;
+{
+ switch (c)
+ {
+ default:
+ return 0;
+
+ case 'G':
+ g_switch_value = atoi (arg);
+ if (! g_switch_value)
+ frv_flags |= EF_FRV_G0;
+ break;
+
+ case OPTION_GPR_32:
+ frv_flags = (frv_flags & ~EF_FRV_GPR_MASK) | EF_FRV_GPR_32;
+ break;
+
+ case OPTION_GPR_64:
+ frv_flags = (frv_flags & ~EF_FRV_GPR_MASK) | EF_FRV_GPR_64;
+ break;
+
+ case OPTION_FPR_32:
+ frv_flags = (frv_flags & ~EF_FRV_FPR_MASK) | EF_FRV_FPR_32;
+ break;
+
+ case OPTION_FPR_64:
+ frv_flags = (frv_flags & ~EF_FRV_FPR_MASK) | EF_FRV_FPR_64;
+ break;
+
+ case OPTION_SOFT_FLOAT:
+ frv_flags = (frv_flags & ~EF_FRV_FPR_MASK) | EF_FRV_FPR_NONE;
+ break;
+
+ case OPTION_DWORD_YES:
+ frv_flags = (frv_flags & ~EF_FRV_DWORD_MASK) | EF_FRV_DWORD_YES;
+ break;
+
+ case OPTION_DWORD_NO:
+ frv_flags = (frv_flags & ~EF_FRV_DWORD_MASK) | EF_FRV_DWORD_NO;
+ break;
+
+ case OPTION_DOUBLE:
+ frv_flags |= EF_FRV_DOUBLE;
+ break;
+
+ case OPTION_NO_DOUBLE:
+ frv_flags &= ~EF_FRV_DOUBLE;
+ break;
+
+ case OPTION_MEDIA:
+ frv_flags |= EF_FRV_MEDIA;
+ break;
+
+ case OPTION_NO_MEDIA:
+ frv_flags &= ~EF_FRV_MEDIA;
+ break;
+
+ case OPTION_MULADD:
+ frv_flags |= EF_FRV_MULADD;
+ break;
+
+ case OPTION_NO_MULADD:
+ frv_flags &= ~EF_FRV_MULADD;
+ break;
+
+ case OPTION_PACK:
+ frv_flags &= ~EF_FRV_NOPACK;
+ break;
+
+ case OPTION_NO_PACK:
+ frv_flags |= EF_FRV_NOPACK;
+ break;
+
+ case OPTION_CPU:
+ {
+ char *p;
+ int cpu_flags = EF_FRV_CPU_GENERIC;
+
+ /* Identify the processor type */
+ p = arg;
+ if (strcmp (p, "frv") == 0)
+ {
+ cpu_flags = EF_FRV_CPU_GENERIC;
+ frv_mach = bfd_mach_frv;
+ }
+
+ else if (strcmp (p, "fr500") == 0)
+ {
+ cpu_flags = EF_FRV_CPU_FR500;
+ frv_mach = bfd_mach_fr500;
+ }
+
+ else if (strcmp (p, "fr400") == 0)
+ {
+ cpu_flags = EF_FRV_CPU_FR400;
+ frv_mach = bfd_mach_fr400;
+ }
+
+ else if (strcmp (p, "fr300") == 0)
+ {
+ cpu_flags = EF_FRV_CPU_FR300;
+ frv_mach = bfd_mach_fr300;
+ }
+
+ else if (strcmp (p, "simple") == 0)
+ {
+ cpu_flags = EF_FRV_CPU_SIMPLE;
+ frv_mach = bfd_mach_frvsimple;
+ frv_flags |= EF_FRV_NOPACK;
+ }
+
+ else if (strcmp (p, "tomcat") == 0)
+ {
+ cpu_flags = EF_FRV_CPU_TOMCAT;
+ frv_mach = bfd_mach_frvtomcat;
+ }
+
+ else
+ {
+ as_fatal ("Unknown cpu -mcpu=%s", arg);
+ return 0;
+ }
+
+ frv_flags = (frv_flags & ~EF_FRV_CPU_MASK) | cpu_flags;
+ }
+ break;
+
+ case OPTION_PIC:
+ frv_flags |= EF_FRV_PIC;
+ frv_pic_p = 1;
+ frv_pic_flag = "-fpic";
+ break;
+
+ case OPTION_BIGPIC:
+ frv_flags |= EF_FRV_BIGPIC;
+ frv_pic_p = 1;
+ frv_pic_flag = "-fPIC";
+ break;
+
+ case OPTION_LIBPIC:
+ frv_flags |= (EF_FRV_LIBPIC | EF_FRV_G0);
+ frv_pic_p = 1;
+ frv_pic_flag = "-mlibrary-pic";
+ g_switch_value = 0;
+ break;
+
+ case OPTION_TOMCAT_DEBUG:
+ tomcat_debug = 1;
+ break;
+
+ case OPTION_TOMCAT_STATS:
+ tomcat_stats = 1;
+ break;
+ }
+
+ return 1;
+}
+
+void
+md_show_usage (stream)
+ FILE * stream;
+{
+ fprintf (stream, _("FRV specific command line options:\n"));
+ fprintf (stream, _("-G n Data >= n bytes is in small data area\n"));
+ fprintf (stream, _("-mgpr-32 Note 32 gprs are used\n"));
+ fprintf (stream, _("-mgpr-64 Note 64 gprs are used\n"));
+ fprintf (stream, _("-mfpr-32 Note 32 fprs are used\n"));
+ fprintf (stream, _("-mfpr-64 Note 64 fprs are used\n"));
+ fprintf (stream, _("-msoft-float Note software fp is used\n"));
+ fprintf (stream, _("-mdword Note stack is aligned to a 8 byte boundary\n"));
+ fprintf (stream, _("-mno-dword Note stack is aligned to a 4 byte boundary\n"));
+ fprintf (stream, _("-mdouble Note fp double insns are used\n"));
+ fprintf (stream, _("-mmedia Note media insns are used\n"));
+ fprintf (stream, _("-mmuladd Note multiply add/subtract insns are used\n"));
+ fprintf (stream, _("-mpack Note instructions are packed\n"));
+ fprintf (stream, _("-mno-pack Do not allow instructions to be packed\n"));
+ fprintf (stream, _("-mpic Note small position independent code\n"));
+ fprintf (stream, _("-mPIC Note large position independent code\n"));
+ fprintf (stream, _("-mlibrary-pic Compile library for large position indepedent code\n"));
+ fprintf (stream, _("-mcpu={fr500|fr400|fr300|frv|simple|tomcat}\n"));
+ fprintf (stream, _(" Record the cpu type\n"));
+ fprintf (stream, _("-mtomcat-stats Print out stats for tomcat workarounds\n"));
+ fprintf (stream, _("-mtomcat-debug Debug tomcat workarounds\n"));
+}
+
+
+void
+md_begin ()
+{
+ /* Initialize the `cgen' interface. */
+
+ /* Set the machine number and endian. */
+ gas_cgen_cpu_desc = frv_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, 0,
+ CGEN_CPU_OPEN_ENDIAN,
+ CGEN_ENDIAN_BIG,
+ CGEN_CPU_OPEN_END);
+ frv_cgen_init_asm (gas_cgen_cpu_desc);
+
+ /* This is a callback from cgen to gas to parse operands. */
+ cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand);
+
+ /* Set the ELF flags if desired. */
+ if (frv_flags)
+ bfd_set_private_flags (stdoutput, frv_flags);
+
+ /* Set the machine type */
+ bfd_default_set_arch_mach (stdoutput, bfd_arch_frv, frv_mach);
+
+ /* Set up gp size so we can put local common items in .sbss */
+ bfd_set_gp_size (stdoutput, g_switch_value);
+
+ frv_vliw_reset (& vliw, frv_mach, frv_flags);
+}
+
+int chain_num = 0;
+
+struct vliw_insn_list *
+frv_insert_vliw_insn (count)
+ boolean count;
+{
+ struct vliw_insn_list *vliw_insn_list_entry;
+ struct vliw_chain *vliw_chain_entry;
+
+ if (current_vliw_chain == NULL)
+ {
+ vliw_chain_entry = (struct vliw_chain *) xmalloc (sizeof (struct vliw_chain));
+ vliw_chain_entry->insn_count = 0;
+ vliw_chain_entry->insn_list = NULL;
+ vliw_chain_entry->next = NULL;
+ vliw_chain_entry->num = chain_num++;
+
+ if (!vliw_chain_top)
+ vliw_chain_top = vliw_chain_entry;
+ current_vliw_chain = vliw_chain_entry;
+ if (previous_vliw_chain)
+ previous_vliw_chain->next = vliw_chain_entry;
+ }
+
+ vliw_insn_list_entry = (struct vliw_insn_list *) xmalloc (sizeof (struct vliw_insn_list));
+ vliw_insn_list_entry->type = VLIW_GENERIC_TYPE;
+ vliw_insn_list_entry->insn = NULL;
+ vliw_insn_list_entry->sym = NULL;
+ vliw_insn_list_entry->snop_frag = NULL;
+ vliw_insn_list_entry->dnop_frag = NULL;
+ vliw_insn_list_entry->next = NULL;
+
+ if (count)
+ current_vliw_chain->insn_count++;
+
+ if (current_vliw_insn)
+ current_vliw_insn->next = vliw_insn_list_entry;
+ current_vliw_insn = vliw_insn_list_entry;
+
+ if (!current_vliw_chain->insn_list)
+ current_vliw_chain->insn_list = current_vliw_insn;
+
+ return vliw_insn_list_entry;
+}
+
+ /* Identify the following cases:
+
+ 1) A VLIW insn that contains both a branch and the branch destination.
+ This requires the insertion of two vliw instructions before the
+ branch. The first consists of two nops. The second consists of
+ a single nop.
+
+ 2) A single instruction VLIW insn which is the destination of a branch
+ that is in the next VLIW insn. This requires the insertion of a vliw
+ insn containing two nops before the branch.
+
+ 3) A double instruction VLIW insn which contains the destination of a
+ branch that is in the next VLIW insn. This requires the insertion of
+ a VLIW insn containing a single nop before the branch.
+
+ 4) A single instruction VLIW insn which contains branch destination (x),
+ followed by a single instruction VLIW insn which does not contain
+ the branch to (x), followed by a VLIW insn which does contain the branch
+ to (x). This requires the insertion of a VLIW insn containing a single
+ nop before the VLIW instruction containing the branch.
+
+ */
+#define FRV_IS_NOP(insn) (insn.buffer[0] == FRV_NOP_PACK || insn.buffer[0] == FRV_NOP_NOPACK)
+#define FRV_NOP_PACK 0x00880000 /* ori.p gr0,0,gr0 */
+#define FRV_NOP_NOPACK 0x80880000 /* ori gr0,0,gr0 */
+
+/* Check a vliw insn for an insn of type containing the sym passed in label_sym. */
+
+static struct vliw_insn_list *
+frv_find_in_vliw (vliw_insn_type, this_chain, label_sym)
+ enum vliw_insn_type vliw_insn_type;
+ struct vliw_chain *this_chain;
+ symbolS *label_sym;
+{
+
+ struct vliw_insn_list *the_insn;
+
+ if (!this_chain)
+ return NULL;
+
+ for (the_insn = this_chain->insn_list; the_insn; the_insn = the_insn->next)
+ {
+ if (the_insn->type == vliw_insn_type
+ && the_insn->sym == label_sym)
+ return the_insn;
+ }
+
+ return NULL;
+}
+
+enum vliw_nop_type
+{
+ /* A Vliw insn containing a single nop insn. */
+ VLIW_SINGLE_NOP,
+
+ /* A Vliw insn containing two nop insns. */
+ VLIW_DOUBLE_NOP,
+
+ /* Two vliw insns. The first containing two nop insns.
+ The second contain a single nop insn. */
+ VLIW_DOUBLE_THEN_SINGLE_NOP
+};
+
+static void
+frv_debug_tomcat (start_chain)
+ struct vliw_chain *start_chain;
+{
+ struct vliw_chain *this_chain;
+ struct vliw_insn_list *this_insn;
+ int i = 1;
+
+ for (this_chain = start_chain; this_chain; this_chain = this_chain->next, i++)
+ {
+ fprintf (stderr, "\nVliw Insn #%d, #insns: %d\n", i, this_chain->insn_count);
+
+ for (this_insn = this_chain->insn_list; this_insn; this_insn = this_insn->next)
+ {
+ if (this_insn->type == VLIW_LABEL_TYPE)
+ fprintf (stderr, "Label Value: %d\n", (int) this_insn->sym);
+ else if (this_insn->type == VLIW_BRANCH_TYPE)
+ fprintf (stderr, "%s to %d\n", this_insn->insn->base->name, (int) this_insn->sym);
+ else if (this_insn->type == VLIW_BRANCH_HAS_NOPS)
+ fprintf (stderr, "nop'd %s to %d\n", this_insn->insn->base->name, (int) this_insn->sym);
+ else if (this_insn->type == VLIW_NOP_TYPE)
+ fprintf (stderr, "Nop\n");
+ else
+ fprintf (stderr, " %s\n", this_insn->insn->base->name);
+ }
+ }
+}
+
+
+static void
+frv_adjust_vliw_count (this_chain)
+ struct vliw_chain *this_chain;
+{
+ struct vliw_insn_list *this_insn;
+
+ this_chain->insn_count = 0;
+
+ for (this_insn = this_chain->insn_list;
+ this_insn;
+ this_insn = this_insn->next)
+ {
+ if (this_insn->type != VLIW_LABEL_TYPE)
+ this_chain->insn_count++;
+ }
+
+}
+
+/* Insert the desired nop combination in the vliw chain before insert_before_insn.
+ Rechain the vliw insn. */
+
+
+static struct vliw_chain *
+frv_tomcat_shuffle (this_nop_type, vliw_to_split, insert_before_insn)
+ enum vliw_nop_type this_nop_type;
+ struct vliw_chain *vliw_to_split;
+ struct vliw_insn_list *insert_before_insn;
+{
+
+ boolean pack_prev = false;
+ struct vliw_chain *return_me = NULL;
+ struct vliw_insn_list *prev_insn = NULL;
+ struct vliw_insn_list *curr_insn = vliw_to_split->insn_list;
+
+ struct vliw_chain *double_nop = (struct vliw_chain *) xmalloc (sizeof (struct vliw_chain));
+ struct vliw_chain *single_nop = (struct vliw_chain *) xmalloc (sizeof (struct vliw_chain));
+ struct vliw_chain *second_part = (struct vliw_chain *) xmalloc (sizeof (struct vliw_chain));
+ struct vliw_chain *curr_vliw = vliw_chain_top;
+ struct vliw_chain *prev_vliw = NULL;
+
+ while (curr_insn && curr_insn != insert_before_insn)
+ {
+ /* We can't set the packing bit on a label. If we have the case
+ label 1:
+ label 2:
+ label 3:
+ branch that needs nops
+ Then don't set pack bit later. */
+
+ if (curr_insn->type != VLIW_LABEL_TYPE)
+ pack_prev = true;
+ prev_insn = curr_insn;
+ curr_insn = curr_insn->next;
+ }
+
+ while (curr_vliw && curr_vliw != vliw_to_split)
+ {
+ prev_vliw = curr_vliw;
+ curr_vliw = curr_vliw->next;
+ }
+
+ switch (this_nop_type)
+ {
+ case VLIW_SINGLE_NOP:
+ if (!prev_insn)
+ {
+ /* Branch is first, Insert the NOP prior to this vliw insn. */
+ if (prev_vliw)
+ prev_vliw->next = single_nop;
+ else
+ vliw_chain_top = single_nop;
+ single_nop->next = vliw_to_split;
+ vliw_to_split->insn_list->type = VLIW_BRANCH_HAS_NOPS;
+ return_me = vliw_to_split;
+ }
+ else
+ {
+ /* Set the packing bit on the previous insn. */
+ if (pack_prev)
+ {
+ unsigned char *buffer = prev_insn->address;
+ buffer[0] |= 0x80;
+ }
+ /* The branch is in the middle. Split this vliw insn into first
+ and second parts. Insert the NOP inbetween. */
+
+ second_part->insn_list = insert_before_insn;
+ second_part->insn_list->type = VLIW_BRANCH_HAS_NOPS;
+ second_part->next = vliw_to_split->next;
+ frv_adjust_vliw_count (second_part);
+
+ single_nop->next = second_part;
+
+ vliw_to_split->next = single_nop;
+ prev_insn->next = NULL;
+
+ return_me = second_part;
+ frv_adjust_vliw_count (vliw_to_split);
+ }
+ break;
+
+ case VLIW_DOUBLE_NOP:
+ if (!prev_insn)
+ {
+ /* Branch is first, Insert the NOP prior to this vliw insn. */
+ if (prev_vliw)
+ prev_vliw->next = double_nop;
+ else
+ vliw_chain_top = double_nop;
+
+ double_nop->next = vliw_to_split;
+ return_me = vliw_to_split;
+ vliw_to_split->insn_list->type = VLIW_BRANCH_HAS_NOPS;
+ }
+ else
+ {
+ /* Set the packing bit on the previous insn. */
+ if (pack_prev)
+ {
+ unsigned char *buffer = prev_insn->address;
+ buffer[0] |= 0x80;
+ }
+
+ /* The branch is in the middle. Split this vliw insn into first
+ and second parts. Insert the NOP inbetween. */
+ second_part->insn_list = insert_before_insn;
+ second_part->insn_list->type = VLIW_BRANCH_HAS_NOPS;
+ second_part->next = vliw_to_split->next;
+ frv_adjust_vliw_count (second_part);
+
+ double_nop->next = second_part;
+
+ vliw_to_split->next = single_nop;
+ prev_insn->next = NULL;
+ frv_adjust_vliw_count (vliw_to_split);
+
+ return_me = second_part;
+ }
+ break;
+
+ case VLIW_DOUBLE_THEN_SINGLE_NOP:
+ double_nop->next = single_nop;
+ double_nop->insn_count = 2;
+ double_nop->insn_list = &double_nop_insn;
+ single_nop->insn_count = 1;
+ single_nop->insn_list = &single_nop_insn;
+
+ if (!prev_insn)
+ {
+ /* The branch is the first insn in this vliw. Don't split the vliw. Insert
+ the nops prior to this vliw. */
+ if (prev_vliw)
+ prev_vliw->next = double_nop;
+ else
+ vliw_chain_top = double_nop;
+
+ single_nop->next = vliw_to_split;
+ return_me = vliw_to_split;
+ vliw_to_split->insn_list->type = VLIW_BRANCH_HAS_NOPS;
+ }
+ else
+ {
+ /* Set the packing bit on the previous insn. */
+ if (pack_prev)
+ {
+ unsigned char *buffer = prev_insn->address;
+ buffer[0] |= 0x80;
+ }
+
+ /* The branch is in the middle of this vliw insn. Split into first and
+ second parts. Insert the nop vliws in between. */
+ second_part->insn_list = insert_before_insn;
+ second_part->insn_list->type = VLIW_BRANCH_HAS_NOPS;
+ second_part->next = vliw_to_split->next;
+ frv_adjust_vliw_count (second_part);
+
+ single_nop->next = second_part;
+
+ vliw_to_split->next = double_nop;
+ prev_insn->next = NULL;
+ frv_adjust_vliw_count (vliw_to_split);
+
+ return_me = second_part;
+ }
+ break;
+ }
+
+ return return_me;
+}
+
+static void
+frv_tomcat_analyze_vliw_chains ()
+{
+ struct vliw_chain *vliw1 = NULL;
+ struct vliw_chain *vliw2 = NULL;
+ struct vliw_chain *vliw3 = NULL;
+
+ struct vliw_insn_list *this_insn = NULL;
+ struct vliw_insn_list *temp_insn = NULL;
+
+ /* We potentially need to look at three VLIW insns to determine if the
+ workaround is required. Set them up. Ignore existing nops during analysis. */
+
+#define FRV_SET_VLIW_WINDOW(VLIW1, VLIW2, VLIW3) \
+ if (VLIW1 && VLIW1->next) \
+ VLIW2 = VLIW1->next; \
+ else \
+ VLIW2 = NULL; \
+ if (VLIW2 && VLIW2->next) \
+ VLIW3 = VLIW2->next; \
+ else \
+ VLIW3 = NULL
+
+ vliw1 = vliw_chain_top;
+
+workaround_top:
+
+ FRV_SET_VLIW_WINDOW (vliw1, vliw2, vliw3);
+
+ if (!vliw1)
+ return;
+
+ if (vliw1->insn_count == 1)
+ {
+ /* check vliw1 for a label. */
+ if (vliw1->insn_list->type == VLIW_LABEL_TYPE)
+ {
+ temp_insn = frv_find_in_vliw (VLIW_BRANCH_TYPE, vliw2, vliw1->insn_list->sym);
+ if (temp_insn)
+ {
+ vliw1 = frv_tomcat_shuffle (VLIW_DOUBLE_NOP, vliw2, vliw1->insn_list);
+ temp_insn->dnop_frag->fr_subtype = NOP_KEEP;
+ vliw1 = vliw1->next;
+ if (tomcat_stats)
+ tomcat_doubles++;
+ goto workaround_top;
+ }
+ else if (vliw2
+ && vliw2->insn_count == 1
+ && (temp_insn = frv_find_in_vliw (VLIW_BRANCH_TYPE, vliw3, vliw1->insn_list->sym)) != NULL)
+ {
+ temp_insn->snop_frag->fr_subtype = NOP_KEEP;
+ vliw1 = frv_tomcat_shuffle (VLIW_SINGLE_NOP, vliw3, vliw3->insn_list);
+ if (tomcat_stats)
+ tomcat_singles++;
+ goto workaround_top;
+ }
+ }
+ }
+
+ if (vliw1->insn_count == 2)
+ {
+ struct vliw_insn_list *this_insn;
+
+ /* check vliw1 for a label. */
+ for (this_insn = vliw1->insn_list; this_insn; this_insn = this_insn->next)
+ {
+ if (this_insn->type == VLIW_LABEL_TYPE)
+ {
+ if ((temp_insn = frv_find_in_vliw (VLIW_BRANCH_TYPE, vliw2, this_insn->sym, temp_insn)) != NULL)
+ {
+ temp_insn->snop_frag->fr_subtype = NOP_KEEP;
+ vliw1 = frv_tomcat_shuffle (VLIW_SINGLE_NOP, vliw2, this_insn);
+ if (tomcat_stats)
+ tomcat_singles++;
+ }
+ else
+ vliw1 = vliw1->next;
+ goto workaround_top;
+ }
+ }
+ }
+ /* Examine each insn in this VLIW. Look for the workaround criteria. */
+ for (this_insn = vliw1->insn_list; this_insn; this_insn = this_insn->next)
+ {
+ /* Don't look at labels or nops. */
+ while (this_insn
+ && (this_insn->type == VLIW_LABEL_TYPE
+ || this_insn->type == VLIW_NOP_TYPE
+ || this_insn->type == VLIW_BRANCH_HAS_NOPS))
+ this_insn = this_insn->next;
+
+ if (!this_insn)
+ {
+ vliw1 = vliw2;
+ goto workaround_top;
+ }
+
+ if (frv_is_branch_insn (this_insn->insn))
+ {
+ if ((temp_insn = frv_find_in_vliw (VLIW_LABEL_TYPE, vliw1, this_insn->sym, temp_insn)) != NULL)
+ {
+ /* Insert [nop/nop] [nop] before branch. */
+ this_insn->snop_frag->fr_subtype = NOP_KEEP;
+ this_insn->dnop_frag->fr_subtype = NOP_KEEP;
+ vliw1 = frv_tomcat_shuffle (VLIW_DOUBLE_THEN_SINGLE_NOP, vliw1, this_insn);
+ goto workaround_top;
+ }
+ }
+
+
+ }
+ /* This vliw insn checks out okay. Take a look at the next one. */
+ vliw1 = vliw1->next;
+ goto workaround_top;
+}
+
+void
+frv_tomcat_workaround ()
+{
+ if (frv_mach != bfd_mach_frvtomcat)
+ return;
+
+ if (tomcat_debug)
+ frv_debug_tomcat (vliw_chain_top);
+
+ frv_tomcat_analyze_vliw_chains ();
+
+ if (tomcat_stats)
+ {
+ fprintf (stderr, "Inserted %d Single Nops\n", tomcat_singles);
+ fprintf (stderr, "Inserted %d Double Nops\n", tomcat_doubles);
+ }
+}
+
+void
+md_assemble (str)
+ char * str;
+{
+ frv_insn insn;
+ char *errmsg;
+ int packing_constraint;
+ finished_insnS finished_insn;
+ fragS *double_nop_frag = NULL;
+ fragS *single_nop_frag = NULL;
+ struct vliw_insn_list *vliw_insn_list_entry = NULL;
+
+ /* Initialize GAS's cgen interface for a new instruction. */
+ gas_cgen_init_parse ();
+
+ insn.insn = frv_cgen_assemble_insn
+ (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, &errmsg);
+
+ if (!insn.insn)
+ {
+ as_bad (errmsg);
+ return;
+ }
+
+ /* If the cpu is tomcat, then we need to insert nops to workaround
+ hardware limitations. We need to keep track of each vliw unit
+ and examine the length of the unit and the individual insns
+ within the unit to determine the number and location of the
+ required nops. */
+ if (frv_mach == bfd_mach_frvtomcat)
+ {
+ /* If we've just finished a VLIW insn OR this is a branch,
+ then start up a new frag. Fill it with nops. We will get rid
+ of those that are not required after we've seen all of the
+ instructions but before we start resolving fixups. */
+ if ( !FRV_IS_NOP (insn)
+ && (frv_is_branch_insn (insn.insn) || insn.fields.f_pack))
+ {
+ char *buffer;
+
+ frag_wane (frag_now);
+ frag_new (0);
+ double_nop_frag = frag_now;
+ buffer = frag_var (rs_machine_dependent, 8, 8, NOP_DELETE, NULL, 0, 0);
+ md_number_to_chars (buffer, FRV_NOP_PACK, 4);
+ md_number_to_chars (buffer+4, FRV_NOP_NOPACK, 4);
+
+ frag_wane (frag_now);
+ frag_new (0);
+ single_nop_frag = frag_now;
+ buffer = frag_var (rs_machine_dependent, 4, 4, NOP_DELETE, NULL, 0, 0);
+ md_number_to_chars (buffer, FRV_NOP_NOPACK, 4);
+ }
+
+ vliw_insn_list_entry = frv_insert_vliw_insn (DO_COUNT);
+ vliw_insn_list_entry->insn = insn.insn;
+ if (frv_is_branch_insn (insn.insn))
+ vliw_insn_list_entry->type = VLIW_BRANCH_TYPE;
+
+ if ( !FRV_IS_NOP (insn)
+ && (frv_is_branch_insn (insn.insn) || insn.fields.f_pack))
+ {
+ vliw_insn_list_entry->snop_frag = single_nop_frag;
+ vliw_insn_list_entry->dnop_frag = double_nop_frag;
+ }
+ }
+
+ /* Make sure that this insn does not violate the VLIW packing constraints. */
+ /* -mno-pack disallows any packing whatsoever. */
+ if (frv_flags & EF_FRV_NOPACK)
+ {
+ if (! insn.fields.f_pack)
+ {
+ as_bad (_("VLIW packing used for -mno-pack"));
+ return;
+ }
+ }
+ /* -mcpu=FRV is an idealized FR-V implementation that supports all of the
+ instructions, don't do vliw checking. */
+ else if (frv_mach != bfd_mach_frv)
+ {
+ packing_constraint = frv_vliw_add_insn (& vliw, insn.insn);
+ if (insn.fields.f_pack)
+ frv_vliw_reset (& vliw, frv_mach, frv_flags);
+ if (packing_constraint)
+ {
+ as_bad (_("VLIW packing constraint violation"));
+ return;
+ }
+ }
+
+ /* Doesn't really matter what we pass for RELAX_P here. */
+ gas_cgen_finish_insn (insn.insn, insn.buffer,
+ CGEN_FIELDS_BITSIZE (& insn.fields), 1, &finished_insn);
+
+
+ /* If the cpu is tomcat, then we need to insert nops to workaround
+ hardware limitations. We need to keep track of each vliw unit
+ and examine the length of the unit and the individual insns
+ within the unit to determine the number and location of the
+ required nops. */
+ if (frv_mach == bfd_mach_frvtomcat)
+ {
+ if (vliw_insn_list_entry)
+ vliw_insn_list_entry->address = finished_insn.addr;
+ else
+ abort();
+
+ if (insn.fields.f_pack)
+ {
+ /* We've completed a VLIW insn. */
+ previous_vliw_chain = current_vliw_chain;
+ current_vliw_chain = NULL;
+ current_vliw_insn = NULL;
+ }
+ }
+}
+
+/* The syntax in the manual says constants begin with '#'.
+ We just ignore it. */
+
+void
+md_operand (expressionP)
+ expressionS * expressionP;
+{
+ if (* input_line_pointer == '#')
+ {
+ input_line_pointer ++;
+ expression (expressionP);
+ }
+}
+
+valueT
+md_section_align (segment, size)
+ segT segment;
+ valueT size;
+{
+ int align = bfd_get_section_alignment (stdoutput, segment);
+ return ((size + (1 << align) - 1) & (-1 << align));
+}
+
+symbolS *
+md_undefined_symbol (name)
+ char * name ATTRIBUTE_UNUSED;
+{
+ return 0;
+}
+
+/* Interface to relax_segment. */
+
+/* FIXME: Build table by hand, get it working, then machine generate. */
+const relax_typeS md_relax_table[] =
+{
+ {1, 1, 0, 0},
+ {511 - 2 - 2, -512 - 2 + 2, 0, 2 },
+ {0x2000000 - 1 - 2, -0x2000000 - 2, 2, 0 },
+ {0x2000000 - 1 - 2, -0x2000000 - 2, 4, 0 }
+};
+
+long
+frv_relax_frag (fragP, stretch)
+ fragS *fragP ATTRIBUTE_UNUSED;
+ long stretch ATTRIBUTE_UNUSED;
+{
+ return 0;
+}
+
+/* Return an initial guess of the length by which a fragment must grow to
+ hold a branch to reach its destination.
+ Also updates fr_type/fr_subtype as necessary.
+
+ Called just before doing relaxation.
+ Any symbol that is now undefined will not become defined.
+ The guess for fr_var is ACTUALLY the growth beyond fr_fix.
+ Whatever we do to grow fr_fix or fr_var contributes to our returned value.
+ Although it may not be explicit in the frag, pretend fr_var starts with a
+ 0 value. */
+
+int
+md_estimate_size_before_relax (fragP, segment)
+ fragS * fragP;
+ segT segment ATTRIBUTE_UNUSED;
+{
+ switch (fragP->fr_subtype)
+ {
+ case NOP_KEEP:
+ return fragP->fr_var;
+
+ default:
+ case NOP_DELETE:
+ return 0;
+ }
+}
+
+/* *fragP has been relaxed to its final size, and now needs to have
+ the bytes inside it modified to conform to the new size.
+
+ Called after relaxation is finished.
+ fragP->fr_type == rs_machine_dependent.
+ fragP->fr_subtype is the subtype of what the address relaxed to. */
+
+void
+md_convert_frag (abfd, sec, fragP)
+ bfd * abfd ATTRIBUTE_UNUSED;
+ segT sec ATTRIBUTE_UNUSED;
+ fragS * fragP;
+{
+ switch (fragP->fr_subtype)
+ {
+ default:
+ case NOP_DELETE:
+ return;
+
+ case NOP_KEEP:
+ fragP->fr_fix = fragP->fr_var;
+ fragP->fr_var = 0;
+ return;
+ }
+}
+
+/* Functions concerning relocs. */
+
+/* The location from which a PC relative jump should be calculated,
+ given a PC relative reloc. */
+
+long
+md_pcrel_from_section (fixP, sec)
+ fixS * fixP;
+ segT sec;
+{
+ if (fixP->fx_addsy != (symbolS *) NULL
+ && (! S_IS_DEFINED (fixP->fx_addsy)
+ || S_GET_SEGMENT (fixP->fx_addsy) != sec))
+ {
+ /* The symbol is undefined (or is defined but not in this section).
+ Let the linker figure it out. */
+ return 0;
+ }
+
+ return (fixP->fx_frag->fr_address + fixP->fx_where) & ~1;
+}
+
+/* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
+ Returns BFD_RELOC_NONE if no reloc type can be found.
+ *FIXP may be modified if desired. */
+
+bfd_reloc_code_real_type
+md_cgen_lookup_reloc (insn, operand, fixP)
+ const CGEN_INSN * insn ATTRIBUTE_UNUSED;
+ const CGEN_OPERAND * operand;
+ fixS * fixP;
+{
+ switch (operand->type)
+ {
+ case FRV_OPERAND_LABEL16:
+ fixP->fx_pcrel = true;
+ return BFD_RELOC_FRV_LABEL16;
+
+ case FRV_OPERAND_LABEL24:
+ fixP->fx_pcrel = true;
+ return BFD_RELOC_FRV_LABEL24;
+
+ case FRV_OPERAND_UHI16:
+ case FRV_OPERAND_ULO16:
+ case FRV_OPERAND_SLO16:
+
+ /* The relocation type should be recorded in opinfo */
+ if (fixP->fx_cgen.opinfo != 0)
+ return fixP->fx_cgen.opinfo;
+ break;
+
+ case FRV_OPERAND_D12:
+ case FRV_OPERAND_S12:
+ return BFD_RELOC_FRV_GPREL12;
+
+ case FRV_OPERAND_U12:
+ return BFD_RELOC_FRV_GPRELU12;
+
+ default:
+ break;
+ }
+ return BFD_RELOC_NONE;
+}
+
+
+/* See whether we need to force a relocation into the output file.
+ This is used to force out switch and PC relative relocations when
+ relaxing. */
+
+int
+frv_force_relocation (fix)
+ fixS * fix;
+{
+ if (fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY
+ || fix->fx_r_type == BFD_RELOC_FRV_GPREL12
+ || fix->fx_r_type == BFD_RELOC_FRV_GPRELU12)
+ return 1;
+
+ return 0;
+}
+
+/* Write a value out to the object file, using the appropriate endianness. */
+
+void
+frv_md_number_to_chars (buf, val, n)
+ char * buf;
+ valueT val;
+ int n;
+{
+ number_to_chars_bigendian (buf, val, n);
+}
+
+/* Turn a string in input_line_pointer into a floating point constant of type
+ type, and store the appropriate bytes in *litP. The number of LITTLENUMS
+ emitted is stored in *sizeP . An error message is returned, or NULL on OK.
+*/
+
+/* Equal to MAX_PRECISION in atof-ieee.c */
+#define MAX_LITTLENUMS 6
+
+char *
+md_atof (type, litP, sizeP)
+ char type;
+ char * litP;
+ int * sizeP;
+{
+ int i;
+ int prec;
+ LITTLENUM_TYPE words [MAX_LITTLENUMS];
+ char * t;
+ char * atof_ieee ();
+
+ switch (type)
+ {
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ prec = 4;
+ break;
+
+ /* FIXME: Some targets allow other format chars for bigger sizes here. */
+
+ default:
+ * sizeP = 0;
+ return _("Bad call to md_atof()");
+ }
+
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+ * sizeP = prec * sizeof (LITTLENUM_TYPE);
+
+ for (i = 0; i < prec; i++)
+ {
+ md_number_to_chars (litP, (valueT) words[i],
+ sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+
+ return 0;
+}
+
+boolean
+frv_fix_adjustable (fixP)
+ fixS * fixP;
+{
+ bfd_reloc_code_real_type reloc_type;
+
+ if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
+ {
+ const CGEN_INSN *insn = NULL;
+ int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
+ const CGEN_OPERAND *operand = cgen_operand_lookup_by_num(gas_cgen_cpu_desc, opindex);
+ reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
+ }
+ else
+ reloc_type = fixP->fx_r_type;
+
+ if (fixP->fx_addsy == NULL)
+ return 1;
+
+ /* Prevent all adjustments to global symbols. */
+ if (S_IS_EXTERN (fixP->fx_addsy))
+ return 0;
+
+ if (S_IS_WEAK (fixP->fx_addsy))
+ return 0;
+
+ /* We need the symbol name for the VTABLE entries */
+ if ( reloc_type == BFD_RELOC_VTABLE_INHERIT
+ || reloc_type == BFD_RELOC_VTABLE_ENTRY
+ || reloc_type == BFD_RELOC_FRV_GPREL12
+ || reloc_type == BFD_RELOC_FRV_GPRELU12)
+ return 0;
+
+ return 1;
+}
+
+/* Allow user to set flags bits. */
+void
+frv_set_flags (arg)
+ int arg ATTRIBUTE_UNUSED;
+{
+ flagword new_flags = get_absolute_expression ();
+ flagword new_mask = ~ (flagword)0;
+
+ frv_user_set_flags_p = 1;
+ if (*input_line_pointer == ',')
+ {
+ ++input_line_pointer;
+ new_mask = get_absolute_expression ();
+ }
+
+ frv_flags = (frv_flags & ~new_mask) | (new_flags & new_mask);
+ bfd_set_private_flags (stdoutput, frv_flags);
+}
+
+/* Frv specific function to handle 4 byte initializations for pointers that are
+ considered 'safe' for use with pic support. Until frv_frob_file{,_section}
+ is run, we encode it a BFD_RELOC_CTOR, and it is turned back into a normal
+ BFD_RELOC_32 at that time. */
+
+void
+frv_pic_ptr (nbytes)
+ int nbytes;
+{
+ expressionS exp;
+ char *p;
+
+ if (nbytes != 4)
+ abort ();
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ if (is_it_end_of_statement ())
+ {
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+#ifdef md_cons_align
+ md_cons_align (nbytes);
+#endif
+
+ do
+ {
+ expression (&exp);
+
+ p = frag_more (4);
+ memset (p, 0, 4);
+ fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &exp, 0,
+ BFD_RELOC_CTOR);
+ }
+ while (*input_line_pointer++ == ',');
+
+ input_line_pointer--; /* Put terminator back into stream. */
+ demand_empty_rest_of_line ();
+}
+
+
+
+#ifdef DEBUG
+#define DPRINTF1(A) fprintf (stderr, A)
+#define DPRINTF2(A,B) fprintf (stderr, A, B)
+#define DPRINTF3(A,B,C) fprintf (stderr, A, B, C)
+
+#else
+#define DPRINTF1(A)
+#define DPRINTF2(A,B)
+#define DPRINTF3(A,B,C)
+#endif
+
+/* Go through a the sections looking for relocations that are problematical for
+ pic. If not pic, just note that this object can't be linked with pic. If
+ it is pic, see if it needs to be marked so that it will be fixed up, or if
+ not possible, issue an error. */
+
+static void
+frv_frob_file_section (abfd, sec, ptr)
+ bfd *abfd;
+ asection *sec;
+ PTR ptr ATTRIBUTE_UNUSED;
+{
+ segment_info_type *seginfo = seg_info (sec);
+ fixS *fixp;
+ CGEN_CPU_DESC cd = gas_cgen_cpu_desc;
+ flagword flags = bfd_get_section_flags (abfd, sec);
+
+ /* Skip relocations in known sections (.ctors, .dtors, and .gcc_except_table)
+ since we can fix those up by hand. */
+ int known_section_p = (sec->name
+ && sec->name[0] == '.'
+ && ((sec->name[1] == 'c'
+ && strcmp (sec->name, ".ctor") == 0)
+ || (sec->name[1] == 'd'
+ && strcmp (sec->name, ".dtor") == 0)
+ || (sec->name[1] == 'g'
+ && strcmp (sec->name, ".gcc_except_table") == 0)));
+
+ DPRINTF3 ("\nFrv section %s%s\n", sec->name, (known_section_p) ? ", known section" : "");
+ if ((flags & SEC_ALLOC) == 0)
+ {
+ DPRINTF1 ("\tSkipping non-loaded section\n");
+ return;
+ }
+
+ for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
+ {
+ symbolS *s = fixp->fx_addsy;
+ bfd_reloc_code_real_type reloc;
+ int non_pic_p;
+ int opindex;
+ const CGEN_OPERAND *operand;
+ const CGEN_INSN *insn = fixp->fx_cgen.insn;
+
+ if (fixp->fx_done)
+ {
+ DPRINTF1 ("\tSkipping reloc that has already been done\n");
+ continue;
+ }
+
+ if (fixp->fx_pcrel)
+ {
+ DPRINTF1 ("\tSkipping reloc that is PC relative\n");
+ continue;
+ }
+
+ if (! s)
+ {
+ DPRINTF1 ("\tSkipping reloc without symbol\n");
+ continue;
+ }
+
+ if (fixp->fx_r_type < BFD_RELOC_UNUSED)
+ {
+ opindex = -1;
+ reloc = fixp->fx_r_type;
+ }
+ else
+ {
+ opindex = (int) fixp->fx_r_type - (int) BFD_RELOC_UNUSED;
+ operand = cgen_operand_lookup_by_num (cd, opindex);
+ reloc = md_cgen_lookup_reloc (insn, operand, fixp);
+ }
+
+ DPRINTF3 ("\treloc %s\t%s", bfd_get_reloc_code_name (reloc), S_GET_NAME (s));
+
+ non_pic_p = 0;
+ switch (reloc)
+ {
+ default:
+ break;
+
+ case BFD_RELOC_32:
+ /* Skip relocations in known sections (.ctors, .dtors, and
+ .gcc_except_table) since we can fix those up by hand. Also
+ skip forward references to constants. Also skip a difference
+ of two symbols, which still uses the BFD_RELOC_32 at this
+ point. */
+ if (! known_section_p
+ && S_GET_SEGMENT (s) != absolute_section
+ && !fixp->fx_subsy
+ && (flags & (SEC_READONLY | SEC_CODE)) == 0)
+ {
+ non_pic_p = 1;
+ }
+ break;
+
+ /* FIXME -- should determine if any of the GP relocation really uses
+ gr16 (which is not pic safe) or not. Right now, assume if we
+ aren't being compiled with -mpic, the usage is non pic safe, but
+ is safe with -mpic. */
+ case BFD_RELOC_FRV_GPREL12:
+ case BFD_RELOC_FRV_GPRELU12:
+ case BFD_RELOC_FRV_GPREL32:
+ case BFD_RELOC_FRV_GPRELHI:
+ case BFD_RELOC_FRV_GPRELLO:
+ non_pic_p = ! frv_pic_p;
+ break;
+
+ case BFD_RELOC_FRV_LO16:
+ case BFD_RELOC_FRV_HI16:
+ if (S_GET_SEGMENT (s) != absolute_section)
+ non_pic_p = 1;
+ break;
+
+ case BFD_RELOC_VTABLE_INHERIT:
+ case BFD_RELOC_VTABLE_ENTRY:
+ non_pic_p = 1;
+ break;
+
+ /* If this is a blessed BFD_RELOC_32, convert it back to the normal
+ relocation. */
+ case BFD_RELOC_CTOR:
+ fixp->fx_r_type = BFD_RELOC_32;
+ break;
+ }
+
+ if (non_pic_p)
+ {
+ DPRINTF1 (" (Non-pic relocation)\n");
+ if (frv_pic_p)
+ as_warn_where (fixp->fx_file, fixp->fx_line,
+ _("Relocation %s is not safe for %s"),
+ bfd_get_reloc_code_name (reloc), frv_pic_flag);
+
+ else if ((frv_flags & EF_FRV_NON_PIC_RELOCS) == 0)
+ {
+ frv_flags |= EF_FRV_NON_PIC_RELOCS;
+ bfd_set_private_flags (abfd, frv_flags);
+ }
+ }
+#ifdef DEBUG
+ else
+ DPRINTF1 ("\n");
+#endif
+ }
+}
+
+/* After all of the symbols have been adjusted, go over the file looking
+ for any relocations that pic won't support. */
+
+void
+frv_frob_file ()
+{
+ bfd_map_over_sections (stdoutput, frv_frob_file_section, (PTR)0);
+}
+
+void
+frv_frob_label (this_label)
+ symbolS *this_label;
+{
+ struct vliw_insn_list *vliw_insn_list_entry;
+
+ if (frv_mach != bfd_mach_frvtomcat)
+ return;
+
+ if (now_seg != text_section)
+ return;
+
+ vliw_insn_list_entry = frv_insert_vliw_insn(DONT_COUNT);
+ vliw_insn_list_entry->type = VLIW_LABEL_TYPE;
+ vliw_insn_list_entry->sym = this_label;
+}
+
+fixS *
+frv_cgen_record_fixup_exp (frag, where, insn, length, operand, opinfo, exp)
+ fragS * frag;
+ int where;
+ const CGEN_INSN * insn;
+ int length;
+ const CGEN_OPERAND * operand;
+ int opinfo;
+ expressionS * exp;
+{
+ fixS * fixP = gas_cgen_record_fixup_exp (frag, where, insn, length,
+ operand, opinfo, exp);
+
+ if (frv_mach == bfd_mach_frvtomcat
+ && current_vliw_insn
+ && current_vliw_insn->type == VLIW_BRANCH_TYPE
+ && exp != NULL)
+ current_vliw_insn->sym = exp->X_add_symbol;
+
+ return fixP;
+}
Index: gas/config/tc-frv.h
===================================================================
RCS file: gas/config/tc-frv.h
diff -N gas/config/tc-frv.h
--- gas/config/tc-frv.h 1 Jan 1970 00:00:00 -0000
+++ gas/config/tc-frv.h 10 Jun 2002 22:02:41 -0000
@@ -0,0 +1,89 @@
+/* tc-frv.h -- Header file for tc-frv.c.
+ Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#define TC_FRV
+
+#ifndef BFD_ASSEMBLER
+/* leading space so will compile with cc */
+ #error FRV support requires BFD_ASSEMBLER
+#endif
+
+#define LISTING_HEADER "FRV GAS "
+
+/* The target BFD architecture. */
+#define TARGET_ARCH bfd_arch_frv
+
+#define TARGET_FORMAT "elf32-frv"
+
+#define TARGET_BYTES_BIG_ENDIAN 1
+
+/* call md_pcrel_from_section, not md_pcrel_from */
+long md_pcrel_from_section PARAMS ((struct fix *, segT));
+#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section (FIXP, SEC)
+
+/* Permit temporary numeric labels. */
+#define LOCAL_LABELS_FB 1
+
+#define DIFF_EXPR_OK /* .-foo gets turned into PC relative relocs */
+
+/* We don't need to handle .word strangely. */
+#define WORKING_DOT_WORD
+
+#define md_apply_fix3 gas_cgen_md_apply_fix3
+
+extern void frv_tomcat_workaround PARAMS ((void));
+#define md_cleanup frv_tomcat_workaround
+
+#define md_number_to_chars frv_md_number_to_chars
+
+extern long frv_relax_frag PARAMS ((fragS *, long));
+#define md_relax_frag(segment, fragP, stretch) frv_relax_frag(fragP, stretch)
+
+#define obj_fix_adjustable(fixP) frv_fix_adjustable (fixP)
+extern boolean frv_fix_adjustable PARAMS ((struct fix *));
+
+#ifdef OBJ_ELF
+/* This arranges for gas/write.c to not apply a relocation if
+ obj_fix_adjustable() says it is not adjustable. */
+#define TC_FIX_ADJUSTABLE(fixP) obj_fix_adjustable (fixP)
+#endif
+
+/* When relaxing, we need to emit various relocs we otherwise wouldn't. */
+#define TC_FORCE_RELOCATION(fix) frv_force_relocation (fix)
+extern int frv_force_relocation PARAMS ((struct fix *));
+
+#undef GAS_CGEN_MAX_FIXUPS
+#define GAS_CGEN_MAX_FIXUPS 1
+
+void frv_frob_label PARAMS ((symbolS *));
+#define tc_frob_label(sym) frv_frob_label(sym)
+
+#define tc_gen_reloc gas_cgen_tc_gen_reloc
+
+#define md_cgen_record_fixup_exp frv_cgen_record_fixup_exp
+
+/* Call md_pcrel_from_section(), not md_pcrel_from(). */
+#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section (FIXP, SEC)
+extern long md_pcrel_from_section PARAMS ((struct fix *, segT));
+
+/* After all of the symbols have been adjusted, go over the file looking
+ for any relocations that pic won't support. */
+#define tc_frob_file() frv_frob_file ()
+extern void frv_frob_file PARAMS ((void));
Index: gas/po/POTFILES.in
===================================================================
RCS file: /cvs/src/src/gas/po/POTFILES.in,v
retrieving revision 1.16
diff -c -p -d -u -p -r1.16 POTFILES.in
--- gas/po/POTFILES.in 31 May 2002 04:25:51 -0000 1.16
+++ gas/po/POTFILES.in 10 Jun 2002 22:02:41 -0000
@@ -60,6 +60,8 @@ config/tc-dlx.c
config/tc-dlx.h
config/tc-fr30.c
config/tc-fr30.h
+config/tc-frv.c
+config/tc-frv.h
config/tc-h8300.c
config/tc-h8300.h
config/tc-h8500.c
Index: include/dis-asm.h
===================================================================
RCS file: /cvs/src/src/include/dis-asm.h,v
retrieving revision 1.34
diff -c -p -d -u -p -r1.34 dis-asm.h
--- include/dis-asm.h 28 May 2002 14:08:14 -0000 1.34
+++ include/dis-asm.h 10 Jun 2002 22:02:43 -0000
@@ -236,6 +236,7 @@ extern int print_insn_w65 PARAMS ((bfd_
extern int print_insn_xstormy16 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_sh64 PARAMS ((bfd_vma, disassemble_info *));
extern int print_insn_sh64x_media PARAMS ((bfd_vma, disassemble_info *));
+extern int print_insn_frv PARAMS ((bfd_vma, disassemble_info *));
extern disassembler_ftype arc_get_disassembler PARAMS ((void *));
extern disassembler_ftype cris_get_disassembler PARAMS ((bfd *));
Index: include/elf/common.h
===================================================================
RCS file: /cvs/src/src/include/elf/common.h,v
retrieving revision 1.45
diff -c -p -d -u -p -r1.45 common.h
--- include/elf/common.h 6 Jun 2002 09:59:38 -0000 1.45
+++ include/elf/common.h 10 Jun 2002 22:02:43 -0000
@@ -244,6 +244,8 @@ Foundation, Inc., 59 Temple Place - Suit
#define EM_XSTORMY16 0xad45
+/* FRV magic number - no EABI available??. */
+#define EM_CYGNUS_FRV 0x5441
/* See the above comment before you add a new EM_* value here. */
/* Values for e_version. */
Index: include/elf/frv.h
===================================================================
RCS file: include/elf/frv.h
diff -N include/elf/frv.h
--- include/elf/frv.h 1 Jan 1970 00:00:00 -0000
+++ include/elf/frv.h 10 Jun 2002 22:02:43 -0000
@@ -0,0 +1,95 @@
+/* FRV ELF support for BFD.
+ Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _ELF_FRV_H
+#define _ELF_FRV_H
+
+#include "elf/reloc-macros.h"
+
+/* Relocations. */
+START_RELOC_NUMBERS (elf_frv_reloc_type)
+ RELOC_NUMBER (R_FRV_NONE, 0)
+ RELOC_NUMBER (R_FRV_32, 1)
+ RELOC_NUMBER (R_FRV_LABEL16, 2)
+ RELOC_NUMBER (R_FRV_LABEL24, 3)
+ RELOC_NUMBER (R_FRV_LO16, 4)
+ RELOC_NUMBER (R_FRV_HI16, 5)
+ RELOC_NUMBER (R_FRV_GPREL12, 6)
+ RELOC_NUMBER (R_FRV_GPRELU12, 7)
+ RELOC_NUMBER (R_FRV_GPREL32, 8)
+ RELOC_NUMBER (R_FRV_GPRELHI, 9)
+ RELOC_NUMBER (R_FRV_GPRELLO, 10)
+ RELOC_NUMBER (R_FRV_GNU_VTINHERIT, 200)
+ RELOC_NUMBER (R_FRV_GNU_VTENTRY, 201)
+END_RELOC_NUMBERS(R_FRV_max)
+
+/* Processor specific flags for the ELF header e_flags field. */
+ /* gpr support */
+#define EF_FRV_GPR_MASK 0x00000003 /* mask for # of gprs */
+#define EF_FRV_GPR_32 0x00000001 /* -mgpr-32 */
+#define EF_FRV_GPR_64 0x00000002 /* -mgpr-64 */
+
+ /* fpr support */
+#define EF_FRV_FPR_MASK 0x0000000c /* mask for # of fprs */
+#define EF_FRV_FPR_32 0x00000004 /* -mfpr-32 */
+#define EF_FRV_FPR_64 0x00000008 /* -mfpr-64 */
+#define EF_FRV_FPR_NONE 0x0000000c /* -msoft-float */
+
+ /* double word support */
+#define EF_FRV_DWORD_MASK 0x00000030 /* mask for dword support */
+#define EF_FRV_DWORD_YES 0x00000010 /* use double word insns */
+#define EF_FRV_DWORD_NO 0x00000020 /* don't use double word insn*/
+
+#define EF_FRV_DOUBLE 0x00000040 /* -mdouble */
+#define EF_FRV_MEDIA 0x00000080 /* -mmedia */
+
+#define EF_FRV_PIC 0x00000100 /* -fpic */
+#define EF_FRV_NON_PIC_RELOCS 0x00000200 /* used non pic safe relocs */
+
+#define EF_FRV_MULADD 0x00000400 /* -mmuladd */
+#define EF_FRV_BIGPIC 0x00000800 /* -fPIC */
+#define EF_FRV_LIBPIC 0x00001000 /* -mlibrary-pic */
+#define EF_FRV_G0 0x00002000 /* -G 0, no small data ptr */
+#define EF_FRV_NOPACK 0x00004000 /* -mnopack */
+
+#define EF_FRV_CPU_MASK 0xff000000 /* specific cpu bits */
+#define EF_FRV_CPU_GENERIC 0x00000000 /* generic FRV */
+#define EF_FRV_CPU_FR500 0x01000000 /* FRV500 */
+#define EF_FRV_CPU_FR300 0x02000000 /* FRV300 */
+#define EF_FRV_CPU_SIMPLE 0x03000000 /* SIMPLE */
+#define EF_FRV_CPU_TOMCAT 0x04000000 /* Tomcat, FR500 prototype */
+#define EF_FRV_CPU_FR400 0x05000000 /* FRV400 */
+
+ /* Mask of PIC related bits */
+#define EF_FRV_PIC_FLAGS (EF_FRV_PIC | EF_FRV_LIBPIC | EF_FRV_BIGPIC)
+
+ /* Mask of all flags */
+#define EF_FRV_ALL_FLAGS (EF_FRV_GPR_MASK | \
+ EF_FRV_FPR_MASK | \
+ EF_FRV_DWORD_MASK | \
+ EF_FRV_DOUBLE | \
+ EF_FRV_MEDIA | \
+ EF_FRV_PIC_FLAGS | \
+ EF_FRV_NON_PIC_RELOCS | \
+ EF_FRV_MULADD | \
+ EF_FRV_G0 | \
+ EF_FRV_NOPACK | \
+ EF_FRV_CPU_MASK)
+
+#endif /* _ELF_FRV_H */
Index: ld/NEWS
===================================================================
RCS file: /cvs/src/src/ld/NEWS,v
retrieving revision 1.23
diff -c -p -d -u -p -r1.23 NEWS
--- ld/NEWS 30 May 2002 02:58:04 -0000 1.23
+++ ld/NEWS 11 Jun 2002 20:44:57 -0000
@@ -1,4 +1,7 @@
-*- text -*-
+Support for the Fujitsu FRV architecture added by Red Hat. Models for FR400 and
+FR500 included.
+
Changes in version 2.13:
* DEC VAX ELF support, by Matt Thomas.
Index: ld/Makefile.am
===================================================================
RCS file: /cvs/src/src/ld/Makefile.am,v
retrieving revision 1.101
diff -c -p -d -u -p -r1.101 Makefile.am
--- ld/Makefile.am 4 Jun 2002 02:57:42 -0000 1.101
+++ ld/Makefile.am 10 Jun 2002 22:02:43 -0000
@@ -159,6 +159,7 @@ ALL_EMULATIONS = \
eelf32ebmip.o \
eelf32elmip.o \
eelf32fr30.o \
+ eelf32frv.o \
eelf32i370.o \
eelf32l4300.o \
eelf32lmip.o \
@@ -526,6 +527,9 @@ eelf32vax.c: $(srcdir)/emulparams/elf32v
eelf32fr30.c: $(srcdir)/emulparams/elf32fr30.sh \
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32fr30 "$(tdir_fr30)"
+eelf32frv.c: $(srcdir)/emulparams/elf32frv.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf32frv "$(tdir_frv)"
eelf32mcore.c: $(srcdir)/emulparams/elf32mcore.sh \
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32mcore "$(tdir_mcore)"
Index: ld/configure.tgt
===================================================================
RCS file: /cvs/src/src/ld/configure.tgt,v
retrieving revision 1.95
diff -c -p -d -u -p -r1.95 configure.tgt
--- ld/configure.tgt 5 Jun 2002 19:54:28 -0000 1.95
+++ ld/configure.tgt 10 Jun 2002 22:02:43 -0000
@@ -481,6 +481,7 @@ tic80-*-*) targ_emul=tic80coff ;;
v850-*-*) targ_emul=v850 ;;
v850e-*-*) targ_emul=v850 ;;
v850ea-*-*) targ_emul=v850 ;;
+frv-*-*) targ_emul=elf32frv ;;
w65-*-*) targ_emul=w65 ;;
xstormy16-*-*) targ_emul=elf32xstormy16 ;;
fr30-*-*) targ_emul=elf32fr30 ;;
Index: ld/emulparams/elf32frv.sh
===================================================================
RCS file: ld/emulparams/elf32frv.sh
diff -N ld/emulparams/elf32frv.sh
--- ld/emulparams/elf32frv.sh 1 Jan 1970 00:00:00 -0000
+++ ld/emulparams/elf32frv.sh 10 Jun 2002 22:02:43 -0000
@@ -0,0 +1,20 @@
+MACHINE=
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-frv"
+TEXT_START_ADDR=0x10000
+ARCH=frv
+MAXPAGESIZE=256
+ENTRY=_start
+EMBEDDED=yes
+OTHER_EXCLUDE_FILES='*frvend.o'
+OTHER_BSS_END_SYMBOLS='__end = .;'
+DATA_START_SYMBOLS='__data_start = . ;'
+OTHER_RELOCATING_SECTIONS='
+ PROVIDE (_stack = 0x200000);
+ PROVIDE (__stack = 0x200000);'
+OTHER_GOT_SYMBOLS='
+ . = ALIGN(8); _gp = . + 2048;
+ PROVIDE (gp = _gp);'
+OTHER_READONLY_SECTIONS='
+ .rofixup : { *(.rofixup) }
+'
Index: opcodes/Makefile.am
===================================================================
RCS file: /cvs/src/src/opcodes/Makefile.am,v
retrieving revision 1.52
diff -c -p -d -u -p -r1.52 Makefile.am
--- opcodes/Makefile.am 31 May 2002 04:27:35 -0000 1.52
+++ opcodes/Makefile.am 10 Jun 2002 22:02:46 -0000
@@ -26,6 +26,7 @@ LIBIBERTY = ../libiberty/libiberty.a
HFILES = \
arm-opc.h \
fr30-desc.h fr30-opc.h \
+ frv-desc.h frv-opc.h \
h8500-opc.h \
ia64-asmtab.h \
ia64-opc.h \
@@ -66,6 +67,11 @@ CFILES = \
fr30-dis.c \
fr30-ibld.c \
fr30-opc.c \
+ frv-asm.c \
+ frv-desc.c \
+ frv-dis.c \
+ frv-ibld.c \
+ frv-opc.c \
h8300-dis.c \
h8500-dis.c \
hppa-dis.c \
@@ -168,6 +174,11 @@ ALL_MACHINES = \
fr30-dis.lo \
fr30-ibld.lo \
fr30-opc.lo \
+ frv-asm.lo \
+ frv-desc.lo \
+ frv-dis.lo \
+ frv-ibld.lo \
+ frv-opc.lo \
h8300-dis.lo \
h8500-dis.lo \
hppa-dis.lo \
@@ -301,7 +312,7 @@ uninstall_libopcodes:
rm -f $(DESTDIR)$(bfdincludedir)/dis-asm.h
CLEANFILES = \
- stamp-m32r stamp-fr30 stamp-openrisc \
+ stamp-m32r stamp-fr30 stamp-frv stamp-openrisc \
stamp-xstormy16 \
libopcodes.a stamp-lib dep.sed DEP DEPA DEP1 DEP2
@@ -321,11 +332,13 @@ CGENDEPS = ../cgen/stamp-cgen \
if CGEN_MAINT
M32R_DEPS = stamp-m32r
FR30_DEPS = stamp-fr30
+FRV_DEPS = stamp-frv
OPENRISC_DEPS = stamp-openrisc
XSTORMY16_DEPS = stamp-xstormy16
else
M32R_DEPS =
FR30_DEPS =
+FRV_DEPS =
OPENRISC_DEPS =
XSTORMY16_DEPS =
endif
@@ -348,6 +361,11 @@ $(srcdir)/fr30-desc.h $(srcdir)/fr30-des
stamp-fr30: $(CGENDEPS) $(CPUDIR)/fr30.cpu $(CPUDIR)/fr30.opc
$(MAKE) run-cgen arch=fr30 prefix=fr30 options= extrafiles=
+$(srcdir)/frv-desc.h $(srcdir)/frv-desc.c $(srcdir)/frv-opc.h $(srcdir)/frv-opc.c $(srcdir)/frv-ibld.c $(srcdir)/frv-asm.c $(srcdir)/frv-dis.c: $(FRV_DEPS)
+ @true
+stamp-frv: $(CGENDEPS) $(CPUDIR)/frv.cpu $(CPUDIR)/frv.opc
+ $(MAKE) run-cgen arch=frv prefix=frv options= extrafiles=
+
$(srcdir)/openrisc-desc.h $(srcdir)/openrisc-desc.c $(srcdir)/openrisc-opc.h $(srcdir)/openrisc-opc.c $(srcdir)/openrisc-ibld.c $(srcdir)/openrisc-asm.c $(srcdir)/openrisc-dis.c: $(OPENRISC_DEPS)
@true
stamp-openrisc: $(CGENDEPS) $(CPUDIR)/openrisc.cpu $(CPUDIR)/openrisc.opc
@@ -495,6 +513,23 @@ fr30-ibld.lo: fr30-ibld.c sysdep.h confi
fr30-opc.lo: fr30-opc.c sysdep.h config.h $(INCDIR)/ansidecl.h \
$(BFD_H) $(INCDIR)/symcat.h fr30-desc.h $(INCDIR)/opcode/cgen.h \
fr30-opc.h $(INCDIR)/libiberty.h
+frv-asm.lo: frv-asm.c sysdep.h config.h $(BFD_H) \
+ $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h frv-desc.h \
+ $(INCDIR)/opcode/cgen.h frv-opc.h opintl.h
+frv-desc.lo: frv-desc.c sysdep.h config.h $(BFD_H) \
+ $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h frv-desc.h \
+ $(INCDIR)/opcode/cgen.h frv-opc.h opintl.h
+frv-dis.lo: frv-dis.c sysdep.h config.h $(INCDIR)/dis-asm.h \
+ $(BFD_H) $(INCDIR)/ansidecl.h \
+ $(INCDIR)/symcat.h frv-desc.h $(INCDIR)/opcode/cgen.h \
+ frv-opc.h opintl.h
+frv-ibld.lo: frv-ibld.c sysdep.h config.h $(INCDIR)/dis-asm.h \
+ $(BFD_H) $(INCDIR)/ansidecl.h \
+ $(INCDIR)/symcat.h frv-desc.h $(INCDIR)/opcode/cgen.h \
+ frv-opc.h opintl.h
+frv-opc.lo: frv-opc.c sysdep.h config.h $(BFD_H) \
+ $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h frv-desc.h \
+ $(INCDIR)/opcode/cgen.h frv-opc.h
h8300-dis.lo: h8300-dis.c sysdep.h config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/opcode/h8300.h $(INCDIR)/dis-asm.h $(BFD_H) \
$(INCDIR)/symcat.h opintl.h
Index: opcodes/configure.in
===================================================================
RCS file: /cvs/src/src/opcodes/configure.in,v
retrieving revision 1.38
diff -c -p -d -u -p -r1.38 configure.in
--- opcodes/configure.in 4 Jun 2002 02:57:44 -0000 1.38
+++ opcodes/configure.in 10 Jun 2002 22:02:46 -0000
@@ -238,6 +238,7 @@ if test x${all_targets} = xfalse ; then
bfd_we32k_arch) ;;
bfd_xstormy16_arch) ta="$ta xstormy16-asm.lo xstormy16-desc.lo xstormy16-dis.lo xstormy16-ibld.lo xstormy16-opc.lo" using_cgen=yes ;;
bfd_z8k_arch) ta="$ta z8k-dis.lo" ;;
+ bfd_frv_arch) ta="$ta frv-asm.lo frv-desc.lo frv-dis.lo frv-ibld.lo frv-opc.lo" using_cgen=yes ;;
"") ;;
*) AC_MSG_ERROR(*** unknown target architecture $arch) ;;
Index: opcodes/disassemble.c
===================================================================
RCS file: /cvs/src/src/opcodes/disassemble.c,v
retrieving revision 1.34
diff -c -p -d -u -p -r1.34 disassemble.c
--- opcodes/disassemble.c 28 May 2002 14:08:47 -0000 1.34
+++ opcodes/disassemble.c 10 Jun 2002 22:02:46 -0000
@@ -66,6 +66,7 @@ Foundation, Inc., 59 Temple Place - Suit
#define ARCH_w65
#define ARCH_xstormy16
#define ARCH_z8k
+#define ARCH_frv
#define INCLUDE_SHMEDIA
#endif
@@ -334,6 +335,11 @@ disassembler (abfd)
#ifdef ARCH_vax
case bfd_arch_vax:
disassemble = print_insn_vax;
+ break;
+#endif
+#ifdef ARCH_frv
+ case bfd_arch_frv:
+ disassemble = print_insn_frv;
break;
#endif
default:
Index: opcodes/po/POTFILES.in
===================================================================
RCS file: /cvs/src/src/opcodes/po/POTFILES.in,v
retrieving revision 1.20
diff -c -p -d -u -p -r1.20 POTFILES.in
--- opcodes/po/POTFILES.in 31 May 2002 04:27:37 -0000 1.20
+++ opcodes/po/POTFILES.in 10 Jun 2002 22:02:47 -0000
@@ -26,6 +26,13 @@ fr30-dis.c
fr30-ibld.c
fr30-opc.c
fr30-opc.h
+frv-asm.c
+frv-desc.c
+frv-desc.h
+frv-dis.c
+frv-ibld.c
+frv-opc.c
+frv-opc.h
h8300-dis.c
h8500-dis.c
h8500-opc.h
Attachment:
frv.binutils.gen.patch.tgz
Description: application/compressed
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |