From e665b9bf7357581b476631fb0b3e932560f8c67a Mon Sep 17 00:00:00 2001 From: John Mark Bell Date: Thu, 16 Dec 2010 16:52:50 +0000 Subject: Import toolchains tree svn path=/toolchains/; revision=11073 --- m68k-unknown-amigaos/Makefile | 94 +++ .../recipes/files/gcc/amigacollect2.c | 558 ++++++++++++++++ .../recipes/files/gcc/config/m68k/amigaos-protos.h | 45 ++ .../recipes/files/gcc/config/m68k/amigaos.c | 726 +++++++++++++++++++++ .../recipes/files/gcc/config/m68k/amigaos.h | 678 +++++++++++++++++++ .../recipes/files/gcc/config/m68k/host-amigaos.c | 42 ++ .../recipes/files/gcc/config/m68k/t-amigaos | 30 + .../recipes/files/gcc/config/m68k/x-amigaos | 104 +++ .../recipes/files/gcc/config/m68k/xm-amigaos.h | 64 ++ m68k-unknown-amigaos/recipes/patches/config.gcc.p | 17 + 10 files changed, 2358 insertions(+) create mode 100644 m68k-unknown-amigaos/Makefile create mode 100644 m68k-unknown-amigaos/recipes/files/gcc/amigacollect2.c create mode 100644 m68k-unknown-amigaos/recipes/files/gcc/config/m68k/amigaos-protos.h create mode 100644 m68k-unknown-amigaos/recipes/files/gcc/config/m68k/amigaos.c create mode 100644 m68k-unknown-amigaos/recipes/files/gcc/config/m68k/amigaos.h create mode 100644 m68k-unknown-amigaos/recipes/files/gcc/config/m68k/host-amigaos.c create mode 100644 m68k-unknown-amigaos/recipes/files/gcc/config/m68k/t-amigaos create mode 100644 m68k-unknown-amigaos/recipes/files/gcc/config/m68k/x-amigaos create mode 100644 m68k-unknown-amigaos/recipes/files/gcc/config/m68k/xm-amigaos.h create mode 100644 m68k-unknown-amigaos/recipes/patches/config.gcc.p (limited to 'm68k-unknown-amigaos') diff --git a/m68k-unknown-amigaos/Makefile b/m68k-unknown-amigaos/Makefile new file mode 100644 index 0000000..68b91a0 --- /dev/null +++ b/m68k-unknown-amigaos/Makefile @@ -0,0 +1,94 @@ +UPSTREAM_VERSION := 4.5.1 +UPSTREAM_TARBALL := gcc-$(UPSTREAM_VERSION).tar.bz2 +UPSTREAM_URI := http://ftp.gnu.org/gnu/gcc/gcc-$(UPSTREAM_VERSION)/$(UPSTREAM_TARBALL) + +UPSTREAM_GMP_VERSION := 4.3.2 +UPSTREAM_GMP_TARBALL := gmp-$(UPSTREAM_GMP_VERSION).tar.bz2 +UPSTREAM_GMP_URI := http://ftp.gnu.org/gnu/gmp/$(UPSTREAM_GMP_TARBALL) + +# Would use 3.0.0, but that dislikes in-tree gmp sources +UPSTREAM_MPFR_VERSION := 2.4.2 +UPSTREAM_MPFR_TARBALL := mpfr-$(UPSTREAM_MPFR_VERSION).tar.bz2 +UPSTREAM_MPFR_URI := http://www.mpfr.org/mpfr-$(UPSTREAM_MPFR_VERSION)/$(UPSTREAM_MPFR_TARBALL) + +UPSTREAM_MPC_VERSION := 0.8.2 +UPSTREAM_MPC_TARBALL := mpc-$(UPSTREAM_MPC_VERSION).tar.gz +UPSTREAM_MPC_URI := http://www.multiprecision.org/mpc/download/$(UPSTREAM_MPC_TARBALL) + +TOP := $(CURDIR) +RECIPES := $(TOP)/recipes +BUILDSTEPS := $(TOP)/build-steps +SRCDIR := $(TOP)/srcdir +BUILDDIR := $(TOP)/builddir + +PREFIX ?= /usr/local/netsurf/cross/amiga68k/ + +TARGET_NAME := m68k-unknown-amigaos + +.PHONY: all install +all: $(BUILDSTEPS)/make.d + +install: $(BUILDSTEPS)/install.d + +$(BUILDSTEPS)/install.d: $(BUILDSTEPS)/make.d + cd $(BUILDDIR) && make install + touch $@ + +$(BUILDSTEPS)/make.d: $(BUILDSTEPS)/configure.d + cd $(BUILDDIR) && make all + touch $@ + +$(BUILDSTEPS)/configure.d: $(BUILDSTEPS)/builddir.d + cd $(BUILDDIR) && $(SRCDIR)/configure --prefix=$(PREFIX) --target=$(TARGET_NAME) \ + --with-cpu=m68040 --disable-threads --disable-nls --disable-c-mbchar \ + --enable-languages=c --enable-checking=no --enable-c99 --with-cross-host \ + --disable-multilib --without-x --enable-maintainer-mode + touch $@ + +$(BUILDSTEPS)/builddir.d: $(BUILDSTEPS)/srcdir-step3.d + mkdir -p $(BUILDDIR) + touch $@ + +$(BUILDSTEPS)/srcdir-step3.d: $(BUILDSTEPS)/srcdir-step2.d $(UPSTREAM_GMP_TARBALL) $(UPSTREAM_MPFR_TARBALL) $(UPSTREAM_MPC_TARBALL) + tar xjf $(UPSTREAM_GMP_TARBALL) + mv gmp-$(UPSTREAM_GMP_VERSION) $(SRCDIR)/gmp + tar xjf $(UPSTREAM_MPFR_TARBALL) + mv mpfr-$(UPSTREAM_MPFR_VERSION) $(SRCDIR)/mpfr + tar xzf $(UPSTREAM_MPC_TARBALL) + mv mpc-$(UPSTREAM_MPC_VERSION) $(SRCDIR)/mpc + touch $@ + +$(BUILDSTEPS)/srcdir-step2.d: $(BUILDSTEPS)/srcdir-step1.d + for p in `ls $(RECIPES)/patches/*.p` ; do patch -d $(SRCDIR) -p0 <$$p ; done + for dir in `find $(RECIPES)/files -type d | grep -v '\.svn' | sed 's#$(RECIPES)/files/##'` ; do mkdir -p $(SRCDIR)/$$dir ; done + for file in `find $(RECIPES)/files -type f | grep -v '\.svn' | sed 's#$(RECIPES)/files/##'` ; do cp -p $(RECIPES)/files/$$file $(SRCDIR)/$$file ; done + touch $@ + +$(BUILDSTEPS)/srcdir-step1.d: $(BUILDSTEPS)/orig.gcc.d + mkdir -p $(SRCDIR) + cp -r orig.gcc/* $(SRCDIR) + touch $@ + +$(BUILDSTEPS)/orig.gcc.d: $(BUILDSTEPS)/orig.gcc-$(UPSTREAM_TARBALL).d + tar xjf orig.gcc-$(UPSTREAM_TARBALL) + mv gcc-$(UPSTREAM_VERSION) orig.gcc + touch $@ + +$(BUILDSTEPS)/orig.gcc-$(UPSTREAM_TARBALL).d: $(BUILDSTEPS)/buildsteps.d orig.gcc-$(UPSTREAM_TARBALL) + touch $@ + +orig.gcc-$(UPSTREAM_TARBALL): + wget -q -O $@ $(UPSTREAM_URI) + +$(UPSTREAM_GMP_TARBALL): + wget -q -O $@ $(UPSTREAM_GMP_URI) + +$(UPSTREAM_MPFR_TARBALL): + wget -q -O $@ $(UPSTREAM_MPFR_URI) + +$(UPSTREAM_MPC_TARBALL): + wget -q -O $@ $(UPSTREAM_MPC_URI) + +$(BUILDSTEPS)/buildsteps.d: + mkdir -p $(BUILDSTEPS) + touch $@ diff --git a/m68k-unknown-amigaos/recipes/files/gcc/amigacollect2.c b/m68k-unknown-amigaos/recipes/files/gcc/amigacollect2.c new file mode 100644 index 0000000..9df71a7 --- /dev/null +++ b/m68k-unknown-amigaos/recipes/files/gcc/amigacollect2.c @@ -0,0 +1,558 @@ +/* GG-local whole file: dynamic libraries */ +/* Supplimentary functions that get compiled and linked to collect2 for + AmigaOS target. + Copyright (C) 1996 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC 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. + +GCC 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 GCC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" + +/* From collect2.c: */ + +void maybe_unlink(const char *); +void fatal_perror(const char *, ...); +void fork_execute(const char *, char **); +void fatal(const char *, ...); + +extern char *c_file_name; +extern int debug; + +/* Local functions. */ + +static void safename (char *); +static void add_lib (const char *); +static void cat (const char *, FILE *); + +/* Names of temporary files we create. */ +#define XLIBS_C_NAME "xlibs.c" +#define XLIBS_O_NAME "xlibs.o" +#define SHARED_X_NAME "shared.x" + +/* Suffix which is prepended to "-l" options for dynamic libraries. */ +#define DYNAMIC_LIB_SUFFIX "_ixlibrary" + +/* Structure that holds library names. */ +struct liblist +{ + struct liblist *next; + char *name; + char *cname; +}; + +/* Not zero if "-static" was specified on GCC command line or if all the + libraries are static. */ +static int flag_static=0; + +/* Not zero if linking a base relative executable. This is recognized by + presence of "-m amiga_bss" on the linker's commandline. */ +static int flag_baserel=0; + +/* Not zero if some of the specified libraries are dynamic. */ +static int found_dynamic_libs=0; + +/* List of linker libraries. */ +struct liblist *head = NULL; + +/* Return 1 if collect2 should do something more apart from tlink. We want it + to call "postlink" and "strip" if linking with dynamic libraries. */ + +int +amigaos_do_collecting (void) +{ + return !flag_static; +} + +/* Check for presence of "-static" on the GCC command line. We should not do + collecting if this flag was specified. */ + +void +amigaos_gccopts_hook (const char *arg) +{ + if (strncmp(arg, "-static", strlen("-static"))==0) + flag_static=1; +} + +/* Replace unprintable characters with underscores. Used by "add_lib()". */ + +static void +safename (char *p) +{ + if (!ISALPHA(*p)) + *p = '_'; + p++; + while (*p) + { + if (!ISALNUM(*p)) + *p = '_'; + p++; + } +} + +/* Add a library to the list of dynamic libraries. First make sure that the + library is actually dynamic. Used by "amigaos_libname_hook()". */ + +static void +add_lib (const char *name) +{ + struct liblist *lib; + static char buf[256]; + + for (lib = head; lib; lib = lib->next) + if (!strcmp(lib->name, name)) + return; + + /* A2IXDIR_PREFIX is passed by "make". */ + sprintf(buf, A2IXDIR_PREFIX "/ldscripts/%s.x", name); + if (access(buf, R_OK)) + return; + + lib = (struct liblist*)xmalloc(sizeof(struct liblist)); + lib->name = xstrdup(name); + lib->cname = xstrdup(name); + safename(lib->cname); + lib->next = head; + head = lib; + + if (debug) + fprintf(stderr, "found dynamic library, name: %s, cname: %s\n", lib->name, + lib->cname); + + found_dynamic_libs=1; +} + +/* Check if the argument is a linker library. Call "add_lib()" if yes. */ + +void +amigaos_libname_hook (const char *arg) +{ + int len = strlen(arg); + if (flag_static) + return; + + if (len > 2 && !memcmp(arg, "-l", 2)) + add_lib(arg + 2); + else if (len > 2 && !strcmp(arg + len - 2, ".a")) + { + const char *lib; + + ((char*)arg)[len - 2] = '\0'; + lib = strrchr(arg, '/'); + if (lib == NULL) + lib = strrchr(arg, ':'); + if (lib == NULL) + lib = arg - 1; + if (!strncmp(lib + 1, "lib", 3)) + add_lib(lib + 4); + ((char *)arg)[len - 2] = '.'; + } +} + +/* Delete temporary files. */ + +void +amigaos_collect2_cleanup (void) +{ + if (flag_static) + return; + maybe_unlink(XLIBS_C_NAME); + maybe_unlink(XLIBS_O_NAME); + maybe_unlink(SHARED_X_NAME); +} + +/* Copy file named by FNAME to X. */ + +static void +cat (const char *fname, FILE *x) +{ +#define BUFSIZE 16384 + FILE *in; + static char buf[BUFSIZE]; + int bytes; + + in = fopen(fname, "r"); + if (in == NULL) + fatal_perror("%s", fname); + while (!feof(in) && (bytes = fread(buf, 1, BUFSIZE, in))) + fwrite(buf, 1, bytes, x); + fclose(in); +} + +/* If no dynamic libraries were found, perform like "-static". Otherwise, + create "xlibs.c", "shared.x" and invoke "gcc" to create "xlibs.o". We also + have to adjust the linker commandline. */ + +void +amigaos_prelink_hook (const char **ld1_argv, int *strip_flag) +{ + if (flag_static) + return; + + if (!found_dynamic_libs) + { + flag_static=1; + /* If the user has not requested "-static", but has requested "-s", + collect2 removes "-s" from the "ld1_argv", and calls "strip" after + linking. However, this would not be efficient if we linked the + executable without any dynamic library. In this case, we put "-s" + back. */ + if (*strip_flag) + { + /* Add "-s" as the last argument on the command line. */ + while (*ld1_argv) + ld1_argv++; + *ld1_argv++="-s"; + *ld1_argv=0; + *strip_flag=0; + } + } + else + { + FILE *x, *out; + struct liblist *lib; + static const char* argv[]={0, "-c", XLIBS_C_NAME, 0}; + const char **ld1_end, **ld1; + + /* Prepend suffixes to dynamic lib names. In addition, check if we are + linking a base relative executable. */ + for (ld1=ld1_argv; *ld1; ld1++) + { + int len=strlen(*ld1); + if (strncmp(*ld1, "-l", strlen("-l"))==0) + { + for (lib=head; lib; lib=lib->next) + if (strcmp(*ld1+strlen("-l"), lib->name)==0) + { + char *newname= + xmalloc(strlen(*ld1)+strlen(DYNAMIC_LIB_SUFFIX)+1); + strcpy(newname, *ld1); + strcat(newname, DYNAMIC_LIB_SUFFIX); + *ld1=newname; + break; + } + } + else if (len > 2 && !strcmp(*ld1 + len - 2, ".a")) + { + const char *libname; + int substituted=0; + + ((char *)(*ld1))[len - 2] = '\0'; + libname = strrchr(*ld1, '/'); + if (libname == NULL) + libname = strrchr(*ld1, ':'); + if (libname == NULL) + libname = *ld1 - 1; + if (!strncmp(libname + 1, "lib", 3)) + for (lib=head; lib; lib=lib->next) + if (strcmp(libname+4, lib->name)==0) + { + char *newname=xmalloc(strlen(*ld1)+ + strlen(DYNAMIC_LIB_SUFFIX)+3); + strcpy(newname, *ld1); + strcat(newname, DYNAMIC_LIB_SUFFIX); + strcat(newname, ".a"); + *ld1=newname; + substituted=1; + break; + } + if (!substituted) + ((char *)(*ld1))[len - 2] = '.'; + } + else if (strcmp(ld1[0], "-m")==0 && ld1[1] + && strcmp(ld1[1], "amiga_bss")==0) + { + flag_baserel=1; + break; + } + } + + out = fopen(XLIBS_C_NAME, "w"); + if (out == NULL) + fatal_perror("%s", XLIBS_C_NAME); + x = fopen(SHARED_X_NAME, "w"); + if (x == NULL) + fatal_perror("%s", SHARED_X_NAME); + + cat((flag_baserel ? A2IXDIR_PREFIX "/amiga_exe_baserel_script.x" + : A2IXDIR_PREFIX "/amiga_exe_script.x"), x); + for (lib = head; lib; lib = lib->next) + { + static char buf[256]; + sprintf(buf, A2IXDIR_PREFIX "/ldscripts/%s.x", lib->name); + fprintf(out, "extern long %sBase; long *__p%sBase = &%sBase;\n", + lib->cname, lib->cname, lib->cname); + cat(buf, x); + } /* {{ */ + fprintf(x, "}}\n"); + fclose(out); + fclose(x); + argv[0]=c_file_name; + fork_execute("gcc", (char **)argv); + + /* Unfortunately, unlike "-s", "-T" cannot be specified as the last + argument. We put it after "-L" args. */ + ld1_end=ld1_argv; + while (*ld1_end) + ld1_end++; + ld1_end++; + /* "ld1_end" now points after the terminating 0 of "ld1_argv". */ + + ld1=ld1_end-2; + while (ld1>ld1_argv && strncmp(*ld1, "-L", strlen("-L"))) + ld1--; + if (ld1==ld1_argv) + fatal("no -L arguments"); + ld1++; + /* "ld1" now points after "-L". */ + + /* Shift all the arguments after "-L" one position right. */ + memmove(ld1+1, ld1, (ld1_end-ld1)*sizeof(*ld1)); + /* Put -Tshared.x in the now empty space. */ + *ld1="-T" SHARED_X_NAME; + } +} + +/* Be lazy and just call "postlink". */ + +void +amigaos_postlink_hook (const char *output_file) +{ + static const char *argv[]={"postlink", 0, 0, 0}; + if (flag_static) + return; + + if (flag_baserel) + { + argv[1]="-baserel"; + argv[2]=output_file; + } + else + argv[1]=output_file; + fork_execute("postlink", (char **)argv); +} + +* Write out the constructor and destructor tables statically (for a shared + object), along with the functions to execute them. */ + +static void +write_c_file_stat (FILE *stream, const char *name ATTRIBUTE_UNUSED) +{ + const char *p, *q; + char *prefix, *r; + int frames = (frame_tables.number > 0); + + /* Figure out name of output_file, stripping off .so version. */ + p = strrchr (output_file, '/'); + if (p == 0) + p = output_file; + else + p++; + q = p; + while (q) + { + q = strchr (q,'.'); + if (q == 0) + { + q = p + strlen (p); + break; + } + else + { + if (strncmp (q, SHLIB_SUFFIX, strlen (SHLIB_SUFFIX)) == 0) + { + q += strlen (SHLIB_SUFFIX); + break; + } + else + q++; + } + } + /* q points to null at end of the string (or . of the .so version) */ + prefix = XNEWVEC (char, q - p + 1); + strncpy (prefix, p, q - p); + prefix[q - p] = 0; + for (r = prefix; *r; r++) + if (!ISALNUM ((unsigned char)*r)) + *r = '_'; + if (debug) + notice ("\nwrite_c_file - output name is %s, prefix is %s\n", + output_file, prefix); + + initname = concat ("_GLOBAL__FI_", prefix, NULL); + fininame = concat ("_GLOBAL__FD_", prefix, NULL); + + free (prefix); + + /* Write the tables as C code. */ + + fprintf (stream, "static int count;\n"); + fprintf (stream, "typedef void entry_pt();\n"); + write_list_with_asm (stream, "extern entry_pt ", constructors.first); + + if (frames) + { + write_list_with_asm (stream, "extern void *", frame_tables.first); + + fprintf (stream, "\tstatic void *frame_table[] = {\n"); + write_list (stream, "\t\t&", frame_tables.first); + fprintf (stream, "\t0\n};\n"); + + /* This must match what's in frame.h. */ + fprintf (stream, "struct object {\n"); + fprintf (stream, " void *pc_begin;\n"); + fprintf (stream, " void *pc_end;\n"); + fprintf (stream, " void *fde_begin;\n"); + fprintf (stream, " void *fde_array;\n"); + fprintf (stream, " __SIZE_TYPE__ count;\n"); + fprintf (stream, " struct object *next;\n"); + fprintf (stream, "};\n"); + + fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n"); + fprintf (stream, "extern void *__deregister_frame_info (void *);\n"); + + fprintf (stream, "static void reg_frame () {\n"); + fprintf (stream, "\tstatic struct object ob;\n"); + fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n"); + fprintf (stream, "\t}\n"); + + fprintf (stream, "static void dereg_frame () {\n"); + fprintf (stream, "\t__deregister_frame_info (frame_table);\n"); + fprintf (stream, "\t}\n"); + } + + fprintf (stream, "void %s() {\n", initname); + if (constructors.number > 0 || frames) + { + fprintf (stream, "\tstatic entry_pt *ctors[] = {\n"); + write_list (stream, "\t\t", constructors.first); + if (frames) + fprintf (stream, "\treg_frame,\n"); + fprintf (stream, "\t};\n"); + fprintf (stream, "\tentry_pt **p;\n"); + fprintf (stream, "\tif (count++ != 0) return;\n"); + fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames); + fprintf (stream, "\twhile (p > ctors) (*--p)();\n"); + } + else + fprintf (stream, "\t++count;\n"); + fprintf (stream, "}\n"); + write_list_with_asm (stream, "extern entry_pt ", destructors.first); + fprintf (stream, "void %s() {\n", fininame); + if (destructors.number > 0 || frames) + { + fprintf (stream, "\tstatic entry_pt *dtors[] = {\n"); + write_list (stream, "\t\t", destructors.first); + if (frames) + fprintf (stream, "\tdereg_frame,\n"); + fprintf (stream, "\t};\n"); + fprintf (stream, "\tentry_pt **p;\n"); + fprintf (stream, "\tif (--count != 0) return;\n"); + fprintf (stream, "\tp = dtors;\n"); + fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n", + destructors.number + frames); + } + fprintf (stream, "}\n"); + + if (shared_obj) + { + COLLECT_SHARED_INIT_FUNC(stream, initname); + COLLECT_SHARED_FINI_FUNC(stream, fininame); + } +} + +/* Write the constructor/destructor tables. */ + + +#ifndef LD_INIT_SWITCH +static void +write_c_file_glob (FILE *stream, const char *name ATTRIBUTE_UNUSED) +{ + /* Write the tables as C code. */ + + int frames = (frame_tables.number > 0); + + fprintf (stream, "typedef void entry_pt();\n\n"); + + write_list_with_asm (stream, "extern entry_pt ", constructors.first); + + if (frames) + { + write_list_with_asm (stream, "extern void *", frame_tables.first); + + fprintf (stream, "\tstatic void *frame_table[] = {\n"); + write_list (stream, "\t\t&", frame_tables.first); + fprintf (stream, "\t0\n};\n"); + + /* This must match what's in frame.h. */ + fprintf (stream, "struct object {\n"); + fprintf (stream, " void *pc_begin;\n"); + fprintf (stream, " void *pc_end;\n"); + fprintf (stream, " void *fde_begin;\n"); + fprintf (stream, " void *fde_array;\n"); + fprintf (stream, " __SIZE_TYPE__ count;\n"); + fprintf (stream, " struct object *next;\n"); + fprintf (stream, "};\n"); + + fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n"); + fprintf (stream, "extern void *__deregister_frame_info (void *);\n"); + + fprintf (stream, "static void reg_frame () {\n"); + fprintf (stream, "\tstatic struct object ob;\n"); + fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n"); + fprintf (stream, "\t}\n"); + + fprintf (stream, "static void dereg_frame () {\n"); + fprintf (stream, "\t__deregister_frame_info (frame_table);\n"); + fprintf (stream, "\t}\n"); + } + + fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n"); + fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames); + write_list (stream, "\t", constructors.first); + if (frames) + fprintf (stream, "\treg_frame,\n"); + fprintf (stream, "\t0\n};\n\n"); + + write_list_with_asm (stream, "extern entry_pt ", destructors.first); + + fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n"); + fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames); + write_list (stream, "\t", destructors.first); + if (frames) + fprintf (stream, "\tdereg_frame,\n"); + fprintf (stream, "\t0\n};\n\n"); + + fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN); + fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN); +} +#endif /* ! LD_INIT_SWITCH */ + +static void +write_c_file (FILE *stream, const char *name) +{ + fprintf (stream, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n"); +#ifndef LD_INIT_SWITCH + if (! shared_obj) + write_c_file_glob (stream, name); + else +#endif + write_c_file_stat (stream, name); + fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n"); +} \ No newline at end of file diff --git a/m68k-unknown-amigaos/recipes/files/gcc/config/m68k/amigaos-protos.h b/m68k-unknown-amigaos/recipes/files/gcc/config/m68k/amigaos-protos.h new file mode 100644 index 0000000..d192f03 --- /dev/null +++ b/m68k-unknown-amigaos/recipes/files/gcc/config/m68k/amigaos-protos.h @@ -0,0 +1,45 @@ +/* Configuration for GNU C-compiler for m68k Amiga, running AmigaOS. + Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2003 + Free Software Foundation, Inc. + Contributed by Markus M. Wild (wild@amiga.physik.unizh.ch). + Heavily modified by Kamil Iskra (iskra@student.uci.agh.edu.pl). + +This file is part of GCC. + +GCC 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. + +GCC 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 GCC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +extern int amigaos_restore_a4 (void); +#ifdef RTX_CODE +extern int read_only_operand (rtx); +extern void amigaos_select_section (tree, int, unsigned HOST_WIDE_INT); +extern void amigaos_encode_section_info (tree, rtx, int); +extern void amigaos_alternate_pic_setup (FILE *); +extern void amigaos_prologue_begin_hook (FILE *, int); +extern void amigaos_alternate_frame_setup_f (FILE *, int); +extern void amigaos_alternate_frame_setup (FILE *, int); +extern struct rtx_def* gen_stack_cleanup_call (rtx, rtx); +extern void amigaos_alternate_allocate_stack (rtx *); +#ifdef TREE_CODE +extern void amigaos_init_cumulative_args (CUMULATIVE_ARGS *, tree); +//extern void amigaos_function_arg_advance (CUMULATIVE_ARGS *); +extern struct rtx_def *amigaos_function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree); +#endif +#endif +#ifdef TREE_CODE +extern tree amigaos_handle_decl_attribute (tree *, tree, tree, int, bool *); +extern tree amigaos_handle_type_attribute (tree *, tree, tree, int, bool *); +extern int amigaos_comp_type_attributes (tree, tree); +#endif diff --git a/m68k-unknown-amigaos/recipes/files/gcc/config/m68k/amigaos.c b/m68k-unknown-amigaos/recipes/files/gcc/config/m68k/amigaos.c new file mode 100644 index 0000000..3b1782c --- /dev/null +++ b/m68k-unknown-amigaos/recipes/files/gcc/config/m68k/amigaos.c @@ -0,0 +1,726 @@ +/* Configuration for GNU C-compiler for m68k Amiga, running AmigaOS. + Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2003 + Free Software Foundation, Inc. + Contributed by Markus M. Wild (wild@amiga.physik.unizh.ch). + Heavily modified by Kamil Iskra (iskra@student.uci.agh.edu.pl). + +This file is part of GCC. + +GCC 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. + +GCC 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 GCC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +//work without flag_writable_strings which is not in GCC4 +//#include "config/m68k/amigaos.h" +#define REGPARMS_68K 1 + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "rtl.h" +#include "output.h" +#include "tree.h" +#include "flags.h" +#include "expr.h" +#include "toplev.h" +#include "tm_p.h" + +static int amigaos_put_in_text (tree); +static rtx gen_stack_management_call (rtx, rtx, const char *); +int m68k_regparm; +/* Baserel support. */ + +/* Does operand (which is a symbolic_operand) live in text space? If + so SYMBOL_REF_FLAG, which is set by ENCODE_SECTION_INFO, will be true. + + This function is used in base relative code generation. */ + +int +read_only_operand (rtx operand) +{ + if (GET_CODE (operand) == CONST) + operand = XEXP (XEXP (operand, 0), 0); + if (GET_CODE (operand) == SYMBOL_REF) + return SYMBOL_REF_FLAG (operand) || CONSTANT_POOL_ADDRESS_P (operand); + return 1; +} + +/* Choose the section to use for DECL. RELOC is true if its value contains + any relocatable expression. */ + +void +amigaos_select_section (tree decl, int reloc, + unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED) +{ + // if (TREE_CODE (decl) == STRING_CST) +// { +//// flag_writable_strings /data_section not in gcc4, +////make life easy and put to same section +//// if (! flag_writable_strings) +//// readonly_data_section (); +//// else +// //data_section (); +// } +// else if (TREE_CODE (decl) == VAR_DECL) +// { +// if (TREE_READONLY (decl) +// && ! TREE_THIS_VOLATILE (decl) +// && DECL_INITIAL (decl) +// && (DECL_INITIAL (decl) == error_mark_node +// || TREE_CONSTANT (DECL_INITIAL (decl))) +// && (!flag_pic || (flag_pic<3 && !reloc) +// || SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)))) +// readonly_data_section (); +// else +// data_section (); +// } +// else if ((!flag_pic || (flag_pic<3 && !reloc)) && DECL_P(decl) +// && SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0))) +// readonly_data_section (); +// else + //data_section (); +} + +/* This function is used while generating a base relative code. + It returns 1 if a decl is not relocatable, i. e., if it can be put + in the text section. + Currently, it's very primitive: it just checks if the object size + is less than 4 bytes (i. e., if it can hold a pointer). It also + supports arrays and floating point types. */ + +static int +amigaos_put_in_text (tree decl) +{ + tree type = TREE_TYPE (decl); + if (TREE_CODE (type) == ARRAY_TYPE) + type = TREE_TYPE (type); + return (TREE_INT_CST_HIGH (TYPE_SIZE (type)) == 0 + && TREE_INT_CST_LOW (TYPE_SIZE (type)) < 32) + || FLOAT_TYPE_P (type); +} + +/* Record properties of a DECL into the associated SYMBOL_REF. */ + +void +amigaos_encode_section_info (tree decl, rtx rtl, int first) +{ + default_encode_section_info (decl, rtl, first); + + + SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1; + //if (TREE_CODE (decl) == FUNCTION_DECL) // huh seem do same. not in gcc4 flag_writable_strings +// SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1; +// else +// { +// if ((RTX_UNCHANGING_P (rtl) && !MEM_VOLATILE_P (rtl) +// && (flag_pic<3 || (TREE_CODE (decl) == STRING_CST +// && !flag_writable_strings) +// || amigaos_put_in_text (decl))) +// || (TREE_CODE (decl) == VAR_DECL +// && DECL_SECTION_NAME (decl) != NULL_TREE)) +// SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1; +// } +} + +/* Common routine used to check if a4 should be preserved/restored. */ + +int +amigaos_restore_a4 (void) +{ + return (flag_pic >= 3 && + (TARGET_RESTORE_A4 || TARGET_ALWAYS_RESTORE_A4 + || lookup_attribute ("saveds", + TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))); +} + +void +amigaos_alternate_pic_setup (FILE *stream) +{ + if (TARGET_RESTORE_A4 || TARGET_ALWAYS_RESTORE_A4) + asm_fprintf (stream, "\tjbsr %U__restore_a4\n"); + else if (lookup_attribute ("saveds", + TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl)))) + asm_fprintf (stream, "\tlea %U__a4_init,%Ra4\n"); +} + +/* Attributes support. */ + +#define AMIGA_CHIP_SECTION_NAME ".datachip" + +/* Handle a "chip" attribute; + arguments as in struct attribute_spec.handler. */ + +tree +amigaos_handle_decl_attribute (tree *node, tree name, + tree args ATTRIBUTE_UNUSED, + int flags ATTRIBUTE_UNUSED, + bool *no_add_attrs) +{ + if (TREE_CODE (*node) == VAR_DECL) + { + if (is_attribute_p ("chip", name)) +#ifdef TARGET_ASM_NAMED_SECTION + { + if (! TREE_STATIC (*node) && ! DECL_EXTERNAL (*node)) + error ("`chip' attribute cannot be specified for local variables"); + else + { + /* The decl may have already been given a section attribute from + a previous declaration. Ensure they match. */ + if (DECL_SECTION_NAME (*node) == NULL_TREE) + DECL_SECTION_NAME (*node) = + build_string (strlen (AMIGA_CHIP_SECTION_NAME) + 1, + AMIGA_CHIP_SECTION_NAME); + else if (strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (*node)), + AMIGA_CHIP_SECTION_NAME) != 0) + { + error_with_decl (*node, + "`chip' for `%s' conflicts with previous declaration"); + } + } + } +#else + error ("`chip' attribute is not supported for this target"); +#endif + } + else + { + warning ("`%s' attribute only applies to variables", + IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + } + + return NULL_TREE; +} + +//----- from 68k.c start + + + + + +/* Handle a "regparm" or "stkparm" attribute; + arguments as in struct attribute_spec.handler. */ + + +static tree +m68k_handle_type_attribute (tree *node, tree name, tree args, + int flags ATTRIBUTE_UNUSED, bool *no_add_attrs) +{ + + if (TREE_CODE (*node) == FUNCTION_TYPE || TREE_CODE (*node) == METHOD_TYPE) + { + /* 'regparm' accepts one optional argument - number of registers in + single class that should be used to pass arguments. */ + if (is_attribute_p ("regparm_x", name)) + { + if (lookup_attribute ("stkparm_x", TYPE_ATTRIBUTES(*node))) + { + error ("`regparm' and `stkparm' are mutually exclusive"); + } + if (args && TREE_CODE (args) == TREE_LIST) + { + tree numofregs = TREE_VALUE (args); + if (numofregs) + if (TREE_CODE (numofregs) != INTEGER_CST +/* + || compare_tree_int(numofregs, 1) < 0 + || compare_tree_int(numofregs, M68K_MAX_REGPARM) > 0) +*/ + || TREE_INT_CST_HIGH (numofregs) + || TREE_INT_CST_LOW (numofregs) < 1 + || TREE_INT_CST_LOW (numofregs) > M68K_MAX_REGPARM) + { + error ("invalid argument to `regparm' attribute"); + } + } + } + else if (is_attribute_p ("stkparm_x", name)) + { + if (lookup_attribute ("regparm_x", TYPE_ATTRIBUTES(*node))) + { + error ("`regparm' and `stkparm' are mutually exclusive"); + } + } + } + else + { + warning ("`%s' attribute only applies to functions", + IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + } + + return NULL_TREE; +} + +/* Return zero if the attributes on TYPE1 and TYPE2 are incompatible, + one if they are compatible, and two if they are nearly compatible + (which causes a warning to be generated). */ + +static int +m68k_comp_type_attributes (tree type1, tree type2) +{ + + /* Functions or methods are incompatible if they specify mutually + exclusive ways of passing arguments. */ + if (TREE_CODE (type1) == FUNCTION_TYPE || TREE_CODE (type1) == METHOD_TYPE) + { + tree arg1, arg2; + if (!! lookup_attribute ("stkparm_x", TYPE_ATTRIBUTES (type1)) != + !! lookup_attribute ("stkparm_x", TYPE_ATTRIBUTES (type2)) + || !! lookup_attribute ("regparm_x", TYPE_ATTRIBUTES (type1)) != + !! lookup_attribute ("regparm_x", TYPE_ATTRIBUTES (type2))) + return 0; /* 'regparm' and 'stkparm' are mutually exclusive. */ + + arg1 = lookup_attribute ("regparm_x", TYPE_ATTRIBUTES (type1)); + arg2 = lookup_attribute ("regparm_x", TYPE_ATTRIBUTES (type2)); + if (arg1 && arg2) + { + int num1 = 0, num2 = 0; + if (TREE_VALUE (arg1) && TREE_CODE (TREE_VALUE (arg1)) == TREE_LIST) + { + tree numofregs = TREE_VALUE (TREE_VALUE (arg1)); + if (numofregs) + num1 = TREE_INT_CST_LOW (numofregs); + } + if (TREE_VALUE (arg2) && TREE_CODE (TREE_VALUE (arg2)) == TREE_LIST) + { + tree numofregs = TREE_VALUE (TREE_VALUE (arg2)); + if (numofregs) + num2 = TREE_INT_CST_LOW (numofregs); + } + if (num1 != num2) + return 0; /* Different numbers, or no number in one type. */ + } + } +#ifdef TARGET_AMIGAOS + return amigaos_comp_type_attributes(type1, type2); +#else + return 1; +#endif +} + +/* Argument-passing support functions. */ + +/* Initialize a variable CUM of type CUMULATIVE_ARGS + for a call to a function whose data type is FNTYPE. + For a library call, FNTYPE is 0. */ + +void +m68k_init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype) +{ + cum->last_arg_reg = -1; + cum->regs_already_used = 0; + if (fntype) + { + if (lookup_attribute ("stkparm_x", TYPE_ATTRIBUTES (fntype))) + cum->num_of_regs = 0; + else + { + tree ratree = lookup_attribute ("regparm_x", TYPE_ATTRIBUTES (fntype)); + if (ratree) + { + cum->num_of_regs = m68k_regparm ? m68k_regparm + : M68K_DEFAULT_REGPARM; + if (TREE_VALUE (ratree) + && TREE_CODE (TREE_VALUE (ratree)) == TREE_LIST) + { + tree num_of_regs = TREE_VALUE (TREE_VALUE (ratree)); + cum->num_of_regs = + num_of_regs ? TREE_INT_CST_LOW (num_of_regs) : + (m68k_regparm ? m68k_regparm : M68K_DEFAULT_REGPARM); + } + } + else + cum->num_of_regs = m68k_regparm; + } + } + else /* Libcall. */ + cum->num_of_regs = 0; + + if (cum->num_of_regs) + { + /* If this is a vararg call, put all arguments on stack. */ + tree param, next_param; + for (param = TYPE_ARG_TYPES (fntype); param; param = next_param) + { + next_param = TREE_CHAIN (param); + if (!next_param && TREE_VALUE (param) != void_type_node) + cum->num_of_regs = 0; + } + } + +#if ! defined (PCC_STATIC_STRUCT_RETURN) && defined (M68K_STRUCT_VALUE_REGNUM) + /* If return value is a structure, and we pass the buffer address in a + register, we can't use this register for our own purposes. + FIXME: Something similar would be useful for static chain. */ + if (fntype && aggregate_value_p (TREE_TYPE (fntype), fntype)) + cum->regs_already_used |= (1 << M68K_STRUCT_VALUE_REGNUM); +#endif +} + +/* Update the data in CUM to advance over an argument. */ + +void +m68k_function_arg_advance (CUMULATIVE_ARGS *cum) +{ + if (cum->last_arg_reg != -1) + { + int count; + for (count = 0; count < cum->last_arg_len; count++) + cum->regs_already_used |= (1 << (cum->last_arg_reg + count)); + cum->last_arg_reg = -1; + } +} + +/* Define where to put the arguments to a function. + Value is zero to push the argument on the stack, + or a hard register in which to store the argument. + + MODE is the argument's machine mode. + TYPE is the data type of the argument (as a tree). + This is null for libcalls where that information may + not be available. + CUM is a variable of type CUMULATIVE_ARGS which gives info about + the preceding args and about the function being called. */ + +struct rtx_def * +m68k_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type) +{ + if (cum->num_of_regs) + { + int regbegin = -1, altregbegin = -1, len; + + /* FIXME: The last condition below is a workaround for a bug. */ + if (TARGET_68881 && FLOAT_MODE_P (mode) && + GET_MODE_UNIT_SIZE (mode) <= 12 && + (GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT || mode == SCmode)) + { + regbegin = 16; /* FPx */ + len = GET_MODE_NUNITS (mode); + } + /* FIXME: Two last conditions below are workarounds for bugs. */ + else if (INTEGRAL_MODE_P (mode) && mode !=CQImode && mode != CHImode) + { + if (POINTER_TYPE_P (type)) + regbegin = 8; /* Ax */ + else + regbegin = 0; /* Dx */ + altregbegin = 8 - regbegin; + len = (GET_MODE_SIZE (mode) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD; + } + + if (regbegin != -1) + { + int reg; + long mask; + +look_for_reg: + mask = 1 << regbegin; + for (reg = 0; reg < cum->num_of_regs; reg++, mask <<= 1) + if (!(cum->regs_already_used & mask)) + { + int end; + for (end = reg; end < cum->num_of_regs && end < reg + len; + end++, mask <<= 1) + if (cum->regs_already_used & mask) + break; + if (end == reg + len) + { + cum->last_arg_reg = reg + regbegin; + cum->last_arg_len = len; + break; + } + } + + if (reg == cum->num_of_regs && altregbegin != -1) + { + regbegin = altregbegin; + altregbegin = -1; + goto look_for_reg; + } + } + + if (cum->last_arg_reg != -1) + return gen_rtx_REG (mode, cum->last_arg_reg); + } + return 0; +} + +// end from 68k.h diff + +/* Handle a "stackext", "interrupt" or "saveds" attribute; ++ arguments as in struct attribute_spec.handler. */ + +tree +amigaos_handle_type_attribute (tree *node, tree name, + tree args ATTRIBUTE_UNUSED, + int flags ATTRIBUTE_UNUSED, + bool *no_add_attrs) +{ + if (TREE_CODE (*node) == FUNCTION_TYPE || TREE_CODE (*node) == METHOD_TYPE) + { + if (is_attribute_p ("stackext", name)) + { + if (lookup_attribute ("interrupt", TYPE_ATTRIBUTES(*node))) + { + error ("`stackext' and `interrupt' are mutually exclusive"); + } + } + else if (is_attribute_p ("interrupt", name)) + { + if (lookup_attribute ("stackext", TYPE_ATTRIBUTES(*node))) + { + error ("`stackext' and `interrupt' are mutually exclusive"); + } + } + else if (is_attribute_p ("saveds", name)) + { + } + } + else + { + warning ("`%s' attribute only applies to functions", + IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + } + + return NULL_TREE; +} + +/* Stack checking and automatic extension support. */ + +void +amigaos_prologue_begin_hook (FILE *stream, int fsize) +{ + if (TARGET_STACKCHECK) + { + if (fsize < 256) + asm_fprintf (stream, "\tcmpl %s,%Rsp\n" + "\tjcc 0f\n" + "\tjra %U__stkovf\n" + "\t0:\n", + (flag_pic == 3 ? "a4@(___stk_limit:W)" : + (flag_pic == 4 ? "a4@(___stk_limit:L)" : + "___stk_limit"))); + else + asm_fprintf (stream, "\tmovel %I%d,%Rd0\n\tjbsr %U__stkchk_d0\n", + fsize); + } +} + +void +amigaos_alternate_frame_setup_f (FILE *stream, int fsize) +{ + if (fsize < 128) + asm_fprintf (stream, "\tcmpl %s,%Rsp\n" + "\tjcc 0f\n" + "\tmoveq %I%d,%Rd0\n" + "\tmoveq %I0,%Rd1\n" + "\tjbsr %U__stkext_f\n" + "0:\tlink %Ra5,%I%d:W\n", + (flag_pic == 3 ? "a4@(___stk_limit:W)" : + (flag_pic == 4 ? "a4@(___stk_limit:L)" : + "___stk_limit")), + fsize, -fsize); + else + asm_fprintf (stream, "\tmovel %I%d,%Rd0\n\tjbsr %U__link_a5_d0_f\n", + fsize); +} + +void +amigaos_alternate_frame_setup (FILE *stream, int fsize) +{ + if (!fsize) + asm_fprintf (stream, "\tcmpl %s,%Rsp\n" + "\tjcc 0f\n" + "\tmoveq %I0,%Rd0\n" + "\tmoveq %I0,%Rd1\n" + "\tjbsr %U__stkext_f\n" + "0:\n", + (flag_pic == 3 ? "a4@(___stk_limit:W)" : + (flag_pic == 4 ? "a4@(___stk_limit:L)" : + "___stk_limit"))); + else if (fsize < 128) + asm_fprintf (stream, "\tcmpl %s,%Rsp\n" + "\tjcc 0f\n" + "\tmoveq %I%d,%Rd0\n" + "\tmoveq %I0,%Rd1\n" + "\tjbsr %U__stkext_f\n" + "0:\taddw %I%d,%Rsp\n", + (flag_pic == 3 ? "a4@(___stk_limit:W)" : + (flag_pic == 4 ? "a4@(___stk_limit:L)" : + "___stk_limit")), + fsize, -fsize); + else + asm_fprintf (stream, "\tmovel %I%d,%Rd0\n\tjbsr %U__sub_d0_sp_f\n", + fsize); +} + +//static rtx +//gen_stack_management_call (rtx stack_pointer, rtx arg, const char *func) +//{ +// rtx call_insn, call, seq, name; +// start_sequence (); +// +// /* Move arg to d0. */ +// emit_move_insn (gen_rtx_REG (SImode, 0), arg); +// +// /* Generate the function reference. */ +// name = gen_rtx_SYMBOL_REF (Pmode, func); +// SYMBOL_REF_FLAG (name) = 1; +// /* If optimizing, put it in a psedo so that several loads can be merged +// into one. */ +// if (optimize && ! flag_no_function_cse) +// name = copy_to_reg (name); +// +// /* Generate the function call. */ +// call = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (FUNCTION_MODE, name), +// const0_rtx); +// /* If we are doing stack extension, notify about the sp change. */ +// if (stack_pointer) +// call = gen_rtx_SET (VOIDmode, stack_pointer, call); +// +// /* Generate the call instruction. */ +// call_insn = emit_call_insn (call); +// /* Stack extension does not change memory in an unpredictable way. */ +// RTL_CONST_OR_PURE_CALL_P (call_insn) = 1; +// /* We pass an argument in d0. */ +// CALL_INSN_FUNCTION_USAGE (call_insn) = gen_rtx_EXPR_LIST (VOIDmode, +// gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 0)), 0); +// +// seq = get_insns (); +// end_sequence (); +// return seq; +//} +// +//rtx +//gen_stack_cleanup_call (rtx stack_pointer, rtx sa) +//{ +// return gen_stack_management_call (stack_pointer, sa, "__move_d0_sp"); +//} +// +//void +//amigaos_alternate_allocate_stack (rtx *operands) +//{ +// if (TARGET_STACKEXTEND) +// emit_insn (gen_stack_management_call (stack_pointer_rtx, operands[1], +// "__sub_d0_sp")); +// else +// { +// if (TARGET_STACKCHECK) +// emit_insn (gen_stack_management_call (0, operands[1], "__stkchk_d0")); +// anti_adjust_stack (operands[1]); +// } +// emit_move_insn (operands[0], virtual_stack_dynamic_rtx); +//} + +/* begin-GG-local: explicit register specification for parameters */ + +/* Initialize a variable CUM of type CUMULATIVE_ARGS + for a call to a function whose data type is FNTYPE. + For a library call, FNTYPE is 0. */ + +void +amigaos_init_cumulative_args(CUMULATIVE_ARGS *cum, tree fntype) +{ + m68k_init_cumulative_args(cum, fntype); + + if (fntype) + cum->formal_type=TYPE_ARG_TYPES(fntype); + else /* Call to compiler-support function. */ + cum->formal_type=0; +} + +/* Update the data in CUM to advance over an argument. */ + +void +amigaos_function_arg_advance(CUMULATIVE_ARGS *cum) +{ + m68k_function_arg_advance(cum); + + if (cum->formal_type) + cum->formal_type=TREE_CHAIN((tree)cum->formal_type); +} + +/* A C expression that controls whether a function argument is passed + in a register, and which register. */ + +struct rtx_def * +amigaos_function_arg(CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type) +{ + tree asmtree; + return m68k_function_arg(cum, mode, type); // use old routine + if (cum->formal_type && TREE_VALUE((tree)cum->formal_type) + && (asmtree=lookup_attribute("asm_x", + TYPE_ATTRIBUTES(TREE_VALUE((tree)cum->formal_type))))) + { + int i; +#if 0 + /* See c-decl.c/push_parm_decl for an explanation why this doesn't work. + */ + cum->last_arg_reg=TREE_INT_CST_LOW(TREE_VALUE(TREE_VALUE(asmtree))); +#else + cum->last_arg_reg=TREE_INT_CST_LOW(TREE_VALUE(asmtree)); +#endif + cum->last_arg_len=HARD_REGNO_NREGS(cum->last_arg_reg, mode); + + for (i=0; ilast_arg_len; i++) + if (cum->regs_already_used & (1 << cum->last_arg_reg+i)) + { + error("two parameters allocated for one register"); + break; + } + return gen_rtx_REG (mode, cum->last_arg_reg); + } + else + return m68k_function_arg(cum, mode, type); +} + +/* Return zero if the attributes on TYPE1 and TYPE2 are incompatible, + one if they are compatible, and two if they are nearly compatible + (which causes a warning to be generated). */ + +int +amigaos_comp_type_attributes (tree type1, tree type2) +{ + /* Functions or methods are incompatible if they specify mutually exclusive + ways of passing arguments. */ + if (TREE_CODE(type1)==FUNCTION_TYPE || TREE_CODE(type1)==METHOD_TYPE) + { + tree arg1, arg2; + arg1=TYPE_ARG_TYPES(type1); + arg2=TYPE_ARG_TYPES(type2); + for (; arg1 && arg2; arg1=TREE_CHAIN(arg1), arg2=TREE_CHAIN(arg2)) + if (TREE_VALUE(arg1) && TREE_VALUE(arg2)) + { + tree asm1, asm2; + asm1=lookup_attribute("asm_x", TYPE_ATTRIBUTES(TREE_VALUE(arg1))); + asm2=lookup_attribute("asm_x", TYPE_ATTRIBUTES(TREE_VALUE(arg2))); + if (asm1 && asm2) + { + if (TREE_INT_CST_LOW(TREE_VALUE(asm1))!= + TREE_INT_CST_LOW(TREE_VALUE(asm2))) + return 0; /* Two different registers specified. */ + } + else + if (asm1 || asm2) + return 0; /* "asm" used in only one type. */ + } + } + return 1; +} + +/* end-GG-local */ diff --git a/m68k-unknown-amigaos/recipes/files/gcc/config/m68k/amigaos.h b/m68k-unknown-amigaos/recipes/files/gcc/config/m68k/amigaos.h new file mode 100644 index 0000000..5d86e79 --- /dev/null +++ b/m68k-unknown-amigaos/recipes/files/gcc/config/m68k/amigaos.h @@ -0,0 +1,678 @@ +/* Configuration for GNU C-compiler for m68k Amiga, running AmigaOS. + Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2003 + Free Software Foundation, Inc. + Contributed by Markus M. Wild (wild@amiga.physik.unizh.ch). + Heavily modified by Kamil Iskra (iskra@student.uci.agh.edu.pl). + + +This file is part of GCC. + +GCC 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. + +GCC 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 GCC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +//use the motorola syntax, other mode is broken. + +#undef TARGET_VERSION +#define TARGET_VERSION fprintf (stderr, " (68k, Motorola syntax)") + +#undef MOTOROLA +#define MOTOROLA 1 + +//#define IRA_COVER_CLASSES + +// disable 80 bit and 128 bit floats, dont work in libgcc + +#undef LIBGCC2_HAS_XF_MODE +#define LIBGCC2_HAS_XF_MODE 0 + +#undef LIBGCC2_HAS_TF_MODE +#define LIBGCC2_HAS_TF_MODE 0 + +/* The function name __transfer_from_trampoline is not actually used. + The function definition just permits use of asm with operands" + (though the operand list is empty). */ + +#undef TRANSFER_FROM_TRAMPOLINE + + +/* Compile using the first 'm68k_regparm' data, address and float + registers for arguments passing. */ +/*#define SUBTARGET_OPTIONS { "regparm=", &m68k_regparm_string, \ + N_("Use this register count to pass arguments"), 0},*/ + + + +/* Nonzero if we need to generate special stack-allocating insns. + On most systems they are not needed. + When they are needed, also define ALTERNATE_ALLOCATE_STACK (see m68k.md) + to perform the necessary actions. */ +//#undef TARGET_ALTERNATE_ALLOCATE_STACK +//#define TARGET_ALTERNATE_ALLOCATE_STACK 0 + + +/* Specs, switches. */ + +/* amiga/amigaos are the new "standard" defines for the Amiga. + MCH_AMIGA, AMIGA, __chip etc. are used in other compilers and are + provided for compatibility reasons. + When creating shared libraries, use different 'errno'. */ + + + +#undef TARGET_OS_CPP_BUILTINS +#define TARGET_OS_CPP_BUILTINS() \ + do \ + { \ + builtin_define ("__chip=__attribute__((__chip__))"); \ + builtin_define ("__saveds=__attribute__((__saveds__))"); \ + builtin_define ("__interrupt=__attribute__((__interrupt__))"); \ + builtin_define ("__stackext=__attribute__((__stackext__))"); \ + builtin_define ("__regargs_x=__attribute__((__regparm__))"); \ + builtin_define ("__stdargs_x=__attribute__((__stkparm__))"); \ + builtin_define ("__aligned=__attribute__((__aligned__(4)))"); \ + if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \ + builtin_define ("errno=(*ixemul_errno)"); \ + builtin_define_std ("amiga"); \ + builtin_define_std ("amigaos"); \ + builtin_define_std ("AMIGA"); \ + builtin_define_std ("MCH_AMIGA"); \ + builtin_assert ("system=amigaos"); \ + } \ + while (0) + +/* Inform the program which CPU we compile for. */ + +//#undef TARGET_CPU_CPP_BUILTINS +/* + use --with-cpu=mc68040 etc.. instead on config. code was after #define TARGET_CPU_CPP_BUILTINS() + if (TARGET_68040_ONLY) \ + { \ + if (TARGET_68060) \ + builtin_define_std ("mc68060"); \ + else \ + builtin_define_std ("mc68040"); \ + } \ + else if (TARGET_68030 && !TARGET_68040) \ + builtin_define_std ("mc68030"); \ + else if (TARGET_68020) \ + builtin_define_std ("mc68020"); \ + builtin_define_std ("mc68000"); \ +*/ +/* +#define TARGET_CPU_CPP_BUILTINS() \ + do \ + { \ + builtin_define_std ("mc68040"); \ + if (flag_pic > 2) \ + { \ + builtin_define ("__pic__"); \ + if (flag_pic > 3) \ + builtin_define ("__PIC__"); \ + } \ + builtin_assert ("cpu=m68k"); \ + builtin_assert ("machine=m68k"); \ + } \ + while (0) +*/ +/* Define __HAVE_68881__ in preprocessor according to the -m flags. + This will control the use of inline 68881 insns in certain macros. + Note: it should be set in TARGET_CPU_CPP_BUILTINS but TARGET_68881 + isn't the same -m68881 since its also true for -m680[46]0 ... + Differentiate between libnix and ixemul. */ + +#define CPP_SPEC \ + "%{m68881:-D__HAVE_68881__} " \ + "%{noixemul:%{!ansi:%{!std=*:-Dlibnix}%{std=gnu*:-Dlibnix}} -D__libnix -D__libnix__} " \ + "%{!noixemul:%{!ansi:%{!std=*:-Dixemul}%{std=gnu*:-Dixemul}} -D__ixemul -D__ixemul__}" + +/* Translate '-resident' to '-fbaserel' (they differ in linking stage only). + Don't put function addresses in registers for PC-relative code. */ + +#define CC1_SPEC \ + "%{resident:-fbaserel} " \ + "%{resident32:-fbaserel32} " \ + "%{msmall-code:-fno-function-cse}" + +/* Various -m flags require special flags to the assembler. */ + +#undef ASM_SPEC +#define ASM_SPEC \ + "%(asm_cpu) %(asm_cpu_default) %{msmall-code:-sc}" + +#undef ASM_CPU_SPEC +#define ASM_CPU_SPEC \ + "%{m68000|mc68000:-m68010} " \ + "%{m6802*|mc68020:-m68020} " \ + "%{m68030} " \ + "%{m68040} " \ + "%{m68060}" + +#define ASM_CPU_DEFAULT_SPEC \ + "%{!m680*:%{!mc680*:-m68040}}" + +/* If debugging, tell the linker to output amiga-hunk symbols *and* a BSD + compatible debug hunk. + Also, pass appropriate linker flavours depending on user-supplied + commandline options. */ + +#define LINK_SPEC \ + "%{noixemul:-fl libnix} " \ + "%{resident*:-amiga-datadata-reloc} " \ + "%{resident|fbaserel:-m amiga_bss -fl libb} " \ + "%{resident32|fbaserel32:-m amiga_bss -fl libb32} " \ + "%{g:-amiga-debug-hunk} " \ + "%(link_cpu)" + +#define LINK_CPU_SPEC \ + "%{m6802*|mc68020|m68030|m68040|m68060:-fl libm020} " \ + "%{m68881:-fl libm881}" + +/* Choose the right startup file, depending on whether we use base relative + code, base relative code with automatic relocation (-resident), their + 32-bit versions, libnix, profiling or plain crt0.o. */ + +#define STARTFILE_SPEC \ + "%{!noixemul:" \ + "%{fbaserel:%{!resident:bcrt0.o%s}}" \ + "%{resident:rcrt0.o%s}" \ + "%{fbaserel32:%{!resident32:lcrt0.o%s}}" \ + "%{resident32:scrt0.o%s}" \ + "%{!resident:%{!fbaserel:%{!resident32:%{!fbaserel32:" \ + "%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}}}}}}" \ + "%{noixemul:" \ + "%{resident:libnix/nrcrt0.o%s} " \ + "%{!resident:%{fbaserel:libnix/nbcrt0.o%s}%{!fbaserel:libnix/ncrt0.o%s}}}" + +#define ENDFILE_SPEC \ + "%{noixemul:-lstubs}" + +/* put return values in FPU build in FP0 Reg */ +#undef FUNCTION_VALUE_REGNO_P +#define FUNCTION_VALUE_REGNO_P(N) \ + ((N) == D0_REG || (N) == A0_REG || (TARGET_68881 && (N) == FP0_REG)) + + +/* Automatically search libamiga.a for AmigaOS specific functions. Note + that we first search the standard C library to resolve as much as + possible from there, since it has names that are duplicated in libamiga.a + which we *don't* want from there. Then search libamiga.a for any calls + that were not generated inline, and finally search the standard C library + again to resolve any references that libamiga.a might have generated. + This may only be a temporary solution since it might be better to simply + remove the things from libamiga.a that should be pulled in from libc.a + instead, which would eliminate the first reference to libc.a. Note that + if we don't search it automatically, it is very easy for the user to try + to put in a -lamiga himself and get it in the wrong place, so that (for + example) calls like sprintf come from -lamiga rather than -lc. */ + +#define LIB_SPEC \ + "%{!noixemul:" \ + "%{p|pg:-lc_p}" \ + "%{!p:%{!pg:-lc -lamiga -lc}}}" \ + "%{noixemul:" \ + "-lnixmain -lnix -lamiga %{mstackcheck|mstackextend:-lstack}}" + +/* This macro defines names of additional specifications to put in the specs + that can be used in various specifications like CC1_SPEC. Its definition + is an initializer with a subgrouping for each command option. + + Each subgrouping contains a string constant, that defines the + specification name, and a string constant that used by the GCC driver + program. + + Do not define this macro if it does not need to do anything. */ +#undef EXTRA_SPECS +#define EXTRA_SPECS \ + { "asm_cpu", ASM_CPU_SPEC }, \ + { "asm_cpu_default", ASM_CPU_DEFAULT_SPEC }, \ + { "link_cpu", LINK_CPU_SPEC } + +/* Compile with stack extension. */ + +#define MASK_STACKEXTEND 0x40000000 /* 1 << 30 */ +#define TARGET_STACKEXTEND (((target_flags & MASK_STACKEXTEND) \ + && !lookup_attribute ("interrupt", \ + TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl)))) \ + || lookup_attribute ("stackext", \ + TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl)))) + +///* Compile with stack checking. */ +// +#define MASK_STACKCHECK 0x20000000 /* 1 << 29 */ +#define TARGET_STACKCHECK ((target_flags & MASK_STACKCHECK) \ + && !(target_flags & MASK_STACKEXTEND) \ + && !lookup_attribute ("interrupt", \ + TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))) \ + && !lookup_attribute ("stackext", \ + TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl)))) + +/* Compile with a4 restoring in public functions. */ + +#define MASK_RESTORE_A4 0x10000000 /* 1 << 28 */ +#define TARGET_RESTORE_A4 \ + ((target_flags & MASK_RESTORE_A4) && TREE_PUBLIC (current_function_decl)) + +/* Compile with a4 restoring in all functions. */ + +#define MASK_ALWAYS_RESTORE_A4 0x8000000 /* 1 << 27 */ +#define TARGET_ALWAYS_RESTORE_A4 (target_flags & MASK_ALWAYS_RESTORE_A4) + +/* Provide a dummy entry for the '-msmall-code' switch. This is used by + the assembler and '*_SPEC'. */ + +#undef SUBTARGET_SWITCHES +#define SUBTARGET_SWITCHES \ + { "small-code", 0, \ + "" /* Undocumented. */ }, \ + { "stackcheck", MASK_STACKCHECK, \ + N_("Generate stack-check code") }, \ + { "no-stackcheck", - MASK_STACKCHECK, \ + N_("Do not generate stack-check code") }, \ + { "stackextend", MASK_STACKEXTEND, \ + N_("Generate stack-extension code") }, \ + { "no-stackextend", - MASK_STACKEXTEND, \ + N_("Do not generate stack-extension code") }, \ + { "fixedstack", - (MASK_STACKCHECK|MASK_STACKEXTEND), \ + N_("Do not generate stack-check/stack-extension code") }, \ + { "restore-a4", MASK_RESTORE_A4, \ + N_("Restore a4 in public functions") }, \ + { "no-restore-a4", - MASK_RESTORE_A4, \ + N_("Do not restore a4 in public functions") }, \ + { "always-restore-a4", MASK_ALWAYS_RESTORE_A4, \ + N_("Restore a4 in all functions") }, \ + { "no-always-restore-a4", - MASK_ALWAYS_RESTORE_A4, \ + N_("Do not restore a4 in all functions") }, \ + { "regparm_x", MASK_REGPARM, \ + N_("Pass arguments through registers") }, \ + { "no-regparm_x", - MASK_REGPARM, \ + N_("Don't pass arguments through registers") }, + +#undef SUBTARGET_OVERRIDE_OPTIONS +#define SUBTARGET_OVERRIDE_OPTIONS \ +do \ + { \ + if (!TARGET_68020 && flag_pic==4) \ + error ("-fbaserel32 is not supported on the 68000 or 68010\n"); \ + } \ +while (0) + +/* Various ABI issues. */ + +/* This is (almost;-) BSD, so it wants DBX format. */ + +#define DBX_DEBUGGING_INFO + +/* GDB goes mad if it sees the function end marker. */ + +#define NO_DBX_FUNCTION_END 1 + +/* Allow folding division by zero. */ + +#define REAL_INFINITY + +/* Don't try using XFmode since we don't have appropriate runtime software + support. */ +#undef LONG_DOUBLE_TYPE_SIZE +#define LONG_DOUBLE_TYPE_SIZE 64 + +/* Use A5 as framepointer instead of A6, since the AmigaOS ABI requires A6 + to be used as a shared library base pointer in direct library calls. */ + +#undef FRAME_POINTER_REGNUM +#define FRAME_POINTER_REGNUM 13 + +/* We use A4 for the PIC pointer, not A5, which is the framepointer. */ + +#undef PIC_OFFSET_TABLE_REGNUM +#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 12 : INVALID_REGNUM) + +/* The AmigaOS ABI does not define how structures should be returned, so, + contrary to 'm68k.h', we prefer a multithread-safe solution. */ + +#undef PCC_STATIC_STRUCT_RETURN + +/* Setup a default shell return value for those (gazillion..) programs that + (inspite of ANSI-C) declare main() to be void (or even VOID...) and thus + cause the shell to randomly caugh upon executing such programs (contrary + to Unix, AmigaOS scripts are terminated with an error if a program returns + with an error code above the `error' or even `failure' level + (which is configurable with the FAILAT command)). */ + +//+2004-06-24 Ulrich Weigand +//+ +//+ * c-decl.c (finish_function): Do not check for DEFAULT_MAIN_RETURN. +//+ * system.h (DEFAULT_MAIN_RETURN): Poison. +//+ * doc/tm.texi (DEFAULT_MAIN_RETURN): Remove documentation. +//+ + +//poison VAR +//#define DEFAULT_MAIN_RETURN c_expand_return (integer_zero_node) + +#undef WCHAR_TYPE +#define WCHAR_TYPE "unsigned int" + +/* XXX: section support */ +#if 0 +/* Support sections in chip memory, currently '.datachip' only. */ +#undef TARGET_ASM_NAMED_SECTION +#define TARGET_ASM_NAMED_SECTION amiga_named_section + +/* We define TARGET_ASM_NAMED_SECTION, but we don't support arbitrary sections, + including '.gcc_except_table', so we emulate the standard behaviour. */ +#undef TARGET_ASM_EXCEPTION_SECTION +#define TARGET_ASM_EXCEPTION_SECTION amiga_exception_section + +#undef TARGET_ASM_EH_FRAME_SECTION +#define TARGET_ASM_EH_FRAME_SECTION amiga_eh_frame_section +#endif + +/* Use sjlj exceptions because dwarf work only on elf targets */ +#undef DWARF2_UNWIND_INFO +#define DWARF2_UNWIND_INFO 0 + + + +/* GAS supports alignment up to 32768 bytes. */ +#undef ASM_OUTPUT_ALIGN +#define ASM_OUTPUT_ALIGN(FILE, LOG) \ +do \ + { \ + if ((LOG) == 1) \ + fprintf ((FILE), "\t.even\n"); \ + else \ + fprintf ((FILE), "\t.align %d\n", (LOG)); \ + } \ +while (0) + +#define MAX_OFILE_ALIGNMENT ((1 << 15)*BITS_PER_UNIT) + +/* Call __flush_cache() after building the trampoline: it will call + an appropriate OS cache-clearing routine. */ + +#undef FINALIZE_TRAMPOLINE +#define FINALIZE_TRAMPOLINE(TRAMP) \ + emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__flush_cache"), \ + 0, VOIDmode, 2, (TRAMP), Pmode, \ + GEN_INT (TRAMPOLINE_SIZE), SImode) + +/* Baserel support. */ + +/* Given that symbolic_operand(X), return TRUE if no special + base relative relocation is necessary */ + +#define LEGITIMATE_BASEREL_OPERAND_P(X) \ + (flag_pic >= 3 && read_only_operand (X)) + +#undef LEGITIMATE_PIC_OPERAND_P +#define LEGITIMATE_PIC_OPERAND_P(X) \ + (! symbolic_operand (X, VOIDmode) || LEGITIMATE_BASEREL_OPERAND_P (X)) + +/* Define this macro if references to a symbol must be treated + differently depending on something about the variable or + function named by the symbol (such as what section it is in). + + The macro definition, if any, is executed immediately after the + rtl for DECL or other node is created. + The value of the rtl will be a `mem' whose address is a + `symbol_ref'. + + The usual thing for this macro to do is to a flag in the + `symbol_ref' (such as `SYMBOL_REF_FLAG') or to store a modified + name string in the `symbol_ref' (if one bit is not enough + information). + + On the Amiga we use this to indicate if references to a symbol should be + absolute or base relative. */ + +#undef TARGET_ENCODE_SECTION_INFO +#define TARGET_ENCODE_SECTION_INFO amigaos_encode_section_info + +#define LIBCALL_ENCODE_SECTION_INFO(FUN) \ +do \ + { \ + if (flag_pic >= 3) \ + SYMBOL_REF_FLAG (FUN) = 1; \ + } \ +while (0) + +/* Select and switch to a section for EXP. */ + +//#undef TARGET_ASM_SELECT_SECTION +//#define TARGET_ASM_SELECT_SECTION amigaos_select_section + +/* Preserve A4 for baserel code if necessary. */ + +#define EXTRA_SAVE_REG(REGNO) \ +do { \ + if (flag_pic && flag_pic >= 3 && REGNO == PIC_OFFSET_TABLE_REGNUM \ + && amigaos_restore_a4()) \ + return true; \ +} while (0) + +/* Predicate for ALTERNATE_PIC_SETUP. */ + +#define HAVE_ALTERNATE_PIC_SETUP (flag_pic >= 3) + +/* Make a4 point at data hunk. */ + +#define ALTERNATE_PIC_SETUP(STREAM) \ + (amigaos_alternate_pic_setup (STREAM)) + +/* Attribute support. */ + +/* Generate the test of d0 before return to set cc register in 'interrupt' + function. */ + +#define EPILOGUE_END_HOOK(STREAM) \ +do \ + { \ + if (lookup_attribute ("interrupt", \ + TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl)))) \ + asm_fprintf ((STREAM), "\ttstl %Rd0\n"); \ + } \ +while (0) + +/* begin-GG-local: explicit register specification for parameters */ + +/* Note: this is an extension of m68k_args */ + + +/* A C type for declaring a variable that is used as the first + argument of `FUNCTION_ARG' and other related values. */ +/* Max. number of data, address and float registers to be used for passing + integer, pointer and float arguments when TARGET_REGPARM. + It's 4, so d0-d3, a0-a3 and fp0-fp3 can be used. */ +#undef M68K_MAX_REGPARM +#define M68K_MAX_REGPARM 4 + +/* The default number of data, address and float registers to use when + user specified '-mregparm' switch, not '-mregparm=' option. */ +#undef M68K_DEFAULT_REGPARM +#define M68K_DEFAULT_REGPARM 2 + +#undef FUNCTION_ARG_ADVANCE +#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ + (m68k_function_arg_advance (&(CUM))) + +#undef FUNCTION_ARG +#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ + (m68k_function_arg (&(CUM), (MODE), (TYPE))) + +#undef INIT_CUMULATIVE_ARGS +#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \ + (m68k_init_cumulative_args (&(CUM), (FNTYPE))) + + +#define MASK_REGPARM (1<<24) +#define TARGET_REGPARM (target_flags & MASK_REGPARM) + +#undef CLASS_MAX_NREGS +#define CLASS_MAX_NREGS(CLASS, MODE) \ + ((CLASS) == FP_REGS ? GET_MODE_NUNITS (MODE) \ + : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) + +/* 1 if N is a possible register number for function argument passing. */ +#undef FUNCTION_ARG_REGNO_P +#define FUNCTION_ARG_REGNO_P(N) \ + ((((int)N) >= 0 && (N) < M68K_MAX_REGPARM) \ + || ((N) >= 8 && (N) < 8 + M68K_MAX_REGPARM) \ + || (TARGET_68881 && (N) >= 16 && (N) < 16 + M68K_MAX_REGPARM)) + +/* + On the m68k, this is a structure: + num_of_regs: number of data, address and float registers to use for + arguments passing (if it's 2, than pass arguments in d0, d1, a0, a1, + fp0 and fp1). 0 - pass everything on stack. vararg calls are + always passed entirely on stack. + regs_already_used: bitmask of the already used registers. + last_arg_reg - register number of the most recently passed argument. + -1 if passed on stack. + last_arg_len - number of registers used by the most recently passed + argument. +*/ + +struct m68k_args +{ + int num_of_regs; + long regs_already_used; + int last_arg_reg; + int last_arg_len; +}; +#undef CUMULATIVE_ARGS +#define CUMULATIVE_ARGS struct m68k_args + +struct amigaos_args +{ + int num_of_regs; + long regs_already_used; + int last_arg_reg; + int last_arg_len; + void *formal_type; /* New field: formal type of the current argument. */ +}; +#undef CUMULATIVE_ARGS +#define CUMULATIVE_ARGS struct amigaos_args + +/* Initialize a variable CUM of type CUMULATIVE_ARGS + for a call to a function whose data type is FNTYPE. + For a library call, FNTYPE is 0. */ + +#undef INIT_CUMULATIVE_ARGS +#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \ + (amigaos_init_cumulative_args(&(CUM), (FNTYPE))) + +/* Update the data in CUM to advance over an argument + of mode MODE and data type TYPE. + (TYPE is null for libcalls where that information may not be available.) */ + +#undef FUNCTION_ARG_ADVANCE +#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ + (amigaos_function_arg_advance (&(CUM))) + +/* A C expression that controls whether a function argument is passed + in a register, and which register. */ + +#undef FUNCTION_ARG +#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ + (amigaos_function_arg (&(CUM), (MODE), (TYPE))) +/* end-GG-local */ + +/* Stack checking and automatic extension support. */ + +#define PROLOGUE_BEGIN_HOOK(STREAM, FSIZE) \ + (amigaos_prologue_begin_hook ((STREAM), (FSIZE))) + +#define HAVE_ALTERNATE_FRAME_SETUP_F(FSIZE) TARGET_STACKEXTEND + +#define ALTERNATE_FRAME_SETUP_F(STREAM, FSIZE) \ + (amigaos_alternate_frame_setup_f ((STREAM), (FSIZE))) + +#define HAVE_ALTERNATE_FRAME_SETUP(FSIZE) TARGET_STACKEXTEND + +#define ALTERNATE_FRAME_SETUP(STREAM, FSIZE) \ + (amigaos_alternate_frame_setup ((STREAM), (FSIZE))) + +#define HAVE_ALTERNATE_FRAME_DESTR_F(FSIZE) \ + (TARGET_STACKEXTEND && current_function_calls_alloca) + +#define ALTERNATE_FRAME_DESTR_F(STREAM, FSIZE) \ + (asm_fprintf ((STREAM), "\tjra %U__unlk_a5_rts\n")) + +#define HAVE_ALTERNATE_RETURN \ + (TARGET_STACKEXTEND && frame_pointer_needed && \ + current_function_calls_alloca) + +#define ALTERNATE_RETURN(STREAM) + +//#define HAVE_restore_stack_nonlocal TARGET_STACKEXTEND +//#define gen_restore_stack_nonlocal gen_stack_cleanup_call + +//#define HAVE_restore_stack_function TARGET_STACKEXTEND +//#define gen_restore_stack_function gen_stack_cleanup_call + +//#define HAVE_restore_stack_block TARGET_STACKEXTEND +//#define gen_restore_stack_block gen_stack_cleanup_call + +//#undef TARGET_ALTERNATE_ALLOCATE_STACK +//#define TARGET_ALTERNATE_ALLOCATE_STACK 1 +// +//#define ALTERNATE_ALLOCATE_STACK(OPERANDS) \ +//do \ +// { \ +// amigaos_alternate_allocate_stack (OPERANDS); \ +// DONE; \ +// } \ +//while (0) + +/* begin-GG-local: dynamic libraries */ + +extern int amigaos_do_collecting (void); +extern void amigaos_gccopts_hook (const char *); +extern void amigaos_libname_hook (const char* arg); +extern void amigaos_collect2_cleanup (void); +extern void amigaos_prelink_hook (const char **, int *); +extern void amigaos_postlink_hook (const char *); + +/* This macro is used to check if all collect2 facilities should be used. + We need a few special ones, like stripping after linking. */ + +#define DO_COLLECTING (do_collecting || amigaos_do_collecting()) +#define COLLECT2_POSTLINK_HOOK(OUTPUT_FILE) amigaos_postlink_hook(OUTPUT_FILE) //new + +/* This macro is called in collect2 for every GCC argument name. + ARG is a part of commandline (without '\0' at the end). */ + +#define COLLECT2_GCC_OPTIONS_HOOK(ARG) amigaos_gccopts_hook(ARG) + +/* This macro is called in collect2 for every ld's "-l" or "*.o" or "*.a" + argument. ARG is a complete argument, with '\0' at the end. */ + +#define COLLECT2_LIBNAME_HOOK(ARG) amigaos_libname_hook(ARG) + +/* This macro is called at collect2 exit, to clean everything up. */ + +#define COLLECT2_EXTRA_CLEANUP amigaos_collect2_cleanup + +/* This macro is called just before the first linker invocation. + LD1_ARGV is "char** argv", which will be passed to "ld". STRIP is an + *address* of "strip_flag" variable. */ + +#define COLLECT2_PRELINK_HOOK(LD1_ARGV, STRIP) \ +amigaos_prelink_hook((const char **)(LD1_ARGV), (STRIP)) + +/* This macro is called just after the first linker invocation, in place of + "nm" and "ldd". OUTPUT_FILE is the executable's filename. */ + +#define COLLECT2_POSTLINK_HOOK(OUTPUT_FILE) amigaos_postlink_hook(OUTPUT_FILE) +/* end-GG-local */ diff --git a/m68k-unknown-amigaos/recipes/files/gcc/config/m68k/host-amigaos.c b/m68k-unknown-amigaos/recipes/files/gcc/config/m68k/host-amigaos.c new file mode 100644 index 0000000..8c72d51 --- /dev/null +++ b/m68k-unknown-amigaos/recipes/files/gcc/config/m68k/host-amigaos.c @@ -0,0 +1,42 @@ +/* AmigaOS/m68k host-specific hook definitions. + Copyright (C) 2003 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC 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. + +GCC 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 GCC; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ + + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "hosthooks.h" +#include "hosthooks-def.h" +#include "toplev.h" + +static void * amigaos_m68k_gt_pch_get_address (size_t); + +/* Return the address of the PCH address space, if the PCH will fit in it. */ + +static void * +amigaos_m68k_gt_pch_get_address (size_t sz ATTRIBUTE_UNUSED) +{ + fatal_error ("PCH not supported\n"); +} + +#undef HOST_HOOKS_GT_PCH_GET_ADDRESS +#define HOST_HOOKS_GT_PCH_GET_ADDRESS amigaos_m68k_gt_pch_get_address + +const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; \ No newline at end of file diff --git a/m68k-unknown-amigaos/recipes/files/gcc/config/m68k/t-amigaos b/m68k-unknown-amigaos/recipes/files/gcc/config/m68k/t-amigaos new file mode 100644 index 0000000..12f5a57 --- /dev/null +++ b/m68k-unknown-amigaos/recipes/files/gcc/config/m68k/t-amigaos @@ -0,0 +1,30 @@ +# Makefile fragment for AmigaOS target. + +# Extra object file linked to the cc1* executables. +amigaos.o: $(srcdir)/config/m68k/amigaos.c $(CONFIG_H) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +# Additional target dependent options for compiling libgcc.a. This just +# ensures that we don't compile libgcc* with anything other than a +# fixed stack. + +#TARGET_LIBGCC2_CFLAGS = -mfixedstack + +# Support for building multiple version of libgcc. + +LIBGCC_MULTI = .; \ + libb;@fbaserel \ + libm020;@m68020 \ + libb/libm020;@fbaserel@m68020 \ + libb32/libm020;@fbaserel32@m68020 + +### begin-GG-local: dynamic libraries +# Extra objects that get compiled and linked to collect2 + +#EXTRA_COLLECT2_OBJS = amigacollect2.o + +# Build supplimentary AmigaOS target support file for collect2 +#amigacollect2.o: amigacollect2.c +# $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ +# -DA2IXDIR_PREFIX=\"$(prefix)/share/a2ixlibrary\" $< $(OUTPUT_OPTION) +### end-GG-local diff --git a/m68k-unknown-amigaos/recipes/files/gcc/config/m68k/x-amigaos b/m68k-unknown-amigaos/recipes/files/gcc/config/m68k/x-amigaos new file mode 100644 index 0000000..a8f60b8 --- /dev/null +++ b/m68k-unknown-amigaos/recipes/files/gcc/config/m68k/x-amigaos @@ -0,0 +1,104 @@ +# Makefile fragment for AmigaOS host + +# Each compilation environment (Manx, Dice, GCC, SAS/C, etc) provides its +# own equivalent of the UNIX /usr/include tree. For gcc, the standard headers +# are in /gg/include and system specific headers are in /gg/os-include. +# Use these paths for fixincludes. + +SYSTEM_HEADER_DIR = $(prefix)/include + +# Uncomment the following macro to get a resident GCC. We don't do it +# by default, since we want to support users with mc68000. +# WARNING! If you uncomment this, you MUST add the same flags to the +# libiberty's Makefile (libiberty is now linked into GCC executables). + +#RESIDENT = -m68020 -resident32 + +# Additional host flags that are not used when compiling with GCC_FOR_TARGET, +# such as when compiling the libgcc* runtime archives. GCC uses stack +# a lot, and since AmigaOS provides processes with a small, fixed size +# stack, we have to generate code that will extend it whenever necessary. + +XCFLAGS = -mstackextend $(RESIDENT) + +# AmigaOS supports "AmigaGuide(R)" hypertext files. For GCC, these are +# build with a custom "makeinfo". + +# Arrange for guides to be build with GCC, in the build directory. + +### begin-GG-local: gcc-amigaos +#EXTRA_DOC_TARGETS = guide gcc-amigaos-doc +### end-GG-local + +# Actually build guides + +guide:: doc/cpp.guide doc/gcc.guide doc/gccint.guide \ + doc/gccinstall.guide doc/cppinternals.guide + +doc/cpp.guide: $(TEXI_CPP_FILES) +doc/gcc.guide: $(TEXI_GCC_FILES) +doc/gccint.guide: $(TEXI_GCCINT_FILES) +doc/cppinternals.guide: $(TEXI_CPPINT_FILES) + +doc/%.guide: %.texi + if [ x$(BUILD_INFO) = xinfo ]; then \ + $(MAKEINFO) --amiga $(MAKEINFOFLAGS) -I $(docdir) \ + -I $(docdir)/include -o $@ $<; \ + fi + +# Duplicate entry to handle renaming of gccinstall.guide +doc/gccinstall.guide: $(TEXI_GCCINSTALL_FILES) + if [ x$(BUILD_INFO) = xinfo ]; then \ + $(MAKEINFO) --amiga $(MAKEINFOFLAGS) -I $(docdir) \ + -I $(docdir)/include -o $@ install.texi; \ + fi + +# Arrange for guides to be installed with GCC. + +### begin-GG-local: gcc-amigaos +#EXTRA_INSTALL_TARGETS = install-guide install-gcc-amigaos-doc +### end-GG-local + +# Where the guide files go + +guidedir = $(prefix)/guide + +# Actually install guides. + +installdirs-guide: + $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(guidedir) + +install-guide: doc installdirs-guide \ + $(DESTDIR)$(guidedir)/cpp.guide \ + $(DESTDIR)$(guidedir)/gcc.guide \ + $(DESTDIR)$(guidedir)/cppinternals.guide \ + $(DESTDIR)$(guidedir)/gccinstall.guide \ + $(DESTDIR)$(guidedir)/gccint.guide + +$(DESTDIR)$(guidedir)/%.guide: doc/%.guide installdirs-guide + rm -f $@ + if [ -f $< ]; then \ + for f in $(<)*; do \ + realfile=`echo $$f | sed -e 's|.*/\([^/]*\)$$|\1|'`; \ + $(INSTALL_DATA) $$f $(DESTDIR)$(guidedir)/$$realfile; \ + chmod a-x $(DESTDIR)$(guidedir)/$$realfile; \ + done; \ + else true; fi + +### begin-GG-local: gcc-amigaos +# Build and install gcc-amigaos.guide - documentation specific to the +# AmigaOS port of GCC. + +gcc-amigaos-doc:: doc/gcc-amigaos.info doc/gcc-amigaos.guide + +doc/gcc-amigaos.info doc/gcc-amigaos.guide: gcc-amigaos.texi + +install-gcc-amigaos-doc: doc installdirs installdirs-guide \ + $(DESTDIR)$(infodir)/gcc-amigaos.info \ + $(DESTDIR)$(guidedir)/gcc-amigaos.guide +### end-GG-local + +host-amigaos.o : $(srcdir)/config/m68k/host-amigaos.c $(CONFIG_H) $(SYSTEM_H) \ + coretypes.h hosthooks.h hosthooks-def.h toplev.h diagnostic.h + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ + $(srcdir)/config/m68k/host-amigaos.c diff --git a/m68k-unknown-amigaos/recipes/files/gcc/config/m68k/xm-amigaos.h b/m68k-unknown-amigaos/recipes/files/gcc/config/m68k/xm-amigaos.h new file mode 100644 index 0000000..bb571ba --- /dev/null +++ b/m68k-unknown-amigaos/recipes/files/gcc/config/m68k/xm-amigaos.h @@ -0,0 +1,64 @@ +/* Configuration for GNU C-compiler for m68k Amiga, running AmigaOS. + Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2003 + Free Software Foundation, Inc. + Contributed by Markus M. Wild (wild@amiga.physik.unizh.ch). + +This file is part of GCC. + +GCC 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. + +GCC 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 GCC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#ifndef _FCNTL_H_ +#include +#endif + +/* AmigaOS specific headers, such as from the Native Developer Update kits, + go in SYSTEM_INCLUDE_DIR. STANDARD_INCLUDE_DIR is the equivalent of + Unix "/usr/include". All other include paths are set in Makefile. */ + +#define SYSTEM_INCLUDE_DIR "/gg/os-include" +#define STANDARD_INCLUDE_DIR "/gg/include" + +#define STANDARD_EXEC_PREFIX_1 "/gg/libexec/gcc/" +#define STANDARD_EXEC_PREFIX_2 "/gg/lib/gcc/" +#define STANDARD_STARTFILE_PREFIX_1 "/gg/lib/" +#define STANDARD_STARTFILE_PREFIX_2 "/gg/lib/" + +/* The AmigaOS stores file names with regard to upper/lower case, but actions + on existing files are case independent on the standard filesystems. + + A good example of where this causes problems is the conflict between the C + include file and the C++ include file , where the C++ + include file dir is searched first and thus causes includes of + to include instead. + + In order to solve this problem we define the macro OPEN_CASE_SENSITIVE as + the name of the function that takes the same args as open() and does case + dependent opens. */ + +#define OPEN_CASE_SENSITIVE(NAME, FLAGS, MODE) open ((NAME), (FLAGS) | O_CASE, (MODE)) + +/* On the AmigaOS, there are two pathname separators, '/' (DIR_SEPARATOR) + and ':' (VOL_SEPARATOR). DIR_SEPARATOR defaults to the correct + character, so we don't have to explicitly set it. */ + +#define DIR_SEPARATOR '/' +#define VOL_SEPARATOR ':' +#define DIR_SEPARATOR_2 VOL_SEPARATOR + +/* Zap PREFIX_INCLUDE_DIR, since with the AmigaOS port it is the same as + STANDARD_INCLUDE_DIR. */ + +#undef PREFIX_INCLUDE_DIR diff --git a/m68k-unknown-amigaos/recipes/patches/config.gcc.p b/m68k-unknown-amigaos/recipes/patches/config.gcc.p new file mode 100644 index 0000000..0f0438c --- /dev/null +++ b/m68k-unknown-amigaos/recipes/patches/config.gcc.p @@ -0,0 +1,17 @@ +--- gcc/config.gcc 2010-12-16 13:06:35.000000000 +0000 ++++ gcc/config.gcc 2010-12-16 13:09:52.000000000 +0000 +@@ -1671,6 +1671,14 @@ + tm_defines="${tm_defines} MOTOROLA=1" + extra_parts="crtbegin.o crtend.o" + ;; ++m68k-*-amigaos*) ++ tmake_file="m68k/t-amigaos" ++ tm_file="${tm_file} m68k/amigaos.h" ++ tm_p_file="${tm_p_file} m68k/amigaos-protos.h" ++ tm_defines="${tm_defines} TARGET_AMIGAOS TARGET_DEFAULT=0" ++ extra_objs="amigaos.o" ++ gnu_ld=yes ++ ;; + mcore-*-elf) + tm_file="dbxelf.h elfos.h svr4.h newlib-stdint.h ${tm_file} mcore/mcore-elf.h" + tmake_file=mcore/t-mcore -- cgit v1.2.3