From d94aca1affb15af8374bcb002f6a52fb724c9ccd Mon Sep 17 00:00:00 2001 From: Michael Tiemann Date: Thu, 24 Nov 1994 20:30:11 +0000 Subject: [PATCH] Safely check in r16 targets for binutils. --- bfd/.Sanitize | 8 + bfd/aout-r16.c | 38 ++ bfd/archures.c | 108 +++-- bfd/config.bfd | 8 +- bfd/configure.in | 3 + bfd/cpu-r16.c | 79 ++++ bfd/targets.c | 6 + config.sub | 37 +- gas/config/.Sanitize | 8 + gas/config/tc-r16.c | 1016 +++++++++++++++++++++++++++++++++++++++++ gas/config/tc-r16.h | 55 +++ gas/configure.in | 20 +- ld/config/.Sanitize | 7 + ld/config/r16-aout.mt | 1 + opcodes/.Sanitize | 8 + opcodes/configure.in | 171 +++++-- opcodes/r16-dis.c | 49 ++ opcodes/r16-opc.h | 118 +++++ 18 files changed, 1630 insertions(+), 110 deletions(-) create mode 100644 bfd/aout-r16.c create mode 100644 bfd/cpu-r16.c create mode 100644 gas/config/tc-r16.c create mode 100644 gas/config/tc-r16.h create mode 100644 ld/config/r16-aout.mt create mode 100644 opcodes/r16-dis.c create mode 100644 opcodes/r16-opc.h diff --git a/bfd/.Sanitize b/bfd/.Sanitize index c6442d20d7..3cbe36b885 100644 --- a/bfd/.Sanitize +++ b/bfd/.Sanitize @@ -23,6 +23,14 @@ else lose_these_too="${mpw_files} ${lose_these_too}" fi +r16_files="cpu-r16.c aout-r16.c" + +if ( echo $* | grep keep\-r16 > /dev/null ) ; then + keep_these_too="${r16_files} ${keep_these_too}" +else + lose_these_too="${r16_files} ${lose_these_too}" +fi + # All files listed between the "Things-to-keep:" line and the # "Files-to-sed:" line will be kept. All other files will be removed. # Directories listed in this section will have their own Sanitize diff --git a/bfd/aout-r16.c b/bfd/aout-r16.c new file mode 100644 index 0000000000..a89f1406be --- /dev/null +++ b/bfd/aout-r16.c @@ -0,0 +1,38 @@ +/* BFD back-end for SOP a.out binaries. + Copyright 1990, 1991, 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#define TARGET_IS_BIG_ENDIAN_P +#define PAGE_SIZE 4096 +#define SEGMENT_SIZE 4096 +#define TEXT_START_ADDR 0x0 +/* #define N_HEADER_IN_TEXT(x) 0 */ +#define N_SHARED_LIB(x) 0 +#define ARCH 32 +#define BYTES_IN_WORD 4 +#include "bfd.h" +#include "sysdep.h" +#include "libbfd.h" +#include "aout/aout64.h" +#include "aout/stab_gnu.h" +#include "aout/ar.h" +#include "libaout.h" +#define DEFAULT_ARCH bfd_arch_sop +#define MY(OP) CAT(sop_aout_,OP) +#define TARGETNAME "a.out-sop" +#include "aout-target.h" diff --git a/bfd/archures.c b/bfd/archures.c index d58e332430..31acf4a19f 100644 --- a/bfd/archures.c +++ b/bfd/archures.c @@ -1,8 +1,7 @@ /* BFD library support routines for architectures. - Copyright (C) 1990-1991 Free Software Foundation, Inc. + Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. Hacked by John Gilmore and Steve Chamberlain of Cygnus Support. - This file is part of BFD, the Binary File Descriptor library. This program is free software; you can redistribute it and/or modify @@ -35,7 +34,7 @@ SECTION The architecture information is provided by each architecture package. The set of default architectures is selected by the macro <>. This is normally set up in the - <> file of your choice. If the name is not + @file{config/@var{target}.mt} file of your choice. If the name is not defined, then all the architectures supported are included. When BFD starts up, all the architectures are called with an @@ -44,7 +43,7 @@ SECTION generally this would be one for each machine and one for the default case (an item with a machine field of 0). - BFD's idea of an architecture is implemented in <>. + BFD's idea of an architecture is implemented in @file{archures.c}. */ /* @@ -82,6 +81,9 @@ DESCRIPTION .#define bfd_mach_i960_mc 4 .#define bfd_mach_i960_xa 5 .#define bfd_mach_i960_ca 6 +. {* start-sanitize-i960xl *} +.#define bfd_mach_i960_xl 7 +. {* end-sanitize-i960xl *} . . bfd_arch_a29k, {* AMD 29000 *} . bfd_arch_sparc, {* SPARC *} @@ -98,6 +100,7 @@ DESCRIPTION . bfd_arch_h8300, {* Hitachi H8/300 *} .#define bfd_mach_h8300 1 .#define bfd_mach_h8300h 2 +. bfd_arch_powerpc, {* PowerPC *} . bfd_arch_rs6000, {* IBM RS/6000 *} . bfd_arch_hppa, {* HP PA RISC *} . bfd_arch_z8k, {* Zilog Z8000 *} @@ -106,6 +109,8 @@ DESCRIPTION . bfd_arch_h8500, {* Hitachi H8/500 *} . bfd_arch_sh, {* Hitachi SH *} . bfd_arch_alpha, {* Dec Alpha *} +. bfd_arch_arm, {* Advanced Risc Machines ARM *} +. bfd_arch_ns32k, {* National Semiconductors ns32000 *} . bfd_arch_last . }; @@ -172,8 +177,8 @@ DESCRIPTION */ CONST char * -DEFUN(bfd_printable_name, (abfd), - bfd *abfd) +bfd_printable_name (abfd) + bfd *abfd; { return abfd->arch_info->printable_name; } @@ -195,8 +200,8 @@ DESCRIPTION */ bfd_arch_info_type * -DEFUN(bfd_scan_arch,(string), - CONST char *string) +bfd_scan_arch (string) + CONST char *string; { struct bfd_arch_info *ap; @@ -231,10 +236,9 @@ DESCRIPTION */ CONST bfd_arch_info_type * -DEFUN(bfd_arch_get_compatible,(abfd, bbfd), -CONST bfd *abfd AND -CONST bfd *bbfd) - +bfd_arch_get_compatible (abfd, bbfd) + CONST bfd *abfd; + CONST bfd *bbfd; { return abfd->arch_info->compatible(abfd->arch_info,bbfd->arch_info); } @@ -274,9 +278,10 @@ DESCRIPTION Set the architecture info of @var{abfd} to @var{arg}. */ -void DEFUN(bfd_set_arch_info,(abfd, arg), -bfd *abfd AND -bfd_arch_info_type *arg) +void +bfd_set_arch_info (abfd, arg) + bfd *abfd; + bfd_arch_info_type *arg; { abfd->arch_info = arg; } @@ -297,10 +302,11 @@ DESCRIPTION pointer. */ -boolean DEFUN(bfd_default_set_arch_mach,(abfd, arch, mach), - bfd *abfd AND - enum bfd_architecture arch AND - unsigned long mach) +boolean +bfd_default_set_arch_mach (abfd, arch, mach) + bfd *abfd; + enum bfd_architecture arch; + unsigned long mach; { static struct bfd_arch_info *old_ptr = &bfd_default_arch_struct; boolean found = false; @@ -322,7 +328,7 @@ boolean DEFUN(bfd_default_set_arch_mach,(abfd, arch, mach), if (found==false) { /*looked for it and it wasn't there, so put in the default */ old_ptr = &bfd_default_arch_struct; - bfd_error = bad_value; + bfd_set_error (bfd_error_bad_value); } } else { @@ -349,7 +355,9 @@ DESCRIPTION */ -enum bfd_architecture DEFUN(bfd_get_arch, (abfd), bfd *abfd) +enum bfd_architecture +bfd_get_arch (abfd) + bfd *abfd; { return abfd->arch_info->arch; } @@ -367,7 +375,8 @@ DESCRIPTION */ unsigned long -DEFUN(bfd_get_mach, (abfd), bfd *abfd) +bfd_get_mach (abfd) + bfd *abfd; { return abfd->arch_info->mach; } @@ -385,7 +394,9 @@ DESCRIPTION */ -unsigned int DEFUN(bfd_arch_bits_per_byte, (abfd), bfd *abfd) +unsigned int +bfd_arch_bits_per_byte (abfd) + bfd *abfd; { return abfd->arch_info->bits_per_byte; } @@ -402,7 +413,9 @@ DESCRIPTION architecture's addresses. */ -unsigned int DEFUN(bfd_arch_bits_per_address, (abfd), bfd *abfd) +unsigned int +bfd_arch_bits_per_address (abfd) + bfd *abfd; { return abfd->arch_info->bits_per_address; } @@ -410,6 +423,7 @@ unsigned int DEFUN(bfd_arch_bits_per_address, (abfd), bfd *abfd) extern void bfd_a29k_arch PARAMS ((void)); extern void bfd_alpha_arch PARAMS ((void)); +extern void bfd_arm_arch PARAMS ((void)); extern void bfd_h8300_arch PARAMS ((void)); extern void bfd_h8500_arch PARAMS ((void)); extern void bfd_hppa_arch PARAMS ((void)); @@ -418,12 +432,17 @@ extern void bfd_i960_arch PARAMS ((void)); extern void bfd_m68k_arch PARAMS ((void)); extern void bfd_m88k_arch PARAMS ((void)); extern void bfd_mips_arch PARAMS ((void)); +extern void bfd_powerpc_arch PARAMS ((void)); extern void bfd_rs6000_arch PARAMS ((void)); extern void bfd_sh_arch PARAMS ((void)); +/* start-sanitize-r16 */ +extern void bfd_r16_arch PARAMS ((void)); +/* end-sanitize-r16 */ extern void bfd_sparc_arch PARAMS ((void)); extern void bfd_vax_arch PARAMS ((void)); extern void bfd_we32k_arch PARAMS ((void)); extern void bfd_z8k_arch PARAMS ((void)); +extern void bfd_ns32k_arch PARAMS ((void)); static void (*archures_init_table[]) PARAMS ((void)) = { @@ -432,6 +451,7 @@ static void (*archures_init_table[]) PARAMS ((void)) = #else bfd_a29k_arch, bfd_alpha_arch, + bfd_arm_arch, bfd_h8300_arch, bfd_h8500_arch, bfd_hppa_arch, @@ -440,12 +460,17 @@ static void (*archures_init_table[]) PARAMS ((void)) = bfd_m68k_arch, bfd_m88k_arch, bfd_mips_arch, + bfd_powerpc_arch, bfd_rs6000_arch, bfd_sh_arch, +/* start-sanitize-r16 */ + bfd_r16_arch, +/* end-sanitize-r16 */ bfd_sparc_arch, bfd_vax_arch, bfd_we32k_arch, bfd_z8k_arch, + bfd_ns32k_arch, #endif 0 }; @@ -466,7 +491,7 @@ DESCRIPTION */ void -DEFUN_VOID(bfd_arch_init) +bfd_arch_init () { void (**ptable) PARAMS ((void)); for (ptable = archures_init_table; @@ -489,8 +514,9 @@ DESCRIPTION Link the architecture info structure @var{ptr} into the list. */ -void DEFUN(bfd_arch_linkin,(ptr), - bfd_arch_info_type *ptr) +void +bfd_arch_linkin (ptr) + bfd_arch_info_type *ptr; { ptr->next = bfd_arch_info_list; bfd_arch_info_list = ptr; @@ -511,9 +537,9 @@ DESCRIPTION */ CONST bfd_arch_info_type * -DEFUN(bfd_default_compatible,(a,b), - CONST bfd_arch_info_type *a AND - CONST bfd_arch_info_type *b) +bfd_default_compatible (a,b) + CONST bfd_arch_info_type *a; + CONST bfd_arch_info_type *b; { if(a->arch != b->arch) return NULL; @@ -540,9 +566,9 @@ DESCRIPTION */ boolean -DEFUN(bfd_default_scan,(info, string), -CONST struct bfd_arch_info *info AND -CONST char *string) +bfd_default_scan (info, string) + CONST struct bfd_arch_info *info; + CONST char *string; { CONST char *ptr_src; CONST char *ptr_tst; @@ -661,8 +687,8 @@ DESCRIPTION */ bfd_arch_info_type * -DEFUN(bfd_get_arch_info,(abfd), -bfd *abfd) +bfd_get_arch_info (abfd) + bfd *abfd; { return abfd->arch_info; } @@ -686,9 +712,9 @@ DESCRIPTION */ bfd_arch_info_type * -DEFUN(bfd_lookup_arch,(arch, machine), -enum bfd_architecture arch AND -long machine) +bfd_lookup_arch (arch, machine) + enum bfd_architecture arch; + long machine; { bfd_arch_info_type *ap; bfd_check_init(); @@ -721,9 +747,9 @@ DESCRIPTION */ CONST char * -DEFUN(bfd_printable_arch_mach,(arch, machine), - enum bfd_architecture arch AND - unsigned long machine) +bfd_printable_arch_mach (arch, machine) + enum bfd_architecture arch; + unsigned long machine; { bfd_arch_info_type *ap = bfd_lookup_arch(arch, machine); if(ap) return ap->printable_name; diff --git a/bfd/config.bfd b/bfd/config.bfd index 5153d8e3d5..3f93128745 100755 --- a/bfd/config.bfd +++ b/bfd/config.bfd @@ -25,6 +25,7 @@ strip_underscore=no case "${canon}" in alpha-*-netware*) bfd_name=alpha-nlm ;; alpha-*-*) bfd_name=alphaosf ;; + arm-*-riscix*) bfd_name=riscix ;; a29k-*-ebmon*) bfd_name=a29k-coff strip_underscore=yes ;; a29k-*-udi*) bfd_name=a29k-coff strip_underscore=yes ;; a29k-*-aout*) bfd_name=a29k-aout strip_underscore=yes ;; @@ -33,6 +34,9 @@ case "${canon}" in h8300*-*-*) bfd_name=h8300-coff strip_underscore=yes ;; h8500-*-*) bfd_name=h8500-coff strip_underscore=yes ;; sh-*-*) bfd_name=sh-coff strip_underscore=yes ;; +# start-sanitize-r16 + r16-*-aout) bfd_name=r16-aout ;; +# end-sanitize-r16 hppa*-*-*elf*) bfd_name=hppa-elf ;; hppa*-*-bsd*) bfd_name=hppabsd ;; hppa*-*-hpux*) bfd_name=hppahpux ;; @@ -49,7 +53,7 @@ case "${canon}" in i[345]86-*-coff) bfd_name=i386-coff ;; i[345]86-*-aix*) bfd_name=i386-coff ;; i[345]86-*-elf) bfd_name=i386-elf ;; - i[345]86-*-netbsd*) bfd_name=i386-netbsd strip_underscore=yes ;; + i[345]86-*-netbsd*) bfd_name=i386-nbsd strip_underscore=yes ;; i[345]86-*-netware*) bfd_name=i386-nlm ;; i[345]86-*-linux*) bfd_name=i386-linux strip_underscore=yes ;; i[345]86-*-lynxos*) bfd_name=i386-lynx ;; @@ -73,6 +77,7 @@ case "${canon}" in m68*-*-coff*) bfd_name=m68k-coff ;; m68*-*-hpux*) bfd_name=hp300hpux strip_underscore=yes ;; m68*-*-lynxos*) bfd_name=m68k-lynx ;; + m68*-*-netbsd*) bfd_name=m68k-nbsd strip_underscore=yes ;; m68*-*-os68k*) bfd_name=m68k-aout strip_underscore=yes ;; m68*-*-sunos*) bfd_name=m68k-aout strip_underscore=yes ;; m68*-*-sysv4*) bfd_name=m68k-elf ;; @@ -111,6 +116,7 @@ case "${canon}" in powerpc-*-netware*) bfd_name=ppc-nlm ;; rs6000-*-*) bfd_name=rs6000 ;; sparc-*-lynxos*) bfd_name=sparc-lynx ;; + sparc-*-netbsd*) bfd_name=sparc-nbsd strip_underscore=yes;; sparc-*-solaris2*) bfd_name=sparc-elf ;; sparc-*-sysv4*) bfd_name=sparc-elf ;; sparc64-*-aout*) bfd_name=sparc-aout strip_underscore=yes ;; diff --git a/bfd/configure.in b/bfd/configure.in index 41d31cdfcc..04a42238d3 100644 --- a/bfd/configure.in +++ b/bfd/configure.in @@ -202,6 +202,9 @@ do pc532machaout_vec) tb="$tb pc532-mach.o aout-ns32k.o stab-syms.o" ;; rs6000coff_vec) tb="$tb coff-rs6000.o" ;; shcoff_vec) tb="$tb coff-sh.o cofflink.o" ;; +# start-sanitize-r16 + r16_aout_vec) tb="$tb aout32.o reloc16.o" ;; +# end-sanitize-r16 shlcoff_vec) tb="$tb coff-sh.o cofflink.o" ;; som_vec) tb="$tb som.o" ;; sparclynx_aout_vec) tb="$tb sparclynx.o lynx-core.o aout32.o stab-syms.o" ;; diff --git a/bfd/cpu-r16.c b/bfd/cpu-r16.c new file mode 100644 index 0000000000..276fe3ad33 --- /dev/null +++ b/bfd/cpu-r16.c @@ -0,0 +1,79 @@ +/* BFD library support routines for the Experiment SOP architecture. + Copyright (C) 1993 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "bfd.h" +#include "sysdep.h" +#include "libbfd.h" + + +int bfd_default_scan_num_mach(); + +static boolean +DEFUN(scan_mach,(info, string), +CONST struct bfd_arch_info *info AND +CONST char *string) +{ + if (strcmp(string,"sop") == 0) return true; + if (strcmp(string,"SOP") == 0) return true; + return false; +} + + +#if 0 +/* This routine is provided two arch_infos and returns whether + they'd be compatible */ + +static CONST bfd_arch_info_type * +DEFUN(compatible,(a,b), + CONST bfd_arch_info_type *a AND + CONST bfd_arch_info_type *b) +{ + if (a->arch != b->arch || a->mach != b->mach) + return NULL; + return a; +} +#endif + +static bfd_arch_info_type arch_info_struct[] = +{ + { + 32, /* 32 bits in a word */ + 32, /* 32 bits in an address */ + 8, /* 8 bits in a byte */ + bfd_arch_r16, + 0, /* only 1 machine */ + "SOP", /* arch_name */ + "SOP", /* printable name */ + 1, + true, /* the default machine */ + bfd_default_compatible, + scan_mach, + 0, + 0, + }, +}; + + + +void +DEFUN_VOID(bfd_sop_arch) +{ + bfd_arch_linkin(&arch_info_struct[0]); +} + diff --git a/bfd/targets.c b/bfd/targets.c index 5cf0130e74..4bfe7697d3 100644 --- a/bfd/targets.c +++ b/bfd/targets.c @@ -486,6 +486,9 @@ extern const bfd_target pc532machaout_vec; extern const bfd_target riscix_vec; extern const bfd_target rs6000coff_vec; extern const bfd_target shcoff_vec; +/* start-sanitize-r16 */ +extern bfd_target r16_aout_vec; +/* end-sanitize-r16 */ extern const bfd_target shlcoff_vec; extern const bfd_target sparclynx_aout_vec; extern const bfd_target sparclynx_coff_vec; @@ -637,6 +640,9 @@ const bfd_target * const bfd_target_vector[] = { &rs6000coff_vec, &shcoff_vec, &shlcoff_vec, +/* start-sanitize-r16 */ + &r16_aout_vec, +/* end-sanitize-r16 */ &sparclynx_aout_vec, &sparclynx_coff_vec, &sparcnetbsd_vec, diff --git a/config.sub b/config.sub index c9fc8ac011..52dcd9f12c 100755 --- a/config.sub +++ b/config.sub @@ -126,6 +126,9 @@ case $os in -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; esac # Decode aliases for certain CPU-COMPANY combinations. @@ -156,7 +159,7 @@ case $basic_machine in | sh-* | powerpc-* | sparc64-* | mips64-* | mipsel-* \ | mips64el-* | mips64orion-* | mips64orionel-* \ | m88110-* | m680[01234]0-* | m683?2-* | z8k-* \ - | h8500-*) # CYGNUS LOCAL + | h8500-* ) # CYGNUS LOCAL ;; # start-sanitize-arc arc) @@ -165,6 +168,13 @@ case $basic_machine in arc-*) ;; # end-sanitize-arc +# start-sanitize-r16 + r16) + basic_machine=$basic_machine-unknown + ;; + r16-*) + ;; +# end-sanitize-r16 # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) # CYGNUS LOCAL @@ -304,11 +314,7 @@ case $basic_machine in basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; - h8300hds) - basic_machine=h8300-hitachi - os=-hds - ;; - h8300hms) # CYGNUS LOCAL + h8300hms) basic_machine=h8300-hitachi os=-hms ;; @@ -363,7 +369,7 @@ case $basic_machine in hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; - hppaosf) + hppaosf) # CYGNUS LOCAL basic_machine=hppa1.1-hp os=-osf ;; @@ -447,7 +453,7 @@ case $basic_machine in mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; - monitor) # CYGNUS LOCAL + monitor) # CYGNUS LOCAL basic_machine=m68k-rom68k os=-coff ;; @@ -652,7 +658,7 @@ case $basic_machine in os=-sysv4 basic_machine=i386-unknown ;; - v810 | necv810) + v810 | necv810) # CYGNUS LOCAL basic_machine=v810-nec os=-none ;; @@ -764,6 +770,9 @@ case $os in -solaris) os=-solaris2 ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux|'` + ;; # First accept the basic system types. # The portable systems comes first. # Each alternative must end in a *, to match a version number. @@ -776,9 +785,9 @@ case $os in | -riscos* | -linux* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -netbsd* | -freebsd* | -riscix* \ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \ - | -ptx* \ - | -go32 | -vsta | -sim | -es1800* | -udi | -hms* | -xray | -hds* \ - | -os68k* | -none* | -v88r* | -coff \ + | -ptx* | -coff* | -winnt* \ + | -go32 | -vsta | -sim | -es1800* | -udi | -hms* | -xray \ + | -os68k* | -none* | -v88r* | -windows* | -osx \ | -abug | -ecoff* | -netware* | -proelf | -os9* ) # The last three lines above are CYGNUS LOCAL ;; @@ -876,10 +885,10 @@ case $basic_machine in # default. # os=-sunos4 ;; - m68*-cisco) + m68*-cisco) # CYGNUS LOCAL os=-aout ;; - mips*-cisco) + mips*-cisco) # CYGNUS LOCAL os=-elf ;; *-tti) # must be before sparc entry or we get the wrong os. diff --git a/gas/config/.Sanitize b/gas/config/.Sanitize index 8eec333af5..1a23079515 100644 --- a/gas/config/.Sanitize +++ b/gas/config/.Sanitize @@ -15,6 +15,14 @@ Do-first: +r16_files="tc-r16.c tc-r16.h" + +if ( echo $* | grep keep\-r16 > /dev/null ) ; then + keep_these_too="${r16_files} ${keep_these_too}" +else + lose_these_too="${r16_files} ${lose_these_too}" +fi + # All files listed between the "Things-to-keep:" line and the # "Files-to-sed:" line will be kept. All other files will be removed. # Directories listed in this section will have their own Sanitize diff --git a/gas/config/tc-r16.c b/gas/config/tc-r16.c new file mode 100644 index 0000000000..153274e6bd --- /dev/null +++ b/gas/config/tc-r16.c @@ -0,0 +1,1016 @@ +/* tc-r16.c -- Assemble code for the Experimental R16 + + Copyright (C) 1993 Free Software Foundation. + + This file is part of GAS, the GNU Assembler. + + GAS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GAS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GAS; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* + Adapted from the SH assember + Relocation doesnt work yet. + */ + +#include +#include "as.h" +#include "bfd.h" +#include "subsegs.h" +#define DEFINE_TABLE +#include "../opcodes/r16-opc.h" +#include + +#if 1 /**** TEMP ****/ +#define R_PCRELIMM8BY4 23 /* 8 bit pc relative to long boundary shifted 4 */ +#define R_PCRELIMM11BY2 24 /* 11 bit pc relative to long boundary shifted 2 */ +#endif /**** TEMP ****/ + +const char comment_chars[] = "!"; +const char line_separator_chars[] = ";"; +const char line_comment_chars[] = "!"; + +/* This table describes all the machine specific pseudo-ops the assembler + has to support. The fields are: + pseudo-op name without dot + function to call to execute this pseudo-op + Integer arg to pass to the function + */ + +void cons (); +void s_align_bytes (); + +const pseudo_typeS md_pseudo_table[] = +{ + {"page", listing_eject, 0}, + {0, 0, 0} +}; + +const int md_reloc_size = 8; + +static int relax; /* set if -relax seen */ + +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"; + +#define JREG 0 /* Register used as a temp when relaxing */ +#define C(what,length) (((what) << 2) + (length)) +#define GET_WHAT(x) ((x>>2)) + +/* These are the two types of relaxable instruction */ +#define COND_JUMP 1 +#define UNCD_JUMP 2 + +#define UNDEF_DISP 0 +#define COND12 1 +#define COND32 2 +#define UNCD12 1 +#define UNCD32 2 +#define UNDEF_WORD_DISP 4 +#define END 5 + +#define C12_LEN 2 +#define C32_LEN 10 /* allow for align */ +#define U12_LEN 2 +#define U32_LEN 8 /* allow for align */ + + +/* Initialize the relax table */ +const relax_typeS md_relax_table[] = +{ +{ 1, 1, 0, 0 }, /* 0: unused */ +{ 1, 1, 0, 0 }, /* 1: unused */ +{ 1, 1, 0, 0 }, /* 2: unused */ +{ 1, 1, 0, 0 }, /* 3: unused */ +{ 1, 1, 0, 0 }, /* 4: unused */ +{ 2048, -2046, C12_LEN, C(COND_JUMP, COND32) }, /* 5: C(COND_JUMP, COND12) */ +{ 0, 0, C32_LEN, 0 }, /* 6: C(COND_JUMP, COND32) */ +{ 1, 1, 0, 0 }, /* 7: unused */ +{ 1, 1, 0, 0 }, /* 8: unused */ +{ 2048, -2046, U12_LEN, C(UNCD_JUMP, UNCD32) }, /* 9: C(UNCD_JUMP, UNCD12) */ +{ 0, 0, U32_LEN, 0 }, /*10: C(UNCD_JUMP, UNCD32) */ +{ 1, 1, 0, 0 }, /*11: unused */ +}; + +static struct hash_control *opcode_hash_control; /* Opcode mnemonics */ + +/* + This function is called once, at assembler startup time. This should + set up all the tables, etc that the MD part of the assembler needs + */ + +void +md_begin () +{ + r16_opcode_info *opcode; + char *prev_name = ""; + + opcode_hash_control = hash_new (); + + /* Insert unique names into hash table */ + for (opcode = r16_table; opcode->name; opcode++) + { + if (strcmp (prev_name, opcode->name)) + { + prev_name = opcode->name; + hash_insert (opcode_hash_control, opcode->name, (char *) opcode); + } + else + { + /* Make all the opcodes with the same name point to the same + string */ + opcode->name = prev_name; + } + } +} + +static int reg_m; +static int reg_n; +static expressionS immediate; /* absolute expression */ + +/* try and parse a reg name */ +static char * +parse_reg (s, reg) +char *s; +unsigned *reg; +{ + if (s[0] == 'r') + { + if (s[1] == '1' && s[2] >= '0' && s[2] <= '5') + { + *reg = 10 + s[2] - '0'; + return s+3; + } + if (s[1] >= '0' && s[1] <= '9') + { + *reg = (s[1] - '0'); + return s+2; + } + } + as_bad("register expected"); + return s; +} + +static char * +parse_creg (s, reg) +char *s; +unsigned *reg; +{ + if (s[0] == 'c' && s[1] == 'r') + { + if (s[2] == '1' && s[3] >= '0' && s[3] <= '5') + { + *reg = 10 + s[3] - '0'; + return s+4; + } + if (s[2] >= '0' && s[2] <= '9') + { + *reg = (s[2] - '0'); + return s+3; + } + } + as_bad("register expected"); + return s; +} + +static char * +parse_exp(s) +char *s; +{ char *save; + char *new; + + save = input_line_pointer; + input_line_pointer = s; + expression(&immediate); + if (immediate.X_op == O_absent) + as_bad("missing operand"); + new = input_line_pointer; + input_line_pointer = save; + return new; +} + +static char * +parse_imm(s, val, min, max) +char *s; +unsigned *val; +unsigned min, max; +{ char *new; + + new = parse_exp(s); + if (immediate.X_op != O_constant + || immediate.X_add_number < min + || immediate.X_add_number > max) + { + as_bad ("operand must be absolute in range %d..%d", min, max); + } + *val = immediate.X_add_number; + return new; +} + + +static char * +parse_mem(s, reg, off, siz) +char *s; +unsigned *reg; +unsigned *off; +unsigned siz; +{ char *new; + + if (*s == '(') + { s = parse_reg(s+1, reg); + if (*s == ',') + { s = parse_imm(s+1, off, 0, 63); + if (siz > 1) + { if (siz > 2) + { + if (*off & 0x3) + as_bad ("operand must be a multiple of 4"); + *off >>= 2; + } + else + { + if (*off & 0x1) + as_bad ("operand must be a multiple of 2"); + *off >>= 1; + } + } + } + else + *off = 0; + if (*s == ')') + s++; + } + else + as_bad("base register expected"); + return s; +} + + + +/* This is the guts of the machine-dependent assembler. STR points to a + machine dependent instruction. This function is supposed to emit + the frags/bytes it assembles to. + */ + +void +md_assemble (str) +char *str; +{ + char *op_start; + char *op_end; + r16_opcode_info *opcode; + char *output; + int nlen = 0; + unsigned short inst; + unsigned reg, off; + char name[20]; + + /* Drop leading whitespace */ + while (*str == ' ') + str++; + + /* find the op code end */ + for (op_start = op_end = str; + *op_end && nlen < 20 && !is_end_of_line[*op_end] && *op_end != ' '; + op_end++) + { + name[nlen] = op_start[nlen]; + nlen++; + } + name[nlen] = 0; + if (nlen == 0) + { + as_bad ("can't find opcode "); + return; + } + + opcode = (r16_opcode_info *) hash_find (opcode_hash_control, name); + if (opcode == NULL) + { + as_bad ("unknown opcode \"%s\"", name); + return; + } + inst = opcode->inst; + switch (opcode->opclass) + { case O0: + output = frag_more (2); + break; + case OT: + op_end = parse_imm(op_end + 1, ®, 0, 15); + inst |= reg; + output = frag_more (2); + break; + case O1: + op_end = parse_reg (op_end + 1, ®); + inst |= reg; + output = frag_more (2); + break; + case OC: + op_end = parse_reg (op_end + 1, ®); + inst |= reg; + if (*op_end == ',') + { op_end = parse_creg(op_end + 1, ®); + inst |= reg<<4; + } + output = frag_more (2); + break; + case O2: + op_end = parse_reg (op_end + 1, ®); + inst |= reg; + if (*op_end == ',') + { op_end = parse_reg(op_end + 1, ®); + inst |= reg<<4; + } + else + as_bad("second operand missing"); + output = frag_more (2); + break; + case OI: + op_end = parse_reg (op_end + 1, ®); + inst |= reg; + if (*op_end == ',') + { op_end = parse_imm(op_end + 1, ®, 1, 32); + inst |= (reg-1)<<4; + } + else + as_bad("second operand missing"); + output = frag_more (2); + break; + case OB: + op_end = parse_reg (op_end + 1, ®); + inst |= reg; + if (*op_end == ',') + { op_end = parse_imm(op_end + 1, ®, 0, 31); + inst |= reg<<4; + } + else + as_bad("second operand missing"); + output = frag_more (2); + break; + case LS: + op_end = parse_reg(op_end + 1, ®); + inst |= reg<<8; + if (*op_end == ',') + { + int size; + if ((inst & 0x6000) == 0) + size = 4; + else if ((inst & 0x6000) == 0x4000) + size = 2; + else if ((inst & 0x6000) == 0x2000) + size = 1; + op_end = parse_mem(op_end + 1, ®, &off, size); + inst |= (reg) | (off<<4); + } + else + as_bad("second operand missing"); + output = frag_more (2); + break; + case LI: + op_end = parse_reg (op_end + 1, ®); + if (*op_end == ',') + { unsigned val; + op_end = parse_imm(op_end + 1, &val, 0, 0x7FF); + inst |= val&0x7FF; + } + else + as_bad("second operand missing"); + if (reg != 1) + as_bad("register must be r1"); + output = frag_more (2); + break; + case LR: + op_end = parse_reg(op_end + 1, ®); + if (reg == 3 || reg == 15) + as_bad("register must not be r3 or r15"); + inst |= (reg<<8); + output = frag_more (2); + if (*op_end++ == ',') + { + if (*op_end++ != '[') + as_bad ("second operand missing '['"); + input_line_pointer = parse_exp(op_end); + if (*input_line_pointer++ != ']') + as_bad ("second operand missing ']'"); + fix_new_exp(frag_now, output-frag_now->fr_literal, 2, &immediate, + 1, R_PCRELIMM8BY4); + } + else + as_bad("second operand missing"); + break; + case LJ: + output = frag_more (2); + if (*++op_end != '[') + as_bad ("operand missing '['"); + input_line_pointer = parse_exp(op_end+1); + if (*input_line_pointer++ != ']') + as_bad ("operand missing ']'"); + fix_new_exp(frag_now, output-frag_now->fr_literal, 2, &immediate, + 1, R_PCRELIMM8BY4); + break; + case OM: + op_end = parse_reg(op_end + 1, ®); + if (*op_end == '-') + { int endreg; + op_end = parse_reg(op_end + 1, &endreg); + if (*op_end == ',') + { int basereg; + op_end++; + if (*op_end == '(') + { op_end = parse_reg(op_end + 1, &basereg); + if (*op_end == ')') + op_end++; + if (endreg == 15 && basereg == 3) + { inst |= 0x0080; /* list form */ + inst |= reg; + } + else if (endreg - reg == 3) + { inst |= basereg; /* quadrant form */ + switch (reg) + { case 0: break; + case 4: inst |= (1<<5); break; + case 8: inst |= (2<<5); break; + case 12: inst |= (3<<5); break; + default: + as_bad("first register must be r0, r4, r8, or r12"); + } + } + else + as_bad("bad register list or base register"); + } + else + as_bad("base register expected"); + } + else + as_bad("second operand missing"); + } + else + as_bad("reg-reg expected"); + output = frag_more (2); + break; + case BR: + output = frag_more (2); + input_line_pointer = parse_exp(op_end+1); + fix_new_exp (frag_now, output-frag_now->fr_literal, 2, &immediate, + 1, R_PCRELIMM11BY2); + break; + default: + as_bad("cant deal with opcode \"%s\"", name); + } + output[0] = (inst>>8); + output[1] = (inst); +} + +#ifndef BFD_ASSEMBLER +void +DEFUN (tc_crawl_symbol_chain, (headers), + object_headers * headers) +{ +} + +void +DEFUN (tc_headers_hook, (headers), + object_headers * headers) +{ +} +#endif + +symbolS * +DEFUN (md_undefined_symbol, (name), + char *name) +{ + return 0; +} + +void +DEFUN_VOID (md_end) +{ +} + +/* Various routines to kill one day */ +/* Equal to MAX_PRECISION in atof-ieee.c */ +#define MAX_LITTLENUMS 6 + +/* 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. + */ +char * +md_atof (type, litP, sizeP) + char type; + char *litP; + int *sizeP; +{ + int prec; + LITTLENUM_TYPE words[MAX_LITTLENUMS]; + LITTLENUM_TYPE *wordP; + char *t; + char *atof_ieee (); + + switch (type) + { + case 'f': + case 'F': + case 's': + case 'S': + prec = 2; + break; + + case 'd': + case 'D': + case 'r': + case 'R': + prec = 4; + break; + + case 'x': + case 'X': + prec = 6; + break; + + case 'p': + case 'P': + prec = 6; + break; + + default: + *sizeP = 0; + return "Bad call to MD_NTOF()"; + } + 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, (long) (*wordP++), sizeof (LITTLENUM_TYPE)); + litP += sizeof (LITTLENUM_TYPE); + } + return 0; +} + +int +md_parse_option (argP, cntP, vecP) + char **argP; + int *cntP; + char ***vecP; + +{ + if (!strcmp (*argP, "relax")) + { + relax = 1; + **argP = 0; + } + return 1; +} + +int md_short_jump_size; + +void +tc_Nout_fix_to_chars () +{ + as_fatal ("call to tc_Nout_fix_to_chars"); +} + +void +md_create_short_jump (ptr, from_Nddr, to_Nddr, frag, to_symbol) + char *ptr; + addressT from_Nddr; + addressT to_Nddr; + fragS *frag; + symbolS *to_symbol; +{ + as_fatal ("failed sanity check: short_jump"); +} + +void +md_create_long_jump (ptr, from_Nddr, to_Nddr, frag, to_symbol) + char *ptr; + addressT from_Nddr, to_Nddr; + fragS *frag; + symbolS *to_symbol; +{ + as_fatal ("failed sanity check: long_jump"); +} + +/* +called after relaxing, change the frags so they know how big they are +*/ +#ifndef BFD_ASSEMBLER +void +md_convert_frag (headers, fragP) + object_headers *headers; + register fragS *fragP; +#else +void +md_convert_frag (abfd, sec, fragP) + bfd *abfd; + segT sec; + register fragS *fragP; +#endif +{ + unsigned char *buffer = (unsigned char *) (fragP->fr_fix + fragP->fr_literal); + int targ_addr = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset; +#ifdef BFD_ASSEMBLER /* not needed otherwise? */ + targ_addr += fragP->fr_symbol->sy_frag->fr_address; +#endif + switch (fragP->fr_subtype) + { + case C (COND_JUMP, COND12): + case C (UNCD_JUMP, UNCD12): + { + /* Get the address of the end of the instruction */ + int next_inst = fragP->fr_fix + fragP->fr_address + 2; + unsigned char t0; + int disp = targ_addr - next_inst; + if (disp&1) + as_bad("odd displacement at %x", next_inst-2); + if (disp < 0) /* move sign to low order bit */ + disp |= 1; + t0 = buffer[0] & 0xF8; + md_number_to_chars (buffer, disp, 2); + buffer[0] = (buffer[0] & 0x07) | t0; + fragP->fr_fix += 2; + fragP->fr_var = 0; + } + break; + + case C (COND_JUMP, COND32): + case C (COND_JUMP, UNDEF_WORD_DISP): + { + /* A conditional branch wont fit into 12 bits so: + * b!cond 1f + * jmpi 0f + * .align 2 + * 0: .long disp + * 1: + */ + int next_inst = fragP->fr_fix + fragP->fr_address + C32_LEN; + int align = next_inst&02; + buffer[0] ^= 0x08; /* Toggle T/F bit */ + buffer[2] = 0x73; /* Build jmpi */ + buffer[3] = 0x00; + if (align) + { + buffer[1] = 3; /* branch over jmpi, and ptr */ + buffer[4] = 0; /* space for 32 bit address */ + buffer[5] = 0; + buffer[6] = 0; + buffer[7] = 0; + /* Make reloc for the long disp */ + fix_new(fragP, fragP->fr_fix + 4, 4, + fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_32); +#if 0 + /**** frag has shrunk but gas can't deal with that */ + fragP->fr_fix += C32_LEN - 2; +#else + fragP->fr_fix += C32_LEN; +#endif + } + else + { + buffer[1] = 4; /* branch over jmpi, and ptr */ + buffer[4] = 0; /* alignment */ + buffer[5] = 0; + buffer[6] = 0; /* space for 32 bit address */ + buffer[7] = 0; + buffer[8] = 0; + buffer[9] = 0; + /* Make reloc for the long disp */ + fix_new(fragP, fragP->fr_fix + 6, 4, + fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_32); + fragP->fr_fix += C32_LEN; + } + fragP->fr_var = 0; + } + break; + + case C (UNCD_JUMP, UNCD32): + case C (UNCD_JUMP, UNDEF_WORD_DISP): + { + /* An unconditional branch wont fit in 12 bits, make code which looks like + * jmpi 0f + * .align 2 + * 0: .long disp + */ + int next_inst = fragP->fr_fix + fragP->fr_address + U32_LEN; + int align = next_inst&02; + buffer[0] = 0x73; /* build jmpi */ + buffer[1] = 0x00; + if (align) + { + buffer[2] = 0; /* space for 32 bit address */ + buffer[3] = 0; + buffer[4] = 0; + buffer[5] = 0; + /* Make reloc for the long disp */ + fix_new (fragP, fragP->fr_fix + 2, 4, + fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_32); +#if 0 + /**** frag has shrunk but gas can't deal with that */ + fragP->fr_fix += U32_LEN - 2; +#else + fragP->fr_fix += U32_LEN; +#endif + } + else + { + buffer[2] = 0; /* alignment */ + buffer[3] = 0; + buffer[4] = 0; /* space for 32 bit address */ + buffer[5] = 0; + buffer[6] = 0; + buffer[7] = 0; + /* Make reloc for the long disp */ + fix_new (fragP, fragP->fr_fix + 4, 4, + fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_32); + fragP->fr_fix += U32_LEN; + } + fragP->fr_var = 0; + } + break; + + default: + abort (); + } +} + +void +md_apply_fix1 (fixP, val) + fixS *fixP; + long val; +{ + char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; + int addr = fixP->fx_frag->fr_address + fixP->fx_where; + + switch (fixP->fx_r_type) + { + case R_PCRELIMM11BY2: /* second byte of 2 byte opcode */ + val /= 2; + if (((val & ~0x3ff) != 0) && ((val | 0x3ff) != -1)) + as_warn ("pcrel for branch too far (0x%x) at 0x%x", val, addr); + buf[0] |= ((val >> 7) & 0x7); + buf[1] |= ((val & 0x7f) << 1); + buf[1] |= ((val >> 10) & 0x1); + break; + case R_PCRELIMM8BY4: /* lower 8 bits of 2 byte opcode */ + val += 3; + val /= 4; + if (val & ~0xff) + as_warn ("pcrel for lrw too far (0x%x) at 0x%x", val, addr); + buf[1] |= (val & 0xff); + break; + default: + if (fixP->fx_size != 4) + abort (); + *buf++ = val >> 24; + *buf++ = val >> 16; + *buf++ = val >> 8; + *buf = val >> 0; + break; + } +} + +#ifdef BFD_ASSEMBLER +int +md_apply_fix (fixP, valp) + fixS *fixP; + valueT *valp; +{ + md_apply_fix1 (fixP, *valp); + return 1; +} +#else +void +md_apply_fix (fixP, val) + fixS *fixP; + long val; +{ + md_apply_fix1 (fixP, val); +} +#endif + +void +DEFUN (md_operand, (expressionP), expressionS * expressionP) +{ +} + +int md_long_jump_size; + +/* +called just before address relaxation, return the length +by which a fragment must grow to reach it's destination +*/ +int +md_estimate_size_before_relax (fragP, segment_type) + register fragS *fragP; + register segT segment_type; +{ + switch (fragP->fr_subtype) + { + case C (UNCD_JUMP, UNDEF_DISP): + /* used to be a branch to somewhere which was unknown */ + if (!fragP->fr_symbol) + { + fragP->fr_subtype = C (UNCD_JUMP, UNCD12); + fragP->fr_var = md_relax_table[C (UNCD_JUMP, UNCD12)].rlx_length; + } + else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type) + { + fragP->fr_subtype = C (UNCD_JUMP, UNCD12); + fragP->fr_var = md_relax_table[C (UNCD_JUMP, UNCD12)].rlx_length; + } + else + { + fragP->fr_subtype = C (UNCD_JUMP, UNDEF_WORD_DISP); + fragP->fr_var = md_relax_table[C (UNCD_JUMP, UNCD32)].rlx_length; + return md_relax_table[C (UNCD_JUMP, UNCD32)].rlx_length; + } + break; + + default: + abort (); + case C (COND_JUMP, UNDEF_DISP): + /* used to be a branch to somewhere which was unknown */ + if (fragP->fr_symbol + && S_GET_SEGMENT (fragP->fr_symbol) == segment_type) + { + /* Got a symbol and it's defined in this segment, become byte + sized - maybe it will fix up */ + fragP->fr_subtype = C (COND_JUMP, COND12); + fragP->fr_var = md_relax_table[C (COND_JUMP, COND12)].rlx_length; + } + else if (fragP->fr_symbol) + { + /* Its got a segment, but its not ours, so it will always be long */ + fragP->fr_subtype = C (COND_JUMP, UNDEF_WORD_DISP); + fragP->fr_var = md_relax_table[C (COND_JUMP, COND32)].rlx_length; + return md_relax_table[C (COND_JUMP, COND32)].rlx_length; + } + else + { + /* We know the abs value */ + fragP->fr_subtype = C (COND_JUMP, COND12); + fragP->fr_var = md_relax_table[C (COND_JUMP, COND12)].rlx_length; + } + + break; + } + return fragP->fr_var; +} + +/* Put number into target byte order */ + +void +md_number_to_chars (ptr, use, nbytes) + char *ptr; + valueT use; + int nbytes; +{ + switch (nbytes) + { + case 4: + *ptr++ = (use >> 24) & 0xff; + case 3: + *ptr++ = (use >> 16) & 0xff; + case 2: + *ptr++ = (use >> 8) & 0xff; + case 1: + *ptr++ = (use >> 0) & 0xff; + break; + default: + abort (); + } +} + + +/* Round up a section size to the appropriate boundary. */ +valueT +md_section_align (segment, size) + segT segment; + valueT size; +{ + return size; /* Byte alignment is fine */ +} + + +long +md_pcrel_from (fixP) + fixS *fixP; + +{ + int gap = fixP->fx_size + fixP->fx_where + + fixP->fx_frag->fr_address; + return gap; +} + + + +#ifdef BFD_ASSEMBLER + +arelent * +tc_gen_reloc (section, fixp) + asection *section; + fixS *fixp; +{ + arelent *rel; + bfd_reloc_code_real_type code; + +#define F(SZ,PCREL) (((SZ) << 1) + (PCREL)) + switch (F (fixp->fx_size, fixp->fx_pcrel)) + { +#define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break + MAP (1, 0, BFD_RELOC_8); + MAP (2, 0, BFD_RELOC_16); + MAP (4, 0, BFD_RELOC_32); + MAP (1, 1, BFD_RELOC_8_PCREL); + MAP (2, 1, BFD_RELOC_16_PCREL); + MAP (4, 1, BFD_RELOC_32_PCREL); + default: + as_bad ("Can not do %d byte %srelocation", fixp->fx_size, + fixp->fx_pcrel ? "pc-relative" : ""); + } + + rel = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent)); + assert (rel != 0); + rel->sym_ptr_ptr = &fixp->fx_addsy->bsym; + rel->address = fixp->fx_frag->fr_address + fixp->fx_where; + if (fixp->fx_pcrel) + rel->addend = fixp->fx_addnumber; + else + rel->addend = 0; + + rel->howto = bfd_reloc_type_lookup (stdoutput, code); + if (!rel->howto) + { + const char *name; + + name = S_GET_NAME (fixp->fx_addsy); + if (name == NULL) + name = ""; + as_fatal ("Cannot find relocation type for symbol %s, code %d", + name, (int) code); + } + + return rel; +} + +#else /* !BFD_ASSEMBLER */ + +#if (defined(OBJ_AOUT) | defined(OBJ_BOUT)) +void +tc_aout_fix_to_chars(where, fixP, segment_address_in_file) +char *where; +fixS *fixP; +relax_addressT segment_address_in_file; +{ + /* + * In: length of relocation (or of address) in chars: 1, 2 or 4. + * Out: GNU LD relocation length code: 0, 1, or 2. + */ + + static CONST unsigned char nbytes_r_length[] = {42, 0, 1, 42, 2}; + long r_symbolnum; + + know (fixP->fx_addsy != NULL); + + md_number_to_chars (where, + fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file, + 4); + + r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy) + ? S_GET_TYPE (fixP->fx_addsy) + : fixP->fx_addsy->sy_number); + + where[4] = (r_symbolnum >> 16) & 0x0ff; + where[5] = (r_symbolnum >> 8) & 0x0ff; + where[6] = r_symbolnum & 0x0ff; + where[7] = (((fixP->fx_pcrel << 7) & 0x80) + | ((nbytes_r_length[fixP->fx_size] << 5) & 0x60) + | (((!S_IS_DEFINED (fixP->fx_addsy)) << 4) & 0x10)); + +} + +void +tc_aout_pre_write_hook (headers) + object_headers *headers; +{ +} +#endif +#endif /* !BFD_ASSEMBLER */ + diff --git a/gas/config/tc-r16.h b/gas/config/tc-r16.h new file mode 100644 index 0000000000..7e82378d15 --- /dev/null +++ b/gas/config/tc-r16.h @@ -0,0 +1,55 @@ +/* This file is tc-r16.h + + Copyright (C) 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef TC_R16 +#define TC_R16 1 + +#ifdef BFD_ASSEMBLER + +#define TARGET_ARCH bfd_arch_r16 +#define TARGET_BYTES_BIG_ENDIAN 1 +#ifdef OBJ_AOUT +#define TARGET_FORMAT "a.out-r16" +#endif + +#else /* ! BFD_ASSEMBLER */ + +#define BFD_ARCH bfd_arch_r16 +#define NO_RELOC 0 +#define RELOC_32 1234 + +#endif /* ! BFD_ASSEMBLER */ + +#define AOUT_MACHTYPE 155 + +/* Don't write out relocs for pcrel stuff*/ +#define TC_COUNT_RELOC(x) (((x)->fx_addsy||(x)->fx_subsy)&&(x)->fx_r_type < 22) +#define IGNORE_NONSTANDARD_ESCAPES + +#define TC_RELOC_MANGLE(a,b,c) tc_reloc_mangle(a,b,c) + +#define DO_NOT_STRIP 0 +#define DO_STRIP 0 +#define LISTING_HEADER "R16 Experimental GAS " +#define NEED_FX_R_TYPE 1 +#define COFF_FLAGS 1 +#define TC_COFF_SIZEMACHDEP(frag) tc_coff_sizemachdep(frag) + +#endif diff --git a/gas/configure.in b/gas/configure.in index 01fb6efc09..3098eec6a5 100644 --- a/gas/configure.in +++ b/gas/configure.in @@ -150,18 +150,22 @@ case ${generic_target} in sh-*-coff) obj_format=coff ;; +# start-sanitize-r16 + r16-*-aout) obj_format=aout ;; +# end-sanitize-r16 + ns32k-pc532-mach*) obj_format=aout emulation=pc532 ;; ns32k-pc532-netbsd*) obj_format=aout emulation=nbsd532 ;; - sparc*-*-sunos4*) obj_format=aout emulation=sun3 ;; - sparc*-*-aout | sparc*-*-vxworks) + sparc-*-sunos4*) obj_format=aout emulation=sun3 ;; + sparc-*-aout | sparc*-*-vxworks) obj_format=aout ;; - sparc*-*-coff) obj_format=coff ;; - sparc*-*-lynxos*) obj_format=coff emulation=lynx ;; - sparc*-fujitsu-none) obj_format=aout ;; - sparc*-*-elf | sparc*-*-solaris*) + sparc-*-coff) obj_format=coff ;; + sparc-*-lynxos*) obj_format=coff emulation=lynx ;; + sparc-fujitsu-none) obj_format=aout ;; + sparc-*-elf | sparc*-*-solaris*) obj_format=elf ;; - sparc*-*-netbsd*) obj_format=aout emulation=nbsd bfd_gas=yes ;; + sparc-*-netbsd*) obj_format=aout emulation=nbsd bfd_gas=yes ;; vax-*-bsd* | vax-*-ultrix*) obj_format=aout ;; @@ -225,7 +229,7 @@ case ${cpu_type}-${obj_format} in mips-*) bfd_gas=yes ;; ns32k-*) bfd_gas=yes ;; ppc-*) bfd_gas=yes ;; - sparc*-*) bfd_gas=yes ;; + sparc-*) bfd_gas=yes ;; *-elf) bfd_gas=yes ;; *-ecoff) bfd_gas=yes ;; *-som) bfd_gas=yes ;; diff --git a/ld/config/.Sanitize b/ld/config/.Sanitize index 6f992decda..5abf00617f 100644 --- a/ld/config/.Sanitize +++ b/ld/config/.Sanitize @@ -15,6 +15,13 @@ Do-first: +r16_files="r16-aout.mt" + +if ( echo $* | grep keep\-r16 > /dev/null ) ; then + keep_these_too="${r16_files} ${keep_these_too}" +else + lose_these_too="${r16_files} ${lose_these_too}" +fi # All files listed between the "Things-to-keep:" line and the # "Do-last:" line will be kept. All other files will be removed. diff --git a/ld/config/r16-aout.mt b/ld/config/r16-aout.mt new file mode 100644 index 0000000000..e053df992e --- /dev/null +++ b/ld/config/r16-aout.mt @@ -0,0 +1 @@ +EMUL=sopaout diff --git a/opcodes/.Sanitize b/opcodes/.Sanitize index 57e5aba474..83c73b4561 100644 --- a/opcodes/.Sanitize +++ b/opcodes/.Sanitize @@ -23,6 +23,14 @@ else lose_these_too="${mpw_files} ${lose_these_too}" fi +r16_files="r16-dis.c r16-opc.h" + +if ( echo $* | grep keep\-r16 > /dev/null ) ; then + keep_these_too="${r16_files} ${keep_these_too}" +else + lose_these_too="${r16_files} ${lose_these_too}" +fi + # All files listed between the "Things-to-keep:" line and the # "Files-to-sed:" line will be kept. All other files will be removed. # Directories listed in this section will have their own Sanitize diff --git a/opcodes/configure.in b/opcodes/configure.in index b6487a62ca..8feb9dfacc 100644 --- a/opcodes/configure.in +++ b/opcodes/configure.in @@ -8,58 +8,15 @@ srcname="opcodes" # per-host: -case "${host}" in - a29k-nyu-sym1) my_host=ultra3 ;; - hppa*-hp-bsd) my_host=hppabsd ;; - hppa*-hp-hpux) my_host=hppahpux ;; - i860-stratus-sysv4) my_host=stratus ;; - i[34]86-*-go32) my_host=go32 ;; - i[34]86-*-linux) my_host=i386linux ;; - i[34]86-*-mach) my_host=i386mach ;; - i[34]86-*-msdos*) my_host=dose ;; - i[34]86-*-sysv*) my_host=i386v ;; - i[34]86-*-sco) my_host=i386v ;; - i[34]86-*-sysv4*) my_host=i386v4 ;; - i[34]86-ncr-sysv4*) my_host=ncr3000 ;; - m68k-apollo-bsd*) my_host=apollo68 ;; - m68k-apollo-sysv*) my_host=apollov68 ;; - m68k-cbm-amigados) my_host=amigados ;; - m68k-cbm-sysv4*) my_host=amix ;; - m68k-hp-bsd) my_host=hp300bsd ;; - m68k-hp-hpux) my_host=hp300 ;; # renamed from hp9000 - m68k-sony-*) my_host=news ;; - m68k-sun-sunos*) my_host=sun3 ;; - m88k-dg-dgux) my_host=dgux ;; - m88k-harris-*) my_host=harris ;; - m88k-motorola-*) my_host=delta88 ;; - mips-dec-ultrix) my_host=decstation ;; - mips-sgi-irix | mips-sgi-irix3) my_host=irix3 ;; - mips-sgi-irix4) my_host=irix4 ;; - romp-ibm-bsd*) my_host=rtbsd ;; - rs6000-ibm-aix) my_host=rs6000 ;; - sparc-*-sysv4) my_host=sysv4 ;; - sparc-*-sysv64) my_host=sysv4-ll ;; - sparc-sun-solaris2) my_host=solaris2 ;; - sparc-sun-sunos*) my_host=sparc ;; - sparc-sun-sunos64) my_host=sparc-ll ;; - tahoe-*-*) my_host=tahoe ;; - vax-dec-bsd*) my_host=vaxbsd ;; - vax-dec-ultrix*) my_host=vaxult ;; - we32k-*-*) my_host=we32k ;; -esac - +. ${srcdir}/../bfd/configure.host # Set up to make a link between the host's include file and "sysdep.h". files="../bfd/hosts/${my_host}.h" - links="sysdep.h" if [ ! -f ${srcdir}/${files} ] ; then - if [ -n "${my_host}" ] ; then - echo '***' No file ${srcdir}/${files} 1>&2 - fi - echo '***' ${srcname} does not support host ${host} 1>&2 - exit 1 + files=../bfd/hosts/std-host.h + echo "[${srcname} has no specific support for host ${host} -- using std-host]" fi host_makefile_frag= @@ -68,3 +25,125 @@ if [ -f ${srcdir}/../bfd/config/${my_host}.mh ] ; then fi # per-target: + +# Canonicalize the secondary target names. +if [ -n "$enable_targets" ]; then + for targ in `echo $enable_targets | sed 's/,/ /g'` + do + result=`$configsub $targ 2>/dev/null` + if [ -n "$result" ]; then + canon_targets="$canon_targets $result" + else + # Allow targets that config.sub doesn't recognize, like "all". + canon_targets="$canon_targets $targ" + fi + done +fi + +all_targets=false + +for targ in $target $canon_targets +do + bfd_target=`${config_shell} $srcdir/../bfd/config.bfd $targ` + + if [ "x$bfd_target" = "xall" ]; then + all_targets=true + else + if [ ! -f ${srcdir}/../bfd/config/${bfd_target}.mt ] ; then + echo '***' No file ${srcdir}/../bfd/config/${bfd_target}.mt 1>&2 + echo '***' opcodes does not support target ${bfd_target} 1>&2 + echo '***' Look in bfd/config.bfd for supported targets 1>&2 + exit 1 + fi + + if [ "x$targ" = "x$target" ]; then + target_makefile_frag=${srcdir}/../bfd/config/${bfd_target}.mt + else + target_extra_frags="$target_extra_frags ${srcdir}/../bfd/config/${bfd_target}.mt" + fi + fi +done + +# We don't do any links based on the target system, just makefile config. + +# post-target: + +rm -f Makefile.tmp Makefile.2 +mv Makefile Makefile.tmp + +if [ x${all_targets} = xfalse ]; then + + allfrags="$target_makefile_frag $target_extra_frags" + + # The architectures in all the configured targets. + SELECT_ARCHITECTURES=`sed -n ' + s/SELECT_ARCHITECTURES[ ]*=[ ]*//p + ' $allfrags` + + # Target architecture .o files. + ta= + + for arch in $SELECT_ARCHITECTURES + do + ad=`echo $arch | sed -e s/bfd_//g -e s/_arch//g` + archdefs="$archdefs -DARCH_$ad" + case "$arch" in + bfd_a29k_arch) ta="$ta a29k-dis.o" ;; + bfd_alpha_arch) ta="$ta alpha-dis.o" ;; + bfd_arm_arch) ta="$ta arm-dis.o" ;; + bfd_h8300_arch) ta="$ta h8300-dis.o" ;; + bfd_h8500_arch) ta="$ta h8500-dis.o" ;; + bfd_hppa_arch) ta="$ta hppa-dis.o" ;; + bfd_i386_arch) ta="$ta i386-dis.o" ;; + bfd_i960_arch) ta="$ta i960-dis.o" ;; + bfd_m68k_arch) ta="$ta m68k-dis.o" ;; + bfd_m88k_arch) ta="$ta m88k-dis.o" ;; + bfd_mips_arch) ta="$ta mips-dis.o mips-opc.o" ;; + bfd_ns32k_arch) ta="$ta ns32k-dis.o" ;; + bfd_powerpc_arch) ta="$ta ppc-dis.o ppc-opc.o" ;; + bfd_rs6000_arch) ta="$ta ppc-dis.o ppc-opc.o" ;; + bfd_sh_arch) ta="$ta sh-dis.o" ;; +# start-sanitize-r16 + bfd_r16_arch) ta="$ta r16-dis.o" ;; +# end-sanitize-r16 + bfd_sparc_arch) ta="$ta sparc-dis.o sparc-opc.o" ;; + bfd_vax_arch) ;; + bfd_we32k_arch) ;; + bfd_z8k_arch) ta="$ta z8k-dis.o" ;; + + "") ;; + *) echo "*** unknown target architecture $arch" 1>&2; exit 1 ;; + esac + done + + # Weed out duplicate .o files. + f="" + for i in $ta ; do + case " $f " in + *" $i "*) ;; + *) f="$f $i" ;; + esac + done + ta="$f" + + # And duplicate -D flags. + f="" + for i in $archdefs ; do + case " $f " in + *" $i "*) ;; + *) f="$f $i" ;; + esac + done + archdefs="$f" + + echo "ARCHDEFS = $archdefs" >> Makefile.2 + echo "BFD_MACHINES = $ta" >> Makefile.2 + +else # all_targets is true + echo 'ARCHDEFS = -DARCH_all' >> Makefile.2 + echo 'BFD_MACHINES = $(ALL_MACHINES)' >> Makefile.2 +fi # all_targets is true + +cat Makefile.tmp >> Makefile.2 +rm -f Makefile.tmp +mv Makefile.2 Makefile diff --git a/opcodes/r16-dis.c b/opcodes/r16-dis.c new file mode 100644 index 0000000000..cf3016030a --- /dev/null +++ b/opcodes/r16-dis.c @@ -0,0 +1,49 @@ +/* Disassemble R16 instructions. + Copyright (C) 1993 Free Software Foundation, Inc. + +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., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include +#define STATIC_TABLE +#define DEFINE_TABLE + +#include "r16-opc.h" +#include "dis-asm.h" + +int +print_insn_sop(memaddr, info) + bfd_vma memaddr; + struct disassemble_info *info; +{ + fprintf_ftype fprintf = info->fprintf_func; + void *stream = info->stream; + unsigned char insn[2]; + unsigned char nibs[4]; + int status; + int relmask = ~0; + r16_opcode_info *op; + int dslot = 0; + + status = info->read_memory_func(memaddr, insn, 2, info); + + if (status != 0) + { + info->memory_error_func(status, memaddr, info); + return -1; + } + /**** DISASSEMBLY NOT YET IMPLEMENTED ****/ + fprintf(stream,".word 0x%02x%02x", insn[0], insn[1]); + return 2; +} diff --git a/opcodes/r16-opc.h b/opcodes/r16-opc.h new file mode 100644 index 0000000000..4e2987887f --- /dev/null +++ b/opcodes/r16-opc.h @@ -0,0 +1,118 @@ +typedef enum { + O0, OT, O1, OC, O2, OI, OB, LS, BR, LI, LR, LJ, OM +} r16_opclass; + +typedef struct inst +{ char *name; + unsigned short opclass; + unsigned short inst; +} r16_opcode_info; + +#ifdef DEFINE_TABLE +r16_opcode_info r16_table[]={ +{ "bkpt", O0, 0x0000 }, +{ "sync", O0, 0x0001 }, +{ "rte", O0, 0x0002 }, +{ "rfi", O0, 0x0003 }, +{ "stop", O0, 0x0004 }, +{ "wait", O0, 0x0005 }, + +{ "trap", OT, 0x0010 }, +{ "mvc", O1, 0x0020 }, +{ "mvcv", O1, 0x0030 }, +{ "jmp", O1, 0x0040 }, +{ "jsr", O1, 0x0050 }, +{ "jmpt", O1, 0x0060 }, +{ "jmpf", O1, 0x0070 }, +{ "tsteq", O1, 0x0080 }, +{ "tstgt", O1, 0x0090 }, +{ "tstlt", O1, 0x00A0 }, +{ "tstbz", O1, 0x00B0 }, +{ "inct", O1, 0x00C0 }, +{ "incf", O1, 0x00D0 }, +{ "dect", O1, 0x00E0 }, +{ "decf", O1, 0x00F0 }, +{ "zextb", O1, 0x0100 }, +{ "sextb", O1, 0x0110 }, +{ "zexth", O1, 0x0120 }, +{ "sexth", O1, 0x0130 }, +{ "xtrb3", O1, 0x0140 }, +{ "xtrb2", O1, 0x0150 }, +{ "xtrb1", O1, 0x0160 }, +{ "xtrb0", O1, 0x0170 }, + +{ "decgt", O1, 0x01C0 }, +{ "declt", O1, 0x01D0 }, +{ "brev", O1, 0x01E0 }, +{ "not", O1, 0x01F0 }, +{ "mfcr", OC, 0x0200 }, +{ "mtcr", OC, 0x0300 }, +{ "mov", O2, 0x0400 }, +{ "movnc", O2, 0x0600 }, +{ "tst", O2, 0x0700 }, +{ "cmpeq", O2, 0x0800 }, +{ "cmpgt", O2, 0x0900 }, +{ "cmphi", O2, 0x0A00 }, +{ "bgenr", O2, 0x0D00 }, +{ "movt", O2, 0x0E00 }, +{ "movf", O2, 0x0F00 }, +{ "and", O2, 0x1000 }, +{ "andn", O2, 0x1100 }, +{ "xor", O2, 0x1200 }, +{ "xnor", O2, 0x1300 }, +{ "or", O2, 0x1400 }, +{ "rsub", O2, 0x1500 }, +{ "addu", O2, 0x1600 }, +{ "subu", O2, 0x1700 }, +{ "ixh", O2, 0x1800 }, +{ "ixw", O2, 0x1900 }, +{ "addc", O2, 0x1A00 }, +{ "subc", O2, 0x1B00 }, +{ "lsr", O2, 0x1C00 }, +{ "asr", O2, 0x1D00 }, +{ "lsl", O2, 0x1E00 }, +{ "rotl", O2, 0x1F00 }, +{ "movi", OB, 0x2000 }, + +{ "andi", OB, 0x2200 }, +{ "movit", OB, 0x2400 }, +{ "movif", OB, 0x2600 }, +{ "btsti", OB, 0x2800 }, +{ "bclri", OB, 0x2A00 }, +{ "bseti", OB, 0x2C00 }, +{ "bmaski", OB, 0x2E00 }, +{ "bgeni", OB, 0x3000 }, +{ "rsubi", OB, 0x3200 }, +{ "addi", OI, 0x3400 }, +{ "subi", OI, 0x3600 }, +{ "lsri", OB, 0x3800 }, +{ "lsrc", O1, 0x3800 }, +{ "asri", OB, 0x3A00 }, +{ "asrc", O1, 0x3A00 }, +{ "lsli", OB, 0x3C00 }, +{ "lslc", O1, 0x3C00 }, +{ "rotli", OB, 0x3E00 }, +{ "rotlc", O1, 0x3E00 }, + +{ "ldm", OM, 0x6000 }, +{ "stm", OM, 0x6010 }, +{ "mult", O2, 0x6100 }, + +{ "mvir1", LI, 0x6800 }, +{ "lrw", LR, 0x7000 }, +{ "jmpi", LJ, 0x7300 }, +{ "jsri", LJ, 0x7F00 }, + +{ "ld", LS, 0x8000 }, +{ "st", LS, 0x9000 }, +{ "ld.b", LS, 0xA000 }, +{ "st.b", LS, 0xB000 }, +{ "ld.h", LS, 0xC000 }, +{ "st.h", LS, 0xD000 }, +{ "br", BR, 0xE000 }, +{ "bsr", BR, 0xE800 }, +{ "bt", BR, 0xF000 }, +{ "bf", BR, 0xF800 }, +{ 0, 0, 0 } +}; +#endif