diff options
-rw-r--r-- | bfd/ChangeLog | 14 | ||||
-rw-r--r-- | bfd/Makefile.am | 9 | ||||
-rw-r--r-- | bfd/Makefile.in | 11 | ||||
-rw-r--r-- | bfd/archures.c | 3 | ||||
-rw-r--r-- | bfd/bfd-in2.h | 10 | ||||
-rw-r--r-- | bfd/config.bfd | 7 | ||||
-rwxr-xr-x | bfd/configure | 29 | ||||
-rw-r--r-- | bfd/configure.in | 1 | ||||
-rw-r--r-- | bfd/cpu-dlx.c | 39 | ||||
-rw-r--r-- | bfd/doc/Makefile.in | 4 | ||||
-rw-r--r-- | bfd/elf32-dlx.c | 659 | ||||
-rw-r--r-- | bfd/libbfd.h | 3 | ||||
-rw-r--r-- | bfd/reloc.c | 13 | ||||
-rw-r--r-- | bfd/syms.c | 7 | ||||
-rw-r--r-- | bfd/targets.c | 2 | ||||
-rw-r--r-- | include/ChangeLog | 6 | ||||
-rw-r--r-- | include/dis-asm.h | 1 | ||||
-rw-r--r-- | include/elf/ChangeLog | 5 | ||||
-rw-r--r-- | include/elf/common.h | 4 | ||||
-rw-r--r-- | include/elf/dlx.h | 53 | ||||
-rw-r--r-- | include/opcode/ChangeLog | 4 | ||||
-rw-r--r-- | include/opcode/dlx.h | 282 | ||||
-rw-r--r-- | opcodes/ChangeLog | 9 | ||||
-rw-r--r-- | opcodes/Makefile.am | 5 | ||||
-rw-r--r-- | opcodes/Makefile.in | 7 | ||||
-rwxr-xr-x | opcodes/configure | 1 | ||||
-rw-r--r-- | opcodes/configure.in | 1 | ||||
-rw-r--r-- | opcodes/disassemble.c | 7 | ||||
-rw-r--r-- | opcodes/dlx-dis.c | 544 |
29 files changed, 1718 insertions, 22 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 6b7381b88f8..c4b7cc71b00 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,17 @@ +2002-05-28 Kuang Hwa Lin <kuang@sbcglobal.net> + + * config.bfd: Added DLX configuraton. + * Makefile.am: Added DLX configuraton. + * configure.in: Added DLX configuraton. + * archures.c: Add DLX architecure. + * reloc.c: Add DLX relocs. + * targets.c: Added DLX target vector. + * configure: Regenerate. + * Makefile.in: Regenreate. + * bfd-in2.h: Regenreate. + * elf32-dlx.c: New file: Support DLX target. + * cpu-dlx.c: New file: Support DLX target. + 2002-05-25 Alan Modra <amodra@bigpond.net.au> * elf32-m68k.c (elf32_m68k_print_private_bfd_data): Formatting. diff --git a/bfd/Makefile.am b/bfd/Makefile.am index 8cc206ff7cb..e8e0cc07ca6 100644 --- a/bfd/Makefile.am +++ b/bfd/Makefile.am @@ -56,6 +56,7 @@ ALL_MACHINES = \ cpu-cris.lo \ cpu-d10v.lo \ cpu-d30v.lo \ + cpu-dlx.lo \ cpu-fr30.lo \ cpu-h8300.lo \ cpu-h8500.lo \ @@ -104,6 +105,7 @@ ALL_MACHINES_CFILES = \ cpu-cris.c \ cpu-d10v.c \ cpu-d30v.c \ + cpu-dlx.c \ cpu-fr30.c \ cpu-h8300.c \ cpu-h8500.c \ @@ -198,6 +200,7 @@ BFD32_BACKENDS = \ elf32-cris.lo \ elf32-d10v.lo \ elf32-d30v.lo \ + elf32-dlx.lo \ elf32-fr30.lo \ elf32-gen.lo \ elf32-h8300.lo \ @@ -347,6 +350,7 @@ BFD32_BACKENDS_CFILES = \ elf32-cris.c \ elf32-d10v.c \ elf32-d30v.c \ + elf32-dlx.c \ elf32-fr30.c \ elf32-gen.c \ elf32-h8300.c \ @@ -867,6 +871,7 @@ cpu-avr.lo: cpu-avr.c $(INCDIR)/filenames.h cpu-cris.lo: cpu-cris.c $(INCDIR)/filenames.h cpu-d10v.lo: cpu-d10v.c $(INCDIR)/filenames.h cpu-d30v.lo: cpu-d30v.c $(INCDIR)/filenames.h +cpu-dlx.lo: cpu-d30v.c $(INCDIR)/filenames.h cpu-fr30.lo: cpu-fr30.c $(INCDIR)/filenames.h cpu-h8300.lo: cpu-h8300.c $(INCDIR)/filenames.h cpu-h8500.lo: cpu-h8500.c $(INCDIR)/filenames.h @@ -1083,6 +1088,10 @@ elf32-d30v.lo: elf32-d30v.c $(INCDIR)/filenames.h elf-bfd.h \ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \ $(INCDIR)/bfdlink.h $(INCDIR)/elf/d30v.h $(INCDIR)/elf/reloc-macros.h \ elf32-target.h +elf32-dlx.lo: elf32-dlx.c $(INCDIR)/filenames.h elf-bfd.h \ + $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/elf/dlx.h $(INCDIR)/elf/reloc-macros.h \ + elf32-target.h 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 \ diff --git a/bfd/Makefile.in b/bfd/Makefile.in index 224ca05dd8a..cffcb077472 100644 --- a/bfd/Makefile.in +++ b/bfd/Makefile.in @@ -182,6 +182,7 @@ ALL_MACHINES = \ cpu-cris.lo \ cpu-d10v.lo \ cpu-d30v.lo \ + cpu-dlx.lo \ cpu-fr30.lo \ cpu-h8300.lo \ cpu-h8500.lo \ @@ -231,6 +232,7 @@ ALL_MACHINES_CFILES = \ cpu-cris.c \ cpu-d10v.c \ cpu-d30v.c \ + cpu-dlx.c \ cpu-fr30.c \ cpu-h8300.c \ cpu-h8500.c \ @@ -326,6 +328,7 @@ BFD32_BACKENDS = \ elf32-cris.lo \ elf32-d10v.lo \ elf32-d30v.lo \ + elf32-dlx.lo \ elf32-fr30.lo \ elf32-gen.lo \ elf32-h8300.lo \ @@ -476,6 +479,7 @@ BFD32_BACKENDS_CFILES = \ elf32-cris.c \ elf32-d10v.c \ elf32-d30v.c \ + elf32-dlx.c \ elf32-fr30.c \ elf32-gen.c \ elf32-h8300.c \ @@ -756,7 +760,7 @@ configure.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) -TAR = tar +TAR = gtar GZIP_ENV = --best SOURCES = $(libbfd_a_SOURCES) $(libbfd_la_SOURCES) OBJECTS = $(libbfd_a_OBJECTS) $(libbfd_la_OBJECTS) @@ -1396,6 +1400,7 @@ cpu-avr.lo: cpu-avr.c $(INCDIR)/filenames.h cpu-cris.lo: cpu-cris.c $(INCDIR)/filenames.h cpu-d10v.lo: cpu-d10v.c $(INCDIR)/filenames.h cpu-d30v.lo: cpu-d30v.c $(INCDIR)/filenames.h +cpu-dlx.lo: cpu-d30v.c $(INCDIR)/filenames.h cpu-fr30.lo: cpu-fr30.c $(INCDIR)/filenames.h cpu-h8300.lo: cpu-h8300.c $(INCDIR)/filenames.h cpu-h8500.lo: cpu-h8500.c $(INCDIR)/filenames.h @@ -1612,6 +1617,10 @@ elf32-d30v.lo: elf32-d30v.c $(INCDIR)/filenames.h elf-bfd.h \ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \ $(INCDIR)/bfdlink.h $(INCDIR)/elf/d30v.h $(INCDIR)/elf/reloc-macros.h \ elf32-target.h +elf32-dlx.lo: elf32-dlx.c $(INCDIR)/filenames.h elf-bfd.h \ + $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/elf/dlx.h $(INCDIR)/elf/reloc-macros.h \ + elf32-target.h 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 \ diff --git a/bfd/archures.c b/bfd/archures.c index 40102e8b0f1..36fc56873d5 100644 --- a/bfd/archures.c +++ b/bfd/archures.c @@ -193,6 +193,7 @@ DESCRIPTION .#define bfd_mach_d10v_ts2 2 .#define bfd_mach_d10v_ts3 3 . bfd_arch_d30v, {* Mitsubishi D30V *} +. bfd_arch_dlx, {* DLX *} . bfd_arch_m68hc11, {* Motorola 68HC11 *} . bfd_arch_m68hc12, {* Motorola 68HC12 *} . bfd_arch_z8k, {* Zilog Z8000 *} @@ -312,6 +313,7 @@ extern const bfd_arch_info_type bfd_avr_arch; extern const bfd_arch_info_type bfd_cris_arch; extern const bfd_arch_info_type bfd_d10v_arch; 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_h8300_arch; extern const bfd_arch_info_type bfd_h8500_arch; @@ -365,6 +367,7 @@ static const bfd_arch_info_type * const bfd_archures_list[] = &bfd_cris_arch, &bfd_d10v_arch, &bfd_d30v_arch, + &bfd_dlx_arch, &bfd_fr30_arch, &bfd_h8300_arch, &bfd_h8500_arch, diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 8a0c45304fd..1dd397a7979 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -1573,6 +1573,7 @@ enum bfd_architecture #define bfd_mach_d10v_ts2 2 #define bfd_mach_d10v_ts3 3 bfd_arch_d30v, /* Mitsubishi D30V */ + bfd_arch_dlx, /* DLX */ bfd_arch_m68hc11, /* Motorola 68HC11 */ bfd_arch_m68hc12, /* Motorola 68HC12 */ bfd_arch_z8k, /* Zilog Z8000 */ @@ -2521,6 +2522,15 @@ of the container. */ /* This is a 32-bit pc-relative reloc. */ BFD_RELOC_D30V_32_PCREL, +/* DLX relocs */ + BFD_RELOC_DLX_HI16_S, + +/* DLX relocs */ + BFD_RELOC_DLX_LO16, + +/* DLX relocs */ + BFD_RELOC_DLX_JMP26, + /* Mitsubishi M32R relocs. This is a 24 bit absolute address. */ BFD_RELOC_M32R_24, diff --git a/bfd/config.bfd b/bfd/config.bfd index 1afdd85cda9..bba8d966762 100644 --- a/bfd/config.bfd +++ b/bfd/config.bfd @@ -35,6 +35,7 @@ alpha*) targ_archs=bfd_alpha_arch ;; arm*) targ_archs=bfd_arm_arch ;; c30*) targ_archs=bfd_tic30_arch ;; c54x*) targ_archs=bfd_tic54x_arch ;; +dlx*) targ_archs=bfd_dlx_arch ;; hppa*) targ_archs=bfd_hppa_arch ;; i[3456]86) targ_archs=bfd_i386_arch ;; i370) targ_archs=bfd_i370_arch ;; @@ -57,7 +58,6 @@ v850*) targ_archs=bfd_v850_arch ;; x86_64) targ_archs=bfd_i386_arch ;; xscale*) targ_archs=bfd_arm_arch ;; z8k*) targ_archs=bfd_z8k_arch ;; -sh*) targ_archs=bfd_sh_arch ;; *) targ_archs=bfd_${targ_cpu}_arch ;; esac @@ -267,6 +267,11 @@ case "${targ}" in targ_defvec=bfd_elf32_d10v_vec ;; + dlx-*-elf*) + targ_defvec=bfd_elf32_dlx_big_vec + targ_selvecs="bfd_elf32_dlx_big_vec" + ;; + d30v-*-*) targ_defvec=bfd_elf32_d30v_vec ;; diff --git a/bfd/configure b/bfd/configure index b5b977dd9b7..5345211921c 100755 --- a/bfd/configure +++ b/bfd/configure @@ -6065,6 +6065,7 @@ do bfd_elf32_cris_vec) tb="$tb elf32-cris.lo elf32.lo $elf" ;; bfd_elf32_d10v_vec) tb="$tb elf32-d10v.lo elf32.lo $elf" ;; bfd_elf32_d30v_vec) tb="$tb elf32-d30v.lo elf32.lo $elf" ;; + bfd_elf32_dlx_big_vec) tb="$tb elf32-dlx.lo elf32.lo $elf" ;; bfd_elf32_fr30_vec) tb="$tb elf32-fr30.lo elf32.lo $elf" ;; bfd_elf32_h8300_vec) tb="$tb elf32-h8300.lo elf32.lo $elf" ;; bfd_elf32_hppa_linux_vec) tb="$tb elf32-hppa.lo elf32.lo $elf" ;; @@ -6306,10 +6307,10 @@ case ${host64}-${target64}-${want64} in if test -n "$GCC" ; then bad_64bit_gcc=no; echo $ac_n "checking for gcc version with buggy 64-bit support""... $ac_c" 1>&6 -echo "configure:6310: checking for gcc version with buggy 64-bit support" >&5 +echo "configure:6311: checking for gcc version with buggy 64-bit support" >&5 # Add more tests for gcc versions with non-working 64-bit support here. cat > conftest.$ac_ext <<EOF -#line 6313 "configure" +#line 6314 "configure" #include "confdefs.h" :__GNUC__:__GNUC_MINOR__:__i386__: EOF @@ -6354,17 +6355,17 @@ for ac_hdr in stdlib.h unistd.h sys/stat.h sys/types.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:6358: checking for $ac_hdr" >&5 +echo "configure:6359: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 6363 "configure" +#line 6364 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:6368: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:6369: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -6393,12 +6394,12 @@ done for ac_func in getpagesize do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6397: checking for $ac_func" >&5 +echo "configure:6398: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 6402 "configure" +#line 6403 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -6421,7 +6422,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:6425: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6426: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6446,7 +6447,7 @@ fi done echo $ac_n "checking for working mmap""... $ac_c" 1>&6 -echo "configure:6450: checking for working mmap" >&5 +echo "configure:6451: checking for working mmap" >&5 if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -6454,7 +6455,7 @@ else ac_cv_func_mmap_fixed_mapped=no else cat > conftest.$ac_ext <<EOF -#line 6458 "configure" +#line 6459 "configure" #include "confdefs.h" /* Thanks to Mike Haertel and Jim Avera for this test. @@ -6607,7 +6608,7 @@ main() } EOF -if { (eval echo configure:6611: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:6612: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_mmap_fixed_mapped=yes else @@ -6632,12 +6633,12 @@ fi for ac_func in madvise mprotect do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6636: checking for $ac_func" >&5 +echo "configure:6637: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 6641 "configure" +#line 6642 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -6660,7 +6661,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:6664: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6665: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else diff --git a/bfd/configure.in b/bfd/configure.in index aca7baca611..340da095340 100644 --- a/bfd/configure.in +++ b/bfd/configure.in @@ -566,6 +566,7 @@ do bfd_elf32_cris_vec) tb="$tb elf32-cris.lo elf32.lo $elf" ;; bfd_elf32_d10v_vec) tb="$tb elf32-d10v.lo elf32.lo $elf" ;; bfd_elf32_d30v_vec) tb="$tb elf32-d30v.lo elf32.lo $elf" ;; + bfd_elf32_dlx_big_vec) tb="$tb elf32-dlx.lo elf32.lo $elf" ;; bfd_elf32_fr30_vec) tb="$tb elf32-fr30.lo elf32.lo $elf" ;; bfd_elf32_h8300_vec) tb="$tb elf32-h8300.lo elf32.lo $elf" ;; bfd_elf32_hppa_linux_vec) tb="$tb elf32-hppa.lo elf32.lo $elf" ;; diff --git a/bfd/cpu-dlx.c b/bfd/cpu-dlx.c new file mode 100644 index 00000000000..2023ff53121 --- /dev/null +++ b/bfd/cpu-dlx.c @@ -0,0 +1,39 @@ +/* BFD support for the DLX Microprocessor architecture. + Copyright 2002 Free Software Foundation, Inc. + Hacked by Kuang Hwa Lin <kuang@sbcglobal.net> + + 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" + +const bfd_arch_info_type bfd_dlx_arch = + { + 32, /* 32 bits in a word. */ + 32, /* 32 bits in an address. */ + 8, /* 8 bits in a byte. */ + bfd_arch_dlx, + 0, /* Only 1 machine. */ + "dlx", + "dlx", + 4, + true, /* The one and only. */ + bfd_default_compatible, + bfd_default_scan , + 0, +}; diff --git a/bfd/doc/Makefile.in b/bfd/doc/Makefile.in index 0036c0be529..0e46ceb934d 100644 --- a/bfd/doc/Makefile.in +++ b/bfd/doc/Makefile.in @@ -121,6 +121,8 @@ bfd_machines = @bfd_machines@ bfd_version = @bfd_version@ bfd_version_date = @bfd_version_date@ bfd_version_string = @bfd_version_string@ +bfdincludedir = @bfdincludedir@ +bfdlibdir = @bfdlibdir@ l = @l@ tdefaults = @tdefaults@ wordsize = @wordsize@ @@ -242,7 +244,7 @@ DIST_COMMON = ChangeLog Makefile.am Makefile.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) -TAR = tar +TAR = gtar GZIP_ENV = --best all: all-redirect .SUFFIXES: diff --git a/bfd/elf32-dlx.c b/bfd/elf32-dlx.c new file mode 100644 index 00000000000..d7d419c962d --- /dev/null +++ b/bfd/elf32-dlx.c @@ -0,0 +1,659 @@ +/* DLX specific support for 32-bit ELF + Copyright 2002 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/dlx.h" + +int set_dlx_skip_hi16_flag PARAMS ((int)); + +static boolean elf32_dlx_check_relocs + PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *)); +static void elf32_dlx_info_to_howto + PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *)); +static void elf32_dlx_info_to_howto_rel + PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *)); +static bfd_reloc_status_type elf32_dlx_relocate16 + PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); +static bfd_reloc_status_type elf32_dlx_relocate26 + PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); +static reloc_howto_type *elf32_dlx_reloc_type_lookup + PARAMS ((bfd *, bfd_reloc_code_real_type)); +static bfd_reloc_status_type _bfd_dlx_elf_hi16_reloc + PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); +static reloc_howto_type * dlx_rtype_to_howto + PARAMS ((unsigned int)); + + +#define USE_REL 1 + +#define bfd_elf32_bfd_reloc_type_lookup elf32_dlx_reloc_type_lookup +#define elf_info_to_howto elf32_dlx_info_to_howto +#define elf_info_to_howto_rel elf32_dlx_info_to_howto_rel +#define elf_backend_check_relocs elf32_dlx_check_relocs + +static reloc_howto_type dlx_elf_howto_table[]= + { + /* No relocation. */ + HOWTO (R_DLX_NONE, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont,/* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_DLX_NONE", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* 8 bit relocation. */ + HOWTO (R_DLX_RELOC_8, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 8, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont,/* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_DLX_RELOC_8", /* name */ + true, /* partial_inplace */ + 0xff, /* src_mask */ + 0xff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 16 bit relocation. */ + HOWTO (R_DLX_RELOC_16, /* type */ + 0, /* rightshift */ + 1, /* 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_DLX_RELOC_16", /* name */ + true, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + +#if 0 + /* 26 bit jump address. */ + HOWTO (R_DLX_RELOC_26, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 26, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont,/* complain_on_overflow */ + /* This needs complex overflow detection, because the upper four + bits must match the PC + 4. */ + bfd_elf_generic_reloc, /* special_function */ + "R_DLX_RELOC_26", /* name */ + true, /* partial_inplace */ + 0x3ffffff, /* src_mask */ + 0x3ffffff, /* dst_mask */ + false), /* pcrel_offset */ +#endif + + /* 32 bit relocation. */ + HOWTO (R_DLX_RELOC_32, /* 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_DLX_RELOC_32", /* name */ + true, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* GNU extension to record C++ vtable hierarchy */ + HOWTO (R_DLX_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_DLX_GNU_VTINHERIT", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* GNU extension to record C++ vtable member usage */ + HOWTO (R_DLX_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_DLX_GNU_VTENTRY", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false) /* pcrel_offset */ + }; + +/* 16 bit offset for pc-relative branches. */ +static reloc_howto_type elf_dlx_gnu_rel16_s2 = +HOWTO (R_DLX_RELOC_16_PCREL, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + elf32_dlx_relocate16, /* special_function */ + "R_DLX_RELOC_16_PCREL",/* name */ + true, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + true); /* pcrel_offset */ + +/* 26 bit offset for pc-relative branches. */ +static reloc_howto_type elf_dlx_gnu_rel26_s2 = +HOWTO (R_DLX_RELOC_26_PCREL, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 26, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont,/* complain_on_overflow */ + elf32_dlx_relocate26, /* special_function */ + "R_DLX_RELOC_26_PCREL",/* name */ + true, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + true); /* pcrel_offset */ + +/* High 16 bits of symbol value. */ +static reloc_howto_type elf_dlx_reloc_16_hi = +HOWTO (R_DLX_RELOC_16_HI, /* type */ + 16, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_dlx_elf_hi16_reloc,/* special_function */ + "R_DLX_RELOC_16_HI", /* name */ + true, /* partial_inplace */ + 0xFFFF, /* src_mask */ + 0xffff, /* dst_mask */ + false); /* pcrel_offset */ + + /* Low 16 bits of symbol value. */ +static reloc_howto_type elf_dlx_reloc_16_lo = +HOWTO (R_DLX_RELOC_16_LO, /* type */ + 0, /* rightshift */ + 1, /* 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_DLX_RELOC_16_LO", /* name */ + true, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false); /* pcrel_offset */ + + +/* The gas default beheaver is not to preform the %hi modifier so that the + GNU assembler can have the lower 16 bits offset placed in the insn, BUT + we do like the gas to indicate it is %hi reloc type so when we in the link + loader phase we can have the corrected hi16 vale replace the buggous lo16 + value that was placed there by gas. */ + +static int skip_dlx_elf_hi16_reloc = 0; + +int +set_dlx_skip_hi16_flag (flag) + int flag; +{ + skip_dlx_elf_hi16_reloc = flag; + return flag; +} + +static bfd_reloc_status_type +_bfd_dlx_elf_hi16_reloc (abfd, reloc_entry, symbol, data, + input_section, output_bfd, error_message) + bfd *abfd; + arelent *reloc_entry; + asymbol *symbol; + PTR data; + asection *input_section; + bfd *output_bfd; + char **error_message; +{ + bfd_reloc_status_type ret; + bfd_vma relocation; + + /* If the skip flag is set then we simply do the generic relocating, this + is more of a hack for dlx gas/gld, so we do not need to do the %hi/%lo + fixup like mips gld did. */ +#if 0 + printf ("DEBUG: skip_dlx_elf_hi16_reloc = 0x%08x\n", skip_dlx_elf_hi16_reloc); +#endif + if (skip_dlx_elf_hi16_reloc) + return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, + input_section, output_bfd, error_message); + + /* If we're relocating, and this an external symbol, we don't want + to change anything. */ + if (output_bfd != (bfd *) NULL + && (symbol->flags & BSF_SECTION_SYM) == 0 + && reloc_entry->addend == 0) + { + reloc_entry->address += input_section->output_offset; + return bfd_reloc_ok; + } + + ret = bfd_reloc_ok; + + if (bfd_is_und_section (symbol->section) + && output_bfd == (bfd *) NULL) + ret = bfd_reloc_undefined; + +#if 0 + { + unsigned long vallo, val; + + vallo = bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address); + printf ("DEBUG: The relocation address = 0x%08x\n", reloc_entry->address); + printf ("DEBUG: The symbol = 0x%08x\n", vallo); + printf ("DEBUG: The symbol name = %s\n", bfd_asymbol_name (symbol)); + printf ("DEBUG: The symbol->value = 0x%08x\n", symbol->value); + printf ("DEBUG: The vma = 0x%08x\n", symbol->section->output_section->vma); + printf ("DEBUG: The output_offset = 0x%08x\n", symbol->section->output_offset); + printf ("DEBUG: The input_offset = 0x%08x\n", input_section->output_offset); + printf ("DEBUG: The input_vma = 0x%08x\n", input_section->vma); + printf ("DEBUG: The addend = 0x%08x\n", reloc_entry->addend); + } +#endif + + relocation = (bfd_is_com_section (symbol->section)) ? 0 : symbol->value; + relocation += symbol->section->output_section->vma; + relocation += symbol->section->output_offset; + relocation += reloc_entry->addend; + relocation += bfd_get_16 (abfd, (bfd_byte *)data + reloc_entry->address); + + if (reloc_entry->address > input_section->_cooked_size) + return bfd_reloc_outofrange; + +#if 0 + printf ("DEBUG: The finial relocation value = 0x%08x\n", relocation); +#endif + + bfd_put_16 (abfd, (short)((relocation >> 16) & 0xFFFF), + (bfd_byte *)data + reloc_entry->address); + + return ret; +} + +/* ELF relocs are against symbols. If we are producing relocateable + output, and the reloc is against an external symbol, and nothing + has given us any additional addend, the resulting reloc will also + be against the same symbol. In such a case, we don't want to + change anything about the way the reloc is handled, since it will + all be done at final link time. Rather than put special case code + into bfd_perform_relocation, all the reloc types use this howto + function. It just short circuits the reloc if producing + relocateable output against an external symbol. */ + +static bfd_reloc_status_type +elf32_dlx_relocate16 (abfd, reloc_entry, symbol, data, + input_section, output_bfd, error_message) + bfd *abfd; + arelent *reloc_entry; + asymbol *symbol; + PTR data; + asection *input_section; + bfd *output_bfd; + char **error_message ATTRIBUTE_UNUSED; +{ + unsigned long insn, vallo, allignment; + int val; + + /* HACK: I think this first condition is necessary when producing + relocatable output. After the end of HACK, the code is identical + to bfd_elf_generic_reloc(). I would _guess_ the first change + belongs there rather than here. martindo 1998-10-23. */ + + if (skip_dlx_elf_hi16_reloc) + return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, + input_section, output_bfd, error_message); + + /* Check undefined section and undefined symbols */ + if (bfd_is_und_section (symbol->section) + && output_bfd == (bfd *) NULL) + return bfd_reloc_undefined; + + /* Can not support a long jump to sections other then .text */ + if (strcmp (input_section->name, symbol->section->output_section->name) != 0) + { + fprintf (stderr, + "BFD Link Error: branch (PC rel16) to section (%s) not supported\n", + symbol->section->output_section->name); + return bfd_reloc_undefined; + } + + insn = bfd_get_32 (abfd, (bfd_byte *)data + reloc_entry->address); + allignment = 1 << (input_section->output_section->alignment_power - 1); + vallo = insn & 0x0000FFFF; + + if (vallo & 0x8000) + vallo = ~(vallo | 0xFFFF0000) + 1; + + /* vallo points to the vma of next instruction. */ + vallo += (((unsigned long)(input_section->output_section->vma + + input_section->output_offset) + + allignment) & ~allignment); + + /* val is the displacement (PC relative to next instruction). */ + val = (symbol->section->output_offset + + symbol->section->output_section->vma + + symbol->value) - vallo; +#if 0 + printf ("DEBUG elf32_dlx_relocate: We are here\n"); + printf ("DEBUG: The insn = 0x%08x\n", insn); + printf ("DEBUG: The vallo = 0x%08x\n", vallo); + printf ("DEBUG: The val = 0x%08x\n", val); + printf ("DEBUG: The symbol name = %s\n", bfd_asymbol_name (symbol)); + printf ("DEBUG: The symbol->value = 0x%08x\n", symbol->value); + printf ("DEBUG: The vma = 0x%08x\n", symbol->section->output_section->vma); + printf ("DEBUG: The lma = 0x%08x\n", symbol->section->output_section->lma); + printf ("DEBUG: The alignment_power = 0x%08x\n", symbol->section->output_section->alignment_power); + printf ("DEBUG: The output_offset = 0x%08x\n", symbol->section->output_offset); + printf ("DEBUG: The addend = 0x%08x\n", reloc_entry->addend); +#endif + + if (abs ((int) val) > 0x00007FFF) + return bfd_reloc_outofrange; + + insn = (insn & 0xFFFF0000) | (val & 0x0000FFFF); + + bfd_put_32 (abfd, insn, + (bfd_byte *) data + reloc_entry->address); + + return bfd_reloc_ok; +} + +static bfd_reloc_status_type +elf32_dlx_relocate26 (abfd, reloc_entry, symbol, data, + input_section, output_bfd, error_message) + bfd *abfd; + arelent *reloc_entry; + asymbol *symbol; + PTR data; + asection *input_section; + bfd *output_bfd; + char **error_message ATTRIBUTE_UNUSED; +{ + unsigned long insn, vallo, allignment; + int val; + + /* HACK: I think this first condition is necessary when producing + relocatable output. After the end of HACK, the code is identical + to bfd_elf_generic_reloc(). I would _guess_ the first change + belongs there rather than here. martindo 1998-10-23. */ + + if (skip_dlx_elf_hi16_reloc) + return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, + input_section, output_bfd, error_message); + + /* Check undefined section and undefined symbols. */ + if (bfd_is_und_section (symbol->section) + && output_bfd == (bfd *) NULL) + return bfd_reloc_undefined; + + /* Can not support a long jump to sections other then .text */ + if (strcmp (input_section->name, symbol->section->output_section->name) != 0) + { + fprintf (stderr, + "BFD Link Error: jump (PC rel26) to section (%s) not supported\n", + symbol->section->output_section->name); + return bfd_reloc_undefined; + } + + insn = bfd_get_32 (abfd, (bfd_byte *)data + reloc_entry->address); + allignment = 1 << (input_section->output_section->alignment_power - 1); + vallo = insn & 0x03FFFFFF; + + if (vallo & 0x03000000) + vallo = ~(vallo | 0xFC000000) + 1; + + /* vallo is the vma for the next instruction. */ + vallo += (((unsigned long) (input_section->output_section->vma + + input_section->output_offset) + + allignment) & ~allignment); + + /* val is the displacement (PC relative to next instruction). */ + val = (symbol->section->output_offset + + symbol->section->output_section->vma + symbol->value) + - vallo; +#if 0 + printf ("DEBUG elf32_dlx_relocate26: We are here\n"); + printf ("DEBUG: The insn = 0x%08x\n", insn); + printf ("DEBUG: The vallo = 0x%08x\n", vallo); + printf ("DEBUG: The val = 0x%08x\n", val); + printf ("DEBUG: The abs(val) = 0x%08x\n", abs (val)); + printf ("DEBUG: The symbol name = %s\n", bfd_asymbol_name (symbol)); + printf ("DEBUG: The symbol->value = 0x%08x\n", symbol->value); + printf ("DEBUG: The vma = 0x%08x\n", symbol->section->output_section->vma); + printf ("DEBUG: The output_offset = 0x%08x\n", symbol->section->output_offset); + printf ("DEBUG: The input_vma = 0x%08x\n", input_section->output_section->vma); + printf ("DEBUG: The input_offset = 0x%08x\n", input_section->output_offset); + printf ("DEBUG: The input_name = %s\n", input_section->name); + printf ("DEBUG: The addend = 0x%08x\n", reloc_entry->addend); +#endif + + if (abs ((int) val) > 0x01FFFFFF) + return bfd_reloc_outofrange; + + insn = (insn & 0xFC000000) | (val & 0x03FFFFFF); + bfd_put_32 (abfd, insn, + (bfd_byte *) data + reloc_entry->address); + + return bfd_reloc_ok; +} + +/* A mapping from BFD reloc types to DLX ELF reloc types. + Stolen from elf32-mips.c. + + More about this table - for dlx elf relocation we do not really + need this table, if we have a rtype defined in this table will + caused tc_gen_relocate confused and die on us, but if we remove + this table it will caused more problem, so for now simple soulation + is to remove those entries which may cause problem. */ +struct elf_reloc_map +{ + bfd_reloc_code_real_type bfd_reloc_val; + enum elf_dlx_reloc_type elf_reloc_val; +}; + +static CONST struct elf_reloc_map dlx_reloc_map[] = + { + { BFD_RELOC_NONE, R_DLX_NONE }, + { BFD_RELOC_16, R_DLX_RELOC_16 }, +#if 0 + { BFD_RELOC_DLX_JMP26, R_DLX_RELOC_26_PCREL }, +#endif + { BFD_RELOC_32, R_DLX_RELOC_32 }, + { BFD_RELOC_DLX_HI16_S, R_DLX_RELOC_16_HI }, + { BFD_RELOC_DLX_LO16, R_DLX_RELOC_16_LO }, + { BFD_RELOC_VTABLE_INHERIT, R_DLX_GNU_VTINHERIT }, + { BFD_RELOC_VTABLE_ENTRY, R_DLX_GNU_VTENTRY } + }; + + +/* 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_dlx_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_DLX_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_DLX_GNU_VTENTRY: + if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + return false; + break; + } + } + + return true; +} + +/* Given a BFD reloc type, return a howto structure. */ + +static reloc_howto_type * +elf32_dlx_reloc_type_lookup (abfd, code) + bfd *abfd ATTRIBUTE_UNUSED; + bfd_reloc_code_real_type code; +{ + unsigned int i; + + for (i = 0; i < sizeof (dlx_reloc_map) / sizeof (struct elf_reloc_map); i++) + if (dlx_reloc_map[i].bfd_reloc_val == code) + return &dlx_elf_howto_table[(int) dlx_reloc_map[i].elf_reloc_val]; + + switch (code) + { + default: + bfd_set_error (bfd_error_bad_value); + return NULL; + case BFD_RELOC_16_PCREL_S2: + return &elf_dlx_gnu_rel16_s2; + case BFD_RELOC_DLX_JMP26: + return &elf_dlx_gnu_rel26_s2; + case BFD_RELOC_HI16_S: + return &elf_dlx_reloc_16_hi; + case BFD_RELOC_LO16: + return &elf_dlx_reloc_16_lo; + } +} + +static reloc_howto_type * +dlx_rtype_to_howto (r_type) + unsigned int r_type; +{ + switch (r_type) + { + case R_DLX_RELOC_16_PCREL: + return & elf_dlx_gnu_rel16_s2; + break; + case R_DLX_RELOC_26_PCREL: + return & elf_dlx_gnu_rel26_s2; + break; + case R_DLX_RELOC_16_HI: + return & elf_dlx_reloc_16_hi; + break; + case R_DLX_RELOC_16_LO: + return & elf_dlx_reloc_16_lo; + break; + + default: + BFD_ASSERT (r_type < (unsigned int) R_DLX_max); + return & dlx_elf_howto_table[r_type]; + break; + } +} + +static void +elf32_dlx_info_to_howto (abfd, cache_ptr, dst) + bfd * abfd ATTRIBUTE_UNUSED; + arelent * cache_ptr ATTRIBUTE_UNUSED; + Elf32_Internal_Rela * dst ATTRIBUTE_UNUSED; +{ + abort (); +} + +static void +elf32_dlx_info_to_howto_rel (abfd, cache_ptr, dst) + bfd *abfd ATTRIBUTE_UNUSED; + arelent *cache_ptr; + Elf32_Internal_Rel *dst; +{ + unsigned int r_type; + + r_type = ELF32_R_TYPE (dst->r_info); + cache_ptr->howto = dlx_rtype_to_howto (r_type); + return; +} + +#define TARGET_BIG_SYM bfd_elf32_dlx_big_vec +#define TARGET_BIG_NAME "elf32-dlx" +#define ELF_ARCH bfd_arch_dlx +#define ELF_MACHINE_CODE EM_DLX +#define ELF_MAXPAGESIZE 1 /* FIXME: This number is wrong, It should be the page size in bytes. */ + +#include "elf32-target.h" diff --git a/bfd/libbfd.h b/bfd/libbfd.h index c3c8126d490..cbb6390af1a 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -986,6 +986,9 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_D30V_21_PCREL_R", "BFD_RELOC_D30V_32", "BFD_RELOC_D30V_32_PCREL", + "BFD_RELOC_DLX_HI16_S", + "BFD_RELOC_DLX_LO16", + "BFD_RELOC_DLX_JMP26", "BFD_RELOC_M32R_24", "BFD_RELOC_M32R_10_PCREL", "BFD_RELOC_M32R_18_PCREL", diff --git a/bfd/reloc.c b/bfd/reloc.c index e60062e12d2..20df4f86fde 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -2616,6 +2616,19 @@ ENUMDOC This is a 32-bit pc-relative reloc. ENUM + BFD_RELOC_DLX_HI16_S +ENUMDOC + DLX relocs +ENUM + BFD_RELOC_DLX_LO16 +ENUMDOC + DLX relocs +ENUM + BFD_RELOC_DLX_JMP26 +ENUMDOC + DLX relocs + +ENUM BFD_RELOC_M32R_24 ENUMDOC Mitsubishi M32R relocs. diff --git a/bfd/syms.c b/bfd/syms.c index 2a889414774..1c4bf288a83 100644 --- a/bfd/syms.c +++ b/bfd/syms.c @@ -883,6 +883,7 @@ _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset, pfound, char *file_name; char *directory_name; int saw_fun; + boolean saw_line, saw_func; *pfound = false; *pfilename = bfd_get_filename (abfd); @@ -1239,13 +1240,13 @@ _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset, pfound, directory_name = indexentry->directory_name; str = indexentry->str; + saw_line = false; + saw_func = false; for (; stab < (indexentry+1)->stab; stab += STABSIZE) { - boolean done, saw_line, saw_func; + boolean done; bfd_vma val; - saw_line = false; - saw_func = false; done = false; switch (stab[TYPEOFF]) diff --git a/bfd/targets.c b/bfd/targets.c index c53afdd29bf..fe778caead8 100644 --- a/bfd/targets.c +++ b/bfd/targets.c @@ -507,6 +507,7 @@ extern const bfd_target bfd_elf32_bigmips_vec; extern const bfd_target bfd_elf32_cris_vec; extern const bfd_target bfd_elf32_d10v_vec; 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_h8300_vec; extern const bfd_target bfd_elf32_hppa_linux_vec; @@ -757,6 +758,7 @@ static const bfd_target * const _bfd_target_vector[] = { &bfd_elf32_cris_vec, &bfd_elf32_d10v_vec, &bfd_elf32_d30v_vec, + &bfd_elf32_dlx_big_vec, &bfd_elf32_fr30_vec, &bfd_elf32_h8300_vec, &bfd_elf32_hppa_linux_vec, diff --git a/include/ChangeLog b/include/ChangeLog index e6ff3f17656..d64d48cae28 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,7 @@ +2002-05-28 Kuang Hwa Lin <kuang@sbcglobal.net> + + * dis-asm.h: Prototype print_insn_dlx. + 2002-05-23 Andrew Cagney <ac131313@redhat.com> * sim-d10v.h: Delete file. Moved to include/gdb/. @@ -12,7 +16,7 @@ * bfdlink.h (bfd_link_info): Add allow_multiple_definition. -Fri May 17 14:25:40 2002 J"orn Rennecke <joern.rennecke@superh.com> +2002-05-17 J"orn Rennecke <joern.rennecke@superh.com> * dis-asm.h (print_insn_shl, print_insn_sh64l): Remove prototype. diff --git a/include/dis-asm.h b/include/dis-asm.h index 1fc570f96ca..8d38f7e8d2b 100644 --- a/include/dis-asm.h +++ b/include/dis-asm.h @@ -205,6 +205,7 @@ extern int print_insn_little_a29k PARAMS ((bfd_vma, disassemble_info*)); extern int print_insn_avr PARAMS ((bfd_vma, disassemble_info*)); extern int print_insn_d10v PARAMS ((bfd_vma, disassemble_info*)); extern int print_insn_d30v PARAMS ((bfd_vma, disassemble_info*)); +extern int print_insn_dlx PARAMS ((bfd_vma, disassemble_info*)); extern int print_insn_fr30 PARAMS ((bfd_vma, disassemble_info*)); extern int print_insn_hppa PARAMS ((bfd_vma, disassemble_info*)); extern int print_insn_i860 PARAMS ((bfd_vma, disassemble_info*)); diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog index fe3823b1b67..1deec0daa90 100644 --- a/include/elf/ChangeLog +++ b/include/elf/ChangeLog @@ -1,3 +1,8 @@ +2002-05-28 Kuang Hwa Lin <kuang@sbcglobal.net> + + * common.h (EM_DLX): Define. + * dlx.h: New file. + 2002-05-08 Jason Thorpe <thorpej@wasabisystems.com> * common.h (NT_GNU_ABI_TAG): Define. diff --git a/include/elf/common.h b/include/elf/common.h index f14f7bb679c..48e2f4ae5e8 100644 --- a/include/elf/common.h +++ b/include/elf/common.h @@ -236,6 +236,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ Written in the absense of an ABI. */ #define EM_OPENRISC_OLD 0x3426 +/* DLX magic number + Written in the absense of an ABI. */ +#define EM_DLX 0x5aa5 + #define EM_XSTORMY16 0xad45 /* See the above comment before you add a new EM_* value here. */ diff --git a/include/elf/dlx.h b/include/elf/dlx.h new file mode 100644 index 00000000000..562f600f35d --- /dev/null +++ b/include/elf/dlx.h @@ -0,0 +1,53 @@ +/* DLX support for BFD. + Copyright 2002 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_DLX_H +#define _ELF_DLX_H + +#include "elf/reloc-macros.h" + +#if 0 +START_RELOC_NUMBERS (elf_dlx_reloc_type) + RELOC_NUMBER (R_DLX_NONE, 0) + RELOC_NUMBER (R_DLX_RELOC_16, 1) + RELOC_NUMBER (R_DLX_RELOC_26, 2) + RELOC_NUMBER (R_DLX_RELOC_32, 3) + RELOC_NUMBER (R_DLX_GNU_VTINHERIT, 4) + RELOC_NUMBER (R_DLX_GNU_VTENTRY, 5) + RELOC_NUMBER (R_DLX_RELOC_16_HI, 6) + RELOC_NUMBER (R_DLX_RELOC_16_LO, 7) + RELOC_NUMBER (R_DLX_RELOC_16_PCREL, 8) + RELOC_NUMBER (R_DLX_RELOC_26_PCREL, 9) +END_RELOC_NUMBERS (R_DLX_max) +#else +START_RELOC_NUMBERS (elf_dlx_reloc_type) + RELOC_NUMBER (R_DLX_NONE, 0) + RELOC_NUMBER (R_DLX_RELOC_8, 1) + RELOC_NUMBER (R_DLX_RELOC_16, 2) + RELOC_NUMBER (R_DLX_RELOC_32, 3) + RELOC_NUMBER (R_DLX_GNU_VTINHERIT, 4) + RELOC_NUMBER (R_DLX_GNU_VTENTRY, 5) + RELOC_NUMBER (R_DLX_RELOC_16_HI, 6) + RELOC_NUMBER (R_DLX_RELOC_16_LO, 7) + RELOC_NUMBER (R_DLX_RELOC_16_PCREL, 8) + RELOC_NUMBER (R_DLX_RELOC_26_PCREL, 9) +END_RELOC_NUMBERS (R_DLX_max) +#endif /* 0 */ + +#endif /* _ELF_DLX_H */ diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog index 7e5799c6bb5..100c886a7aa 100644 --- a/include/opcode/ChangeLog +++ b/include/opcode/ChangeLog @@ -1,3 +1,7 @@ +2002-05-28 Kuang Hwa Lin <kuang@sbcglobal.net> + + * dlx.h: New file. + 2002-05-25 Alan Modra <amodra@bigpond.net.au> * ia64.h: Use #include "" instead of <> for local header files. diff --git a/include/opcode/dlx.h b/include/opcode/dlx.h new file mode 100644 index 00000000000..23e3b00bccc --- /dev/null +++ b/include/opcode/dlx.h @@ -0,0 +1,282 @@ +/* Table of opcodes for the DLX microprocess. + Copyright 2002 Free Software Foundation, Inc. + + This file is part of GDB and GAS. + + 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. + + Initially created by Kuang Hwa Lin, 2002. */ + +/* Following are the function codes for the Special OP (ALU). */ +#define ALUOP 0x00000000 +#define SPECIALOP 0x00000000 + +#define NOPF 0x00000000 +#define SLLF 0x00000004 +#define SRLF 0x00000006 +#define SRAF 0x00000007 + +#define SEQUF 0x00000010 +#define SNEUF 0x00000011 +#define SLTUF 0x00000012 +#define SGTUF 0x00000013 +#define SLEUF 0x00000014 +#define SGEUF 0x00000015 + +#define ADDF 0x00000020 +#define ADDUF 0x00000021 +#define SUBF 0x00000022 +#define SUBUF 0x00000023 +#define ANDF 0x00000024 +#define ORF 0x00000025 +#define XORF 0x00000026 + +#define SEQF 0x00000028 +#define SNEF 0x00000029 +#define SLTF 0x0000002A +#define SGTF 0x0000002B +#define SLEF 0x0000002C +#define SGEF 0x0000002D + /* Following special functions was not mentioned in the + Hennessy's book but was implemented in the RTL. */ +#define MVTSF 0x00000030 +#define MVFSF 0x00000031 +#define BSWAPF 0x00000032 +#define LUTF 0x00000033 +/* Following special functions was mentioned in the + Hennessy's book but was not implemented in the RTL. */ +#define MULTF 0x00000005 +#define MULTUF 0x00000006 +#define DIVF 0x00000007 +#define DIVUF 0x00000008 + + +/* Following are the rest of the OPcodes: + JOP = (0x002 << 26), JALOP = (0x003 << 26), BEQOP = (0x004 << 26), BNEOP = (0x005 << 26) + ADDIOP = (0x008 << 26), ADDUIOP= (0x009 << 26), SUBIOP = (0x00A << 26), SUBUIOP= (0x00B << 26) + ANDIOP = (0x00C << 26), ORIOP = (0x00D << 26), XORIOP = (0x00E << 26), LHIOP = (0x00F << 26) + RFEOP = (0x010 << 26), TRAPOP = (0x011 << 26), JROP = (0x012 << 26), JALROP = (0x013 << 26) + BREAKOP= (0x014 << 26) + SEQIOP = (0x018 << 26), SNEIOP = (0x019 << 26), SLTIOP = (0x01A << 26), SGTIOP = (0x01B << 26) + SLEIOP = (0x01C << 26), SGEIOP = (0x01D << 26) + LBOP = (0x020 << 26), LHOP = (0x021 << 26), LWOP = (0x023 << 26), LBUOP = (0x024 << 26) + LHUOP = (0x025 << 26), SBOP = (0x028 << 26), SHOP = (0x029 << 26), SWOP = (0x02B << 26) + LSBUOP = (0x026 << 26), LSHU = (0x027 << 26), LSW = (0x02C << 26), + SEQUIOP= (0x030 << 26), SNEUIOP= (0x031 << 26), SLTUIOP= (0x032 << 26), SGTUIOP= (0x033 << 26) + SLEUIOP= (0x034 << 26), SGEUIOP= (0x035 << 26) + SLLIOP = (0x036 << 26), SRLIOP = (0x037 << 26), SRAIOP = (0x038 << 26). */ +#define JOP 0x08000000 +#define JALOP 0x0c000000 +#define BEQOP 0x10000000 +#define BNEOP 0x14000000 + +#define ADDIOP 0x20000000 +#define ADDUIOP 0x24000000 +#define SUBIOP 0x28000000 +#define SUBUIOP 0x2c000000 +#define ANDIOP 0x30000000 +#define ORIOP 0x34000000 +#define XORIOP 0x38000000 +#define LHIOP 0x3c000000 +#define RFEOP 0x40000000 +#define TRAPOP 0x44000000 +#define JROP 0x48000000 +#define JALROP 0x4c000000 +#define BREAKOP 0x50000000 + +#define SEQIOP 0x60000000 +#define SNEIOP 0x64000000 +#define SLTIOP 0x68000000 +#define SGTIOP 0x6c000000 +#define SLEIOP 0x70000000 +#define SGEIOP 0x74000000 + +#define LBOP 0x80000000 +#define LHOP 0x84000000 +#define LWOP 0x8c000000 +#define LBUOP 0x90000000 +#define LHUOP 0x94000000 +#define LDSTBU +#define LDSTHU +#define SBOP 0xa0000000 +#define SHOP 0xa4000000 +#define SWOP 0xac000000 +#define LDST + +#define SEQUIOP 0xc0000000 +#define SNEUIOP 0xc4000000 +#define SLTUIOP 0xc8000000 +#define SGTUIOP 0xcc000000 +#define SLEUIOP 0xd0000000 +#define SGEUIOP 0xd4000000 + +#define SLLIOP 0xd8000000 +#define SRLIOP 0xdc000000 +#define SRAIOP 0xe0000000 + +/* Following 3 ops was added to provide the MP atonmic operation. */ +#define LSBUOP 0x98000000 +#define LSHUOP 0x9c000000 +#define LSWOP 0xb0000000 + +/* Following opcode was defined in the Hennessy's book as + "normal" opcode but was implemented in the RTL as special + functions. */ +#if 0 +#define MVTSOP 0x50000000 +#define MVFSOP 0x54000000 +#endif + +struct dlx_opcode +{ + /* Name of the instruction. */ + char *name; + + /* Opcode word. */ + unsigned long opcode; + + /* A string of characters which describe the operands. + Valid characters are: + , Itself. The character appears in the assembly code. + a rs1 The register number is in bits 21-25 of the instruction. + b rs2/rd The register number is in bits 16-20 of the instruction. + c rd. The register number is in bits 11-15 of the instruction. + f FUNC bits 0-10 of the instruction. + i An immediate operand is in bits 0-16 of the instruction. 0 extended + I An immediate operand is in bits 0-16 of the instruction. sign extended + d An 16 bit PC relative displacement. + D An immediate operand is in bits 0-25 of the instruction. + N No opperands needed, for nops. + P it can be a register or a 16 bit operand. */ + char *args; +}; + +static CONST struct dlx_opcode dlx_opcodes[] = + { + /* Arithmetic and Logic R-TYPE instructions. */ + { "nop", (ALUOP|NOPF), "N" }, /* NOP */ + { "add", (ALUOP|ADDF), "c,a,b" }, /* Add */ + { "addu", (ALUOP|ADDUF), "c,a,b" }, /* Add Unsigned */ + { "sub", (ALUOP|SUBF), "c,a,b" }, /* SUB */ + { "subu", (ALUOP|SUBUF), "c,a,b" }, /* Sub Unsigned */ + { "mult", (ALUOP|MULTF), "c,a,b" }, /* MULTIPLY */ + { "multu", (ALUOP|MULTUF), "c,a,b" }, /* MULTIPLY Unsigned */ + { "div", (ALUOP|DIVF), "c,a,b" }, /* DIVIDE */ + { "divu", (ALUOP|DIVUF), "c,a,b" }, /* DIVIDE Unsigned */ + { "and", (ALUOP|ANDF), "c,a,b" }, /* AND */ + { "or", (ALUOP|ORF), "c,a,b" }, /* OR */ + { "xor", (ALUOP|XORF), "c,a,b" }, /* Exclusive OR */ + { "sll", (ALUOP|SLLF), "c,a,b" }, /* SHIFT LEFT LOGICAL */ + { "sra", (ALUOP|SRAF), "c,a,b" }, /* SHIFT RIGHT ARITHMETIC */ + { "srl", (ALUOP|SRLF), "c,a,b" }, /* SHIFT RIGHT LOGICAL */ + { "seq", (ALUOP|SEQF), "c,a,b" }, /* Set if equal */ + { "sne", (ALUOP|SNEF), "c,a,b" }, /* Set if not equal */ + { "slt", (ALUOP|SLTF), "c,a,b" }, /* Set if less */ + { "sgt", (ALUOP|SGTF), "c,a,b" }, /* Set if greater */ + { "sle", (ALUOP|SLEF), "c,a,b" }, /* Set if less or equal */ + { "sge", (ALUOP|SGEF), "c,a,b" }, /* Set if greater or equal */ + { "sequ", (ALUOP|SEQUF), "c,a,b" }, /* Set if equal unsigned */ + { "sneu", (ALUOP|SNEUF), "c,a,b" }, /* Set if not equal unsigned */ + { "sltu", (ALUOP|SLTUF), "c,a,b" }, /* Set if less unsigned */ + { "sgtu", (ALUOP|SGTUF), "c,a,b" }, /* Set if greater unsigned */ + { "sleu", (ALUOP|SLEUF), "c,a,b" }, /* Set if less or equal unsigned*/ + { "sgeu", (ALUOP|SGEUF), "c,a,b" }, /* Set if greater or equal */ + { "mvts", (ALUOP|MVTSF), "c,a" }, /* Move to special register */ + { "mvfs", (ALUOP|MVFSF), "c,a" }, /* Move from special register */ + { "bswap", (ALUOP|BSWAPF), "c,a,b" }, /* ??? Was not documented */ + { "lut", (ALUOP|LUTF), "c,a,b" }, /* ????? same as above */ + + /* Arithmetic and Logical Immediate I-TYPE instructions. */ + { "addi", ADDIOP, "b,a,I" }, /* Add Immediate */ + { "addui", ADDUIOP, "b,a,i" }, /* Add Usigned Immediate */ + { "subi", SUBIOP, "b,a,I" }, /* Sub Immediate */ + { "subui", SUBUIOP, "b,a,i" }, /* Sub Unsigned Immedated */ + { "andi", ANDIOP, "b,a,i" }, /* AND Immediate */ + { "ori", ORIOP, "b,a,i" }, /* OR Immediate */ + { "xori", XORIOP, "b,a,i" }, /* Exclusive OR Immediate */ + { "slli", SLLIOP, "b,a,i" }, /* SHIFT LEFT LOCICAL Immediate */ + { "srai", SRAIOP, "b,a,i" }, /* SHIFT RIGHT ARITH. Immediate */ + { "srli", SRLIOP, "b,a,i" }, /* SHIFT RIGHT LOGICAL Immediate*/ + { "seqi", SEQIOP, "b,a,i" }, /* Set if equal */ + { "snei", SNEIOP, "b,a,i" }, /* Set if not equal */ + { "slti", SLTIOP, "b,a,i" }, /* Set if less */ + { "sgti", SGTIOP, "b,a,i" }, /* Set if greater */ + { "slei", SLEIOP, "b,a,i" }, /* Set if less or equal */ + { "sgei", SGEIOP, "b,a,i" }, /* Set if greater or equal */ + { "sequi", SEQUIOP, "b,a,i" }, /* Set if equal */ + { "sneui", SNEUIOP, "b,a,i" }, /* Set if not equal */ + { "sltui", SLTUIOP, "b,a,i" }, /* Set if less */ + { "sgtui", SGTUIOP, "b,a,i" }, /* Set if greater */ + { "sleui", SLEUIOP, "b,a,i" }, /* Set if less or equal */ + { "sgeui", SGEUIOP, "b,a,i" }, /* Set if greater or equal */ + /* Macros for I type instructions. */ + { "mov", ADDIOP, "b,P" }, /* a move macro */ + { "movu", ADDUIOP, "b,P" }, /* a move macro, unsigned */ + +#if 0 + /* Move special. */ + { "mvts", MVTSOP, "b,a" }, /* Move From Integer to Special */ + { "mvfs", MVFSOP, "b,a" }, /* Move From Special to Integer */ +#endif + + /* Load high Immediate I-TYPE instruction. */ + { "lhi", LHIOP, "b,i" }, /* Load High Immediate */ + { "lui", LHIOP, "b,i" }, /* Load High Immediate */ + { "sethi", LHIOP, "b,i" }, /* Load High Immediate */ + + /* LOAD/STORE BYTE 8 bits I-TYPE. */ + { "lb", LBOP, "b,a,I" }, /* Load Byte */ + { "lbu", LBUOP, "b,a,I" }, /* Load Byte Unsigned */ + { "ldstbu", LSBUOP, "b,a,I" }, /* Load store Byte Unsigned */ + { "sb", SBOP, "b,a,I" }, /* Store Byte */ + + /* LOAD/STORE HALFWORD 16 bits. */ + { "lh", LHOP, "b,a,I" }, /* Load Halfword */ + { "lhu", LHUOP, "b,a,I" }, /* Load Halfword Unsigned */ + { "ldsthu", LSHUOP, "b,a,I" }, /* Load Store Halfword Unsigned */ + { "sh", SHOP, "b,a,I" }, /* Store Halfword */ + + /* LOAD/STORE WORD 32 bits. */ + { "lw", LWOP, "b,a,I" }, /* Load Word */ + { "sw", SWOP, "b,a,I" }, /* Store Word */ + { "ldstw", LSWOP, "b,a,I" }, /* Load Store Word */ + + /* Branch PC-relative, 16 bits offset. */ + { "beqz", BEQOP, "a,d" }, /* Branch if a == 0 */ + { "bnez", BNEOP, "a,d" }, /* Branch if a != 0 */ + { "beq", BEQOP, "a,d" }, /* Branch if a == 0 */ + { "bne", BNEOP, "a,d" }, /* Branch if a != 0 */ + + /* Jumps Trap and RFE J-TYPE. */ + { "j", JOP, "D" }, /* Jump, PC-relative 26 bits */ + { "jal", JALOP, "D" }, /* JAL, PC-relative 26 bits */ + { "break", BREAKOP, "D" }, /* break to OS */ + { "trap" , TRAPOP, "D" }, /* TRAP to OS */ + { "rfe", RFEOP, "N" }, /* Return From Exception */ + /* Macros. */ + { "call", JOP, "D" }, /* Jump, PC-relative 26 bits */ + + /* Jumps Trap and RFE I-TYPE. */ + { "jr", JROP, "a" }, /* Jump Register, Abs (32 bits) */ + { "jalr", JALROP, "a" }, /* JALR, Abs (32 bits) */ + /* Macros. */ + { "retr", JROP, "a" }, /* Jump Register, Abs (32 bits) */ + + { "", 0x0, "" } /* Dummy entry, not included in NUM_OPCODES. + This lets code examine entry i + 1 without + checking if we've run off the end of the table. */ + }; + +const unsigned int num_dlx_opcodes = (((sizeof dlx_opcodes) / (sizeof dlx_opcodes[0])) - 1); diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 5554b6dec42..2c5816bb16a 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,12 @@ +2002-05-28 Kuang Hwa Lin <kuang@sbcglobal.net> + + * configure.in: Add DLX configuraton support. + * configure: Regenerate. + * Makefile.am: Add DLX configuraton support. + * Makefile.in: Regenerate. + * disassemble.c: Add DLX support. + * dlx-dis.c: New file. + 2002-05-25 Alan Modra <amodra@bigpond.net.au> * Makefile.am (sh-dis.lo): Don't put make commands in deps. diff --git a/opcodes/Makefile.am b/opcodes/Makefile.am index a709193a6a0..0996b2e5338 100644 --- a/opcodes/Makefile.am +++ b/opcodes/Makefile.am @@ -58,6 +58,7 @@ CFILES = \ d10v-opc.c \ d30v-dis.c \ d30v-opc.c \ + dlx-dis.c \ dis-buf.c \ disassemble.c \ fr30-asm.c \ @@ -161,6 +162,7 @@ ALL_MACHINES = \ d10v-opc.lo \ d30v-dis.lo \ d30v-opc.lo \ + dlx-dis.lo \ fr30-asm.lo \ fr30-desc.lo \ fr30-dis.lo \ @@ -471,6 +473,9 @@ d30v-dis.lo: d30v-dis.c sysdep.h config.h $(INCDIR)/ansidecl.h \ $(INCDIR)/symcat.h opintl.h d30v-opc.lo: d30v-opc.c sysdep.h config.h $(INCDIR)/ansidecl.h \ $(INCDIR)/opcode/d30v.h +dlx-dis.lo: dlx-dis.c sysdep.h config.h $(INCDIR)/ansidecl.h \ + $(INCDIR)/opcode/dlx.h $(INCDIR)/dis-asm.h $(BFD_H) \ + $(INCDIR)/symcat.h opintl.h dis-buf.lo: dis-buf.c sysdep.h config.h $(INCDIR)/ansidecl.h \ $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/symcat.h opintl.h disassemble.lo: disassemble.c sysdep.h config.h $(INCDIR)/ansidecl.h \ diff --git a/opcodes/Makefile.in b/opcodes/Makefile.in index e578ed80cdb..3602cbd89eb 100644 --- a/opcodes/Makefile.in +++ b/opcodes/Makefile.in @@ -169,6 +169,7 @@ CFILES = \ d10v-opc.c \ d30v-dis.c \ d30v-opc.c \ + dlx-dis.c \ dis-buf.c \ disassemble.c \ fr30-asm.c \ @@ -273,6 +274,7 @@ ALL_MACHINES = \ d10v-opc.lo \ d30v-dis.lo \ d30v-opc.lo \ + dlx-dis.lo \ fr30-asm.lo \ fr30-desc.lo \ fr30-dis.lo \ @@ -419,7 +421,7 @@ acinclude.m4 aclocal.m4 config.in configure configure.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) -TAR = tar +TAR = gtar GZIP_ENV = --best SOURCES = libopcodes.a.c $(libopcodes_la_SOURCES) OBJECTS = libopcodes.a.$(OBJEXT) $(libopcodes_la_OBJECTS) @@ -967,6 +969,9 @@ d30v-dis.lo: d30v-dis.c sysdep.h config.h $(INCDIR)/ansidecl.h \ $(INCDIR)/symcat.h opintl.h d30v-opc.lo: d30v-opc.c sysdep.h config.h $(INCDIR)/ansidecl.h \ $(INCDIR)/opcode/d30v.h +dlx-dis.lo: dlx-dis.c sysdep.h config.h $(INCDIR)/ansidecl.h \ + $(INCDIR)/opcode/dlx.h $(INCDIR)/dis-asm.h $(BFD_H) \ + $(INCDIR)/symcat.h opintl.h dis-buf.lo: dis-buf.c sysdep.h config.h $(INCDIR)/ansidecl.h \ $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/symcat.h opintl.h disassemble.lo: disassemble.c sysdep.h config.h $(INCDIR)/ansidecl.h \ diff --git a/opcodes/configure b/opcodes/configure index 6da1cc90364..a83d43df19c 100755 --- a/opcodes/configure +++ b/opcodes/configure @@ -4604,6 +4604,7 @@ if test x${all_targets} = xfalse ; then bfd_cris_arch) ta="$ta cris-dis.lo cris-opc.lo" ;; bfd_d10v_arch) ta="$ta d10v-dis.lo d10v-opc.lo" ;; bfd_d30v_arch) ta="$ta d30v-dis.lo d30v-opc.lo" ;; + bfd_dlx_arch) ta="$ta dlx-dis.lo" ;; bfd_fr30_arch) ta="$ta fr30-asm.lo fr30-desc.lo fr30-dis.lo fr30-ibld.lo fr30-opc.lo" using_cgen=yes ;; bfd_h8300_arch) ta="$ta h8300-dis.lo" ;; bfd_h8500_arch) ta="$ta h8500-dis.lo" ;; diff --git a/opcodes/configure.in b/opcodes/configure.in index 09f0d3882f5..96e5a6b9f7f 100644 --- a/opcodes/configure.in +++ b/opcodes/configure.in @@ -179,6 +179,7 @@ if test x${all_targets} = xfalse ; then bfd_cris_arch) ta="$ta cris-dis.lo cris-opc.lo" ;; bfd_d10v_arch) ta="$ta d10v-dis.lo d10v-opc.lo" ;; bfd_d30v_arch) ta="$ta d30v-dis.lo d30v-opc.lo" ;; + bfd_dlx_arch) ta="$ta dlx-dis.lo" ;; bfd_fr30_arch) ta="$ta fr30-asm.lo fr30-desc.lo fr30-dis.lo fr30-ibld.lo fr30-opc.lo" using_cgen=yes ;; bfd_h8300_arch) ta="$ta h8300-dis.lo" ;; bfd_h8500_arch) ta="$ta h8500-dis.lo" ;; diff --git a/opcodes/disassemble.c b/opcodes/disassemble.c index 5bfa786cd23..bfb22c2c188 100644 --- a/opcodes/disassemble.c +++ b/opcodes/disassemble.c @@ -28,6 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define ARCH_cris #define ARCH_d10v #define ARCH_d30v +#define ARCH_dlx #define ARCH_h8300 #define ARCH_h8500 #define ARCH_hppa @@ -126,6 +127,12 @@ disassembler (abfd) disassemble = print_insn_d30v; break; #endif +#ifdef ARCH_dlx + case bfd_arch_dlx: + /* As far as I know we only handle big-endian DLX objects. */ + disassemble = print_insn_dlx; + break; +#endif #ifdef ARCH_h8300 case bfd_arch_h8300: if (bfd_get_mach(abfd) == bfd_mach_h8300h) diff --git a/opcodes/dlx-dis.c b/opcodes/dlx-dis.c new file mode 100644 index 00000000000..8878b98aef0 --- /dev/null +++ b/opcodes/dlx-dis.c @@ -0,0 +1,544 @@ +/* Instruction printing code for the DLX Microprocessor + Copyright 2002 Free Software Foundation, Inc. + Contributed by Kuang Hwa Lin. Written by Kuang Hwa Lin, 03/2002. + + 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 "sysdep.h" +#include "dis-asm.h" +#include "opcode/dlx.h" + +#define R_ERROR 0x1 +#define R_TYPE 0x2 +#define ILD_TYPE 0x3 +#define IST_TYPE 0x4 +#define IAL_TYPE 0x5 +#define IBR_TYPE 0x6 +#define IJ_TYPE 0x7 +#define IJR_TYPE 0x8 +#define NIL 0x9 + +#define OPC(x) ((x >> 26) & 0x3F) +#define FUNC(x) (x & 0x7FF) + +unsigned char opc, rs1, rs2, rd; +unsigned long imm26, imm16, func, current_insn_addr; + +static unsigned char dlx_get_opcode PARAMS ((unsigned long)); +static unsigned char dlx_get_rs1 PARAMS ((unsigned long)); +static unsigned char dlx_get_rs2 PARAMS ((unsigned long)); +static unsigned char dlx_get_rdR PARAMS ((unsigned long)); +static unsigned long dlx_get_func PARAMS ((unsigned long)); +static unsigned long dlx_get_imm16 PARAMS ((unsigned long)); +static unsigned long dlx_get_imm26 PARAMS ((unsigned long)); +static void operand_deliminator PARAMS ((struct disassemble_info *, char *)); +static unsigned char dlx_r_type PARAMS ((struct disassemble_info *)); +static unsigned char dlx_load_type PARAMS ((struct disassemble_info *)); +static unsigned char dlx_store_type PARAMS ((struct disassemble_info *)); +static unsigned char dlx_aluI_type PARAMS ((struct disassemble_info *)); +static unsigned char dlx_br_type PARAMS ((struct disassemble_info *)); +static unsigned char dlx_jmp_type PARAMS ((struct disassemble_info *)); +static unsigned char dlx_jr_type PARAMS ((struct disassemble_info *)); + +/* Print one instruction from MEMADDR on INFO->STREAM. + Return the size of the instruction (always 4 on dlx). */ + +static unsigned char +dlx_get_opcode (opcode) + unsigned long opcode; +{ + return (unsigned char) ((opcode >> 26) & 0x3F); +} + +static unsigned char +dlx_get_rs1 (opcode) + unsigned long opcode; +{ + return (unsigned char) ((opcode >> 21) & 0x1F); +} + +static unsigned char +dlx_get_rs2 (opcode) + unsigned long opcode; +{ + return (unsigned char) ((opcode >> 16) & 0x1F); +} + +static unsigned char +dlx_get_rdR (opcode) + unsigned long opcode; +{ + return (unsigned char) ((opcode >> 11) & 0x1F); +} + +static unsigned long +dlx_get_func (opcode) + unsigned long opcode; +{ + return (unsigned char) (opcode & 0x7FF); +} + +static unsigned long +dlx_get_imm16 (opcode) + unsigned long opcode; +{ + return (unsigned long) (opcode & 0xFFFF); +} + +static unsigned long +dlx_get_imm26 (opcode) + unsigned long opcode; +{ + return (unsigned long) (opcode & 0x03FFFFFF); +} + +/* Fill the opcode to the max length. */ +static void +operand_deliminator (info, ptr) + struct disassemble_info *info; + char *ptr; +{ + int difft = 8 - (int) strlen (ptr); + + while (difft > 0) + { + (*info->fprintf_func) (info->stream, "%c", ' '); + difft -= 1; + } +} + +/* Process the R-type opcode. */ +static unsigned char +dlx_r_type (info) + struct disassemble_info *info; +{ + unsigned char r_opc[] = { OPC(ALUOP) }; /* Fix ME */ + int r_opc_num = (sizeof r_opc) / (sizeof (char)); + struct _r_opcode + { + unsigned long func; + char *name; + } + dlx_r_opcode[] = + { + { NOPF, "nop" }, /* NOP */ + { ADDF, "add" }, /* Add */ + { ADDUF, "addu" }, /* Add Unsigned */ + { SUBF, "sub" }, /* SUB */ + { SUBUF, "subu" }, /* Sub Unsigned */ + { MULTF, "mult" }, /* MULTIPLY */ + { MULTUF, "multu" }, /* MULTIPLY Unsigned */ + { DIVF, "div" }, /* DIVIDE */ + { DIVUF, "divu" }, /* DIVIDE Unsigned */ + { ANDF, "and" }, /* AND */ + { ORF, "or" }, /* OR */ + { XORF, "xor" }, /* Exclusive OR */ + { SLLF, "sll" }, /* SHIFT LEFT LOGICAL */ + { SRAF, "sra" }, /* SHIFT RIGHT ARITHMETIC */ + { SRLF, "srl" }, /* SHIFT RIGHT LOGICAL */ + { SEQF, "seq" }, /* Set if equal */ + { SNEF, "sne" }, /* Set if not equal */ + { SLTF, "slt" }, /* Set if less */ + { SGTF, "sgt" }, /* Set if greater */ + { SLEF, "sle" }, /* Set if less or equal */ + { SGEF, "sge" }, /* Set if greater or equal */ + { SEQUF, "sequ" }, /* Set if equal */ + { SNEUF, "sneu" }, /* Set if not equal */ + { SLTUF, "sltu" }, /* Set if less */ + { SGTUF, "sgtu" }, /* Set if greater */ + { SLEUF, "sleu" }, /* Set if less or equal */ + { SGEUF, "sgeu" }, /* Set if greater or equal */ + { MVTSF, "mvts" }, /* Move to special register */ + { MVFSF, "mvfs" }, /* Move from special register */ + { BSWAPF, "bswap" }, /* Byte swap ?? */ + { LUTF, "lut" } /* ????????? ?? */ + }; + int dlx_r_opcode_num = (sizeof dlx_r_opcode) / (sizeof dlx_r_opcode[0]); + int idx; + + for (idx = 0; idx < r_opc_num; idx++) + { + if (r_opc[idx] != opc) + continue; + else + break; + } + + if (idx == r_opc_num) + return NIL; + + for (idx = 0 ; idx < dlx_r_opcode_num; idx++) + if (dlx_r_opcode[idx].func == func) + { + (*info->fprintf_func) (info->stream, "%s", dlx_r_opcode[idx].name); + + if (func != NOPF) + { + /* This is not a nop. */ + operand_deliminator (info, dlx_r_opcode[idx].name); + (*info->fprintf_func) (info->stream, "r%d,", (int)rd); + (*info->fprintf_func) (info->stream, "r%d", (int)rs1); + if (func != MVTSF && func != MVFSF) + (*info->fprintf_func) (info->stream, ",r%d", (int)rs2); + } + return (unsigned char) R_TYPE; + } + + return (unsigned char) R_ERROR; +} + +/* Process the memory read opcode. */ + +static unsigned char +dlx_load_type (info) + struct disassemble_info* info; +{ + struct _load_opcode + { + unsigned long opcode; + char *name; + } + dlx_load_opcode[] = + { + { OPC(LHIOP), "lhi" }, /* Load HI to register. */ + { OPC(LBOP), "lb" }, /* load byte sign extended. */ + { OPC(LBUOP), "lbu" }, /* load byte unsigned. */ + { OPC(LSBUOP),"ldstbu"}, /* load store byte unsigned. */ + { OPC(LHOP), "lh" }, /* load halfword sign extended. */ + { OPC(LHUOP), "lhu" }, /* load halfword unsigned. */ + { OPC(LSHUOP),"ldsthu"}, /* load store halfword unsigned. */ + { OPC(LWOP), "lw" }, /* load word. */ + { OPC(LSWOP), "ldstw" } /* load store word. */ + }; + int dlx_load_opcode_num = + (sizeof dlx_load_opcode) / (sizeof dlx_load_opcode[0]); + int idx; + + for (idx = 0 ; idx < dlx_load_opcode_num; idx++) + if (dlx_load_opcode[idx].opcode == opc) + { + if (opc == OPC (LHIOP)) + { + (*info->fprintf_func) (info->stream, "%s", dlx_load_opcode[idx].name); + operand_deliminator (info, dlx_load_opcode[idx].name); + (*info->fprintf_func) (info->stream, "r%d,", (int)rs2); + (*info->fprintf_func) (info->stream, "0x%04x", (int)imm16); + } + else + { + (*info->fprintf_func) (info->stream, "%s", dlx_load_opcode[idx].name); + operand_deliminator (info, dlx_load_opcode[idx].name); + (*info->fprintf_func) (info->stream, "r%d,", (int)rs2); + (*info->fprintf_func) (info->stream, "0x%04x[r%d]", (int)imm16, (int)rs1); + } + + return (unsigned char) ILD_TYPE; + } + + return (unsigned char) NIL; +} + +/* Process the memory store opcode. */ + +static unsigned char +dlx_store_type (info) + struct disassemble_info* info; +{ + struct _store_opcode + { + unsigned long opcode; + char *name; + } + dlx_store_opcode[] = + { + { OPC(SBOP), "sb" }, /* Store byte. */ + { OPC(SHOP), "sh" }, /* Store halfword. */ + { OPC(SWOP), "sw" }, /* Store word. */ + }; + int dlx_store_opcode_num = + (sizeof dlx_store_opcode) / (sizeof dlx_store_opcode[0]); + int idx; + + for (idx = 0 ; idx < dlx_store_opcode_num; idx++) + if (dlx_store_opcode[idx].opcode == opc) + { + (*info->fprintf_func) (info->stream, "%s", dlx_store_opcode[idx].name); + operand_deliminator (info, dlx_store_opcode[idx].name); + (*info->fprintf_func) (info->stream, "0x%04x[r%d],", (int)imm16, (int)rs1); + (*info->fprintf_func) (info->stream, "r%d", (int)rs2); + return (unsigned char) IST_TYPE; + } + + return (unsigned char) NIL; +} + +/* Process the Arithmetic and Logical I-TYPE opcode. */ + +static unsigned char +dlx_aluI_type (info) + struct disassemble_info* info; +{ + struct _aluI_opcode + { + unsigned long opcode; + char *name; + } + dlx_aluI_opcode[] = + { + { OPC(ADDIOP), "addi" }, /* Store byte. */ + { OPC(ADDUIOP), "addui" }, /* Store halfword. */ + { OPC(SUBIOP), "subi" }, /* Store word. */ + { OPC(SUBUIOP), "subui" }, /* Store word. */ + { OPC(ANDIOP), "andi" }, /* Store word. */ + { OPC(ORIOP), "ori" }, /* Store word. */ + { OPC(XORIOP), "xori" }, /* Store word. */ + { OPC(SLLIOP), "slli" }, /* Store word. */ + { OPC(SRAIOP), "srai" }, /* Store word. */ + { OPC(SRLIOP), "srli" }, /* Store word. */ + { OPC(SEQIOP), "seqi" }, /* Store word. */ + { OPC(SNEIOP), "snei" }, /* Store word. */ + { OPC(SLTIOP), "slti" }, /* Store word. */ + { OPC(SGTIOP), "sgti" }, /* Store word. */ + { OPC(SLEIOP), "slei" }, /* Store word. */ + { OPC(SGEIOP), "sgei" }, /* Store word. */ + { OPC(SEQUIOP), "sequi" }, /* Store word. */ + { OPC(SNEUIOP), "sneui" }, /* Store word. */ + { OPC(SLTUIOP), "sltui" }, /* Store word. */ + { OPC(SGTUIOP), "sgtui" }, /* Store word. */ + { OPC(SLEUIOP), "sleui" }, /* Store word. */ + { OPC(SGEUIOP), "sgeui" }, /* Store word. */ +#if 0 + { OPC(MVTSOP), "mvts" }, /* Store word. */ + { OPC(MVFSOP), "mvfs" }, /* Store word. */ +#endif + }; + int dlx_aluI_opcode_num = + (sizeof dlx_aluI_opcode) / (sizeof dlx_aluI_opcode[0]); + int idx; + + for (idx = 0 ; idx < dlx_aluI_opcode_num; idx++) + if (dlx_aluI_opcode[idx].opcode == opc) + { + (*info->fprintf_func) (info->stream, "%s", dlx_aluI_opcode[idx].name); + operand_deliminator (info, dlx_aluI_opcode[idx].name); + (*info->fprintf_func) (info->stream, "r%d,", (int)rs2); + (*info->fprintf_func) (info->stream, "r%d,", (int)rs1); + (*info->fprintf_func) (info->stream, "0x%04x", (int)imm16); + + return (unsigned char) IAL_TYPE; + } + + return (unsigned char) NIL; +} + +/* Process the branch instruction. */ + +static unsigned char +dlx_br_type (info) + struct disassemble_info* info; +{ + struct _br_opcode + { + unsigned long opcode; + char *name; + } + dlx_br_opcode[] = + { + { OPC(BEQOP), "beqz" }, /* Store byte. */ + { OPC(BNEOP), "bnez" } /* Store halfword. */ + }; + int dlx_br_opcode_num = + (sizeof dlx_br_opcode) / (sizeof dlx_br_opcode[0]); + int idx; + + for (idx = 0 ; idx < dlx_br_opcode_num; idx++) + if (dlx_br_opcode[idx].opcode == opc) + { + if (imm16 & 0x00008000) + imm16 |= 0xFFFF0000; + + imm16 += (current_insn_addr + 4); + (*info->fprintf_func) (info->stream, "%s", dlx_br_opcode[idx].name); + operand_deliminator (info, dlx_br_opcode[idx].name); + (*info->fprintf_func) (info->stream, "r%d,", (int)rs1); + (*info->fprintf_func) (info->stream, "0x%08x", (int)imm16); + + return (unsigned char) IBR_TYPE; + } + + return (unsigned char) NIL; +} + +/* Process the jump instruction. */ + +static unsigned char +dlx_jmp_type (info) + struct disassemble_info* info; +{ + struct _jmp_opcode + { + unsigned long opcode; + char *name; + } + dlx_jmp_opcode[] = + { + { OPC(JOP), "j" }, /* Store byte. */ + { OPC(JALOP), "jal" }, /* Store halfword. */ + { OPC(BREAKOP), "break" }, /* Store halfword. */ + { OPC(TRAPOP), "trap" }, /* Store halfword. */ + { OPC(RFEOP), "rfe" } /* Store halfword. */ + }; + int dlx_jmp_opcode_num = + (sizeof dlx_jmp_opcode) / (sizeof dlx_jmp_opcode[0]); + int idx; + + for (idx = 0 ; idx < dlx_jmp_opcode_num; idx++) + if (dlx_jmp_opcode[idx].opcode == opc) + { + if (imm26 & 0x02000000) + imm26 |= 0xFC000000; + + imm26 += (current_insn_addr + 4); + + (*info->fprintf_func) (info->stream, "%s", dlx_jmp_opcode[idx].name); + operand_deliminator (info, dlx_jmp_opcode[idx].name); + (*info->fprintf_func) (info->stream, "0x%08x", (int)imm26); + + return (unsigned char) IJ_TYPE; + } + + return (unsigned char) NIL; +} + +/* Process the jump register instruction. */ + +static unsigned char +dlx_jr_type (info) + struct disassemble_info* info; +{ + struct _jr_opcode + { + unsigned long opcode; + char *name; + } + dlx_jr_opcode[] = { + { OPC(JROP), "jr" }, /* Store byte. */ + { OPC(JALROP), "jalr" } /* Store halfword. */ + }; + int dlx_jr_opcode_num = + (sizeof dlx_jr_opcode) / (sizeof dlx_jr_opcode[0]); + int idx; + + for (idx = 0 ; idx < dlx_jr_opcode_num; idx++) + if (dlx_jr_opcode[idx].opcode == opc) + { + (*info->fprintf_func) (info->stream, "%s", dlx_jr_opcode[idx].name); + operand_deliminator (info, dlx_jr_opcode[idx].name); + (*info->fprintf_func) (info->stream, "r%d", (int)rs1); + return (unsigned char) IJR_TYPE; + } + + return (unsigned char) NIL; +} + +typedef unsigned char (* dlx_insn) PARAMS ((struct disassemble_info *)); + +/* This is the main DLX insn handling routine. */ + +int +print_insn_dlx (memaddr, info) + bfd_vma memaddr; + struct disassemble_info* info; +{ + bfd_byte buffer[4]; + int insn_idx; + unsigned long insn_word; + unsigned char rtn_code; + unsigned long dlx_insn_type[] = + { + (unsigned long) dlx_r_type, + (unsigned long) dlx_load_type, + (unsigned long) dlx_store_type, + (unsigned long) dlx_aluI_type, + (unsigned long) dlx_br_type, + (unsigned long) dlx_jmp_type, + (unsigned long) dlx_jr_type, + (unsigned long) NULL + }; + int dlx_insn_type_num = ((sizeof dlx_insn_type) / (sizeof (unsigned long))) - 1; + int status = + (*info->read_memory_func) (memaddr, (bfd_byte *) &buffer[0], 4, info); + + if (status != 0) + { + (*info->memory_error_func) (status, memaddr, info); + return -1; + } + + /* Now decode the insn */ + insn_word = bfd_getb32 (buffer); + opc = dlx_get_opcode (insn_word); + rs1 = dlx_get_rs1 (insn_word); + rs2 = dlx_get_rs2 (insn_word); + rd = dlx_get_rdR (insn_word); + func = dlx_get_func (insn_word); + imm16= dlx_get_imm16 (insn_word); + imm26= dlx_get_imm26 (insn_word); + +#if 0 + printf ("print_insn_big_dlx: opc = 0x%02x\n" + " rs1 = 0x%02x\n" + " rs2 = 0x%02x\n" + " rd = 0x%02x\n" + " func = 0x%08x\n" + " imm16 = 0x%08x\n" + " imm26 = 0x%08x\n", + opc, rs1, rs2, rd, func, imm16, imm26); +#endif + + /* Scan through all the insn type and print the insn out. */ + rtn_code = 0; + current_insn_addr = (unsigned long) memaddr; + + for (insn_idx = 0; dlx_insn_type[insn_idx] != 0x0; insn_idx++) + switch (((dlx_insn) (dlx_insn_type[insn_idx])) (info)) + { + /* Found the correct opcode */ + case R_TYPE: + case ILD_TYPE: + case IST_TYPE: + case IAL_TYPE: + case IBR_TYPE: + case IJ_TYPE: + case IJR_TYPE: + return 4; + + /* Wrong insn type check next one. */ + default: + case NIL: + continue; + + /* All rest of the return code are not recongnized, treat it as error */ + /* we should never get here, I hope! */ + case R_ERROR: + return -1; + } + + if (insn_idx == dlx_insn_type_num) + /* Well, does not recoganize this opcode. */ + (*info->fprintf_func) (info->stream, "<%s>", "Unrecognized Opcode"); + + return 4; +} |