summaryrefslogtreecommitdiff
path: root/m68k-unknown-amigaos
diff options
context:
space:
mode:
authorChris Young <chris@unsatisfactorysoftware.co.uk>2015-01-01 15:15:33 +0000
committerVincent Sanders <vince@kyllikki.org>2015-01-11 12:59:46 +0000
commit6d07d38a48ccb71f55cfacffbe86b83f4c75a28c (patch)
tree11490b607e64a3bc98b22f08625d548e285a39af /m68k-unknown-amigaos
parent786ec473315d6960a65c4efdb64f71774b902f5b (diff)
downloadtoolchains-6d07d38a48ccb71f55cfacffbe86b83f4c75a28c.tar.gz
toolchains-6d07d38a48ccb71f55cfacffbe86b83f4c75a28c.tar.bz2
Use gcc 3.4.6 for m68k-amigaos-toolchain
This changes to using the 3.4 series gcc with patches from github:cahirwpz/m68k-amigaos-toolchain and some other modifications to make it compile. clib2 is currently failing to build with this compiler with the following errors: Compiling unistd_getopt.c [large_data_020:c] /tmp/ccrQcqYy.s: Assembler messages: /tmp/ccrQcqYy.s:36: Error: parse error -- statement `cmpl (sp.0),d0' ignored /tmp/ccrQcqYy.s:58: Error: parse error -- statement `movel (sp.0),a0' ignored /tmp/ccrQcqYy.s:86: Error: parse error -- statement `addql #1,(sp.0)' ignored /tmp/ccrQcqYy.s:89: Error: parse error -- statement `movel (sp.0),a0' ignored /tmp/ccrQcqYy.s:94: Error: parse error -- statement `movel d0,(sp.0)' ignored /tmp/ccrQcqYy.s:104: Error: parse error -- statement `addl (sp.0),a0' ignored /tmp/ccrQcqYy.s:129: Error: parse error -- statement `movel d0,(sp.0)' ignored /tmp/ccrQcqYy.s:139: Error: parse error -- statement `movel d0,(sp.0)' ignored /tmp/ccrQcqYy.s:143: Error: parse error -- statement `addql #1,(sp.0)' ignored /tmp/ccrQcqYy.s:146: Error: parse error -- statement `movel (sp.0),a0' ignored /tmp/ccrQcqYy.s:150: Error: parse error -- statement `movel d0,(sp.0)' ignored make[2]: *** [large_data_020/libc_objs/unistd_getopt.o] Error 1
Diffstat (limited to 'm68k-unknown-amigaos')
-rw-r--r--m68k-unknown-amigaos/Makefile4
-rw-r--r--m68k-unknown-amigaos/recipes/files/gcc/gcc/amigacollect2.c841
-rw-r--r--m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/amigaos-protos.h90
-rw-r--r--m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/amigaos.c1187
-rw-r--r--m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/amigaos.h1251
-rw-r--r--m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/host-amigaos.c2
-rw-r--r--m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/t-amigaos66
-rw-r--r--m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/x-amigaos208
-rw-r--r--m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/xm-amigaos.h128
-rw-r--r--m68k-unknown-amigaos/recipes/files/gcc/gcc/doc/gcc-amigaos.texi1116
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/configure.p12
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.Makefile.in.p133
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.c-decl.c.p87
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.c-incpath.c.p19
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.c-parse.in.p223
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.c-tree.h.p13
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.calls.c.p24
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.collect2.c.p200
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.common.opt.p17
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.gcc.p16
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.host-linux.c.p11
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.host.p18
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.m68k.m68k-protos.h.p14
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.m68k.m68k.c.p513
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.m68k.m68k.h.p175
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.m68k.m68k.md.p82
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.configure.ac.p35
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.configure.p61
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.cppfiles.c.p48
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.defaults.h.p13
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.fixinc.mkfixinc.sh.p10
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.flow.c.p19
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.function.c.p31
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.function.h.p11
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.gcc.c.p63
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.ginclude.stdarg.h.p20
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.loop.c.p13
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.mklibgcc.in.p13
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.opts.c.p26
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.rtl.h.p11
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc.toplev.c.p11
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/include.filenames.h.p14
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/libgcc.config.host.p11
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/libiberty.configure.p105
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/libiberty.lbasename.c.p13
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/libiberty.make-temp-file.c.p27
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/libiberty.pex-unix.c.p13
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/libiberty.strsignal.c.p13
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/libstdc++-v3.config.cpu.m68k.atomicity.h.p25
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/libstdc++-v3.configure.p13
50 files changed, 4841 insertions, 2228 deletions
diff --git a/m68k-unknown-amigaos/Makefile b/m68k-unknown-amigaos/Makefile
index 879e9ea..9c2b095 100644
--- a/m68k-unknown-amigaos/Makefile
+++ b/m68k-unknown-amigaos/Makefile
@@ -1,4 +1,4 @@
-UPSTREAM_GCC_VERSION := 4.5.4
+UPSTREAM_GCC_VERSION := 3.4.6
UPSTREAM_GCC_TARBALL := gcc-$(UPSTREAM_GCC_VERSION).tar.bz2
UPSTREAM_GCC_URI := http://ftp.gnu.org/gnu/gcc/gcc-$(UPSTREAM_GCC_VERSION)/$(UPSTREAM_GCC_TARBALL)
@@ -106,7 +106,7 @@ $(BUILDSTEPS)/bootstrap-compiler.d: $(BUILDSTEPS)/srcdir-step3.d $(BUILDSTEPS)/b
cd $(BUILDDIR) && $(GCC_ENV_PARAMS) $(GCC_SRCDIR)/configure \
--prefix=$(PREFIX) \
--target=$(TARGET_NAME) \
- --with-cpu=m68040 --disable-threads \
+ --disable-threads \
--disable-nls --disable-c-mbchar \
--enable-languages=c --enable-checking=no \
--enable-c99 --with-cross-host \
diff --git a/m68k-unknown-amigaos/recipes/files/gcc/gcc/amigacollect2.c b/m68k-unknown-amigaos/recipes/files/gcc/gcc/amigacollect2.c
index 9df71a7..97e5e55 100644
--- a/m68k-unknown-amigaos/recipes/files/gcc/gcc/amigacollect2.c
+++ b/m68k-unknown-amigaos/recipes/files/gcc/gcc/amigacollect2.c
@@ -1,558 +1,349 @@
-/* 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. */
+/* 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
-write_c_file_stat (FILE *stream, const char *name ATTRIBUTE_UNUSED)
+safename (char *p)
{
- 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)
+ if (!ISALPHA(*p))
+ *p = '_';
+ p++;
+ while (*p)
{
- 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++;
- }
+ if (!ISALNUM(*p))
+ *p = '_';
+ p++;
}
- /* 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);
+/* Add a library to the list of dynamic libraries. First make sure that the
+ library is actually dynamic. Used by "amigaos_libname_hook()". */
- free (prefix);
+static void
+add_lib (const char *name)
+{
+ struct liblist *lib;
+ static char buf[256];
- /* Write the tables as C code. */
+ for (lib = head; lib; lib = lib->next)
+ if (!strcmp(lib->name, name))
+ return;
- fprintf (stream, "static int count;\n");
- fprintf (stream, "typedef void entry_pt();\n");
- write_list_with_asm (stream, "extern entry_pt ", constructors.first);
+ /* A2IXDIR_PREFIX is passed by "make". */
+ sprintf(buf, A2IXDIR_PREFIX "/ldscripts/%s.x", name);
+ if (access(buf, R_OK))
+ return;
- 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");
- }
+ lib = (struct liblist*)xmalloc(sizeof(struct liblist));
+ lib->name = xstrdup(name);
+ lib->cname = xstrdup(name);
+ safename(lib->cname);
+ lib->next = head;
+ head = lib;
- 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 (debug)
+ fprintf(stderr, "found dynamic library, name: %s, cname: %s\n", lib->name,
+ lib->cname);
- if (shared_obj)
+ 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"))
{
- COLLECT_SHARED_INIT_FUNC(stream, initname);
- COLLECT_SHARED_FINI_FUNC(stream, fininame);
+ 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] = '.';
}
}
-/* Write the constructor/destructor tables. */
+/* 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. */
-#ifndef LD_INIT_SWITCH
static void
-write_c_file_glob (FILE *stream, const char *name ATTRIBUTE_UNUSED)
+cat (const char *fname, FILE *x)
{
- /* Write the tables as C code. */
-
- int frames = (frame_tables.number > 0);
+#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);
+}
- fprintf (stream, "typedef void entry_pt();\n\n");
+/* 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. */
- write_list_with_asm (stream, "extern entry_pt ", constructors.first);
+void
+amigaos_prelink_hook (const char **ld1_argv, int *strip_flag)
+{
+ if (flag_static)
+ return;
- if (frames)
+ if (!found_dynamic_libs)
{
- 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");
+ 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;
- 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");
+ /* 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;
+ }
+ }
- write_list_with_asm (stream, "extern entry_pt ", destructors.first);
+ 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);
- 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");
+ 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". */
- fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN);
- fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);
+ /* 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;
+ }
}
-#endif /* ! LD_INIT_SWITCH */
-static void
-write_c_file (FILE *stream, const char *name)
+/* Be lazy and just call "postlink". */
+
+void
+amigaos_postlink_hook (const char *output_file)
{
- fprintf (stream, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
-#ifndef LD_INIT_SWITCH
- if (! shared_obj)
- write_c_file_glob (stream, name);
+ static const char *argv[]={"postlink", 0, 0, 0};
+ if (flag_static)
+ return;
+
+ if (flag_baserel)
+ {
+ argv[1]="-baserel";
+ argv[2]=output_file;
+ }
else
-#endif
- write_c_file_stat (stream, name);
- fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n");
-} \ No newline at end of file
+ argv[1]=output_file;
+ fork_execute("postlink", (char **)argv);
+}
diff --git a/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/amigaos-protos.h b/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/amigaos-protos.h
index f7f7e97..dd059f8 100644
--- a/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/amigaos-protos.h
+++ b/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/amigaos-protos.h
@@ -1,45 +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
+/* 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/gcc/config/m68k/amigaos.c b/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/amigaos.c
index 3b1782c..2c5cab1 100644
--- a/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/amigaos.c
+++ b/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/amigaos.c
@@ -1,726 +1,461 @@
-/* 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; i<cum->last_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 */
+/* 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. */
+
+#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 *);
+
+/* 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)
+ {
+ 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);
+
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ 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;
+}
+
+/* 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. */
+ 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;
+ if (cum->formal_type && TREE_VALUE((tree)cum->formal_type)
+ && (asmtree=lookup_attribute("asm",
+ 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; i<cum->last_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", TYPE_ATTRIBUTES(TREE_VALUE(arg1)));
+ asm2=lookup_attribute("asm", 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/gcc/config/m68k/amigaos.h b/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/amigaos.h
index 7ddf20b..b1e2660 100644
--- a/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/amigaos.h
+++ b/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/amigaos.h
@@ -1,698 +1,553 @@
-/* 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 \
- "%{g:-amiga-debug-hunk} " \
- "%(link_cpu)"
-
-/*
- "%{resident*:-amiga-datadata-reloc} " \
- "%{resident|fbaserel:-m amiga_bss -fl libb} " \
- "%{resident32|fbaserel32:-m amiga_bss -fl libb32} " \
- "%{g:-amiga-debug-hunk} " \
- "%(link_cpu)"
- "%{noixemul:-fl libnix} "
-*/
-
-#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 \
- "ncrt0.o%s"
-/*
- "%{!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 \
- "%{!nostdlib:-lc -lamiga -lnet -lunix -lm -lc}"
-/* "%{!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 <uweigand@de.ibm.com>
-+
-+ * 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=<value>' 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 */
+/* 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. */
+
+
+/* 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=__attribute__((__regparm__))"); \
+ builtin_define ("__stdargs=__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
+#define TARGET_CPU_CPP_BUILTINS() \
+ do \
+ { \
+ 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"); \
+ 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. */
+
+#define ASM_SPEC \
+ "%(asm_cpu) %(asm_cpu_default) %{msmall-code:-sc}"
+
+#define ASM_CPU_SPEC \
+ "%{m68000|mc68000:-m68010} " \
+ "%{m6802*|mc68020:-m68020} " \
+ "%{m68030} " \
+ "%{m68040} " \
+ "%{m68060}"
+
+#define ASM_CPU_DEFAULT_SPEC \
+ "%{!m680*:%{!mc680*:-m68010}}"
+
+/* 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}"
+
+/* 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. */
+
+#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") },
+
+#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)). */
+
+#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 until problems with DWARF2 unwind info on a.out
+ targets using GNU ld are fixed. */
+/*
+#define DWARF2_UNWIND_INFO 0
+*/
+#define NO_DWARF2_UNWIND_INFO
+
+/* 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 */
+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. */
+};
+
+/* A C type for declaring a variable that is used as the first
+ argument of `FUNCTION_ARG' and other related values. */
+
+#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())
+
+/* 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 */
+
+/* Don't use any specific register allocation order. */
+#undef REG_ALLOC_ORDER
diff --git a/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/host-amigaos.c b/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/host-amigaos.c
index 8c72d51..aec68d0 100644
--- a/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/host-amigaos.c
+++ b/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/host-amigaos.c
@@ -39,4 +39,4 @@ amigaos_m68k_gt_pch_get_address (size_t sz ATTRIBUTE_UNUSED)
#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
+const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;
diff --git a/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/t-amigaos b/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/t-amigaos
index 3b2d16f..085de81 100644
--- a/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/t-amigaos
+++ b/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/t-amigaos
@@ -1,36 +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
-
-# Prevent fixincludes clobbering our limits.h
-LIMITS_H_TEST = true
-
-# Prevent installation of GCC's limits.h
-INSTALL_LIMITS_H = false
+# 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/gcc/config/m68k/x-amigaos b/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/x-amigaos
index a8f60b8..4409fc5 100644
--- a/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/x-amigaos
+++ b/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/x-amigaos
@@ -1,104 +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
+# 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/gcc/config/m68k/xm-amigaos.h b/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/xm-amigaos.h
index bb571ba..8b1a3d6 100644
--- a/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/xm-amigaos.h
+++ b/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/xm-amigaos.h
@@ -1,64 +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 <fcntl.h>
-#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 <string.h> and the C++ include file <String.h>, where the C++
- include file dir is searched first and thus causes includes of <string.h>
- to include <String.h> 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
+/* 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 <fcntl.h>
+#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 <string.h> and the C++ include file <String.h>, where the C++
+ include file dir is searched first and thus causes includes of <string.h>
+ to include <String.h> 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/files/gcc/gcc/doc/gcc-amigaos.texi b/m68k-unknown-amigaos/recipes/files/gcc/gcc/doc/gcc-amigaos.texi
new file mode 100644
index 0000000..481c676
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/files/gcc/gcc/doc/gcc-amigaos.texi
@@ -0,0 +1,1116 @@
+\input texinfo.tex @c -*-texinfo-*-
+@c %**start of header
+@setfilename gcc-amigaos.info
+@settitle AmigaOS-only features of GCC
+@set lastupdate Nov 5th, 2003
+@c %**end of header
+
+@ifinfo
+This document describes implementation specific features of the GCC
+compiler collection port for the AmigaOS.
+
+@copying
+Copyright @copyright{} 1996, 1997 Kamil Iskra
+
+Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+@end copying
+@end ifinfo
+
+@titlepage
+@sp 10
+@center @titlefont{GCC Amiga}
+@subtitle Description of the AmigaOS-only features of GCC
+@subtitle @value{lastupdate}
+@author Kamil Iskra
+@page
+@end titlepage
+
+@ifinfo
+@node Top, Introduction, (dir), (dir)
+This document describes the AmigaOS-only features of the @samp{GCC}
+compiler collection.
+
+Last updated @value{lastupdate}.
+@end ifinfo
+
+@menu
+* Introduction:: Purpose of this document.
+
+* Invocation:: Command line options.
+* Attributes:: Variable and function attributes.
+* Defines:: Preprocessor symbols.
+* Miscellaneous:: Uncategorizable.
+
+* Index:: Concept index.
+@end menu
+
+@node Introduction, Invocation, Top, Top
+@chapter Introduction
+@cindex Introduction
+@cindex Purpose of this document
+
+This document is supposed to be an addendum to the baseline @samp{GCC}
+documentation.
+Note that given email addresses and urls might be obsolete!
+
+It focuses on the features that are visible by users and are important
+to them. It is not supposed to document the internals of the AmigaOS
+port of @samp{GCC}.
+
+It describes features implemented in the @samp{Geek Gadgets GCC} port.
+For more information about @samp{Geek Gadgets}, please refer to:
+
+@format
+http://www.geekgadgets.org/
+ftp://ftp.geekgadgets.org/pub/geekgadgets/README
+@end format
+
+This document focuses on @samp{GCC}. It does not describe the
+AmigaOS-only features of other @samp{GNU} packages, such as
+@samp{binutils}, unless they are very closely connected to @samp{GCC}.
+
+This means, that, unless stated otherwise, when we talk about the
+``compiler'', we mean the @file{gcc}, @file{cpp} and @file{cc1}
+executables, i.e., the executables that convert @samp{C} source code
+to assembly source code. The assembler and linker are generally beyond
+the scope of this document.
+
+The primary source of information used to create this document was the
+@samp{GCC} source code. Some parts of this document are based on:
+
+@itemize @bullet
+@item
+The @samp{LibNIX} manual, written by Matthias Fleischer and Gunther
+Nikl:
+
+@format
+fleischr@@izfm.uni-stuttgart.de
+gnikl@@informatik.uni-rostock.de
+@end format
+
+@item
+The @samp{A2IXLibrary} manual, written by Hans Verkuil:
+
+@format
+hans@@wyst.hobby.nl
+@end format
+
+@item
+The @samp{README} file, maintained by Rask Ingemann Lambertsen:
+
+@format
+gc948374@@gbar.dtu.dk
+http://www.gbar.dtu.dk/~c948374/GNU/
+@end format
+
+@item
+The @samp{Geek Gadgets FAQ}, maintained by Lynn Winebarger:
+
+@format
+owinebar@@indiana.edu
+http://nickel.ucs.indiana.edu/~owinebar/interests/amiga/amiga.html
+@end format
+
+@item
+The @samp{FAQ for g++ and libg++}, written by Joe Buck:
+
+@format
+jbuck@@synopsys.com
+http://www.cygnus.com/misc/g++FAQ_toc.html
+@end format
+
+@item
+Discussions on the @samp{Geek Gadgets} mailing list:
+
+@format
+gg@@geekgadgets.org
+@end format
+@end itemize
+
+This document was created by Kamil Iskra. Please email any questions,
+suggestions etc. to <iskra@@student.uci.agh.edu.pl> or, even better,
+to the <gg@@geekgadgets.org> mailing list.
+
+The author would like to thank Kriton Kyrimis <kyrimis@@cti.gr> and
+Lars Hecking <lhecking@@nmrc.ucc.ie> for correcting an awful lot of
+language mistakes in this document.
+
+@node Invocation, Attributes, Introduction, Top
+@chapter Invocation
+@cindex Invocation
+@cindex Command line options
+
+The AmigaOS port of @samp{GCC} supports the following non-standard
+command line options:
+
+@menu
+* -noixemul:: Link with @samp{LibNIX}.
+
+* -fbaserel:: Produce @samp{a4}-relative data.
+* -resident:: Produce a @samp{pure} executable.
+* -fbaserel32:: Produce @samp{a4}-relative data with no size limits.
+* -resident32:: Produce a @samp{pure} executable with no size limits.
+* -msmall-code:: Produce @samp{PC}-relative code.
+
+* -mstackcheck:: Produce stack-checking code.
+* -mstackextend:: Produce stack-extending code.
+* -mfixedstack:: Produce plain code.
+
+* -mrestore-a4:: Reload @samp{a4} in public functions.
+* -malways-restore-a4:: Reload @samp{a4} in all functions.
+
+* -mregparm:: Pass function arguments in registers.
+
+* -frepo:: Enable @samp{C++} Template Repository.
+@end menu
+
+Accordingly, the AmigaOS port of @samp{GCC} supports several flavors
+of linker libraries. @xref{Library flavors, Relation between library
+flavors and compile-time options}.
+
+@node -noixemul, -fbaserel, Invocation, Invocation
+@section -noixemul
+@cindex -noixemul
+@cindex Link with LibNIX
+
+@cindex IXEmul
+By default, the executables created with @samp{GCC} require
+@samp{ixemul.library} to run. This has its advantages (easy porting of
+@samp{UN*X} programs, resource tracking, debugging, profiling, etc)
+and disadvantages (@samp{UN*X}-style pathnames, large shared library,
+etc).
+
+@cindex LibNIX
+If @samp{-noixemul} is specified on the @samp{GCC} command line, the
+executable created will not require @samp{ixemul.library} --- it will
+use the static linker library @samp{LibNIX} instead. This library is
+very Amiga-like and @samp{SAS/C}-like, so it is convenient for the
+AmigaOS-specific development.
+
+@quotation
+@emph{Note}: There is no great mystery about the @samp{-noixemul}
+option. It has absolutely no effect on the code generated by the
+compiler, only instructing the @samp{gcc} driver to pass different
+options to the linker and preprocessor (@pxref{Options information},
+@pxref{Library flavors}).
+
+This option has no negative form.
+@end quotation
+
+For more information, please refer to the @samp{LibNIX} documentation.
+
+@node -fbaserel, -resident, -noixemul, Invocation
+@section -fbaserel
+@cindex -fbaserel
+@cindex Produce a4-relative data
+
+By default, the code generated by @samp{GCC} references data using
+32-bit, absolute addressing.
+
+@cindex a4
+@cindex 64 KB data limit
+The @samp{-fbaserel} option will make @samp{GCC} generate code that
+references data with 16 bit offsets relative to the @samp{a4} address
+register. This makes executables smaller and faster. Unfortunately,
+the size of the data section cannot exceed 64 KB, so this option
+cannot be used for large programs, like @samp{GCC} itself.
+
+@quotation
+@emph{Note}: For a base-relative executable, @samp{-fbaserel} needs to
+be specified for compiling @emph{and} linking. Base-relative programs
+require special startup code and special versions of linker libraries.
+Since not all linker libraries are available in both plain and base
+relative versions, the usefulness of this option is limited. It is
+important to note that when the base-relative library is missing, the
+linker will attempt to use the plain one. This might result in strange
+link-time or even run-time errors.
+
+@cindex -fpic
+This option is the AmigaOS equivalent of the standard @samp{GCC}
+option @samp{-fpic}, which is not supported by the AmigaOS port.
+@samp{-fpic} generates code that references data indirectly, through a
+@dfn{global offset table}. The special addressing modes available on
+the @samp{m68k} processor family allow for a much more efficient
+implementation with @samp{-fbaserel}.
+
+The negative form of @samp{-fbaserel} is @samp{-fno-baserel}, and is
+on by default.
+@end quotation
+
+For more information, please refer to the @samp{LibNIX} documentation.
+
+@node -resident, -fbaserel32, -fbaserel, Invocation
+@section -resident
+@cindex -resident
+@cindex Produce a pure executable
+
+Executables produced with the @samp{-resident} option are @dfn{pure},
+so they can be made @dfn{resident} using the AmigaShell
+@samp{resident} command. @samp{resident} executables are loaded to
+memory just once, and several concurrent instances share the code
+section.
+
+@quotation
+@emph{Note}: The compiler generates the same code for @samp{-resident}
+as for @samp{-fbaserel} (@pxref{-fbaserel}). Only the linking stage is
+different (special startup code is linked).
+
+This option has no negative form.
+@end quotation
+
+For more information, please refer to the @samp{LibNIX} documentation.
+
+@node -fbaserel32, -resident32, -resident, Invocation
+@section -fbaserel32
+@cindex -fbaserel32
+@cindex Produce a4-relative data with no size limits
+
+The difference between the @samp{-fbaserel32} and @samp{-fbaserel}
+options (@pxref{-fbaserel}) is the same as between the standard
+@samp{GCC} options @samp{-fPIC} and @samp{-fpic}.
+
+Code generated with @samp{-fbaserel32} references data with 32 bit
+offsets relative to the @samp{a4} address register. In contrast to the
+@samp{-fbaserel} (@pxref{-fbaserel}) option, there is no 64 KB size
+limit. Unfortunately, the addressing modes with 32 bit offsets are
+only available on 68020 and higher processors. Therefore, it is
+necessary to specify @samp{-m68020} or higher to use this option.
+
+@quotation
+@emph{Note}: This option used to be called @samp{-flarge-baserel}
+before @samp{Geek Gadgets} snapshot @samp{970109}. Since it was not
+functional then, this should not cause any compatibility problems.
+
+The negative form of @samp{-fbaserel32} is @samp{-fno-baserel32}, and
+is on by default.
+@end quotation
+
+@node -resident32, -msmall-code, -fbaserel32, Invocation
+@section -resident32
+@cindex -resident32
+@cindex Produce a pure executable with no size limits
+
+This option is an improved version of @samp{-resident}
+(@pxref{-resident}) --- it does not impose any limits on data section
+size. Unfortunately, just like @samp{-fbaserel32}
+(@pxref{-fbaserel32}), it is only available for 68020 or higher
+processors. Therefore, it is necessary to specify @samp{-m68020} or
+higher to use this option.
+
+@quotation
+@emph{Note}: This option was first made available in the @samp{GCC}
+2.7.2.1, @samp{Geek Gadgets} snapshot @samp{970109}.
+
+This option has no negative form.
+@end quotation
+
+@node -msmall-code, -mstackcheck, -resident32, Invocation
+@section -msmall-code
+@cindex -msmall-code
+@cindex Produce PC-relative code
+
+By default, the code generated by the compiler references functions
+using 32-bit, absolute addressing.
+
+@cindex 32 KB code limit
+Code generated by @samp{GCC} with the @samp{-msmall-code} option
+references symbols in the code section with 16 bit offsets, relative
+to the @samp{PC} (@dfn{program counter}). This makes executables
+smaller and faster. Unfortunately, the size of the code section is
+generally limited to 32 KB, so this option can only be used for
+relatively small programs.
+
+@quotation
+@emph{Note}: Actually, the compiler always generates 32-bit code
+references. If the assembler can calculate the offset between the
+referencing instruction and the referenced symbol (in other words, if
+the referenced symbol is in the same source file), it replaces the
+32-bit reference with the @samp{PC}-relative one. External references
+are left intact, unless @samp{-msmall-code} is used, in which case the
+assembler generates @samp{PC}-relative references, and the exact
+offsets are calculated by the linker.
+
+This option has no negative form.
+@end quotation
+
+For more information, please refer to the @samp{LibNIX} documentation.
+
+@node -mstackcheck, -mstackextend, -msmall-code, Invocation
+@section -mstackcheck
+@cindex -mstackcheck
+@cindex Produce stack-checking code
+
+By default, the code generated by @samp{GCC} does not check if there
+is enough stack available before performing stack-consuming
+operations. This is generally not necessary on @samp{UN*X} systems,
+where the stack is extended automagically whenever needed.
+
+Unfortunately, the AmigaOS provides tasks with a static, fixed size
+stack.
+
+However, if a program is compiled with @samp{-mstackcheck}, it will
+check if there is enough stack available before performing any
+stack-hungry operations. If there is a danger of stack overflow, the
+program will abort and the user will be notified.
+
+Needless to say, stack checking increases the executable size and the
+execution time.
+
+@quotation
+@emph{Note}: Stack checking cannot be used for functions that might be
+called from outside your task. This includes interrupt handlers,
+shared library functions, hooks etc. In such cases, you should either
+avoid using @samp{-mstackcheck} for files containing such functions,
+or use @code{__attribute__((interrupt))} (@pxref{interrupt}).
+
+It is safe to call a function that performs stack checking from one
+that does not, and vice versa.
+
+The negative form of @samp{-mstackcheck} is @samp{-mno-stackcheck},
+and is on by default.
+
+@emph{Warning}: @samp{-mno-stackcheck} used to be called
+@samp{-mnostackcheck} before @samp{Geek Gadgets} snapshot
+@samp{961012}.
+@end quotation
+
+For more information, please refer to the @samp{LibNIX} documentation.
+
+@node -mstackextend, -mfixedstack, -mstackcheck, Invocation
+@section -mstackextend
+@cindex -mstackextend
+@cindex Produce stack-extending code
+
+@samp{-mstackextend} is very similar to @samp{-mstackcheck}
+(@pxref{-mstackcheck}).
+
+The main difference is that when a program runs out of stack, it is
+not aborted, but a new stack area is allocated and the program
+continues to run.
+
+@quotation
+@emph{Note}: Stack extension can slow down programs significantly. It
+is advised that programs are written in such a way that they do not
+require too much stack. This can generally be achieved by explicitly
+allocating memory for large structures and arrays using functions like
+@samp{malloc()} or @samp{AllocMem()}, instead of creating them as
+local variables. Another method is replacing recursion with iteration.
+In addition, it might be considered to use stack extension only for
+selected, ``dangerous'' functions (@pxref{stackext}), not for all
+functions in a given program.
+
+The negative form of @samp{-mstackextend} is @samp{-mno-stackextend},
+and is on by default.
+
+@emph{Warning}: @samp{-mno-stackextend} used to be called
+@samp{-mnostackextend} before @samp{Geek Gadgets} snapshot
+@samp{961012}.
+@end quotation
+
+For more information, please refer to the @samp{LibNIX} documentation.
+
+@node -mfixedstack, -mrestore-a4, -mstackextend, Invocation
+@section -mfixedstack
+@cindex -mfixedstack
+@cindex Produce plain code
+
+This option makes @samp{GCC} generate plain code, that does neither
+stack checking nor extension. Since this is the default, there is
+generally no need to use this option.
+
+@quotation
+@emph{Note}: This option has no negative form.
+@end quotation
+
+@node -mrestore-a4, -malways-restore-a4, -mfixedstack, Invocation
+@section -mrestore-a4
+@cindex -mrestore-a4
+@cindex Reload a4 in public functions
+
+This option is used to create the @samp{IXEmul} shared libraries
+(those @file{*.ixlibrary} files).
+
+It sets @samp{a4} to the appropriate value in the prologues of all
+public functions (i.e., functions with external linkage). This is
+necessary if these functions are called from the code of application.
+
+@quotation
+@emph{Note}: This option should not be used except for the creation of
+an @samp{IXEmul} shared library.
+
+This option was first made available in the @samp{GCC} 2.7.2,
+@samp{Geek Gadgets} snapshot @samp{960902}. It used to be called
+@samp{-frestore-a4}, and was relabeled to its current name in the
+@samp{GCC} 2.7.2.1, @samp{Geek Gadgets} snapshot @samp{961012}.
+
+The negative form of @samp{-mrestore-a4} is @samp{-mno-restore-a4},
+and is on by default.
+@end quotation
+
+For more information, please refer to the @samp{A2IXLibrary}
+documentation.
+
+@node -malways-restore-a4, -mregparm, -mrestore-a4, Invocation
+@section -malways-restore-a4
+@cindex -malways-restore-a4
+@cindex Reload a4 in all functions
+
+This option is very similar to @samp{-mrestore-a4}
+(@pxref{-mrestore-a4}).
+
+The only difference is that it sets @samp{a4} in all functions,
+including private ones (i.e., functions with internal linkage,
+@samp{static}). This is safer than @samp{-mrestore-a4}
+(@pxref{-mrestore-a4}), but is also slower.
+
+@quotation
+@emph{Note}: This option should not be used except for the creation of
+an @samp{IXEmul} shared library.
+
+This option was first made available in the @samp{GCC} 2.7.2,
+@samp{Geek Gadgets} snapshot @samp{960902}. It used to be called
+@samp{-falways-restore-a4}, and was relabeled to its current name in
+the @samp{GCC} 2.7.2.1, @samp{Geek Gadgets} snapshot @samp{961012}.
+
+The negative form of @samp{-malways-restore-a4} is
+@samp{-mno-always-restore-a4}, and is on by default.
+@end quotation
+
+For more information, please refer to the @samp{A2IXLibrary}
+documentation.
+
+@node -mregparm, -frepo, -malways-restore-a4, Invocation
+@section -mregparm
+@cindex -mregparm
+@cindex Pass function arguments in registers
+
+On the @samp{m68k} architecture, @samp{GCC} passes function arguments
+on the stack by default.
+
+@samp{-mregparm} allows for passing arguments in registers. This can
+be slightly faster than the standard method of passing arguments on
+the stack.
+
+The full syntax of this option is:
+
+@format
+-mregparm[=<value>]
+@end format
+
+@samp{value} should be an integer ranging from 1 to 4. If no
+@samp{value} is provided, 2 will be used.
+
+Four types of function arguments are recognized:
+
+@table @samp
+@item Integer
+Integer numbers (this includes enumerations, small structures and
+@samp{bool} in @samp{C++}, but excludes @samp{long long}, which is too
+large). They are passed in data registers, starting from @samp{d0}.
+
+@item Pointer
+Pointers to objects or functions (this includes @samp{C++} references
+and the implicit @samp{this} argument). They are passed in address
+registers, starting from @samp{a0}.
+
+@item Float
+Floating point numbers. If the floating point code generation is
+enabled, they are passed in floating point registers, starting from
+@samp{fp0}. Otherwise, they are handled like the next type.
+
+@item Other
+All the other types of arguments, like large structures, pointers to
+class methods in @samp{C++}, etc. They are always passed on the stack.
+@end table
+
+The value given for @samp{-mregparm} indicates how many arguments of
+each of the above first three types should be passed in registers.
+
+Example: @samp{GCC} is invoked with @samp{-mregparm} (without any
+value, so 2 will be used) to compile a source containing the function:
+
+@example
+void fun(int a, char *str, char b, int c);
+@end example
+
+@samp{a} and @samp{b} will be passed in @samp{d0} and @samp{d1},
+respectively, @samp{str} will be passed in @samp{a0}, and @samp{c}
+will be passed on the stack.
+
+@quotation
+@emph{Note}: To use this option properly, it is very important that
+all sources are fully prototyped. There may be very serious problems
+if they are not, since @samp{GCC} will have to ``guess'' where to put
+arguments, potentially making a wrong decission. Example:
+
+@example
+[in file1.c]
+void f(void)
+@{
+ g(0); /* Call to a function with no prototype. The argument
+ will be put in d0, since it is an integer. */
+@}
+
+[in file2.c]
+void g(char *a) /* The argument is expected in a0, since it is
+ a pointer. */
+@{
+@}
+@end example
+
+@samp{-Wimplicit -Wstrict-prototypes} should be used to ensure that
+there are no prototypes missing.
+
+In case of @samp{stdargs} functions, such as @samp{printf}, all
+arguments are passed on the stack.
+
+As of this writing, @samp{-mregparm} is supported by neither
+@samp{IXEmul} nor @samp{LibNIX}, so its usefulness is very limited.
+
+This option was first made available in the @samp{GCC} 2.7.2.1,
+@samp{Geek Gadgets} snapshot @samp{961012}.
+
+The negative form of @samp{-mregparm} is @samp{-mno-regparm}, and is
+on by default.
+@end quotation
+
+@node -frepo, , -mregparm, Invocation
+@section -frepo
+@cindex -frepo
+@cindex Enable C++ Template Repository
+
+The AmigaOS port of @samp{GCC} includes @samp{C++} @dfn{Template
+Repository} patch, so-called @samp{repo} patch.
+
+In order to activate it, please compile @samp{C++} source files with
+@samp{-frepo}. The compiler will not generate unnecessary
+@samp{template} code, and will create @samp{.rpo} files that contain
+information about @samp{template} symbols used in each source file.
+Afterwards, during linking stage, a special tool called
+@samp{collect2} will make sure that every required instantiation of
+each @samp{template} is linked into the executable, recompiling some
+source files if necessary.
+
+@quotation
+@emph{Note}: This option was first made available in the @samp{GCC}
+2.7.2.1, @samp{Geek Gadgets} snapshot @samp{970109}.
+
+This option is not specific to the AmigaOS port of
+@samp{GCC}, nevertheless it is not fully supported in the baseline
+sources.
+
+This patch has been created in Cygnus Support, a company that is a
+major contributor to the @samp{GNU} project. It has not been
+integrated into the baseline sources due to design disagreements.
+
+The negative form of @samp{-frepo} is @samp{-fno-repo}, and is on by
+default.
+@end quotation
+
+For more information, please refer to the @samp{G++ FAQ}.
+
+@node Attributes, Defines, Invocation, Top
+@chapter Attributes
+@cindex Attributes
+@cindex Variable and function attributes
+
+The following non-standard attributes are available in the AmigaOS
+port of @samp{GCC}:
+
+@menu
+Variable attributes:
+* chip:: Put object in @samp{chip} memory.
+
+Function attributes:
+* saveds:: Reload @samp{a4}.
+* interrupt:: Do not mess with the stack.
+* stackext:: Generate stack extension.
+* regparm:: Pass arguments in registers.
+* stkparm:: Pass arguments on the stack.
+@end menu
+
+@node chip, saveds, Attributes, Attributes
+@section chip
+@cindex chip
+@cindex Put object in chip memory
+
+Amiga hardware requires some data to be located in @samp{chip} memory.
+
+Typically, if an initialized buffer is required (containing a picture
+bitmap, for example), a plain, statically initialized buffer is used,
+and the data is copied into a dynamically allocated @samp{MEMF_CHIP}
+buffer.
+
+This is not necessary with the @samp{chip} attribute. If this
+attribute is specified for an initialized, static variable, it will be
+allocated in @samp{chip} memory automagically by the AmigaOS.
+
+A small example:
+
+@example
+UWORD __attribute__((chip)) bitmap1[] = @{ ... @};
+@end example
+
+@quotation
+@emph{Note}: For compatibility with other AmigaOS @samp{C} compilers,
+a preprocessor symbol @samp{__chip} is available, which expands to
+@code{__attribute__((chip))} (@pxref{Keyword macros}).
+
+All the @samp{chip} attribute does is specifying that data should go
+to a section called @samp{.datachip}. Therefore, the standard
+@samp{GCC} feature @code{__attribute__((section(".datachip")))} can be
+used instead.
+
+This attribute was first made available in the @samp{GCC} 2.7.2.1,
+@samp{Geek Gadgets} snapshot @samp{970328}.
+
+For proper operation, this attribute requires a special version of the
+assembler, which generates standard AmigaOS object files. This version
+is not yet available in @samp{Geek Gadgets} in binary form, since
+support for this object files format is not yet complete.
+@end quotation
+
+@format
+This attribute is not supported with @samp{GCC} 3.3 or newer!
+@end format
+
+@node saveds, interrupt, chip, Attributes
+@section saveds
+@cindex saveds
+@cindex Reload a4
+
+This attribute is ignored, unless base-relative data
+(@pxref{-fbaserel}) is compiled.
+
+To improve speed, programs compiled with the AmigaOS port of
+@samp{GCC} set the @samp{a4} register to the appropriate value only
+once, in the startup code. Code generated with the standard @samp{GCC}
+option @samp{-fpic}, in contrast, sets the @samp{a4} register in every
+function which references global data.
+
+This is only safe as long as all function calls are performed from
+within your own code. Things become ``tricky'' if callback functions,
+like the AmigaOS hooks, interrupt handlers etc. are used. If global
+data is referenced in such functions, @samp{a4} has to be set
+properly.
+
+This is exactly what the @samp{saveds} attribute does: it initializes
+@samp{a4} in the function prologue, and restores it to its original
+value in the function epilogue.
+
+@quotation
+@emph{Note}: For compatibility with other AmigaOS @samp{C} compilers,
+a preprocessor symbol @samp{__saveds} is available, which expands to
+@code{__attribute__((saveds))} (@pxref{Keyword macros}).
+
+Please do not use this attribute in pure executables
+(@pxref{-resident}, @pxref{-resident32}). This is because several
+invocations of pure executables can run concurrently, each one having
+its own data section, and there is no way to find out to which of
+these sections should @samp{a4} be set.
+
+The @samp{saveds} attribute is not necessary in function declarations
+(prototypes).
+@end quotation
+
+This attribute was first made available in the @samp{GCC} 2.7.2.1,
+@samp{Geek Gadgets} snapshot @samp{961012}.
+
+@node interrupt, stackext, saveds, Attributes
+@section interrupt
+@cindex interrupt
+@cindex Do not mess with the stack
+
+This attribute should be used for any kind of callback functions that
+can be called from outside your task. This includes interrupt
+handlers, shared library functions, etc.
+
+Most often, the @samp{interrupt} attribute is only necessary if a
+program is compiled with stack checking or extension
+(@pxref{-mstackcheck}, @pxref{-mstackextend}). It will prevent the
+compiler from generating stack checking or extension code for the
+function it was specified for.
+
+Additionally, it will set @samp{CC} (@dfn{condition codes register})
+in the function epilogue to return value, by performing @code{tstl
+d0}.
+
+@quotation
+@emph{Note}: For compatibility with other AmigaOS @samp{C} compilers,
+a preprocessor symbol @samp{__interrupt} is available, which expands
+to @code{__attribute__((interrupt))} (@pxref{Keyword macros}).
+
+The @samp{interrupt} attribute is mutually exclusive with the
+@samp{stackext} attribute (@pxref{stackext}).
+
+This attribute is not necessary in function declarations (prototypes).
+@end quotation
+
+This attribute was first made available in the @samp{GCC} 2.7.2.1,
+@samp{Geek Gadgets} snapshot @samp{961012}.
+
+@node stackext, regparm, interrupt, Attributes
+@section stackext
+@cindex stackext
+@cindex Generate stack extension
+
+This attribute makes @samp{GCC} generate stack extension code for the
+function for which it was used (@pxref{-mstackextend}). This makes it
+possible to use stack extension selectively, only for the
+``dangerous'' functions --- recursive functions, functions with large
+local variables, etc.
+
+@quotation
+@emph{Note}: For compatibility with other AmigaOS @samp{C} compilers,
+a preprocessor symbol @samp{__stackext} is available, which expands to
+@code{__attribute__((stackext))} (@pxref{Keyword macros}).
+
+The @samp{stackext} attribute is mutually exclusive with the
+@samp{interrupt} attribute (@pxref{interrupt}).
+
+This attribute is not necessary in function declarations (prototypes).
+@end quotation
+
+This attribute was first made available in the @samp{GCC} 2.7.2.1,
+@samp{Geek Gadgets} snapshot @samp{961012}.
+
+@node regparm, stkparm, stackext, Attributes
+@section regparm
+@cindex regparm
+@cindex Pass arguments in registers
+
+The @samp{regparm} attribute, together with the @samp{stkparm}
+attribute (@pxref{stkparm}), can be used to fine-tune the way
+arguments are passed. It makes @samp{GCC} pass arguments in registers
+for the function for which it was used, regardless of whether the
+global @samp{-mregparm} option was used or not (@pxref{-mregparm}).
+
+An optional integer argument ranging from 1 to 4 indicates how many
+arguments of each type should be passed in registers
+(@pxref{-mregparm}). The syntax is the following:
+
+@example
+void __attribute__((regparm(3))) fun(int a, char *str, char b, int c);
+@end example
+
+This will make @samp{GCC} pass @samp{a}, @samp{b} and @samp{c} in
+@samp{d0}, @samp{d1} and @samp{d2}, respectively, and @samp{str} in
+@samp{a0}.
+
+If the argument is not provided, the value given for @samp{-mregparm}
+will be used (or 2 if that option was not specified,
+@pxref{-mregparm}).
+
+@quotation
+@emph{Note}: There is generally no need to use this attribute unless
+files compiled with different calling conventions are linked together.
+
+For compatibility with other AmigaOS @samp{C} compilers, a
+preprocessor symbol @samp{__regargs} is available, which expands to
+@code{__attribute__((regparm))} (@pxref{Keyword macros}).
+
+The @samp{regparm} attribute is mutually exclusive with the
+@samp{stkparm} attribute (@pxref{stkparm}).
+
+This attribute is necessary both in function declarations (prototypes)
+and definitions (function code).
+@end quotation
+
+This attribute was first made available in the @samp{GCC} 2.7.2.1,
+@samp{Geek Gadgets} snapshot @samp{961012}.
+
+@node stkparm, , regparm, Attributes
+@section stkparm
+@cindex stkparm
+@cindex Pass arguments on the stack
+
+The @samp{stkparm} attribute, together with the @samp{regparm}
+attribute (@pxref{regparm}), can be used to fine-tune the way
+arguments are passed. It makes @samp{GCC} pass arguments on stack for
+the function for which it was used, regardless of whether the global
+@samp{-mregparm} option was used or not (@pxref{-mregparm}).
+
+@quotation
+@emph{Note}: There is generally no need to use this attribute unless
+files compiled with different calling conventions are linked together.
+
+For compatibility with other AmigaOS @samp{C} compilers, a
+preprocessor symbol @samp{__stdargs} is available, which expands to
+@code{__attribute__((stkparm))} (@pxref{Keyword macros}).
+
+The @samp{stkparm} attribute is mutually exclusive with the
+@samp{regparm} attribute (@pxref{regparm}).
+
+This attribute is necessary both in function declarations (prototypes)
+and definitions (function code).
+@end quotation
+
+This attribute was first made available in the @samp{GCC} 2.7.2.1,
+@samp{Geek Gadgets} snapshot @samp{961012}.
+
+@node Defines, Miscellaneous, Attributes, Top
+@chapter Defines
+@cindex Defines
+@cindex Preprocessor symbols
+
+The AmigaOS-specific preprocessor symbols available in @samp{GCC} can
+be divided into three groups:
+
+@menu
+* Identifying machine:: What machine is this?
+* Options information:: Which options have been specified?
+* Keyword macros:: Compatibility with other compilers.
+@end menu
+
+@node Identifying machine, Options information, Defines, Defines
+@section Symbols identifying machine
+@cindex Symbols identifying machine
+@cindex What machine is this
+
+The following machine-identifying preprocessor symbols are available:
+
+@table @samp
+@item mc68000
+This macro identifies the machine as having a CPU from the Motorola
+68000 family.
+
+@item amiga
+@item amigaos
+@item amigados
+These macros identify the machine as being an Amiga, running the
+AmigaOS.
+
+@item AMIGA
+@item MCH_AMIGA
+These macros are provided for compatibility with other AmigaOS
+@samp{C} compilers.
+@end table
+
+@quotation
+@emph{Note}: These symbols are available in three groups: plain (as
+specified above), with two leading underscores, and with two leading
+and two tailing underscores. The plain ones are not available when
+compiling with the @samp{-ansi} option.
+
+The @samp{amigados} symbol is obsolete and will be removed in future.
+Please use @samp{amigaos}, which was first made available in the
+@samp{GCC} 2.7.2.1, @samp{Geek Gadgets} snapshot @samp{961012}.
+@end quotation
+
+@node Options information, Keyword macros, Identifying machine, Defines
+@section Symbols identifying specified options
+@cindex Symbols identifying specified options
+@cindex Symbols identifying CPU
+@cindex Symbols identifying ixemul
+@cindex Which CPU model options have been specified
+
+@samp{GCC} has several options to choose the CPU model that the code
+should be generated for. The following preprocessor symbols identify
+which options have been specified on the command line:
+
+@table @samp
+@item mc68020
+Either one of @samp{-m68020}, @samp{-mc68020} or @samp{-mc68020-40}
+has been specified.
+
+@item mc68030
+@samp{-m68030} has been specified.
+
+@item mc68040
+@samp{-m68040} has been specified.
+
+@item mc68060
+@samp{-m68060} @emph{[EXPERIMENTAL]} has been specified.
+
+@item __HAVE_68881__
+@samp{-m68881} has been specified.
+@end table
+
+@quotation
+@emph{Note}: The symbols beginning with @samp{mc} are available in
+three groups: plain (as specified above), with two leading
+underscores, and with two leading and two tailing underscores. The
+plain ones are not available when compiling with the @samp{-ansi}
+option. The ``underscored'' ones were first made available in the
+@samp{GCC} 2.7.2.1, @samp{Geek Gadgets} snapshot @samp{970109}.
+
+@samp{mc68000} is defined regardless of which @samp{-m680x0} options
+have been used.
+@end quotation
+
+In addition to the above, a preprocessor symbol @samp{ixemul}
+(together with the ``underscored'' versions) is available when not
+compiling with @samp{-noixemul} (@pxref{-noixemul}) and identifies the
+runtime environment as @samp{IXEmul}. This symbol was first made
+available in the @samp{GCC} 2.7.2.1, @samp{Geek Gadgets} snapshot
+@samp{970328}.
+
+@node Keyword macros, , Options information, Defines
+@section ``Keyword'' macros
+@cindex Keyword macros
+@cindex Compatibility with other compilers
+
+Most AmigaOS-specific @samp{C} compilers have special ``custom
+keywords'', which make the AmigaOS-specific development easier.
+Unfortunately, the idea of ``custom keywords'' is not available in
+@samp{GCC}. However, @samp{attributes} are available, and they provide
+virtually identical functionality. For compatibility with other
+AmigaOS @samp{C} compilers, preprocessor symbols are provided, which
+expand to the appropriate @samp{attributes} (@pxref{Attributes}).
+
+@table @samp
+@item __chip
+@xref{chip}.
+
+@item __saveds
+@xref{saveds}.
+
+@item __interrupt
+@xref{interrupt}.
+
+@item __stackext
+@xref{stackext}.
+
+@item __regargs
+@xref{regparm}.
+
+@item __stdargs
+@xref{stkparm}.
+
+@item __aligned
+This expands to the standard @samp{GCC}
+@samp{__attribute__((aligned(4)))}.
+@end table
+
+@quotation
+@emph{Note}: With @samp{SAS/C}, these keywords may be specified either
+before or after the type, so the following declaration is correct:
+
+@example
+__saveds void func(void);
+@end example
+
+Unfortunately, the syntax rules of @samp{GCC} 2.7.2.1 do not allow to
+specify the attributes before the type, so the above example must be
+changed to:
+
+@example
+void __saveds func(void);
+@end example
+
+This will be fixed in @samp{GCC} 2.8.0.
+@end quotation
+
+@node Miscellaneous, Index, Defines, Top
+@chapter Miscellaneous
+@cindex Miscellaneous
+@cindex Uncategorizable
+
+The following ``hard to categorize'' features are available in the
+AmigaOS port of @samp{GCC}:
+
+@menu
+* Explicit register specification:: Specify registers for arguments.
+* Case sensitive CPP:: <String.h> is not the same as <string.h>
+* Library flavors:: Linker libraries.
+@end menu
+
+@node Explicit register specification, Case sensitive CPP, Miscellaneous, Miscellaneous
+@section Explicit register specification
+@cindex Explicit register specification
+@cindex Specify registers for arguments
+
+In certain situations, like writing callback hooks, ``patchers'',
+standard shared libraries, etc., functions have to receive arguments
+in particular registers.
+
+@samp{-mregparm} (@pxref{-mregparm}) is not appropriate in this case,
+since it does not give the programmer enough control on @emph{which}
+registers will be used.
+
+To overcome this problem in the AmigaOS port of @samp{GCC}, explicit
+register specification has been extended to be available for function
+arguments, as well:
+
+@example
+void myhook(struct Hook* hook __asm("a0"), APTR object __asm("a2"),
+ APTR message __asm("a1"))
+@{
+ ...
+@}
+@end example
+
+@quotation
+@emph{Note}: This feature is currently not available in @samp{G++}.
+
+Only the @samp{ANSI}-style declarations (prototypes) are supported.
+
+Registers have to be specified both in function declarations
+(prototypes) and definitions (function code).
+@end quotation
+
+This feature was first made available in the @samp{GCC} 2.7.2.1,
+@samp{Geek Gadgets} snapshot @samp{961012}.
+
+@node Case sensitive CPP, Library flavors, Explicit register specification, Miscellaneous
+@section Case sensitive CPP
+@cindex Case sensitive CPP
+@cindex <String.h> is not the same as <string.h>
+
+The preprocessor available in the AmigaOS port of @samp{GCC} is case
+sensitive. This means, that the header names provided in the
+@code{#include} directives have to be correct, including upper and
+lower case letters. This affects only the way the preprocessor works.
+Currently available native AmigaOS file systems are case insensitive.
+
+@quotation
+@emph{Note}: This might seem like a horrible hack and a crazy attempt
+to implement a ``ridiculous'' UNIX feature on Amiga. However, this
+feature has been introduced to terminate the endless @samp{G++}
+problems with a standard @samp{ANSI C} header @file{string.h}: under
+the AmigaOS, a @samp{C++} header @file{String.h} would be included,
+instead.
+@end quotation
+
+@node Library flavors, , Case sensitive CPP, Miscellaneous
+@section Library flavors
+@cindex Library flavors
+@cindex Linker libraries
+
+The AmigaOS port of @samp{GCC} may use different linker libraries
+depending upon the options used while invoking the compiler. These
+libraries reside in subdirectories of the standard locations, such as
+@file{GG:lib/} or, with @samp{GCC} 2.7.2.1,
+@file{GG:lib/gcc-lib/m68k-amigaos/2.7.2.1/}.
+
+If you invoke @code{gcc} with @samp{-v}, you'll see the precise flavor
+of libraries used as a @samp{-fl} option in the @code{ld} invocation.
+Here is a list of the available flavors (and hence the subdirectories
+names):
+
+@itemize @bullet
+@item
+@file{libb} corresponds to the @ref{-fbaserel} option.
+@item
+@file{libb32} corresponds to the @ref{-fbaserel32} option.
+@item
+@file{libm020} corresponds to the @samp{-m68020} (or higher) options.
+@item
+@file{libm881} corresponds to the @samp{-m68881} option.
+@item
+@file{libnix} corresponds to the @ref{-noixemul} option.
+@end itemize
+
+More than one flavor can be specified simultaneously. For example,
+when both @ref{-fbaserel} and @samp{-m68020} are specified, the
+libraries will be searched in @file{libb/libm020} subdirectory (as
+well as in @file{libb} subdirectory and in the standard location).
+
+@node Index, , Miscellaneous, Top
+@chapter Index
+@printindex cp
+
+@contents
+@bye
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/configure.p b/m68k-unknown-amigaos/recipes/patches/gcc/configure.p
new file mode 100644
index 0000000..2561988
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/configure.p
@@ -0,0 +1,12 @@
+--- gcc-3.4.6/configure 2013-05-19 20:08:05.000000000 +0200
++++ configure 2013-05-19 20:23:32.000000000 +0200
+@@ -1060,6 +1060,9 @@
+ *-*-cygwin*)
+ noconfigdirs="autoconf automake send-pr rcs guile perl"
+ ;;
++ m68k-*-amigaos*)
++ noconfigdirs="$noconfigdirs texinfo"
++ ;;
+ *-*-netbsd*)
+ noconfigdirs="rcs"
+ ;;
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.Makefile.in.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.Makefile.in.p
new file mode 100644
index 0000000..2564f97
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.Makefile.in.p
@@ -0,0 +1,133 @@
+--- gcc-3.4.6/gcc/Makefile.in 2013-05-19 20:08:05.000000000 +0200
++++ gcc/Makefile.in 2013-05-19 20:23:32.000000000 +0200
+@@ -541,10 +541,36 @@
+ # List of additional header files to install.
+ EXTRA_HEADERS =@extra_headers_list@
+
++### begin-GG-local
++# List of extra targets that should be executed by make when building
++# the `doc' target.
++EXTRA_DOC_TARGETS =
++### end-GG-local
++
++### begin-GG-local
++# List of extra targets that should be executed by make when building
++# targets `stage1' to `stage4'.
++EXTRA_STAGE1_TARGETS =
++EXTRA_STAGE2_TARGETS =
++EXTRA_STAGE3_TARGETS =
++EXTRA_STAGE4_TARGETS =
++### end-GG-local
++
+ # It is convenient for configure to add the assignment at the beginning,
+ # so don't override it here.
+ USE_COLLECT2 = collect2$(exeext)
+
++### begin-GG-local: dynamic libraries
++# List of extra object files that should be compiled and linked with
++# collect2.
++EXTRA_COLLECT2_OBJS =
++### end-GG-local
++
++### begin-GG-local
++# List of extra targets that should be executed by make when installing.
++EXTRA_INSTALL_TARGETS =
++### end-GG-local
++
+ # List of extra C and assembler files to add to static and shared libgcc2.
+ # Assembler files should have names ending in `.asm'.
+ LIB2FUNCS_EXTRA =
+@@ -651,6 +677,11 @@
+ # at build time.
+ SPECS = specs
+
++# Even if ALLOCA is set, don't use it if compiling with GCC, unless
++# a configuration file overrides this default.
++USE_ALLOCA= ` case "${CC}" in "${OLDCC}") echo "${ALLOCA}" ;; esac `
++USE_HOST_ALLOCA= ` case "${HOST_CC}"@"${HOST_ALLOCA}" in "${OLDCC}"@?*) echo ${HOST_PREFIX}${HOST_ALLOCA} ;; esac `
++
+ # End of variables for you to override.
+
+ # GTM_H lists the config files that the generator files depend on,
+@@ -1186,6 +1217,7 @@
+ SHLIB_NM_FLAGS='$(SHLIB_NM_FLAGS)' \
+ MULTILIB_OSDIRNAMES='$(MULTILIB_OSDIRNAMES)' \
+ mkinstalldirs='$(SHELL) $(srcdir)/mkinstalldirs' \
++ LIBGCC_MULTI='$(LIBGCC_MULTI)' \
+ $(SHELL) mklibgcc > tmp-libgcc.mk
+ mv tmp-libgcc.mk libgcc.mk
+
+@@ -1351,7 +1383,9 @@
+ sbitmap.o: sbitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) flags.h \
+ hard-reg-set.h $(BASIC_BLOCK_H)
+
+-COLLECT2_OBJS = collect2.o tlink.o intl.o version.o
++### begin-GG-local: dynamic libraries
++COLLECT2_OBJS = collect2.o tlink.o intl.o version.o $(EXTRA_COLLECT2_OBJS)
++### end-GG-local
+ COLLECT2_LIBS = @COLLECT2_LIBS@
+ collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS)
+ # Don't try modifying collect2 (aka ld) in place--it might be linking this.
+@@ -2641,7 +2675,7 @@
+ #
+ # Remake the info files.
+
+-doc: $(BUILD_INFO) $(GENERATED_MANPAGES) gccbug
++doc: $(BUILD_INFO) $(GENERATED_MANPAGES) gccbug $(EXTRA_DOC_TARGETS)
+
+ INFOFILES = doc/cpp.info doc/gcc.info doc/gccint.info \
+ doc/gccinstall.info doc/cppinternals.info
+@@ -2810,7 +2844,7 @@
+ -rm -f config.h tconfig.h bconfig.h tm_p.h tm.h
+ -rm -f cs-*
+ -rm -rf libgcc
+- -rm -f doc/*.dvi
++ -rm -f doc/*.dvi doc/*.guide
+ # Delete the include directory.
+ -rm -rf include
+ # Delete files used by the "multilib" facility (including libgcc subdirs).
+@@ -2870,7 +2904,7 @@
+ # broken is small.
+ install: install-common $(INSTALL_HEADERS) $(INSTALL_LIBGCC) \
+ install-cpp install-man install-info install-@POSUB@ \
+- lang.install-normal install-driver
++ $(EXTRA_INSTALL_TARGETS) lang.install-normal install-driver
+
+ # Handle cpp installation.
+ install-cpp: cpp$(exeext)
+@@ -3647,7 +3681,7 @@
+ cp stage1/$${f} . ; \
+ else true; \
+ fi; done
+-stage1: force stage1-start lang.stage1
++stage1: force stage1-start lang.stage1 $(EXTRA_STAGE1_TARGETS)
+ -for dir in . $(SUBDIRS) ; \
+ do \
+ rm -f $$dir/*$(coverageexts) ; \
+@@ -3684,7 +3718,7 @@
+ cp stage2/$${f} . ; \
+ else true; \
+ fi; done
+-stage2: force stage2-start lang.stage2
++stage2: force stage2-start lang.stage2 $(EXTRA_STAGE2_TARGETS)
+
+ stage3-start:
+ -if [ -d stage3 ] ; then true ; else mkdir stage3 ; fi
+@@ -3717,7 +3751,7 @@
+ cp stage3/$${f} . ; \
+ else true; \
+ fi; done
+-stage3: force stage3-start lang.stage3
++stage3: force stage3-start lang.stage3 $(EXTRA_STAGE3_TARGETS)
+
+ stage4-start:
+ -if [ -d stage4 ] ; then true ; else mkdir stage4 ; fi
+@@ -3750,7 +3784,7 @@
+ cp stage4/$${f} . ; \
+ else true; \
+ fi; done
+-stage4: force stage4-start lang.stage4
++stage4: force stage4-start lang.stage4 $(EXTRA_STAGE4_TARGETS)
+
+ stageprofile-start:
+ -if [ -d stageprofile ] ; then true ; else mkdir stageprofile ; fi
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.c-decl.c.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.c-decl.c.p
new file mode 100644
index 0000000..6e7e353
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.c-decl.c.p
@@ -0,0 +1,87 @@
+--- gcc-3.4.6/gcc/c-decl.c 2013-05-19 20:09:27.000000000 +0200
++++ gcc/c-decl.c 2013-05-19 20:23:32.000000000 +0200
+@@ -2960,7 +2960,7 @@
+ and push that on the current scope. */
+
+ void
+-push_parm_decl (tree parm)
++push_parm_decl (tree parm, tree asmspec)
+ {
+ tree decl;
+ int old_dont_save_pending_sizes_p = 0;
+@@ -2983,6 +2983,75 @@
+ PARM, 0, NULL);
+ decl_attributes (&decl, TREE_VALUE (parm), 0);
+
++ /* begin-GG-local: explicit register specification for parameters */
++ if (asmspec)
++#ifdef TARGET_AMIGAOS
++ {
++ const char *regname=TREE_STRING_POINTER(asmspec);
++ int regnum;
++ if ((regnum=decode_reg_name(regname))>=0)
++ {
++ tree type=TREE_TYPE(decl);
++ if (HARD_REGNO_MODE_OK(regnum, TYPE_MODE(type)))
++ {
++ tree t, attrs;
++ /* Build tree for __attribute__ ((asm(regnum))). */
++#if 0
++ /* This doesn't work well because of a bug in
++ attribute_list_contained(), which passes list of arguments to
++ simple_cst_equal() instead of passing every argument
++ separately. */
++ attrs=tree_cons(get_identifier("asm"), tree_cons(NULL_TREE,
++ build_int_2_wide(regnum, 0), NULL_TREE), NULL_TREE);
++#else
++ attrs=tree_cons(get_identifier("asm"),
++ build_int_2_wide(regnum, 0), NULL_TREE);
++#endif
++#if 0
++ /* build_type_attribute_variant() would seem to be more
++ appropriate here. However, that function does not support
++ attributes for parameters properly. It modifies
++ TYPE_MAIN_VARIANT of a new type. As a result, comptypes()
++ thinks that types of parameters in prototype and definition
++ are different and issues error messages. See also comment
++ below. */
++ type=build_type_attribute_variant(type, attrs);
++#else
++ /* First check whether such a type already exists - if yes, use
++ that one. This is very important, since otherwise
++ common_type() would think that it sees two different
++ types and would try to merge them - this could result in
++ warning messages. */
++ for (t=TYPE_MAIN_VARIANT(type); t; t=TYPE_NEXT_VARIANT(t))
++ if (comptypes(t, type, COMPARE_STRICT)==1
++ && attribute_list_equal(TYPE_ATTRIBUTES(t), attrs))
++ break;
++ if (t)
++ type=t;
++ else
++ {
++ /* Create a new variant, with differing attributes.
++ (Hack! Type with differing attributes should no longer be
++ a variant of its main type. See comment above for
++ explanation why this was necessary). */
++ type=build_type_copy(type);
++ TYPE_ATTRIBUTES(type)=attrs;
++ }
++#endif
++ TREE_TYPE(decl)=type;
++ }
++ else
++ error ("%Jregister specified for '%D' isn't suitable for data type",
++ decl, decl);
++ }
++ else
++ error ("invalid register name `%s'", regname);
++ }
++#else /* !TARGET_AMIGAOS */
++ error("explicit register specification for parameters is not supported for this target");
++#endif /* !TARGET_AMIGAOS */
++ /* end-GG-local */
++
+ decl = pushdecl (decl);
+
+ finish_decl (decl, NULL_TREE, NULL_TREE);
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.c-incpath.c.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.c-incpath.c.p
new file mode 100644
index 0000000..9e91ea1
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.c-incpath.c.p
@@ -0,0 +1,19 @@
+--- gcc-3.4.6/gcc/c-incpath.c 2013-05-19 19:56:46.000000000 +0200
++++ gcc/c-incpath.c 2013-05-19 20:23:32.000000000 +0200
+@@ -28,14 +28,14 @@
+ #include "c-incpath.h"
+ #include "cppdefault.h"
+
+-/* Windows does not natively support inodes, and neither does MSDOS.
++/* Windows does not natively support inodes, and neither does MSDOS or AmigaOS.
+ Cygwin's emulation can generate non-unique inodes, so don't use it.
+ VMS has non-numeric inodes. */
+ #ifdef VMS
+ # define INO_T_EQ(A, B) (!memcmp (&(A), &(B), sizeof (A)))
+ # define INO_T_COPY(DEST, SRC) memcpy(&(DEST), &(SRC), sizeof (SRC))
+ #else
+-# if (defined _WIN32 && ! defined (_UWIN)) || defined __MSDOS__
++# if (defined _WIN32 && ! defined (_UWIN)) || defined __MSDOS__ || __amigaos__
+ # define INO_T_EQ(A, B) 0
+ # else
+ # define INO_T_EQ(A, B) ((A) == (B))
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.c-parse.in.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.c-parse.in.p
new file mode 100644
index 0000000..bedb438
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.c-parse.in.p
@@ -0,0 +1,223 @@
+--- c-parse.in 2004-10-15 00:12:53.000000000 +0100
++++ gcc/c-parse.in 2015-01-01 13:56:51.039003490 +0000
+@@ -29,7 +29,7 @@ Software Foundation, 59 Temple Place - S
+ written by AT&T, but I have never seen it. */
+
+ @@ifc
+-%expect 10 /* shift/reduce conflicts, and no reduce/reduce conflicts. */
++%expect 11 /* shift/reduce conflicts, and no reduce/reduce conflicts. */
+ @@end_ifc
+
+ %{
+@@ -1730,7 +1730,7 @@ enum_head:
+
+ structsp_attr:
+ struct_head identifier '{'
+- { $$ = start_struct (RECORD_TYPE, $2);
++ { $<ttype>$ = start_struct (RECORD_TYPE, $2);
+ /* Start scope of tag before parsing components. */
+ }
+ component_decl_list '}' maybe_attribute
+@@ -1741,7 +1741,7 @@ structsp_attr:
+ nreverse ($3), chainon ($1, $5));
+ }
+ | union_head identifier '{'
+- { $$ = start_struct (UNION_TYPE, $2); }
++ { $<ttype>$ = start_struct (UNION_TYPE, $2); }
+ component_decl_list '}' maybe_attribute
+ { $$ = finish_struct ($<ttype>4, nreverse ($5),
+ chainon ($1, $7)); }
+@@ -1750,12 +1750,12 @@ structsp_attr:
+ nreverse ($3), chainon ($1, $5));
+ }
+ | enum_head identifier '{'
+- { $$ = start_enum ($2); }
++ { $<ttype>$ = start_enum ($2); }
+ enumlist maybecomma_warn '}' maybe_attribute
+ { $$ = finish_enum ($<ttype>4, nreverse ($5),
+ chainon ($1, $8)); }
+ | enum_head '{'
+- { $$ = start_enum (NULL_TREE); }
++ { $<ttype>$ = start_enum (NULL_TREE); }
+ enumlist maybecomma_warn '}' maybe_attribute
+ { $$ = finish_enum ($<ttype>3, nreverse ($4),
+ chainon ($1, $7)); }
+@@ -1927,20 +1927,25 @@ absdcl: /* an absolute declarator */
+ | absdcl1
+ ;
+
++/* begin-GG-local: explicit register specification for parameters */
+ absdcl_maybe_attribute: /* absdcl maybe_attribute, but not just attributes */
+- /* empty */
+- { $$ = build_tree_list (build_tree_list (current_declspecs,
+- NULL_TREE),
+- all_prefix_attributes); }
+- | absdcl1
+- { $$ = build_tree_list (build_tree_list (current_declspecs,
+- $1),
+- all_prefix_attributes); }
+- | absdcl1_noea attributes
+- { $$ = build_tree_list (build_tree_list (current_declspecs,
+- $1),
+- chainon ($2, all_prefix_attributes)); }
++ maybeasm
++ { $$ = build_tree_list (
++ build_tree_list (build_tree_list (current_declspecs, NULL_TREE),
++ all_prefix_attributes),
++ $1); }
++ | absdcl1 maybeasm
++ { $$ = build_tree_list (
++ build_tree_list (build_tree_list (current_declspecs, $1),
++ all_prefix_attributes),
++ $2); }
++ | absdcl1_noea maybeasm attributes
++ { $$ = build_tree_list (
++ build_tree_list (build_tree_list (current_declspecs, $1),
++ chainon ($3, all_prefix_attributes)),
++ $2); }
+ ;
++/* end-GG-local */
+
+ absdcl1: /* a nonempty absolute declarator */
+ absdcl1_ea
+@@ -2596,33 +2601,37 @@ parmlist_2: /* empty */
+ }
+ ;
+
++/* begin-GG-local: explicit register specification for parameters */
+ parms:
+ firstparm
+- { push_parm_decl ($1); }
++ { push_parm_decl (TREE_PURPOSE($1), TREE_VALUE($1)); }
+ | parms ',' parm
+- { push_parm_decl ($3); }
++ { push_parm_decl (TREE_PURPOSE($3), TREE_VALUE($3)); }
+ ;
+
+ /* A single parameter declaration or parameter type name,
+ as found in a parmlist. */
+ parm:
+- declspecs_ts setspecs parm_declarator maybe_attribute
+- { $$ = build_tree_list (build_tree_list (current_declspecs,
+- $3),
+- chainon ($4, all_prefix_attributes));
++ declspecs_ts setspecs parm_declarator maybeasm maybe_attribute
++ { $$ = build_tree_list (
++ build_tree_list (build_tree_list (current_declspecs, $3),
++ chainon ($5, all_prefix_attributes)),
++ $4);
+ POP_DECLSPEC_STACK; }
+- | declspecs_ts setspecs notype_declarator maybe_attribute
+- { $$ = build_tree_list (build_tree_list (current_declspecs,
+- $3),
+- chainon ($4, all_prefix_attributes));
++ | declspecs_ts setspecs notype_declarator maybeasm maybe_attribute
++ { $$ = build_tree_list (
++ build_tree_list (build_tree_list (current_declspecs, $3),
++ chainon ($5, all_prefix_attributes)),
++ $4);
+ POP_DECLSPEC_STACK; }
+ | declspecs_ts setspecs absdcl_maybe_attribute
+ { $$ = $3;
+ POP_DECLSPEC_STACK; }
+- | declspecs_nots setspecs notype_declarator maybe_attribute
+- { $$ = build_tree_list (build_tree_list (current_declspecs,
+- $3),
+- chainon ($4, all_prefix_attributes));
++ | declspecs_nots setspecs notype_declarator maybeasm maybe_attribute
++ { $$ = build_tree_list (
++ build_tree_list (build_tree_list (current_declspecs, $3),
++ chainon ($5, all_prefix_attributes)),
++ $4);
+ POP_DECLSPEC_STACK; }
+
+ | declspecs_nots setspecs absdcl_maybe_attribute
+@@ -2633,29 +2642,33 @@ parm:
+ /* The first parm, which must suck attributes from off the top of the parser
+ stack. */
+ firstparm:
+- declspecs_ts_nosa setspecs_fp parm_declarator maybe_attribute
+- { $$ = build_tree_list (build_tree_list (current_declspecs,
+- $3),
+- chainon ($4, all_prefix_attributes));
++ declspecs_ts_nosa setspecs_fp parm_declarator maybeasm maybe_attribute
++ { $$ = build_tree_list (
++ build_tree_list (build_tree_list (current_declspecs, $3),
++ chainon ($5, all_prefix_attributes)),
++ $4);
+ POP_DECLSPEC_STACK; }
+- | declspecs_ts_nosa setspecs_fp notype_declarator maybe_attribute
+- { $$ = build_tree_list (build_tree_list (current_declspecs,
+- $3),
+- chainon ($4, all_prefix_attributes));
++ | declspecs_ts_nosa setspecs_fp notype_declarator maybeasm maybe_attribute
++ { $$ = build_tree_list (
++ build_tree_list (build_tree_list (current_declspecs, $3),
++ chainon ($5, all_prefix_attributes)),
++ $4);
+ POP_DECLSPEC_STACK; }
+ | declspecs_ts_nosa setspecs_fp absdcl_maybe_attribute
+ { $$ = $3;
+ POP_DECLSPEC_STACK; }
+- | declspecs_nots_nosa setspecs_fp notype_declarator maybe_attribute
+- { $$ = build_tree_list (build_tree_list (current_declspecs,
+- $3),
+- chainon ($4, all_prefix_attributes));
++ | declspecs_nots_nosa setspecs_fp notype_declarator maybeasm maybe_attribute
++ { $$ = build_tree_list (
++ build_tree_list (build_tree_list (current_declspecs, $3),
++ chainon ($5, all_prefix_attributes)),
++ $4);
+ POP_DECLSPEC_STACK; }
+
+ | declspecs_nots_nosa setspecs_fp absdcl_maybe_attribute
+ { $$ = $3;
+ POP_DECLSPEC_STACK; }
+ ;
++/* end-GG-local */
+
+ setspecs_fp:
+ setspecs
+@@ -3055,28 +3068,32 @@ mydecl:
+ { pedwarn ("empty declaration"); }
+ ;
+
++/* begin-GG-local: explicit register specification for parameters */
+ myparms:
+ myparm
+- { push_parm_decl ($1); }
++ { push_parm_decl (TREE_PURPOSE($1), TREE_VALUE($1)); }
+ | myparms ',' myparm
+- { push_parm_decl ($3); }
++ { push_parm_decl (TREE_PURPOSE($3), TREE_VALUE($3)); }
+ ;
+
+ /* A single parameter declaration or parameter type name,
+ as found in a parmlist. DOES NOT ALLOW AN INITIALIZER OR ASMSPEC */
+
+ myparm:
+- parm_declarator maybe_attribute
+- { $$ = build_tree_list (build_tree_list (current_declspecs,
+- $1),
+- chainon ($2, all_prefix_attributes)); }
+- | notype_declarator maybe_attribute
+- { $$ = build_tree_list (build_tree_list (current_declspecs,
+- $1),
+- chainon ($2, all_prefix_attributes)); }
++ parm_declarator maybeasm maybe_attribute
++ { $$ = build_tree_list (
++ build_tree_list (build_tree_list (current_declspecs, $1),
++ chainon ($3, all_prefix_attributes)),
++ $2); }
++ | notype_declarator maybeasm maybe_attribute
++ { $$ = build_tree_list (
++ build_tree_list (build_tree_list (current_declspecs, $1),
++ chainon ($2, all_prefix_attributes)),
++ $2); }
+ | absdcl_maybe_attribute
+ { $$ = $1; }
+ ;
++/* end-GG-local */
+
+ optparmlist:
+ /* empty */
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.c-tree.h.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.c-tree.h.p
new file mode 100644
index 0000000..629c4ef
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.c-tree.h.p
@@ -0,0 +1,13 @@
+--- gcc-3.4.6/gcc/c-tree.h 2004-03-01 00:34:49.000000000 +0100
++++ gcc/c-tree.h 2013-05-19 20:23:32.000000000 +0200
+@@ -214,7 +214,9 @@
+ extern void pending_xref_error (void);
+ extern void c_push_function_context (struct function *);
+ extern void c_pop_function_context (struct function *);
+-extern void push_parm_decl (tree);
++/* begin-GG-local: explicit register specification for parameters */
++extern void push_parm_decl (tree, tree);
++/* end-GG-local */
+ extern tree pushdecl_top_level (tree);
+ extern void pushtag (tree, tree);
+ extern tree set_array_declarator_type (tree, tree, int);
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.calls.c.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.calls.c.p
new file mode 100644
index 0000000..b75a0f5
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.calls.c.p
@@ -0,0 +1,24 @@
+--- gcc-3.4.6/gcc/calls.c 2013-05-19 20:08:05.000000000 +0200
++++ gcc/calls.c 2013-05-19 20:23:32.000000000 +0200
+@@ -3777,6 +3777,10 @@
+ }
+ fun = orgfun;
+
++#ifdef LIBCALL_ENCODE_SECTION_INFO
++ LIBCALL_ENCODE_SECTION_INFO (fun);
++#endif
++
+ /* Ensure current function's preferred stack boundary is at least
+ what we need. */
+ if (cfun->preferred_stack_boundary < PREFERRED_STACK_BOUNDARY)
+@@ -3812,6 +3816,10 @@
+
+ /* ??? Unfinished: must pass the memory address as an argument. */
+
++#ifdef LIBCALL_ENCODE_SECTION_INFO
++ LIBCALL_ENCODE_SECTION_INFO (fun);
++#endif
++
+ /* Copy all the libcall-arguments out of the varargs data
+ and into a vector ARGVEC.
+
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.collect2.c.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.collect2.c.p
new file mode 100644
index 0000000..519a71f
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.collect2.c.p
@@ -0,0 +1,200 @@
+--- gcc-3.4.6/gcc/collect2.c 2013-05-19 20:08:05.000000000 +0200
++++ gcc/collect2.c 2013-05-19 20:23:32.000000000 +0200
+@@ -144,6 +144,12 @@
+ #define SCAN_LIBRARIES
+ #endif
+
++/* begin-GG-local: dynamic libraries */
++#ifndef DO_COLLECTING
++#define DO_COLLECTING do_collecting
++#endif
++/* end-GG-local */
++
+ #ifdef USE_COLLECT2
+ int do_collecting = 1;
+ #else
+@@ -256,8 +262,10 @@
+ static void prefix_from_env (const char *, struct path_prefix *);
+ static void prefix_from_string (const char *, struct path_prefix *);
+ static void do_wait (const char *);
+-static void fork_execute (const char *, char **);
+-static void maybe_unlink (const char *);
++/* begin-GG-local: dynamic libraries */
++void fork_execute (const char *, char **);
++void maybe_unlink (const char *);
++/* end-GG-local */
+ static void add_to_list (struct head *, const char *);
+ static int extract_init_priority (const char *);
+ static void sort_ids (struct head *);
+@@ -335,6 +343,12 @@
+ if (status != 0 && output_file != 0 && output_file[0])
+ maybe_unlink (output_file);
+
++/* begin-GG-local: dynamic libraries */
++#ifdef COLLECT2_EXTRA_CLEANUP
++ COLLECT2_EXTRA_CLEANUP();
++#endif
++/* end-GG-local */
++
+ exit (status);
+ }
+
+@@ -423,6 +437,12 @@
+ maybe_unlink (export_file);
+ #endif
+
++/* begin-GG-local: dynamic libraries */
++#ifdef COLLECT2_EXTRA_CLEANUP
++ COLLECT2_EXTRA_CLEANUP();
++#endif
++/* end-GG-local */
++
+ signal (signo, SIG_DFL);
+ kill (getpid (), signo);
+ }
+@@ -609,11 +629,7 @@
+
+ /* Determine the filename to execute (special case for absolute paths). */
+
+- if (*name == '/'
+-#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+- || (*name && name[1] == ':')
+-#endif
+- )
++ if (IS_ABSOLUTE_PATH (name))
+ {
+ if (access (name, X_OK) == 0)
+ {
+@@ -881,6 +897,11 @@
+ const char *q = extract_string (&p);
+ if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
+ num_c_args++;
++/* begin-GG-local: dynamic libraries */
++#ifdef COLLECT2_GCC_OPTIONS_HOOK
++ COLLECT2_GCC_OPTIONS_HOOK(q);
++#endif
++/* end-GG-local */
+ }
+ obstack_free (&temporary_obstack, temporary_firstobj);
+
+@@ -1112,6 +1133,11 @@
+ add_to_list (&libs, s);
+ }
+ #endif
++/* begin-GG-local: dynamic libraries */
++#ifdef COLLECT2_LIBNAME_HOOK
++ COLLECT2_LIBNAME_HOOK(arg);
++#endif
++/* end-GG-local */
+ break;
+
+ #ifdef COLLECT_EXPORT_LIST
+@@ -1146,7 +1172,9 @@
+ break;
+
+ case 's':
+- if (arg[2] == '\0' && do_collecting)
++/* begin-GG-local: dynamic libraries */
++ if (arg[2] == '\0' && DO_COLLECTING)
++/* end-GG-local */
+ {
+ /* We must strip after the nm run, otherwise C++ linking
+ will not work. Thus we strip in the second ld run, or
+@@ -1190,6 +1218,11 @@
+ add_to_list (&libs, arg);
+ }
+ #endif
++/* begin-GG-local: dynamic libraries */
++#ifdef COLLECT2_LIBNAME_HOOK
++ COLLECT2_LIBNAME_HOOK(arg);
++#endif
++/* end-GG-local */
+ }
+ }
+
+@@ -1283,6 +1316,12 @@
+ fprintf (stderr, "\n");
+ }
+
++/* begin-GG-local: dynamic libraries */
++#ifdef COLLECT2_PRELINK_HOOK
++ COLLECT2_PRELINK_HOOK(ld1_argv, &strip_flag);
++#endif
++/* end-GG-local */
++
+ /* Load the program, searching all libraries and attempting to provide
+ undefined symbols from repository information. */
+
+@@ -1295,7 +1334,9 @@
+ constructor or destructor list, just return now. */
+ if (rflag
+ #ifndef COLLECT_EXPORT_LIST
+- || ! do_collecting
++/* begin-GG-local: dynamic libraries */
++ || ! DO_COLLECTING
++/* end-GG-local */
+ #endif
+ )
+ {
+@@ -1312,6 +1353,8 @@
+ return 0;
+ }
+
++/* begin-GG-local: dynamic libraries */
++#ifndef COLLECT2_POSTLINK_HOOK
+ /* Examine the namelist with nm and search it for static constructors
+ and destructors to call.
+ Write the constructor and destructor tables to a .s file and reload. */
+@@ -1331,6 +1374,10 @@
+ notice ("%d destructor(s) found\n", destructors.number);
+ notice ("%d frame table(s) found\n", frame_tables.number);
+ }
++#else /* COLLECT2_POSTLINK_HOOK */
++ COLLECT2_POSTLINK_HOOK(output_file);
++#endif
++/* end-GG-local */
+
+ if (constructors.number == 0 && destructors.number == 0
+ && frame_tables.number == 0
+@@ -1363,6 +1410,11 @@
+ #endif
+ maybe_unlink (c_file);
+ maybe_unlink (o_file);
++/* begin-GG-local: dynamic libraries */
++#ifdef COLLECT2_EXTRA_CLEANUP
++ COLLECT2_EXTRA_CLEANUP();
++#endif
++/* end-GG-local */
+ return 0;
+ }
+
+@@ -1454,6 +1506,11 @@
+ maybe_unlink (export_file);
+ #endif
+
++/* begin-GG-local: dynamic libraries */
++#ifdef COLLECT2_EXTRA_CLEANUP
++ COLLECT2_EXTRA_CLEANUP();
++#endif
++/* end-GG-local */
+ return 0;
+ }
+
+@@ -1567,7 +1624,7 @@
+ fatal_perror (errmsg_fmt, errmsg_arg);
+ }
+
+-static void
++void
+ fork_execute (const char *prog, char **argv)
+ {
+ collect_execute (prog, argv, NULL);
+@@ -1576,7 +1633,7 @@
+
+ /* Unlink a file unless we are debugging. */
+
+-static void
++void
+ maybe_unlink (const char *file)
+ {
+ if (!debug)
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.common.opt.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.common.opt.p
new file mode 100644
index 0000000..61050e1
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.common.opt.p
@@ -0,0 +1,17 @@
+--- gcc-3.4.6/gcc/common.opt 2013-05-19 20:02:45.000000000 +0200
++++ gcc/common.opt 2013-05-19 20:23:32.000000000 +0200
+@@ -226,6 +226,14 @@
+ Common
+ Generate unwind tables that are exact at each instruction boundary
+
++fbaserel
++Common
++Generate base-relative code
++
++fbaserel32
++Common
++Generate base-relative code with no data limits
++
+ fbounds-check
+ Common
+ Generate code to check bounds before indexing arrays
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.gcc.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.gcc.p
index 0f0438c..76465d5 100644
--- a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.gcc.p
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.gcc.p
@@ -1,17 +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"
+--- gcc-3.4.6/gcc/config.gcc 2013-05-19 20:09:27.000000000 +0200
++++ gcc/config.gcc 2013-05-19 20:23:32.000000000 +0200
+@@ -1466,6 +1466,14 @@
+ tm_defines="MOTOROLA USE_GAS"
extra_parts="crtbegin.o crtend.o"
;;
+m68k-*-amigaos*)
-+ tmake_file="m68k/t-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"
++ tm_defines="TARGET_AMIGAOS TARGET_DEFAULT=0" # 68000, no 68881, no bitfield ops
++ 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"
+ tm_file="dbxelf.h elfos.h svr4.h ${tm_file} mcore/mcore-elf.h"
tmake_file=mcore/t-mcore
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.host-linux.c.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.host-linux.c.p
new file mode 100644
index 0000000..c040f23
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.host-linux.c.p
@@ -0,0 +1,11 @@
+--- gcc-3.4.6/gcc/config/host-linux.c 2013-05-19 20:51:29.000000000 +0200
++++ gcc/config/host-linux.c 2013-05-19 20:51:47.000000000 +0200
+@@ -189,7 +189,7 @@
+
+ /* Try to make an anonymous private mmap at the desired location. */
+ addr = mmap (base, size, PROT_READ | PROT_WRITE,
+- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
++ MAP_PRIVATE | MAP_ANON, -1, 0);
+
+ if (addr != base)
+ {
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.host.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.host.p
index f13685e..065fa66 100644
--- a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.host.p
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.host.p
@@ -1,12 +1,14 @@
---- gcc/config.host 2010-12-20 02:28:16.000000000 +0000
-+++ gcc/config.host 2010-12-20 02:31:32.000000000 +0000
-@@ -264,4 +264,9 @@
- out_host_hook_obj=host-hpux.o
- host_xmake_file="${host_xmake_file} x-hpux"
+--- gcc-3.4.6/gcc/config.host 2013-05-19 20:09:27.000000000 +0200
++++ gcc/config.host 2013-05-19 20:23:32.000000000 +0200
+@@ -154,6 +154,11 @@
+ i860-*-sysv4*)
+ host_xmake_file=i860/x-sysv4
;;
+ m68k-*-amigaos*)
-+ host_xm_file="m68k/xm-amigaos.h"
-+ host_xmake_file="m68k/x-amigaos"
++ host_xm_file=m68k/xm-amigaos.h
++ host_xmake_file=m68k/x-amigaos
+ out_host_hook_obj=host-amigaos.o
+ ;;
- esac
+ powerpc-*-darwin*)
+ # powerpc-darwin host support.
+ out_host_hook_obj=host-darwin.o
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.m68k.m68k-protos.h.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.m68k.m68k-protos.h.p
new file mode 100644
index 0000000..222d80c
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.m68k.m68k-protos.h.p
@@ -0,0 +1,14 @@
+--- gcc-3.4.6/gcc/config/m68k/m68k-protos.h 2013-05-19 20:09:27.000000000 +0200
++++ gcc/config/m68k/m68k-protos.h 2013-05-19 20:23:32.000000000 +0200
+@@ -68,3 +68,11 @@
+ extern void override_options (void);
+ extern void init_68881_table (void);
+ extern int m68k_hard_regno_rename_ok(unsigned int, unsigned int);
++
++#ifdef RTX_CODE
++#ifdef TREE_CODE
++extern void m68k_init_cumulative_args (CUMULATIVE_ARGS *, tree);
++extern void m68k_function_arg_advance (CUMULATIVE_ARGS *);
++extern struct rtx_def *m68k_function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree);
++#endif
++#endif
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.m68k.m68k.c.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.m68k.m68k.c.p
new file mode 100644
index 0000000..9ca42a1
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.m68k.m68k.c.p
@@ -0,0 +1,513 @@
+--- gcc-3.4.6/gcc/config/m68k/m68k.c 2013-05-19 20:09:27.000000000 +0200
++++ gcc/config/m68k/m68k.c 2013-05-19 20:23:32.000000000 +0200
+@@ -123,6 +123,8 @@
+ static tree m68k_handle_fndecl_attribute (tree *node, tree name,
+ tree args, int flags,
+ bool *no_add_attrs);
++static tree m68k_handle_type_attribute (tree *, tree, tree, int, bool *);
++static int m68k_comp_type_attributes (tree, tree);
+ static void m68k_compute_frame_layout (void);
+ static bool m68k_save_reg (unsigned int regno, bool interrupt_handler);
+ static int const_int_cost (rtx);
+@@ -138,6 +140,8 @@
+ const char *m68k_align_funcs_string;
+ /* Specify the identification number of the library being built */
+ const char *m68k_library_id_string;
++/* Specify number of registers for integer, pointer and float arguments. */
++const char *m68k_regparm_string;
+
+ /* Specify power of two alignment used for loops. */
+ int m68k_align_loops;
+@@ -145,6 +149,8 @@
+ int m68k_align_jumps;
+ /* Specify power of two alignment used for functions. */
+ int m68k_align_funcs;
++/* Specify number of registers for integer, pointer and float arguments. */
++int m68k_regparm;
+
+ /* Nonzero if the last compare/test insn had FP operands. The
+ sCC expanders peek at this to determine what to do for the
+@@ -208,9 +214,30 @@
+ {
+ /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
+ { "interrupt_handler", 0, 0, true, false, false, m68k_handle_fndecl_attribute },
++
++ /* Stkparm attribute specifies to pass arguments on the stack */
++ { "stkparm", 0, 0, false, true, true, m68k_handle_type_attribute },
++ /* Regparm attribute specifies how many integer arguments are to be
++ passed in registers. */
++ { "regparm", 0, 1, false, true, true, m68k_handle_type_attribute },
++
++#ifdef TARGET_AMIGAOS
++ /* Stackext attribute specifies to generate stackextension code */
++ { "stackext", 0, 0, false, true, true, amigaos_handle_type_attribute },
++ /* Interrupt attribute specifies to generate a special exit code */
++ { "interrupt", 0, 0, false, true, true, amigaos_handle_type_attribute },
++ /* Saveds attribute specifies to generate baserel setup code */
++ { "saveds", 0, 0, false, true, true, amigaos_handle_type_attribute },
++ /* Chip attribute specifies to place data in a "special" section */
++ { "chip", 0, 0, true, false, false, amigaos_handle_decl_attribute },
++#endif
++
+ { NULL, 0, 0, false, false, false, NULL }
+ };
+
++#undef TARGET_COMP_TYPE_ATTRIBUTES
++#define TARGET_COMP_TYPE_ATTRIBUTES m68k_comp_type_attributes
++
+ struct gcc_target targetm = TARGET_INITIALIZER;
+
+ /* Sometimes certain combinations of command options do not make
+@@ -296,6 +323,23 @@
+ m68k_align_funcs = i;
+ }
+
++ /* Validate -mregparm and -mregparm= value. */
++ if (m68k_regparm_string)
++ {
++ m68k_regparm = atoi (m68k_regparm_string);
++ if (m68k_regparm < 1 || m68k_regparm > M68K_MAX_REGPARM)
++ error ("-mregparm=%d is not between 1 and %d",
++ m68k_regparm, M68K_MAX_REGPARM);
++ target_flags |= MASK_REGPARM;
++ }
++ else
++ if (TARGET_REGPARM)
++ m68k_regparm = M68K_DEFAULT_REGPARM;
++
++ /* XXX: FIXME: Workaround for a bug. */
++ if (flag_pic >= 3)
++ flag_strength_reduce = 0;
++
+ /* -fPIC uses 32-bit pc-relative displacements, which don't exist
+ until the 68020. */
+ if (!TARGET_68020 && !TARGET_COLDFIRE && (flag_pic == 2))
+@@ -312,12 +356,14 @@
+ the PLT entry for `foo'. Doing function cse will cause the address of
+ `foo' to be loaded into a register, which is exactly what we want to
+ avoid when we are doing PIC on svr4 m68k. */
+- if (flag_pic)
++ if (flag_pic && flag_pic < 3)
+ flag_no_function_cse = 1;
+
+ SUBTARGET_OVERRIDE_OPTIONS;
+ }
+
++/* Attributes support. */
++
+ /* Return nonzero if FUNC is an interrupt function as specified by the
+ "interrupt_handler" attribute. */
+ static bool
+@@ -350,6 +396,251 @@
+ return NULL_TREE;
+ }
+
++/* 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", name))
++ {
++ if (lookup_attribute ("stkparm", 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", name))
++ {
++ if (lookup_attribute ("regparm", 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", TYPE_ATTRIBUTES (type1)) !=
++ !! lookup_attribute ("stkparm", TYPE_ATTRIBUTES (type2))
++ || !! lookup_attribute ("regparm", TYPE_ATTRIBUTES (type1)) !=
++ !! lookup_attribute ("regparm", TYPE_ATTRIBUTES (type2)))
++ return 0; /* 'regparm' and 'stkparm' are mutually exclusive. */
++
++ arg1 = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type1));
++ arg2 = lookup_attribute ("regparm", 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", TYPE_ATTRIBUTES (fntype)))
++ cum->num_of_regs = 0;
++ else
++ {
++ tree ratree = lookup_attribute ("regparm", 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 (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 << 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;
++}
++
+ static void
+ m68k_compute_frame_layout (void)
+ {
+@@ -428,10 +719,14 @@
+ static bool
+ m68k_save_reg (unsigned int regno, bool interrupt_handler)
+ {
+- if (flag_pic && current_function_uses_pic_offset_table
++ if (flag_pic && flag_pic < 3 && current_function_uses_pic_offset_table
+ && regno == PIC_OFFSET_TABLE_REGNUM)
+ return true;
+
++#ifdef EXTRA_SAVE_REG
++ EXTRA_SAVE_REG(regno);
++#endif
++
+ if (current_function_calls_eh_return)
+ {
+ unsigned int i;
+@@ -480,6 +775,9 @@
+ m68k_output_function_prologue (FILE *stream, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
+ {
+ HOST_WIDE_INT fsize_with_regs;
++#if !defined (DWARF2_DEBUGGING_INFO) && !defined (DWARF2_UNWIND_INFO)
++#define dwarf2out_do_frame() 0
++#endif
+ HOST_WIDE_INT cfa_offset = INCOMING_FRAME_SP_OFFSET;
+
+ m68k_compute_frame_layout();
+@@ -496,8 +794,17 @@
+ if (TARGET_COLDFIRE && current_frame.reg_no > 2)
+ fsize_with_regs += current_frame.reg_no * 4;
+
++#ifdef PROLOGUE_BEGIN_HOOK
++ PROLOGUE_BEGIN_HOOK (stream, fsize_with_regs);
++#endif
++
+ if (frame_pointer_needed)
+ {
++#ifdef HAVE_ALTERNATE_FRAME_SETUP_F
++ if (HAVE_ALTERNATE_FRAME_SETUP_F (fsize_with_regs))
++ ALTERNATE_FRAME_SETUP_F (stream, fsize_with_regs);
++ else
++#endif
+ if (current_frame.size == 0 && TARGET_68040)
+ /* on the 68040, pea + move is faster than link.w 0 */
+ fprintf (stream, MOTOROLA ?
+@@ -528,6 +835,10 @@
+ cfa_offset += current_frame.size;
+ }
+ }
++#ifdef HAVE_ALTERNATE_FRAME_SETUP
++ else if (HAVE_ALTERNATE_FRAME_SETUP (fsize_with_regs))
++ ALTERNATE_FRAME_SETUP (stream, fsize_with_regs);
++#endif
+ else if (fsize_with_regs) /* !frame_pointer_needed */
+ {
+ if (fsize_with_regs < 0x8000)
+@@ -658,7 +969,12 @@
+ dwarf2out_reg_save (l, regno, -cfa_offset + n_regs++ * 4);
+ }
+ }
+- if (!TARGET_SEP_DATA && flag_pic &&
++#ifdef HAVE_ALTERNATE_PIC_SETUP
++ if (HAVE_ALTERNATE_PIC_SETUP)
++ ALTERNATE_PIC_SETUP (stream);
++ else
++#endif
++ if (!TARGET_SEP_DATA && flag_pic && flag_pic < 3 &&
+ (current_function_uses_pic_offset_table ||
+ (!current_function_is_leaf && TARGET_ID_SHARED_LIBRARY)))
+ {
+@@ -921,6 +1237,11 @@
+ }
+ }
+ if (frame_pointer_needed)
++#ifdef HAVE_ALTERNATE_FRAME_DESTR_F
++ if (HAVE_ALTERNATE_FRAME_DESTR_F (fsize_with_regs))
++ ALTERNATE_FRAME_DESTR_F (stream, fsize_with_regs);
++ else
++#endif
+ fprintf (stream, "\tunlk %s\n",
+ reg_names[FRAME_POINTER_REGNUM]);
+ else if (fsize_with_regs)
+@@ -958,10 +1279,17 @@
+ }
+ if (current_function_calls_eh_return)
+ asm_fprintf (stream, "\tadd" ASM_DOT"l %Ra0,%Rsp\n");
++#ifdef EPILOGUE_END_HOOK
++ EPILOGUE_END_HOOK (stream);
++#endif
+ if (m68k_interrupt_function_p (current_function_decl))
+ fprintf (stream, "\trte\n");
+ else if (current_function_pops_args)
+ asm_fprintf (stream, "\trtd %I%d\n", current_function_pops_args);
++#ifdef HAVE_ALTERNATE_RETURN
++ else if (HAVE_ALTERNATE_RETURN)
++ ALTERNATE_RETURN (stream);
++#endif
+ else
+ fprintf (stream, "\trts\n");
+ }
+@@ -1454,12 +1782,20 @@
+ /* First handle a simple SYMBOL_REF or LABEL_REF */
+ if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)
+ {
++#ifdef LEGITIMATE_BASEREL_OPERAND_P
++ if (LEGITIMATE_BASEREL_OPERAND_P (orig))
++ return orig;
++#endif
++
+ if (reg == 0)
+ abort ();
+
+- pic_ref = gen_rtx_MEM (Pmode,
+- gen_rtx_PLUS (Pmode,
+- pic_offset_table_rtx, orig));
++ if (flag_pic < 3)
++ pic_ref = gen_rtx_MEM (Pmode,
++ gen_rtx_PLUS (Pmode,
++ pic_offset_table_rtx, orig));
++ else
++ pic_ref = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, orig);
+ current_function_uses_pic_offset_table = 1;
+ RTX_UNCHANGING_P (pic_ref) = 1;
+ emit_move_insn (reg, pic_ref);
+@@ -3001,6 +3337,10 @@
+ fprintf (file, ":w"); break;
+ case 2:
+ fprintf (file, ":l"); break;
++ case 3:
++ fprintf (file, ":W"); break;
++ case 4:
++ fprintf (file, ":L"); break;
+ default:
+ break;
+ }
+@@ -3488,7 +3828,7 @@
+ xops[0] = DECL_RTL (function);
+
+ /* Logic taken from call patterns in m68k.md. */
+- if (flag_pic)
++ if (flag_pic && flag_pic < 3)
+ {
+ if (TARGET_PCREL)
+ fmt = "bra.l %o0";
+@@ -3544,7 +3884,8 @@
+
+ /* Value is true if hard register REGNO can hold a value of machine-mode MODE.
+ On the 68000, the cpu registers can hold any mode except bytes in address
+- registers, but the 68881 registers can hold only SFmode or DFmode. */
++ registers, but the 68881 registers can hold only SFmode or DFmode.
++ The 68881 registers can't hold anything if 68881 use is disabled. */
+ bool
+ m68k_regno_mode_ok (int regno, enum machine_mode mode)
+ {
+@@ -3569,6 +3910,7 @@
+ smaller. */
+ if ((GET_MODE_CLASS (mode) == MODE_FLOAT
+ || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
++ && TARGET_68881
+ && GET_MODE_UNIT_SIZE (mode) <= 12)
+ return true;
+ }
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.m68k.m68k.h.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.m68k.m68k.h.p
new file mode 100644
index 0000000..b6d1f66
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.m68k.m68k.h.p
@@ -0,0 +1,175 @@
+--- gcc-3.4.6/gcc/config/m68k/m68k.h 2013-05-19 20:09:27.000000000 +0200
++++ gcc/config/m68k/m68k.h 2013-05-19 20:23:32.000000000 +0200
+@@ -226,6 +226,11 @@
+ #define MASK_ID_SHARED_LIBRARY (1<<18)
+ #define TARGET_ID_SHARED_LIBRARY (target_flags & MASK_ID_SHARED_LIBRARY)
+
++/* Compile using the first 'm68k_regparm' data, address and float
++ registers for arguments passing. */
++#define MASK_REGPARM (1<<24)
++#define TARGET_REGPARM (target_flags & MASK_REGPARM)
++
+ /* Compile for a CPU32. A 68020 without bitfields is a good
+ heuristic for a CPU32. */
+ #define TARGET_CPU32 (TARGET_68020 && !TARGET_BITFIELD)
+@@ -342,6 +347,10 @@
+ N_("Use different calling convention using 'rtd'") }, \
+ { "nortd", - MASK_RTD, \
+ N_("Use normal calling convention") }, \
++ { "regparm", MASK_REGPARM, \
++ N_("Pass arguments through registers") }, \
++ { "no-regparm", - MASK_REGPARM, \
++ N_("Don't pass arguments through registers") }, \
+ SUBTARGET_SWITCHES \
+ { "", TARGET_DEFAULT, "" }}
+ /* TARGET_DEFAULT is defined in m68k-none.h, netbsd.h, etc. */
+@@ -364,6 +373,8 @@
+ N_("Function starts are aligned to this power of 2"), 0}, \
+ { "shared-library-id=", &m68k_library_id_string, \
+ N_("ID of shared library to build"), 0}, \
++ { "regparm=", &m68k_regparm_string, \
++ N_("Use this register count to pass arguments"), 0}, \
+ SUBTARGET_OPTIONS \
+ }
+
+@@ -556,7 +567,8 @@
+
+ /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
+ On the 68000, the cpu registers can hold any mode except bytes in
+- address registers, the 68881 registers can hold only SFmode or DFmode. */
++ address registers, the 68881 registers can hold only SFmode or DFmode.
++ The 68881 registers can't hold anything if 68881 use is disabled. */
+
+ #define HARD_REGNO_MODE_OK(REGNO, MODE) \
+ m68k_regno_mode_ok ((REGNO), (MODE))
+@@ -805,7 +817,7 @@
+ /* On the 68000, this is the size of MODE in words,
+ except in the FP regs, where a single reg is always enough. */
+ #define CLASS_MAX_NREGS(CLASS, MODE) \
+- ((CLASS) == FP_REGS ? 1 \
++ ((CLASS) == FP_REGS ? GET_MODE_NUNITS (MODE) \
+ : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
+
+ /* Moves between fp regs and other regs are two insns. */
+@@ -901,10 +913,19 @@
+
+ #define PCC_STATIC_STRUCT_RETURN
+
+-/* 1 if N is a possible register number for function argument passing.
+- On the 68000, no registers are used in this way. */
++/* 1 if N is a possible register number for function argument passing. */
+
+-#define FUNCTION_ARG_REGNO_P(N) 0
++#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))
++
++/* 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. */
++
++#define TARGET_ALTERNATE_ALLOCATE_STACK 0
+
+ /* Define a data type for recording info about an argument list
+ during the scan of that argument list. This data type should
+@@ -912,28 +933,52 @@
+ and about the args processed so far, enough to enable macros
+ such as FUNCTION_ARG to determine where the next arg should go.
+
+- On the m68k, this is a single integer, which is a number of bytes
+- of arguments scanned so far. */
++ 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.
++*/
+
+-#define CUMULATIVE_ARGS int
++struct m68k_args
++{
++ int num_of_regs;
++ long regs_already_used;
++ int last_arg_reg;
++ int last_arg_len;
++};
++
++#define CUMULATIVE_ARGS struct m68k_args
++
++/* 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. */
++
++#define M68K_MAX_REGPARM 4
++
++/* The default number of data, address and float registers to use when
++ user specified '-mregparm' switch, not '-mregparm=<value>' option. */
++
++#define M68K_DEFAULT_REGPARM 2
+
+ /* 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.
+-
+- On the m68k, the offset starts at 0. */
++ For a library call, FNTYPE is 0. */
+
+ #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
+- ((CUM) = 0)
++ (m68k_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.) */
+
+ #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
+- ((CUM) += ((MODE) != BLKmode \
+- ? (GET_MODE_SIZE (MODE) + 3) & ~3 \
+- : (int_size_in_bytes (TYPE) + 3) & ~3))
++ (m68k_function_arg_advance (&(CUM)))
+
+ /* Define where to put the arguments to a function.
+ Value is zero to push the argument on the stack,
+@@ -948,9 +993,15 @@
+ NAMED is nonzero if this argument is a named parameter
+ (otherwise it is an extra parameter matching an ellipsis).
+
+- On the m68k all args are always pushed. */
++ On m68k all args are pushed, except if -mregparm is specified, then
++ a number of arguments is passed in the first 'm68k_regparm' data,
++ address and float registers.
++ Note: by default, the static-chain is passed in a0. Targets that want
++ to make full use of '-mregparm' are advised to pass the static-chain
++ somewhere else. */
+
+-#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) 0
++#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
++ (m68k_function_arg (&(CUM), (MODE), (TYPE)))
+
+ /* For an arg passed partly in registers and partly in memory,
+ this is the number of registers used.
+@@ -1688,14 +1739,17 @@
+
+ #define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
+
++
+ /* Variables in m68k.c */
+ extern const char *m68k_align_loops_string;
+ extern const char *m68k_align_jumps_string;
+ extern const char *m68k_align_funcs_string;
+ extern const char *m68k_library_id_string;
++extern const char *m68k_regparm_string;
+ extern int m68k_align_loops;
+ extern int m68k_align_jumps;
+ extern int m68k_align_funcs;
++extern int m68k_regparm;
+ extern int m68k_last_compare_had_fp_operands;
+
+
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.m68k.m68k.md.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.m68k.m68k.md.p
new file mode 100644
index 0000000..c63b8d5
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.config.m68k.m68k.md.p
@@ -0,0 +1,82 @@
+--- m68k.md.orig 2005-07-26 21:32:25.000000000 +0100
++++ gcc/config/m68k/m68k.md 2015-01-01 14:46:17.666994805 +0000
+@@ -3679,7 +3679,7 @@
+ target = operand_subword_force (operands[0], 0, SFmode);
+ result = expand_binop (SImode, xor_optab,
+ operand_subword_force (operands[1], 0, SFmode),
+- GEN_INT (0x80000000), target, 0, OPTAB_WIDEN);
++ GEN_INT (-2147483647 - 1), target, 0, OPTAB_WIDEN);
+ if (result == 0)
+ abort ();
+
+@@ -3723,7 +3723,7 @@
+ target = operand_subword (operands[0], 0, 1, DFmode);
+ result = expand_binop (SImode, xor_optab,
+ operand_subword_force (operands[1], 0, DFmode),
+- GEN_INT (0x80000000), target, 0, OPTAB_WIDEN);
++ GEN_INT (-2147483647 - 1), target, 0, OPTAB_WIDEN);
+ if (result == 0)
+ abort ();
+
+@@ -6418,7 +6418,7 @@
+ (match_operand:SI 1 "general_operand" "g"))]
+ ;; Operand 1 not really used on the m68000.
+
+- "! flag_pic"
++ "(! flag_pic || flag_pic >= 3)"
+ {
+ #if MOTOROLA && !defined (USE_GAS)
+ return "jsr %0";
+@@ -6433,7 +6433,7 @@
+ (match_operand:SI 1 "general_operand" "g"))]
+ ;; Operand 1 not really used on the m68000.
+
+- "flag_pic"
++ "(flag_pic && flag_pic < 3)"
+ {
+ m68k_output_pic_call(operands[0]);
+ return "";
+@@ -6460,7 +6460,7 @@
+ (call (match_operand:QI 1 "memory_operand" "o")
+ (match_operand:SI 2 "general_operand" "g")))]
+ ;; Operand 2 not really used on the m68000.
+- "! flag_pic"
++ "(! flag_pic || flag_pic >= 3)"
+ {
+ #if MOTOROLA && !defined (USE_GAS)
+ return "jsr %1";
+@@ -6475,7 +6475,7 @@
+ (call (match_operand:QI 1 "memory_operand" "o")
+ (match_operand:SI 2 "general_operand" "g")))]
+ ;; Operand 2 not really used on the m68000.
+- "flag_pic"
++ "(flag_pic && flag_pic < 3)"
+ {
+ m68k_output_pic_call(operands[1]);
+ return "";
+@@ -7170,7 +7170,7 @@
+ target = operand_subword (operands[0], 0, 1, XFmode);
+ result = expand_binop (SImode, xor_optab,
+ operand_subword_force (operands[1], 0, XFmode),
+- GEN_INT (0x80000000), target, 0, OPTAB_WIDEN);
++ GEN_INT (-2147483647 - 1), target, 0, OPTAB_WIDEN);
+ if (result == 0)
+ abort ();
+
+@@ -7334,3 +7334,16 @@
+ default: abort();
+ }
+ })
++
++; This is only needed for some subtargets.
++(define_expand "allocate_stack"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (minus:SI (reg:SI 15) (match_operand:SI 1 "general_operand" "")))
++ (set (reg:SI 15) (minus:SI (reg:SI 15) (match_dup 1)))]
++ "TARGET_ALTERNATE_ALLOCATE_STACK"
++ "
++{
++#ifdef ALTERNATE_ALLOCATE_STACK
++ ALTERNATE_ALLOCATE_STACK(operands);
++#endif
++}")
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.configure.ac.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.configure.ac.p
new file mode 100644
index 0000000..728be6d
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.configure.ac.p
@@ -0,0 +1,35 @@
+--- gcc-3.4.6/gcc/configure.ac 2013-05-19 20:09:27.000000000 +0200
++++ gcc/configure.ac 2013-05-19 20:23:32.000000000 +0200
+@@ -101,10 +101,11 @@
+ # Directories
+ # -----------
+
++### begin-GG-local: local prefix
+ # Specify the local prefix
+ local_prefix=
+ AC_ARG_WITH(local-prefix,
+-[ --with-local-prefix=DIR specifies directory to put local include],
++[ --with-local-prefix=DIR specifies directory to put local include directory (not files).],
+ [case "${withval}" in
+ yes) AC_MSG_ERROR(bad value ${withval} given for local include directory prefix) ;;
+ no) ;;
+@@ -113,8 +114,9 @@
+
+ # Default local prefix if it is empty
+ if test x$local_prefix = x; then
+- local_prefix=/usr/local
++ local_prefix='${prefix}'/local
+ fi
++### end-GG-local
+
+ # Don't set gcc_gxx_include_dir to gxx_include_dir since that's only
+ # passed in by the toplevel make and thus we'd get different behavior
+@@ -962,6 +964,8 @@
+
+ gcc_AC_INITFINI_ARRAY
+
++AC_FUNC_ALLOCA
++
+ # mkdir takes a single argument on some systems.
+ gcc_AC_FUNC_MKDIR_TAKES_ONE_ARG
+
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.configure.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.configure.p
new file mode 100644
index 0000000..d8ba1cf
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.configure.p
@@ -0,0 +1,61 @@
+--- gcc-3.4.6/gcc/configure 2013-05-19 20:09:27.000000000 +0200
++++ gcc/configure 2013-05-19 20:23:32.000000000 +0200
+@@ -1583,6 +1583,7 @@
+ # Directories
+ # -----------
+
++### begin-GG-local: local prefix
+ # Specify the local prefix
+ local_prefix=
+
+@@ -1600,8 +1601,9 @@
+
+ # Default local prefix if it is empty
+ if test x$local_prefix = x; then
+- local_prefix=/usr/local
++ local_prefix='${prefix}'/local
+ fi
++### end-GG-local
+
+ # Don't set gcc_gxx_include_dir to gxx_include_dir since that's only
+ # passed in by the toplevel make and thus we'd get different behavior
+@@ -7258,7 +7260,7 @@
+ # read() to the same fd. The only system known to have a problem here
+ # is VMS, where text files have record structure.
+ case "$host_os" in
+- vms* | ultrix*)
++ vms* | ultrix* | amigaos*)
+ gcc_cv_func_mmap_file=no ;;
+ *)
+ gcc_cv_func_mmap_file=yes;;
+@@ -7282,7 +7284,7 @@
+ # Systems known to be in this category are Windows (all variants),
+ # VMS, and Darwin.
+ case "$host_os" in
+- vms* | cygwin* | pe | mingw* | darwin* | ultrix* | hpux10* | hpux11.00)
++ vms* | cygwin* | pe | mingw* | darwin* | ultrix* | hpux10* | hpux11.00 | amigaos*)
+ gcc_cv_func_mmap_dev_zero=no ;;
+ *)
+ gcc_cv_func_mmap_dev_zero=yes;;
+@@ -7367,7 +7369,7 @@
+ # above for use of /dev/zero.
+ # Systems known to be in this category are Windows, VMS, and SCO Unix.
+ case "$host_os" in
+- vms* | cygwin* | pe | mingw* | sco* | udk* )
++ vms* | cygwin* | pe | mingw* | sco* | udk* | amigaos*)
+ gcc_cv_func_mmap_anon=no ;;
+ *)
+ gcc_cv_func_mmap_anon=yes;;
+@@ -7762,6 +7764,12 @@
+
+ sparc_address_test (0);
+
++#ifdef __amigaos__
++ /* Force this test to succeed for AmigaOS, which has a fairly good
++ vfork() emulation, but doesn't support fork() at all. -fnf */
++ exit (0);
++#endif
++
+ child = vfork ();
+
+ if (child == 0) {
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.cppfiles.c.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.cppfiles.c.p
new file mode 100644
index 0000000..6457748
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.cppfiles.c.p
@@ -0,0 +1,48 @@
+--- gcc-3.4.6/gcc/cppfiles.c 2013-05-19 20:22:04.000000000 +0200
++++ gcc/cppfiles.c 2013-05-19 20:23:32.000000000 +0200
+@@ -50,6 +50,10 @@
+ #ifndef O_BINARY
+ # define O_BINARY 0
+ #endif
++#ifndef OPEN_CASE_SENSITIVE
++/* Default is standard open(). */
++# define OPEN_CASE_SENSITIVE open
++#endif
+
+ /* This structure represents a file searched for by CPP, whether it
+ exists or not. An instance may be pointed to by more than one
+@@ -210,7 +214,7 @@
+ set_stdin_to_binary_mode ();
+ }
+ else
+- file->fd = open (file->path, O_RDONLY | O_NOCTTY | O_BINARY, 0666);
++ file->fd = OPEN_CASE_SENSITIVE (file->path, O_RDONLY | O_NOCTTY | O_BINARY, 0666);
+
+ if (file->fd != -1)
+ {
+@@ -1109,7 +1113,11 @@
+ flen = strlen (fname);
+ path = xmalloc (dlen + 1 + flen + 1);
+ memcpy (path, dir->name, dlen);
+- if (dlen && path[dlen - 1] != '/')
++ if (dlen
++#ifdef VOL_SEPARATOR
++ && path[dlen - 1] != VOL_SEPARATOR
++#endif
++ && path[dlen - 1] != '/')
+ path[dlen++] = '/';
+ memcpy (&path[dlen], fname, flen + 1);
+
+@@ -1157,7 +1165,11 @@
+ len = dir->len;
+ name = alloca (len + sizeof (FILE_NAME_MAP_FILE) + 1);
+ memcpy (name, dir->name, len);
+- if (len && name[len - 1] != '/')
++ if (len
++#ifdef VOL_SEPARATOR
++ && name[len - 1] != VOL_SEPARATOR
++#endif
++ && name[len - 1] != '/')
+ name[len++] = '/';
+ strcpy (name + len, FILE_NAME_MAP_FILE);
+ f = fopen (name, "r");
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.defaults.h.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.defaults.h.p
new file mode 100644
index 0000000..016e899
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.defaults.h.p
@@ -0,0 +1,13 @@
+--- gcc-3.4.6/gcc/defaults.h 2013-05-19 20:08:05.000000000 +0200
++++ gcc/defaults.h 2013-05-19 20:23:32.000000000 +0200
+@@ -280,8 +280,10 @@
+ /* If we have a definition of INCOMING_RETURN_ADDR_RTX, assume that
+ the rest of the DWARF 2 frame unwind support is also provided. */
+ #if !defined (DWARF2_UNWIND_INFO) && defined (INCOMING_RETURN_ADDR_RTX)
++#if !defined (NO_DWARF2_UNWIND_INFO)
+ #define DWARF2_UNWIND_INFO 1
+ #endif
++#endif
+
+ /* If we have named sections, and we're using crtstuff to run ctors,
+ use them for registering eh frame information. */
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.fixinc.mkfixinc.sh.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.fixinc.mkfixinc.sh.p
new file mode 100644
index 0000000..9024640
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.fixinc.mkfixinc.sh.p
@@ -0,0 +1,10 @@
+--- gcc-3.4.6/gcc/fixinc/mkfixinc.sh 2003-10-24 19:47:51.000000000 +0200
++++ gcc/fixinc/mkfixinc.sh 2013-05-19 20:23:32.000000000 +0200
+@@ -47,6 +47,7 @@
+ i?86-*-mingw32* | \
+ i?86-*-uwin* | \
+ i?86-*-interix* | \
++ m68k-*-amigaos* | \
+ powerpc-*-eabiaix* | \
+ powerpc-*-eabisim* | \
+ powerpc-*-eabi* | \
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.flow.c.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.flow.c.p
new file mode 100644
index 0000000..2934804
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.flow.c.p
@@ -0,0 +1,19 @@
+--- gcc-3.4.6/gcc/flow.c 2013-05-19 20:09:27.000000000 +0200
++++ gcc/flow.c 2013-05-19 20:23:32.000000000 +0200
+@@ -2335,11 +2335,13 @@
+ if (n_basic_blocks == 0
+ || (regno < FIRST_PSEUDO_REGISTER
+ && (global_regs[regno]
+- || fixed_regs[regno]
+- || FUNCTION_ARG_REGNO_P (regno))))
++/* begin-GG-local: explicit register specification for parameters */
++ || fixed_regs[regno])))
+ return 0;
+
+- return REGNO_REG_SET_P (ENTRY_BLOCK_PTR->global_live_at_end, regno);
++ return (REGNO_REG_SET_P (ENTRY_BLOCK_PTR->global_live_at_end, regno)
++ && (regno >= FIRST_PSEUDO_REGISTER || ! function_arg_regno_p (regno)));
++/* end-GG-local */
+ }
+
+ /* 1 if register REGNO was alive at a place where `setjmp' was called
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.function.c.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.function.c.p
new file mode 100644
index 0000000..299ea70
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.function.c.p
@@ -0,0 +1,31 @@
+--- gcc-3.4.6/gcc/function.c 2013-05-19 20:08:05.000000000 +0200
++++ gcc/function.c 2013-05-19 20:23:32.000000000 +0200
+@@ -8153,3 +8153,28 @@
+ }
+
+ #include "gt-function.h"
++
++/* begin-GG-local: explicit register specification for parameters */
++/* Return 1 if an argument for the current function was passed in
++ register REGNO. */
++
++int
++function_arg_regno_p (int regno)
++{
++ tree parm = DECL_ARGUMENTS (current_function_decl);
++ for (; parm; parm = TREE_CHAIN (parm))
++ {
++ rtx incoming = DECL_INCOMING_RTL (parm);
++ if (GET_CODE (incoming) == REG)
++ {
++ int incoming_reg;
++ incoming_reg = REGNO (incoming);
++ if (regno >= incoming_reg &&
++ regno < incoming_reg + HARD_REGNO_NREGS (incoming_reg,
++ GET_MODE (incoming)))
++ return 1;
++ }
++ }
++ return 0;
++}
++/* end-GG-local */
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.function.h.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.function.h.p
new file mode 100644
index 0000000..7752b0e
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.function.h.p
@@ -0,0 +1,11 @@
+--- gcc-3.4.6/gcc/function.h 2013-05-19 19:56:54.000000000 +0200
++++ gcc/function.h 2013-05-19 20:23:32.000000000 +0200
+@@ -643,4 +643,8 @@
+
+ extern void do_warn_unused_parameter (tree);
+
++/* begin-GG-local: explicit register specification for parameters */
++extern int function_arg_regno_p (int);
++/* end-GG-local */
++
+ #endif /* GCC_FUNCTION_H */
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.gcc.c.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.gcc.c.p
new file mode 100644
index 0000000..4399b19
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.gcc.c.p
@@ -0,0 +1,63 @@
+--- gcc-3.4.6/gcc/gcc.c 2013-05-19 20:22:04.000000000 +0200
++++ gcc/gcc.c 2013-05-19 20:23:32.000000000 +0200
+@@ -1403,16 +1403,29 @@
+ #define MD_STARTFILE_PREFIX_1 ""
+ #endif
+
++#ifndef STANDARD_EXEC_PREFIX_1
++#define STANDARD_EXEC_PREFIX_1 "/usr/libexec/gcc/"
++#endif
++#ifndef STANDARD_EXEC_PREFIX_2
++#define STANDARD_EXEC_PREFIX_2 "/usr/lib/gcc/"
++#endif
++#ifndef STANDARD_STARTFILE_PREFIX_1
++#define STANDARD_STARTFILE_PREFIX_1 "/lib/"
++#endif
++#ifndef STANDARD_STARTFILE_PREFIX_2
++#define STANDARD_STARTFILE_PREFIX_2 "/usr/lib/"
++#endif
++
+ static const char *const standard_exec_prefix = STANDARD_EXEC_PREFIX;
+-static const char *const standard_exec_prefix_1 = "/usr/libexec/gcc/";
+-static const char *const standard_exec_prefix_2 = "/usr/lib/gcc/";
++static const char *const standard_exec_prefix_1 = STANDARD_EXEC_PREFIX_1;
++static const char *const standard_exec_prefix_2 = STANDARD_EXEC_PREFIX_2;
+ static const char *md_exec_prefix = MD_EXEC_PREFIX;
+
+ static const char *md_startfile_prefix = MD_STARTFILE_PREFIX;
+ static const char *md_startfile_prefix_1 = MD_STARTFILE_PREFIX_1;
+ static const char *const standard_startfile_prefix = STANDARD_STARTFILE_PREFIX;
+-static const char *const standard_startfile_prefix_1 = "/lib/";
+-static const char *const standard_startfile_prefix_2 = "/usr/lib/";
++static const char *const standard_startfile_prefix_1 = STANDARD_STARTFILE_PREFIX_1;
++static const char *const standard_startfile_prefix_2 = STANDARD_STARTFILE_PREFIX_2;
+
+ static const char *const tooldir_base_prefix = TOOLDIR_BASE_PREFIX;
+ static const char *tooldir_prefix;
+@@ -4483,7 +4496,9 @@
+ and it is better not to use them for searching
+ at run time. In particular, stage1 loses. */
+ if (!IS_ABSOLUTE_PATH (pl->prefix))
++#ifndef VOL_SEPARATOR
+ continue;
++#endif /* VOL_SEPARATOR */
+ #endif
+ /* Try subdirectory if there is one. */
+ if (multilib_dir != NULL
+@@ -5853,12 +5868,11 @@
+ /* Exclude directories that the linker is known to search. */
+ if (linker
+ && ((cp - path == 6
+- && strcmp (path, concat (dir_separator_str, "lib",
+- dir_separator_str, ".", NULL)) == 0)
++ && strcmp (path, concat (STANDARD_STARTFILE_PREFIX_1,
++ ".", NULL)) == 0)
+ || (cp - path == 10
+- && strcmp (path, concat (dir_separator_str, "usr",
+- dir_separator_str, "lib",
+- dir_separator_str, ".", NULL)) == 0)))
++ && strcmp (path, concat (STANDARD_STARTFILE_PREFIX_2,
++ ".", NULL)) == 0)))
+ return 0;
+
+ return (stat (path, &st) >= 0 && S_ISDIR (st.st_mode));
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.ginclude.stdarg.h.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.ginclude.stdarg.h.p
new file mode 100644
index 0000000..934c0c9
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.ginclude.stdarg.h.p
@@ -0,0 +1,20 @@
+--- gcc-3.4.6/gcc/ginclude/stdarg.h 2003-03-13 03:58:40.000000000 +0100
++++ gcc/ginclude/stdarg.h 2013-05-19 20:23:32.000000000 +0200
+@@ -93,7 +93,7 @@
+ But on BSD NET2 we must not test or define or undef it.
+ (Note that the comments in NET 2's ansi.h
+ are incorrect for _VA_LIST_--see stdio.h!) */
+-#if !defined (_VA_LIST_) || defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__) || defined(WINNT)
++#if !defined (_VA_LIST_) || defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__) || defined(WINNT) || defined(__amigaos__)
+ /* The macro _VA_LIST_DEFINED is used in Windows NT 3.5 */
+ #ifndef _VA_LIST_DEFINED
+ /* The macro _VA_LIST is used in SCO Unix 3.2. */
+@@ -107,7 +107,7 @@
+ #endif /* not _VA_LIST_T_H */
+ #endif /* not _VA_LIST */
+ #endif /* not _VA_LIST_DEFINED */
+-#if !(defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__))
++#if !(defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__) || defined(__amigaos__))
+ #define _VA_LIST_
+ #endif
+ #ifndef _VA_LIST
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.loop.c.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.loop.c.p
new file mode 100644
index 0000000..6040ce4
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.loop.c.p
@@ -0,0 +1,13 @@
+--- gcc-3.4.6/gcc/loop.c 2013-05-19 20:09:27.000000000 +0200
++++ gcc/loop.c 2013-05-19 20:23:32.000000000 +0200
+@@ -934,6 +934,10 @@
+ == INSN_UID (regs->array[regno].single_usage))
+ && regs->array[regno].set_in_loop == 1
+ && GET_CODE (SET_SRC (set)) != ASM_OPERANDS
++ && (regno >= FIRST_PSEUDO_REGISTER
++ || asm_noperands (PATTERN (regs->array[regno]
++ .single_usage))
++ < 0)
+ && ! side_effects_p (SET_SRC (set))
+ && ! find_reg_note (p, REG_RETVAL, NULL_RTX)
+ && (! SMALL_REGISTER_CLASSES
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.mklibgcc.in.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.mklibgcc.in.p
new file mode 100644
index 0000000..a169484
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.mklibgcc.in.p
@@ -0,0 +1,13 @@
+--- gcc-3.4.6/gcc/mklibgcc.in 2013-05-19 20:09:27.000000000 +0200
++++ gcc/mklibgcc.in 2013-05-19 20:23:32.000000000 +0200
+@@ -42,6 +42,10 @@
+ # SHLIB_INSTALL
+ # MULTILIB_OSDIRNAMES
+
++if [ "$LIBGCC_MULTI" != '' ]; then
++ MULTILIBS=$LIBGCC_MULTI
++fi
++
+ # Make needs VPATH to be literal.
+ echo 'srcdir = @srcdir@'
+ echo 'VPATH = @srcdir@'
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.opts.c.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.opts.c.p
new file mode 100644
index 0000000..1eb8198
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.opts.c.p
@@ -0,0 +1,26 @@
+--- gcc-3.4.6/gcc/opts.c 2004-02-18 01:09:04.000000000 +0100
++++ gcc/opts.c 2013-05-19 20:23:32.000000000 +0200
+@@ -619,7 +619,7 @@
+
+ if (flag_pie)
+ flag_pic = flag_pie;
+- if (flag_pic && !flag_pie)
++ if (flag_pic && flag_pic < 3 && !flag_pie)
+ flag_shlib = 1;
+
+ if (flag_no_inline == 2)
+@@ -889,6 +889,14 @@
+ flag_bounds_check = value;
+ break;
+
++ case OPT_fbaserel:
++ flag_pic = value + value + value;
++ break;
++
++ case OPT_fbaserel32:
++ flag_pic = value + value + value + value;
++ break;
++
+ case OPT_fbranch_count_reg:
+ flag_branch_on_count_reg = value;
+ break;
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.rtl.h.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.rtl.h.p
new file mode 100644
index 0000000..779a3e9
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.rtl.h.p
@@ -0,0 +1,11 @@
+--- gcc-3.4.6/gcc/rtl.h 2013-05-19 20:22:04.000000000 +0200
++++ gcc/rtl.h 2013-05-19 20:23:32.000000000 +0200
+@@ -587,7 +587,7 @@
+ JUMP_INSN, INSN_LIST, BARRIER, CODE_LABEL, CONST, \
+ NOTE)->integrated)
+ #define RTX_UNCHANGING_P(RTX) \
+- (RTL_FLAG_CHECK3("RTX_UNCHANGING_P", (RTX), REG, MEM, CONCAT)->unchanging)
++ (RTL_FLAG_CHECK4("RTX_UNCHANGING_P", (RTX), REG, MEM, CONCAT, PLUS)->unchanging)
+ #define RTX_FRAME_RELATED_P(RTX) \
+ (RTL_FLAG_CHECK5("RTX_FRAME_RELATED_P", (RTX), INSN, CALL_INSN, \
+ JUMP_INSN, BARRIER, SET)->frame_related)
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.toplev.c.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.toplev.c.p
new file mode 100644
index 0000000..8eecf05
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.toplev.c.p
@@ -0,0 +1,11 @@
+--- gcc-3.4.6/gcc/toplev.c 2013-05-19 20:09:28.000000000 +0200
++++ gcc/toplev.c 2013-05-19 20:23:32.000000000 +0200
+@@ -1100,6 +1100,8 @@
+ {"branch-count-reg",&flag_branch_on_count_reg, 1 },
+ {"pic", &flag_pic, 1 },
+ {"PIC", &flag_pic, 2 },
++ {"baserel", &flag_pic, 3 },
++ {"baserel32", &flag_pic, 4 },
+ {"pie", &flag_pie, 1 },
+ {"PIE", &flag_pie, 2 },
+ {"exceptions", &flag_exceptions, 1 },
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/include.filenames.h.p b/m68k-unknown-amigaos/recipes/patches/gcc/include.filenames.h.p
new file mode 100644
index 0000000..a9d5548
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/include.filenames.h.p
@@ -0,0 +1,14 @@
+--- gcc-3.4.6/include/filenames.h 2003-07-01 22:29:16.000000000 +0200
++++ include/filenames.h 2013-05-19 20:23:32.000000000 +0200
+@@ -43,7 +43,11 @@
+ #else /* not DOSish */
+
+ #define IS_DIR_SEPARATOR(c) ((c) == '/')
++#if !defined(__amigaos__)
+ #define IS_ABSOLUTE_PATH(f) (IS_DIR_SEPARATOR((f)[0]))
++#else
++#define IS_ABSOLUTE_PATH(f) (IS_DIR_SEPARATOR((f)[0]) || strchr((f), VOL_SEPARATOR))
++#endif
+ #define FILENAME_CMP(s1, s2) strcmp(s1, s2)
+
+ #endif /* not DOSish */
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/libgcc.config.host.p b/m68k-unknown-amigaos/recipes/patches/gcc/libgcc.config.host.p
deleted file mode 100644
index b02e61f..0000000
--- a/m68k-unknown-amigaos/recipes/patches/gcc/libgcc.config.host.p
+++ /dev/null
@@ -1,11 +0,0 @@
---- libgcc/config.host 2010-12-22 16:21:16.000000000 +0000
-+++ libgcc/config.host 2010-12-22 16:21:42.000000000 +0000
-@@ -391,6 +391,8 @@
- ;;
- m68k-*-rtems*)
- ;;
-+m68k-*-amigaos*)
-+ ;;
- mcore-*-elf)
- ;;
- mcore-*-pe*)
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/libiberty.configure.p b/m68k-unknown-amigaos/recipes/patches/gcc/libiberty.configure.p
new file mode 100644
index 0000000..928f83e
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/libiberty.configure.p
@@ -0,0 +1,105 @@
+--- gcc-3.4.6/libiberty/configure 2003-10-01 19:11:29.000000000 +0200
++++ libiberty/configure 2013-05-19 20:23:32.000000000 +0200
+@@ -347,6 +347,10 @@
+ includedir='${prefix}/include'
+ oldincludedir='/usr/include'
+ infodir='${prefix}/info'
++guidedir='${prefix}/guide'
++htmldir='${prefix}/html'
++psdir='${prefix}/ps'
++dvidir='${prefix}/dvi'
+ mandir='${prefix}/man'
+
+ ac_prev=
+@@ -450,6 +454,26 @@
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
++ -guidedir | --guidedir | --guidedi | --guided | --guide | --gui)
++ ac_prev=guidedir ;;
++ -guidedir=* | --guidedir=* | --guidedi=* | --guided=* | --guide=* |--gui=*)
++ guidedir=$ac_optarg ;;
++
++ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm)
++ ac_prev=htmldir ;;
++ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* |--htm=*)
++ htmldir=$ac_optarg ;;
++
++ -psdir | --psdir | --psdi | --psd | --ps)
++ ac_prev=psdir ;;
++ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
++ psdir=$ac_optarg ;;
++
++ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
++ ac_prev=dvidir ;;
++ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* |--dv=*)
++ dvidir=$ac_optarg ;;
++
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+@@ -825,6 +849,10 @@
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --infodir=DIR info documentation [PREFIX/info]
++ --guidedir=DIR Amigaguide documentation in DIR [PREFIX/guide]
++ --htmldir=DIR HTML documentation in DIR [PREFIX/html]
++ --psdir=DIR postscript documentation in DIR [PREFIX/ps]
++ --dvidir=DIR TeX dvi documentation in DIR [PREFIX/dvi]
+ --mandir=DIR man documentation [PREFIX/man]
+ _ACEOF
+
+@@ -3322,7 +3350,7 @@
+ # Account for people who put trailing slashes in PATH elements.
+ case $as_dir/ in
+ ./ | .// | /cC/* | \
+- /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
++ /etc/* | /c/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+@@ -5108,6 +5136,12 @@
+
+ sparc_address_test (0);
+
++#ifdef __amigaos__
++ /* Force this test to succeed for AmigaOS, which has a fairly good
++ vfork() emulation, but doesn't support fork() at all. -fnf */
++ exit (0);
++#endif
++
+ child = vfork ();
+
+ if (child == 0) {
+@@ -5208,6 +5242,11 @@
+ #define HAVE_WORKING_FORK 1
+ _ACEOF
+
++else
++ cat >> confdefs.h <<\EOF
++#define HAVE_VFORK 1
++EOF
++
+ fi
+
+ if test $ac_cv_func_vfork_works = no; then
+@@ -6761,6 +6800,10 @@
+ s,@includedir@,$includedir,;t t
+ s,@oldincludedir@,$oldincludedir,;t t
+ s,@infodir@,$infodir,;t t
++s,@guidedir@,$guidedir,;t t
++s,@htmldir@,$htmldir,;t t
++s,@psdir@,$psdir,;t t
++s,@dvidir@,$dvidir,;t t
+ s,@mandir@,$mandir,;t t
+ s,@build_alias@,$build_alias,;t t
+ s,@host_alias@,$host_alias,;t t
+@@ -7297,7 +7340,7 @@
+ case $ac_dest in
+ default ) test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
+ if test -n "$CONFIG_FILES"; then
+- if test -n "${with_build_subdir}" || test -n "${with_target_subdir}"; then
++ if test -n "${with_target_subdir}"; then
+ # FIXME: We shouldn't need to set ac_file
+ ac_file=Makefile
+ LD="${ORIGINAL_LD_FOR_MULTILIBS}"
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/libiberty.lbasename.c.p b/m68k-unknown-amigaos/recipes/patches/gcc/libiberty.lbasename.c.p
new file mode 100644
index 0000000..735ca77
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/libiberty.lbasename.c.p
@@ -0,0 +1,13 @@
+--- gcc-3.4.6/libiberty/lbasename.c 2003-12-22 20:21:37.000000000 +0100
++++ libiberty/lbasename.c 2013-05-19 20:23:32.000000000 +0200
+@@ -42,6 +42,10 @@
+ #include "safe-ctype.h"
+ #include "filenames.h"
+
++#ifdef __amigaos__
++#define VOL_SEPARATOR ':'
++#endif
++
+ const char *
+ lbasename (name)
+ const char *name;
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/libiberty.make-temp-file.c.p b/m68k-unknown-amigaos/recipes/patches/gcc/libiberty.make-temp-file.c.p
new file mode 100644
index 0000000..fec49da
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/libiberty.make-temp-file.c.p
@@ -0,0 +1,27 @@
+--- gcc-3.4.6/libiberty/make-temp-file.c 2001-10-17 23:15:41.000000000 +0200
++++ libiberty/make-temp-file.c 2013-05-19 20:23:32.000000000 +0200
+@@ -50,6 +50,10 @@
+ #define DIR_SEPARATOR '/'
+ #endif
+
++#ifdef __amigaos__
++#define VOL_SEPARATOR ':'
++#endif
++
+ /* Name of temporary file.
+ mktemp requires 6 trailing X's. */
+ #define TEMP_FILE "ccXXXXXX"
+@@ -126,8 +130,13 @@
+ len = strlen (base);
+ tmpdir = xmalloc (len + 2);
+ strcpy (tmpdir, base);
++#ifdef VOL_SEPARATOR
++ if (tmpdir[len-1] != DIR_SEPARATOR && tmpdir[len-1] != VOL_SEPARATOR)
++#endif
++{
+ tmpdir[len] = DIR_SEPARATOR;
+ tmpdir[len+1] = '\0';
++}
+
+ memoized_tmpdir = tmpdir;
+ return tmpdir;
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/libiberty.pex-unix.c.p b/m68k-unknown-amigaos/recipes/patches/gcc/libiberty.pex-unix.c.p
new file mode 100644
index 0000000..b90f69e
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/libiberty.pex-unix.c.p
@@ -0,0 +1,13 @@
+--- gcc-3.4.6/libiberty/pex-unix.c 2003-01-24 21:02:11.000000000 +0100
++++ libiberty/pex-unix.c 2013-05-19 20:23:32.000000000 +0200
+@@ -44,6 +44,10 @@
+ #define waitpid(pid, status, flags) wait(status)
+ #endif
+
++#ifdef __amigaos__
++#define fork() vfork()
++#endif
++
+ extern int execv ();
+ extern int execvp ();
+
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/libiberty.strsignal.c.p b/m68k-unknown-amigaos/recipes/patches/gcc/libiberty.strsignal.c.p
new file mode 100644
index 0000000..db4ce9e
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/libiberty.strsignal.c.p
@@ -0,0 +1,13 @@
+--- gcc-3.4.6/libiberty/strsignal.c 2003-04-15 22:36:33.000000000 +0200
++++ libiberty/strsignal.c 2013-05-19 20:23:32.000000000 +0200
+@@ -558,8 +558,8 @@
+
+ void
+ psignal (signo, message)
+- unsigned signo;
+- char *message;
++ unsigned int signo;
++ const char *message;
+ {
+ if (signal_names == NULL)
+ {
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/libstdc++-v3.config.cpu.m68k.atomicity.h.p b/m68k-unknown-amigaos/recipes/patches/gcc/libstdc++-v3.config.cpu.m68k.atomicity.h.p
new file mode 100644
index 0000000..192d911
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/libstdc++-v3.config.cpu.m68k.atomicity.h.p
@@ -0,0 +1,25 @@
+--- gcc-3.4.6/libstdc++-v3/config/cpu/m68k/atomicity.h 2004-03-18 18:36:28.000000000 +0100
++++ libstdc++-v3/config/cpu/m68k/atomicity.h 2013-05-19 20:23:32.000000000 +0200
+@@ -31,7 +31,21 @@
+
+ namespace __gnu_cxx
+ {
+-#if ( defined(__mc68020__) || defined(__mc68030__) \
++#if defined(__amigaos__)
++
++ _Atomic_word
++ __attribute__ ((__unused__))
++ __exchange_and_add (volatile _Atomic_word *__mem, int __val)
++ {
++ _Atomic_word __result;
++
++ __result = *__mem;
++ *__mem = __result + __val;
++
++ return __result;
++ }
++
++#elif ( defined(__mc68020__) || defined(__mc68030__) \
+ || defined(__mc68040__) || defined(__mc68060__) ) \
+ && !defined(__mcpu32__)
+ // These variants support compare-and-swap.
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/libstdc++-v3.configure.p b/m68k-unknown-amigaos/recipes/patches/gcc/libstdc++-v3.configure.p
new file mode 100644
index 0000000..d0f9e88
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/libstdc++-v3.configure.p
@@ -0,0 +1,13 @@
+--- gcc-3.4.6/libstdc++-v3/configure 2013-05-19 20:08:06.000000000 +0200
++++ libstdc++-v3/configure 2013-05-19 20:23:32.000000000 +0200
+@@ -31093,6 +31093,10 @@
+
+ # Base decisions on target environment.
+ case "${host}" in
++ m68k-*-amigaos*)
++ #os_include_dir="os/newlib"
++ ;;
++
+ *-darwin*)
+ # Darwin versions vary, but the linker should work in a cross environment,
+ # so we just check for all the features here.