diff options
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. |