From d172d4ba0352f8b593fec9165c65257c3b64836d Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Tue, 28 May 2002 14:08:47 +0000 Subject: [PATCH] Add DLX target --- bfd/ChangeLog | 14 + bfd/Makefile.am | 9 + bfd/Makefile.in | 11 +- bfd/archures.c | 3 + bfd/bfd-in2.h | 10 + bfd/config.bfd | 7 +- bfd/configure | 29 +- bfd/configure.in | 1 + bfd/cpu-dlx.c | 39 + bfd/doc/Makefile.in | 4 +- bfd/elf32-dlx.c | 659 +++++++++++++ bfd/libbfd.h | 3 + bfd/reloc.c | 13 + bfd/syms.c | 7 +- bfd/targets.c | 2 + binutils/ChangeLog | 4 + binutils/readelf.c | 7 + gas/ChangeLog | 9 + gas/Makefile.am | 15 + gas/Makefile.in | 20 +- gas/config/tc-dlx.c | 1460 ++++++++++++++++++++++++++++ gas/config/tc-dlx.h | 102 ++ gas/configure | 360 +++---- gas/configure.in | 1 + gas/doc/Makefile.in | 2 +- gas/testsuite/ChangeLog | 17 + gas/testsuite/gas/dlx/alltests.exp | 10 + gas/testsuite/gas/dlx/branch.d | 43 + gas/testsuite/gas/dlx/branch.s | 31 + gas/testsuite/gas/dlx/itype.d | 40 + gas/testsuite/gas/dlx/itype.s | 30 + gas/testsuite/gas/dlx/lhi.d | 23 + gas/testsuite/gas/dlx/lhi.s | 10 + gas/testsuite/gas/dlx/load.d | 33 + gas/testsuite/gas/dlx/load.s | 19 + gas/testsuite/gas/dlx/rtype.d | 38 + gas/testsuite/gas/dlx/rtype.s | 33 + gas/testsuite/gas/dlx/store.d | 22 + gas/testsuite/gas/dlx/store.s | 9 + include/ChangeLog | 6 +- include/dis-asm.h | 1 + include/elf/ChangeLog | 5 + include/elf/common.h | 4 + include/elf/dlx.h | 53 + include/opcode/ChangeLog | 4 + include/opcode/dlx.h | 282 ++++++ ld/ChangeLog | 8 + ld/Makefile.am | 4 + ld/Makefile.in | 4 + ld/configure.tgt | 1 + ld/emulparams/elf32_dlx.sh | 9 + ld/scripttempl/dlx.sc | 30 + opcodes/ChangeLog | 9 + opcodes/Makefile.am | 5 + opcodes/Makefile.in | 7 +- opcodes/configure | 1 + opcodes/configure.in | 1 + opcodes/disassemble.c | 7 + opcodes/dlx-dis.c | 544 +++++++++++ 59 files changed, 3937 insertions(+), 197 deletions(-) create mode 100644 bfd/cpu-dlx.c create mode 100644 bfd/elf32-dlx.c create mode 100644 gas/config/tc-dlx.c create mode 100644 gas/config/tc-dlx.h create mode 100644 gas/testsuite/gas/dlx/alltests.exp create mode 100644 gas/testsuite/gas/dlx/branch.d create mode 100644 gas/testsuite/gas/dlx/branch.s create mode 100644 gas/testsuite/gas/dlx/itype.d create mode 100644 gas/testsuite/gas/dlx/itype.s create mode 100644 gas/testsuite/gas/dlx/lhi.d create mode 100644 gas/testsuite/gas/dlx/lhi.s create mode 100644 gas/testsuite/gas/dlx/load.d create mode 100644 gas/testsuite/gas/dlx/load.s create mode 100644 gas/testsuite/gas/dlx/rtype.d create mode 100644 gas/testsuite/gas/dlx/rtype.s create mode 100644 gas/testsuite/gas/dlx/store.d create mode 100644 gas/testsuite/gas/dlx/store.s create mode 100644 include/elf/dlx.h create mode 100644 include/opcode/dlx.h create mode 100644 ld/emulparams/elf32_dlx.sh create mode 100644 ld/scripttempl/dlx.sc create mode 100644 opcodes/dlx-dis.c diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 6b7381b88f..c4b7cc71b0 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,17 @@ +2002-05-28 Kuang Hwa Lin + + * 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 * elf32-m68k.c (elf32_m68k_print_private_bfd_data): Formatting. diff --git a/bfd/Makefile.am b/bfd/Makefile.am index 8cc206ff7c..e8e0cc07ca 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 224ca05dd8..cffcb07747 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 40102e8b0f..36fc56873d 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 8a0c45304f..1dd397a797 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 1afdd85cda..bba8d96676 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 b5b977dd9b..5345211921 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 <&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 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 <&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 <&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 <&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 aca7baca61..340da09534 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 0000000000..2023ff5312 --- /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 + + 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 0036c0be52..0e46ceb934 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 0000000000..d7d419c962 --- /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 c3c8126d49..cbb6390af1 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 e60062e12d..20df4f86fd 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -2615,6 +2615,19 @@ ENUM 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 diff --git a/bfd/syms.c b/bfd/syms.c index 2a88941477..1c4bf288a8 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 c53afdd29b..fe778caead 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/binutils/ChangeLog b/binutils/ChangeLog index 5ddea10fdd..3fd6b68087 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,7 @@ +2002-05-28 Kuang Hwa Lin + + * readelf.c: Modified/Added DLX elf support. + 2002-05-27 Nick Clifton * arsup.c: Fix formatting. diff --git a/binutils/readelf.c b/binutils/readelf.c index d91f3d2b5e..8521cf548e 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -56,6 +56,7 @@ #include "elf/cris.h" #include "elf/d10v.h" #include "elf/d30v.h" +#include "elf/dlx.h" #include "elf/fr30.h" #include "elf/h8.h" #include "elf/hppa.h" @@ -601,6 +602,7 @@ guess_is_rela (e_machine) case EM_386: case EM_486: case EM_960: + case EM_DLX: case EM_OPENRISC: case EM_OR32: case EM_M32R: @@ -1006,6 +1008,10 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela) rtype = elf_d30v_reloc_type (type); break; + case EM_DLX: + rtype = elf_dlx_reloc_type (type); + break; + case EM_SH: rtype = elf_sh_reloc_type (type); break; @@ -1537,6 +1543,7 @@ get_machine_name (e_machine) case EM_XSTORMY16: return "Sanyo Xstormy16 CPU core"; case EM_OPENRISC: case EM_OR32: return "OpenRISC"; + case EM_DLX: return "OpenDLX"; default: sprintf (buff, _(": %x"), e_machine); return buff; diff --git a/gas/ChangeLog b/gas/ChangeLog index 2cbb8d1b63..082edac864 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,12 @@ +2002-05-28 Kuang Hwa Lin + + * configure.in: Add DLX configuraton + * Makefile.am: Add DLX configuraton + * configure: Regenerate. + * Makefile.in: Regenerate. + * config/tc-dlx.c: New file. + * config/tc-dlx.h: New files. + 2002-05-27 Nick Clifton * config/obj-coff.c (write_object_file): Add missing semicolon. diff --git a/gas/Makefile.am b/gas/Makefile.am index fabcafc585..c284f74cb4 100644 --- a/gas/Makefile.am +++ b/gas/Makefile.am @@ -45,6 +45,7 @@ CPU_TYPES = \ cris \ d10v \ d30v \ + dlx \ fr30 \ h8300 \ h8500 \ @@ -233,6 +234,7 @@ TARGET_CPU_CFILES = \ config/tc-cris.c \ config/tc-d10v.c \ config/tc-d30v.c \ + config/tc-dlx.c \ config/tc-fr30.c \ config/tc-h8300.c \ config/tc-h8500.c \ @@ -280,6 +282,7 @@ TARGET_CPU_HFILES = \ config/tc-cris.h \ config/tc-d10v.h \ config/tc-d30v.h \ + config/tc-dlx.h \ config/tc-fr30.h \ config/tc-h8300.h \ config/tc-h8500.h \ @@ -1044,6 +1047,11 @@ DEPTC_d30v_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-d30v.h \ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \ $(INCDIR)/opcode/d30v.h +DEPTC_dlx_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \ + $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \ + $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-dlx.h \ + $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \ + $(INCDIR)/opcode/dlx.h DEPTC_fr30_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \ $(srcdir)/config/tc-fr30.h $(INCDIR)/coff/internal.h \ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \ @@ -1548,6 +1556,10 @@ DEPOBJ_d30v_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-d30v.h \ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \ $(INCDIR)/aout/aout64.h +DEPOBJ_dlx_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \ + $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \ + $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-dlx.h \ + $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h DEPOBJ_fr30_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \ $(srcdir)/config/tc-fr30.h $(INCDIR)/coff/internal.h \ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \ @@ -1982,6 +1994,9 @@ DEP_d30v_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-d30v.h \ DEP_d30v_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-d30v.h +DEP_dlx_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \ + $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \ + $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-dlx.h DEP_fr30_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-fr30.h \ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \ $(INCDIR)/bfdlink.h diff --git a/gas/Makefile.in b/gas/Makefile.in index defe689671..287eda3d5a 100644 --- a/gas/Makefile.in +++ b/gas/Makefile.in @@ -156,6 +156,7 @@ CPU_TYPES = \ cris \ d10v \ d30v \ + dlx \ fr30 \ h8300 \ h8500 \ @@ -350,6 +351,7 @@ TARGET_CPU_CFILES = \ config/tc-cris.c \ config/tc-d10v.c \ config/tc-d30v.c \ + config/tc-dlx.c \ config/tc-fr30.c \ config/tc-h8300.c \ config/tc-h8500.c \ @@ -398,6 +400,7 @@ TARGET_CPU_HFILES = \ config/tc-cris.h \ config/tc-d10v.h \ config/tc-d30v.h \ + config/tc-dlx.h \ config/tc-fr30.h \ config/tc-h8300.h \ config/tc-h8500.h \ @@ -768,6 +771,12 @@ DEPTC_d30v_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \ $(INCDIR)/opcode/d30v.h +DEPTC_dlx_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \ + $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \ + $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-dlx.h \ + $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \ + $(INCDIR)/opcode/dlx.h + DEPTC_fr30_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \ $(srcdir)/config/tc-fr30.h $(INCDIR)/coff/internal.h \ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \ @@ -1379,6 +1388,11 @@ DEPOBJ_d30v_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \ $(INCDIR)/aout/aout64.h +DEPOBJ_dlx_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \ + $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \ + $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-dlx.h \ + $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h + DEPOBJ_fr30_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \ $(srcdir)/config/tc-fr30.h $(INCDIR)/coff/internal.h \ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \ @@ -1920,6 +1934,10 @@ DEP_d30v_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-d30v.h +DEP_dlx_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \ + $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \ + $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-dlx.h + DEP_fr30_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-fr30.h \ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \ $(INCDIR)/bfdlink.h @@ -2307,7 +2325,7 @@ configure configure.in gdbinit.in itbl-lex.c itbl-parse.c DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) -TAR = tar +TAR = gtar GZIP_ENV = --best SOURCES = $(gasp_new_SOURCES) $(itbl_test_SOURCES) $(as_new_SOURCES) $(EXTRA_as_new_SOURCES) OBJECTS = $(gasp_new_OBJECTS) $(itbl_test_OBJECTS) $(as_new_OBJECTS) diff --git a/gas/config/tc-dlx.c b/gas/config/tc-dlx.c new file mode 100644 index 0000000000..e95ab5bf7b --- /dev/null +++ b/gas/config/tc-dlx.c @@ -0,0 +1,1460 @@ +/* tc-ldx.c -- Assemble for the DLX + Copyright 2002 Free Software Foundation, Inc. + + This file is part of GAS, the GNU Assembler. + + GAS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GAS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GAS; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +/* Initially created by Kuang Hwa Lin, 3/20/2002. */ + +#include "safe-ctype.h" +#include "as.h" +#include "tc-dlx.h" +#include "opcode/dlx.h" +#if 0 +#include "elf/dlx.h" +#endif + +/* Make it easier to clone this machine desc into another one. */ +#define machine_opcode dlx_opcode +#define machine_opcodes dlx_opcodes +#define machine_ip dlx_ip +#define machine_it dlx_it + +#define NO_RELOC BFD_RELOC_NONE +#define RELOC_DLX_REL26 BFD_RELOC_DLX_JMP26 +#define RELOC_DLX_16 BFD_RELOC_16 +#define RELOC_DLX_REL16 BFD_RELOC_16_PCREL_S2 +#define RELOC_DLX_HI16 BFD_RELOC_HI16_S +#define RELOC_DLX_LO16 BFD_RELOC_LO16 +#define RELOC_DLX_VTINHERIT BFD_RELOC_VTABLE_INHERIT +#define RELOC_DLX_VTENTRY BFD_RELOC_VTABLE_ENTRY + +/* handle of the OPCODE hash table */ +static struct hash_control *op_hash = NULL; + +struct machine_it +{ + char *error; + unsigned long opcode; + struct nlist *nlistp; + expressionS exp; + int pcrel; + int size; + int reloc_offset; /* Offset of reloc within insn. */ + int reloc; + int HI; + int LO; +} +the_insn; + +/* static void print_insn PARAMS ((struct machine_it *)); */ +char * parse_operand PARAMS ((char *, expressionS *)); +int md_chars_to_number PARAMS ((unsigned char *, int)); + +static void machine_ip PARAMS ((char *)); +static void s_proc PARAMS ((int)); +static void insert_sreg PARAMS ((char *, int)); +static int hilo_modifier_ok PARAMS ((char *)); +static int is_ldst_registers PARAMS ((char *)); +static int match_sft_register PARAMS ((char *)); +static void define_some_regs PARAMS ((void)); +static char * dlx_parse_loadop PARAMS ((char *)); +static char * dlx_parse_storeop PARAMS ((char *)); +static char * fix_ld_st_operand PARAMS ((unsigned long, char *)); + +const pseudo_typeS + +dlx_pseudo_table[] = + { + /* Some additional ops that are used by gcc-dlx. */ + {"asciiz", stringer, 1}, + {"half", cons, 2}, + {"dword", cons, 8}, + {"word", cons, 4}, + {"proc", s_proc, 0}, + {"endproc", s_proc, 1}, + {NULL, 0, 0}, + }; + +/* This array holds the chars that always start a comment. If the + pre-processor is disabled, these aren't very useful. */ +const char comment_chars[] = ";"; + +/* This array holds the chars that only start a comment at the beginning of + a line. If the line seems to have the form '# 123 filename' + .line and .file directives will appear in the pre-processed output. */ +/* Note that input_file.c hand checks for '#' at the beginning of the + first line of the input file. This is because the compiler outputs + #NO_APP at the beginning of its output. */ +/* Also note that comments like this one will always work. */ +const char line_comment_chars[] = "#"; + +/* We needed an unused char for line separation to work around the + lack of macros, using sed and such. */ +const char line_separator_chars[] = "@"; + +/* Chars that can be used to separate mant from exp in floating point nums. */ +const char EXP_CHARS[] = "eE"; + +/* Chars that mean this number is a floating point constant. + As in 0f12.456 + or 0d1.2345e12. */ +const char FLT_CHARS[] = "rRsSfFdDxXpP"; + +static void +insert_sreg (regname, regnum) + char *regname; + int regnum; +{ + /* Must be large enough to hold the names of the special registers. */ + char buf[80]; + int i; + + symbol_table_insert (symbol_new (regname, reg_section, (valueT) regnum, + &zero_address_frag)); + for (i = 0; regname[i]; i++) + buf[i] = ISLOWER (regname[i]) ? TOUPPER (regname[i]) : regname[i]; + buf[i] = '\0'; + + symbol_table_insert (symbol_new (buf, reg_section, (valueT) regnum, + &zero_address_frag)); +} + +/* Install symbol definitions for assorted special registers. + See MIPS Assembly Language Programmer's Guide page 1-4 */ + +static void +define_some_regs () +{ +#if 0 + /* Hardware representation. */ + insert_sreg ("r0", 0); + insert_sreg ("r1", 1); + insert_sreg ("r2", 2); + insert_sreg ("r3", 3); + insert_sreg ("r4", 4); + insert_sreg ("r5", 5); + insert_sreg ("r6", 6); + insert_sreg ("r7", 7); + insert_sreg ("r8", 8); + insert_sreg ("r9", 9); + insert_sreg ("r10", 10); + insert_sreg ("r11", 11); + insert_sreg ("r12", 12); + insert_sreg ("r13", 13); + insert_sreg ("r14", 14); + insert_sreg ("r15", 15); + insert_sreg ("r16", 16); + insert_sreg ("r17", 17); + insert_sreg ("r18", 18); + insert_sreg ("r19", 19); + insert_sreg ("r20", 20); + insert_sreg ("r21", 21); + insert_sreg ("r22", 22); + insert_sreg ("r23", 23); + insert_sreg ("r24", 24); + insert_sreg ("r25", 25); + insert_sreg ("r26", 26); + insert_sreg ("r27", 27); + insert_sreg ("r28", 28); + insert_sreg ("r29", 29); + insert_sreg ("r30", 30); + insert_sreg ("r31", 31); +#endif + /* Software representation. */ + insert_sreg ("zero", 0); + insert_sreg ("at", 1); + insert_sreg ("v0", 2); + insert_sreg ("v1", 3); + insert_sreg ("a0", 4); + insert_sreg ("a1", 5); + insert_sreg ("a2", 6); + insert_sreg ("a3", 7); + insert_sreg ("t0", 8); + insert_sreg ("t1", 9); + insert_sreg ("t2", 10); + insert_sreg ("t3", 11); + insert_sreg ("t4", 12); + insert_sreg ("t5", 13); + insert_sreg ("t6", 14); + insert_sreg ("t7", 15); + insert_sreg ("s0", 16); + insert_sreg ("s1", 17); + insert_sreg ("s2", 18); + insert_sreg ("s3", 19); + insert_sreg ("s4", 20); + insert_sreg ("s5", 21); + insert_sreg ("s6", 22); + insert_sreg ("s7", 23); + insert_sreg ("t8", 24); + insert_sreg ("t9", 25); + insert_sreg ("k0", 26); + insert_sreg ("k1", 27); + insert_sreg ("gp", 28); + insert_sreg ("sp", 29); + insert_sreg ("fp", 30); + insert_sreg ("ra", 31); + /* Special registers. */ + insert_sreg ("pc", 0); + insert_sreg ("npc", 1); + insert_sreg ("iad", 2); +} + +/* Subroutine check the string to match an register, */ + +static int +match_sft_register (name) + char *name; +{ +#define MAX_REG_NO 35 +/* Currently we have 35 software registers defined - + we borrowed from MIPS. */ + static char *soft_reg[] = + { + "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", + "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", + "s0", "s1", "s2", "s3", "s4", "s5", "s7", "k0", "k1", + "gp", "sp", "fp", "ra", "pc", "npc", "iad", + "EndofTab" /* End of the Table indicator */ + }; + char low_name[21], *ptr; + int idx; + + for (ptr = name,idx = 0; *ptr != '\0'; ptr++) + low_name[idx++] = TOLOWER (*ptr); + + low_name[idx] = '\0'; + idx = 0; + + while (idx < MAX_REG_NO && strcmp (soft_reg[idx], & low_name [0])) + idx += 1; + + return idx < MAX_REG_NO; +} + +/* Subroutine check the string to match an register. */ + +static int +is_ldst_registers (name) + char *name; +{ + char *ptr = name; + + /* The first character of the register name got to be either %, $, r of R. */ + if ((ptr[0] == '%' || ptr[0] == '$' || ptr[0] == 'r' || ptr[0] == 'R') + && ISDIGIT ((unsigned char) ptr[1])) + return 1; + + /* Now check the software register representation. */ + return match_sft_register (ptr); +} + +/* Subroutine of s_proc so targets can choose a different default prefix. + If DEFAULT_PREFIX is NULL, use the target's "leading char". */ + +static void +s_proc (end_p) + int end_p; +{ + /* Record the current function so that we can issue an error message for + misplaced .func,.endfunc, and also so that .endfunc needs no + arguments. */ + static char *current_name; + static char *current_label; + + if (end_p) + { + if (current_name == NULL) + { + as_bad (_("missing .proc")); + ignore_rest_of_line (); + return; + } + + current_name = current_label = NULL; + SKIP_WHITESPACE (); + while (!is_end_of_line[(unsigned char) *input_line_pointer]) + input_line_pointer++; + } + else + { + char *name, *label; + char delim1, delim2; + + if (current_name != NULL) + { + as_bad (_(".endfunc missing for previous .proc")); + ignore_rest_of_line (); + return; + } + + name = input_line_pointer; + delim1 = get_symbol_end (); + name = xstrdup (name); + *input_line_pointer = delim1; + SKIP_WHITESPACE (); + + if (*input_line_pointer != ',') + { + char leading_char = 0; + + leading_char = bfd_get_symbol_leading_char (stdoutput); + /* Missing entry point, use function's name with the leading + char prepended. */ + if (leading_char) + asprintf (&label, "%c%s", leading_char, name); + else + label = name; + } + else + { + ++input_line_pointer; + SKIP_WHITESPACE (); + label = input_line_pointer; + delim2 = get_symbol_end (); + label = xstrdup (label); + *input_line_pointer = delim2; + } + + current_name = name; + current_label = label; + } + demand_empty_rest_of_line (); +} + +/* This function is called once, at assembler startup time. It should + set up all the tables, etc., that the MD part of the assembler will + need. */ + +void +md_begin () +{ + const char *retval = NULL; + int lose = 0; + unsigned int i; + + /* Create a new hash table. */ + op_hash = hash_new (); + + /* Hash up all the opcodes for fast use later. */ + for (i = 0; i < num_dlx_opcodes; i++) + { + const char *name = machine_opcodes[i].name; + + retval = hash_insert (op_hash, name, (PTR) &machine_opcodes[i]); + + if (retval != NULL) + { + fprintf (stderr, "internal error: can't hash `%s': %s\n", + machine_opcodes[i].name, retval); + lose = 1; + } + } + + if (lose) + as_fatal (_("Broken assembler. No assembly attempted.")); + + define_some_regs (); + return; +} + +/* Assemble a single instruction. Its label has already been handled + by the generic front end. We just parse opcode and operands, and + produce the bytes of data and relocation. */ + +void +md_assemble (str) + char *str; +{ + char *toP; + fixS *fixP; + bit_fixS *bitP; + + know (str); + machine_ip (str); + toP = frag_more (4); + /* Put out the opcode. */ + md_number_to_chars (toP, the_insn.opcode, 4); + + /* Put out the symbol-dependent stuff. */ + if (the_insn.reloc != NO_RELOC) + { + fixP = fix_new_exp (frag_now, + (toP - frag_now->fr_literal + the_insn.reloc_offset), + the_insn.size, & the_insn.exp, the_insn.pcrel, + the_insn.reloc); + + switch (fixP->fx_r_type) + { + case RELOC_DLX_REL26: + bitP = malloc (sizeof (bit_fixS)); + bitP->fx_bit_size = 26; + bitP->fx_bit_offset = 25; + bitP->fx_bit_base = the_insn.opcode & 0xFC000000; + bitP->fx_bit_base_adj = 0; + bitP->fx_bit_max = 0; + bitP->fx_bit_min = 0; + bitP->fx_bit_add = 0x03FFFFFF; + fixP->fx_bit_fixP = bitP; + break; + case RELOC_DLX_REL16: + bitP = malloc (sizeof (bit_fixS)); + bitP->fx_bit_size = 16; + bitP->fx_bit_offset = 15; + bitP->fx_bit_base = the_insn.opcode & 0xFFFF0000; + bitP->fx_bit_base_adj = 0; + bitP->fx_bit_max = 0; + bitP->fx_bit_min = 0; + bitP->fx_bit_add = 0x0000FFFF; + fixP->fx_bit_fixP = bitP; + break; + case RELOC_DLX_HI16: + bitP = malloc (sizeof (bit_fixS)); + bitP->fx_bit_size = 16; + bitP->fx_bit_offset = 15; + bitP->fx_bit_base = the_insn.opcode & 0xFFFF0000; + bitP->fx_bit_base_adj = 0; + bitP->fx_bit_max = 0; + bitP->fx_bit_min = 0; + bitP->fx_bit_add = 0x0000FFFF; + fixP->fx_bit_fixP = bitP; + break; + default: + fixP->fx_bit_fixP = (bit_fixS *)NULL; + break; + } + } +} + +static int +hilo_modifier_ok (s) + char *s; +{ + char *ptr = s; + int idx, count = 1; + + if (*ptr != '(') + return 1; + + for (idx = 1; ptr[idx] != '\0' && ptr[idx] != '[' && idx < 73; idx += 1) + { + if (count == 0) + return count; + + if (ptr[idx] == '(') + count += 1; + + if (ptr[idx] == ')') + count -= 1; + } + + return (count == 0) ? 1:0; +} + +char * +parse_operand (s, operandp) + char *s; + expressionS *operandp; +{ + char *save = input_line_pointer; + char *new; + + the_insn.HI = the_insn.LO = 0; + + /* Search for %hi and %lo, make a mark and skip it. */ + if (strncmp (s, "%hi", 3) == 0) + { + s += 3; + the_insn.HI = 1; + } + else + { + if (strncmp (s, "%lo", 3) == 0) + { + s += 3; + the_insn.LO = 1; + } + else + the_insn.LO = 0; + } + + if (the_insn.HI || the_insn.LO) + { + if (!hilo_modifier_ok (s)) + as_bad (_("Expression Error for operand modifier %%hi/%%lo\n")); + } + + /* Check for the % and $ register representation */ + if ((s[0] == '%' || s[0] == '$' || s[0] == 'r' || s[0] == 'R') + && ISDIGIT ((unsigned char) s[1])) + { + /* We have a numeric register expression. No biggy. */ + s += 1; + input_line_pointer = s; + (void) expression (operandp); + if (operandp->X_op != O_constant + || operandp->X_add_number > 31) + as_bad (_("Invalid expression after %%%%\n")); + operandp->X_op = O_register; + } + else + { + /* Normal operand parsing. */ + input_line_pointer = s; + (void) expression (operandp); + } + + new = input_line_pointer; + input_line_pointer = save; + return new; +} + +/* This function will check the opcode and return 1 if the opcode is one + of the load/store instruction, and it will fix the operand string to + the standard form so we can use the standard parse_operand routine. */ + +#define READ_OP 0x100 +#define WRITE_OP 0x200 +static char iBuf[81]; + +static char * +dlx_parse_loadop (str) + char * str; +{ + char *ptr = str; + int idx = 0; + + /* The last pair of ()/[] is the register, all other are the + reloc displacement, and if there is a register then it ought + to have a pair of ()/[] + This is not necessarily true, what if the load instruction come + without the register and with %hi/%lo modifier? */ + for (idx = 0; idx < 72 && ptr[idx] != '\0'; idx++) + ; + + if (idx == 72) + { + badoperand_load: + as_bad (_("Bad operand for a load instruction: <%s>"), str); + return NULL; + } + else + { + int i, pb = 0; + int m2 = 0; + char rs1[7], rd[7], endm, match = '0'; + char imm[72]; + + idx -= 1; + switch (str[idx]) + { + case ')': + match = '('; + endm = ')'; + break; + case ']': + match = '['; + endm = ']'; + break; + default: + /* No register indicated, fill in zero. */ + rs1[0] = 'r'; + rs1[1] = '0'; + rs1[2] = '\0'; + match = 0; + endm = 0; + m2 = 1; + } + + if (!m2) + { + /* Searching for (/[ which will match the ]/). */ + for (pb = idx - 1; str[pb] != match; pb -= 1) + /* Match can only be either '[' or '(', if it is + '(' then this can be an normal expression, we'll treat + it as an operand. */ + if (str[pb] == endm || pb < (idx - 5)) + goto load_no_rs1; + pb += 1; + + for (i = 0; (pb + i) < idx; i++) + rs1[i] = str[pb+i]; + + rs1[i] = '\0'; + + if (is_ldst_registers (& rs1[0])) + /* Point to the last character of the imm. */ + pb -= 1; + else + { + load_no_rs1: + if (match == '[') + goto badoperand_load; + /* No register indicated, fill in zero and restore the imm. */ + rs1[0] = 'r'; + rs1[1] = '0'; + rs1[2] = '\0'; + m2 = 1; + } + } + + /* Duplicate the first register. */ + for (i = 0; i < 7 && str[i] != ','; i++) + rd[i] = ptr[i]; + + if (str[i] != ',') + goto badoperand_load; + else + rd[i] = '\0'; + + /* Copy the immd. */ + if (m2) + /* Put the '\0' back in. */ + pb = idx + 1; + + for (i++, m2 = 0; i < pb; m2++,i++) + imm[m2] = ptr[i]; + + imm[m2] = '\0'; + + /* Assemble the instruction to gas intrernal format. */ + for (i = 0; rd[i] != '\0'; i++) + iBuf[i] = rd[i]; + + iBuf[i++] = ','; + + for (pb = 0 ; rs1[pb] != '\0'; i++, pb++) + iBuf[i] = rs1[pb]; + + iBuf[i++] = ','; + + for (pb = 0; imm[pb] != '\0'; i++, pb++) + iBuf[i] = imm[pb]; + + iBuf[i] = '\0'; + return iBuf; + } +} + +static char * +dlx_parse_storeop (str) + char * str; +{ + char *ptr = str; + int idx = 0; + + /* Search for the ','. */ + for (idx = 0; idx < 72 && ptr[idx] != ','; idx++) + ; + + if (idx == 72) + { + badoperand_store: + as_bad (_("Bad operand for a store instruction: <%s>"), str); + return NULL; + } + else + { + /* idx now points to the ','. */ + int i, pb = 0; + int comma = idx; + int m2 = 0; + char rs1[7], rd[7], endm, match = '0'; + char imm[72]; + + /* Now parse the '(' and ')', and make idx point to ')'. */ + idx -= 1; + switch (str[idx]) + { + case ')': + match = '('; + endm = ')'; + break; + case ']': + match = '['; + endm = ']'; + break; + default: + /* No register indicated, fill in zero. */ + rs1[0] = 'r'; + rs1[1] = '0'; + rs1[2] = '\0'; + match = 0; + endm = 0; + m2 = 1; + } + + if (!m2) + { + /* Searching for (/[ which will match the ]/). */ + for (pb = idx - 1; str[pb] != match; pb -= 1) + if (pb < (idx - 5) || str[pb] == endm) + goto store_no_rs1; + pb += 1; + + for (i = 0; (pb + i) < idx; i++) + rs1[i] = str[pb + i]; + + rs1[i] = '\0'; + + if (is_ldst_registers (& rs1[0])) + /* Point to the last character of the imm. */ + pb -= 1; + else + { + store_no_rs1: + if (match == '[') + goto badoperand_store; + + /* No register indicated, fill in zero and restore the imm. */ + rs1[0] = 'r'; + rs1[1] = '0'; + rs1[2] = '\0'; + pb = comma; + } + } + else + /* No register was specified. */ + pb = comma; + + /* Duplicate the first register. */ + for (i = comma + 1; (str[i] == ' ' || str[i] == '\t'); i++) + ; + + for (m2 = 0; (m2 < 7 && str[i] != '\0'); i++, m2++) + { + if (str[i] != ' ' && str[i] != '\t') + rd[m2] = str[i]; + else + goto badoperand_store; + } + + if (str[i] != '\0') + goto badoperand_store; + else + rd[m2] = '\0'; + + /* Copy the immd. */ + for (i = 0; i < pb; i++) + imm[i] = ptr[i]; + + imm[i] = '\0'; + + /* Assemble the instruction to gas intrernal format. */ + for (i = 0; rd[i] != '\0'; i++) + iBuf[i] = rd[i]; + iBuf[i++] = ','; + for (pb = 0 ; rs1[pb] != '\0'; i++, pb++) + iBuf[i] = rs1[pb]; + iBuf[i++] = ','; + for (pb = 0; imm[pb] != '\0'; i++, pb++) + iBuf[i] = imm[pb]; + iBuf[i] = '\0'; + return iBuf; + } +} + +static char * +fix_ld_st_operand (opcode, str) + unsigned long opcode; + char* str; +{ + /* Check the opcode. */ + switch ((int) opcode) + { + case LBOP: + case LBUOP: + case LSBUOP: + case LHOP: + case LHUOP: + case LSHUOP: + case LWOP: + case LSWOP: + return dlx_parse_loadop (str); + case SBOP: + case SHOP: + case SWOP: + return dlx_parse_storeop (str); + default: + return str; + } +} + +/* Instruction parsing. Takes a string containing the opcode. + Operands are at input_line_pointer. Output is in the_insn. + Warnings or errors are generated. */ + +static void +machine_ip (str) + char *str; +{ + char *s; + const char *args; + struct machine_opcode *insn; + char *argsStart; + unsigned long opcode; + expressionS the_operand; + expressionS *operand = &the_operand; + unsigned int reg, reg_shift = 0; + + /* Fixup the opcode string to all lower cases, and also + allow numerical digits. */ + s = str; + + if (ISALPHA (*s)) + for (; ISALNUM (*s); ++s) + if (ISUPPER (*s)) + *s = TOLOWER (*s); + + switch (*s) + { + case '\0': + break; + + /* FIXME-SOMEDAY more whitespace. */ + case ' ': + *s++ = '\0'; + break; + + default: + as_bad (_("Unknown opcode: `%s'"), str); + return; + } + + /* Hash the opcode, insn will have the string from opcode table. + also initialized the_insn struct. */ + if ((insn = (struct machine_opcode *) hash_find (op_hash, str)) == NULL) + { + /* Handle the ret and return macro here. */ + if ((strcmp (str, "ret") == 0) || (strcmp (str, "return") == 0)) + { + memset (&the_insn, '\0', sizeof (the_insn)); + the_insn.reloc = NO_RELOC; + the_insn.pcrel = 0; + the_insn.opcode = + (unsigned long)(JROP | 0x03e00000); /* 0x03e00000 = r31 << 21 */ + } + else + as_bad (_("Unknown opcode `%s'."), str); + + return; + } + + argsStart = s; + opcode = insn->opcode; + memset (&the_insn, '\0', sizeof (the_insn)); + the_insn.reloc = NO_RELOC; + the_insn.pcrel = 0; + + /* Set the sip reloc HI16 flag. */ + if (!set_dlx_skip_hi16_flag (1)) + as_bad (_("Can not set dlx_skip_hi16_flag")); + + /* Fix the operand string if it is one of load store instructions. */ + s = fix_ld_st_operand (opcode, s); + + /* Build the opcode, checking as we go to make sure that the + operands match. + If an operand matches, we modify the_insn or opcode appropriately, + and do a "continue". If an operand fails to match, we "break". */ + if (insn->args[0] != '\0' && insn->args[0] != 'N') + { + /* Prime the pump. */ + if (*s == '\0') + { + as_bad (_("Missing arguments for opcode <%s>."), str); + return; + } + else + s = parse_operand (s, operand); + } + else if (insn->args[0] == 'N') + { + /* Clean up the insn and done! */ + the_insn.opcode = opcode; + return; + } + + /* Parse through the args (this is from opcode table), *s point to + the current character of the instruction stream. */ + for (args = insn->args;; ++args) + { + switch (*args) + { + /* End of Line. */ + case '\0': + /* End of args. */ + if (*s == '\0') + { + /* We are truly done. */ + the_insn.opcode = opcode; + /* Clean up the HI and LO mark. */ + the_insn.HI = 0; + the_insn.LO = 0; + return; + } + + the_insn.HI = 0; + the_insn.LO = 0; + as_bad (_("Too many operands: %s"), s); + break; + + /* ',' Args separator */ + case ',': + /* Must match a comma. */ + if (*s++ == ',') + { + /* Parse next operand. */ + s = parse_operand (s, operand); + continue; + } + break; + + /* It can be a 'a' register or 'i' operand. */ + case 'P': + /* Macro move operand/reg. */ + if (operand->X_op == O_register) + { + /* Its a register. */ + reg_shift = 21; + goto general_reg; + } + + /* The immediate 16 bits literal, bit 0-15. */ + case 'i': + /* offset, unsigned. */ + case 'I': + /* offset, signed. */ + if (operand->X_op == O_constant) + { + if (the_insn.HI) + operand->X_add_number >>= 16; + + opcode |= operand->X_add_number & 0xFFFF; + + if (the_insn.HI && the_insn.LO) + as_bad (_("Both the_insn.HI and the_insn.LO are set : %s"), s); + else + { + the_insn.HI = 0; + the_insn.LO = 0; + } + continue; + } + + the_insn.reloc = (the_insn.HI) ? RELOC_DLX_HI16 : RELOC_DLX_16; + the_insn.reloc_offset = 2; + the_insn.size = 2; + the_insn.pcrel = 0; + the_insn.exp = * operand; + the_insn.HI = 0; + the_insn.LO = 0; + continue; + + case 'd': + /* offset, signed. */ + if (operand->X_op == O_constant) + { + opcode |= operand->X_add_number & 0xFFFF; + continue; + } + the_insn.reloc = RELOC_DLX_REL16; + the_insn.reloc_offset = 0; /* BIG-ENDIAN Byte 3 of insn. */ + the_insn.size = 4; + the_insn.pcrel = 1; + the_insn.exp = *operand; + continue; + + /* The immediate 26 bits literal, bit 0-25. */ + case 'D': + /* offset, signed. */ + if (operand->X_op == O_constant) + { + opcode |= operand->X_add_number & 0x3FFFFFF; + continue; + } + the_insn.reloc = RELOC_DLX_REL26; + the_insn.reloc_offset = 0; /* BIG-ENDIAN Byte 3 of insn. */ + the_insn.size = 4; + the_insn.pcrel = 1; + the_insn.exp = *operand; + continue; + + /* Type 'a' Register. */ + case 'a': + /* A general register at bits 21-25, rs1. */ + know (operand->X_op != O_register); + reg_shift = 21; + goto general_reg; + + /* Type 'b' Register. */ + case 'b': + /* A general register at bits 16-20, rs2/rd. */ + know (operand->X_op != O_register); + reg_shift = 16; + goto general_reg; + + /* Type 'c' Register. */ + case 'c': + /* A general register at bits 11-15, rd. */ + know (operand->X_op != O_register); + reg_shift = 11; + + general_reg: + know (operand->X_add_symbol == 0); + know (operand->X_op_symbol == 0); + reg = operand->X_add_number; + if (reg & 0xffffffe0) + as_fatal (_("failed regnum sanity check.")); + else + /* Got the register, now figure out where it goes in the opcode. */ + opcode |= reg << reg_shift; + + switch (*args) + { + case 'a': + case 'b': + case 'c': + case 'P': + continue; + } + as_fatal (_("failed general register sanity check.")); + break; + + default: + BAD_CASE (*args); + } + + /* Types or values of args don't match. */ + as_bad ("Invalid operands"); + return; + } +} + +/* This is identical to the md_atof in m68k.c. I think this is right, + but I'm not sure. + + Turn a string in input_line_pointer into a floating point constant + of type TYPE, and store the appropriate bytes in *LITP. The number + of LITTLENUMS emitted is stored in *SIZEP. An error message is + returned, or NULL on OK. */ +/* Dlx will not use it anyway, so I just leave it here for now. */ + +/* Equal to MAX_PRECISION in atof-ieee.c. */ +#define MAX_LITTLENUMS 6 + +char * +md_atof (type, litP, sizeP) + char type; + char *litP; + int *sizeP; +{ + int prec; + LITTLENUM_TYPE words[MAX_LITTLENUMS]; + LITTLENUM_TYPE *wordP; + char *t; + + switch (type) + { + case 'f': + case 'F': + case 's': + case 'S': + prec = 2; + break; + + case 'd': + case 'D': + case 'r': + case 'R': + prec = 4; + break; + + case 'x': + case 'X': + prec = 6; + break; + + case 'p': + case 'P': + prec = 6; + break; + + default: + *sizeP = 0; + return "Bad call to MD_ATOF()"; + } + + t = atof_ieee (input_line_pointer, type, words); + if (t) + input_line_pointer = t; + + *sizeP = prec * sizeof (LITTLENUM_TYPE); + + for (wordP = words; prec--;) + { + md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE)); + litP += sizeof (LITTLENUM_TYPE); + } + + return 0; +} + +/* Write out big-endian. */ +void +md_number_to_chars (buf, val, n) + char *buf; + valueT val; + int n; +{ + number_to_chars_bigendian (buf, val, n); +} + +/* md_chars_to_number: convert from target byte order to host byte order. */ + +int +md_chars_to_number (val, n) + unsigned char *val; /* Value in target byte order. */ + int n; /* Number of bytes in the input. */ +{ + int retval; + + for (retval = 0; n--;) + { + retval <<= 8; + retval |= val[n]; + } + + return retval; +} + +/* Definition of TC_FORCE_RELOCATION. + we need this for gas to force relocation for VTABLE. */ + +int +md_dlx_force_relocation (fixp) + struct fix *fixp; +{ + return (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT + || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY); +} + +boolean +md_dlx_fix_adjustable (fixP) + fixS *fixP; +{ + /* We need the symbol name for the VTABLE entries. */ + return !(fixP->fx_addsy != NULL && + (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT + || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)) ; +} + +void +md_apply_fix3 (fixP, valP, seg) + fixS *fixP; + valueT * valP; + segT seg ATTRIBUTE_UNUSED; +{ + long val = *valP; + char *place = fixP->fx_where + fixP->fx_frag->fr_literal; + + know (fixP->fx_size == 4); + know (fixP->fx_r_type < NO_RELOC); + + switch (fixP->fx_r_type) + { + case RELOC_DLX_REL16: + if (fixP->fx_bit_fixP != (bit_fixS *) NULL) + { + val = (val & 0x0000FFFF) | fixP->fx_bit_fixP->fx_bit_base; + free (fixP->fx_bit_fixP); + fixP->fx_bit_fixP = (bit_fixS *) NULL; + } +#ifdef DEBUG + else + know ((fixP->fx_bit_fixP != (bit_fixS *) NULL)); +#endif + break; + + case RELOC_DLX_HI16: + if (fixP->fx_bit_fixP != (bit_fixS *) NULL) + { + val = (val >> 16) | fixP->fx_bit_fixP->fx_bit_base; + free (fixP->fx_bit_fixP); + fixP->fx_bit_fixP = (bit_fixS *)NULL; + } +#ifdef DEBUG + else + know ((fixP->fx_bit_fixP != (bit_fixS *) NULL)); +#endif + break; + + case RELOC_DLX_REL26: + if (fixP->fx_bit_fixP != (bit_fixS *) NULL) + { + val = (val & 0x03FFFFFF) | fixP->fx_bit_fixP->fx_bit_base; + free (fixP->fx_bit_fixP); + fixP->fx_bit_fixP = (bit_fixS *) NULL; + } +#ifdef DEBUG + else + know ((fixP->fx_bit_fixP != (bit_fixS *) NULL)); +#endif + break; + + case BFD_RELOC_VTABLE_INHERIT: + /* This borrowed from tc-ppc.c on a whim. */ + fixP->fx_done = 0; + if (fixP->fx_addsy + && !S_IS_DEFINED (fixP->fx_addsy) + && !S_IS_WEAK (fixP->fx_addsy)) + S_SET_WEAK (fixP->fx_addsy); + return; + + case BFD_RELOC_VTABLE_ENTRY: + fixP->fx_done = 0; + return; + + default: + break; + } + + number_to_chars_bigendian (place, val, fixP->fx_size); + if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0) + fixP->fx_done = 1; + return; +} + +CONST char *md_shortopts = ""; + +struct option md_longopts[] = + { + {NULL, no_argument, NULL, 0} + }; + +size_t md_longopts_size = sizeof (md_longopts); + +int +md_parse_option (c, arg) + int c ATTRIBUTE_UNUSED; + char *arg ATTRIBUTE_UNUSED; +{ + return 0; +} + +void +md_show_usage (stream) + FILE *stream ATTRIBUTE_UNUSED; +{ + return; +} + +/* This is called when a line is unrecognized. */ + +int +dlx_unrecognized_line (c) + int c; +{ + int lab; + char *s; + + if (c != '$' || ! ISDIGIT ((unsigned char) input_line_pointer[0])) + return 0; + + s = input_line_pointer; + + lab = 0; + while (ISDIGIT ((unsigned char) *s)) + { + lab = lab * 10 + *s - '0'; + ++s; + } + + if (*s != ':') + { + /* Not a label definition. */ + return 0; + } + + if (dollar_label_defined (lab)) + { + as_bad (_("label \"$%d\" redefined"), lab); + return 0; + } + + define_dollar_label (lab); + colon (dollar_label_name (lab, 0)); + input_line_pointer = s + 1; + + return 1; +} + +/* Default the values of symbols known that should be "predefined". We + don't bother to predefine them unless you actually use one, since there + are a lot of them. */ + +symbolS * +md_undefined_symbol (name) + char *name ATTRIBUTE_UNUSED; +{ + return NULL; +} + + +/* Parse an operand that is machine-specific, the function was called + in expr.c by operand() function, when everything failed bdfore it + call a quit. */ + +void +md_operand (expressionP) + expressionS* expressionP; +{ + /* Check for the #number representation */ + if (input_line_pointer[0] == '#' && + ISDIGIT ((unsigned char) input_line_pointer[1])) + { + /* We have a numeric number expression. No biggy. */ + input_line_pointer += 1; /* Skip # */ + + (void) expression (expressionP); + + if (expressionP->X_op != O_constant) + as_bad (_("Invalid expression after # number\n")); + } + + return; +#if 0 + else if (input_line_pointer[0] == '$' + && ISDIGIT ((unsigned char) input_line_pointer[1])) + { + long lab; + char *name; + symbolS *sym; + + /* This is a local label. */ + ++input_line_pointer; + lab = (long) get_absolute_expression (); + if (dollar_label_defined (lab)) + { + name = dollar_label_name (lab, 0); + sym = symbol_find (name); + } + else + { + name = dollar_label_name (lab, 1); + sym = symbol_find_or_make (name); + } + + expressionP->X_op = O_symbol; + expressionP->X_add_symbol = sym; + expressionP->X_add_number = 0; + } +#endif +} + +/* Round up a section size to the appropriate boundary. */ + +valueT +md_section_align (segment, size) + segT segment ATTRIBUTE_UNUSED; + valueT size; +{ + /* Byte alignment is fine. */ + return size; +} + +/* Exactly what point is a PC-relative offset relative TO? + On the 29000, they're relative to the address of the instruction, + which we have set up as the address of the fixup too. */ + +long +md_pcrel_from (fixP) + fixS* fixP; +{ + return 4 + fixP->fx_where + fixP->fx_frag->fr_address; +} + +/* From cgen.c: */ + +#if 0 +static short +tc_bfd_fix2rtype (fixP) + fixS* fixP; +{ +#if 0 + if (fixP->fx_bsr) + abort (); +#endif + + if (fixP->fx_pcrel == 0 && fixP->fx_size == 4) + return BFD_RELOC_32; + + if (fixP->fx_pcrel != 0 && fixP->fx_size == 4) + return BFD_RELOC_26_PCREL; + + abort (); + + return 0; +} +#endif + +/* Translate internal representation of relocation info to BFD target + format. + FIXME: To what extent can we get all relevant targets to use this? + The above FIXME is from a29k, but I think it is also needed here. */ + +arelent * +tc_gen_reloc (section, fixP) + asection *section ATTRIBUTE_UNUSED; + fixS *fixP; +{ + arelent * reloc; + + reloc = (arelent *) xmalloc (sizeof (arelent)); + reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type); + + if (reloc->howto == (reloc_howto_type *) NULL) + { + as_bad_where (fixP->fx_file, fixP->fx_line, + "internal error: can't export reloc type %d (`%s')", + fixP->fx_r_type, + bfd_get_reloc_code_name (fixP->fx_r_type)); + return NULL; + } + + assert (!fixP->fx_pcrel == !reloc->howto->pc_relative); + + reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy); + reloc->address = fixP->fx_frag->fr_address + fixP->fx_where; + + if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT || + fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY) + reloc->addend = fixP->fx_offset; + else + reloc->addend = fixP->fx_addnumber; + return reloc; +} + +extern void pop_insert PARAMS ((const pseudo_typeS *)); + +void +dlx_pop_insert () +{ + pop_insert (dlx_pseudo_table); + return ; +} diff --git a/gas/config/tc-dlx.h b/gas/config/tc-dlx.h new file mode 100644 index 0000000000..cbdf7f7959 --- /dev/null +++ b/gas/config/tc-dlx.h @@ -0,0 +1,102 @@ +/* tc-dlx.h -- Assemble for the DLX + Copyright 2002 Free Software Foundation, Inc. + + This file is part of GAS, the GNU Assembler. + + GAS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GAS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GAS; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +/* Initially created by Kuang Hwa Lin, 3/20/2002. */ + +#include "write.h" /* For the definition of fixS. */ + +#define TC_DLX + +#ifndef BFD_ASSEMBLER + #error DLX support requires BFD_ASSEMBLER +#endif + +#ifndef __BFD_H_SEEN__ +#include "bfd.h" +#endif + +/* The target BFD architecture. */ +#define TARGET_ARCH bfd_arch_dlx +#define TARGET_FORMAT "elf32-dlx" +#define TARGET_BYTES_BIG_ENDIAN 1 + +#define WORKING_DOT_WORD + +#define LEX_DOLLAR 1 + +/* #define md_operand(x) */ +extern void dlx_pop_insert PARAMS ((void)); +extern int set_dlx_skip_hi16_flag PARAMS ((int)); + +#define md_pop_insert() dlx_pop_insert () + +#define md_convert_frag(b,s,f) as_fatal ("alpha convert_frag\n") +#define md_convert_frag(b,s,f) as_fatal ("alpha convert_frag\n") +#define md_estimate_size_before_relax(f,s) \ + (as_fatal ("estimate_size_before_relax called"),1) + +#define tc_unrecognized_line(c) dlx_unrecognized_line (c) + +extern int dlx_unrecognized_line PARAMS ((int)); + +#define tc_headers_hook(a) ; /* not used */ +#define tc_headers_hook(a) ; /* not used */ +#define tc_crawl_symbol_chain(a) ; /* not used */ +#define tc_coff_symbol_emit_hook(a) ; /* not used */ + +#define AOUT_MACHTYPE 101 +#define TC_COFF_FIX2RTYPE(fix_ptr) tc_coff_fix2rtype (fix_ptr) +#define BFD_ARCH bfd_arch_dlx +#define COFF_MAGIC DLXMAGIC +/* Should the reloc be output ? + on the 29k, this is true only if there is a symbol attatched. + on the h8, this is allways true, since no fixup is done + on dlx, I have no idea!! but lets keep it here just for fun. +*/ +#define TC_COUNT_RELOC(x) (x->fx_addsy) +#define TC_CONS_RELOC BFD_RELOC_32_PCREL + +/* We need to force out some relocations when relaxing. */ +#define TC_FORCE_RELOCATION(fix) md_dlx_force_relocation (fix) +struct fix; +extern int md_dlx_force_relocation PARAMS ((struct fix *)); + +#define obj_fix_adjustable(fixP) md_dlx_fix_adjustable(fixP) +struct fix; +extern boolean md_dlx_fix_adjustable PARAMS ((struct fix *)); + +/* This arranges for gas/write.c to not apply a relocation if + obj_fix_adjustable() says it is not adjustable. */ +#define TC_FIX_ADJUSTABLE(fixP) obj_fix_adjustable (fixP) + +#define NEED_FX_R_TYPE + +/* Zero Based Segment?? sound very dangerous to me! */ +#define ZERO_BASED_SEGMENTS + +/* Permit temporary numeric labels. */ +#define LOCAL_LABELS_FB 1 +#ifdef LOCAL_LABELS_DOLLAR +#undef LOCAL_LABELS_DOLLAR +#endif +#define LOCAL_LABELS_DOLLAR 0 + +#define DIFF_EXPR_OK /* .-foo gets turned into PC relative relocs */ + diff --git a/gas/configure b/gas/configure index 45e013a5fb..a2beaaf04c 100755 --- a/gas/configure +++ b/gas/configure @@ -2361,6 +2361,7 @@ for this_target in $target $canon_targets ; do d10v-*-*) fmt=elf bfd_gas=yes ;; d30v-*-*) fmt=elf bfd_gas=yes ;; + dlx-*-*) fmt=elf ;; fr30-*-*) fmt=elf bfd_gas=yes ;; @@ -3143,7 +3144,7 @@ EOF # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:3147: checking for $ac_word" >&5 +echo "configure:3148: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3173,7 +3174,7 @@ if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:3177: checking for $ac_word" >&5 +echo "configure:3178: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3224,7 +3225,7 @@ fi # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:3228: checking for $ac_word" >&5 +echo "configure:3229: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3256,7 +3257,7 @@ fi fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:3260: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 +echo "configure:3261: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. @@ -3267,12 +3268,12 @@ cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF -#line 3271 "configure" +#line 3272 "configure" #include "confdefs.h" main(){return(0);} EOF -if { (eval echo configure:3276: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3277: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then @@ -3298,12 +3299,12 @@ if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:3302: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "configure:3303: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:3307: checking whether we are using GNU C" >&5 +echo "configure:3308: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3312,7 +3313,7 @@ else yes; #endif EOF -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:3316: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:3317: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -3331,7 +3332,7 @@ ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:3335: checking whether ${CC-cc} accepts -g" >&5 +echo "configure:3336: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3368,7 +3369,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:3372: checking for $ac_word" >&5 +echo "configure:3373: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3399,7 +3400,7 @@ done test -n "$YACC" || YACC="yacc" echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:3403: checking how to run the C preprocessor" >&5 +echo "configure:3404: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -3414,13 +3415,13 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3424: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3425: \"$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 : @@ -3431,13 +3432,13 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3441: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3442: \"$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 : @@ -3448,13 +3449,13 @@ else rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3458: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3459: \"$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 : @@ -3484,7 +3485,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:3488: checking for $ac_word" >&5 +echo "configure:3489: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3517,7 +3518,7 @@ test -n "$LEX" || LEX="$missing_dir/missing flex" # Extract the first word of "flex", so it can be a program name with args. set dummy flex; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:3521: checking for $ac_word" >&5 +echo "configure:3522: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3551,7 +3552,7 @@ then *) ac_lib=l ;; esac echo $ac_n "checking for yywrap in -l$ac_lib""... $ac_c" 1>&6 -echo "configure:3555: checking for yywrap in -l$ac_lib" >&5 +echo "configure:3556: checking for yywrap in -l$ac_lib" >&5 ac_lib_var=`echo $ac_lib'_'yywrap | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -3559,7 +3560,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$ac_lib $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3575: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -3593,7 +3594,7 @@ fi fi echo $ac_n "checking lex output file root""... $ac_c" 1>&6 -echo "configure:3597: checking lex output file root" >&5 +echo "configure:3598: checking lex output file root" >&5 if eval "test \"`echo '$''{'ac_cv_prog_lex_root'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3614,7 +3615,7 @@ echo "$ac_t""$ac_cv_prog_lex_root" 1>&6 LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root echo $ac_n "checking whether yytext is a pointer""... $ac_c" 1>&6 -echo "configure:3618: checking whether yytext is a pointer" >&5 +echo "configure:3619: checking whether yytext is a pointer" >&5 if eval "test \"`echo '$''{'ac_cv_prog_lex_yytext_pointer'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3626,14 +3627,14 @@ echo 'extern char *yytext;' >>$LEX_OUTPUT_ROOT.c ac_save_LIBS="$LIBS" LIBS="$LIBS $LEXLIB" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3638: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_prog_lex_yytext_pointer=yes else @@ -3659,7 +3660,7 @@ ALL_LINGUAS="fr tr es" # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:3663: checking for $ac_word" >&5 +echo "configure:3664: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3687,12 +3688,12 @@ else fi echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:3691: checking for ANSI C header files" >&5 +echo "configure:3692: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -3700,7 +3701,7 @@ else #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3704: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3705: \"$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* @@ -3717,7 +3718,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -3735,7 +3736,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -3756,7 +3757,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -3767,7 +3768,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -if { (eval echo configure:3771: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:3772: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else @@ -3791,12 +3792,12 @@ EOF fi echo $ac_n "checking for working const""... $ac_c" 1>&6 -echo "configure:3795: checking for working const" >&5 +echo "configure:3796: checking for working const" >&5 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3850: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else @@ -3866,21 +3867,21 @@ EOF fi echo $ac_n "checking for inline""... $ac_c" 1>&6 -echo "configure:3870: checking for inline" >&5 +echo "configure:3871: checking for inline" >&5 if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3885: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_inline=$ac_kw; break else @@ -3906,12 +3907,12 @@ EOF esac echo $ac_n "checking for off_t""... $ac_c" 1>&6 -echo "configure:3910: checking for off_t" >&5 +echo "configure:3911: checking for off_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -3939,12 +3940,12 @@ EOF fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 -echo "configure:3943: checking for size_t" >&5 +echo "configure:3944: checking for size_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -3974,19 +3975,19 @@ fi # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 -echo "configure:3978: checking for working alloca.h" >&5 +echo "configure:3979: checking for working alloca.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { char *p = alloca(2 * sizeof(int)); ; return 0; } EOF -if { (eval echo configure:3990: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3991: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_header_alloca_h=yes else @@ -4007,12 +4008,12 @@ EOF fi echo $ac_n "checking for alloca""... $ac_c" 1>&6 -echo "configure:4011: checking for alloca" >&5 +echo "configure:4012: checking for alloca" >&5 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4045: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_alloca_works=yes else @@ -4072,12 +4073,12 @@ EOF echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 -echo "configure:4076: checking whether alloca needs Cray hooks" >&5 +echo "configure:4077: checking whether alloca needs Cray hooks" >&5 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&6 if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4106: checking for $ac_func" >&5 +echo "configure:4107: 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 <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4135: \"$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 @@ -4157,7 +4158,7 @@ done fi echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 -echo "configure:4161: checking stack direction for C alloca" >&5 +echo "configure:4162: checking stack direction for C alloca" >&5 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4165,7 +4166,7 @@ else ac_cv_c_stack_direction=0 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:4189: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_stack_direction=1 else @@ -4205,21 +4206,21 @@ EOF fi -for ac_hdr in unistd.h +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:4213: checking for $ac_hdr" >&5 +echo "configure:4214: 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 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4223: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4224: \"$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* @@ -4248,12 +4249,12 @@ done for ac_func in getpagesize do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4252: checking for $ac_func" >&5 +echo "configure:4253: 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 <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4281: \"$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 @@ -4301,7 +4302,7 @@ fi done echo $ac_n "checking for working mmap""... $ac_c" 1>&6 -echo "configure:4305: checking for working mmap" >&5 +echo "configure:4306: 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 @@ -4309,7 +4310,7 @@ else ac_cv_func_mmap_fixed_mapped=no else cat > conftest.$ac_ext < #include +#if HAVE_SYS_TYPES_H +# include +#endif + +#if HAVE_STDLIB_H +# include +#endif + +#if HAVE_SYS_STAT_H +# include +#endif + +#if HAVE_UNISTD_H +# include +#endif + /* This mess was copied from the GNU getpagesize.h. */ #ifndef HAVE_GETPAGESIZE -# ifdef HAVE_UNISTD_H -# include -# endif /* Assume that all systems that can run configure have sys/param.h. */ # ifndef HAVE_SYS_PARAM_H @@ -4449,7 +4463,7 @@ main() } EOF -if { (eval echo configure:4453: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:4467: \"$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 @@ -4477,17 +4491,17 @@ unistd.h values.h sys/param.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:4481: checking for $ac_hdr" >&5 +echo "configure:4495: 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 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4491: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4505: \"$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* @@ -4517,12 +4531,12 @@ done __argz_count __argz_stringify __argz_next do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4521: checking for $ac_func" >&5 +echo "configure:4535: 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 <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4563: \"$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 @@ -4574,12 +4588,12 @@ done for ac_func in stpcpy do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4578: checking for $ac_func" >&5 +echo "configure:4592: 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 <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4620: \"$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 @@ -4636,19 +4650,19 @@ EOF if test $ac_cv_header_locale_h = yes; then echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6 -echo "configure:4640: checking for LC_MESSAGES" >&5 +echo "configure:4654: checking for LC_MESSAGES" >&5 if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { return LC_MESSAGES ; return 0; } EOF -if { (eval echo configure:4652: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4666: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* am_cv_val_LC_MESSAGES=yes else @@ -4669,7 +4683,7 @@ EOF fi fi echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6 -echo "configure:4673: checking whether NLS is requested" >&5 +echo "configure:4687: checking whether NLS is requested" >&5 # Check whether --enable-nls or --disable-nls was given. if test "${enable_nls+set}" = set; then enableval="$enable_nls" @@ -4689,7 +4703,7 @@ fi EOF echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6 -echo "configure:4693: checking whether included gettext is requested" >&5 +echo "configure:4707: checking whether included gettext is requested" >&5 # Check whether --with-included-gettext or --without-included-gettext was given. if test "${with_included_gettext+set}" = set; then withval="$with_included_gettext" @@ -4708,17 +4722,17 @@ fi ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for libintl.h""... $ac_c" 1>&6 -echo "configure:4712: checking for libintl.h" >&5 +echo "configure:4726: checking for libintl.h" >&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 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4722: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4736: \"$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* @@ -4735,19 +4749,19 @@ fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6 -echo "configure:4739: checking for gettext in libc" >&5 +echo "configure:4753: checking for gettext in libc" >&5 if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { return (int) gettext ("") ; return 0; } EOF -if { (eval echo configure:4751: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4765: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* gt_cv_func_gettext_libc=yes else @@ -4763,7 +4777,7 @@ echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6 if test "$gt_cv_func_gettext_libc" != "yes"; then echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6 -echo "configure:4767: checking for bindtextdomain in -lintl" >&5 +echo "configure:4781: checking for bindtextdomain in -lintl" >&5 ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4771,7 +4785,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lintl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4800: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4798,19 +4812,19 @@ fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6 -echo "configure:4802: checking for gettext in libintl" >&5 +echo "configure:4816: checking for gettext in libintl" >&5 if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4828: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* gt_cv_func_gettext_libintl=yes else @@ -4838,7 +4852,7 @@ EOF # Extract the first word of "msgfmt", so it can be a program name with args. set dummy msgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:4842: checking for $ac_word" >&5 +echo "configure:4856: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4872,12 +4886,12 @@ fi for ac_func in dcgettext do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4876: checking for $ac_func" >&5 +echo "configure:4890: 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 <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4918: \"$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 @@ -4927,7 +4941,7 @@ done # Extract the first word of "gmsgfmt", so it can be a program name with args. set dummy gmsgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:4931: checking for $ac_word" >&5 +echo "configure:4945: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4963,7 +4977,7 @@ fi # Extract the first word of "xgettext", so it can be a program name with args. set dummy xgettext; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:4967: checking for $ac_word" >&5 +echo "configure:4981: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4995,7 +5009,7 @@ else fi cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5021: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* CATOBJEXT=.gmo DATADIRNAME=share @@ -5035,7 +5049,7 @@ fi # Extract the first word of "msgfmt", so it can be a program name with args. set dummy msgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:5039: checking for $ac_word" >&5 +echo "configure:5053: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5069,7 +5083,7 @@ fi # Extract the first word of "gmsgfmt", so it can be a program name with args. set dummy gmsgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:5073: checking for $ac_word" >&5 +echo "configure:5087: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5105,7 +5119,7 @@ fi # Extract the first word of "xgettext", so it can be a program name with args. set dummy xgettext; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:5109: checking for $ac_word" >&5 +echo "configure:5123: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5195,7 +5209,7 @@ fi LINGUAS= else echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6 -echo "configure:5199: checking for catalogs to be installed" >&5 +echo "configure:5213: checking for catalogs to be installed" >&5 NEW_LINGUAS= for lang in ${LINGUAS=$ALL_LINGUAS}; do case "$ALL_LINGUAS" in @@ -5223,17 +5237,17 @@ echo "configure:5199: checking for catalogs to be installed" >&5 if test "$CATOBJEXT" = ".cat"; then ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6 -echo "configure:5227: checking for linux/version.h" >&5 +echo "configure:5241: checking for linux/version.h" >&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 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5237: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5251: \"$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* @@ -5296,7 +5310,7 @@ fi echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6 -echo "configure:5300: checking whether to enable maintainer-specific portions of Makefiles" >&5 +echo "configure:5314: checking whether to enable maintainer-specific portions of Makefiles" >&5 # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. if test "${enable_maintainer_mode+set}" = set; then enableval="$enable_maintainer_mode" @@ -5321,7 +5335,7 @@ fi echo $ac_n "checking for executable suffix""... $ac_c" 1>&6 -echo "configure:5325: checking for executable suffix" >&5 +echo "configure:5339: checking for executable suffix" >&5 if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5331,7 +5345,7 @@ else rm -f conftest* echo 'int main () { return 0; }' > conftest.$ac_ext ac_cv_exeext= - if { (eval echo configure:5335: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then + if { (eval echo configure:5349: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then for file in conftest.*; do case $file in *.c | *.o | *.obj) ;; @@ -5356,17 +5370,17 @@ for ac_hdr in string.h stdlib.h memory.h strings.h unistd.h stdarg.h varargs.h e do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:5360: checking for $ac_hdr" >&5 +echo "configure:5374: 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 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5370: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5384: \"$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* @@ -5396,7 +5410,7 @@ done # Put this here so that autoconf's "cross-compiling" message doesn't confuse # people who are not cross-compiling but are compiling cross-assemblers. echo $ac_n "checking whether compiling a cross-assembler""... $ac_c" 1>&6 -echo "configure:5400: checking whether compiling a cross-assembler" >&5 +echo "configure:5414: checking whether compiling a cross-assembler" >&5 if test "${host}" = "${target}"; then cross_gas=no else @@ -5411,19 +5425,19 @@ echo "$ac_t""$cross_gas" 1>&6 # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 -echo "configure:5415: checking for working alloca.h" >&5 +echo "configure:5429: checking for working alloca.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { char *p = alloca(2 * sizeof(int)); ; return 0; } EOF -if { (eval echo configure:5427: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5441: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_header_alloca_h=yes else @@ -5444,12 +5458,12 @@ EOF fi echo $ac_n "checking for alloca""... $ac_c" 1>&6 -echo "configure:5448: checking for alloca" >&5 +echo "configure:5462: checking for alloca" >&5 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5495: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_alloca_works=yes else @@ -5509,12 +5523,12 @@ EOF echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 -echo "configure:5513: checking whether alloca needs Cray hooks" >&5 +echo "configure:5527: checking whether alloca needs Cray hooks" >&5 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&6 if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5543: checking for $ac_func" >&5 +echo "configure:5557: 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 <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5585: \"$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 @@ -5594,7 +5608,7 @@ done fi echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 -echo "configure:5598: checking stack direction for C alloca" >&5 +echo "configure:5612: checking stack direction for C alloca" >&5 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5602,7 +5616,7 @@ else ac_cv_c_stack_direction=0 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:5639: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_stack_direction=1 else @@ -5643,21 +5657,21 @@ EOF fi echo $ac_n "checking for inline""... $ac_c" 1>&6 -echo "configure:5647: checking for inline" >&5 +echo "configure:5661: checking for inline" >&5 if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5675: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_inline=$ac_kw; break else @@ -5687,12 +5701,12 @@ esac for ac_func in unlink remove do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5691: checking for $ac_func" >&5 +echo "configure:5705: 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 <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5733: \"$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 @@ -5744,12 +5758,12 @@ done for ac_func in sbrk do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5748: checking for $ac_func" >&5 +echo "configure:5762: 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 <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5790: \"$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 @@ -5807,7 +5821,7 @@ case $host in ;; *-ncr-sysv4.3*) echo $ac_n "checking for _mwvalidcheckl in -lmw""... $ac_c" 1>&6 -echo "configure:5811: checking for _mwvalidcheckl in -lmw" >&5 +echo "configure:5825: checking for _mwvalidcheckl in -lmw" >&5 ac_lib_var=`echo mw'_'_mwvalidcheckl | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5815,7 +5829,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lmw $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5844: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5847,7 +5861,7 @@ else fi echo $ac_n "checking for main in -lm""... $ac_c" 1>&6 -echo "configure:5851: checking for main in -lm" >&5 +echo "configure:5865: checking for main in -lm" >&5 ac_lib_var=`echo m'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5855,14 +5869,14 @@ else ac_save_LIBS="$LIBS" LIBS="-lm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5880: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5885,7 +5899,7 @@ fi ;; *) echo $ac_n "checking for main in -lm""... $ac_c" 1>&6 -echo "configure:5889: checking for main in -lm" >&5 +echo "configure:5903: checking for main in -lm" >&5 ac_lib_var=`echo m'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5893,14 +5907,14 @@ else ac_save_LIBS="$LIBS" LIBS="-lm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5918: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5931,12 +5945,12 @@ esac # enough, but on some of those systems, the assert macro relies on requoting # working properly! echo $ac_n "checking for working assert macro""... $ac_c" 1>&6 -echo "configure:5935: checking for working assert macro" >&5 +echo "configure:5949: checking for working assert macro" >&5 if eval "test \"`echo '$''{'gas_cv_assert_ok'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -5952,7 +5966,7 @@ assert (a == b ; return 0; } EOF -if { (eval echo configure:5956: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5970: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* gas_cv_assert_ok=yes else @@ -5993,12 +6007,12 @@ gas_test_headers=" " echo $ac_n "checking whether declaration is required for strstr""... $ac_c" 1>&6 -echo "configure:5997: checking whether declaration is required for strstr" >&5 +echo "configure:6011: checking whether declaration is required for strstr" >&5 if eval "test \"`echo '$''{'gas_cv_decl_needed_strstr'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6027: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* gas_cv_decl_needed_strstr=no else @@ -6030,12 +6044,12 @@ fi echo $ac_n "checking whether declaration is required for malloc""... $ac_c" 1>&6 -echo "configure:6034: checking whether declaration is required for malloc" >&5 +echo "configure:6048: checking whether declaration is required for malloc" >&5 if eval "test \"`echo '$''{'gas_cv_decl_needed_malloc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6064: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* gas_cv_decl_needed_malloc=no else @@ -6067,12 +6081,12 @@ fi echo $ac_n "checking whether declaration is required for free""... $ac_c" 1>&6 -echo "configure:6071: checking whether declaration is required for free" >&5 +echo "configure:6085: checking whether declaration is required for free" >&5 if eval "test \"`echo '$''{'gas_cv_decl_needed_free'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6101: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* gas_cv_decl_needed_free=no else @@ -6104,12 +6118,12 @@ fi echo $ac_n "checking whether declaration is required for sbrk""... $ac_c" 1>&6 -echo "configure:6108: checking whether declaration is required for sbrk" >&5 +echo "configure:6122: checking whether declaration is required for sbrk" >&5 if eval "test \"`echo '$''{'gas_cv_decl_needed_sbrk'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6138: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* gas_cv_decl_needed_sbrk=no else @@ -6141,12 +6155,12 @@ fi echo $ac_n "checking whether declaration is required for environ""... $ac_c" 1>&6 -echo "configure:6145: checking whether declaration is required for environ" >&5 +echo "configure:6159: checking whether declaration is required for environ" >&5 if eval "test \"`echo '$''{'gas_cv_decl_needed_environ'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6175: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* gas_cv_decl_needed_environ=no else @@ -6181,12 +6195,12 @@ fi # for it? echo $ac_n "checking whether declaration is required for errno""... $ac_c" 1>&6 -echo "configure:6185: checking whether declaration is required for errno" >&5 +echo "configure:6199: checking whether declaration is required for errno" >&5 if eval "test \"`echo '$''{'gas_cv_decl_needed_errno'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6219: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* gas_cv_decl_needed_errno=no else diff --git a/gas/configure.in b/gas/configure.in index fcbac092d1..a13ea65d05 100644 --- a/gas/configure.in +++ b/gas/configure.in @@ -211,6 +211,7 @@ changequote([,])dnl d10v-*-*) fmt=elf bfd_gas=yes ;; d30v-*-*) fmt=elf bfd_gas=yes ;; + dlx-*-*) fmt=elf ;; fr30-*-*) fmt=elf bfd_gas=yes ;; diff --git a/gas/doc/Makefile.in b/gas/doc/Makefile.in index 5c7b067570..25daeaf19f 100644 --- a/gas/doc/Makefile.in +++ b/gas/doc/Makefile.in @@ -193,7 +193,7 @@ DIST_COMMON = 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/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index f443499138..dde62c57d4 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,20 @@ +2002-05-28 Kuang Hwa Lin + + * gas/dlx: New directory: DLX gas testsuite + * alltests.exp: New file: Test driver + * branch.d: New file: Expected results. + * branch.s: New file: Test branch insns. + * itype.d: New file: Expected results. + * itype.s: New file: Test ordinary insns. + * lhi.d: New file: Expected results. + * lhi.s: New file: Test load hi insns. + * load.d: New file: Expected results. + * load.s: New file: Test load insns. + * rtype.d: New file: Expected results. + * rtype.s: New file: Test arithmetic insns. + * store.d: New file: Expected results. + * store.s: New file: Test store insns. + 2002-05-23 Tom Rix * gas/d10v/d10v.exp: Add instruction packing test. diff --git a/gas/testsuite/gas/dlx/alltests.exp b/gas/testsuite/gas/dlx/alltests.exp new file mode 100644 index 0000000000..003448bc68 --- /dev/null +++ b/gas/testsuite/gas/dlx/alltests.exp @@ -0,0 +1,10 @@ +# DLX assembler testsuite. + +if [istarget dlx*-*-*] { + run_dump_test "branch" + run_dump_test "itype" + run_dump_test "lhi" + run_dump_test "load" + run_dump_test "rtype" + run_dump_test "store" +} diff --git a/gas/testsuite/gas/dlx/branch.d b/gas/testsuite/gas/dlx/branch.d new file mode 100644 index 0000000000..d34048e103 --- /dev/null +++ b/gas/testsuite/gas/dlx/branch.d @@ -0,0 +1,43 @@ +#as: +#objdump: -dr +#name: branch + +.*: +file format .* + +Disassembly of section .text: + +00000000 : + 0: 10 80 00 38 beqz r4,0x0000003c + 4: 00 00 00 00 nop + 8: 14 a0 ff f4 bnez r5,0x00000000 + +0000000c : + c: 20 04 00 44 addi r4,r0,0x0044 + e: R_DLX_RELOC_16 .text + 10: 08 00 00 30 j 0x00000044 + 14: 00 00 00 00 nop + 18: 0c 00 00 20 jal 0x0000003c + 1c: 00 00 00 00 nop + 20: 50 00 00 18 break 0x0000003c + 24: 00 00 00 00 nop + 28: 47 ff ff d4 trap 0x00000000 + 2c: 00 00 00 00 nop + 30: 4a 20 00 00 jr r17 + 34: 00 00 00 00 nop + 38: 4e 20 00 00 jalr r17 + +0000003c : + 3c: 8c 42 00 88 lw r2,0x0088\[r2\] + 40: 40 00 00 00 rfe 0x00000044 + +00000044 : + 44: 8c 02 00 00 lw r2,0x0000\[r0\] + 46: R_DLX_RELOC_16 .text + 48: 0b ff ff b4 j 0x00000000 + 4c: 00 00 00 00 nop + 50: 4b e0 00 00 jr r31 + 54: 00 00 00 00 nop + 58: 4b e0 00 00 jr r31 + 5c: 00 00 00 00 nop + 60: 48 20 00 00 jr r1 + 64: 00 00 00 00 nop diff --git a/gas/testsuite/gas/dlx/branch.s b/gas/testsuite/gas/dlx/branch.s new file mode 100644 index 0000000000..a61f1d0a43 --- /dev/null +++ b/gas/testsuite/gas/dlx/branch.s @@ -0,0 +1,31 @@ +.text +L1: +1: beqz r4, L4 + nop + bnez r5, 1b +L2: + mov r4, L5 + j L5 + nop + jal L4 + nop + break L4 + nop + trap 1b + nop + jr s1 + nop + jalr s1 +L4: + lw r2, 8+((L5 - L4)<<4)(r2) + rfe +L5: + lw r2, L1 + call 1b + nop + return + nop + ret + nop + retr at + nop diff --git a/gas/testsuite/gas/dlx/itype.d b/gas/testsuite/gas/dlx/itype.d new file mode 100644 index 0000000000..845ae4162e --- /dev/null +++ b/gas/testsuite/gas/dlx/itype.d @@ -0,0 +1,40 @@ +#as: +#objdump: -dr +#name: itype + +.*: +file format .* + +Disassembly of section .text: + +00000000 <.text>: + 0: 20 23 7f ff addi r3,r1,0x7fff + 4: 24 23 ff fb addui r3,r1,0xfffb + 8: 28 44 00 30 subi r4,r2,0x0030 + c: 2c 44 00 00 subui r4,r2,0x0000 + e: R_DLX_RELOC_16_HI .text + 10: 30 c5 00 00 andi r5,r6,0x0000 + 12: R_DLX_RELOC_16 .text + 14: 35 4c 00 78 ori r12,r10,0x0078 + 18: 39 af 00 00 xori r15,r13,0x0000 + 1a: R_DLX_RELOC_16 .text + 1c: da 30 00 1c slli r16,r17,0x001c + 1e: R_DLX_RELOC_16 .text + 20: e2 93 00 0f srai r19,r20,0x000f + 24: de f6 ff ff srli r22,r23,0xffff + 28: 63 0f 7f ff seqi r15,r24,0x7fff + 2c: 67 0f 7f ff snei r15,r24,0x7fff + 30: 6b 0f 7f ff slti r15,r24,0x7fff + 34: 6f 7a 00 00 sgti r26,r27,0x0000 + 38: 73 bc a3 29 slei r28,r29,0xa329 + 3c: 75 af 00 30 sgei r15,r13,0x0030 + 40: c3 0f 7f ff sequi r15,r24,0x7fff + 44: c7 0f 7f ff sneui r15,r24,0x7fff + 48: cb 0f 7f ff sltui r15,r24,0x7fff + 4c: cf 7a 00 00 sgtui r26,r27,0x0000 + 50: d3 bc ff fd sleui r28,r29,0xfffd + 54: d5 af 00 30 sgeui r15,r13,0x0030 + 58: 20 01 80 03 addi r1,r0,0x8003 + 5c: 21 28 00 00 addi r8,r9,0x0000 + 60: 24 01 00 00 addui r1,r0,0x0000 + 62: R_DLX_RELOC_16_HI .text + 64: 25 28 00 00 addui r8,r9,0x0000 diff --git a/gas/testsuite/gas/dlx/itype.s b/gas/testsuite/gas/dlx/itype.s new file mode 100644 index 0000000000..45506842b3 --- /dev/null +++ b/gas/testsuite/gas/dlx/itype.s @@ -0,0 +1,30 @@ +.text +2: addi $3,$1,32767 + addui r3,r1,-5 + subi r4,r2,0x30 + subui r4,r2,%hi(2b) + andi a1,a2,2b + ori t4,t2,'x' + xori t7,t5,%lo(2b) +1: slli s0,s1,1b + srai s3,s4,15 + srli s6,s7,0xffff + + seqi t7,t8,0x7fff + snei t7,t8,0x7fff + slti t7,t8,0x7fff + sgti k0,k1,0 + slei gp,sp,-23767 + sgei t7,t5,'0' + + sequi t7,t8,0x7fff + sneui t7,t8,0x7fff + sltui t7,t8,0x7fff + sgtui k0,k1,0 + sleui gp,sp,-3 + sgeui t7,t5,'0' + + mov at,-32765 + mov t0,t1 + movu at,%hi(1b) + movu t0,t1 diff --git a/gas/testsuite/gas/dlx/lhi.d b/gas/testsuite/gas/dlx/lhi.d new file mode 100644 index 0000000000..db3b35d659 --- /dev/null +++ b/gas/testsuite/gas/dlx/lhi.d @@ -0,0 +1,23 @@ +#as: +#objdump: -dr +#name: itype + +.*: +file format .* + +Disassembly of section .text: + +00000000 <.text>: + 0: 3c 03 7f ff lhi r3,0x7fff + 4: 3c 03 00 00 lhi r3,0x0000 + 6: R_DLX_RELOC_16_HI .text + 8: 3c 04 00 00 lhi r4,0x0000 + a: R_DLX_RELOC_16 .text + c: 3c 04 ff fb lhi r4,0xfffb + e: R_DLX_RELOC_16 .text + 10: 3c 04 00 0c lhi r4,0x000c + 14: 20 04 00 00 addi r4,r0,0x0000 + 18: 20 04 00 00 addi r4,r0,0x0000 + 1a: R_DLX_RELOC_16_HI .text + 1c: 34 84 00 18 ori r4,r4,0x0018 + 1e: R_DLX_RELOC_16 .text + 20: 20 64 00 00 addi r4,r3,0x0000 diff --git a/gas/testsuite/gas/dlx/lhi.s b/gas/testsuite/gas/dlx/lhi.s new file mode 100644 index 0000000000..9b56bb5b9f --- /dev/null +++ b/gas/testsuite/gas/dlx/lhi.s @@ -0,0 +1,10 @@ +.text +2: lhi $3,32767 + lui r3,%hi(2b) + sethi r4,%lo(2b) + lui r4, 2b - 5 + sethi r4,('9' - '0') + ('3' - '0') + mov r4,%hi(. - 2b) + mov r4,%hi(.) + ori r4,r4,%lo(. - 4) + mov r4,r3 diff --git a/gas/testsuite/gas/dlx/load.d b/gas/testsuite/gas/dlx/load.d new file mode 100644 index 0000000000..64ec5514e7 --- /dev/null +++ b/gas/testsuite/gas/dlx/load.d @@ -0,0 +1,33 @@ +#as: +#objdump: -dr +#name: load + +.*: +file format .* + +Disassembly of section .text: + +00000000 : + 0: 80 03 00 00 lb r3,0x0000\[r0\] + 2: R_DLX_RELOC_16_HI .text + 4: 80 43 00 00 lb r3,0x0000\[r2\] + 8: 80 03 00 00 lb r3,0x0000\[r0\] + a: R_DLX_RELOC_16_HI .text + c: 90 43 00 00 lbu r3,0x0000\[r2\] + +00000010 : + 10: 84 a3 00 00 lh r3,0x0000\[r5\] + 12: R_DLX_RELOC_16_HI .text + 14: 95 e3 00 08 lhu r3,0x0008\[r15\] + 18: 8c 41 7f ff lw r1,0x7fff\[r2\] + 1c: 8c 01 00 08 lw r1,0x0008\[r0\] + 1e: R_DLX_RELOC_16 .text + 20: 00 00 10 00 nop + 24: 00 00 20 00 nop + 28: 74 68 69 73 sgei r8,r3,0x6973 + 2c: 20 69 73 20 addi r9,r3,0x7320 + 30: 61 20 74 65 seqi r0,r9,0x7465 + 34: 73 74 00 00 slei r20,r27,0x0000 + ... + 40: 98 43 00 00 ldstbu r3,0x0000\[r2\] + 44: 9c 43 00 00 ldsthu r3,0x0000\[r2\] + 48: b0 43 00 00 ldstw r3,0x0000\[r2\] diff --git a/gas/testsuite/gas/dlx/load.s b/gas/testsuite/gas/dlx/load.s new file mode 100644 index 0000000000..417a58a016 --- /dev/null +++ b/gas/testsuite/gas/dlx/load.s @@ -0,0 +1,19 @@ +.text + lb %3,%hi(L) + lb %3,%hi(L - 7f + ((4f - 5f)<<4))(r2) +2: lb %3,%hi(1f) +1: lbu %3,%hi((4f - 5f) + 8 - ((5f - 4f)<<4))(r2) +7: +L: + lh r3,%hi(5f)[r5] +5: lhu v1,('8' - '0')(t7) + lw r1,32767($2) + lw r1,2b + .word 0x1000 + .long 0x2000 +4: + .asciz "this is a test" + .align 4 + ldstbu %3,%hi((4b - 5b) + 8 - ((5b - 4b)<<4))(r2) + ldsthu %3,%hi((4b - 5b) + 8 - ((5b - 4b)<<4))(r2) + ldstw %3,%hi((4b - 5b) + 8 - ((5b - 4b)<<4))(r2) diff --git a/gas/testsuite/gas/dlx/rtype.d b/gas/testsuite/gas/dlx/rtype.d new file mode 100644 index 0000000000..0d48e639eb --- /dev/null +++ b/gas/testsuite/gas/dlx/rtype.d @@ -0,0 +1,38 @@ +#as: +#objdump: -dr +#name: rtype + +.*: +file format .* + +Disassembly of section .text: + +00000000 <.text>: + 0: 00 22 18 20 add r3,r1,r2 + 4: 00 22 18 20 add r3,r1,r2 + 8: 00 22 18 21 addu r3,r1,r2 + c: 00 43 20 22 sub r4,r2,r3 + 10: 00 43 20 23 subu r4,r2,r3 + 14: 00 c7 28 05 mult r5,r6,r7 + 18: 01 4b 60 06 multu r12,r10,r11 + 1c: 01 ae 78 07 div r15,r13,r14 + 20: 02 32 80 08 divu r16,r17,r18 + 24: 02 95 98 24 and r19,r20,r21 + 28: 02 e0 b0 25 or r22,r23,r0 + 2c: 03 19 78 26 xor r15,r24,r25 + 30: 03 60 d0 04 sll r26,r27,r0 + 34: 03 be e0 07 div r28,r29,r30 + 38: 01 bf 78 06 multu r15,r13,r31 + 3c: 00 43 08 28 seq r1,r2,r3 + 40: 03 e0 20 29 sne r4,r31,r0 + 44: 01 2a 40 2a slt r8,r9,r10 + 48: 00 a6 38 2b sgt r7,r5,r6 + 4c: 00 a6 38 2c sle r7,r5,r6 + 50: 00 a6 38 2d sge r7,r5,r6 + 54: 00 43 08 28 seq r1,r2,r3 + 58: 03 e0 20 29 sne r4,r31,r0 + 5c: 01 2a 40 2a slt r8,r9,r10 + 60: 00 a6 38 2b sgt r7,r5,r6 + 64: 00 a6 38 2c sle r7,r5,r6 + 68: 00 a6 38 2d sge r7,r5,r6 + 6c: 00 a0 50 30 mvts r10,r5 + 70: 00 a0 50 31 mvfs r10,r5 diff --git a/gas/testsuite/gas/dlx/rtype.s b/gas/testsuite/gas/dlx/rtype.s new file mode 100644 index 0000000000..c091f1ed3d --- /dev/null +++ b/gas/testsuite/gas/dlx/rtype.s @@ -0,0 +1,33 @@ +.text +1: add $3,$1,$2 + add %3,%1,%2 + addu r3,r1,r2 + sub r4,r2,r3 + subu r4,r2,r3 + mult a1,a2,a3 + multu t4,t2,t3 + div t7,t5,t6 + divu s0,s1,s2 + and s3,s4,s5 + or s6,s7,zero + xor t7,t8,t9 + sll k0,k1,zero + sra gp,sp,fp + srl t7,t5,ra + + seq at,v0,v1 + sne a0,ra,zero + slt t0,t1,t2 + sgt $7,%5,r6 + sle r7,$5,%6 + sge r7,$5,%6 + + seq at,v0,v1 + sne a0,ra,zero + slt t0,t1,t2 + sgt $7,%5,r6 + sle r7,$5,%6 + sge r7,$5,%6 + + mvts $10,r5 + mvfs r10,$5 diff --git a/gas/testsuite/gas/dlx/store.d b/gas/testsuite/gas/dlx/store.d new file mode 100644 index 0000000000..04b763a382 --- /dev/null +++ b/gas/testsuite/gas/dlx/store.d @@ -0,0 +1,22 @@ +#as: +#objdump: -dr +#name: store + +.*: +file format .* + +Disassembly of section .text: + +00000000 : + 0: ac 03 00 1c sw 0x001c\[r0\],r3 + 2: R_DLX_RELOC_16 .text + 4: ac 03 00 00 sw 0x0000\[r0\],r3 + 6: R_DLX_RELOC_16_HI .text + 8: a4 43 ff 90 sh 0xff90\[r2\],r3 + c: a0 03 00 3c sb 0x003c\[r0\],r3 + e: R_DLX_RELOC_16 .text + 10: a0 03 00 30 sb 0x0030\[r0\],r3 + 14: ac 43 00 00 sw 0x0000\[r2\],r3 + 18: 00 00 00 00 nop + +0000001c : + 1c: 00 00 00 00 nop diff --git a/gas/testsuite/gas/dlx/store.s b/gas/testsuite/gas/dlx/store.s new file mode 100644 index 0000000000..fbda68bd0e --- /dev/null +++ b/gas/testsuite/gas/dlx/store.s @@ -0,0 +1,9 @@ +.text +2: sw L1(r0),%3 + sw %hi(L1)(r0),%3 +1: sh (1b - 2b) + 8 - ((5f - 4f)<<4)[r2],r3 +4: sb 4b+'0',$3 +4: sb L1+'0'-L1,$3 +5: sw %hi((L1 - 2b) + 8 + ((5b - 4b)<<4))(r2),%3 + nop +L1: nop diff --git a/include/ChangeLog b/include/ChangeLog index e6ff3f1765..d64d48cae2 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,7 @@ +2002-05-28 Kuang Hwa Lin + + * dis-asm.h: Prototype print_insn_dlx. + 2002-05-23 Andrew Cagney * 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 +2002-05-17 J"orn Rennecke * dis-asm.h (print_insn_shl, print_insn_sh64l): Remove prototype. diff --git a/include/dis-asm.h b/include/dis-asm.h index 1fc570f96c..8d38f7e8d2 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 fe3823b1b6..1deec0daa9 100644 --- a/include/elf/ChangeLog +++ b/include/elf/ChangeLog @@ -1,3 +1,8 @@ +2002-05-28 Kuang Hwa Lin + + * common.h (EM_DLX): Define. + * dlx.h: New file. + 2002-05-08 Jason Thorpe * common.h (NT_GNU_ABI_TAG): Define. diff --git a/include/elf/common.h b/include/elf/common.h index f14f7bb679..48e2f4ae5e 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 0000000000..562f600f35 --- /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 7e5799c6bb..100c886a7a 100644 --- a/include/opcode/ChangeLog +++ b/include/opcode/ChangeLog @@ -1,3 +1,7 @@ +2002-05-28 Kuang Hwa Lin + + * dlx.h: New file. + 2002-05-25 Alan Modra * 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 0000000000..23e3b00bcc --- /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/ld/ChangeLog b/ld/ChangeLog index 6bcc8b67b5..06eefdb315 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,11 @@ +2002-05-28 Kuang Hwa Lin + + * Makefile.am: Add DLX make target. + * configure.tgt: Add DLX configuration. + * Makefile.in: Regenerate. + * emulparams/elf32_dlx.sh: New file + * scripttempl/dlx.sc: New file + 2002-05-27 Per Lundberg * Makefile.am (eelf_i386_chaos): Use elf_chaos.sc script. diff --git a/ld/Makefile.am b/ld/Makefile.am index 74f44e7540..66901be0cd 100644 --- a/ld/Makefile.am +++ b/ld/Makefile.am @@ -146,6 +146,7 @@ ALL_EMULATIONS = \ ed30v_o.o \ ed30velf.o \ edelta68.o \ + eelf32_dlx.o \ eebmon29k.o \ eelf32_i960.o \ eelf32_i860.o \ @@ -502,6 +503,9 @@ ed30v_e.c: $(srcdir)/emulparams/d30v_e.sh \ edelta68.c: $(srcdir)/emulparams/delta68.sh \ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/delta68.sc ${GEN_DEPENDS} ${GENSCRIPTS} delta68 "$(tdir_delta68)" +eelf32_dlx.c: $(srcdir)/emulparams/elf32_dlx.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/dlx.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32_dlx "$(tdir_elf32_dlx)" eebmon29k.c: $(srcdir)/emulparams/ebmon29k.sh \ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/ebmon29k.sc ${GEN_DEPENDS} ${GENSCRIPTS} ebmon29k "$(tdir_ebmon29k)" diff --git a/ld/Makefile.in b/ld/Makefile.in index 6bcc193dc4..92d8b549ab 100644 --- a/ld/Makefile.in +++ b/ld/Makefile.in @@ -257,6 +257,7 @@ ALL_EMULATIONS = \ ed30v_o.o \ ed30velf.o \ edelta68.o \ + eelf32_dlx.o \ eebmon29k.o \ eelf32_i960.o \ eelf32_i860.o \ @@ -1225,6 +1226,9 @@ ed30v_e.c: $(srcdir)/emulparams/d30v_e.sh \ edelta68.c: $(srcdir)/emulparams/delta68.sh \ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/delta68.sc ${GEN_DEPENDS} ${GENSCRIPTS} delta68 "$(tdir_delta68)" +eelf32_dlx.c: $(srcdir)/emulparams/elf32_dlx.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/dlx.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32_dlx "$(tdir_elf32_dlx)" eebmon29k.c: $(srcdir)/emulparams/ebmon29k.sh \ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/ebmon29k.sc ${GEN_DEPENDS} ${GENSCRIPTS} ebmon29k "$(tdir_ebmon29k)" diff --git a/ld/configure.tgt b/ld/configure.tgt index 1eae3fdd68..0f0411724d 100644 --- a/ld/configure.tgt +++ b/ld/configure.tgt @@ -33,6 +33,7 @@ d10v-*-*) targ_emul=d10velf ;; d30v-*-*ext*) targ_emul=d30v_e; targ_extra_emuls="d30velf d30v_o" ;; d30v-*-*onchip*) targ_emul=d30v_o; targ_extra_emuls="d30velf d30v_e" ;; d30v-*-*) targ_emul=d30velf; targ_extra_emuls="d30v_e d30v_o" ;; +dlx-*-elf*) targ_emul=elf32_dlx ;; sparc64-*-aout*) targ_emul=sparcaout ;; sparc64-*-elf*) targ_emul=elf64_sparc ;; sparc-sun-sunos4*) targ_emul=sun4 ;; diff --git a/ld/emulparams/elf32_dlx.sh b/ld/emulparams/elf32_dlx.sh new file mode 100644 index 0000000000..a3e2f46bf4 --- /dev/null +++ b/ld/emulparams/elf32_dlx.sh @@ -0,0 +1,9 @@ +SCRIPT_NAME=dlx +TEMPLATE_NAME=generic +OUTPUT_FORMAT="elf32-dlx" +ARCH=dlx +MACHINE= +TEXT_START_ADDR=0 +TARGET_PAGE_SIZE=0 +EMBEDDED=yes +MAXPAGESIZE=0 diff --git a/ld/scripttempl/dlx.sc b/ld/scripttempl/dlx.sc new file mode 100644 index 0000000000..b222b33560 --- /dev/null +++ b/ld/scripttempl/dlx.sc @@ -0,0 +1,30 @@ +cat < + + * 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 * Makefile.am (sh-dis.lo): Don't put make commands in deps. diff --git a/opcodes/Makefile.am b/opcodes/Makefile.am index a709193a6a..0996b2e533 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 e578ed80cd..3602cbd89e 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 6da1cc9036..a83d43df19 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 09f0d3882f..96e5a6b9f7 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 5bfa786cd2..bfb22c2c18 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 0000000000..8878b98aef --- /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; +} -- 2.34.1