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] |