summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2002-05-28 14:08:47 +0000
committerNick Clifton <nickc@redhat.com>2002-05-28 14:08:47 +0000
commit099b5c98f1a2696f37dbe535705034339dd73f59 (patch)
tree4374d9ae6549f2a8a1e3aa264827366473897e8e
parent79c0399f2387759c35c4a41b7e309fc6fc8d286c (diff)
downloadgdb-099b5c98f1a2696f37dbe535705034339dd73f59.tar.gz
Add DLX target
-rw-r--r--bfd/ChangeLog14
-rw-r--r--bfd/Makefile.am9
-rw-r--r--bfd/Makefile.in11
-rw-r--r--bfd/archures.c3
-rw-r--r--bfd/bfd-in2.h10
-rw-r--r--bfd/config.bfd7
-rwxr-xr-xbfd/configure29
-rw-r--r--bfd/configure.in1
-rw-r--r--bfd/cpu-dlx.c39
-rw-r--r--bfd/doc/Makefile.in4
-rw-r--r--bfd/elf32-dlx.c659
-rw-r--r--bfd/libbfd.h3
-rw-r--r--bfd/reloc.c13
-rw-r--r--bfd/syms.c7
-rw-r--r--bfd/targets.c2
-rw-r--r--include/ChangeLog6
-rw-r--r--include/dis-asm.h1
-rw-r--r--include/elf/ChangeLog5
-rw-r--r--include/elf/common.h4
-rw-r--r--include/elf/dlx.h53
-rw-r--r--include/opcode/ChangeLog4
-rw-r--r--include/opcode/dlx.h282
-rw-r--r--opcodes/ChangeLog9
-rw-r--r--opcodes/Makefile.am5
-rw-r--r--opcodes/Makefile.in7
-rwxr-xr-xopcodes/configure1
-rw-r--r--opcodes/configure.in1
-rw-r--r--opcodes/disassemble.c7
-rw-r--r--opcodes/dlx-dis.c544
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;
+}